diff --git a/Bld/_init.mak.lnx b/Bld/_init.mak.lnx index e203117631..4adba00be8 100644 --- a/Bld/_init.mak.lnx +++ b/Bld/_init.mak.lnx @@ -62,24 +62,20 @@ include $(BUILD_ROOT)/Bld/_rule.mak.lnx DEBUGPROCS_OBJ = $(OBJ_DIR)/$(BUILD_CONFIG)/$(DEBUGPROCS_NAME) GENERIC_OBJ = $(OBJ_DIR)/$(BUILD_CONFIG)/$(GENERIC_NAME) KERNEL_OBJ = $(OBJ_DIR)/$(BUILD_CONFIG)/$(KERNEL_NAME) -LANGUAGE_OBJ= $(OBJ_DIR)/$(BUILD_CONFIG)/$(LANGUAGE_NAME) APPCORE_OBJ= $(OBJ_DIR)/$(BUILD_CONFIG)/$(APPCORE_NAME) TEXT_OBJ= $(OBJ_DIR)/$(BUILD_CONFIG)/$(TEXT_NAME) CELLAR_OBJ= $(OBJ_DIR)/$(BUILD_CONFIG)/$(CELLAR_NAME) GRENGINE_OBJ= $(OBJ_DIR)/$(BUILD_CONFIG)/$(GRENGINE_NAME) VIEWS_OBJ= $(OBJ_DIR)/$(BUILD_CONFIG)/$(VIEWS_NAME) -DBACCESS_OBJ= $(OBJ_DIR)/$(BUILD_CONFIG)/$(DBACCESS_NAME) DEBUGPROCS_SRC = $(SRC)/$(DEBUGPROCS_NAME) GENERIC_SRC = $(SRC)/$(GENERIC_NAME) KERNEL_SRC = $(SRC)/$(KERNEL_NAME) -LANGUAGE_SRC = $(SRC)/$(LANGUAGE_NAME) APPCORE_SRC = $(SRC)/$(APPCORE_NAME) TEXT_SRC = $(SRC)/$(TEXT_NAME) CELLAR_SRC = $(SRC)/$(CELLAR_NAME) GRENGINE_SRC = $(SRC)/Graphite/$(GRENGINE_NAME) VIEWS_SRC = $(SRC)/$(VIEWS_NAME) -DBACCESS_SRC = $(SRC)/$(DBACCESS_NAME) # Include user specific settings -include $(BUILD_ROOT)/Bld/_user.mak.lnx diff --git a/Bld/_names.mak b/Bld/_names.mak index 768ba7e8ac..29f296c3d0 100644 --- a/Bld/_names.mak +++ b/Bld/_names.mak @@ -7,7 +7,6 @@ KERNEL_NAME =Kernel GENERIC_NAME =Generic GRENGINE_NAME =GrEngine FDO_NAME =FDO -LANGUAGE_NAME =Language FWRESOURCES_NAME =FwResources TEXT_NAME =Text VIEWS_NAME =views diff --git a/Build/FwBuildTasks.dll b/Build/FwBuildTasks.dll index 818bac80c7..6e526b4d95 100755 Binary files a/Build/FwBuildTasks.dll and b/Build/FwBuildTasks.dll differ diff --git a/Build/Linux.targets b/Build/Linux.targets index 568f025ffb..fe60c48b1c 100644 --- a/Build/Linux.targets +++ b/Build/Linux.targets @@ -8,7 +8,7 @@ - - - - + + @@ -161,7 +160,6 @@ - @@ -233,4 +231,16 @@ SecondLine="8856396c-63a9-4bc7-ad47-87ec8b6ef5a4 libManagedComBridge.so"/> + + + + + + + + + + + + diff --git a/Build/RegFree.targets b/Build/RegFree.targets index 88ee3c37c1..c3566f9801 100644 --- a/Build/RegFree.targets +++ b/Build/RegFree.targets @@ -7,17 +7,15 @@ This allows our programs to run without registering our COM DLLs, which in turn allows different versions of FieldWorks to coexist on the same computer. This is only relevant for Windows.--> - - - - + + + - - + + diff --git a/Build/Src/FwBuildTasks/RegFree.cs b/Build/Src/FwBuildTasks/RegFree.cs index 265507b971..26cb4af371 100644 --- a/Build/Src/FwBuildTasks/RegFree.cs +++ b/Build/Src/FwBuildTasks/RegFree.cs @@ -15,7 +15,8 @@ // // --------------------------------------------------------------------------------------------- using System; -using System.Collections.Generic; +using System.Collections.Specialized; +using System.Diagnostics; using System.IO; using System.Linq; using System.Security.Principal; @@ -103,6 +104,12 @@ public RegFree() /// ------------------------------------------------------------------------------------ public ITaskItem[] AsIs { get; set; } + /// + /// Gets or sets the dependent assemblies. Currently, this only accepts paths to assembly + /// manifests. + /// + public ITaskItem[] DependentAssemblies { get; set; } + private bool? m_IsAdmin; private bool UserIsAdmin { @@ -128,7 +135,14 @@ public override bool Execute() Log.LogMessage(MessageImportance.Normal, "RegFree processing {0}", Path.GetFileName(Executable)); - var manifestFile = string.IsNullOrEmpty(Output) ? Executable + ".manifest" : Output; + StringCollection dllPaths = IdlImp.GetFilesFrom(Dlls); + if (dllPaths.Count == 0) + { + string ext = Path.GetExtension(Executable); + if (ext != null && ext.Equals(".dll", StringComparison.InvariantCultureIgnoreCase)) + dllPaths.Add(Executable); + } + string manifestFile = string.IsNullOrEmpty(Output) ? Executable + ".manifest" : Output; try { @@ -145,7 +159,6 @@ public override bool Execute() { regHelper.RedirectRegistry(!UserIsAdmin); var creator = new RegFreeCreator(doc, Log); - var dllPaths = IdlImp.GetFilesFrom(Dlls); var filesToRemove = dllPaths.Cast().Where(fileName => !File.Exists(fileName)).ToList(); foreach (var file in filesToRemove) dllPaths.Remove(file); @@ -164,7 +177,23 @@ public override bool Execute() } } - XmlElement root = creator.CreateExeInfo(Executable); + string assemblyName = Path.GetFileNameWithoutExtension(manifestFile); + Debug.Assert(assemblyName != null); + // The C++ test programs won't run if an assemblyIdentity element exists. + //if (assemblyName.StartsWith("test")) + // assemblyName = null; + string assemblyVersion = null; + try + { + assemblyVersion = FileVersionInfo.GetVersionInfo(Executable).FileVersion; + } + catch + { + // just ignore + } + if (string.IsNullOrEmpty(assemblyVersion)) + assemblyVersion = "1.0.0.0"; + XmlElement root = creator.CreateExeInfo(assemblyName, assemblyVersion); foreach (string fileName in dllPaths) { if (NoTypeLib.Count(f => f.ItemSpec == fileName) != 0) @@ -187,6 +216,12 @@ public override bool Execute() creator.AddAsIs(root, fragmentName); } + foreach (string assemblyFileName in IdlImp.GetFilesFrom(DependentAssemblies)) + { + Log.LogMessage(MessageImportance.Low, "\tAdding dependent assembly {0}", Path.GetFileName(assemblyFileName)); + creator.AddDependentAssembly(root, assemblyFileName); + } + var settings = new XmlWriterSettings { OmitXmlDeclaration = false, diff --git a/Build/Src/FwBuildTasks/RegFreeCreator.cs b/Build/Src/FwBuildTasks/RegFreeCreator.cs index c0ed9527d0..d9c38133bc 100644 --- a/Build/Src/FwBuildTasks/RegFreeCreator.cs +++ b/Build/Src/FwBuildTasks/RegFreeCreator.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.IO; using System.Linq; using System.Runtime.InteropServices; @@ -52,6 +53,7 @@ public class RegFreeCreator private readonly Dictionary _interfaceProxies = new Dictionary(); private readonly Dictionary _tlbGuids = new Dictionary(); private readonly List _nonExistingServers = new List(); + private readonly XmlNamespaceManager _nsManager; private const string UrnSchema = "http://www.w3.org/2001/XMLSchema-instance"; private const string UrnAsmv1 = "urn:schemas-microsoft-com:asm.v1"; @@ -69,6 +71,7 @@ public class RegFreeCreator public RegFreeCreator(XmlDocument doc) { _doc = doc; + _nsManager = CreateNamespaceManager(_doc); } /// ------------------------------------------------------------------------------------ @@ -76,29 +79,37 @@ public RegFreeCreator(XmlDocument doc) /// Initializes a new instance of the class. /// /// The XML document. - /// set to true to display warnings, otherwise - /// false. + /// /// ------------------------------------------------------------------------------------ - public RegFreeCreator(XmlDocument doc, TaskLoggingHelper Log): this(doc) + public RegFreeCreator(XmlDocument doc, TaskLoggingHelper log): this(doc) { - this._log = Log; + _log = log; } #endregion - /// ------------------------------------------------------------------------------------ - /// - /// Creates the info for the executable. The info consist of: - /// - /// name (from file name) - /// version info (from assembly) - /// type (hard coded as "win32" for now) - /// - /// This method also adds the root element with all necessary namespaces. - /// - /// pathname of the file. - /// ------------------------------------------------------------------------------------ - public XmlElement CreateExeInfo(string pathName) + private static XmlNamespaceManager CreateNamespaceManager(XmlDocument doc) + { + var namespaceManager = new XmlNamespaceManager(doc.NameTable); + namespaceManager.AddNamespace("asmv1", UrnAsmv1); + namespaceManager.AddNamespace("asmv2", UrnAsmv2); + namespaceManager.AddNamespace("dsig", UrnDsig); + namespaceManager.AddNamespace("xsi", UrnSchema); + return namespaceManager; + } + + /// ------------------------------------------------------------------------------------ + /// + /// Creates the info for the executable. The info consist of: + /// + /// name (from file name) + /// version info (from assembly) + /// type (hard coded as "win32" for now) + /// + /// This method also adds the root element with all necessary namespaces. + /// + /// ------------------------------------------------------------------------------------ + public XmlElement CreateExeInfo(string assemblyName, string assemblyVersion) { XmlElement elem = _doc.CreateElement("assembly", UrnAsmv1); elem.SetAttribute("manifestVersion", "1.0"); @@ -108,33 +119,21 @@ public XmlElement CreateExeInfo(string pathName) elem.SetAttribute("xmlns:xsi", UrnSchema); elem.SetAttribute("schemaLocation", UrnSchema, UrnAsmv1 + " assembly.adaptive.xsd"); - XmlNode oldChild = _doc.SelectSingleNode("assembly"); + XmlNode oldChild = _doc.SelectSingleNode("asmv1:assembly", _nsManager); if (oldChild != null) _doc.ReplaceChild(elem, oldChild); else _doc.AppendChild(elem); - // The C++ test programs won't run if an assemblyIdentity element exists. - string fileName = Path.GetFileName(pathName); - if (!fileName.StartsWith("test")) + if (!string.IsNullOrEmpty(assemblyName)) { // XmlElement assemblyIdentity = _doc.CreateElement("assemblyIdentity", UrnAsmv1); - assemblyIdentity.SetAttribute("name", fileName); - // ReSharper disable EmptyGeneralCatchClause - try - { - FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(pathName); - assemblyIdentity.SetAttribute("version", versionInfo.FileVersion); - } - catch - { - // just ignore - } - // ReSharper restore EmptyGeneralCatchClause + assemblyIdentity.SetAttribute("name", assemblyName); + assemblyIdentity.SetAttribute("version", assemblyVersion); assemblyIdentity.SetAttribute("type", "win32"); - oldChild = elem.SelectSingleNode("assemblyIdentity"); + oldChild = elem.SelectSingleNode("asmv1:assemblyIdentity", _nsManager); if (oldChild != null) elem.ReplaceChild(assemblyIdentity, oldChild); else @@ -194,16 +193,16 @@ public void ProcessTypeLibrary(XmlElement parent, string fileName) elem.SetAttribute("helpdir", string.Empty); elem.SetAttribute("resourceid", "0"); elem.SetAttribute("flags", flags); - oldChild = file.SelectSingleNode(string.Format("typelib[tlbid='{0}']", - libAttr.guid.ToString("B"))); + oldChild = file.SelectSingleNode(string.Format("asmv1:typelib[asmv1:tlbid='{0}']", + libAttr.guid.ToString("B")), _nsManager); if (oldChild != null) file.ReplaceChild(elem, oldChild); else file.AppendChild(elem); } - Debug.WriteLine(string.Format(@"typelib tlbid=""{0}"" version=""{1}.{2}"" helpdir="""" resourceid=""0"" flags=""{3}""", - libAttr.guid, libAttr.wMajorVerNum, libAttr.wMinorVerNum, flags)); + Debug.WriteLine(@"typelib tlbid=""{0}"" version=""{1}.{2}"" helpdir="""" resourceid=""0"" flags=""{3}""", + libAttr.guid, libAttr.wMajorVerNum, libAttr.wMinorVerNum, flags); int count = typeLib.GetTypeInfoCount(); _log.LogMessage(MessageImportance.Low, "\t\tTypelib has {0} types", count); @@ -215,8 +214,8 @@ public void ProcessTypeLibrary(XmlElement parent, string fileName) ProcessTypeInfo(parent, libAttr.guid, typeInfo); } - oldChild = parent.SelectSingleNode(string.Format("file[name='{0}']", - Path.GetFileName(fileName))); + oldChild = parent.SelectSingleNode(string.Format("asmv1:file[asmv1:name='{0}']", + Path.GetFileName(fileName)), _nsManager); if (oldChild != null) parent.ReplaceChild(file, oldChild); else @@ -258,7 +257,7 @@ private static string GetDefaultValueForKey(RegistryKey parentKey, string keyNam /// ------------------------------------------------------------------------------------ public void ProcessClasses(XmlElement parent) { - using (var regKeyClsid = Registry.CurrentUser.OpenSubKey(Tasks.RegHelper.TmpRegistryKeyHKCR + @"\CLSID")) + using (var regKeyClsid = Registry.CurrentUser.OpenSubKey(RegHelper.TmpRegistryKeyHKCR + @"\CLSID")) { if (regKeyClsid == null) { @@ -274,7 +273,7 @@ public void ProcessClasses(XmlElement parent) if (_coClasses.ContainsKey(clsId.ToLower())) continue; - using (var regKeyClass = regKeyClsid.OpenSubKey(clsId)) + using (RegistryKey regKeyClass = regKeyClsid.OpenSubKey(clsId)) { var className = (string)regKeyClass.GetValue(string.Empty, string.Empty); using (var regKeyInProcServer = regKeyClass.OpenSubKey("InProcServer32")) @@ -301,7 +300,7 @@ public void ProcessClasses(XmlElement parent) /// ------------------------------------------------------------------------------------ public void ProcessInterfaces(XmlElement root) { - using (var regKeyBase = Registry.CurrentUser.OpenSubKey(Tasks.RegHelper.TmpRegistryKeyHKCR)) + using (var regKeyBase = Registry.CurrentUser.OpenSubKey(RegHelper.TmpRegistryKeyHKCR)) using (var regKeyInterfaces = regKeyBase.OpenSubKey("Interface")) { if (regKeyInterfaces == null) @@ -320,8 +319,7 @@ public void ProcessInterfaces(XmlElement root) _log.LogError("no proxyStubClsid32 set for interface with iid {0}", interfaceIid); continue; } - Debug.WriteLine(string.Format("Interface {0} is {1}: {2} methods, proxy: {3}", interfaceIid, - interfaceName, numMethods, proxyStubClsId)); + Debug.WriteLine("Interface {0} is {1}: {2} methods, proxy: {3}", interfaceIid, interfaceName, numMethods, proxyStubClsId); if (!_coClasses.ContainsKey(proxyStubClsId)) { @@ -357,21 +355,6 @@ public void ProcessInterfaces(XmlElement root) } } - /// ------------------------------------------------------------------------------------ - /// - /// Gets the child node. This is similar to XmlNode.SelectSingleNode which has the draw- - /// back that it doesn't work "live". - /// - /// The parent node. - /// Name of the child. - /// The child node, or null if no child with name - /// exists. - /// ------------------------------------------------------------------------------------ - private static XmlNode GetChildNode(XmlNode parentNode, string childName) - { - return parentNode.ChildNodes.Cast().FirstOrDefault(child => child.Name == childName); - } - /// ------------------------------------------------------------------------------------ /// /// Gets the child node with name which has an @@ -478,6 +461,34 @@ public void AddAsIs(XmlElement parent, string fileName) AddFragmentInternal(parent, fileName, null); } + public void AddDependentAssembly(XmlElement parent, string fileName) + { + var depAsmElem = (XmlElement) parent.SelectSingleNode(string.Format("asmv1:dependency/asmv1:dependentAssembly[@asmv2:codebase = '{0}']", Path.GetFileName(fileName)), _nsManager); + if (depAsmElem == null) + { + var depElem = _doc.CreateElement("dependency", UrnAsmv1); + parent.AppendChild(depElem); + depAsmElem = _doc.CreateElement("dependentAssembly", UrnAsmv1); + depElem.AppendChild(depAsmElem); + depAsmElem.SetAttribute("codebase", UrnAsmv2, Path.GetFileName(fileName)); + } + var asmIdElem = (XmlElement) depAsmElem.SelectSingleNode("asmv1:assemblyIdentity", _nsManager); + if (asmIdElem == null) + { + asmIdElem = _doc.CreateElement("assemblyIdentity", UrnAsmv1); + depAsmElem.AppendChild(asmIdElem); + } + + var depAsmManifestDoc = new XmlDocument(); + depAsmManifestDoc.Load(fileName); + var depAsmNsManager = CreateNamespaceManager(depAsmManifestDoc); + var manifestAsmIdElem = (XmlElement) depAsmManifestDoc.SelectSingleNode("/asmv1:assembly/asmv1:assemblyIdentity", depAsmNsManager); + Debug.Assert(manifestAsmIdElem != null); + asmIdElem.SetAttribute("name", manifestAsmIdElem.GetAttribute("name")); + asmIdElem.SetAttribute("version", manifestAsmIdElem.GetAttribute("version")); + asmIdElem.SetAttribute("type", manifestAsmIdElem.GetAttribute("type")); + } + /// ------------------------------------------------------------------------------------ /// /// Processes one type info. We get the necessary information from the type library @@ -509,7 +520,7 @@ private void ProcessTypeInfo(XmlNode parent, Guid tlbGuid, ITypeInfo typeInfo) // Try to get the file element for the server var bldr = new StringBuilder(255); - Tasks.RegHelper.GetLongPathName((string)inprocServer.GetValue(null), bldr, 255); + RegHelper.GetLongPathName((string)inprocServer.GetValue(null), bldr, 255); string serverFullPath = bldr.ToString(); string server = Path.GetFileName(serverFullPath); if (!File.Exists(serverFullPath) && @@ -595,6 +606,7 @@ private void AddOrReplaceCoClass(XmlElement parent, string clsId, string threadi private XmlElement GetOrCreateFileNode(XmlNode parent, string filePath) { string fileName = Path.GetFileName(filePath); + Debug.Assert(fileName != null); if (_files.ContainsKey(fileName)) return _files[fileName]; @@ -606,7 +618,7 @@ private XmlElement GetOrCreateFileNode(XmlNode parent, string filePath) if (fileInfo.Exists) { parent.AppendChild(file); - file.SetAttribute("size", "urn:schemas-microsoft-com:asm.v2", fileInfo.Length.ToString()); + file.SetAttribute("size", "urn:schemas-microsoft-com:asm.v2", fileInfo.Length.ToString(CultureInfo.InvariantCulture)); } _files.Add(fileName, file); return file; diff --git a/Build/Windows.targets b/Build/Windows.targets index 8574610ea9..4eca312d03 100644 --- a/Build/Windows.targets +++ b/Build/Windows.targets @@ -2,10 +2,11 @@ + + DependsOnTargets="Initialize;EncConvertersDlls;CopyOtherDlls;BuildWindowsXslAssemblies"> @@ -99,5 +100,13 @@ --> - + + + ..\Src\Transforms\Application + ..\Src\Transforms\Presentation + + + + + diff --git a/Build/mkall.targets b/Build/mkall.targets index d1107df9a5..a06c25dc66 100644 --- a/Build/mkall.targets +++ b/Build/mkall.targets @@ -4,6 +4,7 @@ + @@ -14,13 +15,13 @@ - + - + @@ -30,10 +31,10 @@ - + @@ -65,7 +66,7 @@ - + @@ -103,10 +103,12 @@ Configuration="$(config-capital)" Target="$(make-target)" BuildRoot="$(fwrt)" WorkingDirectory="$(fwrt)/Src/Graphite/GrEngine"/> + - + + - + @@ -162,52 +164,7 @@ - - - - - - - - - - - - - - - - - - - - - - - + + - + @@ -288,12 +245,6 @@ - http://build.palaso.org/guestAuth/repository/download/bt278/.lastSuccessful http://build.palaso.org/guestAuth/repository/download/bt279/.lastSuccessful + https://protobuf-net.googlecode.com/files/protobuf-net%20r668.zip + https://drive.google.com/uc?export=download&id= dll.mdb pdb @@ -402,6 +355,20 @@ + + + + + + + + + + + + + + @@ -441,6 +408,15 @@ + + + + + + + + + @@ -463,9 +439,6 @@ SkipUnchangedFiles="true" OverwriteReadOnlyFiles="true" Condition="'$(OS)'=='Windows_NT'"/> - - @@ -475,15 +448,6 @@ SkipUnchangedFiles="true" OverwriteReadOnlyFiles="true" Condition="'$(OS)'=='Windows_NT'"/> - - - - - diff --git a/DistFiles/FormattedEditor.dll b/DistFiles/FormattedEditor.dll deleted file mode 100644 index d52e4f82ae..0000000000 Binary files a/DistFiles/FormattedEditor.dll and /dev/null differ diff --git a/DistFiles/HelpSystem.dll b/DistFiles/HelpSystem.dll deleted file mode 100644 index 3c40d5e136..0000000000 Binary files a/DistFiles/HelpSystem.dll and /dev/null differ diff --git a/DistFiles/HtmlEditor.dll b/DistFiles/HtmlEditor.dll deleted file mode 100644 index 8711ce9338..0000000000 Binary files a/DistFiles/HtmlEditor.dll and /dev/null differ diff --git a/DistFiles/Language Explorer/Configuration/Grammar/Edit/toolConfiguration.xml b/DistFiles/Language Explorer/Configuration/Grammar/Edit/toolConfiguration.xml index 826d54ddeb..3e80dac5a3 100644 --- a/DistFiles/Language Explorer/Configuration/Grammar/Edit/toolConfiguration.xml +++ b/DistFiles/Language Explorer/Configuration/Grammar/Edit/toolConfiguration.xml @@ -401,7 +401,7 @@ - + @@ -419,7 +419,7 @@ - + diff --git a/DistFiles/Language Explorer/Transforms/XLingPaperForXXE.xsl b/DistFiles/Language Explorer/Export Templates/XLingPaperForXXE.xsl similarity index 100% rename from DistFiles/Language Explorer/Transforms/XLingPaperForXXE.xsl rename to DistFiles/Language Explorer/Export Templates/XLingPaperForXXE.xsl diff --git a/DistFiles/NetLoc.dll b/DistFiles/NetLoc.dll deleted file mode 100644 index 32d9b148fe..0000000000 Binary files a/DistFiles/NetLoc.dll and /dev/null differ diff --git a/DistFiles/ParatextShared.dll b/DistFiles/ParatextShared.dll deleted file mode 100644 index f02882beaf..0000000000 Binary files a/DistFiles/ParatextShared.dll and /dev/null differ diff --git a/DistFiles/Utilities.dll b/DistFiles/Utilities.dll deleted file mode 100644 index 27c4ef21de..0000000000 Binary files a/DistFiles/Utilities.dll and /dev/null differ diff --git a/Lib/debug/SIL.Collections.dll b/Lib/debug/SIL.Collections.dll index 376a32c006..c810910247 100644 Binary files a/Lib/debug/SIL.Collections.dll and b/Lib/debug/SIL.Collections.dll differ diff --git a/Lib/debug/SIL.Collections.pdb b/Lib/debug/SIL.Collections.pdb index fc9634651b..9b94257cd1 100644 Binary files a/Lib/debug/SIL.Collections.pdb and b/Lib/debug/SIL.Collections.pdb differ diff --git a/Lib/debug/SIL.Machine.dll b/Lib/debug/SIL.Machine.dll index 704ad6aad6..c498f521df 100644 Binary files a/Lib/debug/SIL.Machine.dll and b/Lib/debug/SIL.Machine.dll differ diff --git a/Lib/debug/SIL.Machine.pdb b/Lib/debug/SIL.Machine.pdb index dc96f5e191..ce55ef491c 100644 Binary files a/Lib/debug/SIL.Machine.pdb and b/Lib/debug/SIL.Machine.pdb differ diff --git a/Lib/linux/Common/FwKernelTlb.h b/Lib/linux/Common/FwKernelTlb.h index 44bf793ce4..b2f4a07fd7 100644 --- a/Lib/linux/Common/FwKernelTlb.h +++ b/Lib/linux/Common/FwKernelTlb.h @@ -4,7 +4,7 @@ /* File created by MIDL compiler version 7.00.0555 */ -/* at Tue Sep 10 15:51:54 2013 +/* at Thu Jan 23 11:04:42 2014 */ /* Compiler settings for C:\fwrepo\fw\Output\Common\FwKernelTlb.idl: Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555 diff --git a/Lib/linux/Common/FwKernelTlb.idl b/Lib/linux/Common/FwKernelTlb.idl index 63a8827ba3..9de379b284 100644 --- a/Lib/linux/Common/FwKernelTlb.idl +++ b/Lib/linux/Common/FwKernelTlb.idl @@ -10,7 +10,6 @@ - import "oaidl.idl"; import "ocidl.idl"; import "objidl.idl"; @@ -79,7 +78,6 @@ import "objidl.idl"; - cpp_quote("") @@ -119,7 +117,7 @@ cpp_quote("// This is for code that uses a 64-bit integer for SilTime.") cpp_quote("typedef __int64 SilTime;") cpp_quote("#endif") cpp_quote("") -#line 18 "C:\\fwrepo\\fw\\src\\Kernel\\FwKernelTlb.idl" +#line 17 "C:\\fwrepo\\fw\\src\\Kernel\\FwKernelTlb.idl" cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("F1EF76E0-BE04-11d3-8D9A-005004DEFEC4") cpp_quote(",") cpp_quote("FwKernelLib") cpp_quote(");") [ uuid(F1EF76E0-BE04-11d3-8D9A-005004DEFEC4), version(1.0), helpstring("FieldWorks Kernel") ] library FwKernelLib { @@ -137,7 +135,6 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("F1EF76E0-BE04-11d3-8D9A-0050 - interface ITsString; interface IUndoGrouper; interface IFwMetaDataCache; @@ -442,7 +439,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("6A46D810-7F14-4151-80F5-0B13 { interface IActionHandler; }; -#line 320 "c:\\fwrepo\\fw\\src\\kernel\\FwKernel.idh" +#line 319 "c:\\fwrepo\\fw\\src\\kernel\\FwKernel.idh" @@ -829,9 +826,9 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("24636FD1-DB8D-4b2c-B4C0-44C2 { interface IDebugReport; }; -#line 707 "c:\\fwrepo\\fw\\src\\kernel\\FwKernel.idh" +#line 706 "c:\\fwrepo\\fw\\src\\kernel\\FwKernel.idh" -#line 709 "c:\\fwrepo\\fw\\src\\kernel\\FwKernel.idh" +#line 708 "c:\\fwrepo\\fw\\src\\kernel\\FwKernel.idh" @@ -872,7 +869,7 @@ cpp_quote("GENERIC_DECLARE_SMART_INTERFACE_PTR(") cpp_quote("IUndoGrouper") cpp_ -#line 750 "c:\\fwrepo\\fw\\src\\kernel\\FwKernel.idh" +#line 749 "c:\\fwrepo\\fw\\src\\kernel\\FwKernel.idh" @@ -893,9 +890,9 @@ cpp_quote("GENERIC_DECLARE_SMART_INTERFACE_PTR(") cpp_quote("IComDisposable") cp -#line 771 "c:\\fwrepo\\fw\\src\\kernel\\FwKernel.idh" +#line 770 "c:\\fwrepo\\fw\\src\\kernel\\FwKernel.idh" -#line 22 "C:\\fwrepo\\fw\\src\\Kernel\\FwKernelTlb.idl" +#line 21 "C:\\fwrepo\\fw\\src\\Kernel\\FwKernelTlb.idl" #line 1 "c:\\fwrepo\\fw\\src\\kernel\\TextServ.idh" @@ -932,7 +929,6 @@ cpp_quote("GENERIC_DECLARE_SMART_INTERFACE_PTR(") cpp_quote("IComDisposable") cp - interface ITsString; @@ -2373,11 +2369,10 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("7A1B89C0-C2D6-11d3-9BB7-0040 { interface ITsMultiString; }; -#line 1478 "c:\\fwrepo\\fw\\src\\kernel\\TextServ.idh" - -#line 23 "C:\\fwrepo\\fw\\src\\Kernel\\FwKernelTlb.idl" - #line 1 "C:\\fwrepo\\fw\\src\\Language\\Render.idh" +#line 1477 "c:\\fwrepo\\fw\\src\\kernel\\TextServ.idh" +#line 22 "C:\\fwrepo\\fw\\src\\Kernel\\FwKernelTlb.idl" + #line 1 "c:\\fwrepo\\fw\\src\\kernel\\Render.idh" @@ -2867,7 +2862,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("7A1B89C0-C2D6-11d3-9BB7-0040 { interface IVwGraphicsWin32; }; - #line 492 "C:\\fwrepo\\fw\\src\\Language\\Render.idh" + #line 491 "c:\\fwrepo\\fw\\src\\kernel\\Render.idh" @@ -3020,7 +3015,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("7A1B89C0-C2D6-11d3-9BB7-0040 { interface IVwJustifier; }; - #line 645 "C:\\fwrepo\\fw\\src\\Language\\Render.idh" + #line 644 "c:\\fwrepo\\fw\\src\\kernel\\Render.idh" @@ -3493,7 +3488,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("7A1B89C0-C2D6-11d3-9BB7-0040 { interface IRenderEngine; }; - #line 1118 "C:\\fwrepo\\fw\\src\\Language\\Render.idh" + #line 1117 "c:\\fwrepo\\fw\\src\\kernel\\Render.idh" @@ -3579,8 +3574,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("7A1B89C0-C2D6-11d3-9BB7-0040 { interface IJustifyingRenderer; }; - #line 1204 "C:\\fwrepo\\fw\\src\\Language\\Render.idh" - + #line 1203 "c:\\fwrepo\\fw\\src\\kernel\\Render.idh" @@ -3627,11 +3621,11 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("7A1B89C0-C2D6-11d3-9BB7-0040 -#line 1252 "C:\\fwrepo\\fw\\src\\Language\\Render.idh" -#line 24 "C:\\fwrepo\\fw\\src\\Kernel\\FwKernelTlb.idl" - #line 1 "C:\\fwrepo\\fw\\src\\Language\\Language.idh" +#line 1251 "c:\\fwrepo\\fw\\src\\kernel\\Render.idh" +#line 23 "C:\\fwrepo\\fw\\src\\Kernel\\FwKernelTlb.idl" + #line 1 "c:\\fwrepo\\fw\\src\\kernel\\Language.idh" @@ -5461,7 +5455,7 @@ cpp_quote("GENERIC_DECLARE_SMART_INTERFACE_PTR(") cpp_quote("IRegexMatcher") cpp { interface ILgIcuLocaleEnumerator; }; -#line 1832 "C:\\fwrepo\\fw\\src\\Language\\Language.idh" +#line 1831 "c:\\fwrepo\\fw\\src\\kernel\\Language.idh" -#line 25 "C:\\fwrepo\\fw\\src\\Kernel\\FwKernelTlb.idl" +#line 24 "C:\\fwrepo\\fw\\src\\Kernel\\FwKernelTlb.idl" }; diff --git a/Lib/linux/Common/FwKernelTlb.tlb b/Lib/linux/Common/FwKernelTlb.tlb index 3bcde46556..9fa1ed4a38 100644 Binary files a/Lib/linux/Common/FwKernelTlb.tlb and b/Lib/linux/Common/FwKernelTlb.tlb differ diff --git a/Lib/linux/Common/ViewsTlb.h b/Lib/linux/Common/ViewsTlb.h index a856b4b653..8c4da04eff 100644 --- a/Lib/linux/Common/ViewsTlb.h +++ b/Lib/linux/Common/ViewsTlb.h @@ -4,7 +4,7 @@ /* File created by MIDL compiler version 7.00.0555 */ -/* at Tue Sep 10 15:51:55 2013 +/* at Thu Jan 23 11:04:44 2014 */ /* Compiler settings for C:\fwrepo\fw\Output\Common\ViewsTlb.idl: Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555 diff --git a/Lib/linux/Common/ViewsTlb.idl b/Lib/linux/Common/ViewsTlb.idl index bac77d9218..3a750a7838 100644 --- a/Lib/linux/Common/ViewsTlb.idl +++ b/Lib/linux/Common/ViewsTlb.idl @@ -13,7 +13,6 @@ - import "oaidl.idl"; import "ocidl.idl"; import "objidl.idl"; @@ -82,7 +81,6 @@ import "objidl.idl"; - cpp_quote("") @@ -122,10 +120,10 @@ cpp_quote("// This is for code that uses a 64-bit integer for SilTime.") cpp_quote("typedef __int64 SilTime;") cpp_quote("#endif") cpp_quote("") -#line 21 "C:\\fwrepo\\fw\\Src\\Views\\ViewsTlb.idl" +#line 20 "C:\\fwrepo\\fw\\Src\\Views\\ViewsTlb.idl" cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("f6d10640-c00c-11d2-8078-0000c0fb81b5") cpp_quote(",") cpp_quote("Views") cpp_quote(");") [ uuid(f6d10640-c00c-11d2-8078-0000c0fb81b5), version(1.0), helpstring("Views 1.0 Type Library") ] library Views -#line 24 "C:\\fwrepo\\fw\\Src\\Views\\ViewsTlb.idl" +#line 23 "C:\\fwrepo\\fw\\Src\\Views\\ViewsTlb.idl" { importlib("FwKernelTlb.tlb"); @@ -150,7 +148,6 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("f6d10640-c00c-11d2-8078-0000 - @@ -1514,7 +1511,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("f6d10640-c00c-11d2-8078-0000 interface IVwCacheDa; interface IStructuredTextDataAccess; }; - #line 1385 "c:\\fwrepo\\fw\\src\\views\\Views.idh" + #line 1384 "c:\\fwrepo\\fw\\src\\views\\Views.idh" @@ -1728,7 +1725,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("f6d10640-c00c-11d2-8078-0000 -#line 1599 "c:\\fwrepo\\fw\\src\\views\\Views.idh" +#line 1598 "c:\\fwrepo\\fw\\src\\views\\Views.idh" @@ -2530,7 +2527,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("f6d10640-c00c-11d2-8078-0000 { interface IVwRootBox; }; -#line 2401 "c:\\fwrepo\\fw\\src\\views\\Views.idh" +#line 2400 "c:\\fwrepo\\fw\\src\\views\\Views.idh" @@ -4376,14 +4373,14 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("f6d10640-c00c-11d2-8078-0000 -#line 4247 "c:\\fwrepo\\fw\\src\\views\\Views.idh" +#line 4246 "c:\\fwrepo\\fw\\src\\views\\Views.idh" }; cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("CCE2A7ED-464C-4ec7-A0B0-E3C1F6B94C5A") cpp_quote(",") cpp_quote("VwStylesheet") cpp_quote(");") [ uuid(CCE2A7ED-464C-4ec7-A0B0-E3C1F6B94C5A) ] coclass VwStylesheet { interface IVwStylesheet; }; -#line 4254 "c:\\fwrepo\\fw\\src\\views\\Views.idh" +#line 4253 "c:\\fwrepo\\fw\\src\\views\\Views.idh" @@ -4460,7 +4457,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("f6d10640-c00c-11d2-8078-0000 { interface IVwPropertyStore; }; - #line 4331 "c:\\fwrepo\\fw\\src\\views\\Views.idh" + #line 4330 "c:\\fwrepo\\fw\\src\\views\\Views.idh" typedef [v1_enum] enum VwOverlayFlags @@ -4744,7 +4741,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("f6d10640-c00c-11d2-8078-0000 { interface IVwOverlay; }; - #line 4615 "c:\\fwrepo\\fw\\src\\views\\Views.idh" + #line 4614 "c:\\fwrepo\\fw\\src\\views\\Views.idh" @@ -4956,7 +4953,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("f6d10640-c00c-11d2-8078-0000 { interface IVwPrintContext; }; - #line 4827 "c:\\fwrepo\\fw\\src\\views\\Views.idh" + #line 4826 "c:\\fwrepo\\fw\\src\\views\\Views.idh" @@ -5267,7 +5264,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("f6d10640-c00c-11d2-8078-0000 { interface IVwPattern; }; - #line 5138 "c:\\fwrepo\\fw\\src\\views\\Views.idh" + #line 5137 "c:\\fwrepo\\fw\\src\\views\\Views.idh" @@ -5301,7 +5298,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("f6d10640-c00c-11d2-8078-0000 interface IVwTxtSrcInit2; interface IVwTextSource; }; - #line 5172 "c:\\fwrepo\\fw\\src\\views\\Views.idh" + #line 5171 "c:\\fwrepo\\fw\\src\\views\\Views.idh" @@ -5333,7 +5330,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("f6d10640-c00c-11d2-8078-0000 interface IVwTxtSrcInit; interface IVwTextSource; }; - #line 5204 "c:\\fwrepo\\fw\\src\\views\\Views.idh" + #line 5203 "c:\\fwrepo\\fw\\src\\views\\Views.idh" @@ -5375,7 +5372,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("f6d10640-c00c-11d2-8078-0000 { interface IVwSearchKiller; }; - #line 5246 "c:\\fwrepo\\fw\\src\\views\\Views.idh" + #line 5245 "c:\\fwrepo\\fw\\src\\views\\Views.idh" @@ -5455,7 +5452,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("f6d10640-c00c-11d2-8078-0000 { interface IVwDrawRootBuffered; }; - #line 5326 "c:\\fwrepo\\fw\\src\\views\\Views.idh" + #line 5325 "c:\\fwrepo\\fw\\src\\views\\Views.idh" @@ -5503,7 +5500,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("f6d10640-c00c-11d2-8078-0000 { interface IVwSynchronizer; }; - #line 5374 "c:\\fwrepo\\fw\\src\\views\\Views.idh" + #line 5373 "c:\\fwrepo\\fw\\src\\views\\Views.idh" @@ -5672,7 +5669,7 @@ cpp_quote("ATTACH_GUID_TO_CLASS(class,") cpp_quote("1CD09E06-6978-4969-A1FC-4627 { interface IVwLayoutStream; }; -#line 5543 "c:\\fwrepo\\fw\\src\\views\\Views.idh" +#line 5542 "c:\\fwrepo\\fw\\src\\views\\Views.idh" @@ -5785,7 +5782,7 @@ cpp_quote("GENERIC_DECLARE_SMART_INTERFACE_PTR(") cpp_quote("IVwLayoutManager") { interface IPictureFactory; }; -#line 5656 "c:\\fwrepo\\fw\\src\\views\\Views.idh" +#line 5655 "c:\\fwrepo\\fw\\src\\views\\Views.idh" @@ -6019,7 +6016,7 @@ cpp_quote("GENERIC_DECLARE_SMART_INTERFACE_PTR(") cpp_quote("IVwLayoutManager") { interface IVwWindow; }; - #line 5890 "c:\\fwrepo\\fw\\src\\views\\Views.idh" + #line 5889 "c:\\fwrepo\\fw\\src\\views\\Views.idh" typedef [v1_enum] enum VwMouseEvent @@ -6088,6 +6085,6 @@ cpp_quote("GENERIC_DECLARE_SMART_INTERFACE_PTR(") cpp_quote("IViewInputMgr") cpp HRESULT OnTextChange(); } -#line 29 "C:\\fwrepo\\fw\\Src\\Views\\ViewsTlb.idl" +#line 28 "C:\\fwrepo\\fw\\Src\\Views\\ViewsTlb.idl" }; diff --git a/Lib/linux/Common/ViewsTlb.tlb b/Lib/linux/Common/ViewsTlb.tlb index 0e8bd01012..3ea4c3e5ae 100644 Binary files a/Lib/linux/Common/ViewsTlb.tlb and b/Lib/linux/Common/ViewsTlb.tlb differ diff --git a/Lib/linux/Common/idhfiles.MD5 b/Lib/linux/Common/idhfiles.MD5 index 3091832506..1ae0185143 100644 --- a/Lib/linux/Common/idhfiles.MD5 +++ b/Lib/linux/Common/idhfiles.MD5 @@ -1 +1 @@ -b1342b26fd1307740812278bc500d5dd \ No newline at end of file +326b264da2b700e4cccb0fdfd40269bd \ No newline at end of file diff --git a/Lib/release/SIL.Collections.dll b/Lib/release/SIL.Collections.dll index bd76f6b4ec..6c6dd14eb7 100644 Binary files a/Lib/release/SIL.Collections.dll and b/Lib/release/SIL.Collections.dll differ diff --git a/Lib/release/SIL.Collections.pdb b/Lib/release/SIL.Collections.pdb index cbe3d291ac..6ffc217c7e 100644 Binary files a/Lib/release/SIL.Collections.pdb and b/Lib/release/SIL.Collections.pdb differ diff --git a/Lib/release/SIL.Machine.dll b/Lib/release/SIL.Machine.dll index a9da1ea30d..7cf3a7effd 100644 Binary files a/Lib/release/SIL.Machine.dll and b/Lib/release/SIL.Machine.dll differ diff --git a/Lib/release/SIL.Machine.pdb b/Lib/release/SIL.Machine.pdb index 37fe090cd4..8eddb57687 100644 Binary files a/Lib/release/SIL.Machine.pdb and b/Lib/release/SIL.Machine.pdb differ diff --git a/Lib/src/Machine b/Lib/src/Machine index a1165c9405..49a53b057a 160000 --- a/Lib/src/Machine +++ b/Lib/src/Machine @@ -1 +1 @@ -Subproject commit a1165c9405973d5c6bd4bc0d56a051f9d587f346 +Subproject commit 49a53b057aab5a2e67f86fb5bba7e377ccb5ab69 diff --git a/Src/AppCore/Makefile b/Src/AppCore/Makefile index 6857f943e6..21651c4d83 100644 --- a/Src/AppCore/Makefile +++ b/Src/AppCore/Makefile @@ -13,7 +13,11 @@ BUILD_PRODUCT = $(APPCORE_NAME) include $(BUILD_ROOT)/Bld/_init.mak.lnx AFLIB_SRC = $(APPCORE_SRC)/AfLib -CELLAR_SRC = $(SRC)/Cellar +GRAPHITE_SRC = $(SRC)/Graphite +GRFW_SRC = $(GRAPHITE_SRC)/FwOnly +GRUTIL_LIB = $(GRAPHITE_SRC)/lib +TTFUTIL_LIB = $(GRAPHITE_SRC)/TtfUtil +VIEWS_LIB = $(VIEWS_SRC)/lib PACKAGES = glib-2.0 gtk+-2.0 glibmm-2.4 gtkmm-2.4 cairomm-1.0 @@ -22,12 +26,12 @@ ifeq ($(BUILD_CONFIG),Debug) DEFINES := $(DEFINES) -D_DEBUG endif - # Make sure AfLib is first, as we want to get the Main.h from there, # not any of the others (e.g., in Views) INCLUDES := -I$(AFLIB_SRC) -I$(GENERIC_SRC) -I$(APPCORE_SRC) -I$(TEXT_SRC) -I$(DEBUGPROCS_SRC) -INCLUDES := $(INCLUDES) -I$(KERNEL_SRC) -I$(DBACCESS_SRC) +INCLUDES := $(INCLUDES) -I$(KERNEL_SRC) +INCLUDES := $(INCLUDES) -I$(GRUTIL_LIB) -I$(TTFUTIL_LIB) -I$(VIEWS_SRC) -I$(VIEWS_LIB) -I$(GRFW_SRC) INCLUDES := $(INCLUDES) \ -I$(FWINCLUDE) \ diff --git a/Src/Common/COMInterfaces/BuildInclude.targets b/Src/Common/COMInterfaces/BuildInclude.targets index ff8fde0277..e1187676be 100644 --- a/Src/Common/COMInterfaces/BuildInclude.targets +++ b/Src/Common/COMInterfaces/BuildInclude.targets @@ -12,8 +12,8 @@ - - + + diff --git a/Src/Common/COMInterfaces/IcuWrappers.cs b/Src/Common/COMInterfaces/IcuWrappers.cs index a473e10cd0..3e6633558e 100644 --- a/Src/Common/COMInterfaces/IcuWrappers.cs +++ b/Src/Common/COMInterfaces/IcuWrappers.cs @@ -14,8 +14,6 @@ using System.Globalization; using System.Text; using System.Windows.Forms; -using Microsoft.Win32; - using SIL.Utils; namespace SIL.FieldWorks.Common.COMInterfaces @@ -132,8 +130,10 @@ private static bool IsInRange(string codepoint, CharacterRange[] rangesToCheck) return false; } - private static readonly CharacterRange[] s_validCodepointRanges = new[] { - new CharacterRange {Start = "0000", End = "10FFFD"} }; + private static readonly CharacterRange[] s_validCodepointRanges = + { + new CharacterRange {Start = "0000", End = "10FFFD"} + }; /// ------------------------------------------------------------------------------------ /// @@ -147,11 +147,12 @@ public static bool IsValidCodepoint(string codepoint) } // List of the ranges that are acceptable - private static readonly CharacterRange[] s_puaRanges = new[] { - new CharacterRange { Start = "E000", End = "F8FF" }, - new CharacterRange { Start = "F0000", End = "FFFFD" }, - new CharacterRange { Start = "100000", End = "10FFFD" } - }; + private static readonly CharacterRange[] s_puaRanges = + { + new CharacterRange { Start = "E000", End = "F8FF" }, + new CharacterRange { Start = "F0000", End = "FFFFD" }, + new CharacterRange { Start = "100000", End = "10FFFD" } + }; /// ------------------------------------------------------------------------------------ /// @@ -174,11 +175,12 @@ public static bool IsPrivateUse(string codepoint) // but that's not clear, so we're adding plane 16 as of September 15, 2005. If // there's really a reason why plane 16 was not included here, remove it and // document the reason! - private static readonly CharacterRange[] s_customPuaRanges = new[] { - new CharacterRange { Start = "E000", End = "EFFF" }, - new CharacterRange { Start = "F0000", End = "FFFFD" }, - new CharacterRange { Start = "100000", End = "10FFFD"} - }; + private static readonly CharacterRange[] s_customPuaRanges = + { + new CharacterRange { Start = "E000", End = "EFFF" }, + new CharacterRange { Start = "F0000", End = "FFFFD" }, + new CharacterRange { Start = "100000", End = "10FFFD"} + }; /// ------------------------------------------------------------------------------------ /// @@ -192,8 +194,10 @@ public static bool IsCustomUse(string codepoint) } // List of the ranges that are set aside for surrogates - private static readonly CharacterRange[] s_surrogateRanges = new[] { - new CharacterRange {Start = "D800", End = "DFFF"} }; + private static readonly CharacterRange[] s_surrogateRanges = + { + new CharacterRange {Start = "D800", End = "DFFF"} + }; /// ------------------------------------------------------------------------------------ /// @@ -215,7 +219,7 @@ public static bool IsSurrogate(string codepoint) /// ------------------------------------------------------------------------------------ public static void InitIcuDataDir() { - System.Diagnostics.Debug.Assert(kIcuVersion == "_50", "Yo developers! We are using a different version of ICU. " + + Debug.Assert(kIcuVersion == "_50", "Yo developers! We are using a different version of ICU. " + "Change UnicodeVersion to return the correct version, and then change this assertion so that it checks for the new version of kIcuVersion." + "We had to do it this way because ICU can't tell us which version of Unicode it supports. " + "If they add a method to do this in the future, then we can just make UnicodeVersion work by calling that method." + @@ -646,7 +650,7 @@ public static bool IsControl(int characterCode) /// ------------------------------------------------------------------------------------ public static bool IsControl(string chr) { - return (string.IsNullOrEmpty(chr) || chr.Length != 1 ? false : IsControl(chr[0])); + return (!string.IsNullOrEmpty(chr) && chr.Length == 1 && IsControl(chr[0])); } /// ------------------------------------------------------------------------------------ @@ -687,7 +691,7 @@ public static bool IsSpace(int characterCode) /// ------------------------------------------------------------------------------------ public static bool IsSpace(string chr) { - return (string.IsNullOrEmpty(chr) || chr.Length != 1 ? false : IsSpace(chr[0])); + return (!string.IsNullOrEmpty(chr) && chr.Length == 1 && IsSpace(chr[0])); } /// ------------------------------------------------------------------------------------ @@ -746,7 +750,7 @@ public static string GetCharName(int code) string name; UErrorCode error; if (u_CharName(code, UCharNameChoice.U_UNICODE_CHAR_NAME, out name, out error) > 0 && - error == UErrorCode.U_ZERO_ERROR) + IsSuccess(error)) { return name; } @@ -889,20 +893,14 @@ public static int GetLanguageCode(string localeID, out string language, out UErr /// /// the locale to get the language code with /// the language code for the locale. - /// Thrown if ICU method fails with an error. - /// /// ------------------------------------------------------------------------------------ public static string GetLanguageCode(string locale) { string languageCode; UErrorCode err; GetLanguageCode(locale, out languageCode, out err); - if (err != UErrorCode.U_ZERO_ERROR) - { - throw new ArgumentException( - string.Format("ICU uloc_getLanguage with argument '{0}' failed with error {1}", locale, err), - "locale"); - } + if (IsFailure(err)) + throw new IcuException(string.Format("uloc_getLanguage() with argument '{0}' failed with error {1}", locale, err), err); return languageCode; } @@ -998,20 +996,14 @@ public static int GetCountryCode(string localeID, out string country, out UError /// /// the locale to get the country code with /// The country code for the locale. - /// Thrown if ICU method fails with an error. - /// /// ------------------------------------------------------------------------------------ public static string GetCountryCode(string locale) { string countryCode; UErrorCode err; GetCountryCode(locale, out countryCode, out err); - if (err != UErrorCode.U_ZERO_ERROR) - { - throw new ArgumentException( - string.Format("ICU uloc_getCountry with argument '{0}' failed with error {1}", locale, err), - "locale"); - } + if (IsFailure(err)) + throw new IcuException(string.Format("uloc_getCountry() with argument '{0}' failed with error {1}", locale, err), err); return countryCode; } @@ -1138,7 +1130,7 @@ public static string GetDisplayName(string localeID) string displayName; UErrorCode uerr; GetDisplayName(localeID, uilocale, out displayName, out uerr); - if (uerr == UErrorCode.U_ZERO_ERROR) + if (IsSuccess(uerr)) return displayName; return string.Empty; } @@ -1266,15 +1258,20 @@ private static extern int uloc_getName(string localeID, IntPtr name, /// /// Gets the name of the locale (e.g. en_US). /// - public static int GetName(string localeID, out string localeName, out UErrorCode err) + public static string GetName(string localeID) { + if (string.IsNullOrEmpty(localeID)) + return string.Empty; + const int nSize = 255; IntPtr resPtr = Marshal.AllocCoTaskMem(nSize); try { - int nResult = uloc_getName(localeID, resPtr, nSize, out err); - localeName = Marshal.PtrToStringAnsi(resPtr); - return nResult; + UErrorCode err; + uloc_getName(localeID, resPtr, nSize, out err); + if (IsFailure(err)) + throw new IcuException("uloc_getName() failed with code " + err, err); + return Marshal.PtrToStringAnsi(resPtr); } finally { @@ -1324,18 +1321,17 @@ public static string ToLower(string src, string locale) { UErrorCode err; int outLength = u_strToLower(resPtr, length, src, src.Length, locale, out err); - if (err > 0 && err != UErrorCode.U_BUFFER_OVERFLOW_ERROR) - throw new Exception("Icu.ToLower() failed with code " + err); + if (IsFailure(err) && err != UErrorCode.U_BUFFER_OVERFLOW_ERROR) + throw new IcuException("u_strToLower() failed with code " + err, err); if (outLength > length) { - err = UErrorCode.U_ZERO_ERROR; // ignore possible U_BUFFER_OVERFLOW_ERROR Marshal.FreeCoTaskMem(resPtr); length = outLength + 1; resPtr = Marshal.AllocCoTaskMem(length * 2); u_strToLower(resPtr, length, src, src.Length, locale, out err); } - if (err > 0) - throw new Exception("Icu.ToLower() failed with code " + err); + if (IsFailure(err)) + throw new IcuException("u_strToLower() failed with code " + err, err); string result = Marshal.PtrToStringUni(resPtr); // Strip any garbage left over at the end of the string. @@ -1360,13 +1356,17 @@ private static extern IntPtr ucol_open( out UErrorCode err); /// - public static IntPtr ucol_Open(byte[] loc, out UErrorCode err) + public static IntPtr OpenCollator(string locale) { - return ucol_open(loc, out err); + UErrorCode err; + IntPtr collator = ucol_open(string.IsNullOrEmpty(locale) ? null : Encoding.UTF8.GetBytes(locale), out err); + if (IsFailure(err)) + throw new IcuException("ucol_open() failed with code " + err, err); + return collator; } /// - public static void ucol_Close(IntPtr collator) + public static void CloseCollator(IntPtr collator) { ucol_close(collator); } @@ -1379,9 +1379,25 @@ public static void ucol_Close(IntPtr collator) private static extern int ucol_getSortKey(IntPtr col1, string source, int sourceLength, byte[] result, int resultLength); /// - public static int ucol_GetSortKey(IntPtr col1, string source, int sourceLength, ref byte[] result, int resultLength) + public static byte[] GetSortKey(IntPtr collator, string source) { - return ucol_getSortKey(col1, source, sourceLength, result, resultLength); + const int keyLength = 1024; + var key = new byte[keyLength + 1]; + var len = ucol_getSortKey(collator, source, source.Length, key, keyLength); + if (len > keyLength) + { + key = new byte[len + 1]; + len = ucol_getSortKey(collator, source, source.Length, key, len); + } + // Ensure that the byte array is truncated to its actual data length. + Debug.Assert(len <= key.Length); + if (len < key.Length) + { + var result = new byte[len]; + Array.Copy(key, result, len); + return result; + } + return key; } @@ -1424,21 +1440,20 @@ private static extern IntPtr ucol_openRules(string rules, int rulesLength, UColA CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] private static extern void ucol_close(IntPtr coll); - /// ------------------------------------------------------------------------------------ /// - /// Simple class to allow passing collation error info back to the caller of CheckRules. + /// Opens the specified collation rules as a collator. /// - /// ------------------------------------------------------------------------------------ - public class CollationRuleErrorInfo + /// The rules. + /// + public static IntPtr OpenRuleBasedCollator(string rules) { - /// Line number (1-based) containing the error - public int Line; - /// Character offset (1-based) on Line where the error was detected - public int Offset; - /// Characters preceding the the error - public String PreContext; - /// Characters following the the error - public String PostContext; + UErrorCode err; + UParseError parseError; + IntPtr collator = ucol_openRules(rules, rules.Length, UColAttributeValue.UCOL_DEFAULT, + UColAttributeValue.UCOL_DEFAULT_STRENGTH, out parseError, out err); + if (IsSuccess(err)) + return collator; + throw new CollationRuleException(err, new CollationRuleErrorInfo(parseError)); } /// ------------------------------------------------------------------------------------ @@ -1459,16 +1474,10 @@ public static CollationRuleErrorInfo CheckRules(string rules) UColAttributeValue.UCOL_DEFAULT_STRENGTH, out parseError, out err); try { - if (err == UErrorCode.U_ZERO_ERROR) + if (IsSuccess(err)) return null; - return new CollationRuleErrorInfo - { - Line = parseError.line + 1, - Offset = parseError.offset + 1, - PreContext = parseError.preContext, - PostContext = parseError.postContext - }; + return new CollationRuleErrorInfo(parseError); } finally { @@ -1545,17 +1554,33 @@ public static void GetSortKeyBound(byte[] sortKey, UColBoundMode boundType, ref { UErrorCode err; int size = ucol_getBound(sortKey, sortKey.Length, boundType, 1, result, result.Length, out err); - if (err > 0 && err != UErrorCode.U_BUFFER_OVERFLOW_ERROR) - throw new Exception("Icu.GetSortKeyBound() failed with code " + err); + if (IsFailure(err) && err != UErrorCode.U_BUFFER_OVERFLOW_ERROR) + throw new IcuException("ucol_getBound() failed with code " + err, err); if (size > result.Length) { result = new byte[size + 1]; ucol_getBound(sortKey, sortKey.Length, boundType, 1, result, result.Length, out err); - if (err > 0) - throw new Exception("Icu.GetSortKeyBound() failed with code " + err); + if (IsFailure(err)) + throw new IcuException("ucol_getBound() failed with code " + err, err); } } + [DllImport(kIcuinDllName, EntryPoint = "ucol_strcoll" + kIcuVersion, + CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] + private static extern int ucol_strcoll(IntPtr coll, string source, int sourceLength, string target, int targetLength); + + /// + /// Compares strings using the specified collator. + /// + /// The collator. + /// The source. + /// The target. + /// + public static int Compare(IntPtr coll, string source, string target) + { + return ucol_strcoll(coll, source, source.Length, target, target.Length); + } + /// /// Convert the string to title case, using the convention of the specified locale. /// This may be null for the universal locale, or "" for a 'root' locale (whatever that means). @@ -1580,18 +1605,17 @@ public static string ToTitle(string src, string locale) { UErrorCode err; int outLength = u_strToTitle(resPtr, length, src, src.Length, IntPtr.Zero, locale, out err); - if (err > 0 && err != UErrorCode.U_BUFFER_OVERFLOW_ERROR) - throw new Exception("Icu.ToTitle() failed with code " + err); + if (IsFailure(err) && err != UErrorCode.U_BUFFER_OVERFLOW_ERROR) + throw new IcuException("u_strToTitle() failed with code " + err, err); if (outLength > length) { - err = UErrorCode.U_ZERO_ERROR; // ignore possible U_BUFFER_OVERFLOW_ERROR Marshal.FreeCoTaskMem(resPtr); length = outLength + 1; resPtr = Marshal.AllocCoTaskMem(length * 2); u_strToTitle(resPtr, length, src, src.Length, IntPtr.Zero, locale, out err); } - if (err > 0) - throw new Exception("Icu.ToTitle() failed with code " + err); + if (IsFailure(err)) + throw new IcuException("u_strToTitle() failed with code " + err, err); string result = Marshal.PtrToStringUni(resPtr); if (result != null) @@ -1628,8 +1652,8 @@ public static string ToUpper(string src, string locale) { UErrorCode err; int outLength = u_strToUpper(resPtr, length, src, src.Length, locale, out err); - if (err > 0 && err != UErrorCode.U_BUFFER_OVERFLOW_ERROR) - throw new Exception("Icu.ToUpper() failed with code " + err); + if (IsFailure(err) && err != UErrorCode.U_BUFFER_OVERFLOW_ERROR) + throw new IcuException("u_strToUpper() failed with code " + err, err); if (outLength > length) { err = UErrorCode.U_ZERO_ERROR; // ignore possible U_BUFFER_OVERFLOW_ERROR @@ -1638,8 +1662,8 @@ public static string ToUpper(string src, string locale) resPtr = Marshal.AllocCoTaskMem(length * 2); u_strToUpper(resPtr, length, src, src.Length, locale, out err); } - if (err > 0) - throw new Exception("Icu.ToUpper() failed with code " + err); + if (IsFailure(err)) + throw new IcuException("u_strToUpper() failed with code " + err, err); string result = Marshal.PtrToStringUni(resPtr); // Strip any garbage left over at the end of the string. @@ -1712,8 +1736,8 @@ public static string Normalize(string src, UNormalizationMode mode) { UErrorCode err; int outLength = unorm_normalize(src, src.Length, mode, 0, resPtr, length, out err); - if (err > 0 && err != UErrorCode.U_BUFFER_OVERFLOW_ERROR) - throw new Exception("Icu.Normalize() failed with code " + err); + if (IsFailure(err) && err != UErrorCode.U_BUFFER_OVERFLOW_ERROR) + throw new IcuException("unorm_normalize() failed with code " + err, err); if (outLength >= length) { err = UErrorCode.U_ZERO_ERROR; // ignore possible U_BUFFER_OVERFLOW_ERROR @@ -1722,8 +1746,8 @@ public static string Normalize(string src, UNormalizationMode mode) resPtr = Marshal.AllocCoTaskMem(length * 2); unorm_normalize(src, src.Length, mode, 0, resPtr, length, out err); } - if (err > 0) - throw new Exception("Icu.Normalize() failed with code " + err); + if (IsFailure(err)) + throw new IcuException("unorm_normalize() failed with code " + err, err); string result = Marshal.PtrToStringUni(resPtr); // Strip any garbage left over at the end of the string. @@ -1752,8 +1776,8 @@ public static bool IsNormalized(string src, UNormalizationMode mode) UErrorCode err; byte fIsNorm = unorm_isNormalize(src, src.Length, mode, out err); - if (err > 0) - throw new Exception("Icu.IsNormalized() failed with code " + err); + if (IsFailure(err)) + throw new IcuException("unorm_isNormalize() failed with code " + err, err); return fIsNorm != 0; } @@ -1867,8 +1891,8 @@ public static IEnumerable Split(UBreakIteratorType type, string locale, UErrorCode err; IntPtr bi = ubrk_open(type, locale, text, text.Length, out err); - if (err > 0) - throw new Exception("Icu.Split() failed with code " + err); + if (IsFailure(err)) + throw new IcuException("ubrk_open() failed with code " + err, err); var tokens = new List(); int cur = ubrk_first(bi); while (cur != UBRK_DONE) @@ -1885,6 +1909,16 @@ public static IEnumerable Split(UBreakIteratorType type, string locale, #endregion Break iterator + private static bool IsSuccess(UErrorCode errorCode) + { + return errorCode <= 0; + } + + private static bool IsFailure(UErrorCode errorCode) + { + return errorCode > 0; + } + /** * Selector constants for u_charName(). * u_charName() returns the "modern" name of a @@ -2564,4 +2598,84 @@ public enum UCharCategory } // JT notes on how to pass arguments // const char *: pass string. + + + /// + /// General ICU exception + /// + public class IcuException : Exception + { + private readonly Icu.UErrorCode m_errorCode; + + /// + /// Initializes a new instance of the class. + /// + /// The message. + /// The error code. + public IcuException(string message, Icu.UErrorCode errorCode) + : base(message) + { + m_errorCode = errorCode; + } + + /// + /// Gets the ICU error code. + /// + public Icu.UErrorCode ErrorCode + { + get { return m_errorCode; } + } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Simple class to allow passing collation error info back to the caller of CheckRules. + /// + /// ------------------------------------------------------------------------------------ + public class CollationRuleErrorInfo + { + internal CollationRuleErrorInfo(Icu.UParseError parseError) + { + Line = parseError.line + 1; + Offset = parseError.offset + 1; + PreContext = parseError.preContext; + PostContext = parseError.postContext; + } + + /// Line number (1-based) containing the error + public int Line { get; private set; } + /// Character offset (1-based) on Line where the error was detected + public int Offset { get; private set; } + /// Characters preceding the the error + public String PreContext { get; private set; } + /// Characters following the the error + public String PostContext { get; private set; } + } + + /// + /// Collation rule exception + /// + public class CollationRuleException : IcuException + { + private readonly CollationRuleErrorInfo m_errorInfo; + + /// + /// Initializes a new instance of the class. + /// + /// The ICU error code. + /// The error information. + public CollationRuleException(Icu.UErrorCode errorCode, CollationRuleErrorInfo errorInfo) + : base("Failed to parse collation rules.", errorCode) + { + m_errorInfo = errorInfo; + } + + /// + /// Gets the parse error information. + /// + public CollationRuleErrorInfo ErrorInfo + { + get { return m_errorInfo; } + } + } } diff --git a/Src/Common/Controls/DetailControls/BasicTypeSlices.cs b/Src/Common/Controls/DetailControls/BasicTypeSlices.cs index 865eb5ce7e..7fd2471ab6 100644 --- a/Src/Common/Controls/DetailControls/BasicTypeSlices.cs +++ b/Src/Common/Controls/DetailControls/BasicTypeSlices.cs @@ -12,6 +12,7 @@ using System; using System.Windows.Forms; using System.Xml; +using SIL.CoreImpl; using SIL.FieldWorks.Common.Controls; using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.Application; @@ -70,7 +71,6 @@ private void SetToggleValue(XmlNode node) /// "reused" (e.g. refresh or new target object) /// /// - /// public override void Install(DataTree parent) { CheckDisposed(); @@ -378,7 +378,7 @@ protected override void Dispose(bool disposing) protected override void UpdateDisplayFromDatabase() { RichTextBox rtb = ((RichTextBox)this.Control); - DateTime dt = FwUtils.SilTime.GetTimeProperty(m_cache.DomainDataByFlid, Object.Hvo, m_flid); + DateTime dt = SilTime.GetTimeProperty(m_cache.DomainDataByFlid, Object.Hvo, m_flid); if (dt == DateTime.MinValue) { rtb.Text = "Date/Time not set"; diff --git a/Src/Common/Controls/DetailControls/DataTree.cs b/Src/Common/Controls/DetailControls/DataTree.cs index fdd72be826..99043d97cd 100644 --- a/Src/Common/Controls/DetailControls/DataTree.cs +++ b/Src/Common/Controls/DetailControls/DataTree.cs @@ -19,6 +19,7 @@ using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.FDO.Infrastructure; +using SIL.FieldWorks.Resources; using SIL.Utils; using XCore; @@ -510,7 +511,7 @@ public FwStyleSheet StyleSheet { m_styleSheet = new FwStyleSheet(); m_styleSheet.Init(m_cache, m_cache.LanguageProject.Hvo, - LangProjectTags.kflidStyles); + LangProjectTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); } return m_styleSheet; } diff --git a/Src/Common/Controls/DetailControls/DetailControlsTests/DataTreeTests.cs b/Src/Common/Controls/DetailControls/DetailControlsTests/DataTreeTests.cs index b9b757b84b..f9eca42b74 100644 --- a/Src/Common/Controls/DetailControls/DetailControlsTests/DataTreeTests.cs +++ b/Src/Common/Controls/DetailControls/DetailControlsTests/DataTreeTests.cs @@ -32,7 +32,7 @@ public class DataTreeTests : MemoryOnlyBackendProviderRestoredForEachTestTestBas #region Fixture Setup and Teardown internal static StringTable GenerateStringTable() { - string configurationDir = Path.Combine(DirectoryFinder.FWCodeDirectory, + string configurationDir = Path.Combine(FwDirectoryFinder.CodeDirectory, @"Language Explorer/Configuration"); var stringTable = new SIL.Utils.StringTable(configurationDir); @@ -41,7 +41,7 @@ internal static StringTable GenerateStringTable() internal static Inventory GenerateParts() { - string partDirectory = Path.Combine(DirectoryFinder.FwSourceDirectory, + string partDirectory = Path.Combine(FwDirectoryFinder.SourceDirectory, @"Common/Controls/DetailControls/DetailControlsTests"); var keyAttrs = new Dictionary(); @@ -55,7 +55,7 @@ internal static Inventory GenerateParts() internal static Inventory GenerateLayouts() { - string partDirectory = Path.Combine(DirectoryFinder.FwSourceDirectory, + string partDirectory = Path.Combine(FwDirectoryFinder.SourceDirectory, @"Common/Controls/DetailControls/DetailControlsTests"); Dictionary keyAttrs = new Dictionary(); diff --git a/Src/Common/Controls/DetailControls/DetailControlsTests/DetailControlsMainWnd.cs b/Src/Common/Controls/DetailControls/DetailControlsTests/DetailControlsMainWnd.cs index 39abfb8da5..d60a105543 100644 --- a/Src/Common/Controls/DetailControls/DetailControlsTests/DetailControlsMainWnd.cs +++ b/Src/Common/Controls/DetailControls/DetailControlsTests/DetailControlsMainWnd.cs @@ -159,7 +159,7 @@ public void InitAndShowClient() m_dataEntryForm = new DataTree(); SuspendLayout(); - string partDirectory = Path.Combine(DirectoryFinder.FWCodeDirectory, + string partDirectory = Path.Combine(FwDirectoryFinder.CodeDirectory, @"Language Explorer\Configuration\Parts"); Dictionary keyAttrs = new Dictionary(); keyAttrs["layout"] = new string[] {"class", "type", "mode", "name" }; diff --git a/Src/Common/Controls/DetailControls/GenDateChooserDlg.cs b/Src/Common/Controls/DetailControls/GenDateChooserDlg.cs index 93a977c99f..5291471bf5 100644 --- a/Src/Common/Controls/DetailControls/GenDateChooserDlg.cs +++ b/Src/Common/Controls/DetailControls/GenDateChooserDlg.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Text; using System.Windows.Forms; - +using SIL.CoreImpl; using SIL.FieldWorks.FDO; using SIL.FieldWorks.Common.Framework.DetailControls.Resources; using SIL.FieldWorks.Common.FwUtils; diff --git a/Src/Common/Controls/DetailControls/GenDateLauncher.cs b/Src/Common/Controls/DetailControls/GenDateLauncher.cs index 63e2a0f3d0..c4b22734c1 100644 --- a/Src/Common/Controls/DetailControls/GenDateLauncher.cs +++ b/Src/Common/Controls/DetailControls/GenDateLauncher.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Text; using System.Windows.Forms; - +using SIL.CoreImpl; using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.Application; using SIL.FieldWorks.FDO.Infrastructure; diff --git a/Src/Common/Controls/DetailControls/PossibilityAutoComplete.cs b/Src/Common/Controls/DetailControls/PossibilityAutoComplete.cs index d52f6505e4..644e8e28c7 100644 --- a/Src/Common/Controls/DetailControls/PossibilityAutoComplete.cs +++ b/Src/Common/Controls/DetailControls/PossibilityAutoComplete.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.Linq; using System.Windows.Forms; +using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.Common.Controls; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.Common.Widgets; using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.DomainServices; diff --git a/Src/Common/Controls/DetailControls/SliceFactory.cs b/Src/Common/Controls/DetailControls/SliceFactory.cs index 92dd4456eb..7ea86dcada 100644 --- a/Src/Common/Controls/DetailControls/SliceFactory.cs +++ b/Src/Common/Controls/DetailControls/SliceFactory.cs @@ -230,7 +230,7 @@ public static Slice Create(FdoCache cache, string editor, int flid, XmlNode node { try { - slice = new ImageSlice(DirectoryFinder.FWCodeDirectory, XmlUtils.GetManditoryAttributeValue(node, "param1")); + slice = new ImageSlice(FwDirectoryFinder.CodeDirectory, XmlUtils.GetManditoryAttributeValue(node, "param1")); } catch (Exception error) { @@ -379,7 +379,7 @@ public static Slice Create(FdoCache cache, string editor, int flid, XmlNode node //Since the editor has not been implemented yet, //is there a bitmap file that we can show for this editor? //Such bitmaps belong in the distFiles xde directory - string fwCodeDir = DirectoryFinder.FWCodeDirectory; + string fwCodeDir = FwDirectoryFinder.CodeDirectory; string editorBitmapRelativePath = "xde/" + editor + ".bmp"; if(File.Exists(Path.Combine(fwCodeDir, editorBitmapRelativePath))) slice = new ImageSlice(fwCodeDir, editorBitmapRelativePath); diff --git a/Src/Common/Controls/DetailControls/StringSlice.cs b/Src/Common/Controls/DetailControls/StringSlice.cs index f366509aa8..ff8ac8ba6d 100644 --- a/Src/Common/Controls/DetailControls/StringSlice.cs +++ b/Src/Common/Controls/DetailControls/StringSlice.cs @@ -263,7 +263,7 @@ private ITsString NameOfWs(int ws) m_wsLabel = ws; var sWs = m_cache.WritingSystemFactory.GetStrFromWs(ws); IWritingSystem wsys; - WritingSystemServices.FindOrCreateWritingSystem(m_cache, sWs, false, false, out wsys); + WritingSystemServices.FindOrCreateWritingSystem(m_cache, FwDirectoryFinder.TemplateDirectory, sWs, false, false, out wsys); var result = wsys.Abbreviation; if (string.IsNullOrEmpty(result)) result = "??"; diff --git a/Src/Common/Controls/FwControls/FilterAllTextsDialog.cs b/Src/Common/Controls/FwControls/FilterAllTextsDialog.cs index ea42796943..879cd8cc1f 100644 --- a/Src/Common/Controls/FwControls/FilterAllTextsDialog.cs +++ b/Src/Common/Controls/FwControls/FilterAllTextsDialog.cs @@ -253,9 +253,9 @@ protected override void OnHandleCreated(EventArgs e) { // Selecting node(s) changed something, so save it so that the UI doesn't become // unresponsive - using (var progressDlg = new ProgressDialogWithTask(this, m_cache.ThreadHelper)) + using (var progressDlg = new ProgressDialogWithTask(this)) { - progressDlg.ProgressBarStyle = ProgressBarStyle.Marquee; + progressDlg.IsIndeterminate = true; progressDlg.Title = Text; progressDlg.Message = ResourceHelper.GetResourceString("kstidSavingChanges"); progressDlg.RunTask((progDlg, parms) => @@ -276,7 +276,7 @@ protected override void OnHandleCreated(EventArgs e) /// /// /// ------------------------------------------------------------------------------------ - protected override void m_btnHelp_Click(object sender, System.EventArgs e) + protected override void m_btnHelp_Click(object sender, EventArgs e) { ShowHelp.ShowHelpTopic(m_helpTopicProvider, m_helpTopicId); } diff --git a/Src/Common/Controls/FwControls/FwControls.csproj b/Src/Common/Controls/FwControls/FwControls.csproj index 6823a44abe..4df5638cd6 100644 --- a/Src/Common/Controls/FwControls/FwControls.csproj +++ b/Src/Common/Controls/FwControls/FwControls.csproj @@ -95,11 +95,23 @@ False + + False + ..\..\..\..\Output\Debug\FwUtils.dll + False ..\..\..\..\Output\Debug\ManagedLgIcuCollator.dll + + False + ..\..\..\..\Output\Debug\ParatextShared.dll + + + False + ..\..\..\..\Output\Debug\ScriptureUtils.dll + System @@ -127,18 +139,12 @@ ..\..\..\..\Output\Debug\FwResources.dll - - ..\..\..\..\Output\Debug\FwUtils.dll - ..\..\..\..\Output\Debug\SilUtils.dll ..\..\..\..\Downloads\Palaso.dll - - ..\..\..\..\DistFiles\ParatextShared.dll - ..\..\..\..\Output\Debug\ScrUtilsInterfaces.dll diff --git a/Src/Common/Controls/FwControls/FwControlsTests/ProgressDlgTests.cs b/Src/Common/Controls/FwControls/FwControlsTests/ProgressDlgTests.cs index 8769ce4bda..80cbdb1270 100644 --- a/Src/Common/Controls/FwControls/FwControlsTests/ProgressDlgTests.cs +++ b/Src/Common/Controls/FwControls/FwControlsTests/ProgressDlgTests.cs @@ -5,10 +5,10 @@ // File: ProgressDlgTests.cs using System; +using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Threading; using NUnit.Framework; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.Test.TestUtils; using SIL.Utils; @@ -27,21 +27,11 @@ public class DummyProgressDlg : ProgressDialogWithTask /// Initializes a new instance of the class. /// /// ------------------------------------------------------------------------------------ - public DummyProgressDlg() : base(null, new ThreadHelper()) + public DummyProgressDlg(ISynchronizeInvoke synchronizeInvoke) + : base(synchronizeInvoke) { } - /// - protected override void Dispose(bool disposing) - { - if (disposing && !IsDisposed) - { - if (ThreadHelper != null) - ThreadHelper.Dispose(); - } - base.Dispose(disposing); - } - /// ------------------------------------------------------------------------------------ /// /// Gets a value indicating wether or not the cancel button is visible. @@ -79,6 +69,7 @@ public void SimulatePressCancel() Justification="Unit test, object is disposed in TearDown method")] public class ProgressDlgTests : BaseTest { + private ThreadHelper m_threadHelper; private DummyProgressDlg m_dlg; private Timer m_timer; @@ -92,7 +83,8 @@ public class ProgressDlgTests : BaseTest Justification="Unit test, object is disposed in TearDown method")] public void Setup() { - m_dlg = new DummyProgressDlg {Maximum = 10}; + m_threadHelper = new ThreadHelper(); + m_dlg = new DummyProgressDlg(m_threadHelper) {Maximum = 10}; } /// ------------------------------------------------------------------------------------ @@ -115,6 +107,12 @@ public void Teardown() m_dlg = null; } + if (m_threadHelper != null) + { + m_threadHelper.Dispose(); + m_threadHelper = null; + } + } /// ------------------------------------------------------------------------------------ @@ -175,7 +173,7 @@ private static object BackgroundTask(IThreadedProgress progressDlg, object[] par /// /// ------------------------------------------------------------------------------------ [Test] - [Category("DesktopRequired")] + [NUnit.Framework.Category("DesktopRequired")] public void TestWithCancel() { StartTimer(2500); @@ -193,7 +191,7 @@ public void TestWithCancel() /// /// ------------------------------------------------------------------------------------ [Test] - [Category("DesktopRequired")] + [NUnit.Framework.Category("DesktopRequired")] public void TestWithoutCancel() { var nProgress = (int) m_dlg.RunTask(false, BackgroundTask); diff --git a/Src/Common/Controls/FwControls/ObtainProjectMethod.cs b/Src/Common/Controls/FwControls/ObtainProjectMethod.cs index 60989ec91b..fdfd858bcf 100644 --- a/Src/Common/Controls/FwControls/ObtainProjectMethod.cs +++ b/Src/Common/Controls/FwControls/ObtainProjectMethod.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.ComponentModel; using System.IO; using System.Linq; using System.Text; @@ -25,12 +26,11 @@ public static class ObtainProjectMethod /// The repo may be a lift or full FW repo, but it can be from any source source, as long as the code can create an FW project from it. /// /// Null if the operation was cancelled or otherwise did not work. The full pathname of an fwdata file, if it did work. - public static string ObtainProjectFromAnySource(Form parent, IHelpTopicProvider helpTopicProvider, - out ObtainedProjectType obtainedProjectType) + public static string ObtainProjectFromAnySource(Form parent, IHelpTopicProvider helpTopicProvider, out ObtainedProjectType obtainedProjectType) { bool dummy; string fwdataFileFullPathname; - var success = FLExBridgeHelper.LaunchFieldworksBridge(DirectoryFinder.ProjectsDirectory, null, FLExBridgeHelper.Obtain, null, + var success = FLExBridgeHelper.LaunchFieldworksBridge(FwDirectoryFinder.ProjectsDirectory, null, FLExBridgeHelper.Obtain, null, FDOBackendProvider.ModelVersion, "0.13", null, out dummy, out fwdataFileFullPathname); if (!success) { @@ -95,34 +95,25 @@ private static string CreateProjectFromLift(Form parent, IHelpTopicProvider help var anthroListFile = ReflectionHelper.CallStaticMethod(@"FwCoreDlgs.dll", @"SIL.FieldWorks.FwCoreDlgs.FwCheckAnthroListDlg", @"PickAnthroList", parent, null, helpTopicProvider); - // Do NOT dispose of the thread helper until we dispose of the cache... - // CreateProjectTask makes it the thread helper of the FdoCache that it creates and returns, - // and we must NOT dispose of the cache's thread helper until after we import the lexicon. - // We will actually dispose it twice, most likely, since disposing the cache will dispose it; - // but this is harmless. - using (var helper = new ThreadHelper()) + using (var progressDlg = new ProgressDialogWithTask(parent)) { - using (var progressDlg = new ProgressDialogWithTask(parent, helper)) - { - progressDlg.ProgressBarStyle = ProgressBarStyle.Continuous; - progressDlg.Title = FwControls.ksCreatingLiftProject; - var cacheReceiver = new FdoCache[1]; // a clumsy way of handling an out parameter, consistent with RunTask - projectPath = (string)progressDlg.RunTask(true, CreateProjectTask, - new object[] { liftPath, helper, anthroListFile, cacheReceiver }); - cache = cacheReceiver[0]; - } + progressDlg.Title = FwControls.ksCreatingLiftProject; + var cacheReceiver = new FdoCache[1]; // a clumsy way of handling an out parameter, consistent with RunTask + projectPath = (string)progressDlg.RunTask(true, CreateProjectTask, + new[] { liftPath, parent, anthroListFile, cacheReceiver }); + cache = cacheReceiver[0]; + } - // this is a horrible way to invoke this, but the current project organization does not allow us to reference - // the LexEdDll project, nor is there any straightforward way to move the code we need into some project we can - // reference, or any obviously suitable project to move it to without creating other References loops. - // One nasty reflection call seems less technical debt than creating an otherwise unnecessary project. - // (It puts up its own progress dialog.) - ReflectionHelper.CallStaticMethod(@"LexEdDll.dll", @"SIL.FieldWorks.XWorks.LexEd.FLExBridgeListener", - @"ImportObtainedLexicon", cache, liftPath, parent); + // this is a horrible way to invoke this, but the current project organization does not allow us to reference + // the LexEdDll project, nor is there any straightforward way to move the code we need into some project we can + // reference, or any obviously suitable project to move it to without creating other References loops. + // One nasty reflection call seems less technical debt than creating an otherwise unnecessary project. + // (It puts up its own progress dialog.) + ReflectionHelper.CallStaticMethod(@"LexEdDll.dll", @"SIL.FieldWorks.XWorks.LexEd.FLExBridgeListener", + @"ImportObtainedLexicon", cache, liftPath, parent); - ProjectLockingService.UnlockCurrentProject(cache); // finish all saves and completely write the file so we can proceed to open it - cache.Dispose(); - } + ProjectLockingService.UnlockCurrentProject(cache); // finish all saves and completely write the file so we can proceed to open it + cache.Dispose(); return projectPath; } @@ -137,21 +128,21 @@ private static string CreateProjectFromLift(Form parent, IHelpTopicProvider help private static object CreateProjectTask(IThreadedProgress progress, object[] parameters) { // Get required parameters. Ideally these would just be the signature of the method, but RunTask requires object[]. - var liftPathname = (string)parameters[0]; - var helper = (ThreadHelper)parameters[1]; - var anthroFile = (string)parameters[2]; - var cacheReceiver = (FdoCache[])parameters[3]; + var liftPathname = (string) parameters[0]; + var synchronizeInvoke = (ISynchronizeInvoke) parameters[1]; + var anthroFile = (string) parameters[2]; + var cacheReceiver = (FdoCache[]) parameters[3]; IWritingSystem wsVern, wsAnalysis; RetrieveDefaultWritingSystemsFromLift(liftPathname, out wsVern, out wsAnalysis); string projectPath = FdoCache.CreateNewLangProj(progress, Directory.GetParent(Path.GetDirectoryName(liftPathname)).Parent.Name, // Get the new Flex project name from the Lift pathname. - helper, wsAnalysis, wsVern, null, null, null, anthroFile); + FwDirectoryFinder.FdoDirectories, synchronizeInvoke, wsAnalysis, wsVern, null, null, null, anthroFile); // This is a temporary cache, just to do the import, and AFAIK we have no access to the current // user WS. So create it as "English". Put it in the array to return to the caller. - cacheReceiver[0] = FdoCache.CreateCacheFromLocalProjectFile(projectPath, "en", progress); + cacheReceiver[0] = FdoCache.CreateCacheFromLocalProjectFile(projectPath, "en", new SilentFdoUI(synchronizeInvoke), FwDirectoryFinder.FdoDirectories, progress); return projectPath; } @@ -163,8 +154,7 @@ private static void RetrieveDefaultWritingSystemsFromLift(string liftPath, out I string vernWsId, analysisWsId; using (var reader = XmlReader.Create(liftReader)) RetrieveDefaultWritingSystemIdsFromLift(reader, out vernWsId, out analysisWsId); - var wsManager = new PalasoWritingSystemManager( - new GlobalFileWritingSystemStore(DirectoryFinder.GlobalWritingSystemStoreDirectory)); + var wsManager = new PalasoWritingSystemManager(new GlobalFileWritingSystemStore()); wsManager.GetOrSet(vernWsId, out wsVern); wsManager.GetOrSet(analysisWsId, out wsAnalysis); } diff --git a/Src/Common/Controls/FwControls/ProgressDialogImpl.Designer.cs b/Src/Common/Controls/FwControls/ProgressDialogImpl.Designer.cs index 264bb1968e..76919f0a7c 100644 --- a/Src/Common/Controls/FwControls/ProgressDialogImpl.Designer.cs +++ b/Src/Common/Controls/FwControls/ProgressDialogImpl.Designer.cs @@ -49,29 +49,30 @@ private void InitializeComponent() this.progressBar = new System.Windows.Forms.ProgressBar(); this.btnCancel = new System.Windows.Forms.Button(); this.SuspendLayout(); - // + // // lblStatusMessage - // + // this.lblStatusMessage.AutoEllipsis = true; resources.ApplyResources(this.lblStatusMessage, "lblStatusMessage"); this.lblStatusMessage.Name = "lblStatusMessage"; - // + // // progressBar - // + // resources.ApplyResources(this.progressBar, "progressBar"); this.progressBar.Name = "progressBar"; this.progressBar.Step = 1; - // + this.progressBar.Style = System.Windows.Forms.ProgressBarStyle.Continuous; + // // btnCancel - // + // this.btnCancel.Cursor = System.Windows.Forms.Cursors.Arrow; this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; resources.ApplyResources(this.btnCancel, "btnCancel"); this.btnCancel.Name = "btnCancel"; this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); - // + // // ProgressDialogImpl - // + // resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.btnCancel; diff --git a/Src/Common/Controls/FwControls/ProgressDialogImpl.cs b/Src/Common/Controls/FwControls/ProgressDialogImpl.cs index 5a2acafd1c..bea351d6dc 100644 --- a/Src/Common/Controls/FwControls/ProgressDialogImpl.cs +++ b/Src/Common/Controls/FwControls/ProgressDialogImpl.cs @@ -274,6 +274,15 @@ public string CancelButtonText } } + /// + /// Gets an object to be used for ensuring that required tasks are invoked on the main + /// UI thread. + /// + public ISynchronizeInvoke SynchronizeInvoke + { + get { return this; } + } + /// ------------------------------------------------------------------------------------ /// /// Gets the form displaying the progress (used for message box owners, etc). @@ -284,15 +293,13 @@ public Form Form get { return this; } } - /// ------------------------------------------------------------------------------------ /// - /// Gets or sets the style of the ProgressBar. + /// Gets or sets a value indicating whether this progress is indeterminate. /// - /// ------------------------------------------------------------------------------------ - public ProgressBarStyle ProgressBarStyle + public bool IsIndeterminate { - get { return progressBar.Style; } - set { progressBar.Style = value; } + get { return progressBar.Style == ProgressBarStyle.Marquee; } + set { progressBar.Style = value ? ProgressBarStyle.Marquee : ProgressBarStyle.Continuous; } } #endregion diff --git a/Src/Common/Controls/FwControls/ProgressDialogImpl.resx b/Src/Common/Controls/FwControls/ProgressDialogImpl.resx index 136760a418..3e83cd4d6c 100644 --- a/Src/Common/Controls/FwControls/ProgressDialogImpl.resx +++ b/Src/Common/Controls/FwControls/ProgressDialogImpl.resx @@ -1,231 +1,231 @@ - + 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. + --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - text/microsoft-resx + text/microsoft-resx - 2.0 + 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + - NoControl + NoControl - + - 15, 12 + 15, 12 - 388, 13 + 388, 13 - + - 5 + 5 - # + # - lblStatusMessage + lblStatusMessage - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - $this + $this - 0 + 0 - Top, Left, Right + Top, Left, Right - NoControl + NoControl - 15, 32 + 15, 32 - 388, 20 + 388, 20 - 4 + 4 - progressBar + progressBar - System.Windows.Forms.ProgressBar, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.ProgressBar, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - $this + $this - 1 + 1 - System + System - NoControl + NoControl - 145, 68 + 145, 68 - 133, 23 + 133, 23 - 3 + 3 - Cancel + Cancel - btnCancel + btnCancel - System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - $this + $this - 2 + 2 - - True + + True - ProgressDialogImp + ProgressDialogImp - 6, 13 + 6, 13 - 422, 102 + 422, 102 - Manual + Manual - Progress Dialog + Progress Dialog - ProgressDialogImpl + ProgressDialogImpl - System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 \ No newline at end of file diff --git a/Src/Common/Controls/FwControls/ProgressDialogWithTask.cs b/Src/Common/Controls/FwControls/ProgressDialogWithTask.cs index 77de1546f0..8a536192f5 100644 --- a/Src/Common/Controls/FwControls/ProgressDialogWithTask.cs +++ b/Src/Common/Controls/FwControls/ProgressDialogWithTask.cs @@ -34,89 +34,77 @@ public class ProgressDialogWithTask : IThreadedProgress, IFWDisposable #region Member variables /// The form that actually displays the progress - protected IProgress m_progressDialog; + internal ProgressDialogWithTaskDlgImpl m_progressDialog; private readonly bool m_fCreatedProgressDlg; private volatile bool m_fDisposed; + private readonly Form m_owner; private Func m_backgroundTask; private object[] m_parameters; private object m_RetValue; private Exception m_Exception; - private ThreadHelper m_threadHelper; private bool m_fOwnerWasTopMost; private BackgroundWorker m_worker; - private readonly ISynchronizeInvoke m_synchInvoke; + private readonly ISynchronizeInvoke m_synchronizeInvoke; #endregion #region Constructors - /// ------------------------------------------------------------------------------------ - /// - /// Initializes a new instance of the class that - /// uses an externally supplied object to track the progress. - /// - /// The object that will be used to track the progress. - /// ------------------------------------------------------------------------------------ - public ProgressDialogWithTask(IProgress progress) : - this(progress, null, progress.Form) - { - } - /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class that + /// Initializes a new instance of the class that /// will create an actual progress dialog box to track the progress. /// /// The form to use as the owner when creating the actual progress /// dialog. - /// The thread helper (must been created on the UI thread). - /// ------------------------------------------------------------------------------------ - public ProgressDialogWithTask(Form owner, ThreadHelper threadHelper) : - this(null, owner, (ISynchronizeInvoke)owner ?? threadHelper) + public ProgressDialogWithTask(Form owner) + : this(owner, owner) { - m_threadHelper = threadHelper; - m_fCreatedProgressDlg = true; } - /// ------------------------------------------------------------------------------------ /// /// Initializes a new instance of the class. /// - /// An external implementation of IProgress that should be - /// used to report progress. If this is null, then this class will create a generic - /// progress dialog for the purpose of running tasks. + /// + public ProgressDialogWithTask(ISynchronizeInvoke synchronizeInvoke) + : this(null, synchronizeInvoke) + { + } + + /// + /// Initializes a new instance of the class. + /// /// The "owning" form (can be null if progressDlg is specified or if /// there is no suitable form available to own the progress dialog) - /// Object that can ensure that certain operations are - /// invoked on the UI thread. - /// ------------------------------------------------------------------------------------ - private ProgressDialogWithTask(IProgress progress, Form owner, ISynchronizeInvoke synchInvoke) + /// The synchronize invoke. + private ProgressDialogWithTask(Form owner, ISynchronizeInvoke synchronizeInvoke) { - m_synchInvoke = synchInvoke; - m_progressDialog = progress; - InitOnOwnerThread(owner); + m_owner = owner; + m_synchronizeInvoke = synchronizeInvoke; + m_fCreatedProgressDlg = true; + InitOnOwnerThread(); + if (m_synchronizeInvoke == null) + m_synchronizeInvoke = m_progressDialog.SynchronizeInvoke; m_progressDialog.Canceling += m_progressDialog_Canceling; - m_progressDialog.Form.FormClosing += m_progressDialog_FormClosing; + m_progressDialog.FormClosing += m_progressDialog_FormClosing; m_worker.DoWork += RunBackgroundTask; m_worker.RunWorkerCompleted += m_worker_RunWorkerCompleted; } [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", Justification="m_worker gets disposed in Dispose()")] - private void InitOnOwnerThread(Form owner) + private void InitOnOwnerThread() { - if (m_synchInvoke != null && m_synchInvoke.InvokeRequired) + if (m_synchronizeInvoke != null && m_synchronizeInvoke.InvokeRequired) { - m_synchInvoke.Invoke((Action
)InitOnOwnerThread, new object[] { owner }); + m_synchronizeInvoke.Invoke(InitOnOwnerThread); return; } m_worker = new BackgroundWorker { WorkerSupportsCancellation = true }; - if (m_progressDialog == null) - { - m_progressDialog = new ProgressDialogWithTaskDlgImpl(owner); - } + + m_progressDialog = new ProgressDialogWithTaskDlgImpl(m_owner); // This is the only way to force handle creation for a form that is not yet visible. - IntPtr handle = m_progressDialog.Form.Handle; + IntPtr handle = m_progressDialog.Handle; } #endregion @@ -189,10 +177,10 @@ protected virtual void Dispose(bool disposing) if (m_progressDialog != null) { m_progressDialog.Canceling -= m_progressDialog_Canceling; - m_progressDialog.Form.FormClosing -= m_progressDialog_FormClosing; + m_progressDialog.FormClosing -= m_progressDialog_FormClosing; RemoveStartListener(); if (m_fCreatedProgressDlg) - m_progressDialog.Form.DisposeOnGuiThread(); + m_progressDialog.DisposeOnGuiThread(); } if (m_worker != null) { @@ -220,9 +208,9 @@ public virtual void Step(int cSteps) { CheckDisposed(); - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) { - m_synchInvoke.Invoke((Action)Step, new object[] {cSteps}); + m_synchronizeInvoke.Invoke((Action)Step, new object[] {cSteps}); return; } m_progressDialog.Position += (cSteps > 0) ? cSteps : m_progressDialog.StepSize; @@ -238,16 +226,16 @@ public virtual string Title { CheckDisposed(); - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - return (string)m_synchInvoke.Invoke((Func)(() => m_progressDialog.Title), null); + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) + return (string)m_synchronizeInvoke.Invoke((Func)(() => m_progressDialog.Title), null); return m_progressDialog.Title; } set { CheckDisposed(); - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - m_synchInvoke.Invoke((Action)(s => m_progressDialog.Title = s), new [] {value}); + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) + m_synchronizeInvoke.Invoke((Action)(s => m_progressDialog.Title = s), new [] {value}); else m_progressDialog.Title = value; } @@ -263,16 +251,16 @@ public virtual string Message { CheckDisposed(); - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - return (string)m_synchInvoke.Invoke((Func)(() => m_progressDialog.Message), null); + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) + return (string)m_synchronizeInvoke.Invoke((Func)(() => m_progressDialog.Message), null); return m_progressDialog.Message; } set { CheckDisposed(); - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - m_synchInvoke.Invoke((Action)(s => m_progressDialog.Message = s), new [] {value}); + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) + m_synchronizeInvoke.Invoke((Action)(s => m_progressDialog.Message = s), new [] {value}); else m_progressDialog.Message = value; } @@ -288,16 +276,16 @@ public virtual int Position { CheckDisposed(); - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - return (int)m_synchInvoke.Invoke((Func)(() => m_progressDialog.Position), null); + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) + return (int)m_synchronizeInvoke.Invoke((Func)(() => m_progressDialog.Position), null); return m_progressDialog.Position; } set { CheckDisposed(); - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - m_synchInvoke.Invoke((Action)(i => m_progressDialog.Position = i), new object[] {value}); + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) + m_synchronizeInvoke.Invoke((Action)(i => m_progressDialog.Position = i), new object[] {value}); else m_progressDialog.Position = value; } @@ -313,33 +301,39 @@ public virtual int StepSize { CheckDisposed(); - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - return (int)m_synchInvoke.Invoke((Func)(() => m_progressDialog.StepSize), null); + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) + return (int)m_synchronizeInvoke.Invoke((Func)(() => m_progressDialog.StepSize), null); return m_progressDialog.StepSize; } set { CheckDisposed(); - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - m_synchInvoke.Invoke((Action)(i => m_progressDialog.StepSize = i), new object[] {value}); + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) + m_synchronizeInvoke.Invoke((Action)(i => m_progressDialog.StepSize = i), new object[] {value}); else m_progressDialog.StepSize = value; } } - /// ------------------------------------------------------------------------------------ /// - /// Gets the progress as a form (used for message box owners, etc). If the progress - /// is not associated with a visible Form, then this returns its owning form, if any. + /// Gets or sets a value indicating whether this progress is indeterminate. /// - /// ------------------------------------------------------------------------------------ - public virtual Form Form + public bool IsIndeterminate { get { - CheckDisposed(); - return m_progressDialog.Form.Visible ? m_progressDialog.Form : m_synchInvoke as Form; + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) + return m_synchronizeInvoke.Invoke(() => m_progressDialog.IsIndeterminate); + return m_progressDialog.IsIndeterminate; + } + + set + { + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) + m_synchronizeInvoke.Invoke(() => m_progressDialog.IsIndeterminate = value); + else + m_progressDialog.IsIndeterminate = value; } } @@ -353,16 +347,16 @@ public int Minimum { CheckDisposed(); - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - return (int)m_synchInvoke.Invoke((Func)(() => m_progressDialog.Minimum), null); + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) + return (int)m_synchronizeInvoke.Invoke((Func)(() => m_progressDialog.Minimum), null); return m_progressDialog.Maximum; } set { CheckDisposed(); - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - m_synchInvoke.Invoke((Action)(i => m_progressDialog.Minimum = i), new object[] {value}); + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) + m_synchronizeInvoke.Invoke((Action)(i => m_progressDialog.Minimum = i), new object[] {value}); else m_progressDialog.Maximum = value; } @@ -380,16 +374,16 @@ public int Maximum { CheckDisposed(); - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - return (int)m_synchInvoke.Invoke((Func) (() => m_progressDialog.Maximum), null); + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) + return (int)m_synchronizeInvoke.Invoke((Func) (() => m_progressDialog.Maximum), null); return m_progressDialog.Maximum; } set { CheckDisposed(); - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - m_synchInvoke.Invoke((Action) (i => m_progressDialog.Maximum = i), new object[] {value}); + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) + m_synchronizeInvoke.Invoke((Action) (i => m_progressDialog.Maximum = i), new object[] {value}); else m_progressDialog.Maximum = value; } @@ -408,49 +402,21 @@ public string CancelButtonText { CheckDisposed(); - if (!(m_progressDialog is ProgressDialogImpl)) - throw new InvalidOperationException("The underlying progress dialog implementation probably does not implement CancelButtonText."); - - if (m_synchInvoke.InvokeRequired) - return (string)m_synchInvoke.Invoke((Func)(() => ((ProgressDialogImpl)m_progressDialog).CancelButtonText), null); + if (m_synchronizeInvoke.InvokeRequired) + return (string)m_synchronizeInvoke.Invoke((Func)(() => ((ProgressDialogImpl)m_progressDialog).CancelButtonText), null); return ((ProgressDialogImpl)m_progressDialog).CancelButtonText; } set { CheckDisposed(); - if (!(m_progressDialog is ProgressDialogImpl)) - throw new InvalidOperationException("The underlying progress dialog implementation probably does not implement CancelButtonText."); - - if (m_synchInvoke.InvokeRequired) - m_synchInvoke.Invoke((Action)(s => ((ProgressDialogImpl)m_progressDialog).CancelButtonText = s), new object[] {value}); + if (m_synchronizeInvoke.InvokeRequired) + m_synchronizeInvoke.Invoke((Action)(s => ((ProgressDialogImpl)m_progressDialog).CancelButtonText = s), new object[] {value}); else ((ProgressDialogImpl)m_progressDialog).CancelButtonText = value; } } - /// ------------------------------------------------------------------------------------ - /// - /// Gets or sets the style of the ProgressBar. - /// - /// ------------------------------------------------------------------------------------ - public ProgressBarStyle ProgressBarStyle - { - get - { - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - return (ProgressBarStyle) m_synchInvoke.Invoke((Func) (() => m_progressDialog.ProgressBarStyle), null); - return m_progressDialog.ProgressBarStyle; - } - set - { - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - m_synchInvoke.Invoke((Action) (style => m_progressDialog.ProgressBarStyle = style), new object[] {value}); - else - m_progressDialog.ProgressBarStyle = value; - } - } - /// ------------------------------------------------------------------------------------ /// /// Gets or sets a value indicating whether or not the progress indicator can restart @@ -463,17 +429,13 @@ public bool Restartable { CheckDisposed(); - if (!(m_progressDialog is ProgressDialogImpl)) - throw new InvalidOperationException("The underlying progress dialog implementation probably does not implement Restartable."); - return ((ProgressDialogImpl)m_progressDialog).Restartable; + return m_progressDialog.Restartable; } set { CheckDisposed(); - if (!(m_progressDialog is ProgressDialogImpl)) - throw new InvalidOperationException("The underlying progress dialog implementation probably does not implement Restartable."); - ((ProgressDialogImpl)m_progressDialog).Restartable = value; + m_progressDialog.Restartable = value; } } #endregion @@ -502,16 +464,16 @@ public bool AllowCancel { CheckDisposed(); - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - return (bool)m_synchInvoke.Invoke((Func)(() => m_progressDialog.AllowCancel), null); + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) + return (bool)m_synchronizeInvoke.Invoke((Func)(() => m_progressDialog.AllowCancel), null); return m_progressDialog.AllowCancel; } set { CheckDisposed(); - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - m_synchInvoke.Invoke((Action)(f => m_progressDialog.AllowCancel = f), new object[] {value}); + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) + m_synchronizeInvoke.Invoke((Action)(f => m_progressDialog.AllowCancel = f), new object[] {value}); else m_progressDialog.AllowCancel = value; } @@ -523,19 +485,9 @@ public bool AllowCancel /// UI thread. /// /// ------------------------------------------------------------------------------------ - public ThreadHelper ThreadHelper + public ISynchronizeInvoke SynchronizeInvoke { - get - { - if (m_threadHelper == null && m_synchInvoke != null) - { - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - { - m_synchInvoke.Invoke((Action)(() => { m_threadHelper = new ThreadHelper(); }), null); - } - } - return m_threadHelper; - } + get { return m_synchronizeInvoke; } } /// ------------------------------------------------------------------------------------ @@ -571,7 +523,7 @@ public object RunTask(Func backgroundTask, public object RunTask(bool fDisplayUi, Func backgroundTask, params object[] parameters) { - if (m_progressDialog.Form.Visible) + if (m_progressDialog.Visible) { int nMin = Minimum; int nMax = Maximum; @@ -590,10 +542,10 @@ public object RunTask(bool fDisplayUi, Func if (!fDisplayUi) { - if (m_synchInvoke.InvokeRequired) - m_synchInvoke.Invoke((Action) (() => m_progressDialog.Form.WindowState = FormWindowState.Minimized), null); + if (m_synchronizeInvoke.InvokeRequired) + m_synchronizeInvoke.Invoke((Action) (() => m_progressDialog.WindowState = FormWindowState.Minimized), null); else - m_progressDialog.Form.WindowState = FormWindowState.Minimized; + m_progressDialog.WindowState = FormWindowState.Minimized; } // On Linux using Xephyr (and possibly other environments that lack a taskbar), @@ -602,19 +554,19 @@ public object RunTask(bool fDisplayUi, Func // course throws an exception. This is really a bug in Mono's Form.ShowDialog implementation. if (Application.OpenForms.Count == 0 && fDisplayUi && !MiscUtils.IsUnix) { - if (m_synchInvoke.InvokeRequired) - m_synchInvoke.Invoke((Action)(() => m_progressDialog.Form.ShowInTaskbar = true), null); + if (m_synchronizeInvoke.InvokeRequired) + m_synchronizeInvoke.Invoke((Action)(() => m_progressDialog.ShowInTaskbar = true), null); else - m_progressDialog.Form.ShowInTaskbar = true; + m_progressDialog.ShowInTaskbar = true; } // Don't let the owner hide the progress dialog. See FWR-3482. - Form owner = Form; + Form owner = m_owner; if (owner != null && owner.TopMost) { m_fOwnerWasTopMost = true; owner.TopMost = false; - m_progressDialog.Form.TopMost = true; + m_progressDialog.TopMost = true; } LaunchDialogAndTask(owner); @@ -633,9 +585,9 @@ private void LaunchDialogAndTask(IWin32Window owner) var progressDlg = m_progressDialog as ProgressDialogWithTaskDlgImpl; if (progressDlg != null) { - if (m_synchInvoke.InvokeRequired) + if (m_synchronizeInvoke.InvokeRequired) { - m_synchInvoke.Invoke((Func)progressDlg.LaunchDialogAndStartTask, + m_synchronizeInvoke.Invoke((Func)progressDlg.LaunchDialogAndStartTask, new object[] { owner }); } else @@ -645,14 +597,14 @@ private void LaunchDialogAndTask(IWin32Window owner) } else { - if (m_synchInvoke.InvokeRequired) + if (m_synchronizeInvoke.InvokeRequired) { - m_synchInvoke.Invoke((Func)m_progressDialog.Form.ShowDialog, + m_synchronizeInvoke.Invoke((Func)m_progressDialog.ShowDialog, new object[] { owner }); } else { - m_progressDialog.Form.ShowDialog(owner); + m_progressDialog.ShowDialog(owner); } } } @@ -666,7 +618,7 @@ private void AddStartListener() } else { - m_progressDialog.Form.Shown += DialogShown; + m_progressDialog.Shown += DialogShown; } } @@ -679,7 +631,7 @@ private void RemoveStartListener() } else { - m_progressDialog.Form.Shown -= DialogShown; + m_progressDialog.Shown -= DialogShown; } } @@ -710,10 +662,10 @@ private void DialogShown() /// public static void ImportTranslatedListsForWs(Form parentWindow, FdoCache cache, string ws) { - string path = XmlTranslatedLists.TranslatedListsPathForWs(ws); + string path = XmlTranslatedLists.TranslatedListsPathForWs(ws, FwDirectoryFinder.TemplateDirectory); if (!File.Exists(path)) return; - using (var dlg = new ProgressDialogWithTask(parentWindow, cache.ThreadHelper)) + using (var dlg = new ProgressDialogWithTask(parentWindow)) { dlg.AllowCancel = true; dlg.Maximum = 200; @@ -735,7 +687,7 @@ private static object ImportTranslatedListsForWs(IThreadedProgress dlg, object[] { var ws = (string)args[0]; var cache = (FdoCache) args[1]; - XmlTranslatedLists.ImportTranslatedListsForWs(ws, cache, dlg); + XmlTranslatedLists.ImportTranslatedListsForWs(ws, cache, FwDirectoryFinder.TemplateDirectory, dlg); return null; } #endregion @@ -753,24 +705,31 @@ private void RunBackgroundTask(object sender, DoWorkEventArgs e) if (string.IsNullOrEmpty(Thread.CurrentThread.Name)) Thread.CurrentThread.Name = "Background thread"; - if (MiscUtils.RunningTests) - ManifestHelper.CreateActivationContext(); m_Exception = null; m_RetValue = null; + ActivationContextHelper activationContext = null; + IDisposable activation = null; try { + if (MiscUtils.RunningTests) + { + activationContext = new ActivationContextHelper("FieldWorks.Tests.manifest"); + activation = activationContext.Activate(); + } m_RetValue = m_backgroundTask(this, m_parameters); } catch (Exception ex) { - System.Diagnostics.Debug.WriteLine("Got exception in background thread: " + ex.Message); + Debug.WriteLine("Got exception in background thread: " + ex.Message); m_Exception = ex; } finally { - if (MiscUtils.RunningTests) - ManifestHelper.DestroyActivationContext(); + if (activation != null) + activation.Dispose(); + if (activationContext != null) + activationContext.Dispose(); } } @@ -806,10 +765,10 @@ private void m_progressDialog_FormClosing(object sender, FormClosingEventArgs e) private void m_worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { - if (m_fCreatedProgressDlg && m_synchInvoke.InvokeRequired) - m_synchInvoke.Invoke((Action)m_progressDialog.Form.Close, null); + if (m_fCreatedProgressDlg && m_synchronizeInvoke.InvokeRequired) + m_synchronizeInvoke.Invoke((Action)m_progressDialog.Close, null); else - m_progressDialog.Form.Close(); + m_progressDialog.Close(); } #endregion } diff --git a/Src/Common/Controls/FwControls/TextsTriStateTreeView.cs b/Src/Common/Controls/FwControls/TextsTriStateTreeView.cs index fa3697c9a9..c44e646bea 100644 --- a/Src/Common/Controls/FwControls/TextsTriStateTreeView.cs +++ b/Src/Common/Controls/FwControls/TextsTriStateTreeView.cs @@ -12,8 +12,8 @@ using System.Windows.Forms; using Paratext; using SIL.FieldWorks.Common.COMInterfaces; +using SIL.FieldWorks.Common.ScriptureUtils; using SIL.FieldWorks.FDO; -using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.Language; using SIL.FieldWorks.Resources; using SILUBS.SharedScrUtils; diff --git a/Src/Common/Controls/ScrControls/FilterTextsDialogTE.cs b/Src/Common/Controls/ScrControls/FilterTextsDialogTE.cs index 320e97827c..ad80b3a629 100644 --- a/Src/Common/Controls/ScrControls/FilterTextsDialogTE.cs +++ b/Src/Common/Controls/ScrControls/FilterTextsDialogTE.cs @@ -41,7 +41,7 @@ public FilterTextsDialogTE(FdoCache cache, IStText[] objList, : base(cache, objList, helpTopicProvider) { m_bookImporter = importer; - using (var progressDlg = new ProgressDialogWithTask(null, cache.ThreadHelper)) + using (var progressDlg = new ProgressDialogWithTask(this)) { // This somewhat duplicates some logic in FieldWorks.GetHelpTopicProvider, but it feels // wrong to reference the main exe even though I can't find an actual circular dependency. @@ -52,12 +52,12 @@ public FilterTextsDialogTE(FdoCache cache, IStText[] objList, IHelpTopicProvider helpProvider; if (FwUtils.FwUtils.IsTEInstalled) { - helpProvider = (IHelpTopicProvider) DynamicLoader.CreateObject(DirectoryFinder.TeDll, + helpProvider = (IHelpTopicProvider) DynamicLoader.CreateObject(FwDirectoryFinder.TeDll, "SIL.FieldWorks.TE.TeHelpTopicProvider"); } else { - helpProvider = (IHelpTopicProvider)DynamicLoader.CreateObject(DirectoryFinder.FlexDll, + helpProvider = (IHelpTopicProvider)DynamicLoader.CreateObject(FwDirectoryFinder.FlexDll, "SIL.FieldWorks.XWorks.LexText.FlexHelpTopicProvider"); } NonUndoableUnitOfWorkHelper.Do(cache.ActionHandlerAccessor, () => diff --git a/Src/Common/Controls/ScrControls/ScrControls.csproj b/Src/Common/Controls/ScrControls/ScrControls.csproj index 8b6f48a707..f72c327a3d 100644 --- a/Src/Common/Controls/ScrControls/ScrControls.csproj +++ b/Src/Common/Controls/ScrControls/ScrControls.csproj @@ -1,257 +1,267 @@ - + - Local - 9.0.30729 - 2.0 - {330F1096-A67E-4A08-9A09-D4CFE8FC4079} - SAK - SAK - SAK - Debug - AnyCPU - - - - - ScrControls - - - JScript - Grid - IE50 - false - Library - SIL.FieldWorks.Common.Controls - OnBuildSuccess - - - - - - - SAK - 3.5 - false - v4.0 - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - true - + Local + 9.0.30729 + 2.0 + {330F1096-A67E-4A08-9A09-D4CFE8FC4079} + + + + + + + Debug + AnyCPU + + + + + ScrControls + + + JScript + Grid + IE50 + false + Library + SIL.FieldWorks.Common.Controls + OnBuildSuccess + + + + + + + + + 3.5 + false + v4.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + - ..\..\..\..\Output\Debug\ - false - 285212672 - false - - - DEBUG;TRACE - ..\..\..\..\Output\Debug\ScrControls.xml - true - 4096 - false - 168,169,219,414,649,1635,1702,1701 - false - false - false - true - 4 - full - prompt - AllRules.ruleset - x86 + ..\..\..\..\Output\Debug\ + false + 285212672 + false + + + DEBUG;TRACE + ..\..\..\..\Output\Debug\ScrControls.xml + true + 4096 + false + 168,169,219,414,649,1635,1702,1701 + false + false + false + true + 4 + full + prompt + AllRules.ruleset + x86 - ..\..\..\..\Output\Release\ - false - 285212672 - false - - - TRACE - - - true - 4096 - false - 168,169,219,414,649,1635,1702,1701 - true - false - false - false - 4 - full - prompt - AllRules.ruleset - x86 + ..\..\..\..\Output\Release\ + false + 285212672 + false + + + TRACE + + + true + 4096 + false + 168,169,219,414,649,1635,1702,1701 + true + false + false + false + 4 + full + prompt + AllRules.ruleset + x86 - - False - ..\..\..\..\Output\Debug\BasicUtils.dll - - - COMInterfaces - ..\..\..\..\Output\Debug\COMInterfaces.dll - - - FDO - ..\..\..\..\Output\debug\FDO.dll - - - Framework - ..\..\..\..\Output\Debug\Framework.dll - - - FwControls - ..\..\..\..\Output\Debug\FwControls.dll - - - FwResources - ..\..\..\..\Output\Debug\FwResources.dll - - - FwUtils - ..\..\..\..\Output\Debug\FwUtils.dll - - - False - ..\..\..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll - - - Reporting - ..\..\..\..\Output\Debug\Reporting.dll - - - RootSite - ..\..\..\..\Output\Debug\RootSite.dll - - - ScriptureUtils - ..\..\..\..\Output\debug\ScriptureUtils.dll - - - ScrUtilsInterfaces - ..\..\..\..\Output\Debug\ScrUtilsInterfaces.dll - - - False - - - False - ..\..\..\..\Output\Debug\SharedScrUtils.dll - - - System - - - System.Data - - - System.Drawing - - - System.Windows.Forms - - - System.XML - - - False - - - xCoreInterfaces - ..\..\..\..\Output\Debug\xCoreInterfaces.dll - - - False - + + False + ..\..\..\..\Output\Debug\BasicUtils.dll + + + COMInterfaces + ..\..\..\..\Output\Debug\COMInterfaces.dll + + + FDO + ..\..\..\..\Output\debug\FDO.dll + + + Framework + ..\..\..\..\Output\Debug\Framework.dll + + + FwControls + ..\..\..\..\Output\Debug\FwControls.dll + + + FwResources + ..\..\..\..\Output\Debug\FwResources.dll + + + FwUtils + ..\..\..\..\Output\Debug\FwUtils.dll + + + False + ..\..\..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll + + + Reporting + ..\..\..\..\Output\Debug\Reporting.dll + + + RootSite + ..\..\..\..\Output\Debug\RootSite.dll + + + ScriptureUtils + ..\..\..\..\Output\debug\ScriptureUtils.dll + + + ScrUtilsInterfaces + ..\..\..\..\Output\Debug\ScrUtilsInterfaces.dll + + + False + + + False + ..\..\..\..\Output\Debug\SharedScrUtils.dll + + + System + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + False + + + xCoreInterfaces + ..\..\..\..\Output\Debug\xCoreInterfaces.dll + + + False + - - Code - - - - CommonAssemblyInfo.cs - - - - - True - True - ScrControls.resx - - - - - FilterTextsDialogTE.cs - - - ResXFileCodeGenerator - ScrControls.Designer.cs - Designer - - - DbScrPassageControl.cs - Designer - - - DbScrPassageDropDown.cs - Designer - + + CommonAssemblyInfo.cs + + + + Form + + + True + True + ScrControls.resx + + + UserControl + + + Form + + + FilterTextsDialogTE.cs + + + ResXFileCodeGenerator + ScrControls.Designer.cs + Designer + + + DbScrPassageControl.cs + Designer + + + DbScrPassageDropDown.cs + Designer + - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 2.0 %28x86%29 - true - - - False - .NET Framework 3.0 %28x86%29 - false - - - False - .NET Framework 3.5 - false - - - False - .NET Framework 3.5 SP1 - false - + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + - + - - - - + + + + \ No newline at end of file diff --git a/Src/Common/Controls/Widgets/LabeledMultiStringView.cs b/Src/Common/Controls/Widgets/LabeledMultiStringView.cs index 27148fdc10..38e8fd6529 100644 --- a/Src/Common/Controls/Widgets/LabeledMultiStringView.cs +++ b/Src/Common/Controls/Widgets/LabeledMultiStringView.cs @@ -332,7 +332,7 @@ private void SetupSoundControls() } else { - var mediaDir = DirectoryFinder.GetMediaDir(m_innerView.Cache.LangProject.LinkedFilesRootDir); + var mediaDir = FdoFileHelper.GetMediaDir(m_innerView.Cache.LangProject.LinkedFilesRootDir); Directory.CreateDirectory(mediaDir); // Palaso media library does not cope if it does not exist. path = Path.Combine(mediaDir, filename.Normalize(NormalizationForm.FormC)); @@ -384,7 +384,7 @@ void soundFieldControl_BeforeStartingToRecord(object sender, EventArgs e) private string CreateNewSoundFilename(out string path) { var obj = m_innerView.Cache.ServiceLocator.GetObject(m_innerView.HvoObj); - var mediaDir = DirectoryFinder.GetMediaDir(m_innerView.Cache.LangProject.LinkedFilesRootDir); + var mediaDir = FdoFileHelper.GetMediaDir(m_innerView.Cache.LangProject.LinkedFilesRootDir); Directory.CreateDirectory(mediaDir); // Palaso media library does not cope if it does not exist. // Make up a unique file name for the new recording. It starts with the shortname of the object // so as to somewhat link them together, then adds a unique timestamp, then if by any chance diff --git a/Src/Common/Controls/Widgets/UserInterfaceChooser.cs b/Src/Common/Controls/Widgets/UserInterfaceChooser.cs index 245ada1495..7b557f4bdc 100644 --- a/Src/Common/Controls/Widgets/UserInterfaceChooser.cs +++ b/Src/Common/Controls/Widgets/UserInterfaceChooser.cs @@ -174,10 +174,10 @@ private void AddAvailableLangsFromSatelliteDlls() /// ------------------------------------------------------------------------------------ private void AddAvailableLangsFromKeyTermsLocalizations() { - foreach (string file in DirectoryFinder.KeyTermsLocalizationFiles) + foreach (string file in FwDirectoryFinder.KeyTermsLocalizationFiles) { if (!String.IsNullOrEmpty(file)) - AddLanguage(DirectoryFinder.GetLocaleFromKeyTermsLocFile(file)); + AddLanguage(FwDirectoryFinder.GetLocaleFromKeyTermsLocFile(file)); } } diff --git a/Src/Common/Controls/Widgets/Widgets.csproj b/Src/Common/Controls/Widgets/Widgets.csproj index c549f26009..e338430f0d 100644 --- a/Src/Common/Controls/Widgets/Widgets.csproj +++ b/Src/Common/Controls/Widgets/Widgets.csproj @@ -1,4 +1,4 @@ - + Local @@ -318,4 +318,4 @@ ../../../../DistFiles - + \ No newline at end of file diff --git a/Src/Common/Controls/Widgets/WidgetsTests/WidgetsTests.csproj b/Src/Common/Controls/Widgets/WidgetsTests/WidgetsTests.csproj index 1d4d5924c2..741b837290 100644 --- a/Src/Common/Controls/Widgets/WidgetsTests/WidgetsTests.csproj +++ b/Src/Common/Controls/Widgets/WidgetsTests/WidgetsTests.csproj @@ -5,9 +5,12 @@ 9.0.30729 2.0 {EAF5AE4B-B92E-48C1-AA17-8B27C13D228F} - - - + + + + + + Debug AnyCPU diff --git a/Src/Common/Controls/XMLViews/ConfiguredExport.cs b/Src/Common/Controls/XMLViews/ConfiguredExport.cs index 46fb84c67a..ef875402db 100644 --- a/Src/Common/Controls/XMLViews/ConfiguredExport.cs +++ b/Src/Common/Controls/XMLViews/ConfiguredExport.cs @@ -640,14 +640,20 @@ private string GetLeadChar(string sEntryNFD, string sWs) } } // We don't want sFirst for an ignored first character or digraph. - var loc = Encoding.UTF8.GetBytes(sWs); - Icu.UErrorCode err; - var col = Icu.ucol_Open(loc, out err); - if ((int)err > (int)Icu.UErrorCode.U_ZERO_ERROR) + + IntPtr col; + try + { + string icuLocale = Icu.GetName(sWs); + col = Icu.OpenCollator(icuLocale); + } + catch (IcuException) + { return sFirst; + } try { - var ka = CmObjectComparer.GetSortKey(col, sFirst); + byte[] ka = Icu.GetSortKey(col, sFirst); if (ka.Length > 0 && ka[0] == 1) { string sT = sEntry.Substring(sFirst.Length); @@ -656,7 +662,7 @@ private string GetLeadChar(string sEntryNFD, string sWs) } finally { - Icu.ucol_Close(col); + Icu.CloseCollator(col); } return sFirst; } diff --git a/Src/Common/Controls/XMLViews/LayoutCache.cs b/Src/Common/Controls/XMLViews/LayoutCache.cs index 5f54ea89fb..8d5feabcf0 100644 --- a/Src/Common/Controls/XMLViews/LayoutCache.cs +++ b/Src/Common/Controls/XMLViews/LayoutCache.cs @@ -91,7 +91,7 @@ public static void InitializePartInventories(string sDatabase, { Debug.Assert(app != null, "app cannot be null"); - string partDirectory = Path.Combine(DirectoryFinder.FlexFolder, + string partDirectory = Path.Combine(FwDirectoryFinder.FlexFolder, Path.Combine("Configuration", "Parts")); var keyAttrs = new Dictionary(); keyAttrs["layout"] = new[] {"class", "type", "name", "choiceGuid" }; diff --git a/Src/Common/Controls/XMLViews/ReallySimpleListChooser.cs b/Src/Common/Controls/XMLViews/ReallySimpleListChooser.cs index fd4f687661..5fff265ed2 100644 --- a/Src/Common/Controls/XMLViews/ReallySimpleListChooser.cs +++ b/Src/Common/Controls/XMLViews/ReallySimpleListChooser.cs @@ -1215,7 +1215,7 @@ private void NavigateToSelectedTopic() if (!Path.IsPathRooted(helpFile)) { // Helps are part of the installed code files. See FWR-1002. - string helpsPath = Path.Combine(DirectoryFinder.FWCodeDirectory, "Helps"); + string helpsPath = Path.Combine(FwDirectoryFinder.CodeDirectory, "Helps"); helpFile = Path.Combine(helpsPath, helpFile); } #if __MonoCS__ diff --git a/Src/Common/Controls/XMLViews/XMLViews.csproj b/Src/Common/Controls/XMLViews/XMLViews.csproj index a1512e3c5f..7c79fb6018 100644 --- a/Src/Common/Controls/XMLViews/XMLViews.csproj +++ b/Src/Common/Controls/XMLViews/XMLViews.csproj @@ -1,4 +1,4 @@ - + Local @@ -227,10 +227,10 @@ \usr\lib\cli\geckofx-14.0.1\geckofx-core-14.dll - + \usr\lib\cli\geckofx-14.0.1\Geckofx-Winforms-14.dll - + PreserveNewest @@ -424,11 +424,10 @@ - ../../../../DistFiles - + \ No newline at end of file diff --git a/Src/Common/Controls/XMLViews/XMLViewsTests/TestColumnConfigureDialog.cs b/Src/Common/Controls/XMLViews/XMLViewsTests/TestColumnConfigureDialog.cs index 42c085fb3f..b767746a00 100644 --- a/Src/Common/Controls/XMLViews/XMLViewsTests/TestColumnConfigureDialog.cs +++ b/Src/Common/Controls/XMLViews/XMLViewsTests/TestColumnConfigureDialog.cs @@ -11,6 +11,7 @@ using SIL.FieldWorks.Common.Controls; using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO; +using SIL.FieldWorks.FDO.FDOTests; using SIL.FieldWorks.Test.TestUtils; using SIL.Utils; using XCore; @@ -30,7 +31,7 @@ public void SetUp() m_mediator = new Mediator(); m_mediator.StringTbl = new StringTable("../../DistFiles/Language Explorer/Configuration"); m_cache = FdoCache.CreateCacheWithNewBlankLangProj( - new TestProjectId(FDOBackendProviderType.kMemoryOnly, null), "en", "en", "en", new ThreadHelper()); + new TestProjectId(FDOBackendProviderType.kMemoryOnly, null), "en", "en", "en", new DummyFdoUI(), FwDirectoryFinder.FdoDirectories); m_mediator.PropertyTable.SetProperty("cache", m_cache); } @@ -38,7 +39,6 @@ public void SetUp() public void TearDown() { m_mediator.Dispose(); - m_cache.ThreadHelper.Dispose(); m_cache.Dispose(); } diff --git a/Src/Common/Controls/XMLViews/XMLViewsTests/TestManyOneBrowse.cs b/Src/Common/Controls/XMLViews/XMLViewsTests/TestManyOneBrowse.cs index 1131b51125..9cb2be616e 100644 --- a/Src/Common/Controls/XMLViews/XMLViewsTests/TestManyOneBrowse.cs +++ b/Src/Common/Controls/XMLViews/XMLViewsTests/TestManyOneBrowse.cs @@ -60,7 +60,7 @@ public void Setup() // - MoMorphSynAnalysis // - MoStemMsa // - MoDerivationalMsa - string m_sTestPath = Path.Combine(DirectoryFinder.FwSourceDirectory, + string m_sTestPath = Path.Combine(FwDirectoryFinder.SourceDirectory, Path.Combine("Common", Path.Combine("Controls", Path.Combine("XMLViews", @@ -82,7 +82,7 @@ public void Setup() m_sda.WritingSystemFactory = m_wsManager; var parser = new SimpleDataParser(m_mdc, m_cda); - parser.Parse(Path.Combine(DirectoryFinder.FwSourceDirectory, + parser.Parse(Path.Combine(FwDirectoryFinder.SourceDirectory, Path.Combine("Common", Path.Combine("Controls", Path.Combine("XMLViews", @@ -102,7 +102,7 @@ public void Setup() // - Semantic domains (pair of strings in para in seq in seq, using layout refs) // - MSAs (simplified, but polymorphic with one having and one to CmPossibility XmlDocument docColumns = new XmlDocument(); - docColumns.Load(Path.Combine(DirectoryFinder.FwSourceDirectory, + docColumns.Load(Path.Combine(FwDirectoryFinder.SourceDirectory, Path.Combine("Common", Path.Combine("Controls", Path.Combine("XMLViews", @@ -110,7 +110,7 @@ public void Setup() m_columnList = docColumns.DocumentElement.ChildNodes; // Parts just has what those columns need. - string partDirectory = Path.Combine(DirectoryFinder.FwSourceDirectory, + string partDirectory = Path.Combine(FwDirectoryFinder.SourceDirectory, Path.Combine("Common", Path.Combine("Controls", Path.Combine("XMLViews", "XMLViewsTests")))); diff --git a/Src/Common/Controls/XMLViews/XMLViewsTests/XMLViewsTests.csproj b/Src/Common/Controls/XMLViews/XMLViewsTests/XMLViewsTests.csproj index e8e2a399b7..b10234b971 100644 --- a/Src/Common/Controls/XMLViews/XMLViewsTests/XMLViewsTests.csproj +++ b/Src/Common/Controls/XMLViews/XMLViewsTests/XMLViewsTests.csproj @@ -1,4 +1,4 @@ - + Local @@ -233,7 +233,9 @@ - + + UserControl + diff --git a/Src/Common/Controls/XMLViews/XmlVc.cs b/Src/Common/Controls/XMLViews/XmlVc.cs index 7054085857..1f27450099 100644 --- a/Src/Common/Controls/XMLViews/XmlVc.cs +++ b/Src/Common/Controls/XMLViews/XmlVc.cs @@ -181,7 +181,7 @@ public class XmlVc : FwBaseVc // This is the new constructor, where we find parts in the master inventory. /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The string table. /// Name of the root layout. @@ -199,7 +199,7 @@ public XmlVc(StringTable stringTable, string rootLayoutName, bool fEditable, // This is a variant which can take a condition element to control which items in a list display. /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The string table. /// Name of the root layout. @@ -223,7 +223,7 @@ public XmlVc(StringTable stringTable, string rootLayoutName, bool fEditable, /// /// This is another new constructor, for using the new approach without a single /// top-level layout name, such as browse view. - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The string table. /// ------------------------------------------------------------------------------------ @@ -1528,7 +1528,7 @@ public virtual void ProcessFrag(XmlNode frag, IVwEnv vwenv, int hvo, bool fEdita CellarPropertyType itype = (CellarPropertyType)m_sda.MetaDataCache.GetFieldType(flid); if (itype == CellarPropertyType.Time) { - DateTime dt = FwUtils.SilTime.GetTimeProperty(m_sda, hvo, flid); + DateTime dt = SilTime.GetTimeProperty(m_sda, hvo, flid); XmlNode dtNode = XmlViewsUtils.CopyWithParamDefaults(frag); string format; if (vwenv is SortCollectorEnv) @@ -4951,7 +4951,7 @@ public class NodeDisplayCommand : DisplayCommand /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The node. /// ------------------------------------------------------------------------------------ @@ -5031,7 +5031,7 @@ public class NodeChildrenDisplayCommand : NodeDisplayCommand { /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The node. /// ------------------------------------------------------------------------------------ @@ -5657,7 +5657,7 @@ public class PropWs { /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The xflid. /// The XWS. @@ -5734,12 +5734,12 @@ public int Compare(int x, int y) string ws = xobj.SortKeyWs; if (string.IsNullOrEmpty(ws)) ws = yobj.SortKeyWs; - Icu.UErrorCode err; - m_col = Icu.ucol_Open(Encoding.UTF8.GetBytes(ws), out err); + string icuLocale = Icu.GetName(ws); + m_col = Icu.OpenCollator(icuLocale); } - byte[] xkey = GetSortKey(m_col, xkeyStr); - byte[] ykey = GetSortKey(m_col, ykeyStr); + byte[] xkey = Icu.GetSortKey(m_col, xkeyStr); + byte[] ykey = Icu.GetSortKey(m_col, ykeyStr); // Simulate strcmp on the two NUL-terminated byte strings. // This avoids marshalling back and forth. // JohnT: but apparently the strings are not null-terminated if the input was empty. @@ -5769,33 +5769,11 @@ public int Compare(int x, int y) return nVal; } - internal static byte[] GetSortKey(IntPtr collater, string keyStr) - { - const int keyLength = 1024; - var key = new byte[keyLength+1]; - var len = Icu.ucol_GetSortKey(collater, keyStr, keyStr.Length, ref key, keyLength); - if (len > keyLength) - { - key = new byte[len + 1]; - len = Icu.ucol_GetSortKey(collater, keyStr, keyStr.Length, ref key, len); - } - // Ensure that the byte array is truncated to its actual data length. - Debug.Assert(len <= key.Length); - if (len < key.Length) - { - var result = new byte[len]; - for (int i = 0; i < len; ++i) - result[i] = key[i]; - return result; - } - return key; - } - protected override void DisposeUnmanagedResources() { if (m_col != IntPtr.Zero) { - Icu.ucol_Close(m_col); + Icu.CloseCollator(m_col); m_col = IntPtr.Zero; } } diff --git a/Src/Common/Controls/XMLViews/XmlViewsUtils.cs b/Src/Common/Controls/XMLViews/XmlViewsUtils.cs index 30da878cb4..5b0768c576 100644 --- a/Src/Common/Controls/XMLViews/XmlViewsUtils.cs +++ b/Src/Common/Controls/XMLViews/XmlViewsUtils.cs @@ -959,7 +959,7 @@ static public string[] StringsFor(FdoCache fdoCache, ISilDataAccess sda, XmlNode CellarPropertyType itype = (CellarPropertyType)sda.MetaDataCache.GetFieldType(flid); if (itype == CellarPropertyType.Time) { - DateTime dt = FwUtils.SilTime.GetTimeProperty(sda, hvo, flid); + DateTime dt = SilTime.GetTimeProperty(sda, hvo, flid); return new[] {DateTimeCompString(dt)}; } else diff --git a/Src/Common/FwUtils/CaseFunctions.cs b/Src/Common/CoreImpl/CaseFunctions.cs similarity index 98% rename from Src/Common/FwUtils/CaseFunctions.cs rename to Src/Common/CoreImpl/CaseFunctions.cs index d25a597d5b..89a01ca485 100644 --- a/Src/Common/FwUtils/CaseFunctions.cs +++ b/Src/Common/CoreImpl/CaseFunctions.cs @@ -7,7 +7,7 @@ // --------------------------------------------------------------------------------------------- using SIL.FieldWorks.Common.COMInterfaces; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.CoreImpl { /// /// CaseFunctions provides a set of case conversion functions derived from the ICU diff --git a/Src/Common/CoreImpl/CoreImpl.csproj b/Src/Common/CoreImpl/CoreImpl.csproj index 674455805c..eb3f4caaf5 100644 --- a/Src/Common/CoreImpl/CoreImpl.csproj +++ b/Src/Common/CoreImpl/CoreImpl.csproj @@ -99,7 +99,14 @@ CommonAssemblyInfo.cs + + + + + + + @@ -132,6 +139,9 @@ + + + diff --git a/Src/Common/CoreImpl/CoreImplStrings.Designer.cs b/Src/Common/CoreImpl/CoreImplStrings.Designer.cs index 13c195dfcc..ee90a048b7 100644 --- a/Src/Common/CoreImpl/CoreImplStrings.Designer.cs +++ b/Src/Common/CoreImpl/CoreImplStrings.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.296 +// Runtime Version:4.0.30319.18052 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -61,7 +61,7 @@ internal CoreImplStrings() { } /// - /// Looks up a localized string similar to FieldWorks is unable to save some writing system settings because access to {0} is not authorized. This may cause unexpected behavior, and may be indicative of a wider problem with access permissions that could cause program crashes.. + /// Looks up a localized string similar to Unable to save some writing system settings because access to {0} is not authorized. This may cause unexpected behavior, and may be indicative of a wider problem with access permissions that could cause program crashes.. /// internal static string ksCannotWriteWritingSystemInfo { get { @@ -69,6 +69,87 @@ internal static string ksCannotWriteWritingSystemInfo { } } + /// + /// Looks up a localized string similar to AD. + /// + internal static string ksGenDateAD { + get { + return ResourceManager.GetString("ksGenDateAD", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to After. + /// + internal static string ksGenDateAfter { + get { + return ResourceManager.GetString("ksGenDateAfter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to About. + /// + internal static string ksGenDateApprox { + get { + return ResourceManager.GetString("ksGenDateApprox", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to BC. + /// + internal static string ksGenDateBC { + get { + return ResourceManager.GetString("ksGenDateBC", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Before. + /// + internal static string ksGenDateBefore { + get { + return ResourceManager.GetString("ksGenDateBefore", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Version: {0} {1} {2}. + /// + internal static string kstidAppVersionFmt { + get { + return ResourceManager.GetString("kstidAppVersionFmt", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This software is licensed under the MIT License. + /// + internal static string kstidLicense { + get { + return ResourceManager.GetString("kstidLicense", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to (http://opensource.org/licenses/MIT). + /// + internal static string kstidLicenseURL { + get { + return ResourceManager.GetString("kstidLicenseURL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Version: {0}. + /// + internal static string kstidMajorVersionFmt { + get { + return ResourceManager.GetString("kstidMajorVersionFmt", resourceCulture); + } + } + /// /// Looks up a localized string similar to Warning. /// @@ -96,8 +177,7 @@ internal static string ksWarning { ///AQ 2005-10-16 Antarctica ///AR 2005-10-16 Argentina ///AS 2005-10-16 American Samoa - ///AT 2005-10-16 Austria - ///AU 2005-10 [rest of string was truncated]";. + ///AT 2005-10-16 A [rest of string was truncated]";. /// internal static string regions { get { @@ -114,8 +194,7 @@ internal static string regions { ///1694acad 2007-03-20 Early Modern French fr ///1901 2005-10-16 Traditional German orthography de ///1959acad 2008-09-30 "Academic" ("governmental") variant of Belarusian as codified in 1959 be - ///1994 2007-07-28 Standardized Resian orthography sl-rozaj / sl-rozaj-biske / sl-rozaj-njiva / sl-rozaj-osojs / sl-rozaj-solba - ///1996 20 [rest of string was truncated]";. + ///1994 2007-07-28 Standardized Resian orthography sl-rozaj / sl-rozaj-biske / sl-rozaj-njiva / sl-rozaj-osojs / sl-rozaj-solba [rest of string was truncated]";. ///
internal static string variants { get { diff --git a/Src/Common/CoreImpl/CoreImplStrings.resx b/Src/Common/CoreImpl/CoreImplStrings.resx index 026e43da47..995ede0202 100644 --- a/Src/Common/CoreImpl/CoreImplStrings.resx +++ b/Src/Common/CoreImpl/CoreImplStrings.resx @@ -118,7 +118,38 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - FieldWorks is unable to save some writing system settings because access to {0} is not authorized. This may cause unexpected behavior, and may be indicative of a wider problem with access permissions that could cause program crashes. + Unable to save some writing system settings because access to {0} is not authorized. This may cause unexpected behavior, and may be indicative of a wider problem with access permissions that could cause program crashes. + + + AD + + + After + + + About + + + BC + + + Before + + + Version: {0} {1} {2} + Displays in the Help/About box and the splash screen + + + Version: {0} + Displays in the Help/About box and the splash screen + + + This software is licensed under the LGPL, version 2.1 or later + Displays in the Help/About box and the splash screen + + + (http://www.gnu.org/licenses/lgpl-2.1.html) + Displays in the Help/About box Warning diff --git a/Src/Common/CoreImpl/CoreImplTests/CoreImplTests.csproj b/Src/Common/CoreImpl/CoreImplTests/CoreImplTests.csproj index 4fdd3f52b9..ae2a29e712 100644 --- a/Src/Common/CoreImpl/CoreImplTests/CoreImplTests.csproj +++ b/Src/Common/CoreImpl/CoreImplTests/CoreImplTests.csproj @@ -1,4 +1,4 @@ - + Debug @@ -110,12 +110,15 @@ AssemblyInfoForTests.cs + + + @@ -143,8 +146,7 @@ - ../../../../DistFiles - + \ No newline at end of file diff --git a/Src/Common/CoreImpl/CoreImplTests/DirectoryFinderTests.cs b/Src/Common/CoreImpl/CoreImplTests/DirectoryFinderTests.cs new file mode 100644 index 0000000000..4b8974a8fa --- /dev/null +++ b/Src/Common/CoreImpl/CoreImplTests/DirectoryFinderTests.cs @@ -0,0 +1,62 @@ +using System; +using NUnit.Framework; + +namespace SIL.CoreImpl +{ + [TestFixture] + public class DirectoryFinderTests + { + private string m_previousEnvironment; + + private void SetupEnvironment(string path) + { + m_previousEnvironment = Environment.GetEnvironmentVariable("FW_CommonAppData"); + DirectoryFinder.ResetStaticVars(); + Environment.SetEnvironmentVariable("FW_CommonAppData", path); + } + + private void ResetEnvironment() + { + Environment.SetEnvironmentVariable("FW_CommonAppData", m_previousEnvironment); + } + + [Test] + public void GetFolderPath_NoEnvVariableSet() + { + try + { + SetupEnvironment(null); + string path = DirectoryFinder.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); +#if __MonoCS__ + Assert.That(path, Is.EqualTo("/var/lib/fieldworks")); +#else + Assert.That(path, Is.EqualTo(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData))); +#endif + } + finally + { + ResetEnvironment(); + } + } + + [Test] + public void GetFolderPath_EnvVariableSet() + { + try + { + SetupEnvironment("/bla"); + string path = DirectoryFinder.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); +#if __MonoCS__ + Assert.That(path, Is.EqualTo("/bla")); +#else + Assert.That(path, Is.EqualTo(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData))); +#endif + } + finally + { + ResetEnvironment(); + } + } + + } +} diff --git a/Src/Common/CoreImpl/CoreImplTests/PalasoWritingSystemManagerTests.cs b/Src/Common/CoreImpl/CoreImplTests/PalasoWritingSystemManagerTests.cs index ca7566611b..45ae10a9db 100644 --- a/Src/Common/CoreImpl/CoreImplTests/PalasoWritingSystemManagerTests.cs +++ b/Src/Common/CoreImpl/CoreImplTests/PalasoWritingSystemManagerTests.cs @@ -102,6 +102,8 @@ public void SerializeDeserialize() /// /// Tests to make sure that the special fw extensions of ldml aren't duplicated when round tripping. /// + [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", + Justification = "In .NET 4.5 XmlNodeList implements IDisposable, but not in 4.0.")] [Test] [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", Justification = "In .NET 4.5 XmlNodeList implements IDisposable, but not in 4.0.")] diff --git a/Src/Common/FwUtils/FwUtilsTests/SpellingHelperTests.cs b/Src/Common/CoreImpl/CoreImplTests/SpellingHelperTests.cs similarity index 99% rename from Src/Common/FwUtils/FwUtilsTests/SpellingHelperTests.cs rename to Src/Common/CoreImpl/CoreImplTests/SpellingHelperTests.cs index 4e8c7df279..8ce5bf316e 100644 --- a/Src/Common/FwUtils/FwUtilsTests/SpellingHelperTests.cs +++ b/Src/Common/CoreImpl/CoreImplTests/SpellingHelperTests.cs @@ -1,12 +1,11 @@ using System; -using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using NUnit.Framework; using SIL.Utils; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.CoreImpl { /// /// Tests (for now pretty incomplete) of the SpellingHelper class. diff --git a/Src/Common/FwUtils/FwUtilsTests/StringSearcherTests.cs b/Src/Common/CoreImpl/CoreImplTests/StringSearcherTests.cs similarity index 94% rename from Src/Common/FwUtils/FwUtilsTests/StringSearcherTests.cs rename to Src/Common/CoreImpl/CoreImplTests/StringSearcherTests.cs index 216450f465..f995d16e0e 100644 --- a/Src/Common/FwUtils/FwUtilsTests/StringSearcherTests.cs +++ b/Src/Common/CoreImpl/CoreImplTests/StringSearcherTests.cs @@ -1,16 +1,14 @@ -using System.Linq; +using System.Linq; using NUnit.Framework; -using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Test.TestUtils; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.CoreImpl { /// /// StringSearcher tests /// [TestFixture] - public class StringSearcherTests: BaseTest + public class StringSearcherTests { private IWritingSystemManager m_wsManager; private int m_enWs; @@ -21,10 +19,8 @@ public class StringSearcherTests: BaseTest /// Setup the test fixture. /// [TestFixtureSetUp] - public override void FixtureSetup() + public void FixtureSetup() { - base.FixtureSetup(); - m_wsManager = new PalasoWritingSystemManager(); IWritingSystem enWs; m_wsManager.GetOrSet("en", out enWs); diff --git a/Src/Common/CoreImpl/DirectoryFinder.cs b/Src/Common/CoreImpl/DirectoryFinder.cs new file mode 100644 index 0000000000..31fcfc40f3 --- /dev/null +++ b/Src/Common/CoreImpl/DirectoryFinder.cs @@ -0,0 +1,124 @@ +using System; +using System.IO; +using System.Reflection; +using SIL.Utils; + +namespace SIL.CoreImpl +{ + /// + /// This class is used to find files and directories for an SIL app. + /// + public static class DirectoryFinder + { + private static string s_CommonAppDataFolder; + + /// + /// Resets the static variables. Used for unit tests. + /// + internal static void ResetStaticVars() + { + s_CommonAppDataFolder = null; + } + + + /// + /// Gets the company name (should be SIL). + /// + public static string CompanyName + { + get + { + return ((AssemblyCompanyAttribute)Attribute.GetCustomAttribute( + Assembly.GetExecutingAssembly(), typeof(AssemblyCompanyAttribute), false)) + .Company; + } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the path for storing user-specific application data. + /// + /// Name of the application. + /// ------------------------------------------------------------------------------------ + public static string UserAppDataFolder(string appName) + { + string path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + return Path.Combine(Path.Combine(path, CompanyName), appName); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the path for storing common application data that might be shared between + /// multiple applications and multiple users on the same machine. + /// + /// On Windows this returns Environment.SpecialFolder.CommonApplicationData + /// (C:\ProgramData),on Linux /var/lib/fieldworks. + /// + /// ------------------------------------------------------------------------------------ + private static string CommonApplicationData + { + get + { + if (s_CommonAppDataFolder == null) + { + if (MiscUtils.IsUnix) + { + // allow to override the /var/lib/fieldworks path by setting the + // environment variable FW_CommonAppData. Is this is needed on our CI + // build machines. + s_CommonAppDataFolder = + Environment.GetEnvironmentVariable("FW_CommonAppData") ?? + "/var/lib/fieldworks"; + } + else + { + s_CommonAppDataFolder = + Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); + } + } + return s_CommonAppDataFolder; + } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets a special folder, very similar to Environment.GetFolderPath. The main + /// difference is that this method works cross-platform and does some translations. + /// For example CommonApplicationData (/usr/share) is not writeable on Linux, so we + /// translate that to /var/lib/fieldworks instead. + /// + /// ------------------------------------------------------------------------------------ + public static string GetFolderPath(Environment.SpecialFolder folder) + { + if (folder == Environment.SpecialFolder.CommonApplicationData) + return CommonApplicationData; + return Environment.GetFolderPath(folder); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the path for storing common application data that might be shared between + /// multiple applications and multiple users on the same machine. + /// + /// On Windows this returns a subdirectory of + /// Environment.SpecialFolder.CommonApplicationData (C:\ProgramData),on Linux + /// /var/lib/fieldworks. + /// + /// Name of the application. + /// ------------------------------------------------------------------------------------ + public static string CommonAppDataFolder(string appName) + { + return Path.Combine(Path.Combine(CommonApplicationData, CompanyName), appName); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the global writing system store directory. The directory is guaranteed to exist. + /// + /// ------------------------------------------------------------------------------------ + public static string GlobalWritingSystemStoreDirectory + { + get { return CommonAppDataFolder("WritingSystemStore"); } + } + } +} diff --git a/Src/Common/FwUtils/GenDate.cs b/Src/Common/CoreImpl/GenDate.cs similarity index 92% rename from Src/Common/FwUtils/GenDate.cs rename to Src/Common/CoreImpl/GenDate.cs index 1d5ac08d34..db34f706f6 100644 --- a/Src/Common/FwUtils/GenDate.cs +++ b/Src/Common/CoreImpl/GenDate.cs @@ -1,9 +1,8 @@ -using System; -using System.Text; -using System.Globalization; +using System; using System.Collections.Generic; +using System.Text; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.CoreImpl { /// /// This class encapsulates the generic (vague) date type. This type can store dates @@ -215,15 +214,15 @@ public string ToLongString() switch (m_precision) { case PrecisionType.Approximate: - sb.Append(FwUtilsStrings.ksGenDateApprox); + sb.Append(CoreImplStrings.ksGenDateApprox); sb.Append(" "); break; case PrecisionType.After: - sb.Append(FwUtilsStrings.ksGenDateAfter); + sb.Append(CoreImplStrings.ksGenDateAfter); sb.Append(" "); break; case PrecisionType.Before: - sb.Append(FwUtilsStrings.ksGenDateBefore); + sb.Append(CoreImplStrings.ksGenDateBefore); sb.Append(" "); break; } @@ -247,7 +246,7 @@ public string ToLongString() } else if (m_year != UnknownYear && m_ad) { - sb.Append(FwUtilsStrings.ksGenDateAD); + sb.Append(CoreImplStrings.ksGenDateAD); sb.Append(" "); } @@ -257,7 +256,7 @@ public string ToLongString() if (!m_ad) { sb.Append(" "); - sb.Append(FwUtilsStrings.ksGenDateBC); + sb.Append(CoreImplStrings.ksGenDateBC); } } return sb.ToString(); @@ -279,15 +278,15 @@ public string ToXMLExportShortString() switch (m_precision) { case PrecisionType.Approximate: - sb.Append(FwUtilsStrings.ksGenDateApprox); + sb.Append(CoreImplStrings.ksGenDateApprox); sb.Append(" "); break; case PrecisionType.After: - sb.Append(FwUtilsStrings.ksGenDateAfter); + sb.Append(CoreImplStrings.ksGenDateAfter); sb.Append(" "); break; case PrecisionType.Before: - sb.Append(FwUtilsStrings.ksGenDateBefore); + sb.Append(CoreImplStrings.ksGenDateBefore); sb.Append(" "); break; } @@ -316,15 +315,15 @@ public string ToShortString() switch (m_precision) { case PrecisionType.Approximate: - sb.Append(FwUtilsStrings.ksGenDateApprox); + sb.Append(CoreImplStrings.ksGenDateApprox); sb.Append(" "); break; case PrecisionType.After: - sb.Append(FwUtilsStrings.ksGenDateAfter); + sb.Append(CoreImplStrings.ksGenDateAfter); sb.Append(" "); break; case PrecisionType.Before: - sb.Append(FwUtilsStrings.ksGenDateBefore); + sb.Append(CoreImplStrings.ksGenDateBefore); sb.Append(" "); break; } @@ -380,30 +379,30 @@ public static bool TryParse(string date, out GenDate gen) bool fAD = true; date = date.Trim(); - if (date.StartsWith(FwUtilsStrings.ksGenDateApprox)) + if (date.StartsWith(CoreImplStrings.ksGenDateApprox)) { precision = PrecisionType.Approximate; - date = date.Substring(FwUtilsStrings.ksGenDateApprox.Length + 1); + date = date.Substring(CoreImplStrings.ksGenDateApprox.Length + 1); } - else if (date.StartsWith(FwUtilsStrings.ksGenDateAfter)) + else if (date.StartsWith(CoreImplStrings.ksGenDateAfter)) { precision = PrecisionType.After; - date = date.Substring(FwUtilsStrings.ksGenDateAfter.Length + 1); + date = date.Substring(CoreImplStrings.ksGenDateAfter.Length + 1); } - else if (date.StartsWith(FwUtilsStrings.ksGenDateBefore)) + else if (date.StartsWith(CoreImplStrings.ksGenDateBefore)) { precision = PrecisionType.Before; - date = date.Substring(FwUtilsStrings.ksGenDateBefore.Length + 1); + date = date.Substring(CoreImplStrings.ksGenDateBefore.Length + 1); } - if (date.Contains(FwUtilsStrings.ksGenDateAD + " ")) + if (date.Contains(CoreImplStrings.ksGenDateAD + " ")) { fAD = true; - date = date.Replace(FwUtilsStrings.ksGenDateAD + " ", ""); + date = date.Replace(CoreImplStrings.ksGenDateAD + " ", ""); } - else if (date.EndsWith(FwUtilsStrings.ksGenDateBC)) + else if (date.EndsWith(CoreImplStrings.ksGenDateBC)) { fAD = false; - date = date.Substring(0, date.Length - (FwUtilsStrings.ksGenDateBC.Length + 1)); + date = date.Substring(0, date.Length - (CoreImplStrings.ksGenDateBC.Length + 1)); } int nDay = UnknownDay; int nMonth = UnknownMonth; diff --git a/Src/Common/CoreImpl/GlobalFileWritingSystemStore.cs b/Src/Common/CoreImpl/GlobalFileWritingSystemStore.cs index 914349f7ea..dcae8cba80 100644 --- a/Src/Common/CoreImpl/GlobalFileWritingSystemStore.cs +++ b/Src/Common/CoreImpl/GlobalFileWritingSystemStore.cs @@ -3,13 +3,11 @@ using System.Globalization; using System.IO; using System.Linq; -using System.Runtime.InteropServices; +using System.Security.AccessControl; +using System.Security.Principal; using System.Threading; -using System.Xml; using System.Collections.Generic; -using System.Xml.Linq; using Palaso.WritingSystems; -using SIL.FieldWorks.Common.COMInterfaces; using SIL.Utils; namespace SIL.CoreImpl @@ -25,14 +23,49 @@ public class GlobalFileWritingSystemStore : IFwWritingSystemStore /// Reference to a mutex. The owner of the mutex is the SingletonContainer private readonly Mutex m_mutex; + /// + /// Initializes a new instance of the class. + /// + public GlobalFileWritingSystemStore() + : this(DirectoryFinder.GlobalWritingSystemStoreDirectory) + { + } + /// /// Initializes a new instance of the class. /// /// The path. - public GlobalFileWritingSystemStore(string path) + [SuppressMessage("Gendarme.Rules.Portability", "MonoCompatibilityReviewRule", + Justification="Offending code is not executed on Linux")] + internal GlobalFileWritingSystemStore(string path) { m_path = path; - Directory.CreateDirectory(m_path); + if (!Directory.Exists(m_path)) + { + DirectoryInfo di; + + // Provides FW on Linux multi-user access. Overrides the system + // umask and creates the directory with the permissions "775". + // The "fieldworks" group was created outside the app during + // configuration of the package which allows group access. + using(new FileModeOverride()) + { + di = Directory.CreateDirectory(m_path); + } + + if (!MiscUtils.IsUnix) + { + // NOTE: GetAccessControl/ModifyAccessRule/SetAccessControl is not implemented in Mono + DirectorySecurity ds = di.GetAccessControl(); + var sid = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null); + AccessRule rule = new FileSystemAccessRule(sid, FileSystemRights.Write | FileSystemRights.ReadAndExecute + | FileSystemRights.Modify, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, + PropagationFlags.InheritOnly, AccessControlType.Allow); + bool modified; + ds.ModifyAccessRule(AccessControlModification.Add, rule, out modified); + di.SetAccessControl(ds); + } + } m_mutex = SingletonsContainer.Get(typeof(Mutex).FullName + m_path, () => new Mutex(false, m_path.Replace('\\', '_').Replace('/', '_'))); } diff --git a/Src/Common/FwUtils/ISpellEngine.cs b/Src/Common/CoreImpl/ISpellEngine.cs similarity index 92% rename from Src/Common/FwUtils/ISpellEngine.cs rename to Src/Common/CoreImpl/ISpellEngine.cs index 8e868a0b24..690b8f6c9f 100644 --- a/Src/Common/FwUtils/ISpellEngine.cs +++ b/Src/Common/CoreImpl/ISpellEngine.cs @@ -1,7 +1,7 @@ -using System.Collections.Generic; +using System.Collections.Generic; using SIL.FieldWorks.Common.COMInterfaces; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.CoreImpl { /// /// This is our wrapper for Hunspell, currently. It hides everything we don't use in case we want to change again! diff --git a/Src/Common/FwUtils/SilTime.cs b/Src/Common/CoreImpl/SilTime.cs similarity index 96% rename from Src/Common/FwUtils/SilTime.cs rename to Src/Common/CoreImpl/SilTime.cs index 1c245336b8..894711479f 100644 --- a/Src/Common/FwUtils/SilTime.cs +++ b/Src/Common/CoreImpl/SilTime.cs @@ -8,13 +8,11 @@ // // -using System; -using System.Collections.Generic; -using System.Text; +using System; using SIL.FieldWorks.Common.COMInterfaces; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.CoreImpl { /// ---------------------------------------------------------------------------------------- /// diff --git a/Src/Common/FwUtils/SpellEngine.cs b/Src/Common/CoreImpl/SpellEngine.cs similarity index 99% rename from Src/Common/FwUtils/SpellEngine.cs rename to Src/Common/CoreImpl/SpellEngine.cs index aa4dac108c..82399e007c 100644 --- a/Src/Common/FwUtils/SpellEngine.cs +++ b/Src/Common/CoreImpl/SpellEngine.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -6,7 +6,7 @@ using System.Text; using SIL.FieldWorks.Common.COMInterfaces; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.CoreImpl { internal class SpellEngine : ISpellEngine, IDisposable { diff --git a/Src/Common/FwUtils/SpellingHelper.cs b/Src/Common/CoreImpl/SpellingHelper.cs similarity index 99% rename from Src/Common/FwUtils/SpellingHelper.cs rename to Src/Common/CoreImpl/SpellingHelper.cs index bfe3127791..361278570d 100644 --- a/Src/Common/FwUtils/SpellingHelper.cs +++ b/Src/Common/CoreImpl/SpellingHelper.cs @@ -1,16 +1,14 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; -using System.Windows.Forms; using SIL.FieldWorks.Common.COMInterfaces; using SIL.Utils; -using XCore; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.CoreImpl { /// /// This class manages a dictionary of (currently) Hunspell objects so that we can do spell checking. diff --git a/Src/Common/FwUtils/FwStartupException.cs b/Src/Common/CoreImpl/StartupException.cs similarity index 69% rename from Src/Common/FwUtils/FwStartupException.cs rename to Src/Common/CoreImpl/StartupException.cs index d109d8369c..3b46e2dd70 100644 --- a/Src/Common/FwUtils/FwStartupException.cs +++ b/Src/Common/CoreImpl/StartupException.cs @@ -2,7 +2,7 @@ // This software is licensed under the LGPL, version 2.1 or later // (http://www.gnu.org/licenses/lgpl-2.1.html) // -// File: FwStartupException.cs +// File: StartupException.cs // Responsibility: TE Team // // @@ -10,83 +10,83 @@ using System; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.CoreImpl { /// ---------------------------------------------------------------------------------------- /// /// Exception thrown during FieldWorks startup if something goes wrong /// /// ---------------------------------------------------------------------------------------- - public class FwStartupException : Exception + public class StartupException : Exception { /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The message. /// ------------------------------------------------------------------------------------ - public FwStartupException(string message) : this(message, null) + public StartupException(string message) : this(message, null) { } /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The message. /// The inner exception. /// ------------------------------------------------------------------------------------ - public FwStartupException(string message, Exception innerException) : + public StartupException(string message, Exception innerException) : this(message, innerException, true) { } /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The message. /// True to report this error to the user, false otherwise /// /// ------------------------------------------------------------------------------------ - public FwStartupException(string message, bool fReportToUser) : + public StartupException(string message, bool fReportToUser) : this(message, null, fReportToUser) { } /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The inner exception. /// ------------------------------------------------------------------------------------ - public FwStartupException(Exception innerException) : this(innerException, true) + public StartupException(Exception innerException) : this(innerException, true) { } /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The inner exception. /// True to report this error to the user, false otherwise /// /// ------------------------------------------------------------------------------------ - public FwStartupException(Exception innerException, bool fReportToUser) : + public StartupException(Exception innerException, bool fReportToUser) : this(null, innerException, fReportToUser) { } /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The message. /// The inner exception. /// True to report this error to the user, false otherwise /// /// ------------------------------------------------------------------------------------ - public FwStartupException(string message, Exception innerException, bool fReportToUser) : + public StartupException(string message, Exception innerException, bool fReportToUser) : base(message, innerException) { ReportToUser = fReportToUser; @@ -103,17 +103,4 @@ public bool ReportToUser private set; } } - - /// - /// Exception thrown when we try to open a project that belongs to a newer version of FieldWorks than this. - /// - public class FwNewerVersionException : FwStartupException - { - /// - /// Make one. - /// - public FwNewerVersionException(string message) : base(message) - { - } - } } diff --git a/Src/Common/FwUtils/StringSearcher.cs b/Src/Common/CoreImpl/StringSearcher.cs similarity index 57% rename from Src/Common/FwUtils/StringSearcher.cs rename to Src/Common/CoreImpl/StringSearcher.cs index 9311a3afdf..fefdb9f74e 100644 --- a/Src/Common/FwUtils/StringSearcher.cs +++ b/Src/Common/CoreImpl/StringSearcher.cs @@ -2,12 +2,10 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using Palaso.WritingSystems.Collation; -using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; using SIL.Utils; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.CoreImpl { /// /// Type of string searching. @@ -116,7 +114,8 @@ public IEnumerable GetItems(byte[] lower, byte[] upper) private readonly Dictionary, SortKeyIndex> m_indices = new Dictionary, SortKeyIndex>(); private readonly SearchType m_type; - private readonly IWritingSystemManager m_wsManager; + private readonly Func m_sortKeySelector; + private readonly Func> m_tokenizer; /// /// Initializes a new instance of the class. @@ -125,8 +124,30 @@ public IEnumerable GetItems(byte[] lower, byte[] upper) /// The writing system store. public StringSearcher(SearchType type, IWritingSystemManager wsManager) { + if (wsManager == null) + throw new ArgumentNullException("wsManager"); + m_type = type; - m_wsManager = wsManager; + m_sortKeySelector = (ws, text) => wsManager.Get(ws).Collator.GetSortKey(text).KeyData; + m_tokenizer = (ws, text) => Icu.Split(Icu.UBreakIteratorType.UBRK_WORD, wsManager.Get(ws).IcuLocale, text); + } + + /// + /// Initializes a new instance of the class. + /// + /// The type. + /// The sort key selector. + /// The text tokenizer + public StringSearcher(SearchType type, Func sortKeySelector, Func> tokenizer) + { + if (sortKeySelector == null) + throw new ArgumentNullException("sortKeySelector"); + if (type == SearchType.FullText && tokenizer == null) + throw new ArgumentNullException("tokenizer"); + + m_type = type; + m_sortKeySelector = sortKeySelector; + m_tokenizer = tokenizer; } /// @@ -136,33 +157,35 @@ public void Add(T item, int indexId, ITsString tss) { if (tss.RunCount == 1) // VERY common special case { - Add(indexId, tss.get_WritingSystemAt(0), tss.Text, item); - return; + Add(item, indexId, tss.get_WritingSystemAt(0), tss.Text); } - - foreach (Tuple wsStr in GetWsStrings(tss)) + else { - var wsId = wsStr.Item1; - var text = wsStr.Item2; - Add(indexId, wsId, text, item); + foreach (Tuple wsStr in GetWsStrings(tss)) + { + var wsId = wsStr.Item1; + var text = wsStr.Item2; + Add(item, indexId, wsId, text); + } } } - private void Add(int indexId, int wsId, string text, T item) + /// + /// Adds the specified item to an index using the specified string. + /// + public void Add(T item, int indexId, int wsId, string text) { SortKeyIndex index = GetIndex(indexId, wsId); - IWritingSystem ws = m_wsManager.Get(wsId); - ICollator collator = ws.Collator; switch (m_type) { case SearchType.Exact: case SearchType.Prefix: - index.Add(collator.GetSortKey(text).KeyData, item); + index.Add(m_sortKeySelector(wsId, text), item); break; case SearchType.FullText: - foreach (string token in Icu.Split(Icu.UBreakIteratorType.UBRK_WORD, ws.IcuLocale, text)) - index.Add(collator.GetSortKey(token).KeyData, item); + foreach (string token in m_tokenizer(wsId, text)) + index.Add(m_sortKeySelector(wsId, token), item); break; } } @@ -178,57 +201,76 @@ public IEnumerable Search(int indexId, ITsString tss) if (tss == null || string.IsNullOrEmpty(tss.Text)) return Enumerable.Empty(); - HashSet results = null; + if (tss.RunCount == 1) // VERY common special case + return Search(indexId, tss.get_WritingSystemAt(0), tss.Text); + + IEnumerable results = null; foreach (Tuple wsStr in GetWsStrings(tss)) { - SortKeyIndex index = GetIndex(indexId, wsStr.Item1); - ICollator collator = m_wsManager.Get(wsStr.Item1).Collator; - switch (m_type) - { - case SearchType.Exact: - case SearchType.Prefix: - { - byte[] sortKey = collator.GetSortKey(wsStr.Item2).KeyData; - var lower = new byte[wsStr.Item2.Length * SortKeyFactor]; - Icu.GetSortKeyBound(sortKey, Icu.UColBoundMode.UCOL_BOUND_LOWER, ref lower); - var upper = new byte[wsStr.Item2.Length * SortKeyFactor]; - Icu.GetSortKeyBound(sortKey, - m_type == SearchType.Exact - ? Icu.UColBoundMode.UCOL_BOUND_UPPER - : Icu.UColBoundMode.UCOL_BOUND_UPPER_LONG, ref upper); - IEnumerable items = index.GetItems(lower, upper); - if (results == null) - results = new HashSet(items); - else - results.IntersectWith(items); - break; - } - - case SearchType.FullText: - string locale = m_wsManager.GetStrFromWs(wsStr.Item1); - string[] tokens = Icu.Split(Icu.UBreakIteratorType.UBRK_WORD, locale, wsStr.Item2).ToArray(); - for (int i = 0; i < tokens.Length; i++) - { - byte[] sortKey = collator.GetSortKey(tokens[i]).KeyData; - var lower = new byte[tokens[i].Length*SortKeyFactor]; - Icu.GetSortKeyBound(sortKey, Icu.UColBoundMode.UCOL_BOUND_LOWER, ref lower); - var upper = new byte[tokens[i].Length*SortKeyFactor]; - Icu.GetSortKeyBound(sortKey, - i < tokens.Length - 1 - ? Icu.UColBoundMode.UCOL_BOUND_UPPER - : Icu.UColBoundMode.UCOL_BOUND_UPPER_LONG, ref upper); - IEnumerable items = index.GetItems(lower, upper); - if (results == null) - results = new HashSet(items); - else - results.IntersectWith(items); - } - break; - } + IEnumerable items = Search(indexId, wsStr.Item1, wsStr.Item2); + if (results == null) + results = items; + else + results = results.Intersect(items); } return results ?? Enumerable.Empty(); } + /// + /// Searches an index for the specified string. + /// + /// The index id. + /// The ws id. + /// The text. + /// The search results. + public IEnumerable Search(int indexId, int wsId, string text) + { + if (string.IsNullOrEmpty(text)) + return Enumerable.Empty(); + + SortKeyIndex index = GetIndex(indexId, wsId); + switch (m_type) + { + case SearchType.Exact: + case SearchType.Prefix: + { + byte[] sortKey = m_sortKeySelector(wsId, text); + var lower = new byte[text.Length * SortKeyFactor]; + Icu.GetSortKeyBound(sortKey, Icu.UColBoundMode.UCOL_BOUND_LOWER, ref lower); + var upper = new byte[text.Length * SortKeyFactor]; + Icu.GetSortKeyBound(sortKey, + m_type == SearchType.Exact + ? Icu.UColBoundMode.UCOL_BOUND_UPPER + : Icu.UColBoundMode.UCOL_BOUND_UPPER_LONG, ref upper); + + return index.GetItems(lower, upper); + } + + case SearchType.FullText: + IEnumerable results = null; + string[] tokens = m_tokenizer(wsId, text).ToArray(); + for (int i = 0; i < tokens.Length; i++) + { + byte[] sortKey = m_sortKeySelector(wsId, tokens[i]); + var lower = new byte[tokens[i].Length*SortKeyFactor]; + Icu.GetSortKeyBound(sortKey, Icu.UColBoundMode.UCOL_BOUND_LOWER, ref lower); + var upper = new byte[tokens[i].Length*SortKeyFactor]; + Icu.GetSortKeyBound(sortKey, + i < tokens.Length - 1 + ? Icu.UColBoundMode.UCOL_BOUND_UPPER + : Icu.UColBoundMode.UCOL_BOUND_UPPER_LONG, ref upper); + IEnumerable items = index.GetItems(lower, upper); + if (results == null) + results = items; + else + results = results.Intersect(items); + } + return results; + } + + return null; + } + /// /// Clears all of the indices. /// diff --git a/Src/Common/FwUtils/FwVersionInfoProvider.cs b/Src/Common/CoreImpl/VersionInfoProvider.cs similarity index 87% rename from Src/Common/FwUtils/FwVersionInfoProvider.cs rename to Src/Common/CoreImpl/VersionInfoProvider.cs index ab2fedf0ae..c3f58bb6c7 100644 --- a/Src/Common/FwUtils/FwVersionInfoProvider.cs +++ b/Src/Common/CoreImpl/VersionInfoProvider.cs @@ -1,8 +1,8 @@ -// Copyright (c) 2010-2013 SIL International +// Copyright (c) 2010-2013 SIL International // This software is licensed under the LGPL, version 2.1 or later // (http://www.gnu.org/licenses/lgpl-2.1.html) // -// File: FwVersionInfoProvider.cs +// File: VersionInfoProvider.cs // Responsibility: FW Team using System; @@ -10,14 +10,14 @@ using System.Reflection; using System.Windows.Forms; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.CoreImpl { /// ---------------------------------------------------------------------------------------- /// - /// Class for getting version information out of a FieldWorks assembly + /// Class for getting version information out of an assembly /// /// ---------------------------------------------------------------------------------------- - public class FwVersionInfoProvider + public class VersionInfoProvider { /// Default copyright string if no assembly could be found public const string kDefaultCopyrightString = "Copyright (c) 2002-2013 SIL International"; @@ -30,13 +30,13 @@ public class FwVersionInfoProvider /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The assembly used to get the information. /// if set to false, any SIL-identifying information /// will be hidden. /// ------------------------------------------------------------------------------------ - public FwVersionInfoProvider(Assembly assembly, bool fShowSILInfo) + public VersionInfoProvider(Assembly assembly, bool fShowSILInfo) { if (assembly == null) throw new ArgumentNullException("assembly"); @@ -122,9 +122,9 @@ public string ApplicationVersion } } #if DEBUG - return string.Format(FwUtilsStrings.kstidAppVersionFmt, appVersion, productDate, "(Debug version)"); + return string.Format(CoreImplStrings.kstidAppVersionFmt, appVersion, productDate, "(Debug version)"); #else - return string.Format(FwUtilsStrings.kstidAppVersionFmt, appVersion, productDate, ""); + return string.Format(CoreImplStrings.kstidAppVersionFmt, appVersion, productDate, ""); #endif } } @@ -134,17 +134,17 @@ public string ApplicationVersion /// Gets the version of FieldWorks. /// /// ------------------------------------------------------------------------------------ - public string FieldWorksVersion + public string MajorVersion { get { // Set the Fieldworks version text object[] attributes = m_assembly.GetCustomAttributes( typeof(AssemblyInformationalVersionAttribute), false); - string fwVersion = (attributes != null && attributes.Length > 0) ? + string version = (attributes != null && attributes.Length > 0) ? ((AssemblyInformationalVersionAttribute)attributes[0]).InformationalVersion : Application.ProductVersion; - return string.Format(FwUtilsStrings.kstidFwVersionFmt, fwVersion); + return string.Format(CoreImplStrings.kstidMajorVersionFmt, version); } } @@ -174,7 +174,7 @@ public string CopyrightString copyRight = kDefaultCopyrightString; } } - return copyRight.Replace("(c)", "©"); + return copyRight.Replace("(c)", ""); } } @@ -185,7 +185,7 @@ public string LicenseString { get { - return FwUtilsStrings.kstidLicense; + return CoreImplStrings.kstidLicense; } } @@ -194,7 +194,7 @@ public string LicenseURL { get { - return FwUtilsStrings.kstidLicenseURL; + return CoreImplStrings.kstidLicenseURL; } } } diff --git a/Src/Common/CoreImpl/gendarme-CoreImpl.ignore b/Src/Common/CoreImpl/gendarme-CoreImpl.ignore index 7b653475d4..ef6495d129 100644 --- a/Src/Common/CoreImpl/gendarme-CoreImpl.ignore +++ b/Src/Common/CoreImpl/gendarme-CoreImpl.ignore @@ -7,3 +7,5 @@ R: Gendarme.Rules.Correctness.EnsureLocalDisposalRule M: System.Collections.IEnumerator SIL.CoreImpl.KernelExtensions/*::System.Collections.IEnumerable.GetEnumerator() M: System.Collections.IEnumerator SIL.CoreImpl.KernelExtensions/*::System.Collections.IEnumerable.GetEnumerator() M: System.Collections.IEnumerator SIL.CoreImpl.TsRunPart/*::System.Collections.IEnumerable.GetEnumerator() +M: System.Collections.IEnumerator SIL.CoreImpl.StringSearcher`1/SortKeyIndex/*::System.Collections.IEnumerable.GetEnumerator() +M: System.Collections.IEnumerator SIL.CoreImpl.StringSearcher`1/*::System.Collections.IEnumerable.GetEnumerator() diff --git a/Src/Common/FieldWorks/FieldWorks.cs b/Src/Common/FieldWorks/FieldWorks.cs index d9a09cba07..8b54fe2054 100644 --- a/Src/Common/FieldWorks/FieldWorks.cs +++ b/Src/Common/FieldWorks/FieldWorks.cs @@ -32,16 +32,19 @@ using SIL.FieldWorks.Common.Framework; using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.Common.RootSites; +using SIL.FieldWorks.Common.ScriptureUtils; using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.FDO.DomainServices.BackupRestore; +using SIL.FieldWorks.FDO.DomainServices.DataMigration; using SIL.FieldWorks.FDO.Infrastructure; +using SIL.FieldWorks.FdoUi; using SIL.FieldWorks.FwCoreDlgs; using SIL.FieldWorks.FwCoreDlgs.BackupRestore; using SIL.FieldWorks.PaObjects; using SIL.FieldWorks.Resources; -using SIL.FieldWorks.LexicalProvider; using SIL.Utils; +using SIL.Utils.FileDialog; using XCore; using SIL.CoreImpl; using ConfigurationException = SIL.Utils.ConfigurationException; @@ -53,6 +56,7 @@ using Gecko; #else using NetSparkle; + #endif [assembly:SuppressMessage("Gendarme.Rules.Portability", "ExitCodeIsLimitedOnUnixRule", @@ -122,6 +126,7 @@ private enum StartupStatus // true if we have no previous reporting settings, typically the first time a version of FLEx that // supports usage reporting has been run. private static bool s_noPreviousReportingSettings; + private static IFdoUI s_ui; #endregion #region Main Method and Initialization Methods @@ -232,6 +237,8 @@ static int Main(string[] rgArgs) s_noUserInterface = appArgs.NoUserInterface; s_appServerMode = appArgs.AppServerMode; + s_ui = new FwFdoUI(GetHelpTopicProvider(appArgs.AppAbbrev), s_threadHelper); + if (Settings.Default.CallUpgrade) { Settings.Default.Upgrade(); @@ -275,6 +282,10 @@ static int Main(string[] rgArgs) // from HKCU/Software/SIL/FieldWorks/7.0 -> FieldWorks/8. FwRegistryHelper.UpgradeUserSettingsIfNeeded(); + // initialize client-server services to use Db4O backend + ClientServerServices.SetCurrentToDb4OBackend(s_ui, FwDirectoryFinder.FdoDirectories, + () => FwDirectoryFinder.ProjectsDirectory == FwDirectoryFinder.ProjectsDirectoryLocalMachine); + if (appArgs.ShowHelp) { ShowCommandLineHelp(); @@ -328,9 +339,6 @@ static int Main(string[] rgArgs) else if (!LaunchApplicationFromCommandLine(appArgs)) return 0; // Didn't launch, but probably not a serious error - // Create a listener for this project for applications using FLEx as a LexicalProvider. - LexicalProviderManager.StartLexicalServiceProvider(s_projectId, s_cache); - #if __MonoCS__ UglyHackForXkbIndicator(); #endif @@ -411,6 +419,9 @@ private static bool LaunchApplicationFromCommandLine(FwAppArgs appArgs) // Get the project the user wants to open and attempt to launch it. ProjectId projectId = DetermineProject(appArgs); + if (projectId != null && IsSharedXmlBackendNeeded(projectId)) + projectId.Type = FDOBackendProviderType.kSharedXML; + // s_projectId can be non-null if the user decided to restore a project from // the Welcome to Fieldworks dialog. (FWR-2146) if (s_projectId == null && !LaunchProject(appArgs, ref projectId)) @@ -430,6 +441,11 @@ private static bool LaunchApplicationFromCommandLine(FwAppArgs appArgs) return true; } + private static bool IsSharedXmlBackendNeeded(ProjectId projectId) + { + return projectId.Type == FDOBackendProviderType.kXML && ParatextHelper.GetAssociatedProject(projectId) != null; + } + /// ------------------------------------------------------------------------------------ /// /// Creates the application requested on the command line. @@ -468,7 +484,7 @@ private static void LaunchRestoreFromCommandLine(FwAppArgs appArgs) // There is no need to re-show the dialog since the user has already chosen // the options and confirmed to overwrite any existing database. Logger.WriteEvent("Restoring project: " + appArgs.BackupFile); - RestoreProjectSettings restoreSettings = new RestoreProjectSettings(appArgs.Database, + RestoreProjectSettings restoreSettings = new RestoreProjectSettings(FwDirectoryFinder.ProjectsDirectory, appArgs.Database, appArgs.BackupFile, appArgs.RestoreOptions); RestoreCurrentProject(new FwRestoreProjectSettings(appArgs.AppAbbrev, restoreSettings), null); } @@ -792,15 +808,62 @@ private static FdoCache CreateCache(ProjectId projectId) WriteSplashScreen(string.Format(Properties.Resources.kstidLoadingProject, projectId.UiName)); Form owner = s_splashScreen != null ? s_splashScreen.Form : Form.ActiveForm; - using (var progressDlg = new ProgressDialogWithTask(owner, s_threadHelper)) + using (var progressDlg = new ProgressDialogWithTask(owner)) { - FdoCache cache = FdoCache.CreateCacheFromExistingData(projectId, s_sWsUser, progressDlg); - cache.ProjectNameChanged += ProjectNameChanged; - cache.ServiceLocator.GetInstance().OnSave += FieldWorks_OnSave; + FdoCache cache = FdoCache.CreateCacheFromExistingData(projectId, s_sWsUser, s_ui, FwDirectoryFinder.FdoDirectories, progressDlg); + EnsureValidLinkedFilesFolder(cache); + cache.ProjectNameChanged += ProjectNameChanged; + cache.ServiceLocator.GetInstance().OnSave += FieldWorks_OnSave; + + SetupErrorPropertiesNeedingCache(cache); + return cache; + } + } - SetupErrorPropertiesNeedingCache(cache); - return cache; + /// + /// Ensure a valid folder for LangProject.LinkedFilesRootDir. When moving projects + /// between systems, the stored value may become hopelessly invalid. See FWNX-1005 + /// for an example of the havoc than can ensue. + /// + /// This method gets called when we open the FDO cache. + private static void EnsureValidLinkedFilesFolder(FdoCache cache) + { + if (MiscUtils.RunningTests) + return; + + var linkedFilesFolder = cache.LangProject.LinkedFilesRootDir; + var defaultFolder = FdoFileHelper.GetDefaultLinkedFilesDir(cache.ProjectId.ProjectFolder); + EnsureValidLinkedFilesFolderCore(linkedFilesFolder, defaultFolder); + + if (!Directory.Exists(linkedFilesFolder)) + { + if (!Directory.Exists(defaultFolder)) + defaultFolder = cache.ProjectId.ProjectFolder; + MessageBox.Show(String.Format(Properties.Resources.ksInvalidLinkedFilesFolder, linkedFilesFolder), Properties.Resources.ksErrorCaption); + while (!Directory.Exists(linkedFilesFolder)) + { + using (var folderBrowserDlg = new FolderBrowserDialogAdapter()) + { + folderBrowserDlg.Description = Properties.Resources.ksLinkedFilesFolder; + folderBrowserDlg.RootFolder = Environment.SpecialFolder.Desktop; + folderBrowserDlg.SelectedPath = defaultFolder; + if (folderBrowserDlg.ShowDialog() == DialogResult.OK) + linkedFilesFolder = folderBrowserDlg.SelectedPath; + } + } + NonUndoableUnitOfWorkHelper.DoUsingNewOrCurrentUOW(cache.ActionHandlerAccessor, () => + { cache.LangProject.LinkedFilesRootDir = linkedFilesFolder; }); + } } + + /// + /// Just make the directory if it's the default. + /// See FWNX-1092, LT-14491. + /// + internal static void EnsureValidLinkedFilesFolderCore(string linkedFilesFolder, string defaultLinkedFilesFolder) + { + if (linkedFilesFolder == defaultLinkedFilesFolder) + FileUtils.EnsureDirectoryExists(defaultLinkedFilesFolder); } /// ------------------------------------------------------------------------------------ @@ -1187,7 +1250,7 @@ private static ProjectId DetermineProject(FwAppArgs args) // If we try to use command-line arguments and it fails, we will use the Welcome dialog // to help the user figure out what to do next. var projId = new ProjectId(args.DatabaseType, args.Database, args.Server); - FwStartupException projectOpenError; + StartupException projectOpenError; if (TryCommandLineOption(projId, out projectOpenError)) return projId; @@ -1210,7 +1273,7 @@ private static ProjectId DetermineProject(FwAppArgs args) else if (previousStartupStatus == StartupStatus.Failed && !string.IsNullOrEmpty(latestProject)) { // The previous project failed to open, so notify the user. - projectOpenError = new FwStartupException(String.Format( + projectOpenError = new StartupException(String.Format( Properties.Resources.kstidUnableToOpenLastProject, app.ApplicationName, latestProject)); } @@ -1244,10 +1307,10 @@ private static ProjectId GetBestGuessProjectId(string latestProject, string late if (!File.Exists(projId.Path)) { string altProject; - if (Path.GetExtension(latestProject) == FwFileExtensions.ksFwDataXmlFileExtension) - altProject = Path.ChangeExtension(latestProject, FwFileExtensions.ksFwDataDb4oFileExtension); + if (Path.GetExtension(latestProject) == FdoFileHelper.ksFwDataXmlFileExtension) + altProject = Path.ChangeExtension(latestProject, FdoFileHelper.ksFwDataDb4oFileExtension); else - altProject = Path.ChangeExtension(latestProject, FwFileExtensions.ksFwDataXmlFileExtension); + altProject = Path.ChangeExtension(latestProject, FdoFileHelper.ksFwDataXmlFileExtension); projId = new ProjectId(altProject, latestServer); } } @@ -1262,15 +1325,15 @@ private static ProjectId GetBestGuessProjectId(string latestProject, string late /// /// /// - private static bool TryCommandLineOption(ProjectId projId, out FwStartupException exception) + private static bool TryCommandLineOption(ProjectId projId, out StartupException exception) { exception = null; if (string.IsNullOrEmpty(projId.Name)) return false; var ex = projId.GetExceptionIfInvalid(); - if (ex is FwStartupException) + if (ex is StartupException) { - exception = (FwStartupException) ex; + exception = (StartupException) ex; return false; // Invalid command-line arguments supplied. } if (ex == null) @@ -1321,7 +1384,7 @@ private static bool LaunchProject(FwAppArgs args, ref ProjectId projectId) { return InitializeFirstApp(app, projectId); } - catch (FwStartupException e) + catch (StartupException e) { if (s_cache != null) { @@ -1525,7 +1588,7 @@ private static void ProjectNameChanged(FdoCache sender) /// ------------------------------------------------------------------------------------ [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", Justification="startingApp is a reference")] - private static ProjectId ShowWelcomeDialog(FwAppArgs args, FwApp startingApp, ProjectId lastProjectId, FwStartupException exception) + private static ProjectId ShowWelcomeDialog(FwAppArgs args, FwApp startingApp, ProjectId lastProjectId, StartupException exception) { CloseSplashScreen(); @@ -1614,7 +1677,7 @@ private static ProjectId ShowWelcomeDialog(FwAppArgs args, FwApp startingApp, Pr if (projectToTry != null) projectToTry.AssertValid(); } - catch (FwStartupException e) + catch (StartupException e) { exception = e; } @@ -1727,7 +1790,16 @@ internal static ProjectId ChooseLangProject(Form dialogOwner, IHelpTopicProvider PropertyTable.SettingsGroup.LocalSettings); } } - return dlg.DialogResult != DialogResult.OK ? null : new ProjectId(dlg.Project, dlg.Server); + + if (dlg.DialogResult == DialogResult.OK) + { + var projId = new ProjectId(dlg.Project, dlg.Server); + if (IsSharedXmlBackendNeeded(projId)) + projId.Type = FDOBackendProviderType.kSharedXML; + return projId; + } + + return null; } } @@ -1835,7 +1907,7 @@ internal static string BackupProject(Form dialogOwner, FwApp fwApp) internal static void RestoreProject(Form dialogOwner, string backupFile) { BackupFileSettings settings = null; - if (!ProjectRestoreService.HandleRestoreFileErrors(null, FwUtils.ksSuiteName, backupFile, + if (!RestoreProjectDlg.HandleRestoreFileErrors(null, FwUtils.ksSuiteName, backupFile, () => settings = new BackupFileSettings(backupFile, true))) { return; @@ -1913,7 +1985,7 @@ internal static void FileProjectSharingLocation(Form dialogOwner, FwApp fwApp) return; string projectPath = fwApp.Cache.ProjectId.Path; string parentDirectory = Path.GetDirectoryName(fwApp.Cache.ProjectId.ProjectFolder); - string projectsDirectory = DirectoryFinder.ProjectsDirectory; + string projectsDirectory = FwDirectoryFinder.ProjectsDirectory; if (!MiscUtils.IsUnix) { parentDirectory = parentDirectory.ToLowerInvariant(); @@ -1927,7 +1999,7 @@ internal static void FileProjectSharingLocation(Form dialogOwner, FwApp fwApp) if (!ClientServerServices.Current.Local.ShareMyProjects) UpdateProjectsLocation(dlg.ProjectsFolder, fwApp, projectPath); if (!MiscUtils.IsUnix) - projectsDirectory = DirectoryFinder.ProjectsDirectory.ToLowerInvariant(); + projectsDirectory = FwDirectoryFinder.ProjectsDirectory.ToLowerInvariant(); if (UpdateProjectsSharing(true, dialogOwner, fwApp, projectPath, parentDirectory, projectsDirectory)) { using (var dlgShare = new ShareProjectsFolderDlg()) @@ -1973,7 +2045,7 @@ private static bool UpdateProjectsSharing(bool fShareProjects, Form dialogOwner { // We aren't going to convert this one, so no complication to just switching it. // Both these setters check and do nothing if not changed. - using (var progressDlg = new ProgressDialogWithTask(null, s_threadHelper)) + using (var progressDlg = new ProgressDialogWithTask(s_threadHelper)) { return ClientServerServices.Current.Local.SetProjectSharing(fShareProjects, progressDlg); } @@ -1982,7 +2054,7 @@ private static bool UpdateProjectsSharing(bool fShareProjects, Form dialogOwner bool fSuccess = false; ExecuteWithAllFwProcessesShutDown(GetCommandLineAbbrevForAppName(fwApp.ApplicationName), () => { - using (var progressDlg = new ProgressDialogWithTask(null, s_threadHelper)) + using (var progressDlg = new ProgressDialogWithTask(s_threadHelper)) { fSuccess = ClientServerServices.Current.Local.SetProjectSharing(fShareProjects, progressDlg); } @@ -2002,7 +2074,7 @@ private static bool UpdateProjectsSharing(bool fShareProjects, Form dialogOwner private static void UpdateProjectsLocation(string newFolderForProjects, FwApp fwApp, string projectPath) { - if (newFolderForProjects == null || newFolderForProjects == DirectoryFinder.ProjectsDirectory || + if (newFolderForProjects == null || newFolderForProjects == FwDirectoryFinder.ProjectsDirectory || !FileUtils.EnsureDirectoryExists(newFolderForProjects)) return; @@ -2011,10 +2083,10 @@ private static void UpdateProjectsLocation(string newFolderForProjects, FwApp fw { fMoveFiles = dlg.ShowDialog(fwApp.ActiveMainWindow) == DialogResult.Yes; } - string oldFolderForProjects = DirectoryFinder.ProjectsDirectory; + string oldFolderForProjects = FwDirectoryFinder.ProjectsDirectory; try { - DirectoryFinder.ProjectsDirectory = newFolderForProjects; + FwDirectoryFinder.ProjectsDirectory = newFolderForProjects; } catch (Exception) { @@ -2130,7 +2202,7 @@ private static ProjectId MoveProjectFolders(string oldFolderForProjects, string { List rgErrors = new List(); bool fCopy = MustCopyFoldersAndFiles(oldFolderForProjects, newFolderForProjects); - using (ProgressDialogWithTask progressDlg = new ProgressDialogWithTask(null, s_threadHelper)) + using (ProgressDialogWithTask progressDlg = new ProgressDialogWithTask(s_threadHelper)) { string[] subDirs = Directory.GetDirectories(oldFolderForProjects); progressDlg.Maximum = subDirs.Length; @@ -2219,7 +2291,7 @@ private static ProjectId MoveProjectFolders(string oldFolderForProjects, string { if (projectPath.StartsWith(oldFolderForProjects)) { - // This is perhaps a temporary workaround. On Linux, DirectoryFinder.ProjectsDirectory + // This is perhaps a temporary workaround. On Linux, FwDirectoryFinder.ProjectsDirectory // isn't returning the updated value, but rather the original value. This seems to // last for the duration of the program, but if you exit and restart the program, it // gets the correct (updated) value!? @@ -2250,12 +2322,12 @@ private static bool IsFieldWorksProjectFolder(string projectFolder) { var projectName = Path.GetFileName(projectFolder); // If it contains a matching fwdata file it is a project folder. - var projectFileName = Path.ChangeExtension(Path.Combine(projectFolder, projectName), FwFileExtensions.ksFwDataXmlFileExtension); + var projectFileName = Path.ChangeExtension(Path.Combine(projectFolder, projectName), FdoFileHelper.ksFwDataXmlFileExtension); if(File.Exists(projectFileName)) return true; // Just in case some project didn't get converted back to fwdata before we ask this question, // allow folders containing fwdb files, too. - projectFileName = Path.ChangeExtension(projectFileName, FwFileExtensions.ksFwDataDb4oFileExtension); + projectFileName = Path.ChangeExtension(projectFileName, FdoFileHelper.ksFwDataDb4oFileExtension); if (File.Exists(projectFileName)) return true; return false; @@ -2263,7 +2335,7 @@ private static bool IsFieldWorksProjectFolder(string projectFolder) private static bool IsFieldWorksSettingsFolder(string projectFolder) { - var settingsDir = Path.Combine(projectFolder, DirectoryFinder.ksConfigurationSettingsDir); + var settingsDir = Path.Combine(projectFolder, FdoFileHelper.ksConfigurationSettingsDir); if (Directory.Exists(settingsDir)) return true; return false; @@ -2325,7 +2397,7 @@ private static bool MigrateProjectsTo70() // TODO (TimS): We should probably put FW into single process mode for these // migrations. It would probably be very bad to have two processes attempting to // do migrations at the same time. - ProcessStartInfo info = new ProcessStartInfo(DirectoryFinder.MigrateSqlDbsExe); + ProcessStartInfo info = new ProcessStartInfo(FwDirectoryFinder.MigrateSqlDbsExe); info.UseShellExecute = false; using (Process proc = Process.Start(info)) { @@ -2447,10 +2519,9 @@ private static void RestoreCurrentProject(FwRestoreProjectSettings restoreSettin retry = false; try { - ProjectRestoreService restoreService = new ProjectRestoreService(restoreSettings.Settings, - GetHelpTopicProvider(restoreSettings.FwAppCommandLineAbbrev)); + var restoreService = new ProjectRestoreService(restoreSettings.Settings, s_ui, FwDirectoryFinder.ConverterConsoleExe, FwDirectoryFinder.DbExe); Logger.WriteEvent("Restoring from " + restoreSettings.Settings.Backup.File); - if (ProjectRestoreService.HandleRestoreFileErrors(null, ResourceHelper.GetResourceString("ksRestoreFailed"), + if (RestoreProjectDlg.HandleRestoreFileErrors(null, ResourceHelper.GetResourceString("ksRestoreFailed"), restoreSettings.Settings.Backup.File, () => DoRestore(restoreService))) { s_LinkDirChangedTo = restoreService.LinkDirChangedTo; @@ -2458,6 +2529,10 @@ private static void RestoreCurrentProject(FwRestoreProjectSettings restoreSettin new ProjectId(ClientServerServices.Current.Local.IdForLocalProject(restoreSettings.Settings.ProjectName), null); } } + catch (CannotConvertException e) + { + MessageBoxUtils.Show(e.Message, ResourceHelper.GetResourceString("ksRestoreFailed")); + } catch (MissingOldFwException e) { using (var dlg = new MissingOldFieldWorksDlg(restoreSettings.Settings, @@ -2468,6 +2543,7 @@ private static void RestoreCurrentProject(FwRestoreProjectSettings restoreSettin } catch (FailedFwRestoreException e) { + MessageBoxUtils.Show(Properties.Resources.ksRestoringOldFwBackupFailed, Properties.Resources.ksFailed); } } while (retry); @@ -2484,7 +2560,7 @@ private static void RestoreCurrentProject(FwRestoreProjectSettings restoreSettin /// ------------------------------------------------------------------------------------ private static void DoRestore(ProjectRestoreService restoreService) { - using (ProgressDialogWithTask progressDlg = new ProgressDialogWithTask(null, s_threadHelper)) + using (var progressDlg = new ProgressDialogWithTask(s_threadHelper)) restoreService.RestoreProject(progressDlg); } @@ -2505,20 +2581,26 @@ private static void DoRestore(ProjectRestoreService restoreService) private static bool BackupProjectForRestore(FwRestoreProjectSettings restoreSettings, FdoCache existingCache, Form dialogOwner) { - using (var progressDlg = new ProgressDialogWithTask(dialogOwner, s_threadHelper)) + using (var progressDlg = new ProgressDialogWithTask(dialogOwner)) { FdoCache cache = existingCache ?? FdoCache.CreateCacheFromExistingData( new ProjectId(restoreSettings.Settings.FullProjectPath, null), - s_sWsUser, progressDlg); + s_sWsUser, s_ui, FwDirectoryFinder.FdoDirectories, progressDlg); try { - BackupProjectSettings settings = new BackupProjectSettings(cache, restoreSettings.Settings); - settings.DestinationFolder = DirectoryFinder.DefaultBackupDirectory; + BackupProjectSettings settings = new BackupProjectSettings(cache, restoreSettings.Settings, FwDirectoryFinder.DefaultBackupDirectory); + settings.DestinationFolder = FwDirectoryFinder.DefaultBackupDirectory; settings.AppAbbrev = restoreSettings.FwAppCommandLineAbbrev; ProjectBackupService backupService = new ProjectBackupService(cache, settings); - backupService.BackupProject(progressDlg); + string backupFile; + if (!backupService.BackupProject(progressDlg, out backupFile)) + { + string msg = string.Format(FwCoreDlgs.FwCoreDlgs.ksCouldNotBackupSomeFiles, backupService.FailedFiles.ToString(", ", Path.GetFileName)); + if (MessageBox.Show(msg, FwCoreDlgs.FwCoreDlgs.ksWarning, MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes) + File.Delete(backupFile); + } } catch (FwBackupException e) { @@ -2681,7 +2763,7 @@ private static void CheckForMovingExternalLinkDirectory(FwApp app) if (oldDir == null) { // e.g. "C:\\ProgramData\\SIL\\FieldWorks" - oldDir = DirectoryFinder.CommonAppDataFolder("SIL/FieldWorks"); + oldDir = DirectoryFinder.CommonAppDataFolder("FieldWorks"); } oldDir = oldDir.TrimEnd(new [] {Path.PathSeparator}); var newDir = app.Cache.LangProject.LinkedFilesRootDir; @@ -2725,7 +2807,7 @@ private static void MoveExternalLinkDirectoryAndFiles(FwApp app) var sLinkedFilesRootDir = app.Cache.LangProject.LinkedFilesRootDir; NonUndoableUnitOfWorkHelper.Do(app.Cache.ActionHandlerAccessor, () => { - app.Cache.LangProject.LinkedFilesRootDir = DirectoryFinder.GetDefaultLinkedFilesDir( + app.Cache.LangProject.LinkedFilesRootDir = FdoFileHelper.GetDefaultLinkedFilesDir( app.Cache.ProjectId.ProjectFolder); }); app.UpdateExternalLinks(sLinkedFilesRootDir); @@ -2798,7 +2880,7 @@ internal static bool CreateAndInitNewMainWindow(FwApp app, bool fNewCache, Form // so just record it now as the active one. s_activeMainWnd = (IFwMainWnd)fwMainWindow; } - catch (FwStartupException ex) + catch (StartupException ex) { // REVIEW: Can this actually happen when just creating a new main window? CloseSplashScreen(); @@ -2877,7 +2959,7 @@ internal static void KickOffAppFromOtherProcess(FwAppArgs args) if (s_appServerMode) { // Make sure the cache is initialized for the application. - using (ProgressDialogWithTask dlg = new ProgressDialogWithTask(null, s_threadHelper)) + using (ProgressDialogWithTask dlg = new ProgressDialogWithTask(s_threadHelper)) InitializeApp(app, dlg); return; } @@ -2905,7 +2987,7 @@ internal static void KickOffAppFromOtherProcess(FwAppArgs args) else { // Make sure the cache is initialized for the application - using (ProgressDialogWithTask dlg = new ProgressDialogWithTask(otherApp.ActiveMainWindow, s_threadHelper)) + using (var dlg = new ProgressDialogWithTask(otherApp.ActiveMainWindow)) InitializeApp(app, dlg); } }); @@ -2933,7 +3015,7 @@ private static FwApp GetOrCreateApplication(FwAppArgs args) { if (s_teApp == null) { - s_teApp = (FwApp)DynamicLoader.CreateObject(DirectoryFinder.TeDll, + s_teApp = (FwApp)DynamicLoader.CreateObject(FwDirectoryFinder.TeDll, FwUtils.ksFullTeAppObjectName, s_fwManager, GetHelpTopicProvider(appAbbrev), args); s_teAppKey = s_teApp.SettingsKey; } @@ -2946,7 +3028,7 @@ private static FwApp GetOrCreateApplication(FwAppArgs args) { if (s_flexApp == null) { - s_flexApp = (FwApp)DynamicLoader.CreateObject(DirectoryFinder.FlexDll, + s_flexApp = (FwApp)DynamicLoader.CreateObject(FwDirectoryFinder.FlexDll, FwUtils.ksFullFlexAppObjectName, s_fwManager, GetHelpTopicProvider(appAbbrev), args); s_flexAppKey = s_flexApp.SettingsKey; } @@ -3032,7 +3114,7 @@ private static bool InitializeFirstApp(FwApp app, ProjectId projectId) sparkle.AboutToExitForInstallerRun += delegate(object sender, CancelEventArgs args) { CloseAllMainWindows(); - if(app.ActiveMainWindow != null) + if (app.ActiveMainWindow != null) { args.Cancel = true; } @@ -3043,6 +3125,21 @@ private static bool InitializeFirstApp(FwApp app, ProjectId projectId) return true; } } + catch (UnauthorizedAccessException uae) + { + if (MiscUtils.IsUnix) + { + // Tell Mono user he/she needs to logout and log back in + MessageBox.Show(ResourceHelper.GetResourceString("ksNeedToJoinFwGroup")); + } + throw; + } + catch (FdoDataMigrationForbiddenException) + { + // tell the user to close all other applications using this project + MessageBox.Show(ResourceHelper.GetResourceString("kstidDataMigrationProhibitedText"), + ResourceHelper.GetResourceString("kstidDataMigrationProhibitedCaption"), MessageBoxButtons.OK, MessageBoxIcon.Error); + } finally { CloseSplashScreen(); @@ -3060,7 +3157,7 @@ private static bool InitializeFirstApp(FwApp app, ProjectId projectId) /// The progress dialog. /// True if the application was started successfully, false otherwise /// ------------------------------------------------------------------------------------ - private static bool InitializeApp(FwApp app, IProgress progressDlg) + private static bool InitializeApp(FwApp app, IThreadedProgress progressDlg) { using (new DataUpdateMonitor(null, "Application Initialization")) app.DoApplicationInitialization(progressDlg); @@ -3074,13 +3171,13 @@ private static bool InitializeApp(FwApp app, IProgress progressDlg) try { if (!app.InitCacheForApp(progressDlg)) - throw new FwStartupException(Properties.Resources.kstidCacheInitFailure); + throw new StartupException(Properties.Resources.kstidCacheInitFailure); } catch (Exception e) { - if (e is FwStartupException) + if (e is StartupException) throw; - throw new FwStartupException(Properties.Resources.kstidCacheInitFailure, e, true); + throw new StartupException(Properties.Resources.kstidCacheInitFailure, e, true); } undoHelper.RollBack = false; } @@ -3090,11 +3187,11 @@ private static bool InitializeApp(FwApp app, IProgress progressDlg) if (progressDlg != null) { progressDlg.Message = String.Format(Properties.Resources.kstidSaving, s_cache.ProjectId.UiName); - progressDlg.ProgressBarStyle = ProgressBarStyle.Marquee; + progressDlg.IsIndeterminate = true; } s_cache.ServiceLocator.GetInstance().Save(); if (progressDlg != null) - progressDlg.ProgressBarStyle = ProgressBarStyle.Continuous; + progressDlg.IsIndeterminate = false; } return CreateAndInitNewMainWindow(app, true, null, false); @@ -3193,7 +3290,7 @@ private static string GetDefaultApp(FwAppArgs args) if (!Directory.Exists(projectFolder)) return FwUtils.ksFlexAbbrev; // got to do something - var settingsFolder = Path.Combine(projectFolder, DirectoryFinder.ksConfigurationSettingsDir); + var settingsFolder = Path.Combine(projectFolder, FdoFileHelper.ksConfigurationSettingsDir); if (!Directory.Exists(settingsFolder)) return FwUtils.ksFlexAbbrev; // no settings at all, take the default. @@ -3217,7 +3314,7 @@ private static void RecordLastAppForProject() if (s_flexApp != null && s_teApp != null) return; // this isn't the last one to shut down, not time to record. - var settingsFolder = Path.Combine(Cache.ProjectId.ProjectFolder, DirectoryFinder.ksConfigurationSettingsDir); + var settingsFolder = Path.Combine(Cache.ProjectId.ProjectFolder, FdoFileHelper.ksConfigurationSettingsDir); var teMarkerPath = Path.Combine(settingsFolder, ksTeOpenMarkerFileName); try { @@ -3480,7 +3577,6 @@ private static RemoteRequest CreateRequestor(int port, string requestType) private static void StaticDispose() { s_appServerMode = false; // Make sure the cache can be cleaned up - LexicalProviderManager.StaticDispose(); // Must be done before disposing the cache if (s_serviceChannel != null) { ChannelServices.UnregisterChannel(s_serviceChannel); @@ -3536,10 +3632,10 @@ internal static IHelpTopicProvider GetHelpTopicProvider(string appAbbrev) if ((appAbbrev.Equals(FwUtils.ksTeAbbrev, StringComparison.InvariantCultureIgnoreCase) && FwUtils.IsTEInstalled) || !FwUtils.IsFlexInstalled) { - return s_teApp ?? (IHelpTopicProvider)DynamicLoader.CreateObject(DirectoryFinder.TeDll, + return s_teApp ?? (IHelpTopicProvider)DynamicLoader.CreateObject(FwDirectoryFinder.TeDll, "SIL.FieldWorks.TE.TeHelpTopicProvider"); } - return s_flexApp ?? (IHelpTopicProvider)DynamicLoader.CreateObject(DirectoryFinder.FlexDll, + return s_flexApp ?? (IHelpTopicProvider)DynamicLoader.CreateObject(FwDirectoryFinder.FlexDll, "SIL.FieldWorks.XWorks.LexText.FlexHelpTopicProvider"); } @@ -3844,12 +3940,12 @@ private static void ExitCleanly() { DataUpdateMonitor.ClearSemaphore(); - using (var progressDlg = new ProgressDialogWithTask(null, s_threadHelper)) + using (var progressDlg = new ProgressDialogWithTask(s_threadHelper)) { progressDlg.Title = string.Format(ResourceHelper.GetResourceString("kstidShutdownCaption"), s_cache.ProjectId.UiName); progressDlg.AllowCancel = false; - progressDlg.ProgressBarStyle = ProgressBarStyle.Marquee; + progressDlg.IsIndeterminate = true; var stackMgr = s_cache.ServiceLocator.GetInstance(); if (stackMgr.HasUnsavedChanges) progressDlg.RunTask(true, CommitAndDisposeCache); diff --git a/Src/Common/FieldWorks/FieldWorks.csproj b/Src/Common/FieldWorks/FieldWorks.csproj index 65ae5049c2..5f66aade27 100644 --- a/Src/Common/FieldWorks/FieldWorks.csproj +++ b/Src/Common/FieldWorks/FieldWorks.csproj @@ -127,6 +127,10 @@ False ..\..\..\Downloads\PalasoUIWindowsForms.dll + + False + ..\..\..\Output\Debug\ParatextShared.dll + False ..\..\..\DistFiles\PaToFdoInterfaces.dll @@ -139,6 +143,10 @@ False ..\..\..\Output\Debug\RootSite.dll + + False + ..\..\..\Output\Debug\ScriptureUtils.dll + False ..\..\..\Output\Debug\SilUtils.dll @@ -200,9 +208,6 @@ - - - Form @@ -221,7 +226,6 @@ - diff --git a/Src/Common/FieldWorks/FieldWorksManager.cs b/Src/Common/FieldWorks/FieldWorksManager.cs index 818d9f734e..91698d8eae 100644 --- a/Src/Common/FieldWorks/FieldWorksManager.cs +++ b/Src/Common/FieldWorks/FieldWorksManager.cs @@ -12,7 +12,7 @@ using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO; using System.Windows.Forms; -using XCore; +using SIL.Utils; namespace SIL.FieldWorks { diff --git a/Src/Common/FieldWorks/FieldWorksTests/FieldWorksTests.cs b/Src/Common/FieldWorks/FieldWorksTests/FieldWorksTests.cs index 71fe5d7943..25a7115cec 100644 --- a/Src/Common/FieldWorks/FieldWorksTests/FieldWorksTests.cs +++ b/Src/Common/FieldWorks/FieldWorksTests/FieldWorksTests.cs @@ -5,8 +5,10 @@ // File: FieldWorksTests.cs // Responsibility: FW Team // --------------------------------------------------------------------------------------------- +using System; using NUnit.Framework; -using SIL.FieldWorks.Common.FwUtils; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.FDO.FDOTests; using SIL.FieldWorks.Test.TestUtils; using SIL.Utils; @@ -20,6 +22,14 @@ namespace SIL.FieldWorks [TestFixture] public class FieldWorksTests : BaseTest { + /// Setup for FieldWorks tests. + public override void FixtureSetup() + { + base.FixtureSetup(); + + FdoTestHelper.SetupClientServerServices(); + } + #region GetProjectMatchStatus tests /// ------------------------------------------------------------------------------------ /// @@ -114,5 +124,83 @@ public void GetProjectMatchStatus_SingleProcessMode() #endregion + /// + [Test] + public void EnsureValidLinkedFilesFolderCore_IfUsingDefaultDir_CreatesDirIfNotExist() + { + EnsureValidLinkedFilesFolderCore_TestHelper(defaultFolder => { + var configuredFolder = defaultFolder; + Assert.That(FileUtils.DirectoryExists(configuredFolder), Is.False, "Unit test not testing what it's supposed to"); + FieldWorks.EnsureValidLinkedFilesFolderCore(configuredFolder, defaultFolder); + Assert.That(FileUtils.DirectoryExists(configuredFolder), Is.True, "Should have created directory"); + }); + } + + /// + [Test] + public void EnsureValidLinkedFilesFolderCore_IfUsingDefaultDirAndItExists_DoesntCrashOrAnything() + { + EnsureValidLinkedFilesFolderCore_TestHelper(defaultFolder => { + // Make default linked files directory already exist + FileUtils.EnsureDirectoryExists(defaultFolder); + + // Not crash or anything + Assert.DoesNotThrow(() => FieldWorks.EnsureValidLinkedFilesFolderCore(defaultFolder, defaultFolder)); + }); + } + + /// + [Test] + public void EnsureValidLinkedFilesFolderCore_NonDefaultLocation_NotCreateNonExistentDir() + { + EnsureValidLinkedFilesFolderCore_TestHelper(defaultFolder => { + var configuredFolder = FileUtils.ChangePathToPlatform("/nondefaultAndNonexistentPath"); + + Assert.That(defaultFolder, Is.Not.EqualTo(configuredFolder), "Unit test not set up right"); + Assert.That(FileUtils.DirectoryExists(configuredFolder), Is.False, "Unit test not testing what it's supposed to"); + + FieldWorks.EnsureValidLinkedFilesFolderCore(configuredFolder, defaultFolder); + Assert.That(FileUtils.DirectoryExists(configuredFolder), Is.False, "Shouldn't have just made the nondefault directory"); + }); + } + + /// + [Test] + public void EnsureValidLinkedFilesFolderCore_NonDefaultLocationAndExists_DoesntCrashOrAnything() + { + EnsureValidLinkedFilesFolderCore_TestHelper(defaultFolder => { + var configuredFolder = FileUtils.ChangePathToPlatform("/nondefaultPath"); + + // Make linked files directory already exist + FileUtils.EnsureDirectoryExists(configuredFolder); + + Assert.That(defaultFolder, Is.Not.EqualTo(configuredFolder), "Unit test not set up right"); + Assert.That(FileUtils.DirectoryExists(configuredFolder), Is.True, "Unit test not testing what it's supposed to"); + + // Not crash or anything + FieldWorks.EnsureValidLinkedFilesFolderCore(configuredFolder, defaultFolder); + }); + } + + /// + /// Unit test helper to set up environment in which to test EnsureValidLinkedFilesFolderCore. + /// testToExecute takes (string defaultFolder, FdoCache cache). + /// + public void EnsureValidLinkedFilesFolderCore_TestHelper(Action testToExecute) + { + var defaultFolder = FileUtils.ChangePathToPlatform("/ProjectDir/LinkedFiles"); + + var fileOs = new MockFileOS(); + try + { + FileUtils.Manager.SetFileAdapter(fileOs); + + testToExecute(defaultFolder); + } + finally + { + FileUtils.Manager.Reset(); + } + } } } diff --git a/Src/Common/FieldWorks/FieldWorksTests/FieldWorksTests.csproj b/Src/Common/FieldWorks/FieldWorksTests/FieldWorksTests.csproj index 881ee50095..78a577aed8 100644 --- a/Src/Common/FieldWorks/FieldWorksTests/FieldWorksTests.csproj +++ b/Src/Common/FieldWorks/FieldWorksTests/FieldWorksTests.csproj @@ -72,10 +72,18 @@ False ..\..\..\..\Output\Debug\COMInterfacesTests.dll + + False + ..\..\..\..\Output\Debug\CoreImpl.dll + False ..\..\..\..\Output\Debug\FDO.dll + + False + ..\..\..\..\Output\Debug\FDOTests.dll + False .exe diff --git a/Src/Common/FieldWorks/FieldWorksTests/ProjectIDTests.cs b/Src/Common/FieldWorks/FieldWorksTests/ProjectIDTests.cs index dcd19691fa..b7d9147aaf 100644 --- a/Src/Common/FieldWorks/FieldWorksTests/ProjectIDTests.cs +++ b/Src/Common/FieldWorks/FieldWorksTests/ProjectIDTests.cs @@ -9,7 +9,9 @@ using System.IO; using NUnit.Framework; using Rhino.Mocks; +using SIL.CoreImpl; using SIL.FieldWorks.Common.FwUtils; +using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.Test.TestUtils; using SIL.Utils; @@ -46,17 +48,6 @@ public override void FixtureSetup() m_localCsSvcs.Stub(cs => cs.DefaultBackendType).Do(new Func( () => m_defaultBepType)); } - /// ------------------------------------------------------------------------------------ - /// - /// Fixture teardown. - /// - /// ------------------------------------------------------------------------------------ - public override void FixtureTeardown() - { - base.FixtureTeardown(); - ReflectionHelper.CallMethod(typeof(ClientServerServices), "SetCurrentToDefaultBackend"); - } - /// ------------------------------------------------------------------------------------ /// /// Sets up default member values for each test. @@ -119,7 +110,7 @@ public void IsValid_BogusType() public void IsValid_NullType() { const string sProjectName = "monkey"; - string sFile = DirectoryFinder.GetXmlDataFileName(sProjectName); + string sFile = FdoFileHelper.GetXmlDataFileName(sProjectName); m_mockFileOs.AddExistingFile(GetXmlProjectFilename(sProjectName)); ProjectId proj = new ProjectId(null, sFile, null); Assert.AreEqual(FDOBackendProviderType.kXML, proj.Type); @@ -147,7 +138,7 @@ public void IsValid_XML_False() public void IsValid_XML_True() { const string sProjectName = "monkey"; - string sFile = DirectoryFinder.GetXmlDataFileName(sProjectName); + string sFile = FdoFileHelper.GetXmlDataFileName(sProjectName); m_mockFileOs.AddExistingFile(GetXmlProjectFilename(sProjectName)); ProjectId proj = new ProjectId("xml", sFile, null); Assert.IsTrue(proj.IsValid); @@ -193,8 +184,8 @@ public void CleanUpNameForType_EmptyName() public void CleanUpNameForType_Default_onlyName() { m_defaultBepType = FDOBackendProviderType.kDb4oClientServer; - string expectedPath = Path.Combine(Path.Combine(DirectoryFinder.ProjectsDirectory, "ape"), - DirectoryFinder.GetDb4oDataFileName("ape")); + string expectedPath = Path.Combine(Path.Combine(FwDirectoryFinder.ProjectsDirectory, "ape"), + FdoFileHelper.GetDb4oDataFileName("ape")); m_localCsSvcs.Stub(cs => cs.IdForLocalProject("ape")).Return(expectedPath); m_mockFileOs.AddExistingFile(expectedPath); @@ -214,7 +205,7 @@ public void CleanUpNameForType_Default_onlyName() [Test] public void CleanUpNameForType_Default_NameWithPeriod_Exists() { - string expectedPath = Path.Combine(Path.Combine(DirectoryFinder.ProjectsDirectory, "my.monkey"), "my.monkey"); + string expectedPath = Path.Combine(Path.Combine(FwDirectoryFinder.ProjectsDirectory, "my.monkey"), "my.monkey"); m_localCsSvcs.Stub(cs => cs.IdForLocalProject("my.monkey")).Return(expectedPath); m_mockFileOs.AddExistingFile(expectedPath); @@ -234,8 +225,8 @@ public void CleanUpNameForType_Default_NameWithPeriod_Exists() [Test] public void CleanUpNameForType_XML_NameWithPeriod_FilesWithAndWithoutExtensionExist() { - string myMonkeyProjectFolder = Path.Combine(DirectoryFinder.ProjectsDirectory, "my.monkey"); - string expectedPath = Path.Combine(myMonkeyProjectFolder, DirectoryFinder.GetXmlDataFileName("my.monkey")); + string myMonkeyProjectFolder = Path.Combine(FwDirectoryFinder.ProjectsDirectory, "my.monkey"); + string expectedPath = Path.Combine(myMonkeyProjectFolder, FdoFileHelper.GetXmlDataFileName("my.monkey")); m_mockFileOs.AddExistingFile(expectedPath); m_mockFileOs.AddExistingFile(Path.Combine(myMonkeyProjectFolder, "my.monkey")); @@ -259,7 +250,7 @@ public void CleanUpNameForType_XML_NameWithPeriod_WithXmlExtension() string expectedPath = GetXmlProjectFilename(projectName); m_mockFileOs.AddExistingFile(expectedPath); - var proj = new ProjectId(DirectoryFinder.GetXmlDataFileName(projectName), null); + var proj = new ProjectId(FdoFileHelper.GetXmlDataFileName(projectName), null); Assert.AreEqual(expectedPath, proj.Path); Assert.AreEqual(FDOBackendProviderType.kXML, proj.Type); Assert.IsTrue(proj.IsValid); @@ -295,7 +286,7 @@ public void CleanUpNameForType_XML_onlyNameWithExtension() string expectedPath = GetXmlProjectFilename("monkey"); m_mockFileOs.AddExistingFile(expectedPath); - var proj = new ProjectId(DirectoryFinder.GetXmlDataFileName("monkey"), null); + var proj = new ProjectId(FdoFileHelper.GetXmlDataFileName("monkey"), null); Assert.AreEqual(expectedPath, proj.Path); Assert.AreEqual(FDOBackendProviderType.kXML, proj.Type); Assert.IsTrue(proj.IsValid); @@ -310,7 +301,7 @@ public void CleanUpNameForType_XML_onlyNameWithExtension() [Test] public void CleanUpNameForType_XML_FullPath() { - string expectedPath = Path.Combine(DirectoryFinder.ProjectsDirectory, DirectoryFinder.GetXmlDataFileName("monkey")); + string expectedPath = Path.Combine(FwDirectoryFinder.ProjectsDirectory, FdoFileHelper.GetXmlDataFileName("monkey")); m_mockFileOs.AddExistingFile(expectedPath); var proj = new ProjectId(expectedPath, null); @@ -329,8 +320,8 @@ public void CleanUpNameForType_XML_FullPath() [Ignore("Not sure what this would be useful for or if this would be the desired behavior.")] public void CleanUpNameForType_XML_RelativePath() { - string relativePath = Path.Combine("primate", DirectoryFinder.GetXmlDataFileName("monkey")); - string expectedPath = Path.Combine(DirectoryFinder.ProjectsDirectory, relativePath); + string relativePath = Path.Combine("primate", FdoFileHelper.GetXmlDataFileName("monkey")); + string expectedPath = Path.Combine(FwDirectoryFinder.ProjectsDirectory, relativePath); m_mockFileOs.AddExistingFile(expectedPath); ProjectId proj = new ProjectId(relativePath, null); @@ -352,7 +343,7 @@ public void AssertValid_Valid() string projFile = GetXmlProjectFilename("monkey"); m_mockFileOs.AddExistingFile(projFile); - var proj = new ProjectId(DirectoryFinder.GetXmlDataFileName("monkey"), null); + var proj = new ProjectId(FdoFileHelper.GetXmlDataFileName("monkey"), null); proj.AssertValid(); // no exception should be thrown here for a valid project. } @@ -371,7 +362,7 @@ public void AssertValid_Invalid_NoName() proj.AssertValid(); Assert.Fail("FwStartupException expected"); } - catch (FwStartupException exception) + catch (StartupException exception) { Assert.IsFalse(exception.ReportToUser); } @@ -386,13 +377,13 @@ public void AssertValid_Invalid_NoName() [Test] public void AssertValid_Invalid_FileNotFound() { - var proj = new ProjectId(DirectoryFinder.GetXmlDataFileName("notfound"), null); + var proj = new ProjectId(FdoFileHelper.GetXmlDataFileName("notfound"), null); try { proj.AssertValid(); Assert.Fail("FwStartupException expected"); } - catch (FwStartupException exception) + catch (StartupException exception) { Assert.IsTrue(exception.ReportToUser); } @@ -407,13 +398,13 @@ public void AssertValid_Invalid_FileNotFound() [Test] public void AssertValid_InvalidProjectType() { - var proj = new ProjectId(FDOBackendProviderType.kInvalid, DirectoryFinder.GetXmlDataFileName("invalid"), null); + var proj = new ProjectId(FDOBackendProviderType.kInvalid, FdoFileHelper.GetXmlDataFileName("invalid"), null); try { proj.AssertValid(); Assert.Fail("FwStartupException expected"); } - catch (FwStartupException exception) + catch (StartupException exception) { Assert.IsTrue(exception.ReportToUser); } @@ -428,13 +419,13 @@ public void AssertValid_InvalidProjectType() [Test] public void AssertValid_Invalid_SharedFolderNotFound() { - var proj = new ProjectId(DirectoryFinder.GetDb4oDataFileName("monkey"), FwLinkArgs.kLocalHost); + var proj = new ProjectId(FdoFileHelper.GetDb4oDataFileName("monkey"), FwLinkArgs.kLocalHost); try { proj.AssertValid(); Assert.Fail("FwStartupException expected"); } - catch (FwStartupException exception) + catch (StartupException exception) { Assert.IsTrue(exception.ReportToUser); } @@ -451,12 +442,12 @@ public void AssertValid_Invalid_SharedFolderNotFound() [Test] public void CheckProperties() { - string expectedProjectDir = Path.Combine(DirectoryFinder.ProjectsDirectory, "SomeTest"); + string expectedProjectDir = Path.Combine(FwDirectoryFinder.ProjectsDirectory, "SomeTest"); m_mockFileOs.ExistingDirectories.Add(expectedProjectDir); const string type = "db4ocs"; const string host = "127.0.0.1"; - string filename = DirectoryFinder.GetDb4oDataFileName("SomeTest"); + string filename = FdoFileHelper.GetDb4oDataFileName("SomeTest"); var proj = new ProjectId(type, filename, host); proj.AssertValid(); @@ -475,13 +466,13 @@ public void CheckProperties() [Test] public void NameAndPath() { - string myProjectFolder = Path.Combine(DirectoryFinder.ProjectsDirectory, "My.Project"); + string myProjectFolder = Path.Combine(FwDirectoryFinder.ProjectsDirectory, "My.Project"); ProjectId projId = new ProjectId(FDOBackendProviderType.kXML, "My.Project", null); - Assert.AreEqual(Path.Combine(myProjectFolder, DirectoryFinder.GetXmlDataFileName("My.Project")), projId.Path); + Assert.AreEqual(Path.Combine(myProjectFolder, FdoFileHelper.GetXmlDataFileName("My.Project")), projId.Path); Assert.AreEqual("My.Project", projId.Name); projId = new ProjectId(FDOBackendProviderType.kDb4oClientServer, "My.Project", null); - Assert.AreEqual(Path.Combine(myProjectFolder, DirectoryFinder.GetDb4oDataFileName("My.Project")), projId.Path); + Assert.AreEqual(Path.Combine(myProjectFolder, FdoFileHelper.GetDb4oDataFileName("My.Project")), projId.Path); Assert.AreEqual("My.Project", projId.Name); } @@ -497,8 +488,8 @@ public void NameAndPath() /// ------------------------------------------------------------------------------------ public static string GetXmlProjectFilename(string projectName) { - return Path.Combine(Path.Combine(DirectoryFinder.ProjectsDirectory, projectName), - DirectoryFinder.GetXmlDataFileName(projectName)); + return Path.Combine(Path.Combine(FwDirectoryFinder.ProjectsDirectory, projectName), + FdoFileHelper.GetXmlDataFileName(projectName)); } #endregion } diff --git a/Src/Common/FieldWorks/LexicalProvider/ILexicalProvider.cs b/Src/Common/FieldWorks/LexicalProvider/ILexicalProvider.cs deleted file mode 100644 index 132516e556..0000000000 --- a/Src/Common/FieldWorks/LexicalProvider/ILexicalProvider.cs +++ /dev/null @@ -1,321 +0,0 @@ -// Copyright (c) 2011-2013 SIL International -// This software is licensed under the LGPL, version 2.1 or later -// (http://www.gnu.org/licenses/lgpl-2.1.html) -// -// File: ILexicalProvider.cs -// Responsibility: FW Team -// -// -// - -using System; -using System.Collections.Generic; -using System.Runtime.Serialization; -using System.ServiceModel; - -namespace SIL.FieldWorks.LexicalProvider -{ - #region ILexicalServiceProvider interface - /// ---------------------------------------------------------------------------------------- - /// - /// Provides a service contract for getting a lexical provider from an application. - /// WARNING: Paratext contains its own identical definition of these interfaces. - /// Any change must be coordinated (both in corresponding source files and in terms - /// of product release schedules. - /// - /// ---------------------------------------------------------------------------------------- - [ServiceContract] - public interface ILexicalServiceProvider - { - /// ------------------------------------------------------------------------------------ - /// - /// Gets the location for the provider for the specified project and - /// provider type. If the providerType is not supported, return null for the Uri. - /// - /// ------------------------------------------------------------------------------------ - [OperationContract] - Uri GetProviderLocation(string projhandle, string providerType); - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the version of the specified provider that the server supports. If the - /// providerType is not supported, return 0 for the version. - /// - /// ------------------------------------------------------------------------------------ - [OperationContract] - int GetSupportedVersion(string providerType); - - /// ------------------------------------------------------------------------------------ - /// - /// Unlike a normal ping method that gets a response, we just use this ping method - /// to determine if the service provider is actually valid since no exception is - /// thrown until a method is called. - /// - /// ------------------------------------------------------------------------------------ - [OperationContract] - void Ping(); - } - #endregion - - #region ILexicalProvider interface - /// ---------------------------------------------------------------------------------------- - /// - /// Provides a service contract for accessing lexical data from other applications. - /// - /// ---------------------------------------------------------------------------------------- - [ServiceContract] - public interface ILexicalProvider - { - /// ------------------------------------------------------------------------------------ - /// - /// Displays the specified entry using the application with the lexical data. - /// - /// ------------------------------------------------------------------------------------ - [OperationContract] - void ShowEntry(string entry, EntryType entryType); - - /// ------------------------------------------------------------------------------------ - /// - /// Displays the related words using the application with the lexical data. - /// - /// ------------------------------------------------------------------------------------ - [OperationContract] - void ShowRelatedWords(string entry, EntryType entryType); - - /// ------------------------------------------------------------------------------------ - /// - /// Gets all lexemes in the Lexicon - /// - /// ------------------------------------------------------------------------------------ - [OperationContract] - IEnumerable Lexemes(); - - /// - /// Looks up an lexeme in the lexicon - /// - [OperationContract] - LexicalEntry GetLexeme(LexemeType type, string lexicalForm, int homograph); - - /// - /// Adds the lexeme to the lexicon. - /// - /// if matching lexeme is already in lexicon - [OperationContract] - void AddLexeme(LexicalEntry lexeme); - - /// - /// Adds a new sense to the lexeme with the specified information - /// - [OperationContract] - LexSense AddSenseToEntry(LexemeType type, string lexicalForm, int homograph); - - /// - /// Adds a new gloss to the sense with the specified information - /// - [OperationContract] - LexGloss AddGlossToSense(LexemeType type, string lexicalForm, int homograph, string senseId, string language, string text); - - /// - /// Removes the gloss with the specified language form the sense with the specified information - /// - [OperationContract] - void RemoveGloss(LexemeType type, string lexicalForm, int homograph, string senseId, string language); - - /// ------------------------------------------------------------------------------------ - /// - /// Forces a save of lexicon - /// - /// ------------------------------------------------------------------------------------ - [OperationContract] - void Save(); - - /// ------------------------------------------------------------------------------------ - /// - /// This must be called before entries are changed to ensure that - /// it is saved to disk. Since the lexicon is a complex structure - /// and other features depend on knowing when it is changed, - /// all work done with the lexicon is marked with a begin and - /// end change. - /// - /// ------------------------------------------------------------------------------------ - [OperationContract] - void BeginChange(); - - /// ------------------------------------------------------------------------------------ - /// - /// This must be called after entries are changed to ensure that - /// other features dependent on the lexicon are made aware of the - /// change. - /// - /// ------------------------------------------------------------------------------------ - [OperationContract] - void EndChange(); - } - #endregion - - #region EntryType enumeration - /// ---------------------------------------------------------------------------------------- - /// - /// Types of lexical entries that can be requested by a client of a LexicalProvider - /// - /// ---------------------------------------------------------------------------------------- - public enum EntryType - { - /// entry represents a word - Word - } - #endregion - - #region LexemeType enumeration - /// ---------------------------------------------------------------------------------------- - /// - /// All known lexeme types - /// - /// ---------------------------------------------------------------------------------------- - public enum LexemeType - { - /// - Phrase, - /// - Word, - /// - Lemma, - /// - Stem, - /// - Prefix, - /// - Suffix - }; - #endregion - - #region LexicalEntry class - /// ---------------------------------------------------------------------------------------- - /// - /// Data contract used by WCF for holding information about a Lexeme - /// - /// ---------------------------------------------------------------------------------------- - [DataContract(Namespace = "LexicalData")] - public sealed class LexicalEntry - { - /// ------------------------------------------------------------------------------------ - /// - /// Initializes a new instance of the class. - /// - /// ------------------------------------------------------------------------------------ - public LexicalEntry(LexemeType type, string form, int homograph) - { - Type = type; - LexicalForm = form; - Homograph = homograph; - Senses = new List(); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets or sets the type. - /// - /// ------------------------------------------------------------------------------------ - [DataMember] - public LexemeType Type { get; private set; } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets or sets the lexical form. - /// - /// ------------------------------------------------------------------------------------ - [DataMember] - public string LexicalForm { get; private set; } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets or sets the homograph. - /// - /// ------------------------------------------------------------------------------------ - [DataMember] - public int Homograph { get; private set; } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets or sets the senses. - /// - /// ------------------------------------------------------------------------------------ - [DataMember] - public IList Senses { get; set; } - } - #endregion - - #region LexSense class - /// ---------------------------------------------------------------------------------------- - /// - /// Data contract used by WCF for holding information about a Sense - /// - /// ---------------------------------------------------------------------------------------- - [DataContract(Namespace = "LexicalData")] - public sealed class LexSense - { - /// ------------------------------------------------------------------------------------ - /// - /// Initializes a new instance of the class. - /// - /// ------------------------------------------------------------------------------------ - public LexSense(string id) - { - Id = id; - Glosses = new List(); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets or sets the id. - /// - /// ------------------------------------------------------------------------------------ - [DataMember] - public string Id { get; private set; } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets or sets the glosses. - /// - /// ------------------------------------------------------------------------------------ - [DataMember] - public IList Glosses { get; set; } - } - #endregion - - #region LexGloss class - /// - /// Data contract used by WCF for holding information about a Gloss - /// - [DataContract(Namespace = "LexicalData")] - public sealed class LexGloss - { - /// ------------------------------------------------------------------------------------ - /// - /// Initializes a new instance of the class. - /// - /// ------------------------------------------------------------------------------------ - public LexGloss(string language, string text) - { - Language = language; - Text = text; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets or sets the language. - /// - /// ------------------------------------------------------------------------------------ - [DataMember] - public string Language { get; private set; } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets or sets the text. - /// - /// ------------------------------------------------------------------------------------ - [DataMember] - public string Text { get; private set; } - } - #endregion -} diff --git a/Src/Common/FieldWorks/LexicalProvider/LexicalProviderImpl.cs b/Src/Common/FieldWorks/LexicalProvider/LexicalProviderImpl.cs deleted file mode 100644 index d34f56251f..0000000000 --- a/Src/Common/FieldWorks/LexicalProvider/LexicalProviderImpl.cs +++ /dev/null @@ -1,595 +0,0 @@ -// Copyright (c) 2011-2013 SIL International -// This software is licensed under the LGPL, version 2.1 or later -// (http://www.gnu.org/licenses/lgpl-2.1.html) -// -// File: LexicalProviderImpl.cs -// Responsibility: FW Team -// -// -// - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.ServiceModel; -using SIL.FieldWorks.Common.COMInterfaces; -using SIL.CoreImpl; -using SIL.FieldWorks.FDO; -using SIL.FieldWorks.FDO.DomainServices; -using SIL.FieldWorks.FDO.Infrastructure; -using SIL.FieldWorks.FdoUi; -using SIL.FieldWorks.Common.FwUtils; -using SIL.Utils; -using XCore; - -namespace SIL.FieldWorks.LexicalProvider -{ - /// ---------------------------------------------------------------------------------------- - /// - /// This class implements the ILexicalProvider - /// - /// ---------------------------------------------------------------------------------------- - [ServiceBehavior(IncludeExceptionDetailInFaults = true, - InstanceContextMode = InstanceContextMode.Single, - MaxItemsInObjectGraph = 2147483647)] - [SuppressMessage("Gendarme.Rules.Design", "TypesWithDisposableFieldsShouldBeDisposableRule", - Justification="m_cache is a reference")] - public sealed class LexicalProviderImpl : ILexicalProvider - { - private const string kAnalysisPrefix = "Analysis:"; - private readonly FdoCache m_cache; - - /// ------------------------------------------------------------------------------------ - /// - /// Initializes a new instance of the class for the - /// specified cache. - /// - /// ------------------------------------------------------------------------------------ - public LexicalProviderImpl(FdoCache cache) - { - m_cache = cache; - } - - #region ILexicalProvider Members - /// ------------------------------------------------------------------------------------ - /// - /// Displays the specified entry using the application with the lexical data. - /// - /// ------------------------------------------------------------------------------------ - public void ShowEntry(string entry, EntryType entryType) - { - LexicalProviderManager.ResetLexicalProviderTimer(); - Logger.WriteEvent("Showing entry from external application for the " + entryType + " " + entry); - - if (entryType != EntryType.Word) - throw new ArgumentException("Unknown entry type specified."); - - // An asynchronous call is necessary because the WCF server (FieldWorks) will not - // respond until this method returns. This also allows methods that show dialogs on the - // WCF server to not be OneWay. (Otherwise, time-out exceptions occur.) - FieldWorks.ThreadHelper.InvokeAsync(() => - { - ITsString tss = TsStringUtils.MakeTss(entry, FieldWorks.Cache.DefaultVernWs); - Mediator mediator = new Mediator(); - mediator.HelpTopicProvider = FieldWorks.GetHelpTopicProvider(FwUtils.ksFlexAbbrev); - mediator.FeedbackInfoProvider = FieldWorks.GetOrCreateFlexApp(); - mediator.PropertyTable.SetProperty("App", FieldWorks.GetOrCreateFlexApp()); - - LexEntryUi.DisplayEntry(FieldWorks.Cache, mediator, mediator.HelpTopicProvider, - "UserHelpFile", tss, null); - }); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Displays the related words to the specified entry using the application with the - /// lexical data. - /// - /// ------------------------------------------------------------------------------------ - public void ShowRelatedWords(string entry, EntryType entryType) - { - LexicalProviderManager.ResetLexicalProviderTimer(); - Logger.WriteEvent("Showing related word from external application for the " + entryType + " " + entry); - - if (entryType != EntryType.Word) - throw new ArgumentException("Unknown entry type specified."); - - // An asynchronous call is necessary because the WCF server (FieldWorks) will not - // respond until this method returns. This also allows methods that show dialogs on the - // WCF server to not be OneWay. (Otherwise, time-out exceptions occur.) - FieldWorks.ThreadHelper.InvokeAsync(() => - { - ITsString tss = TsStringUtils.MakeTss(entry, FieldWorks.Cache.DefaultVernWs); - Mediator mediator = new Mediator(); - mediator.HelpTopicProvider = FieldWorks.GetHelpTopicProvider(FwUtils.ksFlexAbbrev); - mediator.FeedbackInfoProvider = FieldWorks.GetOrCreateFlexApp(); - mediator.PropertyTable.SetProperty("App", FieldWorks.GetOrCreateFlexApp()); - - LexEntryUi.DisplayRelatedEntries(FieldWorks.Cache, mediator, mediator.HelpTopicProvider, - "UserHelpFile", tss); - }); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets all lexemes in the Lexicon - /// - /// ------------------------------------------------------------------------------------ - public IEnumerable Lexemes() - { - LexicalProviderManager.ResetLexicalProviderTimer(); - - List entries = new List(); - // Get all of the lexical entries in the database - foreach (ILexEntry dbEntry in m_cache.ServiceLocator.GetInstance().AllInstances()) - { - IMoMorphType morphType = dbEntry.PrimaryMorphType; - if (morphType != null) - entries.Add(CreateEntryFromDbEntry(GetLexemeTypeForMorphType(morphType), dbEntry)); - } - - // Get all the wordforms in the database - foreach (IWfiWordform wordform in m_cache.ServiceLocator.GetInstance().AllInstances()) - entries.Add(CreateEntryFromDbWordform(wordform)); - - return entries; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Looks up an lexeme - /// - /// ------------------------------------------------------------------------------------ - public LexicalEntry GetLexeme(LexemeType type, string lexicalForm, int homograph) - { - LexicalProviderManager.ResetLexicalProviderTimer(); - - switch (type) - { - case LexemeType.Word: - IWfiWordform wf = GetDbWordform(lexicalForm); - return (wf != null) ? CreateEntryFromDbWordform(wf) : null; - default: - ILexEntry dbEntry = GetDbLexeme(type, lexicalForm, homograph); - return (dbEntry != null) ? CreateEntryFromDbEntry(type, dbEntry) : null; - } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Adds the lexeme to the lexicon. - /// - /// if matching lexeme is already in lexicon - /// ------------------------------------------------------------------------------------ - public void AddLexeme(LexicalEntry lexeme) - { - LexicalProviderManager.ResetLexicalProviderTimer(); - Logger.WriteEvent("Adding new lexeme from an external application: " + lexeme.LexicalForm); - - NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, () => - { - string sForm = lexeme.LexicalForm; - switch(lexeme.Type) - { - case LexemeType.Word: - ITsString tss = TsStringUtils.MakeTss(lexeme.LexicalForm, m_cache.DefaultVernWs); - m_cache.ServiceLocator.GetInstance().Create(tss); - break; - default: - { - SandboxGenericMSA msa = new SandboxGenericMSA(); - msa.MsaType = (lexeme.Type == LexemeType.Stem) ? MsaType.kStem : MsaType.kUnclassified; - - IMoMorphType morphType = GetMorphTypeForLexemeType(lexeme.Type); - ITsString tssForm = TsStringUtils.MakeTss(sForm, m_cache.DefaultVernWs); - m_cache.ServiceLocator.GetInstance().Create(morphType, tssForm, (ITsString)null, msa); - break; - } - } - }); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Adds a new sense to the lexeme with the specified information - /// - /// ------------------------------------------------------------------------------------ - public LexSense AddSenseToEntry(LexemeType type, string lexicalForm, int homograph) - { - LexicalProviderManager.ResetLexicalProviderTimer(); - Logger.WriteEvent("Adding new sense to lexeme '" + lexicalForm + "' from an external application"); - - return NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, () => - { - string guid = string.Empty; - switch (type) - { - case LexemeType.Word: - { - IWfiWordform dbWordform = GetDbWordform(lexicalForm); - if (dbWordform == null) - throw new ArgumentException("Entry in the lexicon not found for the specified information"); - - // For wordforms, our "senses" could be new meanings of an analysis for the word - // or it could be a brand new analysis. Because we have no idea what the user actually - // wanted, we just assume the worst (they want to create a new analysis for the word - // with a new meaning). - IWfiAnalysis dbAnalysis = m_cache.ServiceLocator.GetInstance().Create(); - dbWordform.AnalysesOC.Add(dbAnalysis); - guid = kAnalysisPrefix + dbAnalysis.Guid; - break; - } - default: - { - ILexEntry dbEntry = GetDbLexeme(type, lexicalForm, homograph); - if (dbEntry == null) - throw new ArgumentException("Entry in the lexicon not found for the specified information"); - - if (dbEntry.SensesOS.Count == 1 && dbEntry.SensesOS[0].Gloss.StringCount == 0) - { - // An empty sense exists (probably was created during a call to AddLexeme) - guid = dbEntry.SensesOS[0].Guid.ToString(); - break; - } - - ILexSense newSense = m_cache.ServiceLocator.GetInstance().Create( - dbEntry, new SandboxGenericMSA(), (ITsString)null); - guid = newSense.Guid.ToString(); - break; - } - } - return new LexSense(guid); - }); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Adds a new gloss to the sense with the specified information - /// - /// ------------------------------------------------------------------------------------ - public LexGloss AddGlossToSense(LexemeType type, string lexicalForm, int homograph, - string senseId, string language, string text) - { - LexicalProviderManager.ResetLexicalProviderTimer(); - Logger.WriteEvent("Adding new gloss to lexeme '" + lexicalForm + "' from an external application"); - - return NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, () => - { - IMultiUnicode dbGlosses; - if (senseId.StartsWith(kAnalysisPrefix)) - { - // The "sense" is actually an analysis for a wordform and our new - // gloss is a new meaning for that analysis. - Guid analysisGuid = new Guid(senseId.Substring(kAnalysisPrefix.Length)); - IWfiAnalysis dbAnalysis = m_cache.ServiceLocator.GetInstance().GetObject(analysisGuid); - IWfiGloss dbGloss = dbAnalysis.MeaningsOC.FirstOrDefault(); - if (dbGloss == null) - { - dbGloss = m_cache.ServiceLocator.GetInstance().Create(); - dbAnalysis.MeaningsOC.Add(dbGloss); - } - dbGlosses = dbGloss.Form; - dbAnalysis.ApprovalStatusIcon = 1; // Assume the analysis from the external application is user approved - } - else - { - Guid senseGuid = new Guid(senseId); - ILexSense dbSense = m_cache.ServiceLocator.GetInstance().GetObject(senseGuid); - dbGlosses = dbSense.Gloss; - } - - // Add the new gloss to the list of glosses for the sense - ILgWritingSystem writingSystem = m_cache.WritingSystemFactory.get_Engine(language); - dbGlosses.set_String(writingSystem.Handle, TsStringUtils.MakeTss(text, writingSystem.Handle)); - - return new LexGloss(language, text); - }); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Removes the gloss with the specified language form the sense with the specified information - /// - /// ------------------------------------------------------------------------------------ - public void RemoveGloss(LexemeType type, string lexicalForm, int homograph, - string senseId, string language) - { - LexicalProviderManager.ResetLexicalProviderTimer(); - Logger.WriteEvent("Removing gloss from lexeme '" + lexicalForm + "' from an external application"); - - NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, () => - { - IMultiUnicode dbGlosses; - Guid guid; - if (senseId.StartsWith(kAnalysisPrefix)) - { - // The "sense" is actually an analysis for a wordform and the gloss - // we want to delete is a meaning for that analysis. - guid = new Guid(senseId.Substring(kAnalysisPrefix.Length)); - IWfiAnalysis dbAnalysis = m_cache.ServiceLocator.GetInstance().GetObject(guid); - IWfiGloss dbGloss = dbAnalysis.MeaningsOC.First(); - dbGlosses = dbGloss.Form; - } - else - { - guid = new Guid(senseId); - ILexSense dbSense = m_cache.ServiceLocator.GetInstance().GetObject(guid); - dbGlosses = dbSense.Gloss; - } - // Remove the gloss from the list of glosses for the sense - int wsId = m_cache.WritingSystemFactory.GetWsFromStr(language); - dbGlosses.set_String(wsId, (ITsString)null); - - // Delete the sense if there are no more glosses for it - if (dbGlosses.StringCount == 0) - RemoveSense(senseId, guid); - }); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Forces a save of lexicon - /// - /// ------------------------------------------------------------------------------------ - public void Save() - { - LexicalProviderManager.ResetLexicalProviderTimer(); - - // ENHANCE: We could do a save on the cache here. It doesn't seem really important - // since the cache will be saved automatically with 10 seconds of inactivity anyways. - } - - /// ------------------------------------------------------------------------------------ - /// - /// This must be called before entries are changed to ensure that - /// it is saved to disk. Since the lexicon is a complex structure - /// and other features depend on knowing when it is changed, - /// all work done with the lexicon is marked with a begin and - /// end change. - /// - /// ------------------------------------------------------------------------------------ - public void BeginChange() - { - LexicalProviderManager.ResetLexicalProviderTimer(); - - // Ideally, we would like to be able to begin an undo task here and then end it in - // EndChange(). However, because there is no guarantee that EndChange() will ever - // get called (and to keep the data in a consistant state), we need to wrap - // each individual change in it's own undo task. - } - - /// ------------------------------------------------------------------------------------ - /// - /// This must be called after entries are changed to ensure that - /// other features dependent on the lexicon are made aware of the - /// change. - /// - /// ------------------------------------------------------------------------------------ - public void EndChange() - { - LexicalProviderManager.ResetLexicalProviderTimer(); - } - #endregion - - #region Private helper methods - /// ------------------------------------------------------------------------------------ - /// - /// Gets the DB LexEntry for the specified type and form (homograph currently ignored) or - /// null if none could be found. - /// - /// ------------------------------------------------------------------------------------ - private ILexEntry GetDbLexeme(LexemeType type, string lexicalForm, int homograph) - { - if (type == LexemeType.Word) - throw new ArgumentException("LexEntry can not be found for the Lexeme type specified"); - - // ENHANCE: We may have to do something with the homograph number eventually, but - // currently there is no correlation between the homograph number in the DB and - // the homograph number passed from the external application. - return m_cache.ServiceLocator.GetInstance().GetHomographs(lexicalForm).FirstOrDefault( - dbEntry => LexemeTypeAndMorphTypeMatch(type, dbEntry.PrimaryMorphType)); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the DB Wordform for the form or null if none could be found. - /// - /// ------------------------------------------------------------------------------------ - private IWfiWordform GetDbWordform(string lexicalForm) - { - IWfiWordform wf; - m_cache.ServiceLocator.GetInstance().TryGetObject( - TsStringUtils.MakeTss(lexicalForm, m_cache.DefaultVernWs), true, out wf); - return wf; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Creates a new LexicalEntry from the specified lexical entry in the DB - /// - /// ------------------------------------------------------------------------------------ - private LexicalEntry CreateEntryFromDbEntry(LexemeType type, ILexEntry dbEntry) - { - if (type == LexemeType.Word) - throw new ArgumentException("Lexeme type specified can not be created from a LexEntry"); - - // A homograph number of zero in the DB means there is only one entry for the wordform. - // However, the interface requires there be an entry with a homograph of one even if - // there is only one entry. - LexicalEntry entry = new LexicalEntry(type, dbEntry.HomographForm, - dbEntry.HomographNumber > 0 ? dbEntry.HomographNumber : 1); - - // Add the senses to the interface (non-DB) entry - foreach (ILexSense dbSense in dbEntry.SensesOS) - { - LexSense sense = new LexSense(dbSense.Guid.ToString()); - AddDbGlossesToSense(sense, dbSense.Gloss); - entry.Senses.Add(sense); // Add the sense to the list of senses - } - return entry; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Creates a new LexicalEntry from the specified word form in the DB - /// - /// ------------------------------------------------------------------------------------ - private LexicalEntry CreateEntryFromDbWordform(IWfiWordform wordform) - { - const int homograph = 1; - LexicalEntry entry = new LexicalEntry(LexemeType.Word, wordform.Form.VernacularDefaultWritingSystem.Text, homograph); - foreach (IWfiAnalysis dbAnalysis in wordform.AnalysesOC) - { - // Since our "sense" is really an analysis for a wordform, assume that any meanings - // for that analysis are glosses for the same "sense". - LexSense sense = new LexSense(kAnalysisPrefix + dbAnalysis.Guid.ToString()); - foreach (IWfiGloss gloss in dbAnalysis.MeaningsOC) - AddDbGlossesToSense(sense, gloss.Form); - entry.Senses.Add(sense); - } - return entry; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Adds the glosses in all available writing systems to the specified sense. - /// - /// ------------------------------------------------------------------------------------ - private void AddDbGlossesToSense(LexSense sense, IMultiUnicode glosses) - { - for (int i = 0; i < glosses.StringCount; i++) - { - int ws; - ITsString tssGloss = glosses.GetStringFromIndex(i, out ws); - string icuLocale = m_cache.WritingSystemFactory.GetStrFromWs(ws); - sense.Glosses.Add(new LexGloss(icuLocale, tssGloss.Text)); - } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Removes the sense with the specified ID and guid from the DB. - /// - /// ------------------------------------------------------------------------------------ - private void RemoveSense(string senseId, Guid guid) - { - if (senseId.StartsWith(kAnalysisPrefix)) - { - IWfiAnalysis dbAnalysis = m_cache.ServiceLocator.GetInstance().GetObject(guid); - IWfiWordform dbWordform = (IWfiWordform)dbAnalysis.Owner; - dbWordform.AnalysesOC.Remove(dbAnalysis); - } - else - { - ILexSense dbSense = m_cache.ServiceLocator.GetInstance().GetObject(guid); - ILexEntry dbEntry = (ILexEntry)dbSense.Owner; - - // Make sure we keep at least one sense around. This seems to be required. - if (dbEntry.SensesOS.Count > 1) - dbEntry.SensesOS.Remove(dbSense); - } - } - #endregion - - #region LexemeType and MorphType matching methods - /// ------------------------------------------------------------------------------------ - /// - /// Determines if the specified lexeme type matches the specified morph type - /// - /// ------------------------------------------------------------------------------------ - private static bool LexemeTypeAndMorphTypeMatch(LexemeType type, IMoMorphType morphType) - { - if (type == LexemeType.Word || type == LexemeType.Lemma) - throw new ArgumentException("Morph type can never be of the specified lexeme type"); - - switch (type) - { - case LexemeType.Prefix: return morphType.IsPrefixishType; - case LexemeType.Suffix: return morphType.IsSuffixishType; - case LexemeType.Stem: return morphType.IsStemType && - morphType.Guid != MoMorphTypeTags.kguidMorphPhrase && - morphType.Guid != MoMorphTypeTags.kguidMorphDiscontiguousPhrase; - case LexemeType.Phrase: - return morphType.Guid == MoMorphTypeTags.kguidMorphPhrase || - morphType.Guid == MoMorphTypeTags.kguidMorphDiscontiguousPhrase; - } - return false; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the morph type for the specified lexeme type. - /// - /// ------------------------------------------------------------------------------------ - private IMoMorphType GetMorphTypeForLexemeType(LexemeType type) - { - if (type == LexemeType.Word || type == LexemeType.Lemma) - throw new ArgumentException("Morph type can never be of the specified lexeme type"); - - IMoMorphTypeRepository repo = m_cache.ServiceLocator.GetInstance(); - switch (type) - { - case LexemeType.Prefix: return repo.GetObject(MoMorphTypeTags.kguidMorphPrefix); - case LexemeType.Suffix: return repo.GetObject(MoMorphTypeTags.kguidMorphSuffix); - case LexemeType.Phrase: return repo.GetObject(MoMorphTypeTags.kguidMorphPhrase); - case LexemeType.Stem: return repo.GetObject(MoMorphTypeTags.kguidMorphStem); - } - return null; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the lexeme type that most closely represents the specified morph type. - /// - /// This method attempts to do it's best to get the correct lexeme type. - /// However, the FW database contains many more morph types then can be represented with - /// the few lexeme types. This creates some ambiguous mappings which are commented - /// inside this method body. - /// ------------------------------------------------------------------------------------ - private LexemeType GetLexemeTypeForMorphType(IMoMorphType type) - { - switch (type.Guid.ToString()) - { - case MoMorphTypeTags.kMorphCircumfix: - case MoMorphTypeTags.kMorphInfix: - case MoMorphTypeTags.kMorphInfixingInterfix: - case MoMorphTypeTags.kMorphSimulfix: - case MoMorphTypeTags.kMorphSuprafix: - case MoMorphTypeTags.kMorphClitic: - case MoMorphTypeTags.kMorphProclitic: - // These don't map neatly to a lexeme type, so we just return prefix - return LexemeType.Prefix; - - case MoMorphTypeTags.kMorphEnclitic: - // This one also isn't a great match, but there is no better choice - return LexemeType.Suffix; - - case MoMorphTypeTags.kMorphPrefix: - case MoMorphTypeTags.kMorphPrefixingInterfix: - return LexemeType.Prefix; - - case MoMorphTypeTags.kMorphSuffix: - case MoMorphTypeTags.kMorphSuffixingInterfix: - return LexemeType.Suffix; - - case MoMorphTypeTags.kMorphPhrase: - case MoMorphTypeTags.kMorphDiscontiguousPhrase: - return LexemeType.Phrase; - - case MoMorphTypeTags.kMorphStem: - case MoMorphTypeTags.kMorphRoot: - case MoMorphTypeTags.kMorphBoundRoot: - case MoMorphTypeTags.kMorphBoundStem: - case MoMorphTypeTags.kMorphParticle: - return LexemeType.Stem; - } - - // Shouldn't ever get here, but since we don't know what type it is just return - // a random default and hope for the best. - return LexemeType.Stem; - } - #endregion - } -} diff --git a/Src/Common/FieldWorks/LexicalProvider/LexicalProviderManager.cs b/Src/Common/FieldWorks/LexicalProvider/LexicalProviderManager.cs deleted file mode 100644 index 534e004469..0000000000 --- a/Src/Common/FieldWorks/LexicalProvider/LexicalProviderManager.cs +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright (c) 2011-2013 SIL International -// This software is licensed under the LGPL, version 2.1 or later -// (http://www.gnu.org/licenses/lgpl-2.1.html) -// -// File: LexicalProviderManager.cs -// Responsibility: FW Team - -using System; -using System.Collections.Generic; -using System.IO; -using System.Diagnostics.CodeAnalysis; -using System.ServiceModel; -using System.Threading; -using System.Windows.Forms; -using SIL.FieldWorks.Common.FwUtils; -using SIL.FieldWorks.FDO; -using SIL.Utils; -using Timer = System.Threading.Timer; - -namespace SIL.FieldWorks.LexicalProvider -{ - - /// ---------------------------------------------------------------------------------------- - /// - /// Manages FieldWorks's lexical service provider for access by external applications. - /// - /// ---------------------------------------------------------------------------------------- - internal static class LexicalProviderManager - { - private const int kInactivityTimeout = 1800000; // 30 minutes in msec - - private static Timer s_lexicalProviderTimer; - private static readonly Dictionary s_runningProviders = new Dictionary(); - - private static string PtCommunicationProbTitle = "Paratext Communication Problem"; - private static string PtCommunicationProb = - "The project you are opening will not communicate with Paratext because a project with the same name is " + - "already open. If you want to use Paratext with this project, make a change in this project" + - " (so that it will start first), close both projects, then restart Flex."; - - // The different URL prefixes that are required for Windows named pipes and Linux basic http binding. - #if __MonoCS__ - // Just in case port 40001 is in use for something else on a particular system, we allow the user to configure both - // programs to use a different port. - internal static string UrlPrefix = "http://127.0.0.1:" + (Environment.GetEnvironmentVariable("LEXICAL_PROVIDER_PORT") ?? "40001") + "/"; - #else - internal const string UrlPrefix = "net.pipe://localhost/"; - #endif - - // Mono requires the pipe handle to use slashes instead of colons. - // We could put this conditional code somewhere in the routines that generate the pipe handles, - // but it seemed cleaner to keep all the conditional code for different kinds of pipe more-or-less in one place. - internal static string FixPipeHandle(string pipeHandle) - { - #if __MonoCS__ - return pipeHandle.Replace (":", "/"); - #else - return pipeHandle; - #endif - } - - /// ------------------------------------------------------------------------------------ - /// - /// Creates a LexicalServiceProvider listener for the specified project. - /// - /// ------------------------------------------------------------------------------------ - internal static void StartLexicalServiceProvider(ProjectId projectId, FdoCache cache) - { - if (projectId == null) - throw new InvalidOperationException("Project identity must be known before creating the lexical provider listener"); - var url = UrlPrefix + FixPipeHandle(projectId.PipeHandle); - StartProvider(new Uri(url), - new LexicalServiceProvider(cache), typeof(ILexicalServiceProvider)); - - s_lexicalProviderTimer = new Timer(s_timeSinceLexicalProviderUsed_Tick, null, - kInactivityTimeout, Timeout.Infinite); - Logger.WriteEvent("Started listening for lexical service provider requests."); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Starts the provider. - /// - /// The provider location. - /// The provider. - /// Type of the provider. - /// ------------------------------------------------------------------------------------ - [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", - Justification="See review comment")] - [SuppressMessage("Gendarme.Rules.Portability", "MonoCompatibilityReviewRule", - Justification="See TODO-Linux comment")] - internal static void StartProvider(Uri providerLocation, object provider, Type providerType) - { - if (s_runningProviders.ContainsKey(providerType)) - return; - - string sNamedPipe = providerLocation.ToString(); - // REVIEW: we don't dispose ServiceHost. It might be better to add it to the - // SingletonsContainer - ServiceHost providerHost = null; - try - { - providerHost = new ServiceHost(provider); - // Named pipes are better for Windows...don't tie up a dedicated port and perform better. - // However, Mono does not yet support them, so on Mono we use a different binding. - // Note that any attempt to unify these will require parallel changes in Paratext - // and some sort of coordinated release of the new versions. -#if __MonoCS__ - BasicHttpBinding binding = new BasicHttpBinding(); -#else - NetNamedPipeBinding binding = new NetNamedPipeBinding(); - binding.Security.Mode = NetNamedPipeSecurityMode.None; -#endif - binding.MaxBufferSize *= 4; - binding.MaxReceivedMessageSize *= 4; - binding.MaxBufferPoolSize *= 2; - binding.ReaderQuotas.MaxBytesPerRead *= 4; - binding.ReaderQuotas.MaxArrayLength *= 4; - binding.ReaderQuotas.MaxDepth *= 4; - binding.ReaderQuotas.MaxNameTableCharCount *= 4; - binding.ReaderQuotas.MaxStringContentLength *= 4; - - providerHost.AddServiceEndpoint(providerType, binding, sNamedPipe); - providerHost.Open(); - } - catch (Exception e) - { - Logger.WriteError(e); - providerHost = null; - var paratextInstalled = FwRegistryHelper.Paratext7orLaterInstalled(); - if (paratextInstalled) - { - MessageBox.Show(PtCommunicationProb, PtCommunicationProbTitle, - MessageBoxButtons.OK, MessageBoxIcon.Information); - } - return; - } - Logger.WriteEvent("Started provider " + providerLocation + " for type " + providerType + "."); - s_runningProviders.Add(providerType, providerHost); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Resets the lexical provider timer. - /// - /// ------------------------------------------------------------------------------------ - internal static void ResetLexicalProviderTimer() - { - s_lexicalProviderTimer.Change(kInactivityTimeout, Timeout.Infinite); - FieldWorks.InAppServerMode = true; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Releases unmanaged and - optionally - managed resources - /// - /// ------------------------------------------------------------------------------------ - internal static void StaticDispose() - { - Logger.WriteEvent("Closing service hosts"); - - if (s_lexicalProviderTimer != null) - s_lexicalProviderTimer.Dispose(); - s_lexicalProviderTimer = null; - - foreach (ServiceHost host in s_runningProviders.Values) - host.Close(); - s_runningProviders.Clear(); - FieldWorks.InAppServerMode = false; // Make sure FW can shut down - } - - /// ------------------------------------------------------------------------------------ - /// - /// Handles the Tick event of the s_timeSinceLexicalProviderUsed control. - /// - /// The source of the event. - /// ------------------------------------------------------------------------------------ - private static void s_timeSinceLexicalProviderUsed_Tick(object sender) - { - FieldWorks.InAppServerMode = false; - if (FieldWorks.ProcessCanBeAutoShutDown) - FieldWorks.GracefullyShutDown(); - } - } -} diff --git a/Src/Common/FieldWorks/LexicalProvider/LexicalServiceProvider.cs b/Src/Common/FieldWorks/LexicalProvider/LexicalServiceProvider.cs deleted file mode 100644 index ffe189a08b..0000000000 --- a/Src/Common/FieldWorks/LexicalProvider/LexicalServiceProvider.cs +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2011-2013 SIL International -// This software is licensed under the LGPL, version 2.1 or later -// (http://www.gnu.org/licenses/lgpl-2.1.html) -// -// File: LexicalServiceProvider.cs -// Responsibility: FW Team - -using System; -using System.Diagnostics.CodeAnalysis; -using System.ServiceModel; -using SIL.FieldWorks.Common.FwUtils; -using SIL.FieldWorks.FDO; - -namespace SIL.FieldWorks.LexicalProvider -{ - /// ---------------------------------------------------------------------------------------- - /// - /// Provides a service contract for getting a lexical provider from an application. - /// - /// ---------------------------------------------------------------------------------------- - [ServiceBehavior(IncludeExceptionDetailInFaults = true, - InstanceContextMode = InstanceContextMode.Single, - MaxItemsInObjectGraph = 2147483647)] - [SuppressMessage("Gendarme.Rules.Design", "TypesWithDisposableFieldsShouldBeDisposableRule", - Justification="m_cache is a reference")] - public sealed class LexicalServiceProvider : ILexicalServiceProvider - { - /// String representing the type of the LexicalProvider - public const string kLexicalProviderType = "LexicalProvider"; - private const int kSupportedLexicalProviderVersion = 3; - - private FdoCache m_cache; - - /// ------------------------------------------------------------------------------------ - /// - /// Initializes a new instance of the class. - /// - /// ------------------------------------------------------------------------------------ - public LexicalServiceProvider(FdoCache cache) - { - m_cache = cache; - } - - #region ILexicalServiceProvider Members - /// ------------------------------------------------------------------------------------ - /// - /// Gets the location for the provider for the specified project and provider type. - /// If the providerType is not supported, return null for the Uri. - /// - /// ------------------------------------------------------------------------------------ - public Uri GetProviderLocation(string projhandle, string providerType) - { - LexicalProviderManager.ResetLexicalProviderTimer(); - - if (providerType == kLexicalProviderType) - { - var url = LexicalProviderManager.UrlPrefix + LexicalProviderManager.FixPipeHandle(FwUtils.GeneratePipeHandle(projhandle + ":LP")); - Uri projUri = new Uri(url); - LexicalProviderManager.StartProvider(projUri, new LexicalProviderImpl(m_cache), typeof(ILexicalProvider)); - return projUri; - } - - return null; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the version of the specified provider that the server supports. If the - /// providerType is not supported, return 0 for the version. - /// - /// ------------------------------------------------------------------------------------ - public int GetSupportedVersion(string providerType) - { - LexicalProviderManager.ResetLexicalProviderTimer(); - if (providerType == kLexicalProviderType) - return kSupportedLexicalProviderVersion; - return 0; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Unlike a normal ping method that gets a response, we just use this ping method - /// to determine if the service provider is actually valid since no exception is - /// thrown until a method is called. - /// - /// ------------------------------------------------------------------------------------ - public void Ping() - { - // Nothing to do for this method except reset our timer for the life of the LexicalProvider. - // See comment for this method. - LexicalProviderManager.ResetLexicalProviderTimer(); - } - - #endregion - } -} diff --git a/Src/Common/FieldWorks/PaObjects/PaLexicalInfo.cs b/Src/Common/FieldWorks/PaObjects/PaLexicalInfo.cs index 503dc25f09..d784ce0505 100644 --- a/Src/Common/FieldWorks/PaObjects/PaLexicalInfo.cs +++ b/Src/Common/FieldWorks/PaObjects/PaLexicalInfo.cs @@ -13,7 +13,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Drawing; -using System.Linq; using System.Threading; using System.Windows.Forms; using SIL.PaToFdoInterfaces; @@ -52,7 +51,7 @@ public void Dispose() /// protected virtual void Dispose(bool fDisposing) { - System.Diagnostics.Debug.WriteLineIf(!fDisposing, "****** Missing Dispose() call for " + GetType().ToString() + " *******"); + Debug.WriteLineIf(!fDisposing, "****** Missing Dispose() call for " + GetType() + " *******"); if (fDisposing && !IsDisposed) { // dispose managed and unmanaged objects @@ -240,7 +239,7 @@ private bool LoadFwDataForPa(PaRemoteRequest requestor, string name, string serv /// ------------------------------------------------------------------------------------ public IEnumerable LexEntries { - get { return m_lexEntries.Cast(); } + get { return m_lexEntries; } } /// ------------------------------------------------------------------------------------ @@ -250,7 +249,7 @@ public IEnumerable LexEntries /// ------------------------------------------------------------------------------------ public IEnumerable WritingSystems { - get { return m_writingSystems.Cast(); } + get { return m_writingSystems; } } #endregion diff --git a/Src/Common/FieldWorks/ProjectId.cs b/Src/Common/FieldWorks/ProjectId.cs index f9758c0848..f8ab610fc3 100644 --- a/Src/Common/FieldWorks/ProjectId.cs +++ b/Src/Common/FieldWorks/ProjectId.cs @@ -8,10 +8,9 @@ using System; using System.Diagnostics; using System.Net; +using SIL.CoreImpl; using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.DomainServices; -using SIL.FieldWorks.FDO.Infrastructure; -using SIL.FieldWorks.Resources; using SIL.Utils; using System.Runtime.Serialization; using SIL.FieldWorks.Common.FwUtils; @@ -39,7 +38,7 @@ public class ProjectId : ISerializable, IProjectIdentifier #region Member variables private string m_path; - private readonly FDOBackendProviderType m_type; + private FDOBackendProviderType m_type; private readonly string m_serverName; #endregion @@ -147,6 +146,7 @@ private static string LocalHostName public FDOBackendProviderType Type { get { return m_type; } + set { m_type = value; } } /// ------------------------------------------------------------------------------------ @@ -193,7 +193,7 @@ public string Handle { get { - return !IsLocal || (DirectoryFinder.IsSubFolderOfProjectsDirectory(ProjectFolder) && + return !IsLocal || (FwDirectoryFinder.IsSubFolderOfProjectsDirectory(ProjectFolder) && SysPath.GetExtension(m_path) == ClientServerServices.Current.Local.DefaultBackendType.GetExtension()) ? Name : m_path; } @@ -241,7 +241,7 @@ public string ProjectFolder get { return IsLocal ? SysPath.GetDirectoryName(m_path) : - SysPath.Combine(SysPath.Combine(DirectoryFinder.ProjectsDirectory, ServerName), Name); + SysPath.Combine(SysPath.Combine(FwDirectoryFinder.ProjectsDirectory, ServerName), Name); } } @@ -259,7 +259,7 @@ public string SharedProjectFolder return ProjectFolder; // TODO-Linux FWNX-446: Implement alternative way of getting path to shared folder // Currently assumes projects also exist in the local Project Directory. - string baseDir = (MiscUtils.IsUnix) ? DirectoryFinder.ProjectsDirectory : + string baseDir = (MiscUtils.IsUnix) ? FwDirectoryFinder.ProjectsDirectory : @"\\" + ServerName + @"\Projects"; return SysPath.Combine(baseDir, Name); } @@ -315,7 +315,8 @@ public string UiName } return string.Format(Properties.Resources.ksProjectNameAndServerFmt, Name, hostName); case FDOBackendProviderType.kXML: - return (SysPath.GetExtension(Path) != FwFileExtensions.ksFwDataXmlFileExtension) ? + case FDOBackendProviderType.kSharedXML: + return (SysPath.GetExtension(Path) != FdoFileHelper.ksFwDataXmlFileExtension) ? SysPath.GetFileName(Path) : Name; case FDOBackendProviderType.kInvalid: return string.Empty; @@ -339,7 +340,7 @@ public bool IsValid var ex = GetExceptionIfInvalid(); if (ex == null) return true; - if (ex is FwStartupException) + if (ex is StartupException) return false; // something totally unexpected that we don't know how to handle happened. // Don't suppress it. @@ -375,7 +376,7 @@ public string TypeString /// /// here. /// - /// If invalid (e.g., project Name is not set, the + /// If invalid (e.g., project Name is not set, the /// XML file can not be found, etc.) /// ------------------------------------------------------------------------------------ public void AssertValid() @@ -396,7 +397,7 @@ public void AssertValid() internal Exception GetExceptionIfInvalid() { if (string.IsNullOrEmpty(Name)) - return new FwStartupException(Properties.Resources.kstidNoProjectName, false); + return new StartupException(Properties.Resources.kstidNoProjectName, false); switch (Type) { @@ -407,7 +408,7 @@ internal Exception GetExceptionIfInvalid() } catch (SocketException e) { - return new FwStartupException(String.Format(Properties.Resources.kstidInvalidServer, ServerName, e.Message), e); + return new StartupException(String.Format(Properties.Resources.kstidInvalidServer, ServerName, e.Message), e); } catch (Exception ex) { @@ -415,11 +416,12 @@ internal Exception GetExceptionIfInvalid() } break; case FDOBackendProviderType.kXML: + case FDOBackendProviderType.kSharedXML: if (!FileUtils.SimilarFileExists(Path)) - return new FwStartupException(string.Format(Properties.Resources.kstidFileNotFound, Path)); + return new StartupException(string.Format(Properties.Resources.kstidFileNotFound, Path)); break; case FDOBackendProviderType.kInvalid: - return new FwStartupException(Properties.Resources.kstidInvalidFwProjType); + return new StartupException(Properties.Resources.kstidInvalidFwProjType); default: return new NotImplementedException("Unknown type of project."); } @@ -427,7 +429,7 @@ internal Exception GetExceptionIfInvalid() // Check this after checking for other valid information (e.g. if the server is // not available, we want to show that error, not this error). if (!FileUtils.DirectoryExists(SharedProjectFolder)) - return new FwStartupException(String.Format(Properties.Resources.kstidCannotAccessProjectPath, SharedProjectFolder)); + return new StartupException(String.Format(Properties.Resources.kstidCannotAccessProjectPath, SharedProjectFolder)); return null; // valid } @@ -524,12 +526,12 @@ private static string CleanUpNameForType(FDOBackendProviderType type, string nam switch (type) { case FDOBackendProviderType.kXML: - ext = FwFileExtensions.ksFwDataXmlFileExtension; + ext = FdoFileHelper.ksFwDataXmlFileExtension; break; case FDOBackendProviderType.kDb4oClientServer: if (!IsServerLocal(server)) return name; - ext = FwFileExtensions.ksFwDataDb4oFileExtension; + ext = FdoFileHelper.ksFwDataDb4oFileExtension; break; default: return name; @@ -538,7 +540,7 @@ private static string CleanUpNameForType(FDOBackendProviderType type, string nam if (!SysPath.IsPathRooted(name)) { string sProjName = (SysPath.GetExtension(name) == ext) ? SysPath.GetFileNameWithoutExtension(name) : name; - name = SysPath.Combine(SysPath.Combine(DirectoryFinder.ProjectsDirectory, sProjName), name); + name = SysPath.Combine(SysPath.Combine(FwDirectoryFinder.ProjectsDirectory, sProjName), name); } // If the file doesn't have the expected extension and exists with the extension or // does not exist without it, we add the expected extension. @@ -578,9 +580,9 @@ private static FDOBackendProviderType GetType(string type, string pathname, stri switch (ext) // Includes period. { case ".db4o": // for historical purposes - case FwFileExtensions.ksFwDataDb4oFileExtension: + case FdoFileHelper.ksFwDataDb4oFileExtension: return FDOBackendProviderType.kDb4oClientServer; - case FwFileExtensions.ksFwDataXmlFileExtension: + case FdoFileHelper.ksFwDataXmlFileExtension: return FDOBackendProviderType.kXML; } } diff --git a/Src/Common/FieldWorks/Properties/Resources.Designer.cs b/Src/Common/FieldWorks/Properties/Resources.Designer.cs index 5b79962ab0..cc4579cf6c 100644 --- a/Src/Common/FieldWorks/Properties/Resources.Designer.cs +++ b/Src/Common/FieldWorks/Properties/Resources.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.296 +// Runtime Version:4.0.30319.18052 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -60,6 +60,9 @@ internal Resources() { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// internal static System.Drawing.Bitmap DatabaseNew { get { object obj = ResourceManager.GetObject("DatabaseNew", resourceCulture); @@ -67,6 +70,9 @@ internal static System.Drawing.Bitmap DatabaseNew { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// internal static System.Drawing.Bitmap Download { get { object obj = ResourceManager.GetObject("Download", resourceCulture); @@ -74,6 +80,9 @@ internal static System.Drawing.Bitmap Download { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// internal static System.Drawing.Bitmap Import { get { object obj = ResourceManager.GetObject("Import", resourceCulture); @@ -81,6 +90,9 @@ internal static System.Drawing.Bitmap Import { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// internal static System.Drawing.Bitmap Info { get { object obj = ResourceManager.GetObject("Info", resourceCulture); @@ -198,6 +210,24 @@ internal static string ksInsufficientPrivilegesToUpdateProjectLocationText { } } + /// + /// Looks up a localized string similar to {0} is not a valid directory for linked files. Please select a valid directory.. + /// + internal static string ksInvalidLinkedFilesFolder { + get { + return ResourceManager.GetString("ksInvalidLinkedFilesFolder", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Linked Files Folder. + /// + internal static string ksLinkedFilesFolder { + get { + return ResourceManager.GetString("ksLinkedFilesFolder", resourceCulture); + } + } + /// /// Looks up a localized string similar to Migrate projects. /// @@ -566,6 +596,9 @@ internal static string ksYouCanTryToMoveProjects { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// internal static System.Drawing.Bitmap OpenFile { get { object obj = ResourceManager.GetObject("OpenFile", resourceCulture); @@ -573,6 +606,9 @@ internal static System.Drawing.Bitmap OpenFile { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// internal static System.Drawing.Bitmap Receive { get { object obj = ResourceManager.GetObject("Receive", resourceCulture); @@ -580,6 +616,9 @@ internal static System.Drawing.Bitmap Receive { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// internal static System.Drawing.Bitmap SendReceiveGetArrow32x32 { get { object obj = ResourceManager.GetObject("SendReceiveGetArrow32x32", resourceCulture); diff --git a/Src/Common/FieldWorks/Properties/Resources.resx b/Src/Common/FieldWorks/Properties/Resources.resx index 2fe644bee5..44c45ac29a 100644 --- a/Src/Common/FieldWorks/Properties/Resources.resx +++ b/Src/Common/FieldWorks/Properties/Resources.resx @@ -327,4 +327,12 @@ We have sometimes seen cases where installing other software leaves the machine We don't know why this happens. If you have any idea what recently changed on your computer to cause it, please pass this on to the developers. This message should never be seen. Some users however have gotten into a weird state we don't understand where they have to run-as-administrator in order to access required local-machine keys. + + {0} is not a valid directory for linked files. Please select a valid directory. + Error message for accessing an invalid LangProject.LinkedFilesRootDir value + + + Linked Files Folder + Caption for folder dialog, when setting a new LangProject.LinkedFilesRootDir value + \ No newline at end of file diff --git a/Src/Common/FieldWorks/ShareProjectsFolderDlg.cs b/Src/Common/FieldWorks/ShareProjectsFolderDlg.cs index e0e629590e..f0bede8546 100644 --- a/Src/Common/FieldWorks/ShareProjectsFolderDlg.cs +++ b/Src/Common/FieldWorks/ShareProjectsFolderDlg.cs @@ -28,7 +28,7 @@ public partial class ShareProjectsFolderDlg : Form { /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// ------------------------------------------------------------------------------------ public ShareProjectsFolderDlg() @@ -39,7 +39,7 @@ public ShareProjectsFolderDlg() private void m_btnViewFolder_Click(object sender, EventArgs e) { // This fires up Windows Explorer, showing the owner of the projects folder. - using (Process.Start(Path.GetDirectoryName(DirectoryFinder.ProjectsDirectory))) + using (Process.Start(Path.GetDirectoryName(FwDirectoryFinder.ProjectsDirectory))) { } } diff --git a/Src/Common/FieldWorks/WelcomeToFieldWorksDlg.cs b/Src/Common/FieldWorks/WelcomeToFieldWorksDlg.cs index fe9fb1ad2f..3d92f6169c 100644 --- a/Src/Common/FieldWorks/WelcomeToFieldWorksDlg.cs +++ b/Src/Common/FieldWorks/WelcomeToFieldWorksDlg.cs @@ -8,9 +8,9 @@ using System.ComponentModel; using System.Diagnostics; using System.Windows.Forms; -using Palaso.Reporting; -using SIL.CoreImpl.Properties; +using SIL.CoreImpl; using SIL.FieldWorks.Common.FwUtils; +using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.DomainServices; using SIL.Utils; using XCore; @@ -71,7 +71,7 @@ public enum ButtonPress /// True (usually only on the first run) when we want to show the first-time warning about /// sending google analytics information /// ------------------------------------------------------------------------------------ - public WelcomeToFieldWorksDlg(IHelpTopicProvider helpTopicProvider, string appAbbrev, FwStartupException exception, bool showReportingRow) + public WelcomeToFieldWorksDlg(IHelpTopicProvider helpTopicProvider, string appAbbrev, StartupException exception, bool showReportingRow) { m_appAbbrev = appAbbrev; InitializeComponent(); @@ -102,7 +102,7 @@ public WelcomeToFieldWorksDlg(IHelpTopicProvider helpTopicProvider, string appAb m_helpTopicProvider = helpTopicProvider; helpProvider = new HelpProvider(); - helpProvider.HelpNamespace = DirectoryFinder.FWCodeDirectory + m_helpTopicProvider.GetHelpString("UserHelpFile"); + helpProvider.HelpNamespace = FwDirectoryFinder.CodeDirectory + m_helpTopicProvider.GetHelpString("UserHelpFile"); helpProvider.SetHelpKeyword(this, m_helpTopicProvider.GetHelpString(m_helpTopic)); helpProvider.SetHelpNavigator(this, HelpNavigator.Topic); receiveButton.Enabled = diff --git a/Src/Common/Filters/DateTimeMatcher.cs b/Src/Common/Filters/DateTimeMatcher.cs index 0dc553ce5f..d9d2957b4f 100644 --- a/Src/Common/Filters/DateTimeMatcher.cs +++ b/Src/Common/Filters/DateTimeMatcher.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; using System.Globalization; - +using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; using SIL.Utils; using SIL.FieldWorks.Common.FwUtils; diff --git a/Src/Common/Framework/ExternalSettingsAccessorBase.cs b/Src/Common/Framework/ExternalSettingsAccessorBase.cs index 07790fb7f8..327b06c4bb 100644 --- a/Src/Common/Framework/ExternalSettingsAccessorBase.cs +++ b/Src/Common/Framework/ExternalSettingsAccessorBase.cs @@ -148,7 +148,7 @@ static protected void ReportInvalidInstallation(string message, Exception e) /// /// The progress dialog if one is already up. /// ------------------------------------------------------------------------------------ - public void EnsureCurrentResource(IProgress progressDlg) + public void EnsureCurrentResource(IThreadedProgress progressDlg) { var doc = LoadDoc(); Guid newVersion; @@ -166,13 +166,7 @@ public void EnsureCurrentResource(IProgress progressDlg) // Re-load the factory settings if they are not at current version. if (IsResourceOutdated(ResourceName, newVersion)) { - if (progressDlg is IThreadedProgress) - ProcessResources((IThreadedProgress)progressDlg, doc); - else - { - using (var dlg = new ProgressDialogWithTask(progressDlg)) - ProcessResources(dlg, doc); - } + ProcessResources(progressDlg, doc); #if DEBUG Debug.Assert(m_fVersionUpdated); #endif @@ -188,7 +182,7 @@ public void EnsureCurrentResource(IProgress progressDlg) /// (i.e., IsResourceOutdated returns false for ResourceName. /// /// ------------------------------------------------------------------------------------ - protected virtual void EnsureCurrentLocalizations(IProgress progressDlg) + protected virtual void EnsureCurrentLocalizations(IThreadedProgress progressDlg) { // Default is a no-op } diff --git a/Src/Common/Framework/Framework.csproj b/Src/Common/Framework/Framework.csproj index 1bd34cd8b7..7759329535 100644 --- a/Src/Common/Framework/Framework.csproj +++ b/Src/Common/Framework/Framework.csproj @@ -244,7 +244,9 @@ Code - + + UserControl + diff --git a/Src/Common/Framework/FrameworkTests/MainWindowDelegateTests.cs b/Src/Common/Framework/FrameworkTests/MainWindowDelegateTests.cs index e5fc9ec1de..b25988d753 100644 --- a/Src/Common/Framework/FrameworkTests/MainWindowDelegateTests.cs +++ b/Src/Common/Framework/FrameworkTests/MainWindowDelegateTests.cs @@ -151,7 +151,7 @@ public DummyFwApp() : base(null, null) #region abstract members of SIL.FieldWorks.Common.Framework.FwApp /// - public override bool InitCacheForApp(IProgress progressDlg) + public override bool InitCacheForApp(IThreadedProgress progressDlg) { throw new System.NotImplementedException(); } diff --git a/Src/Common/Framework/FwApp.cs b/Src/Common/Framework/FwApp.cs index 1f905a168a..f2f0851eaa 100644 --- a/Src/Common/Framework/FwApp.cs +++ b/Src/Common/Framework/FwApp.cs @@ -263,7 +263,7 @@ public virtual void DoApplicationInitialization(IProgress progressDlg) /// The progress dialog. /// True if the initialization was successful, false otherwise /// ------------------------------------------------------------------------------------ - public abstract bool InitCacheForApp(IProgress progressDlg); + public abstract bool InitCacheForApp(IThreadedProgress progressDlg); /// ------------------------------------------------------------------------------------ diff --git a/Src/Common/Framework/FwMainWnd.cs b/Src/Common/Framework/FwMainWnd.cs index 462ca07ae5..e396a7aaa3 100644 --- a/Src/Common/Framework/FwMainWnd.cs +++ b/Src/Common/Framework/FwMainWnd.cs @@ -334,7 +334,7 @@ protected void InitStyleSheet(int hvoStylesOwner, int tagStylesList) if (m_cache == null) throw new Exception("Cache not yet intialized."); - StyleSheet.Init(m_cache, hvoStylesOwner, tagStylesList); + StyleSheet.Init(m_cache, hvoStylesOwner, tagStylesList, ResourceHelper.DefaultParaCharsStyleName); InitStyleComboBox(); } @@ -347,7 +347,7 @@ protected void InitStyleSheet(int hvoStylesOwner, int tagStylesList) protected void ReSynchStyleSheet() { Debug.Assert(StyleSheet != null); - StyleSheet.Init(m_cache, StyleSheet.RootObjectHvo, StyleSheet.StyleListTag); + StyleSheet.Init(m_cache, StyleSheet.RootObjectHvo, StyleSheet.StyleListTag, ResourceHelper.DefaultParaCharsStyleName); InitStyleComboBox(); } #endregion @@ -409,7 +409,7 @@ protected virtual void CreateMenusAndToolBars() // Use this to initialize combo box items. m_tmAdapter.InitializeComboItem += InitializeToolBarCombos; - string sMenuToolBarDefinition = Path.Combine(DirectoryFinder.FWCodeDirectory, "FwTMDefinition.xml"); + string sMenuToolBarDefinition = Path.Combine(FwDirectoryFinder.CodeDirectory, "FwTMDefinition.xml"); m_tmAdapter.Initialize(this, AdapterContentControl, m_mediator, m_app.ProjectSpecificSettingsKey.ToString(), new string[] { sMenuToolBarDefinition, GetAppSpecificMenuToolBarDefinition() }); diff --git a/Src/Common/Framework/FwRegistrySettings.cs b/Src/Common/Framework/FwRegistrySettings.cs index ad086fd2fa..958804608c 100644 --- a/Src/Common/Framework/FwRegistrySettings.cs +++ b/Src/Common/Framework/FwRegistrySettings.cs @@ -334,7 +334,7 @@ public void AddErrorReportingInfo() ErrorReporter.AddProperty("AutoOpenLastEditedProjectSetting", AutoOpenLastEditedProject.ToString()); ErrorReporter.AddProperty("DisableSplashScreenSetting", DisableSplashScreenSetting.ToString()); ErrorReporter.AddProperty("MeasurementUnitSetting", ((MsrSysType)MeasurementUnitSetting).ToString()); - ErrorReporter.AddProperty("BackupDirectorySetting", DirectoryFinder.DefaultBackupDirectory); + ErrorReporter.AddProperty("BackupDirectorySetting", FwDirectoryFinder.DefaultBackupDirectory); } } } diff --git a/Src/Common/Framework/HelpTopicProviderBase.cs b/Src/Common/Framework/HelpTopicProviderBase.cs index 186d2fe9eb..c651fbf53c 100644 --- a/Src/Common/Framework/HelpTopicProviderBase.cs +++ b/Src/Common/Framework/HelpTopicProviderBase.cs @@ -40,7 +40,7 @@ public string HelpFile { get { - return DirectoryFinder.FWCodeDirectory + GetHelpString("UserHelpFile"); + return FwDirectoryFinder.CodeDirectory + GetHelpString("UserHelpFile"); } } #endregion diff --git a/Src/Common/Framework/SettingsXmlAccessorBase.cs b/Src/Common/Framework/SettingsXmlAccessorBase.cs index 88d82aecf4..16ad3ac67f 100644 --- a/Src/Common/Framework/SettingsXmlAccessorBase.cs +++ b/Src/Common/Framework/SettingsXmlAccessorBase.cs @@ -83,7 +83,7 @@ protected override Guid GetVersion(XmlNode baseNode) Justification = "TODO-Linux: XmlReaderSettings.DtdProcessing is missing from Mono")] protected override XmlNode LoadDoc() { - string sXmlFilePath = DirectoryFinder.FWCodeDirectory + ResourceFilePathFromFwInstall; + string sXmlFilePath = FwDirectoryFinder.CodeDirectory + ResourceFilePathFromFwInstall; try { XmlReaderSettings settings = new XmlReaderSettings(); diff --git a/Src/Common/Framework/StatusBarProgressHandler.cs b/Src/Common/Framework/StatusBarProgressHandler.cs index 2a1d6c6330..58406675b6 100644 --- a/Src/Common/Framework/StatusBarProgressHandler.cs +++ b/Src/Common/Framework/StatusBarProgressHandler.cs @@ -188,6 +188,15 @@ public bool Canceled get { return false; } } + /// + /// Gets an object to be used for ensuring that required tasks are invoked on the main + /// UI thread. + /// + public ISynchronizeInvoke SynchronizeInvoke + { + get { return m_progressBar.Control; } + } + /// ------------------------------------------------------------------------------------ /// /// Gets the progress as a form (used for message box owners, etc). @@ -200,15 +209,13 @@ public Form Form get { return m_progressBar.Control.FindForm(); } } - /// ------------------------------------------------------------------------------------ /// - /// Gets or sets the progress bar style. + /// Gets or sets a value indicating whether this progress is indeterminate. /// - /// ------------------------------------------------------------------------------------ - public ProgressBarStyle ProgressBarStyle + public bool IsIndeterminate { - get { return m_progressBar.Style; } - set { m_progressBar.Style = value; } + get { return m_progressBar.Style == ProgressBarStyle.Marquee; } + set { m_progressBar.Style = value ? ProgressBarStyle.Marquee : ProgressBarStyle.Blocks; } } /// ------------------------------------------------------------------------------------ diff --git a/Src/Common/Framework/StylesXmlAccessor.cs b/Src/Common/Framework/StylesXmlAccessor.cs index fd6b003a44..c539cb9778 100644 --- a/Src/Common/Framework/StylesXmlAccessor.cs +++ b/Src/Common/Framework/StylesXmlAccessor.cs @@ -12,7 +12,6 @@ using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Globalization; -using System.Linq; using System.Xml; using SIL.FieldWorks.Common.FwUtils; @@ -457,14 +456,14 @@ private void CreateAndUpdateStyles(XmlNodeList tagList) } SetFontProperties(styleName, styleTag, - ((tpt, nVar, nVal) => m_cache.ThreadHelper.Invoke(() => propsBldr.SetIntPropValues(tpt, nVar, nVal))), - ((tpt, sVal) => m_cache.ThreadHelper.Invoke(() => propsBldr.SetStrPropValue(tpt, sVal))), + ((tpt, nVar, nVal) => m_progressDlg.SynchronizeInvoke.Invoke(() => propsBldr.SetIntPropValues(tpt, nVar, nVal))), + ((tpt, sVal) => m_progressDlg.SynchronizeInvoke.Invoke(() => propsBldr.SetStrPropValue(tpt, sVal))), option); // Get paragraph properties if (style.Type == StyleType.kstParagraph) SetParagraphProperties(styleName, styleTag, - ((tpt, nVar, nVal) => m_cache.ThreadHelper.Invoke(() => propsBldr.SetIntPropValues(tpt, nVar, nVal))), + ((tpt, nVar, nVal) => m_progressDlg.SynchronizeInvoke.Invoke(() => propsBldr.SetIntPropValues(tpt, nVar, nVal))), option); style.Rules = propsBldr.GetTextProps(); diff --git a/Src/Common/FwRemoteDatabaseConnectorService/FwRemoteDatabaseConnectorService.csproj b/Src/Common/FwRemoteDatabaseConnectorService/FwRemoteDatabaseConnectorService.csproj index 45d854a45f..c7c8ee46c5 100644 --- a/Src/Common/FwRemoteDatabaseConnectorService/FwRemoteDatabaseConnectorService.csproj +++ b/Src/Common/FwRemoteDatabaseConnectorService/FwRemoteDatabaseConnectorService.csproj @@ -12,11 +12,14 @@ FwRemoteDatabaseConnectorService v4.0 512 - - + + + + - + + 3.5 @@ -70,6 +73,14 @@ ..\..\..\Output\Debug\FDO.dll + + False + ..\..\..\Output\Debug\FwUtils.dll + + + False + ..\..\..\Output\Debug\SilUtils.dll + diff --git a/Src/Common/FwRemoteDatabaseConnectorService/Program.cs b/Src/Common/FwRemoteDatabaseConnectorService/Program.cs index 0ae61801fa..922ab04f87 100644 --- a/Src/Common/FwRemoteDatabaseConnectorService/Program.cs +++ b/Src/Common/FwRemoteDatabaseConnectorService/Program.cs @@ -1,4 +1,8 @@ using System.ServiceProcess; +using SIL.FieldWorks.Common.FwUtils; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.FDO.DomainServices; +using SIL.Utils; namespace FwRemoteDatabaseConnectorService { @@ -9,6 +13,14 @@ static class Program /// static void Main() { + // We need FieldWorks here to get the correct registry key HKLM\Software\SIL\FieldWorks. + // The default without this would be HKLM\Software\SIL\SIL FieldWorks, + // which breaks FwRemoteDatabaseConnectorService.exe. + RegistryHelper.ProductName = "FieldWorks"; + + ClientServerServices.SetCurrentToDb4OBackend(new SilentFdoUI(new SingleThreadedSynchronizeInvoke()), + FwDirectoryFinder.FdoDirectories, () => FwDirectoryFinder.ProjectsDirectory == FwDirectoryFinder.ProjectsDirectoryLocalMachine); + ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { diff --git a/Src/Common/FwRemoteDatabaseConnectorService/Service1.cs b/Src/Common/FwRemoteDatabaseConnectorService/Service1.cs index fade05db75..811b1d67ed 100644 --- a/Src/Common/FwRemoteDatabaseConnectorService/Service1.cs +++ b/Src/Common/FwRemoteDatabaseConnectorService/Service1.cs @@ -4,12 +4,15 @@ using System.ServiceProcess; using System.Threading; using FwRemoteDatabaseConnector; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices; namespace FwRemoteDatabaseConnectorService { public partial class FwRemoteDatabaseConnectorService : ServiceBase { + private const string ksSharedProjectKey = "ProjectShared"; + private Thread m_clientListenerThread; private Socket m_clientListenerSocket; @@ -55,7 +58,7 @@ protected override void OnStart(string[] args) { try { - RemotingServer.Start(); + RemotingServer.Start(FwDirectoryFinder.RemotingTcpServerConfigFile, FwDirectoryFinder.FdoDirectories, GetSharedProject, SetSharedProject); } catch (Exception e) { @@ -67,6 +70,19 @@ protected override void OnStart(string[] args) m_clientListenerThread.Start(); } + private static bool GetSharedProject() + { + bool result; + FwRegistryHelper.MigrateVersion7ValueIfNeeded(); + var value = FwRegistryHelper.FieldWorksRegistryKey.GetValue(ksSharedProjectKey, "false"); + return (bool.TryParse((string)value, out result) && result); + } + + private static void SetSharedProject(bool v) + { + FwRegistryHelper.FieldWorksRegistryKey.SetValue(ksSharedProjectKey, v); + } + protected override void OnStop() { if (m_clientListenerSocket != null) diff --git a/Src/Common/FwUtils/ConsoleProgress.cs b/Src/Common/FwUtils/ConsoleProgress.cs index 7646dfc492..4c2aa5beae 100644 --- a/Src/Common/FwUtils/ConsoleProgress.cs +++ b/Src/Common/FwUtils/ConsoleProgress.cs @@ -6,6 +6,8 @@ // Responsibility: mcconnel using System; +using System.ComponentModel; +using SIL.Utils; namespace SIL.FieldWorks.Common.FwUtils { @@ -18,6 +20,7 @@ namespace SIL.FieldWorks.Common.FwUtils /// ---------------------------------------------------------------------------------------- public class ConsoleProgress : IProgress { + private readonly SingleThreadedSynchronizeInvoke m_sychronizeInvoke = new SingleThreadedSynchronizeInvoke(); int m_min; int m_max = 100; string m_message; @@ -35,6 +38,15 @@ public bool DotsWritten #region IProgress Members + /// + /// Gets an object to be used for ensuring that required tasks are invoked on the main + /// UI thread. + /// + public ISynchronizeInvoke SynchronizeInvoke + { + get { return m_sychronizeInvoke; } + } + /// /// Gets the form displaying the progress (used for message box owners, etc). If the progress /// is not associated with a visible Form, then this returns its owning form, if any. @@ -44,6 +56,15 @@ public System.Windows.Forms.Form Form get { return null; } } + /// + /// Gets or sets a value indicating whether this progress is indeterminate. + /// + public bool IsIndeterminate + { + get { return false; } + set { } + } + /// /// Gets or sets the maximum value of the progress bar. /// @@ -164,15 +185,6 @@ public bool AllowCancel /// public event System.ComponentModel.CancelEventHandler Canceling; - /// - /// Gets or sets the progress bar style. - /// - public System.Windows.Forms.ProgressBarStyle ProgressBarStyle - { - get { return System.Windows.Forms.ProgressBarStyle.Continuous; } - set { } - } - #endregion } } diff --git a/Src/Common/FwUtils/DirectoryFinder.cs b/Src/Common/FwUtils/DirectoryFinder.cs deleted file mode 100644 index 45e03c3f59..0000000000 --- a/Src/Common/FwUtils/DirectoryFinder.cs +++ /dev/null @@ -1,1296 +0,0 @@ -// Copyright (c) 2003-2013 SIL International -// This software is licensed under the LGPL, version 2.1 or later -// (http://www.gnu.org/licenses/lgpl-2.1.html) -// -// File: DirectoryFinder.cs -// -// -// To find the current user's "My Documents" folder, use something like: -// string sMyDocs = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); -// See the MSDN documentation for the System.Environment.SpecialFolder enumeration for details. -// - -using System; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Diagnostics; -using System.Reflection; -using System.Security; -using System.Security.AccessControl; -using System.Security.Principal; -using System.Text; -using System.Windows.Forms; -using Microsoft.Win32; -using SIL.FieldWorks.Resources; -using SIL.Utils; - -namespace SIL.FieldWorks.Common.FwUtils -{ - /// - /// Summary description for DirectoryFinder. - /// - public static class DirectoryFinder - { - private static string s_CommonAppDataFolder; - - /// - /// The name of the Translation Editor folder (Even though this is the same as - /// FwUtils.ksTeAppName and FwSubKey.TE, PLEASE do not use them interchangeably. Use - /// the one that is correct for your context, in case they need to be changed later.) - /// - public const string ksTeFolderName = FwUtils.ksTeAppName; - /// - /// The name of the Language Explorer folder (Even though this is the same as - /// FwUtils.ksFlexAppName and FwSubKey.LexText, PLEASE do not use them interchangeably. - /// Use the one that is correct for your context, in case they need to be changed later.) - /// - public const string ksFlexFolderName = FwUtils.ksFlexAppName; - - /// The name of the folder containing FLEx configuration settings - public const string ksConfigurationSettingsDir = "ConfigurationSettings"; - /// The name of the folder containing FLEx backup settings - public const string ksBackupSettingsDir = "BackupSettings"; - /// The name of the folder where the user can copy files for backup such as fonts and keyboards - public const string ksSupportingFilesDir = "SupportingFiles"; - /// The default name of the folder containing LinkedFiles (media, pictures, etc) for a project - public const string ksLinkedFilesDir = "LinkedFiles"; - /// The name of the subfolder containing media for a project - public const string ksMediaDir = "AudioVisual"; - /// The name of the subfolder containing pictures for a project - public const string ksPicturesDir = "Pictures"; - /// The name of the subfolder containing other LinkedFiles for a project - public const string ksOtherLinkedFilesDir = "Others"; - /// The name of the folder containing writing systems for a project - public const string ksWritingSystemsDir = "WritingSystemStore"; - /// The name of the folder containing temporary persisted sort sequence info for a project - public const string ksSortSequenceTempDir = "Temp"; - /// The Scripture-specific stylesheet (ideally, this would be in a TE-specific place, but FDO needs it) - public const string kTeStylesFilename = "TeStyles.xml"; - /// The filename of the backup settings file - public const string kBackupSettingsFilename = "BackupSettings.xml"; - - private const string ksBiblicaltermsLocFilePrefix = "BiblicalTerms-"; - private const string ksBiblicaltermsLocFileExtension = ".xml"; - private const string ksProjectsDir = "ProjectsDir"; - - /// - /// Resets the static variables. Used for unit tests. - /// - internal static void ResetStaticVars() - { - s_CommonAppDataFolder = null; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the full path of the Scripture-specific stylesheet. - /// This should NOT be in the TE folder, because it is used by the SE edition, when - /// doing minimal scripture initialization in order to include Paratext texts. - /// - /// ------------------------------------------------------------------------------------ - public static string TeStylesPath - { - get { return Path.Combine(FWCodeDirectory, kTeStylesFilename); } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the full path of the folder where TE-specific files are installed. - /// - /// ------------------------------------------------------------------------------------ - public static string TeFolder - { - get { return GetFWCodeSubDirectory(ksTeFolderName); } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the full path of the folder where FLEx-specific files are installed. - /// - /// ------------------------------------------------------------------------------------ - public static string FlexFolder - { - get { return GetFWCodeSubDirectory(ksFlexFolderName); } - } - - /// - /// Return the folder in which FlexBridge resides, or empty string if it is not installed. - /// - public static string FlexBridgeFolder - { - get { return GetFLExBridgeFolderPath(); } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the path for storing user-specific application data. - /// - /// Name of the application. - /// ------------------------------------------------------------------------------------ - public static string UserAppDataFolder(string appName) - { - string path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); - return Path.Combine(Path.Combine(path, CompanyName), appName); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the path for storing common application data that might be shared between - /// multiple applications and multiple users on the same machine. - /// - /// On Windows this returns Environment.SpecialFolder.CommonApplicationData - /// (C:\ProgramData),on Linux /var/lib/fieldworks. - /// - /// ------------------------------------------------------------------------------------ - private static string CommonApplicationData - { - get - { - if (s_CommonAppDataFolder == null) - { - if (MiscUtils.IsUnix) - { - // allow to override the /var/lib/fieldworks path by setting the - // environment variable FW_CommonAppData. Is this is needed on our CI - // build machines. - s_CommonAppDataFolder = - Environment.GetEnvironmentVariable("FW_CommonAppData") ?? - "/var/lib/fieldworks"; - } - else - { - s_CommonAppDataFolder = - Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); - } - } - return s_CommonAppDataFolder; - } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets a special folder, very similar to Environment.GetFolderPath. The main - /// difference is that this method works cross-platform and does some translations. - /// For example CommonApplicationData (/usr/share) is not writeable on Linux, so we - /// translate that to /var/lib/fieldworks instead. - /// - /// ------------------------------------------------------------------------------------ - public static string GetFolderPath(Environment.SpecialFolder folder) - { - if (folder == Environment.SpecialFolder.CommonApplicationData) - return CommonApplicationData; - return Environment.GetFolderPath(folder); - } - - static string s_companyName = Application.CompanyName; // default for real use; tests may override. - /// ------------------------------------------------------------------------------------ - /// - /// Sets the name of the company used for registry settings (replaces - /// Application.CompanyName) - /// NOTE: THIS SHOULD ONLY BE SET IN TESTS AS THE DEFAULT Application.CompanyName IN - /// TESTS WILL BE "nunit.org" or jetbrains.something!!! - /// - /// ------------------------------------------------------------------------------------ - public static string CompanyName - { - set { s_companyName = value; } - private get - { - // This might be a good idea but will require all unit tests that depend on these functions to set one. Many of them - // don't seem to affected by using an NUnit or JetBrains application name. - //if (s_companyName.IndexOf("nunit", StringComparison.InvariantCultureIgnoreCase) >= 0 || s_companyName.IndexOf("jetbrains", StringComparison.InvariantCultureIgnoreCase) >= 0) - // throw new ArgumentException("CompanyName can not be NUnit.org or some variant of NUnit or jetbrains!" + - // " Make sure the test is overriding this property in RegistryHelper"); - return s_companyName; - } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the path for storing common application data that might be shared between - /// multiple applications and multiple users on the same machine. - /// - /// On Windows this returns a subdirectory of - /// Environment.SpecialFolder.CommonApplicationData (C:\ProgramData),on Linux - /// /var/lib/fieldworks. - /// - /// Name of the application. - /// ------------------------------------------------------------------------------------ - public static string CommonAppDataFolder(string appName) - { - return Path.Combine(Path.Combine(CommonApplicationData, CompanyName), appName); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the full path of the Translation Editor executable. - /// - /// ------------------------------------------------------------------------------------ - public static string TeExe - { - get { return ExeOrDllPath("TE.exe"); } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the full path of the Translation Editor dynamic load library. - /// - /// ------------------------------------------------------------------------------------ - public static string TeDll - { - get { return ExeOrDllPath("TeDll.dll"); } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the full path of the FW Language Explorer executable. - /// - /// ------------------------------------------------------------------------------------ - public static string FlexExe - { - get { return ExeOrDllPath("Flex.exe"); } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the full path of the FW Language Explorer dynamic load library. - /// - /// ------------------------------------------------------------------------------------ - public static string FlexDll - { - get { return ExeOrDllPath("LexTextDll.dll"); } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the full path of the Migrate SQL databases executable. - /// - /// ------------------------------------------------------------------------------------ - public static string MigrateSqlDbsExe - { - get { return ExeOrDllPath("MigrateSqlDbs.exe"); } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the full path of the config file - /// - /// ------------------------------------------------------------------------------------ - public static string RemotingTcpServerConfigFile - { - get - { - if (MiscUtils.RunningTests) - return ExeOrDllPath("remoting_tcp_server_tests.config"); - return ExeOrDllPath("remoting_tcp_server.config"); - } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the full path of the requested executable/dll file in the folder from which FW - /// is being executed. - /// - /// Name of the file (case-sensistive, with the extension) - /// ------------------------------------------------------------------------------------ - private static string ExeOrDllPath(string file) - { - if (file == null) - throw new ArgumentNullException("file"); - - if (Assembly.GetEntryAssembly() == null) - { - // This seems to happen when tests call this method when run from NUnit - // for some reason. - - // The following code should only run by unittests. -#if DEBUG - const string arch = "Debug"; -#else - const string arch = "Release"; -#endif - return Path.Combine(Path.Combine(Path.Combine(Path.GetDirectoryName(FwSourceDirectory), "Output"), arch), file); - } - - return Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), file); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Get a sub directory of the given , - /// or return a tidied up version of the original path, - /// if it is not in the FW code folder structure. - /// - /// Base directory. - /// examples: "WW\XAMPLE or \WW\XAMPLE" - /// - /// ------------------------------------------------------------------------------------ - private static string GetSubDirectory(string directory, string subDirectory) - { - Debug.Assert(subDirectory != null); - - string retval = subDirectory.Trim(); - if (retval.Length > 0 && (retval[0] == Path.DirectorySeparatorChar - || retval[0] == Path.AltDirectorySeparatorChar)) - { - // remove leading directory separator from subdirectory - retval = retval.Substring(1); - } - string possiblePath = Path.Combine(directory, retval); - if (Directory.Exists(possiblePath)) - retval = possiblePath; - // Implicit 'else' assumes it to be a full path, - // but not in the code folder structure. - // Sure hope the caller can handle it. - -#if __MonoCS__ - else if (!Directory.Exists(retval)) // previous Substring(1) causes problem for 'full path' in Linux - return subDirectory; -#endif - - return retval; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Get a sub directory of the FW code directory, - /// or return a tidied up version of the original path, - /// if it is not in the FW code folder structure. - /// - /// examples: "WW\XAMPLE or \WW\XAMPLE" - /// - /// ------------------------------------------------------------------------------------ - public static string GetFWCodeSubDirectory(string subDirectory) - { - return GetSubDirectory(FWCodeDirectory, subDirectory); - } - - private static string GetFLExBridgeFolderPath() - { - // Setting a Local Machine registry value is problematic for Linux/Mono. (FWNX-1180) - // Try an alternative way of finding FLExBridge first. - var dir = Environment.GetEnvironmentVariable("FLEXBRIDGEDIR"); - if (!String.IsNullOrEmpty(dir) && Directory.Exists(dir)) - return dir; - var key = FwRegistryHelper.FieldWorksBridgeRegistryKeyLocalMachine; - if (key != null) - return GetDirectory(key, "InstallationDir", ""); - return ""; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Get a sub directory of the FW data directory, - /// or return a tidied up version of the original path, - /// if it is not in the FW data folder structure. - /// - /// examples: "Languages or \Languages" - /// - /// ------------------------------------------------------------------------------------ - public static string GetFWDataSubDirectory(string subDirectory) - { - return GetSubDirectory(FWDataDirectory, subDirectory); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Get a file in the FW code directory. - /// - /// examples: "iso-8859-1.tec" - /// - /// ------------------------------------------------------------------------------------ - public static string GetFWCodeFile(string filename) - { - return Path.Combine(FWCodeDirectory, filename); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the path to the configuration settings for the specified project. - /// - /// The path to the project folder. - /// ------------------------------------------------------------------------------------ - public static string GetConfigSettingsDir(string projectFolder) - { - return Path.Combine(projectFolder, ksConfigurationSettingsDir); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the path to the backup settings for the specified project - /// - /// The path to the project folder. - /// ------------------------------------------------------------------------------------ - public static string GetBackupSettingsDir(string projectFolder) - { - return Path.Combine(projectFolder, ksBackupSettingsDir); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the path to the fonts for the specified project. - /// - /// The path to the project folder. - /// ------------------------------------------------------------------------------------ - public static string GetSupportingFilesDir(string projectFolder) - { - return Path.Combine(projectFolder, ksSupportingFilesDir); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the path to the writing systems for the specified project. - /// - /// The path to the project folder. - /// ------------------------------------------------------------------------------------ - public static string GetWritingSystemDir(string projectFolder) - { - return Path.Combine(projectFolder, ksWritingSystemsDir); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the path without the root directory (i.e. make it un-rooted). - /// - /// ------------------------------------------------------------------------------------ - public static string GetPathWithoutRoot(string pathWithRoot) - { - string pathRoot = Path.GetPathRoot(pathWithRoot); - return pathWithRoot.Substring(pathRoot.Length); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Takes a windows path and returns it in the format which our backup zip files - /// stores them in. - /// - /// ------------------------------------------------------------------------------------ - public static string GetZipfileFormattedPath(string path) - { - StringBuilder strBldr = new StringBuilder(path); - string pathRoot = Path.GetPathRoot(path); - strBldr.Remove(0, pathRoot.Length); - // replace back slashes with forward slashes (for Windows) - if (!MiscUtils.IsUnix && !MiscUtils.IsMac) - strBldr.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); - return strBldr.ToString(); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the name of the XML data file, given a project name (basically just adds the - /// FW data XML file extension). - /// - /// Name of the project (not a filename). - /// ------------------------------------------------------------------------------------ - public static string GetXmlDataFileName(string projectName) - { - Debug.Assert(Path.GetExtension(projectName) != FwFileExtensions.ksFwDataXmlFileExtension, - String.Format("There is a faint chance the user might have specified a real project name ending in {0} (in which case, sorry, but we're going to trim it off), but probably this is a programming error", FwFileExtensions.ksFwDataXmlFileExtension)); - // Do not use Path.ChangeExtension because it will strip off anything following a period in the project name! - return projectName.EndsWith(FwFileExtensions.ksFwDataXmlFileExtension) ? projectName : - projectName + FwFileExtensions.ksFwDataXmlFileExtension; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the name of the DB4O data file, given a project name (basically just adds the - /// FW db4o file extension). - /// - /// Name of the project (not a filename). - /// ------------------------------------------------------------------------------------ - public static string GetDb4oDataFileName(string projectName) - { - Debug.Assert(Path.GetExtension(projectName) != FwFileExtensions.ksFwDataDb4oFileExtension, - String.Format("There is a faint chance the user might have specified a real project name ending in {0} (in which case, sorry, but we're going to trim it off), but probably this is a programming error", FwFileExtensions.ksFwDataDb4oFileExtension)); - // Do not use Path.ChangeExtension because it will strip off anything following a period in the project name! - return projectName.EndsWith(FwFileExtensions.ksFwDataDb4oFileExtension) ? projectName : - projectName + FwFileExtensions.ksFwDataDb4oFileExtension; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets a subdirectory of FieldWorks either by reading the - /// or by getting . - /// Will not return null. - /// - /// The name of the registry value to read from the FW root - /// key in HKLM. - /// The default directory to use if there is no value in the - /// registry. - /// - /// The desired subdirectory of FieldWorks (without trailing directory separator). - /// - /// ------------------------------------------------------------------------------------ - private static string GetDirectory(string registryValue, string defaultDir) - { - using (var userKey = FwRegistryHelper.FieldWorksRegistryKey) - using (var machineKey = FwRegistryHelper.FieldWorksRegistryKeyLocalMachine) - { - var registryKey = userKey; - if (userKey == null || userKey.GetValue(registryValue) == null) - { - registryKey = machineKey; - } - - return GetDirectory(registryKey, registryValue, defaultDir); - } - } - - /// - /// Get a directory for a particular key ignoring current user settings. - /// - /// - /// - /// - private static string GetDirectoryLocalMachine(string registryValue, string defaultDir) - { - using (RegistryKey machineKey = FwRegistryHelper.FieldWorksRegistryKeyLocalMachine) - { - return GetDirectory(machineKey, registryValue, defaultDir); - } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets a subdirectory of FieldWorks either by reading the - /// or by getting . - /// Will not return null. - /// - /// The registry key where the value is stored. - /// The name of the registry value under the given key that - /// contains the desired directory. - /// The default directory to use if there is no value in the - /// registry. - /// - /// The desired subdirectory of FieldWorks (without trailing directory separator). - /// - /// If the desired directory could not be found. - /// - /// ------------------------------------------------------------------------------------ - private static string GetDirectory(RegistryKey registryKey, string registryValue, - string defaultDir) - { - string rootDir = (registryKey == null) ? null : registryKey.GetValue(registryValue, null) as string; - - if (string.IsNullOrEmpty(rootDir) && !string.IsNullOrEmpty(defaultDir)) - rootDir = defaultDir; - if (string.IsNullOrEmpty(rootDir)) - { - throw new ApplicationException( - ResourceHelper.GetResourceString("kstidInvalidInstallation")); - } - // Hundreds of callers of this method are using Path.Combine with the results. - // Combine only works with a root directory if it is followed by \ (e.g., c:\) - // so we don't want to trim the \ in this situation. - string dir = rootDir.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); - return dir.Length > 2 ? dir : dir + Path.DirectorySeparatorChar; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the directory where FieldWorks code was installed (usually - /// C:\Program Files\SIL\FieldWorks n). - /// Will not return null. - /// - /// If an installation directory could not be - /// found. - /// ------------------------------------------------------------------------------------ - public static string FWCodeDirectory - { - get - { - string defaultDir = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), CompanyName), - string.Format("FieldWorks {0}", FwUtils.SuiteVersion)); - return GetDirectory("RootCodeDir", defaultDir); - } - } - - private const string ksRootDataDir = "RootDataDir"; - private const string ksFieldWorks = "FieldWorks"; - /// ------------------------------------------------------------------------------------ - /// - /// Gets the directory where FieldWorks data was installed (i.e. under AppData). - /// - /// If an installation directory could not be - /// found. - /// ------------------------------------------------------------------------------------ - public static string FWDataDirectory - { - get { return GetDirectory(ksRootDataDir, CommonAppDataFolder(ksFieldWorks)); } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the directory where FieldWorks data was installed (i.e. under AppData), - /// as it would be determined ignoring current user registry settings. - /// - /// If an installation directory could not be - /// found. - /// ------------------------------------------------------------------------------------ - public static string FWDataDirectoryLocalMachine - { - get { return GetDirectoryLocalMachine(ksRootDataDir, CommonAppDataFolder(ksFieldWorks)); } - } - - private static string m_srcdir; - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the src dir (for running tests) - /// - /// ------------------------------------------------------------------------------------ - public static string FwSourceDirectory - { - get - { - if (!String.IsNullOrEmpty(m_srcdir)) - return m_srcdir; - if (MiscUtils.IsUnix) - { - // Linux doesn't have the registry setting, at least while running tests, - // so we'll assume the executing assembly is $FW/Output/Debug/FwUtils.dll, - // and the source dir is $FW/Src. - Uri uriBase = new Uri(Assembly.GetExecutingAssembly().CodeBase); - var dir = Path.GetDirectoryName(Uri.UnescapeDataString(uriBase.AbsolutePath)); - dir = Path.GetDirectoryName(dir); // strip the parent directory name (Debug) - dir = Path.GetDirectoryName(dir); // strip the parent directory again (Output) - dir = Path.Combine(dir, "Src"); - if (!Directory.Exists(dir)) - throw new ApplicationException("Could not find the Src directory. Was expecting it at: " + dir); - m_srcdir = dir; - } - else - { - string rootDir = null; - if (FwRegistryHelper.FieldWorksRegistryKey != null) - { - rootDir = FwRegistryHelper.FieldWorksRegistryKey.GetValue("RootCodeDir") as string; - } - else if (FwRegistryHelper.FieldWorksRegistryKeyLocalMachine != null) - { - rootDir = FwRegistryHelper.FieldWorksRegistryKeyLocalMachine.GetValue("RootCodeDir") as string; - } - if (string.IsNullOrEmpty(rootDir)) - { - throw new ApplicationException( - string.Format(@"You need to have the registry key {0}\RootCodeDir pointing at your DistFiles dir.", - FwRegistryHelper.FieldWorksRegistryKeyLocalMachine.Name)); - } - string fw = Directory.GetParent(rootDir).FullName; - string src = Path.Combine(fw, "Src"); - if (!Directory.Exists(src)) - throw new ApplicationException(@"Could not find the Src directory. Was expecting it at: " + src); - m_srcdir = src; - } - return m_srcdir; - } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the full path name of the editorial checks directory. - /// - /// ------------------------------------------------------------------------------------ - public static string EditorialChecksDirectory - { - get - { - string directory = GetFWCodeSubDirectory(@"Editorial Checks"); - if (!Directory.Exists(directory)) - { - string msg = ResourceHelper.GetResourceString("kstidUnableToFindEditorialChecks"); - throw new ApplicationException(string.Format(msg, directory)); - } - return directory; - } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the basic editorial checks DLL. Note that this is currently the ScrChecks DLL, - /// but if we ever split this DLL to separate Scripture-specific checks from more - /// generic checks that are really based on the WS and could be used to check any text, - /// then this property should be made to return the DLL containing the punctuation - /// patterns and characters checks. - /// - /// ------------------------------------------------------------------------------------ - public static string BasicEditorialChecksDll - { - get - { -#if RELEASE - try - { -#endif - string directory = EditorialChecksDirectory; - string checksDll = Path.Combine(directory, "ScrChecks.dll"); - if (!File.Exists(checksDll)) - { - string msg = ResourceHelper.GetResourceString("kstidUnableToFindEditorialChecks"); - throw new ApplicationException(string.Format(msg, directory)); - } - return checksDll; -#if RELEASE - } - catch (ApplicationException e) - { - throw new InstallationException(e); - } -#endif - } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the dir where templates are installed - /// - /// ------------------------------------------------------------------------------------ - public static string TemplateDirectory - { - get { return GetFWCodeSubDirectory("Templates"); } - } - - private const string ksProjects = "Projects"; - - /// ------------------------------------------------------------------------------------ - /// - /// Gets or sets the dir where projects are stored. Setting to null will delete the HKCU - /// key, so that the HKLM key (system default) will be used for this user. - /// - /// If user does not have permission to write to HKLM - /// - /// ------------------------------------------------------------------------------------ - public static string ProjectsDirectory - { - get { return GetDirectory(ksProjectsDir, Path.Combine(FWDataDirectory, ksProjects)); } - set - { - if (ProjectsDirectory == value) - return; // no change. - - using (var registryKey = FwRegistryHelper.FieldWorksRegistryKey) - { - if (value == null) - { - registryKey.DeleteValue(ksProjectsDir); - } - else - { - registryKey.SetValue(ksProjectsDir, value); - } - } - } - } - - /// - /// The project directory that would be identified if we didn't have any current user registry settings. - /// - public static string ProjectsDirectoryLocalMachine - { - get { return GetDirectoryLocalMachine(ksProjectsDir, Path.Combine(FWDataDirectoryLocalMachine, ksProjects)); } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Determines whether the given path is a direct sub folder of the projects directory. - /// (This is typically true for the a project-specific folder.) - /// - /// The path. - /// ------------------------------------------------------------------------------------ - public static bool IsSubFolderOfProjectsDirectory(string path) - { - return !string.IsNullOrEmpty(path) && Path.GetDirectoryName(path) == ProjectsDirectory; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the default directory for Backup files. This is per-user. - /// - /// If setting this value and the user does not have - /// permission to write to HKCU (probably can never happen) - /// ------------------------------------------------------------------------------------ - public static string DefaultBackupDirectory - { - get - { - // NOTE: SpecialFolder.MyDocuments returns $HOME on Linux - string myDocs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); - // FWNX-501: use slightly different default path on Linux - string defaultDir = MiscUtils.IsUnix ? - Path.Combine(myDocs, "Documents/fieldworks/backups") : - Path.Combine(Path.Combine(myDocs, "My FieldWorks"), "Backups"); - - using (RegistryKey registryKey = FwRegistryHelper.FieldWorksRegistryKey.OpenSubKey("ProjectBackup")) - return GetDirectory(registryKey, "DefaultBackupDirectory", defaultDir); - } - set - { - using (RegistryKey key = FwRegistryHelper.FieldWorksRegistryKey.CreateSubKey("ProjectBackup")) - { - if (key != null) - key.SetValue("DefaultBackupDirectory", value); - } - } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the global writing system store directory. The directory is guaranteed to exist. - /// - /// ------------------------------------------------------------------------------------ - [SuppressMessage("Gendarme.Rules.Portability", "MonoCompatibilityReviewRule", - Justification="Offending code is not executed on Linux")] - public static string GlobalWritingSystemStoreDirectory - { - get - { - string path = CommonAppDataFolder(ksWritingSystemsDir); - if (!Directory.Exists(path)) - { - DirectoryInfo di; - - // Provides FW on Linux multi-user access. Overrides the system - // umask and creates the directory with the permissions "775". - // The "fieldworks" group was created outside the app during - // configuration of the package which allows group access. - using(new FileModeOverride()) - { - di = Directory.CreateDirectory(path); - } - - if (!MiscUtils.IsUnix) - { - // NOTE: GetAccessControl/ModifyAccessRule/SetAccessControl is not implemented in Mono - DirectorySecurity ds = di.GetAccessControl(); - var sid = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null); - AccessRule rule = new FileSystemAccessRule(sid, FileSystemRights.Write | FileSystemRights.ReadAndExecute - | FileSystemRights.Modify, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, - PropagationFlags.InheritOnly, AccessControlType.Allow); - bool modified; - ds.ModifyAccessRule(AccessControlModification.Add, rule, out modified); - di.SetAccessControl(ds); - } - } - return path; - } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the biblical key terms localization files. - /// - /// ------------------------------------------------------------------------------------ - static public string[] KeyTermsLocalizationFiles - { - get - { - // SE version doesn't install the TE folder. - if (!Directory.Exists(TeFolder)) - return new string[]{""}; - return Directory.GetFiles(TeFolder, ksBiblicaltermsLocFilePrefix + "*" + - ksBiblicaltermsLocFileExtension, SearchOption.TopDirectoryOnly); - } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Returns the file name containing the localization of the key terms list for the - /// given ICU locale. - /// - /// ------------------------------------------------------------------------------------ - static public string GetKeyTermsLocFilename(string locale) - { - return Path.Combine(TeFolder, ksBiblicaltermsLocFilePrefix + locale + - ksBiblicaltermsLocFileExtension); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Extracts the locale identifier (string) from a key terms localization file name. - /// - /// ------------------------------------------------------------------------------------ - static public string GetLocaleFromKeyTermsLocFile(string locFilename) - { - return Path.GetFileName(locFilename).Replace(ksBiblicaltermsLocFilePrefix, - String.Empty).Replace(ksBiblicaltermsLocFileExtension, String.Empty); - } - - #region ExternalLinks folders - //This region has all methods which return the values for the ExternalLinks files associated with a project. - //This includes .../ProjectName/LinkedFiles and all subfolders. i.e. Pictures, AudioVisual and Others. - - - /// - /// Gets the path to the standard eternal linked files directory for the specified project. - /// - /// The path to the project. - /// - public static string GetDefaultLinkedFilesDir(string projectPath) - { - return Path.Combine(projectPath, ksLinkedFilesDir); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the path to the standard media files directory for the specified project. Note - /// that if this project keepes its externally linked files in a separate folder from - /// the rest of the project files (such as a shared folder common to multiple projects - /// on a server), the directory returned by this method will not actually contain any - /// files. - /// - /// The path to the project. - /// ------------------------------------------------------------------------------------ - public static string GetDefaultMediaDir(string projectPath) - { - return Path.Combine(projectPath, Path.Combine(ksLinkedFilesDir, ksMediaDir)); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the path to the standard pictures directory for the specified project. Note - /// that if this project keepes its externally linked files in a separate folder from - /// the rest of the project files (such as a shared folder common to multiple projects - /// on a server), the directory returned by this method will not actually contain any - /// files. - /// - /// The path to the project. - /// ------------------------------------------------------------------------------------ - public static string GetDefaultPicturesDir(string projectPath) - { - return Path.Combine(projectPath, Path.Combine(ksLinkedFilesDir, ksPicturesDir)); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the path to the standard directory for other externally linked project files. - /// Note that if this project keepes its externally linked files in a separate folder - /// from the rest of the project files (such as a shared folder common to multiple - /// projects on a server), the directory returned by this method will not actually - /// contain any files. - /// - /// The path to the project. - /// ------------------------------------------------------------------------------------ - public static string GetDefaultOtherExternalFilesDir(string projectPath) - { - return Path.Combine(projectPath, Path.Combine(ksLinkedFilesDir, ksOtherLinkedFilesDir)); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the path to the media files directory for the project. - /// - /// The project's LinkedFiles path. (eg. m_cache.LangProject.LinkedFilesRootDir) - /// ------------------------------------------------------------------------------------ - public static string GetMediaDir(string projectLinkedFilesPath) - { - return Path.Combine(projectLinkedFilesPath, ksMediaDir); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the path to the pictures directory for the project. - /// - /// The project's LinkedFiles path. (eg. m_cache.LangProject.LinkedFilesRootDir) - /// ------------------------------------------------------------------------------------ - public static string GetPicturesDir(string projectLinkedFilesPath) - { - return Path.Combine(projectLinkedFilesPath, ksPicturesDir); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the path to the directory for other externally linked project files. - /// - /// The project's LinkedFiles path. (eg. m_cache.LangProject.LinkedFilesRootDir) - /// ------------------------------------------------------------------------------------ - public static string GetOtherExternalFilesDir(string projectLinkedFilesPath) - { - return Path.Combine(projectLinkedFilesPath, ksOtherLinkedFilesDir); - } - - #endregion - } - - /// - /// This class is designed for converting between relative paths and full paths for the LinkedFiles of a FW project - /// - public class DirectoryFinderRelativePaths - { - /// Substitution string for a path that is under the LinkedFiles directory. - public const string ksLFrelPath = "%lf%"; - /// Substitution string for a path that is under the project's directory. - public const string ksProjectRelPath = "%proj%"; - /// Substitution string for a path that is under the default directory for projects. - public const string ksProjectsRelPath = "%Projects%"; - /// Substitution string for a path that is under the My Documents directory. - public const string ksMyDocsRelPath = "%MyDocuments%"; - /// Substitution string for a path that is under the Shared Application Data directory. - public const string ksCommonAppDataRelPath = "%CommonApplicationData%"; - - #region Methods to covert between RelativePaths and FullPaths - - /// - /// If a filePath is stored in the format %lf%\path\filename then this method returns the full path. - /// Otherwise return null - /// - /// - /// - /// - public static String GetFullFilePathFromRelativeLFPath(string relativePath, string projectLinkedFilesPath) - { - String fullfilePath = null; - fullfilePath = GetFullPathForRelativePath(relativePath, ksLFrelPath, projectLinkedFilesPath); - - if (String.IsNullOrEmpty(fullfilePath)) - return null; - return FixPathSlashesIfNeeded(fullfilePath); - } - - /// - /// If a file path is non rooted then return combination of the linkedFiledRootDir and the relative - /// path. Otherwise just return the full path passed in as an arguement. - /// - /// - /// - /// - public static String GetFullPathFromRelativeLFPath(string relativeLFPath, string linkedFilesRootDir) - { - // We could just catch the exception that IsPathRooted throws if there are invalid characters, - // or use Path.GetInvalidPathChars(). But that would pass things on Linux that will fail on Windows, - // which both makes unit testing difficult, and also may hide from Linux users the fact that their - // paths will cause problems on Windows. - var invalidChars = MiscUtils.GetInvalidProjectNameChars(MiscUtils.FilenameFilterStrength.kFilterProjName); - // relativeLFPath is allowed to include directories. And it MAY be rooted, meaning on Windows it could start X: - invalidChars = invalidChars.Replace(@"\", "").Replace("/", "").Replace(":", ""); - // colon is allowed only as second character--such a path is probably no good on Linux, but will just be not found, not cause a crash - int indexOfColon = relativeLFPath.IndexOf(':'); - if (relativeLFPath.IndexOfAny(invalidChars.ToCharArray()) != -1 - || (indexOfColon != -1 && indexOfColon != 1)) - { - // This is a fairly clumsy solution, designed as a last-resort way to avoid crashing the program. - // Hopefully most paths for entering path names into the relevant fields do something nicer to - // avoid getting illegal characters there. - return FixPathSlashesIfNeeded(Path.Combine(linkedFilesRootDir, "__ILLEGALCHARS__")); - } - if (Path.IsPathRooted(relativeLFPath)) - return FixPathSlashesIfNeeded(relativeLFPath); - else - return FixPathSlashesIfNeeded(Path.Combine(linkedFilesRootDir, relativeLFPath)); - } - - /// - /// If a path gets stored with embedded \, fix it to work away from Windows. (FWNX-882) - /// - public static string FixPathSlashesIfNeeded(string path) - { - if (string.IsNullOrEmpty(path)) - return string.Empty; - if (MiscUtils.IsUnix || MiscUtils.IsMac) - { - if (path.Contains("\\")) - return path.Replace('\\', '/'); - } - return path; - } - - /// - /// If the path is relative to the project's linkedFiles path then substitute %lf% - /// and return it. Otherwise return an empty string - /// - /// - /// - /// - public static string GetRelativeLFPathFromFullFilePath(string filePath, - string projectLinkedFilesPath) - { - if (string.IsNullOrEmpty(projectLinkedFilesPath)) - return string.Empty; - - var linkedFilesPathLowercaseRoot = GetPathWithLowercaseRoot(filePath); - - var relativePath = GetRelativePathIfExists(ksLFrelPath, linkedFilesPathLowercaseRoot, - projectLinkedFilesPath); - if (!string.IsNullOrEmpty(relativePath)) - return FixPathSlashesIfNeeded(relativePath); - //Just return an empty path if we cannot find a relative path. - return string.Empty; - } - - /// - /// If the specified path starts with the LinkedFiles root directory then return - /// the part after the linkedFilesRootDir; - /// otherwise if it is a file path at all convert it to the current platform and return it; - /// otherwise (it's a URL, determined by containing a colon after more than one initial character) - /// return null to indicate no change made. - /// - /// - /// - /// - public static string GetRelativeLinkedFilesPath(string filePath, - string linkedFilesRootDir) - { - if (filePath.IndexOf(':') > 1) - { - // It's a URL, not a path at all; don't mess with it. - return null; - } - string directory = FileUtils.ChangePathToPlatform(linkedFilesRootDir); - string relativePath = FileUtils.ChangePathToPlatform(filePath); - - // Does the specified path start with the LinkedFiles root directory? - if (relativePath.StartsWith(directory, true, System.Globalization.CultureInfo.InvariantCulture) && - relativePath.Length > directory.Length + 1) - { - // Keep the portion of the specified path that is a subfolder of - // the LinkedFiles folder and make sure to strip off an initial - // path separator if there is one. - relativePath = relativePath.Substring(directory.Length); - if (relativePath[0] == Path.DirectorySeparatorChar) - relativePath = relativePath.Substring(1); - } - return FixPathSlashesIfNeeded(relativePath); - } - - - /// - /// Return the fullPath for a project's LinkedFiles based on the relative path that was persisted. - /// If no match on a relativePath match is made then return the relativePath passed in assuming it - /// is actually a full path. - /// - /// - /// - /// - public static String GetLinkedFilesFullPathFromRelativePath(string relativePath, String projectPath) - { - String fullPath = null; - fullPath = GetFullPathForRelativePath(relativePath, ksProjectRelPath, projectPath); - - if (String.IsNullOrEmpty(fullPath)) - fullPath = GetFullPathForRelativePath(relativePath, ksProjectsRelPath, - DirectoryFinder.ProjectsDirectory); - if (String.IsNullOrEmpty(fullPath)) - fullPath = GetFullPathForRelativePath(relativePath, ksCommonAppDataRelPath, - DirectoryFinder.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); - if (String.IsNullOrEmpty(fullPath)) - fullPath = GetFullPathForRelativePath(relativePath, ksMyDocsRelPath, - DirectoryFinder.GetFolderPath(Environment.SpecialFolder.MyDocuments)); - if (String.IsNullOrEmpty(fullPath)) - return FixPathSlashesIfNeeded(relativePath); - return FixPathSlashesIfNeeded(fullPath); - } - - private static String GetFullPathForRelativePath(String relativePath, String relativePart, String fullPathReplacement) - { - if (relativePath.StartsWith(relativePart)) - { - var length = relativePart.Length; - var restOfPath = relativePath.Substring(length, relativePath.Length - length); - return fullPathReplacement + restOfPath; - } - else - { - return string.Empty; - } - } - - /// - /// Get a relative path for the LinkedFilesPath which we will persist to be used when - /// restoring a project. - /// - /// - /// - /// - /// - public static string GetLinkedFilesRelativePathFromFullPath(string linkedFilesFullPath, - string projectPath, string projectName) - { - var linkedFilesPathLowercaseRoot = GetPathWithLowercaseRoot(linkedFilesFullPath); - // Case where the ExternalLinks folder is located somewhere under the project folder. - // This is the default location. - var relativePath = GetRelativePathIfExists(ksProjectRelPath, linkedFilesPathLowercaseRoot, - projectPath); - if (!string.IsNullOrEmpty(relativePath)) - return FixPathSlashesIfNeeded(relativePath); - // GetRelativePathIfExists may miss a case where, say, projectPath is - // \\ls-thomson-0910.dallas.sil.org\Projects\MyProj, and linkedFilesFullPath is - // C:\Documents and settings\All Users\SIL\FieldWorks\Projects\MyProj\LinkedFiles - // Even though the MyProj directory in both paths is the same directory. - // It's important to catch this case and return a relative path. - var projectFolderName = Path.GetFileName(projectPath); - var projectsPath = Path.GetDirectoryName(projectPath); - var allProjectsName = Path.GetFileName(projectsPath); - var match = Path.Combine(allProjectsName, projectFolderName); - int index = linkedFilesFullPath.IndexOf(match, StringComparison.InvariantCultureIgnoreCase); - if (index >= 0) - { - // There's a very good chance these are the same folders! - var alternateProjectPath = linkedFilesFullPath.Substring(0, index + match.Length); - if (Directory.Exists(alternateProjectPath) && - Directory.GetLastWriteTime(alternateProjectPath) == Directory.GetLastWriteTime(projectPath)) - { - // They ARE the same directory! (I suppose we could miss if someone wrote to it at the - // exact wrong moment, but we shouldn't be changing this setting while shared, anyway.) - return FixPathSlashesIfNeeded(ksProjectRelPath + linkedFilesFullPath.Substring(index + match.Length)); - } - } - - //See if linkedFilesPath begins with one of the other standard paths. - - // Case where user is presumably having a LinkedFiles folder shared among a number - // of projects under the Projects folder. That would be a good reason to put it in - // the projects folder common to all projects. - relativePath = GetRelativePathIfExists(ksProjectsRelPath, linkedFilesPathLowercaseRoot, - DirectoryFinder.ProjectsDirectory); - if (!String.IsNullOrEmpty(relativePath)) - return FixPathSlashesIfNeeded(relativePath); - - // Case where the user has the LinkedFiles folder in a shared folder. - relativePath = GetRelativePathIfExists(ksCommonAppDataRelPath, - linkedFilesPathLowercaseRoot, DirectoryFinder.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); - if (!string.IsNullOrEmpty(relativePath)) - return FixPathSlashesIfNeeded(relativePath); - - // Case where the user has the LinkedFiles folder in their MyDocuments folder - relativePath = GetRelativePathIfExists(ksMyDocsRelPath, - linkedFilesPathLowercaseRoot, - DirectoryFinder.GetFolderPath(Environment.SpecialFolder.MyDocuments)); - if (!string.IsNullOrEmpty(relativePath)) - return FixPathSlashesIfNeeded(relativePath); - - //Just return the complete path if we cannot find a relative path. - return FixPathSlashesIfNeeded(linkedFilesFullPath); - } - - private static string GetRelativePathIfExists(string relativePart, string fullPath, - string parentPath) - { - var parentPathLowerCaseRoot = GetPathWithLowercaseRoot(parentPath); - if (!string.IsNullOrEmpty(parentPathLowerCaseRoot) && - fullPath.StartsWith(parentPathLowerCaseRoot)) - { - var length = parentPath.Length; - var restOfPath = fullPath.Substring(length, fullPath.Length - length); - return relativePart + restOfPath; - } - return string.Empty; - } - - private static string GetPathWithLowercaseRoot(string path) - { - try - { - var rootOfPath = Path.GetPathRoot(path); - return rootOfPath.ToLowerInvariant() + - path.Substring(rootOfPath.Length, path.Length - rootOfPath.Length); - } - catch (ArgumentException e) - { - return path.ToLowerInvariant(); - } - } - - - #endregion - } -} diff --git a/Src/Common/FwUtils/FLExBridgeHelper.cs b/Src/Common/FwUtils/FLExBridgeHelper.cs index 48073140e1..4b388bb388 100644 --- a/Src/Common/FwUtils/FLExBridgeHelper.cs +++ b/Src/Common/FwUtils/FLExBridgeHelper.cs @@ -120,13 +120,9 @@ public class FLExBridgeHelper #endregion End of available '-v' parameter options: - // The two paths of a path that locate the Lift repository within a FLEx project. /// - /// constant for locating the nested lift repository (part 1 of 2) - /// - public const string OtherRepositories = @"OtherRepositories"; - /// - /// constant for locating the nested lift repository (part 2 of 2) + /// constant for locating the nested lift repository (within the "OtherRepositories" path of a project). + /// See also SIL.FieldWorks.FDO.FdoFileHelper.OtherRepositories /// public const string LIFT = @"LIFT"; @@ -195,7 +191,7 @@ public static bool LaunchFieldworksBridge(string projectFolder, string userName, if (!String.IsNullOrEmpty(projectFolder)) { // can S/R multiple projects simultaneously AddArg(ref args, "-p", projectFolder); - if (projectFolder != DirectoryFinder.ProjectsDirectory) + if (projectFolder != FwDirectoryFinder.ProjectsDirectory) _sFwProjectName = Path.GetFileNameWithoutExtension(projectFolder); // REVIEW (Hasso) 2014.01: this variable is never read } @@ -212,7 +208,7 @@ public static bool LaunchFieldworksBridge(string projectFolder, string userName, } // Add two paths: to FW projDir & FW apps folder. Then, FB won't have to look in a zillion registry entries - AddArg(ref args, "-projDir", DirectoryFinder.ProjectsDirectory); + AddArg(ref args, "-projDir", FwDirectoryFinder.ProjectsDirectory); AddArg(ref args, "-fwAppsDir", FieldWorksAppsDir); // Tell Flex Bridge which model version of data are expected by FLEx. AddArg(ref args, "-fwmodel", fwmodelVersionNumber.ToString()); @@ -350,7 +346,7 @@ private static void AddArg(ref string extant, string flag, string value) /// public static string FullFieldWorksBridgePath() { - return Path.Combine(DirectoryFinder.FlexBridgeFolder, FLExBridgeName); + return Path.Combine(FwDirectoryFinder.FlexBridgeFolder, FLExBridgeName); } /// diff --git a/Src/Common/FwUtils/FwDirectoryFinder.cs b/Src/Common/FwUtils/FwDirectoryFinder.cs new file mode 100644 index 0000000000..1551201c08 --- /dev/null +++ b/Src/Common/FwUtils/FwDirectoryFinder.cs @@ -0,0 +1,698 @@ +// Copyright (c) 2003-2014 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) +// +// File: FwDirectoryFinder.cs +// +// +// To find the current user's "My Documents" folder, use something like: +// string sMyDocs = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); +// See the MSDN documentation for the System.Environment.SpecialFolder enumeration for details. +// + +using System; +using System.IO; +using System.Diagnostics; +using System.Reflection; +using System.Security; +using Microsoft.Win32; +using SIL.CoreImpl; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.Resources; +using SIL.Utils; + +namespace SIL.FieldWorks.Common.FwUtils +{ + /// + /// This class is used to find files and directories for FW apps. + /// + public static class FwDirectoryFinder + { + /// + /// The name of the Translation Editor folder (Even though this is the same as + /// FwUtils.ksTeAppName and FwSubKey.TE, PLEASE do not use them interchangeably. Use + /// the one that is correct for your context, in case they need to be changed later.) + /// + public const string ksTeFolderName = FwUtils.ksTeAppName; + /// + /// The name of the Language Explorer folder (Even though this is the same as + /// FwUtils.ksFlexAppName and FwSubKey.LexText, PLEASE do not use them interchangeably. + /// Use the one that is correct for your context, in case they need to be changed later.) + /// + public const string ksFlexFolderName = FwUtils.ksFlexAppName; + + /// The Scripture-specific stylesheet (ideally, this would be in a TE-specific place, but FDO needs it) + public const string kTeStylesFilename = "TeStyles.xml"; + + /// The name of the folder containing global writing systems. + /// Also see SIL.FieldWorks.FDO.FdoFileHelper.ksWritingSystemsDir + /// for the project-level directory. + private const string ksWritingSystemsDir = "WritingSystemStore"; + + private const string ksBiblicaltermsLocFilePrefix = "BiblicalTerms-"; + private const string ksBiblicaltermsLocFileExtension = ".xml"; + private const string ksProjectsDir = "ProjectsDir"; + + private static readonly IFdoDirectories s_fdoDirs = new FwFdoDirectories(); + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the full path of the Scripture-specific stylesheet. + /// This should NOT be in the TE folder, because it is used by the SE edition, when + /// doing minimal scripture initialization in order to include Paratext texts. + /// + /// ------------------------------------------------------------------------------------ + public static string TeStylesPath + { + get { return Path.Combine(CodeDirectory, kTeStylesFilename); } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the full path of the folder where TE-specific files are installed. + /// + /// ------------------------------------------------------------------------------------ + public static string TeFolder + { + get { return GetCodeSubDirectory(ksTeFolderName); } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the full path of the folder where FLEx-specific files are installed. + /// + /// ------------------------------------------------------------------------------------ + public static string FlexFolder + { + get { return GetCodeSubDirectory(ksFlexFolderName); } + } + + /// + /// Return the folder in which FlexBridge resides, or empty string if it is not installed. + /// + public static string FlexBridgeFolder + { + get { return GetFLExBridgeFolderPath(); } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the full path of the Translation Editor executable. + /// + /// ------------------------------------------------------------------------------------ + public static string TeExe + { + get { return ExeOrDllPath("TE.exe"); } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the full path of the Translation Editor dynamic load library. + /// + /// ------------------------------------------------------------------------------------ + public static string TeDll + { + get { return ExeOrDllPath("TeDll.dll"); } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the full path of the FW Language Explorer executable. + /// + /// ------------------------------------------------------------------------------------ + public static string FlexExe + { + get { return ExeOrDllPath("Flex.exe"); } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the full path of the FW Language Explorer dynamic load library. + /// + /// ------------------------------------------------------------------------------------ + public static string FlexDll + { + get { return ExeOrDllPath("LexTextDll.dll"); } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the full path of the Migrate SQL databases executable. + /// + /// ------------------------------------------------------------------------------------ + public static string MigrateSqlDbsExe + { + get { return ExeOrDllPath("MigrateSqlDbs.exe"); } + } + + /// + /// Gets the path to MSSQLMigration\Db.exe. + /// + public static string DbExe + { + get { return Path.Combine(GetCodeSubDirectory("MSSQLMigration"), "db.exe"); } + } + + /// + /// Gets the converter console executable. + /// + public static string ConverterConsoleExe + { + get { return ExeOrDllPath("ConverterConsole.exe"); } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the full path of the config file + /// + /// ------------------------------------------------------------------------------------ + public static string RemotingTcpServerConfigFile + { + get + { + if (MiscUtils.RunningTests) + return ExeOrDllPath("remoting_tcp_server_tests.config"); + return ExeOrDllPath("remoting_tcp_server.config"); + } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the full path of the requested executable/dll file in the folder from which FW + /// is being executed. + /// + /// Name of the file (case-sensistive, with the extension) + /// ------------------------------------------------------------------------------------ + private static string ExeOrDllPath(string file) + { + if (file == null) + throw new ArgumentNullException("file"); + + if (Assembly.GetEntryAssembly() == null) + { + // This seems to happen when tests call this method when run from NUnit + // for some reason. + + // The following code should only run by unittests. +#if DEBUG + const string arch = "Debug"; +#else + const string arch = "Release"; +#endif + return Path.Combine(Path.Combine(Path.Combine(Path.GetDirectoryName(SourceDirectory), "Output"), arch), file); + } + + return Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), file); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Get a sub directory of the given , + /// or return a tidied up version of the original path, + /// if it is not in the FW code folder structure. + /// + /// Base directory. + /// examples: "WW\XAMPLE or \WW\XAMPLE" + /// + /// ------------------------------------------------------------------------------------ + private static string GetSubDirectory(string directory, string subDirectory) + { + Debug.Assert(subDirectory != null); + + string retval = subDirectory.Trim(); + if (retval.Length > 0 && (retval[0] == Path.DirectorySeparatorChar + || retval[0] == Path.AltDirectorySeparatorChar)) + { + // remove leading directory separator from subdirectory + retval = retval.Substring(1); + } + string possiblePath = Path.Combine(directory, retval); + if (Directory.Exists(possiblePath)) + retval = possiblePath; + // Implicit 'else' assumes it to be a full path, + // but not in the code folder structure. + // Sure hope the caller can handle it. + +#if __MonoCS__ + else if (!Directory.Exists(retval)) // previous Substring(1) causes problem for 'full path' in Linux + return subDirectory; +#endif + + return retval; + } + + /// ------------------------------------------------------------------------------------ + /// + /// Get a sub directory of the FW code directory, + /// or return a tidied up version of the original path, + /// if it is not in the FW code folder structure. + /// + /// examples: "WW\XAMPLE or \WW\XAMPLE" + /// + /// ------------------------------------------------------------------------------------ + public static string GetCodeSubDirectory(string subDirectory) + { + return GetSubDirectory(CodeDirectory, subDirectory); + } + + private static string GetFLExBridgeFolderPath() + { + // Setting a Local Machine registry value is problematic for Linux/Mono. (FWNX-1180) + // Try an alternative way of finding FLExBridge first. + var dir = Environment.GetEnvironmentVariable("FLEXBRIDGEDIR"); + if (!String.IsNullOrEmpty(dir) && Directory.Exists(dir)) + return dir; + var key = FwRegistryHelper.FieldWorksBridgeRegistryKeyLocalMachine; + if (key != null) + return GetDirectory(key, "InstallationDir", ""); + return ""; + } + + /// ------------------------------------------------------------------------------------ + /// + /// Get a sub directory of the FW data directory, + /// or return a tidied up version of the original path, + /// if it is not in the FW data folder structure. + /// + /// examples: "Languages or \Languages" + /// + /// ------------------------------------------------------------------------------------ + public static string GetDataSubDirectory(string subDirectory) + { + return GetSubDirectory(DataDirectory, subDirectory); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Get a file in the FW code directory. + /// + /// examples: "iso-8859-1.tec" + /// + /// ------------------------------------------------------------------------------------ + public static string GetCodeFile(string filename) + { + return Path.Combine(CodeDirectory, filename); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets a subdirectory of FieldWorks either by reading the + /// or by getting . + /// Will not return null. + /// + /// The name of the registry value to read from the FW root + /// key in HKLM. + /// The default directory to use if there is no value in the + /// registry. + /// + /// The desired subdirectory of FieldWorks (without trailing directory separator). + /// + /// ------------------------------------------------------------------------------------ + private static string GetDirectory(string registryValue, string defaultDir) + { + using (var userKey = FwRegistryHelper.FieldWorksRegistryKey) + using (var machineKey = FwRegistryHelper.FieldWorksRegistryKeyLocalMachine) + { + var registryKey = userKey; + if (userKey == null || userKey.GetValue(registryValue) == null) + { + registryKey = machineKey; + } + + return GetDirectory(registryKey, registryValue, defaultDir); + } + } + + /// + /// Get a directory for a particular key ignoring current user settings. + /// + /// + /// + /// + private static string GetDirectoryLocalMachine(string registryValue, string defaultDir) + { + using (RegistryKey machineKey = FwRegistryHelper.FieldWorksRegistryKeyLocalMachine) + { + return GetDirectory(machineKey, registryValue, defaultDir); + } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets a subdirectory of FieldWorks either by reading the + /// or by getting . + /// Will not return null. + /// + /// The registry key where the value is stored. + /// The name of the registry value under the given key that + /// contains the desired directory. + /// The default directory to use if there is no value in the + /// registry. + /// + /// The desired subdirectory of FieldWorks (without trailing directory separator). + /// + /// If the desired directory could not be found. + /// + /// ------------------------------------------------------------------------------------ + private static string GetDirectory(RegistryKey registryKey, string registryValue, + string defaultDir) + { + string rootDir = (registryKey == null) ? null : registryKey.GetValue(registryValue, null) as string; + + if (string.IsNullOrEmpty(rootDir) && !string.IsNullOrEmpty(defaultDir)) + rootDir = defaultDir; + if (string.IsNullOrEmpty(rootDir)) + { + throw new ApplicationException( + ResourceHelper.GetResourceString("kstidInvalidInstallation")); + } + // Hundreds of callers of this method are using Path.Combine with the results. + // Combine only works with a root directory if it is followed by \ (e.g., c:\) + // so we don't want to trim the \ in this situation. + string dir = rootDir.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); + return dir.Length > 2 ? dir : dir + Path.DirectorySeparatorChar; + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the directory where FieldWorks code was installed (usually + /// C:\Program Files\SIL\FieldWorks n). + /// Will not return null. + /// + /// If an installation directory could not be + /// found. + /// ------------------------------------------------------------------------------------ + public static string CodeDirectory + { + get + { + string defaultDir = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), DirectoryFinder.CompanyName), + string.Format("FieldWorks {0}", FwUtils.SuiteVersion)); + return GetDirectory("RootCodeDir", defaultDir); + } + } + + private const string ksRootDataDir = "RootDataDir"; + private const string ksFieldWorks = "FieldWorks"; + /// ------------------------------------------------------------------------------------ + /// + /// Gets the directory where FieldWorks data was installed (i.e. under AppData). + /// + /// If an installation directory could not be + /// found. + /// ------------------------------------------------------------------------------------ + public static string DataDirectory + { + get { return GetDirectory(ksRootDataDir, DirectoryFinder.CommonAppDataFolder(ksFieldWorks)); } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the directory where FieldWorks data was installed (i.e. under AppData), + /// as it would be determined ignoring current user registry settings. + /// + /// If an installation directory could not be + /// found. + /// ------------------------------------------------------------------------------------ + public static string DataDirectoryLocalMachine + { + get { return GetDirectoryLocalMachine(ksRootDataDir, DirectoryFinder.CommonAppDataFolder(ksFieldWorks)); } + } + + private static string m_srcdir; + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the src dir (for running tests) + /// + /// ------------------------------------------------------------------------------------ + public static string SourceDirectory + { + get + { + if (!String.IsNullOrEmpty(m_srcdir)) + return m_srcdir; + if (MiscUtils.IsUnix) + { + // Linux doesn't have the registry setting, at least while running tests, + // so we'll assume the executing assembly is $FW/Output/Debug/FwUtils.dll, + // and the source dir is $FW/Src. + Uri uriBase = new Uri(Assembly.GetExecutingAssembly().CodeBase); + var dir = Path.GetDirectoryName(Uri.UnescapeDataString(uriBase.AbsolutePath)); + dir = Path.GetDirectoryName(dir); // strip the parent directory name (Debug) + dir = Path.GetDirectoryName(dir); // strip the parent directory again (Output) + dir = Path.Combine(dir, "Src"); + if (!Directory.Exists(dir)) + throw new ApplicationException("Could not find the Src directory. Was expecting it at: " + dir); + m_srcdir = dir; + } + else + { + string rootDir = null; + if (FwRegistryHelper.FieldWorksRegistryKey != null) + { + rootDir = FwRegistryHelper.FieldWorksRegistryKey.GetValue("RootCodeDir") as string; + } + else if (FwRegistryHelper.FieldWorksRegistryKeyLocalMachine != null) + { + rootDir = FwRegistryHelper.FieldWorksRegistryKeyLocalMachine.GetValue("RootCodeDir") as string; + } + if (string.IsNullOrEmpty(rootDir)) + { + throw new ApplicationException( + string.Format(@"You need to have the registry key {0}\RootCodeDir pointing at your DistFiles dir.", + FwRegistryHelper.FieldWorksRegistryKeyLocalMachine.Name)); + } + string fw = Directory.GetParent(rootDir).FullName; + string src = Path.Combine(fw, "Src"); + if (!Directory.Exists(src)) + throw new ApplicationException(@"Could not find the Src directory. Was expecting it at: " + src); + m_srcdir = src; + } + return m_srcdir; + } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the full path name of the editorial checks directory. + /// + /// ------------------------------------------------------------------------------------ + public static string EditorialChecksDirectory + { + get + { + string directory = GetCodeSubDirectory(@"Editorial Checks"); + if (!Directory.Exists(directory)) + { + string msg = ResourceHelper.GetResourceString("kstidUnableToFindEditorialChecks"); + throw new ApplicationException(string.Format(msg, directory)); + } + return directory; + } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the basic editorial checks DLL. Note that this is currently the ScrChecks DLL, + /// but if we ever split this DLL to separate Scripture-specific checks from more + /// generic checks that are really based on the WS and could be used to check any text, + /// then this property should be made to return the DLL containing the punctuation + /// patterns and characters checks. + /// + /// ------------------------------------------------------------------------------------ + public static string BasicEditorialChecksDll + { + get + { +#if RELEASE + try + { +#endif + string directory = EditorialChecksDirectory; + string checksDll = Path.Combine(directory, "ScrChecks.dll"); + if (!File.Exists(checksDll)) + { + string msg = ResourceHelper.GetResourceString("kstidUnableToFindEditorialChecks"); + throw new ApplicationException(string.Format(msg, directory)); + } + return checksDll; +#if RELEASE + } + catch (ApplicationException e) + { + throw new InstallationException(e); + } +#endif + } + } + + /// + /// Gets the legacy wordforming character overrides file. + /// + public static string LegacyWordformingCharOverridesFile + { + get + { + return Path.Combine(CodeDirectory, "WordFormingCharOverrides.xml"); + } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the dir where templates are installed + /// + /// ------------------------------------------------------------------------------------ + public static string TemplateDirectory + { + get { return GetCodeSubDirectory("Templates"); } + } + + private const string ksProjects = "Projects"; + + /// ------------------------------------------------------------------------------------ + /// + /// Gets or sets the dir where projects are stored. Setting to null will delete the HKCU + /// key, so that the HKLM key (system default) will be used for this user. + /// + /// If user does not have permission to write to HKLM + /// + /// ------------------------------------------------------------------------------------ + public static string ProjectsDirectory + { + get { return GetDirectory(ksProjectsDir, Path.Combine(DataDirectory, ksProjects)); } + set + { + if (ProjectsDirectory == value) + return; // no change. + + using (var registryKey = FwRegistryHelper.FieldWorksRegistryKey) + { + if (value == null) + { + registryKey.DeleteValue(ksProjectsDir); + } + else + { + registryKey.SetValue(ksProjectsDir, value); + } + } + } + } + + /// + /// The project directory that would be identified if we didn't have any current user registry settings. + /// + public static string ProjectsDirectoryLocalMachine + { + get { return GetDirectoryLocalMachine(ksProjectsDir, Path.Combine(DataDirectoryLocalMachine, ksProjects)); } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Determines whether the given path is a direct sub folder of the projects directory. + /// (This is typically true for the a project-specific folder.) + /// + /// The path. + /// ------------------------------------------------------------------------------------ + public static bool IsSubFolderOfProjectsDirectory(string path) + { + return !string.IsNullOrEmpty(path) && Path.GetDirectoryName(path) == ProjectsDirectory; + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the default directory for Backup files. This is per-user. + /// + /// If setting this value and the user does not have + /// permission to write to HKCU (probably can never happen) + /// ------------------------------------------------------------------------------------ + public static string DefaultBackupDirectory + { + get + { + // NOTE: SpecialFolder.MyDocuments returns $HOME on Linux + string myDocs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + // FWNX-501: use slightly different default path on Linux + string defaultDir = MiscUtils.IsUnix ? + Path.Combine(myDocs, "Documents/fieldworks/backups") : + Path.Combine(Path.Combine(myDocs, "My FieldWorks"), "Backups"); + + using (RegistryKey registryKey = FwRegistryHelper.FieldWorksRegistryKey.OpenSubKey("ProjectBackup")) + return GetDirectory(registryKey, "DefaultBackupDirectory", defaultDir); + } + set + { + using (RegistryKey key = FwRegistryHelper.FieldWorksRegistryKey.CreateSubKey("ProjectBackup")) + { + if (key != null) + key.SetValue("DefaultBackupDirectory", value); + } + } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the biblical key terms localization files. + /// + /// ------------------------------------------------------------------------------------ + static public string[] KeyTermsLocalizationFiles + { + get + { + // SE version doesn't install the TE folder. + if (!Directory.Exists(TeFolder)) + return new string[]{""}; + return Directory.GetFiles(TeFolder, ksBiblicaltermsLocFilePrefix + "*" + + ksBiblicaltermsLocFileExtension, SearchOption.TopDirectoryOnly); + } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Returns the file name containing the localization of the key terms list for the + /// given ICU locale. + /// + /// ------------------------------------------------------------------------------------ + static public string GetKeyTermsLocFilename(string locale) + { + return Path.Combine(TeFolder, ksBiblicaltermsLocFilePrefix + locale + + ksBiblicaltermsLocFileExtension); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Extracts the locale identifier (string) from a key terms localization file name. + /// + /// ------------------------------------------------------------------------------------ + static public string GetLocaleFromKeyTermsLocFile(string locFilename) + { + return Path.GetFileName(locFilename).Replace(ksBiblicaltermsLocFilePrefix, + String.Empty).Replace(ksBiblicaltermsLocFileExtension, String.Empty); + } + + /// + /// Gets the FDO directories service. + /// + public static IFdoDirectories FdoDirectories + { + get { return s_fdoDirs; } + } + + private class FwFdoDirectories : IFdoDirectories + { + /// + /// Gets the projects directory. + /// + public string ProjectsDirectory + { + get { return FwDirectoryFinder.ProjectsDirectory; } + } + + public string TemplateDirectory + { + get { return FwDirectoryFinder.TemplateDirectory; } + } + } + } +} diff --git a/Src/Common/FwUtils/FwLinkArgs.cs b/Src/Common/FwUtils/FwLinkArgs.cs index 192eefef45..c170be9ca6 100644 --- a/Src/Common/FwUtils/FwLinkArgs.cs +++ b/Src/Common/FwUtils/FwLinkArgs.cs @@ -10,6 +10,7 @@ using System.Text; using System.Collections.Generic; using System.Web; +using SIL.FieldWorks.FDO; using SIL.FieldWorks.Resources; using SIL.Utils; using XCore; @@ -829,7 +830,7 @@ private static Dictionary ParseCommandLine(string[] rgArgs) // There may not be a key, if this is the first argument, as when opening a file directly. if (sKey.Length == 0) { - sKey = (Path.GetExtension(value) == FwFileExtensions.ksFwBackupFileExtension) ? kRestoreFile : kProject; + sKey = (Path.GetExtension(value) == FdoFileHelper.ksFwBackupFileExtension) ? kRestoreFile : kProject; } } } diff --git a/Src/Common/FwUtils/FwRegistryHelper.cs b/Src/Common/FwUtils/FwRegistryHelper.cs index 68a970d0de..922232f7b9 100644 --- a/Src/Common/FwUtils/FwRegistryHelper.cs +++ b/Src/Common/FwUtils/FwRegistryHelper.cs @@ -197,35 +197,6 @@ public bool Paratext7orLaterInstalled() return false; } } - - /// - /// LT-14787 Database displays error about inaccessible Paratext projects - /// If there is a registry value for this but the folder is not there we need to return false because - /// paratext is not installed correctly. Also if there is no registry entry for this then return false. - /// - public bool ParatextSettingsDirectoryExists() - { - var regValue = ParatextSettingsDirectory(); - return !String.IsNullOrEmpty(regValue) && Directory.Exists(regValue); - } - - /// - /// Returns the path to the Paratext settings (projects) directory as specified in the registry - /// ENHANCE (Hasso) 2013.09: added this to expose the directory for Unix users, because trying to get it from ScrTextCollections - /// always returns null on Unix. This is really a Paratext problem, and this method may have no benefit. - /// - public string ParatextSettingsDirectory() - { - using (var paratextKey = Registry.LocalMachine.OpenSubKey("Software\\ScrChecks\\1.0\\Settings_Directory")) - { - if (paratextKey != null) - { - var keyName = paratextKey.ToString(); - return Registry.GetValue(keyName, "", "") as string; - } - } - return null; - } } /// ------------------------------------------------------------------------------------ @@ -389,29 +360,9 @@ public static bool Paratext7orLaterInstalled() return RegistryHelperImpl.Paratext7orLaterInstalled(); } - /// - /// If there is a registry value for this but the folder is not there we need to return false because - /// paratext is not installed correctly. Also if there is no registry entry for this then return false. - /// - public static bool ParatextSettingsDirectoryExists() - { - return RegistryHelperImpl.ParatextSettingsDirectoryExists(); - } - - /// - /// Returns the path to the Paratext settings (projects) directory as specified in the registry - /// ENHANCE (Hasso) 2013.09: added this to expose the directory for Unix users, because trying to get it from ScrTextCollections - /// always returns null on Unix. This is really a Paratext problem, and this method may have no benefit. - /// - public static string ParatextSettingsDirectory() - { - return RegistryHelperImpl.ParatextSettingsDirectory(); - } - /// /// E.g. the first time the user runs FW8, we need to copy a bunch of registry keys /// from HKCU/Software/SIL/FieldWorks/7.0 -> FieldWorks/8. - /// Also copy HKEY_LOCAL_MACHINE\SOFTWARE\SIL\FieldWorks\7.0 ProjectShared (LT-15154). /// public static void UpgradeUserSettingsIfNeeded() { @@ -433,7 +384,6 @@ public static void UpgradeUserSettingsIfNeeded() // After copying everything delete the old key FieldWorksVersionlessRegistryKey.DeleteSubKeyTree(OldFieldWorksRegistryKeyNameVersion7); - // Don't delete old ProjectShared since it is in HKLM and we would need admin privileges. } catch (SecurityException se) { @@ -441,6 +391,30 @@ public static void UpgradeUserSettingsIfNeeded() } } + /// + /// Migrate the ProjectShared value stored in HKLM in version 7 into the HKCU (.Default since this will be run as system) + /// + /// + public static void MigrateVersion7ValueIfNeeded() + { + // Guard for some broken Windows machines having trouble accessing HKLM (LT-15158). + var hklm = LocalMachineHive; + if (hklm != null) + { + using (var oldProjectSharedSettingLocation = hklm.OpenSubKey(@"SOFTWARE\SIL\FieldWorks\7.0")) + using (var newProjectSharedSettingLocation = FieldWorksRegistryKey) + { + object projectSharedValue; + if (oldProjectSharedSettingLocation != null && + RegistryHelper.RegEntryExists(oldProjectSharedSettingLocation, string.Empty, @"ProjectShared", + out projectSharedValue)) + { + FieldWorksRegistryKey.SetValue(@"ProjectShared", projectSharedValue); + } + } + } + } + private static void CopySubKeyTree(RegistryKey srcSubKey, RegistryKey destSubKey) { // Copies all keys and values from src to dest subKey recursively diff --git a/Src/Common/FwUtils/FwSubKey.cs b/Src/Common/FwUtils/FwSubKey.cs index 3da7a7a32b..72ef5eeb54 100644 --- a/Src/Common/FwUtils/FwSubKey.cs +++ b/Src/Common/FwUtils/FwSubKey.cs @@ -17,13 +17,13 @@ public class FwSubKey { /// /// The name of the Translation Editor registry subkey (Even though this is the same as - /// DirectoryFinder.ksTeFolderName and FwUtils.ksTeAppName, PLEASE do not use them interchangeably. + /// FwDirectoryFinder.ksTeFolderName and FwUtils.ksTeAppName, PLEASE do not use them interchangeably. /// Use the one that is correct for your context, in case they need to be changed later.) /// public const string TE = FwUtils.ksTeAppName; /// /// The name of the Language Explorer registry subkey (Even though this is the same as - /// DirectoryFinder.ksFlexFolderName and FwUtils.ksFlexAppName, PLEASE do not use them interchangeably. + /// FwDirectoryFinder.ksFlexFolderName and FwUtils.ksFlexAppName, PLEASE do not use them interchangeably. /// Use the one that is correct for your context, in case they need to be changed later.) /// public const string LexText = FwUtils.ksFlexAppName; diff --git a/Src/Common/FwUtils/FwUtils.cs b/Src/Common/FwUtils/FwUtils.cs index 11859118c5..4189bbd077 100644 --- a/Src/Common/FwUtils/FwUtils.cs +++ b/Src/Common/FwUtils/FwUtils.cs @@ -30,7 +30,7 @@ public static class FwUtils public const string ksSuiteName = "FieldWorks"; /// /// The name of the Translation Editor folder (Even though this is the same as - /// DirectoryFinder.ksTeFolderName and FwSubKey.TE, PLEASE do not use them interchangeably. + /// FwDirectoryFinder.ksTeFolderName and FwSubKey.TE, PLEASE do not use them interchangeably. /// Use the one that is correct for your context, in case they need to be changed later.) /// public const string ksTeAppName = "Translation Editor"; @@ -42,7 +42,7 @@ public static class FwUtils public const string ksFullTeAppObjectName = "SIL.FieldWorks.TE.TeApp"; /// /// The name of the Language Explorer folder (Even though this is the same as - /// DirectoryFinder.ksFlexFolderName and FwSubKey.LexText, PLEASE do not use them interchangeably. + /// FwDirectoryFinder.ksFlexFolderName and FwSubKey.LexText, PLEASE do not use them interchangeably. /// Use the one that is correct for your context, in case they need to be changed later.) /// public const string ksFlexAppName = "Language Explorer"; @@ -70,7 +70,7 @@ public static bool IsTEInstalled get { if (s_fIsTEInstalled == null) - s_fIsTEInstalled = File.Exists(DirectoryFinder.TeExe); + s_fIsTEInstalled = File.Exists(FwDirectoryFinder.TeExe); return (bool)s_fIsTEInstalled; } } @@ -97,7 +97,7 @@ public static bool IsOkToDisplayScriptureIfPresent /// ------------------------------------------------------------------------------------ public static bool IsFlexInstalled { - get { return File.Exists(DirectoryFinder.FlexExe); } + get { return File.Exists(FwDirectoryFinder.FlexExe); } } /// ------------------------------------------------------------------------------------ @@ -206,13 +206,13 @@ public static string GetFontNameForLanguage(string lang) /// /// Whenever possible use this in place of new PalasoWritingSystemManager. /// It sets the TemplateFolder, which unfortunately the constructor cannot do because - /// the direction of our dependencies does not allow it to reference FwUtils and access DirectoryFinder. + /// the direction of our dependencies does not allow it to reference FwUtils and access FwDirectoryFinder. /// /// public static PalasoWritingSystemManager CreateWritingSystemManager() { var result = new PalasoWritingSystemManager(); - result.TemplateFolder = DirectoryFinder.TemplateDirectory; + result.TemplateFolder = FwDirectoryFinder.TemplateDirectory; return result; } diff --git a/Src/Common/FwUtils/FwUtils.csproj b/Src/Common/FwUtils/FwUtils.csproj index 9b731f79d1..e0f9bd534e 100644 --- a/Src/Common/FwUtils/FwUtils.csproj +++ b/Src/Common/FwUtils/FwUtils.csproj @@ -114,6 +114,10 @@ False ..\..\..\Output\Debug\CoreImpl.dll + + False + ..\..\..\Output\Debug\FDO.dll + FwResources ..\..\..\Output\Debug\FwResources.dll @@ -122,10 +126,6 @@ False ..\..\..\Downloads\IPCFramework.dll - - False - ..\..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll - False ..\..\..\Downloads\Palaso.dll @@ -134,10 +134,6 @@ False ..\..\..\Downloads\Palaso.Lift.dll - - False - ..\..\..\DistFiles\ParatextShared.dll - False ..\..\..\Output\Debug\SharedScrUtils.dll @@ -174,17 +170,12 @@ CommonAssemblyInfo.cs - - - - - + - @@ -192,31 +183,19 @@ True FwUtilsStrings.resx - - - - - - Code - Code - - - - - diff --git a/Src/Common/FwUtils/FwUtilsStrings.Designer.cs b/Src/Common/FwUtils/FwUtilsStrings.Designer.cs index 2bc4fc95a0..8778805662 100644 --- a/Src/Common/FwUtils/FwUtilsStrings.Designer.cs +++ b/Src/Common/FwUtils/FwUtilsStrings.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.239 +// Runtime Version:4.0.30319.18052 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -9,255 +9,219 @@ //------------------------------------------------------------------------------ namespace SIL.FieldWorks.Common.FwUtils { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class FwUtilsStrings { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal FwUtilsStrings() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SIL.FieldWorks.Common.FwUtils.FwUtilsStrings", typeof(FwUtilsStrings).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to The help file could not be located.. - /// - internal static string ksCannotFindHelp { - get { - return ResourceManager.GetString("ksCannotFindHelp", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Change Failed. - /// - internal static string ksChangeFailed { - get { - return ResourceManager.GetString("ksChangeFailed", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to AD. - /// - internal static string ksGenDateAD { - get { - return ResourceManager.GetString("ksGenDateAD", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to After. - /// - internal static string ksGenDateAfter { - get { - return ResourceManager.GetString("ksGenDateAfter", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to About. - /// - internal static string ksGenDateApprox { - get { - return ResourceManager.GetString("ksGenDateApprox", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to BC. - /// - internal static string ksGenDateBC { - get { - return ResourceManager.GetString("ksGenDateBC", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Before. - /// - internal static string ksGenDateBefore { - get { - return ResourceManager.GetString("ksGenDateBefore", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The help topic is not available for topic: {0}. - /// - internal static string ksNoHelpTopicX { - get { - return ResourceManager.GetString("ksNoHelpTopicX", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The project you are opening will not communicate with Paratext - ///because a project with the same name is already open. - ///If you want to use Paratext with this project, make a change in this project (so that it will start first), close both projects, then restart Flex.. - /// - internal static string ksPtCommunicationProblem { - get { - return ResourceManager.GetString("ksPtCommunicationProblem", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to You do not have permission to change the setting "{0}". Administrator privileges are required to make changes affecting all users of this computer.. - /// - internal static string ksRegChangeFailed { - get { - return ResourceManager.GetString("ksRegChangeFailed", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Version: {0} {1} {2}. - /// - internal static string kstidAppVersionFmt { - get { - return ResourceManager.GetString("kstidAppVersionFmt", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to FieldWorks has unexpectedly timed out trying to determine whether the spelling dictionary {0} exists. FieldWorks will assume there is no such dictionary, which may affect spell-checking. If you think this dictionary should exist, we recommend restarting your computer. If you see this message regularly, please report it as a bug.. - /// - internal static string kstIdCantDoDictExists { - get { - return ResourceManager.GetString("kstIdCantDoDictExists", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Spelling Dictionary Problem. - /// - internal static string kstidCantDoDictExistsCaption { - get { - return ResourceManager.GetString("kstidCantDoDictExistsCaption", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to cm. - /// - internal static string kstidCm { - get { - return ResourceManager.GetString("kstidCm", resourceCulture); - } - } - - /// - /// Looks up a localized string - /// - internal static string kstidLicense { - get { - return ResourceManager.GetString("kstidLicense", resourceCulture); - } - } - - /// - /// Looks up a localized string - /// - internal static string kstidLicenseURL { - get { - return ResourceManager.GetString("kstidLicenseURL", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Version: {0}. - /// - internal static string kstidFwVersionFmt { - get { - return ResourceManager.GetString("kstidFwVersionFmt", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to in. - /// - internal static string kstidIn { - get { - return ResourceManager.GetString("kstidIn", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to ". - /// - internal static string kstidInches { - get { - return ResourceManager.GetString("kstidInches", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The writing system {0} specifies an invalid spelling dictionary ({1}). Valid spelling dictionary IDs must only contain ASCII alphanumeric characters or underline. Spell checking will not work for this writing system until you correct this in the Writing System Properties dialog.. - /// - internal static string kstidInvalidDictId { - get { - return ResourceManager.GetString("kstidInvalidDictId", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to mm. - /// - internal static string kstidMm { - get { - return ResourceManager.GetString("kstidMm", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to pt. - /// - internal static string kstidPt { - get { - return ResourceManager.GetString("kstidPt", resourceCulture); - } - } - } + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class FwUtilsStrings { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal FwUtilsStrings() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SIL.FieldWorks.Common.FwUtils.FwUtilsStrings", typeof(FwUtilsStrings).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to The help file could not be located.. + /// + internal static string ksCannotFindHelp { + get { + return ResourceManager.GetString("ksCannotFindHelp", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Change Failed. + /// + internal static string ksChangeFailed { + get { + return ResourceManager.GetString("ksChangeFailed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to AD. + /// + internal static string ksGenDateAD { + get { + return ResourceManager.GetString("ksGenDateAD", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to After. + /// + internal static string ksGenDateAfter { + get { + return ResourceManager.GetString("ksGenDateAfter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to About. + /// + internal static string ksGenDateApprox { + get { + return ResourceManager.GetString("ksGenDateApprox", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to BC. + /// + internal static string ksGenDateBC { + get { + return ResourceManager.GetString("ksGenDateBC", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Before. + /// + internal static string ksGenDateBefore { + get { + return ResourceManager.GetString("ksGenDateBefore", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The help topic is not available for topic: {0}. + /// + internal static string ksNoHelpTopicX { + get { + return ResourceManager.GetString("ksNoHelpTopicX", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The project you are opening will not communicate with Paratext + ///because a project with the same name is already open. + ///If you want to use Paratext with this project, make a change in this project (so that it will start first), close both projects, then restart FLEx.. + /// + internal static string ksPtCommunicationProblem { + get { + return ResourceManager.GetString("ksPtCommunicationProblem", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You do not have permission to change the setting "{0}". Administrator privileges are required to make changes affecting all users of this computer.. + /// + internal static string ksRegChangeFailed { + get { + return ResourceManager.GetString("ksRegChangeFailed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to FieldWorks has unexpectedly timed out trying to determine whether the spelling dictionary {0} exists. FieldWorks will assume there is no such dictionary, which may affect spell-checking. If you think this dictionary should exist, we recommend restarting your computer. If you see this message regularly, please report it as a bug.. + /// + internal static string kstIdCantDoDictExists { + get { + return ResourceManager.GetString("kstIdCantDoDictExists", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Spelling Dictionary Problem. + /// + internal static string kstidCantDoDictExistsCaption { + get { + return ResourceManager.GetString("kstidCantDoDictExistsCaption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to cm. + /// + internal static string kstidCm { + get { + return ResourceManager.GetString("kstidCm", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to in. + /// + internal static string kstidIn { + get { + return ResourceManager.GetString("kstidIn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ". + /// + internal static string kstidInches { + get { + return ResourceManager.GetString("kstidInches", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The writing system {0} specifies an invalid spelling dictionary ({1}). Valid spelling dictionary IDs must only contain ASCII alphanumeric characters or underline. Spell checking will not work for this writing system until you correct this in the Writing System Properties dialog.. + /// + internal static string kstidInvalidDictId { + get { + return ResourceManager.GetString("kstidInvalidDictId", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to mm. + /// + internal static string kstidMm { + get { + return ResourceManager.GetString("kstidMm", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to pt. + /// + internal static string kstidPt { + get { + return ResourceManager.GetString("kstidPt", resourceCulture); + } + } + } } diff --git a/Src/Common/FwUtils/FwUtilsStrings.resx b/Src/Common/FwUtils/FwUtilsStrings.resx index 7ba7ff2218..2d65e11b8e 100644 --- a/Src/Common/FwUtils/FwUtilsStrings.resx +++ b/Src/Common/FwUtils/FwUtilsStrings.resx @@ -1,200 +1,184 @@  - + 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. + --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - text/microsoft-resx + text/microsoft-resx - 2.0 + 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - The help file could not be located. + The help file could not be located. - The help topic is not available for topic: {0} + The help topic is not available for topic: {0} - AD + AD - After + After - About + About - BC + BC - Before + Before - cm - Measurement unit abbreviation for Centimeters (Localized string should preserve leading space if needed in formatted display.) + cm + Measurement unit abbreviation for Centimeters (Localized string should preserve leading space if needed in formatted display.) - in - Measurement unit abbreviation for Inches (Localized string should preserve leading space if needed in formatted display.) + in + Measurement unit abbreviation for Inches (Localized string should preserve leading space if needed in formatted display.) - " - Measurement unit symbol for Inches (If culture doesn't have a separate symbol for specifying inches, localized value for this string should be set to match value of kstidIn.) + " + Measurement unit symbol for Inches (If culture doesn't have a separate symbol for specifying inches, localized value for this string should be set to match value of kstidIn.) - mm - Measurement unit abbreviation for Millimeters (Localized string should preserve leading space if needed in formatted display.) + mm + Measurement unit abbreviation for Millimeters (Localized string should preserve leading space if needed in formatted display.) - pt - Measurement unit abbreviation for Points (Localized string should preserve leading space if needed in formatted display.) - - - Version: {0} {1} {2} - Displays in the Help/About box and the splash screen - - - This software is licensed under the LGPL, version 2.1 or later - Displays in the Help/About box and the splash screen - - - (http://www.gnu.org/licenses/lgpl-2.1.html) - Displays in the Help/About box - - - Version: {0} - Displays in the Help/About box and the splash screen + pt + Measurement unit abbreviation for Points (Localized string should preserve leading space if needed in formatted display.) - Change Failed - Caption for dialog reporting failure to update. + Change Failed + Caption for dialog reporting failure to update. - You do not have permission to change the setting "{0}". Administrator privileges are required to make changes affecting all users of this computer. - Error message when writing a registry setting for "local machine" fails. + You do not have permission to change the setting "{0}". Administrator privileges are required to make changes affecting all users of this computer. + Error message when writing a registry setting for "local machine" fails. - FieldWorks has unexpectedly timed out trying to determine whether the spelling dictionary {0} exists. FieldWorks will assume there is no such dictionary, which may affect spell-checking. If you think this dictionary should exist, we recommend restarting your computer. If you see this message regularly, please report it as a bug. + FieldWorks has unexpectedly timed out trying to determine whether the spelling dictionary {0} exists. FieldWorks will assume there is no such dictionary, which may affect spell-checking. If you think this dictionary should exist, we recommend restarting your computer. If you see this message regularly, please report it as a bug. - Spelling Dictionary Problem + Spelling Dictionary Problem - The writing system {0} specifies an invalid spelling dictionary ({1}). Valid spelling dictionary IDs must only contain ASCII alphanumeric characters or underline. Spell checking will not work for this writing system until you correct this in the Writing System Properties dialog. - Error message. {0} might be a code like "fr" and {1} a bad ID, typically a short string like "frn[". + The writing system {0} specifies an invalid spelling dictionary ({1}). Valid spelling dictionary IDs must only contain ASCII alphanumeric characters or underline. Spell checking will not work for this writing system until you correct this in the Writing System Properties dialog. + Error message. {0} might be a code like "fr" and {1} a bad ID, typically a short string like "frn[". - The project you are opening will not communicate with Paratext + The project you are opening will not communicate with Paratext because a project with the same name is already open. If you want to use Paratext with this project, make a change in this project (so that it will start first), close both projects, then restart FLEx. - + \ No newline at end of file diff --git a/Src/Common/FwUtils/FwUtilsTests/CaseFunctionsTest.cs b/Src/Common/FwUtils/FwUtilsTests/CaseFunctionsTest.cs index 8cd8a11c57..8b55177725 100644 --- a/Src/Common/FwUtils/FwUtilsTests/CaseFunctionsTest.cs +++ b/Src/Common/FwUtils/FwUtilsTests/CaseFunctionsTest.cs @@ -5,9 +5,8 @@ // File: CaseFunctionsTest.cs // Responsibility: -using System; using NUnit.Framework; -using SIL.FieldWorks.Common.COMInterfaces; +using SIL.CoreImpl; using SIL.FieldWorks.Test.TestUtils; using SIL.Utils; diff --git a/Src/Common/FwUtils/FwUtilsTests/DirectoryFinderTests.cs b/Src/Common/FwUtils/FwUtilsTests/DirectoryFinderTests.cs deleted file mode 100644 index 0e41e45d94..0000000000 --- a/Src/Common/FwUtils/FwUtilsTests/DirectoryFinderTests.cs +++ /dev/null @@ -1,459 +0,0 @@ -// Copyright (c) 2008-2013 SIL International -// This software is licensed under the LGPL, version 2.1 or later -// (http://www.gnu.org/licenses/lgpl-2.1.html) -// -// File: DirectoryFinderTests.cs -// Responsibility: Eberhard Beilharz -// Last reviewed: - -using System; -using System.IO; -using NUnit.Framework; -using SIL.FieldWorks.Test.TestUtils; -using SIL.Utils; - -namespace SIL.FieldWorks.Common.FwUtils -{ - - ///----------------------------------------------------------------------------------------- - /// - /// Tests for the DirectoryFinder class - /// - ///----------------------------------------------------------------------------------------- - [TestFixture] - public class DirectoryFinderTests : BaseTest - { - /// - /// Resets the registry helper - /// - [TestFixtureTearDown] - public void TearDown() - { - FwRegistryHelper.Manager.Reset(); - } - - /// - /// Fixture setup - /// - [TestFixtureSetUp] - public void TestFixtureSetup() - { - DirectoryFinder.CompanyName = "SIL"; - FwRegistryHelper.Manager.SetRegistryHelper(new DummyFwRegistryHelper()); - FwRegistryHelper.FieldWorksRegistryKey.SetValue("RootDataDir", Path.GetFullPath(Path.Combine(UtilsAssemblyDir, "../../DistFiles"))); - FwRegistryHelper.FieldWorksRegistryKey.SetValue("RootCodeDir", Path.GetFullPath(Path.Combine(UtilsAssemblyDir, "../../DistFiles"))); - } - - ///------------------------------------------------------------------------------------- - /// - /// Gets the directory where the Utils assembly is - /// - ///------------------------------------------------------------------------------------- - private string UtilsAssemblyDir - { - get - { - return Path.GetDirectoryName(typeof(DirectoryFinder).Assembly.CodeBase - .Substring(MiscUtils.IsUnix ? 7 : 8)); - } - } - - ///------------------------------------------------------------------------------------- - /// - /// Tests the FWCodeDirectory property. This should return the DistFiles directory. - /// - ///------------------------------------------------------------------------------------- - [Test] - public void FWCodeDirectory() - { - var currentDir = Path.GetFullPath(Path.Combine(UtilsAssemblyDir, "../../DistFiles")); - Assert.That(DirectoryFinder.FWCodeDirectory, Is.SamePath(currentDir)); - } - - /// - /// Verify that the user project key falls back to the local machine. - /// - [Test] - public void GettingProjectDirWithEmptyUserKeyReturnsLocalMachineKey() - { - using (var fwHKCU = FwRegistryHelper.FieldWorksRegistryKey) - using (var fwHKLM = FwRegistryHelper.FieldWorksRegistryKeyLocalMachine) - { - if (fwHKCU.GetValue("ProjectsDir") != null) - { - fwHKCU.DeleteValue("ProjectsDir"); - } - fwHKLM.SetValue("ProjectsDir", "HKLM_TEST"); - Assert.That(DirectoryFinder.ProjectsDirectory, Is.EqualTo(DirectoryFinder.ProjectsDirectoryLocalMachine)); - Assert.That(DirectoryFinder.ProjectsDirectory, Is.EqualTo("HKLM_TEST")); - } - } - - /// - /// Verify that the user project key overrides the local machine. - /// - [Test] - public void GettingProjectDirWithUserDifferentFromLMReturnsUser() - { - DirectoryFinder.ProjectsDirectory = "NewHKCU_TEST_Value"; - Assert.That(DirectoryFinder.ProjectsDirectory, Is.Not.EqualTo(DirectoryFinder.ProjectsDirectoryLocalMachine)); - Assert.That(DirectoryFinder.ProjectsDirectory, Is.EqualTo("NewHKCU_TEST_Value")); - } - - /// - /// Verify that setting the user key to null deletes the user setting and falls back to local machine. - /// - [Test] - public void SettingProjectDirToNullDeletesUserKey() - { - DirectoryFinder.ProjectsDirectory = null; - Assert.That(DirectoryFinder.ProjectsDirectory, Is.EqualTo(DirectoryFinder.ProjectsDirectoryLocalMachine)); - - using (var fwHKCU = FwRegistryHelper.FieldWorksRegistryKey) - using (var fwHKLM = FwRegistryHelper.FieldWorksRegistryKeyLocalMachine) - { - Assert.Null(fwHKCU.GetValue("ProjectsDir")); - Assert.NotNull(fwHKLM.GetValue("ProjectsDir")); - } - } - - ///------------------------------------------------------------------------------------- - /// - /// Tests the FWDataDirectory property. This should return the DistFiles directory. - /// - ///------------------------------------------------------------------------------------- - [Test] - public void FWDataDirectory() - { - var currentDir = Path.GetFullPath(Path.Combine(UtilsAssemblyDir, "../../DistFiles")); - Assert.That(DirectoryFinder.FWDataDirectory, Is.SamePath(currentDir)); - } - - ///------------------------------------------------------------------------------------- - /// - /// Tests the FwSourceDirectory property. This should return the DistFiles directory. - /// - ///------------------------------------------------------------------------------------- - [Test] - public void FwSourceDirectory() - { - string expectedDir = Path.GetFullPath(Path.Combine(UtilsAssemblyDir, "../../Src")); - Assert.That(DirectoryFinder.FwSourceDirectory, Is.SamePath(expectedDir)); - } - - ///------------------------------------------------------------------------------------- - /// - /// Tests the GetFWCodeSubDirectory method when we pass a subdirectory without a - /// leading directory separator - /// - ///------------------------------------------------------------------------------------- - [Test] - public void GetFWCodeSubDirectory_NoLeadingSlash() - { - Assert.That(DirectoryFinder.GetFWCodeSubDirectory("Translation Editor/Configuration"), - Is.SamePath(Path.Combine(DirectoryFinder.FWCodeDirectory, "Translation Editor/Configuration"))); - } - - ///------------------------------------------------------------------------------------- - /// - /// Tests the GetFWCodeSubDirectory method when we pass a subdirectory with a - /// leading directory separator - /// - ///------------------------------------------------------------------------------------- - [Test] - public void GetFWCodeSubDirectory_LeadingSlash() - { - Assert.That(DirectoryFinder.GetFWCodeSubDirectory("/Translation Editor/Configuration"), - Is.SamePath(Path.Combine(DirectoryFinder.FWCodeDirectory, "Translation Editor/Configuration"))); - } - - ///------------------------------------------------------------------------------------- - /// - /// Tests the GetFWCodeSubDirectory method when we pass an invalid subdirectory - /// - ///------------------------------------------------------------------------------------- - [Test] - public void GetFWCodeSubDirectory_InvalidDir() - { - Assert.That(DirectoryFinder.GetFWCodeSubDirectory("NotExisting"), - Is.SamePath("NotExisting")); - } - - ///------------------------------------------------------------------------------------- - /// - /// Tests the GetFWDataSubDirectory method when we pass a subdirectory without a - /// leading directory separator - /// - ///------------------------------------------------------------------------------------- - [Test] - public void GetFWDataSubDirectory_NoLeadingSlash() - { - Assert.That(DirectoryFinder.GetFWDataSubDirectory("Translation Editor/Configuration"), - Is.SamePath(Path.Combine(DirectoryFinder.FWDataDirectory, "Translation Editor/Configuration"))); - } - - ///------------------------------------------------------------------------------------- - /// - /// Tests the GetFWDataSubDirectory method when we pass a subdirectory with a - /// leading directory separator - /// - ///------------------------------------------------------------------------------------- - [Test] - public void GetFWDataSubDirectory_LeadingSlash() - { - Assert.That(DirectoryFinder.GetFWDataSubDirectory("/Translation Editor/Configuration"), - Is.SamePath(Path.Combine(DirectoryFinder.FWDataDirectory, "Translation Editor/Configuration"))); - } - - ///------------------------------------------------------------------------------------- - /// - /// Tests the GetFWDataSubDirectory method when we pass an invalid subdirectory - /// - ///------------------------------------------------------------------------------------- - [Test] - public void GetFWDataSubDirectory_InvalidDir() - { - Assert.That(DirectoryFinder.GetFWDataSubDirectory("NotExisting"), - Is.SamePath("NotExisting")); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Tests the GetLinkedFilesRelativePathFromFullPath method - /// - /// ------------------------------------------------------------------------------------ - [Test] - public void GetLinkedFilesRelativePathFromFullPath() - { - Assert.AreEqual(String.Format("%proj%{0}LinkedFiles", Path.DirectorySeparatorChar), - DirectoryFinderRelativePaths.GetLinkedFilesRelativePathFromFullPath(String.Format("%proj%{0}LinkedFiles", Path.DirectorySeparatorChar), - Path.Combine(DirectoryFinder.FwSourceDirectory, "FDO/FDOTests/BackupRestore/Project"), - "Project")); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Tests the GetLinkedFilesFullPathFromRelativePath method - /// - /// ------------------------------------------------------------------------------------ - [Test] - public void GetLinkedFilesFullPathFromRelativePath() - { - var projectPath = Path.Combine(DirectoryFinder.ProjectsDirectory, "TestProject"); - var linkedFilesRootDir = Path.Combine(projectPath, "LinkedFiles"); - var linkedFilesPath = - DirectoryFinderRelativePaths.GetLinkedFilesFullPathFromRelativePath(String.Format("%proj%{0}LinkedFiles", Path.DirectorySeparatorChar), projectPath); - - Assert.AreEqual(linkedFilesRootDir, linkedFilesPath); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Tests the GetFullFilePathFromRelativeLFPath method - /// - /// ------------------------------------------------------------------------------------ - [Test] - public void GetFullFilePathFromRelativeLFPath() - { - var linkedFilesRootDir = Path.Combine(Path.Combine(DirectoryFinder.ProjectsDirectory, "TestProject"), "LinkedFiles"); - var fullLFPath = DirectoryFinderRelativePaths.GetFullFilePathFromRelativeLFPath(String.Format("%lf%{0}AudioVisual{0}StarWars.mvi", Path.DirectorySeparatorChar), linkedFilesRootDir); - var audioVisualFile = Path.Combine(Path.Combine(linkedFilesRootDir, "AudioVisual"), "StarWars.mvi"); - Assert.AreEqual(audioVisualFile, fullLFPath); - - //if a fully rooted path is passed in the return value should be null. - var projectRootDir = DirectoryFinder.FWDataDirectory; - fullLFPath = DirectoryFinderRelativePaths.GetFullFilePathFromRelativeLFPath(projectRootDir, linkedFilesRootDir); - Assert.True(string.IsNullOrEmpty(fullLFPath)); - - } - - /// ------------------------------------------------------------------------------------ - /// - /// Tests the GetRelativeLFPathFromFullFilePath method - /// - /// ------------------------------------------------------------------------------------ - [Test] - public void GetRelativeLFPathFromFullFilePath() - { - var linkedFilesRootDir = Path.Combine(Path.Combine(DirectoryFinder.ProjectsDirectory, "TestProject"), "LinkedFiles"); - var audioVisualFile = Path.Combine(Path.Combine(linkedFilesRootDir, "AudioVisual"), "StarWars.mvi"); - var relativeLFPath = DirectoryFinderRelativePaths.GetRelativeLFPathFromFullFilePath(audioVisualFile, linkedFilesRootDir); - Assert.AreEqual(String.Format("%lf%{0}AudioVisual{0}StarWars.mvi", Path.DirectorySeparatorChar), relativeLFPath); - - //Ensure empty string is returned when the path is not relative to the LinkedFiles directory. - var pathNotUnderLinkedFiles = Path.Combine(DirectoryFinder.FWDataDirectory, "LordOfTheRings.mvi"); - relativeLFPath = DirectoryFinderRelativePaths.GetRelativeLFPathFromFullFilePath(pathNotUnderLinkedFiles, linkedFilesRootDir); - Assert.True(string.IsNullOrEmpty(relativeLFPath)); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Tests the GetRelativeLinkedFilesPath method - /// - /// ------------------------------------------------------------------------------------ - [Test] - public void GetRelativeLinkedFilesPath() - { - var linkedFilesRootDir = Path.Combine(Path.Combine(DirectoryFinder.ProjectsDirectory, "TestProject"), "LinkedFiles"); - var audioVisualFile = Path.Combine(Path.Combine(linkedFilesRootDir, "AudioVisual"), "StarWars.mvi"); - var relativeLFPath = DirectoryFinderRelativePaths.GetRelativeLinkedFilesPath(audioVisualFile, linkedFilesRootDir); - Assert.True(String.Equals(String.Format("AudioVisual{0}StarWars.mvi", Path.DirectorySeparatorChar), relativeLFPath)); - - //Ensure ORIGINAL path is returned when the path is not relative to the LinkedFiles directory. - var pathNotUnderLinkedFiles = Path.Combine(DirectoryFinder.FWDataDirectory, "LordOfTheRings.mvi"); - relativeLFPath = DirectoryFinderRelativePaths.GetRelativeLinkedFilesPath(pathNotUnderLinkedFiles, linkedFilesRootDir); - Assert.True(String.Equals(pathNotUnderLinkedFiles,relativeLFPath)); - Assert.That(DirectoryFinderRelativePaths.GetRelativeLinkedFilesPath( - "silfw:\\localhost\\link?app%3dflex%26database%3dc%3a%5cTestLangProj%5cTestLangProj.fwdata%26server%3d%26tool%3dnaturalClassedit%26guid%3d43c9ba97-2883-4f95-aa5d-ef9309e85025%26tag%3d", - relativeLFPath), Is.Null, "hyperlinks should be left well alone!!"); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Tests the GetFullPathFromRelativeLFPath method - /// - /// ------------------------------------------------------------------------------------ - [Test] - public void GetFullPathFromRelativeLFPath() - { - var linkedFilesRootDir = Path.Combine(Path.Combine(DirectoryFinder.ProjectsDirectory, "TestProject"), "LinkedFiles"); - var fullLFPath = DirectoryFinderRelativePaths.GetFullPathFromRelativeLFPath(String.Format("AudioVisual{0}StarWars.mvi", Path.DirectorySeparatorChar), linkedFilesRootDir); - var audioVisualFile = Path.Combine(Path.Combine(linkedFilesRootDir, "AudioVisual"), "StarWars.mvi"); - Assert.AreEqual(audioVisualFile, fullLFPath); - - //if a fully rooted path is passed in the return value should be the path that was passed in. - var fileUnderProjectRootDir = String.Format("{1}{0}AudioVisual{0}StarWars.mvi", Path.DirectorySeparatorChar, DirectoryFinder.FWDataDirectory); - fullLFPath = DirectoryFinderRelativePaths.GetFullPathFromRelativeLFPath(fileUnderProjectRootDir, linkedFilesRootDir); - Assert.AreEqual(fullLFPath, fileUnderProjectRootDir); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Tests the GetFullPathFromRelativeLFPath method with illegal characters - /// - /// ------------------------------------------------------------------------------------ - [Test] - public void GetFullPathFromRelativeLFPath_WithIllegalCharacters_ReturnsSpecialPath() - { - var linkedFilesRootDir = Path.Combine(Path.Combine(DirectoryFinder.ProjectsDirectory, "TestProject"), "LinkedFiles"); - var fullLFPath = DirectoryFinderRelativePaths.GetFullPathFromRelativeLFPath("1\";1\"", linkedFilesRootDir); - Assert.That(fullLFPath, Is.EqualTo(Path.Combine(linkedFilesRootDir,"__ILLEGALCHARS__"))); - } - - /// - /// Tests the DefaultBackupDirectory property for use on Windows. - /// - [Test] - [Platform(Exclude="Linux", Reason="Test is Windows specific")] - public void DefaultBackupDirectory_Windows() - { - Assert.AreEqual(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), - Path.Combine("My FieldWorks", "Backups")), DirectoryFinder.DefaultBackupDirectory); - } - - /// - /// Tests the DefaultBackupDirectory property for use on Linux - /// - [Test] - [Platform(Include="Linux", Reason="Test is Linux specific")] - public void DefaultBackupDirectory_Linux() - { - // SpecialFolder.MyDocuments returns $HOME on Linux! - Assert.AreEqual(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), - "Documents/fieldworks/backups"), DirectoryFinder.DefaultBackupDirectory); - } - - /// - /// Base class for testing CommonApplicationData. This base class deals with setting - /// and resetting the environment variable. - /// - public class GetCommonAppDataBaseTest: BaseTest - { - private string PreviousEnvironment; - - /// - /// Setup the tests. - /// - public override void FixtureSetup() - { - base.FixtureSetup(); - - DirectoryFinder.ResetStaticVars(); - PreviousEnvironment = Environment.GetEnvironmentVariable("FW_CommonAppData"); - var properties = (PropertyAttribute[])GetType().GetCustomAttributes(typeof(PropertyAttribute), true); - Assert.That(properties.Length, Is.GreaterThan(0)); - Environment.SetEnvironmentVariable("FW_CommonAppData", (string)properties[0].Properties["Value"]); - } - - /// - /// Reset environment variable to previous value - /// - public override void FixtureTeardown() - { - Environment.SetEnvironmentVariable("FW_CommonAppData", PreviousEnvironment); - - base.FixtureTeardown(); - } - } - - /// - /// Tests the GetFolderPath method for CommonApplicationData when no environment variable - /// is set. - /// - [TestFixture] - [Property("Value", null)] - public class GetCommonAppDataNormalTests: GetCommonAppDataBaseTest - { - /// Tests the GetFolderPath method for CommonApplicationData when no environment - /// variable is set - [Test] - [Platform(Include="Linux", Reason="Test is Linux specific")] - public void Linux() - { - Assert.AreEqual("/var/lib/fieldworks", - DirectoryFinder.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); - } - - /// Tests the GetFolderPath method for CommonApplicationData when no environment - /// variable is set - [Test] - [Platform(Exclude="Linux", Reason="Test is Windows specific")] - public void Windows() - { - Assert.AreEqual( - Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), - DirectoryFinder.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); - } - } - - /// - /// Tests the GetFolderPath method for CommonApplicationData when the environment variable - /// is set. - /// - [TestFixture] - [Property("Value", "/bla")] - public class GetCommonAppDataOverrideTests: GetCommonAppDataBaseTest - { - /// Tests the GetFolderPath method for CommonApplicationData when the environment - /// variable is set - [Test] - [Platform(Include="Linux", Reason="Test is Linux specific")] - public void Linux() - { - Assert.AreEqual("/bla", - DirectoryFinder.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); - } - - /// Tests the GetFolderPath method for CommonApplicationData when the environment - /// variable is set - [Test] - [Platform(Exclude="Linux", Reason="Test is Windows specific")] - public void Windows() - { - Assert.AreEqual( - Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), - DirectoryFinder.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); - } - } - } -} diff --git a/Src/Common/FwUtils/FwUtilsTests/FwDirectoryFinderTests.cs b/Src/Common/FwUtils/FwUtilsTests/FwDirectoryFinderTests.cs new file mode 100644 index 0000000000..f6f8f5406e --- /dev/null +++ b/Src/Common/FwUtils/FwUtilsTests/FwDirectoryFinderTests.cs @@ -0,0 +1,243 @@ +// Copyright (c) 2008-2014 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) +// +// File: FwDirectoryFinderTests.cs +// Responsibility: Eberhard Beilharz + +using System; +using System.IO; +using NUnit.Framework; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.Test.TestUtils; +using SIL.Utils; + +namespace SIL.FieldWorks.Common.FwUtils +{ + + ///----------------------------------------------------------------------------------------- + /// + /// Tests for the FwDirectoryFinder class + /// + ///----------------------------------------------------------------------------------------- + [TestFixture] + public class FwDirectoryFinderTests : BaseTest + { + /// + /// Resets the registry helper + /// + [TestFixtureTearDown] + public void TearDown() + { + FwRegistryHelper.Manager.Reset(); + } + + /// + /// Fixture setup + /// + [TestFixtureSetUp] + public void TestFixtureSetup() + { + //FwDirectoryFinder.CompanyName = "SIL"; + FwRegistryHelper.Manager.SetRegistryHelper(new DummyFwRegistryHelper()); + FwRegistryHelper.FieldWorksRegistryKey.SetValue("RootDataDir", Path.GetFullPath(Path.Combine(UtilsAssemblyDir, "../../DistFiles"))); + FwRegistryHelper.FieldWorksRegistryKey.SetValue("RootCodeDir", Path.GetFullPath(Path.Combine(UtilsAssemblyDir, "../../DistFiles"))); + } + + ///------------------------------------------------------------------------------------- + /// + /// Gets the directory where the Utils assembly is + /// + ///------------------------------------------------------------------------------------- + private string UtilsAssemblyDir + { + get + { + return Path.GetDirectoryName(typeof(FwDirectoryFinder).Assembly.CodeBase + .Substring(MiscUtils.IsUnix ? 7 : 8)); + } + } + + ///------------------------------------------------------------------------------------- + /// + /// Tests the CodeDirectory property. This should return the DistFiles directory. + /// + ///------------------------------------------------------------------------------------- + [Test] + public void CodeDirectory() + { + var currentDir = Path.GetFullPath(Path.Combine(UtilsAssemblyDir, "../../DistFiles")); + Assert.That(FwDirectoryFinder.CodeDirectory, Is.SamePath(currentDir)); + } + + /// + /// Verify that the user project key falls back to the local machine. + /// + [Test] + public void GettingProjectDirWithEmptyUserKeyReturnsLocalMachineKey() + { + using (var fwHKCU = FwRegistryHelper.FieldWorksRegistryKey) + using (var fwHKLM = FwRegistryHelper.FieldWorksRegistryKeyLocalMachine) + { + if (fwHKCU.GetValue("ProjectsDir") != null) + { + fwHKCU.DeleteValue("ProjectsDir"); + } + fwHKLM.SetValue("ProjectsDir", "HKLM_TEST"); + Assert.That(FwDirectoryFinder.ProjectsDirectory, Is.EqualTo(FwDirectoryFinder.ProjectsDirectoryLocalMachine)); + Assert.That(FwDirectoryFinder.ProjectsDirectory, Is.EqualTo("HKLM_TEST")); + } + } + + /// + /// Verify that the user project key overrides the local machine. + /// + [Test] + public void GettingProjectDirWithUserDifferentFromLMReturnsUser() + { + FwDirectoryFinder.ProjectsDirectory = "NewHKCU_TEST_Value"; + Assert.That(FwDirectoryFinder.ProjectsDirectory, Is.Not.EqualTo(FwDirectoryFinder.ProjectsDirectoryLocalMachine)); + Assert.That(FwDirectoryFinder.ProjectsDirectory, Is.EqualTo("NewHKCU_TEST_Value")); + } + + /// + /// Verify that setting the user key to null deletes the user setting and falls back to local machine. + /// + [Test] + public void SettingProjectDirToNullDeletesUserKey() + { + FwDirectoryFinder.ProjectsDirectory = null; + Assert.That(FwDirectoryFinder.ProjectsDirectory, Is.EqualTo(FwDirectoryFinder.ProjectsDirectoryLocalMachine)); + + using (var fwHKCU = FwRegistryHelper.FieldWorksRegistryKey) + using (var fwHKLM = FwRegistryHelper.FieldWorksRegistryKeyLocalMachine) + { + Assert.Null(fwHKCU.GetValue("ProjectsDir")); + Assert.NotNull(fwHKLM.GetValue("ProjectsDir")); + } + } + + ///------------------------------------------------------------------------------------- + /// + /// Tests the DataDirectory property. This should return the DistFiles directory. + /// + ///------------------------------------------------------------------------------------- + [Test] + public void DataDirectory() + { + var currentDir = Path.GetFullPath(Path.Combine(UtilsAssemblyDir, "../../DistFiles")); + Assert.That(FwDirectoryFinder.DataDirectory, Is.SamePath(currentDir)); + } + + ///------------------------------------------------------------------------------------- + /// + /// Tests the SourceDirectory property. This should return the DistFiles directory. + /// + ///------------------------------------------------------------------------------------- + [Test] + public void SourceDirectory() + { + string expectedDir = Path.GetFullPath(Path.Combine(UtilsAssemblyDir, "../../Src")); + Assert.That(FwDirectoryFinder.SourceDirectory, Is.SamePath(expectedDir)); + } + + ///------------------------------------------------------------------------------------- + /// + /// Tests the GetCodeSubDirectory method when we pass a subdirectory without a + /// leading directory separator + /// + ///------------------------------------------------------------------------------------- + [Test] + public void GetCodeSubDirectory_NoLeadingSlash() + { + Assert.That(FwDirectoryFinder.GetCodeSubDirectory("Translation Editor/Configuration"), + Is.SamePath(Path.Combine(FwDirectoryFinder.CodeDirectory, "Translation Editor/Configuration"))); + } + + ///------------------------------------------------------------------------------------- + /// + /// Tests the GetCodeSubDirectory method when we pass a subdirectory with a + /// leading directory separator + /// + ///------------------------------------------------------------------------------------- + [Test] + public void GetCodeSubDirectory_LeadingSlash() + { + Assert.That(FwDirectoryFinder.GetCodeSubDirectory("/Translation Editor/Configuration"), + Is.SamePath(Path.Combine(FwDirectoryFinder.CodeDirectory, "Translation Editor/Configuration"))); + } + + ///------------------------------------------------------------------------------------- + /// + /// Tests the GetCodeSubDirectory method when we pass an invalid subdirectory + /// + ///------------------------------------------------------------------------------------- + [Test] + public void GetCodeSubDirectory_InvalidDir() + { + Assert.That(FwDirectoryFinder.GetCodeSubDirectory("NotExisting"), + Is.SamePath("NotExisting")); + } + + ///------------------------------------------------------------------------------------- + /// + /// Tests the GetDataSubDirectory method when we pass a subdirectory without a + /// leading directory separator + /// + ///------------------------------------------------------------------------------------- + [Test] + public void GetDataSubDirectory_NoLeadingSlash() + { + Assert.That(FwDirectoryFinder.GetDataSubDirectory("Translation Editor/Configuration"), + Is.SamePath(Path.Combine(FwDirectoryFinder.DataDirectory, "Translation Editor/Configuration"))); + } + + ///------------------------------------------------------------------------------------- + /// + /// Tests the GetDataSubDirectory method when we pass a subdirectory with a + /// leading directory separator + /// + ///------------------------------------------------------------------------------------- + [Test] + public void GetDataSubDirectory_LeadingSlash() + { + Assert.That(FwDirectoryFinder.GetDataSubDirectory("/Translation Editor/Configuration"), + Is.SamePath(Path.Combine(FwDirectoryFinder.DataDirectory, "Translation Editor/Configuration"))); + } + + ///------------------------------------------------------------------------------------- + /// + /// Tests the GetDataSubDirectory method when we pass an invalid subdirectory + /// + ///------------------------------------------------------------------------------------- + [Test] + public void GetDataSubDirectory_InvalidDir() + { + Assert.That(FwDirectoryFinder.GetDataSubDirectory("NotExisting"), + Is.SamePath("NotExisting")); + } + + /// + /// Tests the DefaultBackupDirectory property for use on Windows. + /// + [Test] + [Platform(Exclude="Linux", Reason="Test is Windows specific")] + public void DefaultBackupDirectory_Windows() + { + Assert.AreEqual(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), + Path.Combine("My FieldWorks", "Backups")), FwDirectoryFinder.DefaultBackupDirectory); + } + + /// + /// Tests the DefaultBackupDirectory property for use on Linux + /// + [Test] + [Platform(Include="Linux", Reason="Test is Linux specific")] + public void DefaultBackupDirectory_Linux() + { + // SpecialFolder.MyDocuments returns $HOME on Linux! + Assert.AreEqual(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), + "Documents/fieldworks/backups"), FwDirectoryFinder.DefaultBackupDirectory); + } + } +} diff --git a/Src/Common/FwUtils/FwUtilsTests/FwRegistryHelperTests.cs b/Src/Common/FwUtils/FwUtilsTests/FwRegistryHelperTests.cs index be228ca112..742b830a58 100644 --- a/Src/Common/FwUtils/FwUtilsTests/FwRegistryHelperTests.cs +++ b/Src/Common/FwUtils/FwUtilsTests/FwRegistryHelperTests.cs @@ -7,6 +7,7 @@ // --------------------------------------------------------------------------------------------- using NUnit.Framework; using SIL.FieldWorks.Test.TestUtils; +using SIL.Utils; namespace SIL.FieldWorks.Common.FwUtils { @@ -16,6 +17,28 @@ namespace SIL.FieldWorks.Common.FwUtils [TestFixture] public class FwRegistryHelperTests : BaseTest { + private DummyFwRegistryHelper m_helper; + + /// + /// Setups the test bed + /// + [SetUp] + public void Setup() + { + m_helper = new DummyFwRegistryHelper(); + FwRegistryHelper.Manager.SetRegistryHelper(m_helper); + m_helper.DeleteAllSubTreesIfPresent(); + } + + /// + /// Tears down the test bed + /// + [TearDown] + public void TearDown() + { + FwRegistryHelper.Manager.Reset(); + } + /// /// Tests that hklm registry keys can be written correctly. /// Marked as ByHand as it should show a UAC dialog on Vista and Windows7. @@ -34,5 +57,65 @@ public void SetValueAsAdmin() Assert.AreEqual("value", registryKey.GetValue("keyname") as string); } } + + /// + /// Tests how ProjectShared key was migrated from version 7. + /// + [Test] + public void MigrateVersion7ValueIfNeeded_7Unset_NotMigrated() + { + // Setup + using (var version7Key = m_helper.SetupVersion7Settings()) + { + FwRegistryHelper.MigrateVersion7ValueIfNeeded(); + + // Verification + // Verify that the version 8 ProjectShared key is missing. + object dummy; + Assert.IsFalse(RegistryHelper.RegEntryExists(FwRegistryHelper.FieldWorksRegistryKey, null, "ProjectShared", out dummy)); + } + } + + /// + /// Tests how ProjectShared key was migrated from version 7. + /// + [Test] + public void MigrateVersion7ValueIfNeeded_7UnsetDespiteExistingPath_NotMigrated() + { + // Setup + using (m_helper.SetupVersion7ProjectSharedSettingLocation()) + using (var version7Key = m_helper.SetupVersion7Settings()) + { + FwRegistryHelper.MigrateVersion7ValueIfNeeded(); + + // Verification + // Verify that the version 8 ProjectShared key is missing. + object dummy; + Assert.IsFalse(RegistryHelper.RegEntryExists(FwRegistryHelper.FieldWorksRegistryKey, null, "ProjectShared", out dummy)); + } + } + + /// + /// Tests how ProjectShared key was migrated from version 7. + /// + [Test] + public void MigrateVersion7ValueIfNeeded_7Set_Migrated() + { + // Setup + using (m_helper.SetupVersion7ProjectSharedSetting()) + using (var version7Key = m_helper.SetupVersion7Settings()) + { + object projectsSharedValue; + // Verify that the version 8 ProjectShared key is missing before migration + Assert.IsFalse(RegistryHelper.RegEntryExists(FwRegistryHelper.FieldWorksRegistryKey, null, "ProjectShared", out projectsSharedValue)); + + FwRegistryHelper.MigrateVersion7ValueIfNeeded(); + + // Verification + // Verify that the version 8 ProjectShared key is set after migration. + Assert.IsTrue(RegistryHelper.RegEntryExists(FwRegistryHelper.FieldWorksRegistryKey, null, "ProjectShared", out projectsSharedValue)); + Assert.IsTrue(bool.Parse((string)projectsSharedValue)); + } + } } } \ No newline at end of file diff --git a/Src/Common/FwUtils/FwUtilsTests/FwUtilsTests.csproj b/Src/Common/FwUtils/FwUtilsTests/FwUtilsTests.csproj index 0b8a84df8c..49e47412ef 100644 --- a/Src/Common/FwUtils/FwUtilsTests/FwUtilsTests.csproj +++ b/Src/Common/FwUtils/FwUtilsTests/FwUtilsTests.csproj @@ -114,6 +114,10 @@ False ..\..\..\..\Output\Debug\CoreImpl.dll + + False + ..\..\..\..\Output\Debug\FDO.dll + False ..\..\..\..\Output\Debug\FwUtils.dll @@ -126,10 +130,6 @@ nunit.framework ..\..\..\..\Bin\NUnit\bin\nunit.framework.dll - - False - ..\..\..\..\DistFiles\ParatextShared.dll - False ..\..\..\..\Output\Debug\SilUtils.dll @@ -154,7 +154,7 @@ AssemblyInfoForTests.cs - + @@ -165,10 +165,7 @@ - - - diff --git a/Src/Common/FwUtils/IFwRegistryHelper.cs b/Src/Common/FwUtils/IFwRegistryHelper.cs index 7135ddc12c..c7e9f01f41 100644 --- a/Src/Common/FwUtils/IFwRegistryHelper.cs +++ b/Src/Common/FwUtils/IFwRegistryHelper.cs @@ -2,7 +2,7 @@ // This software is licensed under the LGPL, version 2.1 or later // (http://www.gnu.org/licenses/lgpl-2.1.html) -using System; + using Microsoft.Win32; namespace SIL.FieldWorks.Common.FwUtils @@ -75,18 +75,5 @@ public interface IFwRegistryHelper /// /// ------------------------------------------------------------------------------------ bool Paratext7orLaterInstalled(); - - /// - /// If there is a registry value for this but the folder is not there we need to return false because - /// paratext is not installed correctly. Also if there is no registry entry for this then return false. - /// - bool ParatextSettingsDirectoryExists(); - - /// - /// Returns the path to the Paratext settings (projects) directory as specified in the registry - /// ENHANCE (Hasso) 2013.09: added this to expose the directory for Unix users, because trying to get it from ScrTextCollections - /// always returns null on Unix. This is really a Paratext problem, and this method may have no benefit. - /// - string ParatextSettingsDirectory(); } } diff --git a/Src/Common/FwUtils/ShowHelp.cs b/Src/Common/FwUtils/ShowHelp.cs index a633a5370b..7f3679bdd0 100644 --- a/Src/Common/FwUtils/ShowHelp.cs +++ b/Src/Common/FwUtils/ShowHelp.cs @@ -75,7 +75,7 @@ public static void ShowHelpTopic(IHelpTopicProvider helpTopicProvider, string he // try to get a path to the help file. try { - helpFile = DirectoryFinder.FWCodeDirectory + + helpFile = FwDirectoryFinder.CodeDirectory + helpTopicProvider.GetHelpString(helpFileKey); } catch diff --git a/Src/Common/FwUtils/ValidationProgress.cs b/Src/Common/FwUtils/ValidationProgress.cs index de190e8705..6d0dc8031a 100644 --- a/Src/Common/FwUtils/ValidationProgress.cs +++ b/Src/Common/FwUtils/ValidationProgress.cs @@ -10,6 +10,7 @@ using System; using Palaso.Lift.Validation; +using SIL.Utils; namespace SIL.FieldWorks.Common.FwUtils { diff --git a/Src/Common/FwUtils/gendarme-FwUtils.ignore b/Src/Common/FwUtils/gendarme-FwUtils.ignore index a226ed4aa8..0e28754d8c 100644 --- a/Src/Common/FwUtils/gendarme-FwUtils.ignore +++ b/Src/Common/FwUtils/gendarme-FwUtils.ignore @@ -1,8 +1,3 @@ # Gendarme filter file to suppress reporting of defects #----------------------------------------------------------------------------------------------- -R: Gendarme.Rules.Correctness.EnsureLocalDisposalRule - -# Reference -M: System.Collections.IEnumerator SIL.FieldWorks.Common.FwUtils.StringSearcher`1/SortKeyIndex/*::System.Collections.IEnumerable.GetEnumerator() -M: System.Collections.IEnumerator SIL.FieldWorks.Common.FwUtils.StringSearcher`1/*::System.Collections.IEnumerable.GetEnumerator() diff --git a/Src/Common/PrintLayout/PrintLayoutTests/PrintLayoutTests.csproj b/Src/Common/PrintLayout/PrintLayoutTests/PrintLayoutTests.csproj index ff32720784..616b40eaea 100644 --- a/Src/Common/PrintLayout/PrintLayoutTests/PrintLayoutTests.csproj +++ b/Src/Common/PrintLayout/PrintLayoutTests/PrintLayoutTests.csproj @@ -133,6 +133,10 @@ FwPrintLayoutComponents ..\..\..\..\Output\Debug\FwPrintLayoutComponents.dll + + False + ..\..\..\..\Output\Debug\FwResources.dll + False ..\..\..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll diff --git a/Src/Common/PrintLayout/PrintLayoutTests/PubTestsNoDb.cs b/Src/Common/PrintLayout/PrintLayoutTests/PubTestsNoDb.cs index d33fb6ace1..1c4dbb75af 100644 --- a/Src/Common/PrintLayout/PrintLayoutTests/PubTestsNoDb.cs +++ b/Src/Common/PrintLayout/PrintLayoutTests/PubTestsNoDb.cs @@ -6,15 +6,10 @@ // Responsibility: TE Team using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using System.Windows.Forms; - using NUnit.Framework; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.PrintLayout; +using SIL.FieldWorks.Resources; using SIL.Utils; using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.FDOTests; @@ -189,7 +184,7 @@ public void DefaultFontAndLineHeightUsed() m_pub.BaseLineSpacing = 0; FwStyleSheet stylesheet = new FwStyleSheet(); stylesheet.Init(Cache, Cache.LangProject.TranslatedScriptureOA.Hvo, - ScriptureTags.kflidStyles); + ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); using (DummyDivision divLayoutMgr = new DummyDivision(new DummyPrintConfigurer(Cache, null), 1)) { @@ -222,7 +217,7 @@ public void PublicationFontAndLineHeightUsed() m_pub.BaseLineSpacing = -11000; FwStyleSheet stylesheet = new FwStyleSheet(); stylesheet.Init(Cache, Cache.LangProject.TranslatedScriptureOA.Hvo, - ScriptureTags.kflidStyles); + ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); using (DummyDivision divLayoutMgr = new DummyDivision(new DummyPrintConfigurer(Cache, null), 1)) { diff --git a/Src/Common/PrintLayout/PublicationControl.cs b/Src/Common/PrintLayout/PublicationControl.cs index 098f32e864..1c41201d53 100644 --- a/Src/Common/PrintLayout/PublicationControl.cs +++ b/Src/Common/PrintLayout/PublicationControl.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2004-2013 SIL International +// Copyright (c) 2004-2013 SIL International // This software is licensed under the LGPL, version 2.1 or later // (http://www.gnu.org/licenses/lgpl-2.1.html) // @@ -3212,7 +3212,7 @@ public virtual bool OnViewUpdatePageBreak(object args) CheckDisposed(); IVwRootBox focusedRootBox = FocusedRootBox; - using (var dialog = new ProgressDialogWithTask(FindForm(), Cache.ThreadHelper)) + using (var dialog = new ProgressDialogWithTask(FindForm())) { dialog.CancelButtonText = ResourceHelper.GetResourceString("kstidUpdatePageBreakButtonText"); dialog.Title = ResourceHelper.GetResourceString("kstidUpdatePageBreakWindowCaption"); @@ -4745,7 +4745,7 @@ public void ApplyPubOverrides(decimal pubCharSize, decimal pubLineSpacing) } printLayoutStylesheet.Init(m_cache, m_origStylesheet.RootObjectHvo, - m_origStylesheet.StyleListTag); + m_origStylesheet.StyleListTag, ResourceHelper.DefaultParaCharsStyleName); } } diff --git a/Src/Common/RootSite/FwBaseVc.cs b/Src/Common/RootSite/FwBaseVc.cs index a72756e1f3..2db0c09c3e 100644 --- a/Src/Common/RootSite/FwBaseVc.cs +++ b/Src/Common/RootSite/FwBaseVc.cs @@ -191,7 +191,7 @@ public override void DisplayEmbeddedObject(IVwEnv vwenv, int hvo) } string linkedFilesRoot = sda.get_UnicodeProp(m_hvoLangProject, LangProjectTags.kflidLinkedFilesRootDir); if (String.IsNullOrEmpty(linkedFilesRoot)) - path = Path.Combine(DirectoryFinder.FWDataDirectory, fileName); + path = Path.Combine(FwDirectoryFinder.DataDirectory, fileName); else path = Path.Combine(linkedFilesRoot, fileName); } diff --git a/Src/Common/RootSite/RootSite.csproj b/Src/Common/RootSite/RootSite.csproj index dde1120a7e..f6e6cc7d23 100644 --- a/Src/Common/RootSite/RootSite.csproj +++ b/Src/Common/RootSite/RootSite.csproj @@ -142,7 +142,7 @@ False - ..\..\..\Downloads\Palaso.dll + ..\..\..\Downloads\Palaso.dll False @@ -273,8 +273,7 @@ - ../../../DistFiles - + \ No newline at end of file diff --git a/Src/Common/RootSite/RootSiteEditingHelper.cs b/Src/Common/RootSite/RootSiteEditingHelper.cs index ab0f936f8b..92d513abfa 100644 --- a/Src/Common/RootSite/RootSiteEditingHelper.cs +++ b/Src/Common/RootSite/RootSiteEditingHelper.cs @@ -548,7 +548,7 @@ private void HandleSelectionChange() // in response to that. There's also a chance we'll never get a selection, but that // might be okay, too, in some views. // Also, need to use Invoke, since this may be running on a progress thread. - Cache.ThreadHelper.Invoke(() => + Control.Invoke(() => { IVwRootBox rootb = EditedRootBox; RootSite site = null; diff --git a/Src/Common/RootSite/RootSiteTests/BasicViewTestsBase.cs b/Src/Common/RootSite/RootSiteTests/BasicViewTestsBase.cs index cda8cf5de2..6ab00f2a0e 100644 --- a/Src/Common/RootSite/RootSiteTests/BasicViewTestsBase.cs +++ b/Src/Common/RootSite/RootSiteTests/BasicViewTestsBase.cs @@ -11,10 +11,10 @@ // -------------------------------------------------------------------------------------------- using System.Diagnostics; using NUnit.Framework; -using SIL.CoreImpl; using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.FDOTests; using SIL.FieldWorks.FDO.DomainServices; +using SIL.FieldWorks.Resources; namespace SIL.FieldWorks.Common.RootSites { @@ -56,7 +56,7 @@ public override void TestSetup() base.TestSetup(); var styleSheet = new FwStyleSheet(); - styleSheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles); + styleSheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); Debug.Assert(m_basicView == null, "m_basicView is not null."); //if (m_basicView != null) diff --git a/Src/Common/RootSite/RootSiteTests/RootSiteTests.csproj b/Src/Common/RootSite/RootSiteTests/RootSiteTests.csproj index 7d42ca262d..588b27945c 100644 --- a/Src/Common/RootSite/RootSiteTests/RootSiteTests.csproj +++ b/Src/Common/RootSite/RootSiteTests/RootSiteTests.csproj @@ -83,7 +83,7 @@ true 4096 false - 168,169,219,414,649,1635,1702,1701 + 168,169,219,414,649,1635,1702,1701,1591,1685 true false false @@ -127,6 +127,10 @@ FDOTests ..\..\..\..\Output\Debug\FDOTests.dll + + False + ..\..\..\..\Output\Debug\FwResources.dll + False ..\..\..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll diff --git a/Src/Common/RootSite/RootSiteTests/RootsiteBasicViewTestsBase.cs b/Src/Common/RootSite/RootSiteTests/RootsiteBasicViewTestsBase.cs index 3aa6a0df69..f609ac3fea 100644 --- a/Src/Common/RootSite/RootSiteTests/RootsiteBasicViewTestsBase.cs +++ b/Src/Common/RootSite/RootSiteTests/RootsiteBasicViewTestsBase.cs @@ -17,6 +17,7 @@ using SIL.FieldWorks.FDO.FDOTests; using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.FDO.Infrastructure; +using SIL.FieldWorks.Resources; namespace SIL.FieldWorks.Common.RootSites { @@ -252,7 +253,7 @@ public override void TestSetup() var styleSheet = new FwStyleSheet(); styleSheet.Init(Cache, m_scr.Hvo, - ScriptureTags.kflidStyles); + ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); Debug.Assert(m_basicView == null, "m_basicView is not null."); diff --git a/Src/Common/RootSite/RootSiteTests/StVcTests.cs b/Src/Common/RootSite/RootSiteTests/StVcTests.cs index d1500d23dc..e5da14cdc9 100644 --- a/Src/Common/RootSite/RootSiteTests/StVcTests.cs +++ b/Src/Common/RootSite/RootSiteTests/StVcTests.cs @@ -14,6 +14,7 @@ using SIL.FieldWorks.FDO; using SIL.FieldWorks.Common.COMInterfaces; +using SIL.FieldWorks.Resources; using SIL.FieldWorks.Test.TestUtils; using SIL.FieldWorks.FDO.FDOTests; using SIL.FieldWorks.FDO.Infrastructure; @@ -298,7 +299,7 @@ public void SpaceAfterFootnoteMarker() footnote.FootnoteMarker = Cache.TsStrFactory.MakeString("a", Cache.WritingSystemFactory.GetWsFromStr("en")); // Prepare the test by creating a footnote view FwStyleSheet styleSheet = new FwStyleSheet(); - styleSheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles); + styleSheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); using (DummyFootnoteView footnoteView = new DummyFootnoteView(Cache)) { @@ -362,7 +363,7 @@ public void FootnoteTranslationTest() translation.Translation.set_String(analWs, TsStringHelper.MakeTSS("abcde", analWs)); FwStyleSheet styleSheet = new FwStyleSheet(); - styleSheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles); + styleSheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); // Prepare the test by creating a footnote view using (DummyFootnoteView footnoteView = new DummyFootnoteView(Cache, true)) @@ -399,7 +400,7 @@ public void ReadOnlySpaceAfterFootnoteMarker() { // Prepare the test by creating a footnote view FwStyleSheet styleSheet = new FwStyleSheet(); - styleSheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles); + styleSheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); using (Form form = new Form()) using (DummyFootnoteView footnoteView = new DummyFootnoteView(Cache)) diff --git a/Src/Common/ScrUtilsInterfaces/ScrUtilsInterfaces.csproj b/Src/Common/ScrUtilsInterfaces/ScrUtilsInterfaces.csproj index 998ce9007c..428996b88e 100644 --- a/Src/Common/ScrUtilsInterfaces/ScrUtilsInterfaces.csproj +++ b/Src/Common/ScrUtilsInterfaces/ScrUtilsInterfaces.csproj @@ -1,185 +1,183 @@ - + - Local - 9.0.30729 - 2.0 - {9CA14238-3229-4FB3-A42A-A173D25F4A6B} - - - - Debug - AnyCPU - - - - - ScrUtilsInterfaces - - - JScript - Grid - IE50 - false - Library - SIL.FieldWorks.Common.ScriptureUtils - OnBuildSuccess - - - - - - - - - 3.5 - false - v4.0 - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - true - + Local + 9.0.30729 + 2.0 + {9CA14238-3229-4FB3-A42A-A173D25F4A6B} + + + + + + + Debug + AnyCPU + + + + + ScrUtilsInterfaces + + + JScript + Grid + IE50 + false + Library + SIL.FieldWorks.Common.ScriptureUtils + OnBuildSuccess + + + + + + + + + 3.5 + false + v4.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + - ..\..\..\Output\Debug\ - false - 285212672 - false - - - DEBUG;TRACE - ..\..\..\Output\Debug\ScrUtilsInterfaces.xml - true - 4096 - false - 168,169,219,414,649,1635,1702,1701 - false - false - false - true - 4 - full - prompt - AllRules.ruleset - x86 + ..\..\..\Output\Debug\ + false + 285212672 + false + + + DEBUG;TRACE + ..\..\..\Output\Debug\ScrUtilsInterfaces.xml + true + 4096 + false + 168,169,219,414,649,1635,1702,1701 + false + false + false + true + 4 + full + prompt + AllRules.ruleset + x86 - ..\..\..\Output\Release\ - false - 285212672 - false - - - TRACE - - - false - 4096 - false - 168,169,219,414,649,1635,1702,1701 - true - false - false - false - 4 - none - prompt - AllRules.ruleset - x86 + ..\..\..\Output\Release\ + false + 285212672 + false + + + TRACE + + + false + 4096 + false + 168,169,219,414,649,1635,1702,1701 + true + false + false + false + 4 + none + prompt + AllRules.ruleset + x86 - - False - ..\..\..\Output\Debug\COMInterfaces.dll - - - False - ..\..\..\Output\Debug\FwResources.dll - - - False - ..\..\..\Output\Debug\SharedScrUtils.dll - - - System - - - - System.Data - - - - System.XML - + + False + ..\..\..\Output\Debug\COMInterfaces.dll + + + False + ..\..\..\Output\Debug\SharedScrUtils.dll + + + System + + + + System.Data + + + System.XML + - - CommonAssemblyInfo.cs - - - Code - - - Code - - - Code - - - Code - - - - + + CommonAssemblyInfo.cs + + + Code + + + Code + + + Code + + + Code + + + + - - Designer - + + Designer + - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 2.0 %28x86%29 - true - - - False - .NET Framework 3.0 %28x86%29 - false - - - False - .NET Framework 3.5 - false - - - False - .NET Framework 3.5 SP1 - false - + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + - - - - + + + + \ No newline at end of file diff --git a/Src/Common/ScrUtilsInterfaces/ScriptureUtilsException.cs b/Src/Common/ScrUtilsInterfaces/ScriptureUtilsException.cs index b9fdd14ad7..0889fdf375 100644 --- a/Src/Common/ScrUtilsInterfaces/ScriptureUtilsException.cs +++ b/Src/Common/ScrUtilsInterfaces/ScriptureUtilsException.cs @@ -9,11 +9,9 @@ // using System; -using System.Runtime; using System.Reflection; using System.Resources; using SILUBS.SharedScrUtils; -using SIL.FieldWorks.Resources; namespace SIL.FieldWorks.Common.ScriptureUtils { diff --git a/Src/FDO/DomainServices/ParatextHelper.cs b/Src/Common/ScriptureUtils/ParatextHelper.cs similarity index 86% rename from Src/FDO/DomainServices/ParatextHelper.cs rename to Src/Common/ScriptureUtils/ParatextHelper.cs index cb5077908b..73815c4beb 100644 --- a/Src/FDO/DomainServices/ParatextHelper.cs +++ b/Src/Common/ScriptureUtils/ParatextHelper.cs @@ -8,14 +8,16 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.IO; using System.Linq; +using Microsoft.Win32; using Paratext; -using Paratext.DerivedTranslation; -using SIL.FieldWorks.Common.FwUtils; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.FDO.DomainServices; using SIL.Utils; using SILUBS.SharedScrUtils; -namespace SIL.FieldWorks.FDO.DomainServices +namespace SIL.FieldWorks.Common.ScriptureUtils { #region IParatextHelper interface /// ---------------------------------------------------------------------------------------- @@ -64,13 +66,8 @@ public interface IParatextHelper /// /// Load the mappings for a Paratext 6/7 project into the specified list. /// - /// Paratext project ID - /// ScrMappingList to which new mappings will be added - /// The import domain for which this project is the source - /// true if the Paratext mappings were loaded successfully; false - /// otherwise /// ------------------------------------------------------------------------------------ - bool LoadProjectMappings(string project, ScrMappingList mappingList, ImportDomain domain); + void LoadProjectMappings(IScrImportSet importSettings); } #endregion @@ -144,6 +141,35 @@ public ParatextHelperAdapter() RefreshProjects(); } + /// + /// LT-14787 Database displays error about inaccessible Paratext projects + /// If there is a registry value for this but the folder is not there we need to return false because + /// paratext is not installed correctly. Also if there is no registry entry for this then return false. + /// + private bool ParatextSettingsDirectoryExists() + { + var regValue = ParatextSettingsDirectory(); + return !String.IsNullOrEmpty(regValue) && Directory.Exists(regValue); + } + + /// + /// Returns the path to the Paratext settings (projects) directory as specified in the registry + /// ENHANCE (Hasso) 2013.09: added this to expose the directory for Unix users, because trying to get it from ScrTextCollections + /// always returns null on Unix. This is really a Paratext problem, and this method may have no benefit. + /// + private string ParatextSettingsDirectory() + { + using (var paratextKey = Registry.LocalMachine.OpenSubKey("Software\\ScrChecks\\1.0\\Settings_Directory")) + { + if (paratextKey != null) + { + var keyName = paratextKey.ToString(); + return Registry.GetValue(keyName, "", "") as string; + } + } + return null; + } + /// ------------------------------------------------------------------------------------ /// /// Gets the Paratext projects directory (null if none) @@ -159,7 +185,7 @@ public string ProjectsDirectory { // TODO FWNX-1235: Why does SrcTextCollection.SettingsDirectory not work in Unix? // Does ScrTextCollection work at all in Unix? - return FwRegistryHelper.ParatextSettingsDirectory(); + return ParatextSettingsDirectory(); } return ScrTextCollection.SettingsDirectory; } @@ -176,7 +202,7 @@ public void RefreshProjects() { try { - if (FwRegistryHelper.ParatextSettingsDirectoryExists()) + if (ParatextSettingsDirectoryExists()) { if (!m_IsParatextInitialized) { @@ -186,7 +212,7 @@ public void RefreshProjects() // We pass the directory (rather than passing no arguments, and letting the paratext dll figure // it out) because the figuring out goes wrong on Linux, where both programs are simulating // the registry. - ScrTextCollection.Initialize(FwRegistryHelper.ParatextSettingsDirectory(), false); + ScrTextCollection.Initialize(ParatextSettingsDirectory(), false); m_IsParatextInitialized = true; } else @@ -263,20 +289,36 @@ public IEnumerable GetProjects() /// /// Load the mappings for a Paratext 6/7 project into the specified list. /// - /// Paratext project ID - /// ScrMappingList to which new mappings will be added - /// The import domain for which this project is the source /// true if the Paratext mappings were loaded successfully; false /// otherwise /// ------------------------------------------------------------------------------------ - [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", - Justification = "See REVIEW comment")] - public bool LoadProjectMappings(string project, ScrMappingList mappingList, ImportDomain domain) + public void LoadProjectMappings(IScrImportSet importSettings) { RefreshProjects(); + if (!m_IsParatextInitialized) + { + importSettings.ParatextScrProj = null; + importSettings.ParatextBTProj = null; + importSettings.ParatextNotesProj = null; + return; + } + + if (!LoadProjectMappings(importSettings.ParatextScrProj, importSettings.GetMappingListForDomain(ImportDomain.Main), ImportDomain.Main)) + importSettings.ParatextScrProj = null; + + if (!LoadProjectMappings(importSettings.ParatextBTProj, importSettings.GetMappingListForDomain(ImportDomain.BackTrans), ImportDomain.BackTrans)) + importSettings.ParatextBTProj = null; - // If Paratext is not initialized or the new project ID is null, then do not load mappings. - if (!m_IsParatextInitialized || project == null) + if (!LoadProjectMappings(importSettings.ParatextNotesProj, importSettings.GetMappingListForDomain(ImportDomain.Annotations), ImportDomain.Annotations)) + importSettings.ParatextNotesProj = null; + } + + [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", + Justification = "See REVIEW comment")] + private bool LoadProjectMappings(string project, ScrMappingList mappingList, ImportDomain domain) + { + // If the new project ID is null, then do not load mappings. + if (string.IsNullOrEmpty(project)) return false; // Load the tags from the paratext project and create mappings for them. @@ -295,7 +337,8 @@ public bool LoadProjectMappings(string project, ScrMappingList mappingList, Impo return false; } - mappingList.ResetInUseFlags(domain); + foreach (ImportMappingInfo mapping in mappingList) + mapping.SetIsInUse(domain, false); try { foreach (ScrTag tag in scParatextText.DefaultStylesheet.Tags) @@ -468,17 +511,12 @@ public static IEnumerable GetProjectBooks(string projShortName) /// ------------------------------------------------------------------------------------ /// - /// Load the mappings for a Paratext 6/7 project into the specified list. + /// Load the mappings for a Paratext 6/7 project into the specified import settings. /// - /// Paratext project ID - /// ScrMappingList to which new mappings will be added - /// The import domain for which this project is the source - /// true if the Paratext mappings were loaded successfully; false - /// otherwise /// ------------------------------------------------------------------------------------ - public static bool LoadProjectMappings(string project, ScrMappingList mappingList, ImportDomain domain) + public static void LoadProjectMappings(IScrImportSet importSettings) { - return s_ptHelper.LoadProjectMappings(project, mappingList, domain); + s_ptHelper.LoadProjectMappings(importSettings); } #endregion diff --git a/Src/Common/ScriptureUtils/ScriptureUtils.csproj b/Src/Common/ScriptureUtils/ScriptureUtils.csproj index eeeefc15a0..b8911d61fe 100644 --- a/Src/Common/ScriptureUtils/ScriptureUtils.csproj +++ b/Src/Common/ScriptureUtils/ScriptureUtils.csproj @@ -1,186 +1,205 @@ - + - Local - 9.0.30729 - 2.0 - {C98A0201-B55C-4B8C-9408-5F5FC2FD22B6} - - - - Debug - AnyCPU - - - - - ScriptureUtils - - - JScript - Grid - IE50 - false - Library - SIL.FieldWorks.Common.ScriptureUtils - OnBuildSuccess - - - - - - - - - 3.5 - false - v4.0 - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - true - + Local + 9.0.30729 + 2.0 + {C98A0201-B55C-4B8C-9408-5F5FC2FD22B6} + + + + + + + Debug + AnyCPU + + + + + ScriptureUtils + + + JScript + Grid + IE50 + false + Library + SIL.FieldWorks.Common.ScriptureUtils + OnBuildSuccess + + + + + + + + + 3.5 + false + v4.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + - ..\..\..\Output\Debug\ - false - 285212672 - false - - - DEBUG;TRACE - ..\..\..\Output\Debug\ScriptureUtils.xml - true - 4096 - false - 168,169,219,414,649,1635,1702,1701 - false - false - false - true - 4 - full - prompt - AllRules.ruleset - x86 + ..\..\..\Output\Debug\ + false + 285212672 + false + + + DEBUG;TRACE + ..\..\..\Output\Debug\ScriptureUtils.xml + true + 4096 + false + 168,169,219,414,649,1635,1702,1701 + false + false + false + true + 4 + full + prompt + AllRules.ruleset + x86 - ..\..\..\Output\Release\ - false - 285212672 - false - - - TRACE - - - true - 4096 - true - false - false - true - 4 - full - prompt - AllRules.ruleset - x86 + ..\..\..\Output\Release\ + false + 285212672 + false + + + TRACE + + + true + 4096 + true + false + false + true + 4 + full + prompt + AllRules.ruleset + x86 - - False - ..\..\..\Output\Debug\BasicUtils.dll - - - False - ..\..\..\Output\Debug\COMInterfaces.dll - - - False - ..\..\..\Output\Debug\FwResources.dll - - - False - ..\..\..\Output\Debug\FwUtils.dll - - - False - ..\..\..\Output\Debug\ScrUtilsInterfaces.dll - - - False - ..\..\..\Output\Debug\SharedScrUtils.dll - - - False - ..\..\..\Output\Debug\SilEncConverters40.dll - - - System - - - - System.Data - - - System.XML - + + False + ..\..\..\Output\Debug\BasicUtils.dll + + + False + ..\..\..\Output\Debug\COMInterfaces.dll + + + False + ..\..\..\Output\Debug\FDO.dll + + + False + ..\..\..\Output\Debug\FwResources.dll + + + False + ..\..\..\Output\Debug\FwUtils.dll + + + False + ..\..\..\Output\Debug\ParatextShared.dll + + + False + ..\..\..\Output\Debug\ScrUtilsInterfaces.dll + + + False + ..\..\..\Output\Debug\SharedScrUtils.dll + + + False + ..\..\..\Output\Debug\SilEncConverters40.dll + + + System + + + + System.Data + + + System.XML + + + False + ..\..\..\Output\Debug\Utilities.dll + - - CommonAssemblyInfo.cs - - - Code - - - - - Code - + + CommonAssemblyInfo.cs + + + Code + + + + + + Code + - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 2.0 %28x86%29 - true - - - False - .NET Framework 3.0 %28x86%29 - false - - - False - .NET Framework 3.5 - false - - - False - .NET Framework 3.5 SP1 - false - + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + + + + - - - - + + + + \ No newline at end of file diff --git a/Src/FDO/FDOTests/ParatextHelperTests.cs b/Src/Common/ScriptureUtils/ScriptureUtilsTests/ParatextHelperTests.cs similarity index 88% rename from Src/FDO/FDOTests/ParatextHelperTests.cs rename to Src/Common/ScriptureUtils/ScriptureUtilsTests/ParatextHelperTests.cs index f0b7a671b7..380fc5deb2 100644 --- a/Src/FDO/FDOTests/ParatextHelperTests.cs +++ b/Src/Common/ScriptureUtils/ScriptureUtilsTests/ParatextHelperTests.cs @@ -7,20 +7,20 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using NUnit.Framework; using Paratext; -using Paratext.DerivedTranslation; -using Paratext.LexicalClient; using SIL.FieldWorks.Common.FwUtils; +using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.DomainServices; +using SIL.FieldWorks.FDO.FDOTests; +using SIL.FieldWorks.Resources; using SIL.FieldWorks.Test.ProjectUnpacker; using SIL.FieldWorks.Test.TestUtils; using SIL.Utils; -namespace SIL.FieldWorks.FDO.FDOTests +namespace SIL.FieldWorks.Common.ScriptureUtils { #region MockParatextHelper class /// ---------------------------------------------------------------------------------------- @@ -128,11 +128,11 @@ public IEnumerable GetProjects() /// We never use this method; for tests, we use Rhino.Mocks.MockRepository /// /// ------------------------------------------------------------------------------------ - public bool LoadProjectMappings(string project, ScrMappingList mappingList, ImportDomain domain) + public void LoadProjectMappings(IScrImportSet importSettings) { if (m_loadProjectMappingsImpl == null) throw new NotImplementedException(); - return m_loadProjectMappingsImpl.LoadProjectMappings(project, mappingList, domain); + m_loadProjectMappingsImpl.LoadProjectMappings(importSettings); } #endregion @@ -205,7 +205,7 @@ public void AddProject(string shortName, string associatedProject, string basePr scrText.Name = shortName; if (!string.IsNullOrEmpty(associatedProject)) - scrText.AssociatedLexicalProject = new AssociatedLexicalProject(LexicalAppType.FieldWorks, associatedProject); + scrText.AssociatedLexicalProject = new AssociatedLexicalProject("FieldWorks", associatedProject); // Don't know how to implement a test involving baseProject now that BaseTranslation is gone from the PT API. // However all clients I can find so far pass null. if (!string.IsNullOrEmpty(baseProject)) @@ -411,7 +411,9 @@ public class ParatextHelperTests : ScrInMemoryFdoTestBase [Test] public void LoadParatextMappings_NullProjectName() { - Assert.IsFalse(ParatextHelper.LoadProjectMappings(null, null, ImportDomain.Main)); + IScrImportSet importSettings = Cache.ServiceLocator.GetInstance().Create(ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); + ParatextHelper.LoadProjectMappings(importSettings); + Assert.That(importSettings.ParatextScrProj, Is.Null); } /// ------------------------------------------------------------------------------------ @@ -425,12 +427,13 @@ public void LoadParatextMappings_Normal() { Unpacker.UnPackParatextTestProjects(); - FwStyleSheet stylesheet = new FwStyleSheet(); - stylesheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles); - ScrMappingList mappingList = new ScrMappingList(MappingSet.Main, stylesheet); - - Assert.IsTrue(ParatextHelper.LoadProjectMappings("KAM", mappingList, ImportDomain.Main)); + var stylesheet = new FwStyleSheet(); + stylesheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); + IScrImportSet importSettings = Cache.ServiceLocator.GetInstance().Create(ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); + importSettings.ParatextScrProj = "KAM"; + ParatextHelper.LoadProjectMappings(importSettings); + ScrMappingList mappingList = importSettings.GetMappingListForDomain(ImportDomain.Main); // Test to see that the projects are set correctly Assert.AreEqual(44, mappingList.Count); @@ -454,9 +457,11 @@ public void LoadParatextMappings_Normal() [Ignore("Has not been run for a while and no longer works; possibly obsolete")] public void LoadParatextMappings_MarkMappingsInUse() { - FwStyleSheet stylesheet = new FwStyleSheet(); - stylesheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles); - ScrMappingList mappingList = new ScrMappingList(MappingSet.Main, stylesheet); + var stylesheet = new FwStyleSheet(); + stylesheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); + IScrImportSet importSettings = Cache.ServiceLocator.GetInstance().Create(ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); + importSettings.ParatextScrProj = "TEV"; + ScrMappingList mappingList = importSettings.GetMappingListForDomain(ImportDomain.Main); mappingList.Add(new ImportMappingInfo(@"\hahaha", @"\*hahaha", false, MappingTargetType.TEStyle, MarkerDomain.Default, "laughing", null, null, true, ImportDomain.Main)); @@ -465,7 +470,8 @@ public void LoadParatextMappings_MarkMappingsInUse() "en", null, true, ImportDomain.Main)); Unpacker.UnPackParatextTestProjects(); - Assert.IsTrue(ParatextHelper.LoadProjectMappings("TEV", mappingList, ImportDomain.Main)); + + ParatextHelper.LoadProjectMappings(importSettings); Assert.IsTrue(mappingList[@"\c"].IsInUse); Assert.IsTrue(mappingList[@"\p"].IsInUse); @@ -486,12 +492,15 @@ public void LoadParatextMappings_MarkMappingsInUse() [Category("LongRunning")] public void LoadParatextMappings_MissingEncodingFile() { - FwStyleSheet stylesheet = new FwStyleSheet(); - stylesheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles); - ScrMappingList mappingList = new ScrMappingList(MappingSet.Main, stylesheet); + var stylesheet = new FwStyleSheet(); + stylesheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); + IScrImportSet importSettings = Cache.ServiceLocator.GetInstance().Create(ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); + importSettings.ParatextScrProj = "NEC"; Unpacker.UnPackMissingFileParatextTestProjects(); - Assert.IsFalse(ParatextHelper.LoadProjectMappings("NEC", mappingList, ImportDomain.Main)); + + ParatextHelper.LoadProjectMappings(importSettings); + Assert.That(importSettings.ParatextScrProj, Is.Null); } /// ------------------------------------------------------------------------------------ @@ -505,11 +514,13 @@ public void LoadParatextMappings_MissingEncodingFile() public void LoadParatextMappings_MissingStyleFile() { FwStyleSheet stylesheet = new FwStyleSheet(); - stylesheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles); - ScrMappingList mappingList = new ScrMappingList(MappingSet.Main, stylesheet); + stylesheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); + IScrImportSet importSettings = Cache.ServiceLocator.GetInstance().Create(ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); + importSettings.ParatextScrProj = "NSF"; Unpacker.UnPackMissingFileParatextTestProjects(); - Assert.IsFalse(ParatextHelper.LoadProjectMappings("NSF", mappingList, ImportDomain.Main)); + ParatextHelper.LoadProjectMappings(importSettings); + Assert.That(importSettings.ParatextScrProj, Is.Null); } #endregion } diff --git a/Src/Common/ScriptureUtils/ScriptureUtilsTests/ScriptureUtilsTests.csproj b/Src/Common/ScriptureUtils/ScriptureUtilsTests/ScriptureUtilsTests.csproj index 14decc95f7..3c40488b41 100644 --- a/Src/Common/ScriptureUtils/ScriptureUtilsTests/ScriptureUtilsTests.csproj +++ b/Src/Common/ScriptureUtils/ScriptureUtilsTests/ScriptureUtilsTests.csproj @@ -5,9 +5,12 @@ 9.0.30729 2.0 {C79E699C-2766-4D5B-9661-3BCE7C9679A6} - SAK - SAK - SAK + + + + + + Debug AnyCPU @@ -30,7 +33,8 @@ - SAK + + 3.5 false v4.0 @@ -98,18 +102,54 @@ x86 + + False + ..\..\..\..\Output\Debug\BasicUtils.dll + False ..\..\..\..\Output\Debug\BasicUtilsTests.dll + + False + ..\..\..\..\Output\Debug\COMInterfaces.dll + False ..\..\..\..\Output\Debug\COMInterfacesTests.dll + + False + ..\..\..\..\Output\Debug\FDO.dll + + + False + ..\..\..\..\Output\Debug\FDOTests.dll + + + False + ..\..\..\..\Output\Debug\FwResources.dll + + + False + ..\..\..\..\Output\Debug\FwUtils.dll + + + False + ..\..\..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll + nunit.framework ..\..\..\..\Bin\NUnit\bin\nunit.framework.dll + + False + ..\..\..\..\Output\Debug\ParatextShared.dll + + + False + ..\..\..\..\Output\Debug\ProjectUnpacker.dll + ScriptureUtils ..\..\..\..\Output\Debug\ScriptureUtils.dll @@ -126,16 +166,22 @@ System + TestUtils ..\..\..\..\Output\Debug\TestUtils.dll + + False + ..\..\..\..\Output\Debug\Utilities.dll + AssemblyInfoForTests.cs + diff --git a/Src/Common/SimpleRootSite/SimpleRootSite.csproj b/Src/Common/SimpleRootSite/SimpleRootSite.csproj index 6daa81ea4b..37625354be 100644 --- a/Src/Common/SimpleRootSite/SimpleRootSite.csproj +++ b/Src/Common/SimpleRootSite/SimpleRootSite.csproj @@ -90,7 +90,7 @@ true 4096 false - 168,169,219,414,649,1635,1702,1701 + 168,169,219,414,649,1635,1702,1701,1685 true false false diff --git a/Src/Common/SimpleRootSite/SimpleRootSiteTests/SimpleRootSiteTests.csproj b/Src/Common/SimpleRootSite/SimpleRootSiteTests/SimpleRootSiteTests.csproj index 241abb38e1..dcd573b1ab 100644 --- a/Src/Common/SimpleRootSite/SimpleRootSiteTests/SimpleRootSiteTests.csproj +++ b/Src/Common/SimpleRootSite/SimpleRootSiteTests/SimpleRootSiteTests.csproj @@ -84,7 +84,7 @@ false 4096 false - 168,169,219,414,649,1635,1702,1701 + 168,169,219,414,649,1635,1702,1701,1685 true false false @@ -206,9 +206,7 @@ - - UserControl - + @@ -251,4 +249,4 @@ - + \ No newline at end of file diff --git a/Src/FDO/Application/ApplicationServices/AppStrings.Designer.cs b/Src/FDO/Application/ApplicationServices/AppStrings.Designer.cs index 5d263ed8ba..777b206e57 100644 --- a/Src/FDO/Application/ApplicationServices/AppStrings.Designer.cs +++ b/Src/FDO/Application/ApplicationServices/AppStrings.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.296 +// Runtime Version:4.0.30319.18052 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -548,15 +548,6 @@ internal static string ksProblemImporting { } } - /// - /// Looks up a localized string similar to Restore Failed. - /// - internal static string ksRestoreDidNotSucceed { - get { - return ResourceManager.GetString("ksRestoreDidNotSucceed", resourceCulture); - } - } - /// /// Looks up a localized string similar to Semantic Domain. /// diff --git a/Src/FDO/Application/ApplicationServices/AppStrings.resx b/Src/FDO/Application/ApplicationServices/AppStrings.resx index 814540a3a5..0c5b98a38e 100644 --- a/Src/FDO/Application/ApplicationServices/AppStrings.resx +++ b/Src/FDO/Application/ApplicationServices/AppStrings.resx @@ -1,302 +1,299 @@  - + 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. + --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - text/microsoft-resx + text/microsoft-resx - 2.0 + 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Created {0} {1} objects during import from {2} + Created {0} {1} objects during import from {2} - Loading the XML file into the database took {0:F1} seconds. + Loading the XML file into the database took {0:F1} seconds. - This was automatically created to satisfy a Lexical Relation, and it should be checked. + This was automatically created to satisfy a Lexical Relation, and it should be checked. - {0}:{1}: Created an entry for "{2}" to satisfy a Lexical Relation. + {0}:{1}: Created an entry for "{2}" to satisfy a Lexical Relation. - This was automatically created to satisfy a Cross Reference, and it should be checked. + This was automatically created to satisfy a Cross Reference, and it should be checked. - {0}:{1}: Created an entry for "{2}" to satisfy a Cross Reference. + {0}:{1}: Created an entry for "{2}" to satisfy a Cross Reference. - Info: Creating Entry Or Sense Pair Lexical Reference Type with name="{0}" and abbr="{1}". + Info: Creating Entry Or Sense Pair Lexical Reference Type with name="{0}" and abbr="{1}". - Warning: Invalid <Binary> data. + Warning: Invalid <Binary> data. - Warning: Ignoring extra character at the end of <Binary> data. + Warning: Ignoring extra character at the end of <Binary> data. - Warning: Cannot create desired Lexical Reference Type: <Link {0}/>. + Warning: Cannot create desired Lexical Reference Type: <Link {0}/>. - Warning: Cannot resolve a link for a cross reference: <Link {0}/>. + Warning: Cannot resolve a link for a cross reference: <Link {0}/>. - Warning: Cannot resolve a link for a lexical relation: <Link {0}/>. + Warning: Cannot resolve a link for a lexical relation: <Link {0}/>. - Info: Creating new writing system for "{0}". + Info: Creating new writing system for "{0}". - Warning: Media file "{0}" does not exist. + Warning: Media file "{0}" does not exist. - Warning: Picture file "{0}" does not exist. + Warning: Picture file "{0}" does not exist. - Info: Creating new item with ws="{0}", abbr="{1}", and name="{2}" in the {3} list. + Info: Creating new item with ws="{0}", abbr="{1}", and name="{2}" in the {3} list. - Anthropology Categories + Anthropology Categories - Semantic Domain + Semantic Domain - Parts of Speech + Parts of Speech - Location + Location - People + People - Confidence Level + Confidence Level - Warning: Cannot resolve <Link {0}/> + Warning: Cannot resolve <Link {0}/> - Info: Creating Reversal Index for the {0} ("{1}") language. + Info: Creating Reversal Index for the {0} ("{1}") language. - Info: Implicit CmPossibility target in a Link element has name attribute "{0}" which matches an Abbreviation value. + Info: Implicit CmPossibility target in a Link element has name attribute "{0}" which matches an Abbreviation value. - Info: Implicit CmPossibility target in a Link element has abbr attribute "{0}" which matches a Name value. + Info: Implicit CmPossibility target in a Link element has abbr attribute "{0}" which matches a Name value. - Warning: Unexpected {0} element in XML file. + Warning: Unexpected {0} element in XML file. - Warning: Expected <Boolean val="..."/> here. + Warning: Expected <Boolean val="..."/> here. - Warning: Need explicit val attribute for Boolean elements! + Warning: Need explicit val attribute for Boolean elements! - Warning: Expected <Integer val="..."/> here. + Warning: Expected <Integer val="..."/> here. - Warning: Need explicit val attribute for Integer elements! + Warning: Need explicit val attribute for Integer elements! - Warning: Expected <Guid val="..."/> here. + Warning: Expected <Guid val="..."/> here. - Warning: Need explicit val attribute for Guid elements! + Warning: Need explicit val attribute for Guid elements! - Warning: Expected <Time val="..."/> here. + Warning: Expected <Time val="..."/> here. - Warning: Need explicit val attribute for Time elements! + Warning: Need explicit val attribute for Time elements! - Warning: Expected <GenDate val="..."/> here. + Warning: Expected <GenDate val="..."/> here. - Warning: Need explicit val attribute for GenDate elements! + Warning: Need explicit val attribute for GenDate elements! - Warning: Expected <Binary>...</Binary> here. + Warning: Expected <Binary>...</Binary> here. - Warning: Expected <Uni>...</Uni> here. + Warning: Expected <Uni>...</Uni> here. - Warning: Expected <AUni>...</AUni> here. + Warning: Expected <AUni>...</AUni> here. - Warning: Expected <Str>...</Str> here. + Warning: Expected <Str>...</Str> here. - Warning: Expected <AStr>...</AStr> here. + Warning: Expected <AStr>...</AStr> here. - Warning: Expected <Link .../> here. + Warning: Expected <Link .../> here. - Warning: Invalid <Link/> element - must have at least one attribute! + Warning: Invalid <Link/> element - must have at least one attribute! - Warning: Problem importing from {0}. + Warning: Problem importing from {0}. {1} - Import could not merge the custom field named "{0}" from one entry to another. + Import could not merge the custom field named "{0}" from one entry to another. - Warning: Nested XML object elements must reflect owning relationships. + Warning: Nested XML object elements must reflect owning relationships. - Warning: Unrecognized ownerless object class. + Warning: Unrecognized ownerless object class. - This was automatically created to satisfy a Components link, and it should be checked. + This was automatically created to satisfy a Components link, and it should be checked. - This was automatically created to satisfy a Show Subentry Under link, and it should be checked. + This was automatically created to satisfy a Show Subentry Under link, and it should be checked. - This was automatically created to satisfy a link target, and it should be checked. + This was automatically created to satisfy a link target, and it should be checked. - {0}:{1}: Created an entry for "{2}" to satisfy a Components link. + {0}:{1}: Created an entry for "{2}" to satisfy a Components link. - {0}:{1}: Created an entry for "{2}" to satisfy a Show Subentry Under link. + {0}:{1}: Created an entry for "{2}" to satisfy a Show Subentry Under link. - {0}:{1}: Created an entry for "{2}" to satisfy a link target. + {0}:{1}: Created an entry for "{2}" to satisfy a link target. - Info: Lexical reference type in a Link element has name attribute "{0}" which matches an Abbreviation value. + Info: Lexical reference type in a Link element has name attribute "{0}" which matches an Abbreviation value. - Info: Lexical reference type in a Link element has abbr attribute "{0}" which matches a Name value. + Info: Lexical reference type in a Link element has abbr attribute "{0}" which matches a Name value. - and {0} subrecords. + and {0} subrecords. - There was an error trying to create a subfolder of the new project. + There was an error trying to create a subfolder of the new project. The error was: {0} - - Restore Failed - - + Saving migrated data before loading. Message on a progress dialog. Appears after a data migration has completed and before the project is opened by FLEx. diff --git a/Src/FDO/Application/ApplicationServices/XmlImportData.cs b/Src/FDO/Application/ApplicationServices/XmlImportData.cs index e3c3687c14..f0c50467ab 100644 --- a/Src/FDO/Application/ApplicationServices/XmlImportData.cs +++ b/Src/FDO/Application/ApplicationServices/XmlImportData.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Text; @@ -15,7 +16,6 @@ using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.FDO.Infrastructure; using SIL.Utils; @@ -178,9 +178,8 @@ public XmlImportData(FdoCache cache) /// Import the file contents into the database represented by the FdoCache established /// by the constructor. /// - /// true if successful, false if an error occurs /// ------------------------------------------------------------------------------------ - public bool ImportData(string sFilename, IProgress progress) + public void ImportData(string sFilename, IProgress progress) { DateTime dtBegin = DateTime.Now; m_sFilename = sFilename; @@ -189,19 +188,18 @@ public bool ImportData(string sFilename, IProgress progress) if (idx >= 0) sLogFile = sLogFile.Substring(0, idx); sLogFile = sLogFile + "-Import.log"; - bool fRetVal = false; var streamReader = new StreamReader(sFilename, Encoding.UTF8); try { - fRetVal = ImportData(streamReader, + ImportData(streamReader, new StreamWriter(sLogFile, false, Encoding.UTF8), progress); - DateTime dtEnd = DateTime.Now; - TimeSpan span = new TimeSpan(dtEnd.Ticks - dtBegin.Ticks); - LogFinalCounts(Path.GetFileName(sFilename), span); } finally { + DateTime dtEnd = DateTime.Now; + var span = new TimeSpan(dtEnd.Ticks - dtBegin.Ticks); + LogFinalCounts(Path.GetFileName(sFilename), span); if (m_wrtrLog != null) { m_wrtrLog.Close(); @@ -209,7 +207,6 @@ public bool ImportData(string sFilename, IProgress progress) } streamReader.Dispose(); } - return fRetVal; } private void LogFinalCounts(string sFilename, TimeSpan span) @@ -260,9 +257,10 @@ private void LogMessage(string sMsg) /// Import the text reader contents into the database represented by the FdoCache set /// in the constructor. /// - /// true if successful, false if an error occurs /// ------------------------------------------------------------------------------------ - public bool ImportData(TextReader rdr, TextWriter wrtrLog, IProgress progress) + [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", + Justification = "xrdr is disposed when closed.")] + public void ImportData(TextReader rdr, TextWriter wrtrLog, IProgress progress) { bool fRetVal = true; m_progress = progress; @@ -301,9 +299,7 @@ public bool ImportData(TextReader rdr, TextWriter wrtrLog, IProgress progress) m_sFilename, e.Message); int line = LineNumber(xrdr); LogMessage(sMsg, line); - string sTitle = String.Format("Error on line {0}", line); - MessageBoxUtils.Show(sMsg, sTitle); - fRetVal = false; + throw; } finally { @@ -311,7 +307,6 @@ public bool ImportData(TextReader rdr, TextWriter wrtrLog, IProgress progress) xrdr.Close(); m_cache.MainCacheAccessor.EndNonUndoableTask(); } - return fRetVal; } ILexSenseFactory m_factLexSense; diff --git a/Src/FDO/Application/ApplicationServices/XmlList.cs b/Src/FDO/Application/ApplicationServices/XmlList.cs index 7609c3dd26..40bf3c3981 100644 --- a/Src/FDO/Application/ApplicationServices/XmlList.cs +++ b/Src/FDO/Application/ApplicationServices/XmlList.cs @@ -17,7 +17,6 @@ using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.Infrastructure; using SIL.Utils; @@ -57,15 +56,8 @@ public void ImportList(ICmObject owner, string sFieldName, string sFile, IProgre #if DEBUG DateTime dtBegin = DateTime.Now; #endif - try - { - using (var reader = new StreamReader(sFile, Encoding.UTF8)) - ImportList(owner, sFieldName, reader, progress); - } - catch (Exception e) - { - MessageBoxUtils.Show(e.Message); - } + using (var reader = new StreamReader(sFile, Encoding.UTF8)) + ImportList(owner, sFieldName, reader, progress); #if DEBUG DateTime dtEnd = DateTime.Now; TimeSpan span = new TimeSpan(dtEnd.Ticks - dtBegin.Ticks); @@ -83,110 +75,103 @@ public void ImportList(ICmObject owner, string sFieldName, TextReader reader, IP m_wsf = m_cache.WritingSystemFactory; m_progress = progress; - try - { - NonUndoableUnitOfWorkHelper.DoUsingNewOrCurrentUOW(m_cache.ActionHandlerAccessor, () => + NonUndoableUnitOfWorkHelper.DoUsingNewOrCurrentUOW(m_cache.ActionHandlerAccessor, () => + { + int flidList = m_mdc.GetFieldId(owner.ClassName, sFieldName, true); + if (flidList == 0) + throw new Exception(String.Format("Invalid list fieldname (programming error): {0}", sFieldName)); + using (var xrdr = XmlReader.Create(reader)) { - int flidList = m_mdc.GetFieldId(owner.ClassName, sFieldName, true); - if (flidList == 0) - throw new Exception(String.Format("Invalid list fieldname (programming error): {0}", sFieldName)); - using (var xrdr = XmlReader.Create(reader)) - { - xrdr.MoveToContent(); - if (xrdr.Name != owner.ClassName) - throw new Exception(String.Format("Unexpected outer element: {0}", xrdr.Name)); + xrdr.MoveToContent(); + if (xrdr.Name != owner.ClassName) + throw new Exception(String.Format("Unexpected outer element: {0}", xrdr.Name)); - if (!xrdr.ReadToDescendant(sFieldName)) - throw new Exception(String.Format("Unexpected second element: {0}", xrdr.Name)); + if (!xrdr.ReadToDescendant(sFieldName)) + throw new Exception(String.Format("Unexpected second element: {0}", xrdr.Name)); - if (!xrdr.ReadToDescendant("CmPossibilityList")) - throw new Exception(String.Format("Unexpected third element: {0}", xrdr.Name)); + if (!xrdr.ReadToDescendant("CmPossibilityList")) + throw new Exception(String.Format("Unexpected third element: {0}", xrdr.Name)); - ICmPossibilityList list; - int hvo = m_cache.MainCacheAccessor.get_ObjectProp(owner.Hvo, flidList); - if (hvo == 0) - hvo = m_cache.MainCacheAccessor.MakeNewObject(CmPossibilityListTags.kClassId, owner.Hvo, flidList, -2); - ICmPossibilityListRepository repo = m_cache.ServiceLocator.GetInstance(); - list = repo.GetObject(hvo); - string sItemClassName = "CmPossibility"; - xrdr.Read(); - while (xrdr.Depth == 3) + ICmPossibilityList list; + int hvo = m_cache.MainCacheAccessor.get_ObjectProp(owner.Hvo, flidList); + if (hvo == 0) + hvo = m_cache.MainCacheAccessor.MakeNewObject(CmPossibilityListTags.kClassId, owner.Hvo, flidList, -2); + ICmPossibilityListRepository repo = m_cache.ServiceLocator.GetInstance(); + list = repo.GetObject(hvo); + string sItemClassName = "CmPossibility"; + xrdr.Read(); + while (xrdr.Depth == 3) + { + xrdr.MoveToContent(); + if (xrdr.Depth < 3) + break; + switch (xrdr.Name) { - xrdr.MoveToContent(); - if (xrdr.Depth < 3) + case "Description": + SetMultiStringFromXml(xrdr, list.Description); break; - switch (xrdr.Name) - { - case "Description": - SetMultiStringFromXml(xrdr, list.Description); - break; - case "Name": - SetMultiUnicodeFromXml(xrdr, list.Name); - break; - case "Abbreviation": - SetMultiUnicodeFromXml(xrdr, list.Abbreviation); - break; - case "Depth": - list.Depth = ReadIntFromXml(xrdr); - break; - case "DisplayOption": - list.DisplayOption = ReadIntFromXml(xrdr); - break; - case "HelpFile": - list.HelpFile = ReadUnicodeFromXml(xrdr); - break; - case "IsClosed": - list.IsClosed = ReadBoolFromXml(xrdr); - break; - case "IsSorted": - list.IsSorted = ReadBoolFromXml(xrdr); - break; - case "IsVernacular": - list.IsVernacular = ReadBoolFromXml(xrdr); - break; - case "ItemClsid": - list.ItemClsid = ReadIntFromXml(xrdr); - sItemClassName = m_mdc.GetClassName(list.ItemClsid); - break; - case "ListVersion": - list.ListVersion = ReadGuidFromXml(xrdr); - break; - case "PreventChoiceAboveLevel": - list.PreventChoiceAboveLevel = ReadIntFromXml(xrdr); - break; - case "PreventDuplicates": - list.PreventDuplicates = ReadBoolFromXml(xrdr); - break; - case "PreventNodeChoices": - list.PreventNodeChoices = ReadBoolFromXml(xrdr); - break; - case "UseExtendedFields": - list.UseExtendedFields = ReadBoolFromXml(xrdr); - break; - case "WsSelector": - list.WsSelector = ReadIntFromXml(xrdr); - break; - case "Possibilities": - LoadPossibilitiesFromXml(xrdr, list, sItemClassName); - break; - case "HeaderFooterSets": - throw new Exception("We don't (yet?) handle HeaderFooterSets for CmPossibilityList (programming issue)"); - case "Publications": - throw new Exception("We don't (yet?) handle Publications for CmPossibilityList (programming issue)"); - default: - throw new Exception(String.Format("Unknown field element in CmPossibilityList: {0}", xrdr.Name)); - } + case "Name": + SetMultiUnicodeFromXml(xrdr, list.Name); + break; + case "Abbreviation": + SetMultiUnicodeFromXml(xrdr, list.Abbreviation); + break; + case "Depth": + list.Depth = ReadIntFromXml(xrdr); + break; + case "DisplayOption": + list.DisplayOption = ReadIntFromXml(xrdr); + break; + case "HelpFile": + list.HelpFile = ReadUnicodeFromXml(xrdr); + break; + case "IsClosed": + list.IsClosed = ReadBoolFromXml(xrdr); + break; + case "IsSorted": + list.IsSorted = ReadBoolFromXml(xrdr); + break; + case "IsVernacular": + list.IsVernacular = ReadBoolFromXml(xrdr); + break; + case "ItemClsid": + list.ItemClsid = ReadIntFromXml(xrdr); + sItemClassName = m_mdc.GetClassName(list.ItemClsid); + break; + case "ListVersion": + list.ListVersion = ReadGuidFromXml(xrdr); + break; + case "PreventChoiceAboveLevel": + list.PreventChoiceAboveLevel = ReadIntFromXml(xrdr); + break; + case "PreventDuplicates": + list.PreventDuplicates = ReadBoolFromXml(xrdr); + break; + case "PreventNodeChoices": + list.PreventNodeChoices = ReadBoolFromXml(xrdr); + break; + case "UseExtendedFields": + list.UseExtendedFields = ReadBoolFromXml(xrdr); + break; + case "WsSelector": + list.WsSelector = ReadIntFromXml(xrdr); + break; + case "Possibilities": + LoadPossibilitiesFromXml(xrdr, list, sItemClassName); + break; + case "HeaderFooterSets": + throw new Exception("We don't (yet?) handle HeaderFooterSets for CmPossibilityList (programming issue)"); + case "Publications": + throw new Exception("We don't (yet?) handle Publications for CmPossibilityList (programming issue)"); + default: + throw new Exception(String.Format("Unknown field element in CmPossibilityList: {0}", xrdr.Name)); } - xrdr.Close(); - if (m_mapRelatedDomains.Count > 0) - SetRelatedDomainsLinks(); } - }); - } - catch (Exception e) - { - MessageBoxUtils.Show(e.Message); - } + xrdr.Close(); + if (m_mapRelatedDomains.Count > 0) + SetRelatedDomainsLinks(); + } + }); } Guid EnsureGuid(Guid guid) diff --git a/Src/FDO/Application/ApplicationServices/XmlTranslatedLists.cs b/Src/FDO/Application/ApplicationServices/XmlTranslatedLists.cs index 407902b62d..17d425f292 100644 --- a/Src/FDO/Application/ApplicationServices/XmlTranslatedLists.cs +++ b/Src/FDO/Application/ApplicationServices/XmlTranslatedLists.cs @@ -14,7 +14,6 @@ using ICSharpCode.SharpZipLib.Zip; using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.Infrastructure; using System.Globalization; using SIL.Utils; @@ -46,30 +45,23 @@ public bool ImportTranslatedLists(string filename, FdoCache cache, IProgress pro #if DEBUG DateTime dtBegin = DateTime.Now; #endif - try + using (var inputStream = FileUtils.OpenStreamForRead(filename)) { - using (var inputStream = FileUtils.OpenStreamForRead(filename)) + var type = Path.GetExtension(filename).ToLowerInvariant(); + if (type == ".zip") { - var type = Path.GetExtension(filename).ToLowerInvariant(); - if (type == ".zip") - { - using (var zipStream = new ZipInputStream(inputStream)) - { - var entry = zipStream.GetNextEntry(); // advances it to where we can read the one zipped file. - using (var reader = new StreamReader(zipStream, Encoding.UTF8)) - ImportTranslatedLists(reader, cache, progress); - } - } - else + using (var zipStream = new ZipInputStream(inputStream)) { - using (var reader = new StreamReader(inputStream, Encoding.UTF8)) + var entry = zipStream.GetNextEntry(); // advances it to where we can read the one zipped file. + using (var reader = new StreamReader(zipStream, Encoding.UTF8)) ImportTranslatedLists(reader, cache, progress); } } - } - catch (Exception e) - { - MessageBoxUtils.Show(e.Message); + else + { + using (var reader = new StreamReader(inputStream, Encoding.UTF8)) + ImportTranslatedLists(reader, cache, progress); + } } #if DEBUG DateTime dtEnd = DateTime.Now; @@ -95,16 +87,9 @@ public bool ImportTranslatedLists(TextReader reader, FdoCache cache, IProgress p Debug.Assert(m_wsEn != 0); m_progress = progress; - try - { - using (var xreader = XmlReader.Create(reader)) + using (var xreader = XmlReader.Create(reader)) Import(xreader); - } - catch (Exception e) - { - MessageBoxUtils.Show(e.Message, "Import Error"); - return false; - } + return true; } @@ -125,10 +110,11 @@ public bool ImportTranslatedLists(TextReader reader, FdoCache cache, IProgress p /// /// /// + /// /// - public static void ImportTranslatedListsForWs(string ws, FdoCache cache, IProgress progress) + public static void ImportTranslatedListsForWs(string ws, FdoCache cache, string templateDir, IProgress progress) { - string path = TranslatedListsPathForWs(ws); + string path = TranslatedListsPathForWs(ws, templateDir); if (File.Exists(path)) { var instance = new XmlTranslatedLists(); @@ -149,10 +135,11 @@ public static string ProgressDialogCaption /// Call before ImportTranslatedListsForWs. Call that only if the file exists. /// /// + /// /// - public static string TranslatedListsPathForWs(string ws) + public static string TranslatedListsPathForWs(string ws, string templateDir) { - return Path.Combine(DirectoryFinder.TemplateDirectory, Path.ChangeExtension(LocalizedListPrefix + ws, "zip")); + return Path.Combine(templateDir, Path.ChangeExtension(LocalizedListPrefix + ws, "zip")); } private int GetWsFromStr(string sWs) diff --git a/Src/FDO/Application/DomainDataByFlidDecoratorBase.cs b/Src/FDO/Application/DomainDataByFlidDecoratorBase.cs index 2e6c5d0e45..0228e3590b 100644 --- a/Src/FDO/Application/DomainDataByFlidDecoratorBase.cs +++ b/Src/FDO/Application/DomainDataByFlidDecoratorBase.cs @@ -10,9 +10,9 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Diagnostics; +using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.FDO.Infrastructure; -using SIL.FieldWorks.Common.FwUtils; using SIL.Utils; namespace SIL.FieldWorks.FDO.Application diff --git a/Src/FDO/Application/ISilDataAccessManaged.cs b/Src/FDO/Application/ISilDataAccessManaged.cs index 4af751be9a..c3c47a4c7f 100644 --- a/Src/FDO/Application/ISilDataAccessManaged.cs +++ b/Src/FDO/Application/ISilDataAccessManaged.cs @@ -1,5 +1,5 @@ +using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using System; namespace SIL.FieldWorks.FDO.Application diff --git a/Src/FDO/Application/Impl/DomainDataByFlid.cs b/Src/FDO/Application/Impl/DomainDataByFlid.cs index 0417aa42fa..b9c87a9cc4 100644 --- a/Src/FDO/Application/Impl/DomainDataByFlid.cs +++ b/Src/FDO/Application/Impl/DomainDataByFlid.cs @@ -13,7 +13,6 @@ using System.Diagnostics; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.Common.ScriptureUtils; using SIL.FieldWorks.FDO.DomainImpl; using SIL.FieldWorks.FDO.DomainServices; diff --git a/Src/FDO/BuildInclude.targets b/Src/FDO/BuildInclude.targets index 2e5cf477f4..d13f12120c 100644 --- a/Src/FDO/BuildInclude.targets +++ b/Src/FDO/BuildInclude.targets @@ -77,7 +77,12 @@ TemplateFile="FDOGenerate/main.vm.cs"/> - + + + + + diff --git a/Src/FDO/DomainImpl/CmObject.cs b/Src/FDO/DomainImpl/CmObject.cs index 5ef25f8ac5..d96a03f52d 100644 --- a/Src/FDO/DomainImpl/CmObject.cs +++ b/Src/FDO/DomainImpl/CmObject.cs @@ -25,7 +25,6 @@ using System.IO; // MemoryStream. using System.Xml.Linq; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.Application; using SIL.FieldWorks.FDO.Infrastructure; using SIL.Utils; diff --git a/Src/FDO/DomainImpl/FdoFactoryAdditions.cs b/Src/FDO/DomainImpl/FdoFactoryAdditions.cs index 0762b502ef..a2534609c9 100644 --- a/Src/FDO/DomainImpl/FdoFactoryAdditions.cs +++ b/Src/FDO/DomainImpl/FdoFactoryAdditions.cs @@ -81,13 +81,6 @@ public ILexSense Create(ILexEntry entry, SandboxGenericMSA sandboxMSA, ITsString if (gloss != null) { - if (gloss.Length > 256) - { - MessageBoxUtils.Show(Strings.ksTruncatingGloss, Strings.ksWarning, - System.Windows.Forms.MessageBoxButtons.OK, - System.Windows.Forms.MessageBoxIcon.Warning); - gloss = gloss.Substring(0, 256); - } sense.Gloss.set_String(gloss.get_WritingSystemAt(0), gloss); } return sense; @@ -2661,4 +2654,18 @@ public IText Create(FdoCache cache, Guid guid) } } #endregion + + #region ScrImportSetFactory class + + internal partial class ScrImportSetFactory + { + public IScrImportSet Create(string defaultParaCharsStyleName, string stylesPath) + { + var settings = new ScrImportSet(defaultParaCharsStyleName, stylesPath); + ((ICmObjectInternal) settings).InitializeNewOwnerlessCmObject(m_cache); + return settings; + } + } + + #endregion } diff --git a/Src/FDO/DomainImpl/FdoScripture.cs b/Src/FDO/DomainImpl/FdoScripture.cs index f93f09b90c..55f776652d 100644 --- a/Src/FDO/DomainImpl/FdoScripture.cs +++ b/Src/FDO/DomainImpl/FdoScripture.cs @@ -12,11 +12,11 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.Linq; using System.Text; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.Common.ScriptureUtils; -using SIL.FieldWorks.Resources; using SILUBS.SharedScrUtils; using SIL.FieldWorks.FDO.DomainServices; using SIL.CoreImpl; @@ -401,8 +401,10 @@ private IScrImportSet DefaultImportSettings_internal /// one (which is probably the only one), or creates new settings if none exist. /// /// type of import type to find + /// The default paragraph characters style name. + /// /// ------------------------------------------------------------------------------------ - public IScrImportSet FindOrCreateDefaultImportSettings(TypeOfImport importType) + public IScrImportSet FindOrCreateDefaultImportSettings(TypeOfImport importType, string defaultParaCharsStyleName, string stylesPath) { IScrImportSet settings = DefaultImportSettings_internal; @@ -428,7 +430,7 @@ public IScrImportSet FindOrCreateDefaultImportSettings(TypeOfImport importType) // Didn't find the specified type of settings, so create a new set. IScrImportSet newSettings = - m_cache.ServiceLocator.GetInstance().Create(); + m_cache.ServiceLocator.GetInstance().Create(defaultParaCharsStyleName, stylesPath); ImportSettingsOC.Add(newSettings); newSettings.ImportType = (int)importType; return newSettings; @@ -866,7 +868,7 @@ public IPublication FindByName(string publicationName) /// first ensure there is no book with that ID. /// /// The book to copy. - /// Attempt to copy book to current version + /// Attempt to copy book to current version /// when that book already exists in the current version /// The copied bok /// ------------------------------------------------------------------------------------ @@ -969,7 +971,7 @@ public string ChapterVerseBridgeAsString(IScrSection section) { if (section.IsIntro) { - return String.Format(ResourceHelper.GetResourceString("kstidScriptureSectionIntroduction"), section.OwnOrd); + return String.Format(Strings.ksScriptureSectionIntroduction, section.OwnOrd); } ScrReference startRef = new ScrReference(section.VerseRefStart, Versification); ScrReference endRef = new ScrReference(section.VerseRefEnd, Versification); @@ -1001,11 +1003,10 @@ public string ContainingRefAsString(IScrFootnote footnote) } else if (footnote.TryGetContainingTitle(out containingTitle)) { - parentContext = ResourceHelper.GetResourceString("kstidScriptureTitle"); - footnoteRef = footnote.OwnOrd.ToString(); + parentContext = Strings.ksScriptureTitle; + footnoteRef = footnote.OwnOrd.ToString(CultureInfo.InvariantCulture); } - return String.Format("{0} {1}({2})", parentContext, - ResourceHelper.GetResourceString("kstidScriptureFootnote"), footnoteRef); + return String.Format("{0} {1}({2})", parentContext, Strings.ksScriptureFootnote, footnoteRef); } /// ------------------------------------------------------------------------------------ @@ -1073,8 +1074,7 @@ public ITsString BookChapterVerseBridgeAsTss(IStText stText, int ws) { ITsStrBldr bldr = tssBookName.GetBldr(); int cch = bldr.Length; - bldr.Replace(cch, cch, String.Format(" ({0})", - ResourceHelper.GetResourceString("kstidScriptureTitle")), null); + bldr.Replace(cch, cch, String.Format(" ({0})", Strings.ksScriptureTitle), null); tssTitle = bldr.GetString(); } } diff --git a/Src/FDO/DomainImpl/OverridesCellar.cs b/Src/FDO/DomainImpl/OverridesCellar.cs index b3b2bf805b..bd68a0526b 100644 --- a/Src/FDO/DomainImpl/OverridesCellar.cs +++ b/Src/FDO/DomainImpl/OverridesCellar.cs @@ -8,15 +8,12 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Windows.Forms; using System.Collections.Generic; using System.Text; // StringBuilder using System.Xml; // XMLWriter using System.Diagnostics; using System.IO; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; -using SIL.FieldWorks.FDO.Application; using SIL.Utils; using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.FDO.Infrastructure; @@ -1761,51 +1758,53 @@ internal static ITsString TSSAbbrforWS(FdoCache cache, ICmPossibility pss, int w return tss; } - /// - /// Return true if this or one of its children is in use as a Constituent chart column. - /// Most efficient to call this after checking that the root is a chart template. - /// - /// - bool ThisOrChildIsInUseAsChartColumn() + public bool IsDefaultDiscourseTemplate + { + get + { + ICmPossibilityList ccTempl = Cache.LangProject.DiscourseDataOA.ConstChartTemplOA; + if (OwningList != ccTempl) + return false; + + IFdoOwningSequence discourseTemplates = ccTempl.PossibilitiesOS; + return discourseTemplates.Count == 1 && Hvo == discourseTemplates[0].Hvo; + } + } + + public bool IsThisOrDescendantInUseAsChartColumn + { + get + { + if (OwningList != Cache.LangProject.DiscourseDataOA.ConstChartTemplOA) + return false; + + CmPossibility rootPossibility = this; + while (rootPossibility.Owner is CmPossibility) + rootPossibility = (CmPossibility) rootPossibility.Owner; + IDsChart chart = Services.GetInstance().InstancesWithTemplate(rootPossibility).FirstOrDefault(); + return chart != null && GetIsThisOrDescendantInUseAsChartColumn(); + } + } + + private bool GetIsThisOrDescendantInUseAsChartColumn() { var repo = Services.GetInstance(); if (repo.InstancesWithChartCellColumn(this).FirstOrDefault() != null) return true; - foreach (var poss in SubPossibilitiesOS) - if (((CmPossibility)poss).ThisOrChildIsInUseAsChartColumn()) - return true; - return false; + return SubPossibilitiesOS.Cast().Any(poss => poss.GetIsThisOrDescendantInUseAsChartColumn()); } - /// - /// If the recipient is a column in a chart that shouldn't be moved or promoted or deleted, report - /// accordingly and return true. Return false if OK to delete or move. - /// - /// - public bool CheckAndReportProtectedChartColumn() + public bool IsOnlyTextMarkupTag { - var discourseTemplates = m_cache.LangProject.DiscourseDataOA.ConstChartTemplOA.PossibilitiesOS; - if (discourseTemplates.Count == 1 && Hvo == discourseTemplates[0].Hvo) + get { - MessageBoxUtils.Show(Strings.ksCantDeleteDefaultDiscourseTemplate, Strings.ksWarning, - MessageBoxButtons.OK, MessageBoxIcon.Warning); - return true; - } - ICmPossibility rootPossibility = this; - while (rootPossibility.Owner is CmPossibility) - rootPossibility = (CmPossibility)rootPossibility.Owner; - var chart = - rootPossibility.Services.GetInstance().InstancesWithTemplate(rootPossibility). - FirstOrDefault(); - if (chart != null && ThisOrChildIsInUseAsChartColumn()) - { - string textName = (chart as DsConstChart).BasedOnRA.Title.BestAnalysisVernacularAlternative.Text; - // This is an actual column; it's a problem if it has instances - string msg = string.Format(Strings.ksCantModifyTemplateInUse, textName); - MessageBoxUtils.Show(msg, Strings.ksErrorCaption, MessageBoxButtons.OK, MessageBoxIcon.Error); - return true; + ICmPossibilityList tags = Cache.LangProject.TextMarkupTagsOA; + if (OwningList != tags) + return false; + + IFdoOwningSequence tagTypes = tags.PossibilitiesOS; + return tagTypes.Count == 1 && this == tagTypes[0]; } - return false; } /// ------------------------------------------------------------------------------------ @@ -1818,24 +1817,11 @@ public override bool CanDelete { get { - if (!base.CanDelete) - return false; - var lp = Cache.LangProject; - if (OwningList == lp.DiscourseDataOA.ConstChartTemplOA && - CheckAndReportProtectedChartColumn()) - return false; - if (OwningList == lp.TextMarkupTagsOA && - CheckAndReportUsedMarkupTag()) - return false; - if (IsProtected == false) - return true; - var information = Strings.ksRequiredItem; - MessageBoxUtils.Show( - information, - "", - System.Windows.Forms.MessageBoxButtons.OK, - System.Windows.Forms.MessageBoxIcon.Information); - return false; + return base.CanDelete + && !IsDefaultDiscourseTemplate && !IsThisOrDescendantInUseAsChartColumn + && !IsOnlyTextMarkupTag + && (OwningList != Cache.LangProject.TextMarkupTagsOA || !Services.GetInstance().GetByTextMarkupTag(this).Any()) + && !IsProtected; } } @@ -1870,67 +1856,6 @@ public override void MergeObject(ICmObject objSrc, bool fLoseNoStringData) base.MergeObject(objSrc, fLoseNoStringData); } - - /// - /// If the recipient is a Tagging possibility that is used in a TextTag object (which shouldn't - /// exist unless used in a text, it shouldn't be deleted. - /// Report accordingly and return true. Return false if OK to delete. - /// - /// TRUE if there is a problem! - public bool CheckAndReportUsedMarkupTag() - { - var tagTypes = m_cache.LangProject.TextMarkupTagsOA.PossibilitiesOS.ToHvoArray(); - if (tagTypes.Length == 1 && Hvo == tagTypes[0]) - { - MessageBoxUtils.Show(Strings.ksCantDeleteLastTagList, Strings.ksWarning, - MessageBoxButtons.OK, MessageBoxIcon.Warning); - return true; - } - - // Check for subpossibilities that might be in use too! - List hvoArray = new List(); - hvoArray.Add(Hvo); - var subArray = SubPossibilitiesOS.ToHvoArray(); - if (subArray.Length > 0) - { - // The presence of SubPossibilities means that this is a tag type - // (if we're in that list), so we need to check all of the SubPossibilities - // to see if they are used. - hvoArray.AddRange(subArray); - } - // Look in TextTag repo for one (or more) with this possibility label. - // If used report and return true, otherwise return false. - var repo = Cache.ServiceLocator.GetInstance(); - var used = (from tag in repo.AllInstances() - where hvoArray.Contains(tag.TagRA.Hvo) - select tag).ToArray(); - var cUsed = used.Length; - if (cUsed == 0) - return false; - // Try to get a nice title. - var msg = GetCorrectErrorMessage(used[0]); - MessageBox.Show(msg, Strings.ksWarning, MessageBoxButtons.OK, MessageBoxIcon.Warning); - return true; - } - - private string GetCorrectErrorMessage(ITextTag usedTag) - { - // Try to get a nice title. - string textName = null; - if (usedTag != null && usedTag.BeginSegmentRA != null) - { - var ws = Cache.LangProject.DefaultWsForMagicWs(WritingSystemServices.kwsFirstAnalOrVern); - var text = usedTag.BeginSegmentRA.Owner.Owner as IStText; - textName = text.Title.get_String(ws).Text; - if (String.IsNullOrEmpty(textName)) - textName = text.ShortName; - } - var msg = string.Format( - (SubPossibilitiesOS.Count == 0) ? - Strings.ksCantDeleteMarkupTagInUse : Strings.ksCantDeleteMarkupTypeInUse, - textName); - return msg; - } } #endregion @@ -2082,7 +2007,7 @@ public string InternalPath if (value == null) throw new ArgumentNullException("value"); - string srcFilename = DirectoryFinderRelativePaths.GetRelativeLinkedFilesPath(value, m_cache.LangProject.LinkedFilesRootDir); + string srcFilename = LinkedFilesRelativePathHelper.GetRelativeLinkedFilesPath(value, m_cache.LangProject.LinkedFilesRootDir); InternalPath_Generated = srcFilename; } @@ -2113,7 +2038,7 @@ public string AbsoluteInternalPath string internalPath = InternalPath; if (String.IsNullOrEmpty(internalPath)) internalPath = DomainObjectServices.EmptyFileName; - return DirectoryFinderRelativePaths.GetFullPathFromRelativeLFPath(internalPath, m_cache.LangProject.LinkedFilesRootDir); + return LinkedFilesRelativePathHelper.GetFullPathFromRelativeLFPath(internalPath, m_cache.LangProject.LinkedFilesRootDir); } } diff --git a/Src/FDO/DomainImpl/OverridesLangProj.cs b/Src/FDO/DomainImpl/OverridesLangProj.cs index 73a6652370..7f601ef1d6 100644 --- a/Src/FDO/DomainImpl/OverridesLangProj.cs +++ b/Src/FDO/DomainImpl/OverridesLangProj.cs @@ -21,7 +21,6 @@ using SIL.FieldWorks.Common.COMInterfaces; using SIL.Utils; // Needed for Set class. -using SIL.FieldWorks.Common.FwUtils; // for LanguageDefinitionFactory using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.FDO.Infrastructure; using SIL.CoreImpl; @@ -82,7 +81,7 @@ public IEnumerable AllWordforms /// ------------------------------------------------------------------------------------ /// - /// Return LinkedFilesRootDir if explicitly set, otherwise FWDataDirectory. + /// Return LinkedFilesRootDir if explicitly set, otherwise DataDirectory. /// /// ------------------------------------------------------------------------------------ [ModelProperty(CellarPropertyType.Unicode, 6001042, "string")] @@ -91,14 +90,14 @@ public string LinkedFilesRootDir get { return String.IsNullOrEmpty(LinkedFilesRootDir_Generated) - ? Path.Combine(m_cache.ProjectId.SharedProjectFolder, DirectoryFinder.ksLinkedFilesDir) - : DirectoryFinderRelativePaths.GetLinkedFilesFullPathFromRelativePath(LinkedFilesRootDir_Generated, - m_cache.ProjectId.SharedProjectFolder); + ? Path.Combine(m_cache.ProjectId.SharedProjectFolder, FdoFileHelper.ksLinkedFilesDir) + : LinkedFilesRelativePathHelper.GetLinkedFilesFullPathFromRelativePath(Services.GetInstance().ProjectsDirectory, + LinkedFilesRootDir_Generated, m_cache.ProjectId.SharedProjectFolder); } set { - string relativePath = DirectoryFinderRelativePaths.GetLinkedFilesRelativePathFromFullPath(value, - m_cache.ProjectId.SharedProjectFolder, ShortName); + string relativePath = LinkedFilesRelativePathHelper.GetLinkedFilesRelativePathFromFullPath(Services.GetInstance().ProjectsDirectory, + value, m_cache.ProjectId.SharedProjectFolder, ShortName); LinkedFilesRootDir_Generated = relativePath; } @@ -144,7 +143,7 @@ public IList InterlinearTexts // Get regular texts. - if (FwUtils.IsOkToDisplayScriptureIfPresent && TranslatedScriptureOA != null) + if (TranslatedScriptureOA != null) { // TE installed, so also get them from Sripture. foreach (var book in TranslatedScriptureOA.ScriptureBooksOS) diff --git a/Src/FDO/DomainImpl/OverridesLing_Lex.cs b/Src/FDO/DomainImpl/OverridesLing_Lex.cs index d5a1fb056b..b32279efe6 100644 --- a/Src/FDO/DomainImpl/OverridesLing_Lex.cs +++ b/Src/FDO/DomainImpl/OverridesLing_Lex.cs @@ -13,15 +13,13 @@ using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Drawing; using System.Globalization; using System.Linq; using System.Text; -using System.Windows.Forms; using System.Collections.Generic; using System.Collections.Specialized; -using System.Windows.Forms.VisualStyles; using System.Xml; // XMLWriter -using System.Drawing; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.FDO.Application; @@ -31,9 +29,6 @@ using SIL.FieldWorks.FDO.Infrastructure; using SIL.FieldWorks.FDO.Validation; using SIL.CoreImpl; -using Sharpen.Util; - -// XmlUtils namespace SIL.FieldWorks.FDO.DomainImpl { @@ -240,29 +235,29 @@ public ICmPossibilityList PublicationTypesOA /// /// Allows user to convert LexEntryType to LexEntryInflType. /// - public void ConvertLexEntryInflTypes(ProgressBar progressBar, IEnumerable list) + public void ConvertLexEntryInflTypes(IProgress progressBar, IEnumerable list) { progressBar.Minimum = 0; progressBar.Maximum = list.Count(); - progressBar.Step = 1; + progressBar.StepSize = 1; foreach (var lexEntryType in list) { var leitFactory = m_cache.ServiceLocator.GetInstance(); var leit = leitFactory.Create(); leit.ConvertLexEntryType(lexEntryType); lexEntryType.Delete(); - progressBar.PerformStep(); + progressBar.Step(1); } } /// /// Allows user to convert LexEntryInflType to LexEntryType. /// - public void ConvertLexEntryTypes(ProgressBar progressBar, IEnumerable list) + public void ConvertLexEntryTypes(IProgress progressBar, IEnumerable list) { progressBar.Minimum = 0; progressBar.Maximum = list.Count(); - progressBar.Step = 1; + progressBar.StepSize = 1; foreach (var lexEntryInflType in list) { var leit = lexEntryInflType as ILexEntryInflType; @@ -273,20 +268,20 @@ public void ConvertLexEntryTypes(ProgressBar progressBar, IEnumerable /// Resets the homograph numbers for all entries but can take a null progress bar. /// - public void ResetHomographNumbers(ProgressBar progressBar) + public void ResetHomographNumbers(IProgress progressBar) { if (progressBar != null) { progressBar.Minimum = 0; progressBar.Maximum = Entries.Count(); - progressBar.Step = 1; + progressBar.StepSize = 1; } var processedEntryIds = new List(); UndoableUnitOfWorkHelper.DoUsingNewOrCurrentUOW(Strings.ksUndoResetHomographs, Strings.ksRedoResetHomographs, Cache.ActionHandlerAccessor, @@ -297,7 +292,7 @@ public void ResetHomographNumbers(ProgressBar progressBar) if (processedEntryIds.Contains(le.Hvo)) { if (progressBar != null) - progressBar.PerformStep(); + progressBar.Step(1); continue; } @@ -315,7 +310,7 @@ public void ResetHomographNumbers(ProgressBar progressBar) { processedEntryIds.Add(homograph.Hvo); if (progressBar != null) - progressBar.PerformStep(); + progressBar.Step(1); } } }); diff --git a/Src/FDO/DomainImpl/OverridesLing_MoClasses.cs b/Src/FDO/DomainImpl/OverridesLing_MoClasses.cs index 1bebc4ac49..85fbad15be 100644 --- a/Src/FDO/DomainImpl/OverridesLing_MoClasses.cs +++ b/Src/FDO/DomainImpl/OverridesLing_MoClasses.cs @@ -14,11 +14,9 @@ using System.Linq; using System.Diagnostics; using System.Text; -using System.Collections; using System.Collections.Generic; using System.Xml; // XMLWriter using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.FDO.Infrastructure; using SIL.Utils; diff --git a/Src/FDO/DomainImpl/ReadWriteServices.cs b/Src/FDO/DomainImpl/ReadWriteServices.cs index 459289b820..e8fe6b6d6b 100644 --- a/Src/FDO/DomainImpl/ReadWriteServices.cs +++ b/Src/FDO/DomainImpl/ReadWriteServices.cs @@ -3,7 +3,6 @@ using System.Xml; using System.Xml.Linq; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.Infrastructure; using SIL.CoreImpl; using System.Collections.Generic; diff --git a/Src/FDO/DomainImpl/ScrBook.cs b/Src/FDO/DomainImpl/ScrBook.cs index 09fa2cff33..5a83cd13db 100644 --- a/Src/FDO/DomainImpl/ScrBook.cs +++ b/Src/FDO/DomainImpl/ScrBook.cs @@ -9,15 +9,11 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics; -using System.Runtime.InteropServices; -using SIL.FieldWorks.FDO; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.Common.ScriptureUtils; using SILUBS.SharedScrUtils; using SIL.Utils; using System.Text; -using System.Data.SqlClient; using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.FDO.Infrastructure; using SIL.CoreImpl; diff --git a/Src/FDO/DomainImpl/ScrImportSet.cs b/Src/FDO/DomainImpl/ScrImportSet.cs index 3f9eb250d2..254943f86a 100644 --- a/Src/FDO/DomainImpl/ScrImportSet.cs +++ b/Src/FDO/DomainImpl/ScrImportSet.cs @@ -6,18 +6,13 @@ // Responsibility: TE Team using System; -using System.IO; using System.Collections; -using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; -using System.Linq; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.Utils; using SILUBS.SharedScrUtils; using SIL.FieldWorks.FDO.Infrastructure; using SIL.FieldWorks.FDO.DomainServices; -using SIL.FieldWorks.Resources; namespace SIL.FieldWorks.FDO.DomainImpl { @@ -46,6 +41,9 @@ internal partial class ScrImportSet /// private Hashtable m_notesFileInfoLists = new Hashtable(); + private readonly string m_defaultParaCharsStyleName; + private readonly string m_stylesPath; + private IOverlappingFileResolver m_resolver; private ScrMappingList m_scrMappingsList; @@ -65,11 +63,16 @@ internal partial class ScrImportSet private bool m_fImportAnnotations; private BCVRef m_startRef; private BCVRef m_endRef; - - private string m_helpFile; #endregion #region Construction & initialization + + internal ScrImportSet(string defaultParaStylesName, string stylesPath) + { + m_defaultParaCharsStyleName = defaultParaStylesName; + m_stylesPath = stylesPath; + } + /// ------------------------------------------------------------------------------------ /// /// Initialize the ScrImportSet. Sets the default values after the initialization of a @@ -85,8 +88,8 @@ protected override void SetDefaultValuesAfterInit() private void DoCommonNonModelSetup() { - m_scrMappingsList = new ScrMappingList(MappingSet.Main, m_stylesheet); - m_notesMappingsList = new ScrMappingList(MappingSet.Notes, m_stylesheet); + m_scrMappingsList = new ScrMappingList(MappingSet.Main, m_stylesheet, m_defaultParaCharsStyleName, m_stylesPath); + m_notesMappingsList = new ScrMappingList(MappingSet.Notes, m_stylesheet, m_defaultParaCharsStyleName, m_stylesPath); LoadInMemoryMappingLists(); LoadSources(false); @@ -129,9 +132,9 @@ private void LoadSources(bool createSourcesIfNeeded) private void LoadInMemoryMappingLists() { foreach (ScrMarkerMapping mapping in ScriptureMappingsOC) - m_scrMappingsList.Add(mapping.ToImportMappingInfo()); + m_scrMappingsList.Add(mapping.ToImportMappingInfo(m_defaultParaCharsStyleName)); foreach (ScrMarkerMapping mapping in NoteMappingsOC) - m_notesMappingsList.Add(mapping.ToImportMappingInfo()); + m_notesMappingsList.Add(mapping.ToImportMappingInfo(m_defaultParaCharsStyleName)); m_scrMappingsList.ResetChangedFlags(); m_notesMappingsList.ResetChangedFlags(); } @@ -149,7 +152,7 @@ private void LoadInMemoryFileLists() { m_scrFileInfoList = new ScrSfFileList((ScrImportSFFiles)source, m_scrMappingsList, ImportDomain.Main, - (ImportTypeEnum == TypeOfImport.Paratext5), m_helpFile); + (ImportTypeEnum == TypeOfImport.Paratext5)); m_scrFileInfoList.OverlappingFileResolver = m_resolver; break; } @@ -164,7 +167,7 @@ private void LoadInMemoryFileLists() string wsId = source.WritingSystem ?? string.Empty; m_btFileInfoLists[wsId] = new ScrSfFileList((ScrImportSFFiles)source, m_scrMappingsList, ImportDomain.BackTrans, - (ImportTypeEnum == TypeOfImport.Paratext5), m_helpFile); + (ImportTypeEnum == TypeOfImport.Paratext5)); } } @@ -177,7 +180,7 @@ private void LoadInMemoryFileLists() ((ScrImportSFFiles)source).NoteTypeRA); m_notesFileInfoLists[key] = new ScrSfFileList((ScrImportSFFiles)source, m_notesMappingsList, ImportDomain.Annotations, - (ImportTypeEnum == TypeOfImport.Paratext5), m_helpFile); + (ImportTypeEnum == TypeOfImport.Paratext5)); } } } @@ -253,107 +256,6 @@ public TypeOfImport ImportTypeEnum } #endregion - #region Import Project Accessibility Methods - /// ----------------------------------------------------------------------------------- - /// - /// Indicates whether the in-memory import projects/files are currently accessible from - /// this machine. - /// - /// A list of Paratext project IDs or file paths that - /// could not be found. - /// - /// For Paratext projects, this will only return true if all projects are accessible. - /// For Standard Format, this will return true if any of the files are accessible. - /// We think this might make sense, but we aren't sure why. - /// - /// ----------------------------------------------------------------------------------- - public bool ImportProjectIsAccessible(out StringCollection thingsNotFound) - { - lock (SyncRoot) - { - if (ImportTypeEnum == TypeOfImport.Paratext6) - return ParatextProjectsAccessible(out thingsNotFound); - else if (ImportTypeEnum == TypeOfImport.Other || ImportTypeEnum == TypeOfImport.Paratext5) - return SFProjectFilesAccessible(out thingsNotFound); - thingsNotFound = null; - return false; - } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Determines whether or not a set of paratext projects can be found and are - /// accessible. - /// - /// A list of the Paratext projects that couldn't - /// be found or are inaccessible. - /// A value indicating whether or not the projects are accessible. True if - /// all are. Otherwise, false. - /// ------------------------------------------------------------------------------------ - private bool ParatextProjectsAccessible(out StringCollection projectsNotFound) - { - projectsNotFound = new StringCollection(); - - if (m_ParatextScrProject == null) - return false; - - // Paratext seems to want to have write access to do an import... - string filename = Path.Combine(ParatextHelper.ProjectsDirectory, m_ParatextScrProject + ".ssf"); - if (!FileUtils.IsFileReadableAndWritable(filename) || - !ParatextHelper.GetProjectBooks(m_ParatextScrProject).Any()) - { - projectsNotFound.Add(m_ParatextScrProject); - } - - if (m_ParatextBTProject != null) - { - filename = Path.Combine(ParatextHelper.ProjectsDirectory, m_ParatextBTProject + ".ssf"); - if (!FileUtils.IsFileReadableAndWritable(filename) || - !ParatextHelper.GetProjectBooks(m_ParatextBTProject).Any()) - { - projectsNotFound.Add(m_ParatextBTProject); - } - } - - if (m_ParatextNotesProject != null) - { - filename = Path.Combine(ParatextHelper.ProjectsDirectory, m_ParatextNotesProject + ".ssf"); - if (!FileUtils.IsFileReadableAndWritable(filename) || - !ParatextHelper.GetProjectBooks(m_ParatextNotesProject).Any()) - { - projectsNotFound.Add(m_ParatextNotesProject); - } - } - - return (projectsNotFound.Count == 0); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Determines whether or not a set of SFM project files can be found and are - /// accessible. - /// - /// A list of files that couldn't be found. - /// true if any SFM files are accessible. Otherwise, false. - /// ------------------------------------------------------------------------------------ - private bool SFProjectFilesAccessible(out StringCollection filesNotFound) - { - filesNotFound = new StringCollection(); - - bool fProjectFileFound = false; - - fProjectFileFound |= m_scrFileInfoList.FilesAreAccessible(ref filesNotFound); - - foreach (ScrSfFileList list in m_btFileInfoLists.Values) - fProjectFileFound |= list.FilesAreAccessible(ref filesNotFound); - - foreach (ScrSfFileList list in m_notesFileInfoLists.Values) - fProjectFileFound |= list.FilesAreAccessible(ref filesNotFound); - - return (fProjectFileFound); - } - #endregion - #region Public Properties /// ------------------------------------------------------------------------------------ /// @@ -639,18 +541,6 @@ public bool Valid } } - /// ------------------------------------------------------------------------------------ - /// - /// Sets the StartRef and EndRef based on the requested canonical book numbers. - /// - /// ------------------------------------------------------------------------------------ - public void IncludeBooks(int startBook, int endBook, Paratext.ScrVers versification) - { - StartRef = new BCVRef(startBook, 0, 0); - int chapter = versification.LastChapter(endBook); - EndRef = new BCVRef(endBook, chapter, versification.LastVerse(endBook, chapter)); - } - /// ------------------------------------------------------------------------------------ /// /// Gets/sets stylesheet for settings. @@ -674,20 +564,6 @@ public IVwStylesheet StyleSheet } } } - - /// ------------------------------------------------------------------------------------ - /// - /// Sets the help file used in a message box if an error occurs. - /// - /// ------------------------------------------------------------------------------------ - public string HelpFile - { - set - { - lock (SyncRoot) - m_helpFile = value; - } - } #endregion #region Public Methods @@ -904,7 +780,7 @@ public virtual string ParatextScrProj if (value != null && (value == ParatextNotesProj || value == ParatextBTProj)) throw new ArgumentException(ScrFdoResources.kstidPtScrAlreadyUsed); - m_ParatextScrProject = SetParatextProject(value, ImportDomain.Main); + m_ParatextScrProject = value; } } } @@ -930,7 +806,7 @@ public virtual string ParatextBTProj if (value != null && (value == ParatextScrProj || value == ParatextNotesProj)) throw new ArgumentException(ScrFdoResources.kstidPtBtAlreadyUsed); - m_ParatextBTProject = SetParatextProject(value, ImportDomain.BackTrans); + m_ParatextBTProject = value; } } } @@ -956,34 +832,11 @@ public virtual string ParatextNotesProj if (value != null && (value == ParatextScrProj || value == ParatextBTProj)) throw new ArgumentException(ScrFdoResources.kstidPtNotesAlreadyUsed); - m_ParatextNotesProject = SetParatextProject(value, ImportDomain.Annotations); + m_ParatextNotesProject = value; } } } - /// ------------------------------------------------------------------------------------ - /// - /// Sets the Paratext project name for the specified domain. - /// - /// The name of the Paratext project. - /// The domain (Scripture, back translation or annotations). - /// name of the project, if not empty and the project loads without error; - /// otherwise null - /// ------------------------------------------------------------------------------------ - private string SetParatextProject(string value, ImportDomain domain) - { - string projName = (value == string.Empty) ? null : value; - if (projName != null) - { - // use notes list for the annotations domain, otherwise use the scripture list. - ScrMappingList loadedList = domain == ImportDomain.Annotations ? m_notesMappingsList : m_scrMappingsList; - bool fValidProj = ParatextHelper.LoadProjectMappings(value, loadedList, domain); - return fValidProj ? value : null; - } - - return null; - } - /// ------------------------------------------------------------------------------------ /// /// Commit the "temporary" in-memory settings to the permanent properties @@ -1070,60 +923,6 @@ private string StartsWithMarker(string line, StringCollection markersList) return null; } - /// ------------------------------------------------------------------------------------ - /// - /// Gets a list of books that exist for all of the files in this project. - /// - /// A List of integers representing 1-based canonical book numbers that exist - /// in any source represented by these import settings - /// If project is not a supported type - /// ------------------------------------------------------------------------------------ - public List BooksForProject - { - get - { - Debug.Assert(BasicSettingsExist, "Vernacular Scripture project not defined."); - switch (ImportTypeEnum) - { - case TypeOfImport.Paratext6: - // TODO (TE-5903): Check BT and Notes projects as well. - return ParatextHelper.GetProjectBooks(ParatextScrProj).ToList(); - case TypeOfImport.Paratext5: - case TypeOfImport.Other: - lock (SyncRoot) - { - List booksPresent = new List(); - foreach (IScrImportFileInfo file in m_scrFileInfoList) - foreach (int iBook in file.BooksInFile) - { - if (!booksPresent.Contains(iBook)) - booksPresent.Add(iBook); - } - - foreach (ScrSfFileList fileList in m_btFileInfoLists.Values) - foreach (IScrImportFileInfo file in fileList) - foreach (int iBook in file.BooksInFile) - { - if (!booksPresent.Contains(iBook)) - booksPresent.Add(iBook); - } - - foreach (ScrSfFileList fileList in m_notesFileInfoLists.Values) - foreach (IScrImportFileInfo file in fileList) - foreach (int iBook in file.BooksInFile) - { - if (!booksPresent.Contains(iBook)) - booksPresent.Add(iBook); - } - booksPresent.Sort(); - return booksPresent; - } - default: - throw new NotSupportedException("Unexpected type of Import Project"); - } - } - } - /// ------------------------------------------------------------------------------------ /// /// Get a MappingSet that is appropriate for the ImportDomain @@ -1451,7 +1250,7 @@ private void SaveMappings(IFdoOwningCollection mappingsOC, Sc mappingsOC.Add(mapping); // The "Default Paragraph Characters" style is not a real style. So, we save it as // as separate target type. We want to set the style now for the in-memory info. - if (info.StyleName == ResourceHelper.DefaultParaCharsStyleName) + if (info.StyleName == m_defaultParaCharsStyleName) info.MappingTarget = MappingTargetType.DefaultParaChars; else if (info.Style == null || info.Style.Name != info.StyleName) info.SetStyle((StStyle)m_cache.LangProject.TranslatedScriptureOA.FindStyle(info.StyleName)); diff --git a/Src/FDO/DomainImpl/ScrMarkerMapping.cs b/Src/FDO/DomainImpl/ScrMarkerMapping.cs index bbb33e7604..6a644ba95b 100644 --- a/Src/FDO/DomainImpl/ScrMarkerMapping.cs +++ b/Src/FDO/DomainImpl/ScrMarkerMapping.cs @@ -5,16 +5,8 @@ // File: ScrMarkerMapping.cs // Responsibility: TE Team -using System; -using System.Collections.Generic; -using System.Collections; -using System.Diagnostics; -using SIL.FieldWorks.FDO; -using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.FDO.DomainServices; -using SIL.FieldWorks.Common.ScriptureUtils; -using SIL.FieldWorks.Resources; namespace SIL.FieldWorks.FDO.DomainImpl { @@ -48,7 +40,7 @@ internal void InitFromImportMappingInfo(ImportMappingInfo info) /// Get the members of a ScrMarkerMapping into an ImportMappingInfo object /// /// ------------------------------------------------------------------------------------ - public ImportMappingInfo ToImportMappingInfo() + public ImportMappingInfo ToImportMappingInfo(string defaultParaCharsStyleName) { MarkerDomain domain = (MarkerDomain)Domain; if ((domain & MarkerDomain.DeprecatedScripture) != 0) @@ -61,7 +53,7 @@ public ImportMappingInfo ToImportMappingInfo() if (Target == (int)MappingTargetType.DefaultParaChars) { return new ImportMappingInfo(BeginMarker, EndMarker, Excluded, - MappingTargetType.TEStyle, domain, ResourceHelper.DefaultParaCharsStyleName, + MappingTargetType.TEStyle, domain, defaultParaCharsStyleName, WritingSystem, NoteTypeRA); } diff --git a/Src/FDO/DomainImpl/ScrScriptureNote.cs b/Src/FDO/DomainImpl/ScrScriptureNote.cs index 6d356f2c10..0add1b6e77 100644 --- a/Src/FDO/DomainImpl/ScrScriptureNote.cs +++ b/Src/FDO/DomainImpl/ScrScriptureNote.cs @@ -10,17 +10,9 @@ // using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Runtime.InteropServices; -using System.Text; - -using SIL.FieldWorks.FDO; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.Utils; using SIL.FieldWorks.Common.ScriptureUtils; -using SIL.FieldWorks.Common.FwUtils; -using SIL.FieldWorks.Resources; using SILUBS.SharedScrUtils; using SIL.FieldWorks.FDO.DomainServices; using SIL.CoreImpl; diff --git a/Src/FDO/DomainImpl/ScrSection.cs b/Src/FDO/DomainImpl/ScrSection.cs index 6581e31253..f05557a31b 100644 --- a/Src/FDO/DomainImpl/ScrSection.cs +++ b/Src/FDO/DomainImpl/ScrSection.cs @@ -10,16 +10,12 @@ using System; using System.Diagnostics; - -using SIL.FieldWorks.FDO; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.Common.ScriptureUtils; using SILUBS.SharedScrUtils; using System.Collections.Generic; using SIL.FieldWorks.FDO.DomainServices; using SIL.CoreImpl; -using SIL.FieldWorks.FDO.Infrastructure; namespace SIL.FieldWorks.FDO.DomainImpl { diff --git a/Src/FDO/DomainImpl/StFootnote.cs b/Src/FDO/DomainImpl/StFootnote.cs index 549b68f0a1..37390bc24e 100644 --- a/Src/FDO/DomainImpl/StFootnote.cs +++ b/Src/FDO/DomainImpl/StFootnote.cs @@ -10,15 +10,9 @@ using System; using System.Diagnostics; -using System.Xml; using System.Text; -using System.Collections.Generic; - -using SIL.FieldWorks.FDO; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.FDO.Infrastructure; -using SIL.Utils; -using SIL.FieldWorks.Common.FwUtils; using SIL.CoreImpl; namespace SIL.FieldWorks.FDO.DomainImpl diff --git a/Src/FDO/DomainServices/BackupRestore/BackupFileRepository.cs b/Src/FDO/DomainServices/BackupRestore/BackupFileRepository.cs index 911821f95b..f5f5a7fe9d 100644 --- a/Src/FDO/DomainServices/BackupRestore/BackupFileRepository.cs +++ b/Src/FDO/DomainServices/BackupRestore/BackupFileRepository.cs @@ -11,9 +11,7 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; -using SIL.FieldWorks.Common.FwUtils; using System.Collections.Generic; -using SIL.FieldWorks.Resources; using SIL.Utils; using System.Globalization; @@ -39,12 +37,12 @@ public class BackupFileRepository /// we'll need to pass in the directory name or have a way to change it. /// /// ------------------------------------------------------------------------------------ - public BackupFileRepository() + public BackupFileRepository(string defaultBackupDir) { string[] backups; try { - backups = FileUtils.GetFilesInDirectory(DirectoryFinder.DefaultBackupDirectory); + backups = FileUtils.GetFilesInDirectory(defaultBackupDir); } catch (Exception) { @@ -55,7 +53,7 @@ public BackupFileRepository() foreach (string backup in backups) { string ext = Path.GetExtension(backup); - if (ext != FwFileExtensions.ksFwBackupFileExtension && ext != FwFileExtensions.ksFw60BackupFileExtension) + if (ext != FdoFileHelper.ksFwBackupFileExtension && ext != FdoFileHelper.ksFw60BackupFileExtension) continue; string filename = Path.GetFileNameWithoutExtension(backup); MatchCollection matches = regex.Matches(filename); @@ -77,7 +75,7 @@ public BackupFileRepository() { SortedDictionary versions = GetOrCreateProjectVersions(projectName); string comment; - if (ext == FwFileExtensions.ksFw60BackupFileExtension) + if (ext == FdoFileHelper.ksFw60BackupFileExtension) comment = Properties.Resources.kstidFw60OrEarlierBackupComment; else { diff --git a/Src/FDO/DomainServices/BackupRestore/BackupFileSettings.cs b/Src/FDO/DomainServices/BackupRestore/BackupFileSettings.cs index 57cc4d217a..540f4990bd 100644 --- a/Src/FDO/DomainServices/BackupRestore/BackupFileSettings.cs +++ b/Src/FDO/DomainServices/BackupRestore/BackupFileSettings.cs @@ -10,9 +10,7 @@ using System.Runtime.Serialization; using ICSharpCode.SharpZipLib; using ICSharpCode.SharpZipLib.Zip; -using SIL.FieldWorks.Common.FwUtils; using SIL.Utils; -using SIL.FieldWorks.Resources; using SIL.FieldWorks.FDO.Infrastructure.Impl; namespace SIL.FieldWorks.FDO.DomainServices.BackupRestore @@ -119,11 +117,11 @@ private BackupFileSettings(BackupProjectSettings settings) m_supportingFiles = settings.IncludeSupportingFiles; m_linkedFiles = settings.IncludeLinkedFiles; m_projectName = settings.ProjectName; - m_projectPathPersisted = DirectoryFinder.GetPathWithoutRoot(settings.ProjectPath); + m_projectPathPersisted = FdoFileHelper.GetPathWithoutRoot(settings.ProjectPath); m_spellCheckAdditions = settings.IncludeSpellCheckAdditions; m_dbVersion = settings.DbVersion; m_fwVersion = settings.FwVersion; - m_linkedFilesPathRelative = DirectoryFinderRelativePaths.GetLinkedFilesRelativePathFromFullPath(settings.LinkedFilesPath, settings.ProjectPath, settings.ProjectName); + m_linkedFilesPathRelative = LinkedFilesRelativePathHelper.GetLinkedFilesRelativePathFromFullPath(settings.ProjectsRootFolder, settings.LinkedFilesPath, settings.ProjectPath, settings.ProjectName); m_linkedFilesPathActual = settings.LinkedFilesPath; m_appAbbrev = settings.AppAbbrev; } @@ -224,8 +222,8 @@ public void Validate() PopulateSettingsFromZipFileIfNeeded(); if (DbVersion > FDOBackendProvider.ModelVersion) { - throw new InvalidBackupFileException(ResourceHelper.FormatResourceString( - "ksBackupFileCreatedByNewerFwVersion", m_sZipFileName, FwVersion)); + throw new InvalidBackupFileException(string.Format(Strings.ksBackupFileCreatedByNewerFwVersion, + m_sZipFileName, FwVersion)); } } #endregion @@ -321,7 +319,7 @@ public string LinkedFilesPathRelativePersisted [DataMember] public string AppAbbrev { - get { PopulateSettingsFromZipFileIfNeeded(); return m_appAbbrev ?? FwUtils.ksFlexAbbrev; } + get { PopulateSettingsFromZipFileIfNeeded(); return m_appAbbrev; } private set { m_appAbbrev = value; } } @@ -391,7 +389,7 @@ private void PopulateSettingsFromZipFileIfNeeded() return; string extension = Path.GetExtension(m_sZipFileName).ToLowerInvariant(); - if (extension == FwFileExtensions.ksFw60BackupFileExtension) + if (extension == FdoFileHelper.ksFw60BackupFileExtension) { ProcessOldZipFile(); return; @@ -417,32 +415,32 @@ private void PopulateSettingsFromZipFileIfNeeded() if (String.IsNullOrEmpty(fileName)) continue; - if (fileName.Equals(DirectoryFinder.kBackupSettingsFilename)) + if (fileName.Equals(FdoFileHelper.kBackupSettingsFilename)) { if (foundBackupSettingsFile) throw new InvalidOperationException("Zip file " + m_sZipFileName + " contained multiple " + - DirectoryFinder.kBackupSettingsFilename + " files."); + FdoFileHelper.kBackupSettingsFilename + " files."); foundBackupSettingsFile = true; InitializeFromStream(zipIn); } - else if (Path.GetExtension(fileName) == FwFileExtensions.ksFwDataXmlFileExtension) + else if (Path.GetExtension(fileName) == FdoFileHelper.ksFwDataXmlFileExtension) { if (dataFileName != null) throw new InvalidOperationException("Zip file " + m_sZipFileName + " contained multiple project data files."); dataFileName = fileName; } - else if (!entry.Name.EndsWith("/") && entry.Name.Contains(DirectoryFinder.ksWritingSystemsDir + "/")) + else if (!entry.Name.EndsWith("/") && entry.Name.Contains(FdoFileHelper.ksWritingSystemsDir + "/")) foundWritingSystemFiles = true; } if (!foundBackupSettingsFile) throw new InvalidOperationException("Zip file " + m_sZipFileName + " did not contain the " + - DirectoryFinder.kBackupSettingsFilename + " file."); + FdoFileHelper.kBackupSettingsFilename + " file."); if (m_projectName == null) - throw new InvalidOperationException(DirectoryFinder.kBackupSettingsFilename + " in " + + throw new InvalidOperationException(FdoFileHelper.kBackupSettingsFilename + " in " + m_sZipFileName + " did not contain a project name."); - string expectedProjectFile = DirectoryFinder.GetXmlDataFileName(m_projectName); + string expectedProjectFile = FdoFileHelper.GetXmlDataFileName(m_projectName); if (dataFileName == null || dataFileName != expectedProjectFile) throw new InvalidOperationException("Zip file " + m_sZipFileName + " did not contain the " + expectedProjectFile + " file."); @@ -539,9 +537,9 @@ private void InitializeFromStream(Stream persistenceStream) m_backupTime = settings.BackupTime; m_comment = settings.Comment; m_projectName = settings.ProjectName; - m_linkedFilesPathRelative = DirectoryFinderRelativePaths.FixPathSlashesIfNeeded(settings.LinkedFilesPathRelativePersisted); - m_linkedFilesPathActual = DirectoryFinderRelativePaths.FixPathSlashesIfNeeded(settings.LinkedFilesPathActualPersisted); - m_projectPathPersisted = DirectoryFinderRelativePaths.FixPathSlashesIfNeeded(settings.ProjectPathPersisted); + m_linkedFilesPathRelative = LinkedFilesRelativePathHelper.FixPathSlashesIfNeeded(settings.LinkedFilesPathRelativePersisted); + m_linkedFilesPathActual = LinkedFilesRelativePathHelper.FixPathSlashesIfNeeded(settings.LinkedFilesPathActualPersisted); + m_projectPathPersisted = LinkedFilesRelativePathHelper.FixPathSlashesIfNeeded(settings.ProjectPathPersisted); m_configurationSettings = settings.IncludeConfigurationSettings; m_linkedFiles = settings.IncludeLinkedFiles; m_supportingFiles = settings.IncludeSupportingFiles; @@ -570,7 +568,7 @@ public class InvalidBackupFileException : Exception /// The inner exception /// ------------------------------------------------------------------------------------ public InvalidBackupFileException(string zipFile, Exception inner) : - base(ResourceHelper.GetResourceString("ksInvalidFwBackupFile") + Environment.NewLine + zipFile, inner) + base(Strings.ksInvalidFwBackupFile + Environment.NewLine + zipFile, inner) { } diff --git a/Src/FDO/DomainServices/BackupRestore/BackupProjectSettings.cs b/Src/FDO/DomainServices/BackupRestore/BackupProjectSettings.cs index 461764c8d5..4eb79e4532 100644 --- a/Src/FDO/DomainServices/BackupRestore/BackupProjectSettings.cs +++ b/Src/FDO/DomainServices/BackupRestore/BackupProjectSettings.cs @@ -7,11 +7,9 @@ using System; using System.IO; -using SIL.FieldWorks.Common.FwUtils; -using SIL.FieldWorks.FDO.Infrastructure; +using SIL.CoreImpl; using SIL.FieldWorks.FDO.Infrastructure.Impl; using System.Reflection; -using SIL.FieldWorks.Resources; using SIL.Utils; namespace SIL.FieldWorks.FDO.DomainServices.BackupRestore @@ -23,17 +21,19 @@ namespace SIL.FieldWorks.FDO.DomainServices.BackupRestore public class BackupProjectSettings : BackupSettings { #region Constructors + /// ------------------------------------------------------------------------------------ /// /// Constructor /// /// The cache. /// The backup info. + /// The destination folder. /// ------------------------------------------------------------------------------------ - public BackupProjectSettings(FdoCache cache, IBackupInfo backupInfo) : + public BackupProjectSettings(FdoCache cache, IBackupInfo backupInfo, string destFolder) : this(Path.GetDirectoryName(cache.ProjectId.ProjectFolder), cache.ProjectId.Name, cache.LanguageProject.LinkedFilesRootDir, cache.ProjectId.SharedProjectFolder, - cache.ProjectId.Type) + cache.ProjectId.Type, destFolder) { if (backupInfo != null) { @@ -57,19 +57,20 @@ public BackupProjectSettings(FdoCache cache, IBackupInfo backupInfo) : /// A possibly alternate project path that /// should be used for things that should be shared. /// Type of the project before converting for backup. + /// The destination folder. /// ------------------------------------------------------------------------------------ protected BackupProjectSettings(string projectsRootFolder, string projectName, - string linkedFilesPath, string sharedProjectFolder, FDOBackendProviderType originalProjType) : + string linkedFilesPath, string sharedProjectFolder, FDOBackendProviderType originalProjType, string destFolder) : base(projectsRootFolder, linkedFilesPath, sharedProjectFolder) { ProjectName = projectName; DbVersion = FDOBackendProvider.ModelVersion; - FwVersion = new FwVersionInfoProvider(Assembly.GetExecutingAssembly(), false).FieldWorksVersion; + FwVersion = new VersionInfoProvider(Assembly.GetExecutingAssembly(), false).MajorVersion; // For DB4o projects, we need to convert them over to XML. We can't put the // converted project in the same directory so we convert them to a temporary // directory (see FWR-2813). - DatabaseFolder = (originalProjType == FDOBackendProviderType.kXML) ? ProjectPath : Path.GetTempPath(); - DestinationFolder = DirectoryFinder.DefaultBackupDirectory; + DatabaseFolder = (originalProjType == FDOBackendProviderType.kXML || originalProjType == FDOBackendProviderType.kSharedXML) ? ProjectPath : Path.GetTempPath(); + DestinationFolder = destFolder; BackupTime = DateTime.Now; } #endregion @@ -149,7 +150,7 @@ public string AdjustedComment private string MakeBackupFileName(string comment) { return ProjectName + " " + BackupTime.ToString(ksBackupDateFormat) + - comment + FwFileExtensions.ksFwBackupFileExtension; + comment + FdoFileHelper.ksFwBackupFileExtension; } /// ------------------------------------------------------------------------------------ @@ -161,8 +162,8 @@ public string BackupSettingsFile { get { - return Path.Combine(DirectoryFinder.GetBackupSettingsDir(ProjectPath), - DirectoryFinder.kBackupSettingsFilename); + return Path.Combine(FdoFileHelper.GetBackupSettingsDir(ProjectPath), + FdoFileHelper.kBackupSettingsFilename); } } #endregion diff --git a/Src/FDO/DomainServices/BackupRestore/BackupSettings.cs b/Src/FDO/DomainServices/BackupRestore/BackupSettings.cs index 77f0073ba9..e7324e4c6f 100644 --- a/Src/FDO/DomainServices/BackupRestore/BackupSettings.cs +++ b/Src/FDO/DomainServices/BackupRestore/BackupSettings.cs @@ -8,7 +8,6 @@ using System; using System.IO; using SIL.Utils; -using SIL.FieldWorks.Common.FwUtils; namespace SIL.FieldWorks.FDO.DomainServices.BackupRestore { @@ -82,7 +81,7 @@ protected BackupSettings(string projectsRootFolder, string linkedFilesPath, /// ------------------------------------------------------------------------------------ public string DbFilename { - get { return DirectoryFinder.GetXmlDataFileName(ProjectName); } + get { return FdoFileHelper.GetXmlDataFileName(ProjectName); } } #region IBackupSettings implementation @@ -152,6 +151,15 @@ public bool IncludeSpellCheckAdditions #endregion #region Paths + + /// + /// Gets the projects root folder. + /// + public string ProjectsRootFolder + { + get { return m_projectsRootFolder; } + } + /// /// This is the path of the project being (or about to be) backed up or restored. /// @@ -175,7 +183,7 @@ public string QuestionNotesFilename /// public string FlexConfigurationSettingsPath { - get { return DirectoryFinder.GetConfigSettingsDir(ProjectPath); } + get { return FdoFileHelper.GetConfigSettingsDir(ProjectPath); } } /// @@ -188,7 +196,7 @@ public string LinkedFilesPath if (String.IsNullOrEmpty(m_linkedFilesPath)) { return Path.Combine(!string.IsNullOrEmpty(m_sharedProjectFolder) ? - m_sharedProjectFolder : ProjectPath, DirectoryFinder.ksLinkedFilesDir); + m_sharedProjectFolder : ProjectPath, FdoFileHelper.ksLinkedFilesDir); } return m_linkedFilesPath; } @@ -203,7 +211,7 @@ public string LinkedFilesPath /// public string PicturesPath { - get { return DirectoryFinder.GetPicturesDir(LinkedFilesPath); } + get { return FdoFileHelper.GetPicturesDir(LinkedFilesPath); } } /// @@ -211,7 +219,7 @@ public string PicturesPath /// public string MediaPath { - get { return DirectoryFinder.GetMediaDir(LinkedFilesPath); } + get { return FdoFileHelper.GetMediaDir(LinkedFilesPath); } } /// @@ -219,7 +227,7 @@ public string MediaPath /// public string OtherExternalFilesPath { - get { return DirectoryFinder.GetOtherExternalFilesDir(LinkedFilesPath); } + get { return FdoFileHelper.GetOtherExternalFilesDir(LinkedFilesPath); } } /// @@ -229,7 +237,7 @@ public string WritingSystemStorePath { get { - return DirectoryFinder.GetWritingSystemDir( + return FdoFileHelper.GetWritingSystemDir( string.IsNullOrEmpty(m_sharedProjectFolder) ? ProjectPath : m_sharedProjectFolder); } } @@ -248,7 +256,7 @@ public string SpellingDictionariesPath /// public string ProjectSupportingFilesPath { - get { return DirectoryFinder.GetSupportingFilesDir(ProjectPath); } + get { return FdoFileHelper.GetSupportingFilesDir(ProjectPath); } } #endregion } diff --git a/Src/FDO/DomainServices/BackupRestore/FilesToRestoreAreOlder.resx b/Src/FDO/DomainServices/BackupRestore/FilesToRestoreAreOlder.resx deleted file mode 100644 index f5ddc71d23..0000000000 --- a/Src/FDO/DomainServices/BackupRestore/FilesToRestoreAreOlder.resx +++ /dev/null @@ -1,351 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 60, 12 - - - 488, 52 - - - - 3 - - - Some files in the Linked Files folder are newer than the ones which will be restored, and these may not be files that this FieldWorks project links to yet. - - - label_message - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - 60, 64 - - - 488, 41 - - - 4 - - - Would you like to keep the newer files in the folder or replace them with the older ones from the backup? - - - label_Question - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - 12, 12 - - - 42, 38 - - - 5 - - - pictureBox1 - - - System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - True - - - - NoControl - - - 64, 132 - - - 192, 17 - - - 13 - - - Use the older files from the backup. - - - radio_Overwrite - - - System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - NoControl - - - 64, 109 - - - 164, 17 - - - 12 - - - Keep newer files in the folder. - - - radio_Keep - - - System.Windows.Forms.RadioButton, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - NoControl - - - 474, 157 - - - 75, 23 - - - 11 - - - Help - - - button_Help - - - System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - NoControl - - - 393, 157 - - - 75, 23 - - - 10 - - - Cancel - - - button_Cancel - - - System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - NoControl - - - 312, 157 - - - 75, 23 - - - 9 - - - OK - - - button_OK - - - System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - True - - - 6, 13 - - - 561, 192 - - - Linked files in backup are older - - - FilesToRestoreAreOlder - - - System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/Src/FDO/DomainServices/BackupRestore/ProjectBackupService.cs b/Src/FDO/DomainServices/BackupRestore/ProjectBackupService.cs index 11282c89f2..2f83126a04 100644 --- a/Src/FDO/DomainServices/BackupRestore/ProjectBackupService.cs +++ b/Src/FDO/DomainServices/BackupRestore/ProjectBackupService.cs @@ -9,10 +9,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Windows.Forms; using ICSharpCode.SharpZipLib.Zip; using SIL.CoreImpl; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.Infrastructure; using SIL.Utils; @@ -25,7 +23,7 @@ public class ProjectBackupService { private readonly FdoCache m_cache; private readonly BackupProjectSettings m_settings; - List m_failedFiles = new List(); + private readonly List m_failedFiles = new List(); /// /// Constructor @@ -36,15 +34,26 @@ public ProjectBackupService(FdoCache cache, BackupProjectSettings settings) m_settings = settings; } + /// + /// Gets the failed files. + /// + /// + /// The failed files. + /// + public IEnumerable FailedFiles + { + get { return m_failedFiles; } + } + /// /// Perform a backup of the current project, using specified settings. /// /// The backup file or null if something went wrong. - public string BackupProject(IThreadedProgress progressDlg) + public bool BackupProject(IThreadedProgress progressDlg, out string backupFile) { PersistBackupFileSettings(); - string backupFile = null; + backupFile = null; try { // Make sure any changes we want backup are saved. @@ -55,23 +64,14 @@ public string BackupProject(IThreadedProgress progressDlg) var filesToZip = CreateListOfFilesToZip(); progressDlg.Title = Strings.ksBackupProgressCaption; - progressDlg.ProgressBarStyle = ProgressBarStyle.Marquee; + progressDlg.IsIndeterminate = true; progressDlg.AllowCancel = false; m_failedFiles.Clear(); // I think it's always a new instance, but play safe. backupFile = (string)progressDlg.RunTask(true, BackupTask, filesToZip); - if (m_failedFiles.Count > 0) - { - var msg = string.Format(Strings.ksCouldNotBackupSomeFiles, m_failedFiles.ToString(", ", Path.GetFileName)); - if (MessageBox.Show(progressDlg.Form, msg, Strings.ksWarning, MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != - DialogResult.Yes) - { - File.Delete(backupFile); - } - } if (tempFilePath != null) File.Delete(tempFilePath); // don't leave the extra fwdata file around to confuse things. } - catch(Exception e) + catch (Exception e) { // Something went catastrophically wrong. Don't leave a junk backup around. if (backupFile != null) @@ -80,7 +80,8 @@ public string BackupProject(IThreadedProgress progressDlg) throw e.InnerException; throw new ContinuableErrorException("Backup did not succeed. Code is needed to handle this case.", e); } - return backupFile; + + return m_failedFiles.Count == 0; } /// ------------------------------------------------------------------------------------ @@ -90,8 +91,8 @@ public string BackupProject(IThreadedProgress progressDlg) /// ------------------------------------------------------------------------------------ private void PersistBackupFileSettings() { - string backupSettingsFile = Path.Combine(DirectoryFinder.GetBackupSettingsDir( - m_settings.ProjectPath), DirectoryFinder.kBackupSettingsFilename); + string backupSettingsFile = Path.Combine(FdoFileHelper.GetBackupSettingsDir( + m_settings.ProjectPath), FdoFileHelper.kBackupSettingsFilename); string settingsDir = Path.GetDirectoryName(backupSettingsFile); if (!Directory.Exists(settingsDir)) diff --git a/Src/FDO/DomainServices/BackupRestore/ProjectRestoreService.cs b/Src/FDO/DomainServices/BackupRestore/ProjectRestoreService.cs index eaea295ee0..3c5bf4bd6b 100644 --- a/Src/FDO/DomainServices/BackupRestore/ProjectRestoreService.cs +++ b/Src/FDO/DomainServices/BackupRestore/ProjectRestoreService.cs @@ -11,14 +11,10 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; -using System.Windows.Forms; using ICSharpCode.SharpZipLib.Zip; -using SIL.FieldWorks.Common.FwUtils; -using SIL.FieldWorks.FDO.Application.ApplicationServices; +using SIL.CoreImpl; using SIL.Utils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; -using XCore; -using SIL.FieldWorks.Resources; namespace SIL.FieldWorks.FDO.DomainServices.BackupRestore { @@ -31,8 +27,10 @@ public class ProjectRestoreService private readonly RestoreProjectSettings m_restoreSettings; private String m_tempBackupFolder; private bool m_fRestoreOverProject; - private readonly IHelpTopicProvider m_helpTopicProvider; private string m_sLinkDirChangedTo; + private readonly IFdoUI m_ui; + private readonly string m_converterConsolePath; + private readonly string m_dbPath; #endregion #region Constructor @@ -41,27 +39,22 @@ public class ProjectRestoreService /// Constructor /// /// The restore settings. - /// + /// The UI service. + /// + /// /// ------------------------------------------------------------------------------------ - public ProjectRestoreService(RestoreProjectSettings settings, IHelpTopicProvider helpTopicProvider) + public ProjectRestoreService(RestoreProjectSettings settings, IFdoUI ui, string converterConsolePath, string dbPath) { m_restoreSettings = settings; - m_helpTopicProvider = helpTopicProvider; + m_ui = ui; + m_converterConsolePath = converterConsolePath; + m_dbPath = dbPath; } - /// ------------------------------------------------------------------------------------ - /// - /// Constructor used in Tests where we do not need to have a helpTopicProvider. - /// - /// The restore settings. - /// ------------------------------------------------------------------------------------ - public ProjectRestoreService(RestoreProjectSettings settings) - { - m_restoreSettings = settings; - } #endregion #region Public methods + /// ------------------------------------------------------------------------------------ /// /// Perform a restore of the project specified in the settings. @@ -96,30 +89,25 @@ public void RestoreProject(IThreadedProgress progressDlg) try { - //Import from FW version 6.0 based on the file extension. - var extension = Path.GetExtension(fileSettings.File).ToLowerInvariant(); - if (extension == FwFileExtensions.ksFw60BackupFileExtension || extension == ".xml") - ImportFrom6_0Backup(fileSettings, progressDlg); - else //Restore from FW version 7.0 and newer backup. - RestoreFrom7_0AndNewerBackup(fileSettings); + //Import from FW version 6.0 based on the file extension. + var extension = Path.GetExtension(fileSettings.File).ToLowerInvariant(); + if (extension == FdoFileHelper.ksFw60BackupFileExtension || extension == ".xml") + ImportFrom6_0Backup(fileSettings, progressDlg); + else //Restore from FW version 7.0 and newer backup. + RestoreFrom7_0AndNewerBackup(fileSettings); } - catch(Exception error) + catch (Exception error) { if (error is IOException || error is InvalidBackupFileException || error is UnauthorizedAccessException) { CleanupAfterRestore(false); - // ENHANCE: If/when we have the restore process using a progress dialog so that this code - // runs in the progress dialog thread instead of the main thread, all message boxes should - // be replaced with the ThreadHelper.ShowMessageBox() method so that they will be thread-safe. - MessageBoxUtils.Show(null, error.Message, AppStrings.ksRestoreDidNotSucceed, - MessageBoxButtons.OK, MessageBoxIcon.Information); } throw; } // switch to the desired backend (if it's in the projects directory...anything else stays XML for now). - if (DirectoryFinder.IsSubFolderOfProjectsDirectory(m_restoreSettings.ProjectPath) && !suppressConversion) + if (Path.GetDirectoryName(m_restoreSettings.ProjectPath) == m_restoreSettings.ProjectsRootFolder && !suppressConversion) ClientServerServices.Current.Local.ConvertToDb4oBackendIfNeeded(progressDlg, m_restoreSettings.FullProjectPath); CleanupAfterRestore(true); @@ -127,27 +115,42 @@ public void RestoreProject(IThreadedProgress progressDlg) private void ImportFrom6_0Backup(BackupFileSettings fileSettings, IThreadedProgress progressDlg) { - ImportFrom6_0 importer = new ImportFrom6_0(progressDlg); - string projFile; - if (!importer.Import(fileSettings.File, m_restoreSettings.ProjectName, out projFile)) + var importer = new ImportFrom6_0(progressDlg, m_converterConsolePath, m_dbPath); + bool importSuccessful; + try { - ExceptionHelper.LogAndIgnoreErrors(() => CleanupFrom6_0FailedRestore(importer)); - ExceptionHelper.LogAndIgnoreErrors(() => CleanupAfterRestore(false)); + string projFile; + importSuccessful = importer.Import(fileSettings.File, m_restoreSettings.ProjectName, m_restoreSettings.ProjectsRootFolder, out projFile); + } + catch (CannotConvertException e) + { + FailedImportCleanUp(importer); + throw; + } + if (!importSuccessful) + { + FailedImportCleanUp(importer); + if (!importer.HaveOldFieldWorks || !importer.HaveFwSqlServer) { throw new MissingOldFwException("Error restoring from FieldWorks 6.0 (or earlier) backup", importer.HaveFwSqlServer, importer.HaveOldFieldWorks); } - MessageBoxUtils.Show(Strings.ksRestoringOldFwBackupFailed, Strings.ksFailed); throw new FailedFwRestoreException("Error restoring from FieldWorks 6.0 (or earlier) backup"); } } + private void FailedImportCleanUp(ImportFrom6_0 importer) + { + ExceptionHelper.LogAndIgnoreErrors(() => CleanupFrom6_0FailedRestore(importer)); + ExceptionHelper.LogAndIgnoreErrors(() => CleanupAfterRestore(false)); + } + private void RestoreFrom7_0AndNewerBackup(BackupFileSettings fileSettings) { // Get rid of any saved settings, since they may not be consistent with something about the data // or settings we are restoring. (This extension is also known to RecordView.GetClerkPersistPathname()). - var tempDirectory = Path.Combine(m_restoreSettings.ProjectPath, DirectoryFinder.ksSortSequenceTempDir); + var tempDirectory = Path.Combine(m_restoreSettings.ProjectPath, FdoFileHelper.ksSortSequenceTempDir); if (Directory.Exists(tempDirectory)) { foreach (var sortSeqFile in Directory.GetFiles(tempDirectory, "*.fwss")) @@ -157,19 +160,19 @@ private void RestoreFrom7_0AndNewerBackup(BackupFileSettings fileSettings) UncompressDataFiles(); // We can't use Path.Combine here, because the zip files stores all file paths with '/'s - UncompressFilesMatchingPath(DirectoryFinder.ksWritingSystemsDir + "/", m_restoreSettings.WritingSystemStorePath); + UncompressFilesMatchingPath(FdoFileHelper.ksWritingSystemsDir + "/", m_restoreSettings.WritingSystemStorePath); if (m_restoreSettings.IncludeSupportingFiles) { Debug.Assert(fileSettings.IncludeSupportingFiles, "The option to include supporting files should not be allowed if they aren't available in the backup settings"); - var zipEntryStartsWith = DirectoryFinder.ksSupportingFilesDir; - UncompressFilesContainedInFolderandSubFolders(DirectoryFinder.GetZipfileFormattedPath(zipEntryStartsWith), + var zipEntryStartsWith = FdoFileHelper.ksSupportingFilesDir; + UncompressFilesContainedInFolderandSubFolders(FdoFileHelper.GetZipfileFormattedPath(zipEntryStartsWith), m_restoreSettings.ProjectSupportingFilesPath); } if (m_restoreSettings.IncludeConfigurationSettings) - UncompressFilesMatchingPath(DirectoryFinder.ksConfigurationSettingsDir + "/", m_restoreSettings.FlexConfigurationSettingsPath); + UncompressFilesMatchingPath(FdoFileHelper.ksConfigurationSettingsDir + "/", m_restoreSettings.FlexConfigurationSettingsPath); if (m_restoreSettings.IncludeLinkedFiles) RestoreLinkedFiles(fileSettings); @@ -202,7 +205,7 @@ private void CleanupFrom6_0FailedRestore(ImportFrom6_0 importer) var fileName = Path.GetFileName(entry.Name); if (!String.IsNullOrEmpty(fileName)) { - string filePath = Path.Combine(DirectoryFinder.ProjectsDirectory, fileName); + string filePath = Path.Combine(m_restoreSettings.ProjectsRootFolder, fileName); if (FileUtils.TrySimilarFileExists(filePath, out filePath)) FileUtils.Delete(filePath); } @@ -245,44 +248,6 @@ private void CleanupAfterRestore(bool succeeded) #endregion - /// ------------------------------------------------------------------------------------ - /// - /// Performs the requested actions and handles any IO or zip error by reporting them to - /// the user. (Intended for operations that deal directly with a backup zip file. - /// - /// The parent window to use when reporting an error (can be - /// null). - /// Used in title bar of message box when reporting an error - /// (typically the name of the application). - /// - /// The backup zip filename. - /// The action to perform. - /// - /// true if successful (no exception caught); false otherwise - /// - /// ------------------------------------------------------------------------------------ - public static bool HandleRestoreFileErrors(IWin32Window parentWindow, string caption, - string zipFilename, Action action) - { - try - { - action(); - } - catch (Exception error) - { - if (error is IOException || error is InvalidBackupFileException || - error is UnauthorizedAccessException) - { - Logger.WriteError(error); - MessageBoxUtils.Show(parentWindow, error.Message, caption, - MessageBoxButtons.OK, MessageBoxIcon.Information); - return false; - } - throw; - } - return true; - } - #region Private methods /// ------------------------------------------------------------------------------------ /// @@ -310,7 +275,7 @@ private void UncompressDataFiles() while ((entry = zipIn.GetNextEntry()) != null) { var fileName = Path.GetFileName(entry.Name); - if (fileName == DirectoryFinder.GetXmlDataFileName(m_restoreSettings.Backup.ProjectName)) + if (fileName == FdoFileHelper.GetXmlDataFileName(m_restoreSettings.Backup.ProjectName)) UnzipFileToRestoreFolder(zipIn, m_restoreSettings.DbFilename, entry.Size, m_restoreSettings.ProjectPath, entry.DateTime); if (fileName == m_restoreSettings.QuestionNotesFilename) @@ -318,7 +283,7 @@ private void UncompressDataFiles() m_restoreSettings.ProjectPath, entry.DateTime); } string bakFile = Path.Combine(m_restoreSettings.ProjectPath, m_restoreSettings.ProjectName) - + FwFileExtensions.ksFwDataFallbackFileExtension; + + FdoFileHelper.ksFwDataFallbackFileExtension; if (FileUtils.TrySimilarFileExists(bakFile, out bakFile)) { FileUtils.Delete(bakFile); // TODO: do something about the .Lock file....... @@ -332,22 +297,22 @@ private void RestoreLinkedFiles(BackupFileSettings fileSettings) "The option to include linked files should not be allowed if they aren't available in the backup settings"); var proposedDestinationLinkedFilesPath = - DirectoryFinderRelativePaths.GetLinkedFilesFullPathFromRelativePath( + LinkedFilesRelativePathHelper.GetLinkedFilesFullPathFromRelativePath(m_restoreSettings.ProjectsRootFolder, fileSettings.LinkedFilesPathRelativePersisted, m_restoreSettings.ProjectPath); var linkedFilesPathInZip = fileSettings.LinkedFilesPathActualPersisted; - if (fileSettings.LinkedFilesPathRelativePersisted.StartsWith(DirectoryFinderRelativePaths.ksProjectRelPath)) + if (fileSettings.LinkedFilesPathRelativePersisted.StartsWith(LinkedFilesRelativePathHelper.ksProjectRelPath)) { // We store any files inside the project folder as a relative path from the project's directory. // Make sure we don't attempt to search for the whole directory structure in the zip file. (FWR-2909) linkedFilesPathInZip = fileSettings.LinkedFilesPathRelativePersisted.Substring( - DirectoryFinderRelativePaths.ksProjectRelPath.Length + 1); + LinkedFilesRelativePathHelper.ksProjectRelPath.Length + 1); } var filesContainedInLinkdFilesFolder = GetAllFilesUnderFolderInZipFileAndDateTimes(linkedFilesPathInZip); //If the proposed location is not in the default location under the project, then ask the user if they want //to restore the files to the default location instead. Otherwise just go ahead and restore the files. - var defaultLinkedFilesPath = DirectoryFinder.GetDefaultLinkedFilesDir(m_restoreSettings.ProjectPath); + var defaultLinkedFilesPath = FdoFileHelper.GetDefaultLinkedFilesDir(m_restoreSettings.ProjectPath); if (proposedDestinationLinkedFilesPath.Equals(defaultLinkedFilesPath)) { if (!Directory.Exists(defaultLinkedFilesPath)) @@ -370,11 +335,7 @@ private void RestoreLinkedFiles(BackupFileSettings fileSettings) /// Protected so we can subclass in tests. protected virtual bool CanRestoreLinkedFilesToProjectsFolder() { - using (var dlg = new RestoreLinkedFilesToProjectsFolder(m_helpTopicProvider)) - { - // Let a Cancel result mean "Keep my old non-standard location" - return dlg.ShowDialog() == DialogResult.OK && dlg.fRestoreLinkedFilesToProjectFolder; - } + return m_ui.RestoreLinkedFilesInProjectFolder(); } /// @@ -390,7 +351,7 @@ protected void RestoreLinkedFiles(bool fPutFilesInProject, Dictionary protected virtual void CouldNotRestoreLinkedFilesToOriginalLocation(string linkedFilesPathPersisted, Dictionary filesContainedInLinkdFilesFolder) { - using (var dlgCantWriteFiles = new CantRestoreLinkedFilesToOriginalLocation(m_helpTopicProvider)) + YesNoCancel userSelection = m_ui.CannotRestoreLinkedFilesToOriginalLocation(); + if (userSelection == YesNoCancel.OkYes) { - if (dlgCantWriteFiles.ShowDialog() == DialogResult.OK) - { - if (dlgCantWriteFiles.fRestoreLinkedFilesToProjectFolder) - { - m_sLinkDirChangedTo = DirectoryFinder.GetDefaultLinkedFilesDir(m_restoreSettings.ProjectPath); - //Restore the files to the project folder. - UncompressLinkedFiles(filesContainedInLinkdFilesFolder, m_sLinkDirChangedTo, linkedFilesPathPersisted); - } - if (dlgCantWriteFiles.fDoNotRestoreLinkedFiles) - { - //Do nothing. Do not restore any LinkedFiles. - } - } + m_sLinkDirChangedTo = FdoFileHelper.GetDefaultLinkedFilesDir(m_restoreSettings.ProjectPath); + //Restore the files to the project folder. + UncompressLinkedFiles(filesContainedInLinkdFilesFolder, m_sLinkDirChangedTo, linkedFilesPathPersisted); + } + else if (userSelection == YesNoCancel.OkNo) + { + //Do nothing. Do not restore any LinkedFiles. } } private Dictionary GetAllFilesUnderFolderInZipFileAndDateTimes(string dir) { var filesAndDateTime = new Dictionary(); - var dirZipFileFormat = DirectoryFinder.GetZipfileFormattedPath(dir); + var dirZipFileFormat = FdoFileHelper.GetZipfileFormattedPath(dir); using (var zipIn = OpenFWBackupZipfile()) { ZipEntry entry; @@ -586,14 +537,14 @@ private void UncompressLinkedFiles(Dictionary fileList, String Debug.Assert(!String.IsNullOrEmpty(fileName)); //Contruct the path where the file will be unzipped too. - var zipFileLinkFilesPath = DirectoryFinder.GetZipfileFormattedPath(linkedFilesPathPersisted); + var zipFileLinkFilesPath = FdoFileHelper.GetZipfileFormattedPath(linkedFilesPathPersisted); var filenameWithSubFolders = entry.Name.Substring(zipFileLinkFilesPath.Length); String pathForFileSubFolders = ""; if (!fileName.Equals(filenameWithSubFolders)) //if they are equal the file is in the root of LinkedFiles { pathForFileSubFolders = GetPathForSubFolders(filenameWithSubFolders, fileName.Length); } - var destFolderZipFileFormat = DirectoryFinder.GetZipfileFormattedPath(destinationLinkedFilesPath); + var destFolderZipFileFormat = FdoFileHelper.GetZipfileFormattedPath(destinationLinkedFilesPath); var pathRoot = Path.GetPathRoot(destinationLinkedFilesPath); Debug.Assert(!String.IsNullOrEmpty(pathRoot)); var pathforfileunzip = Path.Combine(pathRoot, destFolderZipFileFormat, pathForFileSubFolders); @@ -697,7 +648,7 @@ private void UnzipFileToRestoreFolder(ZipInputStream zipIn, string fileName, { Debug.WriteLine("Failed to create directory {0}; {1}", dir, e.Message); var msg = string.Format(Strings.ksCannotRestoreLinkedFilesToDir, dir); - MessageBoxUtils.Show(msg, Strings.ksCannotRestore); + m_ui.DisplayMessage(MessageType.Warning, msg, Strings.ksCannotRestore, null); return; } if (FileUtils.TrySimilarFileExists(newFileName, out newFileName)) @@ -737,7 +688,7 @@ private void UnzipFileToRestoreFolder(ZipInputStream zipIn, string fileName, { Debug.WriteLine("Failed to restore file {0}; {1}", newFileName, e.Message); var msg = string.Format(Strings.ksCannotRestoreBackup, newFileName); - MessageBoxUtils.Show(msg, Strings.ksCannotRestore); + m_ui.DisplayMessage(MessageType.Warning, msg, Strings.ksCannotRestore, null); return; } } diff --git a/Src/FDO/DomainServices/BackupRestore/RestoreProjectSettings.cs b/Src/FDO/DomainServices/BackupRestore/RestoreProjectSettings.cs index f7078bc2b7..66455f8be6 100644 --- a/Src/FDO/DomainServices/BackupRestore/RestoreProjectSettings.cs +++ b/Src/FDO/DomainServices/BackupRestore/RestoreProjectSettings.cs @@ -8,7 +8,6 @@ using System; using System.IO; using System.Linq; -using SIL.FieldWorks.Common.FwUtils; using System.Text; using SIL.Utils; @@ -32,7 +31,7 @@ public class RestoreProjectSettings : BackupSettings /// Initializes a new instance of the class. /// /// ------------------------------------------------------------------------------------ - public RestoreProjectSettings() : base (DirectoryFinder.ProjectsDirectory, null, null) + public RestoreProjectSettings(string projectsRootFolder) : base (projectsRootFolder, null, null) { } @@ -42,12 +41,13 @@ public RestoreProjectSettings() : base (DirectoryFinder.ProjectsDirectory, null, /// a list of command-line options as created from the /// property. /// - /// The command line options. - /// Name of the backup zip file. + /// /// Name of the project. + /// Name of the backup zip file. + /// The command line options. /// ------------------------------------------------------------------------------------ - public RestoreProjectSettings(string projectName, string backupZipFileName, - string commandLineOptions) : this() + public RestoreProjectSettings(string projectsRootFolder, string projectName, string backupZipFileName, + string commandLineOptions) : this(projectsRootFolder) { if (string.IsNullOrEmpty(projectName)) throw new ArgumentNullException("projectName"); @@ -149,7 +149,7 @@ public bool UsingSendReceive { get { - var otherRepoPath = Path.Combine(ProjectPath, FLExBridgeHelper.OtherRepositories); + var otherRepoPath = Path.Combine(ProjectPath, FdoFileHelper.OtherRepositories); return Directory.Exists(Path.Combine(ProjectPath, ".hg")) || (Directory.Exists(otherRepoPath) && Directory.EnumerateDirectories(otherRepoPath).Any(dir => Directory.Exists(Path.Combine(dir, ".hg")))); diff --git a/Src/FDO/DomainServices/BaseStyleInfo.cs b/Src/FDO/DomainServices/BaseStyleInfo.cs index 5d303c8eaf..2fe5239ba2 100644 --- a/Src/FDO/DomainServices/BaseStyleInfo.cs +++ b/Src/FDO/DomainServices/BaseStyleInfo.cs @@ -39,7 +39,7 @@ public class InheritableStyleProp : IStyleProp #region Constructors /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the + /// Initializes a new instance of the /// class for an inherited property (value not set). /// /// ------------------------------------------------------------------------------------ @@ -66,7 +66,7 @@ public InheritableStyleProp(InheritableStyleProp copyFrom) /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the + /// Initializes a new instance of the /// class for a non-inherited (explicit) property. /// /// The (explict) value of the property. @@ -392,7 +392,7 @@ public struct BorderThicknesses /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The thickness of leading border in millipoints /// The thickness of trailing border in millipoints @@ -458,7 +458,7 @@ public struct LineHeightInfo /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The line spacing. /// if set to true line spacing will be @@ -496,7 +496,7 @@ public class IntPropInfo /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// ------------------------------------------------------------------------------------ public IntPropInfo() @@ -505,7 +505,7 @@ public IntPropInfo() /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// ------------------------------------------------------------------------------------ public IntPropInfo(int textPropType, int value) @@ -515,7 +515,7 @@ public IntPropInfo(int textPropType, int value) /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// ------------------------------------------------------------------------------------ public IntPropInfo(int textPropType, int value, int variant) @@ -670,7 +670,7 @@ public class BaseStyleInfo : IStyle #region Constructors /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// ------------------------------------------------------------------------------------ public BaseStyleInfo() @@ -681,7 +681,7 @@ public BaseStyleInfo() /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class from a copy. + /// Initializes a new instance of the class from a copy. /// This constructor is used to make a new copy of a style with a different name. /// /// The copy from. @@ -747,7 +747,7 @@ public BaseStyleInfo(BaseStyleInfo copyFrom, string newName) /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class based on a FW + /// Initializes a new instance of the class based on a FW /// style. It will load style overrides for forceStyleInfo even if it is not in any /// current list. /// @@ -763,7 +763,7 @@ public BaseStyleInfo(IStStyle style, IWritingSystem forceStyleInfo) /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class based on a FW + /// Initializes a new instance of the class based on a FW /// style. /// /// ------------------------------------------------------------------------------------ @@ -785,7 +785,7 @@ public BaseStyleInfo(IStStyle style, ITsTextProps props) /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The cache. /// This constructor is used to create a new style. diff --git a/Src/FDO/DomainServices/BootstrapNewLanguageProject.cs b/Src/FDO/DomainServices/BootstrapNewLanguageProject.cs index 4ebff7aead..4fd2a4454a 100644 --- a/Src/FDO/DomainServices/BootstrapNewLanguageProject.cs +++ b/Src/FDO/DomainServices/BootstrapNewLanguageProject.cs @@ -1,16 +1,10 @@ using System; -using System.Collections.Generic; using System.Diagnostics; -using System.IO; -using System.Net; -using System.Text; -using System.Windows.Forms; using Microsoft.Practices.ServiceLocation; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.FDO.DomainImpl; using SIL.FieldWorks.FDO.Infrastructure; using SIL.CoreImpl; -using SIL.FieldWorks.FDO.Infrastructure.Impl; namespace SIL.FieldWorks.FDO.DomainServices { diff --git a/Src/FDO/DomainServices/ClientServerServices.cs b/Src/FDO/DomainServices/ClientServerServices.cs index 74208c5b9d..e8ff5a5297 100644 --- a/Src/FDO/DomainServices/ClientServerServices.cs +++ b/Src/FDO/DomainServices/ClientServerServices.cs @@ -15,12 +15,9 @@ using System.Net.NetworkInformation; using System.Net.Sockets; using System.Text; -using System.Windows.Forms; using FwRemoteDatabaseConnector; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.Infrastructure; using SIL.FieldWorks.FDO.Infrastructure.Impl; -using SIL.FieldWorks.Resources; using SIL.Utils; namespace SIL.FieldWorks.FDO.DomainServices @@ -42,27 +39,18 @@ public static class ClientServerServices /// ------------------------------------------------------------------------------------ public static IClientServerServices Current { get; internal set; } - /// ------------------------------------------------------------------------------------ - /// - /// Initializes the class. - /// - /// ------------------------------------------------------------------------------------ - static ClientServerServices() - { - SetCurrentToDefaultBackend(); - } - /// ------------------------------------------------------------------------------------ /// /// This is the implementation for the static constructor. It is in a separate method /// to allow tests to reset it (using reflection). /// /// ------------------------------------------------------------------------------------ - private static void SetCurrentToDefaultBackend() + public static void SetCurrentToDb4OBackend(IFdoUI ui, IFdoDirectories dirs, + Func usingDefaultProjectsDirAccessor) { // This is the "one line" that should need to be changed to configure a different backend :-). // Typically a new implementation of IClientServerServices will be needed, as well as the backend itself. - Current = new Db4OClientServerServices(); + Current = new Db4OClientServerServices(ui, dirs, usingDefaultProjectsDirAccessor); } /// ------------------------------------------------------------------------------------ @@ -74,8 +62,8 @@ public static string GetExtension(this FDOBackendProviderType type) { switch (type) { - case FDOBackendProviderType.kDb4oClientServer: return FwFileExtensions.ksFwDataDb4oFileExtension; - case FDOBackendProviderType.kXML: return FwFileExtensions.ksFwDataXmlFileExtension; + case FDOBackendProviderType.kDb4oClientServer: return FdoFileHelper.ksFwDataDb4oFileExtension; + case FDOBackendProviderType.kXML: return FdoFileHelper.ksFwDataXmlFileExtension; default: throw new InvalidEnumArgumentException("type", (int)type, typeof(FDOBackendProviderType)); } } @@ -162,22 +150,10 @@ void BeginFindProjects(string host, Action foundProject, IDisposable GetExclusiveModeToken(FdoCache cache, string id); /// - /// Display a warning indicating that it may be dangerous to change things that the user has just - /// asked to change when other users are connected. The warning should only be shown if, in fact, - /// other users are currently connected. The dialog may contain some information about the other - /// users that are connected. Return true to continue, false to discard the changes. This is typically - /// called in response to clicking an OK button in a dialog which changes dangerous user settings. - /// - /// - bool WarnOnConfirmingSingleUserChanges(FdoCache cache); - /// - /// Display a warning indicating that it may be dangerous to change things in the dialog that - /// is about to open when other users are connected. The warning should only be shown if, in fact, - /// other users are currently connected. The dialog may contain some information about the other - /// users that are connected. Return true to continue, false to cancel opening the dialog. + /// Returns the number of other users currently connected /// - /// - bool WarnOnOpeningSingleUserDialog(FdoCache cache); + /// The FDO cache. + int CountOfOtherUsersConnected(FdoCache cache); } #endregion @@ -294,15 +270,17 @@ internal class Db4OClientServerServices : IClientServerServices private const char ksServerHostSeperatorChar = ':'; private Db4OServerFinder m_serverFinder; private FwProjectFinder m_projectFinder; + private readonly IFdoDirectories m_dirs; /// ------------------------------------------------------------------------------------ /// /// Initializes a new instance of the class. /// /// ------------------------------------------------------------------------------------ - internal Db4OClientServerServices() + internal Db4OClientServerServices(IFdoUI ui, IFdoDirectories dirs, Func usingDefaultProjectsDirAccessor) { - Local = new Db4OLocalClientServerServices(); + m_dirs = dirs; + Local = new Db4OLocalClientServerServices(ui, dirs, usingDefaultProjectsDirAccessor); } /// ------------------------------------------------------------------------------------ @@ -316,9 +294,9 @@ internal Db4OClientServerServices() /// ------------------------------------------------------------------------------------ public void BeginFindServers(Action foundServer) { - if (m_serverFinder != null) + if (m_serverFinder != null && !m_serverFinder.IsCompleted) throw new InvalidOperationException("Can not start a new find servers before the previous one finishes."); - m_serverFinder = new Db4OServerFinder(foundServer, () => m_serverFinder = null); + m_serverFinder = new Db4OServerFinder(foundServer); } /// ------------------------------------------------------------------------------------ @@ -354,7 +332,7 @@ public void BeginFindProjects(string host, Action foundProject, if (m_projectFinder != null) throw new InvalidOperationException("Can not start a new find projects before the previous one finishes."); m_projectFinder = new FwProjectFinder(host, foundProject, () => m_projectFinder = null, - exceptionCallback, showLocalProjects); + exceptionCallback, showLocalProjects, m_dirs.ProjectsDirectory); } /// ------------------------------------------------------------------------------------ @@ -468,7 +446,12 @@ public IDisposable GetExclusiveModeToken(FdoCache cache, string id) return null; } - int CountOfOtherUsersConnected(FdoCache cache) + /// + /// Returns the number of other users currently connected + /// + /// The FDO cache. + /// The number of other users currently connected + public int CountOfOtherUsersConnected(FdoCache cache) { if (cache == null) // Can happen when creating a new project when editing the WS properties. (FWR-2981) return 0; @@ -482,41 +465,6 @@ int CountOfOtherUsersConnected(FdoCache cache) return otherUsers.Length - 1; // Assume this is connected! } - /// - /// Display a warning indicating that it may be dangerous to change things that the user has just - /// asked to change when other users are connected. The warning should only be shown if, in fact, - /// other users are currently connected. The dialog may contain some information about the other - /// users that are connected. Return true to continue, false to discard the changes. This is typically - /// called in response to clicking an OK button in a dialog which changes dangerous user settings. - /// - /// - public bool WarnOnConfirmingSingleUserChanges(FdoCache cache) - { - var others = CountOfOtherUsersConnected(cache); - if (others == 0) - return true; - var msg = string.Format(Strings.ksWarnOnConfirmingSingleUserChanges.Replace("\\n", Environment.NewLine), others); - return ThreadHelper.ShowMessageBox(null, msg, Strings.ksNotAdvisableOthersConnectedCaption, - MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes; - } - - /// - /// Display a warning indicating that it may be dangerous to change things in the dialog that - /// is about to open when other users are connected. The warning should only be shown if, in fact, - /// other users are currently connected. The dialog may contain some information about the other - /// users that are connected. Return true to continue, false to cancel opening the dialog. - /// - /// - public bool WarnOnOpeningSingleUserDialog(FdoCache cache) - { - var others = CountOfOtherUsersConnected(cache); - if (others == 0) - return true; - var msg = string.Format(Strings.ksWarnOnOpeningSingleUserDialog.Replace("\\n", Environment.NewLine), others); - return ThreadHelper.ShowMessageBox(null, msg, Strings.ksOthersConnectedCaption, - MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK; - } - #region TrivialDisposable class private sealed class TrivialDisposable: IDisposable { @@ -571,6 +519,16 @@ internal class Db4OLocalClientServerServices : ILocalClientServerServices { internal const string kLocalService = "localhost"; internal const string ksDoNotShareProjectTxt = "do_not_share_project.txt"; + private readonly Func m_usingDefaultProjectsDirAccessor; + private readonly IFdoUI m_ui; + private readonly IFdoDirectories m_dirs; + + public Db4OLocalClientServerServices(IFdoUI ui, IFdoDirectories dirs, Func usingDefaultProjectsDirAccessor) + { + m_ui = ui; + m_dirs = dirs; + m_usingDefaultProjectsDirAccessor = usingDefaultProjectsDirAccessor; + } /// ------------------------------------------------------------------------------------ /// @@ -592,7 +550,7 @@ public bool ShareMyProjects // their personal projects directory. I'm not sure whether such a user will even see that the // first user has turned on sharing. But in any case, the second user (who did not turn sharing on, // and has their own projects folder) will just go on seeing their own unshared projects. - && DirectoryFinder.ProjectsDirectory == DirectoryFinder.ProjectsDirectoryLocalMachine; + && m_usingDefaultProjectsDirAccessor(); } catch (SocketException) { @@ -622,10 +580,9 @@ public bool SetProjectSharing(bool fShare, IThreadedProgress progress) { } } - while ((serverInfo == null && ThreadHelper.ShowMessageBox(progress.Form, - string.Format(Strings.ksLocalConnectorServiceNotStarted, "FwRemoteDatabaseConnectorService"), - fShare ? Strings.ksConvertingToShared : Strings.ksConvertingToNonShared, - MessageBoxButtons.RetryCancel, MessageBoxIcon.None) == DialogResult.Retry)); + while (serverInfo == null && + m_ui.Retry(string.Format(Strings.ksLocalConnectorServiceNotStarted, "FwRemoteDatabaseConnectorService"), + fShare ? Strings.ksConvertingToShared : Strings.ksConvertingToNonShared)); if (serverInfo == null || serverInfo.AreProjectShared() == fShare) return false; @@ -679,7 +636,7 @@ public bool WillProjectBeConverted(string projectPath, string parentDirectory, s /// /// false if clients are still connected. /// ------------------------------------------------------------------------------------ - private static bool EnsureNoClientsAreConnected() + private bool EnsureNoClientsAreConnected() { var localService = LocalDb4OServerInfoConnection; if (localService == null) @@ -694,8 +651,8 @@ private static bool EnsureNoClientsAreConnected() connectedClientsMsg.AppendFormat("{2}{0} : {1}", client, Dns.GetHostEntry(client).HostName, Environment.NewLine); } - if (MessageBoxUtils.Show(String.Format(Strings.ksAllProjectsMustDisconnectClients, connectedClientsMsg), - Strings.ksAllProjectsMustDisconnectCaption, MessageBoxButtons.RetryCancel) == DialogResult.Cancel) + if (!m_ui.Retry(String.Format(Strings.ksAllProjectsMustDisconnectClients, connectedClientsMsg), + Strings.ksAllProjectsMustDisconnectCaption)) return false; connectedClients = localService.ListConnectedClients(); @@ -712,11 +669,10 @@ private static bool EnsureNoClientsAreConnected() /// TODO: prevent new connections while in this shutdown phase. /// TODO: as an enhancement connected clients could be messaged and asked to disconnect. /// - /// The message box owner. /// project name. /// false if clients are still connected. /// ------------------------------------------------------------------------------------ - private static bool EnsureNoClientsAreConnected(Form messageBoxOwner, string projectName) + private bool EnsureNoClientsAreConnected(string projectName) { Db4oServerInfo localService = LocalDb4OServerInfoConnection; if (localService == null) @@ -728,7 +684,7 @@ private static bool EnsureNoClientsAreConnected(Form messageBoxOwner, string pro foreach (string client in connectedClients) connectedClientsMsg.AppendFormat("{2}{0} : {1}", client, Dns.GetHostEntry(client).HostName, Environment.NewLine); - if (WarnOfOtherConnectedClients(messageBoxOwner, projectName, connectedClientsMsg.ToString()) == DialogResult.Cancel) + if (!WarnOfOtherConnectedClients(projectName, connectedClientsMsg.ToString())) return false; connectedClients = localService.ListConnectedClients(projectName); @@ -741,18 +697,16 @@ private static bool EnsureNoClientsAreConnected(Form messageBoxOwner, string pro /// /// Warns the of other connected clients. /// - /// The message box owner. /// Name of the project. /// The message to show about the connected clients. /// /// ------------------------------------------------------------------------------------ - private static DialogResult WarnOfOtherConnectedClients(Form messageBoxOwner, - string projectName, string connectedClientsMsg) + private bool WarnOfOtherConnectedClients(string projectName, string connectedClientsMsg) { var msg = String.Format(Strings.ksMustDisconnectClients, projectName, connectedClientsMsg); var caption = String.Format(Strings.ksMustDisconnectCaption, projectName); - return ThreadHelper.ShowMessageBox(messageBoxOwner, msg, caption, - MessageBoxButtons.RetryCancel, MessageBoxIcon.None); + + return m_ui.Retry(msg, caption); } /// ------------------------------------------------------------------------------------ @@ -769,19 +723,17 @@ private bool ConvertAllProjectsToXml(IThreadedProgress progressDlg) progressDlg.Title = Strings.ksConvertingToNonShared; progressDlg.AllowCancel = false; - progressDlg.ProgressBarStyle = ProgressBarStyle.Continuous; - progressDlg.Maximum = Directory.GetDirectories(DirectoryFinder.ProjectsDirectory).Count(); + progressDlg.Maximum = Directory.GetDirectories(m_dirs.ProjectsDirectory).Count(); progressDlg.RunTask(true, ConvertAllProjectsToXmlTask); - return true; } private object ConvertAllProjectsToXmlTask(IThreadedProgress progress, object[] args) { - foreach (var projectFolder in Directory.GetDirectories(DirectoryFinder.ProjectsDirectory)) + foreach (string projectFolder in Directory.GetDirectories(m_dirs.ProjectsDirectory)) { var projectName = Path.GetFileName(projectFolder); - var projectPath = Path.Combine(projectFolder, DirectoryFinder.GetDb4oDataFileName(projectName)); + var projectPath = Path.Combine(projectFolder, FdoFileHelper.GetDb4oDataFileName(projectName)); progress.Message = Path.GetFileNameWithoutExtension(projectPath); if (File.Exists(projectPath)) { @@ -790,8 +742,9 @@ private object ConvertAllProjectsToXmlTask(IThreadedProgress progress, object[] // The zero in the object array is for db4o and causes it not to open a port. // This is fine since we aren't yet trying to start up on this restored database. // The null says we are creating the file on the local host. - using (var tempCache = FdoCache.CreateCacheFromExistingData( - new SimpleProjectId(FDOBackendProviderType.kDb4oClientServer, projectPath), "en", progress)) + using (FdoCache tempCache = FdoCache.CreateCacheFromExistingData( + new SimpleProjectId(FDOBackendProviderType.kDb4oClientServer, projectPath), "en", new SilentFdoUI(progress.SynchronizeInvoke), + m_dirs, progress)) { CopyToXmlFile(tempCache, tempCache.ProjectId.ProjectFolder); // Enhance JohnT: how can we tell this succeeded? @@ -800,7 +753,7 @@ private object ConvertAllProjectsToXmlTask(IThreadedProgress progress, object[] } catch (Exception e) { - ReportConversionError(progress.Form, projectPath, e); + ReportConversionError(projectPath, e); } } progress.Step(1); @@ -818,8 +771,7 @@ private bool ConvertAllProjectsToDb4o(IThreadedProgress progressDlg) { progressDlg.Title = Strings.ksConvertingToShared; progressDlg.AllowCancel = false; - progressDlg.ProgressBarStyle = ProgressBarStyle.Continuous; - progressDlg.Maximum = Directory.GetDirectories(DirectoryFinder.ProjectsDirectory).Count(); + progressDlg.Maximum = Directory.GetDirectories(m_dirs.ProjectsDirectory).Count(); return (bool)progressDlg.RunTask(true, ConvertAllProjectsToDb4o); } @@ -828,10 +780,10 @@ private object ConvertAllProjectsToDb4o(IThreadedProgress progress, object[] arg for (; ; ) { string projects = ""; - foreach (var projectFolder in Directory.GetDirectories(DirectoryFinder.ProjectsDirectory)) + foreach (string projectFolder in Directory.GetDirectories(m_dirs.ProjectsDirectory)) { var projectName = Path.GetFileName(projectFolder); - var projectPath = Path.Combine(projectFolder, DirectoryFinder.GetXmlDataFileName(projectName)); + var projectPath = Path.Combine(projectFolder, FdoFileHelper.GetXmlDataFileName(projectName)); var suppressPath = Path.Combine(projectFolder, ksDoNotShareProjectTxt); if (!File.Exists(projectPath) || File.Exists(suppressPath)) continue; // not going to convert, it isn't a problem. @@ -841,37 +793,36 @@ private object ConvertAllProjectsToDb4o(IThreadedProgress progress, object[] arg if (projects.Length == 0) break; projects = projects.Substring(0, projects.Length - ", ".Length); - // ENHANCE (TimS): Showing a message box at this level is not a good idea. - if (ThreadHelper.ShowMessageBox(progress.Form, string.Format(Strings.ksMustCloseProjectsToShare, projects), - Strings.ksConvertingToShared, MessageBoxButtons.RetryCancel, MessageBoxIcon.None) != DialogResult.Retry) + + if (!m_ui.Retry(string.Format(Strings.ksMustCloseProjectsToShare, projects), Strings.ksConvertingToShared)) return false; } - foreach (string projectFolder in Directory.GetDirectories(DirectoryFinder.ProjectsDirectory)) + foreach (string projectFolder in Directory.GetDirectories(m_dirs.ProjectsDirectory)) { string projectName = Path.GetFileName(projectFolder); - string projectPath = Path.Combine(projectFolder, DirectoryFinder.GetXmlDataFileName(projectName)); + string projectPath = Path.Combine(projectFolder, FdoFileHelper.GetXmlDataFileName(projectName)); var suppressPath = Path.Combine(projectFolder, ksDoNotShareProjectTxt); progress.Message = Path.GetFileNameWithoutExtension(projectPath); if (File.Exists(projectPath) && !File.Exists(suppressPath)) { - try - { + try + { ConvertToDb4oBackendIfNeeded(progress, projectPath); - } - catch (Exception e) - { - ReportConversionError(progress.Form, projectPath, e); - } + } + catch (Exception e) + { + ReportConversionError(projectPath, e); + } } progress.Step(1); } return true; } - private static void ReportConversionError(Form messageBoxOwner, string projectPath, Exception e) + private void ReportConversionError(string projectPath, Exception e) { string message; - if (e is FwNewerVersionException) + if (e is FdoNewerVersionException) { message = string.Format(Strings.ksConvertFailedNewerVersion, Path.GetFileName(projectPath), Path.GetDirectoryName(projectPath)); @@ -881,8 +832,7 @@ private static void ReportConversionError(Form messageBoxOwner, string projectPa message = string.Format(Strings.ksConvertFailedDetails, Path.GetFileName(projectPath), Path.GetDirectoryName(projectPath), e.Message); } - ThreadHelper.ShowMessageBox(messageBoxOwner, message, Strings.ksCannotConvert, - MessageBoxButtons.OK, MessageBoxIcon.Error); + m_ui.DisplayMessage(MessageType.Error, message, Strings.ksCannotConvert, null); } /// ------------------------------------------------------------------------------------ @@ -901,28 +851,27 @@ public string ConvertToDb4oBackendIfNeeded(IThreadedProgress progressDlg, string { if (!ShareMyProjects) return xmlFilename; // no conversion needed. - string desiredPath = Path.ChangeExtension(xmlFilename, FwFileExtensions.ksFwDataDb4oFileExtension); - if (!EnsureNoClientsAreConnected(progressDlg.Form, Path.GetFileNameWithoutExtension(desiredPath))) + string desiredPath = Path.ChangeExtension(xmlFilename, FdoFileHelper.ksFwDataDb4oFileExtension); + if (!EnsureNoClientsAreConnected(Path.GetFileNameWithoutExtension(desiredPath))) return null; // fail try { - using (var tempCache = FdoCache.CreateCacheFromExistingData( - new SimpleProjectId(FDOBackendProviderType.kXML, xmlFilename), "en", progressDlg)) - { - - // The zero in the object array is for db4o and causes it not to open a port. - // This is fine since we aren't yet trying to start up on this restored database. - // The null says we are creating the file on the local host. - using (var copyCache = FdoCache.CreateCacheCopy( - new SimpleProjectId(FDOBackendProviderType.kDb4oClientServer, desiredPath), "en", tempCache, progressDlg.ThreadHelper)) + using (FdoCache tempCache = FdoCache.CreateCacheFromExistingData(new SimpleProjectId(FDOBackendProviderType.kXML, xmlFilename), + "en", new SilentFdoUI(progressDlg.SynchronizeInvoke), m_dirs, progressDlg)) { - copyCache.ServiceLocator.GetInstance().Commit(new HashSet(), - new HashSet(), new HashSet()); - // Enhance JohnT: how can we tell this succeeded? + + // The zero in the object array is for db4o and causes it not to open a port. + // This is fine since we aren't yet trying to start up on this restored database. + // The null says we are creating the file on the local host. + using (FdoCache copyCache = FdoCache.CreateCacheCopy(new SimpleProjectId(FDOBackendProviderType.kDb4oClientServer, desiredPath), + "en", new SilentFdoUI(progressDlg.SynchronizeInvoke), m_dirs, tempCache)) + { + copyCache.ServiceLocator.GetInstance().Commit(new HashSet(), new HashSet(), new HashSet()); + // Enhance JohnT: how can we tell this succeeded? + } } } - } catch (Exception) { // If we couldn't convert it, try not to leave a corrupted file around. @@ -951,19 +900,19 @@ public string CopyToXmlFile(FdoCache source, string destDir) if (dataStorer is XMLBackendProvider) return null; // already XML, no new file created. - var newFilePath = Path.Combine(destDir, DirectoryFinder.GetXmlDataFileName(source.ProjectId.Name)); + var newFilePath = Path.Combine(destDir, FdoFileHelper.GetXmlDataFileName(source.ProjectId.Name)); if (File.Exists(newFilePath)) File.Delete(newFilePath); // Can't create a new file with FDO if the file already exists. try { - using (var copyCache = FdoCache.CreateCacheCopy( - new SimpleProjectId(FDOBackendProviderType.kXML, newFilePath), "en", source, source.ThreadHelper)) + using (FdoCache copyCache = FdoCache.CreateCacheCopy(new SimpleProjectId(FDOBackendProviderType.kXML, newFilePath), + "en", new SilentFdoUI(source.ServiceLocator.GetInstance().SynchronizeInvoke), m_dirs, source)) { - copyCache.ServiceLocator.GetInstance().Commit( - new HashSet(), - new HashSet(), - new HashSet()); - // Enhance JohnT: how can we tell this succeeded? + copyCache.ServiceLocator.GetInstance().Commit( + new HashSet(), + new HashSet(), + new HashSet()); + // Enhance JohnT: how can we tell this succeeded? return newFilePath; } } @@ -985,7 +934,7 @@ public string IdForLocalProject(string projectName) // Project Name must not have an extension. Can't use ChangeExtension because // the project name might contain some other period. Debug.Assert(!projectName.EndsWith(".fwdata") && !projectName.EndsWith(".fwdb")); - string projectDirectory = Path.Combine(DirectoryFinder.ProjectsDirectory, projectName); + string projectDirectory = Path.Combine(m_dirs.ProjectsDirectory, projectName); var result = Path.Combine(projectDirectory, projectName + DefaultBackendType.GetExtension()); if (!File.Exists(result)) { diff --git a/Src/FDO/DomainServices/ConstraintFailure.cs b/Src/FDO/DomainServices/ConstraintFailure.cs index 1ab4177343..2803f7a23b 100644 --- a/Src/FDO/DomainServices/ConstraintFailure.cs +++ b/Src/FDO/DomainServices/ConstraintFailure.cs @@ -11,10 +11,7 @@ // // -------------------------------------------------------------------------------------------- -using System.Collections.Generic; using System.Linq; -using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.CoreImpl; namespace SIL.FieldWorks.FDO.DomainServices diff --git a/Src/FDO/DomainServices/DataMigration/DataMigration7000019.cs b/Src/FDO/DomainServices/DataMigration/DataMigration7000019.cs index f135bdcbd1..567191cf9d 100644 --- a/Src/FDO/DomainServices/DataMigration/DataMigration7000019.cs +++ b/Src/FDO/DomainServices/DataMigration/DataMigration7000019.cs @@ -12,7 +12,6 @@ using Palaso.Xml; using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; namespace SIL.FieldWorks.FDO.DomainServices.DataMigration { @@ -124,7 +123,7 @@ public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepositor foreach (DomainObjectDTO dto in domainObjectDtoRepository.AllInstances()) UpdateStringsAndProps(domainObjectDtoRepository, dto, referencedWsIds); - var localStoreFolder = Path.Combine(domainObjectDtoRepository.ProjectFolder, DirectoryFinder.ksWritingSystemsDir); + var localStoreFolder = Path.Combine(domainObjectDtoRepository.ProjectFolder, FdoFileHelper.ksWritingSystemsDir); // If any writing systems that project needs don't already exist as LDML files, // create them, either by copying relevant data from a shipping LDML file, or by @@ -152,7 +151,7 @@ public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepositor // FieldWorks 6 data directory, and this is looking in the FW 7 one. No one has complained // so we decided not to try to fix it for the new implementation of the migration. - //string langDefPath = Path.Combine(DirectoryFinder.GetFWDataSubDirectory("Languages"), + //string langDefPath = Path.Combine(FwDirectoryFinder.GetDataSubDirectory("Languages"), // Path.ChangeExtension(langTag, "xml")); //if (File.Exists(langDefPath)) // FillWritingSystemFromLangDef(XElement.Load(langDefPath), ws); diff --git a/Src/FDO/DomainServices/DataMigration/DataMigration7000024.cs b/Src/FDO/DomainServices/DataMigration/DataMigration7000024.cs index 1ca7ccb420..984f5b9284 100644 --- a/Src/FDO/DomainServices/DataMigration/DataMigration7000024.cs +++ b/Src/FDO/DomainServices/DataMigration/DataMigration7000024.cs @@ -9,13 +9,10 @@ // using System; -using System.Collections; using System.Collections.Generic; -using System.Windows.Forms; using System.Xml.Linq; using System.Linq; using System.Xml.XPath; -using SIL.FieldWorks.FDO.DomainImpl; namespace SIL.FieldWorks.FDO.DomainServices.DataMigration { diff --git a/Src/FDO/DomainServices/DataMigration/DataMigration7000026.cs b/Src/FDO/DomainServices/DataMigration/DataMigration7000026.cs index b70d3ddb6e..0cb797b47e 100644 --- a/Src/FDO/DomainServices/DataMigration/DataMigration7000026.cs +++ b/Src/FDO/DomainServices/DataMigration/DataMigration7000026.cs @@ -8,14 +8,8 @@ // // -using System; -using System.Collections; -using System.Collections.Generic; -using System.Windows.Forms; using System.Xml.Linq; using System.Linq; -using System.Xml.XPath; -using SIL.FieldWorks.FDO.DomainImpl; namespace SIL.FieldWorks.FDO.DomainServices.DataMigration { diff --git a/Src/FDO/DomainServices/DataMigration/DataMigration7000029.cs b/Src/FDO/DomainServices/DataMigration/DataMigration7000029.cs index 62cb888366..132750ebc8 100644 --- a/Src/FDO/DomainServices/DataMigration/DataMigration7000029.cs +++ b/Src/FDO/DomainServices/DataMigration/DataMigration7000029.cs @@ -9,15 +9,10 @@ // using System; -using System.Collections; -using System.Collections.Generic; using System.IO; -using System.Windows.Forms; using System.Xml.Linq; using System.Linq; using System.Xml.XPath; -using SIL.FieldWorks.Common.FwUtils; -using SIL.FieldWorks.FDO.DomainImpl; namespace SIL.FieldWorks.FDO.DomainServices.DataMigration { @@ -70,14 +65,14 @@ public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepositor string persistedLinkedFilesRootDir; if (linkedFilesRootDirElement == null) { - persistedLinkedFilesRootDir = Path.Combine(domainObjectDtoRepository.ProjectFolder, DirectoryFinder.ksLinkedFilesDir); + persistedLinkedFilesRootDir = Path.Combine(domainObjectDtoRepository.ProjectFolder, FdoFileHelper.ksLinkedFilesDir); } else { persistedLinkedFilesRootDir = linkedFilesRootDirElement.Value; } - var linkedFilesRootDir = DirectoryFinderRelativePaths.GetLinkedFilesFullPathFromRelativePath(persistedLinkedFilesRootDir, - domainObjectDtoRepository.ProjectFolder); + var linkedFilesRootDir = LinkedFilesRelativePathHelper.GetLinkedFilesFullPathFromRelativePath(domainObjectDtoRepository.Directories.ProjectsDirectory, + persistedLinkedFilesRootDir, domainObjectDtoRepository.ProjectFolder); //Get the Elements for class="CmFile" var CmFileDtosBeforeMigration = domainObjectDtoRepository.AllInstancesSansSubclasses("CmFile"); @@ -85,7 +80,7 @@ public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepositor { XElement cmFileXML = XElement.Parse(fileDto.Xml); var filePath = cmFileXML.XPathSelectElement("InternalPath").XPathSelectElement("Uni").Value; - var fileAsRelativePath = DirectoryFinderRelativePaths.GetRelativeLinkedFilesPath(filePath, + var fileAsRelativePath = LinkedFilesRelativePathHelper.GetRelativeLinkedFilesPath(filePath, linkedFilesRootDir); //If these two strings do not match then a full path was converted to a LinkedFiles relative path //so replace the path in the CmFile object. diff --git a/Src/FDO/DomainServices/DataMigration/DataMigration7000030.cs b/Src/FDO/DomainServices/DataMigration/DataMigration7000030.cs index 63d1d79dab..d53663e839 100644 --- a/Src/FDO/DomainServices/DataMigration/DataMigration7000030.cs +++ b/Src/FDO/DomainServices/DataMigration/DataMigration7000030.cs @@ -9,18 +9,12 @@ // using System; -using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; -using System.Windows.Forms; -using System.Xml; using System.Xml.Linq; using System.Xml.XPath; -using SIL.CoreImpl; -using SIL.FieldWorks.Common.FwUtils; -using SIL.FieldWorks.FDO.DomainImpl; using SIL.Utils; namespace SIL.FieldWorks.FDO.DomainServices.DataMigration @@ -76,14 +70,14 @@ public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepositor string persistedLinkedFilesRootDir; if (linkedFilesRootDirElement == null) { - persistedLinkedFilesRootDir = Path.Combine(domainObjectDtoRepository.ProjectFolder, DirectoryFinder.ksLinkedFilesDir); + persistedLinkedFilesRootDir = Path.Combine(domainObjectDtoRepository.ProjectFolder, FdoFileHelper.ksLinkedFilesDir); } else { persistedLinkedFilesRootDir = linkedFilesRootDirElement.Value; } - var linkedFilesRootDir = DirectoryFinderRelativePaths.GetLinkedFilesFullPathFromRelativePath(persistedLinkedFilesRootDir, - domainObjectDtoRepository.ProjectFolder); + var linkedFilesRootDir = LinkedFilesRelativePathHelper.GetLinkedFilesFullPathFromRelativePath(domainObjectDtoRepository.Directories.ProjectsDirectory, + persistedLinkedFilesRootDir, domainObjectDtoRepository.ProjectFolder); //------------------------------------------------- var langProjectGuid = langProjElement.Attribute("guid").Value; @@ -221,7 +215,7 @@ private List ProcessExternalLinksRelativePaths(IDomainObjectDTORepositor var filePath = FileUtils.ChangeWindowsPathIfLinux(externalLinkAttributeForThisRun.Value); //Check the path and if it is a rooted path which is relative to the LinkedFilesRootDir //then we will have to confirm that is was changed to a relative path after the migration. - var fileAsRelativePath = DirectoryFinderRelativePaths.GetRelativeLinkedFilesPath(filePath, + var fileAsRelativePath = LinkedFilesRelativePathHelper.GetRelativeLinkedFilesPath(filePath, linkedFilesRootDir); //Save the file paths so they can be turned into CmFiles filePathsInTsStrings.Add(fileAsRelativePath); diff --git a/Src/FDO/DomainServices/DataMigration/DataMigration7000033.cs b/Src/FDO/DomainServices/DataMigration/DataMigration7000033.cs index a601fa9d36..aebe41226d 100644 --- a/Src/FDO/DomainServices/DataMigration/DataMigration7000033.cs +++ b/Src/FDO/DomainServices/DataMigration/DataMigration7000033.cs @@ -55,7 +55,7 @@ public void PerformMigration(IDomainObjectDTORepository repoDto) { DataMigrationServices.CheckVersionNumber(repoDto, 7000032); var projectFolder = repoDto.ProjectFolder; - // This is equivalent to DirectoryFinder.GetConfigSettingsDir(projectFolder) at the time of creating + // This is equivalent to FwDirectoryFinder.GetConfigSettingsDir(projectFolder) at the time of creating // the migration, but could conceivably change later. var targetDir = Path.Combine(projectFolder, "ConfigurationSettings"); if (Directory.Exists(targetDir)) diff --git a/Src/FDO/DomainServices/DataMigration/DataMigration7000037.cs b/Src/FDO/DomainServices/DataMigration/DataMigration7000037.cs index c20ca7ed73..dd2b3456e4 100644 --- a/Src/FDO/DomainServices/DataMigration/DataMigration7000037.cs +++ b/Src/FDO/DomainServices/DataMigration/DataMigration7000037.cs @@ -7,14 +7,10 @@ using System; using System.IO; -using System.Linq; using System.Text; using System.Web; -using System.Xml; using System.Xml.Linq; using System.Xml.XPath; - -using SIL.FieldWorks.Common.FwUtils; using SIL.Utils; namespace SIL.FieldWorks.FDO.DomainServices.DataMigration @@ -30,6 +26,10 @@ internal class DataMigration7000037 : IDataMigration { private static readonly byte[] s_externalLinkTag = Encoding.UTF8.GetBytes("externalLink"); + // Moved here from FWLinkArgs. We don't want it to change here if it is changed there since + // the data migration will expect it to be what it was at that time, not the new value. + private const string kFwUrlPrefix = "silfw://localhost/link?"; + #region IDataMigration Members public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepository) @@ -62,11 +62,11 @@ private bool FixExternalLinks(XElement xel, string projectName) if (attrLink == null) continue; string value = attrLink.Value; - if (value.StartsWith(FwLinkArgs.kFwUrlPrefix.Substring(1))) - value = FwLinkArgs.kFwUrlPrefix.Substring(0, 1) + value; - if (!value.StartsWith(FwLinkArgs.kFwUrlPrefix)) + if (value.StartsWith(kFwUrlPrefix.Substring(1))) + value = kFwUrlPrefix.Substring(0, 1) + value; + if (!value.StartsWith(kFwUrlPrefix)) continue; - string query = HttpUtility.UrlDecode(value.Substring(FwLinkArgs.kFwUrlPrefix.Length)); + string query = HttpUtility.UrlDecode(value.Substring(kFwUrlPrefix.Length)); string[] rgsProps = query.Split(new char[] {'&'}, StringSplitOptions.RemoveEmptyEntries); string database = null; int idxDatabase = -1; @@ -130,7 +130,7 @@ private bool FixExternalLinks(XElement xel, string projectName) if (!fChange) continue; - value = FwLinkArgs.kFwUrlPrefix + HttpUtility.UrlEncode(rgsProps.ToString("&")); + value = kFwUrlPrefix + HttpUtility.UrlEncode(rgsProps.ToString("&")); if (attrLink.Value != value) { attrLink.Value = value; diff --git a/Src/FDO/DomainServices/DataMigration/DataMigration7000040.cs b/Src/FDO/DomainServices/DataMigration/DataMigration7000040.cs index a16a4d5e5d..ed0cc25399 100644 --- a/Src/FDO/DomainServices/DataMigration/DataMigration7000040.cs +++ b/Src/FDO/DomainServices/DataMigration/DataMigration7000040.cs @@ -5,17 +5,8 @@ // File: DataMigration7000037.cs // Responsibility: mcconnel -using System; -using System.IO; using System.Linq; -using System.Text; -using System.Web; -using System.Xml; using System.Xml.Linq; -using System.Xml.XPath; - -using SIL.FieldWorks.Common.FwUtils; -using SIL.Utils; namespace SIL.FieldWorks.FDO.DomainServices.DataMigration { diff --git a/Src/FDO/DomainServices/DataMigration/DataMigration7000041.cs b/Src/FDO/DomainServices/DataMigration/DataMigration7000041.cs index 558c7e6366..e0559794ce 100644 --- a/Src/FDO/DomainServices/DataMigration/DataMigration7000041.cs +++ b/Src/FDO/DomainServices/DataMigration/DataMigration7000041.cs @@ -6,19 +6,12 @@ // Responsibility: lastufka using System; -using System.IO; using System.Linq; -using System.Text; -using System.Web; -using System.Xml; using System.Xml.Linq; using System.Xml.XPath; using System.Collections.Generic; using System.Diagnostics; -using SIL.FieldWorks.Common.FwUtils; -using SIL.Utils; - namespace SIL.FieldWorks.FDO.DomainServices.DataMigration { /// ---------------------------------------------------------------------------------------- diff --git a/Src/FDO/DomainServices/DataMigration/DataMigration7000042.cs b/Src/FDO/DomainServices/DataMigration/DataMigration7000042.cs index 41f1dcc100..f2ed1bf03d 100644 --- a/Src/FDO/DomainServices/DataMigration/DataMigration7000042.cs +++ b/Src/FDO/DomainServices/DataMigration/DataMigration7000042.cs @@ -10,8 +10,8 @@ using System.Text; using System.Xml.Linq; using System.Xml.XPath; -using SIL.FieldWorks.Common.FwUtils; using System; +using SIL.Utils; namespace SIL.FieldWorks.FDO.DomainServices.DataMigration { diff --git a/Src/FDO/DomainServices/DataMigration/DataMigration7000044.cs b/Src/FDO/DomainServices/DataMigration/DataMigration7000044.cs index 28fd82a070..72ae2f8d50 100644 --- a/Src/FDO/DomainServices/DataMigration/DataMigration7000044.cs +++ b/Src/FDO/DomainServices/DataMigration/DataMigration7000044.cs @@ -15,7 +15,7 @@ using System.Xml.XPath; using Palaso.WritingSystems.Migration; using Palaso.WritingSystems.Migration.WritingSystemsLdmlV0To1Migration; -using SIL.FieldWorks.Common.FwUtils; +using SIL.CoreImpl; using System; namespace SIL.FieldWorks.FDO.DomainServices.DataMigration @@ -55,7 +55,7 @@ public void PerformMigration(IDomainObjectDTORepository repoDto) globalMigrator.Migrate(); } - var ldmlFolder = Path.Combine(repoDto.ProjectFolder, DirectoryFinder.ksWritingSystemsDir); + var ldmlFolder = Path.Combine(repoDto.ProjectFolder, FdoFileHelper.ksWritingSystemsDir); var migrator = new LdmlInFolderWritingSystemRepositoryMigrator(ldmlFolder, NoteMigration); migrator.Migrate(); UpdateTags(repoDto); @@ -156,7 +156,7 @@ private void UpdateTags(IDomainObjectDTORepository repoDto) lpChanged |= UpdateAttr(langProj, "VernWss"); if (lpChanged) DataMigrationServices.UpdateDTO(repoDto, langProjDto, langProj.ToString()); - var settingsFolder = Path.Combine(repoDto.ProjectFolder, DirectoryFinder.ksConfigurationSettingsDir); + var settingsFolder = Path.Combine(repoDto.ProjectFolder, FdoFileHelper.ksConfigurationSettingsDir); if (Directory.Exists(settingsFolder)) { m_tagMap["$wsname"] = "$wsname"; // should never be changed. diff --git a/Src/FDO/DomainServices/DataMigration/DataMigration7000060.cs b/Src/FDO/DomainServices/DataMigration/DataMigration7000060.cs index 279dffd9b2..d13954f753 100644 --- a/Src/FDO/DomainServices/DataMigration/DataMigration7000060.cs +++ b/Src/FDO/DomainServices/DataMigration/DataMigration7000060.cs @@ -7,16 +7,6 @@ using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using System.Xml; -using System.Xml.Linq; -using System.Xml.XPath; -using Palaso.WritingSystems.Migration; -using Palaso.WritingSystems.Migration.WritingSystemsLdmlV0To1Migration; -using SIL.FieldWorks.Common.FwUtils; -using System; namespace SIL.FieldWorks.FDO.DomainServices.DataMigration { @@ -45,7 +35,7 @@ public void PerformMigration(IDomainObjectDTORepository repoDto) { DataMigrationServices.CheckVersionNumber(repoDto, 7000059); - var configFolder = Path.Combine(repoDto.ProjectFolder, DirectoryFinder.ksConfigurationSettingsDir); + var configFolder = Path.Combine(repoDto.ProjectFolder, FdoFileHelper.ksConfigurationSettingsDir); if (Directory.Exists(configFolder)) // Some of Randy's test data doesn't have the config folder, so it crashes here. { const string layoutSuffix = "_Layouts.xml"; diff --git a/Src/FDO/DomainServices/DataMigration/DataMigration7000066.cs b/Src/FDO/DomainServices/DataMigration/DataMigration7000066.cs index 0d0aa68ec1..f75dec2e8e 100644 --- a/Src/FDO/DomainServices/DataMigration/DataMigration7000066.cs +++ b/Src/FDO/DomainServices/DataMigration/DataMigration7000066.cs @@ -3,7 +3,6 @@ using System.Linq; using System.Xml.Linq; using SIL.CoreImpl; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.Infrastructure; namespace SIL.FieldWorks.FDO.DomainServices.DataMigration diff --git a/Src/FDO/DomainServices/DataMigration/FdoDataMigrationManager.cs b/Src/FDO/DomainServices/DataMigration/FdoDataMigrationManager.cs index 7b1a00aa87..cfaf727d6f 100644 --- a/Src/FDO/DomainServices/DataMigration/FdoDataMigrationManager.cs +++ b/Src/FDO/DomainServices/DataMigration/FdoDataMigrationManager.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; -using System.Windows.Forms; -using SIL.FieldWorks.Common.FwUtils; +using SIL.Utils; namespace SIL.FieldWorks.FDO.DomainServices.DataMigration { @@ -175,7 +174,6 @@ public void PerformMigration(IDomainObjectDTORepository domainObjectDtoRepositor currentDataStoreModelVersion, updateToVersion)); progressDlg.Title = Strings.ksDataMigrationCaption; - progressDlg.ProgressBarStyle = ProgressBarStyle.Continuous; progressDlg.AllowCancel = false; progressDlg.Minimum = 0; progressDlg.Maximum = (updateToVersion - currentDataStoreModelVersion) + 1; diff --git a/Src/FDO/DomainServices/DataMigration/IDataMigrationManager.cs b/Src/FDO/DomainServices/DataMigration/IDataMigrationManager.cs index 2c7c5ba7fb..08cfe40115 100644 --- a/Src/FDO/DomainServices/DataMigration/IDataMigrationManager.cs +++ b/Src/FDO/DomainServices/DataMigration/IDataMigrationManager.cs @@ -6,7 +6,7 @@ // Responsibility: FW team using System; -using SIL.FieldWorks.Common.FwUtils; +using SIL.Utils; namespace SIL.FieldWorks.FDO.DomainServices.DataMigration { diff --git a/Src/FDO/DomainServices/DataMigration/IDomainObjectDTORepository.cs b/Src/FDO/DomainServices/DataMigration/IDomainObjectDTORepository.cs index fb31b858de..fba990dc56 100644 --- a/Src/FDO/DomainServices/DataMigration/IDomainObjectDTORepository.cs +++ b/Src/FDO/DomainServices/DataMigration/IDomainObjectDTORepository.cs @@ -213,6 +213,11 @@ void CreateCustomField(string className, string fieldName, SIL.CoreImpl.CellarPr /// /// ------------------------------------------------------------------------------------ string ProjectFolder { get; } + + /// + /// Gets the directories service. + /// + IFdoDirectories Directories { get; } } internal sealed class DomainObjectDtoRepository : IDomainObjectDTORepository @@ -233,6 +238,7 @@ internal sealed class DomainObjectDtoRepository : IDomainObjectDTORepository private int m_currentModelVersionNumber; private readonly HashSet m_oldTimers = new HashSet(); private readonly string m_projectFolder; + private readonly IFdoDirectories m_dirs; private readonly IFwMetaDataCacheManaged m_mdc; // needed for some data migrations changing over to custom fields. @@ -247,9 +253,10 @@ internal sealed class DomainObjectDtoRepository : IDomainObjectDTORepository /// The project folder (don't even think about trying to /// pass a path on a server other than the local machine, and -- yes -- I CAN control /// your thoughts!). + /// /// ------------------------------------------------------------------------------------ internal DomainObjectDtoRepository(int startingModelVersionNumber, HashSet dtos, - IFwMetaDataCacheManaged mdc, string projectFolder) + IFwMetaDataCacheManaged mdc, string projectFolder, IFdoDirectories dirs) { if (dtos == null) throw new ArgumentNullException("dtos"); if (mdc == null) throw new ArgumentNullException("mdc"); @@ -258,6 +265,7 @@ internal DomainObjectDtoRepository(int startingModelVersionNumber, HashSet + /// Gets the directories service. + /// + public IFdoDirectories Directories + { + get { return m_dirs; } + } #endregion } } diff --git a/Src/FDO/DomainServices/DataMigration/ImportFrom6_0.cs b/Src/FDO/DomainServices/DataMigration/ImportFrom6_0.cs index 11c93c92ca..ecc6e5dcde 100644 --- a/Src/FDO/DomainServices/DataMigration/ImportFrom6_0.cs +++ b/Src/FDO/DomainServices/DataMigration/ImportFrom6_0.cs @@ -10,12 +10,8 @@ using System.IO; using System.ServiceProcess; using System.Text; -using System.Windows.Forms; using ICSharpCode.SharpZipLib.Zip; using Microsoft.Win32; - -using SIL.FieldWorks.Common.FwUtils; -using SIL.FieldWorks.Resources; using SIL.Utils; namespace SIL.FieldWorks.FDO.DomainServices.DataMigration @@ -45,29 +41,28 @@ public class ImportFrom6_0 bool m_fHaveSqlServer; bool m_fHaveOldFieldWorks; + private readonly string m_converterConsolePath; readonly bool m_fVerboseDebug; private readonly IThreadedProgress m_progressDlg; #endregion - /// - /// provides parent form for progress dialog - /// - public Form ParentForm { get; set; } - #region Constructors /// /// Constructor for run-time debugging. /// - public ImportFrom6_0(IThreadedProgress progressDlg, bool fDebug) + public ImportFrom6_0(IThreadedProgress progressDlg, string converterConsolePath, string dbPath, bool fDebug) { m_progressDlg = progressDlg; + m_converterConsolePath = converterConsolePath; + m_dbPath = dbPath; m_fVerboseDebug = fDebug; } /// /// Constructor. /// - public ImportFrom6_0(IThreadedProgress progressDlg) : this(progressDlg, false) + public ImportFrom6_0(IThreadedProgress progressDlg, string converterConsolePath, string dbPath) + : this(progressDlg, converterConsolePath, dbPath, false) { } #endregion @@ -75,22 +70,17 @@ public ImportFrom6_0(IThreadedProgress progressDlg) : this(progressDlg, false) /// /// Do the import of the specified zip or XML file. Return true if successful and the caller should open the database. /// - public bool Import(string pathname, string projectName, out string projectFile) + public bool Import(string pathname, string projectName, string destFolder, out string projectFile) { - var destFolder = DirectoryFinder.ProjectsDirectory; var folderName = Path.Combine(destFolder, projectName); - projectFile = Path.Combine(folderName, projectName + FwFileExtensions.ksFwDataXmlFileExtension); + projectFile = Path.Combine(folderName, projectName + FdoFileHelper.ksFwDataXmlFileExtension); string extension = Path.GetExtension(pathname); if (extension != null) extension = extension.ToLowerInvariant(); if (extension == ".xml") { if (!IsValid6_0Xml(pathname)) - { - MessageBoxUtils.Show(m_progressDlg.Form, Strings.ksBackupXMLFileTooOld, - Strings.ksCannotConvert); - return false; - } + throw new CannotConvertException(Strings.ksBackupXMLFileTooOld); var result1 = ImportFrom6_0Xml(pathname, folderName, projectFile); return result1; } @@ -109,7 +99,7 @@ public bool Import(string pathname, string projectName, out string projectFile) if (fCreateFolder) Directory.CreateDirectory(folderName); string message = String.Format(Strings.ksExtractingFromZip, Path.GetFileName(entry.Name)); - if (!UnzipFile(zipFile, entry, message, out tempPath)) + if (!UnzipFile(destFolder, zipFile, entry, message, out tempPath)) { return false; } @@ -126,9 +116,16 @@ public bool Import(string pathname, string projectName, out string projectFile) else continue; } - // Next step is to run the converter. It should be in the same directory as FDO.dll - var result = ImportFrom6_0Xml(tempPath, folderName, projectFile); - File.Delete(tempPath); + bool result; + try + { + // Next step is to run the converter. It should be in the same directory as FDO.dll + result = ImportFrom6_0Xml(tempPath, folderName, projectFile); + } + finally + { + File.Delete(tempPath); + } return result; } if (entry.Name.ToLowerInvariant().EndsWith(".bak") && entry.IsFile) @@ -139,10 +136,7 @@ public bool Import(string pathname, string projectName, out string projectFile) } } if (!fHasBak) - { - MessageBoxUtils.Show(m_progressDlg.Form, Strings.ksZipNotFieldWorksBackup, Strings.ksCannotConvert); - return false; - } + throw new CannotConvertException(Strings.ksZipNotFieldWorksBackup); if (HaveFwSqlServer && HaveOldFieldWorks) { foreach (ZipEntry entry in zipFile) @@ -151,7 +145,7 @@ public bool Import(string pathname, string projectName, out string projectFile) { string tempPath; string message = String.Format(Strings.ksExtractingFromZip, Path.GetFileName(entry.Name)); - if (!UnzipFile(zipFile, entry, message, out tempPath)) + if (!UnzipFile(destFolder, zipFile, entry, message, out tempPath)) { return false; } @@ -176,32 +170,37 @@ public bool Import(string pathname, string projectName, out string projectFile) proj, "{0}", "{1}"); if (!DumpDatabaseAsXml(TempDatabaseName, tempXmlPath, msg3, errMsgFmt3)) return false; - // Next step is to run the converter. It should be in the same directory as FDO.dll - var result = ImportFrom6_0Xml(tempXmlPath, folderName, projectFile); - File.Delete(tempXmlPath); - DeleteTempDatabase(); + + bool result; + try + { + // Next step is to run the converter. It should be in the same directory as FDO.dll + result = ImportFrom6_0Xml(tempXmlPath, folderName, projectFile); + } + finally + { + File.Delete(tempXmlPath); + DeleteTempDatabase(); + } return result; } } // Should never get here, but ... - MessageBoxUtils.Show(m_progressDlg.Form, Strings.ksZipNotFieldWorksBackup, Strings.ksCannotConvert); + throw new CannotConvertException(Strings.ksZipNotFieldWorksBackup); } return false; } } - private bool UnzipFile(ZipFile zipFile, ZipEntry entry, string message, out string tempPath) + private bool UnzipFile(string folderName, ZipFile zipFile, ZipEntry entry, string message, out string tempPath) { - string folderName = DirectoryFinder.ProjectsDirectory; if (!Directory.Exists(folderName)) Directory.CreateDirectory(folderName); // We will extract the file to here. tempPath = Path.Combine(folderName, entry.Name); using (var stream = zipFile.GetInputStream(entry)) { - var form = ParentForm ?? Form.ActiveForm; m_progressDlg.Title = Strings.ksConverting; - m_progressDlg.ProgressBarStyle = ProgressBarStyle.Continuous; m_progressDlg.Maximum = (int)entry.Size; if (File.Exists(tempPath)) File.Delete(tempPath); // if we tried and failed earlier, try again. @@ -254,7 +253,7 @@ public bool IsFwSqlServerInstalled() catch (Exception) { if (m_fVerboseDebug) - MessageBoxUtils.Show("The FieldWorks installation of SQL Server (MSSQL$SILFW) does not exist.", + Debug.WriteLine("The FieldWorks installation of SQL Server (MSSQL$SILFW) does not exist.", "DEBUG!"); return false; // The FieldWorks installation of SQL Server isn't available } @@ -279,7 +278,7 @@ public bool IsValidOldFwInstalled(out string version) if (clsidKey == null) { if (m_fVerboseDebug) - MessageBoxUtils.Show("Unable to open the CLSID registry subkey????", "DEBUG!"); + Debug.WriteLine("Unable to open the CLSID registry subkey????"); return false; } // check for registered class id for FwXmlData. @@ -287,7 +286,7 @@ public bool IsValidOldFwInstalled(out string version) if (cellarPath == null) { if (m_fVerboseDebug) - MessageBoxUtils.Show("FwCellar.dll is not registered.", "DEBUG!"); + Debug.WriteLine("FwCellar.dll is not registered.", "DEBUG!"); return false; } // check for registered class id for MigrateData. @@ -295,7 +294,7 @@ public bool IsValidOldFwInstalled(out string version) if (migratePath == null) { if (m_fVerboseDebug) - MessageBoxUtils.Show("MigrateData.dll is not registered.", "DEBUG!"); + Debug.WriteLine("MigrateData.dll is not registered.", "DEBUG!"); return false; } // check for registered class id for LgWritingSystemFactory. @@ -303,7 +302,7 @@ public bool IsValidOldFwInstalled(out string version) if (languagePath == null) { if (m_fVerboseDebug) - MessageBoxUtils.Show("Language.dll is not registered.", "DEBUG!"); + Debug.WriteLine("Language.dll is not registered.", "DEBUG!"); return false; } // check for registered class id for TsStrFactory. @@ -311,7 +310,7 @@ public bool IsValidOldFwInstalled(out string version) if (kernelPath == null) { if (m_fVerboseDebug) - MessageBoxUtils.Show("FwKernel.dll is not registered.", "DEBUG!"); + Debug.WriteLine("FwKernel.dll is not registered.", "DEBUG!"); return false; } // check for registered class id for OleDbEncap. @@ -319,7 +318,7 @@ public bool IsValidOldFwInstalled(out string version) if (dbaccessPath == null) { if (m_fVerboseDebug) - MessageBoxUtils.Show("DbAccess.dll is not registered.", "DEBUG!"); + Debug.WriteLine("DbAccess.dll is not registered.", "DEBUG!"); return false; } // Get (and save) the path to dumpxml.exe. @@ -337,7 +336,7 @@ public bool IsValidOldFwInstalled(out string version) if (!File.Exists(m_dumpxmlPath)) { if (m_fVerboseDebug) - MessageBoxUtils.Show("Cannot find dumpxml.exe in the old FieldWorks installation.", "DEBUG!"); + Debug.WriteLine("Cannot find dumpxml.exe in the old FieldWorks installation.", "DEBUG!"); return false; } } @@ -352,15 +351,14 @@ public bool IsValidOldFwInstalled(out string version) if (!File.Exists(scriptPath)) { if (m_fVerboseDebug) - MessageBoxUtils.Show("Cannot find DataMigration\\200259To200260.sql in the old FieldWorks installation.", "DEBUG!"); + Debug.WriteLine("Cannot find DataMigration\\200259To200260.sql in the old FieldWorks installation.", "DEBUG!"); return false; } } - m_dbPath = Path.Combine(DirectoryFinder.GetFWCodeSubDirectory("MSSQLMigration"), "db.exe"); if (!File.Exists(m_dbPath)) { if (m_fVerboseDebug) - MessageBoxUtils.Show("Cannot find MSSQLMigration\\db.exe in the FieldWorks 7.0 or later installation.", "DEBUG!"); + Debug.WriteLine("Cannot find MSSQLMigration\\db.exe in the FieldWorks 7.0 or later installation.", "DEBUG!"); return false; } return true; @@ -373,7 +371,7 @@ public bool IsValidOldFwInstalled(out string version) string msg = String.Format( "An exception was thrown while checking for an old version of FieldWorks:{1}{0}", e.Message, Environment.NewLine); - MessageBoxUtils.Show(msg, "DEBUG!"); + Debug.WriteLine(msg, "DEBUG!"); } } return false; @@ -395,7 +393,7 @@ private string FindComDllIfRegistered(RegistryKey clsidKey, string sClsid, ref s if (m_fVerboseDebug) { string msg = String.Format("Nonexistent file for a registered COM DLL: {0}", dllPath); - MessageBox.Show(msg, "DEBUG!"); + Debug.WriteLine(msg, "DEBUG!"); } return null; } @@ -411,40 +409,17 @@ private string FindComDllIfRegistered(RegistryKey clsidKey, string sClsid, ref s { string msg = String.Format("Multiple versions found in the registered COM DLLs: {0} and {1} [{2}]", version, fileVersion, dllPath); - MessageBoxUtils.Show(msg, "DEBUG!"); + Debug.WriteLine(msg, "DEBUG!"); } return null; // don't want a mix of versions!! } if (String.IsNullOrEmpty(version) || version.CompareTo("5.4") < 0 || version.CompareTo("6.1") >= 0) { - if (!String.IsNullOrEmpty(version) && version.CompareTo("5.4") < 0) - { - using (FWVersionTooOld dlg = new FWVersionTooOld(version)) - { - dlg.ShowDialog(); - } - string launchesFlex = "0"; - string launchesTE = "0"; - if (RegistryHelper.KeyExists(FwRegistryHelper.FieldWorksRegistryKey, "Language Explorer")) - { - using (RegistryKey keyFlex = FwRegistryHelper.FieldWorksRegistryKey.CreateSubKey("Language Explorer")) - launchesFlex = keyFlex.GetValue("launches", "0") as string; - } - if (RegistryHelper.KeyExists(FwRegistryHelper.FieldWorksRegistryKey, FwSubKey.TE)) - { - using (RegistryKey keyTE = FwRegistryHelper.FieldWorksRegistryKey.CreateSubKey(FwSubKey.TE)) - launchesTE = keyTE.GetValue("launches", "0") as string; - } - if (launchesFlex == "0" && launchesTE == "0") - { - FwRegistryHelper.FieldWorksRegistryKey.SetValue("MigrationTo7Needed", "true"); - } - } - else if (m_fVerboseDebug) + if (m_fVerboseDebug) { string msg = String.Format("Invalid version found in a registered COM DLL: {0} [{1}]", version, dllPath); - MessageBox.Show(msg, "DEBUG!"); + Debug.WriteLine(msg, "DEBUG!"); } return null; } @@ -525,7 +500,7 @@ private bool CallDbProgram(string args, string progressMsg, string errorMsgFmt) { using (var process = CreateAndInitProcess(m_dbPath, args)) { - m_progressDlg.ProgressBarStyle = ProgressBarStyle.Marquee; // Can't get actual progress from external program + m_progressDlg.IsIndeterminate = true; // Can't get actual progress from external program m_progressDlg.Title = Strings.ksConverting; if (!(bool)m_progressDlg.RunTask(true, ProcessFile, process, progressMsg)) { @@ -535,8 +510,7 @@ private bool CallDbProgram(string args, string progressMsg, string errorMsgFmt) if (process.ExitCode != 0 || !string.IsNullOrEmpty(m_errorMessages)) { var msg = string.Format(errorMsgFmt, process.ExitCode, m_errorMessages); - MessageBoxUtils.Show(m_progressDlg.Form, msg, Strings.ksCannotConvert); - return false; + throw new CannotConvertException(msg); } return true; } @@ -551,7 +525,7 @@ public bool DumpDatabaseAsXml(string dbName, string tempXmlPath, string progress { using (var process = CreateAndInitProcess(m_dumpxmlPath, "-d \"" + dbName + "\" -o \"" + tempXmlPath + '"')) { - m_progressDlg.ProgressBarStyle = ProgressBarStyle.Marquee; // Can't get actual progress from external program + m_progressDlg.IsIndeterminate = true; // Can't get actual progress from external program m_progressDlg.Title = Strings.ksConverting; if (!(bool)m_progressDlg.RunTask(true, ProcessFile, process, progressMsg)) { @@ -561,8 +535,7 @@ public bool DumpDatabaseAsXml(string dbName, string tempXmlPath, string progress if (process.ExitCode != 0 || !string.IsNullOrEmpty(m_errorMessages)) { var msg = string.Format(errorMsgFmt, process.ExitCode, m_errorMessages); - MessageBoxUtils.Show(m_progressDlg.Form, msg, Strings.ksCannotConvert); - return false; + throw new CannotConvertException(msg); } return true; } @@ -663,11 +636,9 @@ public bool ImportFrom6_0Xml(string pathname, string folderName, string projectF File.Delete(replacedProj); File.Move(projectFile, replacedProj); } - using (var process = CreateAndInitProcess( - Path.Combine(DirectoryFinder.FWCodeDirectory, "ConverterConsole.exe"), - '"' + pathname + "\" \"" + projectFile + '"')) + using (var process = CreateAndInitProcess(m_converterConsolePath, '"' + pathname + "\" \"" + projectFile + '"')) { - m_progressDlg.ProgressBarStyle = ProgressBarStyle.Marquee; // Can't get actual progress from external program + m_progressDlg.IsIndeterminate = true; // Can't get actual progress from external program m_progressDlg.Title = Strings.ksConverting; string message = String.Format(Strings.ksConvertingFile, Path.GetFileNameWithoutExtension(projectFile)); if (!(bool)m_progressDlg.RunTask(true, ProcessFile, process, message)) @@ -678,19 +649,12 @@ public bool ImportFrom6_0Xml(string pathname, string folderName, string projectF else if (process.ExitCode != 0 || !String.IsNullOrEmpty(m_errorMessages)) { message = String.Format(Strings.ksConversionProcessFailed, process.ExitCode, m_errorMessages); - // ENHANCE (TimS): We should not be showing a message box at this level. If we - // really need to show it here, we should pass in the owning form instead of relying on - // Form.ActiveForm since it can return null if no .Net forms have focus. - MessageBoxUtils.Show(Form.ActiveForm, message, Strings.ksCannotConvert); - retval = false; + BackOutCleanUp(projectFile, fCreateFolder, folderName, replacedProj); + throw new CannotConvertException(message); } if (retval == false) { - File.Delete(projectFile); - if (fCreateFolder) - Directory.Delete(folderName); - else if (replacedProj != null) - File.Move(replacedProj, projectFile); + BackOutCleanUp(projectFile, fCreateFolder, folderName, replacedProj); } else { @@ -715,6 +679,15 @@ public bool ImportFrom6_0Xml(string pathname, string folderName, string projectF } } + private void BackOutCleanUp(string projectFile, bool fCreateFolder, string folderName, string replacedProj) + { + File.Delete(projectFile); + if (fCreateFolder) + Directory.Delete(folderName); + else if (replacedProj != null) + File.Move(replacedProj, projectFile); + } + /// /// Create a process and initialize it according to our standard way of doing things. /// @@ -806,4 +779,25 @@ void process_OutputDataReceived(object sender, DataReceivedEventArgs e) m_stdoutBldr.AppendLine(e.Data); } } + + #region class CannotConvertException + /// ---------------------------------------------------------------------------------------- + /// + /// Exception type to encapsulate a problem while running the conversion + /// + /// ---------------------------------------------------------------------------------------- + public class CannotConvertException : Exception + { + /// ------------------------------------------------------------------------------------ + /// + /// Initializes a new instance of the class. + /// + /// The message. + /// ------------------------------------------------------------------------------------ + public CannotConvertException(string message) + : base(message) + { + } + } + #endregion } diff --git a/Src/FDO/DomainServices/DataStoreInitializationServices.cs b/Src/FDO/DomainServices/DataStoreInitializationServices.cs index 6b47ab586a..e8f79b3fe4 100644 --- a/Src/FDO/DomainServices/DataStoreInitializationServices.cs +++ b/Src/FDO/DomainServices/DataStoreInitializationServices.cs @@ -379,7 +379,7 @@ private static void FixSegmentsForScriptureParas(FdoCache cache) if (hadError) { // Tell the user that something bad happened - ErrorReporter.ReportException(new Exception("Error during resegmentation"), null, null, null, false); + cache.ServiceLocator.GetInstance().ReportException(new Exception("Error during resegmentation"), false); } } diff --git a/Src/FDO/DomainServices/Db4OServerFinder.cs b/Src/FDO/DomainServices/Db4OServerFinder.cs index ad72db773c..7763f133f9 100644 --- a/Src/FDO/DomainServices/Db4OServerFinder.cs +++ b/Src/FDO/DomainServices/Db4OServerFinder.cs @@ -6,6 +6,7 @@ // Responsibility: FW Team using System; +using System.Diagnostics.CodeAnalysis; using System.Net; using System.Net.Sockets; using System.Threading; @@ -18,6 +19,8 @@ namespace SIL.FieldWorks.FDO.DomainServices /// In a separate thread, finds any DB4o servers on the network. /// /// ---------------------------------------------------------------------------------------- + [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", + Justification = "m_hostListenerSocket is disposed when closed.")] internal class Db4OServerFinder { #region Data members @@ -26,10 +29,9 @@ internal class Db4OServerFinder private readonly int HostDiscoveryBroadcastReplyPort = Db4OPorts.ReplyPort; private readonly Thread m_hostListenerThread; - private volatile Socket m_hostListenerSocket; + private Socket m_hostListenerSocket; private readonly object m_syncRoot = new object(); private readonly Action m_foundServerCallback; - private readonly Action m_onCompletedCallback; #endregion #region Constructor @@ -39,12 +41,14 @@ internal class Db4OServerFinder /// /// The method to call when a server is found /// (string parameter is the IP address of the found server) - /// Callback to run when the search is completed. /// ------------------------------------------------------------------------------------ - public Db4OServerFinder(Action foundServerCallback, Action onCompletedCallback) + public Db4OServerFinder(Action foundServerCallback) { m_foundServerCallback = foundServerCallback; - m_onCompletedCallback = onCompletedCallback; + + m_hostListenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp) {Blocking = false}; + EndPoint ep = new IPEndPoint(IPAddress.Any, HostDiscoveryBroadcastReplyPort); + m_hostListenerSocket.Bind(ep); // Start the thread that collects responses from our broadcast. m_hostListenerThread = new Thread(ThreadStartListenForServers); @@ -63,11 +67,6 @@ public Db4OServerFinder(Action foundServerCallback, Action onCompletedCa /// ------------------------------------------------------------------------------------ private void BroadcastToFindHosts() { - // Ensure the thread is listening before doing the broadcast - // as it could return before we are listening for it. - while (m_hostListenerThread.IsAlive && (m_hostListenerSocket == null || !m_hostListenerSocket.IsBound)) - Thread.Sleep(80); - // On Windows 7, this silently fails if the computer isn't connected to the network. // On Windows XP, it eventually (after timeout?) throws a SocketException "A socket // operation was attempted to an unreachable host". @@ -76,11 +75,11 @@ private void BroadcastToFindHosts() // Send the broadcast. using (Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) { - sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); - EndPoint iep = new IPEndPoint(IPAddress.Broadcast, HostDiscoveryBroadcastPort); + sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); + EndPoint iep = new IPEndPoint(IPAddress.Broadcast, HostDiscoveryBroadcastPort); - sock.SendTo(new byte[] { 0 }, iep); - } + sock.SendTo(new byte[] { 0 }, iep); + } } catch (SocketException) { @@ -96,54 +95,44 @@ private void BroadcastToFindHosts() /// ------------------------------------------------------------------------------------ private void ThreadStartListenForServers() { - m_hostListenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - try - { - m_hostListenerSocket.Blocking = false; - EndPoint ep = new IPEndPoint(IPAddress.Any, HostDiscoveryBroadcastReplyPort); try { - m_hostListenerSocket.Bind(ep); - } - catch (SocketException e) - { - MessageBoxUtils.Show(String.Format("Unable to bind to port {0} because {1}", HostDiscoveryBroadcastReplyPort, e)); - return; - } - - byte[] data = new byte[1024]; - int cVainAttempts = 0; - while (true) // keep listening until thread is killed. - { - int recv = 0; - lock (m_syncRoot) - { - if (m_hostListenerSocket == null) // another thread can set this to null. - break; - if (m_hostListenerSocket.Available > 0) - ExceptionHelper.LogAndIgnoreErrors(() => recv = m_hostListenerSocket.ReceiveFrom(data, ref ep)); - } - if (recv > 0) + byte[] data = new byte[1024]; + int cVainAttempts = 0; + while (true) // keep listening until thread is killed. { + EndPoint ep = new IPEndPoint(IPAddress.Any, 0); + int recv = 0; lock (m_syncRoot) - m_foundServerCallback(((IPEndPoint)ep).Address.ToString()); - cVainAttempts = 0; - } - else - { - if (cVainAttempts++ > 50) - break; // if no server has pinged us for 5 seconds, let's hang it up. - Thread.Sleep(100); + { + if (m_hostListenerSocket == null) // another thread can set this to null. + break; + if (m_hostListenerSocket.Available > 0) + ExceptionHelper.LogAndIgnoreErrors(() => recv = m_hostListenerSocket.ReceiveFrom(data, ref ep)); + } + if (recv > 0) + { + lock (m_syncRoot) + m_foundServerCallback(((IPEndPoint)ep).Address.ToString()); + cVainAttempts = 0; + } + else + { + if (cVainAttempts++ > 50) + break; // if no server has pinged us for 5 seconds, let's hang it up. + Thread.Sleep(100); + } } } - - if (m_hostListenerSocket != null && m_onCompletedCallback != null) - m_onCompletedCallback(); - } finally { - CloseSocket(); + CloseSocket(); + } } + + public bool IsCompleted + { + get { return !m_hostListenerThread.IsAlive; } } /// ------------------------------------------------------------------------------------ diff --git a/Src/FDO/DomainServices/DomainObjectServices.cs b/Src/FDO/DomainServices/DomainObjectServices.cs index af29dad57d..7f919a3734 100644 --- a/Src/FDO/DomainServices/DomainObjectServices.cs +++ b/Src/FDO/DomainServices/DomainObjectServices.cs @@ -17,7 +17,6 @@ using SIL.FieldWorks.FDO.Infrastructure; using SILUBS.SharedScrUtils; using SIL.CoreImpl; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainImpl; namespace SIL.FieldWorks.FDO.DomainServices @@ -30,36 +29,9 @@ public static class ScriptureServices { /// Book marker public static readonly string kMarkerBook = @"\id"; - /// Delegate to report a non-fatal "warning" message - private static Action ReportWarning; internal const char kKeyTokenSeparator = '\uffff'; - /// ------------------------------------------------------------------------------------ - /// - /// Initializes the class. - /// - /// ------------------------------------------------------------------------------------ - static ScriptureServices() - { - InitializeWarningHandler(); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Initializes the delegate for reporting warnings. - /// - /// This needs to be a separate method because it is called by reflection in - /// test(s). - /// ------------------------------------------------------------------------------------ - private static void InitializeWarningHandler() - { - ReportWarning = sMsg => - { - ErrorReporter.ReportException(new Exception(sMsg), null, null, null, false); - }; - } - /// ------------------------------------------------------------------------------------ /// /// Creates the import source key for a hashtable. @@ -453,7 +425,8 @@ internal static void AdjustObjectsInArchivedBook(IScrBook book, IScrBook archive ITsTextProps ttp; ITsPropsBldr propsBldr; int iFootnote = 0; - var pictureRepo = book.Cache.ServiceLocator.GetInstance(); + IFdoServiceLocator serviceLocator = book.Cache.ServiceLocator; + var pictureRepo = serviceLocator.GetInstance(); foreach (IScrTxtPara revPara in archivedBook.Paragraphs) { //TODO: TE-5082 Duplicate code! The following should call or use common code with @@ -498,7 +471,7 @@ internal static void AdjustObjectsInArchivedBook(IScrBook book, IScrBook archive BCVRef.MakeReferenceString(startRef, endRef, ":", "-") + " with guid " + guid + " does not have a corresponding footnote object owned by " + book.BookId + " or refers to a footnote that is owned by another ORC that occurs earlier."; - ReportWarning(sMsg); + serviceLocator.GetInstance().ReportException(new Exception(sMsg), false); break; } Logger.WriteEvent("Footnotes out of order in " + book.BookId + ". Expected footnote with guid " + guid + @@ -552,7 +525,7 @@ internal static void AdjustObjectsInArchivedBook(IScrBook book, IScrBook archive { string sMsg = (archivedBook.FootnotesOS.Count - iFootnote) + " footnote(s) in " + book.BookId + " did not correspond to any owned footnotes in the vernacular text of that book. They have been moved to the end of the footnote sequence."; - ReportWarning(sMsg); + serviceLocator.GetInstance().ReportException(new Exception(sMsg), false); } } @@ -2348,49 +2321,6 @@ public static ICmFile FindOrCreateFile(ICmFolder folder, string srcFile) return cmFile; } - /// ------------------------------------------------------------------------------------ - /// - /// Copy source file to a unique file in FW\pictures directory. - /// - /// The path to the original filename (an internal copy will - /// be made in this method) - /// The subfolder of the FW Data directory in which the - /// internal copy of the file should be created, if necessary (no backslashes needed) - /// - /// Destination file path, relative to the FW data directory, or ".__NONE__" - /// if source file doesn't exist. - /// - /// ------------------------------------------------------------------------------------ - public static string CopyFileToInternal(string srcFilename, string dstSubdir) - { - string srcFilenameCorrected; - if (!FileUtils.TrySimilarFileExists(srcFilename, out srcFilenameCorrected)) - return EmptyFileName; - - var strDestFolder = Path.Combine(DirectoryFinder.FWDataDirectory, dstSubdir); - if (!Directory.Exists(strDestFolder)) - Directory.CreateDirectory(strDestFolder); - - var strDestFileRelPath = Path.Combine(dstSubdir, Path.GetFileName(srcFilenameCorrected)); - var strDestFileAbsPath = Path.Combine(DirectoryFinder.FWDataDirectory, strDestFileRelPath); - - // (The case-independent comparison is valid only for Microsoft Windows.) - if (srcFilenameCorrected.Equals(strDestFileAbsPath, StringComparison.OrdinalIgnoreCase)) - return strDestFileRelPath; // don't copy files already in internal directory. - - var strFile = Path.GetFileNameWithoutExtension(srcFilenameCorrected); - var strExt = Path.GetExtension(srcFilenameCorrected); - var iQual = 0; - while (FileUtils.FileExists(strDestFileAbsPath)) - { - iQual++; - strDestFileRelPath = Path.Combine(dstSubdir, strFile + iQual + strExt); - strDestFileAbsPath = Path.Combine(DirectoryFinder.FWDataDirectory, strDestFileRelPath); - } - File.Copy(srcFilenameCorrected, strDestFileAbsPath); - return strDestFileRelPath; - } - /// ------------------------------------------------------------------------------------ /// /// Gets the empty name of the file. diff --git a/Src/FDO/DomainServices/FontInfo.cs b/Src/FDO/DomainServices/FontInfo.cs index e042781dbf..c7c27ac3fe 100644 --- a/Src/FDO/DomainServices/FontInfo.cs +++ b/Src/FDO/DomainServices/FontInfo.cs @@ -8,12 +8,8 @@ // // -using System; using System.Drawing; -using System.Text; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Resources; -using SIL.Utils; namespace SIL.FieldWorks.FDO.DomainServices { @@ -106,66 +102,6 @@ public bool IsAnyExplicit } } - /// ------------------------------------------------------------------------------------ - /// - /// Returns a that represents the current - /// . This method returns a human-readable - /// string that is culture-sensitive - /// - /// - /// A that represents the current - /// . - /// - /// ------------------------------------------------------------------------------------ - public override string ToString() - { - return ToString(false); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Returns a that represents the current - /// . This method returns a human-readable - /// string that is culture-sensitive - /// - /// if set to true forces at least minimum - /// description (i.e., font and size) to be returned. - /// - /// A that represents the current - /// . - /// - /// ------------------------------------------------------------------------------------ - public string ToString(bool fForceMinimumDescription) - { - StringBuilder text = new StringBuilder(); - - if (m_fontName.IsExplicit || fForceMinimumDescription) - AppendToString(text, UIFontName); - - if (m_fontSize.IsExplicit || fForceMinimumDescription) - AppendToString(text, string.Format(Strings.ksXPt, m_fontSize.Value / 1000)); - - if (m_fontColor.IsExplicit || m_backColor.IsExplicit) - AppendFontColor(text); - - if (m_underline.IsExplicit || m_underlineColor.IsExplicit) - AppendUnderline(text); - - if (m_bold.IsExplicit) - AppendToString(text, m_bold.Value ? Strings.ksBold : Strings.ksNotBold); - - if (m_italic.IsExplicit) - AppendToString(text, m_italic.Value ? Strings.ksItalic : Strings.ksNotItalic); - - if (m_superSub.IsExplicit) - AppendSuperSub(text, m_superSub.Value); - - if (m_offset.IsExplicit) - AppendFontOffset(text, m_offset.Value); - - return text.ToString(); - } - /// ------------------------------------------------------------------------------------ /// /// Determines whether the specified is equal to the @@ -228,190 +164,6 @@ public void SetAllDefaults() m_underlineColor.SetDefaultValue(Color.Black); } - /// ------------------------------------------------------------------------------------ - /// - /// Gets the name of the font or a UI-compatible (i.e., localizable) token to represent - /// a magic font value. - /// - /// ------------------------------------------------------------------------------------ - public string UIFontName - { - get { return GetUIFontName(m_fontName.Value); } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the name of the UI font. - /// - /// Name of the font. - /// - /// ------------------------------------------------------------------------------------ - public static string GetUIFontName(string fontName) - { - if (fontName == StyleServices.DefaultFont) - return ResourceHelper.GetResourceString("kstidDefaultFont"); - return fontName; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets the internal font name for the given UI font. - /// - /// UI name of the font. - /// Internal font name - /// ------------------------------------------------------------------------------------ - public static string GetInternalFontName(string fontNameUI) - { - if (fontNameUI == ResourceHelper.GetResourceString("kstidDefaultFont")) - return StyleServices.DefaultFont; - return fontNameUI; - } - - #region Helper methods and properties to build font description - /// ------------------------------------------------------------------------------------ - /// - /// Appends the font and background color information to the description - /// - /// The text. - /// ------------------------------------------------------------------------------------ - private void AppendFontColor(StringBuilder text) - { - if (m_fontColor.IsInherited) - AppendToString(text, String.Format(Strings.ksBackgroundIsX, - ColorUtil.ColorToName(m_backColor.Value))); - else if (m_backColor.IsInherited) - AppendToString(text, String.Format(Strings.ksTextIsX, - ColorUtil.ColorToName(m_fontColor.Value))); - else - AppendToString(text, string.Format(Strings.ksTextIsXonY, - ColorUtil.ColorToName(m_fontColor.Value), - ColorUtil.ColorToName(m_backColor.Value))); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Appends the underline information to the description. - /// - /// The text. - /// ------------------------------------------------------------------------------------ - private void AppendUnderline(StringBuilder text) - { - string sUnder = ""; - if (m_underlineColor.IsExplicit) - { - string sColor = ColorUtil.ColorToName(m_underlineColor.Value); - if (m_underline.IsExplicit) - { - switch (m_underline.Value) - { - case FwUnderlineType.kuntNone: - sUnder = String.Format(Strings.ksNoColorUnderline, sColor); - break; - case FwUnderlineType.kuntSingle: - sUnder = String.Format(Strings.ksSingleColorUnderline, sColor); - break; - case FwUnderlineType.kuntDouble: - sUnder = String.Format(Strings.ksDoubleColorUnderline, sColor); - break; - case FwUnderlineType.kuntDotted: - sUnder = String.Format(Strings.ksDottedColorUnderline, sColor); - break; - case FwUnderlineType.kuntDashed: - sUnder = String.Format(Strings.ksDashedColorUnderline, sColor); - break; - case FwUnderlineType.kuntStrikethrough: - sUnder = String.Format(Strings.ksColorStrikethrough, sColor); - break; - } - } - else - { - sUnder = String.Format(Strings.ksColorUnderline, sColor); - } - } - else if (m_underline.IsExplicit) - { - switch (m_underline.Value) - { - case FwUnderlineType.kuntNone: - sUnder = Strings.ksNoUnderline; - break; - case FwUnderlineType.kuntSingle: - sUnder = Strings.ksSingleUnderline; - break; - case FwUnderlineType.kuntDouble: - sUnder = Strings.ksDoubleUnderline; - break; - case FwUnderlineType.kuntDotted: - sUnder = Strings.ksDottedUnderline; - break; - case FwUnderlineType.kuntDashed: - sUnder = Strings.ksDashedUnderline; - break; - case FwUnderlineType.kuntStrikethrough: - sUnder = Strings.ksStrikethrough; - break; - } - } - AppendToString(text, sUnder); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Appends the superscript/subscript information to the description - /// - /// The text. - /// The superscript/subscript val. - /// ------------------------------------------------------------------------------------ - private void AppendSuperSub(StringBuilder text, FwSuperscriptVal value) - { - switch (value) - { - case FwSuperscriptVal.kssvOff: - AppendToString(text, Strings.ksNoSuperSubscript); - break; - case FwSuperscriptVal.kssvSub: - AppendToString(text, Strings.ksSubscript); - break; - case FwSuperscriptVal.kssvSuper: - AppendToString(text, Strings.ksSuperscript); - break; - } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Appends the font offset information to the description - /// - /// The text. - /// The value. - /// ------------------------------------------------------------------------------------ - private void AppendFontOffset(StringBuilder text, int value) - { - if (value > 0) - AppendToString(text, string.Format(Strings.ksRaisedXpt, value / 1000)); - else if (value < 0) - AppendToString(text, string.Format(Strings.ksLoweredXpt, -value / 1000)); - else - AppendToString(text, Strings.ksNotRaisedLowered); - - } - - /// ------------------------------------------------------------------------------------ - /// - /// Appends to string. - /// - /// The text. - /// The value. - /// ------------------------------------------------------------------------------------ - private void AppendToString(StringBuilder text, string value) - { - if (text.Length > 0) - text.Append(Strings.ksListSep); - text.Append(value); - } - #endregion - /// Name of font to use public IStyleProp FontName { diff --git a/Src/FDO/DomainServices/FwProjectFinder.cs b/Src/FDO/DomainServices/FwProjectFinder.cs index 10db97dcc3..63f7e3a9e5 100644 --- a/Src/FDO/DomainServices/FwProjectFinder.cs +++ b/Src/FDO/DomainServices/FwProjectFinder.cs @@ -7,10 +7,7 @@ using System; using System.IO; -using System.Net; using System.Threading; -using SIL.FieldWorks.Common.FwUtils; -using SIL.FieldWorks.Resources; using SIL.Utils; namespace SIL.FieldWorks.FDO.DomainServices @@ -28,6 +25,7 @@ internal class FwProjectFinder private readonly Action m_projectFoundCallback; private readonly Action m_onCompletedCallback; private volatile bool m_forceStop = false; + private readonly string m_projectsDir; /// ------------------------------------------------------------------------------------ /// @@ -38,9 +36,10 @@ internal class FwProjectFinder /// Callback to run when the search is completed. /// The exception callback. /// true if we want to show local fwdata projects + /// The projects directory. /// ------------------------------------------------------------------------------------ public FwProjectFinder(string host, Action projectFoundCallback, - Action onCompletedCallback, Action exceptionCallback, bool showLocalProjects) + Action onCompletedCallback, Action exceptionCallback, bool showLocalProjects, string projectsDir) { if (string.IsNullOrEmpty(host)) throw new ArgumentNullException("host"); @@ -52,6 +51,7 @@ public FwProjectFinder(string host, Action projectFoundCallback, m_onCompletedCallback = onCompletedCallback; m_exceptionCallback = exceptionCallback; m_fShowLocalProjects = showLocalProjects; + m_projectsDir = projectsDir; m_projectFinderThread = new Thread(FindProjects); m_projectFinderThread.Name = "Project Finder"; @@ -75,21 +75,21 @@ private void FindProjects() if (m_fShowLocalProjects) { // search sub dirs - string[] dirs = Directory.GetDirectories(DirectoryFinder.ProjectsDirectory); + string[] dirs = Directory.GetDirectories(m_projectsDir); foreach (string dir in dirs) { - string file = Path.Combine(dir, DirectoryFinder.GetXmlDataFileName(Path.GetFileName(dir))); + string file = Path.Combine(dir, FdoFileHelper.GetXmlDataFileName(Path.GetFileName(dir))); if (FileUtils.SimilarFileExists(file)) m_projectFoundCallback(file); else { - string db4oFile = Path.Combine(dir, DirectoryFinder.GetDb4oDataFileName(Path.GetFileName(dir))); + string db4oFile = Path.Combine(dir, FdoFileHelper.GetDb4oDataFileName(Path.GetFileName(dir))); //If the db4o file exists it will be added to the list later and therefore we do not want to //show the .bak file to the user in the open project dialog if (!FileUtils.SimilarFileExists(db4oFile)) { // See if there is a .bak file - string backupFile = Path.ChangeExtension(file, FwFileExtensions.ksFwDataFallbackFileExtension); + string backupFile = Path.ChangeExtension(file, FdoFileHelper.ksFwDataFallbackFileExtension); //NOTE: RickM I think this probably should be changed to TrySimilarFileExists but don't want to try this //on a release build. if (FileUtils.SimilarFileExists(backupFile)) diff --git a/Src/FDO/DomainServices/FwStyleSheet.cs b/Src/FDO/DomainServices/FwStyleSheet.cs index 38441c9323..8517eb3d95 100644 --- a/Src/FDO/DomainServices/FwStyleSheet.cs +++ b/Src/FDO/DomainServices/FwStyleSheet.cs @@ -26,7 +26,6 @@ using System.Diagnostics; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.FDO.Application; -using SIL.FieldWorks.Resources; using SIL.Utils; namespace SIL.FieldWorks.FDO.DomainServices @@ -115,7 +114,7 @@ public class StyleInfoCollection : KeyedCollection { /// -------------------------------------------------------------------------------- /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// -------------------------------------------------------------------------------- public StyleInfoCollection() @@ -152,6 +151,7 @@ protected override string GetKeyForItem(BaseStyleInfo item) /// The field ID of the owner(m_hvoStylesOwner)'s collection of StStyles. private int m_tagStylesList; private FwStyleSheet m_styleSheetWithUiStyle; + private string m_defaultParaCharsStyleName; /// Collection of styles protected StyleInfoCollection m_StyleInfos; @@ -184,7 +184,7 @@ private FwStyleSheet StyleSheetWithUiStyle else { m_styleSheetWithUiStyle = new FwStyleSheet(); - m_styleSheetWithUiStyle.Init(Cache, Cache.LangProject.Hvo, LangProjectTags.kflidStyles); + m_styleSheetWithUiStyle.Init(Cache, Cache.LangProject.Hvo, LangProjectTags.kflidStyles, m_defaultParaCharsStyleName); } } return m_styleSheetWithUiStyle; @@ -259,19 +259,21 @@ public StyleInfoCollection Styles #endregion #region Constructor, Init, Load - /// -------------------------------------------------------------------------------------------- - /// - /// FwStyleSheet.Init() sets the FdoCache, the hvo of the owning object, and the tag - /// specifying the owner's property which holds the collection of StStyle objects. - /// Then the internal collections are loaded. - /// + + /// -------------------------------------------------------------------------------------------- + /// + /// FwStyleSheet.Init() sets the FdoCache, the hvo of the owning object, and the tag + /// specifying the owner's property which holds the collection of StStyle objects. + /// Then the internal collections are loaded. + /// /// - /// the FDO cache - /// the owning object - /// the owner(hvoStylesOwner)'s field ID which holds the collection - /// of StStyle objects + /// the FDO cache + /// the owning object + /// the owner(hvoStylesOwner)'s field ID which holds the collection + /// of StStyle objects + /// The default paragraph characters style name. /// -------------------------------------------------------------------------------------------- - public void Init(FdoCache cache, int hvoStylesOwner, int tagStylesList) + public void Init(FdoCache cache, int hvoStylesOwner, int tagStylesList, string defaultParaCharsStyleName) { m_fdoCache = cache; m_hvoStylesOwner = hvoStylesOwner; @@ -462,7 +464,7 @@ public int GetType(string sName) if (style != null) return (int)style.Type; - if (sName == kstrDefaultCharStyle || sName == ResourceHelper.DefaultParaCharsStyleName) + if (sName == kstrDefaultCharStyle || sName == m_defaultParaCharsStyleName) return (int)StyleType.kstCharacter; return 0; //ThrowInternalError(E_INVALIDARG); @@ -926,7 +928,7 @@ private LgCharRenderProps GetStyleChrps(string stylename, int ws, ILgWritingSyst // that the property store does not implement IVwPropertyStore. See FWR-1918. // Some more sophisticated trick may be needed if it is ever the case that the stylesheet // is NOT created on the main UI thread. - return m_fdoCache.ThreadHelper.Invoke(() => GetChrps(ws, ttp, wsf)); + return m_fdoCache.ServiceLocator.GetInstance().SynchronizeInvoke.Invoke(() => GetChrps(ws, ttp, wsf)); } /// ------------------------------------------------------------------------------------ @@ -992,10 +994,8 @@ public virtual IStStyle FindStyle(string name) /// called for a style already known to exist in the stylesheet. /// /// The style info table, containing 0 or more new styles - /// Name of the application calling this (or whatever - /// string you want to appear in a message box if we happen to show one). /// ------------------------------------------------------------------------------------ - public void CheckForDuplicates(StyleInfoTable styleInfoTable, string applicationName) + public void CheckForDuplicates(StyleInfoTable styleInfoTable) { bool fStylesheetReloaded = false; @@ -1022,11 +1022,10 @@ public void CheckForDuplicates(StyleInfoTable styleInfoTable, string application basedOn.Structure != style.Structure || basedOn.Function != style.Function) { - string sMsg = string.Format( - ResourceHelper.GetResourceString("kstidIncompatibleStyleExists"), - style.Name); - MessageBoxUtils.Show(sMsg, applicationName); styleInfo.IsValid = false; + throw new IncompatibleStyleExistsException(string.Format( + Strings.ksIncompatibleStyleExists, + style.Name)); } else { @@ -1583,4 +1582,18 @@ public override void Delete(int hvoStyle) } #endregion } + + /// + /// Exception for handling case when an incompatible style already exists + /// + public class IncompatibleStyleExistsException : Exception + { + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + public IncompatibleStyleExistsException(string message) : base(message) + { + } + } } diff --git a/Src/FDO/DomainServices/IScrImportFileInfo.cs b/Src/FDO/DomainServices/IScrImportFileInfo.cs index 1691fa296a..5dcd066994 100644 --- a/Src/FDO/DomainServices/IScrImportFileInfo.cs +++ b/Src/FDO/DomainServices/IScrImportFileInfo.cs @@ -75,7 +75,7 @@ public interface IScrImportFileInfo /// (only used for Note sources) /// /// ------------------------------------------------------------------------------------ - SIL.FieldWorks.FDO.ICmAnnotationDefn NoteType { get; } + ICmAnnotationDefn NoteType { get; } /// ------------------------------------------------------------------------------------ /// @@ -111,5 +111,18 @@ public interface IScrImportFileInfo /// /// ------------------------------------------------------------------------------------ SILUBS.SharedScrUtils.ScrReference StartRef { get; } + + /// ------------------------------------------------------------------------------------ + /// + /// Rechecks the accessibility of a file that might have been initially determined to + /// be inaccessible. If the file was inaccessible but is now accessible, it will be + /// properly initialized so all the cached info will be valid. + /// + /// Use to recheck accessibility of a file + /// that was initially determined to be accessible. Use to + /// access the cached value. + /// true if the file is currently accessible + /// ------------------------------------------------------------------------------------ + bool RecheckAccessibility(); } } diff --git a/Src/FDO/DomainServices/ITextUtils.cs b/Src/FDO/DomainServices/ITextUtils.cs index 077fac15a6..b32af534b9 100644 --- a/Src/FDO/DomainServices/ITextUtils.cs +++ b/Src/FDO/DomainServices/ITextUtils.cs @@ -10,7 +10,6 @@ using System.Collections.Generic; using System.Linq; using System.Diagnostics; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.Common.ScriptureUtils; using SIL.FieldWorks.FDO.DomainImpl; diff --git a/Src/FDO/DomainServices/M3ModelExportServices.cs b/Src/FDO/DomainServices/M3ModelExportServices.cs index dba93406f6..0d774a88f4 100644 --- a/Src/FDO/DomainServices/M3ModelExportServices.cs +++ b/Src/FDO/DomainServices/M3ModelExportServices.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Xml.Linq; using Microsoft.Practices.ServiceLocation; @@ -51,9 +50,8 @@ public static void ExportGrammarSketch(string outputPath, ILangProject languageP /// /// Export the grammar and lexicon. /// - public static void ExportGrammarAndLexicon(string outputPath, ILangProject languageProject) + public static XDocument ExportGrammarAndLexicon(ILangProject languageProject) { - if (string.IsNullOrEmpty(outputPath)) throw new ArgumentNullException("outputPath"); if (languageProject == null) throw new ArgumentNullException("languageProject"); var servLoc = languageProject.Cache.ServiceLocator; @@ -76,7 +74,7 @@ public static void ExportGrammarAndLexicon(string outputPath, ILangProject langu ExportFeatureSystem(languageProject.PhFeatureSystemOA, "PhFeatureSystem", mode) ) ); - doc.Save(outputPath); + return doc; } private static XElement ExportLanguageProject(ILangProject languageProject, Icu.UNormalizationMode mode) @@ -127,12 +125,12 @@ static bool IsValidTemplate(IMoInflAffixTemplate template) return (from affixSlot in template.PrefixSlotsRS.Concat(template.SuffixSlotsRS) where IsValidSlot(affixSlot) - select affixSlot).Take(1).Count() > 0; + select affixSlot).Take(1).Any(); } private static bool IsValidSlot(IMoInflAffixSlot affixSlot) { - return affixSlot.Affixes.Take(1).Count() > 0; + return affixSlot.Affixes.Take(1).Any(); } @@ -316,7 +314,7 @@ private static XElement ExportLexiconFull(IServiceLocator servLoc, Icu.UNormaliz { return new XElement("Lexicon", ExportEntries(servLoc.GetInstance()), - ExportMSAs(servLoc), + ExportMsas(servLoc), ExportSenses(servLoc.GetInstance(), mode), ExportAllomorphs(servLoc, mode)); } @@ -346,7 +344,7 @@ from lexEntryInflType in lexEntryRef.VariantEntryTypesRS select ExportItemAsReference(lexEntryInflType, "LexEntryInflType")))); } - private static XElement ExportMSAs(IServiceLocator servLoc) + private static XElement ExportMsas(IServiceLocator servLoc) { return new XElement("MorphoSyntaxAnalyses", from stemMsa in servLoc.GetInstance().AllInstances() @@ -503,9 +501,9 @@ private static XElement ExportPhonRuleFeat(IPhPhonRuleFeat phonRuleFeat, Icu.UNo private static XElement ExportPhonRule(IPhSegmentRule phonRule, Icu.UNormalizationMode mode) { - XElement retVal = null; if (phonRule.Disabled) - return retVal; + return null; + XElement retVal = null; switch (phonRule.ClassName) { case "PhMetathesisRule": @@ -930,10 +928,8 @@ from insertContent in insertPhones.ContentRS /// /// Export everything needed by parsers for GAFAWS data. /// - public static void ExportGafaws(string outputFolder, string databaseName, ICollection partsOfSpeech) + public static XDocument ExportGafaws(IEnumerable partsOfSpeech) { - if (string.IsNullOrEmpty(outputFolder)) throw new ArgumentNullException("outputFolder"); - if (string.IsNullOrEmpty(databaseName)) throw new ArgumentNullException("databaseName"); if (partsOfSpeech == null) throw new ArgumentNullException("partsOfSpeech"); var doc = new XDocument( @@ -942,7 +938,7 @@ public static void ExportGafaws(string outputFolder, string databaseName, IColle new XElement("PartsOfSpeech", from IPartOfSpeech pos in partsOfSpeech select ExportPartOfSpeechGafaws("PartOfSpeech", pos)))); - doc.Save(Path.Combine(outputFolder, databaseName + "GAFAWSFxtResult.xml")); + return doc; } /// diff --git a/Src/FDO/DomainServices/ProjectLockingService.cs b/Src/FDO/DomainServices/ProjectLockingService.cs index 2d71ae15ec..037ab3b06d 100644 --- a/Src/FDO/DomainServices/ProjectLockingService.cs +++ b/Src/FDO/DomainServices/ProjectLockingService.cs @@ -17,12 +17,7 @@ public static void LockCurrentProject(FdoCache cache) // Make sure any changes we want backup are saved. var ds = cache.ServiceLocator.GetInstance() as XMLBackendProvider; if (ds != null) - { - // REVIEW (EberhardB): I'm not sure this works as intended: XMLBackendProvider.LockProject - // returns a FileStream, but XMLBackendProvider.UnlockProject works on a private - // variable. - using (XMLBackendProvider.LockProject(cache.ProjectId.Path)) { } - } + ds.LockProject(); } /// diff --git a/Src/FDO/DomainServices/ScrChecksDataSource.cs b/Src/FDO/DomainServices/ScrChecksDataSource.cs index 654825328f..d6e2898fe7 100644 --- a/Src/FDO/DomainServices/ScrChecksDataSource.cs +++ b/Src/FDO/DomainServices/ScrChecksDataSource.cs @@ -13,7 +13,6 @@ using SIL.FieldWorks.Common.ScriptureUtils; using SIL.Utils; using SILUBS.SharedScrUtils; -using SIL.FieldWorks.Resources; using SIL.CoreImpl; namespace SIL.FieldWorks.FDO.DomainServices @@ -46,6 +45,8 @@ public class ScrChecksDataSource : IChecksDataSource private readonly FdoCache m_cache; private readonly IScripture m_scr; private readonly string m_styleSheetFileName; + private readonly string m_punctWhitespaceChar; + private readonly string m_legacyOverridesFile; private static StyleMarkupInfo s_styleMarkupInfo = null; @@ -56,26 +57,32 @@ public class ScrChecksDataSource : IChecksDataSource /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The cache. + /// + /// /// ------------------------------------------------------------------------------------ - public ScrChecksDataSource(FdoCache cache) : this(cache, null) + public ScrChecksDataSource(FdoCache cache, string punctWhitespaceChar, string legacyOverridesFile) : this(cache, punctWhitespaceChar, legacyOverridesFile, null) { } /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The cache. + /// + /// /// Path to the stylesheet definition XML file /// ------------------------------------------------------------------------------------ - public ScrChecksDataSource(FdoCache cache, string styleSheetFileName) + public ScrChecksDataSource(FdoCache cache, string punctWhitespaceChar, string legacyOverridesFile, string styleSheetFileName) { m_cache = cache; m_scr = cache.LangProject.TranslatedScriptureOA; + m_punctWhitespaceChar = punctWhitespaceChar; m_styleSheetFileName = styleSheetFileName; + m_legacyOverridesFile = legacyOverridesFile; } /// ------------------------------------------------------------------------------------ @@ -169,7 +176,7 @@ public string GetParameterValue(string key) return "Intermediate"; case "PunctWhitespaceChar": - return ResourceHelper.GetResourceString("kstidPunctCheckWhitespaceChar").Substring(0, 1); + return m_punctWhitespaceChar.Substring(0, 1); case "MatchedPairs": return ws.MatchedPairs; @@ -698,7 +705,7 @@ private string GetValidCharactersList(string key, IWritingSystem ws) return bldr.ToString(); } - var validChars = ValidCharacters.Load(ws, LoadException ?? NoErrorReport); + var validChars = ValidCharacters.Load(ws, LoadException ?? NoErrorReport, m_legacyOverridesFile); return (validChars != null ? validChars.SpaceDelimitedList : string.Empty); } @@ -713,7 +720,7 @@ private ValidCharacters ValidCharacters { // Get the writing system and valid characters list return ValidCharacters.Load(m_cache.ServiceLocator.WritingSystemManager.Get(m_cache.DefaultVernWs), - LoadException ?? NoErrorReport); + LoadException ?? NoErrorReport, m_legacyOverridesFile); } } diff --git a/Src/FDO/DomainServices/ScrImportFileInfo.cs b/Src/FDO/DomainServices/ScrImportFileInfo.cs index c483f7fb8f..498db95f43 100644 --- a/Src/FDO/DomainServices/ScrImportFileInfo.cs +++ b/Src/FDO/DomainServices/ScrImportFileInfo.cs @@ -495,7 +495,7 @@ protected virtual void GuessFileEncoding() /// access the cached value. /// true if the file is currently accessible /// ------------------------------------------------------------------------------------ - internal bool RecheckAccessibility() + public bool RecheckAccessibility() { if (IsReadable) return IsStillReadable; diff --git a/Src/FDO/DomainServices/ScrMappingList.cs b/Src/FDO/DomainServices/ScrMappingList.cs index 848a0daf95..d837fe44e2 100644 --- a/Src/FDO/DomainServices/ScrMappingList.cs +++ b/Src/FDO/DomainServices/ScrMappingList.cs @@ -11,9 +11,7 @@ using System.Diagnostics.CodeAnalysis; using System.Xml; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Resources; using SIL.FieldWorks.Common.ScriptureUtils; -using SIL.FieldWorks.Common.FwUtils; namespace SIL.FieldWorks.FDO.DomainServices { @@ -32,6 +30,9 @@ public class ScrMappingList : IEnumerable private IVwStylesheet m_stylesheet; + private readonly string m_defaultParaCharsStyleName; + private readonly string m_stylesPath; + private static Dictionary s_defaultMappings = new Dictionary(); private static Dictionary s_defaultProperties = new Dictionary(); private static Dictionary s_defaultExclusions = new Dictionary(); @@ -47,6 +48,7 @@ public class ScrMappingList : IEnumerable #endregion #region Constructor + /// ------------------------------------------------------------------------------------ /// /// Initializes a new instance of the class. @@ -54,11 +56,16 @@ public class ScrMappingList : IEnumerable /// Indicates which type of mapping group this list represents /// /// The stylesheet + /// + /// /// ------------------------------------------------------------------------------------ - public ScrMappingList(MappingSet mappingSet, IVwStylesheet stylesheet) + public ScrMappingList(MappingSet mappingSet, IVwStylesheet stylesheet, string defaultParaCharsStyleName, + string stylesPath) { m_mappingSet = mappingSet; m_stylesheet = stylesheet; + m_defaultParaCharsStyleName = defaultParaCharsStyleName; + m_stylesPath = stylesPath; } #endregion @@ -412,6 +419,7 @@ public IVwStylesheet StyleSheet get { return m_stylesheet; } set { m_stylesheet = value; } } + #endregion #region Private methods @@ -422,10 +430,10 @@ public IVwStylesheet StyleSheet /// ------------------------------------------------------------------------------------ [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", Justification = "In .NET 4.5 XmlNodeList implements IDisposable, but not in 4.0.")] - private static void ReadDefaultMappings() + private void ReadDefaultMappings() { XmlDocument doc = new XmlDocument(); - doc.Load(DirectoryFinder.TeStylesPath); + doc.Load(m_stylesPath); XmlNode mappingNode = doc.SelectSingleNode("Styles/ImportMappingSets/ImportMapping[@name='TE Default']"); foreach (XmlNode mapNode in mappingNode.SelectNodes("mapping")) { @@ -520,12 +528,12 @@ private bool GetDefaultMapping(string marker, out string styleName, out bool exc case "DefaultParagraphCharacters": target = MappingTargetType.TEStyle; - styleName = ResourceHelper.DefaultParaCharsStyleName; + styleName = m_defaultParaCharsStyleName; return true; case "DefaultFootnoteCharacters": target = MappingTargetType.TEStyle; - styleName = ResourceHelper.DefaultParaCharsStyleName; + styleName = m_defaultParaCharsStyleName; markerDomain = MarkerDomain.Footnote; return true; } diff --git a/Src/FDO/DomainServices/ScrSfFileList.cs b/Src/FDO/DomainServices/ScrSfFileList.cs index 4d8ed4df0b..dfdab6233f 100644 --- a/Src/FDO/DomainServices/ScrSfFileList.cs +++ b/Src/FDO/DomainServices/ScrSfFileList.cs @@ -10,10 +10,8 @@ using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; -using System.Windows.Forms; using SIL.FieldWorks.Common.ScriptureUtils; using SILUBS.SharedScrUtils; -using SIL.Utils; namespace SIL.FieldWorks.FDO.DomainServices { @@ -81,7 +79,6 @@ public class ScrSfFileList : ArrayList /// An Overlapping File Resolver /// ------------------------------------------------------------------------------------ public ScrSfFileList(IOverlappingFileResolver resolver) - : base() { m_resolver = resolver; } @@ -99,13 +96,12 @@ public ScrSfFileList(IOverlappingFileResolver resolver) /// in the middle of lines. (Toolbox dictates that fields tagged with backslash markers /// must start on a new line, but Paratext considers all backslashes in the data to be /// SF markers.) - /// The path of the application help file. /// ------------------------------------------------------------------------------------ public ScrSfFileList(IScrImportSFFiles source, ScrMappingList mappingList, - ImportDomain importDomain, bool scanInlineBackslashMarkers, string helpFile) + ImportDomain importDomain, bool scanInlineBackslashMarkers) : this(null) { - List deleteList = new List(); + var deleteList = new List(); // Load the files into an in-memory list foreach (ICmFile file in source.FilesOC) { @@ -117,8 +113,8 @@ public ScrSfFileList(IScrImportSFFiles source, ScrMappingList mappingList, } catch (ScriptureUtilsException e) { - MessageBoxUtils.Show(string.Format(ScrFdoResources.kstidImportBadFile, e.Message), "", MessageBoxButtons.OK, - MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0, helpFile, HelpNavigator.Topic, e.HelpTopic); + var userAction = source.Services.GetInstance(); + userAction.DisplayMessage(MessageType.Error, string.Format(ScrFdoResources.kstidImportBadFile, e.Message), Strings.ksErrorCaption, e.HelpTopic); deleteList.Add(file); } } diff --git a/Src/FDO/DomainServices/SharedBackendServices.cs b/Src/FDO/DomainServices/SharedBackendServices.cs new file mode 100644 index 0000000000..34a56fbd36 --- /dev/null +++ b/Src/FDO/DomainServices/SharedBackendServices.cs @@ -0,0 +1,26 @@ +// Copyright (c) 2013-2014 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) + +using SIL.FieldWorks.FDO.Infrastructure; +using SIL.FieldWorks.FDO.Infrastructure.Impl; + +namespace SIL.FieldWorks.FDO.DomainServices +{ + /// + /// Services for shared backends + /// + public static class SharedBackendServices + { + /// + /// Indicates if there are multiple applications that are currently using this project. + /// + public static bool AreMultipleApplicationsConnected(FdoCache cache) + { + var sharedBep = cache.ServiceLocator.GetInstance() as SharedXMLBackendProvider; + if (sharedBep != null) + return sharedBep.OtherApplicationsConnectedCount > 0; + return false; + } + } +} diff --git a/Src/FDO/DomainServices/StTxtParaBldr.cs b/Src/FDO/DomainServices/StTxtParaBldr.cs index 395bff7780..2505060f77 100644 --- a/Src/FDO/DomainServices/StTxtParaBldr.cs +++ b/Src/FDO/DomainServices/StTxtParaBldr.cs @@ -10,10 +10,7 @@ // using System; -using System.Runtime.InteropServices; // needed for Marshal using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; -using SIL.Utils; using SIL.CoreImpl; namespace SIL.FieldWorks.FDO.DomainServices diff --git a/Src/FDO/DomainServices/StringServices.cs b/Src/FDO/DomainServices/StringServices.cs index d32db086fc..af750c07f1 100644 --- a/Src/FDO/DomainServices/StringServices.cs +++ b/Src/FDO/DomainServices/StringServices.cs @@ -11,7 +11,6 @@ using System.Xml; using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.Application; using SIL.FieldWorks.FDO.DomainImpl; using SIL.FieldWorks.FDO.Infrastructure; @@ -74,7 +73,7 @@ public static void MarkTextInBldrAsHyperlink(ITsStrBldr strBldr, int ichStart, public static string MarkTextInBldrAsHyperlink(ITsStrBldr strBldr, int ichStart, int ichLim, string url, IStStyle linkStyle, string linkedFilesRootDir) { - var relativeUrl = DirectoryFinderRelativePaths.GetRelativeLinkedFilesPath(url, linkedFilesRootDir); + var relativeUrl = LinkedFilesRelativePathHelper.GetRelativeLinkedFilesPath(url, linkedFilesRootDir); if (string.IsNullOrEmpty(relativeUrl)) { MarkTextInBldrAsHyperlink(strBldr, ichStart, ichLim, url, linkStyle); diff --git a/Src/FDO/DomainServices/ValidCharacters.cs b/Src/FDO/DomainServices/ValidCharacters.cs index 25dc4f25e0..1c112e600f 100644 --- a/Src/FDO/DomainServices/ValidCharacters.cs +++ b/Src/FDO/DomainServices/ValidCharacters.cs @@ -7,13 +7,11 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Text; using System.IO; using System.Xml; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.Utils; using System.Xml.Serialization; using SIL.CoreImpl; @@ -93,6 +91,7 @@ public class ValidCharacters private List m_OtherCharacters; private ILgCharacterPropertyEngine m_cpe; private TsStringComparer m_comparer; + private string m_legacyOverridesFile; #endregion @@ -119,6 +118,7 @@ protected ValidCharacters() } #region Methods and Properties to load and initialize the class + /// ------------------------------------------------------------------------------------ /// /// Loads the valid characters from the specified language definition into a new @@ -127,13 +127,14 @@ protected ValidCharacters() /// The writing system. /// The exception handler to use if valid character data /// cannot be loaded. + /// /// A initialized with the valid characters data /// from the language definition. /// ------------------------------------------------------------------------------------ - public static ValidCharacters Load(IWritingSystem ws, LoadExceptionDelegate exceptionHandler) + public static ValidCharacters Load(IWritingSystem ws, LoadExceptionDelegate exceptionHandler, string legacyOverridesFile) { ValidCharacters validChars = Load(ws.ValidChars, ws.DisplayLabel, ws, - exceptionHandler); + exceptionHandler, legacyOverridesFile); if (validChars != null) validChars.InitSortComparer(ws); @@ -150,10 +151,11 @@ public static ValidCharacters Load(IWritingSystem ws, LoadExceptionDelegate exce /// The writing system /// The exception handler to use if valid character data /// cannot be loaded. + /// /// /// ------------------------------------------------------------------------------------ public static ValidCharacters Load(string xmlSrc, string wsName, - IWritingSystem ws, LoadExceptionDelegate exceptionHandler) + IWritingSystem ws, LoadExceptionDelegate exceptionHandler, string legacyOverridesFile) { Exception e; var validChars = XmlSerializationHelper.DeserializeFromString(xmlSrc, out e); @@ -161,7 +163,9 @@ public static ValidCharacters Load(string xmlSrc, string wsName, bool fTryOldStyleList = false; if (validChars != null) + { validChars.LoadException += exceptionHandler; + } else { validChars = new ValidCharacters(); @@ -171,14 +175,14 @@ public static ValidCharacters Load(string xmlSrc, string wsName, if (!fTryOldStyleList && !String.IsNullOrEmpty(xmlSrc)) { var bldr = new StringBuilder(); - bldr.AppendFormat("Invalid ValidChars field while loading the {0} writing system:", - wsName); + bldr.AppendFormat("Invalid ValidChars field while loading the {0} writing system:", wsName); bldr.Append(Environment.NewLine); bldr.Append("\t"); bldr.Append(xmlSrc); validChars.ReportError(new ArgumentException(bldr.ToString(), "xmlSrc", e)); } } + validChars.m_legacyOverridesFile = legacyOverridesFile; List invalidChars = validChars.Init(); @@ -284,15 +288,13 @@ private List Init() /// Gets the default word forming overrides. /// /// ------------------------------------------------------------------------------------ - private static IEnumerable DefaultWordFormingOverrides + private IEnumerable DefaultWordFormingOverrides { get { if (s_fTestingMode) return s_defaultWordformingChars; - string legacyOverrides = Path.Combine(DirectoryFinder.FWCodeDirectory, - "WordFormingCharOverrides.xml"); - return ParseLegacyWordFormingCharOverrides(legacyOverrides) ?? + return ParseLegacyWordFormingCharOverrides(m_legacyOverridesFile) ?? (IEnumerable)s_defaultWordformingChars; } } diff --git a/Src/FDO/DomainServices/WfiWordformServices.cs b/Src/FDO/DomainServices/WfiWordformServices.cs index 8a7edfe56d..105441a609 100644 --- a/Src/FDO/DomainServices/WfiWordformServices.cs +++ b/Src/FDO/DomainServices/WfiWordformServices.cs @@ -12,12 +12,10 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using System.Windows.Forms; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.CoreImpl; using SIL.FieldWorks.FDO.DomainImpl; -using Sharpen.Util; +using SIL.Utils; namespace SIL.FieldWorks.FDO.DomainServices { @@ -202,7 +200,7 @@ public static IPunctuationForm FindOrCreatePunctuationform(FdoCache cache, ITsSt /// /// /// A string containing a list of wordforms that could not be merged because they have differing values for other WSs - public static string FixDuplicates(FdoCache cache, ProgressBar progressBar) + public static string FixDuplicates(FdoCache cache, IProgress progressBar) { var failures = new HashSet(); var wfRepo = cache.ServiceLocator.GetInstance(); @@ -210,10 +208,10 @@ public static string FixDuplicates(FdoCache cache, ProgressBar progressBar) var wfiWordforms = wfRepo.AllInstances().ToArray(); progressBar.Minimum = 0; progressBar.Maximum = wfiWordforms.Length; - progressBar.Step = 1; + progressBar.StepSize = 1; foreach (var wf in wfiWordforms) { - progressBar.PerformStep(); + progressBar.Step(1); var text = wf.Form.VernacularDefaultWritingSystem.Text; if (string.IsNullOrEmpty(text)) continue; @@ -284,15 +282,15 @@ public static string FixDuplicates(FdoCache cache, ProgressBar progressBar) /// Merge duplicate analyses on all wordforms. (Also merges duplicate WfiGlosses.) /// /// - public static void MergeDuplicateAnalyses(FdoCache cache, ProgressBar progressBar) + public static void MergeDuplicateAnalyses(FdoCache cache, IProgress progressBar) { var wfiWordforms = cache.ServiceLocator.GetInstance().AllInstances().ToList(); progressBar.Minimum = 0; progressBar.Maximum = wfiWordforms.Count; - progressBar.Step = 1; + progressBar.StepSize = 1; foreach (var wf in wfiWordforms) { - progressBar.PerformStep(); + progressBar.Step(1); var analyses = wf.AnalysesOC.ToList(); for (int i = 0; i < analyses.Count; i++) { diff --git a/Src/FDO/DomainServices/WritingSystemServices.cs b/Src/FDO/DomainServices/WritingSystemServices.cs index 6f8a989890..af76ddff45 100644 --- a/Src/FDO/DomainServices/WritingSystemServices.cs +++ b/Src/FDO/DomainServices/WritingSystemServices.cs @@ -1329,12 +1329,13 @@ private static List AnalysisVernacularWss(FdoCache cache, bool f /// to the requested collection(s). /// /// The cache. + /// The template directory. /// The identifier. /// if set to true ***new*** writing systems will be added to the list of analysis writing systems. /// if set to true ***new*** writing systems will be added to the list of vernacular writing systems. /// The writing system. /// true if the writing system already exists, false if it had to be created - public static bool FindOrCreateWritingSystem(FdoCache cache, string identifier, bool addAnalWss, bool addVernWss, out IWritingSystem ws) + public static bool FindOrCreateWritingSystem(FdoCache cache, string templateDir, string identifier, bool addAnalWss, bool addVernWss, out IWritingSystem ws) { if (cache.ServiceLocator.WritingSystemManager.GetOrSet(identifier, out ws)) return true; @@ -1346,7 +1347,8 @@ public static bool FindOrCreateWritingSystem(FdoCache cache, string identifier, // If the new writing system is one for which we have localized versions of lists, import them. // We can't easily put up a progress dialog here, because the code is in a project we can't reference. // However this routine is used in relatively long operations anyway so there should already be some kind of progress bar. - XmlTranslatedLists.ImportTranslatedListsForWs(identifier, cache, null); + if (templateDir != null) + XmlTranslatedLists.ImportTranslatedListsForWs(identifier, cache, templateDir, null); return false; } @@ -1357,7 +1359,7 @@ public static bool FindOrCreateWritingSystem(FdoCache cache, string identifier, /// systems if the appropriate flag is set. /// /// true if the writing system already exists, false if it had to be created - public static bool FindOrCreateSomeWritingSystem(FdoCache cache, string identifier, bool addAnalWss, bool addVernWss, out IWritingSystem ws) + public static bool FindOrCreateSomeWritingSystem(FdoCache cache, string templateDir, string identifier, bool addAnalWss, bool addVernWss, out IWritingSystem ws) { if (cache.ServiceLocator.WritingSystemManager.TryGet(identifier, out ws)) return true; @@ -1368,12 +1370,12 @@ public static bool FindOrCreateSomeWritingSystem(FdoCache cache, string identifi if (LangTagUtils.GetSubtags(identifier, out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag)) { // It's a good identifier; we can do this straightforwardly. - return FindOrCreateWritingSystem(cache, identifier, addAnalWss, addVernWss, out ws); + return FindOrCreateWritingSystem(cache, templateDir, identifier, addAnalWss, addVernWss, out ws); } // See if we can convert an old-style identifier to a new one. string newIdentifier = LangTagUtils.ToLangTag(identifier); if (LangTagUtils.GetSubtags(identifier, out languageSubtag, out scriptSubtag, out regionSubtag, out variantSubtag)) - return FindOrCreateWritingSystem(cache, newIdentifier, addAnalWss, addVernWss, out ws); + return FindOrCreateWritingSystem(cache, templateDir, newIdentifier, addAnalWss, addVernWss, out ws); // No, it's nothing we know how to deal with. Get drastic. @@ -1392,7 +1394,7 @@ public static bool FindOrCreateSomeWritingSystem(FdoCache cache, string identifi parts = new [] {"qaa"}.Concat(parts); // Can't start with x, we always use qaa for unknown WS. newIdentifier = parts.Aggregate((first, second) => first + "-" + second); // This should now qualify as a private-use writing system identifier. - return FindOrCreateWritingSystem(cache, newIdentifier, addAnalWss, addVernWss, out ws); + return FindOrCreateWritingSystem(cache, templateDir, newIdentifier, addAnalWss, addVernWss, out ws); } /// diff --git a/Src/FDO/FDO.csproj b/Src/FDO/FDO.csproj index c2167a033f..904b7ff3b8 100644 --- a/Src/FDO/FDO.csproj +++ b/Src/FDO/FDO.csproj @@ -90,8 +90,9 @@ ..\..\Output\Debug\BasicUtils.dll - - ..\..\Output\Debug\FwResources.dll + + False + ..\..\Output\Debug\protobuf-net.dll @@ -106,30 +107,17 @@ COMInterfaces ..\..\Output\Debug\COMInterfaces.dll - - Microsoft.VisualBasic - PhonEnvValidator ..\..\Output\Debug\PhonEnvValidator.dll - - System.Data - System.Drawing - - System.Windows.Forms - System.XML - - False - ..\..\DistFiles\Utilities.dll - XMLUtils ..\..\Output\Debug\XMLUtils.dll @@ -146,12 +134,6 @@ ..\..\Output\Debug\Db4objects.Db4o.Linq.dll - - ..\..\Output\Debug\ECInterfaces.dll - - - ..\..\Output\Debug\FwUtils.dll - ..\..\Lib\debug\ICSharpCode.SharpZipLib.dll @@ -161,24 +143,15 @@ ..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll - - ..\..\DistFiles\ParatextShared.dll - ..\..\Output\Debug\PhraseTranslationHelper.dll - - ..\..\Output\Debug\Reporting.dll - ..\..\Output\Debug\ScrUtilsInterfaces.dll ..\..\Output\Debug\SharedScrUtils.dll - - ..\..\Output\Debug\SilEncConverters40.dll - ..\..\DistFiles\StructureMap.dll @@ -188,15 +161,6 @@ ..\..\Output\Debug\SilUtils.dll - - ..\..\DistFiles\Tamir.SharpSSH.dll - - - ..\..\Output\Debug\xCoreInterfaces.dll - - - ..\..\Output\Debug\ZipUtils.dll - @@ -216,6 +180,13 @@ + + + + + + + @@ -234,30 +205,12 @@ - - Form - - - CantRestoreLinkedFilesToOriginalLocation.cs - - - Form - - - FilesToRestoreAreOlder.cs - Code - - Form - - - RestoreLinkedFilesToProjectsFolder.cs - @@ -313,17 +266,10 @@ - - Form - - - FWVersionTooOld.cs - - @@ -364,7 +310,6 @@ - @@ -417,6 +362,13 @@ + + + + + + + @@ -425,18 +377,6 @@ - - Form - - - ConflictingSaveDlg.cs - - - Form - - - ConnectionLostDlg.cs - @@ -450,7 +390,6 @@ - @@ -557,35 +496,11 @@ AppStrings.Designer.cs Designer - - CantRestoreLinkedFilesToOriginalLocation.cs - Designer - - - FilesToRestoreAreOlder.cs - Designer - - - RestoreLinkedFilesToProjectsFolder.cs - Designer - - - FWVersionTooOld.cs - Designer - PublicResXFileCodeGenerator ScrFdoResources.Designer.cs Designer - - ConflictingSaveDlg.cs - Designer - - - ConnectionLostDlg.cs - Designer - ResXFileCodeGenerator Resources.Designer.cs @@ -627,7 +542,6 @@ - diff --git a/Src/FDO/FDOGenerate/Interfaces.vm.cs b/Src/FDO/FDOGenerate/Interfaces.vm.cs index 47ff469d24..f558fe897c 100644 --- a/Src/FDO/FDOGenerate/Interfaces.vm.cs +++ b/Src/FDO/FDOGenerate/Interfaces.vm.cs @@ -10,7 +10,7 @@ //This is automatically generated by FDOGenerate task. ****Do not edit**** using System; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; +using SIL.CoreImpl; namespace SIL.FieldWorks.FDO // All generated class interfaces are in here. { diff --git a/Src/FDO/FDOGenerate/main.vm.cs b/Src/FDO/FDOGenerate/main.vm.cs index b45c5dbde3..29bfbce333 100644 --- a/Src/FDO/FDOGenerate/main.vm.cs +++ b/Src/FDO/FDOGenerate/main.vm.cs @@ -16,7 +16,6 @@ using System.Xml.Linq; using System.Linq; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.CoreImpl; using SIL.Utils; using SIL.FieldWorks.FDO.Infrastructure; diff --git a/Src/FDO/FDOTests/BackupRestore/BackupFileRepositoryTests.cs b/Src/FDO/FDOTests/BackupRestore/BackupFileRepositoryTests.cs index 79593442a8..2bfcad79cc 100644 --- a/Src/FDO/FDOTests/BackupRestore/BackupFileRepositoryTests.cs +++ b/Src/FDO/FDOTests/BackupRestore/BackupFileRepositoryTests.cs @@ -12,8 +12,6 @@ using NUnit.Framework; using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.BackupRestore; -using SIL.FieldWorks.FDO.Infrastructure; -using SIL.FieldWorks.Resources; using SIL.FieldWorks.Test.TestUtils; using SIL.Utils; @@ -66,9 +64,9 @@ public void Teardown() [Test] public void NoBackupFilesAvailable() { - m_fileOs.ExistingDirectories.Add(DirectoryFinder.DefaultBackupDirectory); + m_fileOs.ExistingDirectories.Add(FwDirectoryFinder.DefaultBackupDirectory); - BackupFileRepository repo = new BackupFileRepository(); + BackupFileRepository repo = new BackupFileRepository(FwDirectoryFinder.DefaultBackupDirectory); Assert.AreEqual(0, repo.AvailableProjectNames.Count()); Assert.Throws(typeof(KeyNotFoundException), () => repo.GetAvailableVersions("monkey")); Assert.Throws(typeof(KeyNotFoundException), () => repo.GetBackupFile("monkey", DateTime.Now, false)); @@ -93,7 +91,7 @@ public void BackupsForSingleProjectExists() string backupFileName2 = backupSettings.ZipFileName; m_fileOs.AddExistingFile(backupFileName2); - BackupFileRepository repo = new BackupFileRepository(); + BackupFileRepository repo = new BackupFileRepository(FwDirectoryFinder.DefaultBackupDirectory); Assert.AreEqual(1, repo.AvailableProjectNames.Count()); Assert.AreEqual(2, repo.GetAvailableVersions("Floozy").Count()); Assert.AreEqual(backupFileName2, repo.GetBackupFile("Floozy", backupSettings.BackupTime, false).File); @@ -122,7 +120,7 @@ public void InavlidBackupFile() string backupFileName2 = backupSettings.ZipFileName; m_fileOs.AddExistingFile(backupFileName2); - BackupFileRepository repo = new BackupFileRepository(); + BackupFileRepository repo = new BackupFileRepository(FwDirectoryFinder.DefaultBackupDirectory); BackupFileSettings invalidFileSettings = repo.GetMostRecentBackup("Floozy"); BackupFileSettings validFileSettings = repo.GetBackupFile("Floozy", backupSettings.BackupTime, false); ReflectionHelper.SetProperty(validFileSettings, "ProjectName", "Floozy"); // Force it to think it's already loaded and happy. @@ -158,7 +156,7 @@ public void BackupsForMultipleProjects() string backupFileName3 = backupSettings.ZipFileName; m_fileOs.AddExistingFile(backupFileName3); - BackupFileRepository repo = new BackupFileRepository(); + BackupFileRepository repo = new BackupFileRepository(FwDirectoryFinder.DefaultBackupDirectory); Assert.AreEqual(2, repo.AvailableProjectNames.Count()); Assert.AreEqual(2, repo.GetAvailableVersions("AAA").Count()); Assert.AreEqual(1, repo.GetAvailableVersions("ZZZ").Count()); @@ -184,11 +182,11 @@ public void BackupHasOldStyleDatetimeFormat() { DummyBackupProjectSettings backupSettings = new DummyBackupProjectSettings("monkey", "Floozy", null, FDOBackendProviderType.kXML); - string backupFileName1 = Path.Combine(DirectoryFinder.DefaultBackupDirectory, - Path.ChangeExtension("Floozy 2010-8-21-0506", FwFileExtensions.ksFwBackupFileExtension)); + string backupFileName1 = Path.Combine(FwDirectoryFinder.DefaultBackupDirectory, + Path.ChangeExtension("Floozy 2010-8-21-0506", FdoFileHelper.ksFwBackupFileExtension)); m_fileOs.AddExistingFile(backupFileName1); - BackupFileRepository repo = new BackupFileRepository(); + BackupFileRepository repo = new BackupFileRepository(FwDirectoryFinder.DefaultBackupDirectory); Assert.AreEqual(1, repo.AvailableProjectNames.Count()); Assert.AreEqual(1, repo.GetAvailableVersions("Floozy").Count()); Assert.AreEqual(backupFileName1, repo.GetMostRecentBackup("Floozy").File); diff --git a/Src/FDO/FDOTests/BackupRestore/BackupRestoreSettingsTests.cs b/Src/FDO/FDOTests/BackupRestore/BackupRestoreSettingsTests.cs index 1ae1199cc5..5997f0afbc 100644 --- a/Src/FDO/FDOTests/BackupRestore/BackupRestoreSettingsTests.cs +++ b/Src/FDO/FDOTests/BackupRestore/BackupRestoreSettingsTests.cs @@ -11,9 +11,6 @@ using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.BackupRestore; -using SIL.FieldWorks.FDO.Infrastructure; -using SIL.FieldWorks.Resources; -using SIL.Utils; namespace SIL.FieldWorks.FDO.FDOTests.BackupRestore { @@ -33,7 +30,7 @@ internal class DummyBackupProjectSettings : BackupProjectSettings /// ------------------------------------------------------------------------------------ internal DummyBackupProjectSettings(string projectsRootFolder, string projectName, string linkedFilesRootDir, FDOBackendProviderType originalProjType) : - base(projectsRootFolder, projectName, linkedFilesRootDir, null, originalProjType) + base(projectsRootFolder, projectName, linkedFilesRootDir, null, originalProjType, FwDirectoryFinder.DefaultBackupDirectory) { } } @@ -53,7 +50,7 @@ public class BackupRestoreSettingsTests : MemoryOnlyBackendProviderBasicTestBase [Test] public void DefaultRestoreSettings() { - var settings = new RestoreProjectSettings(); + var settings = new RestoreProjectSettings(FwDirectoryFinder.ProjectsDirectory); Assert.IsNull(settings.Backup); Assert.True(string.IsNullOrEmpty(settings.ProjectName)); @@ -73,13 +70,13 @@ public void DefaultRestoreSettings() [Test] public void RestoreProjectSettings_VerifyExistenceOfProject() { - string restoreTestsZipFileDir = Path.Combine(DirectoryFinder.FwSourceDirectory, + string restoreTestsZipFileDir = Path.Combine(FwDirectoryFinder.SourceDirectory, "FDO/FDOTests/BackupRestore/RestoreServiceTestsZipFileDir"); - RestoreProjectSettings restoreSettings = new RestoreProjectSettings() + RestoreProjectSettings restoreSettings = new RestoreProjectSettings(FwDirectoryFinder.ProjectsDirectory) { Backup = new BackupFileSettings(Path.Combine(restoreTestsZipFileDir, - Path.ChangeExtension("TestRestoreFWProject", FwFileExtensions.ksFwBackupFileExtension))), + Path.ChangeExtension("TestRestoreFWProject", FdoFileHelper.ksFwBackupFileExtension))), IncludeConfigurationSettings = false, IncludeLinkedFiles = false, IncludeSupportingFiles = true, @@ -89,7 +86,8 @@ public void RestoreProjectSettings_VerifyExistenceOfProject() }; ProjectRestoreServiceTests.RemoveAnyFilesAndFoldersCreatedByTests(restoreSettings); - ProjectRestoreService restoreProjectService = new ProjectRestoreService(restoreSettings); + ProjectRestoreService restoreProjectService = new ProjectRestoreService(restoreSettings, new DummyFdoUI(), + FwDirectoryFinder.ConverterConsoleExe, FwDirectoryFinder.DbExe); Assert.False(restoreSettings.ProjectExists, "Project exists but it should not."); @@ -113,13 +111,13 @@ public void RestoreProjectSettings_VerifyExistenceOfProject() [Test] public void RestoreProjectSettings_VerifyExistenceOfHgRepo() { - string restoreTestsZipFileDir = Path.Combine(DirectoryFinder.FwSourceDirectory, + string restoreTestsZipFileDir = Path.Combine(FwDirectoryFinder.SourceDirectory, "FDO/FDOTests/BackupRestore/RestoreServiceTestsZipFileDir"); - RestoreProjectSettings restoreSettings = new RestoreProjectSettings() + RestoreProjectSettings restoreSettings = new RestoreProjectSettings(FwDirectoryFinder.ProjectsDirectory) { Backup = new BackupFileSettings(Path.Combine(restoreTestsZipFileDir, - Path.ChangeExtension("TestRestoreFWProject", FwFileExtensions.ksFwBackupFileExtension))), + Path.ChangeExtension("TestRestoreFWProject", FdoFileHelper.ksFwBackupFileExtension))), IncludeConfigurationSettings = false, IncludeLinkedFiles = false, IncludeSupportingFiles = true, @@ -128,7 +126,8 @@ public void RestoreProjectSettings_VerifyExistenceOfHgRepo() BackupOfExistingProjectRequested = false, }; - ProjectRestoreService restoreProjectService = new ProjectRestoreService(restoreSettings); + ProjectRestoreService restoreProjectService = new ProjectRestoreService(restoreSettings, new DummyFdoUI(), + FwDirectoryFinder.ConverterConsoleExe, FwDirectoryFinder.DbExe); try { @@ -137,7 +136,7 @@ public void RestoreProjectSettings_VerifyExistenceOfHgRepo() Assert.True(restoreSettings.ProjectExists, "Project does not exist but it should."); Assert.False(restoreSettings.UsingSendReceive, "Project is using S/R but it should not be."); - string otherReposDir = Path.Combine(restoreSettings.ProjectPath, FLExBridgeHelper.OtherRepositories); + string otherReposDir = Path.Combine(restoreSettings.ProjectPath, FdoFileHelper.OtherRepositories); // Create a non-repository folder in OtherRepositories and verify the project is not using Send/Receive Directory.CreateDirectory(Path.Combine(otherReposDir, "NotARepo_LIFT", "RandomSubdir")); @@ -167,7 +166,7 @@ public void RestoreProjectSettings_VerifyExistenceOfHgRepo() [Test] public void RestoreProjectSettings_CommandLineOptions() { - RestoreProjectSettings settings = new RestoreProjectSettings(); + RestoreProjectSettings settings = new RestoreProjectSettings(FwDirectoryFinder.ProjectsDirectory); Assert.AreEqual(string.Empty, settings.CommandLineOptions); settings.IncludeConfigurationSettings = true; Assert.AreEqual("c", settings.CommandLineOptions.ToLower()); @@ -194,15 +193,15 @@ public void RestoreProjectSettings_CommandLineOptions() [Test] public void RestoreProjectSettings_CreateFromCommandLineOptions() { - RestoreProjectSettings settings = new RestoreProjectSettings("project", "notThere.fwbackup", string.Empty); + RestoreProjectSettings settings = new RestoreProjectSettings(FwDirectoryFinder.ProjectsDirectory, "project", "notThere.fwbackup", string.Empty); CheckSettings(settings, false, false, false, false); - settings = new RestoreProjectSettings("project", "notThere.fwbackup", "fl"); + settings = new RestoreProjectSettings(FwDirectoryFinder.ProjectsDirectory, "project", "notThere.fwbackup", "fl"); CheckSettings(settings, false, true, true, false); - settings = new RestoreProjectSettings("project", "notThere.fwbackup", "cls"); + settings = new RestoreProjectSettings(FwDirectoryFinder.ProjectsDirectory, "project", "notThere.fwbackup", "cls"); CheckSettings(settings, true, false, true, true); - settings = new RestoreProjectSettings("project", "notThere.fwbackup", "cfls"); + settings = new RestoreProjectSettings(FwDirectoryFinder.ProjectsDirectory, "project", "notThere.fwbackup", "cfls"); CheckSettings(settings, true, true, true, true); - settings = new RestoreProjectSettings("project", "notThere.fwbackup", "CFLS"); + settings = new RestoreProjectSettings(FwDirectoryFinder.ProjectsDirectory, "project", "notThere.fwbackup", "CFLS"); CheckSettings(settings, true, true, true, true); } @@ -216,8 +215,8 @@ public void RestoreProjectSettings_CreateFromCommandLineOptions() [Test] public void BackupFileSettings_InitializeFromZipfileMetadata() { - string zipFilePath = Path.Combine(Path.Combine(DirectoryFinder.FwSourceDirectory, "FDO/FDOTests/BackupRestore/RestoreProjectPresenterTests"), - Path.ChangeExtension("RestoreProjectPresenterTests", FwFileExtensions.ksFwBackupFileExtension)); + string zipFilePath = Path.Combine(Path.Combine(FwDirectoryFinder.SourceDirectory, "FDO/FDOTests/BackupRestore/RestoreProjectPresenterTests"), + Path.ChangeExtension("RestoreProjectPresenterTests", FdoFileHelper.ksFwBackupFileExtension)); BackupFileSettings backupSettings = new BackupFileSettings(zipFilePath); Assert.AreEqual("BackupOnlyCoreFiles", backupSettings.Comment); @@ -240,7 +239,7 @@ public void BackupFileSettings_InitializeFromZipfileMetadata() public void BackupProjectSettings_DefaultValues() { var settings = new DummyBackupProjectSettings("whatever", "Blah", null, FDOBackendProviderType.kXML); - Assert.AreEqual(DirectoryFinder.DefaultBackupDirectory, settings.DestinationFolder); + Assert.AreEqual(FwDirectoryFinder.DefaultBackupDirectory, settings.DestinationFolder); } /// ------------------------------------------------------------------------------------ @@ -252,7 +251,7 @@ public void BackupProjectSettings_DefaultValues() public void BackupProjectSettings_Values() { var backupSettings = new DummyBackupProjectSettings( - Path.Combine(DirectoryFinder.FwSourceDirectory, "FDO/FDOTests/BackupRestore"), + Path.Combine(FwDirectoryFinder.SourceDirectory, "FDO/FDOTests/BackupRestore"), "FieldWorksLanguageProject", null, FDOBackendProviderType.kXML) { Comment = "Test comment", @@ -277,7 +276,7 @@ public void BackupProjectSettings_Values() public void BackupFileSettings_SerializationAndDeserialization() { var backupSettings = new DummyBackupProjectSettings( - Path.Combine(DirectoryFinder.FwSourceDirectory, "FDO/FDOTests/BackupRestore"), + Path.Combine(FwDirectoryFinder.SourceDirectory, "FDO/FDOTests/BackupRestore"), "FieldWorksLanguageProject", null, FDOBackendProviderType.kXML) { Comment = "Test comment", diff --git a/Src/FDO/FDOTests/BackupRestore/ProjectBackupServiceTestForLinkedFiles.cs b/Src/FDO/FDOTests/BackupRestore/ProjectBackupServiceTestForLinkedFiles.cs index 69e1ca751e..2df6870797 100644 --- a/Src/FDO/FDOTests/BackupRestore/ProjectBackupServiceTestForLinkedFiles.cs +++ b/Src/FDO/FDOTests/BackupRestore/ProjectBackupServiceTestForLinkedFiles.cs @@ -47,7 +47,7 @@ public override void FixtureSetup() { base.FixtureSetup(); var backupRestoreFolder = Path.Combine("FDO",Path.Combine("FDOTests", "BackupRestore")); - m_testProjectsRoot = Path.Combine(DirectoryFinder.FwSourceDirectory, backupRestoreFolder); + m_testProjectsRoot = Path.Combine(FwDirectoryFinder.SourceDirectory, backupRestoreFolder); m_linkedFilesRootDir = Path.Combine(m_testProjectsRoot, "LinkedFilesTestProjectFiles"); } diff --git a/Src/FDO/FDOTests/BackupRestore/ProjectBackupServiceTests.cs b/Src/FDO/FDOTests/BackupRestore/ProjectBackupServiceTests.cs index 0522976638..5704f33ae1 100644 --- a/Src/FDO/FDOTests/BackupRestore/ProjectBackupServiceTests.cs +++ b/Src/FDO/FDOTests/BackupRestore/ProjectBackupServiceTests.cs @@ -42,7 +42,7 @@ public override void FixtureSetup() { base.FixtureSetup(); var backupRestoreFolder = Path.Combine("FDO", Path.Combine("FDOTests", "BackupRestore")); - m_testProjectsRoot = Path.Combine(DirectoryFinder.FwSourceDirectory, backupRestoreFolder); + m_testProjectsRoot = Path.Combine(FwDirectoryFinder.SourceDirectory, backupRestoreFolder); } /// ------------------------------------------------------------------------------------ @@ -320,7 +320,7 @@ private static bool DateTimesAreWithinACoupleSecondsOfEachOther(DateTime dateTim /// ------------------------------------------------------------------------------------ private static void VerifyFileExistsInZipFile(ZipFile zip, String fileNameAndPath) { - string str = DirectoryFinder.GetZipfileFormattedPath(fileNameAndPath); + string str = FdoFileHelper.GetZipfileFormattedPath(fileNameAndPath); //ensure the entry is the correct one. ZipEntry entry = zip.GetEntry(str); Assert.True(entry.Name.Equals(str), String.Format("File {0} should exist in zipFile", str)); diff --git a/Src/FDO/FDOTests/BackupRestore/ProjectRestoreServiceTests.cs b/Src/FDO/FDOTests/BackupRestore/ProjectRestoreServiceTests.cs index 9818b05cd8..41bfba76de 100644 --- a/Src/FDO/FDOTests/BackupRestore/ProjectRestoreServiceTests.cs +++ b/Src/FDO/FDOTests/BackupRestore/ProjectRestoreServiceTests.cs @@ -7,13 +7,11 @@ using System; using System.IO; -using System.Text; using System.Threading; using NUnit.Framework; using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.BackupRestore; -using SIL.FieldWorks.Resources; using SIL.Utils; using FwRemoteDatabaseConnector; @@ -28,26 +26,18 @@ public class ProjectRestoreServiceTests : MemoryOnlyBackendProviderBasicTestBase { private ProjectRestoreService m_restoreProjectService; private RestoreProjectSettings m_restoreSettings; - private bool m_fResetSharedProjectValue; /// Setup for db4o client server tests. [TestFixtureSetUp] public void Init() { // Allow db4o client server unit test to work without running the window service. - RemotingServer.Start(); - if (Db4oServerInfo.AreProjectsShared_Internal) - { - m_fResetSharedProjectValue = true; - Db4oServerInfo.AreProjectsShared_Internal = false; - } + RemotingServer.Start(FwDirectoryFinder.RemotingTcpServerConfigFile, FwDirectoryFinder.FdoDirectories, () => false, v => {}); } /// Stop db4o client server. [TestFixtureTearDown] public void UnInit() { - if (m_fResetSharedProjectValue) - Db4oServerInfo.AreProjectsShared_Internal = m_fResetSharedProjectValue; RemotingServer.Stop(); } @@ -57,13 +47,13 @@ public void UnInit() [SetUp] public void Initialize() { - var restoreTestsZipFileDir = Path.Combine(DirectoryFinder.FwSourceDirectory, "FDO", "FDOTests", + var restoreTestsZipFileDir = Path.Combine(FwDirectoryFinder.SourceDirectory, "FDO", "FDOTests", "BackupRestore","RestoreServiceTestsZipFileDir"); - m_restoreSettings = new RestoreProjectSettings() + m_restoreSettings = new RestoreProjectSettings(FwDirectoryFinder.ProjectsDirectory) { Backup = new BackupFileSettings(Path.Combine(restoreTestsZipFileDir, - Path.ChangeExtension("TestRestoreFWProject", FwFileExtensions.ksFwBackupFileExtension))), + Path.ChangeExtension("TestRestoreFWProject", FdoFileHelper.ksFwBackupFileExtension))), IncludeConfigurationSettings = false, IncludeLinkedFiles = false, IncludeSupportingFiles = false, @@ -91,7 +81,8 @@ public void RestoreProject_CreateNew_OnlyDataFileAndWsFiles() { m_restoreSettings.ProjectName = "TestRestoreFWProject 01"; - m_restoreProjectService = new ProjectRestoreService(m_restoreSettings); + m_restoreProjectService = new ProjectRestoreService(m_restoreSettings, new DummyFdoUI(), + FwDirectoryFinder.ConverterConsoleExe, FwDirectoryFinder.DbExe); m_restoreProjectService.RestoreProject(new DummyProgressDlg()); @@ -107,7 +98,8 @@ public void RestoreProject_CreateNew_DataFileAndConfigurationSettings() { m_restoreSettings.ProjectName = "TestRestoreFWProject 01"; m_restoreSettings.IncludeConfigurationSettings = true; - m_restoreProjectService = new ProjectRestoreService(m_restoreSettings); + m_restoreProjectService = new ProjectRestoreService(m_restoreSettings, new DummyFdoUI(), + FwDirectoryFinder.ConverterConsoleExe, FwDirectoryFinder.DbExe); m_restoreProjectService.RestoreProject(new DummyProgressDlg()); @@ -214,7 +206,7 @@ public void RestoreProject_PutLinkedFilesInOldLocation_CancelSelected() private string GetFullVersionOfRelativeNonStdDir(string nonStdLinkedFilesDir) { - return Path.Combine(Directory.GetParent(DirectoryFinder.FwSourceDirectory).ToString(), nonStdLinkedFilesDir); + return Path.Combine(Directory.GetParent(FwDirectoryFinder.SourceDirectory).ToString(), nonStdLinkedFilesDir); } /// @@ -228,14 +220,15 @@ public void RestoreProject_OverwriteOnlyDataRestored() IThreadedProgress progressDlg = new DummyProgressDlg(); m_restoreSettings.IncludeConfigurationSettings = false; - m_restoreProjectService = new ProjectRestoreService(m_restoreSettings); + m_restoreProjectService = new ProjectRestoreService(m_restoreSettings, new DummyFdoUI(), + FwDirectoryFinder.ConverterConsoleExe, FwDirectoryFinder.DbExe); //Restore the project once and do not delete it so that we can restore the project over the previous one. m_restoreProjectService.RestoreProject(progressDlg); string restoreProjectDirectory = m_restoreSettings.ProjectPath; - VerifyFileExists(restoreProjectDirectory, DirectoryFinder.GetXmlDataFileName("TestRestoreFWProject")); - var dateTimeTicksOfFirstFile = GetLastWriteTimeOfRestoredFile(restoreProjectDirectory, DirectoryFinder.GetXmlDataFileName("TestRestoreFWProject")); + VerifyFileExists(restoreProjectDirectory, FdoFileHelper.GetXmlDataFileName("TestRestoreFWProject")); + var dateTimeTicksOfFirstFile = GetLastWriteTimeOfRestoredFile(restoreProjectDirectory, FdoFileHelper.GetXmlDataFileName("TestRestoreFWProject")); // Linux filesystem modification time precision can be to the second, so wait a moment. if (MiscUtils.IsUnix) @@ -249,7 +242,7 @@ public void RestoreProject_OverwriteOnlyDataRestored() //Now do another restore then verify that the two files are not the same by comparing the LastWriteTime values. m_restoreProjectService.RestoreProject(progressDlg); - var dateTimeTicksOfSecondFile = GetLastWriteTimeOfRestoredFile(restoreProjectDirectory, DirectoryFinder.GetXmlDataFileName("TestRestoreFWProject")); + var dateTimeTicksOfSecondFile = GetLastWriteTimeOfRestoredFile(restoreProjectDirectory, FdoFileHelper.GetXmlDataFileName("TestRestoreFWProject")); Assert.True(dateTimeTicksOfSecondFile.Equals(dateTimeTicksOfFirstFile), "The dates and times of the files should be the same since they are set to the timestamp of the file in the zip file."); VerifyManditoryFilesUnzippedAndDeleteThem(); @@ -284,7 +277,7 @@ private static void RemoveAllFilesFromFolderAndSubfolders(string restoreDirector internal static void RemoveAnyFilesAndFoldersCreatedByTests(RestoreProjectSettings settings) { - RemoveAllFilesFromFolderAndSubfolders(DirectoryFinder.GetBackupSettingsDir(settings.ProjectPath)); + RemoveAllFilesFromFolderAndSubfolders(FdoFileHelper.GetBackupSettingsDir(settings.ProjectPath)); RemoveAllFilesFromFolderAndSubfolders(settings.ProjectSupportingFilesPath); RemoveAllFilesFromFolderAndSubfolders(settings.FlexConfigurationSettingsPath); RemoveAllFilesFromFolderAndSubfolders(settings.PicturesPath); @@ -292,7 +285,7 @@ internal static void RemoveAnyFilesAndFoldersCreatedByTests(RestoreProjectSettin RemoveAllFilesFromFolderAndSubfolders(settings.OtherExternalFilesPath); RemoveAllFilesFromFolderAndSubfolders(settings.LinkedFilesPath); RemoveAllFilesFromFolderAndSubfolders(settings.WritingSystemStorePath); - RemoveAllFilesFromFolderAndSubfolders(Path.Combine(settings.ProjectPath, DirectoryFinder.ksSortSequenceTempDir)); + RemoveAllFilesFromFolderAndSubfolders(Path.Combine(settings.ProjectPath, FdoFileHelper.ksSortSequenceTempDir)); //Remove this one last of all because the other folders need to be removed first. RemoveAllFilesFromFolderAndSubfolders(settings.ProjectPath); diff --git a/Src/FDO/FDOTests/BackupRestore/ProjectRestoreTestService.cs b/Src/FDO/FDOTests/BackupRestore/ProjectRestoreTestService.cs index 7f14c972db..e7e07ea832 100644 --- a/Src/FDO/FDOTests/BackupRestore/ProjectRestoreTestService.cs +++ b/Src/FDO/FDOTests/BackupRestore/ProjectRestoreTestService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.BackupRestore; namespace SIL.FieldWorks.FDO.FDOTests.BackupRestore @@ -14,7 +15,8 @@ public class ProjectRestoreTestService : ProjectRestoreService /// we don't want to show up in tests (a dialog). /// /// - public ProjectRestoreTestService(RestoreProjectSettings settings) : base(settings) + public ProjectRestoreTestService(RestoreProjectSettings settings) + : base(settings, new DummyFdoUI(), FwDirectoryFinder.ConverterConsoleExe, FwDirectoryFinder.DbExe) { PutFilesInProject = false; SimulateOKResult = true; diff --git a/Src/FDO/FDOTests/CellarTests.cs b/Src/FDO/FDOTests/CellarTests.cs index 3363485d95..ce6a7cc114 100644 --- a/Src/FDO/FDOTests/CellarTests.cs +++ b/Src/FDO/FDOTests/CellarTests.cs @@ -491,7 +491,7 @@ public void AddComplexFeaturesToFeatureSystemAndThenToAFeatureStructure() // Set up the xml fs description XmlDocument doc = new XmlDocument(); - string sFileDir = Path.Combine(DirectoryFinder.FwSourceDirectory, @"FDO/FDOTests/TestData"); + string sFileDir = Path.Combine(FwDirectoryFinder.SourceDirectory, @"FDO/FDOTests/TestData"); string sFile = Path.Combine(sFileDir, "FeatureSystem2.xml"); doc.Load(sFile); diff --git a/Src/FDO/FDOTests/ClientServerServicesTests.cs b/Src/FDO/FDOTests/ClientServerServicesTests.cs index 2c90c2da07..b3338463a5 100644 --- a/Src/FDO/FDOTests/ClientServerServicesTests.cs +++ b/Src/FDO/FDOTests/ClientServerServicesTests.cs @@ -1,11 +1,9 @@ using System; using System.IO; -using System.Windows.Forms; using FwRemoteDatabaseConnector; using NUnit.Framework; using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices; -using SIL.FieldWorks.Resources; using SIL.FieldWorks.Test.TestUtils; using SIL.Utils; @@ -22,6 +20,7 @@ public class ClientServerServicesTests : BaseTest private Db4oServerInfo m_db4OServerInfo; private string m_oldProjectDirectory; + private bool m_projectShared; private IThreadedProgress m_progress; @@ -31,11 +30,14 @@ public void StartFwRemoteDatabaseConnector() { // Change the Project Directory to some temporary directory to ensure, other units tests don't add projects // which would slow these tests down. - m_oldProjectDirectory = DirectoryFinder.ProjectsDirectory; - DirectoryFinder.ProjectsDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - Directory.CreateDirectory(DirectoryFinder.ProjectsDirectory); + m_oldProjectDirectory = FwDirectoryFinder.ProjectsDirectory; + FwDirectoryFinder.ProjectsDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + Directory.CreateDirectory(FwDirectoryFinder.ProjectsDirectory); - RemotingServer.Start(); + FdoTestHelper.SetupClientServerServices(); + + m_projectShared = false; + RemotingServer.Start(FwDirectoryFinder.RemotingTcpServerConfigFile, FwDirectoryFinder.FdoDirectories, () => m_projectShared, v => m_projectShared = v); var connectString = String.Format("tcp://{0}:{1}/FwRemoteDatabaseConnector.Db4oServerInfo", "127.0.0.1", Db4OPorts.ServerPort); @@ -53,8 +55,8 @@ public void StopFwRemoteDatabaseConnector() { RemotingServer.Stop(); - Directory.Delete(DirectoryFinder.ProjectsDirectory, true); - DirectoryFinder.ProjectsDirectory = m_oldProjectDirectory; + Directory.Delete(FwDirectoryFinder.ProjectsDirectory, true); + FwDirectoryFinder.ProjectsDirectory = m_oldProjectDirectory; m_db4OServerInfo = null; } @@ -110,10 +112,10 @@ public void ShareMyProjects_TurningShareMyProjectOn_ShareMyProjectsReturnedTrue( Assert.IsTrue(ClientServerServices.Current.Local.SetProjectSharing(true, m_progress)); Assert.IsTrue(Db4OLocalClientServerServices.LocalDb4OServerInfoConnection.AreProjectShared()); Assert.IsFalse(ClientServerServices.Current.Local.ShareMyProjects, "ShareMyProjects should not be true unless HKCU projects dir same as HKLM"); - var temp = DirectoryFinder.ProjectsDirectory; - DirectoryFinder.ProjectsDirectory = DirectoryFinder.ProjectsDirectoryLocalMachine; + var temp = FwDirectoryFinder.ProjectsDirectory; + FwDirectoryFinder.ProjectsDirectory = FwDirectoryFinder.ProjectsDirectoryLocalMachine; Assert.IsTrue(ClientServerServices.Current.Local.ShareMyProjects); - DirectoryFinder.ProjectsDirectory = temp; + FwDirectoryFinder.ProjectsDirectory = temp; } /// @@ -131,10 +133,10 @@ public void IdForLocalProject_SimpleNameProjectsAreNotShared_ReturnedFilenameHas string filename = ClientServerServices.Current.Local.IdForLocalProject("tom"); // Assert ends with .fwdata - Assert.AreEqual(FwFileExtensions.ksFwDataXmlFileExtension, Path.GetExtension(filename)); + Assert.AreEqual(FdoFileHelper.ksFwDataXmlFileExtension, Path.GetExtension(filename)); // Check file is in ProjectDirectory. - Assert.That(filename, Is.SubPath(DirectoryFinder.ProjectsDirectory)); + Assert.That(filename, Is.SubPath(FwDirectoryFinder.ProjectsDirectory)); } /// diff --git a/Src/FDO/FDOTests/ClientServerTests.cs b/Src/FDO/FDOTests/ClientServerTests.cs index 6d99a7bb35..fd9c0adb6f 100644 --- a/Src/FDO/FDOTests/ClientServerTests.cs +++ b/Src/FDO/FDOTests/ClientServerTests.cs @@ -1,15 +1,12 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Xml.Linq; using NUnit.Framework; using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.CoreTests; using SIL.FieldWorks.FDO.DomainImpl; -using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.FDO.Infrastructure; using SIL.FieldWorks.FDO.Infrastructure.Impl; @@ -45,7 +42,7 @@ public void VerifyOkToReconcileChanges() modified.Add(GetSurrogate(sense1, cmoFactory)); m_actionHandler.Undo(); var uowService = (UnitOfWorkService) undoManager; - var reconciler = uowService.Reconciler(new List(), modified, new List()); + var reconciler = uowService.CreateReconciler(new List(), modified, new List()); // Only other client made changes Assert.That(reconciler.OkToReconcileChanges(), Is.True, @@ -55,21 +52,21 @@ public void VerifyOkToReconcileChanges() UndoableUnitOfWorkHelper.Do("undo change gloss", "redo", m_actionHandler, () => sense1.Gloss.AnalysisDefaultWritingSystem = Cache.TsStrFactory.MakeString("strike with shoe", Cache.DefaultAnalWs)); - reconciler = uowService.Reconciler(new List(), modified, new List()); + reconciler = uowService.CreateReconciler(new List(), modified, new List()); Assert.That(reconciler.OkToReconcileChanges(), Is.False, "we should not be able to make a change if we have a conflicting change to the same object."); m_actionHandler.Undo(); - reconciler = uowService.Reconciler(new List(), modified, new List()); + reconciler = uowService.CreateReconciler(new List(), modified, new List()); Assert.That(reconciler.OkToReconcileChanges(), Is.True); // Foreign modified, local deleted. UndoableUnitOfWorkHelper.Do("undo delete sense", "redo", m_actionHandler, () => entry1.SensesOS.RemoveAt(0)); - reconciler = uowService.Reconciler(new List(), modified, new List()); + reconciler = uowService.CreateReconciler(new List(), modified, new List()); Assert.That(reconciler.OkToReconcileChanges(), Is.False, "we should not be able to make a change if we have deleted an object that the change modifies."); m_actionHandler.Undo(); - reconciler = uowService.Reconciler(new List(), modified, new List()); + reconciler = uowService.CreateReconciler(new List(), modified, new List()); Assert.That(reconciler.OkToReconcileChanges(), Is.True); // Local modified, foreign deleted. @@ -78,11 +75,11 @@ public void VerifyOkToReconcileChanges() Cache.TsStrFactory.MakeString("strike with boot", Cache.DefaultAnalWs)); var listOfSense1Id = new List(); listOfSense1Id.Add(sense1.Id); - reconciler = uowService.Reconciler(new List(), new List(), listOfSense1Id); + reconciler = uowService.CreateReconciler(new List(), new List(), listOfSense1Id); Assert.That(reconciler.OkToReconcileChanges(), Is.False, "we should not be able to make a change if it involves deleting an object that we have modified."); m_actionHandler.Undo(); - reconciler = uowService.Reconciler(new List(), modified, new List()); + reconciler = uowService.CreateReconciler(new List(), modified, new List()); Assert.That(reconciler.OkToReconcileChanges(), Is.True); // We added a reference to something they deleted (on a new object). @@ -94,7 +91,7 @@ public void VerifyOkToReconcileChanges() newObjectSurrogates.Add(GetSurrogate(bundle.Owner.Owner, cmoFactory)); newObjectSurrogates.Add(GetSurrogate(bundle.Owner,cmoFactory)); newObjectSurrogates.Add(GetSurrogate(bundle, cmoFactory)); - reconciler = uowService.Reconciler(new List(), new List(), listOfSense1Id); + reconciler = uowService.CreateReconciler(new List(), new List(), listOfSense1Id); Assert.That(reconciler.OkToReconcileChanges(), Is.False, "we should not be able to make a change if it involves deleting an object that one we have added refers to."); @@ -102,11 +99,11 @@ public void VerifyOkToReconcileChanges() UndoableUnitOfWorkHelper.Do("undo clear ref", "redo", m_actionHandler, () => bundle.SenseRA = null); undoManager.Save(); - reconciler = uowService.Reconciler(new List(), new List(), listOfSense1Id); + reconciler = uowService.CreateReconciler(new List(), new List(), listOfSense1Id); Assert.That(reconciler.OkToReconcileChanges(),Is.True); UndoableUnitOfWorkHelper.Do("undo set ref", "redo", m_actionHandler, () => bundle.SenseRA = sense1); - reconciler = uowService.Reconciler(new List(), new List(), listOfSense1Id); + reconciler = uowService.CreateReconciler(new List(), new List(), listOfSense1Id); Assert.That(reconciler.OkToReconcileChanges(), Is.False, "we should not be able to make a change if it involves deleting an object that we have made a reference to."); m_actionHandler.Undo(); // setting the sense of the bundle @@ -118,13 +115,13 @@ public void VerifyOkToReconcileChanges() UndoableUnitOfWorkHelper.Do("undo delete sense", "redo", m_actionHandler, () => entry1.SensesOS.RemoveAt(0)); // Now pretend THEY made the change adding the objects referring to sense1, which we just deleted. - reconciler = uowService.Reconciler(newObjectSurrogates, new List(), new List()); + reconciler = uowService.CreateReconciler(newObjectSurrogates, new List(), new List()); Assert.That(reconciler.OkToReconcileChanges(), Is.False, "we should not be able to make a change if it involves adding an object that refers to an object we have deleted."); // This is cheating a little bit, because we're passing as modified objects things not in our db at all. // But it exercises the relevant code, making sure we check the modified objects for refs to our deleted ones. - reconciler = uowService.Reconciler(new List(), newObjectSurrogates, new List()); + reconciler = uowService.CreateReconciler(new List(), newObjectSurrogates, new List()); Assert.That(reconciler.OkToReconcileChanges(), Is.False, "we should not be able to make a change if it involves adding a ref to an object we have deleted."); } @@ -160,7 +157,7 @@ public void ReconcileCollectionChanges() remove.Delete(); }); var uowService = Cache.ServiceLocator.GetInstance(); - var reconciler = ((UnitOfWorkService)uowService).Reconciler(newbiesClockwise, dirtballsClockwise, gonersClockwise); + var reconciler = ((UnitOfWorkService)uowService).CreateReconciler(newbiesClockwise, dirtballsClockwise, gonersClockwise); var notifiee = new Notifiee(); Cache.DomainDataByFlid.AddNotification(notifiee); Assert.That(reconciler.OkToReconcileChanges(), Is.True); @@ -239,7 +236,7 @@ public void ModifiedDifferentSenses_EarlierTime() var newTime = entry1.DateModified; // should be definitely after oldTime. Assert.That(newTime, Is.GreaterThan(oldTime)); var uowService = Cache.ServiceLocator.GetInstance(); - var reconciler = ((UnitOfWorkService)uowService).Reconciler(newbiesClockwise, dirtballsClockwise, gonersClockwise); + var reconciler = ((UnitOfWorkService)uowService).CreateReconciler(newbiesClockwise, dirtballsClockwise, gonersClockwise); Assert.That(reconciler.OkToReconcileChanges(), Is.True); reconciler.ReconcileForeignChanges(); @@ -314,7 +311,7 @@ public void ModifiedDifferentSenses_LaterTime() Assert.That(newTime, Is.LessThan(foreignTime)); // might not be if stepping in debugger var uowService = Cache.ServiceLocator.GetInstance(); - var reconciler = ((UnitOfWorkService)uowService).Reconciler(newbiesClockwise, dirtballsClockwise, gonersClockwise); + var reconciler = ((UnitOfWorkService)uowService).CreateReconciler(newbiesClockwise, dirtballsClockwise, gonersClockwise); Assert.That(reconciler.OkToReconcileChanges(), Is.True); reconciler.ReconcileForeignChanges(); @@ -644,26 +641,6 @@ void SetString(IMultiUnicode target, int ws, string text) target.set_String(ws, Cache.TsStrFactory.MakeString(text, ws)); } - /// - /// Helper method for tests on this pattern: - /// Create some initial state; - /// Save; - /// Make a change locally; - /// Record the changes and their final state; - /// Undo; - /// Wait until a new DateTime occurs; - /// Make the other change locally; - /// Reconcile the changes in the first group; - /// - /// - /// - /// - void VerifyCheckingAndReconcilingAChange(Action firstChange, Action secondChange, string label) - { - - } - - /// /// Helper method for several tests on this pattern: /// create an object that has the required kind of data; @@ -686,7 +663,7 @@ void VerifyReconcilingAChange(Action makeTheChange, string label) GetEffectsOfChange(makeTheChange, out newbySurrogates, out dirtballSurrogates, out gonerList); var undoManager = Cache.ServiceLocator.GetInstance(); // Re-apply the changes using the reconciliation mechanism - var reconciler = ((UnitOfWorkService)undoManager).Reconciler(newbySurrogates, dirtballSurrogates, gonerList); + var reconciler = ((UnitOfWorkService)undoManager).CreateReconciler(newbySurrogates, dirtballSurrogates, gonerList); reconciler.ReconcileForeignChanges(); // verify deletions foreach (var id in gonerList) diff --git a/Src/FDO/FDOTests/CmSemanticDomainRepositoryTests.cs b/Src/FDO/FDOTests/CmSemanticDomainRepositoryTests.cs index f9d3d91b4c..4766c870d6 100644 --- a/Src/FDO/FDOTests/CmSemanticDomainRepositoryTests.cs +++ b/Src/FDO/FDOTests/CmSemanticDomainRepositoryTests.cs @@ -397,7 +397,7 @@ public void FindDomains_TimingOnLargerDataSet() const string expectedNum2 = "8.3.3"; // group3 match 'sunshine', under 'Light' const string expectedName2 = "Light"; const string filePath = @"Templates\semdom.xml"; - var homeDir = DirectoryFinder.FWCodeDirectory; + var homeDir = FwDirectoryFinder.CodeDirectory; LoadSemDomTestDataFromFile(Path.Combine(homeDir, filePath)); // SUT diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000001Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000001Tests.cs index bd2931b390..70d8d4a4d8 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000001Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000001Tests.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Xml.Linq; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -128,7 +129,7 @@ public void DataMigration7000001_and_Delint_Tests() mockMDC.AddClass(3, "Text", "CmObject", new List()); mockMDC.AddClass(4, "WfiWordform", "CmObject", new List()); mockMDC.AddClass(5, "LexSense", "CmObject", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000000, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000000, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000001, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000002Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000002Tests.cs index 550dc2f317..cef68f1e77 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000002Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000002Tests.cs @@ -10,6 +10,7 @@ using System.Text; using System.Xml.Linq; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -176,7 +177,7 @@ public void DataMigration7000002Test() mockMDC.AddClass(9, "ScrFootnote", "CmObject", new List()); mockMDC.AddClass(10, "ScrTxtPara", "CmObject", new List()); mockMDC.AddClass(11, "StPara", "CmObject", new List { "StTxtPara" }); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000001, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000001, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000002, new DummyProgressDlg()); Assert.AreEqual(7000002, dtoRepos.CurrentModelVersion, "Wrong updated version."); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000003Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000003Tests.cs index 6bc1f1186b..2af15fddc6 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000003Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000003Tests.cs @@ -2,6 +2,7 @@ using System.Text; using System.Xml.Linq; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -91,7 +92,7 @@ public void DataMigration7000003Test() mockMDC.AddClass(9, "ScrFootnote", "CmObject", new List()); mockMDC.AddClass(10, "ScrTxtPara", "CmObject", new List()); mockMDC.AddClass(11, "StPara", "CmObject", new List { "StTxtPara" }); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000002, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000002, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000003, new DummyProgressDlg()); Assert.AreEqual(7000003, dtoRepos.CurrentModelVersion, "Wrong updated version."); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000005Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000005Tests.cs index 2aa7698a9a..737fbf08c9 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000005Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000005Tests.cs @@ -3,6 +3,7 @@ using System.Xml.Linq; using System.Xml.XPath; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -44,7 +45,7 @@ public void DataMigration7000005Test() mockMDC.AddClass(13, "RnAnalysis", "RnGenericRec", new List()); mockMDC.AddClass(14, "CmPerson", "CmPossibility", new List()); mockMDC.AddClass(15, "CmAnthroItem", "CmPossibility", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000004, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000004, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000005, new DummyProgressDlg()); var nbkDto = dtoRepos.AllInstancesSansSubclasses("RnResearchNbk").First(); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000006Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000006Tests.cs index 5f7d31fd3b..92e632d258 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000006Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000006Tests.cs @@ -3,6 +3,7 @@ using System.Xml.Linq; using System.Xml.XPath; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -29,7 +30,7 @@ public void DataMigration7000006Test() mockMDC.AddClass(1, "CmObject", null, new List { "CmProject" }); mockMDC.AddClass(2, "CmProject", "CmObject", new List { "LangProject" }); mockMDC.AddClass(3, "LangProject", "CmProject", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000005, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000005, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000006, new DummyProgressDlg()); var cmProjDto = dtoRepos.AllInstancesSansSubclasses("LangProject").First(); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000007Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000007Tests.cs index 650e975df0..0fe6fa831d 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000007Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000007Tests.cs @@ -3,6 +3,7 @@ using System.Xml.Linq; using System.Xml.XPath; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -35,7 +36,7 @@ public void DataMigration7000007Test() mockMDC.AddClass(7, "StTxtPara", "StPara", new List()); mockMDC.AddClass(9, "StFootnote", "StText", new List {"ScrFootnote"}); mockMDC.AddClass(10, "ScrFootnote", "StFootnote", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000006, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000006, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000007, new DummyProgressDlg()); var ScrInpDto = dtoRepos.AllInstancesSansSubclasses("ScrImportSet").First(); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000008Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000008Tests.cs index 07582429c3..0da1b59962 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000008Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000008Tests.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -33,7 +34,7 @@ public void DataMigration7000008Test() mockMDC.AddClass(2, "LangProject", "CmObject", new List()); mockMDC.AddClass(3, "CmBaseAnnotation", "CmObject", new List { "ScrScriptureNote" }); mockMDC.AddClass(4, "ScrScriptureNote", "CmBaseAnnotation", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000007, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000007, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000008, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000009Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000009Tests.cs index bd1d01983d..f8e447cafb 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000009Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000009Tests.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Text; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -64,7 +65,7 @@ public void DataMigration7000009Test() mockMDC.AddClass(1, "CmObject", null, new List { "LangProject", "Scripture" }); mockMDC.AddClass(2, "LangProject", "CmObject", new List()); mockMDC.AddClass(4, "Scripture", "CmObject", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000008, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000008, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000009, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000010Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000010Tests.cs index 9bcefab21e..2e44900f98 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000010Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000010Tests.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Xml.Linq; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -76,7 +77,7 @@ public void DataMigration7000010_AnnotationDefns_Removed_Test() mockMDC.AddClass(3, "CmAnnotationDefn", "CmObject", new List()); mockMDC.AddClass(4, "StText", "CmObject", new List()); mockMDC.AddClass(5, "StTxtPara", "CmObject", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000009, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000009, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); // Collect the various annotation defns. var annDefnDtos = new Dictionary(); @@ -1160,7 +1161,7 @@ private static IDomainObjectDTORepository SetupMDC(HashSet dtos mockMDC.AddClass(16, "ConstChartMovedTextMarker", "ConstituentChartCellPart", new List()); mockMDC.AddClass(17, "ConstChartClauseMarker", "ConstituentChartCellPart", new List()); mockMDC.AddClass(18, "ConstChartTag", "ConstituentChartCellPart", new List()); - return new DomainObjectDtoRepository(7000009, dtos, mockMDC, null); + return new DomainObjectDtoRepository(7000009, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); } private static void CheckXfics(IDomainObjectDTORepository dtoRepos, diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000011Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000011Tests.cs index 33193000a4..3680fb1552 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000011Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000011Tests.cs @@ -4,7 +4,7 @@ using System.Xml.Linq; using System.Xml.XPath; using NUnit.Framework; - +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -98,7 +98,7 @@ public void DataMigration7000011Test() mockMDC.AddClass(3, "CmPossibilityList", "CmObject", new List()); mockMDC.AddClass(4, "CmPossibility", "CmObject", new List()); mockMDC.AddClass(5, "RnGenericRec", "CmObject", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000010, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000010, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000011, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000012Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000012Tests.cs index 747ea57112..be6ab580f2 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000012Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000012Tests.cs @@ -1,10 +1,9 @@ -using System; using System.Collections.Generic; -using System.Text; using NUnit.Framework; using System.Linq; using System.Xml.Linq; using System.Xml.XPath; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -56,7 +55,7 @@ public void DataMigration7000012_Unneeded_UserViewField_Removed_Test() var mockMDC = new MockMDCForDataMigration(); mockMDC.AddClass(1, "CmObject", null, new List { "UserViewField" }); mockMDC.AddClass(2, "UserViewField", "CmObject", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000011, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000011, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); Assert.AreEqual(40, dtoRepos.AllInstancesWithSubclasses("UserViewField").Count()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000013Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000013Tests.cs index 76fb108a07..56982bd5ac 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000013Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000013Tests.cs @@ -3,6 +3,7 @@ using System.Xml.Linq; using System.Xml.XPath; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -95,7 +96,7 @@ private static IDomainObjectDTORepository DoCommonBasics(IEnumerable ext var mockMDC = SetupMDC(); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000012, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000012, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); return dtoRepos; } diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000014Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000014Tests.cs index 434939b523..4b58ea39e1 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000014Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000014Tests.cs @@ -3,6 +3,7 @@ using System.Xml.Linq; using System.Xml.XPath; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -26,7 +27,7 @@ public void DataMigration7000014Test() var mockMDC = SetupMDC(); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000013, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000013, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); // SUT; Do the migration. m_dataMigrationManager.PerformMigration(dtoRepos, 7000014, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000015Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000015Tests.cs index 221ad7122d..b6eef2503d 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000015Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000015Tests.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Xml.Linq; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -25,7 +26,7 @@ public void DataMigration7000015Test() var mockMdc = SetupMdc(); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000014, dtos, mockMdc, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000014, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); // SUT: Do the migration. m_dataMigrationManager.PerformMigration(dtoRepos, 7000015, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000016Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000016Tests.cs index 49defea49c..2249fd7b02 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000016Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000016Tests.cs @@ -15,7 +15,7 @@ using System.Xml.XPath; using NUnit.Framework; - +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -57,7 +57,7 @@ public void DataMigration7000016Test() var mockMdc = SetupMdc(); - IDomainObjectDTORepository repoDTO = new DomainObjectDtoRepository(7000015, dtos, mockMdc, null); + IDomainObjectDTORepository repoDTO = new DomainObjectDtoRepository(7000015, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); // SUT: Do the migration. m_dataMigrationManager.PerformMigration(repoDTO, 7000016, new DummyProgressDlg()); @@ -117,7 +117,7 @@ public void CheckOnNoPossibilitiesInListAtStart() @"") }; var mockMdc = SetupMdc(); - IDomainObjectDTORepository repoDto = new DomainObjectDtoRepository(7000015, dtos, mockMdc, null); + IDomainObjectDTORepository repoDto = new DomainObjectDtoRepository(7000015, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); // SUT: Do the migration. m_dataMigrationManager.PerformMigration(repoDto, 7000016, new DummyProgressDlg()); // Verification Phase diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000017Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000017Tests.cs index 2e5cdaf16b..b8e6eb642f 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000017Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000017Tests.cs @@ -8,11 +8,9 @@ // // -using System; using System.Collections.Generic; -using System.Text; using NUnit.Framework; -using SIL.FieldWorks.Test.TestUtils; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -37,7 +35,7 @@ public void DeleteWeatherListAndField() var mockMdc = SetupMdc(); - IDomainObjectDTORepository repoDTO = new DomainObjectDtoRepository(7000016, dtos, mockMdc, null); + IDomainObjectDTORepository repoDTO = new DomainObjectDtoRepository(7000016, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); // SUT: Do the migration. m_dataMigrationManager.PerformMigration(repoDTO, 7000017, new DummyProgressDlg()); @@ -138,7 +136,7 @@ private void ConvertWeatherToCustomListAndField(string datafile) var mockMdc = SetupMdc(); - IDomainObjectDTORepository repoDTO = new DomainObjectDtoRepository(7000016, dtos, mockMdc, null); + IDomainObjectDTORepository repoDTO = new DomainObjectDtoRepository(7000016, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); // SUT: Do the migration. m_dataMigrationManager.PerformMigration(repoDTO, 7000017, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000018Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000018Tests.cs index ca8a950304..bd3b2b5d74 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000018Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000018Tests.cs @@ -12,7 +12,7 @@ using System.Text; using System.Xml.Linq; using NUnit.Framework; - +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; using SIL.Utils; @@ -38,7 +38,7 @@ public void PerformMigration7000018() var mockMdc = SetupMdc(); - IDomainObjectDTORepository repoDTO = new DomainObjectDtoRepository(7000017, dtos, mockMdc, null); + IDomainObjectDTORepository repoDTO = new DomainObjectDtoRepository(7000017, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); // SUT: Do the migration. m_dataMigrationManager.PerformMigration(repoDTO, 7000018, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000019Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000019Tests.cs index dcf25f9f3c..cec6515696 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000019Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000019Tests.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; @@ -38,7 +37,7 @@ private static void PrepareStore(string path) [Test] public void DataMigration7000019Test() { - string storePath = Path.Combine(Path.GetTempPath(), DirectoryFinder.ksWritingSystemsDir); + string storePath = Path.Combine(Path.GetTempPath(), FdoFileHelper.ksWritingSystemsDir); PrepareStore(storePath); string globalStorePath = DirectoryFinder.GlobalWritingSystemStoreDirectory; PrepareStore(globalStorePath); @@ -47,7 +46,7 @@ public void DataMigration7000019Test() IFwMetaDataCacheManaged mockMdc = SetupMdc(); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000018, dtos, mockMdc, Path.GetTempPath()); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000018, dtos, mockMdc, Path.GetTempPath(), FwDirectoryFinder.FdoDirectories); // Do the migration. m_dataMigrationManager.PerformMigration(dtoRepos, 7000019, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000020Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000020Tests.cs index 3da9ab5298..baa00d8acb 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000020Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000020Tests.cs @@ -13,7 +13,7 @@ using System.Linq; using NUnit.Framework; - +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; using SIL.FieldWorks.FDO.Infrastructure; @@ -38,7 +38,7 @@ public void DataMigration7000020Test() IFwMetaDataCacheManaged mockMdc = SetupMdc(); IDomainObjectDTORepository repoDto = new DomainObjectDtoRepository(7000019, dtos, mockMdc, - Path.GetTempPath()); + Path.GetTempPath(), FwDirectoryFinder.FdoDirectories); // Initial check that data was read properly. var cObjects = repoDto.AllInstances().Count(); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000022Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000022Tests.cs index f43696fae6..3dd6ed2488 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000022Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000022Tests.cs @@ -4,6 +4,7 @@ using System.Xml.Linq; using System.Xml.XPath; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -39,7 +40,7 @@ public void DataMigration7000022Test() mockMDC.AddClass(5, "RnResearchNbk", "CmMajorObject", new List()); mockMDC.AddClass(6, "LexDb", "CmMajorObject", new List()); mockMDC.AddClass(7, "CmPossibilityList", "CmMajorObject", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000021, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000021, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); // SUT m_dataMigrationManager.PerformMigration(dtoRepos, 7000022, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000023Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000023Tests.cs index 06bf304299..1936a7a0a2 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000023Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000023Tests.cs @@ -1,9 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Collections.Generic; using System.Xml.Linq; -using System.Xml.XPath; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -38,10 +36,10 @@ public void DataMigration7000023Test() mockMDC.AddClass(6, "CmFilter", "CmObject", new List()); mockMDC.AddClass(7, "UserView", "CmObject", new List()); mockMDC.AddClass(8, "UserAppFeatAct", "CmObject", new List()); - mockMDC.AddClass(9, "CmResource", "CmObject", new List()); ; - mockMDC.AddClass(10, "ScrCheckRun", "CmObject", new List()); ; - mockMDC.AddClass(11, "RnResearchNbk", "CmObject", new List()); ; - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000022, dtos, mockMDC, null); + mockMDC.AddClass(9, "CmResource", "CmObject", new List()); + mockMDC.AddClass(10, "ScrCheckRun", "CmObject", new List()); + mockMDC.AddClass(11, "RnResearchNbk", "CmObject", new List()); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000022, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); //SUT m_dataMigrationManager.PerformMigration(dtoRepos, 7000023, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000024Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000024Tests.cs index 099f9b2e15..5c0e4a2799 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000024Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000024Tests.cs @@ -3,6 +3,7 @@ using System.Xml.Linq; using System.Xml.XPath; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -47,7 +48,7 @@ public void DataMigration7000024Test() mockMDC.AddClass(9, "LexEntry", "CmObject", new List()); mockMDC.AddClass(10, "LexSense", "CmObject", new List()); mockMDC.AddClass(11, "CmPossibility", "CmObject", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000023, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000023, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000024, new DummyProgressDlg()); //This object should contain a 'Status' property @@ -233,7 +234,7 @@ public void DataMigration7000024Test1() mockMDC.AddClass(5, "RnResearchNbk", "CmMajorObject", new List()); mockMDC.AddClass(6, "RnGenericRec", "CmObject", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000023, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000023, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000024, new DummyProgressDlg()); //This object should contain a 'Status' property diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000025Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000025Tests.cs index 6e67fbff6b..347d9849eb 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000025Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000025Tests.cs @@ -1,9 +1,8 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Xml.Linq; -using System.Xml.XPath; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -98,7 +97,7 @@ public void DataMigration7000025Test() mockMdc.AddClass(13, "RnGenericRec", "CmObject", new List()); mockMdc.AddClass(14, "ScrDraft", "CmObject", new List()); mockMdc.AddClass(15, "ScrCheckRun", "CmObject", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000024, dtos, mockMdc, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000024, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); // SUT m_dataMigrationManager.PerformMigration(dtoRepos, 7000025, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000026Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000026Tests.cs index d3393ae0d0..3f19bb81f8 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000026Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000026Tests.cs @@ -3,6 +3,7 @@ using System.Xml.Linq; using System.Xml.XPath; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -31,7 +32,7 @@ public void DataMigration7000026Test() mockMDC.AddClass(2, "CmProject", "CmObject", new List { "LangProject" }); mockMDC.AddClass(3, "LangProject", "CmProject", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000025, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000025, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); //Before the migration there should be a ExtLinkRootDir element in the project. var langProjDto = dtoRepos.AllInstancesSansSubclasses("LangProject").First(); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000027Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000027Tests.cs index e5d3b08e04..03d3348b01 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000027Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000027Tests.cs @@ -9,6 +9,7 @@ using System.Text; using System.Xml.Linq; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -152,7 +153,7 @@ public void DataMigration7000027Test() mockMDC.AddClass(9, "ScrFootnote", "StFootnote", new List()); mockMDC.AddClass(10, "ScrTxtPara", "StTxtPara", new List()); mockMDC.AddClass(11, "StPara", "CmObject", new List { "StTxtPara" }); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000026, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000026, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000027, new DummyProgressDlg()); Assert.AreEqual(7000027, dtoRepos.CurrentModelVersion, "Wrong updated version."); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000028Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000028Tests.cs index fb8efc203a..7f63610d55 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000028Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000028Tests.cs @@ -3,6 +3,7 @@ using System.Xml.Linq; using System.Xml.XPath; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -33,7 +34,7 @@ public void DataMigration7000028Test() mockMDC.AddClass(4, "LexDb", "CmObject", new List ()); mockMDC.AddClass(5, "LexEntry", "CmObject", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000027, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000027, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000028, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000029Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000029Tests.cs index 3340e58b10..2e93c0b428 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000029Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000029Tests.cs @@ -4,6 +4,7 @@ using System.Xml.Linq; using System.Xml.XPath; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; using SIL.Utils; @@ -54,7 +55,7 @@ public void DataMigration7000029Test() mockMDC.AddClass(10, "CmFile", "CmObject", new List()); //-------------------+++++++++++++++++++++++++= - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000028, dtos, mockMDC, @"C:\FwWW\DistFiles\Projects\Sena 3"); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000028, dtos, mockMDC, @"C:\FwWW\DistFiles\Projects\Sena 3", FwDirectoryFinder.FdoDirectories); //Get the Element var langProjDto = dtoRepos.AllInstancesSansSubclasses("LangProject").First(); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000030Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000030Tests.cs index 6a4e36cc09..1ac8a2123a 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000030Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000030Tests.cs @@ -6,6 +6,7 @@ using System.Xml.XPath; using NUnit.Framework; using SIL.CoreImpl; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; using SIL.Utils; @@ -71,7 +72,7 @@ public void DataMigration7000030Test() //-------------------+++++++++++++++++++++++++= - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000029, dtos, mockMDC, @"C:\FwWW\DistFiles\Projects\Sena 3"); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000029, dtos, mockMDC, @"C:\FwWW\DistFiles\Projects\Sena 3", FwDirectoryFinder.FdoDirectories); //Get the Element diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000031Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000031Tests.cs index 8639af0bbd..9fc5383255 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000031Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000031Tests.cs @@ -1,5 +1,6 @@ using System.Linq; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; using SIL.FieldWorks.FDO.Infrastructure; using System.IO; @@ -26,7 +27,7 @@ public void DataMigration7000031Test() IFwMetaDataCacheManaged mockMdc = DataMigrationTests7000020.SetupMdc(); IDomainObjectDTORepository repoDto = new DomainObjectDtoRepository(7000030, dtos, mockMdc, - Path.GetTempPath()); + Path.GetTempPath(), FwDirectoryFinder.FdoDirectories); // Initial check that data was read properly. var cObjects = repoDto.AllInstances().Count(); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000032Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000032Tests.cs index 8318692a35..0ef6ab3188 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000032Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000032Tests.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using NUnit.Framework; using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; @@ -28,7 +27,7 @@ public void DataMigration7000032Test() IFwMetaDataCacheManaged mockMdc = DataMigrationTests7000020.SetupMdc(); IDomainObjectDTORepository repoDto = new DomainObjectDtoRepository(7000030, dtos, mockMdc, - Path.Combine(Path.GetTempPath(), "Wildly-testing_Away~Migration7000032")); + Path.Combine(Path.GetTempPath(), "Wildly-testing_Away~Migration7000032"), FwDirectoryFinder.FdoDirectories); var projectFolder = repoDto.ProjectFolder; var projectName = Path.GetFileNameWithoutExtension(projectFolder); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000033Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000033Tests.cs index 507df6ab6e..8197bbb6b0 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000033Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000033Tests.cs @@ -1,6 +1,4 @@ -using System; -using System.Linq; -using System.Xml; +using System.Linq; using System.Xml.Linq; using NUnit.Framework; using SIL.FieldWorks.Common.FwUtils; @@ -30,7 +28,7 @@ public void DataMigration7000032Test() IFwMetaDataCacheManaged mockMdc = DataMigrationTests7000020.SetupMdc(); IDomainObjectDTORepository repoDto = new DomainObjectDtoRepository(7000032, dtos, mockMdc, - Path.GetTempPath()); + Path.GetTempPath(), FwDirectoryFinder.FdoDirectories); var projectFolder = repoDto.ProjectFolder; var projectName = Path.GetFileNameWithoutExtension(projectFolder); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000034Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000034Tests.cs index c6ffdba512..e80784720e 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000034Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000034Tests.cs @@ -47,7 +47,7 @@ public void DataMigration7000034Test() mockMDC.AddClass(9, "CmFolder", "CmObject", new List()); mockMDC.AddClass(10, "CmFile", "CmObject", new List()); IDomainObjectDTORepository repoDto = new DomainObjectDtoRepository(7000033, dtos, mockMDC, - Path.GetTempPath()); + Path.GetTempPath(), FwDirectoryFinder.FdoDirectories); // Do the migration. m_dataMigrationManager.PerformMigration(repoDto, 7000034, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000035Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000035Tests.cs index 7164576b67..d58a1b1ee0 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000035Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000035Tests.cs @@ -9,6 +9,7 @@ using System.Text; using System.Xml.Linq; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -159,7 +160,7 @@ public void DataMigration7000035Test() mockMDC.AddClass(9, "ScrFootnote", "StFootnote", new List()); mockMDC.AddClass(10, "ScrTxtPara", "StTxtPara", new List()); mockMDC.AddClass(11, "StPara", "CmObject", new List { "StTxtPara" }); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000034, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000034, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000035, new DummyProgressDlg()); Assert.AreEqual(7000035, dtoRepos.CurrentModelVersion, "Wrong updated version."); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000036Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000036Tests.cs index a44b9b9ab8..ebc5d89158 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000036Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000036Tests.cs @@ -10,6 +10,7 @@ using System.Text; using System.Xml.Linq; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; using System; using SIL.FieldWorks.FDO.DomainImpl; @@ -171,7 +172,7 @@ public void DataMigration7000036Test() mockMDC.AddClass(10, "ScrTxtPara", "StTxtPara", new List()); mockMDC.AddClass(11, "StPara", "CmObject", new List { "StTxtPara" }); mockMDC.AddClass(12, "StJounalText", "StText", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000035, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000035, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); DateTime beforeMigration = DateTime.Now.AddSeconds(-1); // avoid tick problem diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000037Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000037Tests.cs index 1951f3b2a9..c5351232cd 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000037Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000037Tests.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Text; using System.Web; using System.Xml.Linq; using System.Xml.XPath; @@ -40,7 +39,7 @@ public void DataMigration7000037Test() mockMDC.AddClass(16, "StTxtPara", "StPara", new List()); IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000036, dtos, mockMDC, - FileUtils.ChangePathToPlatform("C:\\WW\\DistFiles\\Projects\\TokPisin")); + FileUtils.ChangePathToPlatform("C:\\WW\\DistFiles\\Projects\\TokPisin"), FwDirectoryFinder.FdoDirectories); // Check that the version is correct. Assert.AreEqual(7000036, dtoRepos.CurrentModelVersion, "Wrong original version."); // Collect the link values that shouldn't change. diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000040Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000040Tests.cs index 24ec9a9d2c..70bdb87e0b 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000040Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000040Tests.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Web; using System.Xml.Linq; using System.Xml.XPath; @@ -40,7 +39,7 @@ public void DataMigration7000040Test() mockMDC.AddClass(3, "LexEntry", "CmObject", new List()); IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000039, dtos, mockMDC, - FileUtils.ChangePathToPlatform("C:\\WW\\DistFiles\\Projects\\TokPisin")); + FileUtils.ChangePathToPlatform("C:\\WW\\DistFiles\\Projects\\TokPisin"), FwDirectoryFinder.FdoDirectories); // Do Migration m_dataMigrationManager.PerformMigration(dtoRepos, 7000040, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000041Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000041Tests.cs index 1227cf8cc2..e3ac57ee6b 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000041Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000041Tests.cs @@ -1,14 +1,9 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Web; using System.Xml.Linq; -using System.Xml.XPath; using NUnit.Framework; using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; -using SIL.Utils; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests { @@ -49,7 +44,7 @@ public void DataMigration7000041Test() private void TryThisProject(HashSet dtos, MockMDCForDataMigration mockMDC, int numOfPubs) { IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000040, dtos, mockMDC, - @"C:\Path\Not\Used"); + @"C:\Path\Not\Used", FwDirectoryFinder.FdoDirectories); // Do Migration m_dataMigrationManager.PerformMigration(dtoRepos, 7000041, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000042Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000042Tests.cs index 664338f45c..1a32ca572c 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000042Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000042Tests.cs @@ -157,7 +157,7 @@ private void VerifyMigration(HashSet dtos) // Create the DTO repository. IDomainObjectDTORepository repoDto = new DomainObjectDtoRepository(7000041, dtos, mockMDC, - FileUtils.ChangePathToPlatform("C:\\WW\\DistFiles\\Projects\\TokPisin")); + FileUtils.ChangePathToPlatform("C:\\WW\\DistFiles\\Projects\\TokPisin"), FwDirectoryFinder.FdoDirectories); // Do Migration m_dataMigrationManager.PerformMigration(repoDto, 7000042, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000044Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000044Tests.cs index 490a7de1ff..f4f3afa06c 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000044Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000044Tests.cs @@ -73,9 +73,9 @@ public DataMigration7000044Tests() public void DataMigration7000044Test() { var projectFolder = Path.GetTempPath(); - var storePath = Path.Combine(projectFolder, DirectoryFinder.ksWritingSystemsDir); + var storePath = Path.Combine(projectFolder, FdoFileHelper.ksWritingSystemsDir); PrepareStore(storePath); - var testDataPath = Path.Combine(DirectoryFinder.FwSourceDirectory, "FDO/FDOTests/TestData"); + var testDataPath = Path.Combine(FwDirectoryFinder.SourceDirectory, "FDO/FDOTests/TestData"); var testEnglishPath = Path.Combine(storePath, "en.ldml"); File.Copy(Path.Combine(testDataPath, "en_7000043.ldml"), testEnglishPath); File.SetAttributes(testEnglishPath, FileAttributes.Normal); // don't want to copy readonly property. @@ -100,14 +100,14 @@ public void DataMigration7000044Test() mockMDC.AddClass(8, "CmPossibilityList", "CmObject", new List()); mockMDC.AddClass(9, "CmBaseAnnotation", "CmObject", new List()); - var settingsFolder = Path.Combine(projectFolder, DirectoryFinder.ksConfigurationSettingsDir); + var settingsFolder = Path.Combine(projectFolder, FdoFileHelper.ksConfigurationSettingsDir); Directory.CreateDirectory(settingsFolder); var sampleLayout = Path.Combine(settingsFolder, "Test_Layouts.xml"); File.WriteAllText(sampleLayout, sampleLayoutData, Encoding.UTF8); var sampleSettings = Path.Combine(settingsFolder, "db$local$Settings.xml"); File.WriteAllText(sampleSettings, sampleLocalSettingsData, Encoding.UTF8); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000043, dtos, mockMDC, projectFolder); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000043, dtos, mockMDC, projectFolder, FwDirectoryFinder.FdoDirectories); // Do the migration. m_dataMigrationManager.PerformMigration(dtoRepos, 7000044, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000047Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000047Tests.cs index 6f67e8aa96..eb3b5cdcae 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000047Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000047Tests.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Text; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -116,7 +117,7 @@ public void DataMigration7000047Test() mockMDC.AddClass(5, "ChkTerm", "CmObject", new List()); mockMDC.AddClass(6, "CkRendering", "CmObject", new List()); mockMDC.AddClass(7, "WfiWordform", "CmObject", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000046, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000046, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000047, new DummyProgressDlg()); Assert.AreEqual(7000047, dtoRepos.CurrentModelVersion, "Wrong updated version."); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000051Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000051Tests.cs index d2662f00e4..8da24179b0 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000051Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000051Tests.cs @@ -10,6 +10,7 @@ using System.Text; using System.Xml.Linq; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -52,7 +53,7 @@ public void DataMigration7000051Test() mockMDC.AddClass(1, "CmObject", null, new List { "LangProject", "CmPossibilityList" }); // Not true, but no matter. mockMDC.AddClass(2, "LangProject", "CmObject", new List()); mockMDC.AddClass(3, "CmPossibilityList", "CmObject", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000050, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000050, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000051, new DummyProgressDlg()); Assert.AreEqual(7000051, dtoRepos.CurrentModelVersion, "Wrong updated version."); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000052Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000052Tests.cs index c6a7439845..58d75f2eca 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000052Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000052Tests.cs @@ -10,6 +10,7 @@ using System.Text; using System.Xml.Linq; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -76,7 +77,7 @@ public void DataMigration7000052Test() mockMDC.AddClass(1, "CmObject", null, new List { "WfiMorphBundle", "MoAffixAllomorph" }); // Not true, but no matter. mockMDC.AddClass(2, "WfiMorphBundle", "CmObject", new List()); mockMDC.AddClass(3, "MoAffixAllomorph", "CmObject", new List()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000051, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000051, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000052, new DummyProgressDlg()); Assert.AreEqual(7000052, dtoRepos.CurrentModelVersion, "Wrong updated version."); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000056Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000056Tests.cs index bd1c8f0eda..3c86a110f5 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000056Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000056Tests.cs @@ -10,6 +10,7 @@ using System.Text; using System.Xml.Linq; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -32,7 +33,7 @@ public void DataMigration7000056Test() var dtos = DataMigrationTestServices.ParseProjectFile("DataMigration7000056.xml"); // Set up mock MDC. var mockMDC = new MockMDCForDataMigration(); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000055, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000055, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000056, new DummyProgressDlg()); Assert.AreEqual(7000056, dtoRepos.CurrentModelVersion, "Wrong updated version."); @@ -59,7 +60,7 @@ public void DataMigration7000056Test() sb.Length = 0; mockMDC = new MockMDCForDataMigration(); - dtoRepos = new DomainObjectDtoRepository(7000055, dtos, mockMDC, null); + dtoRepos = new DomainObjectDtoRepository(7000055, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000056, new DummyProgressDlg()); Assert.AreEqual(7000056, dtoRepos.CurrentModelVersion, "Wrong updated version."); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000057Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000057Tests.cs index 8f4c435794..91ff254089 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000057Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000057Tests.cs @@ -9,6 +9,7 @@ using System.Xml.Linq; using System.Xml.XPath; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -39,7 +40,7 @@ public void DataMigration7000057Test_Normal() var dtos = DataMigrationTestServices.ParseProjectFile("DataMigration7000057_Normal.xml"); // Set up mock MDC. var mockMdc = new MockMDCForDataMigration(); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000056, dtos, mockMdc, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000056, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000057, new DummyProgressDlg()); Assert.AreEqual(7000057, dtoRepos.CurrentModelVersion, "Wrong updated version."); @@ -93,7 +94,7 @@ public void DataMigration7000057Test_SubInflTypes() var dtos = DataMigrationTestServices.ParseProjectFile("DataMigration7000057_SubInflTypes.xml"); // Set up mock MDC. var mockMdc = new MockMDCForDataMigration(); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000056, dtos, mockMdc, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000056, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000057, new DummyProgressDlg()); Assert.AreEqual(7000057, dtoRepos.CurrentModelVersion, "Wrong updated version."); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000058Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000058Tests.cs index 2e6a584091..a15b1bf402 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000058Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000058Tests.cs @@ -9,6 +9,7 @@ using System.Xml.Linq; using System.Xml.XPath; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -36,7 +37,7 @@ public void DataMigration7000058Test_FillEmptyGlossAppend() var dtos = DataMigrationTestServices.ParseProjectFile("DataMigration7000058_EmptyGlossAppend.xml"); // Set up mock MDC. var mockMdc = new MockMDCForDataMigration(); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000057, dtos, mockMdc, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000057, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000058, new DummyProgressDlg()); Assert.AreEqual(7000058, dtoRepos.CurrentModelVersion, "Wrong updated version."); @@ -70,7 +71,7 @@ public void DataMigration7000058Test_SkipNonEmptyGlossAppend() var dtos = DataMigrationTestServices.ParseProjectFile("DataMigration7000058_NonEmptyGlossAppend.xml"); // Set up mock MDC. var mockMdc = new MockMDCForDataMigration(); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000057, dtos, mockMdc, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000057, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000058, new DummyProgressDlg()); Assert.AreEqual(7000058, dtoRepos.CurrentModelVersion, "Wrong updated version."); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000059Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000059Tests.cs index 697170797c..86817f9389 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000059Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000059Tests.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Xml.Linq; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -35,7 +36,7 @@ public void DataMigration7000059Test() mockMDC.AddClass(6, "Text", "CmMajorObject", new List()); mockMDC.AddClass(7, "RnGenericRec", "CmObject", new List ()); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000058, dtos, mockMDC, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000058, dtos, mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000059, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000060Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000060Tests.cs index c47551a888..791ffd56cf 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000060Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000060Tests.cs @@ -1,8 +1,6 @@ using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text; -using System.Xml.Linq; using NUnit.Framework; using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; @@ -26,7 +24,7 @@ public void DataMigration7000060Test() { var projectFolder = Path.GetTempPath(); - var settingsFolder = Path.Combine(projectFolder, DirectoryFinder.ksConfigurationSettingsDir); + var settingsFolder = Path.Combine(projectFolder, FdoFileHelper.ksConfigurationSettingsDir); var sampleLayout = Path.Combine(settingsFolder, "Test_Layouts.xml"); var otherFile = Path.Combine(settingsFolder, "other.xml"); var newLayoutPath = Path.Combine(settingsFolder, "Test.fwlayout"); @@ -40,7 +38,7 @@ public void DataMigration7000060Test() var mockMDC = new MockMDCForDataMigration(); // no classes to migrate here var dtos = new HashSet(); // no objects to migrate - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000059, dtos, mockMDC, projectFolder); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000059, dtos, mockMDC, projectFolder, FwDirectoryFinder.FdoDirectories); // Do the migration. m_dataMigrationManager.PerformMigration(dtoRepos, 7000060, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000061Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000061Tests.cs index ea77e9415f..cd8ac4a536 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000061Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000061Tests.cs @@ -4,6 +4,7 @@ using System.Xml.Linq; using NUnit.Framework; using SIL.CoreImpl; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -42,7 +43,7 @@ public void DataMigration7000061Test() mockMdc.AddField(6001, "StemName", CellarPropertyType.ReferenceAtomic, 7); var dtos = DataMigrationTestServices.ParseProjectFile("DataMigration7000061.xml"); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000060, dtos, mockMdc, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000060, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000061, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000062Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000062Tests.cs index 4c8917b486..8136b8e474 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000062Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000062Tests.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Xml.Linq; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -26,7 +27,7 @@ public void DataMigration7000062Test() mockMdc.AddClass(4, "CmResource", "CmObject", new List()); var dtos = DataMigrationTestServices.ParseProjectFile("DataMigration7000062.xml"); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000061, dtos, mockMdc, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000061, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000062, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000063Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000063Tests.cs index eaf685fb8d..747c1b8d8d 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000063Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000063Tests.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Xml.Linq; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -32,7 +33,7 @@ public void DataMigration7000063Test() mockMdc.AddClass(2, "LangProject", "CmObject", new List()); var dtos = DataMigrationTestServices.ParseProjectFile("DataMigration7000063.xml"); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000062, dtos, mockMdc, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000062, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000063, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000065Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000065Tests.cs index 08beda6049..93cd7fdbde 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000065Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000065Tests.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Xml.Linq; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -37,7 +38,7 @@ public void DataMigration7000065Test() mockMdc.AddClass(7, "PartOfSpeech", "CmPossibility", new List()); var dtos = DataMigrationTestServices.ParseProjectFile("DataMigration7000065.xml"); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000064, dtos, mockMdc, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000064, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000065, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000066Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000066Tests.cs index 23b42b23f2..f028273ba9 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000066Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000066Tests.cs @@ -11,6 +11,7 @@ using System.Xml.Linq; using NUnit.Framework; using SIL.CoreImpl; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -56,7 +57,7 @@ public void AllRegularBasicDataPropertiesExistAfterDataMigration66() mockMdc.AddField(++currentFlid, "NewTimeProperty", CellarPropertyType.Time, 0); var dtos = DataMigrationTestServices.ParseProjectFile("DataMigration7000066_RegularPropertyMagnet.xml"); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000065, dtos, mockMdc, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000065, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000066, new DummyProgressDlg()); @@ -120,7 +121,7 @@ public void AllInheritedRegularBasicDataPropertiesExistAfterDataMigration66() mockMdc.AddField(++currentFlid, "NewTimeProperty", CellarPropertyType.Time, 0); var dtos = DataMigrationTestServices.ParseProjectFile("DataMigration7000066_RegularPropertyMagnet.xml"); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000065, dtos, mockMdc, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000065, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000066, new DummyProgressDlg()); @@ -184,7 +185,7 @@ public void AllCustomBasicDataPropertiesExistAfterDataMigration66() var missingTimeFlid = mockMdc.AddCustomField("CustomPropertyMagnet", "NewTimeProperty", CellarPropertyType.Time, 0); var dtos = DataMigrationTestServices.ParseProjectFile("DataMigration7000066_CustomPropertyMagnet.xml"); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000065, dtos, mockMdc, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000065, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000066, new DummyProgressDlg()); @@ -242,7 +243,7 @@ public void AllInheritedCustomBasicDataPropertiesExistAfterDataMigration66() var missingTimeFlid = mockMdc.AddCustomField("CmObject", "NewTimeProperty", CellarPropertyType.Time, 0); var dtos = DataMigrationTestServices.ParseProjectFile("DataMigration7000066_CustomPropertyMagnet.xml"); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000065, dtos, mockMdc, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000065, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000066, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000067Tests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000067Tests.cs index 9ed18e2755..8a1af61891 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000067Tests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigration7000067Tests.cs @@ -3,6 +3,7 @@ using System.Xml.Linq; using NUnit.Framework; using SIL.CoreImpl; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -35,7 +36,7 @@ public void UniElementPropertiesAreRemoved() mockMdc.AddClass(4, "ClassWithInheritedUnicodeProperties", "AbstractClassWithUnicodeProperties", new List()); var dtos = DataMigrationTestServices.ParseProjectFile("DataMigration7000067TestData.xml"); - IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000066, dtos, mockMdc, null); + IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7000066, dtos, mockMdc, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000067, new DummyProgressDlg()); diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigrationBasicTests.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigrationBasicTests.cs index 93e8f4a11c..972b17b67e 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigrationBasicTests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigrationBasicTests.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.FDOTests.DataMigrationTests @@ -34,7 +35,7 @@ public void DowngradeMigrationTest() { var mockMDC = new MockMDCForDataMigration(); IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(7100000, - new HashSet(), mockMDC, null); + new HashSet(), mockMDC, null, FwDirectoryFinder.FdoDirectories); m_dataMigrationManager.PerformMigration(dtoRepos, 7000000, null); } diff --git a/Src/FDO/FDOTests/DataMigrationTests/DataMigrationTestServices.cs b/Src/FDO/FDOTests/DataMigrationTests/DataMigrationTestServices.cs index 51ec39f79a..758cd6aac4 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/DataMigrationTestServices.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/DataMigrationTestServices.cs @@ -32,7 +32,7 @@ internal static void CheckDtoRemoved(IDomainObjectDTORepository dtoRepos, Domain /// ------------------------------------------------------------------------------------ internal static HashSet ParseProjectFile(string filename) { - var testDataPath = Path.Combine(DirectoryFinder.FwSourceDirectory, "FDO/FDOTests/TestData"); + var testDataPath = Path.Combine(FwDirectoryFinder.SourceDirectory, "FDO/FDOTests/TestData"); var lpElement = XElement.Load(Path.Combine(testDataPath, filename)); return new HashSet( from elem in lpElement.Elements("rt") diff --git a/Src/FDO/FDOTests/DataMigrationTests/IDomainObjectDTORepositoryTests.cs b/Src/FDO/FDOTests/DataMigrationTests/IDomainObjectDTORepositoryTests.cs index 4548801d7a..71e1772c36 100644 --- a/Src/FDO/FDOTests/DataMigrationTests/IDomainObjectDTORepositoryTests.cs +++ b/Src/FDO/FDOTests/DataMigrationTests/IDomainObjectDTORepositoryTests.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.DataMigration; using SIL.FieldWorks.FDO.Infrastructure; @@ -45,7 +46,7 @@ public void FixtureSetup() [ExpectedException(typeof(ArgumentNullException))] public void NulldtosParamTest() { - new DomainObjectDtoRepository(1, null, m_mdc, null); + new DomainObjectDtoRepository(1, null, m_mdc, null, FwDirectoryFinder.FdoDirectories); } /// ------------------------------------------------------------------------------------ @@ -58,7 +59,7 @@ public void NulldtosParamTest() public void NullmdcParamTest() { new DomainObjectDtoRepository(1, new HashSet(), - null, null); + null, null, FwDirectoryFinder.FdoDirectories); } /// ------------------------------------------------------------------------------------ @@ -74,7 +75,7 @@ public void NonExistantGuidTest() 1, new HashSet(), m_mdc, - null); + null, FwDirectoryFinder.FdoDirectories); dtoRepos.GetDTO(Guid.NewGuid().ToString()); } @@ -91,7 +92,7 @@ public void ExtantGuidFindsDTOTest() const string lpGuid = "9719A466-2240-4DEA-9722-9FE0746A30A6"; var lpDto = CreatoDTO(dtos, lpGuid, "LangProject", null); IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(1, dtos, - m_mdc, null); + m_mdc, null, FwDirectoryFinder.FdoDirectories); var resultDto = dtoRepos.GetDTO(lpGuid); Assert.AreSame(lpDto, resultDto, "Wrong DTO."); } @@ -109,7 +110,7 @@ public void TryGetValueTests() const string lpGuid = "9719A466-2240-4DEA-9722-9FE0746A30A6"; CreatoDTO(dtos, lpGuid, "LangProject", null); IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(1, dtos, - m_mdc, null); + m_mdc, null, FwDirectoryFinder.FdoDirectories); DomainObjectDTO dto; var retval = dtoRepos.TryGetValue(Guid.NewGuid().ToString().ToLower(), out dto); Assert.IsNull(dto, "Oops.It does exist."); @@ -147,7 +148,7 @@ public void DtosByClassButNoSubclassesTest() const string lpGuid = "9719A466-2240-4DEA-9722-9FE0746A30A6"; CreatoDTO(dtos, lpGuid, "LangProject", null); IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(1, dtos, - m_mdc, null); + m_mdc, null, FwDirectoryFinder.FdoDirectories); var result = new List(dtoRepos.AllInstancesSansSubclasses("CmObject")); Assert.AreEqual(0, result.Count, "Wrong number of DTOs (expected 0)."); result = new List(dtoRepos.AllInstancesSansSubclasses("LangProject")); @@ -169,7 +170,7 @@ public void DtosByClassWithSubclassesTest() const string lexDbGuid = "6C84F84A-5B99-4CF5-A7D5-A308DDC604E0"; CreatoDTO(dtos, lexDbGuid, "LexDb", null); IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(1, dtos, - m_mdc, null); + m_mdc, null, FwDirectoryFinder.FdoDirectories); var result = new List(dtoRepos.AllInstancesWithSubclasses("CmObject")); Assert.AreEqual(2, result.Count, "Wrong number of DTOs (expected 2)."); } @@ -189,7 +190,7 @@ public void OwningDtoTest() const string lexDbGuid = "6C84F84A-5B99-4CF5-A7D5-A308DDC604E0"; var ldbDto = CreatoDTO(dtos, lexDbGuid, "LexDb", lpGuid); IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(1, dtos, - m_mdc, null); + m_mdc, null, FwDirectoryFinder.FdoDirectories); Assert.IsNull(dtoRepos.GetOwningDTO(lpDto), "LP has owner?"); var ldbOwner = dtoRepos.GetOwningDTO(ldbDto); @@ -212,7 +213,7 @@ public void AddNewDtoTest() const string lexDbGuid = "6C84F84A-5B99-4CF5-A7D5-A308DDC604E0"; CreatoDTO(dtos, lexDbGuid, "LexDb", null); IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(1, dtos, - m_mdc, null); + m_mdc, null, FwDirectoryFinder.FdoDirectories); // Create new DTO and add it. var newGuid = Guid.NewGuid(); @@ -236,7 +237,7 @@ public void RemoveDtoTest() const string lpGuid = "9719A466-2240-4DEA-9722-9FE0746A30A6"; var lpDto = CreatoDTO(dtos, lpGuid, "LangProject", null); IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(1, dtos, - m_mdc, null); + m_mdc, null, FwDirectoryFinder.FdoDirectories); dtoRepos.Remove(lpDto); Assert.IsTrue(((DomainObjectDtoRepository)dtoRepos).Goners.Contains(lpDto), "Goner not in goners set."); @@ -265,7 +266,7 @@ public void UpdateDtoTest() const string lpGuid = "9719A466-2240-4DEA-9722-9FE0746A30A6"; var lpDto = CreatoDTO(dtos, lpGuid, "LangProject", null); IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(1, dtos, - m_mdc, null); + m_mdc, null, FwDirectoryFinder.FdoDirectories); dtoRepos.Update(lpDto); Assert.IsTrue(((DomainObjectDtoRepository)dtoRepos).Dirtballs.Contains(lpDto), "Dirty DTO not in dirtball set."); @@ -285,7 +286,7 @@ public void UpdateUnknownDtoTest() const string lpGuid = "9719A466-2240-4DEA-9722-9FE0746A30A6"; CreatoDTO(dtos, lpGuid, "LangProject", null); IDomainObjectDTORepository dtoRepos = new DomainObjectDtoRepository(1, dtos, - m_mdc, null); + m_mdc, null, FwDirectoryFinder.FdoDirectories); var newGuid = Guid.NewGuid(); var newby = new DomainObjectDTO(newGuid.ToString(), "LexEntry", ""); diff --git a/Src/FDO/FDOTests/Db4oServerInfoTests.cs b/Src/FDO/FDOTests/Db4oServerInfoTests.cs index 688a2f4168..e2694cac7a 100644 --- a/Src/FDO/FDOTests/Db4oServerInfoTests.cs +++ b/Src/FDO/FDOTests/Db4oServerInfoTests.cs @@ -10,9 +10,7 @@ using NUnit.Framework; using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices; -using SIL.FieldWorks.Resources; using SIL.FieldWorks.Test.TestUtils; -using SIL.Utils; namespace SIL.FieldWorks.FDO.FDOTests { @@ -180,16 +178,15 @@ public class Db4oServerInfoTests : BaseTest { // Get created a fresh for each unit test private Db4oServerInfo m_db4OServerInfo; - private DummyFwRegistryHelper m_helper; + private bool m_sharedProject; /// [SetUp] public void StartFwRemoteDatabaseConnector() { - m_helper = new DummyFwRegistryHelper(); - FwRegistryHelper.Manager.SetRegistryHelper(m_helper); - m_helper.DeleteAllSubTreesIfPresent(); - RemotingServer.Start(); + FdoTestHelper.SetupClientServerServices(); + m_sharedProject = true; + RemotingServer.Start(FwDirectoryFinder.RemotingTcpServerConfigFile, FwDirectoryFinder.FdoDirectories, () => m_sharedProject, v => m_sharedProject = v); var connectString = String.Format("tcp://{0}:{1}/FwRemoteDatabaseConnector.Db4oServerInfo", "localhost", Db4OPorts.ServerPort); @@ -200,7 +197,6 @@ public void StartFwRemoteDatabaseConnector() [TearDown] public void StopFwRemoteDatabaseConnector() { - FwRegistryHelper.Manager.Reset(); m_db4OServerInfo = null; RemotingServer.Stop(); } @@ -209,13 +205,13 @@ public void StopFwRemoteDatabaseConnector() [Test] public void ListServers_UnknownNumberOfServers_ReturnsAllServersInProjectsDirectory() { - int projectsCount = Directory.GetFiles(DirectoryFinder.ProjectsDirectory, "*" + FwFileExtensions.ksFwDataDb4oFileExtension, + int projectsCount = Directory.GetFiles(FwDirectoryFinder.ProjectsDirectory, "*" + FdoFileHelper.ksFwDataDb4oFileExtension, SearchOption.AllDirectories).Count(); m_db4OServerInfo.RefreshServerList(); Assert.AreEqual(projectsCount, m_db4OServerInfo.ListServers().Count(), - String.Format("ListServer should return all the db4o projects in the DirectoryFinder.ProjectsDirectory : {0}", DirectoryFinder.ProjectsDirectory)); + String.Format("ListServer should return all the db4o projects in the FwDirectoryFinder.ProjectsDirectory : {0}", FwDirectoryFinder.ProjectsDirectory)); } /// @@ -435,65 +431,5 @@ public void IsLocalHost_NonLocalHost_ReturnsFalse() { Assert.IsFalse(m_db4OServerInfo.IsLocalHost("MyRemoteHost")); } - - /// - /// Tests how ProjectShared key was migrated from version 7. - /// - [Test] - public void AreProjectsSharedInternal_7Unset_NotMigrated() - { - // Setup - using(var version7Key = m_helper.SetupVersion7Settings()) - { - // SUT - object dummy = Db4oServerInfo.AreProjectsShared_Internal; - - // Verification - // Verify that the version 8 ProjectShared key is missing. - Assert.IsFalse(RegistryHelper.RegEntryExists(FwRegistryHelper.FieldWorksRegistryKey, null, "ProjectShared", out dummy)); - } - } - - /// - /// Tests how ProjectShared key was migrated from version 7. - /// - [Test] - public void AreProjectsSharedInternal_7UnsetDespiteExistingPath_NotMigrated() - { - // Setup - using(m_helper.SetupVersion7ProjectSharedSettingLocation()) - using(var version7Key = m_helper.SetupVersion7Settings()) - { - // SUT - object dummy = Db4oServerInfo.AreProjectsShared_Internal; - - // Verification - // Verify that the version 8 ProjectShared key is missing. - Assert.IsFalse(RegistryHelper.RegEntryExists(FwRegistryHelper.FieldWorksRegistryKey, null, "ProjectShared", out dummy)); - } - } - - /// - /// Tests how ProjectShared key was migrated from version 7. - /// - [Test] - public void AreProjectsSharedInternal_7Set_Migrated() - { - // Setup - using(m_helper.SetupVersion7ProjectSharedSetting()) - using(var version7Key = m_helper.SetupVersion7Settings()) - { - object projectsSharedValue; - // Verify that the version 8 ProjectShared key is missing before migration - Assert.IsFalse(RegistryHelper.RegEntryExists(FwRegistryHelper.FieldWorksRegistryKey, null, "ProjectShared", out projectsSharedValue)); - // SUT - projectsSharedValue = Db4oServerInfo.AreProjectsShared_Internal; - - // Verification - // Verify that the version 8 ProjectShared key is set after migration. - Assert.IsTrue(RegistryHelper.RegEntryExists(FwRegistryHelper.FieldWorksRegistryKey, null, "ProjectShared", out projectsSharedValue)); - Assert.IsTrue(bool.Parse((string)projectsSharedValue)); - } - } } } diff --git a/Src/FDO/FDOTests/DummyFdoUI.cs b/Src/FDO/FDOTests/DummyFdoUI.cs new file mode 100644 index 0000000000..0d9d99188a --- /dev/null +++ b/Src/FDO/FDOTests/DummyFdoUI.cs @@ -0,0 +1,173 @@ +// Copyright (c) 2013-2014 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) + +using System; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using SIL.Utils; + +namespace SIL.FieldWorks.FDO.FDOTests +{ + /// + /// Dummy implementation of IFdoUI for unit tests + /// + [SuppressMessage("Gendarme.Rules.Design", "TypesWithDisposableFieldsShouldBeDisposableRule", + Justification="m_threadHelper is a singleton and disposed by the SingletonsContainer")] + public class DummyFdoUI : IFdoUI + { + private readonly ThreadHelper m_threadHelper = SingletonsContainer.Get(); + + /// + /// Gets the object that is used to invoke methods on the main UI thread. + /// + public ISynchronizeInvoke SynchronizeInvoke + { + get { return m_threadHelper; } + } + + /// + /// Gets the error message. + /// + /// + /// The error message. + /// + public string ErrorMessage { get; private set; } + + /// + /// Indicates whether a conflicting save occurred. + /// + public bool ConflictingSaveOccurred { get; private set; } + + /// + /// Check with user regarding conflicting changes + /// + /// True if user wishes to revert to saved state. False otherwise. + public bool ConflictingSave() + { + ConflictingSaveOccurred = true; + return true; + } + + /// + /// Resets all testing metadata. + /// + public void Reset() + { + ConflictingSaveOccurred = false; + ErrorMessage = null; + } + + /// + /// Inform the user of a lost connection + /// + /// True if user wishes to attempt reconnect. False otherwise. + public bool ConnectionLost() + { + throw new NotImplementedException(); + } + + /// + /// Gets the last time that there was user activity. + /// + public DateTime LastActivityTime + { + get { return DateTime.Now; } + } + + /// + /// Check with user regarding which files to use + /// + /// + public FileSelection ChooseFilesToUse() + { + throw new NotImplementedException(); + } + + /// + /// Check with user regarding restoring linked files in the project folder or original path + /// + /// True if user wishes to restore linked files in project folder. False to leave them in the original location. + public bool RestoreLinkedFilesInProjectFolder() + { + throw new NotImplementedException(); + } + + /// + /// Cannot restore linked files to original path. + /// Check with user regarding restoring linked files in the project folder or not at all + /// + /// OkYes to restore to project folder, OkNo to skip restoring linked files, Cancel otherwise + public YesNoCancel CannotRestoreLinkedFilesToOriginalLocation() + { + throw new NotImplementedException(); + } + + /// + /// Displays information to the user + /// + /// + /// + /// + /// + public void DisplayMessage(MessageType type, string message, string caption, string helpTopic) + { + throw new NotImplementedException(); + } + + /// + /// Show a dialog or output to the error log, as appropriate. + /// + /// the exception you want to report + /// set to true if the error is lethal, otherwise + /// false. + /// True if the error was lethal and the user chose to exit the application, + /// false otherwise. + public void ReportException(Exception error, bool isLethal) + { + // Store the message so we can check it later + ErrorMessage = error.Message; + } + + /// + /// Reports duplicate guids to the user + /// + /// The error text. + public void ReportDuplicateGuids(string errorText) + { + throw new NotImplementedException(); + } + + /// + /// Ask user if they wish to restore an XML project from a backup project file. + /// + /// The project path. + /// The backup path. + /// + /// + public bool OfferToRestore(string projectPath, string backupPath) + { + throw new NotImplementedException(); + } + + /// + /// Exits the application. + /// + /// + public void Exit() + { + throw new NotImplementedException(); + } + + /// + /// Present a message to the user and allow the options to Retry or Cancel + /// + /// The message. + /// The caption. + /// True to retry. False otherwise + public bool Retry(string msg, string caption) + { + throw new NotImplementedException(); + } + } +} diff --git a/Src/FDO/FDOTests/DummyProgressDlg.cs b/Src/FDO/FDOTests/DummyProgressDlg.cs index b7e1f3bf44..42384d7071 100644 --- a/Src/FDO/FDOTests/DummyProgressDlg.cs +++ b/Src/FDO/FDOTests/DummyProgressDlg.cs @@ -90,6 +90,15 @@ public void Step(int amount) /// public int Maximum { get; set; } + /// + /// Gets an object to be used for ensuring that required tasks are invoked on the main + /// UI thread. + /// + public ISynchronizeInvoke SynchronizeInvoke + { + get { return m_threadHelper; } + } + /// /// Gets or sets a value indicating whether the task has been canceled. /// @@ -109,6 +118,15 @@ public Form Form get { return null; } } + /// + /// Gets or sets a value indicating whether this progress is indeterminate. + /// + public bool IsIndeterminate + { + get { return false; } + set { } + } + /// ------------------------------------------------------------------------------------ /// /// Gets or sets a value indicating whether the opertation executing on the separate thread @@ -156,29 +174,6 @@ public object RunTask(Func backgroundTask, return backgroundTask(this, parameters); } - /// ------------------------------------------------------------------------------------ - /// - /// Gets a thread helper used for ensuring that required tasks are invoked on the main - /// UI thread. - /// - /// null - /// ------------------------------------------------------------------------------------ - public ThreadHelper ThreadHelper - { - get { return m_threadHelper; } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets or sets the progress bar style. - /// - /// ------------------------------------------------------------------------------------ - public ProgressBarStyle ProgressBarStyle - { - get { return ProgressBarStyle.Continuous; } - set { } - } - #endregion } } diff --git a/Src/FDO/FDOTests/DuplicateAnalysisFixerTests.cs b/Src/FDO/FDOTests/DuplicateAnalysisFixerTests.cs index 1175bd9806..f315cd3bc8 100644 --- a/Src/FDO/FDOTests/DuplicateAnalysisFixerTests.cs +++ b/Src/FDO/FDOTests/DuplicateAnalysisFixerTests.cs @@ -1,13 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Text; +using System.Diagnostics.CodeAnalysis; using System.Windows.Forms; using NUnit.Framework; using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.FDO.DomainServices; +using SIL.FieldWorks.FdoUi; namespace SIL.FieldWorks.FDO.FDOTests { @@ -20,7 +17,7 @@ namespace SIL.FieldWorks.FDO.FDOTests public class DuplicateAnalysisFixerTests : MemoryOnlyBackendProviderRestoredForEachTestTestBase { private IWfiWordformFactory m_wfiFactory; - private ProgressBar m_progress; + private ProgressBarWrapper m_progress; /// /// Set up some common data @@ -29,13 +26,13 @@ public override void TestSetup() { base.TestSetup(); m_wfiFactory = Cache.ServiceLocator.GetInstance(); - m_progress = new ProgressBar(); + m_progress = new ProgressBarWrapper(new ProgressBar()); } /// public override void TestTearDown() { - m_progress.Dispose(); + m_progress.ProgressBar.Dispose(); m_progress = null; base.TestTearDown(); } diff --git a/Src/FDO/FDOTests/DuplicateWordformFixerTests.cs b/Src/FDO/FDOTests/DuplicateWordformFixerTests.cs index e3b88655f2..af90d68462 100644 --- a/Src/FDO/FDOTests/DuplicateWordformFixerTests.cs +++ b/Src/FDO/FDOTests/DuplicateWordformFixerTests.cs @@ -3,6 +3,7 @@ using NUnit.Framework; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.FDO.DomainServices; +using SIL.FieldWorks.FdoUi; namespace SIL.FieldWorks.FDO.FDOTests { @@ -15,7 +16,7 @@ namespace SIL.FieldWorks.FDO.FDOTests public class DuplicateWordformFixerTests : MemoryOnlyBackendProviderRestoredForEachTestTestBase { private IWfiWordformFactory m_wfiFactory; - private ProgressBar m_progress; + private ProgressBarWrapper m_progress; /// /// Set up some common data @@ -24,13 +25,13 @@ public override void TestSetup() { base.TestSetup(); m_wfiFactory = Cache.ServiceLocator.GetInstance(); - m_progress = new ProgressBar(); + m_progress = new ProgressBarWrapper(new ProgressBar()); } /// public override void TestTearDown() { - m_progress.Dispose(); + m_progress.ProgressBar.Dispose(); m_progress = null; base.TestTearDown(); } diff --git a/Src/FDO/FDOTests/FDOTests.csproj b/Src/FDO/FDOTests/FDOTests.csproj index 164a66c025..a53cd74595 100644 --- a/Src/FDO/FDOTests/FDOTests.csproj +++ b/Src/FDO/FDOTests/FDOTests.csproj @@ -169,10 +169,6 @@ False ..\..\..\Downloads\Palaso.dll - - False - ..\..\..\DistFiles\ParatextShared.dll - False ..\..\..\Output\Debug\PhonEnvValidator.dll @@ -299,6 +295,7 @@ + @@ -330,6 +327,7 @@ + @@ -352,7 +350,6 @@ - @@ -381,6 +378,7 @@ + @@ -564,6 +562,12 @@ true + + + {7B119B65-DD6F-4AFB-BBA3-682DC084FB33} + FdoUi + + ../../../DistFiles diff --git a/Src/FDO/FDOTests/FdoCacheTests.cs b/Src/FDO/FDOTests/FdoCacheTests.cs index 7a4eb8dd97..a043f542fd 100644 --- a/Src/FDO/FDOTests/FdoCacheTests.cs +++ b/Src/FDO/FDOTests/FdoCacheTests.cs @@ -29,20 +29,23 @@ namespace SIL.FieldWorks.FDO.CoreTests.FdoCacheTests public class FdoCacheTests : MemoryOnlyBackendProviderTestBase { private string m_oldProjectDirectory; + private IFdoUI m_ui; /// Setup for db4o client server tests. public override void FixtureSetup() { base.FixtureSetup(); - m_oldProjectDirectory = DirectoryFinder.ProjectsDirectory; - DirectoryFinder.ProjectsDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - Directory.CreateDirectory(DirectoryFinder.ProjectsDirectory); + m_oldProjectDirectory = FwDirectoryFinder.ProjectsDirectory; + FwDirectoryFinder.ProjectsDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + Directory.CreateDirectory(FwDirectoryFinder.ProjectsDirectory); + + m_ui = new DummyFdoUI(); try { // Allow db4o client server unit test to work without running the window service. - FwRemoteDatabaseConnector.RemotingServer.Start(); + FwRemoteDatabaseConnector.RemotingServer.Start(FwDirectoryFinder.RemotingTcpServerConfigFile, FwDirectoryFinder.FdoDirectories, () => false, v => {}); } catch (RemotingException e) { @@ -57,8 +60,8 @@ public override void FixtureSetup() public override void FixtureTeardown() { FwRemoteDatabaseConnector.RemotingServer.Stop(); - Directory.Delete(DirectoryFinder.ProjectsDirectory, true); - DirectoryFinder.ProjectsDirectory = m_oldProjectDirectory; + Directory.Delete(FwDirectoryFinder.ProjectsDirectory, true); + FwDirectoryFinder.ProjectsDirectory = m_oldProjectDirectory; base.FixtureTeardown(); } @@ -71,19 +74,19 @@ public override void FixtureTeardown() [ExpectedException(typeof(ArgumentException))] public void CreateNewLangProject_DbFilesExist() { - var preExistingDirs = new List(Directory.GetDirectories(DirectoryFinder.ProjectsDirectory)); + var preExistingDirs = new List(Directory.GetDirectories(FwDirectoryFinder.ProjectsDirectory)); try { // Setup: Create "pre-existing" DB filenames - using (new DummyFileMaker(Path.Combine(DirectoryFinder.ProjectsDirectory, "Gumby", DirectoryFinder.GetXmlDataFileName("Gumby")))) + using (new DummyFileMaker(Path.Combine(FwDirectoryFinder.ProjectsDirectory, "Gumby", FdoFileHelper.GetXmlDataFileName("Gumby")))) { using (var threadHelper = new ThreadHelper()) - FdoCache.CreateNewLangProj(new DummyProgressDlg(), "Gumby", threadHelper); + FdoCache.CreateNewLangProj(new DummyProgressDlg(), "Gumby", FwDirectoryFinder.FdoDirectories, threadHelper); } } finally { - RemoveTestDirs(preExistingDirs, Directory.GetDirectories(DirectoryFinder.ProjectsDirectory)); + RemoveTestDirs(preExistingDirs, Directory.GetDirectories(FwDirectoryFinder.ProjectsDirectory)); } } @@ -97,20 +100,20 @@ public void CreateNewLangProject_DbFilesExist() public void CreateNewLangProject_NameWithSingleQuote() { const string dbName = "!!t'st"; - string dbDir = Path.Combine(DirectoryFinder.ProjectsDirectory, dbName); + string dbDir = Path.Combine(FwDirectoryFinder.ProjectsDirectory, dbName); SureRemoveDb(dbName); - var expectedDirs = new List(Directory.GetDirectories(DirectoryFinder.ProjectsDirectory)) { dbDir }; - var writingSystemsCommonDir = Path.Combine(DirectoryFinder.ProjectsDirectory, DirectoryFinder.ksWritingSystemsDir); + var expectedDirs = new List(Directory.GetDirectories(FwDirectoryFinder.ProjectsDirectory)) { dbDir }; + var writingSystemsCommonDir = Path.Combine(FwDirectoryFinder.ProjectsDirectory, FdoFileHelper.ksWritingSystemsDir); List currentDirs = null; try { string dbFileName; using (var threadHelper = new ThreadHelper()) - dbFileName = FdoCache.CreateNewLangProj(new DummyProgressDlg(), dbName, threadHelper); + dbFileName = FdoCache.CreateNewLangProj(new DummyProgressDlg(), dbName, FwDirectoryFinder.FdoDirectories, threadHelper); - currentDirs = new List(Directory.GetDirectories(DirectoryFinder.ProjectsDirectory)); + currentDirs = new List(Directory.GetDirectories(FwDirectoryFinder.ProjectsDirectory)); if (currentDirs.Contains(writingSystemsCommonDir) && !expectedDirs.Contains(writingSystemsCommonDir)) expectedDirs.Add(writingSystemsCommonDir); CollectionAssert.AreEquivalent(expectedDirs, currentDirs); @@ -132,16 +135,16 @@ public void CreateNewLangProject_AnthropologyCategoriesExist() { const string dbName = "AnthropologicalTest"; SureRemoveDb(dbName); - var preExistingDirs = new List(Directory.GetDirectories(DirectoryFinder.ProjectsDirectory)); + var preExistingDirs = new List(Directory.GetDirectories(FwDirectoryFinder.ProjectsDirectory)); try { // create project string dbFileName; using (var threadHelper = new ThreadHelper()) - dbFileName = FdoCache.CreateNewLangProj(new DummyProgressDlg(), dbName, threadHelper); + dbFileName = FdoCache.CreateNewLangProj(new DummyProgressDlg(), dbName, FwDirectoryFinder.FdoDirectories, threadHelper); - using (var cache = FdoCache.CreateCacheFromLocalProjectFile(dbFileName, "en", new DummyProgressDlg())) + using (var cache = FdoCache.CreateCacheFromLocalProjectFile(dbFileName, "en", m_ui, FwDirectoryFinder.FdoDirectories, new DummyProgressDlg())) { Assert.AreEqual(Strings.ksAnthropologyCategories, cache.LangProject.AnthroListOA.Name.UiString, "Anthropology Categories list was not properly initialized."); @@ -155,7 +158,7 @@ public void CreateNewLangProject_AnthropologyCategoriesExist() } finally { - RemoveTestDirs(preExistingDirs, Directory.GetDirectories(DirectoryFinder.ProjectsDirectory)); + RemoveTestDirs(preExistingDirs, Directory.GetDirectories(FwDirectoryFinder.ProjectsDirectory)); } } @@ -166,8 +169,8 @@ public void CreateNewLangProject_AnthropologyCategoriesExist() /// name of the FW DB to remove private static void SureRemoveDb(string dbName) { - string dbDir = Path.Combine(DirectoryFinder.ProjectsDirectory, dbName); - var tmpDbDir = Path.Combine(DirectoryFinder.ProjectsDirectory, "..", dbName); + string dbDir = Path.Combine(FwDirectoryFinder.ProjectsDirectory, dbName); + var tmpDbDir = Path.Combine(FwDirectoryFinder.ProjectsDirectory, "..", dbName); if (Directory.Exists(dbDir)) { // it might seem strange to move the directory first before deleting it. @@ -209,10 +212,9 @@ private static void RemoveTestDirs(List preExistingDirs, IEnumerable { - WritingSystemServices.FindOrCreateWritingSystem(cache, "de", false, true, out wsObjGerman); + WritingSystemServices.FindOrCreateWritingSystem(cache, FwDirectoryFinder.TemplateDirectory, "de", false, true, out wsObjGerman); Assert.That(cache.DefaultVernWs, Is.EqualTo(wsFr)); cache.LangProject.DefaultVernacularWritingSystem = wsObjGerman; Assert.That(cache.DefaultVernWs, Is.EqualTo(wsObjGerman.Handle)); @@ -243,10 +245,9 @@ public void ChangingLangProjDefaultVernWs_ChangesCacheDefaultVernWs() [Test] public void ChangingLangProjDefaultAnalysisWs_ChangesCacheDefaultAnalWs() { - using (var threadHelper = new ThreadHelper()) using ( var cache = FdoCache.CreateCacheWithNewBlankLangProj(new TestProjectId(FDOBackendProviderType.kMemoryOnly, null), - "en", "fr", "en", threadHelper)) + "en", "fr", "en", m_ui, FwDirectoryFinder.FdoDirectories)) { var wsEn = cache.DefaultAnalWs; Assert.That(cache.LangProject.DefaultAnalysisWritingSystem.Handle, Is.EqualTo(wsEn)); @@ -254,7 +255,7 @@ public void ChangingLangProjDefaultAnalysisWs_ChangesCacheDefaultAnalWs() UndoableUnitOfWorkHelper.Do("undoit", "redoit", cache.ActionHandlerAccessor, () => { - WritingSystemServices.FindOrCreateWritingSystem(cache, "de", true, false, out wsObjGerman); + WritingSystemServices.FindOrCreateWritingSystem(cache, FwDirectoryFinder.TemplateDirectory, "de", true, false, out wsObjGerman); Assert.That(cache.DefaultAnalWs, Is.EqualTo(wsEn)); cache.LangProject.DefaultAnalysisWritingSystem = wsObjGerman; Assert.That(cache.DefaultAnalWs, Is.EqualTo(wsObjGerman.Handle)); @@ -278,10 +279,9 @@ public void ChangingLangProjDefaultAnalysisWs_ChangesCacheDefaultAnalWs() [Test] public void ChangingLangProjDefaultPronunciationWs_ChangesCacheDefaultPronunciationWs() { - using (var threadHelper = new ThreadHelper()) using ( var cache = FdoCache.CreateCacheWithNewBlankLangProj(new TestProjectId(FDOBackendProviderType.kMemoryOnly, null), - "en", "fr", "en", threadHelper)) + "en", "fr", "en", m_ui, FwDirectoryFinder.FdoDirectories)) { var wsFr = cache.DefaultPronunciationWs; Assert.That(cache.LangProject.DefaultPronunciationWritingSystem.Handle, Is.EqualTo(wsFr)); @@ -290,7 +290,7 @@ public void ChangingLangProjDefaultPronunciationWs_ChangesCacheDefaultPronunciat UndoableUnitOfWorkHelper.Do("undoit", "redoit", cache.ActionHandlerAccessor, () => { - WritingSystemServices.FindOrCreateWritingSystem(cache, "de", false, true, out wsObjGerman); + WritingSystemServices.FindOrCreateWritingSystem(cache, FwDirectoryFinder.TemplateDirectory, "de", false, true, out wsObjGerman); Assert.That(cache.DefaultPronunciationWs, Is.EqualTo(wsFr)); cache.LangProject.DefaultVernacularWritingSystem = wsObjGerman; cache.LangProject.CurrentPronunciationWritingSystems.Clear(); @@ -305,7 +305,7 @@ public void ChangingLangProjDefaultPronunciationWs_ChangesCacheDefaultPronunciat //Assert.That(cache.DefaultPronunciationWs, Is.EqualTo(wsObjGermanIpa.Handle)); // Unless we clear the list it does not regenerate. - WritingSystemServices.FindOrCreateWritingSystem(cache, "es", false, true, out wsObjSpanish); + WritingSystemServices.FindOrCreateWritingSystem(cache, FwDirectoryFinder.TemplateDirectory, "es", false, true, out wsObjSpanish); // Once we've found a real pronunciation WS, changing the default vernacular should not change it. Assert.That(cache.DefaultPronunciationWs, Is.EqualTo(wsObjGerman.Handle)); }); @@ -321,91 +321,6 @@ public void ChangingLangProjDefaultPronunciationWs_ChangesCacheDefaultPronunciat Assert.That(cache.DefaultPronunciationWs, Is.EqualTo(wsObjSpanish.Handle)); } } - - /// - /// Unit test helper to set up environment in which to test EnsureValidLinkedFilesFolderCore. - /// testToExecute takes (string defaultFolder, FdoCache cache). - /// - public void EnsureValidLinkedFilesFolderCore_TestHelper(Action testToExecute) - { - using (var cache = new FdoCache()) - { - var defaultFolder = FileUtils.ChangePathToPlatform("/ProjectDir/LinkedFiles"); - - var m_fileOs = new MockFileOS(); - try - { - FileUtils.Manager.SetFileAdapter(m_fileOs); - - testToExecute(defaultFolder, cache); - } - finally - { - FileUtils.Manager.Reset(); - } - } - } - - /// - [Test] - public void EnsureValidLinkedFilesFolderCore_IfUsingDefaultDir_CreatesDirIfNotExist() - { - EnsureValidLinkedFilesFolderCore_TestHelper((defaultFolder, cache) => { - var configuredFolder = defaultFolder; - Assert.That(FileUtils.DirectoryExists(configuredFolder), Is.False, "Unit test not testing what it's supposed to"); - cache.EnsureValidLinkedFilesFolderCore(configuredFolder, defaultFolder); - Assert.That(FileUtils.DirectoryExists(configuredFolder), Is.True, "Should have created directory"); - }); - } - - /// - [Test] - public void EnsureValidLinkedFilesFolderCore_IfUsingDefaultDirAndItExists_DoesntCrashOrAnything() - { - EnsureValidLinkedFilesFolderCore_TestHelper((defaultFolder, cache) => { - var configuredFolder = defaultFolder; - - // Make default linked files directory already exist - FileUtils.EnsureDirectoryExists(defaultFolder); - - Assert.That(FileUtils.DirectoryExists(configuredFolder), Is.True, "Unit test not testing what it's supposed to"); - // Not crash or anything - cache.EnsureValidLinkedFilesFolderCore(configuredFolder, defaultFolder); - }); - } - - /// - [Test] - public void EnsureValidLinkedFilesFolderCore_NonDefaultLocation_NotCreateNonExistentDir() - { - EnsureValidLinkedFilesFolderCore_TestHelper((defaultFolder, cache) => { - var configuredFolder = FileUtils.ChangePathToPlatform("/nondefaultAndNonexistentPath"); - - Assert.That(defaultFolder, Is.Not.EqualTo(configuredFolder), "Unit test not set up right"); - Assert.That(FileUtils.DirectoryExists(configuredFolder), Is.False, "Unit test not testing what it's supposed to"); - - cache.EnsureValidLinkedFilesFolderCore(configuredFolder, defaultFolder); - Assert.That(FileUtils.DirectoryExists(configuredFolder), Is.False, "Shouldn't have just made the nondefault directory"); - }); - } - - /// - [Test] - public void EnsureValidLinkedFilesFolderCore_NonDefaultLocationAndExists_DoesntCrashOrAnything() - { - EnsureValidLinkedFilesFolderCore_TestHelper((defaultFolder, cache) => { - var configuredFolder = FileUtils.ChangePathToPlatform("/nondefaultPath"); - - // Make linked files directory already exist - FileUtils.EnsureDirectoryExists(configuredFolder); - - Assert.That(defaultFolder, Is.Not.EqualTo(configuredFolder), "Unit test not set up right"); - Assert.That(FileUtils.DirectoryExists(configuredFolder), Is.True, "Unit test not testing what it's supposed to"); - - // Not crash or anything - cache.EnsureValidLinkedFilesFolderCore(configuredFolder, defaultFolder); - }); - } } /// ---------------------------------------------------------------------------------------- @@ -416,6 +331,8 @@ public void EnsureValidLinkedFilesFolderCore_NonDefaultLocationAndExists_DoesntC [TestFixture] public class FdoCacheDisposedTests: BaseTest { + private readonly IFdoUI m_ui = new DummyFdoUI(); + /// /// Make sure the CheckDisposed method works. /// @@ -424,16 +341,13 @@ public class FdoCacheDisposedTests: BaseTest public void CacheCheckDisposedTest() { // This can't be in the minimalist class, because it disposes the cache. - using (var threadHelper = new ThreadHelper()) - { - var cache = FdoCache.CreateCacheWithNewBlankLangProj(new TestProjectId(FDOBackendProviderType.kMemoryOnly, null), - "en", "fr", "en", threadHelper); - // Init backend data provider - var dataSetup = cache.ServiceLocator.GetInstance(); - dataSetup.LoadDomain(BackendBulkLoadDomain.All); - cache.Dispose(); - cache.CheckDisposed(); - } + var cache = FdoCache.CreateCacheWithNewBlankLangProj(new TestProjectId(FDOBackendProviderType.kMemoryOnly, null), + "en", "fr", "en", m_ui, FwDirectoryFinder.FdoDirectories); + // Init backend data provider + var dataSetup = cache.ServiceLocator.GetInstance(); + dataSetup.LoadDomain(BackendBulkLoadDomain.All); + cache.Dispose(); + cache.CheckDisposed(); } /// @@ -442,18 +356,15 @@ public void CacheCheckDisposedTest() [Test] public void CacheIsDisposedTest() { - using (var threadHelper = new ThreadHelper()) - { - // This can't be in the minimalist class, because it disposes the cache. - var cache = FdoCache.CreateCacheWithNewBlankLangProj(new TestProjectId(FDOBackendProviderType.kMemoryOnly, null), - "en", "fr", "en", threadHelper); - // Init backend data provider - var dataSetup = cache.ServiceLocator.GetInstance(); - dataSetup.LoadDomain(BackendBulkLoadDomain.All); - Assert.IsFalse(cache.IsDisposed, "Should not have been disposed."); - cache.Dispose(); - Assert.IsTrue(cache.IsDisposed, "Should have been disposed."); - } + // This can't be in the minimalist class, because it disposes the cache. + var cache = FdoCache.CreateCacheWithNewBlankLangProj(new TestProjectId(FDOBackendProviderType.kMemoryOnly, null), + "en", "fr", "en", m_ui, FwDirectoryFinder.FdoDirectories); + // Init backend data provider + var dataSetup = cache.ServiceLocator.GetInstance(); + dataSetup.LoadDomain(BackendBulkLoadDomain.All); + Assert.IsFalse(cache.IsDisposed, "Should not have been disposed."); + cache.Dispose(); + Assert.IsTrue(cache.IsDisposed, "Should have been disposed."); } /// @@ -462,17 +373,14 @@ public void CacheIsDisposedTest() [Test] public void CacheDisposedForFDOObject() { - using (var threadHelper = new ThreadHelper()) - { - var cache = FdoCache.CreateCacheWithNewBlankLangProj(new TestProjectId(FDOBackendProviderType.kMemoryOnly, null), - "en", "fr", "en", threadHelper); - // Init backend data provider - var dataSetup = cache.ServiceLocator.GetInstance(); - dataSetup.LoadDomain(BackendBulkLoadDomain.All); - var lp = cache.LanguageProject; - cache.Dispose(); - Assert.IsFalse(lp.IsValidObject); - } + var cache = FdoCache.CreateCacheWithNewBlankLangProj(new TestProjectId(FDOBackendProviderType.kMemoryOnly, null), + "en", "fr", "en", m_ui, FwDirectoryFinder.FdoDirectories); + // Init backend data provider + var dataSetup = cache.ServiceLocator.GetInstance(); + dataSetup.LoadDomain(BackendBulkLoadDomain.All); + var lp = cache.LanguageProject; + cache.Dispose(); + Assert.IsFalse(lp.IsValidObject); } /// @@ -481,9 +389,8 @@ public void CacheDisposedForFDOObject() [Test] public void FDOObjectDeleted() { - using (var threadHelper = new ThreadHelper()) using (var cache = FdoCache.CreateCacheWithNewBlankLangProj(new TestProjectId(FDOBackendProviderType.kMemoryOnly, null), - "en", "fr", "en", threadHelper)) + "en", "fr", "en", m_ui, FwDirectoryFinder.FdoDirectories)) { // Init backend data provider var dataSetup = cache.ServiceLocator.GetInstance(); @@ -504,10 +411,9 @@ public void FDOObjectDeleted() [Test] public void NumberOfRemoteClients_NotClientServer_ReturnsZero() { - using (var threadHelper = new ThreadHelper()) using ( var cache = FdoCache.CreateCacheWithNewBlankLangProj(new TestProjectId(FDOBackendProviderType.kMemoryOnly, null), - "en", "fr", "en", threadHelper)) + "en", "fr", "en", m_ui, FwDirectoryFinder.FdoDirectories)) { Assert.AreEqual(0, cache.NumberOfRemoteClients); } diff --git a/Src/FDO/FDOTests/FdoScriptureTests.cs b/Src/FDO/FDOTests/FdoScriptureTests.cs index bd962dfa33..d3b7c91cfa 100644 --- a/Src/FDO/FDOTests/FdoScriptureTests.cs +++ b/Src/FDO/FDOTests/FdoScriptureTests.cs @@ -12,7 +12,9 @@ using NUnit.Framework; using SIL.FieldWorks.Common.COMInterfaces; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.Common.ScriptureUtils; +using SIL.FieldWorks.Resources; using SIL.Utils; using SIL.FieldWorks.Test.TestUtils; using SILUBS.SharedScrUtils; @@ -246,7 +248,8 @@ internal class DummyScrChecksDataSource : ScrChecksDataSource /// The maximum number of identical errors that will /// be allowed for a Scripture check. /// ------------------------------------------------------------------------------------ - public DummyScrChecksDataSource(FdoCache cache, int maxIdenticalErrors) : base(cache) + public DummyScrChecksDataSource(FdoCache cache, int maxIdenticalErrors) : base(cache, ResourceHelper.GetResourceString("kstidPunctCheckWhitespaceChar"), + FwDirectoryFinder.LegacyWordformingCharOverridesFile) { m_maxIdenticalErrors = maxIdenticalErrors; } @@ -309,19 +312,6 @@ public override void TestSetup() m_servloc = Cache.ServiceLocator; } - /// ------------------------------------------------------------------------------------ - /// - /// Override to end the undoable UOW, Undo everything, and 'commit', - /// which will essentially clear out the Redo stack. - /// - /// ------------------------------------------------------------------------------------ - public override void TestTearDown() - { - base.TestTearDown(); - - ReflectionHelper.CallMethod(typeof(ScriptureServices), "InitializeWarningHandler"); - } - /// ------------------------------------------------------------------------------------ /// /// Does setup for all the tests @@ -764,7 +754,7 @@ public void AdjustAnnotationReferences_WithQuote() [Test] public void RecordError_ParaContentsToken() { - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0); Dictionary> bkChkFailedLst = @@ -810,7 +800,7 @@ public void RecordError_ParaContentsToken() [Test] public void RecordError_ParaContentsToken_SecondRun() { - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 10); Dictionary> bkChkFailedLst = @@ -854,7 +844,7 @@ public void RecordError_ParaContentsToken_SecondRun() [Test] public void RecordError_PictureCaptionToken() { - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); ScrCheckingToken tok = new DummyPictureCheckingToken(m_scr, Cache.DefaultUserWs, "en"); Dictionary> bkChkFailedLst = @@ -897,7 +887,7 @@ public void RecordError_PictureCaptionToken() [Test] public void RecordError_Duplicate() { - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1); ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0); check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 8, "Lousy message")); @@ -926,7 +916,7 @@ public void RecordError_Duplicate() [Test] public void RecordError_DuplicateAfterAdjustingReference() { - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1); ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0); tok.MissingStartRef = new BCVRef(tok.StartRef); @@ -1248,7 +1238,7 @@ public void RecordError_ErrorMaxIncreased() [Test] public void RecordError_Duplicate_SameErrorTwiceInVerse() { - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1); ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0); check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 2, "Lousy message")); @@ -1289,7 +1279,7 @@ public void RecordError_Duplicate_SameErrorTwiceInVerse() [Test] public void RunCheck_ScrCheckRunRecordsWithFixedInconsistency() { - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1); ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0); check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 2, "Verbification")); @@ -1304,7 +1294,7 @@ public void RunCheck_ScrCheckRunRecordsWithFixedInconsistency() Assert.AreEqual(1, annotations.NotesOS.Count); IScrCheckRun scr = - annotations.ChkHistRecsOC.First(); + annotations.ChkHistRecsOC.First(); Assert.AreEqual(ScrCheckRunResult.Inconsistencies, scr.Result); Assert.AreEqual(NoteStatus.Open, annotations.NotesOS[0].ResolutionStatus); @@ -1315,7 +1305,7 @@ public void RunCheck_ScrCheckRunRecordsWithFixedInconsistency() Assert.AreEqual(1, annotations.ChkHistRecsOC.Count); Assert.AreEqual(0, annotations.NotesOS.Count); - scr = annotations.ChkHistRecsOC.First(); + scr = annotations.ChkHistRecsOC.First(); Assert.AreEqual(ScrCheckRunResult.NoInconsistencies, scr.Result); } @@ -1327,7 +1317,7 @@ public void RunCheck_ScrCheckRunRecordsWithFixedInconsistency() [Test] public void RunCheck_ScrCheckRunRecordsWithOneBookOneCheck() { - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1); ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0); check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 2, "Verbification")); @@ -1370,7 +1360,7 @@ public void RunCheck_ScrCheckRunRecordsWithOneBookOneCheck() [Test] public void RunCheck_ScrCheckRunRecordsWithOneBookTwoChecks() { - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); DummyEditorialCheck check1 = new DummyEditorialCheck(kCheckId1); ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0); check1.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 2, "Verbification")); @@ -1421,7 +1411,7 @@ public void RunCheck_ScrCheckRunRecordsWithOneBookTwoChecks() [Test] public void RunCheck_CorrectedErrorGetsDeleted() { - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1); ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0); check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 8, "Lousy message")); @@ -1457,7 +1447,7 @@ public void RunCheck_CorrectedErrorGetsDeleted() [Test] public void RecordError_NearDuplicate_DifferByMessage() { - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1); ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0); check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 5, 8, "Lousy message")); @@ -1492,7 +1482,7 @@ public void RecordError_NearDuplicate_DifferOnlyByParaHvo() BCVRef reference = new BCVRef(1, 2, 3); - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1); ScrCheckingToken tok = new DummyParaCheckingToken(book, Cache.DefaultVernWs, 0, reference, reference); @@ -1538,7 +1528,7 @@ public void RecordError_NearDuplicate_DifferOnlyByParaHvo() public void RecordError_NearDuplicate_DifferByCheck() { IFdoServiceLocator servloc = Cache.ServiceLocator; - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); ICmAnnotationDefn annDefnChkError = servloc.GetInstance().CheckingError; ICmAnnotationDefn errorCheck1 = servloc.GetInstance().Create( Guid.NewGuid(), annDefnChkError); @@ -1581,7 +1571,7 @@ public void RecordError_NearDuplicate_DifferByStartRef() { BCVRef endRef = new BCVRef(1, 2, 3); - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1); ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0, new BCVRef(1, 2, 3), endRef); @@ -1616,7 +1606,7 @@ public void RecordError_NearDuplicate_DifferByEndRef() { BCVRef startRef = new BCVRef(1, 2, 3); - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1); ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0, startRef, new BCVRef(1, 2, 3)); @@ -1649,7 +1639,7 @@ public void RecordError_NearDuplicate_DifferByEndRef() [Test] public void RecordError_NearDuplicate_DifferByCitedText() { - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); DummyEditorialCheck check = new DummyEditorialCheck(kCheckId1); ScrCheckingToken tok = new DummyParaCheckingToken(m_scr, Cache.DefaultVernWs, 0); check.m_ErrorsToReport.Add(new DummyEditorialCheck.DummyError(tok, 0, 4, "Message")); @@ -1678,7 +1668,7 @@ public void RecordError_NearDuplicate_DifferByCitedText() [Test] public void GetTextTokens_Chapter0() { - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); int iExodus = 2; IScrBook exodus = AddBookToMockedScripture(iExodus, "Exodus"); AddTitleToMockedBook(exodus, "Exodus"); @@ -1712,7 +1702,7 @@ public void GetTextTokens_Chapter0() [Test] public void GetTextTokens_WholeBook() { - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); AddBookToMockedScripture(1, "Genesis"); int iExodus = 2; IScrBook exodus = AddBookToMockedScripture(iExodus, "Exodus"); @@ -1801,7 +1791,7 @@ public void GetTextTokens_FirstChapter() IScrBook exodus = AddBookToMockedScripture(iExodus, "Exodus"); AddTitleToMockedBook(exodus, "Exodus"); - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); IScrSection section = AddSectionToMockedBook(exodus, true); IStTxtPara para = AddParaToMockedText(section.HeadingOA, ScrStyleNames.IntroSectionHead); AddRunToMockedPara(para, "Everything you wanted to know about Exodus but were afraid to ask", null); @@ -1869,7 +1859,7 @@ public void GetTextTokens_DifferentWritingSystem() AddTitleToMockedBook(exodus, "Exodus"); // Get the text (and set the valid characters for each writing system). - var dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); dataSource.GetText(iExodus, 1); iWs = 0; @@ -1891,7 +1881,7 @@ public void GetTextTokens_DifferentWritingSystem() [Test] public void GetTextTokens_LastChapter() { - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); AddBookToMockedScripture(1, "Genesis"); int iExodus = 2; IScrBook exodus = AddBookToMockedScripture(iExodus, "Exodus"); @@ -1939,7 +1929,7 @@ public void GetTextTokens_LastChapter() public void GetTextTokens_ChapterStartsAndEndsMidSection() { - ScrChecksDataSource dataSource = new ScrChecksDataSource(Cache); + ScrChecksDataSource dataSource = CreateScrChecksDataSource(); AddBookToMockedScripture(1, "Genesis"); int iExodus = 2; IScrBook exodus = AddBookToMockedScripture(iExodus, "Exodus"); @@ -1993,6 +1983,12 @@ public void GetTextTokens_ChapterStartsAndEndsMidSection() } #region Helper methods + private ScrChecksDataSource CreateScrChecksDataSource() + { + return new ScrChecksDataSource(Cache, ResourceHelper.GetResourceString("kstidPunctCheckWhitespaceChar"), + FwDirectoryFinder.LegacyWordformingCharOverridesFile); + } + /// ------------------------------------------------------------------------------------ /// /// Verifies that an "empty" journal text has a single empty paragraph with the correct @@ -2528,6 +2524,9 @@ public void SavedVersion_TestFootnoteOrder() [Test] public void SavedVersion_BogusUnownedFootnoteORC() { + var ui = (DummyFdoUI) Cache.ServiceLocator.GetInstance(); + ui.Reset(); + IStText titleText; IScrBook hebrews = m_servloc.GetInstance().Create(58, out titleText); IStTxtPara title = AddParaToMockedText(titleText, ScrStyleNames.MainBookTitle); @@ -2547,8 +2546,6 @@ public void SavedVersion_BogusUnownedFootnoteORC() IScrFootnote footnoteOrig2 = AddFootnote(hebrews, para2, 0); // archive draft - string sWarningMessage = null; - ReflectionHelper.SetAction(typeof(ScriptureServices), "ReportWarning", sMsg => { sWarningMessage = sMsg; }); IScrDraft draft = m_servloc.GetInstance().Create("", new [] { hebrews }); Assert.AreEqual(1, m_scr.ArchivedDraftsOC.Count); @@ -2594,7 +2591,8 @@ public void SavedVersion_BogusUnownedFootnoteORC() string sOrc = tss.get_RunText(0); Assert.AreEqual(StringUtils.kChObject, sOrc[0]); - Assert.AreEqual("1 footnote(s) in HEB did not correspond to any owned footnotes in the vernacular text of that book. They have been moved to the end of the footnote sequence.", sWarningMessage); + // Expecting error to have been thrown in ScriptureServices.AdjustObjectsInArchivedBook, so now we make sure the error is the one expected. + Assert.AreEqual("1 footnote(s) in HEB did not correspond to any owned footnotes in the vernacular text of that book. They have been moved to the end of the footnote sequence.", ui.ErrorMessage); } /// ------------------------------------------------------------------------------------ @@ -2934,7 +2932,7 @@ public override void TestSetup() AddScrStyle("Parallel Passage", ContextValues.Text, StructureValues.Heading, FunctionValues.Prose, false); AddScrStyle("Line 1", ContextValues.Text, StructureValues.Body, FunctionValues.Prose, false); - m_stylesheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles); + m_stylesheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); AddBookWithTwoSections(40, "Matthew"); m_philemon = AddBookWithTwoSections(57, "Philemon"); diff --git a/Src/FDO/FDOTests/FdoTestBase.cs b/Src/FDO/FDOTests/FdoTestBase.cs index e9c5e50c72..f2efcf26eb 100644 --- a/Src/FDO/FDOTests/FdoTestBase.cs +++ b/Src/FDO/FDOTests/FdoTestBase.cs @@ -10,18 +10,15 @@ // Implements FdoTestBase, the base class for the FDO tests // -using System; -using System.Collections.Generic; using System.IO; -using System.Linq; using NUnit.Framework; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.Common.FwUtils; +using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.FDO.Infrastructure; using SIL.FieldWorks.Test.TestUtils; using SIL.Utils; using SIL.CoreImpl; -using SIL.FieldWorks.FDO.Infrastructure.Impl; namespace SIL.FieldWorks.FDO.FDOTests { @@ -101,7 +98,8 @@ protected void SetupEverythingButBase() DisposeEverythingButBase(); // We need FieldWorks here to get the correct registry key HKLM\Software\SIL\FieldWorks. // The default without this would be HKLM\Software\SIL\SIL FieldWorks, which breaks some tests. - SIL.Utils.RegistryHelper.ProductName = "FieldWorks"; + RegistryHelper.ProductName = "FieldWorks"; + FdoTestHelper.SetupClientServerServices(); m_cache = CreateCache(); m_actionHandler = m_cache.ServiceLocator.GetInstance(); } @@ -125,11 +123,7 @@ public override void FixtureTeardown() protected void DisposeEverythingButBase() { if (m_cache != null) - { - if (m_cache.ThreadHelper != null) - m_cache.ThreadHelper.Dispose(); m_cache.Dispose(); - } m_cache = null; m_actionHandler = null; } @@ -176,9 +170,8 @@ public virtual void TestTearDown() /// a working FdoCache protected FdoCache BootstrapSystem(IProjectIdentifier projectId, BackendBulkLoadDomain loadType) { - // This thread helper will be disposed in FixtureTeardown along with the cache. - var retval = m_internalRestart ? FdoCache.CreateCacheFromExistingData(projectId, "en", new DummyProgressDlg()) : - FdoCache.CreateCacheWithNewBlankLangProj(projectId, "en", "fr", "en", new ThreadHelper()); + var retval = m_internalRestart ? FdoCache.CreateCacheFromExistingData(projectId, "en", new DummyFdoUI(), FwDirectoryFinder.FdoDirectories, new DummyProgressDlg()) : + FdoCache.CreateCacheWithNewBlankLangProj(projectId, "en", "fr", "en", new DummyFdoUI(), FwDirectoryFinder.FdoDirectories); var dataSetup = retval.ServiceLocator.GetInstance(); dataSetup.LoadDomain(loadType); return retval; diff --git a/Src/FDO/FDOTests/FdoTestHelper.cs b/Src/FDO/FDOTests/FdoTestHelper.cs index 5d8021889a..17a17642f5 100644 --- a/Src/FDO/FDOTests/FdoTestHelper.cs +++ b/Src/FDO/FDOTests/FdoTestHelper.cs @@ -10,6 +10,7 @@ using System.Linq; using SIL.FieldWorks.Common.COMInterfaces; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices; using SIL.CoreImpl; using SIL.Utils; @@ -410,5 +411,14 @@ public static void VerifyHyperlinkPropsAreCorrect(ITsTextProps props, int expect Assert.AreEqual(Convert.ToChar((int)FwObjDataTypes.kodtExternalPathName), sObjData[0]); Assert.AreEqual(sUrl, sObjData.Substring(1)); } + + /// + /// Sets up the client server services. + /// + public static void SetupClientServerServices() + { + ClientServerServices.SetCurrentToDb4OBackend(new DummyFdoUI(), FwDirectoryFinder.FdoDirectories, + () => FwDirectoryFinder.ProjectsDirectory == FwDirectoryFinder.ProjectsDirectoryLocalMachine); + } } } diff --git a/Src/FDO/FDOTests/FwCharacterCategorizerTests.cs b/Src/FDO/FDOTests/FwCharacterCategorizerTests.cs index 864078621a..409426f136 100644 --- a/Src/FDO/FDOTests/FwCharacterCategorizerTests.cs +++ b/Src/FDO/FDOTests/FwCharacterCategorizerTests.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using NUnit.Framework; using SIL.FieldWorks.Common.COMInterfaces; +using SIL.FieldWorks.Common.FwUtils; using SILUBS.SharedScrUtils; using SIL.FieldWorks.FDO.DomainServices; @@ -51,7 +52,7 @@ public void SymbolPunctuationOnly() "a\uFFFCb\uFFFCc\uFFFCd\uFFFCe" + "1\uFFFC2\uFFFC3\uFFFC4\uFFFC5" + "'\uFFFC-\uFFFC#" + - "", "Test WS", null, null); + "", "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ILgCharacterPropertyEngine lgCharPropEngineEn = Cache.WritingSystemFactory.get_CharPropEngine( m_wsEn); @@ -73,7 +74,7 @@ public void WordAndPuncs_OverridePunc() "a\uFFFCb\uFFFCc\uFFFCd\uFFFCe\uFFFC." + "1\uFFFC2\uFFFC3\uFFFC4\uFFFC5" + "'\uFFFC-\uFFFC#" + - "", "Test WS", null, null); + "", "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ILgCharacterPropertyEngine lgCharPropEngineEn = Cache.WritingSystemFactory.get_CharPropEngine( m_wsEn); @@ -100,7 +101,7 @@ public void WordAndPuncs_Spaces() "a\uFFFCb\uFFFCc" + "1\uFFFC2\uFFFC3\uFFFC4\uFFFC5" + "-\uFFFCU+0020" + - "", "Test WS", null, null); + "", "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); var english = Cache.ServiceLocator.WritingSystemManager.Get("en"); var lgCharPropEngineEn = Cache.WritingSystemFactory.get_CharPropEngine(english.Handle); @@ -126,7 +127,7 @@ public void WordAndPuncs_EmptyString() "a\uFFFCb\uFFFCc" + "1\uFFFC2\uFFFC3\uFFFC4\uFFFC5" + "-\uFFFCU+0020" + - "", "Test WS", null, null); + "", "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); var english = Cache.ServiceLocator.WritingSystemManager.Get("en"); var lgCharPropEngineEn = Cache.WritingSystemFactory.get_CharPropEngine( english.Handle); @@ -152,7 +153,7 @@ public void WordAndPuncs_NoOverridePunc() "a\uFFFCb\uFFFCc\uFFFCd\uFFFCe" + "1\uFFFC2\uFFFC3\uFFFC4\uFFFC5" + "'\uFFFC-\uFFFC#" + - "", "Test WS", null, null); + "", "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ILgCharacterPropertyEngine lgCharPropEngineEn = Cache.WritingSystemFactory.get_CharPropEngine( m_wsEn); diff --git a/Src/FDO/FDOTests/FwSetupFixtureClass.cs b/Src/FDO/FDOTests/FwSetupFixtureClass.cs index 0825a659a3..ac47a4a6df 100644 --- a/Src/FDO/FDOTests/FwSetupFixtureClass.cs +++ b/Src/FDO/FDOTests/FwSetupFixtureClass.cs @@ -3,6 +3,7 @@ // (http://www.gnu.org/licenses/lgpl-2.1.html) using NUnit.Framework; +using SIL.FieldWorks.FDO.FDOTests; using SIL.Utils; namespace SIL.FieldWorks @@ -24,6 +25,7 @@ public class FwSetupFixtureClass [SetUp] public void SetUp() { + FdoTestHelper.SetupClientServerServices(); } ///-------------------------------------------------------------------------------------- diff --git a/Src/FDO/FDOTests/FwStyleSheetTests.cs b/Src/FDO/FDOTests/FwStyleSheetTests.cs index 7b3c56690d..76b24ade5a 100644 --- a/Src/FDO/FDOTests/FwStyleSheetTests.cs +++ b/Src/FDO/FDOTests/FwStyleSheetTests.cs @@ -15,6 +15,7 @@ using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.Common.ScriptureUtils; using SIL.FieldWorks.FDO.DomainServices; +using SIL.FieldWorks.Resources; namespace SIL.FieldWorks.FDO.FDOTests.CellarTests { @@ -92,7 +93,7 @@ public override void TestSetup() base.TestSetup(); m_styleSheet = new DummyFwStyleSheet(); - m_styleSheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles); + m_styleSheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); } /// ------------------------------------------------------------------------------------ diff --git a/Src/FDO/FDOTests/GeneratedPropertyAccessorTests.cs b/Src/FDO/FDOTests/GeneratedPropertyAccessorTests.cs index 3346c8577f..dd47cb9ca2 100644 --- a/Src/FDO/FDOTests/GeneratedPropertyAccessorTests.cs +++ b/Src/FDO/FDOTests/GeneratedPropertyAccessorTests.cs @@ -15,6 +15,7 @@ using System; using System.Linq; using NUnit.Framework; +using SIL.CoreImpl; using SIL.FieldWorks.FDO.FDOTests; using SIL.FieldWorks.FDO.Infrastructure; using SIL.FieldWorks.Common.FwUtils; diff --git a/Src/FDO/FDOTests/LangProjectTests.cs b/Src/FDO/FDOTests/LangProjectTests.cs index 2c6f1df011..77343cb94b 100644 --- a/Src/FDO/FDOTests/LangProjectTests.cs +++ b/Src/FDO/FDOTests/LangProjectTests.cs @@ -7,16 +7,9 @@ using System; using System.IO; -using System.Collections; using System.Collections.Generic; -using System.Reflection; -using System.Diagnostics; - using NUnit.Framework; - -using SIL.FieldWorks.FDO; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Test.TestUtils; using SIL.Utils; using SIL.FieldWorks.Common.FwUtils; using SIL.CoreImpl; @@ -179,14 +172,14 @@ public void AddingWritingSystems() public void LinkedFilesRootDirTests() { //test when LinkedFiles is in the project's root folder - var projectFolder = Path.Combine(DirectoryFinder.ProjectsDirectory, "TestProjectName"); + var projectFolder = Path.Combine(FwDirectoryFinder.ProjectsDirectory, "TestProjectName"); var linkedFilesFullPath = Path.Combine(projectFolder, "LinkedFiles"); Cache.LanguageProject.LinkedFilesRootDir = linkedFilesFullPath; var outputLinkedFilesFullPath = Cache.LanguageProject.LinkedFilesRootDir; Assert.True(linkedFilesFullPath.Equals(outputLinkedFilesFullPath)); //test when linked files is in FW Projects folder - linkedFilesFullPath = Path.Combine(DirectoryFinder.ProjectsDirectory, "LinkedFiles"); + linkedFilesFullPath = Path.Combine(FwDirectoryFinder.ProjectsDirectory, "LinkedFiles"); Cache.LanguageProject.LinkedFilesRootDir = linkedFilesFullPath; outputLinkedFilesFullPath = Cache.LanguageProject.LinkedFilesRootDir; Assert.True(linkedFilesFullPath.Equals(outputLinkedFilesFullPath)); diff --git a/Src/FDO/FDOTests/LingTests.cs b/Src/FDO/FDOTests/LingTests.cs index 286070aca4..6125c6e709 100644 --- a/Src/FDO/FDOTests/LingTests.cs +++ b/Src/FDO/FDOTests/LingTests.cs @@ -16,11 +16,13 @@ using System.Xml; using NUnit.Framework; using SIL.FieldWorks.Common.COMInterfaces; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainImpl; using SIL.FieldWorks.FDO.FDOTests.CellarTests; using SIL.FieldWorks.FDO.Validation; using SIL.FieldWorks.FDO.DomainServices; using SIL.CoreImpl; +using SIL.FieldWorks.FdoUi; using SIL.Utils; namespace SIL.FieldWorks.FDO.FDOTests.LingTests @@ -2470,11 +2472,13 @@ public void ConvertLexEntryInflTypes() using (var progressBar = new ProgressBar()) { + IProgress progressBarWrapper = new ProgressBarWrapper(progressBar); + var itemsToChange = new List(); itemsToChange.Add(lexEntryType1); itemsToChange.Add(lexEntryType1Sub1); - Cache.LangProject.LexDbOA.ConvertLexEntryInflTypes(progressBar, itemsToChange); + Cache.LangProject.LexDbOA.ConvertLexEntryInflTypes(progressBarWrapper, itemsToChange); var leit1 = ler1.VariantEntryTypesRS[0]; Assert.AreEqual(LexEntryInflTypeTags.kClassId, leit1.ClassID, "first lex entry type of first entry should be irregularly inflected form"); leit1 = ler1.VariantEntryTypesRS[1]; @@ -2525,11 +2529,13 @@ public void ConvertLexEntryTypes() using (var progressBar = new ProgressBar()) { + IProgress progressBarWrapper = new ProgressBarWrapper(progressBar); + var itemsToChange = new List(); itemsToChange.Add(lexEntryInflType1); itemsToChange.Add(lexEntryInflType1Sub1); - Cache.LangProject.LexDbOA.ConvertLexEntryTypes(progressBar, itemsToChange); + Cache.LangProject.LexDbOA.ConvertLexEntryTypes(progressBarWrapper, itemsToChange); var let1 = ler1.VariantEntryTypesRS[0]; Assert.AreEqual(LexEntryTypeTags.kClassId, let1.ClassID, "first lex entry type of first entry should be variant"); let1 = ler1.VariantEntryTypesRS[1]; diff --git a/Src/FDO/FDOTests/LinkedFilesRelativePathHelperTests.cs b/Src/FDO/FDOTests/LinkedFilesRelativePathHelperTests.cs new file mode 100644 index 0000000000..57dead5112 --- /dev/null +++ b/Src/FDO/FDOTests/LinkedFilesRelativePathHelperTests.cs @@ -0,0 +1,137 @@ +using System; +using System.IO; +using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; + +namespace SIL.FieldWorks.FDO.FDOTests +{ + /// + /// Test fixture for LinkedFilesRelativePathHelper + /// + [TestFixture] + public class LinkedFilesRelativePathHelperTests + { + /// ------------------------------------------------------------------------------------ + /// + /// Tests the GetLinkedFilesRelativePathFromFullPath method + /// + /// ------------------------------------------------------------------------------------ + [Test] + public void GetLinkedFilesRelativePathFromFullPath() + { + Assert.AreEqual(String.Format("%proj%{0}LinkedFiles", Path.DirectorySeparatorChar), + LinkedFilesRelativePathHelper.GetLinkedFilesRelativePathFromFullPath(FwDirectoryFinder.ProjectsDirectory, String.Format("%proj%{0}LinkedFiles", Path.DirectorySeparatorChar), + Path.Combine(FwDirectoryFinder.SourceDirectory, "FDO", "FDOTests", "BackupRestore", "Project"), + "Project")); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Tests the GetLinkedFilesFullPathFromRelativePath method + /// + /// ------------------------------------------------------------------------------------ + [Test] + public void GetLinkedFilesFullPathFromRelativePath() + { + var projectPath = Path.Combine(FwDirectoryFinder.ProjectsDirectory, "TestProject"); + var linkedFilesRootDir = Path.Combine(projectPath, "LinkedFiles"); + var linkedFilesPath = LinkedFilesRelativePathHelper.GetLinkedFilesFullPathFromRelativePath(FwDirectoryFinder.ProjectsDirectory, + String.Format("%proj%{0}LinkedFiles", Path.DirectorySeparatorChar), projectPath); + + Assert.AreEqual(linkedFilesRootDir, linkedFilesPath); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Tests the GetFullFilePathFromRelativeLFPath method + /// + /// ------------------------------------------------------------------------------------ + [Test] + public void GetFullFilePathFromRelativeLFPath() + { + var linkedFilesRootDir = Path.Combine(FwDirectoryFinder.ProjectsDirectory, "TestProject", "LinkedFiles"); + var fullLFPath = LinkedFilesRelativePathHelper.GetFullFilePathFromRelativeLFPath(String.Format("%lf%{0}AudioVisual{0}StarWars.mvi", Path.DirectorySeparatorChar), linkedFilesRootDir); + var audioVisualFile = Path.Combine(linkedFilesRootDir, "AudioVisual", "StarWars.mvi"); + Assert.AreEqual(audioVisualFile, fullLFPath); + + //if a fully rooted path is passed in the return value should be null. + var projectRootDir = FwDirectoryFinder.DataDirectory; + fullLFPath = LinkedFilesRelativePathHelper.GetFullFilePathFromRelativeLFPath(projectRootDir, linkedFilesRootDir); + Assert.True(string.IsNullOrEmpty(fullLFPath)); + + } + + /// ------------------------------------------------------------------------------------ + /// + /// Tests the GetRelativeLFPathFromFullFilePath method + /// + /// ------------------------------------------------------------------------------------ + [Test] + public void GetRelativeLFPathFromFullFilePath() + { + var linkedFilesRootDir = Path.Combine(FwDirectoryFinder.ProjectsDirectory, "TestProject", "LinkedFiles"); + var audioVisualFile = Path.Combine(linkedFilesRootDir, "AudioVisual", "StarWars.mvi"); + var relativeLFPath = LinkedFilesRelativePathHelper.GetRelativeLFPathFromFullFilePath(audioVisualFile, linkedFilesRootDir); + Assert.AreEqual(String.Format("%lf%{0}AudioVisual{0}StarWars.mvi", Path.DirectorySeparatorChar), relativeLFPath); + + //Ensure empty string is returned when the path is not relative to the LinkedFiles directory. + var pathNotUnderLinkedFiles = Path.Combine(FwDirectoryFinder.DataDirectory, "LordOfTheRings.mvi"); + relativeLFPath = LinkedFilesRelativePathHelper.GetRelativeLFPathFromFullFilePath(pathNotUnderLinkedFiles, linkedFilesRootDir); + Assert.True(string.IsNullOrEmpty(relativeLFPath)); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Tests the GetRelativeLinkedFilesPath method + /// + /// ------------------------------------------------------------------------------------ + [Test] + public void GetRelativeLinkedFilesPath() + { + var linkedFilesRootDir = Path.Combine(FwDirectoryFinder.ProjectsDirectory, "TestProject", "LinkedFiles"); + var audioVisualFile = Path.Combine(linkedFilesRootDir, "AudioVisual", "StarWars.mvi"); + var relativeLFPath = LinkedFilesRelativePathHelper.GetRelativeLinkedFilesPath(audioVisualFile, linkedFilesRootDir); + Assert.True(String.Equals(String.Format("AudioVisual{0}StarWars.mvi", Path.DirectorySeparatorChar), relativeLFPath)); + + //Ensure ORIGINAL path is returned when the path is not relative to the LinkedFiles directory. + var pathNotUnderLinkedFiles = Path.Combine(FwDirectoryFinder.DataDirectory, "LordOfTheRings.mvi"); + relativeLFPath = LinkedFilesRelativePathHelper.GetRelativeLinkedFilesPath(pathNotUnderLinkedFiles, linkedFilesRootDir); + Assert.True(String.Equals(pathNotUnderLinkedFiles,relativeLFPath)); + Assert.That(LinkedFilesRelativePathHelper.GetRelativeLinkedFilesPath( + "silfw://localhost/link?app%3dflex%26database%3dc%3a%5cTestLangProj%5cTestLangProj.fwdata%26server%3d%26tool%3dnaturalClassedit%26guid%3d43c9ba97-2883-4f95-aa5d-ef9309e85025%26tag%3d", + relativeLFPath), Is.Null, "hyperlinks should be left well alone!!"); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Tests the GetFullPathFromRelativeLFPath method + /// + /// ------------------------------------------------------------------------------------ + [Test] + public void GetFullPathFromRelativeLFPath() + { + var linkedFilesRootDir = Path.Combine(FwDirectoryFinder.ProjectsDirectory, "TestProject", "LinkedFiles"); + var fullLFPath = LinkedFilesRelativePathHelper.GetFullPathFromRelativeLFPath(String.Format("AudioVisual{0}StarWars.mvi", Path.DirectorySeparatorChar), linkedFilesRootDir); + var audioVisualFile = Path.Combine(linkedFilesRootDir, "AudioVisual", "StarWars.mvi"); + Assert.AreEqual(audioVisualFile, fullLFPath); + + //if a fully rooted path is passed in the return value should be the path that was passed in. + var fileUnderProjectRootDir = String.Format("{1}{0}AudioVisual{0}StarWars.mvi", Path.DirectorySeparatorChar, FwDirectoryFinder.DataDirectory); + fullLFPath = LinkedFilesRelativePathHelper.GetFullPathFromRelativeLFPath(fileUnderProjectRootDir, linkedFilesRootDir); + Assert.AreEqual(fullLFPath, fileUnderProjectRootDir); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Tests the GetFullPathFromRelativeLFPath method with illegal characters + /// + /// ------------------------------------------------------------------------------------ + [Test] + public void GetFullPathFromRelativeLFPath_WithIllegalCharacters_ReturnsSpecialPath() + { + var linkedFilesRootDir = Path.Combine(FwDirectoryFinder.ProjectsDirectory, "TestProject", "LinkedFiles"); + var fullLFPath = LinkedFilesRelativePathHelper.GetFullPathFromRelativeLFPath("1\";1\"", linkedFilesRootDir); + Assert.That(fullLFPath, Is.EqualTo(Path.Combine(linkedFilesRootDir,"__ILLEGALCHARS__"))); + } + } +} diff --git a/Src/FDO/FDOTests/ParagraphParserTests.cs b/Src/FDO/FDOTests/ParagraphParserTests.cs index fdb9b2738b..836163923b 100644 --- a/Src/FDO/FDOTests/ParagraphParserTests.cs +++ b/Src/FDO/FDOTests/ParagraphParserTests.cs @@ -64,7 +64,7 @@ public object Clone() /// protected string ConfigurationFilePath(string fileRelativePath) { - return Path.Combine(DirectoryFinder.FwSourceDirectory, fileRelativePath); + return Path.Combine(FwDirectoryFinder.SourceDirectory, fileRelativePath); } /// @@ -543,7 +543,7 @@ virtual public IWfiWordform SetAlternateCase(int iSegment, int iSegForm, StringC ITsString tssWordformBaseline = GetBaselineText(iSegment, iSegForm); // Add any relevant 'other case' forms. int nvar; - int ws = tssWordformBaseline.get_Properties(0).GetIntPropValues((int)FwTextPropType.ktptWs, out nvar); ; + int ws = tssWordformBaseline.get_Properties(0).GetIntPropValues((int)FwTextPropType.ktptWs, out nvar); string locale = m_cache.ServiceLocator.WritingSystemManager.Get(ws).IcuLocale; var cf = new CaseFunctions(locale); switch (targetState) @@ -2435,7 +2435,7 @@ void SetupOldWordformingOverrides() { IWritingSystem wsObj = Cache.ServiceLocator.WritingSystems.DefaultVernacularWritingSystem; var validChars = ValidCharacters.Load(wsObj.ValidChars, - wsObj.DisplayLabel, null, null); + wsObj.DisplayLabel, null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); var fChangedSomething = false; if (!validChars.IsWordForming('-')) { diff --git a/Src/FDO/FDOTests/PersistingBackendProviderTests.cs b/Src/FDO/FDOTests/PersistingBackendProviderTests.cs index d7a6a8bece..4080fabf41 100644 --- a/Src/FDO/FDOTests/PersistingBackendProviderTests.cs +++ b/Src/FDO/FDOTests/PersistingBackendProviderTests.cs @@ -2,8 +2,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Linq; using System.IO; +using System.Linq; using FwRemoteDatabaseConnector; using NUnit.Framework; using SIL.FieldWorks.Common.COMInterfaces; @@ -15,6 +15,7 @@ using SIL.FieldWorks.FDO.Infrastructure; using SIL.CoreImpl; using SIL.FieldWorks.FDO.Infrastructure.Impl; +using SIL.Utils; namespace SIL.FieldWorks.FDO.CoreTests.PersistingLayerTests { @@ -187,6 +188,7 @@ public void BasicDataTypes() lp.EthnologueCode = newEthCode; // CellarPropertyType.String: var le = Cache.ServiceLocator.GetInstance().Create(); + Guid leGuid = le.Guid; var irOriginalValue = Cache.TsStrFactory.MakeString("", Cache.WritingSystemFactory.UserWs); le.ImportResidue = irOriginalValue; @@ -276,10 +278,11 @@ public void BasicDataTypes() // Check Unicode Assert.AreEqual(newEthCode, lp.EthnologueCode, "Wrong Unicode value restored."); // Check string (ITsString) - var irRestoredValue = lp.LexDbOA.Entries.ToArray()[0].ImportResidue; + le = Cache.ServiceLocator.GetInstance().GetObject(leGuid); + var irRestoredValue = le.ImportResidue; var xmlRestoredValue = TsStringUtils.GetXmlRep(irRestoredValue, Cache.WritingSystemFactory, Cache.WritingSystemFactory.UserWs, true); Assert.AreEqual(xmlOriginalValue, xmlRestoredValue, "Wrong ITsString value restored."); - var irRestoredBlankValue = lp.LexDbOA.Entries.ToArray()[0].Comment.get_String(Cache.WritingSystemFactory.UserWs); + var irRestoredBlankValue = le.Comment.get_String(Cache.WritingSystemFactory.UserWs); var xmlRestoredBlankValue = TsStringUtils.GetXmlRep(irRestoredBlankValue, Cache.WritingSystemFactory, Cache.WritingSystemFactory.UserWs, true); Assert.AreEqual(xmlOriginalBlankValue, xmlRestoredBlankValue, "Wrong ITsString value restored for blank string."); // ITsTextProps @@ -414,7 +417,7 @@ public void CustomFieldDataTest() public void RenameDatabaseTest() { string sOrigName = Cache.ProjectId.Name; - string newProjectDir = Path.Combine(DirectoryFinder.ProjectsDirectory, NewProjectName); + string newProjectDir = Path.Combine(FwDirectoryFinder.ProjectsDirectory, NewProjectName); if (Cache.ProjectId.Type != FDOBackendProviderType.kMemoryOnly && Directory.Exists(newProjectDir)) { // make sure database doesn't exist before running the test @@ -519,7 +522,7 @@ protected override FdoCache CreateCache() while (true) { _randomProjectName = "TestLangProjCS" + Path.GetFileNameWithoutExtension(Path.GetRandomFileName()); - var projectDir = Path.Combine(DirectoryFinder.ProjectsDirectory, _randomProjectName); + var projectDir = Path.Combine(FwDirectoryFinder.ProjectsDirectory, _randomProjectName); if (!Directory.Exists(projectDir)) { _projectDir = projectDir; @@ -537,7 +540,7 @@ protected override FdoCache CreateCache() /// ------------------------------------------------------------------------------------ public override void FixtureSetup() { - RemotingServer.Start(); + RemotingServer.Start(FwDirectoryFinder.RemotingTcpServerConfigFile, FwDirectoryFinder.FdoDirectories, () => false, v => {}); base.FixtureSetup(); } @@ -562,8 +565,8 @@ public override void FixtureTeardown() /// ------------------------------------------------------------------------------------ protected override void CheckAdditionalStuffAfterFirstRename() { - Assert.AreEqual(Path.Combine(Path.Combine(DirectoryFinder.ProjectsDirectory, NewProjectName), - DirectoryFinder.GetDb4oDataFileName(NewProjectName)), Cache.ProjectId.Path); + Assert.AreEqual(Path.Combine(Path.Combine(FwDirectoryFinder.ProjectsDirectory, NewProjectName), + FdoFileHelper.GetDb4oDataFileName(NewProjectName)), Cache.ProjectId.Path); } } @@ -586,8 +589,8 @@ public sealed class XMLTests : PersistingBackendProviderTestBase protected override FdoCache CreateCache() { const string projName = "TestLangProj-test"; - string filename = Path.Combine(DirectoryFinder.ProjectsDirectory, - Path.Combine(projName, DirectoryFinder.GetXmlDataFileName(projName))); + string filename = Path.Combine(FwDirectoryFinder.ProjectsDirectory, + Path.Combine(projName, FdoFileHelper.GetXmlDataFileName(projName))); if (!m_internalRestart) { if (File.Exists(filename)) @@ -607,7 +610,7 @@ protected override FdoCache CreateCache() [Ignore("There is a timing problem with this test - project file may not exist becuase background thread is doing commit.")] public void OnlyOneCacheAllowed() { - string filename = DirectoryFinder.GetXmlDataFileName("TestLangProj"); + string filename = FdoFileHelper.GetXmlDataFileName("TestLangProj"); Assert.True(File.Exists(filename), "Test XML file not found"); using (FdoCache cache = OpenExistingFile(filename)) Assert.Fail("Able to open XML file that is already open"); @@ -616,7 +619,7 @@ public void OnlyOneCacheAllowed() private FdoCache OpenExistingFile(string filename) { return FdoCache.CreateCacheFromExistingData( - new TestProjectId(FDOBackendProviderType.kXMLWithMemoryOnlyWsMgr, filename), "en", new DummyProgressDlg()); + new TestProjectId(FDOBackendProviderType.kXMLWithMemoryOnlyWsMgr, filename), "en", new DummyFdoUI(), FwDirectoryFinder.FdoDirectories, new DummyProgressDlg()); } /// ------------------------------------------------------------------------------------ @@ -626,8 +629,8 @@ private FdoCache OpenExistingFile(string filename) /// ------------------------------------------------------------------------------------ protected override void CheckAdditionalStuffAfterFirstRename() { - Assert.AreEqual(Path.Combine(Path.Combine(DirectoryFinder.ProjectsDirectory, NewProjectName), - DirectoryFinder.GetXmlDataFileName(NewProjectName)), Cache.ProjectId.Path); + Assert.AreEqual(Path.Combine(Path.Combine(FwDirectoryFinder.ProjectsDirectory, NewProjectName), + FdoFileHelper.GetXmlDataFileName(NewProjectName)), Cache.ProjectId.Path); } /// @@ -635,10 +638,10 @@ protected override void CheckAdditionalStuffAfterFirstRename() /// throw an Exception. /// [Test] - [ExpectedException(typeof(FwStartupException))] + [ExpectedException(typeof(StartupException))] public void CorruptedXMLFileTest() { - var testDataPath = Path.Combine(DirectoryFinder.FwSourceDirectory, "FDO/FDOTests/TestData"); + var testDataPath = Path.Combine(FwDirectoryFinder.SourceDirectory, "FDO/FDOTests/TestData"); var projName = Path.Combine(testDataPath, "CorruptedXMLFileTest.fwdata"); // MockXMLBackendProvider implements IDisposable therefore we need the "using". @@ -646,7 +649,7 @@ public void CorruptedXMLFileTest() using (var xmlBep = new MockXMLBackendProvider(Cache, projName)) { // Should throw an XMLException, but this will be caught and because there's - // no .bak file, an FwStartupException will be thrown instead. + // no .bak file, an StartupException will be thrown instead. xmlBep.Startup(); } } @@ -665,7 +668,7 @@ public void StartupExtantTest() string testFileName = String.Empty; try { - var testDataPath = Path.Combine(DirectoryFinder.FwSourceDirectory, "FDO/FDOTests/BackupRestore/BackupTestProject"); + var testDataPath = Path.Combine(FwDirectoryFinder.SourceDirectory, "FDO/FDOTests/BackupRestore/BackupTestProject"); var projName = Path.Combine(testDataPath, "BackupTestProject.fwdata"); testFileName = Path.GetTempFileName(); // If we leave the extension as .tmp, we get a sharing violation when the @@ -694,7 +697,7 @@ public void StartupExtantTest() [Test] public void SlightlyCorruptedXMLFileTest() { - var testDataPath = Path.Combine(DirectoryFinder.FwSourceDirectory, "FDO/FDOTests/TestData"); + var testDataPath = Path.Combine(FwDirectoryFinder.SourceDirectory, "FDO/FDOTests/TestData"); var projName = Path.Combine(testDataPath, "SlightlyCorruptedXMLFile.fwdata"); // MockXMLBackendProvider implements IDisposable therefore we need the "using". @@ -713,7 +716,7 @@ public void SlightlyCorruptedXMLFileTest() [Test] public void XMLFileWithDuplicateGuidsTest() { - var testDataPath = Path.Combine(DirectoryFinder.FwSourceDirectory, "FDO/FDOTests/TestData"); + var testDataPath = Path.Combine(FwDirectoryFinder.SourceDirectory, "FDO/FDOTests/TestData"); var projName = Path.Combine(testDataPath, "DuplicateGuids.fwdata"); // MockXMLBackendProvider implements IDisposable therefore we need the "using". @@ -741,7 +744,7 @@ public void XMLFileWithDuplicateGuidsTest() public void ClosingTagSpansBufferTest() { int numCharsInClosingTag = kClosingTag.Length; - string testDataPath = Path.Combine(DirectoryFinder.FwSourceDirectory, "FDO/FDOTests/TestData", "ClosingTagSpansBuffer.fwdata"); + string testDataPath = Path.Combine(FwDirectoryFinder.SourceDirectory, "FDO/FDOTests/TestData", "ClosingTagSpansBuffer.fwdata"); var numCharsInFile = (int) new FileInfo(testDataPath).Length; // Try each edge case @@ -788,7 +791,7 @@ internal class MockXMLBackendProvider : XMLBackendProvider public MockXMLBackendProvider(FdoCache cache, string projName): base(cache, new IdentityMap((IFwMetaDataCacheManaged)cache.MetaDataCache), new CmObjectSurrogateFactory(cache), (IFwMetaDataCacheManagedInternal)cache.MetaDataCache, - new FdoDataMigrationManager()) + new FdoDataMigrationManager(), new DummyFdoUI(), FwDirectoryFinder.FdoDirectories) { Project = projName; Cache = cache; @@ -807,7 +810,7 @@ public void StartupExtant() ProjectId = new TestProjectId(FDOBackendProviderType.kXML, Project); // This will throw an UnauthorizedAccessException because of the // StartupInternalWithDataMigrationIfNeeded() override below - StartupExtantLanguageProject(ProjectId, false, new DummyProgressDlg()); + StartupExtantLanguageProject(ProjectId, false, new DummyProgressDlg(), false); } /// @@ -828,9 +831,288 @@ internal override void ReportDuplicateGuidsIfTheyExist() { } - protected override void StartupInternalWithDataMigrationIfNeeded(IThreadedProgress progressDlg) + protected override void StartupInternalWithDataMigrationIfNeeded(IThreadedProgress progressDlg, bool forbidDataMigration) { throw new UnauthorizedAccessException(); } } + + /// ---------------------------------------------------------------------------------------- + /// + /// Base class for testing the FdoCache with the FDOBackendProviderType.kSharedXML + /// backend provider. + /// + /// ---------------------------------------------------------------------------------------- + [TestFixture] + public sealed class SharedXMLTests : PersistingBackendProviderTestBase + { + /// ------------------------------------------------------------------------------------ + /// + /// Override to create and load a very basic cache. + /// + /// ------------------------------------------------------------------------------------ + protected override FdoCache CreateCache() + { + SharedXMLBackendProvider.CommitLogFileSize = 102400; + IProjectIdentifier projectID = ProjectID; + if (!m_internalRestart) + { + if (File.Exists(projectID.Path)) + File.Delete(projectID.Path); + } + return BootstrapSystem(projectID, m_loadType); + } + + private IProjectIdentifier ProjectID + { + get + { + const string projName = "TestLangProj-test"; + string filename = Path.Combine(FwDirectoryFinder.ProjectsDirectory, + Path.Combine(projName, FdoFileHelper.GetXmlDataFileName(projName))); + return new TestProjectId(FDOBackendProviderType.kSharedXMLWithMemoryOnlyWsMgr, filename); + } + } + + private FdoCache CreateOtherCache() + { + FdoCache retval = FdoCache.CreateCacheFromExistingData(ProjectID, "en", new DummyFdoUI(), FwDirectoryFinder.FdoDirectories, new DummyProgressDlg()); + var dataSetup = retval.ServiceLocator.GetInstance(); + dataSetup.LoadDomain(m_loadType); + return retval; + } + + /// + /// Tests sequential changes by two caches on the same project. + /// + [Test] + public void SequentialChanges() + { + Cache.ServiceLocator.GetInstance().Save(); + Cache.ServiceLocator.GetInstance().CompleteAllCommits(); + using (FdoCache otherCache = CreateOtherCache()) + { + ILexEntry entry1 = null; + NonUndoableUnitOfWorkHelper.Do(Cache.ServiceLocator.ActionHandler, () => + { + IMoMorphType stemType = Cache.ServiceLocator.GetInstance().GetObject(MoMorphTypeTags.kguidMorphStem); + entry1 = Cache.ServiceLocator.GetInstance().Create(stemType, Cache.TsStrFactory.MakeString("form1", Cache.DefaultVernWs), + Cache.TsStrFactory.MakeString("gloss1", Cache.DefaultAnalWs), new SandboxGenericMSA()); + }); + Cache.ServiceLocator.GetInstance().Save(); + + ILexEntry otherEntry1; + Assert.That(otherCache.ServiceLocator.GetInstance().TryGetObject(entry1.Guid, out otherEntry1), Is.False); + otherCache.ServiceLocator.GetInstance().Save(); + + Assert.That(otherCache.ServiceLocator.GetInstance().TryGetObject(entry1.Guid, out otherEntry1), Is.True); + Assert.That(otherEntry1.LexemeFormOA.ShortName, Is.EqualTo(entry1.LexemeFormOA.ShortName)); + Assert.That(otherEntry1.SensesOS[0].ShortName, Is.EqualTo(entry1.SensesOS[0].ShortName)); + + ILexEntry otherEntry2 = null; + NonUndoableUnitOfWorkHelper.Do(otherCache.ServiceLocator.ActionHandler, () => + { + IMoMorphType stemType = otherCache.ServiceLocator.GetInstance().GetObject(MoMorphTypeTags.kguidMorphStem); + otherEntry2 = otherCache.ServiceLocator.GetInstance().Create(stemType, otherCache.TsStrFactory.MakeString("form2", otherCache.DefaultVernWs), + otherCache.TsStrFactory.MakeString("gloss2", otherCache.DefaultAnalWs), new SandboxGenericMSA()); + }); + otherCache.ServiceLocator.GetInstance().Save(); + + ILexEntry entry2; + Assert.That(Cache.ServiceLocator.GetInstance().TryGetObject(otherEntry2.Guid, out entry2), Is.False); + Cache.ServiceLocator.GetInstance().Save(); + + Assert.That(Cache.ServiceLocator.GetInstance().TryGetObject(otherEntry2.Guid, out entry2), Is.True); + Assert.That(entry2.LexemeFormOA.ShortName, Is.EqualTo(otherEntry2.LexemeFormOA.ShortName)); + Assert.That(entry2.SensesOS[0].ShortName, Is.EqualTo(otherEntry2.SensesOS[0].ShortName)); + } + } + + /// + /// Tests simultaneous changes by two caches on the same project. + /// + [Test] + public void SimultaneousChanges() + { + Cache.ServiceLocator.GetInstance().Save(); + Cache.ServiceLocator.GetInstance().CompleteAllCommits(); + using (FdoCache otherCache = CreateOtherCache()) + { + ILexEntry entry1 = null; + NonUndoableUnitOfWorkHelper.Do(Cache.ServiceLocator.ActionHandler, () => + { + IMoMorphType stemType = Cache.ServiceLocator.GetInstance().GetObject(MoMorphTypeTags.kguidMorphStem); + entry1 = Cache.ServiceLocator.GetInstance().Create(stemType, Cache.TsStrFactory.MakeString("form1", Cache.DefaultVernWs), + Cache.TsStrFactory.MakeString("gloss1", Cache.DefaultAnalWs), new SandboxGenericMSA()); + }); + + ILexEntry otherEntry2 = null; + NonUndoableUnitOfWorkHelper.Do(otherCache.ServiceLocator.ActionHandler, () => + { + IMoMorphType stemType = otherCache.ServiceLocator.GetInstance().GetObject(MoMorphTypeTags.kguidMorphStem); + otherEntry2 = otherCache.ServiceLocator.GetInstance().Create(stemType, otherCache.TsStrFactory.MakeString("form2", otherCache.DefaultVernWs), + otherCache.TsStrFactory.MakeString("gloss2", otherCache.DefaultAnalWs), new SandboxGenericMSA()); + }); + + Cache.ServiceLocator.GetInstance().Save(); + + ILexEntry otherEntry1; + Assert.That(otherCache.ServiceLocator.GetInstance().TryGetObject(entry1.Guid, out otherEntry1), Is.False); + otherCache.ServiceLocator.GetInstance().Save(); + + ILexEntry entry2; + Assert.That(Cache.ServiceLocator.GetInstance().TryGetObject(otherEntry2.Guid, out entry2), Is.False); + Cache.ServiceLocator.GetInstance().Save(); + + Assert.That(otherCache.ServiceLocator.GetInstance().TryGetObject(entry1.Guid, out otherEntry1), Is.True); + Assert.That(otherEntry1.LexemeFormOA.ShortName, Is.EqualTo(entry1.LexemeFormOA.ShortName)); + Assert.That(otherEntry1.SensesOS[0].ShortName, Is.EqualTo(entry1.SensesOS[0].ShortName)); + + Assert.That(Cache.ServiceLocator.GetInstance().TryGetObject(otherEntry2.Guid, out entry2), Is.True); + Assert.That(entry2.LexemeFormOA.ShortName, Is.EqualTo(otherEntry2.LexemeFormOA.ShortName)); + Assert.That(entry2.SensesOS[0].ShortName, Is.EqualTo(otherEntry2.SensesOS[0].ShortName)); + } + } + + /// + /// Tests that renaming the project is not allowed when there are multiple caches using the same project. + /// + [Test] + public void RenameDatabaseNotAllowedWhenMultipleCaches() + { + Cache.ServiceLocator.GetInstance().Save(); + Cache.ServiceLocator.GetInstance().CompleteAllCommits(); + using (FdoCache otherCache = CreateOtherCache()) + { + Assert.That(Cache.RenameDatabase("NewName"), Is.False); + Assert.That(otherCache.RenameDatabase("NewName"), Is.False); + } + Assert.That(Cache.RenameDatabase("NewName"), Is.True); + Assert.That(Cache.RenameDatabase("TestLangProj-test"), Is.True); + } + + /// + /// Tests conflicting changes by two caches on the same project. + /// + [Test] + public void ConflictingChanges() + { + Cache.ServiceLocator.GetInstance().Save(); + Cache.ServiceLocator.GetInstance().CompleteAllCommits(); + using (FdoCache otherCache = CreateOtherCache()) + { + ILexEntry entry1 = null; + NonUndoableUnitOfWorkHelper.Do(Cache.ServiceLocator.ActionHandler, () => + { + IMoMorphType stemType = Cache.ServiceLocator.GetInstance().GetObject(MoMorphTypeTags.kguidMorphStem); + entry1 = Cache.ServiceLocator.GetInstance().Create(stemType, Cache.TsStrFactory.MakeString("form1", Cache.DefaultVernWs), + Cache.TsStrFactory.MakeString("gloss1", Cache.DefaultAnalWs), new SandboxGenericMSA()); + }); + Cache.ServiceLocator.GetInstance().Save(); + otherCache.ServiceLocator.GetInstance().Save(); + + ILexEntry otherEntry1; + Assert.That(otherCache.ServiceLocator.GetInstance().TryGetObject(entry1.Guid, out otherEntry1), Is.True); + NonUndoableUnitOfWorkHelper.Do(otherCache.ServiceLocator.ActionHandler, () => + { + otherEntry1.CitationForm.set_String(otherCache.DefaultVernWs, "othercitation"); + }); + otherCache.ServiceLocator.GetInstance().Save(); + + NonUndoableUnitOfWorkHelper.Do(Cache.ServiceLocator.ActionHandler, () => + { + entry1.CitationForm.set_String(Cache.DefaultVernWs, "citation"); + }); + var ui = (DummyFdoUI) Cache.ServiceLocator.GetInstance(); + ui.Reset(); + Cache.ServiceLocator.GetInstance().Save(); + // the first in should win + Assert.That(entry1.CitationForm.VernacularDefaultWritingSystem.Text, Is.EqualTo("othercitation")); + // check that the user was prompted about conflicting changes + Assert.That(ui.ConflictingSaveOccurred, Is.True); + } + } + + /// + /// Tests shutting down the master cache and letting the slave take over. + /// + [Test] + public void SwitchMasters() + { + Cache.ServiceLocator.GetInstance().Save(); + Cache.ServiceLocator.GetInstance().CompleteAllCommits(); + Guid otherEntryGuid1; + using (FdoCache otherCache = CreateOtherCache()) + { + DisposeEverythingButBase(); + ILexEntry otherEntry1 = null; + NonUndoableUnitOfWorkHelper.Do(otherCache.ServiceLocator.ActionHandler, () => + { + IMoMorphType stemType = otherCache.ServiceLocator.GetInstance().GetObject(MoMorphTypeTags.kguidMorphStem); + otherEntry1 = otherCache.ServiceLocator.GetInstance().Create(stemType, otherCache.TsStrFactory.MakeString("form1", otherCache.DefaultVernWs), + otherCache.TsStrFactory.MakeString("gloss1", otherCache.DefaultAnalWs), new SandboxGenericMSA()); + }); + otherEntryGuid1 = otherEntry1.Guid; + otherCache.ServiceLocator.GetInstance().Save(); + } + + RestartCache(false); + ILexEntry entry1; + Assert.That(Cache.ServiceLocator.GetInstance().TryGetObject(otherEntryGuid1, out entry1), Is.True); + Assert.That(entry1.LexemeFormOA.Form.VernacularDefaultWritingSystem.Text, Is.EqualTo("form1")); + Assert.That(entry1.SensesOS[0].Gloss.AnalysisDefaultWritingSystem.Text, Is.EqualTo("gloss1")); + } + + /// + /// Tests wrapping around the internal commit log circular buffer. + /// + [Test] + public void WrapAroundCommitLogBuffer() + { + // totally reset project + SetupEverythingButBase(); + + // add some commit records to log, so that the log will wrap around + int i; + for (i = 0; i < 5; i++) + { + NonUndoableUnitOfWorkHelper.Do(Cache.ServiceLocator.ActionHandler, () => + { + IMoMorphType stemType = Cache.ServiceLocator.GetInstance().GetObject(MoMorphTypeTags.kguidMorphStem); + ILexEntry entry1 = Cache.ServiceLocator.GetInstance().Create(stemType, Cache.TsStrFactory.MakeString("form1", Cache.DefaultVernWs), + Cache.TsStrFactory.MakeString("gloss1", Cache.DefaultAnalWs), new SandboxGenericMSA()); + }); + Cache.ServiceLocator.GetInstance().Save(); + } + Cache.ServiceLocator.GetInstance().CompleteAllCommits(); + Cache.ServiceLocator.GetInstance().Save(); + using (FdoCache otherCache = CreateOtherCache()) + { + // add commit records until the log fills up + // once the log is full, we know that the internal buffer has wrapped around + while (true) + { + NonUndoableUnitOfWorkHelper.Do(Cache.ServiceLocator.ActionHandler, () => + { + IMoMorphType stemType = Cache.ServiceLocator.GetInstance().GetObject(MoMorphTypeTags.kguidMorphStem); + ILexEntry entry1 = Cache.ServiceLocator.GetInstance().Create(stemType, Cache.TsStrFactory.MakeString("form1", Cache.DefaultVernWs), + Cache.TsStrFactory.MakeString("gloss1", Cache.DefaultAnalWs), new SandboxGenericMSA()); + }); + try + { + Cache.ServiceLocator.GetInstance().Save(); + } + catch (InvalidOperationException) + { + break; + } + i++; + } + // the other cache will now read the wrapped around commit log buffer + otherCache.ServiceLocator.GetInstance().Save(); + + Assert.That(otherCache.ServiceLocator.GetInstance().GetHomographs("form1").Count, Is.EqualTo(i)); + } + } + } } diff --git a/Src/FDO/FDOTests/PersistingLayerTests.BEPPortTests.cs b/Src/FDO/FDOTests/PersistingLayerTests.BEPPortTests.cs index 3cba5ae764..f63fd560c4 100644 --- a/Src/FDO/FDOTests/PersistingLayerTests.BEPPortTests.cs +++ b/Src/FDO/FDOTests/PersistingLayerTests.BEPPortTests.cs @@ -82,7 +82,7 @@ public void Setup() m_sourceInfo = new List { new BackendStartupParameter(true, BackendBulkLoadDomain.All, - new TestProjectId(FDOBackendProviderType.kXML, DirectoryFinder.GetXmlDataFileName("TLP" + randomFileExtension))), + new TestProjectId(FDOBackendProviderType.kXML, FdoFileHelper.GetXmlDataFileName("TLP" + randomFileExtension))), new BackendStartupParameter(true, BackendBulkLoadDomain.All, new TestProjectId(FDOBackendProviderType.kMemoryOnly, null)), new BackendStartupParameter(true, BackendBulkLoadDomain.All, @@ -91,7 +91,7 @@ public void Setup() m_targetInfo = new List { new BackendStartupParameter(true, BackendBulkLoadDomain.All, - new TestProjectId(FDOBackendProviderType.kXML, DirectoryFinder.GetXmlDataFileName("TLP_New" + randomFileExtension))), + new TestProjectId(FDOBackendProviderType.kXML, FdoFileHelper.GetXmlDataFileName("TLP_New" + randomFileExtension))), new BackendStartupParameter(true, BackendBulkLoadDomain.All, new TestProjectId(FDOBackendProviderType.kMemoryOnly, null)), new BackendStartupParameter(true, BackendBulkLoadDomain.All, @@ -106,7 +106,7 @@ public void Setup() /// ------------------------------------------------------------------------------------ public override void FixtureSetup() { - RemotingServer.Start(); + RemotingServer.Start(FwDirectoryFinder.RemotingTcpServerConfigFile, FwDirectoryFinder.FdoDirectories, () => false, v => {}); base.FixtureSetup(); } @@ -216,10 +216,9 @@ public void PortAllBEPsTestsUsingAnAlreadyOpenedSource( // Set up data source, but only do it once. var sourceGuids = new List(); - using (var threadHelper = new ThreadHelper()) using (var sourceCache = FdoCache.CreateCacheWithNewBlankLangProj( new TestProjectId(sourceBackendStartupParameters.ProjectId.Type, - sourceBackendStartupParameters.ProjectId.Path), "en", "fr", "en", threadHelper)) + sourceBackendStartupParameters.ProjectId.Path), "en", "fr", "en", new DummyFdoUI(), FwDirectoryFinder.FdoDirectories)) { // BEP is a singleton, so we shouldn't call Dispose on it. This will be done // by service locator. @@ -232,10 +231,9 @@ public void PortAllBEPsTestsUsingAnAlreadyOpenedSource( DeleteDatabase(targetBackendStartupParameters); // Migrate source data to new BEP. - using (var otherThreadHelper = new ThreadHelper()) using (var targetCache = FdoCache.CreateCacheCopy( new TestProjectId(targetBackendStartupParameters.ProjectId.Type, - targetBackendStartupParameters.ProjectId.Path), "en", sourceCache, otherThreadHelper)) + targetBackendStartupParameters.ProjectId.Path), "en", new DummyFdoUI(), FwDirectoryFinder.FdoDirectories, sourceCache)) { // BEP is a singleton, so we shouldn't call Dispose on it. This will be done // by service locator. @@ -284,7 +282,7 @@ public void PortAllBEPsTestsUsingAnUnopenedSource( sourceBackendStartupParameters.ProjectId.Path); IThreadedProgress progressDlg = new DummyProgressDlg(); using (FdoCache sourceCache = FdoCache.CreateCacheWithNewBlankLangProj( - projId, "en", "fr", "en", progressDlg.ThreadHelper)) + projId, "en", "fr", "en", new DummyFdoUI(), FwDirectoryFinder.FdoDirectories)) { // BEP is a singleton, so we shouldn't call Dispose on it. This will be done // by service locator. @@ -298,7 +296,7 @@ public void PortAllBEPsTestsUsingAnUnopenedSource( // Migrate source data to new BEP. progressDlg = new DummyProgressDlg(); using (var targetCache = FdoCache.CreateCacheWithNoLangProj( - new TestProjectId(targetBackendStartupParameters.ProjectId.Type, null), "en", progressDlg.ThreadHelper)) + new TestProjectId(targetBackendStartupParameters.ProjectId.Type, null), "en", new DummyFdoUI(), FwDirectoryFinder.FdoDirectories)) { // BEP is a singleton, so we shouldn't call Dispose on it. This will be done // by service locator. diff --git a/Src/FDO/FDOTests/ScrChecksDataSourceTests.cs b/Src/FDO/FDOTests/ScrChecksDataSourceTests.cs index dc2c76ce8c..1eddd524d4 100644 --- a/Src/FDO/FDOTests/ScrChecksDataSourceTests.cs +++ b/Src/FDO/FDOTests/ScrChecksDataSourceTests.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using NUnit.Framework; using SIL.CoreImpl; +using SIL.FieldWorks.Resources; using SIL.Utils; using SILUBS.SharedScrUtils; using SIL.FieldWorks.FDO.DomainServices; @@ -23,7 +24,7 @@ namespace SIL.FieldWorks.FDO.FDOTests [TestFixture] public class ScrChecksDataSourceTests : ScrInMemoryFdoTestBase { - private ScrChecksDataSource m_dataSource = null; + private ScrChecksDataSource m_dataSource; /// ------------------------------------------------------------------------------------ /// @@ -35,7 +36,8 @@ public class ScrChecksDataSourceTests : ScrInMemoryFdoTestBase public override void TestSetup() { base.TestSetup(); - m_dataSource = new ScrChecksDataSource(Cache, DirectoryFinder.TeStylesPath); + m_dataSource = new ScrChecksDataSource(Cache, ResourceHelper.GetResourceString("kstidPunctCheckWhitespaceChar"), + FwDirectoryFinder.LegacyWordformingCharOverridesFile, FwDirectoryFinder.TeStylesPath); } ///-------------------------------------------------------------------------------------- diff --git a/Src/FDO/FDOTests/ScrImportFileInfoTests.cs b/Src/FDO/FDOTests/ScrImportFileInfoTests.cs index 992e6e5e9e..336eb2a07b 100644 --- a/Src/FDO/FDOTests/ScrImportFileInfoTests.cs +++ b/Src/FDO/FDOTests/ScrImportFileInfoTests.cs @@ -9,9 +9,10 @@ using System.IO; using System.Text; using NUnit.Framework; -using SIL.FieldWorks.Test.TestUtils; -using SIL.FieldWorks.FDO; +using SIL.FieldWorks.Common.FwUtils; +using SIL.FieldWorks.Resources; using SIL.FieldWorks.Common.ScriptureUtils; +using SIL.FieldWorks.Test.TestUtils; using SILUBS.SharedScrUtils; using SIL.FieldWorks.FDO.DomainServices; using SIL.Utils; @@ -24,7 +25,7 @@ namespace SIL.FieldWorks.FDO.FDOTests /// /// ---------------------------------------------------------------------------------------- [TestFixture] - public class ScrImportFileInfoTests: SIL.FieldWorks.Test.TestUtils.BaseTest + public class ScrImportFileInfoTests : BaseTest { #region class DummyScrImportFileInfo /// ------------------------------------------------------------------------------------ @@ -122,7 +123,7 @@ protected override TextReader GetReader() [SetUp] public void Init() { - m_mappingList = new ScrMappingList(MappingSet.Main, null); + m_mappingList = new ScrMappingList(MappingSet.Main, null, ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); m_factory = new ScrImportFileInfoFactory(); m_fileOs = new MockFileOS(); FileUtils.Manager.SetFileAdapter(m_fileOs); diff --git a/Src/FDO/FDOTests/ScrImportSetTests.cs b/Src/FDO/FDOTests/ScrImportSetTests.cs index 103fd721dd..6269fcf6d8 100644 --- a/Src/FDO/FDOTests/ScrImportSetTests.cs +++ b/Src/FDO/FDOTests/ScrImportSetTests.cs @@ -8,16 +8,13 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Collections.Specialized; using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Text; - using NUnit.Framework; using Rhino.Mocks; - +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.Common.ScriptureUtils; using SIL.FieldWorks.FDO.DomainServices; +using SIL.FieldWorks.Resources; using SIL.Utils; using SILUBS.SharedScrUtils; @@ -123,39 +120,13 @@ public override IScrImportFileInfo Create(string fileName, ScrMappingList mappin public class ScrImportSetTests : ScrInMemoryFdoTestBase { #region data members - private MockParatextHelper m_ptHelper; private IScrImportSet m_importSettings; private ICmAnnotationDefn m_translatorNoteDefn; private ICmAnnotationDefn m_consultantNoteDefn; - private IParatextHelper m_mockParatextHelper; private MockFileOS m_fileOs; #endregion #region Setup & Teardown - /// ------------------------------------------------------------------------------------ - /// - /// - /// - /// ------------------------------------------------------------------------------------ - public override void FixtureSetup() - { - base.FixtureSetup(); - m_ptHelper = new MockParatextHelper(); - ParatextHelper.Manager.SetParatextHelperAdapter(m_ptHelper); - } - - /// ------------------------------------------------------------------------------------ - /// - /// - /// - /// ------------------------------------------------------------------------------------ - public override void FixtureTeardown() - { - base.FixtureTeardown(); - m_ptHelper.Dispose(); - ParatextHelper.Manager.Reset(); - } - /// ------------------------------------------------------------------------------------ /// /// Test setup stuff @@ -164,12 +135,9 @@ public override void FixtureTeardown() public override void TestSetup() { base.TestSetup(); - m_ptHelper.Projects.Clear(); - m_importSettings = Cache.ServiceLocator.GetInstance().Create(); - m_mockParatextHelper = MockRepository.GenerateMock(); + m_importSettings = Cache.ServiceLocator.GetInstance().Create(ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); m_scr.ImportSettingsOC.Add(m_importSettings); - m_ptHelper.m_loadProjectMappingsImpl = m_mockParatextHelper; m_translatorNoteDefn = Cache.ServiceLocator.GetInstance().TranslatorAnnotationDefn; m_consultantNoteDefn = Cache.ServiceLocator.GetInstance().ConsultantAnnotationDefn; @@ -688,8 +656,6 @@ public void SaveAndReloadSources_SaveSeparateSourcesWhenImportTypeChanges() // Now that we've saved the settings, we'll "revert" in order to re-load from the DB m_importSettings.RevertToSaved(); - m_mockParatextHelper.Stub(x => x.LoadProjectMappings(Arg.Is.Equal("KAM"), - Arg.Is.Anything, Arg.Is.Equal(ImportDomain.Main))).Return(true); m_importSettings.ImportTypeEnum = TypeOfImport.Paratext6; m_importSettings.ParatextScrProj = "KAM"; m_importSettings.SaveSettings(); @@ -794,11 +760,6 @@ public void SaveAndReloadParatext6Projects() ScrMappingList mappingList = (ScrMappingList)m_importSettings.Mappings(MappingSet.Main); - m_mockParatextHelper.Stub(x => x.LoadProjectMappings(Arg.Is.Equal("KAM"), - Arg.Is.Equal(mappingList), Arg.Is.Equal(ImportDomain.Main))).Return(true); - m_mockParatextHelper.Stub(x => x.LoadProjectMappings(Arg.Is.Equal("TEV"), - Arg.Is.Equal(mappingList), Arg.Is.Equal(ImportDomain.BackTrans))).Return(true); - // add Scripture files m_importSettings.ParatextScrProj = "KAM"; m_importSettings.ParatextBTProj = "TEV"; @@ -851,32 +812,6 @@ public void AddFile_Main() ((ScrSfFileList)ReflectionHelper.GetField(m_importSettings, "m_scrFileInfoList"))[0]); } - /// ------------------------------------------------------------------------------------ - /// - /// Test adding a file that is locked - /// - /// ------------------------------------------------------------------------------------ - [Test] - public void AddFileAndCheckAccessibility_Locked() - { - m_importSettings.ImportTypeEnum = TypeOfImport.Other; - - string filename = m_fileOs.MakeSfFile("EPH", @"\c 1", @"\v 1"); - m_fileOs.LockFile(filename); - - // Lock the file - //using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite)) - //{ - IScrImportFileInfo info = m_importSettings.AddFile(filename, ImportDomain.Main, null, null); - Assert.AreEqual(Encoding.ASCII, info.FileEncoding); - Assert.AreEqual(1, m_importSettings.GetImportFiles(ImportDomain.Main).Count); - StringCollection notFound; - Assert.IsFalse(m_importSettings.ImportProjectIsAccessible(out notFound)); - Assert.AreEqual(1, notFound.Count); - Assert.AreEqual(filename, (string)notFound[0]); - //} - } - /// ------------------------------------------------------------------------------------ /// /// Try to add non-existent file to the SF Project. This should be allowed because @@ -973,11 +908,6 @@ public void MarkMappingsInUse_SwitchFromParatext6ToOther() ScrMappingList mappingListMain = (ScrMappingList)m_importSettings.Mappings(MappingSet.Main); ScrMappingList mappingListNotes = (ScrMappingList)m_importSettings.Mappings(MappingSet.Notes); - m_mockParatextHelper.Stub(x => x.LoadProjectMappings(Arg.Is.Equal("KAM"), - Arg.Is.Equal(mappingListMain), Arg.Is.Equal(ImportDomain.Main))).Return(true); - m_mockParatextHelper.Stub(x => x.LoadProjectMappings(Arg.Is.Equal("TEV"), - Arg.Is.Equal(mappingListNotes), Arg.Is.Equal(ImportDomain.Annotations))).Return(true); - // set Scripture project m_importSettings.ParatextScrProj = "TEV"; m_importSettings.ParatextNotesProj = "KAM"; @@ -1055,9 +985,6 @@ public void AttemptToUseSameParatextProjectTwice() { m_importSettings.ImportTypeEnum = TypeOfImport.Paratext6; - m_mockParatextHelper.Stub(x => x.LoadProjectMappings(Arg.Is.Equal("KAM"), - Arg.Is.Anything, Arg.Is.Equal(ImportDomain.BackTrans))).Return(true); - m_importSettings.ParatextBTProj = "KAM"; m_importSettings.ParatextNotesProj = "KAM"; } @@ -1073,9 +1000,6 @@ public void SwitchFromParatext6ToParatext5Project() { m_importSettings.ImportTypeEnum = TypeOfImport.Paratext6; - m_mockParatextHelper.Stub(x => x.LoadProjectMappings(Arg.Is.Equal("KAM"), - Arg.Is.Anything, Arg.Is.Equal(ImportDomain.BackTrans))).Return(true); - ScrMappingList mappings = m_importSettings.GetMappingListForDomain(ImportDomain.Main); m_importSettings.SetMapping(MappingSet.Main, new ImportMappingInfo(@"\q", null, "Qute")); @@ -1142,9 +1066,6 @@ public void BasicSettingsExist_Paratext6() { m_importSettings.ImportTypeEnum = TypeOfImport.Paratext6; - m_mockParatextHelper.Stub(x => x.LoadProjectMappings(Arg.Is.Anything, - Arg.Is.Anything, Arg.Is.Anything)).Return(true); - Assert.IsFalse(m_importSettings.BasicSettingsExist, "No project settings set yet"); m_importSettings.ParatextBTProj = "KAM"; @@ -1209,83 +1130,6 @@ public void BasicSettingsExist_Paretxt5() } #endregion - #region Attempting to load Paratext project with missing files - /// ------------------------------------------------------------------------------------ - /// - /// Attempting to set the Paratext project to a project that can't be loaded should not - /// set the value. - /// - /// ------------------------------------------------------------------------------------ - [Test] - public void ParatextScrProj_Set_FailureToLoadProject() - { - m_importSettings.ImportTypeEnum = TypeOfImport.Paratext6; - - m_mockParatextHelper.Stub(x => x.LoadProjectMappings(Arg.Is.Equal("NEC"), - Arg.Is.Anything, Arg.Is.Anything)).Return(false); - - m_importSettings.ParatextScrProj = "NEC"; - - Assert.IsNull(m_importSettings.ParatextScrProj); - } - #endregion - - #region ImportProjectIsAccessible tests - /// ------------------------------------------------------------------------------------ - /// - /// Test to see if the ImportProjectIsAccessible method works for Paratext 6 projects. - /// - /// ------------------------------------------------------------------------------------ - [Test] - public void ImportProjectIsAccessible_Paratext6() - { - m_importSettings.ImportTypeEnum = TypeOfImport.Paratext6; - - string paratextDir = ParatextHelper.ProjectsDirectory; - m_mockParatextHelper.Stub(x => x.LoadProjectMappings(Arg.Is.Anything, - Arg.Is.Anything, Arg.Is.Anything)).Return(true); - m_ptHelper.AddProject("TEV", null, null, true, false, "100001"); - - m_fileOs.AddExistingFile(Path.Combine(paratextDir, "TEV.ssf")); - - m_importSettings.ParatextScrProj = "KAM"; - m_importSettings.ParatextBTProj = "TEV"; - - StringCollection projectsNotFound; - Assert.IsFalse(m_importSettings.ImportProjectIsAccessible(out projectsNotFound)); - Assert.AreEqual(1, projectsNotFound.Count); - Assert.AreEqual("KAM", projectsNotFound[0]); - - m_fileOs.AddExistingFile(Path.Combine(paratextDir, "KAM.ssf")); - m_ptHelper.AddProject("KAM", null, null, true, false, "000101"); - Assert.IsTrue(m_importSettings.ImportProjectIsAccessible(out projectsNotFound)); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Test to see if the ImportProjectIsAccessible method works for Paratext 5 projects. - /// - /// ------------------------------------------------------------------------------------ - [Test] - public void ImportProjectIsAccessible_Paratext5() - { - m_importSettings.ImportTypeEnum = TypeOfImport.Paratext5; - ImportProjectIsAccessible_helper(); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Test to see if the ImportProjectIsAccessible method works for Other projects. - /// - /// ------------------------------------------------------------------------------------ - [Test] - public void ImportProjectIsAccessible_Other() - { - m_importSettings.ImportTypeEnum = TypeOfImport.Other; - ImportProjectIsAccessible_helper(); - } - #endregion - #region Helper methods /// ------------------------------------------------------------------------------------ /// @@ -1338,77 +1182,6 @@ private void CheckFileListContents(string[] files, ImportDomain domain) for (int index = 0; index < found.Length; index++) Assert.IsTrue(found[index], "File not found in " + domain + " source: " + files[index]); } - - /// ------------------------------------------------------------------------------------ - /// - /// Test to see if the ImportProjectIsAccessible method works for projects other than - /// Paratext 6. - /// - /// ------------------------------------------------------------------------------------ - private void ImportProjectIsAccessible_helper() - { - string scrFile1 = m_fileOs.MakeSfFile("GEN", @"\p", @"\c 1", @"\v 1", @"\v 2"); - string scrFile2 = m_fileOs.MakeSfFile("EXO", @"\p", @"\c 1", @"\v 1", @"\v 2"); - string scrFile3 = m_fileOs.MakeSfFile("LEV", @"\p", @"\c 1", @"\v 1", @"\v 2"); - string btFileDef = m_fileOs.MakeSfFile("GEN", @"\p", @"\c 3", @"\v 1"); - string btFileSpan = m_fileOs.MakeSfFile("GEN", @"\p", @"\c 3", @"\v 1"); - string annotFileCons = m_fileOs.MakeSfFile("GEN", @"\p", @"\c 3", @"\v 1"); - string annotFileTrans = m_fileOs.MakeSfFile("GEN", @"\p", @"\c 3", @"\v 1"); - - m_importSettings.AddFile(scrFile1, ImportDomain.Main, null, null); - m_importSettings.AddFile(scrFile2, ImportDomain.Main, null, null); - m_importSettings.AddFile(scrFile3, ImportDomain.Main, null, null); - m_importSettings.AddFile(btFileDef, ImportDomain.BackTrans, null, null); - m_importSettings.AddFile(btFileSpan, ImportDomain.BackTrans, "es", null); - m_importSettings.AddFile(annotFileCons, ImportDomain.Annotations, null, m_consultantNoteDefn); - m_importSettings.AddFile(annotFileTrans, ImportDomain.Annotations, null, m_translatorNoteDefn); - - StringCollection filesNotFound; - Assert.IsTrue(m_importSettings.ImportProjectIsAccessible(out filesNotFound)); - Assert.AreEqual(0, filesNotFound.Count); - m_importSettings.SaveSettings(); - - // Blow away some project files: should still return true, but should - // report missing files. - FileUtils.Delete(scrFile2); - FileUtils.Delete(scrFile3); - FileUtils.Delete(btFileDef); - FileUtils.Delete(annotFileCons); - FileUtils.Delete(annotFileTrans); - - // Now that we've saved the settings, we'll "revert" in order to re-load from the DB - m_importSettings.RevertToSaved(); - - Assert.IsTrue(m_importSettings.ImportProjectIsAccessible(out filesNotFound)); - Assert.AreEqual(5, filesNotFound.Count); - - Assert.IsTrue(filesNotFound.Contains(scrFile2)); - Assert.IsTrue(filesNotFound.Contains(scrFile3)); - Assert.IsTrue(filesNotFound.Contains(btFileDef)); - Assert.IsTrue(filesNotFound.Contains(annotFileCons)); - Assert.IsTrue(filesNotFound.Contains(annotFileTrans)); - - m_importSettings.SaveSettings(); - - // Blow away the rest of the project files: should return false and report - // missing files. - FileUtils.Delete(scrFile1); - FileUtils.Delete(btFileSpan); - - // Now that we've saved the settings, we'll "revert" in order to re-load from the DB - m_importSettings.RevertToSaved(); - - Assert.IsFalse(m_importSettings.ImportProjectIsAccessible(out filesNotFound)); - Assert.AreEqual(7, filesNotFound.Count); - - Assert.IsTrue(filesNotFound.Contains(scrFile1)); - Assert.IsTrue(filesNotFound.Contains(scrFile2)); - Assert.IsTrue(filesNotFound.Contains(scrFile3)); - Assert.IsTrue(filesNotFound.Contains(btFileDef)); - Assert.IsTrue(filesNotFound.Contains(btFileSpan)); - Assert.IsTrue(filesNotFound.Contains(annotFileCons)); - Assert.IsTrue(filesNotFound.Contains(annotFileTrans)); - } #endregion } } diff --git a/Src/FDO/FDOTests/ScrMappingListTests.cs b/Src/FDO/FDOTests/ScrMappingListTests.cs index 718400bae8..580331eeac 100644 --- a/Src/FDO/FDOTests/ScrMappingListTests.cs +++ b/Src/FDO/FDOTests/ScrMappingListTests.cs @@ -11,7 +11,10 @@ using Rhino.Mocks; using SIL.FieldWorks.Common.COMInterfaces; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.Common.ScriptureUtils; +using SIL.FieldWorks.Resources; +using SIL.FieldWorks.Test.TestUtils; using SIL.Utils; using SIL.FieldWorks.FDO.DomainServices; @@ -23,7 +26,7 @@ namespace SIL.FieldWorks.FDO.FDOTests /// /// ---------------------------------------------------------------------------------------- [TestFixture] - public class ScrMappingListTests: SIL.FieldWorks.Test.TestUtils.BaseTest + public class ScrMappingListTests : BaseTest { #region Save/load mappings tests /// ------------------------------------------------------------------------------------ @@ -34,7 +37,7 @@ public class ScrMappingListTests: SIL.FieldWorks.Test.TestUtils.BaseTest [Test] public void SetMappings_Main() { - ScrMappingList list = new ScrMappingList(MappingSet.Main, null); + ScrMappingList list = new ScrMappingList(MappingSet.Main, null, ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); list.Add(new ImportMappingInfo(@"\a", null, false, MappingTargetType.TEStyle, MarkerDomain.Default, ScrStyleNames.NormalParagraph, null)); list.Add(new ImportMappingInfo(@"\a", null, false, MappingTargetType.TEStyle, MarkerDomain.BackTrans, ScrStyleNames.NormalParagraph, "es")); list.Add(new ImportMappingInfo(@"\b", null, false, MappingTargetType.TEStyle, MarkerDomain.Default, ScrStyleNames.NormalParagraph, null)); @@ -87,7 +90,7 @@ public void SetMappings_Main() [Test] public void SetMappings_Notes() { - ScrMappingList list = new ScrMappingList(MappingSet.Notes, null); + ScrMappingList list = new ScrMappingList(MappingSet.Notes, null, ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); list.Add(new ImportMappingInfo(@"\a", null, false, MappingTargetType.TEStyle, MarkerDomain.Note, ScrStyleNames.Remark, null)); list.Add(new ImportMappingInfo(@"\b", null, false, MappingTargetType.TEStyle, MarkerDomain.Default, ScrStyleNames.Remark, null)); try @@ -116,7 +119,7 @@ public void SetMappings_Notes() [Test] public void Delete() { - ScrMappingList list = new ScrMappingList(MappingSet.Main, null); + ScrMappingList list = new ScrMappingList(MappingSet.Main, null, ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); list.Add(new ImportMappingInfo(@"\aa", null, false, MappingTargetType.TEStyle, MarkerDomain.Default, ScrStyleNames.Remark, null)); list.Add(new ImportMappingInfo(@"\bb", null, false, MappingTargetType.TEStyle, MarkerDomain.Default, ScrStyleNames.Remark, null)); list.Add(new ImportMappingInfo(@"\cc", null, false, MappingTargetType.TEStyle, MarkerDomain.BackTrans, ScrStyleNames.Remark, null)); @@ -139,7 +142,7 @@ public void Delete() [Test] public void HasChanged() { - ScrMappingList list = new ScrMappingList(MappingSet.Main, null); + ScrMappingList list = new ScrMappingList(MappingSet.Main, null, ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); list.Add(new ImportMappingInfo(@"\aa", null, false, MappingTargetType.TEStyle, MarkerDomain.Default, ScrStyleNames.Remark, null)); list.Add(new ImportMappingInfo(@"\bb", null, false, MappingTargetType.TEStyle, MarkerDomain.Default, ScrStyleNames.Remark, null)); list.Add(new ImportMappingInfo(@"\cc", null, false, MappingTargetType.TEStyle, MarkerDomain.BackTrans, ScrStyleNames.Remark, null)); @@ -166,7 +169,7 @@ public void HasChanged() [ExpectedException(typeof(ArgumentOutOfRangeException))] public void Index_OutOfRange() { - ScrMappingList list = new ScrMappingList(MappingSet.Notes, null); + ScrMappingList list = new ScrMappingList(MappingSet.Notes, null, ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); list.Add(new ImportMappingInfo(@"\a", null, false, MappingTargetType.TEStyle, MarkerDomain.Note, ScrStyleNames.Remark, null)); // Access the second element which should throw an exception @@ -181,7 +184,7 @@ public void Index_OutOfRange() [Test] public void LookupByKey() { - ScrMappingList list = new ScrMappingList(MappingSet.Notes, null); + ScrMappingList list = new ScrMappingList(MappingSet.Notes, null, ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); list.Add(new ImportMappingInfo(@"\aa", null, false, MappingTargetType.TEStyle, MarkerDomain.Note, ScrStyleNames.Remark, null)); list.Add(new ImportMappingInfo(@"\bb", null, false, MappingTargetType.TEStyle, MarkerDomain.Note, ScrStyleNames.Remark, null)); list.Add(new ImportMappingInfo(@"\cc", null, false, MappingTargetType.TEStyle, MarkerDomain.Note, ScrStyleNames.Remark, null)); @@ -199,7 +202,7 @@ public void LookupByKey() [Test] public void LookupByKey_NonExistent() { - ScrMappingList list = new ScrMappingList(MappingSet.Notes, null); + ScrMappingList list = new ScrMappingList(MappingSet.Notes, null, ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); Assert.IsNull(list["moogy"]); } @@ -211,7 +214,7 @@ public void LookupByKey_NonExistent() [Test] public void Enumerator() { - ScrMappingList list = new ScrMappingList(MappingSet.Notes, null); + ScrMappingList list = new ScrMappingList(MappingSet.Notes, null, ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); list.Add(new ImportMappingInfo(@"\aa", null, false, MappingTargetType.TEStyle, MarkerDomain.Note, ScrStyleNames.Remark, null)); list.Add(new ImportMappingInfo(@"\bb", null, false, MappingTargetType.TEStyle, MarkerDomain.Note, ScrStyleNames.Remark, null)); list.Add(new ImportMappingInfo(@"\cc", null, false, MappingTargetType.TEStyle, MarkerDomain.Note, ScrStyleNames.Remark, null)); @@ -235,7 +238,7 @@ public void AddDefaultMappingIfNeeded_FigureMarkers() { IVwStylesheet stylesheet = MockRepository.GenerateMock(); - ScrMappingList list = new ScrMappingList(MappingSet.Main, stylesheet); + ScrMappingList list = new ScrMappingList(MappingSet.Main, stylesheet, ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); list.AddDefaultMappingIfNeeded(@"\cap", ImportDomain.Main, true); list.AddDefaultMappingIfNeeded(@"\cat", ImportDomain.Main, true); list.AddDefaultMappingIfNeeded(@"\gmb", ImportDomain.Main, true); @@ -288,7 +291,7 @@ public void AddDefaultMappingIfNeeded_btMappings() stylesheet.Stub(x => x.GetType("Emphasis")).Return((int)StyleType.kstCharacter); stylesheet.Stub(x => x.GetType(ScrStyleNames.Remark)).Return((int)StyleType.kstParagraph); - ScrMappingList list = new ScrMappingList(MappingSet.Main, stylesheet); + ScrMappingList list = new ScrMappingList(MappingSet.Main, stylesheet, ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); list.AddDefaultMappingIfNeeded(@"\bt", ImportDomain.Main, true); list.AddDefaultMappingIfNeeded(@"\btc", ImportDomain.Main, true); list.AddDefaultMappingIfNeeded(@"\btf", ImportDomain.Main, true); @@ -364,7 +367,7 @@ public void AddDefaultMappingIfNeeded_btMappingsWithNonDefaultMappings() stylesheet.Stub(x => x.GetContext("Emphasis")).Return((int)ContextValues.General); stylesheet.Stub(x => x.GetType("Emphasis")).Return((int)StyleType.kstCharacter); - ScrMappingList list = new ScrMappingList(MappingSet.Main, stylesheet); + ScrMappingList list = new ScrMappingList(MappingSet.Main, stylesheet, ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); list.Add(new ImportMappingInfo(@"\p", null, "Emphasis")); list.AddDefaultMappingIfNeeded(@"\btp", ImportDomain.Main, true); Assert.AreEqual(2, list.Count); @@ -390,7 +393,7 @@ public void AddDefaultMappingIfNeeded_btNotFromTeStyle() { IVwStylesheet stylesheet = MockRepository.GenerateStrictMock(); - ScrMappingList list = new ScrMappingList(MappingSet.Main, stylesheet); + ScrMappingList list = new ScrMappingList(MappingSet.Main, stylesheet, ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); list.Add(new ImportMappingInfo(@"\h", null, false, MappingTargetType.TitleShort, MarkerDomain.Default, null, null)); list.AddDefaultMappingIfNeeded(@"\bth", ImportDomain.Main, true); @@ -425,7 +428,7 @@ public void AddDefaultMappingIfNeeded_btNotFromTeStyle() [ExpectedException(typeof(ArgumentNullException))] public void AddNullMappingInfo() { - ScrMappingList list = new ScrMappingList(MappingSet.Main, null); + ScrMappingList list = new ScrMappingList(MappingSet.Main, null, ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); list.Add(null); } @@ -439,7 +442,7 @@ public void AddNullMappingInfo() [ExpectedException(typeof(ArgumentException))] public void AddInfoWithNullMarker() { - ScrMappingList list = new ScrMappingList(MappingSet.Main, null); + ScrMappingList list = new ScrMappingList(MappingSet.Main, null, ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); list.Add(new ImportMappingInfo(null, null, null)); } @@ -453,7 +456,7 @@ public void AddInfoWithNullMarker() [ExpectedException(typeof(ArgumentException))] public void AddBlankMarker() { - ScrMappingList list = new ScrMappingList(MappingSet.Main, null); + ScrMappingList list = new ScrMappingList(MappingSet.Main, null, ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); list.Add(new ImportMappingInfo(string.Empty, string.Empty, string.Empty)); } #endregion diff --git a/Src/FDO/FDOTests/ScrSfFileListTests.cs b/Src/FDO/FDOTests/ScrSfFileListTests.cs index 1b7e408246..9b6b47da78 100644 --- a/Src/FDO/FDOTests/ScrSfFileListTests.cs +++ b/Src/FDO/FDOTests/ScrSfFileListTests.cs @@ -7,8 +7,10 @@ using System.Collections.Generic; using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices; using Rhino.Mocks; +using SIL.FieldWorks.Resources; using SIL.FieldWorks.Test.TestUtils; using SIL.FieldWorks.Common.ScriptureUtils; using SILUBS.SharedScrUtils; @@ -25,7 +27,7 @@ public class ScrSfFileListTests: BaseTest { #region data members private IOverlappingFileResolver m_resolver; - private ScrMappingList m_mappingList = new ScrMappingList(MappingSet.Main, null); + private ScrMappingList m_mappingList = new ScrMappingList(MappingSet.Main, null, ResourceHelper.DefaultParaCharsStyleName, FwDirectoryFinder.TeStylesPath); private ScrSfFileList m_fileList; private List m_expectedRemovedFiles; private int m_callCountForVerifyFileRemoved; diff --git a/Src/Common/FwUtils/FwUtilsTests/TestProjectId.cs b/Src/FDO/FDOTests/TestProjectId.cs similarity index 96% rename from Src/Common/FwUtils/FwUtilsTests/TestProjectId.cs rename to Src/FDO/FDOTests/TestProjectId.cs index 794e619522..a4ae046787 100644 --- a/Src/Common/FwUtils/FwUtilsTests/TestProjectId.cs +++ b/Src/FDO/FDOTests/TestProjectId.cs @@ -5,9 +5,9 @@ // File: TestProjectId.cs // Responsibility: FW Team // --------------------------------------------------------------------------------------------- -using SysPath = System.IO.Path; +using SIL.FieldWorks.Common.FwUtils; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.FieldWorks.FDO.FDOTests { /// ---------------------------------------------------------------------------------------- /// @@ -78,7 +78,7 @@ public string PipeHandle /// ------------------------------------------------------------------------------------ public string Name { - get { return SysPath.GetFileNameWithoutExtension(Path); } + get { return System.IO.Path.GetFileNameWithoutExtension(Path); } } /// ------------------------------------------------------------------------------------ @@ -89,7 +89,7 @@ public string Name /// ------------------------------------------------------------------------------------ public string ProjectFolder { - get { return SysPath.GetDirectoryName(Path); } + get { return System.IO.Path.GetDirectoryName(Path); } } /// ------------------------------------------------------------------------------------ diff --git a/Src/FDO/FDOTests/ValidCharactersTests.cs b/Src/FDO/FDOTests/ValidCharactersTests.cs index b6d1c72c47..34622bbaf2 100644 --- a/Src/FDO/FDOTests/ValidCharactersTests.cs +++ b/Src/FDO/FDOTests/ValidCharactersTests.cs @@ -123,7 +123,7 @@ public List OtherCharacters [Test] public void InitializeFromOldValidCharsList() { - var validChars = ValidCharacters.Load(" a b c d . 1 2 3", "Test WS", null, null); + var validChars = ValidCharacters.Load(" a b c d . 1 2 3", "Test WS", null, null, FwDirectoryFinder.CodeDirectory); ValidCharsWrapper validCharsW = new ValidCharsWrapper(validChars); Assert.AreEqual(4, validCharsW.WordFormingCharacters.Count); Assert.IsTrue(validCharsW.WordFormingCharacters.Contains("a")); @@ -161,7 +161,7 @@ public void InitializeFromXml_Valid() "4\uFFFC5" + ",\uFFFC!\uFFFC*" + ""; - var validChars = ValidCharacters.Load(sXml, "Test WS", null, null); + var validChars = ValidCharacters.Load(sXml, "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ValidCharsWrapper validCharsW = new ValidCharsWrapper(validChars); Assert.AreEqual(4, validCharsW.WordFormingCharacters.Count); Assert.IsTrue(validCharsW.WordFormingCharacters.Contains("e")); @@ -191,7 +191,7 @@ public void InitializeFromXml_ValidEmpty() "" + "" + ""; - var validChars = ValidCharacters.Load(sXml, "Test WS", null, RememberError); + var validChars = ValidCharacters.Load(sXml, "Test WS", null, RememberError, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ValidCharsWrapper validCharsW = new ValidCharsWrapper(validChars); Assert.AreEqual(0, validCharsW.WordFormingCharacters.Count); Assert.AreEqual(0, validCharsW.NumericCharacters.Count); @@ -209,7 +209,7 @@ public void InitializeFromXml_ValidEmpty() [Test] public void InitializeFromXml_ValidNull() { - var validChars = ValidCharacters.Load(null, "Test WS", null, RememberError); + var validChars = ValidCharacters.Load(null, "Test WS", null, RememberError, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ValidCharsWrapper validCharsW = new ValidCharsWrapper(validChars); Assert.AreEqual(0, validCharsW.WordFormingCharacters.Count); Assert.AreEqual(0, validCharsW.NumericCharacters.Count); @@ -225,7 +225,7 @@ public void InitializeFromXml_ValidNull() [Test] public void InitializeFromXml_ValidEmptyString() { - var validChars = ValidCharacters.Load(String.Empty, "Test WS", null, RememberError); + var validChars = ValidCharacters.Load(String.Empty, "Test WS", null, RememberError, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ValidCharsWrapper validCharsW = new ValidCharsWrapper(validChars); Assert.AreEqual(0, validCharsW.WordFormingCharacters.Count); Assert.AreEqual(0, validCharsW.NumericCharacters.Count); @@ -246,7 +246,7 @@ public void InitializeFromXml_AllowHardLineBreakCharacter() "" + "\u2028" + ""; - var validChars = ValidCharacters.Load(sXml, "Test WS", null, null); + var validChars = ValidCharacters.Load(sXml, "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ValidCharsWrapper validCharsW = new ValidCharsWrapper(validChars); Assert.AreEqual(1, validCharsW.OtherCharacters.Count); Assert.IsTrue(validCharsW.OtherCharacters.Contains("\u2028")); @@ -269,7 +269,7 @@ public void InitializeFromXml_NumericElementClosedTooEarly() "4\uFFFC5" + ",\uFFFC!\uFFFC*" + ""; - var validChars = ValidCharacters.Load(ws, null); + var validChars = ValidCharacters.Load(ws, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ValidCharsWrapper validCharsW = new ValidCharsWrapper(validChars); Assert.AreEqual(4, validCharsW.WordFormingCharacters.Count); Assert.IsTrue(validCharsW.WordFormingCharacters.Contains("e")); @@ -299,7 +299,7 @@ public void InitializeFromXml_BogusFormat() ",\uFFFC!\uFFFC*" + ""; - var validChars = ValidCharacters.Load(ws, RememberError); + var validChars = ValidCharacters.Load(ws, RememberError, FwDirectoryFinder.LegacyWordformingCharOverridesFile); VerifyDefaultWordFormingCharacters(validChars); Assert.AreEqual("Invalid ValidChars field while loading the English (United States) writing system:" + @@ -323,7 +323,7 @@ public void InitializeFromXml_SingleBogusCharacter() "" + ""; - var validChars = ValidCharacters.Load(ws, RememberError); + var validChars = ValidCharacters.Load(ws, RememberError, FwDirectoryFinder.LegacyWordformingCharOverridesFile); VerifyDefaultWordFormingCharacters(validChars); Assert.AreEqual("Invalid ValidChars field while loading the English (United States) writing system. " + "The following characters are invalid:" + @@ -347,7 +347,7 @@ public void InitializeFromXml_SingleCompoundBogusCharacter() "" + ""; - var validChars = ValidCharacters.Load(ws, RememberError); + var validChars = ValidCharacters.Load(ws, RememberError, FwDirectoryFinder.LegacyWordformingCharOverridesFile); VerifyDefaultWordFormingCharacters(validChars); Assert.AreEqual("Invalid ValidChars field while loading the English (United States) writing system. " + "The following characters are invalid:" + @@ -371,7 +371,7 @@ public void InitializeFromXml_ValidAndBogusCharacters() "" + ""; - var validChars = ValidCharacters.Load(ws, RememberError); + var validChars = ValidCharacters.Load(ws, RememberError, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ValidCharsWrapper validCharsW = new ValidCharsWrapper(validChars); Assert.AreEqual(2, validCharsW.WordFormingCharacters.Count); Assert.IsTrue(validCharsW.WordFormingCharacters.Contains("g")); @@ -401,7 +401,7 @@ public void InitializeFromXml_SameCharacterInWordFormingAndPunctuationXMLLists() "" + "'" + ""; - var validChars = ValidCharacters.Load(sXml, "Test WS", null, null); + var validChars = ValidCharacters.Load(sXml, "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ValidCharsWrapper validCharsW = new ValidCharsWrapper(validChars); Assert.AreEqual(1, validCharsW.WordFormingCharacters.Count); Assert.IsTrue(validCharsW.WordFormingCharacters.Contains("'")); @@ -422,7 +422,7 @@ public void InitializeFromXml_SameCharacterInWordFormingAndNumbericXMLLists() "1" + "" + ""; - var validChars = ValidCharacters.Load(sXml, "Test WS", null, null); + var validChars = ValidCharacters.Load(sXml, "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ValidCharsWrapper validCharsW = new ValidCharsWrapper(validChars); Assert.AreEqual(1, validCharsW.WordFormingCharacters.Count); Assert.IsTrue(validCharsW.WordFormingCharacters.Contains("1")); @@ -443,7 +443,7 @@ public void InitializeFromXml_SameCharacterInNumericAndPunctuationXMLLists() "1" + "1" + ""; - var validChars = ValidCharacters.Load(sXml, "Test WS", null, null); + var validChars = ValidCharacters.Load(sXml, "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ValidCharsWrapper validCharsW = new ValidCharsWrapper(validChars); Assert.AreEqual(0, validCharsW.WordFormingCharacters.Count); Assert.AreEqual(1, validCharsW.NumericCharacters.Count); @@ -464,7 +464,7 @@ public void InitializeFromXml_DuplicateCharacters() "4\uFFFC4" + "'\uFFFC'" + ""; - var validChars = ValidCharacters.Load(sXml, "Test WS", null, null); + var validChars = ValidCharacters.Load(sXml, "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ValidCharsWrapper validCharsW = new ValidCharsWrapper(validChars); Assert.AreEqual(1, validCharsW.WordFormingCharacters.Count); Assert.IsTrue(validCharsW.WordFormingCharacters.Contains("a")); @@ -482,7 +482,7 @@ public void InitializeFromXml_DuplicateCharacters() [Test] public void InitializeFromNullString() { - var validChars = ValidCharacters.Load(string.Empty, "Test WS", null, null); + var validChars = ValidCharacters.Load(string.Empty, "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ValidCharsWrapper validCharsW = new ValidCharsWrapper(validChars); Assert.AreEqual(0, validCharsW.WordFormingCharacters.Count); Assert.AreEqual(0, validCharsW.NumericCharacters.Count); @@ -500,7 +500,7 @@ public void InitializeFromNullString() [Test] public void AddCharacter_Duplicate() { - var validChars = ValidCharacters.Load(string.Empty, "Test WS", null, null); + var validChars = ValidCharacters.Load(string.Empty, "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ValidCharsWrapper validCharsW = new ValidCharsWrapper(validChars); validChars.AddCharacter("a"); validChars.AddCharacter("a"); @@ -528,7 +528,7 @@ public void AddCharacter_DuplicateOfOverriddenWordFormingChar() "" + "{" + ""; - var validChars = ValidCharacters.Load(sXml, "Test WS", null, null); + var validChars = ValidCharacters.Load(sXml, "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ValidCharsWrapper validCharsW = new ValidCharsWrapper(validChars); Assert.AreEqual(2, validCharsW.WordFormingCharacters.Count); Assert.AreEqual(0, validCharsW.NumericCharacters.Count); @@ -555,7 +555,7 @@ public void AddCharacter_DuplicateOfOverriddenWordFormingChar() [Test] public void AddCharacter_SuperscriptedToneNumber() { - var validChars = ValidCharacters.Load(string.Empty, "Test WS", null, null); + var validChars = ValidCharacters.Load(string.Empty, "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); ValidCharsWrapper validCharsW = new ValidCharsWrapper(validChars); validChars.AddCharacter("\u00b9"); validChars.AddCharacter("\u2079"); @@ -574,7 +574,7 @@ public void AddCharacter_SuperscriptedToneNumber() [Test] public void GetNaturalCharType() { - var validChars = ValidCharacters.Load(string.Empty, "Test WS", null, null); + var validChars = ValidCharacters.Load(string.Empty, "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); DummyCharPropEngine cpe = new DummyCharPropEngine(); ReflectionHelper.SetField(validChars, "m_cpe", cpe); Assert.AreEqual(ValidCharacterType.WordForming, @@ -601,7 +601,7 @@ public void IsWordFormingChar() "a\uFFFCb\uFFFCc\uFFFCd\uFFFCe\uFFFC#" + "" + "" + - "", "Test WS", null, null); + "", "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); Assert.IsTrue(validChars.IsWordForming('#')); //Assert.IsTrue(validChars.IsWordForming("#")); } @@ -614,7 +614,7 @@ public void IsWordFormingChar() [Test] public void SortAfterAddSingles() { - var validChars = ValidCharacters.Load(string.Empty, "Test WS", null, null); + var validChars = ValidCharacters.Load(string.Empty, "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); IWritingSystem ws = m_wsManager.Create("en"); validChars.InitSortComparer(ws); validChars.AddCharacter("z"); @@ -636,7 +636,7 @@ public void SortAfterAddSingles() [Test] public void SortAfterAddRange() { - var validChars = ValidCharacters.Load(string.Empty, "Test WS", null, null); + var validChars = ValidCharacters.Load(string.Empty, "Test WS", null, null, FwDirectoryFinder.LegacyWordformingCharOverridesFile); IWritingSystem ws = m_wsManager.Create("en"); validChars.InitSortComparer(ws); var list = new List(new[] { "z", "c", "t", "b", "8", "7", "6", "5" }); diff --git a/Src/FDO/FDOTests/WritingSystemServicesTests.cs b/Src/FDO/FDOTests/WritingSystemServicesTests.cs index 923922f17a..ca1be12016 100644 --- a/Src/FDO/FDOTests/WritingSystemServicesTests.cs +++ b/Src/FDO/FDOTests/WritingSystemServicesTests.cs @@ -1,14 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Collections.Generic; using NUnit.Framework; using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.FDO.Infrastructure; using SIL.FieldWorks.FDO.Infrastructure.Impl; -using SIL.FieldWorks.Test.TestUtils; namespace SIL.FieldWorks.FDO.FDOTests { @@ -49,7 +45,7 @@ public void UpdateWritingSystemListField_ReplacesNonDuplicateCode() public void FindOrCreateSomeWritingSystem_Converts_x_unk_To_qaa_x_unk() { IWritingSystem ws; - Assert.That(WritingSystemServices.FindOrCreateSomeWritingSystem(Cache, "x-unk", true, false, out ws), Is.False); + Assert.That(WritingSystemServices.FindOrCreateSomeWritingSystem(Cache, null, "x-unk", true, false, out ws), Is.False); Assert.That(ws.Id, Is.EqualTo("qaa-x-unk")); } @@ -62,7 +58,7 @@ public void FindOrCreateSomeWritingSystem_Converts_x_unk_To_qaa_x_unk() public void FindOrCreateSomeWritingSystem_Converts_Fr_Tech_30Oct_To_qaa_x_Fr_Tech_30Oct() { IWritingSystem ws; - Assert.That(WritingSystemServices.FindOrCreateSomeWritingSystem(Cache, "Fr-Tech 30Oct", true, false, out ws), Is.False); + Assert.That(WritingSystemServices.FindOrCreateSomeWritingSystem(Cache, null, "Fr-Tech 30Oct", true, false, out ws), Is.False); Assert.That(ws.Id, Is.EqualTo("qaa-x-Fr-Tech30Oc")); //8 characters is the maximum allowed for a part. } @@ -73,7 +69,7 @@ public void FindOrCreateSomeWritingSystem_Converts_Fr_Tech_30Oct_To_qaa_x_Fr_Tec public void FindOrCreateSomeWritingSystem_Converts_x_To_qaa_x_qaa() { IWritingSystem ws; - Assert.That(WritingSystemServices.FindOrCreateSomeWritingSystem(Cache, "x", true, false, out ws), Is.False); + Assert.That(WritingSystemServices.FindOrCreateSomeWritingSystem(Cache, null, "x", true, false, out ws), Is.False); Assert.That(ws.Id, Is.EqualTo("qaa-x-qaa")); } /// @@ -108,7 +104,7 @@ public void UpdateWritingSystemTag_MarksObjectsAsDirty() { var entry0 = Cache.ServiceLocator.GetInstance().Create(); IWritingSystem newWs; - var ws = WritingSystemServices.FindOrCreateWritingSystem(Cache, "en-NO", true, false, out newWs); + var ws = WritingSystemServices.FindOrCreateWritingSystem(Cache, null, "en-NO", true, false, out newWs); // A string property NOT using the WS we will change. entry0.ImportResidue = Cache.TsStrFactory.MakeString("hello", Cache.DefaultAnalWs); // A multilingual one using the WS. @@ -172,9 +168,9 @@ public void MergeWritingSystem_ConvertsMultiStrings() { var entry1 = Cache.ServiceLocator.GetInstance().Create(); IWritingSystem fromWs; - WritingSystemServices.FindOrCreateWritingSystem(Cache, "en-NO", true, false, out fromWs); + WritingSystemServices.FindOrCreateWritingSystem(Cache, null, "en-NO", true, false, out fromWs); IWritingSystem toWs; - WritingSystemServices.FindOrCreateWritingSystem(Cache, "en-SO", true, false, out toWs); + WritingSystemServices.FindOrCreateWritingSystem(Cache, null, "en-SO", true, false, out toWs); EnsureAnalysisWs(new [] {fromWs, toWs}); var sense1 = Cache.ServiceLocator.GetInstance().Create(); entry1.SensesOS.Add(sense1); @@ -209,9 +205,9 @@ void EnsureAnalysisWs(IWritingSystem[] wss) public void MergeWritingSystem_ConvertsStyleDefinition() { IWritingSystem fromWs; - WritingSystemServices.FindOrCreateWritingSystem(Cache, "en-NO", true, false, out fromWs); + WritingSystemServices.FindOrCreateWritingSystem(Cache, null, "en-NO", true, false, out fromWs); IWritingSystem toWs; - WritingSystemServices.FindOrCreateWritingSystem(Cache, "en-SO", true, false, out toWs); + WritingSystemServices.FindOrCreateWritingSystem(Cache, null, "en-SO", true, false, out toWs); EnsureAnalysisWs(new [] { fromWs, toWs }); var style1 = Cache.ServiceLocator.GetInstance().Create(); @@ -240,9 +236,9 @@ public void MergeWritingSystem_ConvertsStyleDefinition() public void MergeWritingSystemWithStyleDefnForToWs_DoesNotConvertStyleDefinition() { IWritingSystem fromWs; - WritingSystemServices.FindOrCreateWritingSystem(Cache, "en-NO", true, false, out fromWs); + WritingSystemServices.FindOrCreateWritingSystem(Cache, null, "en-NO", true, false, out fromWs); IWritingSystem toWs; - WritingSystemServices.FindOrCreateWritingSystem(Cache, "en-SO", true, false, out toWs); + WritingSystemServices.FindOrCreateWritingSystem(Cache, null, "en-SO", true, false, out toWs); EnsureAnalysisWs(new[] { fromWs, toWs }); var style1 = Cache.ServiceLocator.GetInstance().Create(); @@ -277,9 +273,9 @@ public void MergeWritingSystemWithStyleDefnForToWs_DoesNotConvertStyleDefinition public void MergeWritingSystem_ConvertsLiftResidue() { IWritingSystem fromWs; - WritingSystemServices.FindOrCreateWritingSystem(Cache, "en-NO", true, false, out fromWs); + WritingSystemServices.FindOrCreateWritingSystem(Cache, null, "en-NO", true, false, out fromWs); IWritingSystem toWs; - WritingSystemServices.FindOrCreateWritingSystem(Cache, "en-SO", true, false, out toWs); + WritingSystemServices.FindOrCreateWritingSystem(Cache, null, "en-SO", true, false, out toWs); EnsureAnalysisWs(new[] { fromWs, toWs }); var entry1 = Cache.ServiceLocator.GetInstance().Create(); @@ -306,7 +302,7 @@ public void CollatorSort_DoesNotThrow() Assert.DoesNotThrow(() => { IWritingSystem fromWs; - WritingSystemServices.FindOrCreateWritingSystem(Cache, "sen", false, true, out fromWs); + WritingSystemServices.FindOrCreateWritingSystem(Cache, null, "sen", false, true, out fromWs); Cache.LangProject.DefaultVernacularWritingSystem = fromWs; fromWs.Collator.GetSortKey("boom"); }); diff --git a/Src/FDO/FDOTests/XmlImportDataTests.cs b/Src/FDO/FDOTests/XmlImportDataTests.cs index 54055e1868..961247c76d 100644 --- a/Src/FDO/FDOTests/XmlImportDataTests.cs +++ b/Src/FDO/FDOTests/XmlImportDataTests.cs @@ -21,7 +21,6 @@ using SIL.FieldWorks.FDO.Application.ApplicationServices; using SIL.FieldWorks.FDO.Infrastructure; using SIL.FieldWorks.Test.TestUtils; -using SIL.Utils; namespace SIL.FieldWorks.FDO.FDOTests { @@ -48,7 +47,7 @@ public void CreateTestCache() { m_now = DateTime.Now; m_cache = FdoCache.CreateCacheWithNewBlankLangProj( - new TestProjectId(FDOBackendProviderType.kMemoryOnly, "MemoryOnly.mem"), "en", "fr", "en", new ThreadHelper()); + new TestProjectId(FDOBackendProviderType.kMemoryOnly, "MemoryOnly.mem"), "en", "fr", "en", new DummyFdoUI(), FwDirectoryFinder.FdoDirectories); IDataSetup dataSetup = m_cache.ServiceLocator.GetInstance(); dataSetup.LoadDomain(BackendBulkLoadDomain.All); if (m_cache.LangProject != null) @@ -76,7 +75,6 @@ public void DestroyTestCache() { if (m_cache != null) { - m_cache.ThreadHelper.Dispose(); m_cache.Dispose(); m_cache = null; } @@ -161,8 +159,7 @@ public void ImportData1() Assert.AreEqual(0, m_cache.LangProject.AnthroListOA.PossibilitiesOS.Count); Assert.AreEqual(0, m_cache.LangProject.SemanticDomainListOA.PossibilitiesOS.Count); Assert.AreEqual(0, m_cache.LangProject.PartsOfSpeechOA.PossibilitiesOS.Count); - bool fOk = xid.ImportData(rdr, new StringWriter(sbLog), null); - Assert.IsTrue(fOk, "Import of one lexical entry succeeded."); + xid.ImportData(rdr, new StringWriter(sbLog), null); DateTime dtLexNew = m_cache.LangProject.LexDbOA.DateCreated; DateTime dt2 = new DateTime(1995, 12, 19, 10, 31, 25); Assert.AreEqual(dt2, dtLexNew, "LexDb DateCreated changed to reflect import value."); @@ -385,8 +382,7 @@ public void ImportData2() )) { StringBuilder sbLog = new StringBuilder(); - bool fOk = xid.ImportData(rdr, new StringWriter(sbLog), null); - Assert.IsTrue(fOk, "Import of one LexEntry, one RreversalIndexEntry, and two WfiWordforms succeeded."); + xid.ImportData(rdr, new StringWriter(sbLog), null); IWritingSystem wsEn = m_cache.ServiceLocator.WritingSystemManager.Get("en"); Assert.AreEqual(1, m_cache.LangProject.LexDbOA.ReversalIndexesOC.Count); IReversalIndex revIdx = m_cache.LangProject.LexDbOA.ReversalIndexesOC.ToArray()[0]; @@ -497,7 +493,7 @@ public void ImportData2() public void ImportData3() { XmlImportData xid = new XmlImportData(m_cache); - string sFwSrcDir = DirectoryFinder.FwSourceDirectory; + string sFwSrcDir = FwDirectoryFinder.SourceDirectory; using (var rdr = new StringReader( "" + Environment.NewLine + "" + Environment.NewLine + @@ -868,8 +864,7 @@ public void ImportData3() )) { StringBuilder sbLog = new StringBuilder(); - bool fOk = xid.ImportData(rdr, new StringWriter(sbLog), null); - Assert.IsTrue(fOk, "Import of a bunch of stuff succeeded."); + xid.ImportData(rdr, new StringWriter(sbLog), null); int wsEn = m_cache.WritingSystemFactory.GetWsFromStr("en"); int wsAme = m_cache.WritingSystemFactory.GetWsFromStr("qaa-x-ame"); Assert.AreEqual(0, m_cache.LangProject.LexDbOA.ReversalIndexesOC.Count); @@ -1023,7 +1018,7 @@ private void CheckTheText(IText text) private void CheckFirstEntry(ILexEntry le, int wsEn, int wsAme) { - string sFwSrcDir = DirectoryFinder.FwSourceDirectory; + string sFwSrcDir = FwDirectoryFinder.SourceDirectory; Assert.AreEqual(1, le.LexemeFormOA.Form.StringCount); Assert.AreEqual("an", le.LexemeFormOA.Form.get_String(wsAme).Text); Assert.AreEqual("root", le.LexemeFormOA.MorphTypeRA.Name.get_String(wsEn).Text); @@ -1373,8 +1368,7 @@ public void ImportData4() Assert.AreEqual(0, m_cache.LangProject.SemanticDomainListOA.PossibilitiesOS.Count); Assert.AreEqual(0, m_cache.LangProject.PartsOfSpeechOA.PossibilitiesOS.Count); StringBuilder sbLog = new StringBuilder(); - bool fOk = xid.ImportData(rdr, new StringWriter(sbLog), null); - Assert.IsTrue(fOk, "Import of one lexical entry succeeded."); + xid.ImportData(rdr, new StringWriter(sbLog), null); Assert.AreEqual(1, m_cache.LangProject.LexDbOA.Entries.Count()); ILexEntry le = m_cache.LangProject.LexDbOA.Entries.ToArray()[0]; int wsKal = m_cache.WritingSystemFactory.GetWsFromStr("qaa-x-kal"); diff --git a/Src/FDO/FDOTests/XmlListTests.cs b/Src/FDO/FDOTests/XmlListTests.cs index 671f957225..5e34721cda 100644 --- a/Src/FDO/FDOTests/XmlListTests.cs +++ b/Src/FDO/FDOTests/XmlListTests.cs @@ -10,9 +10,7 @@ using System.IO; using NUnit.Framework; using SIL.FieldWorks.FDO.Application.ApplicationServices; -using SIL.FieldWorks.FDO.Infrastructure; using SIL.FieldWorks.Test.TestUtils; -using SIL.Utils; using SIL.FieldWorks.Common.FwUtils; namespace SIL.FieldWorks.FDO.FDOTests @@ -594,7 +592,7 @@ public class XmlListTests : BaseTest public void CreateMockCache() { m_cache = FdoCache.CreateCacheWithNewBlankLangProj( - new TestProjectId(FDOBackendProviderType.kMemoryOnly, null), "en", "es", "en", new ThreadHelper()); + new TestProjectId(FDOBackendProviderType.kMemoryOnly, null), "en", "es", "en", new DummyFdoUI(), FwDirectoryFinder.FdoDirectories); } /// @@ -603,7 +601,6 @@ public void CreateMockCache() [TearDown] public void DestroyMockCache() { - m_cache.ThreadHelper.Dispose(); m_cache.Dispose(); m_cache = null; } diff --git a/Src/FDO/FDOTests/XmlTranslatedListsTests.cs b/Src/FDO/FDOTests/XmlTranslatedListsTests.cs index bd7fd109df..1e84f6da3f 100644 --- a/Src/FDO/FDOTests/XmlTranslatedListsTests.cs +++ b/Src/FDO/FDOTests/XmlTranslatedListsTests.cs @@ -638,7 +638,7 @@ public class XmlTranslatedListsTests : BaseTest public void CreateMockCache() { m_cache = FdoCache.CreateCacheWithNewBlankLangProj( - new TestProjectId(FDOBackendProviderType.kMemoryOnly, null), "en", "es", "en", new ThreadHelper()); + new TestProjectId(FDOBackendProviderType.kMemoryOnly, null), "en", "es", "en", new DummyFdoUI(), FwDirectoryFinder.FdoDirectories); var xl = new XmlList(); using (var reader = new StringReader(XmlListTests.s_ksPartsOfSpeechXml)) @@ -667,7 +667,6 @@ public void CreateMockCache() [TearDown] public void DestroyMockCache() { - m_cache.ThreadHelper.Dispose(); m_cache.Dispose(); m_cache = null; } diff --git a/Src/FDO/FdoCacheIFwDisposableInterfaceImpl.cs b/Src/FDO/FdoCacheIFwDisposableInterfaceImpl.cs index 9f340f32eb..9523e781e7 100644 --- a/Src/FDO/FdoCacheIFwDisposableInterfaceImpl.cs +++ b/Src/FDO/FdoCacheIFwDisposableInterfaceImpl.cs @@ -10,7 +10,6 @@ using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.FDO.IOC; using SIL.Utils; -using SIL.FieldWorks.FDO.Infrastructure; namespace SIL.FieldWorks.FDO { @@ -159,7 +158,6 @@ private void Dispose(bool disposing) // Main data members. m_lgwsFactory = null; m_serviceLocator = null; - m_threadHelper = null; m_isDisposed = true; } diff --git a/Src/FDO/FdoDataMigrationForbiddenException.cs b/Src/FDO/FdoDataMigrationForbiddenException.cs new file mode 100644 index 0000000000..f0400e25ee --- /dev/null +++ b/Src/FDO/FdoDataMigrationForbiddenException.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2014-2014 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) + +using System; + +namespace SIL.FieldWorks.FDO +{ + /// + /// Exception thrown when we try to open a project which requires data migration but data migration has been forbidden by the application + /// + public class FdoDataMigrationForbiddenException : Exception + { + } +} \ No newline at end of file diff --git a/Src/FDO/FdoFactoryInterfaceAdditions.cs b/Src/FDO/FdoFactoryInterfaceAdditions.cs index d318d55f34..c762285e5c 100644 --- a/Src/FDO/FdoFactoryInterfaceAdditions.cs +++ b/Src/FDO/FdoFactoryInterfaceAdditions.cs @@ -1096,4 +1096,12 @@ public partial interface ICmMediaURIFactory /// A new, unowned CmMediaURI with the given guid ICmMediaURI Create(FdoCache cache, Guid guid); } + + public partial interface IScrImportSetFactory + { + /// + /// Creates a new scripture import settings with the default paragraph characters style name. + /// + IScrImportSet Create(string defaultParaCharsStyleName, string stylesPath); + } } \ No newline at end of file diff --git a/Src/FDO/FdoFileHelper.cs b/Src/FDO/FdoFileHelper.cs new file mode 100644 index 0000000000..be1860eacb --- /dev/null +++ b/Src/FDO/FdoFileHelper.cs @@ -0,0 +1,260 @@ +// Copyright (c) 2013-2014 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) + +using System; +using System.Diagnostics; +using System.IO; +using System.Text; +using SIL.Utils; + +namespace SIL.FieldWorks.FDO +{ + /// ---------------------------------------------------------------------------------------- + /// + /// Static class to hold a few constant FDO file extensions. + /// + /// ---------------------------------------------------------------------------------------- + public static class FdoFileHelper + { + /// Default extension for FieldWorks XML data files (with the period) + public const string ksFwDataXmlFileExtension = ".fwdata"; + /// Default extension for FieldWorks DB4o data files (with the period) + public const string ksFwDataDb4oFileExtension = ".fwdb"; + /// Default extension for FieldWorks backup files (with the period). + public const string ksFwBackupFileExtension = ".fwbackup"; + /// Default extension for FieldWorks 6.0 and earlier backup files (with the period). + public const string ksFw60BackupFileExtension = ".zip"; + /// Default extension for FieldWorks TEMPORARY fallback data files (with the period). + public const string ksFwDataFallbackFileExtension = ".bak"; + + + /// The name of the folder containing FLEx configuration settings + public const string ksConfigurationSettingsDir = "ConfigurationSettings"; + /// The name of the folder containing FLEx backup settings + public const string ksBackupSettingsDir = "BackupSettings"; + /// The name of the folder where the user can copy files for backup such as fonts and keyboards + public const string ksSupportingFilesDir = "SupportingFiles"; + /// The default name of the folder containing LinkedFiles (media, pictures, etc) for a project + public const string ksLinkedFilesDir = "LinkedFiles"; + /// The name of the subfolder containing media for a project + public const string ksMediaDir = "AudioVisual"; + /// The name of the subfolder containing pictures for a project + public const string ksPicturesDir = "Pictures"; + /// The name of the subfolder containing other LinkedFiles for a project + public const string ksOtherLinkedFilesDir = "Others"; + /// The name of the folder containing writing systems for a project + public const string ksWritingSystemsDir = "WritingSystemStore"; + /// The name of the folder containing temporary persisted sort sequence info for a project + public const string ksSortSequenceTempDir = "Temp"; + + /// Constant for locating the other repositories path of a project + public const string OtherRepositories = @"OtherRepositories"; + + /// The filename of the backup settings file + public const string kBackupSettingsFilename = "BackupSettings.xml"; + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the path to the configuration settings for the specified project. + /// + /// The path to the project folder. + /// ------------------------------------------------------------------------------------ + public static string GetConfigSettingsDir(string projectFolder) + { + return Path.Combine(projectFolder, ksConfigurationSettingsDir); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the path to the backup settings for the specified project + /// + /// The path to the project folder. + /// ------------------------------------------------------------------------------------ + public static string GetBackupSettingsDir(string projectFolder) + { + return Path.Combine(projectFolder, ksBackupSettingsDir); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the path to the fonts for the specified project. + /// + /// The path to the project folder. + /// ------------------------------------------------------------------------------------ + public static string GetSupportingFilesDir(string projectFolder) + { + return Path.Combine(projectFolder, ksSupportingFilesDir); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the path to the writing systems for the specified project. + /// + /// The path to the project folder. + /// ------------------------------------------------------------------------------------ + public static string GetWritingSystemDir(string projectFolder) + { + return Path.Combine(projectFolder, ksWritingSystemsDir); + } + + /// + /// Gets the path to the standard eternal linked files directory for the specified project. + /// + /// The path to the project. + /// + public static string GetDefaultLinkedFilesDir(string projectPath) + { + return Path.Combine(projectPath, ksLinkedFilesDir); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the path to the standard media files directory for the specified project. Note + /// that if this project keepes its externally linked files in a separate folder from + /// the rest of the project files (such as a shared folder common to multiple projects + /// on a server), the directory returned by this method will not actually contain any + /// files. + /// + /// The path to the project. + /// ------------------------------------------------------------------------------------ + public static string GetDefaultMediaDir(string projectPath) + { + return Path.Combine(projectPath, Path.Combine(ksLinkedFilesDir, ksMediaDir)); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the path to the standard pictures directory for the specified project. Note + /// that if this project keepes its externally linked files in a separate folder from + /// the rest of the project files (such as a shared folder common to multiple projects + /// on a server), the directory returned by this method will not actually contain any + /// files. + /// + /// The path to the project. + /// ------------------------------------------------------------------------------------ + public static string GetDefaultPicturesDir(string projectPath) + { + return Path.Combine(projectPath, Path.Combine(ksLinkedFilesDir, ksPicturesDir)); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the path to the standard directory for other externally linked project files. + /// Note that if this project keepes its externally linked files in a separate folder + /// from the rest of the project files (such as a shared folder common to multiple + /// projects on a server), the directory returned by this method will not actually + /// contain any files. + /// + /// The path to the project. + /// ------------------------------------------------------------------------------------ + public static string GetDefaultOtherExternalFilesDir(string projectPath) + { + return Path.Combine(projectPath, Path.Combine(ksLinkedFilesDir, ksOtherLinkedFilesDir)); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the path to the other repositories for the specified project. + /// + /// The path to the project folder. + /// ------------------------------------------------------------------------------------ + public static string GetOtherRepositoriesDir(string projectFolder) + { + return Path.Combine(projectFolder, OtherRepositories); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the path to the media files directory for the project. + /// + /// The project's LinkedFiles path. (eg. m_cache.LangProject.LinkedFilesRootDir) + /// ------------------------------------------------------------------------------------ + public static string GetMediaDir(string projectLinkedFilesPath) + { + return Path.Combine(projectLinkedFilesPath, ksMediaDir); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the path to the pictures directory for the project. + /// + /// The project's LinkedFiles path. (eg. m_cache.LangProject.LinkedFilesRootDir) + /// ------------------------------------------------------------------------------------ + public static string GetPicturesDir(string projectLinkedFilesPath) + { + return Path.Combine(projectLinkedFilesPath, ksPicturesDir); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the path to the directory for other externally linked project files. + /// + /// The project's LinkedFiles path. (eg. m_cache.LangProject.LinkedFilesRootDir) + /// ------------------------------------------------------------------------------------ + public static string GetOtherExternalFilesDir(string projectLinkedFilesPath) + { + return Path.Combine(projectLinkedFilesPath, ksOtherLinkedFilesDir); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the name of the XML data file, given a project name (basically just adds the + /// FW data XML file extension). + /// + /// Name of the project (not a filename). + /// ------------------------------------------------------------------------------------ + public static string GetXmlDataFileName(string projectName) + { + Debug.Assert(Path.GetExtension(projectName) != ksFwDataXmlFileExtension, + String.Format("There is a faint chance the user might have specified a real project name ending in {0} (in which case, sorry, but we're going to trim it off), but probably this is a programming error", ksFwDataXmlFileExtension)); + // Do not use Path.ChangeExtension because it will strip off anything following a period in the project name! + return projectName.EndsWith(ksFwDataXmlFileExtension) ? projectName : + projectName + ksFwDataXmlFileExtension; + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the name of the DB4O data file, given a project name (basically just adds the + /// FW db4o file extension). + /// + /// Name of the project (not a filename). + /// ------------------------------------------------------------------------------------ + public static string GetDb4oDataFileName(string projectName) + { + Debug.Assert(Path.GetExtension(projectName) != ksFwDataDb4oFileExtension, + String.Format("There is a faint chance the user might have specified a real project name ending in {0} (in which case, sorry, but we're going to trim it off), but probably this is a programming error", ksFwDataDb4oFileExtension)); + // Do not use Path.ChangeExtension because it will strip off anything following a period in the project name! + return projectName.EndsWith(ksFwDataDb4oFileExtension) ? projectName : + projectName + ksFwDataDb4oFileExtension; + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the path without the root directory (i.e. make it un-rooted). + /// + /// ------------------------------------------------------------------------------------ + public static string GetPathWithoutRoot(string pathWithRoot) + { + string pathRoot = Path.GetPathRoot(pathWithRoot); + return pathWithRoot.Substring(pathRoot.Length); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Takes a windows path and returns it in the format which our backup zip files + /// stores them in. + /// + /// ------------------------------------------------------------------------------------ + public static string GetZipfileFormattedPath(string path) + { + StringBuilder strBldr = new StringBuilder(path); + string pathRoot = Path.GetPathRoot(path); + strBldr.Remove(0, pathRoot.Length); + // replace back slashes with forward slashes (for Windows) + if (!MiscUtils.IsUnix && !MiscUtils.IsMac) + strBldr.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); + return strBldr.ToString(); + } + } +} diff --git a/Src/FDO/FdoFileLockedException.cs b/Src/FDO/FdoFileLockedException.cs new file mode 100644 index 0000000000..dfedc0bb3c --- /dev/null +++ b/Src/FDO/FdoFileLockedException.cs @@ -0,0 +1,40 @@ +// Copyright (c) 2013-2014 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) + +using System; +using SIL.CoreImpl; + +namespace SIL.FieldWorks.FDO +{ + /// + /// Exception thrown when we try to open a project that is locked + /// + public class FdoFileLockedException : StartupException + { + /// ------------------------------------------------------------------------------------ + /// + /// Initializes a new instance of the class. + /// + /// The message. + /// ------------------------------------------------------------------------------------ + public FdoFileLockedException(string message) + : base(message) + { + } + + /// ------------------------------------------------------------------------------------ + /// + /// Initializes a new instance of the class. + /// + /// The message. + /// The inner exception. + /// True to report this error to the user, false otherwise + /// + /// ------------------------------------------------------------------------------------ + public FdoFileLockedException(string message, Exception innerException, bool fReportToUser) : + base(message, innerException, fReportToUser) + { + } + } +} \ No newline at end of file diff --git a/Src/FDO/FdoInterfaceAdditions.cs b/Src/FDO/FdoInterfaceAdditions.cs index ddd1c1765c..0acce21c96 100644 --- a/Src/FDO/FdoInterfaceAdditions.cs +++ b/Src/FDO/FdoInterfaceAdditions.cs @@ -13,12 +13,9 @@ using System; using System.Collections.Generic; using System.Xml; -using System.Windows.Forms; using System.Collections; -using System.Collections.Specialized; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainImpl; using SIL.FieldWorks.FDO.DomainServices; using SIL.Utils; @@ -863,17 +860,17 @@ IEnumerable AllAllomorphs /// /// Resets the homograph numbers for all entries. /// - void ResetHomographNumbers(ProgressBar progressBar); + void ResetHomographNumbers(IProgress progressBar); /// /// Allows user to convert LexEntryType to LexEntryInflType. /// - void ConvertLexEntryInflTypes(ProgressBar progressBar, IEnumerable list); + void ConvertLexEntryInflTypes(IProgress progressBar, IEnumerable list); /// /// Allows user to convert LexEntryInflType to LexEntryType. /// - void ConvertLexEntryTypes(ProgressBar progressBar, IEnumerable list); + void ConvertLexEntryTypes(IProgress progressBar, IEnumerable list); /// /// used when dumping the lexical database for the automated Parser /// @@ -1525,6 +1522,13 @@ string LongNameAdHoc /// /// bool CanDeleteIfSenseDeleted(ILexSense lexSense); + + /// + /// + /// + /// The ws. + /// + ITsString PartOfSpeechForWsTSS(int ws); } /// @@ -1652,11 +1656,20 @@ ICmPossibility MainPossibility } /// - /// If the recipient is a column in a chart that shouldn't be moved or deleted, report - /// accordingly and return true. Return false if OK to delete or move. + /// Gets a value indicating whether this is the default discourse template. /// - /// - bool CheckAndReportProtectedChartColumn(); + bool IsDefaultDiscourseTemplate { get; } + + /// + /// Return true if this or one of its children is in use as a Constituent chart column. + /// Most efficient to call this after checking that the root is a chart template. + /// + bool IsThisOrDescendantInUseAsChartColumn { get; } + + /// + /// Gets a value indicating whether this is the only text markup tag. + /// + bool IsOnlyTextMarkupTag { get; } /// ------------------------------------------------------------------------------------ /// @@ -4158,21 +4171,6 @@ string ParatextNotesProj set; } - /// ----------------------------------------------------------------------------------- - /// - /// Indicates whether the in-memory import projects/files are currently accessible from - /// this machine. - /// - /// A list of Paratext project IDs or file paths that - /// could not be found. - /// - /// For Paratext projects, this will only return true if all projects are accessible. - /// For Standard Format, this will return true if any of the files are accessible. - /// We think this might make sense, but we aren't sure why. - /// - /// ----------------------------------------------------------------------------------- - bool ImportProjectIsAccessible(out StringCollection thingsNotFound); - /// ------------------------------------------------------------------------------------ /// /// Gets whether to import back translations @@ -4342,20 +4340,6 @@ IScrImportFileInfo AddFile(string fileName, ImportDomain domain, string wsId, /// ------------------------------------------------------------------------------------ void RevertToSaved(); - /// ------------------------------------------------------------------------------------ - /// - /// Gets a list of books that exist for all of the files in this project. - /// - /// A List of integers representing 1-based canonical book numbers that exist - /// in any source represented by these import settings - /// If project is not a supported type - /// ------------------------------------------------------------------------------------ - List BooksForProject - { - get; - } - - /// ------------------------------------------------------------------------------------ /// /// Starting reference for the import; for now, we ignore the @@ -4391,16 +4375,6 @@ IVwStylesheet StyleSheet set; } - /// ------------------------------------------------------------------------------------ - /// - /// Sets the help file used in a message box if an error occurs. - /// - /// ------------------------------------------------------------------------------------ - string HelpFile - { - set; - } - /// ------------------------------------------------------------------------------------ /// /// Sets the Overlapping File Resolver @@ -4425,13 +4399,6 @@ bool Valid { get; } - - /// ------------------------------------------------------------------------------------ - /// - /// Sets the StartRef and EndRef based on the requested canonical book numbers. - /// - /// ------------------------------------------------------------------------------------ - void IncludeBooks(int startBook, int endBook, Paratext.ScrVers versification); } /// ---------------------------------------------------------------------------------------- @@ -5110,8 +5077,10 @@ bool HasDefaultFootnoteSettings /// one (which is probably the only one), or creates new settings if none exist. /// /// type of import type to find. + /// The default paragraph characters style name. + /// /// ------------------------------------------------------------------------------------ - IScrImportSet FindOrCreateDefaultImportSettings(TypeOfImport importType); + IScrImportSet FindOrCreateDefaultImportSettings(TypeOfImport importType, string defaultParaCharsStyleName, string stylesPath); /// ------------------------------------------------------------------------------------ /// diff --git a/Src/FDO/FdoInterfaceDeclarations.cs b/Src/FDO/FdoInterfaceDeclarations.cs index ddee48c781..30626a7e0e 100644 --- a/Src/FDO/FdoInterfaceDeclarations.cs +++ b/Src/FDO/FdoInterfaceDeclarations.cs @@ -7,7 +7,6 @@ using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.FDO.Infrastructure; -using SIL.FieldWorks.Common.FwUtils; // Add additional methods/properties to domain object in FdoInterfaceAdditions.cs. // Add new interfaces to the FdoInterfaceDeclarations file. diff --git a/Src/FDO/FdoNewerVersionException.cs b/Src/FDO/FdoNewerVersionException.cs new file mode 100644 index 0000000000..6992ba990f --- /dev/null +++ b/Src/FDO/FdoNewerVersionException.cs @@ -0,0 +1,21 @@ +// Copyright (c) 2013-2014 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) + +using SIL.CoreImpl; + +namespace SIL.FieldWorks.FDO +{ + /// + /// Exception thrown when we try to open a project that belongs to a newer version of FieldWorks than this. + /// + public class FdoNewerVersionException : StartupException + { + /// + /// Make one. + /// + public FdoNewerVersionException(string message) : base(message) + { + } + } +} \ No newline at end of file diff --git a/Src/FDO/FdoRepositoryInterfaceAdditions.cs b/Src/FDO/FdoRepositoryInterfaceAdditions.cs index fcc396b14a..9808695c06 100644 --- a/Src/FDO/FdoRepositoryInterfaceAdditions.cs +++ b/Src/FDO/FdoRepositoryInterfaceAdditions.cs @@ -12,10 +12,10 @@ using System; using System.Collections.Generic; -using System.Windows.Forms; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.FDO.DomainServices.SemanticDomainSearch; +using SIL.Utils; namespace SIL.FieldWorks.FDO { @@ -417,7 +417,7 @@ public partial interface ILexEntryRepository /// /// Clear the list of homograph information /// - void ResetHomographs(ProgressBar progressBar); + void ResetHomographs(IProgress progressBar); /// /// Return a list of all the homographs of the specified form. @@ -435,6 +435,26 @@ public partial interface ILexEntryRepository /// entries to see whether they are homographs. /// int HomographMorphOrder(FdoCache cache, IMoMorphType morphType); + + /// + /// Find the list of LexEntry objects which conceivably match the given wordform. + /// + /// + /// + /// + /// + /// + List FindEntriesForWordform(FdoCache cache, ITsString tssWf, IWfiAnalysis wfa, ref bool duplicates); + + /// ------------------------------------------------------------------------------------ + /// + /// Find wordform given a cache and the string. + /// + /// + /// + /// + /// ------------------------------------------------------------------------------------ + ILexEntry FindEntryForWordform(FdoCache cache, ITsString tssWf); } internal interface ILexEntryRepositoryInternal @@ -643,4 +663,12 @@ public partial interface IScrBookAnnotationsRepository /// The annotations for the requested book IScrBookAnnotations InstanceForBook(int bookId); } + + public partial interface ITextTagRepository + { + /// + /// Gets all text tags that reference the specified text markup tag. + /// + IEnumerable GetByTextMarkupTag(ICmPossibility tag); + } } diff --git a/Src/FDO/FieldDescription.cs b/Src/FDO/FieldDescription.cs index d28ed06d76..b23e327049 100644 --- a/Src/FDO/FieldDescription.cs +++ b/Src/FDO/FieldDescription.cs @@ -16,7 +16,6 @@ using System.Reflection; using System.Collections; using SIL.FieldWorks.FDO.DomainImpl; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.Infrastructure.Impl; namespace SIL.FieldWorks.FDO diff --git a/Src/FDO/IFdoDirectories.cs b/Src/FDO/IFdoDirectories.cs new file mode 100644 index 0000000000..d341680f3f --- /dev/null +++ b/Src/FDO/IFdoDirectories.cs @@ -0,0 +1,18 @@ +namespace SIL.FieldWorks.FDO +{ + /// + /// This interface is used by FDO to retrieve directories that it needs. + /// + public interface IFdoDirectories + { + /// + /// Gets the projects directory. + /// + string ProjectsDirectory { get; } + + /// + /// Gets the template directory. + /// + string TemplateDirectory { get; } + } +} diff --git a/Src/FDO/IFdoUI.cs b/Src/FDO/IFdoUI.cs new file mode 100644 index 0000000000..d4f499ec42 --- /dev/null +++ b/Src/FDO/IFdoUI.cs @@ -0,0 +1,157 @@ +// Copyright (c) 2013-2014 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) + +using System; +using System.ComponentModel; + +namespace SIL.FieldWorks.FDO +{ + /// + /// This interface abstracts the UI from FDO. + /// + public interface IFdoUI + { + /// + /// Gets the object that is used to invoke methods on the main UI thread. + /// + ISynchronizeInvoke SynchronizeInvoke { get; } + + /// + /// Check with user regarding conflicting changes + /// + /// True if user wishes to revert to saved state. False otherwise. + bool ConflictingSave(); + + /// + /// Inform the user of a lost connection + /// + /// True if user wishes to attempt reconnect. False otherwise. + bool ConnectionLost(); + + /// + /// Gets the last time that there was user activity. + /// + DateTime LastActivityTime { get; } + + /// + /// Check with user regarding which files to use + /// + /// + FileSelection ChooseFilesToUse(); + + /// + /// Check with user regarding restoring linked files in the project folder or original path + /// + /// True if user wishes to restore linked files in project folder. False to leave them in the original location. + bool RestoreLinkedFilesInProjectFolder(); + + /// + /// Cannot restore linked files to original path. + /// Check with user regarding restoring linked files in the project folder or not at all + /// + /// OkYes to restore to project folder, OkNo to skip restoring linked files, Cancel otherwise + YesNoCancel CannotRestoreLinkedFilesToOriginalLocation(); + + /// + /// Displays information to the user + /// + void DisplayMessage(MessageType type, string message, string caption, string helpTopic); + + /// + /// Show a dialog or output to the error log, as appropriate. + /// + /// the exception you want to report + /// set to true if the error is lethal, otherwise + /// false. + void ReportException(Exception error, bool isLethal); + + /// + /// Reports duplicate guids to the user + /// + /// The error text. + void ReportDuplicateGuids(string errorText); + + /// + /// Present a message to the user and allow the options to Retry or Cancel + /// + /// The message. + /// The caption. + /// True to retry. False otherwise + bool Retry(string msg, string caption); + + /// + /// Ask user if they wish to restore an XML project from a backup project file. + /// + /// The project path. + /// The backup path. + /// + bool OfferToRestore(string projectPath, string backupPath); + + /// + /// Exits the application. + /// + void Exit(); + } + + /// + /// Message type + /// + public enum MessageType + { + /// + /// Information message + /// + Info, + /// + /// Warning message + /// + Warning, + /// + /// Error message + /// + Error + } + + /// + /// File selection enum + /// + public enum FileSelection + { + /// + /// OK - Keep new files + /// + OkKeepNewer, + + /// + /// OK - Use older files + /// + OkUseOlder, + + /// + /// Cancel + /// + Cancel + } + + /// + /// Yes No Cancel enum + /// + public enum YesNoCancel + { + /// + /// Ok - Yes + /// + OkYes, + + /// + /// Ok - No + /// + OkNo, + + /// + /// Cancel + /// + Cancel + } +} diff --git a/Src/FDO/IOC/FdoServiceLocatorFactory.cs b/Src/FDO/IOC/FdoServiceLocatorFactory.cs index 6f659be17d..a713d613cd 100644 --- a/Src/FDO/IOC/FdoServiceLocatorFactory.cs +++ b/Src/FDO/IOC/FdoServiceLocatorFactory.cs @@ -14,7 +14,6 @@ using Microsoft.Practices.ServiceLocation; using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.Application; using SIL.FieldWorks.FDO.Application.Impl; using SIL.FieldWorks.FDO.DomainImpl; @@ -22,6 +21,7 @@ using SIL.FieldWorks.FDO.Infrastructure; using SIL.FieldWorks.FDO.Infrastructure.Impl; using SIL.FieldWorks.FDO.DomainServices.DataMigration; +using SIL.Utils; using StructureMap; using StructureMap.Configuration.DSL; using StructureMap.Pipeline; @@ -36,16 +36,20 @@ namespace SIL.FieldWorks.FDO.IOC internal sealed partial class FdoServiceLocatorFactory : IServiceLocatorBootstrapper { private readonly FDOBackendProviderType m_backendProviderType; + private readonly IFdoUI m_ui; + private readonly IFdoDirectories m_dirs; - /// ------------------------------------------------------------------------------------ /// /// Constructor /// /// Type of backend provider to create. - /// ------------------------------------------------------------------------------------ - internal FdoServiceLocatorFactory(FDOBackendProviderType backendProviderType) + /// The UI service. + /// The directories service. + internal FdoServiceLocatorFactory(FDOBackendProviderType backendProviderType, IFdoUI ui, IFdoDirectories dirs) { m_backendProviderType = backendProviderType; + m_ui = ui; + m_dirs = dirs; } #region Implementation of IServiceLocatorBootstrapper @@ -171,6 +175,12 @@ public IServiceLocator CreateServiceLocator() .LifecycleIs(new SingletonLifecycle()) .Use(); break; + case FDOBackendProviderType.kSharedXML: + registry + .For() + .LifecycleIs(new SingletonLifecycle()) + .Use(); + break; } // Register two additional interfaces of the BEP, which are injected into other services. registry @@ -233,7 +243,7 @@ public IServiceLocator CreateServiceLocator() registry .For() .LifecycleIs(new SingletonLifecycle()) - .Use(() => FwUtils.CreateWritingSystemManager()); + .Use(() => new PalasoWritingSystemManager {TemplateFolder = m_dirs.TemplateDirectory}); registry .For() .Use(c => (ILgWritingSystemFactory)c.GetInstance()); @@ -242,6 +252,14 @@ public IServiceLocator CreateServiceLocator() .For() .Use(c => c.GetInstance().Singleton); + registry + .For() + .Use(m_ui); + + registry + .For() + .Use(m_dirs); + // ================================================================================= // Don't add COM object to the registry. StructureMap does not properly release COM // objects when the container is disposed, it will crash when the container is diff --git a/Src/Common/FwUtils/IProjectIdentifier.cs b/Src/FDO/IProjectIdentifier.cs similarity index 92% rename from Src/Common/FwUtils/IProjectIdentifier.cs rename to Src/FDO/IProjectIdentifier.cs index ee56f649b7..a7be4d70bb 100644 --- a/Src/Common/FwUtils/IProjectIdentifier.cs +++ b/Src/FDO/IProjectIdentifier.cs @@ -7,7 +7,7 @@ using System; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.FieldWorks.FDO { #region FDOBackendProviderType enum /// @@ -84,6 +84,19 @@ public enum FDOBackendProviderType /// /// db4oClientServer kDb4oClientServer = 103, + + /// + /// A FieldWorks XML file that can be accessed by multiple local clients. + /// + kSharedXML = 104, + + /// + /// A FieldWorks XML file that can be accessed by multiple local clients. + /// This has an actual backend data store on the hard drive, but does not use a real + /// repository of writing systems. There is probably no legitimate reason to use this + /// except for testing the shared XML BEP. + /// + kSharedXMLWithMemoryOnlyWsMgr = 105 }; #endregion diff --git a/Src/FDO/IStylesheet.cs b/Src/FDO/IStylesheet.cs index 3f49bae814..0cadde32b0 100644 --- a/Src/FDO/IStylesheet.cs +++ b/Src/FDO/IStylesheet.cs @@ -1,8 +1,5 @@ using System; -using System.Collections.Generic; using System.Drawing; -using System.Linq; -using System.Text; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.FDO.DomainServices; diff --git a/Src/FDO/Infrastructure/BackendStartupParameter.cs b/Src/FDO/Infrastructure/BackendStartupParameter.cs index 481a175a9b..fe515de7c8 100644 --- a/Src/FDO/Infrastructure/BackendStartupParameter.cs +++ b/Src/FDO/Infrastructure/BackendStartupParameter.cs @@ -1,5 +1,3 @@ -using SIL.FieldWorks.Common.FwUtils; - namespace SIL.FieldWorks.FDO.Infrastructure { /// diff --git a/Src/FDO/Infrastructure/IPersistenceStrategyInterfaces.cs b/Src/FDO/Infrastructure/IPersistenceStrategyInterfaces.cs index 0d604ccfb2..80184bd6f9 100644 --- a/Src/FDO/Infrastructure/IPersistenceStrategyInterfaces.cs +++ b/Src/FDO/Infrastructure/IPersistenceStrategyInterfaces.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using SIL.Utils; -using SIL.FieldWorks.Common.FwUtils; namespace SIL.FieldWorks.FDO.Infrastructure { @@ -43,7 +42,8 @@ public interface IDataSetup : IFWDisposable /// True to bootstrap the existing system, false to skip that /// step /// The progress dialog box - void StartupExtantLanguageProject(IProjectIdentifier projectId, bool fBootstrapSystem, IThreadedProgress progressDlg); + /// True if the application forbids data migration + void StartupExtantLanguageProject(IProjectIdentifier projectId, bool fBootstrapSystem, IThreadedProgress progressDlg, bool forbidDataMigration); /// /// Create a new LanguageProject for the BEP with the given parameters. @@ -261,19 +261,6 @@ internal interface IDataStorer : IFWDisposable /// internal interface IClientServerDataManager { - /// - /// Get any changes we haven't previously seen which other clients have made to our database. - /// - /// New objects created on the other client - /// Object we know about modified on the other client. - /// objects we know about deleted by the other client. - /// if true, we intend to Commit; if there are no conflicts, lock - /// until commit. (If there are conflicts, we don't lock till we reconciled.) - /// true if there are any foreign changes - bool GetUnseenForeignChanges(out List foreignNewbies, - out List foreignDirtballs, - out List foreignGoners, bool fGetCommitLock); - /// /// Return a string (typically at or near shutdown) which may be passed back to NewObjectsSinceVersion. /// diff --git a/Src/FDO/Infrastructure/IUnitOfWorkService.cs b/Src/FDO/Infrastructure/IUnitOfWorkService.cs index 90ef6a7a10..a13b98ec18 100644 --- a/Src/FDO/Infrastructure/IUnitOfWorkService.cs +++ b/Src/FDO/Infrastructure/IUnitOfWorkService.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; +using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.Infrastructure.Impl; namespace SIL.FieldWorks.FDO.Infrastructure @@ -261,5 +261,21 @@ void RegisterVirtualAsModified(ICmObject dirtball, int modifiedFlid, int ws, ITs /// void GatherChanges(HashSet newbies, HashSet dirtballs, HashSet goners); + + /// + /// Creates a change reconciler. + /// + /// The foreign newbies. + /// The foreign dirtballs. + /// The foreign goners. + /// + IReconcileChanges CreateReconciler(List foreignNewbies, + List foreignDirtballs, List foreignGoners); + + /// + /// Notifies the service of conflicting changes. + /// + /// The pending reconciliation. + void ConflictingChanges(IReconcileChanges pendingReconciliation); } } diff --git a/Src/FDO/Infrastructure/Impl/ChangeReconciler.cs b/Src/FDO/Infrastructure/Impl/ChangeReconciler.cs index 181cfa8fd6..15303d20ad 100644 --- a/Src/FDO/Infrastructure/Impl/ChangeReconciler.cs +++ b/Src/FDO/Infrastructure/Impl/ChangeReconciler.cs @@ -5,7 +5,6 @@ using System.Xml.Linq; using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainImpl; using SIL.Utils; @@ -655,6 +654,16 @@ public void GatherChanges(HashSet newbies, HashSet foreignNewbies, List foreignDirtballs, List foreignGoners) + { + throw new NotImplementedException(); + } + + public void ConflictingChanges(IReconcileChanges pendingReconciliation) + { + throw new NotImplementedException(); + } } /// diff --git a/Src/FDO/Infrastructure/Impl/ClientServerBackendProvider.cs b/Src/FDO/Infrastructure/Impl/ClientServerBackendProvider.cs index ea6cfdfa66..bc1bfde669 100644 --- a/Src/FDO/Infrastructure/Impl/ClientServerBackendProvider.cs +++ b/Src/FDO/Infrastructure/Impl/ClientServerBackendProvider.cs @@ -9,7 +9,6 @@ /* This class may well replace ClientServerBackend, which currently is used only by the MySQL classes */ -using System.Collections.Generic; using SIL.FieldWorks.FDO.DomainServices.DataMigration; namespace SIL.FieldWorks.FDO.Infrastructure.Impl @@ -20,17 +19,11 @@ protected ClientServerBackendProvider(FdoCache cache, IdentityMap identityMap, ICmObjectSurrogateFactory surrogateFactory, IFwMetaDataCacheManagedInternal mdc, - IDataMigrationManager dataMigrationManager) : base(cache, identityMap, surrogateFactory, mdc, dataMigrationManager) + IDataMigrationManager dataMigrationManager, + IFdoUI ui, IFdoDirectories dirs) : base(cache, identityMap, surrogateFactory, mdc, dataMigrationManager, ui, dirs) { } - /// - /// Get changes we haven't seen. - /// - public abstract bool GetUnseenForeignChanges(out List foreignNewbies, - out List foreignDirtballs, - out List foreignGoners, bool fGetCommitLock); - public abstract string VersionStamp { get; } public abstract bool NewObjectsSinceVersion(string versionStamp, string classname); } diff --git a/Src/FDO/Infrastructure/Impl/CmObjectSurrogate.cs b/Src/FDO/Infrastructure/Impl/CmObjectSurrogate.cs index c056303c89..a34b553f91 100644 --- a/Src/FDO/Infrastructure/Impl/CmObjectSurrogate.cs +++ b/Src/FDO/Infrastructure/Impl/CmObjectSurrogate.cs @@ -7,7 +7,6 @@ using System.Linq; using System.Reflection; using System.Text; -using System.Windows.Forms; using System.Xml.Linq; using SIL.Utils; using System.Threading; @@ -548,11 +547,9 @@ ICmObject ICmObjectOrSurrogate.Object const int nLines = 40; if (lines.Length > nLines) msg = String.Join("\n", lines.Take(nLines).ToArray()) + "\n..."; - m_cache.ThreadHelper.Invoke(() => - { - MessageBox.Show(null, msg, Strings.ksErrorCaption, MessageBoxButtons.OK, MessageBoxIcon.Error); - ErrorReporter.ReportException(new Exception(fullMsg, e), null, null, null, true); - }); + var userAction = m_cache.ServiceLocator.GetInstance(); + userAction.DisplayMessage(MessageType.Error, msg, Strings.ksErrorCaption, null); + userAction.ReportException(new Exception(fullMsg, e), true); } return m_object; } diff --git a/Src/FDO/Infrastructure/Impl/CommitLogMetadata.cs b/Src/FDO/Infrastructure/Impl/CommitLogMetadata.cs new file mode 100644 index 0000000000..211e714aac --- /dev/null +++ b/Src/FDO/Infrastructure/Impl/CommitLogMetadata.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using ProtoBuf; + +namespace SIL.FieldWorks.FDO.Infrastructure.Impl +{ + /// + /// Contains all of the commit log metadata for the shared XML backend. This + /// class is serialized to a memory mapped file using protobuf-net. + /// + [ProtoContract] + internal class CommitLogMetadata + { + public CommitLogMetadata() + { + Peers = new Dictionary(); + } + + /// + /// The current commit generation of the commit log. + /// + [ProtoMember(1)] + public int CurrentGeneration; + + /// + /// The current commit generation of the XML file. + /// + [ProtoMember(2)] + public int FileGeneration; + + /// + /// The offset into the memory mapped file where the commit log starts. + /// + [ProtoMember(3)] + public int LogOffset; + + /// + /// The length of the commit log. The length includes padding. + /// + [ProtoMember(4)] + public int LogLength; + + /// + /// The amount of padding at the end of the memory mapped file if the commit log wraps + /// around the file. + /// + [ProtoMember(5)] + public int Padding; + + /// + /// All of the peers that are currently accessing the XML file. + /// + [ProtoMember(6)] + public Dictionary Peers; + + /// + /// The GUID of the master peer that is reponsible for reading and writing to the XML file. + /// + [ProtoMember(7)] + public Guid Master; + } + + /// + /// A shared XML backend peer. + /// + [ProtoContract] + internal class CommitLogPeer + { + /// + /// The commit generation that the peer has seen. + /// + [ProtoMember(1)] + public int Generation; + + /// + /// The peer's process ID. + /// + [ProtoMember(2)] + public int ProcessID; + } +} diff --git a/Src/FDO/Infrastructure/Impl/CommitLogRecord.cs b/Src/FDO/Infrastructure/Impl/CommitLogRecord.cs new file mode 100644 index 0000000000..9095883e7c --- /dev/null +++ b/Src/FDO/Infrastructure/Impl/CommitLogRecord.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using ProtoBuf; + +namespace SIL.FieldWorks.FDO.Infrastructure.Impl +{ + /// + /// A record that is used by the shared XML backend to record all information for a commit so that peers + /// can update their FDO instance appropriately. These records are serialized to the commit log memory + /// mapped file using protobuf-net. + /// + [ProtoContract] + internal struct CommitLogRecord + { + /// + /// Corresponds to WriteGeneration in CmObjectSurrogate. Orders all CommitData absolutely, since each + /// Commit gets a fresh WriteGeneration. + /// + [ProtoMember(1)] + public int WriteGeneration; + + /// + /// A guid unique to one particular peer; used by each peer to eliminate its own commits from queries. + /// + [ProtoMember(2)] + public Guid Source; + + /// + /// Our IDs of the objects that were added. + /// + [ProtoMember(3)] + public List ObjectsAdded; + + /// + /// Our IDs of the objects that were modified. + /// + [ProtoMember(4)] + public List ObjectsUpdated; + + /// + /// Our IDs of the objects that were deleted. + /// + [ProtoMember(5)] + public List ObjectsDeleted; + } +} diff --git a/Src/FDO/Infrastructure/Impl/Db4oClientServerBackendProvider.cs b/Src/FDO/Infrastructure/Impl/Db4oClientServerBackendProvider.cs index c4b7cd5cae..f3d81fcdb3 100644 --- a/Src/FDO/Infrastructure/Impl/Db4oClientServerBackendProvider.cs +++ b/Src/FDO/Infrastructure/Impl/Db4oClientServerBackendProvider.cs @@ -16,7 +16,6 @@ using System.Net.Sockets; using System.Runtime.Remoting; using System.Threading; -using System.Windows.Forms; using Db4objects.Db4o; using Db4objects.Db4o.Config; using Db4objects.Db4o.Config.Encoding; @@ -24,7 +23,7 @@ using Db4objects.Db4o.CS.Config; using Db4objects.Db4o.Linq; using FwRemoteDatabaseConnector; -using SIL.FieldWorks.Common.FwUtils; +using SIL.CoreImpl; using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.FDO.DomainServices.DataMigration; using SIL.Utils; @@ -85,13 +84,17 @@ internal class Db4oClientServerBackendProvider : ClientServerBackendProvider /// /// /// + /// + /// public Db4oClientServerBackendProvider( FdoCache cache, IdentityMap identityMap, ICmObjectSurrogateFactory surrogateFactory, IFwMetaDataCacheManagedInternal mdc, - IDataMigrationManager dataMigrationManager) - : base(cache, identityMap, surrogateFactory, mdc, dataMigrationManager) + IDataMigrationManager dataMigrationManager, + IFdoUI ui, + IFdoDirectories dirs) + : base(cache, identityMap, surrogateFactory, mdc, dataMigrationManager, ui, dirs) { } @@ -239,7 +242,7 @@ protected override int StartupInternal(int currentModelVersion) } catch (SocketException e) { - throw new FwStartupException(string.Format(Strings.ksCannotConnectToServer, "FwRemoteDatabaseConnectorService"), e); + throw new StartupException(string.Format(Strings.ksCannotConnectToServer, "FwRemoteDatabaseConnectorService"), e); } finally { @@ -252,13 +255,13 @@ protected override int StartupInternal(int currentModelVersion) /// /// Get changes we haven't seen. (This has a side effect of updating the record of which ones HAVE been seen.) - /// Returns true if there are any unseen foreign changes. + /// This method assumes that the commit lock has already been obtained. Returns true if there are any unseen foreign changes. /// [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", Justification="Ext() returns a reference")] - public override bool GetUnseenForeignChanges(out List foreignNewbies, + private bool GetUnseenForeignChanges(out List foreignNewbies, out List foreignDirtballs, - out List foreignGoners, bool fWaitForCommitLock) + out List foreignGoners) { foreignNewbies = new List(); foreignDirtballs = new List(); @@ -275,8 +278,6 @@ public override bool GetUnseenForeignChanges(out List foreig try { - if (!GetCommitLock(fWaitForCommitLock)) - return false; var unseenCommits = (from CommitData cd in m_dbStore where cd.WriteGeneration > m_lastWriteGenerationSeen && cd.Source != m_mySourceTag select cd).ToList(); @@ -346,17 +347,13 @@ public override bool GetUnseenForeignChanges(out List foreig { if (ResumeDb4oConnectionAskingUser()) - return GetUnseenForeignChanges(out foreignNewbies, out foreignDirtballs, out foreignGoners, fWaitForCommitLock); + return GetUnseenForeignChanges(out foreignNewbies, out foreignDirtballs, out foreignGoners); StopClient(); // get back to a consistant state. m_lastWriteGenerationSeen = startingWriteGeneration; throw new NonRecoverableConnectionLostException(); } - finally - { - ReleaseCommitLock(); - } } private void ReleaseCommitLock() @@ -389,14 +386,34 @@ public override bool Commit( } } - IEnumerable cfiList; - bool anyModifiedCustomFields; - if (!HaveAnythingToCommit(newbies, dirtballs, goners, out anyModifiedCustomFields, out cfiList)) + if (!GetCommitLock(newbies.Count != 0 || dirtballs.Count != 0 || goners.Count != 0)) return true; - - GetCommitLock(true); try { + List foreignNewbies; + List foreignDirtballs; + List foreignGoners; + if (GetUnseenForeignChanges(out foreignNewbies, out foreignDirtballs, out foreignGoners)) + { + IUnitOfWorkService uowService = ((IServiceLocatorInternal) m_cache.ServiceLocator).UnitOfWorkService; + IReconcileChanges reconciler = uowService.CreateReconciler(foreignNewbies, foreignDirtballs, foreignGoners); + if (reconciler.OkToReconcileChanges()) + { + reconciler.ReconcileForeignChanges(); + // And continue looping, in case there are by now MORE foreign changes! + } + else + { + uowService.ConflictingChanges(reconciler); + return true; + } + } + + IEnumerable cfiList; + bool anyModifiedCustomFields; + if (!HaveAnythingToCommit(newbies, dirtballs, goners, out anyModifiedCustomFields, out cfiList)) + return true; + var commitData = new CommitData { Source = m_mySourceTag }; int objectAddedIndex = 0; commitData.ObjectsDeleted = (from item in goners select item.Guid).ToArray(); @@ -517,10 +534,7 @@ private bool GetCommitLock(bool fWaitForCommitLock) while (!m_dbStore.Ext().SetSemaphore(kCommitLock, 3000)) { if (fWaitForCommitLock) - { - ThreadHelper.ShowMessageBox(null, Strings.ksOtherClientsAreWriting, Strings.ksShortDelayCaption, - MessageBoxButtons.OK, MessageBoxIcon.None); - } + m_ui.DisplayMessage(MessageType.Info, Strings.ksOtherClientsAreWriting, Strings.ksShortDelayCaption, null); else return false; } @@ -555,7 +569,7 @@ protected override void CreateInternal() } catch (SocketException e) { - throw new FwStartupException(string.Format(Strings.ksCannotConnectToServer, "FwRemoteDatabaseConnectorService"), e); + throw new StartupException(string.Format(Strings.ksCannotConnectToServer, "FwRemoteDatabaseConnectorService"), e); } catch (Exception err) { @@ -581,7 +595,7 @@ public override bool RenameDatabase(string sNewProjectName) if (!ProjectId.IsLocal) throw new InvalidOperationException("Renaming a database needs to be done on the local machine"); - string sNewProjectFolder = Path.Combine(DirectoryFinder.ProjectsDirectory, sNewProjectName); + string sNewProjectFolder = Path.Combine(m_dirs.ProjectsDirectory, sNewProjectName); if (FileUtils.NonEmptyDirectoryExists(sNewProjectFolder)) return false; @@ -603,9 +617,9 @@ public override bool RenameDatabase(string sNewProjectName) return false; } - string oldProjectFolder = Path.Combine(DirectoryFinder.ProjectsDirectory, ProjectId.Name); - string oldFile = Path.Combine(sNewProjectFolder, DirectoryFinder.GetDb4oDataFileName(ProjectId.Name)); - string newFile = Path.Combine(sNewProjectFolder, DirectoryFinder.GetDb4oDataFileName(sNewProjectName)); + string oldProjectFolder = Path.Combine(m_dirs.ProjectsDirectory, ProjectId.Name); + string oldFile = Path.Combine(sNewProjectFolder, FdoFileHelper.GetDb4oDataFileName(ProjectId.Name)); + string newFile = Path.Combine(sNewProjectFolder, FdoFileHelper.GetDb4oDataFileName(sNewProjectName)); try { @@ -619,7 +633,6 @@ public override bool RenameDatabase(string sNewProjectName) try { Directory.Move(sNewProjectFolder, oldProjectFolder); } catch { } - ; return false; } @@ -679,19 +692,19 @@ private void RequestDatabaseStart() if (!info.StartServer(ProjectId.Name, out port, out exceptionFromStartingServer)) { // failed to start server - throw new FwStartupException(String.Format(Strings.ksFailedToStartServer, + throw new StartupException(String.Format(Strings.ksFailedToStartServer, exceptionFromStartingServer.Message), exceptionFromStartingServer); } m_port = port; } catch (SocketException e) { - throw new FwStartupException(string.Format(Strings.ksCannotConnectToServer, "FwRemoteDatabaseConnectorService"), e); + throw new StartupException(string.Format(Strings.ksCannotConnectToServer, "FwRemoteDatabaseConnectorService"), e); } catch (RemotingException e) { // on Mono we get a RemotingException instead of a SocketException - throw new FwStartupException(string.Format(Strings.ksCannotConnectToServer, "FwRemoteDatabaseConnectorService"), e); + throw new StartupException(string.Format(Strings.ksCannotConnectToServer, "FwRemoteDatabaseConnectorService"), e); } } @@ -741,24 +754,18 @@ private bool ResumeDb4oConnectionAskingUser() return true; } - // It's useful to have this MessageBox handling here, as it allows reconnecting a dropped connection. - // Handling this at the application layer would require either recreating FdoCache or - // adding interface methods to expose resuming a dropped connection. - using (var dlg = new ConnectionLostDlg()) + while (m_ui.ConnectionLost()) { - while (dlg.ShowDialog() == DialogResult.Yes) - { - // if re-connection failed allow user to keep retrying as many times as they want. - if (ResumeDb4oConnection()) - break; - } + // if re-connection failed allow user to keep retrying as many times as they want. + if (ResumeDb4oConnection()) + break; + } - if (m_dbStore == null) - System.Windows.Forms.Application.Exit(); + if (m_dbStore == null) + m_ui.Exit(); - // return true if connection re-established - return (m_dbStore != null); - } + // return true if connection re-established + return (m_dbStore != null); } internal static Db4oServerInfo GetDb4OServerInfo(string host, int port) diff --git a/Src/FDO/Infrastructure/Impl/Db4oServerInfo.cs b/Src/FDO/Infrastructure/Impl/Db4oServerInfo.cs index 580c284f20..f67aeffc70 100644 --- a/Src/FDO/Infrastructure/Impl/Db4oServerInfo.cs +++ b/Src/FDO/Infrastructure/Impl/Db4oServerInfo.cs @@ -19,10 +19,8 @@ using System.Security; using System.Threading; using Db4objects.Db4o; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.Infrastructure.Impl; -using SIL.FieldWorks.Resources; using SIL.FieldWorks.FDO.DomainServices; using System.Runtime.Remoting.Channels; using SIL.Utils; @@ -34,8 +32,6 @@ namespace FwRemoteDatabaseConnector /// public class Db4oServerInfo : MarshalByRefObject { - private const string ksSharedProjectKey = "ProjectShared"; - /// /// Stores the filenames of all the db40 Servers /// @@ -76,10 +72,6 @@ protected struct RunningServerInfo /// public Db4oServerInfo() { - // We need FieldWorks here to get the correct registry key HKLM\Software\SIL\FieldWorks. - // The default without this would be HKLM\Software\SIL\SIL FieldWorks, - // which breaks FwRemoteDatabaseConnectorService.exe. - SIL.Utils.RegistryHelper.ProductName = "FieldWorks"; RemotingServer.ServerObject = this; } @@ -87,17 +79,19 @@ internal void PopulateServerList() { m_allServers = new List(); - if (!Directory.Exists(DirectoryFinder.ProjectsDirectory)) - throw new DirectoryNotFoundException(String.Format(Strings.ksWarningProjectFolderNotFoundOnServer, DirectoryFinder.ProjectsDirectory)); + string projectsDir = RemotingServer.Directories.ProjectsDirectory; + + if (!Directory.Exists(projectsDir)) + throw new DirectoryNotFoundException(String.Format(Strings.ksWarningProjectFolderNotFoundOnServer, projectsDir)); - string[] files = Directory.GetFiles(DirectoryFinder.ProjectsDirectory, "*" + FwFileExtensions.ksFwDataDb4oFileExtension); + string[] files = Directory.GetFiles(projectsDir, "*" + FdoFileHelper.ksFwDataDb4oFileExtension); m_allServers.AddRange(files); // search sub dirs - string[] dirs = Directory.GetDirectories(DirectoryFinder.ProjectsDirectory); + string[] dirs = Directory.GetDirectories(projectsDir); foreach (var dir in dirs) { - files = Directory.GetFiles(dir, "*" + FwFileExtensions.ksFwDataDb4oFileExtension); + files = Directory.GetFiles(dir, "*" + FdoFileHelper.ksFwDataDb4oFileExtension); m_allServers.AddRange(files); } } @@ -167,7 +161,7 @@ public bool IsLocalHost(string hostname) public string[] ListServers() { // Only show Projects/Servers if Projects are shared. - if (!AreProjectsShared_Internal) + if (!RemotingServer.SharedProjectsGetter()) return Enumerable.Empty().ToArray(); if (m_allServers == null) @@ -195,8 +189,8 @@ public string[] ListRunningServers() /// ------------------------------------------------------------------------------------ public void CreateServerFile(string projectName) { - string projectDir = Path.Combine(DirectoryFinder.ProjectsDirectory, projectName); - string newFilename = Path.Combine(projectDir, DirectoryFinder.GetDb4oDataFileName(projectName)); + string projectDir = Path.Combine(RemotingServer.Directories.ProjectsDirectory, projectName); + string newFilename = Path.Combine(projectDir, FdoFileHelper.GetDb4oDataFileName(projectName)); // Ensure directory exists. Directory.CreateDirectory(projectDir); @@ -358,7 +352,7 @@ public bool StopServer(string projectName) public bool AreProjectShared() { EnsureClientIsLocalHost(); - return AreProjectsShared_Internal; + return RemotingServer.SharedProjectsGetter(); } /// ------------------------------------------------------------------------------------ @@ -373,64 +367,7 @@ public bool AreProjectShared() public void ShareProjects(bool enableSharingOfProjects) { EnsureClientIsLocalHost(); - AreProjectsShared_Internal = enableSharingOfProjects; - } - - /// ------------------------------------------------------------------------------------ - /// - /// Gets a value indicating whether projects are shared. - /// - /// Internal method to facilitate testing. Tests can't use public setter - /// because that would actually do the conversion. Since this value is used only - /// temporarily during a test, there is no point in trying to set it on HKLM; - /// that only causes confusion if tests are sometimes run with admin privilege - /// and sometimes not. - /// ------------------------------------------------------------------------------------ - internal static bool AreProjectsShared_Internal - { - get - { - bool result; - object value; - RegistryHelper.RegEntryExists(FwRegistryHelper.FieldWorksRegistryKey, string.Empty, ksSharedProjectKey, - out value); - if(value == null) - { - value = MigrateVersion7Value(); - } - return (bool.TryParse((string)value, out result) && result); - } - set - { - FwRegistryHelper.FieldWorksRegistryKey.SetValue( - ksSharedProjectKey, value); - } - } - - /// - /// Migrate the ProjectShared value stored in HKLM in version 7 into the HKCU (.Default since this will be run as system) - /// - /// - private static object MigrateVersion7Value() - { - // Guard for some broken Windows machines having trouble accessing HKLM (LT-15158). - var hklm = FwRegistryHelper.LocalMachineHive; - if(hklm != null) - { - using(var oldProjectSharedSettingLocation = hklm.OpenSubKey(@"SOFTWARE\SIL\FieldWorks\7.0")) - using(var newProjectSharedSettingLocation = FwRegistryHelper.FieldWorksRegistryKey) - { - object projectSharedValue; - if(oldProjectSharedSettingLocation != null && - RegistryHelper.RegEntryExists(oldProjectSharedSettingLocation, string.Empty, @"ProjectShared", - out projectSharedValue)) - { - FwRegistryHelper.FieldWorksRegistryKey.SetValue(@"ProjectShared", projectSharedValue); - return projectSharedValue; - } - } - } - return @"False"; + RemotingServer.SharedProjectsSetter(enableSharingOfProjects); } /// @@ -552,16 +489,35 @@ public static Db4oServerInfo ServerObject } /// + /// This delegate is used to retrieve the projects directory. + /// + internal static IFdoDirectories Directories { get; private set; } + + /// + /// Gets the shared projects getter. + /// + internal static Func SharedProjectsGetter { get; private set; } + + /// + /// Gets the shared projects setter. + /// + internal static Action SharedProjectsSetter { get; private set; } + + /// /// Start an instance of the .NET remoting server. /// [SuppressMessage("Gendarme.Rules.Portability", "MonoCompatibilityReviewRule", Justification="Added TODO-Linux")] - public static void Start() + public static void Start(string remotingTcpServerConfigFile, IFdoDirectories dirs, Func sharedProjectsGetter, Action sharedProjectsSetter) { // check if we are already running. if (ServerObject != null) return; + Directories = dirs; + SharedProjectsGetter = sharedProjectsGetter; + SharedProjectsSetter = sharedProjectsSetter; + if (ChannelServices.RegisteredChannels.Length > 0) { var tcpChannel = ChannelServices.GetChannel("tcp"); @@ -583,7 +539,7 @@ public static void Start() // TODO: currently running with no security // TODO-Linux: security support has not been implemented in Mono - RemotingConfiguration.Configure(DirectoryFinder.RemotingTcpServerConfigFile, false); + RemotingConfiguration.Configure(remotingTcpServerConfigFile, false); } /// @@ -593,7 +549,10 @@ public static void Start() public static void Stop() { if (ServerObject != null) + { ServerObject.ShutdownAllServers(); + ServerObject = null; + } } } } diff --git a/Src/FDO/Infrastructure/Impl/FDOBackendProvider.cs b/Src/FDO/Infrastructure/Impl/FDOBackendProvider.cs index b6be969385..87a683159f 100644 --- a/Src/FDO/Infrastructure/Impl/FDOBackendProvider.cs +++ b/Src/FDO/Infrastructure/Impl/FDOBackendProvider.cs @@ -15,7 +15,6 @@ using System.Threading; using SIL.CoreImpl; using SIL.CoreImpl.Properties; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.FDO.DomainServices.DataMigration; using SIL.Utils; @@ -36,22 +35,27 @@ internal abstract partial class FDOBackendProvider : IDataSetup, IDataReader, ID protected readonly FdoCache m_cache; protected readonly IFwMetaDataCacheManagedInternal m_mdcInternal; private readonly IDataMigrationManager m_dataMigrationManager; + protected readonly IFdoUI m_ui; protected readonly Dictionary m_extantCustomFields = new Dictionary(); protected int m_modelVersionOverride = ModelVersion; private readonly List m_loadDomainThreads = new List(); private readonly object m_syncRoot = new object(); protected volatile bool m_stopLoadDomain; + protected readonly IFdoDirectories m_dirs; /// /// /// protected FDOBackendProvider(FdoCache cache, IdentityMap identityMap, - ICmObjectSurrogateFactory surrogateFactory, IFwMetaDataCacheManagedInternal mdc, IDataMigrationManager dataMigrationManager) + ICmObjectSurrogateFactory surrogateFactory, IFwMetaDataCacheManagedInternal mdc, IDataMigrationManager dataMigrationManager, + IFdoUI ui, IFdoDirectories dirs) { if (cache == null) throw new ArgumentNullException("cache"); if (identityMap == null) throw new ArgumentNullException("identityMap"); if (surrogateFactory == null) throw new ArgumentNullException("surrogateFactory"); if (dataMigrationManager == null) throw new ArgumentNullException("dataMigrationManager"); + if (ui == null) throw new ArgumentNullException("ui"); + if (dirs == null) throw new ArgumentNullException("dirs"); m_cache = cache; m_cache.Disposing += OnCacheDisposing; @@ -59,6 +63,8 @@ protected FDOBackendProvider(FdoCache cache, IdentityMap identityMap, m_surrogateFactory = surrogateFactory; m_mdcInternal = mdc; m_dataMigrationManager = dataMigrationManager; + m_ui = ui; + m_dirs = dirs; } @@ -344,16 +350,19 @@ protected static string GetFlidTypeAsString(CellarPropertyType flidType) /// /// Protected for testing (see MockXMLBackendProvider) /// - protected virtual void StartupInternalWithDataMigrationIfNeeded(IThreadedProgress progressDlg) + protected virtual void StartupInternalWithDataMigrationIfNeeded(IThreadedProgress progressDlg, bool forbidDataMigration) { var currentDataStoreVersion = StartupInternal(ModelVersion); if (currentDataStoreVersion > ModelVersion) - throw new FwNewerVersionException(Properties.Resources.kstidProjectIsForNewerVersionOfFw); + throw new FdoNewerVersionException(Properties.Resources.kstidProjectIsForNewerVersionOfFw); if (currentDataStoreVersion == ModelVersion) return; + if (forbidDataMigration) + throw new FdoDataMigrationForbiddenException(); + // See if migration involves real data migration(s). // If it does not, just update the stored version number, and keep going. if (!m_dataMigrationManager.NeedsRealMigration(currentDataStoreVersion, ModelVersion)) @@ -394,7 +403,7 @@ private HashSet DoMigrationBasics(int currentDataStoreVers currentDataStoreVersion, dtos, (IFwMetaDataCacheManaged)m_mdcInternal, - ProjectId.ProjectFolder); + ProjectId.ProjectFolder, m_dirs); m_dataMigrationManager.PerformMigration(dtoRepository, ModelVersion, progressDlg); @@ -542,13 +551,12 @@ private void InitializeWritingSystemManager() if (UseMemoryWritingSystemManager || string.IsNullOrEmpty(ProjectId.SharedProjectFolder)) return; - var globalStore = new GlobalFileWritingSystemStore(DirectoryFinder.GlobalWritingSystemStoreDirectory); - string storePath = Path.Combine(ProjectId.SharedProjectFolder, DirectoryFinder.ksWritingSystemsDir); - var wsManager = (PalasoWritingSystemManager)m_cache.ServiceLocator.WritingSystemManager; + var globalStore = new GlobalFileWritingSystemStore(); + string storePath = Path.Combine(ProjectId.SharedProjectFolder, FdoFileHelper.ksWritingSystemsDir); + var wsManager = (PalasoWritingSystemManager) m_cache.ServiceLocator.WritingSystemManager; wsManager.GlobalWritingSystemStore = globalStore; wsManager.LocalWritingSystemStore = new LocalFileWritingSystemStore(storePath, globalStore); wsManager.LocalWritingSystemStore.LocalKeyboardSettings = Settings.Default.LocalKeyboards; - wsManager.TemplateFolder = DirectoryFinder.TemplateDirectory; // Writing systems are not "modified" when the system is freshly-initialized foreach (var ws in wsManager.LocalWritingSystemStore.AllWritingSystems) @@ -618,9 +626,9 @@ public void LoadDomain(BackendBulkLoadDomain bulkLoadDomain) ReconstituteObjectsFor(ScrTxtParaTags.kClassId); ReconstituteObjectsFor(CmTranslationTags.kClassId); ReconstituteObjectsFor(ScrFootnoteTags.kClassId); - ReconstituteObjectsFor(ChkTermTags.kClassId); - ReconstituteObjectsFor(ChkRefTags.kClassId); - ReconstituteObjectsFor(ChkRenderingTags.kClassId); + ReconstituteObjectsFor(ChkTermTags.kClassId); + ReconstituteObjectsFor(ChkRefTags.kClassId); + ReconstituteObjectsFor(ChkRenderingTags.kClassId); break; case BackendBulkLoadDomain.Text: lock (m_syncRoot) @@ -733,30 +741,19 @@ public bool UseMemoryWritingSystemManager /// True to bootstrap the existing system, false to skip /// that step /// The progress dialog box + /// True if the application forbids a data migration /// ------------------------------------------------------------------------------------ public void StartupExtantLanguageProject(IProjectIdentifier projectId, bool fBootstrapSystem, - IThreadedProgress progressDlg) + IThreadedProgress progressDlg, bool forbidDataMigration) { ProjectId = projectId; try { - StartupInternalWithDataMigrationIfNeeded(progressDlg); + StartupInternalWithDataMigrationIfNeeded(progressDlg, forbidDataMigration); InitializeWritingSystemManager(); if (fBootstrapSystem) BootstrapExtantSystem(); } - catch (System.UnauthorizedAccessException e) - { - if (MiscUtils.IsUnix) - { - // Tell Mono user he/she needs to logout and log back in - MessageBoxUtils.Show(Strings.ksNeedToJoinFwGroup); - } - - // Release any resources. - ShutdownInternal(); - throw; - } catch (Exception e) { // If anything unexpected goes wrong give BEP change to release any resources. @@ -782,14 +779,13 @@ public void CreateNewLanguageProject(IProjectIdentifier projectId) internal void RegisterOriginalCustomProperties(IEnumerable originalCustomProperties) { - foreach (var cfi in originalCustomProperties) + m_mdcInternal.AddCustomFields(originalCustomProperties); + foreach (CustomFieldInfo cfi in m_mdcInternal.GetCustomFields()) { if (m_extantCustomFields.ContainsKey(cfi.Key)) return; // Must have done a migration. m_extantCustomFields.Add(cfi.Key, cfi); } - if (originalCustomProperties.Count() > 0) - m_mdcInternal.AddCustomFields(originalCustomProperties); } /// ------------------------------------------------------------------------------------ @@ -816,8 +812,8 @@ public void InitializeFromSource(IProjectIdentifier projectId, InitializeWritingSystemManager(); // 3. Startup source BEP, but without instantiating any FDO objects (surrogates, are loaded). - using (var sourceCache = FdoCache.CreateCacheFromExistingData(sourceDataStore.ProjectId, - userWsIcuLocale, progressDlg)) + using (FdoCache sourceCache = FdoCache.CreateCacheFromExistingData(sourceDataStore.ProjectId, + userWsIcuLocale, m_ui, m_cache.ServiceLocator.GetInstance(), progressDlg)) { // 4. Do the port. var sourceCacheServLoc = sourceCache.ServiceLocator; diff --git a/Src/FDO/Infrastructure/Impl/FdoIFwMetaDataCache.cs b/Src/FDO/Infrastructure/Impl/FdoIFwMetaDataCache.cs index 9121101e20..ac9ad9f29f 100644 --- a/Src/FDO/Infrastructure/Impl/FdoIFwMetaDataCache.cs +++ b/Src/FDO/Infrastructure/Impl/FdoIFwMetaDataCache.cs @@ -65,6 +65,7 @@ internal sealed class FdoMetaDataCache : IFwMetaDataCacheManaged, IFwMetaDataCac private readonly Dictionary m_nameToFlid = new Dictionary(); private readonly Dictionary m_clidToNextCustomFlid = new Dictionary(); private readonly HashSet m_customFields = new HashSet(); + private readonly HashSet m_analysisClids = new HashSet(); #endregion Data Members for IFwMetaDataCache Support @@ -152,6 +153,8 @@ private void InitializeMetaDataCache(IEnumerable cmObjectTypes) fdoType.IsAbstract); #endif + if (fdoType.GetInterface("IAnalysis") != null) + m_analysisClids.Add(((ModelClassAttribute)classAttrs[0]).Clsid); // Cache properties. // Regular foreach loop is faster. //PropertyInfo[] pis = fdoType.GetProperties(); @@ -214,11 +217,21 @@ private void InitializeMetaDataCache(IEnumerable cmObjectTypes) private void ConnectMetaFieldRec(MetaFieldRec mfr) { - int clid; - if (mfr.m_sig == null || !m_nameToClid.TryGetValue(mfr.m_sig, out clid)) return; + if (mfr.m_sig == null) + return; - SetDestClass(mfr, clid); - mfr.m_sig = null; + int clid; + if (m_nameToClid.TryGetValue(mfr.m_sig, out clid)) + { + SetDestClass(mfr, clid); + mfr.m_sig = null; + } + else if (mfr.m_sig == "IAnalyses") + { + foreach (int analysisClid in m_analysisClids) + m_metaClassRecords[analysisClid].m_incomingFields.Add(mfr); + mfr.m_sig = null; + } } private void SetDestClass(MetaFieldRec mfr, int clid) diff --git a/Src/FDO/Infrastructure/Impl/FdoRepositoryAdditions.cs b/Src/FDO/Infrastructure/Impl/FdoRepositoryAdditions.cs index f0cbbea28a..7d4c98448f 100644 --- a/Src/FDO/Infrastructure/Impl/FdoRepositoryAdditions.cs +++ b/Src/FDO/Infrastructure/Impl/FdoRepositoryAdditions.cs @@ -15,9 +15,7 @@ using System.Diagnostics; using System.Linq; using System.Text; -using System.Windows.Forms; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainImpl; using SIL.FieldWorks.FDO.Validation; using SIL.Utils; @@ -1242,7 +1240,7 @@ public IEnumerable GetVariantFormEntries(ICmObject mainEntryOrSense) /// /// Clear the list of homograph information /// - public void ResetHomographs(ProgressBar progressBar) + public void ResetHomographs(IProgress progressBar) { m_homographInfo = null; // GetHomographs() will rebuild the homograph list Cache.LanguageProject.LexDbOA.ResetHomographNumbers(progressBar); @@ -1430,6 +1428,189 @@ public int HomographMorphOrder(FdoCache cache, IMoMorphType morphType) } return morphType.SecondaryOrder; } + + /// + /// Find the list of LexEntry objects which conceivably match the given wordform. + /// + /// + /// + /// + /// + /// + public List FindEntriesForWordform(FdoCache cache, ITsString tssWf, IWfiAnalysis wfa, ref bool duplicates) + { + var entries = FindEntriesForWordformWorker(cache, tssWf, wfa, ref duplicates); + + // if we do not find a match for the word then try converting it to lowercase and see if there + // is an entry in the lexicon for the Wordform in lowercase. This is needed for occurences of + // words which are capitalized at the beginning of sentences. LT-7444 RickM + if (entries == null || entries.Count == 0) + { + //We need to be careful when converting to lowercase therefore use Icu.ToLower() + //get the WS of the tsString + int wsWf = TsStringUtils.GetWsAtOffset(tssWf, 0); + //use that to get the locale for the WS, which is used for + string wsLocale = cache.ServiceLocator.WritingSystemManager.Get(wsWf).IcuLocale; + string sLower = Icu.ToLower(tssWf.Text, wsLocale); + ITsTextProps ttp = tssWf.get_PropertiesAt(0); + ITsStrFactory tsf = TsStrFactoryClass.Create(); + tssWf = tsf.MakeStringWithPropsRgch(sLower, sLower.Length, ttp); + entries = FindEntriesForWordformWorker(cache, tssWf, wfa, ref duplicates); + } + return entries; + } + + public List FindEntriesForWordformWorker(FdoCache cache, ITsString tssWf, IWfiAnalysis wfa, ref bool duplicates) + { + if (tssWf == null) + return new List(); + + string wf = tssWf.Text; + if (string.IsNullOrEmpty(wf)) + return new List(); + + int wsVern = TsStringUtils.GetWsAtOffset(tssWf, 0); + + var entries = new Set(); + + // Get the entries from the matching wordform. + // Get matching wordform. + IWfiWordform[] matchingWordforms = cache.ServiceLocator.GetInstance().AllInstances() + .Where(wrdfrm => wrdfrm.Form.get_String(wsVern).Text == wf).ToArray(); + + duplicates = matchingWordforms.Length > 1; + + if (matchingWordforms.Length > 0) + { + if (wfa != null && matchingWordforms[0].AnalysesOC.Contains(wfa)) + { + entries.AddRange(wfa.MorphBundlesOS + .Where(mb => mb.MorphRA != null) + .Select(mb => mb.MorphRA.OwnerOfClass())); + } + else + { + foreach (IWfiAnalysis analysis in matchingWordforms[0].AnalysesOC.Where(a => a.ApprovalStatusIcon == (int) Opinions.approves)) + { + entries.AddRange(analysis.MorphBundlesOS + .Where(mb => mb.MorphRA != null) + .Select(mb => mb.MorphRA.OwnerOfClass())); + } + } + } + // Get the entries from the matching MoForms. + entries.AddRange( + cache.ServiceLocator.GetInstance().AllInstances() + .Where(mf => mf.Form.get_String(wsVern) != null && mf.Form.get_String(wsVern).Text == wf) + .Select(mf => mf.OwnerOfClass())); + + // Get the entries from the citation form + entries.AddRange( + cache.ServiceLocator.GetInstance().AllInstances() + .Where(entry => entry.CitationForm.get_String(wsVern) != null && entry.CitationForm.get_String(wsVern).Text == wf)); + + // Put the enrties in a List and sort it by the HomographNumber. + var retval = new List(entries); + retval.Sort(CompareEntriesByHomographNumber); + return retval; + } + + private int CompareEntriesByHomographNumber(ILexEntry x, ILexEntry y) + { + return x == null + ? (y == null ? 0 /* Both are null, so are equal */ : -1 /* x not being null is grater than y which is null */) + : (y == null + ? 1 /* y being null is greater than x which is not null */ + : (x.HomographNumber == y.HomographNumber + ? 0 /* Neither are null, and homograph numbers are the same, so they are equal */ + : (x.HomographNumber > y.HomographNumber + ? 1 /* x is greater than x */ + : -1 /* x is less than y */))); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Find wordform given a cache and the string. + /// + /// + /// + /// + /// ------------------------------------------------------------------------------------ + public ILexEntry FindEntryForWordform(FdoCache cache, ITsString tssWf) + { + if (tssWf == null || tssWf.Length == 0) + return null; + + var wsVern = TsStringUtils.GetWsAtOffset(tssWf, 0); + var icuEngine = cache.LanguageWritingSystemFactoryAccessor.get_CharPropEngine(wsVern); + var wf = icuEngine.ToLower(tssWf.Text); + ILexEntry matchingEntry = null; + + // Check for Lexeme form. + matchingEntry = ( + from e in cache.LanguageProject.LexDbOA.Entries + where e.LexemeFormOA != null && GetLowercaseStringFromMultiUnicodeSafely(icuEngine, e.LexemeFormOA.Form, wsVern) == wf + orderby e.HomographNumber + select e + ).FirstOrDefault(); + + // Check for Citation form. + if (matchingEntry == null) + matchingEntry = ( + from e in cache.LanguageProject.LexDbOA.Entries + where GetLowercaseStringFromMultiUnicodeSafely(icuEngine, e.CitationForm, wsVern) == wf + orderby e.HomographNumber + select e + ).FirstOrDefault(); + + // Check for Alternate forms. + if (matchingEntry == null) + matchingEntry = ( + from e in cache.LanguageProject.LexDbOA.Entries + where ( + from af in e.AlternateFormsOS + where GetLowercaseStringFromMultiUnicodeSafely(icuEngine, af.Form, wsVern) == wf + select af + ).FirstOrDefault() != null + orderby e.HomographNumber + select e + ).FirstOrDefault(); + + // Look for the most commonly used analysis of the wordform. + if (matchingEntry == null) + { + IWfiWordform wordform; + if (cache.ServiceLocator.GetInstance().TryGetObject(tssWf, out wordform)) + { + var guesser = new AnalysisGuessServices(cache); + var guess = guesser.GetBestGuess(wordform); + var analysis = guess as IWfiAnalysis; + if (guess is IWfiGloss) + analysis = guess.Owner as IWfiAnalysis; + if (analysis != null) + { + matchingEntry = + (from mb in analysis.MorphBundlesOS + where mb.MorphRA is IMoStemAllomorph + select mb.MorphRA.Owner).FirstOrDefault() as ILexEntry; + } + } + } + + return matchingEntry; + } + + private string GetLowercaseStringFromMultiUnicodeSafely(ILgCharacterPropertyEngine icuEngine, IMultiUnicode form, int ws) + { + if (form == null) + return string.Empty; + + var formTsstring = form.get_String(ws); + if (formTsstring == null || formTsstring.Length == 0) + return string.Empty; + + return icuEngine.ToLower(formTsstring.Text); + } } #endregion @@ -1724,4 +1905,16 @@ public IPublication FindByName(string name) } } #endregion + + #region TextTagRepository class + internal partial class TextTagRepository + { + public IEnumerable GetByTextMarkupTag(ICmPossibility tag) + { + var tags = new HashSet {tag}; + tags.UnionWith(tag.SubPossibilitiesOS); + return AllInstances().Where(ttag => tags.Contains(ttag.TagRA)); + } + } + #endregion } diff --git a/Src/FDO/Infrastructure/Impl/FdoStateChangingClasses.cs b/Src/FDO/Infrastructure/Impl/FdoStateChangingClasses.cs index 723ce4fb68..e5dcbea338 100644 --- a/Src/FDO/Infrastructure/Impl/FdoStateChangingClasses.cs +++ b/Src/FDO/Infrastructure/Impl/FdoStateChangingClasses.cs @@ -12,7 +12,6 @@ using System.Xml.Linq; using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.Application; namespace SIL.FieldWorks.FDO.Infrastructure.Impl diff --git a/Src/FDO/Infrastructure/Impl/MemoryOnlyBackendProvider.cs b/Src/FDO/Infrastructure/Impl/MemoryOnlyBackendProvider.cs index 97a3e42152..ee37c9bc60 100644 --- a/Src/FDO/Infrastructure/Impl/MemoryOnlyBackendProvider.cs +++ b/Src/FDO/Infrastructure/Impl/MemoryOnlyBackendProvider.cs @@ -6,11 +6,9 @@ // Responsibility: Randy Regnier // Last reviewed: never -using System; + using System.Collections.Generic; -using System.IO; using SIL.FieldWorks.FDO.DomainServices.DataMigration; -using SIL.Utils; namespace SIL.FieldWorks.FDO.Infrastructure.Impl { @@ -23,8 +21,9 @@ internal sealed class MemoryOnlyBackendProvider : FDOBackendProvider /// /// Constructor. /// - internal MemoryOnlyBackendProvider(FdoCache cache, IdentityMap identityMap, ICmObjectSurrogateFactory surrogateFactory, IFwMetaDataCacheManagedInternal mdc, IDataMigrationManager dataMigrationManager) - : base(cache, identityMap, surrogateFactory, mdc, dataMigrationManager) + internal MemoryOnlyBackendProvider(FdoCache cache, IdentityMap identityMap, ICmObjectSurrogateFactory surrogateFactory, + IFwMetaDataCacheManagedInternal mdc, IDataMigrationManager dataMigrationManager, IFdoUI ui, IFdoDirectories dirs) + : base(cache, identityMap, surrogateFactory, mdc, dataMigrationManager, ui, dirs) { } diff --git a/Src/FDO/Infrastructure/Impl/SharedXMLBackendProvider.cs b/Src/FDO/Infrastructure/Impl/SharedXMLBackendProvider.cs new file mode 100644 index 0000000000..492ab15cc6 --- /dev/null +++ b/Src/FDO/Infrastructure/Impl/SharedXMLBackendProvider.cs @@ -0,0 +1,670 @@ +// Copyright (c) 2013-2014 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.IO.MemoryMappedFiles; +using System.Linq; +using System.Threading; +using System.Diagnostics.CodeAnalysis; +using ProtoBuf; +using SIL.FieldWorks.FDO.DomainServices.DataMigration; + +namespace SIL.FieldWorks.FDO.Infrastructure.Impl +{ + /// + /// An XML file-based backend provider that allows multiple applications to access the same project + /// simultaneously. It uses memory mapped files to maintain a shared commit log that all applications + /// use to update their state to reflect changes made by other applications. The commit log is + /// implemented as a circular buffer of commit records. A single peer is responsible for updating + /// the XML file. + /// + internal class SharedXMLBackendProvider : XMLBackendProvider + { + private const int PageSize = 4096; + internal static int CommitLogFileSize = 2500 * PageSize; + private const int CommitLogMetadataFileSize = 1 * PageSize; + + /// + /// This mutex synchronizes access to the commit log, its metadata, and the XML file. + /// + private Mutex m_commitLogMutex; + private MemoryMappedFile m_commitLogMetadata; + private MemoryMappedFile m_commitLog; + private readonly Guid m_peerID; + private readonly Dictionary m_peerProcesses; + + internal SharedXMLBackendProvider(FdoCache cache, IdentityMap identityMap, ICmObjectSurrogateFactory surrogateFactory, IFwMetaDataCacheManagedInternal mdc, + IDataMigrationManager dataMigrationManager, IFdoUI ui, IFdoDirectories dirs) + : base(cache, identityMap, surrogateFactory, mdc, dataMigrationManager, ui, dirs) + { + m_peerProcesses = new Dictionary(); + m_peerID = Guid.NewGuid(); + } + + internal int OtherApplicationsConnectedCount + { + get + { + m_commitLogMutex.WaitOne(); + try + { + using (MemoryMappedViewStream stream = m_commitLogMetadata.CreateViewStream()) + { + CommitLogMetadata metadata = GetMetadata(stream); + if (CheckExitedPeerProcesses(metadata)) + SaveMetadata(stream, metadata); + return metadata.Peers.Count - 1; + } + } + finally + { + m_commitLogMutex.ReleaseMutex(); + } + } + } + + protected override int StartupInternal(int currentModelVersion) + { + bool createdNew; + m_commitLogMutex = new Mutex(true, MutexName, out createdNew); + if (!createdNew) + m_commitLogMutex.WaitOne(); + try + { + CreateSharedMemory(createdNew); + using (MemoryMappedViewStream stream = m_commitLogMetadata.CreateViewStream()) + { + CommitLogMetadata metadata; + if (!createdNew && TryGetMetadata(stream, out metadata)) + CheckExitedPeerProcesses(metadata); + else + metadata = new CommitLogMetadata(); + + using (Process curProcess = Process.GetCurrentProcess()) + metadata.Peers[m_peerID] = new CommitLogPeer { ProcessID = curProcess.Id, Generation = metadata.FileGeneration }; + + if (metadata.Master == Guid.Empty) + { + base.LockProject(); + metadata.Master = m_peerID; + } + + int startupModelVersion = ReadInSurrogates(currentModelVersion); + // non-master peers cannot migrate the XML file + if (startupModelVersion < currentModelVersion && metadata.Master != m_peerID) + throw new FdoDataMigrationForbiddenException(); + + SaveMetadata(stream, metadata); + + return startupModelVersion; + } + } + finally + { + m_commitLogMutex.ReleaseMutex(); + } + } + + protected override void ShutdownInternal() + { + if (m_commitLogMutex != null && m_commitLogMetadata != null) + { + CompleteAllCommits(); + m_commitLogMutex.WaitOne(); + try + { +#if __MonoCS__ + bool delete = false; +#endif + using (MemoryMappedViewStream stream = m_commitLogMetadata.CreateViewStream()) + { + CommitLogMetadata metadata; + if (TryGetMetadata(stream, out metadata)) + { + if (metadata.Master == m_peerID) + { + // commit any unseen foreign changes + List foreignNewbies; + List foreignDirtballs; + List foreignGoners; + if (GetUnseenForeignChanges(metadata, out foreignNewbies, out foreignDirtballs, out foreignGoners)) + { + var newObjects = new HashSet(foreignNewbies); + var editedObjects = new HashSet(foreignDirtballs); + var removedObjects = new HashSet(foreignGoners); + + IEnumerable fields; + if (HaveAnythingToCommit(newObjects, editedObjects, removedObjects, out fields) && (StartupVersionNumber == ModelVersion)) + base.WriteCommitWork(new CommitWork(newObjects, editedObjects, removedObjects, fields)); + } + // XML file is now totally up-to-date + metadata.FileGeneration = metadata.CurrentGeneration; + } + RemovePeer(metadata, m_peerID); +#if __MonoCS__ + delete = metadata.Peers.Count == 0; +#endif + SaveMetadata(stream, metadata); + } + } + + base.UnlockProject(); + + m_commitLog.Dispose(); + m_commitLog = null; + + m_commitLogMetadata.Dispose(); + m_commitLogMetadata = null; + +#if __MonoCS__ + if (delete) + { + File.Delete(Path.Combine(Path.GetTempPath(), CommitLogMetadataName)); + File.Delete(Path.Combine(Path.GetTempPath(), CommitLogName)); + } +#endif + } + finally + { + m_commitLogMutex.ReleaseMutex(); + } + } + + if (m_commitLogMutex != null) + { + m_commitLogMutex.Dispose(); + m_commitLogMutex = null; + } + + if (CommitThread != null) + { + CommitThread.Stop(); + CommitThread.Dispose(); + CommitThread = null; + } + + foreach (Process peerProcess in m_peerProcesses.Values) + peerProcess.Close(); + m_peerProcesses.Clear(); + } + + protected override void CreateInternal() + { + bool createdNew; + m_commitLogMutex = new Mutex(true, MutexName, out createdNew); + if (!createdNew) + { + // Mono does not close the named mutex handle until the process exits, this can cause problems + // for some unit tests, so we disable the following check for Mono +#if !__MonoCS__ + throw new InvalidOperationException("Cannot create shared XML backend."); +#else + m_commitLogMutex.WaitOne(); +#endif + } + try + { + CreateSharedMemory(true); + var metadata = new CommitLogMetadata { Master = m_peerID }; + using (Process curProcess = Process.GetCurrentProcess()) + metadata.Peers[m_peerID] = new CommitLogPeer { ProcessID = curProcess.Id, Generation = metadata.FileGeneration }; + using (MemoryMappedViewStream stream = m_commitLogMetadata.CreateViewStream()) + { + SaveMetadata(stream, metadata); + } + + base.CreateInternal(); + } + finally + { + m_commitLogMutex.ReleaseMutex(); + } + } + + private static bool TryGetMetadata(MemoryMappedViewStream stream, out CommitLogMetadata metadata) + { + stream.Seek(0, SeekOrigin.Begin); + int length; + if (Serializer.TryReadLengthPrefix(stream, PrefixStyle.Base128, out length) && length > 0) + { + stream.Seek(0, SeekOrigin.Begin); + metadata = Serializer.DeserializeWithLengthPrefix(stream, PrefixStyle.Base128, 1); + return true; + } + + metadata = null; + return false; + } + + private static CommitLogMetadata GetMetadata(MemoryMappedViewStream stream) + { + stream.Seek(0, SeekOrigin.Begin); + return Serializer.DeserializeWithLengthPrefix(stream, PrefixStyle.Base128, 1); + } + + private static void SaveMetadata(MemoryMappedViewStream stream, CommitLogMetadata metadata) + { + stream.Seek(0, SeekOrigin.Begin); + Serializer.SerializeWithLengthPrefix(stream, metadata, PrefixStyle.Base128, 1); + } + + private string MutexName + { + get { return ProjectId.Name + "_Mutex"; } + } + + private string CommitLogName + { + get { return ProjectId.Name + "_CommitLog"; } + } + + private string CommitLogMetadataName + { + get { return ProjectId.Name + "_CommitLogMetadata"; } + } + + private void CreateSharedMemory(bool createdNew) + { + m_commitLogMetadata = CreateOrOpen(CommitLogMetadataName, CommitLogMetadataFileSize, createdNew); + m_commitLog = CreateOrOpen(CommitLogName, CommitLogFileSize, createdNew); + } + + [SuppressMessage("Gendarme.Rules.Portability", "MonoCompatibilityReviewRule", + Justification = "An actual file is passed into MemoryMappedFile.CreateOrOpen")] + private MemoryMappedFile CreateOrOpen(string name, long capacity, bool createdNew) + { +#if __MonoCS__ + name = Path.Combine(Path.GetTempPath(), name); + // delete old file that could be left after a crash + if (createdNew && File.Exists(name)) + File.Delete(name); + + // Mono only supports memory mapped files that are backed by an actual file + if (!File.Exists(name)) + { + using (var fs = new FileStream(name, FileMode.CreateNew)) + fs.SetLength(capacity); + } +#endif + return MemoryMappedFile.CreateOrOpen(name, capacity); + } + + /// + /// Checks for peer processes that have exited unexpectedly and update the metadata accordingly. + /// + [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", + Justification = "The process is disposed later.")] + private bool CheckExitedPeerProcesses(CommitLogMetadata metadata) + { + bool changed = false; + var processesToRemove = new HashSet(m_peerProcesses.Values); + foreach (KeyValuePair kvp in metadata.Peers.ToArray()) + { + if (kvp.Key == m_peerID) + continue; + + Process process; + if (m_peerProcesses.TryGetValue(kvp.Value.ProcessID, out process)) + { + if (process.HasExited) + { + RemovePeer(metadata, kvp.Key); + changed = true; + } + else + { + processesToRemove.Remove(process); + } + } + else + { + try + { + process = Process.GetProcessById(kvp.Value.ProcessID); + m_peerProcesses[kvp.Value.ProcessID] = process; + } + catch (ArgumentException) + { + RemovePeer(metadata, kvp.Key); + changed = true; + } + } + } + + foreach (Process process in processesToRemove) + { + m_peerProcesses.Remove(process.Id); + process.Close(); + } + return changed; + } + + private static void RemovePeer(CommitLogMetadata metadata, Guid peerID) + { + metadata.Peers.Remove(peerID); + if (metadata.Master == peerID) + metadata.Master = Guid.Empty; + } + + internal override void LockProject() + { + m_commitLogMutex.WaitOne(); + try + { + base.LockProject(); + using (MemoryMappedViewStream stream = m_commitLogMetadata.CreateViewStream()) + { + CommitLogMetadata metadata = GetMetadata(stream); + if (metadata.Master == Guid.Empty) + { + metadata.Master = m_peerID; + SaveMetadata(stream, metadata); + } + } + } + finally + { + m_commitLogMutex.ReleaseMutex(); + } + } + + internal override void UnlockProject() + { + m_commitLogMutex.WaitOne(); + try + { + base.UnlockProject(); + using (MemoryMappedViewStream stream = m_commitLogMetadata.CreateViewStream()) + { + CommitLogMetadata metadata; + if (TryGetMetadata(stream, out metadata)) + { + if (metadata.Master == m_peerID) + { + metadata.Master = Guid.Empty; + SaveMetadata(stream, metadata); + } + } + } + } + finally + { + m_commitLogMutex.ReleaseMutex(); + } + } + + public override bool Commit(HashSet newbies, HashSet dirtballs, HashSet goners) + { + CommitLogMetadata metadata = null; + m_commitLogMutex.WaitOne(); + try + { + using (MemoryMappedViewStream stream = m_commitLogMetadata.CreateViewStream()) + { + metadata = GetMetadata(stream); + } + + List foreignNewbies; + List foreignDirtballs; + List foreignGoners; + if (GetUnseenForeignChanges(metadata, out foreignNewbies, out foreignDirtballs, out foreignGoners)) + { + // we have now seen every commit generation + metadata.Peers[m_peerID].Generation = metadata.CurrentGeneration; + + IUnitOfWorkService uowService = ((IServiceLocatorInternal) m_cache.ServiceLocator).UnitOfWorkService; + IReconcileChanges reconciler = uowService.CreateReconciler(foreignNewbies, foreignDirtballs, foreignGoners); + if (reconciler.OkToReconcileChanges()) + { + reconciler.ReconcileForeignChanges(); + if (metadata.Master == m_peerID) + { + var newObjects = new HashSet(foreignNewbies); + var editedObjects = new HashSet(foreignDirtballs); + var removedObjects = new HashSet(foreignGoners); + + IEnumerable fields; + if (HaveAnythingToCommit(newObjects, editedObjects, removedObjects, out fields) && (StartupVersionNumber == ModelVersion)) + PerformCommit(newObjects, editedObjects, removedObjects, fields); + } + } + else + { + uowService.ConflictingChanges(reconciler); + return true; + } + } + + CheckExitedPeerProcesses(metadata); + if (metadata.Master == Guid.Empty) + { + // Check if the former master left the commit log and XML file in a consistent state. If not, we can't continue. + if (metadata.CurrentGeneration != metadata.FileGeneration) + return false; + base.LockProject(); + metadata.Master = m_peerID; + } + + IEnumerable cfiList; + if (!HaveAnythingToCommit(newbies, dirtballs, goners, out cfiList) && (StartupVersionNumber == ModelVersion)) + return true; + + metadata.CurrentGeneration++; + + var commitRec = new CommitLogRecord + { + Source = m_peerID, + WriteGeneration = metadata.CurrentGeneration, + ObjectsDeleted = goners.Select(g => g.Guid).ToList(), + ObjectsAdded = newbies.Select(n => n.XMLBytes).ToList(), + ObjectsUpdated = dirtballs.Select(d => d.XMLBytes).ToList() + }; + + // we've seen our own change + metadata.Peers[m_peerID].Generation = metadata.CurrentGeneration; + + using (var buffer = new MemoryStream()) + { + Serializer.SerializeWithLengthPrefix(buffer, commitRec, PrefixStyle.Base128, 1); + if (metadata.LogLength + buffer.Length > CommitLogFileSize) + return false; + + byte[] bytes = buffer.GetBuffer(); + int commitRecOffset = (metadata.LogOffset + metadata.LogLength) % CommitLogFileSize; + // check if the record can fit at the end of the commit log. If not, we wrap around to the beginning. + if (commitRecOffset + buffer.Length > CommitLogFileSize) + { + metadata.Padding = CommitLogFileSize - commitRecOffset; + metadata.LogLength += metadata.Padding; + commitRecOffset = 0; + } + using (MemoryMappedViewStream stream = m_commitLog.CreateViewStream(commitRecOffset, buffer.Length)) + { + stream.Write(bytes, 0, (int) buffer.Length); + metadata.LogLength += (int) buffer.Length; + } + } + + if (metadata.Master == m_peerID) + PerformCommit(newbies, dirtballs, goners, cfiList); + + return true; + } + finally + { + try + { + if (metadata != null) + { + using (MemoryMappedViewStream stream = m_commitLogMetadata.CreateViewStream()) + { + SaveMetadata(stream, metadata); + } + } + } + finally + { + m_commitLogMutex.ReleaseMutex(); + } + } + } + + protected override void WriteCommitWork(CommitWork workItem) + { + m_commitLogMutex.WaitOne(); + try + { + base.WriteCommitWork(workItem); + + using (MemoryMappedViewStream stream = m_commitLogMetadata.CreateViewStream()) + { + CommitLogMetadata metadata = GetMetadata(stream); + metadata.FileGeneration = metadata.Peers[m_peerID].Generation; + SaveMetadata(stream, metadata); + } + } + finally + { + m_commitLogMutex.ReleaseMutex(); + } + } + + /// + /// Gets all unseen foreign changes from the commit log. The metadata should be saved after calling this method, + /// because inactive records might have been purged. + /// + private bool GetUnseenForeignChanges(CommitLogMetadata metadata, + out List foreignNewbies, + out List foreignDirtballs, + out List foreignGoners) + { + foreignNewbies = new List(); + foreignDirtballs = new List(); + foreignGoners = new List(); + + int minPeerGeneration = metadata.Peers.Select(p => p.Key == m_peerID ? metadata.CurrentGeneration : p.Value.Generation).Min(); + var unseenCommitRecs = new List(); + + int bytesRemaining = metadata.LogLength; + // read all records up to the end of the file or the end of the log, whichever comes first + int length = Math.Min(metadata.LogLength, CommitLogFileSize - metadata.LogOffset - metadata.Padding); + bytesRemaining -= ReadUnseenCommitRecords(metadata, minPeerGeneration, metadata.LogOffset, length, unseenCommitRecs); + // if there are bytes remaining, it means that we hit the end of the file, so we need to wrap around to the beginning + if (bytesRemaining > 0) + bytesRemaining -= ReadUnseenCommitRecords(metadata, minPeerGeneration, 0, bytesRemaining, unseenCommitRecs); + Debug.Assert(bytesRemaining == 0); + + if (unseenCommitRecs.Count == 0) + return false; + + var idFactory = m_cache.ServiceLocator.GetInstance(); + + var newbies = new Dictionary(); + var dirtballs = new Dictionary(); + var goners = new HashSet(); + + var surrogateFactory = m_cache.ServiceLocator.GetInstance(); + + foreach (CommitLogRecord commitRec in unseenCommitRecs) + { + if (commitRec.ObjectsDeleted != null) + { + foreach (Guid goner in commitRec.ObjectsDeleted) + { + // If it was created by a previous foreign change we haven't seen, we can just forget it. + if (newbies.Remove(goner)) + continue; + // If it was modified by a previous foreign change we haven't seen, we can forget the modification. + // (but we still need to know it's gone). + dirtballs.Remove(goner); + goners.Add(goner); + } + } + if (commitRec.ObjectsUpdated != null) + { + foreach (byte[] dirtballXml in commitRec.ObjectsUpdated) + { + ICmObjectSurrogate dirtballSurrogate = surrogateFactory.Create(DataSortingService.Utf8.GetString(dirtballXml)); + // This shouldn't be necessary; if a previous foreign transaction deleted it, it + // should not show up as a dirtball in a later transaction until it has shown up as a newby. + // goners.Remove(dirtball); + // If this was previously known as a newby or modified, then to us it still is. + if (newbies.ContainsKey(dirtballSurrogate.Guid) || dirtballs.ContainsKey(dirtballSurrogate.Guid)) + continue; + dirtballs[dirtballSurrogate.Guid] = dirtballSurrogate; + } + } + if (commitRec.ObjectsAdded != null) + { + foreach (byte[] newbyXml in commitRec.ObjectsAdded) + { + ICmObjectSurrogate newObj = surrogateFactory.Create(DataSortingService.Utf8.GetString(newbyXml)); + if (goners.Remove(newObj.Guid)) + { + // an object which an earlier transaction deleted is being re-created. + // This means that to us, it is a dirtball. + dirtballs[newObj.Guid] = newObj; + continue; + } + // It shouldn't be in dirtballs; can't be new in one transaction without having been deleted previously. + // So it really is new. + newbies[newObj.Guid] = newObj; + } + } + foreignNewbies.AddRange(newbies.Values); + foreignDirtballs.AddRange(dirtballs.Values); + foreignGoners.AddRange(from guid in goners select idFactory.FromGuid(guid)); + } + return true; + } + + private int ReadUnseenCommitRecords(CommitLogMetadata metadata, int minPeerGeneration, int startOffset, int length, List unseenCommits) + { + if (length == 0) + return 0; + + int generation = metadata.Peers[m_peerID].Generation; + using (MemoryMappedViewStream stream = m_commitLog.CreateViewStream(startOffset, length)) + { + while (stream.Position < length) + { + long startPos = stream.Position; + var rec = Serializer.DeserializeWithLengthPrefix(stream, PrefixStyle.Base128, 1); + if (rec.WriteGeneration > generation && rec.Source != m_peerID) + unseenCommits.Add(rec); + // remove the record from the commit log once all peers have seen it and it has been written to disk + if (rec.WriteGeneration <= minPeerGeneration && rec.WriteGeneration <= metadata.FileGeneration) + { + metadata.LogOffset = startOffset + (int) stream.Position; + metadata.LogLength -= (int) (stream.Position - startPos); + } + } + } + + // if we have read everything to the end of the file, add padding to read length + if (startOffset + length == CommitLogFileSize - metadata.Padding) + length += metadata.Padding; + + // check if we've purged all records up to the end of the file. If so, wrap around to the beginning. + if (metadata.LogOffset == CommitLogFileSize - metadata.Padding) + { + metadata.LogOffset = 0; + metadata.LogLength -= metadata.Padding; + metadata.Padding = 0; + } + + return length; + } + + public override bool RenameDatabase(string sNewProjectName) + { + if (OtherApplicationsConnectedCount > 0) + return false; + return base.RenameDatabase(sNewProjectName); + } + } +} diff --git a/Src/FDO/Infrastructure/Impl/SimpleProjectId.cs b/Src/FDO/Infrastructure/Impl/SimpleProjectId.cs index ca28261ce0..818e66eddb 100644 --- a/Src/FDO/Infrastructure/Impl/SimpleProjectId.cs +++ b/Src/FDO/Infrastructure/Impl/SimpleProjectId.cs @@ -7,7 +7,6 @@ // --------------------------------------------------------------------------------------------- using System; -using SIL.FieldWorks.Common.FwUtils; namespace SIL.FieldWorks.FDO.Infrastructure.Impl { @@ -67,11 +66,12 @@ public string Handle /// ------------------------------------------------------------------------------------ /// /// Gets a token that uniquely identifies the project that can be used for a named pipe. + /// TODO: this will probably go away after we finish integrating FDO into Paratext /// /// ------------------------------------------------------------------------------------ public string PipeHandle { - get { return FwUtils.GeneratePipeHandle(Handle); } + get { throw new NotImplementedException(); } } /// ------------------------------------------------------------------------------------ diff --git a/Src/FDO/Infrastructure/Impl/UndoStack.cs b/Src/FDO/Infrastructure/Impl/UndoStack.cs index 7504997087..1883e85f7f 100644 --- a/Src/FDO/Infrastructure/Impl/UndoStack.cs +++ b/Src/FDO/Infrastructure/Impl/UndoStack.cs @@ -6,12 +6,10 @@ // Responsibility: Randy Regnier using System; -using System.Collections; using System.ComponentModel; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Linq; -using System.Threading; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.FDO.Application; using SIL.Utils; @@ -96,17 +94,19 @@ internal sealed class UndoStack : IActionHandler, IActionHandlerExtensions private bool m_createMarkIfNeeded; internal FdoUnitOfWork m_currentBundle; private readonly UnitOfWorkService m_uowService; + private readonly IFdoUI m_ui; // Positive values count unsaved bundles in m_undoBundles. // Negative values count unsaved bundles in m_redoBundles, that is, things Undone since the last Save. private int m_countUnsavedBundles; - private List m_actionsToDoAtEndOfPropChanged = new List(); + private readonly List m_actionsToDoAtEndOfPropChanged = new List(); #endregion #region Constructor - public UndoStack(UnitOfWorkService uowService) + public UndoStack(UnitOfWorkService uowService, IFdoUI ui) { m_uowService = uowService; + m_ui = ui; m_undoBundles = new Stack(); m_redoBundles = new Stack(); m_currentBundle = null; @@ -313,10 +313,10 @@ private void EndUndoTaskCommon(bool updateDateModified) dmObj.UpdateDateModified(); } // Update the project DateModified, but only once every 2 minutes at most. - if (m_currentBundle.DirtyObjects.Count() > 0) + if (m_currentBundle.DirtyObjects.Any()) { - LangProject proj = m_currentBundle.DirtyObjects.ElementAt(0).Cache.LangProject as LangProject; - TimeSpan span = new TimeSpan(DateTime.Now.Ticks - proj.DateModified.Ticks); + var proj = (LangProject) m_currentBundle.DirtyObjects.ElementAt(0).Cache.LangProject; + var span = new TimeSpan(DateTime.Now.Ticks - proj.DateModified.Ticks); if (span.Minutes >= 2 || m_currentBundle.DirtyObjects.Contains(proj)) proj.UpdateDateModifiedInternal(); } @@ -369,22 +369,25 @@ private void EndUndoTaskCommon(bool updateDateModified) /// ------------------------------------------------------------------------------------ private void DoTasksForEndOfPropChanged(FdoUnitOfWork uow, bool fromUndoRedo) { - ((CmObjectRepository)m_uowService.ObjectRepository).Cache.ThreadHelper.Invoke(() => - { - if (!fromUndoRedo) + var tasks = new List(); + if (!fromUndoRedo) + { + // These notifications must be sent only once. + // In particular they must not be sent again if one of the tasks in the list makes a new UOW. + // Since this method will execute at the end of such a task, we must make sure that there is + // a fresh m_actionsToDoAtEndOfPropChanged for any such UOW so it will not see our list. + tasks.AddRange(m_actionsToDoAtEndOfPropChanged); + m_actionsToDoAtEndOfPropChanged.Clear(); + } + tasks.AddRange(uow.ActionsToDoAtEndOfPropChanged); + if (tasks.Count > 0) + { + m_ui.SynchronizeInvoke.Invoke(() => { - // These notifications must be sent only once. - // In particular they must not be sent again if one of the tasks in the list makes a new UOW. - // Since this method will execute at the end of such a task, we must make sure that there is - // a fresh m_actionsToDoAtEndOfPropChanged for any such UOW so it will not see our list. - var temp = m_actionsToDoAtEndOfPropChanged; - m_actionsToDoAtEndOfPropChanged = new List(); - foreach (var task in temp) + foreach (Action task in tasks) task(); - } - foreach (var task in uow.ActionsToDoAtEndOfPropChanged) - task(); - }); + }); + } } /// @@ -819,7 +822,7 @@ public bool CollapseToMark(int hMark, string bstrUndo, string bstrRedo) bool fActionsCollapsed = false; if (m_undoBundles.Count > markIndex) { - FdoUndoableUnitOfWork newUow = new FdoUndoableUnitOfWork(m_uowService, bstrUndo, bstrRedo); + var newUow = new FdoUndoableUnitOfWork(m_uowService, bstrUndo, bstrRedo); while (m_undoBundles.Count > markIndex) newUow.InsertActionsFrom(PopUndoStack()); diff --git a/Src/FDO/Infrastructure/Impl/UnitOfWorkService.cs b/Src/FDO/Infrastructure/Impl/UnitOfWorkService.cs index 84513f6e04..b51c3cd73f 100644 --- a/Src/FDO/Infrastructure/Impl/UnitOfWorkService.cs +++ b/Src/FDO/Infrastructure/Impl/UnitOfWorkService.cs @@ -6,11 +6,12 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading; -using System.Windows.Forms; +using System.Timers; +using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.FDO.Application; -using SIL.FieldWorks.Common.FwUtils; -using Timer = System.Windows.Forms.Timer; +using SIL.Utils; +using Timer = System.Timers.Timer; namespace SIL.FieldWorks.FDO.Infrastructure.Impl { @@ -88,20 +89,19 @@ internal enum FdoBusinessTransactionState } public event EventHandler OnSave; - private readonly UserActivityMonitor m_monitor; private DateTime m_lastSave = DateTime.Now; private readonly Timer m_saveTimer = new Timer(); - private bool m_fInSaveInternal = false; + private bool m_fInSaveInternal; /// /// Non-null if a Save has failed due to conflicting changes (client-server only). /// No further Saves can be attempted until Refresh allows these changes to be reconciled. /// private IReconcileChanges m_pendingReconciliation; - private readonly IDataStorer m_dataStorer; private readonly IdentityMap m_identityMap; + private readonly IFdoUI m_ui; internal ICmObjectRepositoryInternal ObjectRepository { get; @@ -150,24 +150,26 @@ internal FdoBusinessTransactionState CurrentProcessingState { /// /// Constructor. /// - internal UnitOfWorkService(IDataStorer dataStorer, IdentityMap identityMap, ICmObjectRepositoryInternal objectRepository) + internal UnitOfWorkService(IDataStorer dataStorer, IdentityMap identityMap, ICmObjectRepositoryInternal objectRepository, IFdoUI ui) { if (dataStorer == null) throw new ArgumentNullException("dataStorer"); if (identityMap == null) throw new ArgumentNullException("identityMap"); if (objectRepository == null) throw new ArgumentNullException("objectRepository"); + if (ui == null) throw new ArgumentNullException("ui"); m_dataStorer = dataStorer; m_identityMap = identityMap; ObjectRepository = objectRepository; + m_ui = ui; CurrentProcessingState = FdoBusinessTransactionState.ReadyForBeginTask; NonUndoableStack = (UndoStack)CreateUndoStack(); // Make a separate stack as the initial default. This should be mainly used in tests. // It serves to keep undoable UOWs separate from non-undoable ones, the only things ever put on the NonUndoableStack. m_currentUndoStack = m_activeUndoStack = (UndoStack)CreateUndoStack(); - m_monitor = new UserActivityMonitor(); - System.Windows.Forms.Application.AddMessageFilter(m_monitor); + + m_saveTimer.SynchronizingObject = ui.SynchronizeInvoke; m_saveTimer.Interval = 1000; - m_saveTimer.Tick += SaveOnIdle; + m_saveTimer.Elapsed += SaveOnIdle; m_saveTimer.Start(); } @@ -216,7 +218,7 @@ private void Dispose(bool fDisposing) } #endregion - void SaveOnIdle(object sender, EventArgs e) + void SaveOnIdle(object sender, ElapsedEventArgs e) { lock (this) { @@ -241,7 +243,7 @@ void SaveOnIdle(object sender, EventArgs e) if (DateTime.Now - m_lastSave < TimeSpan.FromSeconds(10.0)) return; // Nor if it's been less than 2s since the user did something. We don't want to interrupt continuous activity. - if (DateTime.Now - m_monitor.LastActivityTime < TimeSpan.FromSeconds(2.0)) + if (DateTime.Now - m_ui.LastActivityTime < TimeSpan.FromSeconds(2.0)) return; SaveInternal(); @@ -299,7 +301,6 @@ private void SaveInternal() bool fWaitForCommitLock = false; if (newbies.Count != 0 || dirtballs.Count != 0 || goners.Count != 0) { - fWaitForCommitLock = true; // raise the OnSave event: something nontrivial is being saved. bool undoable = false; foreach (var stack in m_undoStacks) @@ -315,32 +316,11 @@ private void SaveInternal() (from id in newbies select (ICmObjectOrSurrogate)repo.GetObject(id)).Where(x => x != null)); - if (m_dataStorer is IClientServerDataManager) + + if (m_pendingReconciliation != null) { - if (m_pendingReconciliation != null) - { - ShowConflictingSaveDialogBox(); - return; // Don't try to save the changes we just reverted! - } - List foreignNewbies; - List foreignDirtballs; - List foreignGoners; - var csm = (IClientServerDataManager)m_dataStorer; - while (csm.GetUnseenForeignChanges(out foreignNewbies, out foreignDirtballs, out foreignGoners, fWaitForCommitLock)) - { - var reconciler = Reconciler(foreignNewbies, foreignDirtballs, foreignGoners); - if (reconciler.OkToReconcileChanges()) - { - reconciler.ReconcileForeignChanges(); - // And continue looping, in case there are by now MORE foreign changes! - } - else - { - m_pendingReconciliation = reconciler; - ShowConflictingSaveDialogBox(); - return; - } - } + GetUserInputOnConflictingSave(); + return; // Don't try to save the changes we just reverted! } // let the BEP determine if a commit should occur or not @@ -349,7 +329,14 @@ private void SaveInternal() // TODO: What happens if BEP was not able to commit? throw new InvalidOperationException("Could not save the data for some reason."); } - foreach (var stack in m_undoStacks) + // the BEP might have found a conflicting change during the commit + if (m_pendingReconciliation != null) + { + GetUserInputOnConflictingSave(); + return; + } + + foreach (UndoStack stack in m_undoStacks) stack.RecordSaved(); } finally @@ -358,28 +345,28 @@ private void SaveInternal() } } + public void ConflictingChanges(IReconcileChanges pendingReconciliation) + { + m_pendingReconciliation = pendingReconciliation; + } + /// ------------------------------------------------------------------------------------ /// - /// Shows the conflicting save dialog box. - /// ENHANCE (TimS): We should not be showing a dialog box at this level. If we - /// really need to show it here, we should pass in the owning form instead of relying on - /// Form.ActiveForm since it can return null if no .Net forms have focus. + /// Gets user input on conflicting save /// /// ------------------------------------------------------------------------------------ - private void ShowConflictingSaveDialogBox() + private void GetUserInputOnConflictingSave() { - using (ConflictingSaveDlg dlg = new ConflictingSaveDlg()) + if (m_ui.ConflictingSave()) { - DialogResult result = dlg.ShowDialog(Form.ActiveForm); - if (result != DialogResult.OK) - RevertToSavedState(); + RevertToSavedState(); } } private void RaiseSave(bool undoable) { if (OnSave != null) - OnSave(this, new SaveEventArgs() {UndoableChanges = undoable, Cache = ((CmObjectRepository)ObjectRepository).Cache}); + OnSave(this, new SaveEventArgs {UndoableChanges = undoable, Cache = ((CmObjectRepository)ObjectRepository).Cache}); } /// @@ -434,7 +421,7 @@ private void RevertToSavedState() /// /// A hook for testing. /// - internal IReconcileChanges Reconciler( List foreignNewbies, + public IReconcileChanges CreateReconciler( List foreignNewbies, List foreignDirtballs, List foreignGoners) { return new ChangeReconciler(this, foreignNewbies, foreignDirtballs, foreignGoners); @@ -528,23 +515,28 @@ internal void SendPropChangedNotifications(IEnumerable change // This is very likely to modify the UI, so if the UOW is not being done on the UI thread, we need // to do at least this part on that thread. One known case is a task being done in the background // thread of ProgressDialogWithTask. - ((CmObjectRepository)ObjectRepository).Cache.ThreadHelper.Invoke(() => + IVwNotifyChange[] subscribers = m_changeWatchers.ToArray(); + ChangeInformation[] changes = subscribers.Length == 0 ? changesEnum.Where(ci => ci.HasNotifier).ToArray() : changesEnum.ToArray(); + if (changes.Length == 0) + return; + + m_ui.SynchronizeInvoke.Invoke(() => { - var subscribers = m_changeWatchers.ToArray(); - var changes = changesEnum.ToList(); - foreach (var sub in subscribers) + foreach (IVwNotifyChange sub in subscribers) { - if (sub is IBulkPropChanged) - ((IBulkPropChanged)sub).BeginBroadcastingChanges(changes.Count); + var bulkPropChanged = sub as IBulkPropChanged; + if (bulkPropChanged != null) + bulkPropChanged.BeginBroadcastingChanges(changes.Length); } foreach (ChangeInformation change in changes) { change.BroadcastChanges(SubscriberCanReceivePropChangeCallDelegate, subscribers); } - foreach (var sub in subscribers) + foreach (IVwNotifyChange sub in subscribers) { - if (sub is IBulkPropChanged) - ((IBulkPropChanged)sub).EndBroadcastingChanges(); + var bulkPropChanged = sub as IBulkPropChanged; + if (bulkPropChanged != null) + bulkPropChanged.EndBroadcastingChanges(); } }); } @@ -941,7 +933,7 @@ public void EndReadTask() /// public IActionHandler CreateUndoStack() { - var result = new UndoStack(this); + var result = new UndoStack(this, m_ui); m_undoStacks.Add(result); return result; } @@ -1073,6 +1065,11 @@ private ChangeInformation(int hvo, int tag, int ivMin, int cvIns, int cvDel, IPr m_notifier = notifier; } + internal bool HasNotifier + { + get { return m_notifier != null; } + } + internal void BroadcastChanges(SubscriberCanReceivePropChangeCallDelegate subscriberChecker, IVwNotifyChange[] subscribers) { if (subscriberChecker == null) throw new ArgumentNullException("subscriberChecker"); diff --git a/Src/FDO/Infrastructure/Impl/UserActivityMonitor.cs b/Src/FDO/Infrastructure/Impl/UserActivityMonitor.cs deleted file mode 100644 index ca9967a5c3..0000000000 --- a/Src/FDO/Infrastructure/Impl/UserActivityMonitor.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Windows.Forms; -using SIL.Utils; - -namespace SIL.FieldWorks.FDO.Infrastructure.Impl -{ - /// - /// This class is a message filter which can be installed in order to track when the user last - /// pressed a key or did any mouse action, including moving the mouse. - /// - class UserActivityMonitor : IMessageFilter - { - internal DateTime LastActivityTime; - - private IntPtr m_lastMousePosition; - - public bool PreFilterMessage(ref Message m) - { - if(m.Msg == (int)Win32.WinMsgs.WM_MOUSEMOVE) - { - // For mouse move, we get spurious ones when it didn't really move. So check the actual position. - if (m.LParam != m_lastMousePosition) - { - LastActivityTime = DateTime.Now; - m_lastMousePosition = m.LParam; - // Enhance JohnT: suppress ones where it doesn't move?? - } - return false; - } - if ((m.Msg >= (int)Win32.WinMsgs.WM_MOUSE_Min && m.Msg <= (int)Win32.WinMsgs.WM_MOUSE_Max) - || (m.Msg >= (int)Win32.WinMsgs.WM_KEY_Min && m.Msg <= (int)Win32.WinMsgs.WM_KEY_Max)) - { - LastActivityTime = DateTime.Now; - } - return false; // don't want to block any messages. - } - } -} diff --git a/Src/FDO/Infrastructure/Impl/XMLBackendProvider.cs b/Src/FDO/Infrastructure/Impl/XMLBackendProvider.cs index 02a04ea7e4..6c8207fffc 100644 --- a/Src/FDO/Infrastructure/Impl/XMLBackendProvider.cs +++ b/Src/FDO/Infrastructure/Impl/XMLBackendProvider.cs @@ -11,12 +11,11 @@ using System.IO; using System.Linq; using System.Text; -using System.Windows.Forms; using System.Xml; using System.Xml.Linq; +using SIL.CoreImpl; using SIL.FieldWorks.FDO.DomainServices.DataMigration; using SIL.Utils; -using SIL.FieldWorks.Common.FwUtils; namespace SIL.FieldWorks.FDO.Infrastructure.Impl { @@ -27,7 +26,7 @@ namespace SIL.FieldWorks.FDO.Infrastructure.Impl internal class XMLBackendProvider : FDOBackendProvider { #region CommitWork class - class CommitWork + protected class CommitWork { public CommitWork(HashSet newbies, HashSet dirtballs, HashSet goners, IEnumerable customFields) @@ -111,7 +110,6 @@ public void Combine(CommitWork work) #region Member variables private DateTime m_lastWriteTime; - private ConsumerThread m_thread; private FileStream m_lockFile; private bool m_needConversion; // communicates to MakeSurrogate that we're reading an old version. private int m_startupVersionNumber; @@ -123,8 +121,8 @@ public void Combine(CommitWork work) /// internal XMLBackendProvider(FdoCache cache, IdentityMap identityMap, ICmObjectSurrogateFactory surrogateFactory, IFwMetaDataCacheManagedInternal mdc, - IDataMigrationManager dataMigrationManager) : - base(cache, identityMap, surrogateFactory, mdc, dataMigrationManager) + IDataMigrationManager dataMigrationManager, IFdoUI ui, IFdoDirectories dirs) : + base(cache, identityMap, surrogateFactory, mdc, dataMigrationManager, ui, dirs) { } @@ -133,28 +131,18 @@ public IList ListOfDuplicateGuids get { return m_listOfDuplicateGuids; } } - protected override void Dispose(bool disposing) + protected bool HasLockFile { - Debug.WriteLineIf(!disposing, "****************** Missing Dispose() call for " + GetType().Name + "******************"); - if (IsDisposed) - return; - - if (disposing) - { - CompleteAllCommits(); - // Make sure the commit thread is stopped. (FWR-3179) - if (m_thread != null) - { - m_thread.StopOnIdle(); // CompleteAllCommits should wait until idle, but just in case... - m_thread.Dispose(); - } - UnlockProject(); - } - m_thread = null; + get { return m_lockFile != null; } + } - base.Dispose(disposing); + protected int StartupVersionNumber + { + get { return m_startupVersionNumber; } } + protected ConsumerThread CommitThread { get; set; } + /// ------------------------------------------------------------------------------------ /// /// Start the BEP. @@ -164,7 +152,12 @@ protected override void Dispose(bool disposing) /// ------------------------------------------------------------------------------------ protected override int StartupInternal(int currentModelVersion) { - BasicInit(); + LockProject(); + return ReadInSurrogates(currentModelVersion); + } + + protected int ReadInSurrogates(int currentModelVersion) + { for (; ; ) // Loop is used to retry if we get a corrupt file and restore backup. { var fileSize = new FileInfo(ProjectId.Path).Length; @@ -303,7 +296,7 @@ internal virtual void ReportDuplicateGuidsIfTheyExist() sb.AppendLine(String.Format(Strings.ksDuplicateGuidsMsg2, guid)); sb.AppendLine(); } - ErrorReporter.ReportDuplicateGuids(FwRegistryHelper.FieldWorksRegistryKey, "FLExErrors@sil.org", null, sb.ToString()); + m_cache.ServiceLocator.GetInstance().ReportDuplicateGuids(sb.ToString()); } } @@ -338,6 +331,15 @@ private static int GetActualModelVersionNumber(string path) /// protected override void ShutdownInternal() { + CompleteAllCommits(); + // Make sure the commit thread is stopped. (FWR-3179) + if (CommitThread != null) + { + CommitThread.StopOnIdle(); // CompleteAllCommits should wait until idle, but just in case... + CommitThread.Dispose(); + CommitThread = null; + } + UnlockProject(); } private void OfferToRestore(string message) @@ -345,11 +347,7 @@ private void OfferToRestore(string message) string backupFilePath = Path.ChangeExtension(ProjectId.Path, "bak"); if (File.Exists(backupFilePath)) { - if (ThreadHelper.ShowMessageBox(null, - String.Format(Properties.Resources.kstidOfferToRestore, ProjectId.Path, File.GetLastWriteTime(ProjectId.Path), - backupFilePath, File.GetLastWriteTime(backupFilePath)), - Properties.Resources.kstidProblemOpeningFile, MessageBoxButtons.YesNo, - MessageBoxIcon.Error) == DialogResult.Yes) + if (m_ui.OfferToRestore(ProjectId.Path, backupFilePath)) { string badFilePath = Path.ChangeExtension(ProjectId.Path, "bad"); if (File.Exists(badFilePath)) @@ -362,20 +360,20 @@ private void OfferToRestore(string message) } // No backup, or the user didn't want to try. Show Unable to Open Project dialog box. UnlockProject(); - throw new FwStartupException(message); + throw new StartupException(message); } - private void BasicInit() + internal virtual void LockProject() { - m_lastWriteTime = File.GetLastWriteTimeUtc(ProjectId.Path); try { m_lockFile = LockProject(ProjectId.Path); } catch (IOException e) { - throw new FwStartupException(String.Format(Properties.Resources.kstidLockFileLocked, ProjectId.Name), e, true); + throw new FdoFileLockedException(String.Format(Properties.Resources.kstidLockFileLocked, ProjectId.Name), e, true); } + m_lastWriteTime = File.GetLastWriteTimeUtc(ProjectId.Path); } public static bool IsFileLocked(string projectPath) @@ -399,7 +397,7 @@ internal static FileStream LockProject(string projectPath) return File.Open(projectPath + ".lock", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None); } - internal void UnlockProject() + internal virtual void UnlockProject() { if (m_lockFile != null) { @@ -416,7 +414,7 @@ internal void UnlockProject() //protected override void RestoreWithoutMigration(string xmlBepPathname) //{ // // Copy original file to backup. - // var bakPathname = m_databasePath + FwFileExtensions.ksFwDataFallbackFileExtension; + // var bakPathname = m_databasePath + FdoFileHelper.ksFwDataFallbackFileExtension; // if (File.Exists(bakPathname)) // File.Delete(bakPathname); // File.Copy(m_databasePath, bakPathname); @@ -436,7 +434,6 @@ protected override void CreateInternal() // Make sure the directory exists if (!String.IsNullOrEmpty(ProjectId.ProjectFolder) && !Directory.Exists(ProjectId.ProjectFolder)) Directory.CreateDirectory(ProjectId.ProjectFolder); - BasicInit(); if (File.Exists(ProjectId.Path)) throw new InvalidOperationException(ProjectId.Path + " already exists."); @@ -444,7 +441,7 @@ protected override void CreateInternal() var doc = new XDocument(new XElement("languageproject", new XAttribute("version", m_modelVersionOverride.ToString()))); // Include current model version number. doc.Save(ProjectId.Path, SaveOptions.None); - m_lastWriteTime = File.GetLastWriteTimeUtc(ProjectId.Path); + LockProject(); } #region IDataStorer implementation @@ -461,19 +458,25 @@ public override bool Commit(HashSet newbies, HashSet newbies, HashSet dirtballs, HashSet goners, + IEnumerable customFields) + { + if (CommitThread == null || !CommitThread.WaitForNextRequest()) { // If thread is already dead, then WaitForNextRequest will return false, but we still have to call Dispose() on it. - if (m_thread != null) - m_thread.Dispose(); + if (CommitThread != null) + CommitThread.Dispose(); - m_thread = new ConsumerThread(Work); - m_thread.Start(); + CommitThread = new ConsumerThread(Work); + CommitThread.Start(); } - m_thread.EnqueueWork(new CommitWork(newbies, dirtballs, goners, cfiList)); - - return base.Commit(newbies, dirtballs, goners); + CommitThread.EnqueueWork(new CommitWork(newbies, dirtballs, goners, customFields)); } /// @@ -482,11 +485,11 @@ public override bool Commit(HashSet newbies, HashSet @@ -519,10 +521,15 @@ private void Work(IQueueAccessor queueAccessor) else workItem.Combine(curWorkItem); } - if (workItem == null) return; + WriteCommitWork(workItem); + m_startupVersionNumber = m_modelVersionOverride; + } + + protected virtual void WriteCommitWork(CommitWork workItem) + { // Check m_lastWriteTime against current mod time, // to see if anyone else modified it, while we weren't watching. // Can't lock the file, so it is possible someone could be ill-behaved and have modified it. @@ -666,7 +673,6 @@ private void Work(IQueueAccessor queueAccessor) ReportProblem(String.Format(Strings.ksCannotSave, ProjectId.Path, e.Message), tempPathname); } CopyTempFileToOriginal(fUseLocalTempFile, ProjectId.Path, tempPathname); - m_startupVersionNumber = m_modelVersionOverride; } private void CopyTempFileToOriginal(bool fUseLocalTempFile, string mainPathname, string tempPathname) @@ -739,9 +745,9 @@ protected override void UpdateVersionNumber() /// ------------------------------------------------------------------------------------ public override bool RenameDatabase(string sNewProjectName) { - bool projectIsInDefaultLocation = DirectoryFinder.IsSubFolderOfProjectsDirectory(ProjectId.ProjectFolder); + bool projectIsInDefaultLocation = Path.GetDirectoryName(ProjectId.ProjectFolder) == m_dirs.ProjectsDirectory; string sNewProjectFolder = projectIsInDefaultLocation ? - Path.Combine(DirectoryFinder.ProjectsDirectory, sNewProjectName) : ProjectId.ProjectFolder; + Path.Combine(m_dirs.ProjectsDirectory, sNewProjectName) : ProjectId.ProjectFolder; if (FileUtils.NonEmptyDirectoryExists(sNewProjectFolder)) return false; // Destination directory already exists @@ -758,7 +764,7 @@ public override bool RenameDatabase(string sNewProjectName) ProjectId.Path = newFile; m_stopLoadDomain = true; - m_lockFile = LockProject(newFile); + LockProject(); } catch { @@ -1120,7 +1126,7 @@ public void Dispose() /// protected virtual void Dispose(bool fDisposing) { - System.Diagnostics.Debug.WriteLineIf(!fDisposing, "****** Missing Dispose() call for " + GetType().Name + ". ****** "); + Debug.WriteLineIf(!fDisposing, "****** Missing Dispose() call for " + GetType().Name + ". ****** "); if (fDisposing && !IsDisposed) { // dispose managed and unmanaged objects diff --git a/Src/FDO/Infrastructure/UndoableUnitOfWorkHelper.cs b/Src/FDO/Infrastructure/UndoableUnitOfWorkHelper.cs index 0613bc2145..fa0d2334d8 100644 --- a/Src/FDO/Infrastructure/UndoableUnitOfWorkHelper.cs +++ b/Src/FDO/Infrastructure/UndoableUnitOfWorkHelper.cs @@ -7,7 +7,6 @@ using System; using SIL.FieldWorks.Common.COMInterfaces; -using XCore; namespace SIL.FieldWorks.FDO.Infrastructure { @@ -79,17 +78,6 @@ public static void Do(string undoText, string redoText, ICmObject obj, Action ta Do(undoText, redoText, obj.Cache.ServiceLocator.GetInstance(), task); } - /// - /// Perform the specified task, making it an undoable task in the action handler - /// associated with the input ICmObject, with the labels determined by the command. The task will - /// automatically be begun and ended if all goes well, and rolled back if an exception - /// is thrown. (The exception will then be rethrown.) - /// - public static void Do(Command command, ICmObject obj, Action task) - { - Do(command.UndoText, command.RedoText, obj, task); - } - /// ------------------------------------------------------------------------------------ /// /// Perform the specified task, making it an undoable task in the action handler if diff --git a/Src/FDO/LinkedFilesRelativePathHelper.cs b/Src/FDO/LinkedFilesRelativePathHelper.cs new file mode 100644 index 0000000000..a2077fa7a4 --- /dev/null +++ b/Src/FDO/LinkedFilesRelativePathHelper.cs @@ -0,0 +1,292 @@ +// Copyright (c) 2013-2014 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) + +using System; +using System.IO; +using SIL.CoreImpl; +using SIL.Utils; + +namespace SIL.FieldWorks.FDO +{ + /// + /// This class is designed for converting between relative paths and full paths for the LinkedFiles of a FW project + /// + public static class LinkedFilesRelativePathHelper + { + /// Substitution string for a path that is under the LinkedFiles directory. + public const string ksLFrelPath = "%lf%"; + /// Substitution string for a path that is under the project's directory. + public const string ksProjectRelPath = "%proj%"; + /// Substitution string for a path that is under the default directory for projects. + public const string ksProjectsRelPath = "%Projects%"; + /// Substitution string for a path that is under the My Documents directory. + public const string ksMyDocsRelPath = "%MyDocuments%"; + /// Substitution string for a path that is under the Shared Application Data directory. + public const string ksCommonAppDataRelPath = "%CommonApplicationData%"; + + #region Methods to covert between RelativePaths and FullPaths + + /// + /// If a filePath is stored in the format %lf%\path\filename then this method returns the full path. + /// Otherwise return null + /// + /// + /// + /// + public static String GetFullFilePathFromRelativeLFPath(string relativePath, string projectLinkedFilesPath) + { + String fullfilePath = null; + fullfilePath = GetFullPathForRelativePath(relativePath, ksLFrelPath, projectLinkedFilesPath); + + if (String.IsNullOrEmpty(fullfilePath)) + return null; + return FixPathSlashesIfNeeded(fullfilePath); + } + + /// + /// If a file path is non rooted then return combination of the linkedFiledRootDir and the relative + /// path. Otherwise just return the full path passed in as an arguement. + /// + /// + /// + /// + public static String GetFullPathFromRelativeLFPath(string relativeLFPath, string linkedFilesRootDir) + { + // We could just catch the exception that IsPathRooted throws if there are invalid characters, + // or use Path.GetInvalidPathChars(). But that would pass things on Linux that will fail on Windows, + // which both makes unit testing difficult, and also may hide from Linux users the fact that their + // paths will cause problems on Windows. + var invalidChars = MiscUtils.GetInvalidProjectNameChars(MiscUtils.FilenameFilterStrength.kFilterProjName); + // relativeLFPath is allowed to include directories. And it MAY be rooted, meaning on Windows it could start X: + invalidChars = invalidChars.Replace(@"\", "").Replace("/", "").Replace(":", ""); + // colon is allowed only as second character--such a path is probably no good on Linux, but will just be not found, not cause a crash + int indexOfColon = relativeLFPath.IndexOf(':'); + if (relativeLFPath.IndexOfAny(invalidChars.ToCharArray()) != -1 + || (indexOfColon != -1 && indexOfColon != 1)) + { + // This is a fairly clumsy solution, designed as a last-resort way to avoid crashing the program. + // Hopefully most paths for entering path names into the relevant fields do something nicer to + // avoid getting illegal characters there. + return FixPathSlashesIfNeeded(Path.Combine(linkedFilesRootDir, "__ILLEGALCHARS__")); + } + if (Path.IsPathRooted(relativeLFPath)) + return FixPathSlashesIfNeeded(relativeLFPath); + else + return FixPathSlashesIfNeeded(Path.Combine(linkedFilesRootDir, relativeLFPath)); + } + + /// + /// If a path gets stored with embedded \, fix it to work away from Windows. (FWNX-882) + /// + public static string FixPathSlashesIfNeeded(string path) + { + if (string.IsNullOrEmpty(path)) + return string.Empty; + if (MiscUtils.IsUnix || MiscUtils.IsMac) + { + if (path.Contains("\\")) + return path.Replace('\\', '/'); + } + return path; + } + + /// + /// If the path is relative to the project's linkedFiles path then substitute %lf% + /// and return it. Otherwise return an empty string + /// + /// + /// + /// + public static string GetRelativeLFPathFromFullFilePath(string filePath, + string projectLinkedFilesPath) + { + if (string.IsNullOrEmpty(projectLinkedFilesPath)) + return string.Empty; + + var linkedFilesPathLowercaseRoot = GetPathWithLowercaseRoot(filePath); + + var relativePath = GetRelativePathIfExists(ksLFrelPath, linkedFilesPathLowercaseRoot, + projectLinkedFilesPath); + if (!string.IsNullOrEmpty(relativePath)) + return FixPathSlashesIfNeeded(relativePath); + //Just return an empty path if we cannot find a relative path. + return string.Empty; + } + + /// + /// If the specified path starts with the LinkedFiles root directory then return + /// the part after the linkedFilesRootDir; + /// otherwise if it is a file path at all convert it to the current platform and return it; + /// otherwise (it's a URL, determined by containing a colon after more than one initial character) + /// return null to indicate no change made. + /// + /// + /// + /// + public static string GetRelativeLinkedFilesPath(string filePath, + string linkedFilesRootDir) + { + if (filePath.IndexOf(':') > 1) + { + // It's a URL, not a path at all; don't mess with it. + return null; + } + string directory = FileUtils.ChangePathToPlatform(linkedFilesRootDir); + string relativePath = FileUtils.ChangePathToPlatform(filePath); + + // Does the specified path start with the LinkedFiles root directory? + if (relativePath.StartsWith(directory, true, System.Globalization.CultureInfo.InvariantCulture) && + relativePath.Length > directory.Length + 1) + { + // Keep the portion of the specified path that is a subfolder of + // the LinkedFiles folder and make sure to strip off an initial + // path separator if there is one. + relativePath = relativePath.Substring(directory.Length); + if (relativePath[0] == Path.DirectorySeparatorChar) + relativePath = relativePath.Substring(1); + } + return FixPathSlashesIfNeeded(relativePath); + } + + /// + /// Return the fullPath for a project's LinkedFiles based on the relative path that was persisted. + /// If no match on a relativePath match is made then return the relativePath passed in assuming it + /// is actually a full path. + /// + /// + /// + /// + /// + public static String GetLinkedFilesFullPathFromRelativePath(string projectsPath, string relativePath, String projectPath) + { + String fullPath = null; + fullPath = GetFullPathForRelativePath(relativePath, ksProjectRelPath, projectPath); + + if (String.IsNullOrEmpty(fullPath)) + fullPath = GetFullPathForRelativePath(relativePath, ksProjectsRelPath, + projectsPath); + if (String.IsNullOrEmpty(fullPath)) + fullPath = GetFullPathForRelativePath(relativePath, ksCommonAppDataRelPath, + DirectoryFinder.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); + if (String.IsNullOrEmpty(fullPath)) + fullPath = GetFullPathForRelativePath(relativePath, ksMyDocsRelPath, + DirectoryFinder.GetFolderPath(Environment.SpecialFolder.MyDocuments)); + if (String.IsNullOrEmpty(fullPath)) + return FixPathSlashesIfNeeded(relativePath); + return FixPathSlashesIfNeeded(fullPath); + } + + private static String GetFullPathForRelativePath(String relativePath, String relativePart, String fullPathReplacement) + { + if (relativePath.StartsWith(relativePart)) + { + var length = relativePart.Length; + var restOfPath = relativePath.Substring(length, relativePath.Length - length); + return fullPathReplacement + restOfPath; + } + else + { + return string.Empty; + } + } + + /// + /// Get a relative path for the LinkedFilesPath which we will persist to be used when + /// restoring a project. + /// + /// + /// + /// + /// + /// + public static string GetLinkedFilesRelativePathFromFullPath(string projectsPath, string linkedFilesFullPath, + string projectPath, string projectName) + { + var linkedFilesPathLowercaseRoot = GetPathWithLowercaseRoot(linkedFilesFullPath); + // Case where the ExternalLinks folder is located somewhere under the project folder. + // This is the default location. + var relativePath = GetRelativePathIfExists(ksProjectRelPath, linkedFilesPathLowercaseRoot, + projectPath); + if (!string.IsNullOrEmpty(relativePath)) + return FixPathSlashesIfNeeded(relativePath); + // GetRelativePathIfExists may miss a case where, say, projectPath is + // \\ls-thomson-0910.dallas.sil.org\Projects\MyProj, and linkedFilesFullPath is + // C:\Documents and settings\All Users\SIL\FieldWorks\Projects\MyProj\LinkedFiles + // Even though the MyProj directory in both paths is the same directory. + // It's important to catch this case and return a relative path. + var projectFolderName = Path.GetFileName(projectPath); + var allProjectsName = Path.GetFileName(Path.GetDirectoryName(projectPath)); + var match = Path.Combine(allProjectsName, projectFolderName); + int index = linkedFilesFullPath.IndexOf(match, StringComparison.InvariantCultureIgnoreCase); + if (index >= 0) + { + // There's a very good chance these are the same folders! + var alternateProjectPath = linkedFilesFullPath.Substring(0, index + match.Length); + if (Directory.Exists(alternateProjectPath) && + Directory.GetLastWriteTime(alternateProjectPath) == Directory.GetLastWriteTime(projectPath)) + { + // They ARE the same directory! (I suppose we could miss if someone wrote to it at the + // exact wrong moment, but we shouldn't be changing this setting while shared, anyway.) + return FixPathSlashesIfNeeded(ksProjectRelPath + linkedFilesFullPath.Substring(index + match.Length)); + } + } + + //See if linkedFilesPath begins with one of the other standard paths. + + // Case where user is presumably having a LinkedFiles folder shared among a number + // of projects under the Projects folder. That would be a good reason to put it in + // the projects folder common to all projects. + relativePath = GetRelativePathIfExists(ksProjectsRelPath, linkedFilesPathLowercaseRoot, projectsPath); + if (!String.IsNullOrEmpty(relativePath)) + return FixPathSlashesIfNeeded(relativePath); + + // Case where the user has the LinkedFiles folder in a shared folder. + relativePath = GetRelativePathIfExists(ksCommonAppDataRelPath, + linkedFilesPathLowercaseRoot, DirectoryFinder.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)); + if (!string.IsNullOrEmpty(relativePath)) + return FixPathSlashesIfNeeded(relativePath); + + // Case where the user has the LinkedFiles folder in their MyDocuments folder + relativePath = GetRelativePathIfExists(ksMyDocsRelPath, + linkedFilesPathLowercaseRoot, + DirectoryFinder.GetFolderPath(Environment.SpecialFolder.MyDocuments)); + if (!string.IsNullOrEmpty(relativePath)) + return FixPathSlashesIfNeeded(relativePath); + + //Just return the complete path if we cannot find a relative path. + return FixPathSlashesIfNeeded(linkedFilesFullPath); + } + + private static string GetRelativePathIfExists(string relativePart, string fullPath, + string parentPath) + { + var parentPathLowerCaseRoot = GetPathWithLowercaseRoot(parentPath); + if (!string.IsNullOrEmpty(parentPathLowerCaseRoot) && + fullPath.StartsWith(parentPathLowerCaseRoot)) + { + var length = parentPath.Length; + var restOfPath = fullPath.Substring(length, fullPath.Length - length); + return relativePart + restOfPath; + } + return string.Empty; + } + + private static string GetPathWithLowercaseRoot(string path) + { + try + { + var rootOfPath = Path.GetPathRoot(path); + return rootOfPath.ToLowerInvariant() + + path.Substring(rootOfPath.Length, path.Length - rootOfPath.Length); + } + catch (ArgumentException e) + { + return path.ToLowerInvariant(); + } + } + + + #endregion + } +} \ No newline at end of file diff --git a/Src/Common/FwUtils/ProjectInfo.cs b/Src/FDO/ProjectInfo.cs similarity index 78% rename from Src/Common/FwUtils/ProjectInfo.cs rename to Src/FDO/ProjectInfo.cs index 7ae4f37b3e..a1943a1e12 100644 --- a/Src/Common/FwUtils/ProjectInfo.cs +++ b/Src/FDO/ProjectInfo.cs @@ -10,7 +10,7 @@ using System.IO; using System.Linq; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.FieldWorks.FDO { /// ---------------------------------------------------------------------------------------- /// @@ -54,26 +54,23 @@ public ProjectInfo(string databaseName) /// /// Set of ProjectInfo objects, representing the projects on server /// ------------------------------------------------------------------------------------ - public static List AllProjects + public static List GetAllProjects(string projectsDir) { - get + // Ensure that the folder actually contains a project data file. + List projectList = new List(); + string[] projectDirectories = Directory.GetDirectories(projectsDir); + foreach (var dir in projectDirectories) { - // Ensure that the folder actually contains a project data file. - List projectList = new List(); - string[] projectDirectories = Directory.GetDirectories(DirectoryFinder.ProjectsDirectory); - foreach (var dir in projectDirectories) - { - string basename = Path.GetFileName(dir); - if (File.Exists(Path.Combine(dir, basename + Resources.FwFileExtensions.ksFwDataXmlFileExtension)) || - File.Exists(Path.Combine(dir, basename + Resources.FwFileExtensions.ksFwDataDb4oFileExtension))) - { - projectList.Add(new ProjectInfo(basename)); - } + string basename = Path.GetFileName(dir); + if (File.Exists(Path.Combine(dir, basename + FdoFileHelper.ksFwDataXmlFileExtension)) || + File.Exists(Path.Combine(dir, basename + FdoFileHelper.ksFwDataDb4oFileExtension))) + { + projectList.Add(new ProjectInfo(basename)); } - //projectList.AddRange(projectDirectories.Select(sFolder => new ProjectInfo(Path.GetFileName(sFolder)))); - return projectList; } + //projectList.AddRange(projectDirectories.Select(sFolder => new ProjectInfo(Path.GetFileName(sFolder)))); + return projectList; } #endregion @@ -94,12 +91,13 @@ public override string ToString() /// Get the specified project info if it exists given the UI name (i.e., without path) /// on the local machine. /// + /// /// specified project name (without path) /// the project info for the specified name; otherwise null /// ------------------------------------------------------------------------------------ - public static ProjectInfo GetProjectInfoByName(string projectName) + public static ProjectInfo GetProjectInfoByName(string projectsDir, string projectName) { - return AllProjects.FirstOrDefault(info => ProjectsAreSame(projectName, info.DatabaseName)); + return GetAllProjects(projectsDir).FirstOrDefault(info => ProjectsAreSame(projectName, info.DatabaseName)); } /// ------------------------------------------------------------------------------------ diff --git a/Src/FDO/Properties/Resources.Designer.cs b/Src/FDO/Properties/Resources.Designer.cs index 0bd9356c3b..617a9f9e80 100644 --- a/Src/FDO/Properties/Resources.Designer.cs +++ b/Src/FDO/Properties/Resources.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.239 +// Runtime Version:4.0.30319.18052 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -9,173 +9,148 @@ //------------------------------------------------------------------------------ namespace SIL.FieldWorks.FDO.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SIL.FieldWorks.FDO.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to Loading the initial Parts of Speech. - /// - internal static string ksLoadingPartsOfSpeech { - get { - return ResourceManager.GetString("ksLoadingPartsOfSpeech", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Loading the Semantic Domain List. - /// - internal static string ksLoadingSemanticDomains { - get { - return ResourceManager.GetString("ksLoadingSemanticDomains", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Creating new database.... - /// - internal static string kstidCreatingDB { - get { - return ResourceManager.GetString("kstidCreatingDB", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to FieldWorks 6.0 (or earlier) backup. - /// - internal static string kstidFw60OrEarlierBackupComment { - get { - return ResourceManager.GetString("kstidFw60OrEarlierBackupComment", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to FieldWorks 6.0 XML file. - /// - internal static string kstidFw60XmlBackupComment { - get { - return ResourceManager.GetString("kstidFw60XmlBackupComment", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Initializing new database.... - /// - internal static string kstidInitializingDB { - get { - return ResourceManager.GetString("kstidInitializingDB", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to File is not a valid FieldWorks project file.. - /// - internal static string kstidInvalidFieldWorksXMLFile { - get { - return ResourceManager.GetString("kstidInvalidFieldWorksXMLFile", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to FieldWorks cannot open the project {0} because another program is using it. Please close the other program and try again. Note: this can sometimes occur when there appears to be no other program using the file. The simplest way to fix this is to log off and on again. Other options are discussed in Help.. - /// - internal static string kstidLockFileLocked { - get { - return ResourceManager.GetString("kstidLockFileLocked", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to There was a problem opening the current version of the file {0}, dated {1}. Would you like to open the automatic backup, {2}, dated {3}?. - /// - internal static string kstidOfferToRestore { - get { - return ResourceManager.GetString("kstidOfferToRestore", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Problem opening file. - /// - internal static string kstidProblemOpeningFile { - get { - return ResourceManager.GetString("kstidProblemOpeningFile", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to This project is for a newer version of FieldWorks. - /// - ///To open this project, click Close, and then install the newer version of FieldWorks. - ///To revert to a version of this project which is compatible with this version of FieldWorks, click Restore a Project.. - /// - internal static string kstidProjectIsForNewerVersionOfFw { - get { - return ResourceManager.GetString("kstidProjectIsForNewerVersionOfFw", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to {0} has {1} entries referenced by {2} senses.. - /// - internal static string kstidReversalIndexDeletionText { - get { - return ResourceManager.GetString("kstidReversalIndexDeletionText", resourceCulture); - } - } - - internal static System.Drawing.Bitmap question { - get { - object obj = ResourceManager.GetObject("question", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - } + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SIL.FieldWorks.FDO.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Loading the initial Grammatical Categories. + /// + internal static string ksLoadingPartsOfSpeech { + get { + return ResourceManager.GetString("ksLoadingPartsOfSpeech", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Loading the Semantic Domain List. + /// + internal static string ksLoadingSemanticDomains { + get { + return ResourceManager.GetString("ksLoadingSemanticDomains", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Creating new database.... + /// + internal static string kstidCreatingDB { + get { + return ResourceManager.GetString("kstidCreatingDB", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to FieldWorks 6.0 (or earlier) backup. + /// + internal static string kstidFw60OrEarlierBackupComment { + get { + return ResourceManager.GetString("kstidFw60OrEarlierBackupComment", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to FieldWorks 6.0 XML file. + /// + internal static string kstidFw60XmlBackupComment { + get { + return ResourceManager.GetString("kstidFw60XmlBackupComment", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Initializing new database.... + /// + internal static string kstidInitializingDB { + get { + return ResourceManager.GetString("kstidInitializingDB", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to File is not a valid FieldWorks project file.. + /// + internal static string kstidInvalidFieldWorksXMLFile { + get { + return ResourceManager.GetString("kstidInvalidFieldWorksXMLFile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to FieldWorks cannot open the project {0} because another program is using it. Please close the other program and try again. Note: this can sometimes occur when there appears to be no other program using the file. The simplest way to fix this is to log off and on again. Other options are discussed in Help.. + /// + internal static string kstidLockFileLocked { + get { + return ResourceManager.GetString("kstidLockFileLocked", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This project is for a newer version of FieldWorks. + /// + ///To open this project, click Close, and then install the newer version of FieldWorks. + ///To revert to a version of this project which is compatible with this version of FieldWorks, click Restore a Project.. + /// + internal static string kstidProjectIsForNewerVersionOfFw { + get { + return ResourceManager.GetString("kstidProjectIsForNewerVersionOfFw", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} has {1} entries referenced by {2} senses.. + /// + internal static string kstidReversalIndexDeletionText { + get { + return ResourceManager.GetString("kstidReversalIndexDeletionText", resourceCulture); + } + } + } } diff --git a/Src/FDO/Properties/Resources.resx b/Src/FDO/Properties/Resources.resx index 39451c7c1f..17ee344fb4 100644 --- a/Src/FDO/Properties/Resources.resx +++ b/Src/FDO/Properties/Resources.resx @@ -1,171 +1,160 @@  - + 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. + --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - text/microsoft-resx + text/microsoft-resx - 2.0 + 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Creating new database... - Displayed in the progress dialog box when creating a new FieldWorks project + Creating new database... + Displayed in the progress dialog box when creating a new FieldWorks project - Initializing new database... - Displayed in the progress dialog box when creating a new FieldWorks project + Initializing new database... + Displayed in the progress dialog box when creating a new FieldWorks project - Loading the Semantic Domain List + Loading the Semantic Domain List - File is not a valid FieldWorks project file. - Error message when the user attempts to load a file as a FW project when it isn't. + File is not a valid FieldWorks project file. + Error message when the user attempts to load a file as a FW project when it isn't. - {0} has {1} entries referenced by {2} senses. - format for creating the deletion text for a ReversalIndex object - - - There was a problem opening the current version of the file {0}, dated {1}. Would you like to open the automatic backup, {2}, dated {3}? + {0} has {1} entries referenced by {2} senses. + format for creating the deletion text for a ReversalIndex object - Loading the initial Grammatical Categories - - - Problem opening file - Caption for error dialog - - - - ../Resources/question.ico;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + Loading the initial Grammatical Categories - This project is for a newer version of FieldWorks. + This project is for a newer version of FieldWorks. To open this project, click Close, and then install the newer version of FieldWorks. To revert to a version of this project which is compatible with this version of FieldWorks, click Restore a Project. - FieldWorks 6.0 (or earlier) backup - Comment associated with a backup from FieldWorks 6.0 or earlier (shown in Restore a Project dialog box) + FieldWorks 6.0 (or earlier) backup + Comment associated with a backup from FieldWorks 6.0 or earlier (shown in Restore a Project dialog box) - FieldWorks 6.0 XML file - Comment associated with an XML backup from FieldWorks 6.0 (shown in Restore a Project dialog box) + FieldWorks 6.0 XML file + Comment associated with an XML backup from FieldWorks 6.0 (shown in Restore a Project dialog box) - FieldWorks cannot open the project {0} because another program is using it. Please close the other program and try again. Note: this can sometimes occur when there appears to be no other program using the file. The simplest way to fix this is to log off and on again. Other options are discussed in Help. - Must contain {0} which is a project name + FieldWorks cannot open the project {0} because another program is using it. Please close the other program and try again. Note: this can sometimes occur when there appears to be no other program using the file. The simplest way to fix this is to log off and on again. Other options are discussed in Help. + Must contain {0} which is a project name \ No newline at end of file diff --git a/Src/FDO/SilentFdoUI.cs b/Src/FDO/SilentFdoUI.cs new file mode 100644 index 0000000000..2b5e997661 --- /dev/null +++ b/Src/FDO/SilentFdoUI.cs @@ -0,0 +1,157 @@ +// Copyright (c) 2013-2014 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) + +using System; +using System.ComponentModel; + +namespace SIL.FieldWorks.FDO +{ + /// + /// Silent implementation of FdoUserAction with reasonable defaults for + /// actions which should not require user intervention + /// + public class SilentFdoUI : IFdoUI + { + private readonly ISynchronizeInvoke m_synchronizeInvoke; + + /// + /// Initializes a new instance of the class. + /// + /// The synchronize invoke. + public SilentFdoUI(ISynchronizeInvoke synchronizeInvoke) + { + m_synchronizeInvoke = synchronizeInvoke; + } + + /// + /// Gets the object that is used to invoke methods on the main UI thread. + /// + public ISynchronizeInvoke SynchronizeInvoke + { + get { return m_synchronizeInvoke; } + } + + /// + /// Check with user regarding conflicting changes + /// + /// True if user wishes to revert to saved state. False otherwise. + public bool ConflictingSave() + { + // Assume saved data is correct data + return true; + } + + /// + /// Inform the user of a lost connection + /// + /// True if user wishes to attempt reconnect. False otherwise. + public bool ConnectionLost() + { + // Assume we don't to continue to attempt to reconnect endlessly + return false; + } + + /// + /// Gets the last time that there was user activity. + /// + public DateTime LastActivityTime + { + get { return DateTime.Now; } + } + + /// + /// Check with user regarding which files to use + /// + /// + public FileSelection ChooseFilesToUse() + { + // Assume newer files are correct files + return FileSelection.OkKeepNewer; + } + + /// + /// Check with user regarding restoring linked files in the project folder or original path + /// + /// True if user wishes to restore linked files in project folder. False to leave them in the original location. + public bool RestoreLinkedFilesInProjectFolder() + { + // Assume linked files go in project folder + return true; + } + + /// + /// Cannot restore linked files to original path. + /// Check with user regarding restoring linked files in the project folder or not at all + /// + /// OkYes to restore to project folder, OkNo to skip restoring linked files, Cancel otherwise + public YesNoCancel CannotRestoreLinkedFilesToOriginalLocation() + { + // Assume linked files go in project folder + return YesNoCancel.OkYes; + } + + /// + /// Displays information to the user + /// + /// + /// + /// + /// + public void DisplayMessage(MessageType type, string message, string caption, string helpTopic) + { + // Informational only + } + + /// + /// Show a dialog or output to the error log, as appropriate. + /// + /// the exception you want to report + /// set to true if the error is lethal, otherwise + /// false. + public void ReportException(Exception error, bool isLethal) + { + // Informational only + } + + /// + /// Reports duplicate guids to the user + /// + /// The error text. + public void ReportDuplicateGuids(string errorText) + { + // Informational only + } + + /// + /// Ask user if they wish to restore an XML project from a backup project file. + /// + /// The project path. + /// The backup path. + /// + /// + public bool OfferToRestore(string projectPath, string backupPath) + { + return true; + } + + /// + /// Exits the application. + /// + public void Exit() + { + Environment.Exit(0); + } + + /// + /// Present a message to the user and allow the options to Retry or Cancel + /// + /// The message. + /// The caption. + /// True to retry. False otherwise + public bool Retry(string msg, string caption) + { + return false; + } + } +} diff --git a/Src/FDO/Strings.Designer.cs b/Src/FDO/Strings.Designer.cs index 8434cf46f0..4a24660f44 100644 --- a/Src/FDO/Strings.Designer.cs +++ b/Src/FDO/Strings.Designer.cs @@ -213,6 +213,15 @@ internal static string ksAllProjectsMustDisconnectClients { } } + /// + /// Looks up a localized string similar to analysis. + /// + internal static string ksAnalysis { + get { + return ResourceManager.GetString("ksAnalysis", resourceCulture); + } + } + /// /// Looks up a localized string similar to Anth. /// @@ -259,20 +268,24 @@ internal static string ksAX { } /// - /// Looks up a localized string similar to Background is {0}. + /// Looks up a localized string similar to Writing out backup file.... /// - internal static string ksBackgroundIsX { + internal static string ksBackupClosing { get { - return ResourceManager.GetString("ksBackgroundIsX", resourceCulture); + return ResourceManager.GetString("ksBackupClosing", resourceCulture); } } /// - /// Looks up a localized string similar to Writing out backup file.... + /// Looks up a localized string similar to Backup file contains a version of the project which was created using a newer version of FieldWorks: + ///{0} + /// + ///To restore from this backup, install version {1} of FieldWorks. + ///. /// - internal static string ksBackupClosing { + internal static string ksBackupFileCreatedByNewerFwVersion { get { - return ResourceManager.GetString("ksBackupClosing", resourceCulture); + return ResourceManager.GetString("ksBackupFileCreatedByNewerFwVersion", resourceCulture); } } @@ -361,15 +374,6 @@ internal static string ksBlankSense { } } - /// - /// Looks up a localized string similar to Bold. - /// - internal static string ksBold { - get { - return ResourceManager.GetString("ksBold", resourceCulture); - } - } - /// /// Looks up a localized string similar to Could not connect to server. Check that {0} is running on the remote server and that any firewalls are configured to allow connections to it.. /// @@ -435,42 +439,6 @@ internal static string ksCannotWriteBackup { } } - /// - /// Looks up a localized string similar to The default discourse chart template cannot be deleted, moved or promoted.. - /// - internal static string ksCantDeleteDefaultDiscourseTemplate { - get { - return ResourceManager.GetString("ksCantDeleteDefaultDiscourseTemplate", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The last remaining Text Markup tag list cannot be deleted.. - /// - internal static string ksCantDeleteLastTagList { - get { - return ResourceManager.GetString("ksCantDeleteLastTagList", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to You cannot delete a Text Markup tag when there are texts using the tag. One such text using this tag is {0}.. - /// - internal static string ksCantDeleteMarkupTagInUse { - get { - return ResourceManager.GetString("ksCantDeleteMarkupTagInUse", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to You cannot delete a Text Markup type when there are texts using its tags. One such text using this type of tag is {0}.. - /// - internal static string ksCantDeleteMarkupTypeInUse { - get { - return ResourceManager.GetString("ksCantDeleteMarkupTypeInUse", resourceCulture); - } - } - /// /// Looks up a localized string similar to This part of a chart template cannot be moved or deleted, because it or one of its children is in use in one or more charts (e.g., {0}).. /// @@ -516,24 +484,6 @@ internal static string ksCliticNoCatInfo { } } - /// - /// Looks up a localized string similar to {0} Strikethrough. - /// - internal static string ksColorStrikethrough { - get { - return ResourceManager.GetString("ksColorStrikethrough", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to {0} Underline. - /// - internal static string ksColorUnderline { - get { - return ResourceManager.GetString("ksColorUnderline", resourceCulture); - } - } - /// /// Looks up a localized string similar to It contains 1 lexical relation or cross reference.. /// @@ -624,33 +574,6 @@ internal static string ksConvertingToShared { } } - /// - /// Looks up a localized string similar to FieldWorks was not able to back up some of the files used by this project. Do you want to keep the backup anyway? The files not backed up were {0}. - /// - internal static string ksCouldNotBackupSomeFiles { - get { - return ResourceManager.GetString("ksCouldNotBackupSomeFiles", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Dashed {0} Underline. - /// - internal static string ksDashedColorUnderline { - get { - return ResourceManager.GetString("ksDashedColorUnderline", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Dashed Underline. - /// - internal static string ksDashedUnderline { - get { - return ResourceManager.GetString("ksDashedUnderline", resourceCulture); - } - } - /// /// Looks up a localized string similar to Data Migration. /// @@ -903,42 +826,6 @@ internal static string ksDelWfGlossUsedXTimes { } } - /// - /// Looks up a localized string similar to Dotted {0} Underline. - /// - internal static string ksDottedColorUnderline { - get { - return ResourceManager.GetString("ksDottedColorUnderline", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Dotted Underline. - /// - internal static string ksDottedUnderline { - get { - return ResourceManager.GetString("ksDottedUnderline", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Double {0} Underline. - /// - internal static string ksDoubleColorUnderline { - get { - return ResourceManager.GetString("ksDoubleColorUnderline", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Double Underline. - /// - internal static string ksDoubleUnderline { - get { - return ResourceManager.GetString("ksDoubleUnderline", resourceCulture); - } - } - /// /// Looks up a localized string similar to There are duplicate guids in this project.. /// @@ -1085,15 +972,6 @@ internal static string ksExtractingFromZip { } } - /// - /// Looks up a localized string similar to Failed. - /// - internal static string ksFailed { - get { - return ResourceManager.GetString("ksFailed", resourceCulture); - } - } - /// /// Looks up a localized string similar to Failed to start server: ///{0}. @@ -1132,6 +1010,15 @@ internal static string ksHomographLimits { } } + /// + /// Looks up a localized string similar to Style {0} could not be added because an incompatible style with the same name already exists.. + /// + internal static string ksIncompatibleStyleExists { + get { + return ResourceManager.GetString("ksIncompatibleStyleExists", resourceCulture); + } + } + /// /// Looks up a localized string similar to Inflects any category. /// @@ -1196,11 +1083,11 @@ internal static string ksInvalidForm0Trailing1 { } /// - /// Looks up a localized string similar to {0} is not a valid directory for linked files. Please select a valid directory.. + /// Looks up a localized string similar to File is not a valid FieldWorks backup:. /// - internal static string ksInvalidLinkedFilesFolder { + internal static string ksInvalidFwBackupFile { get { - return ResourceManager.GetString("ksInvalidLinkedFilesFolder", resourceCulture); + return ResourceManager.GetString("ksInvalidFwBackupFile", resourceCulture); } } @@ -1411,15 +1298,6 @@ internal static string ksIsUsedXTimesInTexts { } } - /// - /// Looks up a localized string similar to Italic. - /// - internal static string ksItalic { - get { - return ResourceManager.GetString("ksItalic", resourceCulture); - } - } - /// /// Looks up a localized string similar to lexeme form. /// @@ -1447,15 +1325,6 @@ internal static string ksLexRelation { } } - /// - /// Looks up a localized string similar to Linked Files Folder. - /// - internal static string ksLinkedFilesFolder { - get { - return ResourceManager.GetString("ksLinkedFilesFolder", resourceCulture); - } - } - /// /// Looks up a localized string similar to , . /// @@ -1474,15 +1343,6 @@ internal static string ksLocalConnectorServiceNotStarted { } } - /// - /// Looks up a localized string similar to Lowered by {0} pt. - /// - internal static string ksLoweredXpt { - get { - return ResourceManager.GetString("ksLoweredXpt", resourceCulture); - } - } - /// /// Looks up a localized string similar to a member of the word set(s) called. /// @@ -1618,24 +1478,6 @@ internal static string ksNatClassUsedHere { } } - /// - /// Looks up a localized string similar to FieldWorks has encountered a problem setting up the writing systems. It may be that you need to first log out and then back in. If that doesn't fix it, you can also try asking an administrator to add you to the fieldworks group by using the command: $ sudo adduser 'yourusername' fieldworks. - /// - internal static string ksNeedToJoinFwGroup { - get { - return ResourceManager.GetString("ksNeedToJoinFwGroup", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to No ({0}) Underline. - /// - internal static string ksNoColorUnderline { - get { - return ResourceManager.GetString("ksNoColorUnderline", resourceCulture); - } - } - /// /// Looks up a localized string similar to No explanation available.. /// @@ -1654,33 +1496,6 @@ internal static string ksNoForm { } } - /// - /// Looks up a localized string similar to No Super/Subscript. - /// - internal static string ksNoSuperSubscript { - get { - return ResourceManager.GetString("ksNoSuperSubscript", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Not advisable when other users connected. - /// - internal static string ksNotAdvisableOthersConnectedCaption { - get { - return ResourceManager.GetString("ksNotAdvisableOthersConnectedCaption", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Not Bold. - /// - internal static string ksNotBold { - get { - return ResourceManager.GetString("ksNotBold", resourceCulture); - } - } - /// /// Looks up a localized string similar to not evaluated yet. /// @@ -1708,24 +1523,6 @@ internal static string ksNothingToUndo { } } - /// - /// Looks up a localized string similar to Not Italic. - /// - internal static string ksNotItalic { - get { - return ResourceManager.GetString("ksNotItalic", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Not Raised/Lowered. - /// - internal static string ksNotRaisedLowered { - get { - return ResourceManager.GetString("ksNotRaisedLowered", resourceCulture); - } - } - /// /// Looks up a localized string similar to Not redoable. /// @@ -1754,11 +1551,11 @@ internal static string ksNotUndoable { } /// - /// Looks up a localized string similar to No Underline. + /// Looks up a localized string similar to FieldWorks project has no current {0} writing systems.. /// - internal static string ksNoUnderline { + internal static string ksNoWritingSystems { get { - return ResourceManager.GetString("ksNoUnderline", resourceCulture); + return ResourceManager.GetString("ksNoWritingSystems", resourceCulture); } } @@ -1789,15 +1586,6 @@ internal static string ksOtherClientsAreWriting { } } - /// - /// Looks up a localized string similar to Take care - other users connected. - /// - internal static string ksOthersConnectedCaption { - get { - return ResourceManager.GetString("ksOthersConnectedCaption", resourceCulture); - } - } - /// /// Looks up a localized string similar to If you delete the phoneme, it will be removed from:. /// @@ -1888,15 +1676,6 @@ internal static string ksQuestions { } } - /// - /// Looks up a localized string similar to Raised by {0} pt. - /// - internal static string ksRaisedXpt { - get { - return ResourceManager.GetString("ksRaisedXpt", resourceCulture); - } - } - /// /// Looks up a localized string similar to Redo Create Entry. /// @@ -1951,15 +1730,6 @@ internal static string ksRequiredItem { } } - /// - /// Looks up a localized string similar to Restoring from an old FieldWorks backup failed.. - /// - internal static string ksRestoringOldFwBackupFailed { - get { - return ResourceManager.GetString("ksRestoringOldFwBackupFailed", resourceCulture); - } - } - /// /// Looks up a localized string similar to Restoring {0} to a temporary project. /// @@ -1988,110 +1758,74 @@ internal static string ksReversalIndexPOSListName { } /// - /// Looks up a localized string similar to {0} (Heading). + /// Looks up a localized string similar to Footnote. /// - internal static string ksSectionHeading { + internal static string ksScriptureFootnote { get { - return ResourceManager.GetString("ksSectionHeading", resourceCulture); + return ResourceManager.GetString("ksScriptureFootnote", resourceCulture); } } /// - /// Looks up a localized string similar to The sense is being used in these contexts:. + /// Looks up a localized string similar to Introduction({0}). /// - internal static string ksSenseUsedHere { + internal static string ksScriptureSectionIntroduction { get { - return ResourceManager.GetString("ksSenseUsedHere", resourceCulture); + return ResourceManager.GetString("ksScriptureSectionIntroduction", resourceCulture); } } /// - /// Looks up a localized string similar to Short delay. + /// Looks up a localized string similar to Title. /// - internal static string ksShortDelayCaption { + internal static string ksScriptureTitle { get { - return ResourceManager.GetString("ksShortDelayCaption", resourceCulture); + return ResourceManager.GetString("ksScriptureTitle", resourceCulture); } } /// - /// Looks up a localized string similar to Single {0} Underline. - /// - internal static string ksSingleColorUnderline { - get { - return ResourceManager.GetString("ksSingleColorUnderline", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Single Underline. - /// - internal static string ksSingleUnderline { - get { - return ResourceManager.GetString("ksSingleUnderline", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to ***. - /// - internal static string ksStars { - get { - return ResourceManager.GetString("ksStars", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Stem/root of unknown category; takes any affix. - /// - internal static string ksStemNoCatInfo { - get { - return ResourceManager.GetString("ksStemNoCatInfo", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Strikethrough. + /// Looks up a localized string similar to {0} (Heading). /// - internal static string ksStrikethrough { + internal static string ksSectionHeading { get { - return ResourceManager.GetString("ksStrikethrough", resourceCulture); + return ResourceManager.GetString("ksSectionHeading", resourceCulture); } } /// - /// Looks up a localized string similar to Subscript. + /// Looks up a localized string similar to The sense is being used in these contexts:. /// - internal static string ksSubscript { + internal static string ksSenseUsedHere { get { - return ResourceManager.GetString("ksSubscript", resourceCulture); + return ResourceManager.GetString("ksSenseUsedHere", resourceCulture); } } /// - /// Looks up a localized string similar to Superscript. + /// Looks up a localized string similar to Short delay. /// - internal static string ksSuperscript { + internal static string ksShortDelayCaption { get { - return ResourceManager.GetString("ksSuperscript", resourceCulture); + return ResourceManager.GetString("ksShortDelayCaption", resourceCulture); } } /// - /// Looks up a localized string similar to Text is {0}. + /// Looks up a localized string similar to ***. /// - internal static string ksTextIsX { + internal static string ksStars { get { - return ResourceManager.GetString("ksTextIsX", resourceCulture); + return ResourceManager.GetString("ksStars", resourceCulture); } } /// - /// Looks up a localized string similar to Text is {0} on {1}. + /// Looks up a localized string similar to Stem/root of unknown category; takes any affix. /// - internal static string ksTextIsXonY { + internal static string ksStemNoCatInfo { get { - return ResourceManager.GetString("ksTextIsXonY", resourceCulture); + return ResourceManager.GetString("ksStemNoCatInfo", resourceCulture); } } @@ -2267,11 +2001,11 @@ internal static string ksUsedXTimesInRules { } /// - /// Looks up a localized string similar to Warning. + /// Looks up a localized string similar to vernacular. /// - internal static string ksWarning { + internal static string ksVernacular { get { - return ResourceManager.GetString("ksWarning", resourceCulture); + return ResourceManager.GetString("ksVernacular", resourceCulture); } } @@ -2302,32 +2036,6 @@ internal static string ksWarningProjectFolderNotFoundOnServer { } } - /// - /// Looks up a localized string similar to Number of other users: {0} - ///When saving changes in this dialog with other users connected, FieldWorks may crash or malfunction for those users. - /// - ///Do you want to make the changes anyway?. - /// - internal static string ksWarnOnConfirmingSingleUserChanges { - get { - return ResourceManager.GetString("ksWarnOnConfirmingSingleUserChanges", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Number of other users: {0} - ///The menu command you selected will open a dialog box. If you change any selections or settings in the dialog box, other users who have this project open on their computers will have problems. - /// - ///If you will only look at selections and settings, click OK. - /// - ///If you need to make changes, tell the other users to close this project before you continue, or click Cancel.. - /// - internal static string ksWarnOnOpeningSingleUserDialog { - get { - return ResourceManager.GetString("ksWarnOnOpeningSingleUserDialog", resourceCulture); - } - } - /// /// Looks up a localized string similar to You cannot delete this wordform because it is used as an occurrence of a biblical term ({0}) in Translation Editor.. /// @@ -2384,15 +2092,6 @@ internal static string ksWritingTempCopyAsFw60XMLFailed { } } - /// - /// Looks up a localized string similar to {0} pt. - /// - internal static string ksXPt { - get { - return ResourceManager.GetString("ksXPt", resourceCulture); - } - } - /// /// Looks up a localized string similar to 0. /// diff --git a/Src/FDO/Strings.resx b/Src/FDO/Strings.resx index 004415f119..c1cf4528fb 100644 --- a/Src/FDO/Strings.resx +++ b/Src/FDO/Strings.resx @@ -1,17 +1,17 @@ - @@ -169,10 +169,6 @@ A {0} for instance "A CmObject" or "A ScrWidget" - - Background is {0} - text background color - The abbreviation for the class '{0}' was not found in the set of Natural Classes. @@ -185,27 +181,15 @@ The phoneme which begins '{0}' was not found in the set of representations for any Phoneme. - - Bold - The category is used in these contexts: - - {0} Underline - It contains 1 lexical relation or cross reference. It contains {0} lexical relations or cross references. - - Dashed {0} Underline - - - Dashed Underline - Deleting the allomorph will also delete them. @@ -232,18 +216,6 @@ {0}. Any texts that use it will need more analysis work, as it is used {1} times in your texts. {0} is a number (for showing a numbered list). - - Dotted {0} Underline - - - Dotted Underline - - - Double {0} Underline - - - Double Underline - <empty> @@ -346,9 +318,6 @@ {0}. Is being used {1} times in your texts. - - Italic - The lexical reference type is used in this context: @@ -356,10 +325,6 @@ , separate items in a list (comma space) - - Lowered by {0} pt - Font lowered by X points - There is a missing closing square bracket ']' somewhere around here: '{0}'. @@ -379,38 +344,15 @@ - separate name and abbreviation (space dash space) - - FieldWorks has encountered a problem setting up the writing systems. It may be that you need to first log out and then back in. If that doesn't fix it, you can also try asking an administrator to add you to the fieldworks group by using the command: $ sudo adduser 'yourusername' fieldworks - Used in Linux version if the user forgets to logout and back in after New Install. - - - No ({0}) Underline - nonsense, but a possibility - No explanation available. - - No Super/Subscript - - - Not Bold - not evaluated yet - - Not Italic - - - Not Raised/Lowered - <Not Sure> - - No Underline - *Orphan Annotation @@ -424,10 +366,6 @@ ??? default for an unknown/unrecognized/undefined value - - Raised by {0} pt - Font raised by X points - Redo Create Entry @@ -446,13 +384,6 @@ The Grammatical Info. (which will also be deleted) is being used in these contexts: - - Single {0} Underline - insert explicit color - - - Single Underline - *** indicates a missing value @@ -460,20 +391,6 @@ Stem/root of unknown category; takes any affix - - Subscript - - - Superscript - - - Text is {0} - text foreground color - - - Text is {0} on {1} - text foreground and background colors - today at {0} @@ -530,18 +447,11 @@ Sorry, FieldWorks cannot delete this wordform{1}because it is used {0} times in your texts. {1} is a line separator character. it is optional. - - {0} pt - size in "points" - The word or phrase is too long so the interlinearized wordform has been truncated to the maximum length. Try using the Tools/Guess Word Breaks tool on the baseline text, or insert word breaks into the text manually. - - Warning - The FDOBackendProviderType is not supported. @@ -640,10 +550,6 @@ on the baseline text, or insert word breaks into the text manually. Not undoable - - The default discourse chart template cannot be deleted, moved or promoted. - Error message attempting to delete the one and only discourse chart template. Same message is used for moving or promoting. - Deleting discourse charts for this text. @@ -656,18 +562,6 @@ on the baseline text, or insert word breaks into the text manually. {0}. Being used {1} times by rules. - - You cannot delete a Text Markup tag when there are texts using the tag. One such text using this tag is {0}. - {0} is (one) text that prevents the delete. - - - The last remaining Text Markup tag list cannot be deleted. - Error message attempting to delete the one and only text markup tag type. - - - You cannot delete a Text Markup type when there are texts using its tags. One such text using this type of tag is {0}. - {0} is (one) text that prevents the delete. - There are {0} homographs of {1}. FieldWorks currently supports a maximum of 255 distinct homographs. @@ -817,12 +711,6 @@ Your changes to this entry will be discarded when you exit the project. Error restoring from FieldWorks 6.0 (or earlier) backup - - Restoring from an old FieldWorks backup failed. - - - Failed - Could not connect to server. Check that {0} is running on the remote server and that any firewalls are configured to allow connections to it. Parameter is hard-coded service name (FwRemoteDatabaseConnectorService). This is a message targeted primarily at a computer savvy person. @@ -865,12 +753,6 @@ Your changes to this entry will be discarded when you exit the project. In order to continue with the conversion, you need to close the following projects: {0} {0} may be a single project name or a list. - - {0} Strikethrough - - - Strikethrough - {0} of {1} Pattern string for the contents of the "Subrecord Of" column in Notebook. {0} is a number, {1} is the title of the parent record. For example, the column might say "1.2.3 of Fishing for Piranha" to indicate that the current record is the third subrecord of the second subrecord of the first subrecord of the main record called "Fishing for Piranha". @@ -894,18 +776,6 @@ Your changes to this entry will be discarded when you exit the project. Undo Reset Homograph Numbers - - Number of other users: {0} -When saving changes in this dialog with other users connected, FieldWorks may crash or malfunction for those users. - -Do you want to make the changes anyway? - - - Not advisable when other users connected - - - Take care - other users connected - Cannot Restore Caption for ksCannotRestoreBackup message box @@ -929,17 +799,6 @@ Corrupted Record: Short delay Caption that goes with ksOtherClientsAreWriting - - FieldWorks was not able to back up some of the files used by this project. Do you want to keep the backup anyway? The files not backed up were {0} - - - Number of other users: {0} -The menu command you selected will open a dialog box. If you change any selections or settings in the dialog box, other users who have this project open on their computers will have problems. - -If you will only look at selections and settings, click OK. - -If you need to make changes, tell the other users to close this project before you continue, or click Cancel. - FieldWorks was unable to convert the project {0} because it was created by a more recent version of FieldWorks. To convert this project, install the appropriate version of FieldWorks, and turn sharing off then on again. (Note that doing this will upgrade all your projects to the newer version.) @@ -957,14 +816,6 @@ If you need to make changes, tell the other users to close this project before y Loading list member names Caption for progress dialog, when a new writing system is added - - Linked Files Folder - Caption for folder dialog, when setting a new LangProject.LinkedFilesRootDir value - - - {0} is not a valid directory for linked files. Please select a valid directory. - Error message for accessing an invalid LangProject.LinkedFilesRootDir value - Parts of Speech for {0} Reversal Index @@ -989,4 +840,37 @@ If you need to make changes, tell the other users to close this project before y Anthropology Categories + + analysis + + + Backup file contains a version of the project which was created using a newer version of FieldWorks: +{0} + +To restore from this backup, install version {1} of FieldWorks. + + + + Style {0} could not be added because an incompatible style with the same name already exists. + Error message when someone adds a style that has been added on another machine that is incompatible (e.g. because of different context, structure, etc). + + + File is not a valid FieldWorks backup: + + + FieldWorks project has no current {0} writing systems. + Message box displayed if count of current vernacular/analysis writing systems is 0. (parameter is either verncaular or analysis) + + + Footnote + + + Introduction({0}) + + + Title + + + vernacular + \ No newline at end of file diff --git a/Src/FDO/fdoCache.cs b/Src/FDO/fdoCache.cs index 6d7d086549..b5200b1570 100644 --- a/Src/FDO/fdoCache.cs +++ b/Src/FDO/fdoCache.cs @@ -11,23 +11,19 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using System.Windows.Forms; using System.Xml; using System.Runtime.InteropServices; using System.ComponentModel; using System.Xml.Linq; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.Application.ApplicationServices; using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.FDO.IOC; -using SIL.FieldWorks.Resources; using SIL.Utils; using SIL.FieldWorks.FDO.Application; using SIL.FieldWorks.FDO.Infrastructure; using SIL.CoreImpl; using SIL.FieldWorks.FDO.Infrastructure.Impl; -using SIL.Utils.FileDialog; namespace SIL.FieldWorks.FDO { @@ -42,9 +38,8 @@ namespace SIL.FieldWorks.FDO public sealed partial class FdoCache { #region Data Members - private ThreadHelper m_threadHelper; // FdoCache is NOT responsible to dispose this (typically FieldWorks.s_threadHelper) private IFdoServiceLocator m_serviceLocator; - private static object m_syncRoot = new object(); + private static readonly object m_syncRoot = new object(); /// /// This is the 'hvo' for null values. (This is not very identifiable, but unfortunately, a lot of code (e.g., in Views) knows that @@ -90,13 +85,13 @@ public sealed partial class FdoCache /// /// Identifies the new project to create. /// The ICU locale of the default user WS. - /// The thread helper used for invoking actions on the main - /// UI thread. + /// + /// /// ------------------------------------------------------------------------------------ public static FdoCache CreateCacheWithNoLangProj(IProjectIdentifier projectId, - string userWsIcuLocale, ThreadHelper threadHelper) + string userWsIcuLocale, IFdoUI ui, IFdoDirectories dirs) { - FdoCache createdCache = CreateCacheInternal(projectId, threadHelper); + FdoCache createdCache = CreateCacheInternal(projectId, ui, dirs); createdCache.FullyInitializedAndReadyToRock = true; return createdCache; } @@ -116,14 +111,14 @@ public static FdoCache CreateCacheWithNoLangProj(IProjectIdentifier projectId, /// system. /// The ICU locale of the default user writing /// system. - /// The thread helper used for invoking actions on the main - /// UI thread. + /// + /// /// ------------------------------------------------------------------------------------ public static FdoCache CreateCacheWithNewBlankLangProj(IProjectIdentifier projectId, string analWsIcuLocale, string vernWsIcuLocale, string userWsIcuLocale, - ThreadHelper threadHelper) + IFdoUI ui, IFdoDirectories dirs) { - FdoCache createdCache = CreateCacheInternal(projectId, userWsIcuLocale, threadHelper, + FdoCache createdCache = CreateCacheInternal(projectId, userWsIcuLocale, ui, dirs, dataSetup => dataSetup.CreateNewLanguageProject(projectId)); NonUndoableUnitOfWorkHelper.Do(createdCache.ActionHandlerAccessor, () => { @@ -142,13 +137,33 @@ public static FdoCache CreateCacheWithNewBlankLangProj(IProjectIdentifier projec /// /// Identifies the project to load. /// The ICU locale of the default user WS. + /// + /// /// The progress dialog box /// ------------------------------------------------------------------------------------ public static FdoCache CreateCacheFromExistingData(IProjectIdentifier projectId, - string userWsIcuLocale, IThreadedProgress progressDlg) + string userWsIcuLocale, IFdoUI ui, IFdoDirectories dirs, IThreadedProgress progressDlg) { - return CreateCacheInternal(projectId, userWsIcuLocale, progressDlg.ThreadHelper, - dataSetup => dataSetup.StartupExtantLanguageProject(projectId, true, progressDlg), + return CreateCacheFromExistingData(projectId, userWsIcuLocale, ui, dirs, progressDlg, false); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Creates a new FdoCache that uses a specified data provider type that loads the + /// language project data from an existing source. + /// + /// Identifies the project to load. + /// The ICU locale of the default user WS. + /// + /// + /// The progress dialog box + /// True if data migration is forbidden by the application + /// ------------------------------------------------------------------------------------ + public static FdoCache CreateCacheFromExistingData(IProjectIdentifier projectId, + string userWsIcuLocale, IFdoUI ui, IFdoDirectories dirs, IThreadedProgress progressDlg, bool forbidDataMigration) + { + return CreateCacheInternal(projectId, userWsIcuLocale, ui, dirs, + dataSetup => dataSetup.StartupExtantLanguageProject(projectId, true, progressDlg, forbidDataMigration), cache => cache.Initialize()); } @@ -159,14 +174,16 @@ public static FdoCache CreateCacheFromExistingData(IProjectIdentifier projectId, /// /// /// + /// + /// /// The progress dialog box /// ------------------------------------------------------------------------------------ public static FdoCache CreateCacheFromLocalProjectFile(string projectPath, - string userWsIcuLocale, IThreadedProgress progressDlg) + string userWsIcuLocale, IFdoUI ui, IFdoDirectories dirs, IThreadedProgress progressDlg) { var projectId = new SimpleProjectId(FDOBackendProviderType.kXML, projectPath); - return CreateCacheInternal(projectId, userWsIcuLocale, progressDlg.ThreadHelper, - dataSetup => dataSetup.StartupExtantLanguageProject(projectId, true, progressDlg), + return CreateCacheInternal(projectId, userWsIcuLocale, ui, dirs, + dataSetup => dataSetup.StartupExtantLanguageProject(projectId, true, progressDlg, false), cache => cache.Initialize()); } @@ -177,14 +194,14 @@ public static FdoCache CreateCacheFromLocalProjectFile(string projectPath, /// /// Identifies the project to create (i.e., the copy). /// The ICU locale of the default user WS. + /// + /// /// The FdoCache to copy - /// The thread helper used for invoking actions on the main - /// UI thread. /// ------------------------------------------------------------------------------------ public static FdoCache CreateCacheCopy(IProjectIdentifier projectId, - string userWsIcuLocale, FdoCache sourceCache, ThreadHelper threadHelper) + string userWsIcuLocale, IFdoUI ui, IFdoDirectories dirs, FdoCache sourceCache) { - return CreateCacheInternal(projectId, userWsIcuLocale, threadHelper, + return CreateCacheInternal(projectId, userWsIcuLocale, ui, dirs, dataSetup => dataSetup.InitializeFromSource(projectId, sourceCache)); } @@ -193,22 +210,22 @@ public static FdoCache CreateCacheCopy(IProjectIdentifier projectId, /// Creates a new FdoCache that uses a specified data provider. /// /// Identifies the project to create or load. - /// The thread helper used for invoking actions on the main - /// UI thread. + /// + /// /// ------------------------------------------------------------------------------------ - private static FdoCache CreateCacheInternal(IProjectIdentifier projectId, - ThreadHelper threadHelper) + private static FdoCache CreateCacheInternal(IProjectIdentifier projectId, IFdoUI ui, IFdoDirectories dirs) { FDOBackendProviderType providerType = projectId.Type; if (providerType == FDOBackendProviderType.kXMLWithMemoryOnlyWsMgr) providerType = FDOBackendProviderType.kXML; + if (providerType == FDOBackendProviderType.kSharedXMLWithMemoryOnlyWsMgr) + providerType = FDOBackendProviderType.kSharedXML; - var iocFactory = new FdoServiceLocatorFactory(providerType); + var iocFactory = new FdoServiceLocatorFactory(providerType, ui, dirs); var servLoc = (IFdoServiceLocator)iocFactory.CreateServiceLocator(); var createdCache = servLoc.GetInstance(); createdCache.m_serviceLocator = servLoc; createdCache.m_lgwsFactory = servLoc.GetInstance(); - createdCache.m_threadHelper = threadHelper; return createdCache; } @@ -218,14 +235,14 @@ private static FdoCache CreateCacheInternal(IProjectIdentifier projectId, /// /// Identifies the project to create or load. /// The ICU locale of the default user WS. - /// The thread helper used for invoking actions on the main - /// UI thread. + /// + /// /// The data setup action to perform. /// ------------------------------------------------------------------------------------ private static FdoCache CreateCacheInternal(IProjectIdentifier projectId, - string userWsIcuLocale, ThreadHelper threadHelper, Action doThe) + string userWsIcuLocale, IFdoUI ui, IFdoDirectories dirs, Action doThe) { - return CreateCacheInternal(projectId, userWsIcuLocale, threadHelper, doThe, null); + return CreateCacheInternal(projectId, userWsIcuLocale, ui, dirs, doThe, null); } /// ------------------------------------------------------------------------------------ @@ -234,23 +251,24 @@ private static FdoCache CreateCacheInternal(IProjectIdentifier projectId, /// /// Identifies the project to create or load. /// The ICU locale of the default user WS. - /// The thread helper used for invoking actions on the main - /// UI thread. + /// + /// /// The data setup action to perform. /// The initialization step to perfrom (can be null). /// The newly created cache /// ------------------------------------------------------------------------------------ private static FdoCache CreateCacheInternal(IProjectIdentifier projectId, - string userWsIcuLocale, ThreadHelper threadHelper, Action doThe, + string userWsIcuLocale, IFdoUI ui, IFdoDirectories dirs, Action doThe, Action initialize) { FDOBackendProviderType providerType = projectId.Type; - bool useMemoryWsManager = (providerType == FDOBackendProviderType.kMemoryOnly || - providerType == FDOBackendProviderType.kXMLWithMemoryOnlyWsMgr); - FdoCache createdCache = CreateCacheInternal(projectId, threadHelper); + bool useMemoryWsManager = (providerType == FDOBackendProviderType.kMemoryOnly + || providerType == FDOBackendProviderType.kXMLWithMemoryOnlyWsMgr + || providerType == FDOBackendProviderType.kSharedXMLWithMemoryOnlyWsMgr); + FdoCache createdCache = CreateCacheInternal(projectId, ui, dirs); // Init backend data provider - IDataSetup dataSetup = createdCache.ServiceLocator.GetInstance(); + var dataSetup = createdCache.ServiceLocator.GetInstance(); dataSetup.UseMemoryWritingSystemManager = useMemoryWsManager; doThe(dataSetup); if (initialize != null) @@ -269,7 +287,6 @@ private static FdoCache CreateCacheInternal(IProjectIdentifier projectId, servLoc.WritingSystemManager.UserWritingSystem = wsUser; } - createdCache.EnsureValidLinkedFilesFolder(); return createdCache; } @@ -297,15 +314,9 @@ private void Initialize() } if (ServiceLocator.WritingSystems.DefaultAnalysisWritingSystem == null) - { - throw new FwStartupException(ResourceHelper.FormatResourceString("kstidNoWritingSystems", - ResourceHelper.GetResourceString("kstidAnalysis"))); - } + throw new StartupException(string.Format(Strings.ksNoWritingSystems, Strings.ksAnalysis)); if (ServiceLocator.WritingSystems.DefaultVernacularWritingSystem == null) - { - throw new FwStartupException(ResourceHelper.FormatResourceString("kstidNoWritingSystems", - ResourceHelper.GetResourceString("kstidVernacular"))); - } + throw new StartupException(string.Format(Strings.ksNoWritingSystems, Strings.ksVernacular)); NonUndoableUnitOfWorkHelper.Do(ActionHandlerAccessor, () => DataStoreInitializationServices.PrepareCache(this)); @@ -346,27 +357,29 @@ private static void SaveOnlyLocalWritingSystems(IWritingSystemManager writingSys /// The progress dialog. /// One or more parameters, supplied in this order: /// 0. A string containing the name of the project (required); - /// 1. A ThreadHelper used for invoking actions on the main UI thread (required); - /// 2. An IWritingSystem to be used as the default analylis writing system (default: English); - /// 3. An IWritingSystem to be used as the default vernacular writing system (default: French); - /// 4. A string with the ICU locale of the UI writing system (default: "en"). - /// 5. A set of IWritingSystem to provide additional analysis writing systems (default: no more) - /// 6. A set of IWritingSystem to provide additional vernacular writing systems (default: no more) - /// 7. OCM Data filename. (default: OCM-Frame.xml if available; else, null) + /// 1. An IFdoDirectories used to get needed directories (required); + /// 2. An ISynchronizeInvoke used for invoking actions on the main UI thread (required); + /// 3. An IWritingSystem to be used as the default analylis writing system (default: English); + /// 4. An IWritingSystem to be used as the default vernacular writing system (default: French); + /// 5. A string with the ICU locale of the UI writing system (default: "en"). + /// 6. A set of IWritingSystem to provide additional analysis writing systems (default: no more) + /// 7. A set of IWritingSystem to provide additional vernacular writing systems (default: no more) + /// 8. OCM Data filename. (default: OCM-Frame.xml if available; else, null) /// Path of the newly created project file. /// Override DisplayUi to prevent progress dialog from showing. /// ------------------------------------------------------------------------------------ public static string CreateNewLangProj(IThreadedProgress progressDlg, params object[] parameters) { - if (parameters == null || parameters.Length < 2) - throw new ArgumentException("Parameters must include at least a project name and the ThreadHelper"); - var projectName = (string)parameters[0]; + if (parameters == null || parameters.Length < 3) + throw new ArgumentException("Parameters must include at least a project name, an IFdoDirectories service, and a SynchronizeInvoke object"); + var projectName = (string) parameters[0]; if (string.IsNullOrEmpty(projectName)) - throw new ArgumentNullException("projectName", "Cannot be null or empty"); - var threadHelper = (ThreadHelper)parameters[1]; - IWritingSystem analWrtSys = (parameters.Length > 2) ? (IWritingSystem)parameters[2] : null; - IWritingSystem vernWrtSys = (parameters.Length > 3) ? (IWritingSystem)parameters[3] : null; - var userIcuLocale = (parameters.Length > 4 && parameters[4] != null) ? (string)parameters[4] : "en"; + throw new ArgumentNullException("parameters", "Cannot be null or empty"); + var dirs = (IFdoDirectories) parameters[1]; + var synchronizeInvoke = (ISynchronizeInvoke) parameters[2]; + IWritingSystem analWrtSys = (parameters.Length > 3) ? (IWritingSystem) parameters[3] : null; + IWritingSystem vernWrtSys = (parameters.Length > 4) ? (IWritingSystem) parameters[4] : null; + var userIcuLocale = (parameters.Length > 5 && parameters[5] != null) ? (string) parameters[5] : "en"; const int nMax = 10; if (progressDlg != null) { @@ -375,9 +388,7 @@ public static string CreateNewLangProj(IThreadedProgress progressDlg, params obj progressDlg.Message = Properties.Resources.kstidCreatingDB; } - var dbFileName = CreateNewDbFile(ref projectName); - Debug.Assert(DirectoryFinder.IsSubFolderOfProjectsDirectory(Path.GetDirectoryName(dbFileName)), - "new projects should always be created in the current projects directory"); + var dbFileName = CreateNewDbFile(dirs.ProjectsDirectory, dirs.TemplateDirectory, ref projectName); if (progressDlg != null) { @@ -386,8 +397,8 @@ public static string CreateNewLangProj(IThreadedProgress progressDlg, params obj } var projectId = new SimpleProjectId(FDOBackendProviderType.kXML, dbFileName); - using (var cache = CreateCacheInternal(projectId, - userIcuLocale, threadHelper, dataSetup => dataSetup.StartupExtantLanguageProject(projectId, true, progressDlg))) + using (FdoCache cache = CreateCacheInternal(projectId, userIcuLocale, new SilentFdoUI(synchronizeInvoke), dirs, + dataSetup => dataSetup.StartupExtantLanguageProject(projectId, true, progressDlg, false))) { if (progressDlg != null) { @@ -409,13 +420,13 @@ public static string CreateNewLangProj(IThreadedProgress progressDlg, params obj if (progressDlg != null) progressDlg.Step(0); - var additionalAnalysisWss = (parameters.Length > 5 && parameters[5] != null) - ? (HashSet)parameters[5] + var additionalAnalysisWss = (parameters.Length > 6 && parameters[6] != null) + ? (HashSet) parameters[6] : new HashSet(); foreach (var additionalWs in additionalAnalysisWss) CreateAnalysisWritingSystem(cache, additionalWs, false); - var additionalVernWss = (parameters.Length > 6 && parameters[6] != null) - ? (HashSet)parameters[6] + var additionalVernWss = (parameters.Length > 7 && parameters[7] != null) + ? (HashSet) parameters[7] : new HashSet(); foreach (var additionalWs in additionalVernWss) CreateVernacularWritingSystem(cache, additionalWs, false); @@ -436,7 +447,7 @@ public static string CreateNewLangProj(IThreadedProgress progressDlg, params obj // Load the semantic domain list. // Enhance: allow user to choose among alternative semantic domain lists? - string sFile = Path.Combine(DirectoryFinder.TemplateDirectory, "SemDom.xml"); + string sFile = Path.Combine(dirs.TemplateDirectory, "SemDom.xml"); if (progressDlg != null) { progressDlg.Message = Properties.Resources.ksLoadingSemanticDomains; @@ -448,7 +459,7 @@ public static string CreateNewLangProj(IThreadedProgress progressDlg, params obj xlist.ImportList(cache.LangProject, "SemanticDomainList", sFile, progressDlg); // Load the intitial Part of Speech list. - sFile = Path.Combine(DirectoryFinder.TemplateDirectory, "POS.xml"); + sFile = Path.Combine(dirs.TemplateDirectory, "POS.xml"); if (progressDlg != null) { progressDlg.Message = Properties.Resources.ksLoadingPartsOfSpeech; @@ -461,24 +472,24 @@ public static string CreateNewLangProj(IThreadedProgress progressDlg, params obj // Make sure that the new project has all the writing systems actually used by the // default data. See FWR-1774. - AddMissingWritingSystems(Path.Combine(DirectoryFinder.TemplateDirectory, DirectoryFinder.GetXmlDataFileName("NewLangProj")), + AddMissingWritingSystems(Path.Combine(dirs.TemplateDirectory, FdoFileHelper.GetXmlDataFileName("NewLangProj")), cache.ServiceLocator.WritingSystemManager); - AddMissingWritingSystems(Path.Combine(DirectoryFinder.TemplateDirectory, "POS.xml"), + AddMissingWritingSystems(Path.Combine(dirs.TemplateDirectory, "POS.xml"), cache.ServiceLocator.WritingSystemManager); cache.ServiceLocator.WritingSystemManager.Save(); cache.ActionHandlerAccessor.BeginNonUndoableTask(); InitializeAnthroList(cache.LangProject, cache.WritingSystemFactory.GetWsFromStr(analWrtSys != null ? analWrtSys.IcuLocale : userIcuLocale), - (parameters.Length > 7) ? (string)parameters[7] : null); - ImportLocalizedLists(cache, progressDlg); + (parameters.Length > 8) ? (string) parameters[8] : null); + ImportLocalizedLists(cache, dirs.TemplateDirectory, progressDlg); cache.ActionHandlerAccessor.EndNonUndoableTask(); NonUndoableUnitOfWorkHelper.Do(cache.ServiceLocator.GetInstance(), () => { //Make sure the new project has the default location set up for the External files. cache.LanguageProject.LinkedFilesRootDir = Path.Combine(cache.ProjectId.ProjectFolder, - DirectoryFinder.ksLinkedFilesDir); + FdoFileHelper.ksLinkedFilesDir); // Set the Date Created and Date Modified values. (See FWR-3189.) cache.LangProject.DateCreated = DateTime.Now; @@ -489,7 +500,7 @@ public static string CreateNewLangProj(IThreadedProgress progressDlg, params obj // Rewrite all objects to make sure they all have all of the basic properties. if (progressDlg != null) { - progressDlg.ProgressBarStyle = ProgressBarStyle.Marquee; + progressDlg.IsIndeterminate = true; progressDlg.Message = AppStrings.InitializeSavingMigratedDataProgressMessage; progressDlg.RunTask(cache.SaveAndForceNewestXmlForCmObjectWithoutUnitOfWork, cache.m_serviceLocator.ObjectRepository.AllInstances().ToList()); @@ -560,11 +571,11 @@ private static void AddSubPossibilitiesToOverlay(ICmOverlay over, ICmPossibility /// Check for any localized lists files using pattern Templates\LocalizedLists-*.xml. /// If found, load each one into the project. /// - private static void ImportLocalizedLists(FdoCache cache, IThreadedProgress progress) + private static void ImportLocalizedLists(FdoCache cache, string templateDir, IThreadedProgress progress) { var filePrefix = XmlTranslatedLists.LocalizedListPrefix; var rgsAnthroFiles = new List(); - var rgsXmlFiles = Directory.GetFiles(DirectoryFinder.TemplateDirectory, filePrefix + "*.zip", SearchOption.TopDirectoryOnly); + var rgsXmlFiles = Directory.GetFiles(templateDir, filePrefix + "*.zip", SearchOption.TopDirectoryOnly); string sFile; for (var i = 0; i < rgsXmlFiles.Length; ++i) { @@ -667,20 +678,20 @@ private static void AddMissingWritingSystems(string fileName, /// Build the file name for the new project and copy the template file (NewLangProj.fwdata). /// /// ------------------------------------------------------------------------------------ - private static string CreateNewDbFile(ref string projectName) + private static string CreateNewDbFile(string projectsDir, string templateDir, ref string projectName) { projectName = MiscUtils.FilterForFileName(projectName, MiscUtils.FilenameFilterStrength.kFilterBackup); - if (ProjectInfo.GetProjectInfoByName(projectName) != null) + if (ProjectInfo.GetProjectInfoByName(projectsDir, projectName) != null) throw new ArgumentException("The specified project already exists.", "projectName"); - string dbDirName = Path.Combine(DirectoryFinder.ProjectsDirectory, projectName); - string dbFileName = Path.Combine(dbDirName, DirectoryFinder.GetXmlDataFileName(projectName)); + string dbDirName = Path.Combine(projectsDir, projectName); + string dbFileName = Path.Combine(dbDirName, FdoFileHelper.GetXmlDataFileName(projectName)); try { Directory.CreateDirectory(dbDirName); CreateProjectSubfolders(dbDirName); // Make a copy of the template database that will become the new database - File.Copy(Path.Combine(DirectoryFinder.TemplateDirectory, - DirectoryFinder.GetXmlDataFileName("NewLangProj")), dbFileName, false); + File.Copy(Path.Combine(templateDir, + FdoFileHelper.GetXmlDataFileName("NewLangProj")), dbFileName, false); File.SetAttributes(dbFileName, FileAttributes.Normal); // Change the LangProject Guid to a new one to make it unique between projects, so Lift Bridge won't get cross with FLEx. @@ -716,19 +727,17 @@ internal static void CreateProjectSubfolders(string dbDirName) { try { - Directory.CreateDirectory(DirectoryFinder.GetBackupSettingsDir(dbDirName)); - Directory.CreateDirectory(DirectoryFinder.GetConfigSettingsDir(dbDirName)); - Directory.CreateDirectory(DirectoryFinder.GetSupportingFilesDir(dbDirName)); - Directory.CreateDirectory(DirectoryFinder.GetDefaultMediaDir(dbDirName)); - Directory.CreateDirectory(DirectoryFinder.GetDefaultPicturesDir(dbDirName)); - Directory.CreateDirectory(DirectoryFinder.GetDefaultOtherExternalFilesDir(dbDirName)); - Directory.CreateDirectory(Path.Combine(dbDirName, DirectoryFinder.ksSortSequenceTempDir)); - Directory.CreateDirectory(DirectoryFinder.GetWritingSystemDir(dbDirName)); + Directory.CreateDirectory(FdoFileHelper.GetBackupSettingsDir(dbDirName)); + Directory.CreateDirectory(FdoFileHelper.GetConfigSettingsDir(dbDirName)); + Directory.CreateDirectory(FdoFileHelper.GetSupportingFilesDir(dbDirName)); + Directory.CreateDirectory(FdoFileHelper.GetDefaultMediaDir(dbDirName)); + Directory.CreateDirectory(FdoFileHelper.GetDefaultPicturesDir(dbDirName)); + Directory.CreateDirectory(FdoFileHelper.GetDefaultOtherExternalFilesDir(dbDirName)); + Directory.CreateDirectory(Path.Combine(dbDirName, FdoFileHelper.ksSortSequenceTempDir)); + Directory.CreateDirectory(FdoFileHelper.GetWritingSystemDir(dbDirName)); } catch (Exception e) { - MessageBoxUtils.Show(String.Format(AppStrings.ksCreateNewProjectSubfoldersError, - e.Message)); throw new ApplicationException(e.Message, e); } @@ -832,16 +841,6 @@ internal static object SyncRoot get { return m_syncRoot; } } - /// ------------------------------------------------------------------------------------ - /// - /// Gets the thread helper used for invoking actions on the main UI thread. - /// - /// ------------------------------------------------------------------------------------ - public ThreadHelper ThreadHelper - { - get { return m_threadHelper; } - } - /// ------------------------------------------------------------------------------------ /// /// Gets the information about the loaded project. @@ -1091,6 +1090,7 @@ public int DefaultUserWs #endregion Public Properties #region Public methods + /// ----------------------------------------------------------------------------------- /// /// Change the name of the database represented by this connection. @@ -1418,52 +1418,6 @@ public string GetText(int hvo, int flid, XmlNode frag, out bool fTypeFound) return itype.ToString(); } } - - /// - /// Ensure a valid folder for LangProject.LinkedFilesRootDir. When moving projects - /// between systems, the stored value may become hopelessly invalid. See FWNX-1005 - /// for an example of the havoc than can ensue. - /// - /// This method gets called when we open the FDO cache. - private void EnsureValidLinkedFilesFolder() - { - if (MiscUtils.RunningTests) - return; - - var linkedFilesFolder = this.LangProject.LinkedFilesRootDir; - var defaultFolder = DirectoryFinder.GetDefaultLinkedFilesDir(this.ProjectId.ProjectFolder); - EnsureValidLinkedFilesFolderCore(linkedFilesFolder, defaultFolder); - - if (!Directory.Exists(linkedFilesFolder)) - { - if (!Directory.Exists(defaultFolder)) - defaultFolder = this.ProjectId.ProjectFolder; - MessageBox.Show(String.Format(Strings.ksInvalidLinkedFilesFolder, linkedFilesFolder), Strings.ksErrorCaption); - while (!Directory.Exists(linkedFilesFolder)) - { - using (var folderBrowserDlg = new FolderBrowserDialogAdapter()) - { - folderBrowserDlg.Description = Strings.ksLinkedFilesFolder; - folderBrowserDlg.RootFolder = Environment.SpecialFolder.Desktop; - folderBrowserDlg.SelectedPath = defaultFolder; - if (folderBrowserDlg.ShowDialog() == DialogResult.OK) - linkedFilesFolder = folderBrowserDlg.SelectedPath; - } - } - NonUndoableUnitOfWorkHelper.DoUsingNewOrCurrentUOW(this.ActionHandlerAccessor, () => - { this.LangProject.LinkedFilesRootDir = linkedFilesFolder; }); - } - } - - /// - /// Just make the directory if it's the default. - /// See FWNX-1092, LT-14491. - /// - internal void EnsureValidLinkedFilesFolderCore(string linkedFilesFolder, string defaultLinkedFilesFolder) - { - if (linkedFilesFolder == defaultLinkedFilesFolder) - FileUtils.EnsureDirectoryExists(defaultLinkedFilesFolder); - } #endregion Public methods #endregion Public interface @@ -1989,7 +1943,7 @@ public static List ConvertCmObjectsToHvoList(IEnumerable ConvertCmObjectsToHvos(IEnumerable cmObjects) where TDerived : ICmObject { - foreach (ICmObject cmObject in cmObjects) + foreach (TDerived cmObject in cmObjects) yield return cmObject.Hvo; } } diff --git a/Src/FDOBrowser/FDOBrowser.csproj b/Src/FDOBrowser/FDOBrowser.csproj index e5f152593d..169a893115 100644 --- a/Src/FDOBrowser/FDOBrowser.csproj +++ b/Src/FDOBrowser/FDOBrowser.csproj @@ -1,257 +1,261 @@ - + - Debug - AnyCPU - 9.0.30729 - 2.0 - {C194A88D-5F50-4B2A-988D-E3690FA7384D} - WinExe - Properties - FDOBrowser - FDOBrowser - - - 3.5 - - - v4.0 - false - true - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - true - + Debug + AnyCPU + 9.0.30729 + 2.0 + {C194A88D-5F50-4B2A-988D-E3690FA7384D} + WinExe + Properties + FDOBrowser + FDOBrowser + + + 3.5 + + + v4.0 + false + true + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + - true - full - false - 168,169,219,414,649,1635,1702,1701 - ..\..\Output\Debug\ - DEBUG;TRACE - prompt - 4 - ..\..\Output\Debug\FDOBrowser.xml - false - x86 - AllRules.ruleset + true + full + false + 168,169,219,414,649,1635,1702,1701 + ..\..\Output\Debug\ + DEBUG;TRACE + prompt + 4 + ..\..\Output\Debug\FDOBrowser.xml + false + x86 + AllRules.ruleset - pdbonly - true - 168,169,219,414,649,1635,1702,1701 - ..\..\Output\Release\ - TRACE - prompt - 4 - ..\..\Output\Release\FDOBrowser.XML - x86 - AllRules.ruleset + pdbonly + true + 168,169,219,414,649,1635,1702,1701 + ..\..\Output\Release\ + TRACE + prompt + 4 + ..\..\Output\Release\FDOBrowser.XML + x86 + AllRules.ruleset - - False - ..\..\Output\Debug\CoreImpl.dll - - - False - ..\..\Output\Debug\Db4objects.Db4o.dll - - - False - ..\..\Output\Debug\Db4objects.Db4o.CS.dll - - - False - ..\..\Output\Debug\Db4objects.Db4o.Linq.dll - - - ..\..\Output\Debug\DetailControls.dll - False - - - False - ..\..\Output\Debug\FDO.dll - - - False - - - False - ..\..\Output\Debug\FwResources.dll - - - False - ..\..\Output\Debug\FwUtils.dll - - - False - ..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll - - - False - ..\..\Output\Debug\ObjectBrowser.dll - - - ..\..\Output\Debug\SilUtils.dll - False - - - - - - - - - BasicUtils - ..\..\Output\Debug\BasicUtils.dll - - - COMInterfaces - ..\..\Output\Debug\COMInterfaces.dll - - - False - .\WeifenLuo.WinFormsUI.Docking.dll - - - False - ..\..\Output\Debug\Widgets.dll - - - False - ..\..\Output\Debug\xCoreInterfaces.dll - - - False - ..\..\Output\Debug\XMLViews.dll - + + False + ..\..\Output\Debug\CoreImpl.dll + + + False + ..\..\Output\Debug\Db4objects.Db4o.dll + + + False + ..\..\Output\Debug\Db4objects.Db4o.CS.dll + + + False + ..\..\Output\Debug\Db4objects.Db4o.Linq.dll + + + ..\..\Output\Debug\DetailControls.dll + False + + + False + ..\..\Output\Debug\FDO.dll + + + False + ..\..\Output\Debug\FdoUi.dll + + + False + + + False + ..\..\Output\Debug\FwResources.dll + + + False + ..\..\Output\Debug\FwUtils.dll + + + False + ..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll + + + False + ..\..\Output\Debug\ObjectBrowser.dll + + + ..\..\Output\Debug\SilUtils.dll + False + + + + + + + + + BasicUtils + ..\..\Output\Debug\BasicUtils.dll + + + COMInterfaces + ..\..\Output\Debug\COMInterfaces.dll + + + False + .\WeifenLuo.WinFormsUI.Docking.dll + + + False + ..\..\Output\Debug\Widgets.dll + + + False + ..\..\Output\Debug\xCoreInterfaces.dll + + + False + ..\..\Output\Debug\XMLViews.dll + - - CommonAssemblyInfo.cs - - - - - - Form - - - FDOBrowserForm.cs - - - - - Form - - - FileInOutChooser.cs - - - Form - - - ModelWnd.cs - - - Form - - - ClassPropertySelector.cs - - - - - ClassPropertySelector.cs - Designer - - - FDOBrowserForm.cs - Designer - - - FileInOutChooser.cs - - - ModelWnd.cs - Designer - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - RealListChooser.cs - Designer - - - True - Resources.resx - True - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - Form - - - RealListChooser.cs - + + CommonAssemblyInfo.cs + + + + + + Form + + + FDOBrowserForm.cs + + + + + Form + + + FileInOutChooser.cs + + + Form + + + ModelWnd.cs + + + Form + + + ClassPropertySelector.cs + + + + + ClassPropertySelector.cs + Designer + + + FDOBrowserForm.cs + Designer + + + FileInOutChooser.cs + + + ModelWnd.cs + Designer + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + RealListChooser.cs + Designer + + + True + Resources.resx + True + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + Form + + + RealListChooser.cs + - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 2.0 %28x86%29 - true - - - False - .NET Framework 3.0 %28x86%29 - false - - - False - .NET Framework 3.5 - false - - - False - .NET Framework 3.5 SP1 - false - + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + False + .NET Framework 3.5 SP1 + false + - + - + diff --git a/Src/FDOBrowser/FDOBrowserForm.Designer.cs b/Src/FDOBrowser/FDOBrowserForm.Designer.cs index 2d1113faea..83d56ec786 100644 --- a/Src/FDOBrowser/FDOBrowserForm.Designer.cs +++ b/Src/FDOBrowser/FDOBrowserForm.Designer.cs @@ -26,11 +26,8 @@ protected override void Dispose(bool disposing) m_cache.ServiceLocator.GetInstance().Commit(); m_cache.Dispose(); } - if (m_ThreadHelper != null) - m_ThreadHelper.Dispose(); } m_cache = null; // Don't try to use it again - m_ThreadHelper = null; base.Dispose(disposing); } diff --git a/Src/FDOBrowser/FDOBrowserForm.cs b/Src/FDOBrowser/FDOBrowserForm.cs index 2933047523..3dcbabe8a8 100644 --- a/Src/FDOBrowser/FDOBrowserForm.cs +++ b/Src/FDOBrowser/FDOBrowserForm.cs @@ -8,7 +8,7 @@ using System.Reflection; using System.Resources; using System.Windows.Forms; -using FwRemoteDatabaseConnector; +using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.Common.Controls; using SIL.FieldWorks.Common.Framework.DetailControls; @@ -16,10 +16,9 @@ using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.Application; using SIL.FieldWorks.FDO.Infrastructure; -using SIL.FieldWorks.FDO.Infrastructure.Impl; +using SIL.FieldWorks.FdoUi; using SIL.FieldWorks.Resources; using SIL.ObjectBrowser; -using SIL.Utils; using WeifenLuo.WinFormsUI.Docking; using XCore; @@ -52,7 +51,6 @@ public partial class FDOBrowserForm : ObjectBrowser, IHelpTopicProvider private InspectorWnd m_repositoryWnd; private int saveClid; private string FileName = string.Empty; - private ThreadHelper m_ThreadHelper; //private FwTextBox m_textBox; //private System.Windows.Forms.Panel panel1; @@ -378,16 +376,15 @@ protected override void OpenFile(string fileName) // Init backend data provider // TODO: Get the correct ICU local for the user writing system - if (m_ThreadHelper == null) - m_ThreadHelper = new ThreadHelper(); + var ui = new FwFdoUI(this, this); if (isMemoryBEP) - m_cache = FdoCache.CreateCacheWithNewBlankLangProj(new BrowserProjectId(bepType, null), "en", "en", "en", m_ThreadHelper); + m_cache = FdoCache.CreateCacheWithNewBlankLangProj(new BrowserProjectId(bepType, null), "en", "en", "en", ui, FwDirectoryFinder.FdoDirectories); else { - using (ProgressDialogWithTask progressDlg = new ProgressDialogWithTask(this, m_ThreadHelper)) + using (var progressDlg = new ProgressDialogWithTask(this)) { - m_cache = FdoCache.CreateCacheFromExistingData(new BrowserProjectId(bepType, fileName), "en", progressDlg); + m_cache = FdoCache.CreateCacheFromExistingData(new BrowserProjectId(bepType, fileName), "en", ui, FwDirectoryFinder.FdoDirectories, progressDlg); } } // var v = m_cache. @@ -509,9 +506,9 @@ private static FDOBackendProviderType GetBEPTypeFromFileExtension(string pathnam { default: return FDOBackendProviderType.kMemoryOnly; - case FwFileExtensions.ksFwDataXmlFileExtension: + case FdoFileHelper.ksFwDataXmlFileExtension: return FDOBackendProviderType.kXML; - case FwFileExtensions.ksFwDataDb4oFileExtension: + case FdoFileHelper.ksFwDataDb4oFileExtension: return FDOBackendProviderType.kDb4oClientServer; } @@ -2516,7 +2513,7 @@ public string GetHelpString(string sPropName) /// public string HelpFile { - get { return Path.Combine(DirectoryFinder.FWCodeDirectory, GetHelpString("UserHelpFile")); } + get { return Path.Combine(FwDirectoryFinder.CodeDirectory, GetHelpString("UserHelpFile")); } } #endregion diff --git a/Src/FDOBrowser/FDOClassList.cs b/Src/FDOBrowser/FDOClassList.cs index 431c2227c4..4c1f7d8096 100644 --- a/Src/FDOBrowser/FDOClassList.cs +++ b/Src/FDOBrowser/FDOClassList.cs @@ -1,13 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Reflection; using System.Xml.Serialization; using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.Infrastructure; using SIL.FieldWorks.FDO; -using System.Collections; using System.IO; using SIL.Utils; @@ -139,15 +137,16 @@ private static void LoadFDOClassNames() if (s_allFDOClassNames != null) return; - using (FdoCache cache = FdoCache.CreateCacheWithNoLangProj(new BrowserProjectId(FDOBackendProviderType.kMemoryOnly, null), "en", null)) + using (var threadHelper = new ThreadHelper()) + using (FdoCache cache = FdoCache.CreateCacheWithNoLangProj(new BrowserProjectId(FDOBackendProviderType.kMemoryOnly, null), "en", new SilentFdoUI(threadHelper), FwDirectoryFinder.FdoDirectories)) { - IFwMetaDataCacheManaged mdc = (IFwMetaDataCacheManaged)cache.MainCacheAccessor.MetaDataCache; - s_allFDOClassNames = new List(); + IFwMetaDataCacheManaged mdc = (IFwMetaDataCacheManaged)cache.MainCacheAccessor.MetaDataCache; + s_allFDOClassNames = new List(); - foreach (int clsid in mdc.GetClassIds()) - s_allFDOClassNames.Add(mdc.GetClassName(clsid)); + foreach (int clsid in mdc.GetClassIds()) + s_allFDOClassNames.Add(mdc.GetClassName(clsid)); - s_allFDOClassNames.Sort((x, y) => x.CompareTo(y)); + s_allFDOClassNames.Sort((x, y) => x.CompareTo(y)); } } diff --git a/Src/FDOBrowser/ModelWnd.cs b/Src/FDOBrowser/ModelWnd.cs index 6e5c813d57..4ad4cd5fe0 100644 --- a/Src/FDOBrowser/ModelWnd.cs +++ b/Src/FDOBrowser/ModelWnd.cs @@ -5,10 +5,12 @@ using System.Windows.Forms; using SIL.CoreImpl; using SIL.FieldWorks.Common.FwUtils; +using SIL.FieldWorks.FdoUi; using SIL.Utils; using WeifenLuo.WinFormsUI.Docking; using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.Infrastructure; +using XCore; namespace FDOBrowser { @@ -29,7 +31,7 @@ public partial class ModelWnd : DockContent /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// ------------------------------------------------------------------------------------ public ModelWnd() @@ -40,7 +42,7 @@ public ModelWnd() m_lvModel.Font = SystemFonts.MenuFont; // Add model browsing cache (no data, just model browsing). - m_cache = FdoCache.CreateCacheWithNoLangProj(new BrowserProjectId(FDOBackendProviderType.kMemoryOnly, null), "en", new ThreadHelper()); + m_cache = FdoCache.CreateCacheWithNoLangProj(new BrowserProjectId(FDOBackendProviderType.kMemoryOnly, null), "en", new SilentFdoUI(this), FwDirectoryFinder.FdoDirectories); m_mdc = (IFwMetaDataCacheManaged)m_cache.MainCacheAccessor.MetaDataCache; PopulateModelTree(); @@ -71,7 +73,7 @@ public ModelWnd() /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// ------------------------------------------------------------------------------------ public ModelWnd(ToolStripStatusLabel statuslabel) : this() diff --git a/Src/FXT/FxtDll/FxtDllTests/FxtTestBase.cs b/Src/FXT/FxtDll/FxtDllTests/FxtTestBase.cs index cd9adfc179..462e6d33d2 100644 --- a/Src/FXT/FxtDll/FxtDllTests/FxtTestBase.cs +++ b/Src/FXT/FxtDll/FxtDllTests/FxtTestBase.cs @@ -80,7 +80,7 @@ public virtual void Init() { RegistryHelper.CompanyName = "SIL"; RegistryHelper.ProductName = "FieldWorks"; - m_sExpectedResultsPath = Path.Combine(DirectoryFinder.FwSourceDirectory, + m_sExpectedResultsPath = Path.Combine(FwDirectoryFinder.SourceDirectory, Path.Combine("FXT", Path.Combine("FxtDll", Path.Combine("FxtDllTests", "ExpectedResults")))); diff --git a/Src/FXT/FxtDll/FxtDllTests/SimpleTests.cs b/Src/FXT/FxtDll/FxtDllTests/SimpleTests.cs index f09a6b9ee4..dead7897a2 100644 --- a/Src/FXT/FxtDll/FxtDllTests/SimpleTests.cs +++ b/Src/FXT/FxtDll/FxtDllTests/SimpleTests.cs @@ -30,7 +30,7 @@ public class QuickTests : FxtTestBase /// /// Location of simple test FXT files /// - protected string m_sFxtSimpleTestPath = Path.Combine(SIL.FieldWorks.Common.Utils.DirectoryFinder.FwSourceDirectory, + protected string m_sFxtSimpleTestPath = Path.Combine(SIL.FieldWorks.Common.Utils.DirectoryFinder.SourceDirectory, Path.Combine("FXT", Path.Combine("FxtDll", "FxtDllTests"))); /// ----------------------------------------------------------------------------------- diff --git a/Src/FXT/FxtDll/FxtDllTests/StandFormatExportTests.cs b/Src/FXT/FxtDll/FxtDllTests/StandFormatExportTests.cs index 9239b7898a..9b748ab8e0 100644 --- a/Src/FXT/FxtDll/FxtDllTests/StandFormatExportTests.cs +++ b/Src/FXT/FxtDll/FxtDllTests/StandFormatExportTests.cs @@ -22,19 +22,10 @@ public class StandardFormat : FxtTestBase /// protected string m_testDir; - /// ----------------------------------------------------------------------------------- - /// - /// Initializes a new instance of the class. - /// - /// ----------------------------------------------------------------------------------- - public StandardFormat() - { - } - public override void Init() { base.Init(); - m_testDir = Path.Combine(DirectoryFinder.FlexFolder, "Export Templates"); + m_testDir = Path.Combine(FwDirectoryFinder.FlexFolder, "Export Templates"); } [Test] diff --git a/Src/FdoUi/ConfirmDeleteObjectDlg.resx b/Src/FdoUi/ConfirmDeleteObjectDlg.resx deleted file mode 100644 index 52c20f6ceb..0000000000 --- a/Src/FdoUi/ConfirmDeleteObjectDlg.resx +++ /dev/null @@ -1,367 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 64, 16 - - - 256, 23 - - - - 0 - - - You are deleting the following item: - - - label1 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - 32, 248 - - - 278, 23 - - - Bottom, Right - - - 2 - - - Do you want to continue with the deletion? - - - label2 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - Delete - - - 73, 269 - - - 75, 23 - - - Bottom, Right - - - 4 - - - &Delete - - - m_deleteButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - Cancel - - - 154, 269 - - - 75, 23 - - - Bottom, Right - - - 3 - - - &Cancel - - - m_cancelButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - - iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAANdJREFUWEftl9EO - gCAIRev/P9pmy8ZI4XJ14yHbXA+pHC6YcB7xpzhLzviW/opq9B6l2KPNe97+zs4MyOgISsBQIF1vlYev - MpZCjBpDqRmAqlAEwowzC4BCRJMMCoHMEUsJ17jw4mMYPSWWEqkAkPFVCvRU+DcA7P3KEMgwbICtwFYg - XYFarcAQM9exdSvCAF5NiH7X1zIFELmCNVivLoAhRmFgvW8VazoAlIyzSYgUp6lFKRQOJgcQz3X3Eu4N - nA6J646sn5R3DGdbM0mc1pz2ZBv2BEycL1UsThcV7omAAAAAAElFTkSuQmCC - - - - 16, 8 - - - 32, 32 - - - 5 - - - pictureBox1 - - - System.Windows.Forms.PictureBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - 32, 48 - - - 264, 129 - - - Top, Bottom, Left, Right - - - 1 - - - panel1 - - - System.Windows.Forms.Panel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - 32, 183 - - - 264, 55 - - - Bottom, Left, Right - - - 7 - - - panel2 - - - System.Windows.Forms.Panel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - False - - - 235, 269 - - - 75, 23 - - - Bottom, Right - - - 6 - - - Help - - - False - - - buttonHelp - - - System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - True - - - 5, 13 - - - 334, 300 - - - - CenterParent - - - Delete: - - - ConfirmDeleteObjectDlg - - - System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/Src/FDO/DomainServices/BackupRestore/CantRestoreLinkedFilesToOriginalLocation.Designer.cs b/Src/FdoUi/Dialogs/CantRestoreLinkedFilesToOriginalLocation.Designer.cs similarity index 96% rename from Src/FDO/DomainServices/BackupRestore/CantRestoreLinkedFilesToOriginalLocation.Designer.cs rename to Src/FdoUi/Dialogs/CantRestoreLinkedFilesToOriginalLocation.Designer.cs index a00bc34fcf..205896df93 100644 --- a/Src/FDO/DomainServices/BackupRestore/CantRestoreLinkedFilesToOriginalLocation.Designer.cs +++ b/Src/FdoUi/Dialogs/CantRestoreLinkedFilesToOriginalLocation.Designer.cs @@ -1,6 +1,6 @@ -using System.Windows.Forms; +using System.Windows.Forms; -namespace SIL.FieldWorks.FDO.DomainServices.BackupRestore +namespace SIL.FieldWorks.FdoUi.Dialogs { partial class CantRestoreLinkedFilesToOriginalLocation { @@ -71,7 +71,7 @@ private void InitializeComponent() // // pictureBox1 // - this.pictureBox1.Image = global::SIL.FieldWorks.FDO.Properties.Resources.question; + this.pictureBox1.Image = global::SIL.FieldWorks.FdoUi.Properties.Resources.question; resources.ApplyResources(this.pictureBox1, "pictureBox1"); this.pictureBox1.Name = "pictureBox1"; this.pictureBox1.TabStop = false; diff --git a/Src/FDO/DomainServices/BackupRestore/CantRestoreLinkedFilesToOriginalLocation.cs b/Src/FdoUi/Dialogs/CantRestoreLinkedFilesToOriginalLocation.cs similarity index 83% rename from Src/FDO/DomainServices/BackupRestore/CantRestoreLinkedFilesToOriginalLocation.cs rename to Src/FdoUi/Dialogs/CantRestoreLinkedFilesToOriginalLocation.cs index 955bb2dbc8..9dd5984fec 100644 --- a/Src/FDO/DomainServices/BackupRestore/CantRestoreLinkedFilesToOriginalLocation.cs +++ b/Src/FdoUi/Dialogs/CantRestoreLinkedFilesToOriginalLocation.cs @@ -1,15 +1,9 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; +using System; using System.Windows.Forms; using SIL.FieldWorks.Common.FwUtils; using XCore; -namespace SIL.FieldWorks.FDO.DomainServices.BackupRestore +namespace SIL.FieldWorks.FdoUi.Dialogs { /// /// diff --git a/Src/FDO/DomainServices/BackupRestore/CantRestoreLinkedFilesToOriginalLocation.resx b/Src/FdoUi/Dialogs/CantRestoreLinkedFilesToOriginalLocation.resx similarity index 99% rename from Src/FDO/DomainServices/BackupRestore/CantRestoreLinkedFilesToOriginalLocation.resx rename to Src/FdoUi/Dialogs/CantRestoreLinkedFilesToOriginalLocation.resx index 5ddd81ebef..484e6aa2dd 100644 --- a/Src/FDO/DomainServices/BackupRestore/CantRestoreLinkedFilesToOriginalLocation.resx +++ b/Src/FdoUi/Dialogs/CantRestoreLinkedFilesToOriginalLocation.resx @@ -1,4 +1,4 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + 64, 16 + + + 256, 23 + + + + 0 + + + You are deleting the following item: + + + label1 + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 7 + + + + Bottom, Right + + + 32, 248 + + + 278, 23 + + + 2 + + + Do you want to continue with the deletion? + + + label2 + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 6 + + + Delete + + + Bottom, Right + + + 73, 269 + + + 75, 23 + + + 4 + + + &Delete + + + m_deleteButton + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 5 + + + Cancel + + + Bottom, Right + + + 154, 269 + + + 75, 23 + + + 3 + + + &Cancel + + + m_cancelButton + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 4 + + + + iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAASRJREFUWEe1zVsO + wzAQQtHuf9NpaJnIdS+Tl4J0vgbs14UsOx7J9sGy9Mbu6nYOfZrUXg9dyd6jqNmcCj4kunVoI74fCj5Q + dO/QprjTBocjdTq0GbmHwcFMvQ5tZu7+Bcsz9Tq0mbn7EywSdTu0Ie5vwRJRt0Mb4v4WLBF1O7Qh7n+C + hUT9Dm0Sb/iY1EcJbRJv+JjURwltEm/4mNRHCW0Sb/iY1EcJbRJv+JjURwltEm/4mNRHCW0Sb/iY1EcJ + bRJvPsECUbdDG+L+Fiw9SX9+v/4GS3u0u7n9CRaJuoS6xP2/YJmoS6hL3MfgYKROhzYj99rgsOjeoU1x + 51DwgaI7oW5x51TwIdGNUFd8v5QjD+NN6r66nd3PythdPZL5k9mJvF5v0K5VDpC1lD0AAAAASUVORK5C + YII= + + + + 16, 8 + + + 32, 32 + + + 5 + + + pictureBox1 + + + System.Windows.Forms.PictureBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 3 + + + Top, Left, Right + + + 32, 48 + + + 264, 129 + + + 1 + + + panel1 + + + System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 1 + + + Top, Left, Right + + + 32, 183 + + + 264, 55 + + + 7 + + + panel2 + + + System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 0 + + + Bottom, Right + + + False + + + 235, 269 + + + 75, 23 + + + 6 + + + Help + + + False + + + buttonHelp + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 2 + + + True + + + 5, 13 + + + 334, 300 + + + CenterParent + + + Delete: + + + ConfirmDeleteObjectDlg + + + System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Src/FDO/Infrastructure/Impl/ConflictingSaveDlg.Designer.cs b/Src/FdoUi/Dialogs/ConflictingSaveDlg.Designer.cs similarity index 98% rename from Src/FDO/Infrastructure/Impl/ConflictingSaveDlg.Designer.cs rename to Src/FdoUi/Dialogs/ConflictingSaveDlg.Designer.cs index 9bf4d2d62c..9b05790a80 100644 --- a/Src/FDO/Infrastructure/Impl/ConflictingSaveDlg.Designer.cs +++ b/Src/FdoUi/Dialogs/ConflictingSaveDlg.Designer.cs @@ -1,4 +1,4 @@ -namespace SIL.FieldWorks.FDO.Infrastructure.Impl +namespace SIL.FieldWorks.FdoUi.Dialogs { partial class ConflictingSaveDlg { diff --git a/Src/FDO/Infrastructure/Impl/ConflictingSaveDlg.cs b/Src/FdoUi/Dialogs/ConflictingSaveDlg.cs similarity index 72% rename from Src/FDO/Infrastructure/Impl/ConflictingSaveDlg.cs rename to Src/FdoUi/Dialogs/ConflictingSaveDlg.cs index 2a56e0d603..5ac3ae348c 100644 --- a/Src/FDO/Infrastructure/Impl/ConflictingSaveDlg.cs +++ b/Src/FdoUi/Dialogs/ConflictingSaveDlg.cs @@ -1,13 +1,11 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; +// Copyright (c) 2013-2014 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) + using System.Drawing; -using System.Linq; -using System.Text; using System.Windows.Forms; -namespace SIL.FieldWorks.FDO.Infrastructure.Impl +namespace SIL.FieldWorks.FdoUi.Dialogs { /// /// This dialog is like a message box, but offers two buttons, OK and "Refresh Now", which diff --git a/Src/FDO/Infrastructure/Impl/ConflictingSaveDlg.resx b/Src/FdoUi/Dialogs/ConflictingSaveDlg.resx similarity index 99% rename from Src/FDO/Infrastructure/Impl/ConflictingSaveDlg.resx rename to Src/FdoUi/Dialogs/ConflictingSaveDlg.resx index 3377cb6229..fa19ee177d 100644 --- a/Src/FDO/Infrastructure/Impl/ConflictingSaveDlg.resx +++ b/Src/FdoUi/Dialogs/ConflictingSaveDlg.resx @@ -1,4 +1,4 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + 60, 12 + + + 488, 52 + + + + 3 + + + Some files in the Linked Files folder are newer than the ones which will be restored, and these may not be files that this FieldWorks project links to yet. + + + label_message + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 7 + + + 60, 64 + + + 488, 41 + + + 4 + + + Would you like to keep the newer files in the folder or replace them with the older ones from the backup? + + + label_Question + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 6 + + + 12, 12 + + + 42, 38 + + + 5 + + + pictureBox1 + + + System.Windows.Forms.PictureBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 5 + + + True + + + + NoControl + + + 64, 132 + + + 192, 17 + + + 13 + + + Use the older files from the backup. + + + radio_Overwrite + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 0 + + + True + + + NoControl + + + 64, 109 + + + 164, 17 + + + 12 + + + Keep newer files in the folder. + + + radio_Keep + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 1 + + + NoControl + + + 474, 157 + + + 75, 23 + + + 11 + + + Help + + + button_Help + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 2 + + + NoControl + + + 393, 157 + + + 75, 23 + + + 10 + + + Cancel + + + button_Cancel + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 3 + + + NoControl + + + 312, 157 + + + 75, 23 + + + 9 + + + OK + + + button_OK + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 4 + + + True + + + 6, 13 + + + 561, 192 + + + Linked files in backup are older + + + FilesToRestoreAreOlder + + + System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Src/FdoUi/MergeObjectDlg.cs b/Src/FdoUi/Dialogs/MergeObjectDlg.cs similarity index 99% rename from Src/FdoUi/MergeObjectDlg.cs rename to Src/FdoUi/Dialogs/MergeObjectDlg.cs index 2df2500f2f..e97c2e6c65 100644 --- a/Src/FdoUi/MergeObjectDlg.cs +++ b/Src/FdoUi/Dialogs/MergeObjectDlg.cs @@ -1,22 +1,20 @@ using System; -using System.Drawing; using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; using System.Linq; using System.Windows.Forms; -using System.Diagnostics; using System.Xml; +using SIL.FieldWorks.Common.COMInterfaces; +using SIL.FieldWorks.Common.Controls; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.Application; -using XCore; -using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.LexText.Controls; using SIL.Utils; -using SIL.FieldWorks.Common.Framework; -using SIL.FieldWorks.Common.FwUtils; -using SIL.FieldWorks.Common.Controls; -using SIL.CoreImpl; +using XCore; -namespace SIL.FieldWorks.FdoUi +namespace SIL.FieldWorks.FdoUi.Dialogs { /// /// Summary description for MergeObjectDlg. diff --git a/Src/FdoUi/MergeObjectDlg.resx b/Src/FdoUi/Dialogs/MergeObjectDlg.resx similarity index 99% rename from Src/FdoUi/MergeObjectDlg.resx rename to Src/FdoUi/Dialogs/MergeObjectDlg.resx index 5d1eaac6a1..7993e259eb 100644 --- a/Src/FdoUi/MergeObjectDlg.resx +++ b/Src/FdoUi/Dialogs/MergeObjectDlg.resx @@ -1,4 +1,4 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ../Resources/question.ico;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/Src/FDO/Resources/question.ico b/Src/FdoUi/Resources/question.ico similarity index 100% rename from Src/FDO/Resources/question.ico rename to Src/FdoUi/Resources/question.ico diff --git a/Src/FdoUi/WfiWordformUi.cs b/Src/FdoUi/WfiWordformUi.cs index 8bd5dec59c..3ec4326550 100644 --- a/Src/FdoUi/WfiWordformUi.cs +++ b/Src/FdoUi/WfiWordformUi.cs @@ -70,5 +70,13 @@ protected override bool IsAcceptableContextToJump(string toolCurrent, string too return base.IsAcceptableContextToJump(toolCurrent, toolTarget); } + public override bool CanDelete(out string cannotDeleteMsg) + { + if (base.CanDelete(out cannotDeleteMsg)) + return true; + cannotDeleteMsg = FdoUiStrings.ksCannotDeleteWordform; + return false; + } + } } diff --git a/Src/FwCoreDlgs/ArchiveWithRamp.cs b/Src/FwCoreDlgs/ArchiveWithRamp.cs index e1febf0b89..aa59f054e0 100644 --- a/Src/FwCoreDlgs/ArchiveWithRamp.cs +++ b/Src/FwCoreDlgs/ArchiveWithRamp.cs @@ -70,7 +70,7 @@ private void m_archive_Click(object sender, EventArgs e) private void get_Last_Backup() { - BackupFileRepository backups = new BackupFileRepository(); + BackupFileRepository backups = new BackupFileRepository(FwDirectoryFinder.DefaultBackupDirectory); var projName = backups.AvailableProjectNames.FirstOrDefault(s => s == m_cache.ProjectId.Name); if (!string.IsNullOrEmpty(projName)) diff --git a/Src/FwCoreDlgs/BackupRestore/BackupProjectDlg.cs b/Src/FwCoreDlgs/BackupRestore/BackupProjectDlg.cs index 8ae7a6c069..02b3fa89c0 100644 --- a/Src/FwCoreDlgs/BackupRestore/BackupProjectDlg.cs +++ b/Src/FwCoreDlgs/BackupRestore/BackupProjectDlg.cs @@ -66,7 +66,7 @@ public BackupProjectDlg(FdoCache cache, string appAbbrev, m_supportingFiles.Enabled = false; } - DestinationFolder = DirectoryFinder.DefaultBackupDirectory; + DestinationFolder = FwDirectoryFinder.DefaultBackupDirectory; if (File.Exists(m_presenter.PersistanceFilePath)) { // If something bad happens when loading the previous dialog settings (probably just a @@ -105,7 +105,7 @@ private void m_browse_Click(object sender, EventArgs e) if (String.IsNullOrEmpty(DestinationFolder) || !Directory.Exists(DestinationFolder)) { - dlg.SelectedPath = DirectoryFinder.DefaultBackupDirectory; + dlg.SelectedPath = FwDirectoryFinder.DefaultBackupDirectory; } else { @@ -151,12 +151,12 @@ private void m_backUp_Click(object sender, EventArgs e) } } - if (!DestinationFolder.Equals(DirectoryFinder.DefaultBackupDirectory)) + if (!DestinationFolder.Equals(FwDirectoryFinder.DefaultBackupDirectory)) { using (var dlgChangeDefaultBackupLocation = new ChangeDefaultBackupDir(m_helpTopicProvider)) { if (dlgChangeDefaultBackupLocation.ShowDialog(this) == DialogResult.Yes) - DirectoryFinder.DefaultBackupDirectory = DestinationFolder; + FwDirectoryFinder.DefaultBackupDirectory = DestinationFolder; } } @@ -166,7 +166,7 @@ private void m_backUp_Click(object sender, EventArgs e) try { using (new WaitCursor(this)) - using (ProgressDialogWithTask progressDlg = new ProgressDialogWithTask(this, m_cache.ThreadHelper)) + using (var progressDlg = new ProgressDialogWithTask(this)) { BackupFilePath = m_presenter.BackupProject(progressDlg); } diff --git a/Src/FwCoreDlgs/BackupRestore/BackupProjectPresenter.cs b/Src/FwCoreDlgs/BackupRestore/BackupProjectPresenter.cs index ce4990ce27..f9d4e8822f 100644 --- a/Src/FwCoreDlgs/BackupRestore/BackupProjectPresenter.cs +++ b/Src/FwCoreDlgs/BackupRestore/BackupProjectPresenter.cs @@ -11,6 +11,7 @@ using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.DomainServices.BackupRestore; using SIL.FieldWorks.Common.FwUtils; +using SIL.Utils; namespace SIL.FieldWorks.FwCoreDlgs.BackupRestore { @@ -39,7 +40,7 @@ internal BackupProjectPresenter(IBackupProjectView backupProjectView, string app m_backupProjectView = backupProjectView; //Older projects might not have this folder so when launching the backup dialog we want to create it. - Directory.CreateDirectory(DirectoryFinder.GetSupportingFilesDir(m_cache.ProjectId.ProjectFolder)); + Directory.CreateDirectory(FdoFileHelper.GetSupportingFilesDir(m_cache.ProjectId.ProjectFolder)); } /// @@ -49,8 +50,8 @@ internal String PersistanceFilePath { get { - return Path.Combine(DirectoryFinder.GetBackupSettingsDir(m_cache.ProjectId.ProjectFolder), - DirectoryFinder.kBackupSettingsFilename); + return Path.Combine(FdoFileHelper.GetBackupSettingsDir(m_cache.ProjectId.ProjectFolder), + FdoFileHelper.kBackupSettingsFilename); } } @@ -61,7 +62,7 @@ internal bool SupportingFilesFolderContainsFiles { get { - var supportingFilesFolder = DirectoryFinder.GetSupportingFilesDir(m_cache.ProjectId.ProjectFolder); + var supportingFilesFolder = FdoFileHelper.GetSupportingFilesDir(m_cache.ProjectId.ProjectFolder); var files = ProjectBackupService.GenerateFileListFolderAndSubfolders(supportingFilesFolder); if (files.Count > 0) return true; @@ -80,7 +81,7 @@ internal bool SupportingFilesFolderContainsFiles /// ------------------------------------------------------------------------------------ internal bool FileNameProblems(Form messageBoxOwner) { - BackupProjectSettings settings = new BackupProjectSettings(m_cache, m_backupProjectView); + BackupProjectSettings settings = new BackupProjectSettings(m_cache, m_backupProjectView, FwDirectoryFinder.DefaultBackupDirectory); settings.DestinationFolder = m_backupProjectView.DestinationFolder; if (settings.AdjustedComment.Trim() != settings.Comment.TrimEnd()) { @@ -115,12 +116,20 @@ internal bool FileNameProblems(Form messageBoxOwner) /// ------------------------------------------------------------------------------------ internal string BackupProject(IThreadedProgress progressDlg) { - BackupProjectSettings settings = new BackupProjectSettings(m_cache, m_backupProjectView); + BackupProjectSettings settings = new BackupProjectSettings(m_cache, m_backupProjectView, FwDirectoryFinder.DefaultBackupDirectory); settings.DestinationFolder = m_backupProjectView.DestinationFolder; settings.AppAbbrev = m_appAbbrev; ProjectBackupService backupService = new ProjectBackupService(m_cache, settings); - return backupService.BackupProject(progressDlg); + string backupFile; + if (!backupService.BackupProject(progressDlg, out backupFile)) + { + string msg = string.Format(FwCoreDlgs.ksCouldNotBackupSomeFiles, backupService.FailedFiles.ToString(", ", Path.GetFileName)); + if (MessageBox.Show(msg, FwCoreDlgs.ksWarning, MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes) + File.Delete(backupFile); + backupFile = null; + } + return backupFile; } } } diff --git a/Src/FwCoreDlgs/BackupRestore/RestoreProjectDlg.Designer.cs b/Src/FwCoreDlgs/BackupRestore/RestoreProjectDlg.Designer.cs index 537cda623b..e8c67b7ca3 100644 --- a/Src/FwCoreDlgs/BackupRestore/RestoreProjectDlg.Designer.cs +++ b/Src/FwCoreDlgs/BackupRestore/RestoreProjectDlg.Designer.cs @@ -1,4 +1,12 @@ -namespace SIL.FieldWorks.FwCoreDlgs.BackupRestore +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using System.Windows.Forms; +using SIL.FieldWorks.FDO.DomainServices.BackupRestore; +using SIL.Utils; + +namespace SIL.FieldWorks.FwCoreDlgs.BackupRestore { /// /// @@ -8,7 +16,7 @@ partial class RestoreProjectDlg /// /// Required designer variable. /// - private System.ComponentModel.IContainer components = null; + private IContainer components = null; /// /// Clean up any resources being used. @@ -16,7 +24,7 @@ partial class RestoreProjectDlg /// true if managed resources should be disposed; otherwise, false. protected override void Dispose(bool disposing) { - System.Diagnostics.Debug.WriteLineIf(!disposing, "****** Missing Dispose() call for " + GetType().Name + ". ****** "); + Debug.WriteLineIf(!disposing, "****** Missing Dispose() call for " + GetType().Name + ". ****** "); if (disposing) { if (m_openFileDlg != null) @@ -36,52 +44,52 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - System.Windows.Forms.Button m_btnHelp; - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RestoreProjectDlg)); - System.Windows.Forms.Button m_btnCancel; - System.Windows.Forms.Label label2; - System.Windows.Forms.Label label3; - System.Windows.Forms.Label label4; - System.Windows.Forms.Label label5; - System.Windows.Forms.Label label13; - System.Windows.Forms.Label label16; - this.m_btnBrowse = new System.Windows.Forms.Button(); - this.m_txtOtherProjectName = new System.Windows.Forms.TextBox(); - this.m_configurationSettings = new System.Windows.Forms.CheckBox(); - this.m_linkedFiles = new System.Windows.Forms.CheckBox(); - this.m_supportingFiles = new System.Windows.Forms.CheckBox(); - this.m_gbAlsoRestore = new System.Windows.Forms.GroupBox(); - this.m_spellCheckAdditions = new System.Windows.Forms.CheckBox(); - this.m_btnOk = new System.Windows.Forms.Button(); - this.m_lblOtherBackupIncludes = new System.Windows.Forms.Label(); - this.m_gbBackupProperties = new System.Windows.Forms.GroupBox(); - this.m_pnlDefaultBackupFolder = new System.Windows.Forms.Panel(); - this.m_lstVersions = new System.Windows.Forms.ListView(); - this.colDate = new System.Windows.Forms.ColumnHeader(); - this.colComment = new System.Windows.Forms.ColumnHeader(); - this.m_cboProjects = new System.Windows.Forms.ComboBox(); - this.m_lblDefaultBackupIncludes = new System.Windows.Forms.Label(); - this.label14 = new System.Windows.Forms.Label(); - this.m_pnlAnotherLocation = new System.Windows.Forms.Panel(); - this.m_lblBackupComment = new System.Windows.Forms.Label(); - this.m_lblBackupZipFile = new System.Windows.Forms.Label(); - this.m_lblBackupDate = new System.Windows.Forms.Label(); - this.m_lblBackupProjectName = new System.Windows.Forms.Label(); - this.label6 = new System.Windows.Forms.Label(); - this.m_gbRestoreAs = new System.Windows.Forms.GroupBox(); - this.m_rdoUseOriginalName = new System.Windows.Forms.RadioButton(); - this.m_rdoRestoreToName = new System.Windows.Forms.RadioButton(); - this.m_rdoDefaultFolder = new System.Windows.Forms.RadioButton(); - this.m_rdoAnotherLocation = new System.Windows.Forms.RadioButton(); - this.label1 = new System.Windows.Forms.Label(); - m_btnHelp = new System.Windows.Forms.Button(); - m_btnCancel = new System.Windows.Forms.Button(); - label2 = new System.Windows.Forms.Label(); - label3 = new System.Windows.Forms.Label(); - label4 = new System.Windows.Forms.Label(); - label5 = new System.Windows.Forms.Label(); - label13 = new System.Windows.Forms.Label(); - label16 = new System.Windows.Forms.Label(); + Button m_btnHelp; + ComponentResourceManager resources = new ComponentResourceManager(typeof(RestoreProjectDlg)); + Button m_btnCancel; + Label label2; + Label label3; + Label label4; + Label label5; + Label label13; + Label label16; + this.m_btnBrowse = new Button(); + this.m_txtOtherProjectName = new TextBox(); + this.m_configurationSettings = new CheckBox(); + this.m_linkedFiles = new CheckBox(); + this.m_supportingFiles = new CheckBox(); + this.m_gbAlsoRestore = new GroupBox(); + this.m_spellCheckAdditions = new CheckBox(); + this.m_btnOk = new Button(); + this.m_lblOtherBackupIncludes = new Label(); + this.m_gbBackupProperties = new GroupBox(); + this.m_pnlDefaultBackupFolder = new Panel(); + this.m_lstVersions = new ListView(); + this.colDate = new ColumnHeader(); + this.colComment = new ColumnHeader(); + this.m_cboProjects = new ComboBox(); + this.m_lblDefaultBackupIncludes = new Label(); + this.label14 = new Label(); + this.m_pnlAnotherLocation = new Panel(); + this.m_lblBackupComment = new Label(); + this.m_lblBackupZipFile = new Label(); + this.m_lblBackupDate = new Label(); + this.m_lblBackupProjectName = new Label(); + this.label6 = new Label(); + this.m_gbRestoreAs = new GroupBox(); + this.m_rdoUseOriginalName = new RadioButton(); + this.m_rdoRestoreToName = new RadioButton(); + this.m_rdoDefaultFolder = new RadioButton(); + this.m_rdoAnotherLocation = new RadioButton(); + this.label1 = new Label(); + m_btnHelp = new Button(); + m_btnCancel = new Button(); + label2 = new Label(); + label3 = new Label(); + label4 = new Label(); + label5 = new Label(); + label13 = new Label(); + label16 = new Label(); this.m_gbAlsoRestore.SuspendLayout(); this.m_gbBackupProperties.SuspendLayout(); this.m_pnlDefaultBackupFolder.SuspendLayout(); @@ -94,12 +102,12 @@ private void InitializeComponent() resources.ApplyResources(m_btnHelp, "m_btnHelp"); m_btnHelp.Name = "m_btnHelp"; m_btnHelp.UseVisualStyleBackColor = true; - m_btnHelp.Click += new System.EventHandler(this.m_btnHelp_Click); + m_btnHelp.Click += new EventHandler(this.m_btnHelp_Click); // // m_btnCancel // resources.ApplyResources(m_btnCancel, "m_btnCancel"); - m_btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + m_btnCancel.DialogResult = DialogResult.Cancel; m_btnCancel.Name = "m_btnCancel"; m_btnCancel.UseVisualStyleBackColor = true; // @@ -138,7 +146,7 @@ private void InitializeComponent() resources.ApplyResources(this.m_btnBrowse, "m_btnBrowse"); this.m_btnBrowse.Name = "m_btnBrowse"; this.m_btnBrowse.UseVisualStyleBackColor = true; - this.m_btnBrowse.Click += new System.EventHandler(this.m_btnBrowse_Click); + this.m_btnBrowse.Click += new EventHandler(this.m_btnBrowse_Click); // // m_txtOtherProjectName // @@ -184,7 +192,7 @@ private void InitializeComponent() resources.ApplyResources(this.m_btnOk, "m_btnOk"); this.m_btnOk.Name = "m_btnOk"; this.m_btnOk.UseVisualStyleBackColor = true; - this.m_btnOk.Click += new System.EventHandler(this.m_btnOk_Click); + this.m_btnOk.Click += new EventHandler(this.m_btnOk_Click); // // m_lblOtherBackupIncludes // @@ -213,19 +221,19 @@ private void InitializeComponent() // m_lstVersions // resources.ApplyResources(this.m_lstVersions, "m_lstVersions"); - this.m_lstVersions.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.m_lstVersions.Columns.AddRange(new ColumnHeader[] { this.colDate, this.colComment}); this.m_lstVersions.FullRowSelect = true; - this.m_lstVersions.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None; + this.m_lstVersions.HeaderStyle = ColumnHeaderStyle.None; this.m_lstVersions.HideSelection = false; this.m_lstVersions.MultiSelect = false; this.m_lstVersions.Name = "m_lstVersions"; this.m_lstVersions.ShowGroups = false; this.m_lstVersions.UseCompatibleStateImageBehavior = false; - this.m_lstVersions.View = System.Windows.Forms.View.Details; - this.m_lstVersions.SelectedIndexChanged += new System.EventHandler(this.m_lstVersions_SelectedIndexChanged); - this.m_lstVersions.SizeChanged += new System.EventHandler(this.m_lstVersions_SizeChanged); + this.m_lstVersions.View = View.Details; + this.m_lstVersions.SelectedIndexChanged += new EventHandler(this.m_lstVersions_SelectedIndexChanged); + this.m_lstVersions.SizeChanged += new EventHandler(this.m_lstVersions_SizeChanged); // // colDate // @@ -238,10 +246,10 @@ private void InitializeComponent() // m_cboProjects // resources.ApplyResources(this.m_cboProjects, "m_cboProjects"); - this.m_cboProjects.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.m_cboProjects.DropDownStyle = ComboBoxStyle.DropDownList; this.m_cboProjects.FormattingEnabled = true; this.m_cboProjects.Name = "m_cboProjects"; - this.m_cboProjects.SelectedIndexChanged += new System.EventHandler(this.m_cboProjects_SelectedIndexChanged); + this.m_cboProjects.SelectedIndexChanged += new EventHandler(this.m_cboProjects_SelectedIndexChanged); // // m_lblDefaultBackupIncludes // @@ -316,7 +324,7 @@ private void InitializeComponent() this.m_rdoRestoreToName.Name = "m_rdoRestoreToName"; this.m_rdoRestoreToName.TabStop = true; this.m_rdoRestoreToName.UseVisualStyleBackColor = true; - this.m_rdoRestoreToName.CheckedChanged += new System.EventHandler(this.m_rdoRestoreToName_CheckedChanged); + this.m_rdoRestoreToName.CheckedChanged += new EventHandler(this.m_rdoRestoreToName_CheckedChanged); // // m_rdoDefaultFolder // @@ -325,7 +333,7 @@ private void InitializeComponent() this.m_rdoDefaultFolder.Name = "m_rdoDefaultFolder"; this.m_rdoDefaultFolder.TabStop = true; this.m_rdoDefaultFolder.UseVisualStyleBackColor = true; - this.m_rdoDefaultFolder.CheckedChanged += new System.EventHandler(this.m_rdoDefaultFolder_CheckedChanged); + this.m_rdoDefaultFolder.CheckedChanged += new EventHandler(this.m_rdoDefaultFolder_CheckedChanged); // // m_rdoAnotherLocation // @@ -342,7 +350,7 @@ private void InitializeComponent() // this.AcceptButton = this.m_btnOk; resources.ApplyResources(this, "$this"); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoScaleMode = AutoScaleMode.Font; this.CancelButton = m_btnCancel; this.Controls.Add(this.label1); this.Controls.Add(this.m_gbRestoreAs); @@ -375,34 +383,34 @@ private void InitializeComponent() #endregion - private System.Windows.Forms.Button m_btnBrowse; - private System.Windows.Forms.TextBox m_txtOtherProjectName; - private System.Windows.Forms.CheckBox m_configurationSettings; - private System.Windows.Forms.CheckBox m_linkedFiles; - private System.Windows.Forms.CheckBox m_supportingFiles; - private System.Windows.Forms.GroupBox m_gbAlsoRestore; - private System.Windows.Forms.Button m_btnOk; - private System.Windows.Forms.Label m_lblOtherBackupIncludes; - private System.Windows.Forms.GroupBox m_gbBackupProperties; - private System.Windows.Forms.CheckBox m_spellCheckAdditions; - private System.Windows.Forms.GroupBox m_gbRestoreAs; - private System.Windows.Forms.RadioButton m_rdoUseOriginalName; - private System.Windows.Forms.RadioButton m_rdoRestoreToName; - private System.Windows.Forms.RadioButton m_rdoDefaultFolder; - private System.Windows.Forms.RadioButton m_rdoAnotherLocation; - private System.Windows.Forms.Label label6; - private System.Windows.Forms.Label m_lblBackupComment; - private System.Windows.Forms.Label m_lblBackupDate; - private System.Windows.Forms.Label m_lblBackupProjectName; - private System.Windows.Forms.Label m_lblBackupZipFile; - private System.Windows.Forms.Panel m_pnlAnotherLocation; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Panel m_pnlDefaultBackupFolder; - private System.Windows.Forms.Label m_lblDefaultBackupIncludes; - private System.Windows.Forms.Label label14; - private System.Windows.Forms.ComboBox m_cboProjects; - private System.Windows.Forms.ListView m_lstVersions; - private System.Windows.Forms.ColumnHeader colDate; - private System.Windows.Forms.ColumnHeader colComment; + private Button m_btnBrowse; + private TextBox m_txtOtherProjectName; + private CheckBox m_configurationSettings; + private CheckBox m_linkedFiles; + private CheckBox m_supportingFiles; + private GroupBox m_gbAlsoRestore; + private Button m_btnOk; + private Label m_lblOtherBackupIncludes; + private GroupBox m_gbBackupProperties; + private CheckBox m_spellCheckAdditions; + private GroupBox m_gbRestoreAs; + private RadioButton m_rdoUseOriginalName; + private RadioButton m_rdoRestoreToName; + private RadioButton m_rdoDefaultFolder; + private RadioButton m_rdoAnotherLocation; + private Label label6; + private Label m_lblBackupComment; + private Label m_lblBackupDate; + private Label m_lblBackupProjectName; + private Label m_lblBackupZipFile; + private Panel m_pnlAnotherLocation; + private Label label1; + private Panel m_pnlDefaultBackupFolder; + private Label m_lblDefaultBackupIncludes; + private Label label14; + private ComboBox m_cboProjects; + private ListView m_lstVersions; + private ColumnHeader colDate; + private ColumnHeader colComment; } } \ No newline at end of file diff --git a/Src/FwCoreDlgs/BackupRestore/RestoreProjectDlg.cs b/Src/FwCoreDlgs/BackupRestore/RestoreProjectDlg.cs index eb5da5be57..a9701ca53b 100644 --- a/Src/FwCoreDlgs/BackupRestore/RestoreProjectDlg.cs +++ b/Src/FwCoreDlgs/BackupRestore/RestoreProjectDlg.cs @@ -16,7 +16,6 @@ using SIL.Utils; using SIL.Utils.FileDialog; using XCore; -using System.Diagnostics; namespace SIL.FieldWorks.FwCoreDlgs.BackupRestore { @@ -25,6 +24,42 @@ namespace SIL.FieldWorks.FwCoreDlgs.BackupRestore /// public partial class RestoreProjectDlg : Form { + /// ------------------------------------------------------------------------------------ + /// + /// Performs the requested actions and handles any IO or zip error by reporting them to + /// the user. (Intended for operations that deal directly with a backup zip file. + /// + /// The parent window to use when reporting an error (can be + /// null). + /// Used in title bar of message box when reporting an error + /// (typically the name of the application). + /// + /// The backup zip filename. + /// The action to perform. + /// + /// true if successful (no exception caught); false otherwise + /// + /// ------------------------------------------------------------------------------------ + public static bool HandleRestoreFileErrors(IWin32Window parentWindow, string caption, string zipFilename, Action action) + { + try + { + action(); + } + catch (Exception error) + { + if (error is IOException || error is InvalidBackupFileException || + error is UnauthorizedAccessException) + { + Logger.WriteError(error); + MessageBoxUtils.Show(parentWindow, error.Message, caption, MessageBoxButtons.OK, MessageBoxIcon.Information); + return false; + } + throw; + } + return true; + } + #region Data members private readonly string m_appName; private readonly IHelpTopicProvider m_helpTopicProvider; @@ -94,17 +129,17 @@ private RestoreProjectDlg(string appName, IHelpTopicProvider helpTopicProvider) { m_appName = appName; m_helpTopicProvider = helpTopicProvider; - m_lblOtherBackupIncludes.Text = string.Empty; - m_lblDefaultBackupIncludes.Text = string.Empty; - m_lblBackupZipFile.Text = string.Empty; - m_lblBackupProjectName.Text = string.Empty; - m_lblBackupDate.Text = string.Empty; - m_lblBackupComment.Text = string.Empty; + m_lblOtherBackupIncludes.Text = String.Empty; + m_lblDefaultBackupIncludes.Text = String.Empty; + m_lblBackupZipFile.Text = String.Empty; + m_lblBackupProjectName.Text = String.Empty; + m_lblBackupDate.Text = String.Empty; + m_lblBackupComment.Text = String.Empty; m_fmtUseOriginalName = m_rdoUseOriginalName.Text; m_rdoUseOriginalName.Text = String.Format(m_fmtUseOriginalName, String.Empty); - m_settings = new RestoreProjectSettings(); - m_txtOtherProjectName.KeyPress += new KeyPressEventHandler(m_txtOtherProjectName_KeyPress); - m_txtOtherProjectName.TextChanged += new EventHandler(m_txtOtherProjectName_TextChanged); + m_settings = new RestoreProjectSettings(FwDirectoryFinder.ProjectsDirectory); + m_txtOtherProjectName.KeyPress += m_txtOtherProjectName_KeyPress; + m_txtOtherProjectName.TextChanged += m_txtOtherProjectName_TextChanged; GetIllegalProjectNameChars(); } @@ -250,7 +285,7 @@ private void m_btnBrowse_Click(object sender, EventArgs e) { m_openFileDlg = new OpenFileDialogAdapter(); m_openFileDlg.CheckFileExists = true; - m_openFileDlg.InitialDirectory = DirectoryFinder.DefaultBackupDirectory; + m_openFileDlg.InitialDirectory = FwDirectoryFinder.DefaultBackupDirectory; m_openFileDlg.RestoreDirectory = true; m_openFileDlg.Title = FwCoreDlgs.ksFindBackupFileDialogTitle; m_openFileDlg.ValidateNames = true; @@ -288,7 +323,7 @@ private void OnBackupVersionChosen() return; } - if (ProjectRestoreService.HandleRestoreFileErrors(this, m_appName, BackupZipFile, + if (HandleRestoreFileErrors(this, m_appName, BackupZipFile, () => BackupFileSettings = new BackupFileSettings(BackupZipFile, true))) { SetOriginalNameFromSettings(); diff --git a/Src/FwCoreDlgs/BackupRestore/RestoreProjectPresenter.cs b/Src/FwCoreDlgs/BackupRestore/RestoreProjectPresenter.cs index aa8209f929..f31e34931c 100644 --- a/Src/FwCoreDlgs/BackupRestore/RestoreProjectPresenter.cs +++ b/Src/FwCoreDlgs/BackupRestore/RestoreProjectPresenter.cs @@ -10,6 +10,7 @@ using System.Text; using System.Web.Configuration; using System.Windows.Forms; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices.BackupRestore; using System.Collections.Generic; using System.IO; @@ -53,7 +54,7 @@ public RestoreProjectPresenter(RestoreProjectDlg restoreProjectView) public RestoreProjectPresenter(RestoreProjectDlg restoreProjectView, string defaultProjectName) : this(restoreProjectView) { - m_backupFiles = new BackupFileRepository(); + m_backupFiles = new BackupFileRepository(FwDirectoryFinder.DefaultBackupDirectory); m_defaultProjectName = defaultProjectName; m_fEmptyProjectName = false; } diff --git a/Src/FwCoreDlgs/CharContextCtrl.cs b/Src/FwCoreDlgs/CharContextCtrl.cs index 8bab529462..3ccba8c0c8 100644 --- a/Src/FwCoreDlgs/CharContextCtrl.cs +++ b/Src/FwCoreDlgs/CharContextCtrl.cs @@ -136,7 +136,7 @@ public void Initialize(FdoCache cache, IWritingSystemContainer wsContainer, TokenGrid = tokenGrid; if (FwUtils.IsOkToDisplayScriptureIfPresent) - m_scrChecksDllFile = DirectoryFinder.BasicEditorialChecksDll; + m_scrChecksDllFile = FwDirectoryFinder.BasicEditorialChecksDll; if (m_ws != null) { @@ -328,7 +328,7 @@ private ValidCharacters ValidCharacters // Get the writing system and valid characters list if (m_wsContainer.DefaultVernacularWritingSystem == null) return null; - return ValidCharacters.Load(m_wsContainer.DefaultVernacularWritingSystem, LoadException); + return ValidCharacters.Load(m_wsContainer.DefaultVernacularWritingSystem, LoadException, FwDirectoryFinder.LegacyWordformingCharOverridesFile); } } @@ -636,11 +636,12 @@ private void GetTokensSubStrings(string fileName) /// ------------------------------------------------------------------------------------ private List ReadTEScripture() { - var scrDataSource = new ScrChecksDataSource(m_cache, DirectoryFinder.TeStylesPath); + var scrDataSource = new ScrChecksDataSource(m_cache, ResourceHelper.GetResourceString("kstidPunctCheckWhitespaceChar"), + FwDirectoryFinder.LegacyWordformingCharOverridesFile, FwDirectoryFinder.TeStylesPath); scrDataSource.LoadException += scrDataSource_LoadException; - IScrCheckInventory scrCharInventoryBldr = CreateScrCharInventoryBldr(DirectoryFinder.BasicEditorialChecksDll, + IScrCheckInventory scrCharInventoryBldr = CreateScrCharInventoryBldr(FwDirectoryFinder.BasicEditorialChecksDll, scrDataSource, m_checkToRun == CheckType.Punctuation ? "SILUBS.ScriptureChecks.PunctuationCheck" : "SILUBS.ScriptureChecks.CharactersCheck"); @@ -783,7 +784,7 @@ public class ContextInfo /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The punctuation pattern. /// The TextTokenSubstring. @@ -795,7 +796,7 @@ internal ContextInfo(PuncPattern pattern, TextTokenSubstring tts) : /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The character or pattern to which this context applies. /// The TextTokenSubstring. @@ -807,7 +808,7 @@ internal ContextInfo(string chr, TextTokenSubstring tts) /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The punctuation pattern. /// The offset. @@ -836,7 +837,7 @@ internal ContextInfo(PuncPattern pattern, int offset, string context, string ref /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The character or pattern to which this context applies. /// The offset. @@ -850,7 +851,7 @@ internal ContextInfo(string chr, int offset, string context, string reference) /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The character or pattern to which this context applies. /// The offset (can be negative!). @@ -944,7 +945,7 @@ public class ContextGrid : DataGridView { /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// ------------------------------------------------------------------------------------ public ContextGrid() diff --git a/Src/FwCoreDlgs/ChooseLangProjectDialog.cs b/Src/FwCoreDlgs/ChooseLangProjectDialog.cs index 5db14bd320..16cb4d5e9d 100644 --- a/Src/FwCoreDlgs/ChooseLangProjectDialog.cs +++ b/Src/FwCoreDlgs/ChooseLangProjectDialog.cs @@ -17,6 +17,7 @@ using System.Windows.Forms; using SIL.FieldWorks.Common.Controls; using SIL.FieldWorks.Common.FwUtils; +using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.Resources; using SIL.Utils; @@ -96,7 +97,8 @@ private ChooseLangProjectDialog() /// The initial client bounds of the dialog. /// The initial splitter position. /// ------------------------------------------------------------------------------------ - public ChooseLangProjectDialog(Rectangle bounds, int splitterPosition) : this(null, false) + public ChooseLangProjectDialog(Rectangle bounds, int splitterPosition) + : this(null, false) { m_initialBounds = bounds; m_initialSplitterPosition = splitterPosition; @@ -115,7 +117,8 @@ public ChooseLangProjectDialog(Rectangle bounds, int splitterPosition) : this(nu /// /// ------------------------------------------------------------------------------------ public ChooseLangProjectDialog(IHelpTopicProvider helpTopicProvider, - bool openToAssosiateFwProject) : this() + bool openToAssosiateFwProject) + : this() { m_helpTopicProvider = helpTopicProvider; @@ -220,8 +223,15 @@ protected override void OnShown(EventArgs e) } } - // Asynchronously search for other Servers. - ClientServerServices.Current.BeginFindServers(AddHost1); + try + { + // Asynchronously search for other Servers. + ClientServerServices.Current.BeginFindServers(AddHost1); + } + catch (Exception) + { + MessageBox.Show(FwCoreDlgs.ksFindServersError, FwCoreDlgs.ksError, MessageBoxButtons.OK, MessageBoxIcon.Error); + } m_lstLanguageProjects.SelectedIndexChanged += LanguageProjectsListSelectedIndexChanged; @@ -272,9 +282,6 @@ internal bool AddHost(string ipAddress) return false; } - // store the HostName -> ipaddress mapping. - m_hostIpAddressMap[entry.HostName] = ipAddress; - AddHostInternal(entry); return true; @@ -299,6 +306,9 @@ private void AddHostInternal(IPHostEntry entry) if (IsDisposed || m_networkNeighborhood.Nodes.ContainsKey((entry.HostName))) return; + // store the HostName -> ipaddress mapping. + m_hostIpAddressMap[entry.HostName] = entry.AddressList[0].ToString(); + // if list of associated addresses in entry matches list of associated addresses of any item in hostsTreeView // then ignore as its the same host. try @@ -486,12 +496,12 @@ private void OkButtonClick(object sender, EventArgs e) if (m_hostsTreeView.SelectedNode == m_localhostNode) { Project = ((LanguageProjectInfo)m_lstLanguageProjects.SelectedItem).FullName; - if (Project.EndsWith(FwFileExtensions.ksFwDataFallbackFileExtension)) + if (Project.EndsWith(FdoFileHelper.ksFwDataFallbackFileExtension)) { // The user chose a .bak file, only possible when the fwdata file is missing. // Rename it and open it. string bakFileName = Project; - Project = Path.ChangeExtension(bakFileName, FwFileExtensions.ksFwDataXmlFileExtension); + Project = Path.ChangeExtension(bakFileName, FdoFileHelper.ksFwDataXmlFileExtension); try { File.Move(bakFileName, Project); @@ -519,7 +529,7 @@ private void OkButtonClick(object sender, EventArgs e) private string HostsFileName { - get { return Path.Combine(DirectoryFinder.ProjectsDirectory, "HostsManuallyConnected.txt"); } + get { return Path.Combine(FwDirectoryFinder.ProjectsDirectory, "HostsManuallyConnected.txt"); } } private void AddHostButtonClick(object sender, EventArgs e) @@ -539,7 +549,7 @@ private void OpenFwDataProjectLinkClicked(object sender, LinkLabelLinkClickedEve { Hide(); dlg.CheckFileExists = true; - dlg.InitialDirectory = DirectoryFinder.ProjectsDirectory; + dlg.InitialDirectory = FwDirectoryFinder.ProjectsDirectory; dlg.RestoreDirectory = true; dlg.Title = FwCoreDlgs.ksChooseLangProjectDialogTitle; dlg.ValidateNames = true; diff --git a/Src/FwCoreDlgs/ClientServerServicesHelper.cs b/Src/FwCoreDlgs/ClientServerServicesHelper.cs new file mode 100644 index 0000000000..bfc7b55118 --- /dev/null +++ b/Src/FwCoreDlgs/ClientServerServicesHelper.cs @@ -0,0 +1,53 @@ +// Copyright (c) 2013-2014 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) + +using System; +using System.Windows.Forms; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.FDO.DomainServices; +using SIL.Utils; + +namespace SIL.FieldWorks.FwCoreDlgs +{ + /// + /// Provides a common place for calls which utilize FDO's ClientServerServices + /// + public static class ClientServerServicesHelper + { + /// + /// Display a warning indicating that it may be dangerous to change things in the dialog that + /// is about to open when other users are connected. The warning should only be shown if, in fact, + /// other users are currently connected. The dialog may contain some information about the other + /// users that are connected. Return true to continue, false to cancel opening the dialog. + /// + /// + public static bool WarnOnOpeningSingleUserDialog(FdoCache cache) + { + var others = ClientServerServices.Current.CountOfOtherUsersConnected(cache); + if (others == 0) + return true; + var msg = string.Format(Strings.ksWarnOnOpeningSingleUserDialog.Replace("\\n", Environment.NewLine), others); + return ThreadHelper.ShowMessageBox(null, msg, Strings.ksOthersConnectedCaption, + MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK; + } + + /// + /// Display a warning indicating that it may be dangerous to change things that the user has just + /// asked to change when other users are connected. The warning should only be shown if, in fact, + /// other users are currently connected. The dialog may contain some information about the other + /// users that are connected. Return true to continue, false to discard the changes. This is typically + /// called in response to clicking an OK button in a dialog which changes dangerous user settings. + /// + /// + public static bool WarnOnConfirmingSingleUserChanges(FdoCache cache) + { + var others = ClientServerServices.Current.CountOfOtherUsersConnected(cache); + if (others == 0) + return true; + var msg = string.Format(Strings.ksWarnOnConfirmingSingleUserChanges.Replace("\\n", Environment.NewLine), others); + return ThreadHelper.ShowMessageBox(null, msg, Strings.ksNotAdvisableOthersConnectedCaption, + MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes; + } + } +} diff --git a/Src/FwCoreDlgs/FwApplyStyleDlg.cs b/Src/FwCoreDlgs/FwApplyStyleDlg.cs index f461500b71..7a6e079974 100644 --- a/Src/FwCoreDlgs/FwApplyStyleDlg.cs +++ b/Src/FwCoreDlgs/FwApplyStyleDlg.cs @@ -83,7 +83,7 @@ public FwApplyStyleDlg(IVwRootSite rootSite, FdoCache cache, int hvoStylesOwner, m_styleTable = new StyleInfoTable(normalStyleName, cache.ServiceLocator.WritingSystemManager); m_styleSheet = new FwStyleSheet(); - m_styleSheet.Init(cache, hvoStylesOwner, stylesTag); + m_styleSheet.Init(cache, hvoStylesOwner, stylesTag, ResourceHelper.DefaultParaCharsStyleName); m_styleListHelper = new StyleListBoxHelper(m_lstStyles); m_styleListHelper.ShowInternalStyles = false; } diff --git a/Src/FwCoreDlgs/FwCheckAnthroListDlg.cs b/Src/FwCoreDlgs/FwCheckAnthroListDlg.cs index 0926bbe14c..90c30221c5 100644 --- a/Src/FwCoreDlgs/FwCheckAnthroListDlg.cs +++ b/Src/FwCoreDlgs/FwCheckAnthroListDlg.cs @@ -151,15 +151,15 @@ private void CustomTextClick(object sender, EventArgs e) /// Pops up a dialog to ask the user how they want to initialize their anthro lists. /// Returns a string indicating what file to load, or null if the user selected the custom (make your own) option /// - public static string PickAnthroList(Form parent, string description, IHelpTopicProvider helpTopicProvider) + public static string PickAnthroList(string description, IHelpTopicProvider helpTopicProvider) { // Figure out what lists are available (in {FW}/Templates/*.xml). - var sFilePattern = Path.Combine(DirectoryFinder.TemplateDirectory, "*.xml"); + var sFilePattern = Path.Combine(FwDirectoryFinder.TemplateDirectory, "*.xml"); var fHaveOCM = false; var fHaveFRAME = false; var rgsAnthroFiles = new List(); - var rgsXmlFiles = Directory.GetFiles(DirectoryFinder.TemplateDirectory, "*.xml", SearchOption.TopDirectoryOnly); + var rgsXmlFiles = Directory.GetFiles(FwDirectoryFinder.TemplateDirectory, "*.xml", SearchOption.TopDirectoryOnly); string sFile; for (var i = 0; i < rgsXmlFiles.Length; ++i) { @@ -183,7 +183,7 @@ public static string PickAnthroList(Form parent, string description, IHelpTopicP if (!String.IsNullOrEmpty(description)) dlg.SetDescription(description); //EnableRelatedWindows(hwnd, false); - DialogResult res = dlg.ShowDialog(parent); + DialogResult res = dlg.ShowDialog(); //EnableRelatedWindows(hwnd, true); if (res == DialogResult.OK) { @@ -193,14 +193,14 @@ public static string PickAnthroList(Form parent, string description, IHelpTopicP case kralUserDef: break; case kralOCM: - sFile = Path.Combine(DirectoryFinder.TemplateDirectory, "OCM.xml"); + sFile = Path.Combine(FwDirectoryFinder.TemplateDirectory, "OCM.xml"); break; case kralFRAME: - sFile = Path.Combine(DirectoryFinder.TemplateDirectory, "OCM-Frame.xml"); + sFile = Path.Combine(FwDirectoryFinder.TemplateDirectory, "OCM-Frame.xml"); break; default: Debug.Assert(nChoice >= 0 && nChoice < rgsAnthroFiles.Count); - sFile = Path.Combine(DirectoryFinder.TemplateDirectory, rgsAnthroFiles[nChoice]); + sFile = Path.Combine(FwDirectoryFinder.TemplateDirectory, rgsAnthroFiles[nChoice]); break; } } diff --git a/Src/FwCoreDlgs/FwCoreDlgControls/FontInfoExtensions.cs b/Src/FwCoreDlgs/FwCoreDlgControls/FontInfoExtensions.cs new file mode 100644 index 0000000000..25faca6110 --- /dev/null +++ b/Src/FwCoreDlgs/FwCoreDlgControls/FontInfoExtensions.cs @@ -0,0 +1,219 @@ +using System; +using System.Text; +using SIL.FieldWorks.Common.COMInterfaces; +using SIL.FieldWorks.FDO.DomainServices; +using SIL.FieldWorks.Resources; +using SIL.Utils; + +namespace SIL.FieldWorks.FwCoreDlgControls +{ + /// + /// UI extensions methods for FontInfo + /// + public static class FontInfoExtensions + { + /// + /// Gets the name of the UI font. + /// + /// + public static string UIFontName(this FontInfo fontInfo) + { + if (fontInfo.m_fontName.Value == StyleServices.DefaultFont) + return ResourceHelper.GetResourceString("kstidDefaultFont"); + return fontInfo.m_fontName.Value; + } + + /// ------------------------------------------------------------------------------------ + /// + /// Returns a that represents the current + /// . This method returns a human-readable + /// string that is culture-sensitive + /// + /// + /// if set to true forces at least minimum + /// description (i.e., font and size) to be returned. + /// + /// A that represents the current + /// . + /// + /// ------------------------------------------------------------------------------------ + public static string ToString(this FontInfo fontInfo, bool fForceMinimumDescription) + { + var text = new StringBuilder(); + + if (fontInfo.m_fontName.IsExplicit || fForceMinimumDescription) + AppendToString(text, fontInfo.UIFontName()); + + if (fontInfo.m_fontSize.IsExplicit || fForceMinimumDescription) + AppendToString(text, string.Format(FwCoreDlgControls.ksXPt, fontInfo.m_fontSize.Value / 1000)); + + if (fontInfo.m_fontColor.IsExplicit || fontInfo.m_backColor.IsExplicit) + AppendFontColor(fontInfo, text); + + if (fontInfo.m_underline.IsExplicit || fontInfo.m_underlineColor.IsExplicit) + AppendUnderline(fontInfo, text); + + if (fontInfo.m_bold.IsExplicit) + AppendToString(text, fontInfo.m_bold.Value ? FwCoreDlgControls.ksBold : FwCoreDlgControls.ksNotBold); + + if (fontInfo.m_italic.IsExplicit) + AppendToString(text, fontInfo.m_italic.Value ? FwCoreDlgControls.ksItalic : FwCoreDlgControls.ksNotItalic); + + if (fontInfo.m_superSub.IsExplicit) + AppendSuperSub(text, fontInfo.m_superSub.Value); + + if (fontInfo.m_offset.IsExplicit) + AppendFontOffset(text, fontInfo.m_offset.Value); + + return text.ToString(); + } + + #region Helper methods and properties to build font description + + /// ------------------------------------------------------------------------------------ + /// + /// Appends the font and background color information to the description + /// + /// + /// The text. + /// ------------------------------------------------------------------------------------ + private static void AppendFontColor(FontInfo fontInfo, StringBuilder text) + { + if (fontInfo.m_fontColor.IsInherited) + AppendToString(text, String.Format(FwCoreDlgControls.ksBackgroundIsX, + ColorUtil.ColorToName(fontInfo.m_backColor.Value))); + else if (fontInfo.m_backColor.IsInherited) + AppendToString(text, String.Format(FwCoreDlgControls.ksTextIsX, + ColorUtil.ColorToName(fontInfo.m_fontColor.Value))); + else + AppendToString(text, string.Format(FwCoreDlgControls.ksTextIsXonY, + ColorUtil.ColorToName(fontInfo.m_fontColor.Value), + ColorUtil.ColorToName(fontInfo.m_backColor.Value))); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Appends the underline information to the description. + /// + /// + /// The text. + /// ------------------------------------------------------------------------------------ + private static void AppendUnderline(FontInfo fontInfo, StringBuilder text) + { + string sUnder = ""; + if (fontInfo.m_underlineColor.IsExplicit) + { + string sColor = ColorUtil.ColorToName(fontInfo.m_underlineColor.Value); + if (fontInfo.m_underline.IsExplicit) + { + switch (fontInfo.m_underline.Value) + { + case FwUnderlineType.kuntNone: + sUnder = String.Format(FwCoreDlgControls.ksNoColorUnderline, sColor); + break; + case FwUnderlineType.kuntSingle: + sUnder = String.Format(FwCoreDlgControls.ksSingleColorUnderline, sColor); + break; + case FwUnderlineType.kuntDouble: + sUnder = String.Format(FwCoreDlgControls.ksDoubleColorUnderline, sColor); + break; + case FwUnderlineType.kuntDotted: + sUnder = String.Format(FwCoreDlgControls.ksDottedColorUnderline, sColor); + break; + case FwUnderlineType.kuntDashed: + sUnder = String.Format(FwCoreDlgControls.ksDashedColorUnderline, sColor); + break; + case FwUnderlineType.kuntStrikethrough: + sUnder = String.Format(FwCoreDlgControls.ksColorStrikethrough, sColor); + break; + } + } + else + { + sUnder = String.Format(FwCoreDlgControls.ksColorUnderline, sColor); + } + } + else if (fontInfo.m_underline.IsExplicit) + { + switch (fontInfo.m_underline.Value) + { + case FwUnderlineType.kuntNone: + sUnder = FwCoreDlgControls.ksNoUnderline; + break; + case FwUnderlineType.kuntSingle: + sUnder = FwCoreDlgControls.ksSingleUnderline; + break; + case FwUnderlineType.kuntDouble: + sUnder = FwCoreDlgControls.ksDoubleUnderline; + break; + case FwUnderlineType.kuntDotted: + sUnder = FwCoreDlgControls.ksDottedUnderline; + break; + case FwUnderlineType.kuntDashed: + sUnder = FwCoreDlgControls.ksDashedUnderline; + break; + case FwUnderlineType.kuntStrikethrough: + sUnder = FwCoreDlgControls.ksStrikethrough; + break; + } + } + AppendToString(text, sUnder); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Appends the superscript/subscript information to the description + /// + /// The text. + /// The superscript/subscript val. + /// ------------------------------------------------------------------------------------ + private static void AppendSuperSub(StringBuilder text, FwSuperscriptVal value) + { + switch (value) + { + case FwSuperscriptVal.kssvOff: + AppendToString(text, FwCoreDlgControls.ksNoSuperSubscript); + break; + case FwSuperscriptVal.kssvSub: + AppendToString(text, FwCoreDlgControls.ksSubscript); + break; + case FwSuperscriptVal.kssvSuper: + AppendToString(text, FwCoreDlgControls.ksSuperscript); + break; + } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Appends the font offset information to the description + /// + /// The text. + /// The value. + /// ------------------------------------------------------------------------------------ + private static void AppendFontOffset(StringBuilder text, int value) + { + if (value > 0) + AppendToString(text, string.Format(FwCoreDlgControls.ksRaisedXpt, value / 1000)); + else if (value < 0) + AppendToString(text, string.Format(FwCoreDlgControls.ksLoweredXpt, -value / 1000)); + else + AppendToString(text, FwCoreDlgControls.ksNotRaisedLowered); + + } + + /// ------------------------------------------------------------------------------------ + /// + /// Appends to string. + /// + /// The text. + /// The value. + /// ------------------------------------------------------------------------------------ + private static void AppendToString(StringBuilder text, string value) + { + if (text.Length > 0) + text.Append(FwCoreDlgControls.ksListSep); + text.Append(value); + } + #endregion + } +} diff --git a/Src/FwCoreDlgs/FwCoreDlgControls/FwBulletsTab.cs b/Src/FwCoreDlgs/FwCoreDlgControls/FwBulletsTab.cs index 01e32c4767..89c5b3cbdf 100644 --- a/Src/FwCoreDlgs/FwCoreDlgControls/FwBulletsTab.cs +++ b/Src/FwCoreDlgs/FwCoreDlgControls/FwBulletsTab.cs @@ -173,8 +173,7 @@ public void UpdateForStyle(StyleInfo styleInfo) m_BulletsFontInfo = bulletInfo.FontInfo; // create a number font based on the font for bullets m_NumberFontInfo = new FontInfo(m_BulletsFontInfo); - m_NumberFontInfo.m_fontName.ResetToInherited(FontInfo.GetUIFontName( - styleInfo.FontInfoForWs(-1).m_fontName.Value)); + m_NumberFontInfo.m_fontName.ResetToInherited(styleInfo.FontInfoForWs(-1).UIFontName()); } else { @@ -183,8 +182,7 @@ public void UpdateForStyle(StyleInfo styleInfo) if (bulletType == VwBulNum.kvbnNone) { - m_NumberFontInfo.m_fontName.ResetToInherited(FontInfo.GetUIFontName( - styleInfo.FontInfoForWs(-1).m_fontName.Value)); + m_NumberFontInfo.m_fontName.ResetToInherited(styleInfo.FontInfoForWs(-1).UIFontName()); } // create a bullets font based on the font for numbers diff --git a/Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControls.Designer.cs b/Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControls.Designer.cs index aca39f41ab..a85209812e 100644 --- a/Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControls.Designer.cs +++ b/Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControls.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.239 +// Runtime Version:4.0.30319.18052 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -9,739 +9,991 @@ //------------------------------------------------------------------------------ namespace SIL.FieldWorks.FwCoreDlgControls { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class FwCoreDlgControls { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal FwCoreDlgControls() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SIL.FieldWorks.FwCoreDlgControls.FwCoreDlgControls", typeof(FwCoreDlgControls).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to Line spacing at least. - /// - internal static string ksAtLeastSpacing { - get { - return ResourceManager.GetString("ksAtLeastSpacing", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Center. - /// - internal static string ksCenter { - get { - return ResourceManager.GetString("ksCenter", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Double Spacing. - /// - internal static string ksDoubleSpacing { - get { - return ResourceManager.GetString("ksDoubleSpacing", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Exact Spacing. - /// - internal static string ksExactSpacing { - get { - return ResourceManager.GetString("ksExactSpacing", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to First Line Hanging. - /// - internal static string ksFirstLineHanging { - get { - return ResourceManager.GetString("ksFirstLineHanging", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to First Line Indent. - /// - internal static string ksFirstLineIndent { - get { - return ResourceManager.GetString("ksFirstLineIndent", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Justify. - /// - internal static string ksJustify { - get { - return ResourceManager.GetString("ksJustify", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Leading. - /// - internal static string ksLeading { - get { - return ResourceManager.GetString("ksLeading", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Left. - /// - internal static string ksLeft { - get { - return ResourceManager.GetString("ksLeft", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Left-to-Right. - /// - internal static string ksLeftToRight { - get { - return ResourceManager.GetString("ksLeftToRight", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to None. - /// - internal static string ksNone { - get { - return ResourceManager.GetString("ksNone", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Specifies the font to be used as a default in all “normal” styles when using this writing system.. - /// - internal static string ksNormalDefaultFontHelpMsg { - get { - return ResourceManager.GetString("ksNormalDefaultFontHelpMsg", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to 1.5 Line Spacing. - /// - internal static string ksPlusSpacing { - get { - return ResourceManager.GetString("ksPlusSpacing", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Redo Marking Style {0} as Used. - /// - internal static string ksRedoMarkingStyleAsUsed { - get { - return ResourceManager.GetString("ksRedoMarkingStyleAsUsed", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The Region Abbreviation must be exactly 2 or 3 characters long.. - /// - internal static string ksRegionAbbreviationLength { - get { - return ResourceManager.GetString("ksRegionAbbreviationLength", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Right. - /// - internal static string ksRight { - get { - return ResourceManager.GetString("ksRight", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Right-to-Left. - /// - internal static string ksRightToLeft { - get { - return ResourceManager.GetString("ksRightToLeft", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The Script Abbreviation must be exactly 4 characters long.. - /// - internal static string ksScriptAbbreviationLength { - get { - return ResourceManager.GetString("ksScriptAbbreviationLength", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Single Spacing. - /// - internal static string ksSingleSpacing { - get { - return ResourceManager.GetString("ksSingleSpacing", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Spacing After. - /// - internal static string ksSpacingAfter { - get { - return ResourceManager.GetString("ksSpacingAfter", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Spacing Before. - /// - internal static string ksSpacingBefore { - get { - return ResourceManager.GetString("ksSpacingBefore", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Special Indent. - /// - internal static string ksSpecialIndent { - get { - return ResourceManager.GetString("ksSpecialIndent", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to More. - /// - internal static string kstid_More { - get { - return ResourceManager.GetString("kstid_More", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to None. - /// - internal static string kstid_None { - get { - return ResourceManager.GetString("kstid_None", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to All. - /// - internal static string kstidAllBorders { - get { - return ResourceManager.GetString("kstidAllBorders", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to FieldWorks is unable to recognize a language name. This item will be omitted from the list of System Languages for keyboard input.. - /// - internal static string kstidBadLanguageName { - get { - return ResourceManager.GetString("kstidBadLanguageName", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The following system locales are invalid, so will be omitted from the list of System Languages for keyboard input: {0}. - /// - internal static string kstidBadLocales { - get { - return ResourceManager.GetString("kstidBadLocales", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to "{0}" is not a valid measurement.. - /// - internal static string kstidBadMsr { - get { - return ResourceManager.GetString("kstidBadMsr", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Border ({0}). - /// - internal static string kstidBorder { - get { - return ResourceManager.GetString("kstidBorder", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to {0}, {1} pt. - /// - internal static string kstidBorderDetailsWithColor { - get { - return ResourceManager.GetString("kstidBorderDetailsWithColor", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to {0} pt. - /// - internal static string kstidBorderDetailsWithoutColor { - get { - return ResourceManager.GetString("kstidBorderDetailsWithoutColor", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Bottom. - /// - internal static string kstidBottomBorder { - get { - return ResourceManager.GetString("kstidBottomBorder", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Built In. - /// - internal static string kstidBuiltIn { - get { - return ResourceManager.GetString("kstidBuiltIn", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Bulleted. - /// - internal static string kstidBulleted { - get { - return ResourceManager.GetString("kstidBulleted", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Character. - /// - internal static string kstidCharacterStyleText { - get { - return ResourceManager.GetString("kstidCharacterStyleText", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to <default settings>. - /// - internal static string kstidDefaultSettings { - get { - return ResourceManager.GetString("kstidDefaultSettings", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The writing sytem codes you entered include the code {0} twice. This is not allowed.. - /// - internal static string kstidDuplicateParts { - get { - return ResourceManager.GetString("kstidDuplicateParts", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The region abbreviation you entered is already in use.. - /// - internal static string kstidDupRgnAbbr { - get { - return ResourceManager.GetString("kstidDupRgnAbbr", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The script abbreviation you entered is already in use.. - /// - internal static string kstidDupScrAbbr { - get { - return ResourceManager.GetString("kstidDupScrAbbr", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The variant abbreviation you entered is already in use.. - /// - internal static string kstidDupVarAbbr { - get { - return ResourceManager.GetString("kstidDupVarAbbr", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Error. - /// - internal static string kstidError { - get { - return ResourceManager.GetString("kstidError", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Feature #{0}. - /// - internal static string kstidFeature { - get { - return ResourceManager.GetString("kstidFeature", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Value #{0}. - /// - internal static string kstidFeatureValue { - get { - return ResourceManager.GetString("kstidFeatureValue", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Font Features.... - /// - internal static string kstidFontFeatures { - get { - return ResourceManager.GetString("kstidFontFeatures", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Invalid keyboard. - /// - internal static string kstidInvalidKeyboard { - get { - return ResourceManager.GetString("kstidInvalidKeyboard", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The region abbreviation is invalid. It must be 2 alphabetic characters or 3 numeric characters.. - /// - internal static string kstidInvalidRgnAbbr { - get { - return ResourceManager.GetString("kstidInvalidRgnAbbr", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The script abbreviation is invalid. It must be 4 alphabetic characters. . - /// - internal static string kstidInvalidScrAbbr { - get { - return ResourceManager.GetString("kstidInvalidScrAbbr", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The variant abbreviation is invalid. It must consist of alphanumeric characters, possibly with hyphens separating subsections.. - /// - internal static string kstidInvalidVarAbbr { - get { - return ResourceManager.GetString("kstidInvalidVarAbbr", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to , . - /// - internal static string kstidItemSeparator { - get { - return ResourceManager.GetString("kstidItemSeparator", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to : . - /// - internal static string kstidItemValueSeparator { - get { - return ResourceManager.GetString("kstidItemValueSeparator", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Keyboard. - /// - internal static string kstidKeyboard { - get { - return ResourceManager.GetString("kstidKeyboard", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Keyman initialization failed. - /// - internal static string kstidKeymanInitFailed { - get { - return ResourceManager.GetString("kstidKeymanInitFailed", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to L&eading. - /// - internal static string kstidLeadingCheck { - get { - return ResourceManager.GetString("kstidLeadingCheck", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to L&eft. - /// - internal static string kstidLeftCheck { - get { - return ResourceManager.GetString("kstidLeftCheck", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to <Missing: {0}>. - /// - internal static string kstidMissingFontFmt { - get { - return ResourceManager.GetString("kstidMissingFontFmt", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to You must have a region abbreviation if you specify a region name.. - /// - internal static string kstidMissingRgnAbbr { - get { - return ResourceManager.GetString("kstidMissingRgnAbbr", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to You must have a script abbreviation if you specify a script name.. - /// - internal static string kstidMissingScrAbbr { - get { - return ResourceManager.GetString("kstidMissingScrAbbr", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to You must have a unique variant abbreviation if you specify a variant name. Each variant name must be unique. To edit the variant abbreviation, first edit the variant name.. - /// - internal static string kstidMissingVarAbbr { - get { - return ResourceManager.GetString("kstidMissingVarAbbr", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to No border. - /// - internal static string kstidNoBorder { - get { - return ResourceManager.GetString("kstidNoBorder", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to No bullets or numbering. - /// - internal static string kstidNoBulletsorNumbering { - get { - return ResourceManager.GetString("kstidNoBulletsorNumbering", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Numbered. - /// - internal static string kstidNumbered { - get { - return ResourceManager.GetString("kstidNumbered", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Paragraph. - /// - internal static string kstidParagraphStyleText { - get { - return ResourceManager.GetString("kstidParagraphStyleText", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to &Right. - /// - internal static string kstidRightCheck { - get { - return ResourceManager.GetString("kstidRightCheck", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Schema. - /// - internal static string kstidSchema { - get { - return ResourceManager.GetString("kstidSchema", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Start at. - /// - internal static string kstidStartAt { - get { - return ResourceManager.GetString("kstidStartAt", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Text after. - /// - internal static string kstidTextAfter { - get { - return ResourceManager.GetString("kstidTextAfter", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Text before. - /// - internal static string kstidTextBefore { - get { - return ResourceManager.GetString("kstidTextBefore", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Top. - /// - internal static string kstidTopBorder { - get { - return ResourceManager.GetString("kstidTopBorder", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to T&railing. - /// - internal static string kstidTrailingCheck { - get { - return ResourceManager.GetString("kstidTrailingCheck", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to -- Not Installed. - /// - internal static string kstidUninstalled { - get { - return ResourceManager.GetString("kstidUninstalled", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to (unspecified). - /// - internal static string kstidUnspecified { - get { - return ResourceManager.GetString("kstidUnspecified", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The variant abbreviation "{0}" was associated with "{1}". Do you want to change "{0}" to refer to "{2}"?. - /// - internal static string kstidVarAbbrQuestion { - get { - return ResourceManager.GetString("kstidVarAbbrQuestion", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The variant abbreviation "{0}" is reserved for "{1}", so it cannot be used here.. - /// - internal static string kstidVarAbbrReserved { - get { - return ResourceManager.GetString("kstidVarAbbrReserved", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The variant name "{0}" is already associated with "{1}", so it cannot be used here.. - /// - internal static string kstidVarNameUsed { - get { - return ResourceManager.GetString("kstidVarNameUsed", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Trailing. - /// - internal static string ksTrailing { - get { - return ResourceManager.GetString("ksTrailing", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Undo Marking Style {0} as Used. - /// - internal static string ksUndoMarkingStyleAsUsed { - get { - return ResourceManager.GetString("ksUndoMarkingStyleAsUsed", resourceCulture); - } - } - } + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class FwCoreDlgControls { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal FwCoreDlgControls() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SIL.FieldWorks.FwCoreDlgControls.FwCoreDlgControls", typeof(FwCoreDlgControls).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Line spacing at least. + /// + internal static string ksAtLeastSpacing { + get { + return ResourceManager.GetString("ksAtLeastSpacing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Background is {0}. + /// + internal static string ksBackgroundIsX { + get { + return ResourceManager.GetString("ksBackgroundIsX", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bold. + /// + internal static string ksBold { + get { + return ResourceManager.GetString("ksBold", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Center. + /// + internal static string ksCenter { + get { + return ResourceManager.GetString("ksCenter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} Strikethrough. + /// + internal static string ksColorStrikethrough { + get { + return ResourceManager.GetString("ksColorStrikethrough", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} Underline. + /// + internal static string ksColorUnderline { + get { + return ResourceManager.GetString("ksColorUnderline", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Dashed {0} Underline. + /// + internal static string ksDashedColorUnderline { + get { + return ResourceManager.GetString("ksDashedColorUnderline", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Dashed Underline. + /// + internal static string ksDashedUnderline { + get { + return ResourceManager.GetString("ksDashedUnderline", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Dotted {0} Underline. + /// + internal static string ksDottedColorUnderline { + get { + return ResourceManager.GetString("ksDottedColorUnderline", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Dotted Underline. + /// + internal static string ksDottedUnderline { + get { + return ResourceManager.GetString("ksDottedUnderline", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Double {0} Underline. + /// + internal static string ksDoubleColorUnderline { + get { + return ResourceManager.GetString("ksDoubleColorUnderline", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Double Spacing. + /// + internal static string ksDoubleSpacing { + get { + return ResourceManager.GetString("ksDoubleSpacing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Double Underline. + /// + internal static string ksDoubleUnderline { + get { + return ResourceManager.GetString("ksDoubleUnderline", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Exact Spacing. + /// + internal static string ksExactSpacing { + get { + return ResourceManager.GetString("ksExactSpacing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to First Line Hanging. + /// + internal static string ksFirstLineHanging { + get { + return ResourceManager.GetString("ksFirstLineHanging", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to First Line Indent. + /// + internal static string ksFirstLineIndent { + get { + return ResourceManager.GetString("ksFirstLineIndent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Italic. + /// + internal static string ksItalic { + get { + return ResourceManager.GetString("ksItalic", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Justify. + /// + internal static string ksJustify { + get { + return ResourceManager.GetString("ksJustify", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Leading. + /// + internal static string ksLeading { + get { + return ResourceManager.GetString("ksLeading", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Left. + /// + internal static string ksLeft { + get { + return ResourceManager.GetString("ksLeft", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Left-to-Right. + /// + internal static string ksLeftToRight { + get { + return ResourceManager.GetString("ksLeftToRight", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to , . + /// + internal static string ksListSep { + get { + return ResourceManager.GetString("ksListSep", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lowered by {0} pt. + /// + internal static string ksLoweredXpt { + get { + return ResourceManager.GetString("ksLoweredXpt", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No ({0}) Underline. + /// + internal static string ksNoColorUnderline { + get { + return ResourceManager.GetString("ksNoColorUnderline", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to None. + /// + internal static string ksNone { + get { + return ResourceManager.GetString("ksNone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Specifies the font to be used as a default in all “normal” styles when using this writing system.. + /// + internal static string ksNormalDefaultFontHelpMsg { + get { + return ResourceManager.GetString("ksNormalDefaultFontHelpMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No Super/Subscript. + /// + internal static string ksNoSuperSubscript { + get { + return ResourceManager.GetString("ksNoSuperSubscript", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Not Bold. + /// + internal static string ksNotBold { + get { + return ResourceManager.GetString("ksNotBold", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Not Italic. + /// + internal static string ksNotItalic { + get { + return ResourceManager.GetString("ksNotItalic", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Not Raised/Lowered. + /// + internal static string ksNotRaisedLowered { + get { + return ResourceManager.GetString("ksNotRaisedLowered", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No Underline. + /// + internal static string ksNoUnderline { + get { + return ResourceManager.GetString("ksNoUnderline", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 1.5 Line Spacing. + /// + internal static string ksPlusSpacing { + get { + return ResourceManager.GetString("ksPlusSpacing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Raised by {0} pt. + /// + internal static string ksRaisedXpt { + get { + return ResourceManager.GetString("ksRaisedXpt", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Redo Marking Style {0} as Used. + /// + internal static string ksRedoMarkingStyleAsUsed { + get { + return ResourceManager.GetString("ksRedoMarkingStyleAsUsed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Region Abbreviation must be exactly 2 or 3 characters long.. + /// + internal static string ksRegionAbbreviationLength { + get { + return ResourceManager.GetString("ksRegionAbbreviationLength", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Right. + /// + internal static string ksRight { + get { + return ResourceManager.GetString("ksRight", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Right-to-Left. + /// + internal static string ksRightToLeft { + get { + return ResourceManager.GetString("ksRightToLeft", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Script Abbreviation must be exactly 4 characters long.. + /// + internal static string ksScriptAbbreviationLength { + get { + return ResourceManager.GetString("ksScriptAbbreviationLength", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Single {0} Underline. + /// + internal static string ksSingleColorUnderline { + get { + return ResourceManager.GetString("ksSingleColorUnderline", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Single Spacing. + /// + internal static string ksSingleSpacing { + get { + return ResourceManager.GetString("ksSingleSpacing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Single Underline. + /// + internal static string ksSingleUnderline { + get { + return ResourceManager.GetString("ksSingleUnderline", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Spacing After. + /// + internal static string ksSpacingAfter { + get { + return ResourceManager.GetString("ksSpacingAfter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Spacing Before. + /// + internal static string ksSpacingBefore { + get { + return ResourceManager.GetString("ksSpacingBefore", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Special Indent. + /// + internal static string ksSpecialIndent { + get { + return ResourceManager.GetString("ksSpecialIndent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Strikethrough. + /// + internal static string ksStrikethrough { + get { + return ResourceManager.GetString("ksStrikethrough", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Subscript. + /// + internal static string ksSubscript { + get { + return ResourceManager.GetString("ksSubscript", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Superscript. + /// + internal static string ksSuperscript { + get { + return ResourceManager.GetString("ksSuperscript", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Text is {0}. + /// + internal static string ksTextIsX { + get { + return ResourceManager.GetString("ksTextIsX", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Text is {0} on {1}. + /// + internal static string ksTextIsXonY { + get { + return ResourceManager.GetString("ksTextIsXonY", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to More. + /// + internal static string kstid_More { + get { + return ResourceManager.GetString("kstid_More", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to None. + /// + internal static string kstid_None { + get { + return ResourceManager.GetString("kstid_None", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All. + /// + internal static string kstidAllBorders { + get { + return ResourceManager.GetString("kstidAllBorders", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to FieldWorks is unable to recognize a language name. This item will be omitted from the list of System Languages for keyboard input.. + /// + internal static string kstidBadLanguageName { + get { + return ResourceManager.GetString("kstidBadLanguageName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The following system locales are invalid, so will be omitted from the list of System Languages for keyboard input: {0}. + /// + internal static string kstidBadLocales { + get { + return ResourceManager.GetString("kstidBadLocales", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to "{0}" is not a valid measurement.. + /// + internal static string kstidBadMsr { + get { + return ResourceManager.GetString("kstidBadMsr", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Border ({0}). + /// + internal static string kstidBorder { + get { + return ResourceManager.GetString("kstidBorder", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0}, {1} pt. + /// + internal static string kstidBorderDetailsWithColor { + get { + return ResourceManager.GetString("kstidBorderDetailsWithColor", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} pt. + /// + internal static string kstidBorderDetailsWithoutColor { + get { + return ResourceManager.GetString("kstidBorderDetailsWithoutColor", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bottom. + /// + internal static string kstidBottomBorder { + get { + return ResourceManager.GetString("kstidBottomBorder", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Built In. + /// + internal static string kstidBuiltIn { + get { + return ResourceManager.GetString("kstidBuiltIn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bulleted. + /// + internal static string kstidBulleted { + get { + return ResourceManager.GetString("kstidBulleted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Character. + /// + internal static string kstidCharacterStyleText { + get { + return ResourceManager.GetString("kstidCharacterStyleText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <default settings>. + /// + internal static string kstidDefaultSettings { + get { + return ResourceManager.GetString("kstidDefaultSettings", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The writing sytem codes you entered include the code {0} twice. This is not allowed.. + /// + internal static string kstidDuplicateParts { + get { + return ResourceManager.GetString("kstidDuplicateParts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The region abbreviation you entered is already in use.. + /// + internal static string kstidDupRgnAbbr { + get { + return ResourceManager.GetString("kstidDupRgnAbbr", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The script abbreviation you entered is already in use.. + /// + internal static string kstidDupScrAbbr { + get { + return ResourceManager.GetString("kstidDupScrAbbr", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The variant abbreviation you entered is already in use.. + /// + internal static string kstidDupVarAbbr { + get { + return ResourceManager.GetString("kstidDupVarAbbr", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error. + /// + internal static string kstidError { + get { + return ResourceManager.GetString("kstidError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Feature #{0}. + /// + internal static string kstidFeature { + get { + return ResourceManager.GetString("kstidFeature", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Value #{0}. + /// + internal static string kstidFeatureValue { + get { + return ResourceManager.GetString("kstidFeatureValue", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Font Features.... + /// + internal static string kstidFontFeatures { + get { + return ResourceManager.GetString("kstidFontFeatures", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid keyboard. + /// + internal static string kstidInvalidKeyboard { + get { + return ResourceManager.GetString("kstidInvalidKeyboard", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The region abbreviation is invalid. It must be 2 alphabetic characters or 3 numeric characters.. + /// + internal static string kstidInvalidRgnAbbr { + get { + return ResourceManager.GetString("kstidInvalidRgnAbbr", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The script abbreviation is invalid. It must be 4 alphabetic characters. . + /// + internal static string kstidInvalidScrAbbr { + get { + return ResourceManager.GetString("kstidInvalidScrAbbr", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The variant abbreviation is invalid. It must consist of alphanumeric characters, possibly with hyphens separating subsections.. + /// + internal static string kstidInvalidVarAbbr { + get { + return ResourceManager.GetString("kstidInvalidVarAbbr", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to , . + /// + internal static string kstidItemSeparator { + get { + return ResourceManager.GetString("kstidItemSeparator", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to : . + /// + internal static string kstidItemValueSeparator { + get { + return ResourceManager.GetString("kstidItemValueSeparator", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Keyboard. + /// + internal static string kstidKeyboard { + get { + return ResourceManager.GetString("kstidKeyboard", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Keyman initialization failed. + /// + internal static string kstidKeymanInitFailed { + get { + return ResourceManager.GetString("kstidKeymanInitFailed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to L&eading. + /// + internal static string kstidLeadingCheck { + get { + return ResourceManager.GetString("kstidLeadingCheck", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to L&eft. + /// + internal static string kstidLeftCheck { + get { + return ResourceManager.GetString("kstidLeftCheck", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <Missing: {0}>. + /// + internal static string kstidMissingFontFmt { + get { + return ResourceManager.GetString("kstidMissingFontFmt", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You must have a region abbreviation if you specify a region name.. + /// + internal static string kstidMissingRgnAbbr { + get { + return ResourceManager.GetString("kstidMissingRgnAbbr", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You must have a script abbreviation if you specify a script name.. + /// + internal static string kstidMissingScrAbbr { + get { + return ResourceManager.GetString("kstidMissingScrAbbr", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You must have a unique variant abbreviation if you specify a variant name. Each variant name must be unique. To edit the variant abbreviation, first edit the variant name.. + /// + internal static string kstidMissingVarAbbr { + get { + return ResourceManager.GetString("kstidMissingVarAbbr", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No border. + /// + internal static string kstidNoBorder { + get { + return ResourceManager.GetString("kstidNoBorder", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No bullets or numbering. + /// + internal static string kstidNoBulletsorNumbering { + get { + return ResourceManager.GetString("kstidNoBulletsorNumbering", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Numbered. + /// + internal static string kstidNumbered { + get { + return ResourceManager.GetString("kstidNumbered", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Paragraph. + /// + internal static string kstidParagraphStyleText { + get { + return ResourceManager.GetString("kstidParagraphStyleText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to &Right. + /// + internal static string kstidRightCheck { + get { + return ResourceManager.GetString("kstidRightCheck", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Schema. + /// + internal static string kstidSchema { + get { + return ResourceManager.GetString("kstidSchema", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Start at. + /// + internal static string kstidStartAt { + get { + return ResourceManager.GetString("kstidStartAt", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Text after. + /// + internal static string kstidTextAfter { + get { + return ResourceManager.GetString("kstidTextAfter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Text before. + /// + internal static string kstidTextBefore { + get { + return ResourceManager.GetString("kstidTextBefore", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Top. + /// + internal static string kstidTopBorder { + get { + return ResourceManager.GetString("kstidTopBorder", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to T&railing. + /// + internal static string kstidTrailingCheck { + get { + return ResourceManager.GetString("kstidTrailingCheck", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to -- Not Installed. + /// + internal static string kstidUninstalled { + get { + return ResourceManager.GetString("kstidUninstalled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to (unspecified). + /// + internal static string kstidUnspecified { + get { + return ResourceManager.GetString("kstidUnspecified", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The variant abbreviation "{0}" was associated with "{1}". Do you want to change "{0}" to refer to "{2}"?. + /// + internal static string kstidVarAbbrQuestion { + get { + return ResourceManager.GetString("kstidVarAbbrQuestion", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The variant abbreviation "{0}" is reserved for "{1}", so it cannot be used here.. + /// + internal static string kstidVarAbbrReserved { + get { + return ResourceManager.GetString("kstidVarAbbrReserved", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The variant name "{0}" is already associated with "{1}", so it cannot be used here.. + /// + internal static string kstidVarNameUsed { + get { + return ResourceManager.GetString("kstidVarNameUsed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Trailing. + /// + internal static string ksTrailing { + get { + return ResourceManager.GetString("ksTrailing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Undo Marking Style {0} as Used. + /// + internal static string ksUndoMarkingStyleAsUsed { + get { + return ResourceManager.GetString("ksUndoMarkingStyleAsUsed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} pt. + /// + internal static string ksXPt { + get { + return ResourceManager.GetString("ksXPt", resourceCulture); + } + } + } } diff --git a/Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControls.csproj b/Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControls.csproj index 59d899fffd..6feab02a66 100644 --- a/Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControls.csproj +++ b/Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControls.csproj @@ -203,7 +203,10 @@ ConfigSenseLayout.cs - + + + UserControl + UserControl @@ -222,7 +225,9 @@ FwGeneralTab.cs - + + Component + diff --git a/Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControls.resx b/Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControls.resx index 9473b0b832..28f80012dc 100644 --- a/Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControls.resx +++ b/Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControls.resx @@ -1,397 +1,490 @@  - + 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. + --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - text/microsoft-resx + text/microsoft-resx - 2.0 + 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - You must have a region abbreviation if you specify a region name. + You must have a region abbreviation if you specify a region name. - You must have a unique variant abbreviation if you specify a variant name. Each variant name must be unique. To edit the variant abbreviation, first edit the variant name. + You must have a unique variant abbreviation if you specify a variant name. Each variant name must be unique. To edit the variant abbreviation, first edit the variant name. - Error - Caption for error messages in dialogs + Error + Caption for error messages in dialogs - The region abbreviation you entered is already in use. + The region abbreviation you entered is already in use. - The variant abbreviation you entered is already in use. + The variant abbreviation you entered is already in use. - None - Used in keyboard control (leading space causes it to be first in a sorted list) + None + Used in keyboard control (leading space causes it to be first in a sorted list) - More - Used for a overflow in a list + More + Used for a overflow in a list - Invalid keyboard + Invalid keyboard - -- Not Installed + -- Not Installed - Built In + Built In - Font Features... + Font Features... - The variant name "{0}" is already associated with "{1}", so it cannot be used here. - Used in RegionVariantControl + The variant name "{0}" is already associated with "{1}", so it cannot be used here. + Used in RegionVariantControl - The variant abbreviation "{0}" was associated with "{1}". Do you want to change "{0}" to refer to "{2}"? + The variant abbreviation "{0}" was associated with "{1}". Do you want to change "{0}" to refer to "{2}"? - The variant abbreviation "{0}" is reserved for "{1}", so it cannot be used here. + The variant abbreviation "{0}" is reserved for "{1}", so it cannot be used here. - Feature #{0} - Substring {0} MUST occur and will be replaced by integer feature number. + Feature #{0} + Substring {0} MUST occur and will be replaced by integer feature number. - Value #{0} + Value #{0} - "{0}" is not a valid measurement. + "{0}" is not a valid measurement. - The following system locales are invalid, so will be omitted from the list of System Languages for keyboard input: {0} - Used when filling a list of System keyboards + The following system locales are invalid, so will be omitted from the list of System Languages for keyboard input: {0} + Used when filling a list of System keyboards - FieldWorks is unable to recognize a language name. This item will be omitted from the list of System Languages for keyboard input. + FieldWorks is unable to recognize a language name. This item will be omitted from the list of System Languages for keyboard input. - <default settings> - Used in writing systems list box + <default settings> + Used in writing systems list box - (unspecified) - Used in Font combo box + (unspecified) + Used in Font combo box - Line spacing at least - Used in Description on the General tab of the Style dialog box + Line spacing at least + Used in Description on the General tab of the Style dialog box - Center - Used in Description on the General tab of the Style dialog box + Center + Used in Description on the General tab of the Style dialog box - Double Spacing - Used in Description on the General tab of the Style dialog box + Double Spacing + Used in Description on the General tab of the Style dialog box - Exact Spacing - Used in Description on the General tab of the Style dialog box + Exact Spacing + Used in Description on the General tab of the Style dialog box - First Line Hanging - Used in Description on the General tab of the Style dialog box + First Line Hanging + Used in Description on the General tab of the Style dialog box - First Line Indent - Used in Description on the General tab of the Style dialog box + First Line Indent + Used in Description on the General tab of the Style dialog box - Justify - Used in Description on the General tab of the Style dialog box + Justify + Used in Description on the General tab of the Style dialog box - Leading - Used in Description on the General tab of the Style dialog box + Leading + Used in Description on the General tab of the Style dialog box - Left - Used in Description on the General tab of the Style dialog box + Left + Used in Description on the General tab of the Style dialog box - Left-to-Right - Used in Description on the General tab of the Style dialog box + Left-to-Right + Used in Description on the General tab of the Style dialog box - None - Used in Description on the General tab of the Style dialog box + None + Used in Description on the General tab of the Style dialog box - Specifies the font to be used as a default in all “normal” styles when using this writing system. + Specifies the font to be used as a default in all “normal” styles when using this writing system. - 1.5 Line Spacing - Used in Description on the General tab of the Style dialog box + 1.5 Line Spacing + Used in Description on the General tab of the Style dialog box - Right - Used in Description on the General tab of the Style dialog box + Right + Used in Description on the General tab of the Style dialog box - Right-to-Left - Used in Description on the General tab of the Style dialog box + Right-to-Left + Used in Description on the General tab of the Style dialog box - Single Spacing - Used in Description on the General tab of the Style dialog box + Single Spacing + Used in Description on the General tab of the Style dialog box - Spacing After - Used in Description on the General tab of the Style dialog box + Spacing After + Used in Description on the General tab of the Style dialog box - Spacing Before - Used in Description on the General tab of the Style dialog box + Spacing Before + Used in Description on the General tab of the Style dialog box - Special Indent - Used in Description on the General tab of the Style dialog box + Special Indent + Used in Description on the General tab of the Style dialog box - Trailing - Used in Description on the General tab of the Style dialog box + Trailing + Used in Description on the General tab of the Style dialog box - Bulleted - Used in Description on the General tab of the Style dialog box + Bulleted + Used in Description on the General tab of the Style dialog box - Numbered - Used in Description on the General tab of the Style dialog box + Numbered + Used in Description on the General tab of the Style dialog box - All - Used in Description on the General tab of the Style dialog box + All + Used in Description on the General tab of the Style dialog box - Border ({0}) - Used in Description on the General tab of the Style dialog box + Border ({0}) + Used in Description on the General tab of the Style dialog box - {0}, {1} pt - Used in Description on the General tab of the Style dialog box for formatting the Color and point size of the border + {0}, {1} pt + Used in Description on the General tab of the Style dialog box for formatting the Color and point size of the border - {0} pt - Used in Description on the General tab of the Style dialog box for formatting the point size of the border + {0} pt + Used in Description on the General tab of the Style dialog box for formatting the point size of the border - Bottom - Used in Description on the General tab of the Style dialog box + Bottom + Used in Description on the General tab of the Style dialog box - , - Used in Description on the General tab of the Style dialog box to separate detail items + , + Used in Description on the General tab of the Style dialog box to separate detail items - : - Used in Description on the General tab of the Style dialog box to separate an item label from its value + : + Used in Description on the General tab of the Style dialog box to separate an item label from its value - No border - Used in Description on the General tab of the Style dialog box + No border + Used in Description on the General tab of the Style dialog box - No bullets or numbering - Used in Description on the General tab of the Style dialog box + No bullets or numbering + Used in Description on the General tab of the Style dialog box - Top - Used in Description on the General tab of the Style dialog box + Top + Used in Description on the General tab of the Style dialog box - Keyman initialization failed - Error message to display if Keyman initialization fails (application may append a colon and specific error details) + Keyman initialization failed + Error message to display if Keyman initialization fails (application may append a colon and specific error details) - L&eading - Used in the Border tab to show leading instead of a simple left or right + L&eading + Used in the Border tab to show leading instead of a simple left or right - L&eft - Used in the Border tab to show left instead of leading or trailing + L&eft + Used in the Border tab to show left instead of leading or trailing - &Right - Used in the Border tab to show right instead of leading or trailing + &Right + Used in the Border tab to show right instead of leading or trailing - T&railing - Used in the Border tab to show trailing instead of a simple left or right + T&railing + Used in the Border tab to show trailing instead of a simple left or right - Character + Character - Paragraph + Paragraph - Schema - Used for bullets/numbers in Description on the General tab of the Style dialog box + Schema + Used for bullets/numbers in Description on the General tab of the Style dialog box - Start at - Used for bullets/numbers in Description on the General tab of the + Start at + Used for bullets/numbers in Description on the General tab of the - Text after - Used for bullets/numbers in Description on the General tab of the + Text after + Used for bullets/numbers in Description on the General tab of the - Text before - Used for bullets/numbers in Description on the General tab of the + Text before + Used for bullets/numbers in Description on the General tab of the - <Missing: {0}> + <Missing: {0}> - The Script Abbreviation must be exactly 4 characters long. + The Script Abbreviation must be exactly 4 characters long. - The Region Abbreviation must be exactly 2 or 3 characters long. + The Region Abbreviation must be exactly 2 or 3 characters long. - Undo Marking Style {0} as Used + Undo Marking Style {0} as Used - Redo Marking Style {0} as Used + Redo Marking Style {0} as Used - The script abbreviation you entered is already in use. + The script abbreviation you entered is already in use. - You must have a script abbreviation if you specify a script name. + You must have a script abbreviation if you specify a script name. - The region abbreviation is invalid. It must be 2 alphabetic characters or 3 numeric characters. + The region abbreviation is invalid. It must be 2 alphabetic characters or 3 numeric characters. - The script abbreviation is invalid. It must be 4 alphabetic characters. + The script abbreviation is invalid. It must be 4 alphabetic characters. - The variant abbreviation is invalid. It must consist of alphanumeric characters, possibly with hyphens separating subsections. + The variant abbreviation is invalid. It must consist of alphanumeric characters, possibly with hyphens separating subsections. - Keyboard - Label of combo box in Linux to select a keyboard to use to type a language. + Keyboard + Label of combo box in Linux to select a keyboard to use to type a language. - The writing sytem codes you entered include the code {0} twice. This is not allowed. + The writing sytem codes you entered include the code {0} twice. This is not allowed. + + + Background is {0} + text background color + + + Bold + + + {0} Strikethrough + + + {0} Underline + + + Dashed {0} Underline + + + Dashed Underline + + + Dotted {0} Underline + + + Dotted Underline + + + Double {0} Underline + + + Double Underline + + + Italic + + + , + separate items in a list (comma space) + + + Lowered by {0} pt + Font lowered by X points + + + No ({0}) Underline + nonsense, but a possibility + + + No Super/Subscript + + + Not Bold + + + Not Italic + + + Not Raised/Lowered + + + No Underline + + + Raised by {0} pt + Font raised by X points + + + Single {0} Underline + insert explicit color + + + Single Underline + + + Strikethrough + + + Subscript + + + Superscript + + + Text is {0} + text foreground color + + + Text is {0} on {1} + text foreground and background colors + + + {0} pt + size in "points" \ No newline at end of file diff --git a/Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControlsTests/StylesComboTests.cs b/Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControlsTests/StylesComboTests.cs index b45ced4696..47ee3cb552 100644 --- a/Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControlsTests/StylesComboTests.cs +++ b/Src/FwCoreDlgs/FwCoreDlgControls/FwCoreDlgControlsTests/StylesComboTests.cs @@ -66,7 +66,7 @@ protected override void CreateTestData() m_lp.StylesOC); m_styleSheet = new FwStyleSheet(); m_styleSheet.Init(Cache, m_lp.Hvo, - LangProjectTags.kflidStyles); + LangProjectTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); Debug.Assert(m_stylesComboBox == null, "m_stylesComboBox is not null."); //if (m_stylesComboBox != null) diff --git a/Src/FwCoreDlgs/FwCoreDlgControls/StyleInfo.cs b/Src/FwCoreDlgs/FwCoreDlgControls/StyleInfo.cs index ed0311e2c9..79407ef439 100644 --- a/Src/FwCoreDlgs/FwCoreDlgControls/StyleInfo.cs +++ b/Src/FwCoreDlgs/FwCoreDlgControls/StyleInfo.cs @@ -303,7 +303,7 @@ private void AddBulletInfo(StringBuilder text) AppendItem(tmp, FwCoreDlgControls.kstidSchema, scheme.ToString()); } if (m_bulletInfo.Value.FontInfo.IsAnyExplicit) - AppendItem(tmp, m_bulletInfo.Value.FontInfo.ToString()); + AppendItem(tmp, m_bulletInfo.Value.FontInfo.ToString(false)); } else { @@ -321,7 +321,7 @@ private void AddBulletInfo(StringBuilder text) GetNumberSchemeNameForType(m_bulletInfo.Value.m_numberScheme)); } if (m_bulletInfo.Value.FontInfo.IsAnyExplicit) - AppendItem(tmp, m_bulletInfo.Value.FontInfo.ToString()); + AppendItem(tmp, m_bulletInfo.Value.FontInfo.ToString(false)); } if (tmp.Length > 0) @@ -374,7 +374,7 @@ private void AddWsSpecificFontInfo(StringBuilder text) var ws = m_style.Cache.ServiceLocator.WritingSystemManager.Get(wsInfo.Key); text.Append(ws.DisplayLabel); text.Append(": "); - text.Append(wsInfo.Value.ToString()); + text.Append(wsInfo.Value.ToString(false)); text.AppendLine(); } } diff --git a/Src/FwCoreDlgs/FwCoreDlgs.Designer.cs b/Src/FwCoreDlgs/FwCoreDlgs.Designer.cs index a23661a6ad..e10b03c8db 100644 --- a/Src/FwCoreDlgs/FwCoreDlgs.Designer.cs +++ b/Src/FwCoreDlgs/FwCoreDlgs.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.1008 +// Runtime Version:4.0.30319.18052 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -383,6 +383,15 @@ public static string ksCopyFile { } } + /// + /// Looks up a localized string similar to FieldWorks was not able to back up some of the files used by this project. Do you want to keep the backup anyway? The files not backed up were {0}. + /// + public static string ksCouldNotBackupSomeFiles { + get { + return ResourceManager.GetString("ksCouldNotBackupSomeFiles", resourceCulture); + } + } + /// /// Looks up a localized string similar to If you want to replace a picture file, you must first delete the current picture.. /// @@ -473,6 +482,15 @@ public static string ksFindConvMappingFile { } } + /// + /// Looks up a localized string similar to Unable to search for remote servers.. + /// + public static string ksFindServersError { + get { + return ResourceManager.GetString("ksFindServersError", resourceCulture); + } + } + /// /// Looks up a localized string similar to Find Spec file for unknown mapping type. /// diff --git a/Src/FwCoreDlgs/FwCoreDlgs.csproj b/Src/FwCoreDlgs/FwCoreDlgs.csproj index 6178906c2d..c7e5292de9 100644 --- a/Src/FwCoreDlgs/FwCoreDlgs.csproj +++ b/Src/FwCoreDlgs/FwCoreDlgs.csproj @@ -175,6 +175,10 @@ False ..\..\Output\Debug\RootSite.dll + + False + ..\..\Output\Debug\ScriptureUtils.dll + False ..\..\Output\Debug\SharedScrUtils.dll @@ -297,6 +301,7 @@ Component + UserControl @@ -441,6 +446,12 @@ Component + + + True + True + Strings.resx + Form @@ -614,6 +625,11 @@ RealSplashScreen.cs Designer + + ResXFileCodeGenerator + Strings.Designer.cs + Designer + UtilityDlg.cs Designer @@ -678,4 +694,4 @@ ../../DistFiles - + \ No newline at end of file diff --git a/Src/FwCoreDlgs/FwCoreDlgs.resx b/Src/FwCoreDlgs/FwCoreDlgs.resx index 217d244d5d..e205cfed67 100644 --- a/Src/FwCoreDlgs/FwCoreDlgs.resx +++ b/Src/FwCoreDlgs/FwCoreDlgs.resx @@ -979,4 +979,10 @@ The error was: Click 'OK' to continue with this project name or 'Cancel' to enter a different name. + + FieldWorks was not able to back up some of the files used by this project. Do you want to keep the backup anyway? The files not backed up were {0} + + + Unable to search for remote servers. + \ No newline at end of file diff --git a/Src/FwCoreDlgs/FwCoreDlgsTests/FwNewLangProjectTests.cs b/Src/FwCoreDlgs/FwCoreDlgsTests/FwNewLangProjectTests.cs index 3da938bf4c..20cf5e8547 100644 --- a/Src/FwCoreDlgs/FwCoreDlgsTests/FwNewLangProjectTests.cs +++ b/Src/FwCoreDlgs/FwCoreDlgsTests/FwNewLangProjectTests.cs @@ -14,7 +14,7 @@ using System.Linq; using System.Windows.Forms; using NUnit.Framework; - +using SIL.CoreImpl; using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO; using SIL.FieldWorks.Test.TestUtils; @@ -107,7 +107,7 @@ public class FwNewLangProjectTests: BaseTest public void CreateNewLangProject() { const string dbName = "Maileingwij2025"; - string storePath = DirectoryFinder.GetWritingSystemDir(Path.Combine(DirectoryFinder.ProjectsDirectory, dbName)); + string storePath = FdoFileHelper.GetWritingSystemDir(Path.Combine(FwDirectoryFinder.ProjectsDirectory, dbName)); string sharedStorePath = DirectoryFinder.GlobalWritingSystemStoreDirectory; using (var dlg = new DummyFwNewLangProject()) @@ -126,7 +126,7 @@ public void CreateNewLangProject() // despite of the name is DummyProgressDlg no real dialog (doesn't derive from Control), so // we don't need a 'using' cache = FdoCache.CreateCacheFromExistingData( - new TestProjectId(FDOBackendProviderType.kXML, DbFilename(dbName)), "en", new DummyProgressDlg()); + new TestProjectId(FDOBackendProviderType.kXML, DbFilename(dbName)), "en", new DummyFdoUI(), FwDirectoryFinder.FdoDirectories, new DummyProgressDlg()); CheckInitialSetOfPartsOfSpeech(cache); Assert.AreEqual(1, cache.ServiceLocator.WritingSystems.AnalysisWritingSystems.Count); @@ -351,12 +351,12 @@ private void CheckInitialSetOfPartsOfSpeech(FdoCache cache) private static string DbDirectory(string dbName) { - return Path.Combine(DirectoryFinder.ProjectsDirectory, dbName); + return Path.Combine(FwDirectoryFinder.ProjectsDirectory, dbName); } private static string DbFilename(string dbName) { - return Path.Combine(DbDirectory(dbName), DirectoryFinder.GetXmlDataFileName(dbName)); + return Path.Combine(DbDirectory(dbName), FdoFileHelper.GetXmlDataFileName(dbName)); } /// ------------------------------------------------------------------------------------ diff --git a/Src/FwCoreDlgs/FwCoreDlgsTests/RestoreProjectPresenterTests.cs b/Src/FwCoreDlgs/FwCoreDlgsTests/RestoreProjectPresenterTests.cs index ed7404f640..58bdf7a09e 100644 --- a/Src/FwCoreDlgs/FwCoreDlgsTests/RestoreProjectPresenterTests.cs +++ b/Src/FwCoreDlgs/FwCoreDlgsTests/RestoreProjectPresenterTests.cs @@ -9,6 +9,7 @@ using System.IO; using NUnit.Framework; using SIL.FieldWorks.Common.FwUtils; +using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.DomainServices.BackupRestore; using SIL.FieldWorks.FDO.FDOTests; using SIL.FieldWorks.FwCoreDlgs.BackupRestore; @@ -53,7 +54,7 @@ public void VerifyStringForBackupPropertiesLabel() { var restoreProjectPresenter = new RestoreProjectPresenter(null, string.Empty); BackupFileSettings backupSettings = new BackupFileSettings( - Path.ChangeExtension("dummy", FwFileExtensions.ksFwBackupFileExtension), false); + Path.ChangeExtension("dummy", FdoFileHelper.ksFwBackupFileExtension), false); // This is needed to thwart BackupFileSettings's normal logic to populate the flags // from the backup zip file ReflectionHelper.SetField(backupSettings, "m_projectName", "dummy"); @@ -91,7 +92,7 @@ public void VerifyStringForBackupPropertiesLabel() [Test] public void DefaultBackupFile_NoBackupFilesAvailable() { - m_fileOs.ExistingDirectories.Add(DirectoryFinder.DefaultBackupDirectory); + m_fileOs.ExistingDirectories.Add(FwDirectoryFinder.DefaultBackupDirectory); RestoreProjectPresenter presenter = new RestoreProjectPresenter(null, string.Empty); Assert.AreEqual(String.Empty, presenter.DefaultProjectName); } @@ -105,7 +106,7 @@ public void DefaultBackupFile_NoBackupFilesAvailable() [Test] public void DefaultBackupFile_BackupForCurrentProjectExists() { - BackupProjectSettings backupSettings = new BackupProjectSettings(Cache, null); + BackupProjectSettings backupSettings = new BackupProjectSettings(Cache, null, FwDirectoryFinder.DefaultBackupDirectory); string backupFileName1 = backupSettings.ZipFileName; m_fileOs.AddExistingFile(backupFileName1); // Force the second backup to appear to be older @@ -125,7 +126,7 @@ public void DefaultBackupFile_BackupForCurrentProjectExists() [Test] public void DefaultBackupFile_BackupsForOtherProjectsButNotCurrent() { - BackupProjectSettings backupSettings = new BackupProjectSettings(Cache, null); + BackupProjectSettings backupSettings = new BackupProjectSettings(Cache, null, FwDirectoryFinder.DefaultBackupDirectory); backupSettings.ProjectName = "AAA"; string backupFileName1 = backupSettings.ZipFileName; m_fileOs.AddExistingFile(backupFileName1); @@ -150,14 +151,14 @@ public void DefaultBackupFile_BackupsForOtherProjectsButNotCurrent() public void RestoreToName_GetSuggestedNewProjectName() { // Add three project files, one being a copy of another. - string proj1 = Path.Combine(Path.Combine(DirectoryFinder.ProjectsDirectory, "AAA"), "AAA.fwdata"); + string proj1 = Path.Combine(Path.Combine(FwDirectoryFinder.ProjectsDirectory, "AAA"), "AAA.fwdata"); m_fileOs.AddExistingFile(proj1); - string proj2 = Path.Combine(Path.Combine(DirectoryFinder.ProjectsDirectory, "BBB"), "BBB.fwdata"); + string proj2 = Path.Combine(Path.Combine(FwDirectoryFinder.ProjectsDirectory, "BBB"), "BBB.fwdata"); m_fileOs.AddExistingFile(proj2); - string proj3 = Path.Combine(Path.Combine(DirectoryFinder.ProjectsDirectory, "AAA-01"), "AAA-01.fwdata"); + string proj3 = Path.Combine(Path.Combine(FwDirectoryFinder.ProjectsDirectory, "AAA-01"), "AAA-01.fwdata"); m_fileOs.AddExistingFile(proj3); - BackupProjectSettings backupSettings = new BackupProjectSettings(Cache, null); + BackupProjectSettings backupSettings = new BackupProjectSettings(Cache, null, FwDirectoryFinder.DefaultBackupDirectory); backupSettings.ProjectName = "AAA"; string backupFileName1 = backupSettings.ZipFileName; m_fileOs.AddExistingFile(backupFileName1); diff --git a/Src/FwCoreDlgs/FwDeleteProjectDlg.cs b/Src/FwCoreDlgs/FwDeleteProjectDlg.cs index 41e6ccb90b..3741413b02 100644 --- a/Src/FwCoreDlgs/FwDeleteProjectDlg.cs +++ b/Src/FwCoreDlgs/FwDeleteProjectDlg.cs @@ -68,7 +68,7 @@ private static IEnumerable GetLocalProjects(ICollection pro { // ProjectInfo.AllProjects doesn't set the InUse flag, which is why we // pass a list of open projects to the dialog constructor. - List projectList = ProjectInfo.AllProjects; + List projectList = ProjectInfo.GetAllProjects(FwDirectoryFinder.ProjectsDirectory); foreach (ProjectInfo info in projectList.Where(info => projectsOpen.Contains(info.DatabaseName))) info.InUse = true; return projectList; @@ -266,7 +266,7 @@ private void m_btnDelete_Click(object sender, System.EventArgs e) itemsToDelete.Add(info); foreach (ProjectInfo info in itemsToDelete) { - string folder = Path.Combine(DirectoryFinder.ProjectsDirectory, info.DatabaseName); + string folder = Path.Combine(FwDirectoryFinder.ProjectsDirectory, info.DatabaseName); bool fExtraData = CheckForExtraData(info, folder); string msg; MessageBoxButtons buttons; @@ -293,25 +293,25 @@ private void m_btnDelete_Click(object sender, System.EventArgs e) } else { - string path = Path.Combine(folder, info.DatabaseName + FwFileExtensions.ksFwDataXmlFileExtension); + string path = Path.Combine(folder, info.DatabaseName + FdoFileHelper.ksFwDataXmlFileExtension); if (File.Exists(path)) File.Delete(path); - path = Path.ChangeExtension(path, FwFileExtensions.ksFwDataDb4oFileExtension); + path = Path.ChangeExtension(path, FdoFileHelper.ksFwDataDb4oFileExtension); if (File.Exists(path)) File.Delete(path); - path = Path.ChangeExtension(path, FwFileExtensions.ksFwDataFallbackFileExtension); + path = Path.ChangeExtension(path, FdoFileHelper.ksFwDataFallbackFileExtension); if (File.Exists(path)) File.Delete(path); - path = Path.Combine(folder, DirectoryFinder.ksWritingSystemsDir); + path = Path.Combine(folder, FdoFileHelper.ksWritingSystemsDir); if (Directory.Exists(path)) Directory.Delete(path, true); - path = Path.Combine(folder, DirectoryFinder.ksBackupSettingsDir); + path = Path.Combine(folder, FdoFileHelper.ksBackupSettingsDir); if (Directory.Exists(path)) Directory.Delete(path, true); - path = Path.Combine(folder, DirectoryFinder.ksConfigurationSettingsDir); + path = Path.Combine(folder, FdoFileHelper.ksConfigurationSettingsDir); if (Directory.Exists(path)) Directory.Delete(path, true); - path = Path.Combine(folder, DirectoryFinder.ksSortSequenceTempDir); + path = Path.Combine(folder, FdoFileHelper.ksSortSequenceTempDir); if (Directory.Exists(path)) Directory.Delete(path, true); string[] folders = Directory.GetDirectories(folder); @@ -339,10 +339,10 @@ private static bool CheckForExtraData(ProjectInfo info, string folder) foreach (string dir in folders) { string name = Path.GetFileName(dir); - if (name == DirectoryFinder.ksWritingSystemsDir || - name == DirectoryFinder.ksBackupSettingsDir || - name == DirectoryFinder.ksConfigurationSettingsDir || - name == DirectoryFinder.ksSortSequenceTempDir) + if (name == FdoFileHelper.ksWritingSystemsDir || + name == FdoFileHelper.ksBackupSettingsDir || + name == FdoFileHelper.ksConfigurationSettingsDir || + name == FdoFileHelper.ksSortSequenceTempDir) { continue; } @@ -355,9 +355,9 @@ private static bool CheckForExtraData(ProjectInfo info, string folder) foreach (string filepath in files) { string file = Path.GetFileName(filepath); - if (file != info.DatabaseName + FwFileExtensions.ksFwDataXmlFileExtension && - file != info.DatabaseName + FwFileExtensions.ksFwDataDb4oFileExtension && - file != info.DatabaseName + FwFileExtensions.ksFwDataFallbackFileExtension) + if (file != info.DatabaseName + FdoFileHelper.ksFwDataXmlFileExtension && + file != info.DatabaseName + FdoFileHelper.ksFwDataDb4oFileExtension && + file != info.DatabaseName + FdoFileHelper.ksFwDataFallbackFileExtension) { return true; } diff --git a/Src/FwCoreDlgs/FwFindReplaceDlg.cs b/Src/FwCoreDlgs/FwFindReplaceDlg.cs index d955971167..9b4e2c9909 100644 --- a/Src/FwCoreDlgs/FwFindReplaceDlg.cs +++ b/Src/FwCoreDlgs/FwFindReplaceDlg.cs @@ -305,7 +305,7 @@ public bool SetDialogValues(FdoCache cache, IVwPattern vwPattern, IVwRootSite ro if (m_helpTopicProvider != null) // Will be null when running tests { - helpProvider.HelpNamespace = DirectoryFinder.FWCodeDirectory + + helpProvider.HelpNamespace = FwDirectoryFinder.CodeDirectory + m_helpTopicProvider.GetHelpString("UserHelpFile"); } diff --git a/Src/FwCoreDlgs/FwFontDialog.cs b/Src/FwCoreDlgs/FwFontDialog.cs index 33d68dbbe0..1403365cff 100644 --- a/Src/FwCoreDlgs/FwFontDialog.cs +++ b/Src/FwCoreDlgs/FwFontDialog.cs @@ -10,6 +10,7 @@ using System; using System.Drawing; +using System.Globalization; using System.Linq; using System.Windows.Forms; using SIL.FieldWorks.Common.COMInterfaces; @@ -91,9 +92,9 @@ void IFontDialog.Initialize(FontInfo fontInfo, bool fAllowSubscript, int ws, m_preview.WritingSystemCode = ws; m_preview.StyleSheet = styleSheet; - m_tbFontName.Text = fontInfo.UIFontName; + m_tbFontName.Text = fontInfo.UIFontName(); FontSize = fontInfo.m_fontSize.Value / 1000; - m_tbFontSize.Text = FontSize.ToString(); + m_tbFontSize.Text = FontSize.ToString(CultureInfo.InvariantCulture); m_FontAttributes.UpdateForStyle(fontInfo); m_FontAttributes.AllowSuperSubScript = fAllowSubscript; @@ -123,7 +124,7 @@ DialogResult IFontDialog.ShowDialog(IWin32Window parent) void IFontDialog.SaveFontInfo(FontInfo fontInfo) { // Font name - string newValue = FontInfo.GetInternalFontName(m_tbFontName.Text); + string newValue = GetInternalFontName(m_tbFontName.Text); fontInfo.IsDirty |= fontInfo.m_fontName.Save(false, newValue); // font size @@ -429,5 +430,18 @@ private void btnHelp_Click(object sender, EventArgs e) ShowHelp.ShowHelpTopic(m_helpTopicProvider, "kstidBulletsAndNumberingSelectFont"); } + /// ------------------------------------------------------------------------------------ + /// + /// Gets the internal font name for the given UI font. + /// + /// UI name of the font. + /// Internal font name + /// ------------------------------------------------------------------------------------ + private static string GetInternalFontName(string fontNameUI) + { + if (fontNameUI == ResourceHelper.GetResourceString("kstidDefaultFont")) + return StyleServices.DefaultFont; + return fontNameUI; + } } } diff --git a/Src/FwCoreDlgs/FwHelpAbout.cs b/Src/FwCoreDlgs/FwHelpAbout.cs index 42dc209673..a41fa02152 100644 --- a/Src/FwCoreDlgs/FwHelpAbout.cs +++ b/Src/FwCoreDlgs/FwHelpAbout.cs @@ -10,6 +10,7 @@ using System.IO; using System.Reflection; using System.Windows.Forms; +using SIL.CoreImpl; using SIL.FieldWorks.Common.FwUtils; using SIL.Utils; using System.Diagnostics; @@ -291,10 +292,10 @@ protected override void OnHandleCreated(EventArgs e) try { // Set the Application label to the name of the app - FwVersionInfoProvider viProvider = new FwVersionInfoProvider(ProductExecutableAssembly, true); + VersionInfoProvider viProvider = new VersionInfoProvider(ProductExecutableAssembly, true); lblName.Text = viProvider.ProductName; lblAppVersion.Text = viProvider.ApplicationVersion; - lblFwVersion.Text = viProvider.FieldWorksVersion; + lblFwVersion.Text = viProvider.MajorVersion; lblCopyright.Text = viProvider.CopyrightString + Environment.NewLine + viProvider.LicenseString + Environment.NewLine + viProvider.LicenseURL; // Set the title bar text diff --git a/Src/FwCoreDlgs/FwNewLangProject.cs b/Src/FwCoreDlgs/FwNewLangProject.cs index d1c84c8623..4e9b3905e9 100644 --- a/Src/FwCoreDlgs/FwNewLangProject.cs +++ b/Src/FwCoreDlgs/FwNewLangProject.cs @@ -19,6 +19,7 @@ using SIL.FieldWorks.Common.Drawing; using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.DomainServices; +using SIL.FieldWorks.Resources; using SIL.Utils; using XCore; using SIL.FieldWorks.Common.RootSites; @@ -141,7 +142,7 @@ public FwNewLangProject() // InitializeComponent(); AccessibleName = GetType().Name; - m_wsManager = new PalasoWritingSystemManager(new GlobalFileWritingSystemStore(DirectoryFinder.GlobalWritingSystemStoreDirectory)); + m_wsManager = new PalasoWritingSystemManager(new GlobalFileWritingSystemStore()); #if __MonoCS__ FixLabelFont(m_lblTip); FixLabelFont(m_lblAnalysisWrtSys); @@ -515,7 +516,7 @@ private void btnOK_Click(object sender, EventArgs e) // Project with this name already exists? try { - m_projInfo = ProjectInfo.GetProjectInfoByName(ProjectName); + m_projInfo = ProjectInfo.GetProjectInfoByName(FwDirectoryFinder.ProjectsDirectory, ProjectName); } catch (IOException ex) { @@ -660,13 +661,13 @@ protected void CreateNewLangProjWithProgress() { try { - using (var progressDlg = new ProgressDialogWithTask(this, null)) + using (var progressDlg = new ProgressDialogWithTask(this)) { progressDlg.Title = string.Format(FwCoreDlgs.kstidCreateLangProjCaption, ProjectName); string anthroFile = null; if (DisplayUi) // Prevents dialogs from showing during unit tests. { - anthroFile = FwCheckAnthroListDlg.PickAnthroList(progressDlg.Form, null, m_helpTopicProvider); + anthroFile = FwCheckAnthroListDlg.PickAnthroList(null, m_helpTopicProvider); } using (new WaitCursor()) { @@ -676,8 +677,9 @@ protected void CreateNewLangProjWithProgress() using (var threadHelper = new ThreadHelper()) { - m_dbFile = (string) progressDlg.RunTask(DisplayUi, FdoCache.CreateNewLangProj, - ProjectName, threadHelper, m_cbAnalWrtSys.SelectedItem, + + m_dbFile = (string)progressDlg.RunTask(DisplayUi, FdoCache.CreateNewLangProj, + ProjectName, FwDirectoryFinder.FdoDirectories, threadHelper, m_cbAnalWrtSys.SelectedItem, m_cbVernWrtSys.SelectedItem, ((PalasoWritingSystem)m_wsManager.UserWritingSystem).RFC5646, m_newAnalysisWss, m_newVernWss, anthroFile); @@ -688,7 +690,22 @@ protected void CreateNewLangProjWithProgress() catch (WorkerThreadException wex) { Exception e = wex.InnerException; - if (e.GetBaseException() is PathTooLongException) + if (e is UnauthorizedAccessException) + { + if (MiscUtils.IsUnix) + { + // Tell Mono user he/she needs to logout and log back in + MessageBox.Show(ResourceHelper.GetResourceString("ksNeedToJoinFwGroup")); + } + else + { + MessageBox.Show(string.Format(FwCoreDlgs.kstidErrorNewDb, e.Message), + FwUtils.ksSuiteName); + } + m_fIgnoreClose = true; + DialogResult = DialogResult.Cancel; + } + else if (e.GetBaseException() is PathTooLongException) { Show(); m_fIgnoreClose = true; @@ -703,7 +720,7 @@ protected void CreateNewLangProjWithProgress() m_fIgnoreClose = true; DialogResult = DialogResult.Cancel; } - else if (e is FwStartupException) + else if (e is StartupException) { MessageBox.Show(string.Format(FwCoreDlgs.kstidErrorNewDb, e.Message), FwUtils.ksSuiteName); @@ -780,7 +797,7 @@ public DialogResult DisplayDialog(Form f) public static bool CheckProjectDirectory(Form f, IHelpTopicProvider helpTopicProvider) { string warning = null; - string dataDirectory = DirectoryFinder.ProjectsDirectory; + string dataDirectory = FwDirectoryFinder.ProjectsDirectory; // Get the database directory attributes: var dir = new DirectoryInfo(dataDirectory); @@ -795,17 +812,17 @@ public static bool CheckProjectDirectory(Form f, IHelpTopicProvider helpTopicPro { if (dlg.ShowDialog(f) != DialogResult.OK) return false; // can't go on. - if (DirectoryFinder.ProjectsDirectoryLocalMachine == dlg.ProjectsFolder) + if (FwDirectoryFinder.ProjectsDirectoryLocalMachine == dlg.ProjectsFolder) { //Remove the user override since they reset to the default. - DirectoryFinder.ProjectsDirectory = null; + FwDirectoryFinder.ProjectsDirectory = null; } else { - DirectoryFinder.ProjectsDirectory = dlg.ProjectsFolder; + FwDirectoryFinder.ProjectsDirectory = dlg.ProjectsFolder; } } - dataDirectory = DirectoryFinder.ProjectsDirectory; + dataDirectory = FwDirectoryFinder.ProjectsDirectory; dir = new DirectoryInfo(dataDirectory); // loop on the offchance it didn't get created. } @@ -881,7 +898,7 @@ private void UpdateLanguageCombos() // Make sure our manager knows about any writing systems in the template folder. // In pathological cases where no projects have been installed these might not be in the global store. - foreach (var templateLangFile in Directory.GetFiles(DirectoryFinder.TemplateDirectory, @"*.ldml")) + foreach (var templateLangFile in Directory.GetFiles(FwDirectoryFinder.TemplateDirectory, @"*.ldml")) { var id = Path.GetFileNameWithoutExtension(templateLangFile); IWritingSystem dummy; diff --git a/Src/FwCoreDlgs/FwProjPropertiesDlg.cs b/Src/FwCoreDlgs/FwProjPropertiesDlg.cs index 42089c0c13..5778c93274 100644 --- a/Src/FwCoreDlgs/FwProjPropertiesDlg.cs +++ b/Src/FwCoreDlgs/FwProjPropertiesDlg.cs @@ -180,7 +180,7 @@ public FwProjPropertiesDlg(FdoCache cache, IApp app, IHelpTopicProvider helpTopi txtExtLnkEdit.Enabled = false; } - m_defaultLinkedFilesFolder = DirectoryFinder.GetDefaultLinkedFilesDir(m_cache.ServiceLocator.DataSetup.ProjectId.ProjectFolder); + m_defaultLinkedFilesFolder = FdoFileHelper.GetDefaultLinkedFilesDir(m_cache.ServiceLocator.DataSetup.ProjectId.ProjectFolder); } /// ------------------------------------------------------------------------------------ @@ -970,7 +970,12 @@ protected void m_btnOK_Click(object sender, EventArgs e) return; } - if (!ClientServerServices.Current.WarnOnConfirmingSingleUserChanges(m_cache)) //if Anything changed, check and warn about DB4o + if (!ClientServerServicesHelper.WarnOnConfirmingSingleUserChanges(m_cache)) //if Anything changed, check and warn about DB4o + { + NotifyProjectPropsChangedAndClose(); //The user changed something, but when warned decided against it, so do not save just quit + return; + } + if (!SharedBackendServicesHelper.WarnOnConfirmingSingleUserChanges(m_cache)) //if Anything changed, check and warn about other apps { NotifyProjectPropsChangedAndClose(); //The user changed something, but when warned decided against it, so do not save just quit return; @@ -1446,7 +1451,7 @@ private void WarnOnNonDefaultLinkedFilesChange() private string HandleLinkedFilesPathDoesNotExist(string linkedFilesPath) { - var defaultLinkedFilesPath = DirectoryFinder.GetDefaultLinkedFilesDir(m_cache.ProjectId.ProjectFolder); + var defaultLinkedFilesPath = FdoFileHelper.GetDefaultLinkedFilesDir(m_cache.ProjectId.ProjectFolder); if (!Directory.Exists(linkedFilesPath) && linkedFilesPath.Equals(defaultLinkedFilesPath)) { //if the path points to the default location but does not exist then create it. diff --git a/Src/FwCoreDlgs/FwSplashScreen.cs b/Src/FwCoreDlgs/FwSplashScreen.cs index e7502abf12..657efc6ce8 100644 --- a/Src/FwCoreDlgs/FwSplashScreen.cs +++ b/Src/FwCoreDlgs/FwSplashScreen.cs @@ -6,7 +6,6 @@ // Responsibility: TE Team using System; -using System.Drawing; using System.ComponentModel; using System.Diagnostics; using System.Reflection; @@ -14,6 +13,7 @@ using System.Windows.Forms; using SIL.FieldWorks.Common.FwUtils; +using SIL.Utils; namespace SIL.FieldWorks.FwCoreDlgs { @@ -23,7 +23,7 @@ namespace SIL.FieldWorks.FwCoreDlgs /// FW Splash Screen /// /// ---------------------------------------------------------------------------------------- - public class FwSplashScreen : IProgress, IDisposable + public class FwSplashScreen : IThreadedProgress, IDisposable { #region Events event CancelEventHandler IProgress.Canceling @@ -373,6 +373,15 @@ public string Title set { } } + /// + /// Gets an object to be used for ensuring that required tasks are invoked on the main + /// UI thread. + /// + public ISynchronizeInvoke SynchronizeInvoke + { + get { return m_splashScreen; } + } + /// ------------------------------------------------------------------------------------ /// /// Gets the progress as a form (used for message box owners, etc). @@ -383,25 +392,24 @@ public Form Form get { return m_splashScreen; } } - /// ------------------------------------------------------------------------------------ /// - /// Gets or sets the style of the ProgressBar. + /// Gets or sets a value indicating whether this progress is indeterminate. /// - /// ------------------------------------------------------------------------------------ - public ProgressBarStyle ProgressBarStyle + public bool IsIndeterminate { get { if (m_splashScreen.InvokeRequired) - return (ProgressBarStyle)m_splashScreen.Invoke((Func)(() => m_splashScreen.ProgressBarStyle)); - return m_splashScreen.ProgressBarStyle; + return (bool) m_splashScreen.Invoke((Func)(() => m_splashScreen.IsIndeterminate)); + return m_splashScreen.IsIndeterminate; } + set { if (m_splashScreen.InvokeRequired) - m_splashScreen.Invoke((Action)(style => m_splashScreen.ProgressBarStyle = style), value); + m_splashScreen.Invoke((Action)(b => m_splashScreen.IsIndeterminate = b), value); else - m_splashScreen.ProgressBarStyle = value; + m_splashScreen.IsIndeterminate = value; } } @@ -445,6 +453,51 @@ private void StartSplashScreen() } } #endregion + + #region IThreadedProgress implementation + + /// + /// Gets a value indicating whether the task has been canceled. + /// + public bool Canceled + { + get { return false; } + } + + /// + /// If progress dialog is already showing, we run the background task using it (without + /// creating a separate thread). Otherwise we display a new progress dialog as a modal + /// dialog and start the background task in a separate thread. + /// + /// The background task. + /// The paramters that will be passed to the background task + /// + /// The return value from the background thread. + /// + /// ------------------------------------------------------------------------------------ + /// ------------------------------------------------------------------------------------ + public object RunTask(Func backgroundTask, params object[] parameters) + { + return RunTask(true, backgroundTask, parameters); + } + + /// + /// Displays the progress dialog as a modal dialog and starts the background task. + /// + /// set to true to display the progress dialog, + /// false to run without UI. + /// The background task. + /// The paramters that will be passed to the background task + /// + /// The return value from the background thread. + /// + /// ------------------------------------------------------------------------------------ + /// ------------------------------------------------------------------------------------ + public object RunTask(bool fDisplayUi, Func backgroundTask, params object[] parameters) + { + return backgroundTask(this, parameters); + } + #endregion } #endregion } diff --git a/Src/FwCoreDlgs/FwStylesDlg.cs b/Src/FwCoreDlgs/FwStylesDlg.cs index c0550f17c2..bfb629e476 100644 --- a/Src/FwCoreDlgs/FwStylesDlg.cs +++ b/Src/FwCoreDlgs/FwStylesDlg.cs @@ -808,9 +808,16 @@ private void m_btnOk_Click(object sender, EventArgs e) UpdateChanges(styleInfo); } - // Check to make sure new styles are not going to result in duplicates - // in the database - m_styleSheet.CheckForDuplicates(m_styleTable, m_app.ApplicationName); + try + { + // Check to make sure new styles are not going to result in duplicates + // in the database + m_styleSheet.CheckForDuplicates(m_styleTable); + } + catch (IncompatibleStyleExistsException isee) + { + MessageBoxUtils.Show(isee.Message, m_app.ApplicationName); + } foreach (StyleInfo style in m_styleTable.Values) { diff --git a/Src/FwCoreDlgs/MoveOrCopyFilesDlg.cs b/Src/FwCoreDlgs/MoveOrCopyFilesDlg.cs index 618d9eeff8..568f416b1a 100644 --- a/Src/FwCoreDlgs/MoveOrCopyFilesDlg.cs +++ b/Src/FwCoreDlgs/MoveOrCopyFilesDlg.cs @@ -207,7 +207,7 @@ private void SetupHelp(IHelpTopicProvider helpTopicProvider, string sHelpTopic) m_sHelpTopic = sHelpTopic; if (m_helpTopicProvider != null) { - this.m_helpProvider.HelpNamespace = Path.Combine(DirectoryFinder.FWCodeDirectory, + this.m_helpProvider.HelpNamespace = Path.Combine(FwDirectoryFinder.CodeDirectory, m_helpTopicProvider.GetHelpString("UserHelpFile")); this.m_helpProvider.SetHelpKeyword(this, m_helpTopicProvider.GetHelpString(m_sHelpTopic)); this.m_helpProvider.SetHelpNavigator(this, HelpNavigator.Topic); @@ -314,7 +314,7 @@ public static string MoveCopyOrLeaveMediaFile(string sFile, string sRootDirLinke IHelpTopicProvider helpTopicProvider, bool isLocal) { return MoveCopyOrLeaveFile(sFile, - Path.Combine(sRootDirLinkedFiles, DirectoryFinder.ksMediaDir), + Path.Combine(sRootDirLinkedFiles, FdoFileHelper.ksMediaDir), sRootDirLinkedFiles, helpTopicProvider, isLocal); } @@ -339,7 +339,7 @@ public static string MoveCopyOrLeaveExternalFile(string sFile, string sRootDirLi IHelpTopicProvider helpTopicProvider, bool isLocal) { return MoveCopyOrLeaveFile(sFile, - Path.Combine(sRootDirLinkedFiles, DirectoryFinder.ksOtherLinkedFilesDir), + Path.Combine(sRootDirLinkedFiles, FdoFileHelper.ksOtherLinkedFilesDir), sRootDirLinkedFiles, helpTopicProvider, isLocal); } diff --git a/Src/FwCoreDlgs/PicturePropertiesDialog.cs b/Src/FwCoreDlgs/PicturePropertiesDialog.cs index 9fc75b69e9..539f3d4b14 100644 --- a/Src/FwCoreDlgs/PicturePropertiesDialog.cs +++ b/Src/FwCoreDlgs/PicturePropertiesDialog.cs @@ -122,7 +122,7 @@ public PicturePropertiesDialog(FdoCache cache, ICmPicture initialPicture, if (m_helpTopicProvider != null) // Could be null during tests { helpProvider = new HelpProvider(); - helpProvider.HelpNamespace = DirectoryFinder.FWCodeDirectory + + helpProvider.HelpNamespace = FwDirectoryFinder.CodeDirectory + m_helpTopicProvider.GetHelpString("UserHelpFile"); helpProvider.SetHelpKeyword(this, m_helpTopicProvider.GetHelpString(s_helpTopic)); helpProvider.SetHelpNavigator(this, HelpNavigator.Topic); diff --git a/Src/FwCoreDlgs/ProjectLocationSharingDlg.cs b/Src/FwCoreDlgs/ProjectLocationSharingDlg.cs index 0f0b9bbc7d..0d11208992 100644 --- a/Src/FwCoreDlgs/ProjectLocationSharingDlg.cs +++ b/Src/FwCoreDlgs/ProjectLocationSharingDlg.cs @@ -59,7 +59,7 @@ public ProjectLocationSharingDlg(IHelpTopicProvider helpTopicProvider, FdoCache { m_tbCurrentProjectPath.Text = cache.ProjectId.Path; } - m_tbProjectsFolder.Text = DirectoryFinder.ProjectsDirectory; + m_tbProjectsFolder.Text = FwDirectoryFinder.ProjectsDirectory; // We can only change the folder if sharing is INITIALLY turned off. m_tbProjectsFolder.Enabled = !m_cbShareMyProjects.Checked; m_btnBrowseProjectFolder.Enabled = !m_cbShareMyProjects.Checked; @@ -76,7 +76,7 @@ private void m_tbProjectsFolder_TextChanged(object sender, EventArgs e) if (Directory.Exists(m_tbProjectsFolder.Text)) { var newFolder = m_tbProjectsFolder.Text; - var oldFolder = DirectoryFinder.ProjectsDirectory; + var oldFolder = FwDirectoryFinder.ProjectsDirectory; if (!MiscUtils.IsUnix) { newFolder = newFolder.ToLowerInvariant(); @@ -91,7 +91,7 @@ private void m_tbProjectsFolder_TextChanged(object sender, EventArgs e) { string path = m_tbProjectsFolder.Text; // If it contains a settings directory, assume it's a project settings folder...possibly settings for a remote project. - if (Directory.Exists(Path.Combine(path, DirectoryFinder.ksConfigurationSettingsDir))) + if (Directory.Exists(Path.Combine(path, FdoFileHelper.ksConfigurationSettingsDir))) { m_btnOK.Enabled = false; return; @@ -219,7 +219,7 @@ private void m_tbProjectsFolder_TextChanged(object sender, EventArgs e) /// ------------------------------------------------------------------------------------ private void m_btnBrowseProjectFolder_Click(object sender, EventArgs e) { - string defaultPath = DirectoryFinder.ProjectsDirectory; + string defaultPath = FwDirectoryFinder.ProjectsDirectory; using (var fldrBrowse = new FolderBrowserDialogAdapter()) { @@ -281,14 +281,14 @@ private void m_cbShareMyProjects_CheckedChanged(object sender, EventArgs e) // If we just turned it on, and it was on to start with, changing the project directory is not allowed; // revert any changes that have been made to that. if (m_cbShareMyProjects.Checked && ClientServerServices.Current.Local.ShareMyProjects) - m_tbProjectsFolder.Text = DirectoryFinder.ProjectsDirectory; + m_tbProjectsFolder.Text = FwDirectoryFinder.ProjectsDirectory; // Sharing can only be turned on if these directories are the same, because of complications when the ProjectsDirectory // seen by FieldWorks is different from the one seen by the FwRemoteDatabaseConnectorService. - if (m_cbShareMyProjects.Checked && DirectoryFinder.ProjectsDirectory != DirectoryFinder.ProjectsDirectoryLocalMachine) + if (m_cbShareMyProjects.Checked && FwDirectoryFinder.ProjectsDirectory != FwDirectoryFinder.ProjectsDirectoryLocalMachine) { MessageBox.Show(this, - string.Format(FwCoreDlgs.ksCantShareDiffProjectFolders, DirectoryFinder.ProjectsDirectory, - DirectoryFinder.ProjectsDirectoryLocalMachine), + string.Format(FwCoreDlgs.ksCantShareDiffProjectFolders, FwDirectoryFinder.ProjectsDirectory, + FwDirectoryFinder.ProjectsDirectoryLocalMachine), FwCoreDlgs.ksCantShare); m_cbShareMyProjects.Checked = false; } diff --git a/Src/FwCoreDlgs/PunctuationDlg.cs b/Src/FwCoreDlgs/PunctuationDlg.cs index 38b7738b8b..a937c2bf36 100644 --- a/Src/FwCoreDlgs/PunctuationDlg.cs +++ b/Src/FwCoreDlgs/PunctuationDlg.cs @@ -96,7 +96,7 @@ public PunctuationDlg(FdoCache cache, IWritingSystemContainer wsContainer, if (string.IsNullOrEmpty(wsName)) throw new ArgumentException("Writing system name must not be null or empty.", "wsName"); - m_validChars = ValidCharacters.Load(m_ws, LoadException); + m_validChars = ValidCharacters.Load(m_ws, LoadException, FwDirectoryFinder.LegacyWordformingCharOverridesFile); m_matchedPairList = MatchedPairList.Load(m_ws.MatchedPairs, wsName); m_patternList = PuncPatternsList.Load(m_ws.PunctuationPatterns, wsName); m_chrPropEng = LgIcuCharPropEngineClass.Create(); @@ -861,7 +861,7 @@ private bool ValidateQuotationMarks(QuotationMarksList qmarks) private void UpdateValidCharactersList() { bool validCharsUpdated = false; - ValidCharacters validChars = ValidCharacters.Load(m_ws, LoadException); + ValidCharacters validChars = ValidCharacters.Load(m_ws, LoadException, FwDirectoryFinder.LegacyWordformingCharOverridesFile); if (validChars == null) return; @@ -1497,7 +1497,7 @@ public class QuotationLangList : List internal static string s_customName = Properties.Resources.kstidCustomQuotationMarksName; private static string s_file = - Path.Combine(DirectoryFinder.FWCodeDirectory, "QuotationLanguages.xml"); + Path.Combine(FwDirectoryFinder.CodeDirectory, "QuotationLanguages.xml"); private QuotationLang m_customItem; diff --git a/Src/FwCoreDlgs/RealSplashScreen.cs b/Src/FwCoreDlgs/RealSplashScreen.cs index 9912c8286c..c9cee38b35 100644 --- a/Src/FwCoreDlgs/RealSplashScreen.cs +++ b/Src/FwCoreDlgs/RealSplashScreen.cs @@ -11,6 +11,7 @@ using System.Reflection; using System.Threading; using System.Windows.Forms; +using SIL.CoreImpl; using SIL.FieldWorks.Common.FwUtils; using SIL.Utils; using SIL.FieldWorks.Common.Controls; @@ -345,11 +346,11 @@ protected void InitControlLabels() // Set the Application label to the name of the app if (m_productExecutableAssembly != null) { - FwVersionInfoProvider viProvider = new FwVersionInfoProvider(m_productExecutableAssembly, m_fDisplaySILInfo); + VersionInfoProvider viProvider = new VersionInfoProvider(m_productExecutableAssembly, m_fDisplaySILInfo); lblProductName.Text = viProvider.ProductName; Text = lblProductName.Text; lblAppVersion.Text = viProvider.ApplicationVersion; - lblFwVersion.Text = viProvider.FieldWorksVersion; + lblFwVersion.Text = viProvider.MajorVersion; lblCopyright.Text = viProvider.CopyrightString + Environment.NewLine + viProvider.LicenseString; } } @@ -482,6 +483,15 @@ public string Message } } + /// + /// Gets an object to be used for ensuring that required tasks are invoked on the main + /// UI thread. + /// + public ISynchronizeInvoke SynchronizeInvoke + { + get { return this; } + } + /// ------------------------------------------------------------------------------------ /// /// Gets the form displaying the progress (used for message box owners, etc). If the progress @@ -493,18 +503,13 @@ public Form Form get { return this; } } - /// ------------------------------------------------------------------------------------ /// - /// Gets or sets the style of the ProgressBar. + /// Gets or sets a value indicating whether this progress is indeterminate. /// - /// ------------------------------------------------------------------------------------ - public ProgressBarStyle ProgressBarStyle + public bool IsIndeterminate { - get { return marqueeGif.Visible ? ProgressBarStyle.Marquee : ProgressBarStyle.Continuous; } - set - { - marqueeGif.Visible = (value == ProgressBarStyle.Marquee); - } + get { return marqueeGif.Visible; } + set { marqueeGif.Visible = value; } } /// ------------------------------------------------------------------------------------ diff --git a/Src/FwCoreDlgs/SharedBackendServicesHelper.cs b/Src/FwCoreDlgs/SharedBackendServicesHelper.cs new file mode 100644 index 0000000000..ed65efd226 --- /dev/null +++ b/Src/FwCoreDlgs/SharedBackendServicesHelper.cs @@ -0,0 +1,47 @@ +using System; +using System.Windows.Forms; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.FDO.DomainServices; +using SIL.Utils; + +namespace SIL.FieldWorks.FwCoreDlgs +{ + /// + /// Provides a common place for calls which utilize FDO's SharedBackendServices + /// + public static class SharedBackendServicesHelper + { + /// + /// Display a warning indicating that it may be dangerous to change things in the dialog that + /// is about to open when there are other applications using this project. The warning should only + /// be shown if, in fact, other applications currently have this project open. Return true to continue, + /// false to cancel opening the dialog. + /// + /// + public static bool WarnOnOpeningSingleUserDialog(FdoCache cache) + { + if (!SharedBackendServices.AreMultipleApplicationsConnected(cache)) + return true; + string msg = Strings.ksWarnOnOpeningSingleAppDialog.Replace("\\n", Environment.NewLine); + return ThreadHelper.ShowMessageBox(null, msg, Strings.ksOtherAppsUsingProjectCaption, + MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK; + } + + /// + /// Display a warning indicating that it may be dangerous to change things that the user has just + /// asked to change when other applications are using this project. The warning should only be shown + /// if, in fact, other applications currently have this project open. Return true to continue, false + /// to discard the changes. This is typically called in response to clicking an OK button in a dialog + /// which changes dangerous user settings. + /// + /// + public static bool WarnOnConfirmingSingleUserChanges(FdoCache cache) + { + if (!SharedBackendServices.AreMultipleApplicationsConnected(cache)) + return true; + string msg = Strings.ksWarnOnConfirmingSingleAppChanges.Replace("\\n", Environment.NewLine); + return ThreadHelper.ShowMessageBox(null, msg, Strings.ksNotAdvisableOtherAppsUsingProjectCaption, + MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes; + } + } +} diff --git a/Src/FwCoreDlgs/Strings.Designer.cs b/Src/FwCoreDlgs/Strings.Designer.cs new file mode 100644 index 0000000000..a745e179d8 --- /dev/null +++ b/Src/FwCoreDlgs/Strings.Designer.cs @@ -0,0 +1,149 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.18444 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SIL.FieldWorks.FwCoreDlgs { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Strings { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Strings() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SIL.FieldWorks.FwCoreDlgs.Strings", typeof(Strings).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Not advisable when other applications are using this project. + /// + internal static string ksNotAdvisableOtherAppsUsingProjectCaption { + get { + return ResourceManager.GetString("ksNotAdvisableOtherAppsUsingProjectCaption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Not advisable when other users connected. + /// + internal static string ksNotAdvisableOthersConnectedCaption { + get { + return ResourceManager.GetString("ksNotAdvisableOthersConnectedCaption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Take care - other applications are using this project. + /// + internal static string ksOtherAppsUsingProjectCaption { + get { + return ResourceManager.GetString("ksOtherAppsUsingProjectCaption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Take care - other users connected. + /// + internal static string ksOthersConnectedCaption { + get { + return ResourceManager.GetString("ksOthersConnectedCaption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Saving changes in this dialog while this project is open in other applications may cause those applications to crash or malfunction. + /// + ///Do you want to make the changes anyway?. + /// + internal static string ksWarnOnConfirmingSingleAppChanges { + get { + return ResourceManager.GetString("ksWarnOnConfirmingSingleAppChanges", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Number of other users: {0} + ///When saving changes in this dialog with other users connected, FieldWorks may crash or malfunction for those users. + /// + ///Do you want to make the changes anyway?. + /// + internal static string ksWarnOnConfirmingSingleUserChanges { + get { + return ResourceManager.GetString("ksWarnOnConfirmingSingleUserChanges", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The menu command you selected will open a dialog box. If you change any selections or settings in the dialog box, it can cause problems in other applications that have this project open. + /// + ///If you will only look at selections and settings, click OK. + /// + ///If you need to make changes, close all other applications that have this project open before you continue, or click Cancel.. + /// + internal static string ksWarnOnOpeningSingleAppDialog { + get { + return ResourceManager.GetString("ksWarnOnOpeningSingleAppDialog", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Number of other users: {0} + ///The menu command you selected will open a dialog box. If you change any selections or settings in the dialog box, other users who have this project open on their computers will have problems. + /// + ///If you will only look at selections and settings, click OK. + /// + ///If you need to make changes, tell the other users to close this project before you continue, or click Cancel.. + /// + internal static string ksWarnOnOpeningSingleUserDialog { + get { + return ResourceManager.GetString("ksWarnOnOpeningSingleUserDialog", resourceCulture); + } + } + } +} diff --git a/Src/FwCoreDlgs/Strings.resx b/Src/FwCoreDlgs/Strings.resx new file mode 100644 index 0000000000..838afd988c --- /dev/null +++ b/Src/FwCoreDlgs/Strings.resx @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Not advisable when other applications are using this project + + + Not advisable when other users connected + + + Take care - other applications are using this project + + + Take care - other users connected + + + Saving changes in this dialog while this project is open in other applications may cause those applications to crash or malfunction. + +Do you want to make the changes anyway? + + + Number of other users: {0} +When saving changes in this dialog with other users connected, FieldWorks may crash or malfunction for those users. + +Do you want to make the changes anyway? + + + The menu command you selected will open a dialog box. If you change any selections or settings in the dialog box, it can cause problems in other applications that have this project open. + +If you will only look at selections and settings, click OK. + +If you need to make changes, close all other applications that have this project open before you continue, or click Cancel. + + + Number of other users: {0} +The menu command you selected will open a dialog box. If you change any selections or settings in the dialog box, other users who have this project open on their computers will have problems. + +If you will only look at selections and settings, click OK. + +If you need to make changes, tell the other users to close this project before you continue, or click Cancel. + + \ No newline at end of file diff --git a/Src/FwCoreDlgs/UtilityDlg.cs b/Src/FwCoreDlgs/UtilityDlg.cs index 3b29065a3a..55818b5d04 100644 --- a/Src/FwCoreDlgs/UtilityDlg.cs +++ b/Src/FwCoreDlgs/UtilityDlg.cs @@ -58,7 +58,7 @@ public UtilityDlg(IHelpTopicProvider helpTopicProvider) m_helpTopicProvider = helpTopicProvider; helpProvider = new HelpProvider(); - helpProvider.HelpNamespace = DirectoryFinder.FWCodeDirectory + m_helpTopicProvider.GetHelpString("UserHelpFile"); + helpProvider.HelpNamespace = FwDirectoryFinder.CodeDirectory + m_helpTopicProvider.GetHelpString("UserHelpFile"); helpProvider.SetHelpKeyword(this, m_helpTopicProvider.GetHelpString(s_helpTopic)); helpProvider.SetHelpNavigator(this, HelpNavigator.Topic); @@ -194,7 +194,7 @@ public void SetDlgInfo(Mediator mediator, XmlNode configurationParameters) // this.Text = XmlUtils.GetLocalizedAttributeValue(mediator.StringTbl, configurationParameters, "title", "FieldWorks Project Utilities"); - string utilsPathname = Path.Combine(DirectoryFinder.FWCodeDirectory, + string utilsPathname = Path.Combine(FwDirectoryFinder.CodeDirectory, XmlUtils.GetManditoryAttributeValue(configurationParameters, "filename")); // Get the folder path: string utilsFolderName = Path.GetDirectoryName(utilsPathname); diff --git a/Src/FwCoreDlgs/ValidCharactersDlg.cs b/Src/FwCoreDlgs/ValidCharactersDlg.cs index 3072113ff1..a6b83139dc 100644 --- a/Src/FwCoreDlgs/ValidCharactersDlg.cs +++ b/Src/FwCoreDlgs/ValidCharactersDlg.cs @@ -18,13 +18,13 @@ using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; -using System.Windows.Forms.VisualStyles; using Palaso.WritingSystems; using SIL.CoreImpl; using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.Common.Controls; using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.Common.RootSites; +using SIL.FieldWorks.Common.ScriptureUtils; using SIL.FieldWorks.Common.Widgets; using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.DomainServices; @@ -34,7 +34,6 @@ using SILUBS.SharedScrUtils; using XCore; - namespace SIL.FieldWorks.FwCoreDlgs { /// ---------------------------------------------------------------------------------------- @@ -71,7 +70,7 @@ protected internal class ValidCharGridsManager : IDisposable /// --------------------------------------------------------------------------------- /// - /// Constructs a new instance of the class. + /// Constructs a new instance of the class. /// /// --------------------------------------------------------------------------------- public ValidCharGridsManager() @@ -137,7 +136,7 @@ internal void Init(CharacterGrid gridWf, CharacterGrid gridOther, CharacterGrid m_gridWordForming = gridWf; m_gridNumbers = gridNum; m_gridOther = gridOther; - m_validChars = ValidCharacters.Load(ws, LoadException); + m_validChars = ValidCharacters.Load(ws, LoadException, FwDirectoryFinder.LegacyWordformingCharOverridesFile); RefreshCharacterGrids(ValidCharacterType.All); } @@ -672,7 +671,7 @@ internal void HandleRemoveClick(object sender, EventArgs e) #region Contructors /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// ------------------------------------------------------------------------------------ public ValidCharactersDlg() @@ -704,7 +703,7 @@ public ValidCharactersDlg() /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The cache. Can be null if called from New Project /// dialog. @@ -2018,7 +2017,7 @@ public class CharacterInventoryRow /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The character for this inventory row. /// ------------------------------------------------------------------------------------ diff --git a/Src/FwCoreDlgs/WritingSystemPropertiesDialog.cs b/Src/FwCoreDlgs/WritingSystemPropertiesDialog.cs index c151c2184a..c40ac21876 100644 --- a/Src/FwCoreDlgs/WritingSystemPropertiesDialog.cs +++ b/Src/FwCoreDlgs/WritingSystemPropertiesDialog.cs @@ -149,8 +149,10 @@ public static bool ShowModifyDialog(Form owner, IWritingSystem selectedWs, bool if (addNewForLangOfSelectedWs) wsPropsDlg.AddNewWsForLanguage(); - if (!ClientServerServices.Current.WarnOnOpeningSingleUserDialog(cache)) + if (!ClientServerServicesHelper.WarnOnOpeningSingleUserDialog(cache)) return false; // nothing changed. + if (!SharedBackendServicesHelper.WarnOnOpeningSingleUserDialog(cache)) + return false; if (wsPropsDlg.ShowDialog(owner) == DialogResult.OK) { @@ -1560,8 +1562,11 @@ private void OnOk(object sender, EventArgs e) if (!CheckOkToChangeContext()) return; - if (ThereAreChanges && ClientServerServices.Current.WarnOnConfirmingSingleUserChanges(m_cache)) + if (ThereAreChanges && ClientServerServicesHelper.WarnOnConfirmingSingleUserChanges(m_cache) + && SharedBackendServicesHelper.WarnOnConfirmingSingleUserChanges(m_cache)) + { SaveChanges(); + } DialogResult = DialogResult.OK; } diff --git a/Src/FwParatextLexiconPlugin/BuildInclude.targets b/Src/FwParatextLexiconPlugin/BuildInclude.targets new file mode 100644 index 0000000000..f922c466f0 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/BuildInclude.targets @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Src/FwParatextLexiconPlugin/ChooseFdoProjectForm.Designer.cs b/Src/FwParatextLexiconPlugin/ChooseFdoProjectForm.Designer.cs new file mode 100644 index 0000000000..cc879601b3 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/ChooseFdoProjectForm.Designer.cs @@ -0,0 +1,202 @@ +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + partial class ChooseFdoProjectForm : System.Windows.Forms.Form + { + + //Form overrides dispose to clean up the component list. + [System.Diagnostics.DebuggerNonUserCode()] + protected override void Dispose(bool disposing) + { + if (disposing && components != null) { + components.Dispose(); + } + base.Dispose(disposing); + } + + //Required by the Windows Form Designer + + private System.ComponentModel.IContainer components = null; + //NOTE: The following procedure is required by the Windows Form Designer + //It can be modified using the Windows Form Designer. + //Do not modify it using the code editor. + [System.Diagnostics.DebuggerStepThrough()] + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ChooseFdoProjectForm)); + this.TableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.btnOk = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.groupBoxRestore = new System.Windows.Forms.GroupBox(); + this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); + this.btnBrowse = new System.Windows.Forms.Button(); + this.labelSelectedBackupFile = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.textBoxProjectName = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.listBox = new System.Windows.Forms.ListBox(); + this.TableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); + this.groupBoxExisting = new System.Windows.Forms.GroupBox(); + this.panel1 = new System.Windows.Forms.Panel(); + this.radioExisting = new System.Windows.Forms.RadioButton(); + this.radioRestore = new System.Windows.Forms.RadioButton(); + this.TableLayoutPanel1.SuspendLayout(); + this.groupBoxRestore.SuspendLayout(); + this.tableLayoutPanel3.SuspendLayout(); + this.TableLayoutPanel2.SuspendLayout(); + this.groupBoxExisting.SuspendLayout(); + this.panel1.SuspendLayout(); + this.SuspendLayout(); + // + // TableLayoutPanel1 + // + resources.ApplyResources(this.TableLayoutPanel1, "TableLayoutPanel1"); + this.TableLayoutPanel1.Controls.Add(this.btnOk, 0, 0); + this.TableLayoutPanel1.Controls.Add(this.btnCancel, 1, 0); + this.TableLayoutPanel1.Name = "TableLayoutPanel1"; + // + // btnOk + // + resources.ApplyResources(this.btnOk, "btnOk"); + this.btnOk.Name = "btnOk"; + this.btnOk.Click += new System.EventHandler(this.btnOk_Click); + // + // btnCancel + // + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + resources.ApplyResources(this.btnCancel, "btnCancel"); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); + // + // groupBoxRestore + // + this.groupBoxRestore.Controls.Add(this.tableLayoutPanel3); + resources.ApplyResources(this.groupBoxRestore, "groupBoxRestore"); + this.groupBoxRestore.Name = "groupBoxRestore"; + this.groupBoxRestore.TabStop = false; + // + // tableLayoutPanel3 + // + resources.ApplyResources(this.tableLayoutPanel3, "tableLayoutPanel3"); + this.tableLayoutPanel3.Controls.Add(this.btnBrowse, 2, 0); + this.tableLayoutPanel3.Controls.Add(this.labelSelectedBackupFile, 1, 0); + this.tableLayoutPanel3.Controls.Add(this.label2, 0, 1); + this.tableLayoutPanel3.Controls.Add(this.textBoxProjectName, 1, 1); + this.tableLayoutPanel3.Controls.Add(this.label1, 0, 0); + this.tableLayoutPanel3.Name = "tableLayoutPanel3"; + // + // btnBrowse + // + resources.ApplyResources(this.btnBrowse, "btnBrowse"); + this.btnBrowse.Name = "btnBrowse"; + this.btnBrowse.UseVisualStyleBackColor = true; + this.btnBrowse.Click += new System.EventHandler(this.btnBrowse_Click); + // + // labelSelectedBackupFile + // + resources.ApplyResources(this.labelSelectedBackupFile, "labelSelectedBackupFile"); + this.labelSelectedBackupFile.Name = "labelSelectedBackupFile"; + // + // label2 + // + resources.ApplyResources(this.label2, "label2"); + this.label2.Name = "label2"; + // + // textBoxProjectName + // + resources.ApplyResources(this.textBoxProjectName, "textBoxProjectName"); + this.textBoxProjectName.Name = "textBoxProjectName"; + this.textBoxProjectName.TextChanged += new System.EventHandler(this.textBoxProjectName_TextChanged); + // + // label1 + // + resources.ApplyResources(this.label1, "label1"); + this.label1.Name = "label1"; + // + // listBox + // + resources.ApplyResources(this.listBox, "listBox"); + this.listBox.FormattingEnabled = true; + this.listBox.Name = "listBox"; + this.listBox.SelectedIndexChanged += new System.EventHandler(this.ListBox_SelectedIndexChanged); + this.listBox.DoubleClick += new System.EventHandler(this.ListBox_DoubleClick); + // + // TableLayoutPanel2 + // + resources.ApplyResources(this.TableLayoutPanel2, "TableLayoutPanel2"); + this.TableLayoutPanel2.Controls.Add(this.groupBoxExisting, 1, 0); + this.TableLayoutPanel2.Controls.Add(this.groupBoxRestore, 1, 1); + this.TableLayoutPanel2.Controls.Add(this.panel1, 0, 0); + this.TableLayoutPanel2.Name = "TableLayoutPanel2"; + // + // groupBoxExisting + // + this.groupBoxExisting.Controls.Add(this.listBox); + resources.ApplyResources(this.groupBoxExisting, "groupBoxExisting"); + this.groupBoxExisting.Name = "groupBoxExisting"; + this.groupBoxExisting.TabStop = false; + // + // panel1 + // + this.panel1.Controls.Add(this.radioExisting); + this.panel1.Controls.Add(this.radioRestore); + resources.ApplyResources(this.panel1, "panel1"); + this.panel1.Name = "panel1"; + this.TableLayoutPanel2.SetRowSpan(this.panel1, 2); + // + // radioExisting + // + resources.ApplyResources(this.radioExisting, "radioExisting"); + this.radioExisting.Checked = true; + this.radioExisting.Name = "radioExisting"; + this.radioExisting.TabStop = true; + this.radioExisting.UseVisualStyleBackColor = true; + this.radioExisting.CheckedChanged += new System.EventHandler(this.radio_CheckedChanged); + // + // radioRestore + // + resources.ApplyResources(this.radioRestore, "radioRestore"); + this.radioRestore.Name = "radioRestore"; + this.radioRestore.UseVisualStyleBackColor = true; + // + // ChooseFdoProjectForm + // + this.AcceptButton = this.btnOk; + resources.ApplyResources(this, "$this"); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.Controls.Add(this.TableLayoutPanel2); + this.Controls.Add(this.TableLayoutPanel1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "ChooseFdoProjectForm"; + this.ShowInTaskbar = false; + this.TableLayoutPanel1.ResumeLayout(false); + this.groupBoxRestore.ResumeLayout(false); + this.tableLayoutPanel3.ResumeLayout(false); + this.tableLayoutPanel3.PerformLayout(); + this.TableLayoutPanel2.ResumeLayout(false); + this.groupBoxExisting.ResumeLayout(false); + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + this.ResumeLayout(false); + + } + internal System.Windows.Forms.TableLayoutPanel TableLayoutPanel1; + internal System.Windows.Forms.Button btnOk; + internal System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.GroupBox groupBoxRestore; + private System.Windows.Forms.Button btnBrowse; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3; + internal System.Windows.Forms.ListBox listBox; + internal System.Windows.Forms.TableLayoutPanel TableLayoutPanel2; + private System.Windows.Forms.GroupBox groupBoxExisting; + private System.Windows.Forms.Label labelSelectedBackupFile; + private System.Windows.Forms.RadioButton radioExisting; + private System.Windows.Forms.RadioButton radioRestore; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox textBoxProjectName; + private System.Windows.Forms.Panel panel1; + } +} diff --git a/Src/FwParatextLexiconPlugin/ChooseFdoProjectForm.cs b/Src/FwParatextLexiconPlugin/ChooseFdoProjectForm.cs new file mode 100644 index 0000000000..20921dd155 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/ChooseFdoProjectForm.cs @@ -0,0 +1,295 @@ +using System; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Runtime.Remoting; +using System.Windows.Forms; +using SIL.FieldWorks.FDO.DomainServices; +using SIL.FieldWorks.FDO.DomainServices.BackupRestore; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + internal partial class ChooseFdoProjectForm + { + private LanguageProjectInfo m_selectedItem; + private string m_restoreFileFullPath; + private RestoreProjectSettings m_restoreSettings; + private readonly ParatextLexiconPluginFdoUI m_ui; + + public string SelectedProject + { + get { return m_selectedItem.ToString(); } + } + + #region Event handlers + private void btnOk_Click(Object sender, EventArgs e) + { + if (radioRestore.Checked) + { + textBoxProjectName.Text = textBoxProjectName.Text.Trim(); + if (!DoRestore()) + return; + } + else + { + m_selectedItem = (LanguageProjectInfo)listBox.SelectedItem; + } + DialogResult = DialogResult.OK; + + Close(); + } + + private void btnCancel_Click(Object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + + private void ListBox_DoubleClick(object sender, EventArgs e) + { + if (listBox.Items.Count > 0 && listBox.SelectedIndex > -1) { + btnOk.PerformClick(); + } + } + + private void ListBox_SelectedIndexChanged(object sender, EventArgs e) + { + btnOk.Enabled = listBox.SelectedIndex > -1; + } + + private void btnBrowse_Click(object sender, EventArgs e) + { + using (var openDialog = new OpenFileDialog()) + { + openDialog.Filter = "Backup files|*.fwbackup|All files|*.*"; + openDialog.InitialDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "My FieldWorks", "Backups"); + if (openDialog.ShowDialog() == DialogResult.OK) + { + m_restoreFileFullPath = openDialog.FileName; + if (SetupRestore()) + { + labelSelectedBackupFile.Text = openDialog.SafeFileName; + textBoxProjectName.Text = m_restoreSettings.Backup.ProjectName; + textBoxProjectName.Enabled = true; + } + else + { + m_restoreFileFullPath = null; + labelSelectedBackupFile.Text = ""; + textBoxProjectName.Text = ""; + textBoxProjectName.Enabled = false; + } + } + else + { + m_restoreFileFullPath = null; + labelSelectedBackupFile.Text = ""; + textBoxProjectName.Text = ""; + textBoxProjectName.Enabled = false; + } + } + } + + private void radio_CheckedChanged(object sender, EventArgs e) + { + btnOk.Enabled = (radioExisting.Checked && listBox.SelectedIndex > -1) || (radioRestore.Checked && textBoxProjectName.Text.Any()); + + groupBoxExisting.Enabled = radioExisting.Checked; + groupBoxRestore.Enabled = radioRestore.Checked; + } + + private void textBoxProjectName_TextChanged(object sender, EventArgs e) + { + btnOk.Enabled = textBoxProjectName.Text.Trim().Any() && labelSelectedBackupFile.Text.Any(); + } + #endregion + + public ChooseFdoProjectForm(ParatextLexiconPluginFdoUI ui) + { + // This call is required by the Windows Form Designer. + InitializeComponent(); + m_ui = ui; + PopulateLanguageProjectsList(Dns.GetHostName(), true); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Queries a given host for avaiable Projects on a separate thread + /// + /// The host. + /// true if we want to show local fwdata projects + /// ------------------------------------------------------------------------------------ + private void PopulateLanguageProjectsList(string host, bool showLocalProjects) + { + // Need to end the previous project finder if the user clicks another host while + // searching the current host. + ClientServerServices.Current.ForceEndFindProjects(); + + btnOk.Enabled = false; + listBox.Items.Clear(); + listBox.Enabled = true; + + ClientServerServices.Current.BeginFindProjects(host, AddProject, + HandleProjectFindingExceptions, showLocalProjects); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Handles any exceptions thrown in the thread that looks for projects. + /// + /// ------------------------------------------------------------------------------------ + private void HandleProjectFindingExceptions(Exception e) + { + if (InvokeRequired) + { + Invoke((Action)HandleProjectFindingExceptions, e); + return; + } + + if (e is SocketException || e is RemotingException) + { + MessageBox.Show( + ActiveForm, + Strings.ksCouldNotConnectText, + Strings.ksWarningCaption, + MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + else if (e is DirectoryNotFoundException) + { + // this indicates that the project directory does not exist, just ignore + } + else + { + throw e; + } + } + + /// ------------------------------------------------------------------------------------ + /// + /// Adds an entry to the languageProjectsList if it is not there already. + /// + /// ------------------------------------------------------------------------------------ + private void AddProject(string projectFile) + { + if (InvokeRequired) + { + BeginInvoke((Action)AddProject, projectFile); + return; + } + if (IsDisposed) return; + + var languageProjectInfo = new LanguageProjectInfo(projectFile); + + // Show file extensions for duplicate projects. + LanguageProjectInfo existingItem = listBox.Items.Cast().FirstOrDefault(item => item.ToString() == languageProjectInfo.ToString()); + + if (existingItem != null) + { + listBox.Items.Remove(existingItem); + existingItem.ShowExtenstion = true; + listBox.Items.Add(existingItem); + languageProjectInfo.ShowExtenstion = true; + } + + listBox.Items.Add(languageProjectInfo); + } + + private bool SetupRestore() + { + try + { + var backupSettings = new BackupFileSettings(m_restoreFileFullPath); + m_restoreSettings = new RestoreProjectSettings(ParatextLexiconPluginDirectoryFinder.ProjectsDirectory) + { + Backup = backupSettings, + IncludeConfigurationSettings = backupSettings.IncludeConfigurationSettings, + IncludeLinkedFiles = backupSettings.IncludeLinkedFiles, + IncludeSupportingFiles = backupSettings.IncludeSupportingFiles, + IncludeSpellCheckAdditions = backupSettings.IncludeSpellCheckAdditions, + BackupOfExistingProjectRequested = false + }; + } + catch (InvalidBackupFileException ibfe) + { + MessageBox.Show(ibfe.Message, Strings.ksBackupFileProblemCaption, MessageBoxButtons.OK, MessageBoxIcon.Information); + return false; + } + catch + { + MessageBox.Show(Strings.ksBackupFileProblemText, Strings.ksBackupFileProblemCaption, MessageBoxButtons.OK, MessageBoxIcon.Information); + return false; + } + return true; + } + + private bool DoRestore() + { + m_restoreSettings.ProjectName = textBoxProjectName.Text; + + if (m_restoreSettings.ProjectExists) + { + using (var dlg = new ProjectExistsForm(m_restoreSettings.ProjectName)) + { + dlg.StartPosition = FormStartPosition.CenterParent; + DialogResult result = dlg.ShowDialog(); + if (result == DialogResult.Cancel) + { + textBoxProjectName.SelectAll(); + textBoxProjectName.Focus(); + return false; + } + } + } + + try + { + var restoreService = new ProjectRestoreService(m_restoreSettings, m_ui, null, null); + restoreService.RestoreProject(new ParatextLexiconPluginThreadedProgress(m_ui.SynchronizeInvoke)); + + m_selectedItem = new LanguageProjectInfo(m_restoreSettings.FullProjectPath); + } + catch + { + MessageBox.Show(Strings.ksRestoreProblemText); + return false; + } + + return true; + } + + #region LanguageProjectInfo class + /// type that is inserted in the Language Projects Listbox. + internal class LanguageProjectInfo + { + public string FullName { get; private set; } + + public bool ShowExtenstion + { + get { return m_showExtenstion; } + set + { + m_showExtenstion = value; + m_displayName = m_showExtenstion ? Path.GetFileName(FullName) : Path.GetFileNameWithoutExtension(FullName); + } + } + + protected string m_displayName; + + protected bool m_showExtenstion; + + public LanguageProjectInfo(string filename) + { + FullName = filename; + m_displayName = Path.GetFileNameWithoutExtension(filename); + } + + public override string ToString() + { + return m_displayName; + } + } + #endregion + + } +} diff --git a/Src/FwParatextLexiconPlugin/ChooseFdoProjectForm.resx b/Src/FwParatextLexiconPlugin/ChooseFdoProjectForm.resx new file mode 100644 index 0000000000..dc6e40a56b --- /dev/null +++ b/Src/FwParatextLexiconPlugin/ChooseFdoProjectForm.resx @@ -0,0 +1,597 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + Bottom, Right + + + + 2 + + + Fill + + + False + + + + 3, 3 + + + 91, 23 + + + 0 + + + OK + + + btnOk + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + TableLayoutPanel1 + + + 0 + + + Fill + + + 100, 3 + + + 91, 23 + + + 1 + + + Cancel + + + btnCancel + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + TableLayoutPanel1 + + + 1 + + + 219, 341 + + + 1 + + + 194, 29 + + + 0 + + + TableLayoutPanel1 + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 1 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="btnOk" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="btnCancel" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="Percent,50" /></TableLayoutSettings> + + + Top, Bottom, Left, Right + + + 3 + + + Left, Right + + + 290, 7 + + + 91, 23 + + + 0 + + + Browse + + + btnBrowse + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel3 + + + 0 + + + Left, Right + + + True + + + 85, 12 + + + 199, 13 + + + 1 + + + labelSelectedBackupFile + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel3 + + + 1 + + + Left + + + True + + + 3, 49 + + + 72, 13 + + + 3 + + + Project name: + + + label2 + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel3 + + + 2 + + + None + + + False + + + 85, 46 + + + 199, 20 + + + 4 + + + textBoxProjectName + + + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel3 + + + 3 + + + Left + + + True + + + 3, 12 + + + 73, 13 + + + 2 + + + File to restore: + + + label1 + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel3 + + + 4 + + + 3, 16 + + + 2 + + + 384, 75 + + + 1 + + + tableLayoutPanel3 + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + groupBoxRestore + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="btnBrowse" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="labelSelectedBackupFile" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="label2" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="textBoxProjectName" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="label1" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Absolute,82,Percent,100,AutoSize,0" /><Rows Styles="Percent,50,Percent,50" /></TableLayoutSettings> + + + Fill + + + False + + + 23, 235 + + + 390, 94 + + + 3 + + + Or select a project to restore: + + + groupBoxRestore + + + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + TableLayoutPanel2 + + + 1 + + + Fill + + + False + + + 3, 16 + + + 384, 207 + + + 2 + + + listBox + + + System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + groupBoxExisting + + + 0 + + + Top, Bottom, Left, Right + + + 2 + + + Fill + + + 23, 3 + + + 390, 226 + + + 2 + + + Select an existing project: + + + groupBoxExisting + + + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + TableLayoutPanel2 + + + 0 + + + True + + + 0, 0 + + + 14, 13 + + + 4 + + + radioExisting + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + panel1 + + + 0 + + + True + + + 0, 232 + + + 14, 13 + + + 5 + + + radioRestore + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + panel1 + + + 1 + + + Fill + + + 3, 3 + + + 14, 326 + + + 6 + + + panel1 + + + System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + TableLayoutPanel2 + + + 2 + + + 3, 3 + + + 2 + + + 416, 332 + + + 1 + + + TableLayoutPanel2 + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="groupBoxExisting" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="groupBoxRestore" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="panel1" Row="0" RowSpan="2" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Absolute,20,Percent,100" /><Rows Styles="Percent,100,Absolute,100" /></TableLayoutSettings> + + + True + + + 6, 13 + + + 423, 373 + + + CenterParent + + + Select Lexical Project + + + ChooseFdoProjectForm + + + System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Src/FwParatextLexiconPlugin/FdoLanguageText.cs b/Src/FwParatextLexiconPlugin/FdoLanguageText.cs new file mode 100644 index 0000000000..c94b88d1d0 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FdoLanguageText.cs @@ -0,0 +1,31 @@ +using System.Diagnostics; +using Paratext.LexicalContracts; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + internal class FdoLanguageText : LanguageText + { + /// + /// Creates a new LanguageText by wrapping the specified data + /// + public FdoLanguageText(string language, string text) + { + Debug.Assert(language.IsNormalized(), "We expect all strings to be normalized composed"); + Debug.Assert(text.IsNormalized(), "We expect all strings to be normalized composed"); + Language = language; + Text = text; + } + + #region Implementation of LanguageText + /// + /// Language of the text. + /// + public string Language { get; set; } + + /// + /// The actual text. + /// + public string Text { get; set; } + #endregion + } +} diff --git a/Src/FwParatextLexiconPlugin/FdoLexEntryLexeme.cs b/Src/FwParatextLexiconPlugin/FdoLexEntryLexeme.cs new file mode 100644 index 0000000000..569b5ee1c3 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FdoLexEntryLexeme.cs @@ -0,0 +1,422 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using Paratext.LexicalContracts; +using SIL.CoreImpl; +using SIL.FieldWorks.Common.COMInterfaces; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.FDO.DomainServices; +using SIL.FieldWorks.FDO.Infrastructure; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + #region FdoLexEntryLexeme class + /// + /// + [SuppressMessage("Gendarme.Rules.Design", "TypesWithDisposableFieldsShouldBeDisposableRule", + Justification="m_lexicon is a reference")] + internal class FdoLexEntryLexeme : Lexeme + { + private readonly LexemeKey m_key; + private readonly FdoLexicon m_lexicon; + + public FdoLexEntryLexeme(FdoLexicon lexicon, LexemeKey key) + { + m_lexicon = lexicon; + m_key = key; + } + + public LexemeKey Key + { + get { return m_key; } + } + + #region Lexeme Members + + public string Id + { + get { return m_key.Id; } + } + + public LexemeType Type + { + get { return m_key.Type; } + } + + public string LexicalForm + { + get { return m_key.LexicalForm; } + } + + /// + /// Gets a string that is suitable for display which may contain morphological abbreviations + /// + public string DisplayString + { + get + { + using (m_lexicon.ActivationContext.Activate()) + { + ILexEntry entry; + if (!m_lexicon.TryGetEntry(m_key, out entry)) + return null; + + return StringServices.CitationFormWithAffixTypeStaticForWs(entry, m_lexicon.DefaultVernWs); + } + } + } + + public string CitationForm + { + get + { + using (m_lexicon.ActivationContext.Activate()) + { + ILexEntry entry; + if (!m_lexicon.TryGetEntry(m_key, out entry)) + return null; + + ITsString tss = entry.CitationForm.StringOrNull(m_lexicon.DefaultVernWs); + return tss == null ? null : tss.Text; + } + } + } + + public int HomographNumber + { + get + { + using (m_lexicon.ActivationContext.Activate()) + { + ILexEntry entry; + if (!m_lexicon.TryGetEntry(m_key, out entry)) + return 0; + + return entry.HomographNumber; + } + } + } + + public IEnumerable Senses + { + get + { + using (m_lexicon.ActivationContext.Activate()) + { + ILexEntry entry; + if (!m_lexicon.TryGetEntry(m_key, out entry)) + return Enumerable.Empty(); + + if (entry.AllSenses.Count == 1 && entry.SensesOS[0].Gloss.StringCount == 0) + return Enumerable.Empty(); + + return entry.AllSenses.Select(s => new LexSenseLexiconSense(m_lexicon, m_key, s)).ToArray(); + } + } + } + + public IEnumerable LexicalRelations + { + get + { + using (m_lexicon.ActivationContext.Activate()) + { + ILexEntry entry; + if (!m_lexicon.TryGetEntry(m_key, out entry)) + return Enumerable.Empty(); + + var relations = new List(); + foreach (ILexReference lexRef in entry.LexEntryReferences.Union(entry.AllSenses.SelectMany(s => s.LexSenseReferences))) + { + string name = GetLexReferenceName(entry, lexRef.OwnerOfClass()).Normalize(); + foreach (ICmObject obj in lexRef.TargetsRS) + { + ILexEntry otherEntry = null; + switch (obj.ClassID) + { + case LexEntryTags.kClassId: + otherEntry = (ILexEntry) obj; + break; + case LexSenseTags.kClassId: + otherEntry = obj.OwnerOfClass(); + break; + } + if (otherEntry != null && otherEntry != entry) + relations.Add(new FdoLexicalRelation(m_lexicon.GetEntryLexeme(otherEntry), name)); + } + } + + return relations; + } + } + } + + public IEnumerable AlternateForms + { + get + { + using (m_lexicon.ActivationContext.Activate()) + { + ILexEntry entry; + if (!m_lexicon.TryGetEntry(m_key, out entry)) + return Enumerable.Empty(); + + var forms = new List(); + foreach (IMoForm form in entry.AlternateFormsOS) + { + ITsString tss = form.Form.StringOrNull(m_lexicon.DefaultVernWs); + if (tss != null) + forms.Add(tss.Text.Normalize()); + } + + return forms; + } + } + } + + private string GetLexReferenceName(ILexEntry lexEntry, ILexRefType lexRefType) + { + // The name we want to use for our lex reference is either the name or the reverse name + // (depending on the direction of the relationship, if relevant) of the owning lex ref type. + ITsString lexReferenceName = lexRefType.Name.BestVernacularAnalysisAlternative; + + if (lexRefType.MappingType == (int)MappingTypes.kmtEntryAsymmetricPair || + lexRefType.MappingType == (int)MappingTypes.kmtEntryOrSenseAsymmetricPair || + lexRefType.MappingType == (int)MappingTypes.kmtSenseAsymmetricPair || + lexRefType.MappingType == (int)MappingTypes.kmtEntryTree || + lexRefType.MappingType == (int)MappingTypes.kmtEntryOrSenseTree || + lexRefType.MappingType == (int)MappingTypes.kmtSenseTree) + { + if (lexEntry.OwnOrd == 0 && lexRefType.Name != null) // the original code had a check for name length as well. + lexReferenceName = lexRefType.ReverseName.BestAnalysisAlternative; + } + + return lexReferenceName.Text; + } + + public LexiconSense AddSense() + { + LexiconSense sense = null; + bool lexemeAdded = false; + m_lexicon.UpdatingEntries = true; + try + { + using (m_lexicon.ActivationContext.Activate()) + { + NonUndoableUnitOfWorkHelper.Do(m_lexicon.Cache.ActionHandlerAccessor, () => + { + ILexEntry entry; + if (!m_lexicon.TryGetEntry(m_key, out entry)) + { + entry = m_lexicon.CreateEntry(m_key); + lexemeAdded = true; + } + + if (entry.AllSenses.Count == 1 && entry.SensesOS[0].Gloss.StringCount == 0) + { + // An empty sense exists (probably was created during a call to AddLexeme) + sense = new LexSenseLexiconSense(m_lexicon, m_key, entry.SensesOS[0]); + } + else + { + ILexSense newSense = m_lexicon.Cache.ServiceLocator.GetInstance().Create( + entry, new SandboxGenericMSA(), (string)null); + sense = new LexSenseLexiconSense(m_lexicon, m_key, newSense); + } + }); + } + } + finally + { + m_lexicon.UpdatingEntries = false; + } + if (lexemeAdded) + m_lexicon.OnLexemeAdded(this); + m_lexicon.OnLexiconSenseAdded(this, sense); + return sense; + } + + public void RemoveSense(LexiconSense sense) + { + using (m_lexicon.ActivationContext.Activate()) + { + ILexEntry entry; + if (!m_lexicon.TryGetEntry(m_key, out entry)) + return; + + NonUndoableUnitOfWorkHelper.Do(m_lexicon.Cache.ActionHandlerAccessor, () => + { + var leSense = (LexSenseLexiconSense)sense; + if (entry.AllSenses.Count == 1) + { + foreach (int ws in leSense.Sense.Gloss.AvailableWritingSystemIds) + leSense.Sense.Gloss.set_String(ws, (ITsString) null); + } + else + { + leSense.Sense.Delete(); + } + }); + } + } + + #endregion + + public override string ToString() + { + return DisplayString; + } + + public override bool Equals(object obj) + { + var other = obj as FdoLexEntryLexeme; + return other != null && m_key.Equals(other.m_key); + } + + public override int GetHashCode() + { + return m_key.GetHashCode(); + } + + [SuppressMessage("Gendarme.Rules.Design", "TypesWithDisposableFieldsShouldBeDisposableRule", + Justification="m_lexicon is a reference")] + private class LexSenseLexiconSense : LexiconSense + { + private readonly FdoLexicon m_lexicon; + private readonly LexemeKey m_lexemeKey; + private readonly ILexSense m_lexSense; + + public LexSenseLexiconSense(FdoLexicon lexicon, LexemeKey lexemeKey, ILexSense lexSense) + { + m_lexicon = lexicon; + m_lexemeKey = lexemeKey; + m_lexSense = lexSense; + } + + internal ILexSense Sense + { + get { return m_lexSense; } + } + + public string Id + { + get + { + using (m_lexicon.ActivationContext.Activate()) + return m_lexSense.Guid.ToString(); + } + } + + public string SenseNumber + { + get + { + using (m_lexicon.ActivationContext.Activate()) + return m_lexSense.LexSenseOutline.Text; + } + } + + public string Category + { + get + { + using (m_lexicon.ActivationContext.Activate()) + return m_lexSense.MorphoSyntaxAnalysisRA == null ? "" : m_lexSense.MorphoSyntaxAnalysisRA.PartOfSpeechForWsTSS(m_lexicon.Cache.DefaultAnalWs).Text; + } + } + + public IEnumerable Definitions + { + get + { + using (m_lexicon.ActivationContext.Activate()) + { + IMultiString definition = m_lexSense.Definition; + var defs = new List(); + foreach (IWritingSystem ws in m_lexicon.Cache.ServiceLocator.WritingSystems.CurrentAnalysisWritingSystems) + { + ITsString tss = definition.StringOrNull(ws.Handle); + if (tss != null) + defs.Add(new FdoLanguageText(ws.Id, tss.Text.Normalize())); + } + return defs; + } + } + } + + public IEnumerable Glosses + { + get + { + using (m_lexicon.ActivationContext.Activate()) + { + IMultiUnicode gloss = m_lexSense.Gloss; + var glosses = new List(); + foreach (IWritingSystem ws in m_lexicon.Cache.ServiceLocator.WritingSystems.CurrentAnalysisWritingSystems) + { + ITsString tss = gloss.StringOrNull(ws.Handle); + if (tss != null) + glosses.Add(new FdoLanguageText(ws.Id, tss.Text.Normalize())); + } + return glosses; + } + } + } + + public LanguageText AddGloss(string language, string text) + { + using (m_lexicon.ActivationContext.Activate()) + { + LanguageText lexGloss = null; + NonUndoableUnitOfWorkHelper.Do(m_lexSense.Cache.ActionHandlerAccessor, () => + { + IWritingSystem ws; + if (!m_lexicon.Cache.ServiceLocator.WritingSystemManager.TryGet(language, out ws)) + throw new ArgumentException("The specified language is unrecognized.", "language"); + m_lexSense.Gloss.set_String(ws.Handle, text.Normalize(NormalizationForm.FormD)); + lexGloss = new FdoLanguageText(language, text); + }); + m_lexicon.OnLexiconGlossAdded(new FdoLexEntryLexeme(m_lexicon, m_lexemeKey), this, lexGloss); + return lexGloss; + } + } + + public void RemoveGloss(string language) + { + using (m_lexicon.ActivationContext.Activate()) + { + NonUndoableUnitOfWorkHelper.Do(m_lexSense.Cache.ActionHandlerAccessor, () => + { + IWritingSystem ws; + if (!m_lexicon.Cache.ServiceLocator.WritingSystemManager.TryGet(language, out ws)) + throw new ArgumentException("The specified language is unrecognized.", "language"); + m_lexSense.Gloss.set_String(ws.Handle, (ITsString) null); + }); + } + } + + public IEnumerable SemanticDomains + { + get + { + using (m_lexicon.ActivationContext.Activate()) + return m_lexSense.SemanticDomainsRC.Select(sd => new FdoSemanticDomain(sd.ShortName.Normalize())).ToArray(); + } + } + + public override bool Equals(object obj) + { + var other = obj as LexSenseLexiconSense; + return other != null && m_lexSense == other.m_lexSense; + } + + public override int GetHashCode() + { + return m_lexSense.GetHashCode(); + } + } + } + #endregion +} diff --git a/Src/FwParatextLexiconPlugin/FdoLexemeAddedEventArgs.cs b/Src/FwParatextLexiconPlugin/FdoLexemeAddedEventArgs.cs new file mode 100644 index 0000000000..f103521d9e --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FdoLexemeAddedEventArgs.cs @@ -0,0 +1,20 @@ +using System; +using Paratext.LexicalContracts; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + internal class FdoLexemeAddedEventArgs : EventArgs, LexemeAddedEventArgs + { + private readonly Lexeme m_lexeme; + + public FdoLexemeAddedEventArgs(Lexeme lexeme) + { + m_lexeme = lexeme; + } + + public Lexeme Lexeme + { + get { return m_lexeme; } + } + } +} diff --git a/Src/FwParatextLexiconPlugin/FdoLexicalRelation.cs b/Src/FwParatextLexiconPlugin/FdoLexicalRelation.cs new file mode 100644 index 0000000000..64c8ff582a --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FdoLexicalRelation.cs @@ -0,0 +1,26 @@ +using Paratext.LexicalContracts; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + internal class FdoLexicalRelation : LexicalRelation + { + private readonly Lexeme m_lexeme; + private readonly string m_name; + + public FdoLexicalRelation(Lexeme lexeme, string name) + { + m_lexeme = lexeme; + m_name = name; + } + + public Lexeme Lexeme + { + get { return m_lexeme; } + } + + public string Name + { + get { return m_name; } + } + } +} diff --git a/Src/FwParatextLexiconPlugin/FdoLexicon.cs b/Src/FwParatextLexiconPlugin/FdoLexicon.cs new file mode 100644 index 0000000000..37fa58c3b9 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FdoLexicon.cs @@ -0,0 +1,873 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Web; +using Paratext.LexicalContracts; +using SIL.CoreImpl; +using SIL.FieldWorks.Common.COMInterfaces; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.FDO.DomainImpl; +using SIL.FieldWorks.FDO.DomainServices; +using SIL.FieldWorks.FDO.Infrastructure; +using SIL.FieldWorks.WordWorks.Parser; +using SIL.Machine.Morphology; +using SIL.Utils; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + internal class FdoLexicon : FwDisposableBase, Lexicon, WordAnalyses, IVwNotifyChange + { + private IParser m_parser; + private readonly FdoCache m_cache; + private readonly string m_scrTextName; + private readonly ConditionalWeakTable m_homographNumbers; + private Dictionary> m_entryIndex; + private readonly LexEntryComparer m_entryComparer; + private readonly int m_defaultVernWs; + private PoorMansStemmer m_stemmer; + private readonly ActivationContextHelper m_activationContext; + + internal FdoLexicon(string scrTextName, FdoCache cache, int defaultVernWs, ActivationContextHelper activationContext) + { + m_scrTextName = scrTextName; + m_cache = cache; + m_homographNumbers = new ConditionalWeakTable(); + m_cache.DomainDataByFlid.AddNotification(this); + m_entryComparer = new LexEntryComparer(this); + m_defaultVernWs = defaultVernWs; + m_activationContext = activationContext; + } + + internal FdoCache Cache + { + get { return m_cache; } + } + + internal ActivationContextHelper ActivationContext + { + get { return m_activationContext; } + } + + internal string ScrTextName + { + get { return m_scrTextName; } + } + + internal bool UpdatingEntries { get; set; } + + internal int DefaultVernWs + { + get { return m_defaultVernWs; } + } + + protected override void DisposeManagedResources() + { + if (m_parser != null) + { + m_parser.Dispose(); + m_parser = null; + } + } + + #region Lexicon implementation + + public event LexemeAddedEventHandler LexemeAdded; + + public event LexiconSenseAddedEventHandler LexiconSenseAdded; + + public event LexiconGlossAddedEventHandler LexiconGlossAdded; + + public bool RequiresLanguageId + { + get { return true; } + } + + public IEnumerable Lexemes + { + get + { + using (m_activationContext.Activate()) + { + var lexemes = new List(); + // Get all of the lexical entries in the database + foreach (ILexEntry entry in m_cache.ServiceLocator.GetInstance().AllInstances().Where(e => e.PrimaryMorphType != null)) + lexemes.Add(GetEntryLexeme(entry)); + + // Get all the wordforms in the database + foreach (IWfiWordform wordform in m_cache.ServiceLocator.GetInstance().AllInstances()) + { + string wordFormWs = wordform.Form.get_String(m_defaultVernWs).Text; + if (wordFormWs != null) + lexemes.Add(new FdoWordformLexeme(this, new LexemeKey(LexemeType.Word, wordFormWs.Normalize()))); + } + return lexemes; + } + } + } + + public Lexeme this[string id] + { + get + { + using (m_activationContext.Activate()) + { + Lexeme lexeme; + if (TryGetLexeme(new LexemeKey(id), out lexeme)) + return lexeme; + return null; + } + } + } + + private bool TryGetLexeme(LexemeKey key, out Lexeme lexeme) + { + if (key.Type == LexemeType.Word) + { + IWfiWordform wf; + if (TryGetWordform(key.LexicalForm, out wf)) + { + lexeme = new FdoWordformLexeme(this, key); + return true; + } + } + else + { + ILexEntry entry; + if (TryGetEntry(key, out entry)) + { + lexeme = new FdoLexEntryLexeme(this, key); + return true; + } + } + + lexeme = null; + return false; + } + + public Lexeme FindOrCreateLexeme(LexemeType type, string lexicalForm) + { + using (m_activationContext.Activate()) + { + Lexeme lexeme; + if (!TryGetLexeme(new LexemeKey(type, lexicalForm), out lexeme)) + lexeme = CreateLexeme(type, lexicalForm); + return lexeme; + } + } + + public Lexeme CreateLexeme(LexemeType type, string lexicalForm) + { + using (m_activationContext.Activate()) + { + if (type == LexemeType.Word) + return new FdoWordformLexeme(this, new LexemeKey(type, lexicalForm)); + + int num = 1; + foreach (ILexEntry entry in GetMatchingEntries(type, lexicalForm)) + { + if (m_homographNumbers.GetOrCreateValue(entry).Number != num) + break; + num++; + } + + return new FdoLexEntryLexeme(this, new LexemeKey(type, lexicalForm, num)); + } + } + + public void RemoveLexeme(Lexeme lexeme) + { + using (m_activationContext.Activate()) + { + if (lexeme.Type == LexemeType.Word) + { + IWfiWordform wordform; + if (TryGetWordform(lexeme.LexicalForm, out wordform)) + NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, () => wordform.Delete()); + } + else + { + var entryLexeme = (FdoLexEntryLexeme)lexeme; + ILexEntry entry; + if (TryGetEntry(entryLexeme.Key, out entry)) + { + var key = new LexemeKey(lexeme.Type, lexeme.LexicalForm); + SortedSet entries = m_entryIndex[key]; + entries.Remove(entry); + UpdatingEntries = true; + try + { + NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, () => entry.Delete()); + } + finally + { + UpdatingEntries = false; + } + } + } + } + } + + public void AddLexeme(Lexeme lexeme) + { + if (this[lexeme.Id] != null) + throw new ArgumentException("The specified lexeme has already been added.", "lexeme"); + + using (m_activationContext.Activate()) + { + if (lexeme.Type == LexemeType.Word) + { + NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, () => CreateWordform(lexeme.LexicalForm)); + } + else + { + UpdatingEntries = true; + try + { + var entryLexeme = (FdoLexEntryLexeme) lexeme; + NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, () => CreateEntry(entryLexeme.Key)); + } + finally + { + UpdatingEntries = false; + } + } + } + OnLexemeAdded(lexeme); + } + + public void Save() + { + using (m_activationContext.Activate()) + { + m_cache.ServiceLocator.GetInstance().Save(); + } + } + + public Lexeme FindClosestMatchingLexeme(string wordForm) + { + using (m_activationContext.Activate()) + { + wordForm = wordForm.Normalize(NormalizationForm.FormD); + ITsString tss = TsStringUtils.MakeTss(wordForm, DefaultVernWs); + ILexEntry matchingEntry = m_cache.ServiceLocator.GetInstance().FindEntryForWordform(m_cache, tss); + + if (matchingEntry == null) + matchingEntry = GetMatchingEntryFromParser(wordForm); + + if (matchingEntry == null) + matchingEntry = GetMatchingEntryFromStemmer(wordForm); + + if (matchingEntry == null) + return null; + + return GetEntryLexeme(matchingEntry); + } + } + + public IEnumerable FindMatchingLexemes(string wordForm) + { + using (m_activationContext.Activate()) + { + bool duplicates = false; + return m_cache.ServiceLocator.GetInstance() + .FindEntriesForWordform(m_cache, m_cache.TsStrFactory.MakeString(wordForm.Normalize(NormalizationForm.FormD), DefaultVernWs), null, ref duplicates).Select(GetEntryLexeme); + } + } + + public bool CanOpenInLexicon + { + get { return ParatextLexiconPluginDirectoryFinder.IsFieldWorksInstalled; } + } + + public void OpenInLexicon(Lexeme lexeme) + { + string guid = null, toolName; + using (m_activationContext.Activate()) + { + if (lexeme.Type == LexemeType.Word) + { + toolName = "Analyses"; + IWfiWordform wf; + if (TryGetWordform(lexeme.LexicalForm, out wf)) + guid = wf.Guid.ToString(); + } + else + { + toolName = "lexiconEdit"; + var entryLexeme = (FdoLexEntryLexeme)lexeme; + ILexEntry entry; + if (TryGetEntry(entryLexeme.Key, out entry)) + guid = entry.Guid.ToString(); + } + } + if (guid != null) + { + string url = string.Format("silfw://localhost/link?app=flex&database={0}&tool={1}&guid={2}", + HttpUtility.UrlEncode(m_cache.ProjectId.Name), HttpUtility.UrlEncode(toolName), HttpUtility.UrlEncode(guid)); + using (Process.Start(url)) {} + } + } + + public IEnumerable ValidLanguages + { + get + { + using (m_activationContext.Activate()) + return m_cache.ServiceLocator.WritingSystems.CurrentAnalysisWritingSystems.Select(writingSystem => writingSystem.Id); + } + } + #endregion + + #region WordAnalyses implementation + public WordAnalysis CreateWordAnalysis(string word, IEnumerable lexemes) + { + return new FdoWordAnalysis(word, lexemes); + } + + public IEnumerable GetWordAnalyses(string word) + { + using (m_activationContext.Activate()) + { + IWfiWordform wordform; + if (!TryGetWordform(word, out wordform)) + return Enumerable.Empty(); + + var analyses = new HashSet(); + foreach (IWfiAnalysis analysis in wordform.AnalysesOC.Where(a => a.MorphBundlesOS.Count > 0 && a.ApprovalStatusIcon == (int) Opinions.approves)) + { + WordAnalysis lexemes; + if (GetWordAnalysis(analysis, out lexemes)) + analyses.Add(lexemes); + } + return analyses; + } + } + + public void AddWordAnalysis(WordAnalysis lexemes) + { + using (m_activationContext.Activate()) + { + NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, () => + { + IWfiWordform wordform; + if (!TryGetWordform(lexemes.Word, out wordform)) + { + wordform = m_cache.ServiceLocator.GetInstance().Create( + m_cache.TsStrFactory.MakeString(lexemes.Word.Normalize(NormalizationForm.FormD), DefaultVernWs)); + } + + IWfiAnalysis analysis = m_cache.ServiceLocator.GetInstance().Create(); + wordform.AnalysesOC.Add(analysis); + analysis.ApprovalStatusIcon = (int) Opinions.approves; + + foreach (Lexeme lexeme in lexemes) + { + var entryLexeme = (FdoLexEntryLexeme) lexeme; + ILexEntry entry; + if (TryGetEntry(entryLexeme.Key, out entry)) + { + IWfiMorphBundle mb = m_cache.ServiceLocator.GetInstance().Create(); + analysis.MorphBundlesOS.Add(mb); + mb.MorphRA = entry.LexemeFormOA; + mb.SenseRA = entry.SensesOS[0]; + mb.MsaRA = entry.SensesOS[0].MorphoSyntaxAnalysisRA; + } + } + }); + } + } + + public void RemoveWordAnalysis(WordAnalysis lexemes) + { + using (m_activationContext.Activate()) + { + IWfiWordform wordform; + if (!TryGetWordform(lexemes.Word, out wordform)) + return; + + foreach (IWfiAnalysis analysis in wordform.AnalysesOC.Where(a => a.MorphBundlesOS.Count > 0 && a.ApprovalStatusIcon == (int) Opinions.approves)) + { + bool match = true; + int i = 0; + foreach (Lexeme lexeme in lexemes) + { + if (i == analysis.MorphBundlesOS.Count || analysis.MorphBundlesOS[i].MorphRA == null) + { + match = false; + break; + } + + var entry = analysis.MorphBundlesOS[i].MorphRA.OwnerOfClass(); + if (!GetEntryLexeme(entry).Equals(lexeme)) + { + match = false; + break; + } + i++; + } + if (match && !analysis.OccurrencesInTexts.Any()) + { + NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, () => wordform.AnalysesOC.Remove(analysis)); + break; + } + } + } + } + + public IEnumerable WordAnalyses + { + get + { + using (m_activationContext.Activate()) + { + var analyses = new HashSet(); + foreach (IWfiAnalysis analysis in m_cache.ServiceLocator.GetInstance().AllInstances().Where(a => a.MorphBundlesOS.Count > 0 && a.ApprovalStatusIcon == (int) Opinions.approves)) + { + WordAnalysis lexemes; + string wordFormWs = analysis.Wordform.Form.get_String(m_defaultVernWs).Text; + if (wordFormWs != null && GetWordAnalysis(analysis, out lexemes)) + analyses.Add(lexemes); + } + return analyses; + } + } + } + #endregion + + private bool GetWordAnalysis(IWfiAnalysis analysis, out WordAnalysis lexemes) + { + var lexemeArray = new Lexeme[analysis.MorphBundlesOS.Count]; + for (int i = 0; i < analysis.MorphBundlesOS.Count; i++) + { + IWfiMorphBundle mb = analysis.MorphBundlesOS[i]; + if (mb.MorphRA == null) + { + lexemes = null; + return false; + } + var entry = mb.MorphRA.OwnerOfClass(); + if (entry.LexemeFormOA != mb.MorphRA) + { + lexemes = null; + return false; + } + lexemeArray[i] = GetEntryLexeme(entry); + } + + lexemes = new FdoWordAnalysis(analysis.Wordform.Form.get_String(DefaultVernWs).Text.Normalize(), lexemeArray); + return true; + } + + private ILexEntry GetMatchingEntryFromParser(string wordForm) + { + ILexEntry matchingEntry = null; + if (m_parser == null) + InstantiateParser(); + + if (m_parser == null) + return null; + + if (!m_parser.IsUpToDate()) + { + m_parser.Update(); + //ProgressUtils.Execute(Localizer.Str("Updating Data for Parser"), CancelModes.NonCancelable, () => m_parser.Update() ); + } + + ParseResult parseResult = m_parser.ParseWord(wordForm); + if (parseResult != null && parseResult.Analyses != null && parseResult.Analyses.Any()) + { + foreach (ParseMorph morph in parseResult.Analyses.First().Morphs) + { + if (morph.Form is IMoStemAllomorph) + { + matchingEntry = morph.Form.OwnerOfClass(); + break; + } + } + } + return matchingEntry; + } + + private void InstantiateParser() + { + string parserDataDir = Path.Combine(ParatextLexiconPluginDirectoryFinder.CodeDirectory, "Language Explorer"); + switch (m_cache.LanguageProject.MorphologicalDataOA.ActiveParser) + { + case "XAmple": + m_parser = new XAmpleParser(m_cache, parserDataDir); + break; + case "HC": + m_parser = new HCParser(m_cache, parserDataDir); + break; + default: + throw new InvalidOperationException("The language project is set to use an unrecognized parser."); + } + } + + private ILexEntry GetMatchingEntryFromStemmer(string wordForm) + { + var repo = m_cache.ServiceLocator.GetInstance(); + if (m_stemmer == null) + { + m_stemmer = new PoorMansStemmer(s => s) {NormalizeScores = true, WeightScores = false, Threshold = 0.12}; + var forms = new HashSet(); + foreach (ILexEntry entry in repo.AllInstances()) + { + if (!(entry.LexemeFormOA is IMoStemAllomorph)) + continue; + + forms.UnionWith(GetForms(entry)); + } + m_stemmer.Train(forms); + } + + int bestLen = 0; + double bestScore = 0; + ILexEntry bestMatch = null; + foreach (ILexEntry entry in repo.AllInstances()) + { + if (!(entry.LexemeFormOA is IMoStemAllomorph)) + continue; + + foreach (string form in GetForms(entry)) + { + double formScore; + if (m_stemmer.HaveSameStem(wordForm, form, out formScore)) + { + if (formScore > bestScore) + { + bestMatch = entry; + bestScore = formScore; + bestLen = LongestCommonSubstringLength(wordForm, form); + } + else if (Math.Abs(formScore - bestScore) < double.Epsilon) + { + int len = LongestCommonSubstringLength(wordForm, form); + if (len > bestLen) + { + bestMatch = entry; + bestScore = formScore; + bestLen = len; + } + } + } + } + } + return bestMatch; + } + + private IEnumerable GetForms(ILexEntry entry) + { + ITsString citationFormTss = entry.CitationForm.StringOrNull(m_defaultVernWs); + if (citationFormTss != null) + yield return citationFormTss.Text; + + ITsString lexemeFormTss = entry.LexemeFormOA.Form.StringOrNull(m_defaultVernWs); + if (lexemeFormTss != null) + yield return lexemeFormTss.Text; + } + + private static int LongestCommonSubstringLength(string str1, string str2) + { + if (String.IsNullOrEmpty(str1) || String.IsNullOrEmpty(str2)) + return 0; + + var num = new int[str1.Length, str2.Length]; + int maxlen = 0; + + for (int i = 0; i < str1.Length; i++) + { + for (int j = 0; j < str2.Length; j++) + { + if (str1[i] != str2[j]) + { + num[i, j] = 0; + } + else + { + if ((i == 0) || (j == 0)) + num[i, j] = 1; + else + num[i, j] = 1 + num[i - 1, j - 1]; + + if (num[i, j] > maxlen) + maxlen = num[i, j]; + } + } + } + return maxlen; + } + + private IEnumerable GetMatchingEntries(LexemeType type, string lexicalForm) + { + CreateEntryIndexIfNeeded(); + SortedSet entries; + if (m_entryIndex.TryGetValue(new LexemeKey(type, lexicalForm), out entries)) + return entries; + return Enumerable.Empty(); + } + + private void CreateEntryIndexIfNeeded() + { + if (m_entryIndex != null) + return; + + m_entryIndex = new Dictionary>(); + foreach (ILexEntry entry in m_cache.ServiceLocator.GetInstance().AllInstances()) + { + LexemeType type = GetLexemeTypeForMorphType(entry.PrimaryMorphType); + string form = entry.LexemeFormOA.Form.VernacularDefaultWritingSystem.Text.Normalize(); + var key = new LexemeKey(type, form); + + SortedSet entries; + if (!m_entryIndex.TryGetValue(key, out entries)) + { + entries = new SortedSet(m_entryComparer); + m_entryIndex[key] = entries; + } + + HomographNumber hn = m_homographNumbers.GetOrCreateValue(entry); + if (hn.Number == 0) + { + int num = 1; + foreach (ILexEntry e in entries) + { + if (m_homographNumbers.GetOrCreateValue(e).Number != num) + break; + num++; + } + hn.Number = num; + } + + entries.Add(entry); + } + } + + internal bool TryGetWordform(string lexicalForm, out IWfiWordform wordform) + { + return m_cache.ServiceLocator.GetInstance().TryGetObject( + TsStringUtils.MakeTss(lexicalForm.Normalize(NormalizationForm.FormD), DefaultVernWs), true, out wordform); + } + + internal IWfiWordform CreateWordform(string lexicalForm) + { + ITsString tss = m_cache.TsStrFactory.MakeString(lexicalForm.Normalize(NormalizationForm.FormD), DefaultVernWs); + IWfiWordform wordform = m_cache.ServiceLocator.GetInstance().Create(tss); + return wordform; + } + + internal bool TryGetEntry(LexemeKey key, out ILexEntry entry) + { + entry = GetMatchingEntries(key.Type, key.LexicalForm).FirstOrDefault(e => m_homographNumbers.GetOrCreateValue(e).Number == key.Homograph); + return entry != null; + } + + internal ILexEntry CreateEntry(LexemeKey key) + { + CreateEntryIndexIfNeeded(); + + ITsString tss = m_cache.TsStrFactory.MakeString(key.LexicalForm.Normalize(NormalizationForm.FormD), DefaultVernWs); + var msa = new SandboxGenericMSA {MsaType = (key.Type == LexemeType.Stem) ? MsaType.kStem : MsaType.kUnclassified}; + ILexEntry entry = m_cache.ServiceLocator.GetInstance().Create(GetMorphTypeForLexemeType(key.Type), tss, (ITsString) null, msa); + m_homographNumbers.GetOrCreateValue(entry).Number = key.Homograph; + + var homographKey = new LexemeKey(key.Type, key.LexicalForm); + SortedSet entries; + if (!m_entryIndex.TryGetValue(homographKey, out entries)) + { + entries = new SortedSet(m_entryComparer); + m_entryIndex[homographKey] = entries; + } + entries.Add(entry); + + return entry; + } + + internal FdoLexEntryLexeme GetEntryLexeme(ILexEntry entry) + { + CreateEntryIndexIfNeeded(); + LexemeType type = GetLexemeTypeForMorphType(entry.PrimaryMorphType); + HomographNumber hn = m_homographNumbers.GetOrCreateValue(entry); + return new FdoLexEntryLexeme(this, new LexemeKey(type, entry.LexemeFormOA.Form.VernacularDefaultWritingSystem.Text.Normalize(), hn.Number)); + } + + internal void OnLexemeAdded(Lexeme lexeme) + { + if (LexemeAdded != null) + LexemeAdded(this, new FdoLexemeAddedEventArgs(lexeme)); + } + + internal void OnLexiconSenseAdded(Lexeme lexeme, LexiconSense sense) + { + if (LexiconSenseAdded != null) + LexiconSenseAdded(this, new FdoLexiconSenseAddedEventArgs(lexeme, sense)); + } + + internal void OnLexiconGlossAdded(Lexeme lexeme, LexiconSense sense, LanguageText gloss) + { + if (LexiconGlossAdded != null) + LexiconGlossAdded(this, new FdoLexiconGlossAddedEventArgs(lexeme, sense, gloss)); + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the lexeme type that most closely represents the specified morph type. + /// + /// This method attempts to do it's best to get the correct lexeme type. + /// However, the FW database contains many more morph types then can be represented with + /// the few lexeme types. This creates some ambiguous mappings which are commented + /// inside this method body. + /// ------------------------------------------------------------------------------------ + private static LexemeType GetLexemeTypeForMorphType(IMoMorphType type) + { + switch (type.Guid.ToString()) + { + case MoMorphTypeTags.kMorphCircumfix: + case MoMorphTypeTags.kMorphInfix: + case MoMorphTypeTags.kMorphInfixingInterfix: + case MoMorphTypeTags.kMorphSimulfix: + case MoMorphTypeTags.kMorphSuprafix: + case MoMorphTypeTags.kMorphClitic: + case MoMorphTypeTags.kMorphProclitic: + // These don't map neatly to a lexeme type, so we just return prefix + return LexemeType.Prefix; + + case MoMorphTypeTags.kMorphEnclitic: + // This one also isn't a great match, but there is no better choice + return LexemeType.Suffix; + + case MoMorphTypeTags.kMorphPrefix: + case MoMorphTypeTags.kMorphPrefixingInterfix: + return LexemeType.Prefix; + + case MoMorphTypeTags.kMorphSuffix: + case MoMorphTypeTags.kMorphSuffixingInterfix: + return LexemeType.Suffix; + + case MoMorphTypeTags.kMorphPhrase: + case MoMorphTypeTags.kMorphDiscontiguousPhrase: + return LexemeType.Phrase; + + case MoMorphTypeTags.kMorphStem: + case MoMorphTypeTags.kMorphRoot: + case MoMorphTypeTags.kMorphBoundRoot: + case MoMorphTypeTags.kMorphBoundStem: + case MoMorphTypeTags.kMorphParticle: + return LexemeType.Stem; + } + + // Shouldn't ever get here, but since we don't know what type it is just return + // a random default and hope for the best. + return LexemeType.Stem; + } + + /// ------------------------------------------------------------------------------------ + /// + /// Gets the morph type for the specified lexeme type. + /// + /// ------------------------------------------------------------------------------------ + private IMoMorphType GetMorphTypeForLexemeType(LexemeType type) + { + if (type == LexemeType.Word || type == LexemeType.Lemma) + throw new ArgumentException("Morph type can never be of the specified lexeme type"); + + var repo = m_cache.ServiceLocator.GetInstance(); + switch (type) + { + case LexemeType.Prefix: return repo.GetObject(MoMorphTypeTags.kguidMorphPrefix); + case LexemeType.Suffix: return repo.GetObject(MoMorphTypeTags.kguidMorphSuffix); + case LexemeType.Phrase: return repo.GetObject(MoMorphTypeTags.kguidMorphPhrase); + case LexemeType.Stem: return repo.GetObject(MoMorphTypeTags.kguidMorphStem); + } + return null; + } + + void IVwNotifyChange.PropChanged(int hvo, int tag, int ivMin, int cvIns, int cvDel) + { + ICmObject obj = m_cache.ServiceLocator.GetObject(hvo); + switch (obj.ClassID) + { + case LexDbTags.kClassId: + if (tag == m_cache.ServiceLocator.GetInstance().LexDbEntries) + { + if (!UpdatingEntries) + m_entryIndex = null; + m_stemmer = null; + } + break; + + case MoStemAllomorphTags.kClassId: + if (tag == MoFormTags.kflidForm) + { + if (!UpdatingEntries && obj.OwningFlid == LexEntryTags.kflidLexemeForm) + m_entryIndex = null; + m_stemmer = null; + } + break; + + case MoAffixAllomorphTags.kClassId: + if (!UpdatingEntries && obj.OwningFlid == LexEntryTags.kflidLexemeForm && tag == MoFormTags.kflidForm) + m_entryIndex = null; + break; + + case LexEntryTags.kClassId: + var entry = (ILexEntry) obj; + switch (tag) + { + case LexEntryTags.kflidLexemeForm: + if (!UpdatingEntries) + m_entryIndex = null; + if (entry.LexemeFormOA is IMoStemAllomorph) + m_stemmer = null; + break; + + case LexEntryTags.kflidAlternateForms: + if (entry.LexemeFormOA is IMoStemAllomorph) + m_stemmer = null; + break; + } + break; + + case MoMorphDataTags.kClassId: + if (tag == MoMorphDataTags.kflidParserParameters) + { + if (m_parser != null) + { + m_parser.Dispose(); + m_parser = null; + } + } + break; + } + } + + internal class HomographNumber + { + public int Number { get; set; } + } + + [SuppressMessage("Gendarme.Rules.Design", "TypesWithDisposableFieldsShouldBeDisposableRule", + Justification="m_lexicon is a reference")] + private class LexEntryComparer : IComparer + { + private readonly FdoLexicon m_lexicon; + + public LexEntryComparer(FdoLexicon lexicon) + { + m_lexicon = lexicon; + } + + public int Compare(ILexEntry x, ILexEntry y) + { + HomographNumber hnx = m_lexicon.m_homographNumbers.GetOrCreateValue(x); + HomographNumber hny = m_lexicon.m_homographNumbers.GetOrCreateValue(y); + return hnx.Number.CompareTo(hny.Number); + } + } + } +} diff --git a/Src/FwParatextLexiconPlugin/FdoLexiconGlossAddedEventArgs.cs b/Src/FwParatextLexiconPlugin/FdoLexiconGlossAddedEventArgs.cs new file mode 100644 index 0000000000..5b620f72ae --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FdoLexiconGlossAddedEventArgs.cs @@ -0,0 +1,34 @@ +using System; +using Paratext.LexicalContracts; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + internal class FdoLexiconGlossAddedEventArgs : EventArgs, LexiconGlossAddedEventArgs + { + private readonly Lexeme m_lexeme; + private readonly LexiconSense m_sense; + private readonly LanguageText m_gloss; + + public FdoLexiconGlossAddedEventArgs(Lexeme lexeme, LexiconSense sense, LanguageText gloss) + { + m_lexeme = lexeme; + m_sense = sense; + m_gloss = gloss; + } + + public Lexeme Lexeme + { + get { return m_lexeme; } + } + + public LexiconSense Sense + { + get { return m_sense; } + } + + public LanguageText Gloss + { + get { return m_gloss; } + } + } +} diff --git a/Src/FwParatextLexiconPlugin/FdoLexiconSenseAddedEventArgs.cs b/Src/FwParatextLexiconPlugin/FdoLexiconSenseAddedEventArgs.cs new file mode 100644 index 0000000000..79123b55da --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FdoLexiconSenseAddedEventArgs.cs @@ -0,0 +1,27 @@ +using System; +using Paratext.LexicalContracts; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + internal class FdoLexiconSenseAddedEventArgs : EventArgs, LexiconSenseAddedEventArgs + { + private readonly Lexeme m_lexeme; + private readonly LexiconSense m_sense; + + public FdoLexiconSenseAddedEventArgs(Lexeme lexeme, LexiconSense sense) + { + m_lexeme = lexeme; + m_sense = sense; + } + + public Lexeme Lexeme + { + get { return m_lexeme; } + } + + public LexiconSense Sense + { + get { return m_sense; } + } + } +} diff --git a/Src/FwParatextLexiconPlugin/FdoSemanticDomain.cs b/Src/FwParatextLexiconPlugin/FdoSemanticDomain.cs new file mode 100644 index 0000000000..347cf1366c --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FdoSemanticDomain.cs @@ -0,0 +1,40 @@ +using System.Diagnostics; +using Paratext.LexicalContracts; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + internal class FdoSemanticDomain : LexiconSemanticDomain + { + private readonly string m_name; + + /// + /// Creates a new LexiconSemanticDomain by wrapping the specified data + /// + public FdoSemanticDomain(string name) + { + Debug.Assert(name.IsNormalized(), "We expect all strings to be normalized composed"); + m_name = name; + } + + #region Implementation of LexiconSemanticDomain + /// + /// The name of the semantic domain + /// + public string Name + { + get { return m_name; } + } + #endregion + + public override bool Equals(object obj) + { + var other = obj as FdoSemanticDomain; + return other != null && m_name == other.m_name; + } + + public override int GetHashCode() + { + return m_name.GetHashCode(); + } + } +} diff --git a/Src/FwParatextLexiconPlugin/FdoWordAnalysis.cs b/Src/FwParatextLexiconPlugin/FdoWordAnalysis.cs new file mode 100644 index 0000000000..e4132869f5 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FdoWordAnalysis.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using Paratext.LexicalContracts; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + internal class FdoWordAnalysis : WordAnalysis + { + private readonly string m_word; + private readonly Lexeme[] m_lexemes; + + public FdoWordAnalysis(string word, IEnumerable lexemes) + { + if (!word.IsNormalized()) + throw new ArgumentException("The word is not normalized.", "word"); + m_word = word; + m_lexemes = lexemes.ToArray(); + } + + public string Word + { + get { return m_word; } + } + + public Lexeme this[int index] + { + get { return m_lexemes[index]; } + } + + public int Length + { + get { return m_lexemes.Length; } + } + + public override bool Equals(object obj) + { + var other = obj as FdoWordAnalysis; + if (other == null || m_lexemes.Length != other.m_lexemes.Length) + return false; + + for (int i = 0; i < m_lexemes.Length; i++) + { + if (!m_lexemes[i].Equals(other.m_lexemes[i])) + return false; + } + return true; + } + + public override int GetHashCode() + { + return m_lexemes.Aggregate(23, (code, lexeme) => code * 31 + lexeme.GetHashCode()); + } + + public IEnumerator GetEnumerator() + { + return ((IEnumerable)m_lexemes).GetEnumerator(); + } + + [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", + Justification = "Don't need to dispose an IEnumerator.")] + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} diff --git a/Src/FwParatextLexiconPlugin/FdoWordformLexeme.cs b/Src/FwParatextLexiconPlugin/FdoWordformLexeme.cs new file mode 100644 index 0000000000..d6a9e7a169 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FdoWordformLexeme.cs @@ -0,0 +1,289 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using Paratext.LexicalContracts; +using SIL.CoreImpl; +using SIL.FieldWorks.Common.COMInterfaces; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.FDO.Infrastructure; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + #region FdoWordformLexeme class + /// + /// + [SuppressMessage("Gendarme.Rules.Design", "TypesWithDisposableFieldsShouldBeDisposableRule", + Justification="m_lexicon is a reference")] + internal class FdoWordformLexeme : Lexeme + { + private readonly LexemeKey m_key; + private readonly FdoLexicon m_lexicon; + + public FdoWordformLexeme(FdoLexicon lexicon, LexemeKey key) + { + m_lexicon = lexicon; + m_key = key; + } + + #region Lexeme Members + + public string Id + { + get { return m_key.Id; } + } + + public LexemeType Type + { + get { return LexemeType.Word; } + } + + public string LexicalForm + { + get { return m_key.LexicalForm; } + } + + /// + /// Gets a string that is suitable for display which may contain morphological abbreviations + /// + public string DisplayString + { + get { return LexicalForm; } + } + + public string CitationForm + { + get { return null; } + } + + public int HomographNumber + { + get { return 0; } + } + + public IEnumerable Senses + { + get + { + using (m_lexicon.ActivationContext.Activate()) + { + IWfiWordform wf; + if (!m_lexicon.TryGetWordform(m_key.LexicalForm, out wf)) + return Enumerable.Empty(); + + return wf.AnalysesOC.Where(a => a.ApprovalStatusIcon == (int) Opinions.approves).SelectMany(a => a.MeaningsOC) + .Select(gloss => new WfiGlossLexiconSense(m_lexicon, m_key, gloss)).ToArray(); + } + } + } + + public IEnumerable LexicalRelations + { + get { return Enumerable.Empty(); } + } + + public IEnumerable AlternateForms + { + get { return Enumerable.Empty(); } + } + + public LexiconSense AddSense() + { + LexiconSense sense = null; + bool lexemeAdded = false; + using (m_lexicon.ActivationContext.Activate()) + { + NonUndoableUnitOfWorkHelper.Do(m_lexicon.Cache.ActionHandlerAccessor, () => + { + IWfiWordform wordform; + if (!m_lexicon.TryGetWordform(m_key.LexicalForm, out wordform)) + { + wordform = m_lexicon.CreateWordform(m_key.LexicalForm); + lexemeAdded = true; + } + // For wordforms, our "senses" could be new meanings of an analysis for the word + // or it could be a brand new analysis. Because we have no idea what the user actually + // wanted, we just assume the worst (they want to create a new analysis for the word + // with a new meaning). + IWfiAnalysis analysis = m_lexicon.Cache.ServiceLocator.GetInstance().Create(); + wordform.AnalysesOC.Add(analysis); + analysis.ApprovalStatusIcon = (int) Opinions.approves; // Assume the analysis from the external application is user approved + IMoStemAllomorph morph = m_lexicon.Cache.ServiceLocator.GetInstance().AllInstances().FirstOrDefault(allo => + { + ITsString tss = allo.Form.StringOrNull(m_lexicon.DefaultVernWs); + if (tss != null) + return tss.Text == LexicalForm.Normalize(NormalizationForm.FormD); + return false; + }); + if (morph != null) + { + IWfiMorphBundle mb = m_lexicon.Cache.ServiceLocator.GetInstance().Create(); + analysis.MorphBundlesOS.Add(mb); + mb.MorphRA = morph; + var entry = morph.OwnerOfClass(); + mb.SenseRA = entry.SensesOS[0]; + mb.MsaRA = entry.SensesOS[0].MorphoSyntaxAnalysisRA; + } + IWfiGloss gloss = m_lexicon.Cache.ServiceLocator.GetInstance().Create(); + analysis.MeaningsOC.Add(gloss); + sense = new WfiGlossLexiconSense(m_lexicon, m_key, gloss); + }); + } + if (lexemeAdded) + m_lexicon.OnLexemeAdded(this); + m_lexicon.OnLexiconSenseAdded(this, sense); + return sense; + } + + public void RemoveSense(LexiconSense sense) + { + using (m_lexicon.ActivationContext.Activate()) + { + NonUndoableUnitOfWorkHelper.Do(m_lexicon.Cache.ActionHandlerAccessor, () => + { + var glossSense = (WfiGlossLexiconSense) sense; + if (!glossSense.Gloss.Analysis.OccurrencesInTexts.Any(seg => seg.AnalysesRS.Contains(glossSense.Gloss))) + { + IWfiAnalysis analysis = glossSense.Gloss.Analysis; + if (analysis.MeaningsOC.Count == 1 && !analysis.OccurrencesInTexts.Any()) + analysis.Delete(); + else + glossSense.Gloss.Delete(); + } + }); + } + } + + #endregion + + public override bool Equals(object obj) + { + var other = obj as FdoWordformLexeme; + return other != null && m_key.Equals(other.m_key); + } + + public override int GetHashCode() + { + return m_key.GetHashCode(); + } + + public override string ToString() + { + return DisplayString; + } + + [SuppressMessage("Gendarme.Rules.Design", "TypesWithDisposableFieldsShouldBeDisposableRule", + Justification="m_lexicon is a reference")] + private class WfiGlossLexiconSense : LexiconSense + { + private readonly FdoLexicon m_lexicon; + private readonly LexemeKey m_lexemeKey; + private readonly IWfiGloss m_gloss; + + public WfiGlossLexiconSense(FdoLexicon lexicon, LexemeKey lexemeKey, IWfiGloss gloss) + { + m_lexicon = lexicon; + m_lexemeKey = lexemeKey; + m_gloss = gloss; + } + + internal IWfiGloss Gloss + { + get { return m_gloss; } + } + + public string Id + { + get + { + using (m_lexicon.ActivationContext.Activate()) + return m_gloss.Guid.ToString(); + } + } + + public string SenseNumber + { + get { return null; } + } + + public string Category + { + get { return null; } + } + + public IEnumerable Definitions + { + get { return Enumerable.Empty(); } + } + + public IEnumerable Glosses + { + get + { + using (m_lexicon.ActivationContext.Activate()) + { + var glosses = new List(); + IMultiUnicode fdoGlosses = m_gloss.Form; + foreach (IWritingSystem ws in m_lexicon.Cache.ServiceLocator.WritingSystems.CurrentAnalysisWritingSystems) + { + ITsString tssGloss = fdoGlosses.StringOrNull(ws.Handle); + if (tssGloss != null) + glosses.Add(new FdoLanguageText(ws.Id, tssGloss.Text.Normalize())); + } + return glosses; + } + } + } + + public LanguageText AddGloss(string language, string text) + { + LanguageText lexGloss = null; + using (m_lexicon.ActivationContext.Activate()) + { + NonUndoableUnitOfWorkHelper.Do(m_gloss.Cache.ActionHandlerAccessor, () => + { + IWritingSystem ws; + if (!m_lexicon.Cache.ServiceLocator.WritingSystemManager.TryGet(language, out ws)) + throw new ArgumentException("The specified language is unrecognized.", "language"); + m_gloss.Form.set_String(ws.Handle, text.Normalize(NormalizationForm.FormD)); + lexGloss = new FdoLanguageText(language, text); + }); + } + m_lexicon.OnLexiconGlossAdded(new FdoWordformLexeme(m_lexicon, m_lexemeKey), this, lexGloss); + return lexGloss; + } + + public void RemoveGloss(string language) + { + using (m_lexicon.ActivationContext.Activate()) + { + NonUndoableUnitOfWorkHelper.Do(m_gloss.Cache.ActionHandlerAccessor, () => + { + IWritingSystem ws; + if (!m_lexicon.Cache.ServiceLocator.WritingSystemManager.TryGet(language, out ws)) + throw new ArgumentException("The specified language is unrecognized.", "language"); + m_gloss.Form.set_String(ws.Handle, (ITsString) null); + }); + } + } + + public IEnumerable SemanticDomains + { + get { return Enumerable.Empty(); } + } + + public override bool Equals(object obj) + { + var other = obj as WfiGlossLexiconSense; + return other != null && m_gloss == other.m_gloss; + } + + public override int GetHashCode() + { + return m_gloss.GetHashCode(); + } + } + } + #endregion +} diff --git a/Src/FwParatextLexiconPlugin/FilesToRestoreAreOlder.Designer.cs b/Src/FwParatextLexiconPlugin/FilesToRestoreAreOlder.Designer.cs new file mode 100644 index 0000000000..e80a8242fd --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FilesToRestoreAreOlder.Designer.cs @@ -0,0 +1,123 @@ +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + partial class FilesToRestoreAreOlder + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + System.Diagnostics.Debug.WriteLineIf(!disposing, "****** Missing Dispose() call for " + GetType().Name + ". ****** "); + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FilesToRestoreAreOlder)); + this.label_message = new System.Windows.Forms.Label(); + this.label_Question = new System.Windows.Forms.Label(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.radio_Overwrite = new System.Windows.Forms.RadioButton(); + this.radio_Keep = new System.Windows.Forms.RadioButton(); + this.button_Cancel = new System.Windows.Forms.Button(); + this.button_OK = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.SuspendLayout(); + // + // label_message + // + resources.ApplyResources(this.label_message, "label_message"); + this.label_message.Name = "label_message"; + // + // label_Question + // + resources.ApplyResources(this.label_Question, "label_Question"); + this.label_Question.Name = "label_Question"; + // + // pictureBox1 + // + this.pictureBox1.Image = global::SIL.FieldWorks.ParatextLexiconPlugin.Properties.Resources.question; + resources.ApplyResources(this.pictureBox1, "pictureBox1"); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.TabStop = false; + // + // radio_Overwrite + // + resources.ApplyResources(this.radio_Overwrite, "radio_Overwrite"); + this.radio_Overwrite.Name = "radio_Overwrite"; + this.radio_Overwrite.TabStop = true; + this.radio_Overwrite.UseVisualStyleBackColor = true; + // + // radio_Keep + // + resources.ApplyResources(this.radio_Keep, "radio_Keep"); + this.radio_Keep.Checked = true; + this.radio_Keep.Name = "radio_Keep"; + this.radio_Keep.TabStop = true; + this.radio_Keep.UseVisualStyleBackColor = true; + // + // button_Cancel + // + this.button_Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + resources.ApplyResources(this.button_Cancel, "button_Cancel"); + this.button_Cancel.Name = "button_Cancel"; + this.button_Cancel.UseVisualStyleBackColor = true; + this.button_Cancel.Click += new System.EventHandler(this.button_Cancel_Click); + // + // button_OK + // + resources.ApplyResources(this.button_OK, "button_OK"); + this.button_OK.Name = "button_OK"; + this.button_OK.UseVisualStyleBackColor = true; + this.button_OK.Click += new System.EventHandler(this.button_OK_Click); + // + // FilesToRestoreAreOlder + // + this.AcceptButton = this.button_OK; + resources.ApplyResources(this, "$this"); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.button_Cancel; + this.ControlBox = false; + this.Controls.Add(this.radio_Overwrite); + this.Controls.Add(this.radio_Keep); + this.Controls.Add(this.button_Cancel); + this.Controls.Add(this.button_OK); + this.Controls.Add(this.pictureBox1); + this.Controls.Add(this.label_Question); + this.Controls.Add(this.label_message); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FilesToRestoreAreOlder"; + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label_message; + private System.Windows.Forms.Label label_Question; + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.RadioButton radio_Overwrite; + private System.Windows.Forms.RadioButton radio_Keep; + private System.Windows.Forms.Button button_Cancel; + private System.Windows.Forms.Button button_OK; + } +} \ No newline at end of file diff --git a/Src/FwParatextLexiconPlugin/FilesToRestoreAreOlder.cs b/Src/FwParatextLexiconPlugin/FilesToRestoreAreOlder.cs new file mode 100644 index 0000000000..14e6eec1b9 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FilesToRestoreAreOlder.cs @@ -0,0 +1,51 @@ +using System; +using System.Windows.Forms; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + /// + /// + /// + public partial class FilesToRestoreAreOlder : Form + { + /// + /// + /// + public FilesToRestoreAreOlder() + { + InitializeComponent(); + } + + /// + /// + /// + public bool fKeepFilesThatAreNewer + { + get { return radio_Keep.Checked; } + } + + /// + /// + /// + public bool fOverWriteThatAreNewer + { + get { return radio_Overwrite.Checked; } + } + + private void button_OK_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.OK; + Close(); + } + + private void button_Cancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + + private void button_Help_Click(object sender, EventArgs e) + { + } + } +} diff --git a/Src/FwParatextLexiconPlugin/FilesToRestoreAreOlder.resx b/Src/FwParatextLexiconPlugin/FilesToRestoreAreOlder.resx new file mode 100644 index 0000000000..696f588500 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FilesToRestoreAreOlder.resx @@ -0,0 +1,324 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + 60, 12 + + + 488, 52 + + + + 3 + + + Some files in the Linked Files folder are newer than the ones which will be restored, and these may not be files that this FieldWorks project links to yet. + + + label_message + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 6 + + + 60, 64 + + + 488, 41 + + + 4 + + + Would you like to keep the newer files in the folder or replace them with the older ones from the backup? + + + label_Question + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 5 + + + 12, 12 + + + 42, 38 + + + 5 + + + pictureBox1 + + + System.Windows.Forms.PictureBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 4 + + + True + + + + NoControl + + + 64, 132 + + + 192, 17 + + + 13 + + + Use the older files from the backup. + + + radio_Overwrite + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 0 + + + True + + + NoControl + + + 64, 109 + + + 164, 17 + + + 12 + + + Keep newer files in the folder. + + + radio_Keep + + + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 1 + + + NoControl + + + 473, 157 + + + 75, 23 + + + 10 + + + Cancel + + + button_Cancel + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 2 + + + NoControl + + + 392, 157 + + + 75, 23 + + + 9 + + + OK + + + button_OK + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 3 + + + True + + + 6, 13 + + + 561, 192 + + + Linked files in backup are older + + + FilesToRestoreAreOlder + + + System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Src/FwParatextLexiconPlugin/FwLexiconPlugin.cs b/Src/FwParatextLexiconPlugin/FwLexiconPlugin.cs new file mode 100644 index 0000000000..0d9b869abd --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FwLexiconPlugin.cs @@ -0,0 +1,256 @@ +using System; +using System.Collections.ObjectModel; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Threading; +using System.Windows.Forms; +using Paratext.LexicalContracts; +using SIL.CoreImpl; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.FDO.DomainServices; +using SIL.Utils; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + /// + /// This is the main Paratext lexicon plugin class + /// + [LexiconPlugin(ID = "FieldWorks", DisplayName = "FieldWorks Language Explorer")] + public class FwLexiconPlugin : FwDisposableBase, LexiconPlugin + { + private const int CacheSize = 5; + private readonly FdoLexiconCollection m_lexiconCache; + private readonly FdoCacheCollection m_fdoCacheCache; + private readonly object m_syncRoot; + private ActivationContextHelper m_activationContext; + private readonly ParatextLexiconPluginFdoUI m_ui; + + /// + /// Initializes a new instance of the class. + /// + public FwLexiconPlugin() + { + m_syncRoot = new object(); + m_lexiconCache = new FdoLexiconCollection(); + m_fdoCacheCache = new FdoCacheCollection(); + m_activationContext = new ActivationContextHelper("FwParatextLexiconPlugin.dll.manifest"); + + // initialize client-server services to use Db4O backend for FDO + m_ui = new ParatextLexiconPluginFdoUI(m_activationContext); + var dirs = ParatextLexiconPluginDirectoryFinder.FdoDirectories; + ClientServerServices.SetCurrentToDb4OBackend(m_ui, dirs, + () => dirs.ProjectsDirectory == ParatextLexiconPluginDirectoryFinder.ProjectsDirectoryLocalMachine); + } + + /// + /// Validates the lexical project. + /// + /// The project identifier. + /// The language identifier. + /// + [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", + Justification = "FdoCache is diposed when the plugin is diposed.")] + public bool ValidateLexicalProject(string projectId, string langId) + { + using (m_activationContext.Activate()) + { + lock (m_syncRoot) + { + FdoCache fdoCache = GetFdoCache(projectId); + + if (fdoCache.ServiceLocator.WritingSystems.CurrentVernacularWritingSystems.Any(ws => ws.Id == langId)) + return true; + + DiscardFdoCache(fdoCache); + } + return false; + } + } + + /// + /// Chooses the lexical project. + /// + /// The project identifier. + /// + public bool ChooseLexicalProject(out string projectId) + { + using (m_activationContext.Activate()) + using (var dialog = new ChooseFdoProjectForm(m_ui)) + { + if (dialog.ShowDialog() == DialogResult.OK) + { + projectId = dialog.SelectedProject; + return true; + } + + projectId = null; + return false; + } + } + + /// + /// Gets the lexicon. + /// + /// Name of the SCR text. + /// The project identifier. + /// The language identifier. + /// + [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", + Justification = "FdoLexicon is diposed when the plugin is diposed.")] + public Lexicon GetLexicon(string scrTextName, string projectId, string langId) + { + using (m_activationContext.Activate()) + return GetFdoLexicon(scrTextName, projectId, langId); + } + + /// + /// Gets the word analyses. + /// + /// Name of the SCR text. + /// The project identifier. + /// The language identifier. + /// + [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", + Justification = "FdoLexicon is diposed when the plugin is diposed.")] + public WordAnalyses GetWordAnalyses(string scrTextName, string projectId, string langId) + { + using (m_activationContext.Activate()) + return GetFdoLexicon(scrTextName, projectId, langId); + } + + private FdoLexicon GetFdoLexicon(string scrTextName, string projectId, string langId) + { + lock (m_syncRoot) + { + if (m_lexiconCache.Contains(scrTextName)) + { + FdoLexicon lexicon = m_lexiconCache[scrTextName]; + m_lexiconCache.Remove(scrTextName); + m_lexiconCache.Insert(0, lexicon); + return lexicon; + } + + FdoCache fdoCache = GetFdoCache(projectId); + + IWritingSystem writingSystem; + if (!fdoCache.ServiceLocator.WritingSystemManager.TryGet(langId, out writingSystem)) + throw new ArgumentException("Could not find a matching vernacular writing system.", "langId"); + + if (m_lexiconCache.Count == CacheSize) + { + FdoLexicon oldLexicon = m_lexiconCache[CacheSize - 1]; + m_lexiconCache.RemoveAt(CacheSize - 1); + + DiscardFdoCache(oldLexicon.Cache); + } + + var newLexicon = new FdoLexicon(scrTextName, fdoCache, writingSystem.Handle, m_activationContext); + m_lexiconCache.Insert(0, newLexicon); + return newLexicon; + } + } + + private FdoCache GetFdoCache(string projectId) + { + FdoCache fdoCache; + if (m_fdoCacheCache.Contains(projectId)) + { + fdoCache = m_fdoCacheCache[projectId]; + } + else + { + var backendProviderType = FDOBackendProviderType.kSharedXML; + string path = Path.Combine(ParatextLexiconPluginDirectoryFinder.ProjectsDirectory, projectId, projectId + FdoFileHelper.ksFwDataXmlFileExtension); + if (!File.Exists(path)) + { + backendProviderType = FDOBackendProviderType.kDb4oClientServer; + path = Path.Combine(ParatextLexiconPluginDirectoryFinder.ProjectsDirectory, projectId, projectId + FdoFileHelper.ksFwDataDb4oFileExtension); + if (!File.Exists(path)) + throw new LexiconUnavailableException("The associated Fieldworks project has been moved, renamed, or does not exist."); + } + + var progress = new ParatextLexiconPluginThreadedProgress(m_ui.SynchronizeInvoke) { IsIndeterminate = true, Title = string.Format("Opening {0}", projectId) }; + fdoCache = (FdoCache) progress.RunTask(CreateFdoCache, new ParatextLexiconPluginProjectID(backendProviderType, path)); + + m_fdoCacheCache.Add(fdoCache); + } + return fdoCache; + } + + private FdoCache CreateFdoCache(IThreadedProgress progress, object[] parameters) + { + var projectId = (ParatextLexiconPluginProjectID) parameters[0]; + try + { + return FdoCache.CreateCacheFromExistingData(projectId, Thread.CurrentThread.CurrentUICulture.Name, m_ui, ParatextLexiconPluginDirectoryFinder.FdoDirectories, progress, true); + } + catch (FdoDataMigrationForbiddenException) + { + throw new LexiconUnavailableException("The current version of Paratext is not compatible with the associated Fieldworks lexicon. Please open the lexicon using a compatible version of Fieldworks first."); + } + catch (FdoFileLockedException) + { + throw new LexiconUnavailableException("Paratext cannot currently access the lexicon. Please close FieldWorks."); + } + catch (StartupException se) + { + throw new LexiconUnavailableException(se.Message); + } + } + + private void DiscardFdoCache(FdoCache fdoCache) + { + if (m_lexiconCache.All(lexicon => lexicon.Cache != fdoCache)) + { + m_fdoCacheCache.Remove(fdoCache.ProjectId.Name); + fdoCache.ServiceLocator.GetInstance().Save(); + fdoCache.Dispose(); + } + } + + /// + /// Override to dispose managed resources. + /// + protected override void DisposeManagedResources() + { + if (m_activationContext != null) + { + using (m_activationContext.Activate()) + { + lock (m_syncRoot) + { + foreach (FdoLexicon lexicon in m_lexiconCache) + lexicon.Dispose(); + m_lexiconCache.Clear(); + foreach (FdoCache fdoCache in m_fdoCacheCache) + { + fdoCache.ServiceLocator.GetInstance().Save(); + fdoCache.Dispose(); + } + m_fdoCacheCache.Clear(); + } + } + + m_activationContext.Dispose(); + m_activationContext = null; + } + } + + private class FdoLexiconCollection : KeyedCollection + { + protected override string GetKeyForItem(FdoLexicon item) + { + return item.ScrTextName; + } + } + + private class FdoCacheCollection : KeyedCollection + { + protected override string GetKeyForItem(FdoCache item) + { + return item.ProjectId.Name; + } + } + } +} diff --git a/Src/FwParatextLexiconPlugin/FwParatextLexiconPlugin.csproj b/Src/FwParatextLexiconPlugin/FwParatextLexiconPlugin.csproj new file mode 100644 index 0000000000..7babfa55d7 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FwParatextLexiconPlugin.csproj @@ -0,0 +1,158 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {41FE243C-4D03-45E3-B556-CF361272B3BA} + Library + Properties + SIL.FieldWorks.ParatextLexiconPlugin + FwParatextLexiconPlugin + v4.0 + 512 + + + true + full + false + ..\..\Output\Debug\ + DEBUG;TRACE + prompt + 4 + x86 + true + ..\..\Output\Debug\FwParatextLexiconPlugin.xml + 67 + + + pdbonly + true + ..\..\Output\Release\ + TRACE + prompt + 4 + x86 + 67 + + + + ..\..\Output\Debug\BasicUtils.dll + + + ..\..\Output\Debug\COMInterfaces.dll + + + ..\..\Output\Debug\CoreImpl.dll + + + ..\..\Output\Debug\FDO.dll + + + ..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll + + + False + ..\..\Output\Debug\Paratext.LexicalContracts.dll + + + ..\..\Output\Debug\ParserCore.dll + + + ..\..\Lib\debug\SIL.Machine.dll + + + ..\..\Output\Debug\SilUtils.dll + + + + + + + + + + + Properties\CommonAssemblyInfo.cs + + + Form + + + ChooseFdoProjectForm.cs + + + + + + + + + + Form + + + FilesToRestoreAreOlder.cs + + + + + + + + + + + + + Form + + + ProjectExistsForm.cs + + + + True + True + Resources.resx + + + True + True + Strings.resx + + + + + ChooseFdoProjectForm.cs + + + FilesToRestoreAreOlder.cs + Designer + + + ProjectExistsForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + + + ResXFileCodeGenerator + Strings.Designer.cs + + + + + + + + + \ No newline at end of file diff --git a/Src/FwParatextLexiconPlugin/FwParatextLexiconPluginTests/DummyFdoUI.cs b/Src/FwParatextLexiconPlugin/FwParatextLexiconPluginTests/DummyFdoUI.cs new file mode 100644 index 0000000000..27268912a9 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FwParatextLexiconPluginTests/DummyFdoUI.cs @@ -0,0 +1,153 @@ +using System; +using System.ComponentModel; +using SIL.FieldWorks.FDO; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + internal class DummyFdoUI : IFdoUI + { + private readonly ISynchronizeInvoke m_synchronizeInvoke; + + public DummyFdoUI(ISynchronizeInvoke synchronizeInvoke) + { + m_synchronizeInvoke = synchronizeInvoke; + } + + /// + /// Gets the object that is used to invoke methods on the main UI thread. + /// + public ISynchronizeInvoke SynchronizeInvoke + { + get { return m_synchronizeInvoke; } + } + + /// + /// Gets the error message. + /// + /// + /// The error message. + /// + public string ErrorMessage { get; private set; } + + /// + /// Check with user regarding conflicting changes + /// + /// True if user wishes to revert to saved state. False otherwise. + public bool ConflictingSave() + { + throw new NotImplementedException(); + } + + /// + /// Inform the user of a lost connection + /// + /// True if user wishes to attempt reconnect. False otherwise. + public bool ConnectionLost() + { + throw new NotImplementedException(); + } + + /// + /// Gets the last time that there was user activity. + /// + public DateTime LastActivityTime + { + get { return DateTime.Now; } + } + + /// + /// Check with user regarding which files to use + /// + /// + public FileSelection ChooseFilesToUse() + { + throw new NotImplementedException(); + } + + /// + /// Check with user regarding restoring linked files in the project folder or original path + /// + /// True if user wishes to restore linked files in project folder. False to leave them in the original location. + public bool RestoreLinkedFilesInProjectFolder() + { + throw new NotImplementedException(); + } + + /// + /// Cannot restore linked files to original path. + /// Check with user regarding restoring linked files in the project folder or not at all + /// + /// OkYes to restore to project folder, OkNo to skip restoring linked files, Cancel otherwise + public YesNoCancel CannotRestoreLinkedFilesToOriginalLocation() + { + throw new NotImplementedException(); + } + + /// + /// Displays information to the user + /// + /// + /// + /// + /// + public void DisplayMessage(MessageType type, string message, string caption, string helpTopic) + { + throw new NotImplementedException(); + } + + /// + /// Show a dialog or output to the error log, as appropriate. + /// + /// the exception you want to report + /// set to true if the error is lethal, otherwise + /// false. + /// True if the error was lethal and the user chose to exit the application, + /// false otherwise. + public void ReportException(Exception error, bool isLethal) + { + // Store the message so we can check it later + ErrorMessage = error.Message; + } + + /// + /// Reports duplicate guids to the user + /// + /// The error text. + public void ReportDuplicateGuids(string errorText) + { + throw new NotImplementedException(); + } + + /// + /// Ask user if they wish to restore an XML project from a backup project file. + /// + /// The project path. + /// The backup path. + /// + /// + public bool OfferToRestore(string projectPath, string backupPath) + { + throw new NotImplementedException(); + } + + /// + /// Exits the application. + /// + /// + public void Exit() + { + throw new NotImplementedException(); + } + + /// + /// Present a message to the user and allow the options to Retry or Cancel + /// + /// The message. + /// The caption. + /// True to retry. False otherwise + public bool Retry(string msg, string caption) + { + throw new NotImplementedException(); + } + } +} diff --git a/Src/FwParatextLexiconPlugin/FwParatextLexiconPluginTests/FdoLexiconTests.cs b/Src/FwParatextLexiconPlugin/FwParatextLexiconPluginTests/FdoLexiconTests.cs new file mode 100644 index 0000000000..c0bba53c70 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FwParatextLexiconPluginTests/FdoLexiconTests.cs @@ -0,0 +1,539 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using NUnit.Framework; +using Paratext.LexicalContracts; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.FDO.Infrastructure; +using SIL.Utils; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + /// + /// FDO lexicon tests + /// + [TestFixture] + [SuppressMessage("Gendarme.Rules.Design", "TypesWithDisposableFieldsShouldBeDisposableRule", + Justification="Fields are diposed in test teardown")] + public class FdoLexiconTests + { + private ThreadHelper m_threadHelper; + private FdoLexicon m_lexicon; + private FdoCache m_cache; + private ActivationContextHelper m_activationContext; + + /// + /// Set up the unit tests + /// + [SetUp] + public void SetUp() + { + m_activationContext = new ActivationContextHelper("FwParatextLexiconPlugin.dll.manifest"); + using (m_activationContext.Activate()) + { + m_threadHelper = new ThreadHelper(); + var ui = new DummyFdoUI(m_threadHelper); + var projectId = new ParatextLexiconPluginProjectID(FDOBackendProviderType.kMemoryOnly, "Test.fwdata"); + m_cache = FdoCache.CreateCacheWithNewBlankLangProj(projectId, "en", "fr", "en", ui, ParatextLexiconPluginDirectoryFinder.FdoDirectories); + NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, () => + { + m_cache.ServiceLocator.WritingSystems.AddToCurrentAnalysisWritingSystems(m_cache.ServiceLocator.WritingSystemManager.Get("fr")); + m_cache.LangProject.MorphologicalDataOA.ParserParameters = "1515010XAmple"; + }); + } + m_lexicon = new FdoLexicon("Test", m_cache, m_cache.DefaultVernWs, m_activationContext); + } + + /// + /// Cleans up the unit tests + /// + [TearDown] + public void TearDown() + { + m_lexicon.Dispose(); + m_cache.Dispose(); + m_activationContext.Dispose(); + m_threadHelper.Dispose(); + } + + #region Tests + /// + /// Test multiple lexeme creates where the IDs match + /// + [Test] + public void MultipleCreatesIdsMatch() + { + Lexeme lex = m_lexicon.CreateLexeme(LexemeType.Word, "a"); + Lexeme lex2 = m_lexicon.CreateLexeme(LexemeType.Word, "a"); + Assert.AreEqual(lex.Id, lex2.Id); + Assert.AreEqual(LexemeType.Word, lex.Type); + Assert.AreEqual("a", lex.LexicalForm); + Assert.AreEqual(LexemeType.Word, lex2.Type); + Assert.AreEqual("a", lex2.LexicalForm); + } + + /// + /// Test multiple lexeme creates that refer to the same sense + /// + [Test] + public void MultipleCreatesReferToSameSenses() + { + Lexeme lex = m_lexicon.CreateLexeme(LexemeType.Word, "a"); + Lexeme lex2 = m_lexicon.CreateLexeme(LexemeType.Word, "a"); + + m_lexicon.AddLexeme(lex); + LexiconSense sense = lex.AddSense(); + sense.AddGloss("en", "test"); + + Assert.AreEqual(1, lex2.Senses.Count()); + + // Make sure the one that was added has the right sense now + lex = m_lexicon[lex.Id]; + Assert.AreEqual(LexemeType.Word, lex.Type); + Assert.AreEqual("a", lex.LexicalForm); + Assert.AreEqual(1, lex.Senses.Count()); + Assert.AreEqual("en", lex.Senses.First().Glosses.First().Language); + Assert.AreEqual("test", lex.Senses.First().Glosses.First().Text); + } + + /// + /// Test that adding sense also adds lexeme + /// + [Test] + public void AddingSenseAddsLexeme() + { + Lexeme lex = m_lexicon.CreateLexeme(LexemeType.Word, "a"); + LexiconSense sense = lex.AddSense(); + sense.AddGloss("en", "test"); + + Assert.AreEqual(1, m_lexicon.Lexemes.Count()); + + lex = m_lexicon[lex.Id]; // Make sure we're using the one stored in the lexicon + Assert.AreEqual(LexemeType.Word, lex.Type); + Assert.AreEqual("a", lex.LexicalForm); + Assert.AreEqual(1, lex.Senses.Count()); + Assert.AreEqual("en", lex.Senses.First().Glosses.First().Language); + Assert.AreEqual("test", lex.Senses.First().Glosses.First().Text); + } + + /// + /// Test that homograph increments + /// + [Test] + public void HomographsIncrement() + { + Lexeme lex = m_lexicon.CreateLexeme(LexemeType.Stem, "a"); + Lexeme lex2 = m_lexicon.CreateLexeme(LexemeType.Stem, "a"); + + m_lexicon.AddLexeme(lex); + + Assert.AreEqual(lex.Id, lex2.Id); + + Lexeme lex3 = m_lexicon.CreateLexeme(LexemeType.Stem, "a"); + Assert.AreNotEqual(lex.Id, lex3.Id); + Assert.AreNotEqual(lex2.Id, lex3.Id); + } + + /// + /// + /// + [Test] + public void HomographsFind() + { + Lexeme lex = m_lexicon.CreateLexeme(LexemeType.Stem, "a"); + m_lexicon.AddLexeme(lex); + Lexeme lex2 = m_lexicon.CreateLexeme(LexemeType.Stem, "a"); + m_lexicon.AddLexeme(lex2); + Assert.AreNotEqual(lex.Id, lex2.Id); + + List found = new List(m_lexicon.Lexemes); + Assert.AreEqual(2, found.Count); + Assert.AreEqual(lex.Id, found[0].Id); + Assert.AreEqual(lex2.Id, found[1].Id); + } + + /// + /// Test find or create lexeme + /// + [Test] + public void FindOrCreate() + { + Lexeme lex = m_lexicon.CreateLexeme(LexemeType.Word, "a"); + LexiconSense sense = lex.AddSense(); + sense.AddGloss("en", "monkey"); + + Lexeme lex2 = m_lexicon.FindOrCreateLexeme(LexemeType.Word, "a"); + Assert.AreEqual(lex.Id, lex2.Id); + Assert.AreEqual(LexemeType.Word, lex2.Type); + Assert.AreEqual("a", lex2.LexicalForm); + Assert.AreEqual(1, lex2.Senses.Count()); + Assert.AreEqual(1, lex2.Senses.First().Glosses.Count()); + Assert.AreEqual("en", lex2.Senses.First().Glosses.First().Language); + Assert.AreEqual("monkey", lex2.Senses.First().Glosses.First().Text); + + Lexeme lex3 = m_lexicon.FindOrCreateLexeme(LexemeType.Suffix, "bob"); + Assert.AreNotEqual(lex.Id, lex3.Id); + Assert.AreNotEqual(lex2.Id, lex3.Id); + Assert.AreEqual(LexemeType.Suffix, lex3.Type); + Assert.AreEqual("bob", lex3.LexicalForm); + Assert.AreEqual(0, lex3.Senses.Count()); + } + + /// + /// Test indexer + /// + [Test] + public void Indexer() + { + Lexeme lex = m_lexicon.CreateLexeme(LexemeType.Stem, "a"); + m_lexicon.AddLexeme(lex); + + lex = m_lexicon[lex.Id]; + Assert.IsNotNull(lex); + Assert.AreEqual(LexemeType.Stem, lex.Type); + Assert.AreEqual("a", lex.LexicalForm); + + Lexeme lex2 = m_lexicon.CreateLexeme(LexemeType.Suffix, "monkey"); + Assert.IsNull(m_lexicon[lex2.Id]); + } + + /// + /// Test that creating a lexeme does not add it + /// + [Test] + public void CreatingDoesNotAdd() + { + m_lexicon.CreateLexeme(LexemeType.Word, "a"); + Assert.AreEqual(0, m_lexicon.Lexemes.Count()); + } + + /// + /// Test that getting a sense from a created lexeme does not add it + /// + [Test] + public void GettingSensesDoesNotAdd() + { + Lexeme lexeme = m_lexicon.CreateLexeme(LexemeType.Word, "a"); + lexeme.Senses.Count(); + Assert.AreEqual(0, m_lexicon.Lexemes.Count()); + } + + /// + /// + /// + [Test] + public void AddSucceeds() + { + Lexeme lex = m_lexicon.CreateLexeme(LexemeType.Word, "a"); + m_lexicon.AddLexeme(lex); + Assert.AreEqual(1, m_lexicon.Lexemes.Count()); + + lex = m_lexicon[lex.Id]; // Make sure we're using the one stored in the lexicon + Assert.AreEqual(LexemeType.Word, lex.Type); + Assert.AreEqual("a", lex.LexicalForm); + } + + /// + /// Test that adding the same lexeme multiple times fails + /// + [Test] + public virtual void MultipleAddsFail() + { + Lexeme lex = m_lexicon.CreateLexeme(LexemeType.Word, "a"); + Lexeme lex2 = m_lexicon.CreateLexeme(LexemeType.Word, "a"); + m_lexicon.AddLexeme(lex); + Assert.Throws(typeof (ArgumentException), () => m_lexicon.AddLexeme(lex2)); + } + + /// + /// + /// + [Test] + public void SensesRetained() + { + Lexeme lex = m_lexicon.CreateLexeme(LexemeType.Word, "a"); + m_lexicon.AddLexeme(lex); + LexiconSense sense = lex.AddSense(); + sense.AddGloss("en", "glossen"); + sense.AddGloss("fr", "glossfr"); + + Assert.AreEqual(1, lex.Senses.Count()); + Assert.AreEqual(2, lex.Senses.First().Glosses.Count()); + + sense = m_lexicon[lex.Id].Senses.First(); // Make sure we're working with the one stored in the lexicon + Assert.AreEqual("en", sense.Glosses.First().Language); + Assert.AreEqual("glossen", sense.Glosses.First().Text); + Assert.AreEqual("fr", sense.Glosses.ElementAt(1).Language); + Assert.AreEqual("glossfr", sense.Glosses.ElementAt(1).Text); + + sense.RemoveGloss("en"); + + sense = m_lexicon[lex.Id].Senses.First(); // Make sure we're working with the one stored in the lexicon + Assert.AreEqual(1, sense.Glosses.Count()); + Assert.AreEqual("fr", sense.Glosses.First().Language); + Assert.AreEqual("glossfr", sense.Glosses.First().Text); + } + + /// + /// + /// + [Test] + public void MorphTypeRetained() + { + Lexeme lex = m_lexicon.CreateLexeme(LexemeType.Word, "a"); + m_lexicon.AddLexeme(lex); + Lexeme lex2 = m_lexicon.CreateLexeme(LexemeType.Prefix, "a"); + m_lexicon.AddLexeme(lex2); + Lexeme lex3 = m_lexicon.CreateLexeme(LexemeType.Suffix, "a"); + m_lexicon.AddLexeme(lex3); + Lexeme lex4 = m_lexicon.CreateLexeme(LexemeType.Stem, "a"); + m_lexicon.AddLexeme(lex4); + + Assert.AreEqual(4, m_lexicon.Lexemes.Count()); + Assert.IsTrue(m_lexicon.Lexemes.Contains(lex)); + Assert.IsTrue(m_lexicon.Lexemes.Contains(lex2)); + Assert.IsTrue(m_lexicon.Lexemes.Contains(lex3)); + Assert.IsTrue(m_lexicon.Lexemes.Contains(lex4)); + } + + /// + /// Test removing lexemes + /// + [Test] + public void RemoveLexemeSucceeds() + { + Lexeme lex = m_lexicon.CreateLexeme(LexemeType.Word, "a"); + m_lexicon.AddLexeme(lex); + Lexeme lex2 = m_lexicon.CreateLexeme(LexemeType.Prefix, "a"); + + Assert.IsTrue(m_lexicon.Lexemes.Contains(lex)); + Assert.IsFalse(m_lexicon.Lexemes.Contains(lex2)); + + m_lexicon.RemoveLexeme(lex); + Assert.IsFalse(m_lexicon.Lexemes.Contains(lex)); + + m_lexicon.RemoveLexeme(lex2); + Assert.IsFalse(m_lexicon.Lexemes.Contains(lex2)); + + m_lexicon.AddLexeme(lex2); + Lexeme lex3 = m_lexicon.CreateLexeme(LexemeType.Prefix, "a"); + m_lexicon.AddLexeme(lex3); + + m_lexicon.RemoveLexeme(lex2); + Assert.IsFalse(m_lexicon.Lexemes.Contains(lex2)); + Assert.IsTrue(m_lexicon.Lexemes.Contains(lex3)); + } + + /// + /// Test removing senses + /// + [Test] + public void RemoveSenseSucceeds() + { + Lexeme lex = m_lexicon.CreateLexeme(LexemeType.Word, "a"); + m_lexicon.AddLexeme(lex); + + LexiconSense sense = lex.AddSense(); + sense.AddGloss("en", "gloss1"); + + LexiconSense sense2 = lex.AddSense(); + sense.AddGloss("en", "gloss1"); + + // Test remove at + lex.RemoveSense(sense2); + + Assert.AreEqual(1, lex.Senses.Count()); + Assert.AreEqual(sense, lex.Senses.First()); + } + + /// + /// Test unusual characters in the lexical form + /// + [Test] + public void UnusualCharactersSupported() + { + var stems = new[] { "a:b:c", "a:b:", "a:2", "123-4", "!@#$%^&*()" }; + + foreach (string stem in stems) + { + Lexeme lexeme = m_lexicon.FindOrCreateLexeme(LexemeType.Stem, stem); + Assert.IsFalse(m_lexicon.Lexemes.Contains(lexeme)); + m_lexicon.AddLexeme(lexeme); + Assert.IsTrue(m_lexicon.Lexemes.Contains(lexeme)); + + // Add homomorph + Lexeme lexeme2 = m_lexicon.CreateLexeme(LexemeType.Stem, stem); + Assert.IsFalse(m_lexicon.Lexemes.Contains(lexeme2)); + m_lexicon.AddLexeme(lexeme2); + Assert.IsTrue(m_lexicon.Lexemes.Contains(lexeme2)); + } + } + + /// + /// Tests that the lexicon correctly normalizes strings + /// + [Test] + public void NormalizeStrings() + { + Lexeme lex = m_lexicon.CreateLexeme(LexemeType.Stem, "Vacaci\u00f3n"); // Uses composed accented letter 'o' + m_lexicon.AddLexeme(lex); + + lex = m_lexicon[new LexemeKey(LexemeType.Stem, "Vacaci\u00f3n").Id]; + Assert.IsNotNull(lex); + Assert.AreEqual(LexemeType.Stem, lex.Type); + Assert.AreEqual("Vacaci\u00f3n", lex.LexicalForm); + + LexiconSense sense = lex.AddSense(); + Assert.IsNotNull(sense); + + LanguageText gloss = sense.AddGloss("en", "D\u00f3nde"); + + Lexeme reGetLex = m_lexicon[lex.Id]; + Assert.AreEqual(gloss.Text, reGetLex.Senses.First().Glosses.First().Text); + } + + #region Lexicon Events + + /// + /// Test lexeme added event + /// + [Test] + public void LexemeAddedEvent() + { + // Listen for events + int lexemeAddedCount = 0; + int senseAddedCount = 0; + int glossAddedCount = 0; + m_lexicon.LexemeAdded += (sender, e) => lexemeAddedCount++; + m_lexicon.LexiconSenseAdded += (sender, e) => senseAddedCount++; + m_lexicon.LexiconGlossAdded += (sender, e) => glossAddedCount++; + + Lexeme lexeme = m_lexicon.FindOrCreateLexeme(LexemeType.Word, "word"); + Assert.AreEqual(0, lexemeAddedCount); + + m_lexicon.AddLexeme(lexeme); + Assert.AreEqual(1, lexemeAddedCount); + Assert.AreEqual(0, senseAddedCount); + Assert.AreEqual(0, glossAddedCount); + + // Adding sense adds lexeme + Lexeme lexeme2 = m_lexicon.FindOrCreateLexeme(LexemeType.Word, "word2"); + lexeme2.AddSense(); + Assert.AreEqual(2, lexemeAddedCount); + } + + /// + /// Test sense added event + /// + [Test] + public void SenseAddedEvent() + { + // Listen for events + int lexemeAddedCount = 0; + int senseAddedCount = 0; + int glossAddedCount = 0; + m_lexicon.LexemeAdded += (sender, e) => lexemeAddedCount++; + m_lexicon.LexiconSenseAdded += (sender, e) => senseAddedCount++; + m_lexicon.LexiconGlossAdded += (sender, e) => glossAddedCount++; + + Lexeme lexeme = m_lexicon.FindOrCreateLexeme(LexemeType.Word, "word"); + m_lexicon.AddLexeme(lexeme); + lexeme.AddSense(); + Assert.AreEqual(1, senseAddedCount); + } + + /// + /// Test gloss added event + /// + [Test] + public void GlossAddedEvent() + { + // Listen for events + int lexemeAddedCount = 0; + int senseAddedCount = 0; + int glossAddedCount = 0; + string glossText = ""; + m_lexicon.LexemeAdded += (sender, e) => lexemeAddedCount++; + m_lexicon.LexiconSenseAdded += (sender, e) => senseAddedCount++; + m_lexicon.LexiconGlossAdded += (sender, e) => + { + glossAddedCount++; + glossText = e.Gloss.Text; + }; + + Lexeme lexeme = m_lexicon.FindOrCreateLexeme(LexemeType.Word, "word"); + m_lexicon.AddLexeme(lexeme); + LexiconSense sense = lexeme.AddSense(); + sense.AddGloss("en", "somegloss"); + + Assert.AreEqual(1, glossAddedCount); + Assert.AreEqual("somegloss", glossText); + } + + #endregion + + /// + /// Test find matching lexemes + /// + [Test] + public void FindMatchingLexemes() + { + Lexeme[] matchingLexemes = m_lexicon.FindMatchingLexemes("a").ToArray(); + Assert.That(matchingLexemes, Is.Empty); + + // Just the stem + Lexeme lexemeA = m_lexicon.CreateLexeme(LexemeType.Stem, "a"); + m_lexicon.AddLexeme(lexemeA); + matchingLexemes = m_lexicon.FindMatchingLexemes("a").ToArray(); + Assert.That(matchingLexemes[0].LexicalForm, Is.EqualTo("a")); + + // Other parts, too + Lexeme lexemePre = m_lexicon.CreateLexeme(LexemeType.Prefix, "pre"); + m_lexicon.AddLexeme(lexemePre); + Lexeme lexemeSuf = m_lexicon.CreateLexeme(LexemeType.Suffix, "suf"); + m_lexicon.AddLexeme(lexemeSuf); + m_lexicon.AddWordAnalysis(m_lexicon.CreateWordAnalysis("preasuf", new[] { lexemePre, lexemeA, lexemeSuf })); + matchingLexemes = m_lexicon.FindMatchingLexemes("preasuf").ToArray(); + Assert.That(matchingLexemes.Length, Is.EqualTo(3)); + Assert.IsTrue(matchingLexemes.Contains(lexemePre)); + Assert.IsTrue(matchingLexemes.Contains(lexemeA)); + Assert.IsTrue(matchingLexemes.Contains(lexemeSuf)); + } + + /// + /// Test find closest matching lexeme + /// + [Test] + public void FindClosestMatchingLexeme() + { + // Nothing found + Lexeme matchingLexeme = m_lexicon.FindClosestMatchingLexeme("a"); + Assert.IsNull(matchingLexeme); + + // Found by simple lexicon lookup + Lexeme lexeme = m_lexicon.CreateLexeme(LexemeType.Stem, "a"); + m_lexicon.AddLexeme(lexeme); + matchingLexeme = m_lexicon.FindClosestMatchingLexeme("a"); + Assert.IsTrue(matchingLexeme.LexicalForm == "a"); + + // Found by parser + lexeme = m_lexicon.CreateLexeme(LexemeType.Prefix, "pre"); + m_lexicon.AddLexeme(lexeme); + matchingLexeme = m_lexicon.FindClosestMatchingLexeme("prea"); + Assert.IsTrue(matchingLexeme.LexicalForm == "a"); + + // Found by unsupervised stemmer + m_lexicon.AddLexeme(m_lexicon.CreateLexeme(LexemeType.Stem, "b")); + m_lexicon.AddLexeme(m_lexicon.CreateLexeme(LexemeType.Stem, "c")); + m_lexicon.AddLexeme(m_lexicon.CreateLexeme(LexemeType.Stem, "d")); + m_lexicon.AddLexeme(m_lexicon.CreateLexeme(LexemeType.Stem, "bpos")); + m_lexicon.AddLexeme(m_lexicon.CreateLexeme(LexemeType.Stem, "cpos")); + m_lexicon.AddLexeme(m_lexicon.CreateLexeme(LexemeType.Stem, "dpos")); + matchingLexeme = m_lexicon.FindClosestMatchingLexeme("apos"); + Assert.IsTrue(matchingLexeme.LexicalForm == "a"); + } + + #endregion + } +} diff --git a/Src/FwParatextLexiconPlugin/FwParatextLexiconPluginTests/FwParatextLexiconPluginTests.csproj b/Src/FwParatextLexiconPlugin/FwParatextLexiconPluginTests/FwParatextLexiconPluginTests.csproj new file mode 100644 index 0000000000..a5262d78af --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FwParatextLexiconPluginTests/FwParatextLexiconPluginTests.csproj @@ -0,0 +1,86 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {04DB1DD6-082B-4453-8B83-0B40C019F149} + Library + Properties + SIL.FieldWorks.ParatextLexiconPlugin + FwParatextLexiconPluginTests + v4.0 + 512 + + + true + full + false + ..\..\..\Output\Debug\ + DEBUG;TRACE + prompt + 4 + x86 + ..\..\..\Output\Debug\FwParatextLexiconPluginTests.xml + true + + + pdbonly + true + ..\..\..\Output\Release\ + TRACE + prompt + 4 + x86 + + + + ..\..\..\Output\Debug\BasicUtils.dll + + + False + ..\..\..\Output\Debug\BasicUtilsTests.dll + + + ..\..\..\Output\Debug\COMInterfaces.dll + + + ..\..\..\Output\Debug\CoreImpl.dll + + + ..\..\..\Output\Debug\FDO.dll + + + False + ..\..\..\Output\Debug\FwParatextLexiconPlugin.dll + + + ..\..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll + + + ..\..\..\Bin\NUnit\bin\nunit.framework.dll + + + ..\..\..\DistFiles\Paratext.LexicalContracts.dll + + + + + + + Properties\AssemblyInfoForTests.cs + + + + + + + + \ No newline at end of file diff --git a/Src/FwParatextLexiconPlugin/FwParatextLexiconPluginTests/Properties/AssemblyInfo.cs b/Src/FwParatextLexiconPlugin/FwParatextLexiconPluginTests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..e38add4f9b --- /dev/null +++ b/Src/FwParatextLexiconPlugin/FwParatextLexiconPluginTests/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +using System.Reflection; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("FwParatextLexiconPluginTests")] diff --git a/Src/FwParatextLexiconPlugin/LexemeKey.cs b/Src/FwParatextLexiconPlugin/LexemeKey.cs new file mode 100644 index 0000000000..4fc23754b2 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/LexemeKey.cs @@ -0,0 +1,93 @@ +using System; +using System.Diagnostics; +using System.Globalization; +using System.Text.RegularExpressions; +using Paratext.LexicalContracts; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + internal class LexemeKey + { + private static readonly Regex s_idRegex = new Regex("^(\\w+):(.*?)(:\\d+)?$", RegexOptions.Compiled); + + private readonly LexemeType m_type; + private readonly string m_lexicalForm; + private readonly int m_homograph; + + public LexemeKey(LexemeType type, string lexicalForm) : this(type, lexicalForm, 1) + { + } + + public LexemeKey(LexemeType type, string lexicalForm, int homograph) + { + Debug.Assert(lexicalForm.IsNormalized(), "Key lexical forms should always be in composed form"); + + m_type = type; + m_lexicalForm = lexicalForm; + m_homograph = homograph; + } + + public LexemeKey(string id) + { + Match match = s_idRegex.Match(id); + Debug.Assert(match.Groups[2].Value.IsNormalized(), "Key lexical forms should always be in composed form"); + m_type = (LexemeType)Enum.Parse(typeof(LexemeType), match.Groups[1].Value); + m_lexicalForm = match.Groups[2].Value; + m_homograph = match.Groups[3].Length > 0 ? Int32.Parse(match.Groups[3].Value.Substring(1), CultureInfo.InvariantCulture) : 1; + } + + /// + /// Unique string identifier of the lexeme string. Unique within this lexicon type. + /// + public string Id + { + get + { + if (m_homograph == 1) + return string.Format("{0}:{1}", Type, LexicalForm); + + return string.Format("{0}:{1}:{2}", Type, LexicalForm, m_homograph); + } + } + + public LexemeType Type + { + get { return m_type; } + } + + public string LexicalForm + { + get { return m_lexicalForm; } + } + + public int Homograph + { + get { return m_homograph; } + } + + public override bool Equals(object obj) + { + var other = obj as LexemeKey; + + return other != null + && m_type == other.m_type + && m_lexicalForm == other.m_lexicalForm + && m_homograph == other.m_homograph; + } + + public override int GetHashCode() + { + int code = 23; + code = code * 31 + m_type.GetHashCode(); + code = code * 31 + m_lexicalForm.GetHashCode(); + code = code * 31 + m_homograph.GetHashCode(); + return code; + } + + public override string ToString() + { + return Id; + } + } + +} diff --git a/Src/FwParatextLexiconPlugin/LexiconUnavailableException.cs b/Src/FwParatextLexiconPlugin/LexiconUnavailableException.cs new file mode 100644 index 0000000000..10833248b9 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/LexiconUnavailableException.cs @@ -0,0 +1,21 @@ +using System; +using Paratext.LexicalContracts; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + /// + /// Lexicon unavailable exception + /// + public class LexiconUnavailableException : Exception + { + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + public LexiconUnavailableException(string message) + : base(message) + { + this.SetLexiconUnavailableException(); + } + } +} diff --git a/Src/FwParatextLexiconPlugin/ParatextLexiconPluginDirectoryFinder.cs b/Src/FwParatextLexiconPlugin/ParatextLexiconPluginDirectoryFinder.cs new file mode 100644 index 0000000000..a12778e2c7 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/ParatextLexiconPluginDirectoryFinder.cs @@ -0,0 +1,142 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Reflection; +using Microsoft.Win32; +using SIL.CoreImpl; +using SIL.FieldWorks.FDO; +using SIL.Utils; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + internal static class ParatextLexiconPluginDirectoryFinder + { + private static readonly IFdoDirectories s_fdoDirs = new ParatextLexiconPluginFdoDirectories(); + + static ParatextLexiconPluginDirectoryFinder() + { + RegistryHelper.CompanyName = DirectoryFinder.CompanyName; + RegistryHelper.ProductName = ProductName; + } + + private const string ProjectsDir = "ProjectsDir"; + private const string ProductName = "FieldWorks"; + private const string RootDataDir = "RootDataDir"; + private const string RootCodeDir = "RootCodeDir"; + private const string Projects = "Projects"; + private const string Templates = "Templates"; + private const string FdoVersion = "8"; + + public static string ProjectsDirectory + { + get { return GetDirectory(ProjectsDir, Path.Combine(DataDirectory, Projects)); } + } + + public static string ProjectsDirectoryLocalMachine + { + get { return GetDirectoryLocalMachine(ProjectsDir, Path.Combine(DataDirectoryLocalMachine, Projects)); } + } + + public static string TemplateDirectory + { + get { return Path.Combine(CodeDirectory, Templates); } + } + + public static bool IsFieldWorksInstalled + { + get + { + using (RegistryKey machineKey = FieldWorksRegistryKeyLocalMachine) + { + return machineKey != null; + } + } + } + + public static IFdoDirectories FdoDirectories + { + get { return s_fdoDirs; } + } + + public static string DataDirectory + { + get { return GetDirectory(RootDataDir, DirectoryFinder.CommonAppDataFolder(ProductName)); } + } + + public static string DataDirectoryLocalMachine + { + get { return GetDirectoryLocalMachine(RootDataDir, DirectoryFinder.CommonAppDataFolder(ProductName)); } + } + + public static string CodeDirectory + { + get { return GetDirectory(RootCodeDir, Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); } + } + + [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", + Justification = "Disposed in caller.")] + private static RegistryKey FieldWorksRegistryKey + { + get { return RegistryHelper.SettingsKey(FdoVersion); } + } + + [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", + Justification = "Disposed in caller.")] + private static RegistryKey FieldWorksRegistryKeyLocalMachine + { + get { return RegistryHelper.SettingsKeyLocalMachine(FdoVersion); } + } + + private static string GetDirectory(string registryValue, string defaultDir) + { + using (RegistryKey userKey = FieldWorksRegistryKey) + using (RegistryKey machineKey = FieldWorksRegistryKeyLocalMachine) + { + var registryKey = userKey; + if (userKey == null || userKey.GetValue(registryValue) == null) + { + registryKey = machineKey; + } + + return GetDirectory(registryKey, registryValue, defaultDir); + } + } + + private static string GetDirectory(RegistryKey registryKey, string registryValue, string defaultDir) + { + string rootDir = (registryKey == null) ? null : registryKey.GetValue(registryValue, null) as string; + + if (string.IsNullOrEmpty(rootDir) && !string.IsNullOrEmpty(defaultDir)) + rootDir = defaultDir; + if (string.IsNullOrEmpty(rootDir)) + { + throw new ApplicationException(); + } + // Hundreds of callers of this method are using Path.Combine with the results. + // Combine only works with a root directory if it is followed by \ (e.g., c:\) + // so we don't want to trim the \ in this situation. + string dir = rootDir.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); + return dir.Length > 2 ? dir : dir + Path.DirectorySeparatorChar; + } + + private static string GetDirectoryLocalMachine(string registryValue, string defaultDir) + { + using (RegistryKey machineKey = FieldWorksRegistryKeyLocalMachine) + { + return GetDirectory(machineKey, registryValue, defaultDir); + } + } + + private class ParatextLexiconPluginFdoDirectories : IFdoDirectories + { + public string ProjectsDirectory + { + get { return ParatextLexiconPluginDirectoryFinder.ProjectsDirectory; } + } + public string TemplateDirectory + { + get { return ParatextLexiconPluginDirectoryFinder.TemplateDirectory; } + } + } + } +} diff --git a/Src/FwParatextLexiconPlugin/ParatextLexiconPluginFdoUI.cs b/Src/FwParatextLexiconPlugin/ParatextLexiconPluginFdoUI.cs new file mode 100644 index 0000000000..eaeea93df7 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/ParatextLexiconPluginFdoUI.cs @@ -0,0 +1,192 @@ +using System; +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Windows.Forms; +using SIL.FieldWorks.FDO; +using SIL.Utils; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + internal class ParatextLexiconPluginFdoUI : IFdoUI + { + private readonly SynchronizeInvokeWrapper m_synchronizeInvoke; + private readonly UserActivityMonitor m_activityMonitor; + + public ParatextLexiconPluginFdoUI(ActivationContextHelper activationContext) + { + m_synchronizeInvoke = new SynchronizeInvokeWrapper(activationContext); + m_activityMonitor = new UserActivityMonitor(); + m_activityMonitor.StartMonitoring(); + } + + public bool ConflictingSave() + { + SynchronizeInvoke.Invoke(() => MessageBox.Show(Strings.ksConflictingSaveText, + Strings.ksConflictingSaveCaption, MessageBoxButtons.OK, MessageBoxIcon.Warning)); + return true; + } + + /// + /// Inform the user of a lost connection + /// + /// True if user wishes to attempt reconnect. False otherwise. + public bool ConnectionLost() + { + return SynchronizeInvoke.Invoke(() => MessageBox.Show(Strings.ksConnectionLostText, + Strings.ksConnectionLostCaption, MessageBoxButtons.YesNo) == DialogResult.Yes); + } + + public FileSelection ChooseFilesToUse() + { + using (var dlg = new FilesToRestoreAreOlder()) + { + if (dlg.ShowDialog() == DialogResult.OK) + { + if (dlg.fKeepFilesThatAreNewer) + { + return FileSelection.OkKeepNewer; + } + if (dlg.fOverWriteThatAreNewer) + { + return FileSelection.OkUseOlder; + } + } + return FileSelection.Cancel; + } + } + + public bool RestoreLinkedFilesInProjectFolder() + { + return SynchronizeInvoke.Invoke(() => MessageBox.Show( + Strings.ksRestoreLinkedFilesInProjectFolderText, Strings.ksRestoreLinkedFilesInProjectFolderCaption, + MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes); + } + + public YesNoCancel CannotRestoreLinkedFilesToOriginalLocation() + { + DialogResult result = SynchronizeInvoke.Invoke(() => MessageBox.Show( + Strings.ksCannotRestoreLinkedFilesToOriginalLocationText, Strings.ksCannotRestoreLinkedFilesToOriginalLocationCaption, + MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)); + switch (result) + { + case DialogResult.Yes: + return YesNoCancel.OkYes; + case DialogResult.No: + return YesNoCancel.OkNo; + } + return YesNoCancel.Cancel; + } + + public void DisplayMessage(MessageType type, string message, string caption, string helpTopic) + { + var icon = MessageBoxIcon.Information; + switch (type) + { + case MessageType.Error: + icon = MessageBoxIcon.Error; + break; + case MessageType.Info: + icon = MessageBoxIcon.Information; + break; + case MessageType.Warning: + icon = MessageBoxIcon.Warning; + break; + } + SynchronizeInvoke.Invoke(() => MessageBox.Show(message, caption, MessageBoxButtons.OK, icon)); + } + + public void ReportException(Exception error, bool isLethal) + { + // do nothing + } + + public void ReportDuplicateGuids(string errorText) + { + // do nothing + } + + public bool Retry(string msg, string caption) + { + return SynchronizeInvoke.Invoke(() => MessageBox.Show(msg, caption, + MessageBoxButtons.RetryCancel, MessageBoxIcon.None) == DialogResult.Retry); + } + + public bool OfferToRestore(string projectPath, string backupPath) + { + return SynchronizeInvoke.Invoke(() => MessageBox.Show( + String.Format(Strings.ksOfferToRestoreText, projectPath, File.GetLastWriteTime(projectPath), + backupPath, File.GetLastWriteTime(backupPath)), + Strings.ksOfferToRestoreCaption, MessageBoxButtons.YesNo, + MessageBoxIcon.Error) == DialogResult.Yes); + } + + public void Exit() + { + Application.Exit(); + } + + public ISynchronizeInvoke SynchronizeInvoke + { + get { return m_synchronizeInvoke; } + } + + public DateTime LastActivityTime + { + get { return m_activityMonitor.LastActivityTime; } + } + + [SuppressMessage("Gendarme.Rules.Design", "TypesWithDisposableFieldsShouldBeDisposableRule", + Justification="m_activationContext is a reference")] + private class SynchronizeInvokeWrapper : ISynchronizeInvoke + { + private readonly ActivationContextHelper m_activationContext; + + public SynchronizeInvokeWrapper(ActivationContextHelper activationContext) + { + m_activationContext = activationContext; + } + + private ISynchronizeInvoke SynchronizeInvoke + { + get + { + Form form = Form.ActiveForm; + if (form != null) + return form; + if (Application.OpenForms.Count > 0) + return Application.OpenForms[0]; + return null; + } + } + + public IAsyncResult BeginInvoke(Delegate method, object[] args) + { + return SynchronizeInvoke.BeginInvoke(new Func(() => + { + using (m_activationContext.Activate()) + return method.DynamicInvoke(args); + }), null); + } + + public object EndInvoke(IAsyncResult result) + { + return SynchronizeInvoke.EndInvoke(result); + } + + public object Invoke(Delegate method, object[] args) + { + return SynchronizeInvoke.Invoke(new Func(() => + { + using (m_activationContext) + return method.DynamicInvoke(args); + }), null); + } + + public bool InvokeRequired + { + get { return SynchronizeInvoke.InvokeRequired; } + } + } + } +} diff --git a/Src/FwParatextLexiconPlugin/ParatextLexiconPluginProjectID.cs b/Src/FwParatextLexiconPlugin/ParatextLexiconPluginProjectID.cs new file mode 100644 index 0000000000..4b31f28663 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/ParatextLexiconPluginProjectID.cs @@ -0,0 +1,63 @@ +using System; +using SIL.FieldWorks.FDO; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + internal class ParatextLexiconPluginProjectID : IProjectIdentifier + { + private readonly FDOBackendProviderType m_backendProviderType; + + public ParatextLexiconPluginProjectID(FDOBackendProviderType backendProviderType, string projectPath) + { + m_backendProviderType = backendProviderType; + Path = projectPath; + } + + public bool IsLocal + { + get { return true; } + } + + public string Path { get; set; } + + public string ProjectFolder + { + get { return System.IO.Path.GetDirectoryName(Path); } + } + + public string SharedProjectFolder + { + get { return ProjectFolder; } + } + + public string ServerName + { + get { return null; } + } + + public string Handle + { + get { return Name; } + } + + public string PipeHandle + { + get { throw new NotImplementedException(); } + } + + public string Name + { + get { return System.IO.Path.GetFileNameWithoutExtension(Path); } + } + + public FDOBackendProviderType Type + { + get { return m_backendProviderType; } + } + + public string UiName + { + get { return Name; } + } + } +} diff --git a/Src/FwParatextLexiconPlugin/ParatextLexiconPluginThreadedProgress.cs b/Src/FwParatextLexiconPlugin/ParatextLexiconPluginThreadedProgress.cs new file mode 100644 index 0000000000..06cbfb644b --- /dev/null +++ b/Src/FwParatextLexiconPlugin/ParatextLexiconPluginThreadedProgress.cs @@ -0,0 +1,89 @@ +using System; +using System.ComponentModel; +using SIL.Utils; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + internal class ParatextLexiconPluginThreadedProgress : IThreadedProgress + { + private readonly ISynchronizeInvoke m_synchronizeInvoke; + + public ParatextLexiconPluginThreadedProgress(ISynchronizeInvoke synchronizeInvoke) + { + m_synchronizeInvoke = synchronizeInvoke; + } + + public void Step(int amount) + { + Position += amount * StepSize; + //Progress.Mgr.Incr(amount * StepSize); + } + + public string Title { get; set; } + + public string Message + { + //get { return Progress.Mgr.Text; } + //set { Progress.Mgr.Text = value; } + get; set; + } + + public int Position + { + //get { return Progress.Mgr.Value; } + //set { Progress.Mgr.Value = value; } + get; set; + } + + public int StepSize { get; set; } + + public int Minimum { get; set; } + + public int Maximum { get; set; } + + public ISynchronizeInvoke SynchronizeInvoke + { + get { return m_synchronizeInvoke; } + } + + public bool IsIndeterminate { get; set; } + + public bool AllowCancel { get; set; } + + public event CancelEventHandler Canceling; + + public object RunTask(Func backgroundTask, params object[] parameters) + { + return RunTask(true, backgroundTask, parameters); + } + + public object RunTask(bool fDisplayUi, Func backgroundTask, params object[] parameters) + { + object result = backgroundTask(this, parameters); + //if (Progress.Mgr.InProgress) + //{ + // result = backgroundTask(this, parameters); + //} + //else + //{ + // ProgressUtils.Execute(Title, AllowCancel ? CancelModes.Cancelable : CancelModes.NonCancelable, () => + // { + // if (!IsIndeterminate) + // Progress.Mgr.Begin(Minimum, Maximum); + + // result = backgroundTask(this, parameters); + + // if (!IsIndeterminate) + // Progress.Mgr.End(); + // }); + //} + return result; + } + + public bool Canceled + { + //get { return Progress.Mgr.Cancelled; } + get; set; + } + } +} diff --git a/Src/FwParatextLexiconPlugin/ProjectExistsForm.Designer.cs b/Src/FwParatextLexiconPlugin/ProjectExistsForm.Designer.cs new file mode 100644 index 0000000000..13f6e97efa --- /dev/null +++ b/Src/FwParatextLexiconPlugin/ProjectExistsForm.Designer.cs @@ -0,0 +1,76 @@ +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + partial class ProjectExistsForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + System.Diagnostics.Debug.WriteLineIf(!disposing, "****** Missing Dispose() call for " + GetType() + ". ****** "); + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProjectExistsForm)); + this.btnOverwrite = new System.Windows.Forms.Button(); + this.btnRename = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // btnOverwrite + // + resources.ApplyResources(this.btnOverwrite, "btnOverwrite"); + this.btnOverwrite.Name = "btnOverwrite"; + this.btnOverwrite.UseVisualStyleBackColor = true; + this.btnOverwrite.Click += new System.EventHandler(this.btnOverwrite_Click); + // + // btnRename + // + resources.ApplyResources(this.btnRename, "btnRename"); + this.btnRename.Name = "btnRename"; + this.btnRename.UseVisualStyleBackColor = true; + this.btnRename.Click += new System.EventHandler(this.btnRename_Click); + // + // label1 + // + resources.ApplyResources(this.label1, "label1"); + this.label1.Name = "label1"; + // + // ProjectExistsForm + // + resources.ApplyResources(this, "$this"); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.label1); + this.Controls.Add(this.btnRename); + this.Controls.Add(this.btnOverwrite); + this.Name = "ProjectExistsForm"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnOverwrite; + private System.Windows.Forms.Button btnRename; + private System.Windows.Forms.Label label1; + } +} \ No newline at end of file diff --git a/Src/FwParatextLexiconPlugin/ProjectExistsForm.cs b/Src/FwParatextLexiconPlugin/ProjectExistsForm.cs new file mode 100644 index 0000000000..48cbd46ca1 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/ProjectExistsForm.cs @@ -0,0 +1,32 @@ +using System; +using System.Windows.Forms; + +namespace SIL.FieldWorks.ParatextLexiconPlugin +{ + internal partial class ProjectExistsForm : Form + { + private ProjectExistsForm() + { + InitializeComponent(); + + Icon = System.Drawing.SystemIcons.Warning; + } + + public ProjectExistsForm(string projectName) : this() + { + label1.Text = string.Format(Strings.ksProjectExistsText1, projectName) + Environment.NewLine + Strings.ksProjectExistsText2; + DialogResult = DialogResult.Cancel; + } + + private void btnOverwrite_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.OK; + Close(); + } + + private void btnRename_Click(object sender, EventArgs e) + { + Close(); + } + } +} diff --git a/Src/FwParatextLexiconPlugin/ProjectExistsForm.resx b/Src/FwParatextLexiconPlugin/ProjectExistsForm.resx new file mode 100644 index 0000000000..2f8844c58e --- /dev/null +++ b/Src/FwParatextLexiconPlugin/ProjectExistsForm.resx @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + 189, 85 + + + 75, 23 + + + + 0 + + + Overwrite + + + btnOverwrite + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 2 + + + 271, 84 + + + 75, 23 + + + 1 + + + Rename + + + btnRename + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 1 + + + True + + + 13, 13 + + + 50, 13 + + + 2 + + + labelText + + + label1 + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 0 + + + True + + + 6, 13 + + + 360, 121 + + + Project Already Exists + + + ProjectExistsForm + + + System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Src/FwParatextLexiconPlugin/Properties/AssemblyInfo.cs b/Src/FwParatextLexiconPlugin/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..78ff41fa5a --- /dev/null +++ b/Src/FwParatextLexiconPlugin/Properties/AssemblyInfo.cs @@ -0,0 +1,19 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("FwParatextLexiconPlugin")] +[assembly: AssemblyDescription("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a787fc88-0ff6-4982-9305-8da92ef8fc7f")] + +[assembly: InternalsVisibleTo("FwParatextLexiconPluginTests")] diff --git a/Src/FwParatextLexiconPlugin/Properties/Resources.Designer.cs b/Src/FwParatextLexiconPlugin/Properties/Resources.Designer.cs new file mode 100644 index 0000000000..68d5661ba1 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/Properties/Resources.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.18444 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SIL.FieldWorks.ParatextLexiconPlugin.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SIL.FieldWorks.ParatextLexiconPlugin.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap question { + get { + object obj = ResourceManager.GetObject("question", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/Src/FwParatextLexiconPlugin/Properties/Resources.resx b/Src/FwParatextLexiconPlugin/Properties/Resources.resx new file mode 100644 index 0000000000..465338dcd5 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/Properties/Resources.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\question.ico;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/Src/FwParatextLexiconPlugin/Resources/question.ico b/Src/FwParatextLexiconPlugin/Resources/question.ico new file mode 100644 index 0000000000..b16ecb8719 Binary files /dev/null and b/Src/FwParatextLexiconPlugin/Resources/question.ico differ diff --git a/Src/FwParatextLexiconPlugin/Strings.Designer.cs b/Src/FwParatextLexiconPlugin/Strings.Designer.cs new file mode 100644 index 0000000000..4fac61bb7c --- /dev/null +++ b/Src/FwParatextLexiconPlugin/Strings.Designer.cs @@ -0,0 +1,216 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.18444 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SIL.FieldWorks.ParatextLexiconPlugin { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Strings { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Strings() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SIL.FieldWorks.ParatextLexiconPlugin.Strings", typeof(Strings).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Problem With Backup File. + /// + internal static string ksBackupFileProblemCaption { + get { + return ResourceManager.GetString("ksBackupFileProblemCaption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to An error occurred. Please select a different file.. + /// + internal static string ksBackupFileProblemText { + get { + return ResourceManager.GetString("ksBackupFileProblemText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cannot Restore Linked Files. + /// + internal static string ksCannotRestoreLinkedFilesToOriginalLocationCaption { + get { + return ResourceManager.GetString("ksCannotRestoreLinkedFilesToOriginalLocationCaption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ParaTExt cannot restore the linked files to their original location. If you choose to restore the linked files, they will be placed inside the project folder. Do you wish to restore the linked files anyway? . + /// + internal static string ksCannotRestoreLinkedFilesToOriginalLocationText { + get { + return ResourceManager.GetString("ksCannotRestoreLinkedFilesToOriginalLocationText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cannot Save Lexicon. + /// + internal static string ksConflictingSaveCaption { + get { + return ResourceManager.GetString("ksConflictingSaveCaption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ParaTExt cannot save changes to the lexicon, because they conflict with changes made by another user or application. The conflicting changes will be reverted.. + /// + internal static string ksConflictingSaveText { + get { + return ResourceManager.GetString("ksConflictingSaveText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lexicon Connection Lost. + /// + internal static string ksConnectionLostCaption { + get { + return ResourceManager.GetString("ksConnectionLostCaption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to There is a problem with the connection to the lexicon. Usually, this occurs when there is a problem with the FwRemoteDatabaseConnectorService. Would you like to attempt to reestablish the connection?. + /// + internal static string ksConnectionLostText { + get { + return ResourceManager.GetString("ksConnectionLostText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Could not connect to server. Check service is running and that any running firewalls are configured to allow connections to the service.. + /// + internal static string ksCouldNotConnectText { + get { + return ResourceManager.GetString("ksCouldNotConnectText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Problem opening file. + /// + internal static string ksOfferToRestoreCaption { + get { + return ResourceManager.GetString("ksOfferToRestoreCaption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to There was a problem opening the current version of the file {0}, dated {1}. Would you like to open the automatic backup, {2}, dated {3}?. + /// + internal static string ksOfferToRestoreText { + get { + return ResourceManager.GetString("ksOfferToRestoreText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The {0} project already exists.. + /// + internal static string ksProjectExistsText1 { + get { + return ResourceManager.GetString("ksProjectExistsText1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You may overwrite the existing project or select a different name.. + /// + internal static string ksProjectExistsText2 { + get { + return ResourceManager.GetString("ksProjectExistsText2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Linked Files Folder. + /// + internal static string ksRestoreLinkedFilesInProjectFolderCaption { + get { + return ResourceManager.GetString("ksRestoreLinkedFilesInProjectFolderCaption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Linked Files folder was not previously stored in the project folder. Would you like ParaTExt to restore the linked files within the project folder?. + /// + internal static string ksRestoreLinkedFilesInProjectFolderText { + get { + return ResourceManager.GetString("ksRestoreLinkedFilesInProjectFolderText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to An error occurred and the project could not be restored.. + /// + internal static string ksRestoreProblemText { + get { + return ResourceManager.GetString("ksRestoreProblemText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Warning. + /// + internal static string ksWarningCaption { + get { + return ResourceManager.GetString("ksWarningCaption", resourceCulture); + } + } + } +} diff --git a/Src/FwParatextLexiconPlugin/Strings.resx b/Src/FwParatextLexiconPlugin/Strings.resx new file mode 100644 index 0000000000..ca81e5a929 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/Strings.resx @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ParaTExt cannot save changes to the lexicon, because they conflict with changes made by another user or application. The conflicting changes will be reverted. + + + Cannot Save Lexicon + + + There is a problem with the connection to the lexicon. Usually, this occurs when there is a problem with the FwRemoteDatabaseConnectorService. Would you like to attempt to reestablish the connection? + + + Lexicon Connection Lost + + + Problem opening file + + + There was a problem opening the current version of the file {0}, dated {1}. Would you like to open the automatic backup, {2}, dated {3}? + + + The {0} project already exists. + + + You may overwrite the existing project or select a different name. + + + Warning + + + Could not connect to server. Check service is running and that any running firewalls are configured to allow connections to the service. + + + Problem With Backup File + + + An error occurred. Please select a different file. + + + An error occurred and the project could not be restored. + + + Cannot Restore Linked Files + + + ParaTExt cannot restore the linked files to their original location. If you choose to restore the linked files, they will be placed inside the project folder. Do you wish to restore the linked files anyway? + + + Linked Files Folder + + + The Linked Files folder was not previously stored in the project folder. Would you like ParaTExt to restore the linked files within the project folder? + + \ No newline at end of file diff --git a/Src/FwParatextLexiconPlugin/gendarme-FwParatextLexiconPlugin.ignore b/Src/FwParatextLexiconPlugin/gendarme-FwParatextLexiconPlugin.ignore new file mode 100644 index 0000000000..7d65c093e9 --- /dev/null +++ b/Src/FwParatextLexiconPlugin/gendarme-FwParatextLexiconPlugin.ignore @@ -0,0 +1,7 @@ +# Gendarme filter file to suppress reporting of defects + +#----------------------------------------------------------------------------------------------- +R: Gendarme.Rules.Correctness.EnsureLocalDisposalRule + +# Don't need to dipose IEnumerator +M: System.Collections.IEnumerator SIL.FieldWorks.ParatextLexiconPlugin.FdoLexicon/d__25::System.Collections.IEnumerable.GetEnumerator() diff --git a/Src/FwParatextLexiconPlugin/question.ico b/Src/FwParatextLexiconPlugin/question.ico new file mode 100644 index 0000000000..b16ecb8719 Binary files /dev/null and b/Src/FwParatextLexiconPlugin/question.ico differ diff --git a/Src/FwResources/FwFileExtensions.cs b/Src/FwResources/FwFileExtensions.cs index f7fb685d0f..79aef21b28 100644 --- a/Src/FwResources/FwFileExtensions.cs +++ b/Src/FwResources/FwFileExtensions.cs @@ -14,14 +14,6 @@ namespace SIL.FieldWorks.Resources /// ---------------------------------------------------------------------------------------- public static class FwFileExtensions { - /// Default extension for FieldWorks XML data files (with the period) - public const string ksFwDataXmlFileExtension = ".fwdata"; - /// Default extension for FieldWorks DB4o data files (with the period) - public const string ksFwDataDb4oFileExtension = ".fwdb"; - /// Default extension for FieldWorks backup files (with the period). - public const string ksFwBackupFileExtension = ".fwbackup"; - /// Default extension for FieldWorks 6.0 and earlier backup files (with the period). - public const string ksFw60BackupFileExtension = ".zip"; /// Default extension for Scripture XML (Open XML for Editing Scripture) files (with the period). public const string ksOpenXmlForEditingScripture = ".oxes"; /// Default extension for Scripture annotations XML (Open XML for Exchanging Scripture Annotations) files (with the period). @@ -30,8 +22,6 @@ public static class FwFileExtensions public const string ksOpenXmlForExchangingKeyTerms = ".oxekt"; /// Default extension for Lexicon Interchange FormaT files (with the period). public const string ksLexiconInterchangeFormat = ".lift"; - /// Default extension for FieldWorks TEMPORARY fallback data files (with the period). - public const string ksFwDataFallbackFileExtension = ".bak"; /// Default extension for FlexText format interlinear texts. public const string ksFLexText = ".flextext"; } diff --git a/Src/FwResources/FwResources.csproj b/Src/FwResources/FwResources.csproj index f39bcbdb66..ae90ff0430 100644 --- a/Src/FwResources/FwResources.csproj +++ b/Src/FwResources/FwResources.csproj @@ -102,6 +102,10 @@ x86 + + False + ..\..\Output\Debug\FDO.dll + System diff --git a/Src/FwResources/FwStrings.Designer.cs b/Src/FwResources/FwStrings.Designer.cs index 8f3a25b232..926a270efb 100644 --- a/Src/FwResources/FwStrings.Designer.cs +++ b/Src/FwResources/FwStrings.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.1008 +// Runtime Version:4.0.30319.18444 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -60,19 +60,6 @@ internal FwStrings() { } } - /// - /// Looks up a localized string similar to Backup file contains a version of the project which was created using a newer version of FieldWorks: - ///{0} - /// - ///To restore from this backup, install version {1} of FieldWorks. - ///. - /// - internal static string ksBackupFileCreatedByNewerFwVersion { - get { - return ResourceManager.GetString("ksBackupFileCreatedByNewerFwVersion", resourceCulture); - } - } - /// /// Looks up a localized string similar to .... /// @@ -83,11 +70,11 @@ internal static string ksEllipsis { } /// - /// Looks up a localized string similar to File is not a valid FieldWorks backup:. + /// Looks up a localized string similar to FieldWorks has encountered a problem setting up the writing systems. It may be that you need to first log out and then back in. If that doesn't fix it, you can also try asking an administrator to add you to the fieldworks group by using the command: $ sudo adduser 'yourusername' fieldworks. /// - internal static string ksInvalidFwBackupFile { + internal static string ksNeedToJoinFwGroup { get { - return ResourceManager.GetString("ksInvalidFwBackupFile", resourceCulture); + return ResourceManager.GetString("ksNeedToJoinFwGroup", resourceCulture); } } @@ -235,15 +222,6 @@ internal static string kstidAllVideo { } } - /// - /// Looks up a localized string similar to analysis. - /// - internal static string kstidAnalysis { - get { - return ResourceManager.GetString("kstidAnalysis", resourceCulture); - } - } - /// /// Looks up a localized string similar to Anthropology Codes. /// @@ -460,6 +438,24 @@ internal static string kstidCurrentScriptureProject { } } + /// + /// Looks up a localized string similar to Error migrating project. + /// + internal static string kstidDataMigrationProhibitedCaption { + get { + return ResourceManager.GetString("kstidDataMigrationProhibitedCaption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This project cannot be migrated to a newer version. Please shutdown all other applications that are currently using this project and try opening the project again.. + /// + internal static string kstidDataMigrationProhibitedText { + get { + return ResourceManager.GetString("kstidDataMigrationProhibitedText", resourceCulture); + } + } + /// /// Looks up a localized string similar to Date Created. /// @@ -1669,15 +1665,6 @@ internal static string kstidImportMapping { } } - /// - /// Looks up a localized string similar to Style {0} could not be added because an incompatible style with the same name already exists.. - /// - internal static string kstidIncompatibleStyleExists { - get { - return ResourceManager.GetString("kstidIncompatibleStyleExists", resourceCulture); - } - } - /// /// Looks up a localized string similar to Initializing Window.... /// @@ -1876,15 +1863,6 @@ internal static string kstidNotBaseCharErrorMsg { } } - /// - /// Looks up a localized string similar to FieldWorks project has no current {0} writing systems.. - /// - internal static string kstidNoWritingSystems { - get { - return ResourceManager.GetString("kstidNoWritingSystems", resourceCulture); - } - } - /// /// Looks up a localized string similar to Outdated Version of FieldWorks. /// @@ -2321,15 +2299,6 @@ internal static string kstidSavingChanges { } } - /// - /// Looks up a localized string similar to Footnote. - /// - internal static string kstidScriptureFootnote { - get { - return ResourceManager.GetString("kstidScriptureFootnote", resourceCulture); - } - } - /// /// Looks up a localized string similar to Introduction. /// @@ -2339,15 +2308,6 @@ internal static string kstidScriptureIntro { } } - /// - /// Looks up a localized string similar to Introduction({0}). - /// - internal static string kstidScriptureSectionIntroduction { - get { - return ResourceManager.GetString("kstidScriptureSectionIntroduction", resourceCulture); - } - } - /// /// Looks up a localized string similar to Title. /// @@ -2817,15 +2777,6 @@ internal static string kstidUserStyleSuffix { } } - /// - /// Looks up a localized string similar to vernacular. - /// - internal static string kstidVernacular { - get { - return ResourceManager.GetString("kstidVernacular", resourceCulture); - } - } - /// /// Looks up a localized string similar to Version History. /// diff --git a/Src/FwResources/FwStrings.resx b/Src/FwResources/FwStrings.resx index 6471a490e3..0eb5a042f6 100644 --- a/Src/FwResources/FwStrings.resx +++ b/Src/FwResources/FwStrings.resx @@ -901,10 +901,6 @@ only in multiple-paragraph fields like 'Description' Updating: '{0}' ... This is the status message for the progress dialog used when creating factory (default) styles. (Creating styles requires up to four passes. The message is for the second pass.) - - FieldWorks project has no current {0} writing systems. - Message box displayed if count of current vernacular/analysis writing systems is 0. (parameter is either verncaular or analysis) - Warning Title for warning message box @@ -928,9 +924,6 @@ only in multiple-paragraph fields like 'Description' All Vernacular and Analysis - - analysis - Best Analysis @@ -952,9 +945,6 @@ only in multiple-paragraph fields like 'Description' Default Vernacular - - vernacular - No Filter The name for the no filters menu item @@ -967,18 +957,9 @@ only in multiple-paragraph fields like 'Description' ... ellipsis - mark showing missing words, "more to come", or more info than is displayed. - - Footnote - - - Introduction({0}) - Introduction - - Title - A4 for list of paper sizes in Page Setup dialog @@ -1011,10 +992,6 @@ only in multiple-paragraph fields like 'Description' The gutter is too big for the publication page to fit on the selected paper size. error message from Page Setup dialog - - Style {0} could not be added because an incompatible style with the same name already exists. - Error message when someone adds a style that has been added on another machine that is incompatible (e.g. because of different context, structure, etc). - Paratext Language Files Used in the Browse for Language File filter accessed from the Valid Characters dialog box @@ -1361,16 +1338,6 @@ FieldWorks ReadMe for help in this area. FieldWorks Project Files Used in the list of file types in file open dialogs - - File is not a valid FieldWorks backup: - - - Backup file contains a version of the project which was created using a newer version of FieldWorks: -{0} - -To restore from this backup, install version {1} of FieldWorks. - - Unable to restore. @@ -1445,4 +1412,17 @@ To restore from this backup, install version {1} of FieldWorks. Adding FieldWorks project Used in Archive with RAMP dialog box + + FieldWorks has encountered a problem setting up the writing systems. It may be that you need to first log out and then back in. If that doesn't fix it, you can also try asking an administrator to add you to the fieldworks group by using the command: $ sudo adduser 'yourusername' fieldworks + Used in Linux version if the user forgets to logout and back in after New Install. + + + Title + + + Error migrating project + + + This project cannot be migrated to a newer version. Please shutdown all other applications that are currently using this project and try opening the project again. + \ No newline at end of file diff --git a/Src/FwResources/ResourceHelper.cs b/Src/FwResources/ResourceHelper.cs index 23e633fbde..244248d886 100644 --- a/Src/FwResources/ResourceHelper.cs +++ b/Src/FwResources/ResourceHelper.cs @@ -16,6 +16,7 @@ using System.Resources; using System.Text; using System.Windows.Forms; +using SIL.FieldWorks.FDO; using SIL.Utils; namespace SIL.FieldWorks.Resources @@ -167,10 +168,10 @@ static ResourceHelper() s_fileFilterExtensions[FileFilterType.InterlinearSfm] = "*.db; *.sfm; *.sf; *.it; *.itx; *.txt"; s_fileFilterExtensions[FileFilterType.ShoeboxProjectFiles] = "*.prj"; s_fileFilterExtensions[FileFilterType.FieldWorksProjectFiles] = - "*" + FwFileExtensions.ksFwDataXmlFileExtension + "; *" + FwFileExtensions.ksFwDataDb4oFileExtension; - s_fileFilterExtensions[FileFilterType.FieldWorksBackupFiles] = "*" + FwFileExtensions.ksFwBackupFileExtension; + "*" + FdoFileHelper.ksFwDataXmlFileExtension + "; *" + FdoFileHelper.ksFwDataDb4oFileExtension; + s_fileFilterExtensions[FileFilterType.FieldWorksBackupFiles] = "*" + FdoFileHelper.ksFwBackupFileExtension; s_fileFilterExtensions[FileFilterType.FieldWorksAllBackupFiles] = String.Format("*{0}; *{1}; *.xml", - FwFileExtensions.ksFwBackupFileExtension, FwFileExtensions.ksFw60BackupFileExtension); + FdoFileHelper.ksFwBackupFileExtension, FdoFileHelper.ksFw60BackupFileExtension); s_fileFilterExtensions[FileFilterType.FieldWorksTranslatedLists] = "*.xml; *.zip"; s_fileFilterExtensions[FileFilterType.OXEKT] = "*" + FwFileExtensions.ksOpenXmlForExchangingKeyTerms; s_fileFilterExtensions[FileFilterType.FLExText] = "*" + FwFileExtensions.ksFLexText; diff --git a/Src/Generic/Generic.rc b/Src/Generic/Generic.rc index ca3c11cd9b..b496a1b6b5 100644 --- a/Src/Generic/Generic.rc +++ b/Src/Generic/Generic.rc @@ -1,4 +1,5 @@ // Resources used by generic code +#include "GenericResource.h" // TODO DevLeader(JohnT): move these out of AppCore; include this file everywhere it's needed. STRINGTABLE DISCARDABLE diff --git a/Src/Kernel/FwKernel.mak b/Src/Kernel/FwKernel.mak index bfbbceeaa6..88d8617d39 100644 --- a/Src/Kernel/FwKernel.mak +++ b/Src/Kernel/FwKernel.mak @@ -15,21 +15,21 @@ FWKERNEL_SRC=$(BUILD_ROOT)\src\Kernel GENERIC_SRC=$(BUILD_ROOT)\src\Generic APPCORE_SRC=$(BUILD_ROOT)\src\AppCore DEBUGPROCS_SRC=$(BUILD_ROOT)\src\DebugProcs - +CELLAR_SRC=$(BUILD_ROOT)\Src\Cellar +GRUTIL_LIB=$(BUILD_ROOT)\Src\Graphite\lib +TTFUTIL_LIB=$(BUILD_ROOT)\Src\Graphite\TtfUtil +VIEWS_LIB=$(BUILD_ROOT)\Src\Views\lib +GRFW_SRC=$(BUILD_ROOT)\Src\Graphite\FwOnly # Set the USER_INCLUDE environment variable. -UI=$(FWKERNEL_SRC);$(GENERIC_SRC);$(APPCORE_SRC);$(DEBUGPROCS_SRC) - -LANGUAGE_SRC=$(BUILD_ROOT)\src\Language -UI=$(UI);$(LANGUAGE_SRC) +UI=$(FWKERNEL_SRC);$(GENERIC_SRC);$(APPCORE_SRC);$(DEBUGPROCS_SRC);$(CELLAR_SRC) !IF "$(USER_INCLUDE)"!="" -USER_INCLUDE=$(UI);$(USER_INCLUDE) +USER_INCLUDE=$(UI);$(USER_INCLUDE);$(GRUTIL_LIB);$(TTFUTIL_LIB);$(VIEWS_LIB);$(GRFW_SRC) !ELSE -USER_INCLUDE=$(UI) +USER_INCLUDE=$(UI);$(GRUTIL_LIB);$(TTFUTIL_LIB);$(VIEWS_LIB);$(GRFW_SRC) !ENDIF - !INCLUDE "$(BUILD_ROOT)\bld\_init.mak" !INCLUDE "$(BUILD_ROOT)\bld\_rule.mak" @@ -38,7 +38,7 @@ PATH=$(COM_OUT_DIR);$(PATH) RCFILE=FwKernel.rc DEFFILE=FwKernel.def -LINK_LIBS=Generic.lib xmlparse-utf16.lib $(LINK_LIBS) +LINK_LIBS=Generic.lib xmlparse-utf16.lib Usp10.lib $(LINK_LIBS) # === Object Lists === @@ -52,10 +52,21 @@ OBJ_FWKERNEL=\ $(INT_DIR)\autopch\TsMultiStr.obj\ $(INT_DIR)\usepch\TextProps1.obj\ $(INT_DIR)\autopch\ActionHandler.obj\ + $(INT_DIR)\genpch\RegexMatcherWrapper.obj\ + $(INT_DIR)\autopch\LgIcuWrappers.obj\ + $(INT_DIR)\autopch\UniscribeEngine.obj\ + $(INT_DIR)\autopch\UniscribeSegment.obj\ + $(INT_DIR)\autopch\RomRenderEngine.obj\ + $(INT_DIR)\autopch\RomRenderSegment.obj\ + $(INT_DIR)\autopch\LgSimpleEngines.obj\ + $(INT_DIR)\autopch\LgIcuCharPropEngine.obj\ + $(INT_DIR)\autopch\LgUnicodeCollater.obj\ + $(INT_DIR)\autopch\LgKeymanHandler.obj\ $(INT_DIR)\autopch\ModuleEntry.obj\ $(INT_DIR)\autopch\FwStyledText.obj\ $(INT_DIR)\autopch\WriteXml.obj\ $(INT_DIR)\autopch\DebugReport.obj\ + $(INT_DIR)\autopch\FwXml.obj\ $(INT_DIR)\autopch\dlldatax.obj\ @@ -83,6 +94,9 @@ ARG_SRCDIR=$(GENERIC_SRC) ARG_SRCDIR=$(APPCORE_SRC) !INCLUDE "$(BUILD_ROOT)\bld\_rule.mak" +ARG_SRCDIR=$(CELLAR_SRC) +!INCLUDE "$(BUILD_ROOT)\bld\_rule.mak" + # === Custom Rules === diff --git a/Src/Kernel/FwKernel.rc b/Src/Kernel/FwKernel.rc index 284f6e5046..aad905c1d4 100644 --- a/Src/Kernel/FwKernel.rc +++ b/Src/Kernel/FwKernel.rc @@ -12,11 +12,10 @@ Description: -------------------------------------------------------------------------------*//*:End Ignore*/ 1 TYPELIB FwKernelTlb.tlb - -#include "GenericResource.h" #if WIN32 #include "winresrc.h" #endif +#include "LangResource.h" #include "Generic.rc" @@ -62,3 +61,383 @@ BEGIN VALUE "Translation", 0x409, 1200 END END + +STRINGTABLE DISCARDABLE +BEGIN + kstidBufferTooSmall "The buffer passed to this method was too small to hold the result." + kstidFracNumVal "Can't report a fractional numeric value" + kstidNoNumeric "Unicode does not define a numeric value for this character" + kstidInvalidUnicode "Found an invalid Unicode character or sequence" + kstidICUCharName "The ICU code retrieving the Unicode character name found an error." + kstidICUDecomp "The ICU code finding the Unicode decomposition encountered an error." + kstidICUNormalize "The ICU code normalizing the text found an error." + kstidICUCase "The ICU function for changing the case found an error." + kstidICUBrkInit "The ICU function to initialize the BreakIterator returned an error." + kstidICUBrkRange "The line break asked for was out of range of the given text." + kstidLangDefaultCollation "DefaultCollation" + kstidUserWs "en" // unless and until someone translates all our resources and + // fixes up the resulting problems in the code. + kstidKeymanInitFailedCaption "Keyman initialization failed" + kstidKeymanInitUnexpectedFailMsg "Unexpected Keyman failure" + kstidKeymanNotRegisteredMsg "No known version of Keyman is registered." + kstidKeymanRootNotRegisteredMsg "Keyman program is not registered correctly." + kstidKeymanDllLoadFailureMsg "Failed to load Keyman32.dll" +END + +STRINGTABLE DISCARDABLE +BEGIN + kstidLangDefXmlMsg001 "Missing CharDef code attribute value.\n" + kstidLangDefXmlMsg002 "Missing CharDef data attribute value.\n" + kstidLangDefXmlMsg003 "Invalid CharDef code attribute value: ""%<0>s"".\n" + kstidLangDefXmlMsg004 "Missing Font file attribute value.\n" + kstidLangDefXmlMsg005 "Missing LgWritingSystem definition!?\n" + kstidLangDefXmlMsg006 "Unbalanced object stack!?\n" + kstidLangDefXmlMsg007 "Unbalanced property value stack!?\n" + kstidLangDefXmlMsg008 "Cannot put multiple objects in an atomic property.\n" + kstidLangDefXmlMsg009 "Cannot open language definition file ""%<0>s""!?\n" + kstidLangDefXmlMsg010 "Error accessing language definition file ""%<0>s""!?\n" + kstidLangDefXmlMsg011 "XML parser detected an XML syntax error!\n" + kstidLangDefXmlMsg012 "Error detected while parsing XML file!\n" + kstidLangDefXmlMsg013 "Missing EncodingConverter install attribute value.\n" +END + +STRINGTABLE DISCARDABLE +BEGIN + kstidLangDefXmlMsg014 "Problem while opening project" + kstidLangDefXmlMsg015 "The %<0>s writing system could not be installed, possibly due to insufficient user privileges.%nThis may affect sorting, special character definitions, and other aspects of the writing system.%n" +END + +// Message strings for the XML import/export process. These are shared with the Language DLL. + +STRINGTABLE DISCARDABLE +BEGIN + kstidXmlUserWs "en" +END + +STRINGTABLE DISCARDABLE +BEGIN + kstidXmlInfoMsg001 " %<0>d %<1>s processed, %<2>d successful, %<3>d attempted\n" + kstidParameter "Parameter" + kstidParameters "Parameters" + kstidXmlInfoMsg002 "%<0>d custom %<1>s have been added to the database schema.\n" + kstidField "field" + kstidFields "fields" + kstidXmlInfoMsg003 "First pass of reading the XML file took %<0>d %<1>s.\n" + kstidXmlInfoMsg007 "Creating %<0>d objects after the first pass took %<1>d %<2>s.\n" + kstidXmlInfoMsg009 "Second pass of reading the XML file took %d %s.\n" + kstidXmlInfoMsg004 "Storing data after the second pass took %<0>d %<1>s.\n" + kstidXmlInfoMsg006 "Loading the XML file into the database took %<0>d %<1>s.\n" + kstidSecond "second" + kstidSeconds "seconds" + kstidXmlInfoMsg005 "Storing the data into the database took %<0>d SQL %<1>s.\n" + kstidCommand "command" + kstidCommands "commands" + kstidXmlInfoMsg008 "Creating %<0>d empty structured text paragraphs.\n" + kstidXmlInfoMsg010 "d""> does not match the database version (%<1>d).\n" + kstidXmlInfoMsg011 "No version number given with .\n" + + kstidXmlErrorMsg001 "<%<0>s> elements cannot be nested inside either or !\n" + kstidXmlErrorMsg002 "<%<0>s> is improperly nested!\n" + kstidXmlErrorMsg003 "<%<0>s> must be nested inside <%<1>s> or an object attribute element!\n" + kstidXmlErrorMsg004 "<%<0>s> must be nested inside <%<1>s>...s>!\n" + kstidXmlErrorMsg005 "<%<0>s> must be nested inside an object attribute element!\n" + kstidXmlErrorMsg006 "<%<0>s> must be nested inside an object element!\n" + kstidXmlErrorMsg007 "<%<0>s> not recognized nested within either or !\n" + kstidXmlErrorMsg008 " must be a toplevel element inside !?\n" + kstidXmlErrorMsg009 " must be a toplevel element inside !?\n" + kstidXmlErrorMsg010 "<%<0>s> must be the outermost XML element!?\n" + kstidXmlErrorMsg011 "Cannot convert ""%<0>s"" into a Language Writing system code.\n" + kstidXmlErrorMsg012 "Cannot create GUID for object identifier!\n" + kstidXmlErrorMsg013 "Cannot get buffer from the XML parser [pass 1]! (Out of memory?)\n" + kstidXmlErrorMsg014 "Cannot get buffer from the XML parser [pass 2]! (Out of memory?)\n" + kstidXmlErrorMsg015 "Cannot have some ord attribute values missing and some present!\n" + kstidXmlErrorMsg016 "Cannot read the CmObject table in the database!\n" + kstidXmlErrorMsg017 "Invalid list root id '%<0>s' in custom field definition [%<1>S]??\n" + kstidXmlErrorMsg018 "ERROR %<0>s executing SQL command:\n %<1>s\n" + kstidXmlErrorMsg019 "ERROR %<0>s executing SQL function on line %<1>d of %<2>s:\n %<3>s\n" + kstidXmlErrorMsg020 "ERROR creating %<0>S (%<1>d, %<2>g)\n" + kstidXmlErrorMsg021 "ERROR in SetMultiBigStr$ %<0>d,%<1>d,%<2>d,'...',0x...\n" + kstidXmlErrorMsg022 "ERROR in SetMultiBigTxt$ %<0>d,%<1>d,%<2>d,'...'\n" + kstidXmlErrorMsg023 "ERROR in SetMultiStr$ %<0>d,%<1>d,%<2>d,'...',0x...\n" + kstidXmlErrorMsg024 "ERROR in SetMultiTxt$ %<0>d,%<1>d,%<2>d,'...'\n" + kstidXmlErrorMsg025 "ERROR in UPDATE [%<0>S] SET [%<1>S]=? WHERE [Id]=%<2>d\n" + kstidXmlErrorMsg026 "ERROR in UPDATE [%<0>S] SET [%<1>S]=?,%<2>S_Fmt=? WHERE [Id]=%<3>d\n" + kstidXmlErrorMsg027 "ERROR with INSERT %<0>S_%<1>S (Src, Dst) VALUES (%<2>d, %<3>d)\n" + kstidXmlErrorMsg028 "ERROR with INSERT %<0>S_%<1>S (Src, Dst, Ord) VALUES (%<2>d, %<3>d, %<4>d)\n" + kstidXmlErrorMsg029 "ERROR with UPDATE [%<0>S] SET [%<1>S]=%<2>d WHERE [Id]=%<3>d\n" + kstidXmlErrorMsg030 "ERROR! BUG! Invalid field data type storing data?? (%<0>d)\n" + kstidXmlErrorMsg031 "Empty <%<0>s> element?\n" +// kstidXmlErrorMsg032 "Empty element? (cbtext = 0)\n" + kstidXmlErrorMsg033 "Empty element?\n" +// kstidXmlErrorMsg034 "Empty element? (cbtext = 0)\n" + kstidXmlErrorMsg035 "Empty MultiString element? (cbtext = 0)\n" + kstidXmlErrorMsg036 "Empty String element? (cbtext = 0)\n" + kstidXmlErrorMsg037 "Error detected while parsing XML file [pass 1]!\n" + kstidXmlErrorMsg038 "Error detected while parsing XML file [pass 2]!\n" + kstidXmlErrorMsg039 "Found a with identical properties to preceding : these have been merged.\n" + kstidXmlErrorMsg040 "INTERNAL DATA CORRUPTION: unable to get class for field!\n" + kstidXmlErrorMsg041 "INTERNAL XML ELEMENT STACK CORRUPTED!?\n" + kstidXmlErrorMsg042 "Ignoring s=""%<1>s""> in the absence of a %<2>s attribute.\n" +// kstidXmlErrorMsg043 "Ignoring s""> in the absence of a offset attribute.\n" + kstidXmlErrorMsg044 "Ignoring s""> in the absence of a ws attribute.\n" + kstidXmlErrorMsg045 "Ignoring s""> in the absence of a wsBase attribute.\n" + kstidXmlErrorMsg046 "Improperly nested <%<0>s name=""%<1>s""> element!\n" + kstidXmlErrorMsg047 "Improperly nested <%<0>s> element!\n" + kstidXmlErrorMsg048 "Invalid Boolean value for the %<0>S field of a %<1>S object: ""%<2>s"".\n" + kstidXmlErrorMsg049 "Invalid GUID value in s=""%<1>s""> element!\n" + kstidXmlErrorMsg050 "Invalid GenDate value for the %<0>S field of a %<1>S object: ""%<2>s"".\n" + kstidXmlErrorMsg051 "Invalid Integer value for the %<0>S field of a %<1>S object: ""%<2>s"".\n" + kstidXmlErrorMsg052 "Invalid Numeric value for the %<0>S field of a %<1>S object: ""%<2>s"".\n" + kstidXmlErrorMsg053 "Invalid XML Element: unknown class ""%<0>s""\n" + kstidXmlErrorMsg054 "Invalid XML Element: unknown field ""%<0>s""\n" + kstidXmlErrorMsg055 "Invalid bin attribute in Float element: ""%<0>s"".\n" + kstidXmlErrorMsg056 "Invalid character data found between runs: """ + kstidXmlErrorMsg057 "Invalid class attribute for CustomField element: %<0>s\n" + kstidXmlErrorMsg058 "Invalid writing system in s"">!\n" + kstidXmlErrorMsg059 "Invalid writing system in s"">!\n" + kstidXmlErrorMsg060 "Invalid field type containing <%<0>s> element: %<1>d.\n" + kstidXmlErrorMsg061 "Invalid ord attribute in Link element: ""%<0>s"".\n" + kstidXmlErrorMsg062 "Invalid ord attribute value: ""%<0>s""\n" + kstidXmlErrorMsg063 "Invalid target attribute for CustomField element: %<0>s\n" + kstidXmlErrorMsg064 "Invalid type attribute for CustomField element: %<0>s\n" + kstidXmlErrorMsg065 "Invalid Float value for the %<0>S field of a %<1>S object: ""%<2>s"".\n" + kstidXmlErrorMsg066 "Invalid value in s=""%<1>s"">: need on, off or invert\n" + kstidXmlErrorMsg067 "Invalid value in s=""%<1>s"">.\n" + kstidXmlErrorMsg068 "Invalid value in s=""%<1>s"">.\n" +// kstidXmlErrorMsg069 "Invalid value in s"">: need on, off or invert\n" +// kstidXmlErrorMsg070 "Invalid value in s"">.\n" +// kstidXmlErrorMsg071 "Invalid value in s"">.\n" + kstidXmlErrorMsg072 "Invalid value in s"">: need off, super, or sub\n" + kstidXmlErrorMsg073 "Invalid value in s"">: need chars or picture\n" + kstidXmlErrorMsg074 "Invalid value in s"">: need none, single, double, dotted, dashed, or strikethrough\n" + kstidXmlErrorMsg075 "Invalid Guid value for the %<0>S field of a %<1>S object: ""%<2>s"".\n" + kstidXmlErrorMsg076 "Invalid Time value for the %<0>S field of a %<1>S object: ""%<2>s"".\n" + kstidXmlErrorMsg077 "Missing Link target: ""%<0>s""\n" + kstidXmlErrorMsg078 "Missing both bin and val attributes in Float element.\n" + + kstidXmlErrorMsg079 "Missing %<0>s attribute for %<1>s element.\n" + + kstidXmlErrorMsg080 "Missing writing system for element!\n" + kstidXmlErrorMsg081 "Missing writing system for element!\n" +// THE NEXT SEVERAL ITEMS SHOULD BE REPLACED BY THE NEW kstidXmlErrorMsg079 SOMETIME. + kstidXmlErrorMsg089 "Missing val attribute in GenDate element.\n" + kstidXmlErrorMsg090 "Missing val attribute in Guid element.\n" + kstidXmlErrorMsg091 "Missing val attribute in Integer element.\n" + kstidXmlErrorMsg092 "Missing val attribute in Numeric element.\n" + kstidXmlErrorMsg093 "Missing val attribute in Time element.\n" + kstidXmlErrorMsg094 "Out of memory after first pass through XML file!\n" + kstidXmlErrorMsg095 "Out of memory before parsing anything!\n" + kstidXmlErrorMsg096 "Out of memory!\n" + kstidXmlErrorMsg097 "Repeated object GUID\n" + kstidXmlErrorMsg098 "Repeated object ID\n" + kstidXmlErrorMsg099 "SQL_PARAM_DIAG_UNAVAILABLE INFO creating %<0>S (%<1>d, %<2>g, %<3>d, %<4>d, %<5>d)\n" + kstidXmlErrorMsg100 "SQL_PARAM_ERROR creating %<0>S (%<1>d, %<2>g, %<3>d, %<4>d, %<5>d)\n" + kstidXmlErrorMsg101 "SQL_PARAM_UNUSED creating %<0>S (%<1>d, %<2>g, %<3>d, %<4>d, %<5>d)\n" + kstidXmlErrorMsg102 "The database is not empty!\n" + kstidXmlErrorMsg103 "UNAVAIL INFO in SetMultiBigStr$ %<0>d,%<1>d,%<2>d,'...',0x...\n" + kstidXmlErrorMsg104 "UNAVAIL INFO in SetMultiBigTxt$ %<0>d,%<1>d,%<2>d,'...'\n" + kstidXmlErrorMsg105 "UNAVAIL INFO in SetMultiStr$ %<0>d,%<1>d,%<2>d,'...',0x...\n" + kstidXmlErrorMsg106 "UNAVAIL INFO in SetMultiTxt$ %<0>d,%<1>d,%<2>d,'...'\n" + kstidXmlErrorMsg107 "UNAVAIL INFO in UPDATE [%<0>S] SET [%<1>S]=? WHERE [Id]=%<2>d\n" + kstidXmlErrorMsg108 "UNAVAIL INFO in UPDATE [%<0>S] SET [%<1>S]=?,%<2>S_Fmt=? WHERE [Id]=%<3>d\n" + kstidXmlErrorMsg109 "UNAVAILABLE INFO creating %<0>S (%<1>d, %<2>g)\n" + kstidXmlErrorMsg110 "UNAVAILABLE INFO for INSERT %<0>S_%<1>S (Src, Dst) VALUES (%<2>d, %<3>d)\n" + kstidXmlErrorMsg111 "UNAVAILABLE INFO for INSERT (Src, Dst, Ord) %<0>S_%<1>S VALUES (%<2>d, %<3>d, %<4>d)\n" + kstidXmlErrorMsg112 "UNAVAILABLE INFO for UPDATE [%<0>S] SET [%<1>S]=%<2>d WHERE [Id]=%<3>d\n" + kstidXmlErrorMsg113 "UNUSED creating %<0>S (%<1>d, %<2>g)\n" + kstidXmlErrorMsg114 "UNUSED data INSERT %<0>S_%<1>S (Src, Dst) VALUES (%<2>d, %<3>d)\n" + kstidXmlErrorMsg115 "UNUSED data INSERT %<0>S_%<1>S (Src, Dst, Ord) VALUES (%<2>d, %<3>d, %<4>d)\n" + kstidXmlErrorMsg116 "UNUSED data UPDATE [%<0>S] SET [%<1>S]=%<2>d WHERE [Id]=%<3>d\n" + kstidXmlErrorMsg117 "UNUSED in SetMultiBigStr$ %<0>d,%<1>d,%<2>d,'...',0x...\n" + kstidXmlErrorMsg118 "UNUSED in SetMultiBigTxt$ %<0>d,%<1>d,%<2>d,'...'\n" + kstidXmlErrorMsg119 "UNUSED in SetMultiStr$ %<0>d,%<1>d,%<2>d,'...',0x...\n" + kstidXmlErrorMsg120 "UNUSED in SetMultiTxt$ %<0>d,%<1>d,%<2>d,'...'\n" + kstidXmlErrorMsg121 "UNUSED in UPDATE [%<0>S] SET [%<1>S]=? WHERE [Id]=%<2>d\n" + kstidXmlErrorMsg122 "UNUSED in UPDATE [%<0>S] SET [%<1>S]=?,%<2>S_Fmt=? WHERE [Id]=%<3>d\n" + kstidXmlErrorMsg123 "Unbalanced XML element stack!?\n" + kstidXmlErrorMsg124 "Unbalanced element stack!?\n" + kstidXmlErrorMsg125 "Unbalanced object id stack!?\n" + kstidXmlErrorMsg126 "Unbalanced property name stack!?\n" + kstidXmlErrorMsg127 "Unknown XML end tag: ""%<0>s""\n" + kstidXmlErrorMsg128 "Unknown XML start tag: ""%<0>s""\n" + kstidXmlErrorMsg129 "WARNING: GUID-based id strings do not all begin with the same letter!\n" + kstidXmlErrorMsg130 "WARNING: You've got to be kidding: string property length > 1 gigabyte!!!\n" + kstidXmlErrorMsg131 "WARNING: the ownership hierarchy is not properly nested!\n" + kstidXmlErrorMsg132 "Warning: String does not have a writing system!\n" + kstidXmlErrorMsg133 "Warning: ignoring extra character at the end of %<0>s data.\n" + kstidXmlErrorMsg134 "Wrong field type for Link element: %<0>d\n" + kstidXmlErrorMsg135 "XML parser detected an XML syntax error [pass 1]!\n" + kstidXmlErrorMsg136 "XML parser detected an XML syntax error [pass 2]!\n" + kstidXmlErrorMsg137 "<%<0>s> not recognized nested within !\n" + kstidXmlErrorMsg138 "<%<0>s> not recognized nested within !\n" + kstidXmlErrorMsg139 "Invalid value in <%<0>s bold=""%<1>s"">: need on, off or invert\n" + kstidXmlErrorMsg140 "Ignoring <%<0>s fontsizeUnit=""%<1>s""> in the absence of a fontsize attribute.\n" + kstidXmlErrorMsg141 "Invalid value in <%<0>s fontsize=""%<1>s"">.\n" + kstidXmlErrorMsg142 "Invalid value in <%<0>s fontsizeUnit=""%<1>s"">.\n" + kstidXmlErrorMsg143 "Invalid value in <%<0>s align=""%<1>s"">: need leading, left, center, right, trailing, or justify\n" + kstidXmlErrorMsg144 "Ignoring <%<0>s ows=""%<1>s""> in the absence of a ws attribute.\n" + kstidXmlErrorMsg145 "Ignoring <%<0>s owsBase=""%<1>s""> in the absence of a wsBase attribute.\n" + kstidXmlErrorMsg146 "Invalid value in <%<0>s italic=""%<1>s"">: need on, off or invert\n" + kstidXmlErrorMsg147 "Invalid value in <%<0>s lineHeight=""%<1>s"">.\n" + kstidXmlErrorMsg148 "Invalid value in <%<0>s lineHeightUnit=""%<1>s"">.\n" + kstidXmlErrorMsg149 "Ignoring <%<0>s lineHeightUnit=""%<1>s""> in the absence of a lineHeight attribute.\n" + kstidXmlErrorMsg150 "Invalid value in <%<0>s offset=""%<1>s"">.\n" + kstidXmlErrorMsg151 "Invalid value in <%<0>s offsetUnit=""%<1>s"">.\n" + kstidXmlErrorMsg152 "Ignoring <%<0>s offsetUnit=""%<1>s""> in the absence of a offset attribute.\n" + kstidXmlErrorMsg153 "Invalid value in <%<0>s superscript=""%<1>s"">: need off, super, or sub.\n" + kstidXmlErrorMsg154 "Invalid value in <%<0>s underline=""%<1>s"">: need none, single, double, dotted, dashed, or strikethrough.\n" +// kstidXmlErrorMsg155 "Ignoring an empty .\n" + kstidXmlErrorMsg156 "Warning: Invalid GUID-based id string for importing object.\n" + kstidXmlErrorMsg157 "Warning: Invalid writing system in s"" .../>.\n" + kstidXmlErrorMsg158 "Warning: Invalid field for implicit target in a Link element: %<0>S.\n" + kstidXmlErrorMsg159 "Warning: Implicit MoInflAffixSlot target in a Link element is missing the name attribute.\n" + kstidXmlErrorMsg160 "Warning: Implicit %<0>s target in a Link element cannot access the PartOfSpeech list.\n" + kstidXmlErrorMsg161 "Warning: Implicit %<0>s target in Link element cannot find/create a needed PartOfSpeech.\n" + kstidXmlErrorMsg162 "Warning: Implicit %<0>s target in Link element is missing one or more required attributes.\n" + kstidXmlErrorMsg163 "Warning: Implicit ReversalIndexEntry target in a Link element is missing the form attribute.\n" + kstidXmlErrorMsg164 "Warning: Implicit ReversalIndexEntry target in a Link element cannot find/create the ReversalIndex.\n" + kstidXmlErrorMsg165 "Warning: Implicit ReversalIndexEntry target in a Link element has an invalid form attribute.\n" + kstidXmlErrorMsg166 "Error obtaining LexDb id from the database!?\n" + kstidXmlErrorMsg167 "Info: Implicit %<0>s target in a Link element has abbr attribute ""%<1>S"" which matches a Name value.\n" + kstidXmlErrorMsg168 "Info: Implicit %<0>s target in a Link element has name attribute ""%<1>S"" which matches an Abbreviation value.\n" + kstidXmlErrorMsg169 "Implicit MoInflAffixSlot target in a Link element has neither the nameOwner nor the abbrOwner attribute.\n" + kstidXmlErrorMsg170 "Implicit %<0>s target in a Link element is missing the sense or entry attribute.\n" + kstidXmlErrorMsg171 "Implicit %<0>s target in a Link element is missing the name or abbr attribute.\n" + kstidXmlErrorMsg172 "Invalid class for implicit target in Link element: %<0>S.\n" + kstidXmlErrorMsg173 "Warning: Invalid writing system in s"" .../>.\n" + kstidXmlErrorMsg174 "Warning: empty ws attribute found: substituting analysis writing system.\n" + kstidXmlErrorMsg175 "Invalid value in <%<0>s spellcheck=""%<1>s"">: need normal, doNotCheck, or forceCheck.\n" + + kstidXmlDebugMsg001 "DEBUG: External Link target: db=""%<0>s"", target=""%<1>s""\n" + kstidXmlDebugMsg002 "DEBUG: Repeated run properties found: ibProp = %<0>d, Top()->ibProp = %<1>d\n" + kstidXmlDebugMsg003 "ERROR CAUGHT on line %<0>d of %<1>s: %<2>s\n" + kstidXmlDebugMsg004 "SUCCESSFULLY CREATED %<0>S (%<1>d, %<2>g, %<3>d, %<4>d, %<5>d)\n" + kstidXmlDebugMsg005 "UNKNOWN ERROR CAUGHT on line %<0>d of %<1>s\n" + kstidXmlDebugMsg006 "m_vetiOpen[%<0>d].m_elty = %<1>s, m_icls = %<2>d\n" + kstidXmlDebugMsg007 "rpi[%<0>d] = %<1>d, %<2>d, 0x" + kstidXmlDebugMsg008 "run[%<0>d]: ichMin = %<1>d, ibProp = %<2>d; distinct = %<3>d, fMerge = %<4>s\n" +END + +STRINGTABLE DISCARDABLE +BEGIN + kstidXmlInfoMsg101 "Info: Creating new inflection class with ws=""%<0>S"", abbr=""%<1>s"", and name=""%<2>s"".\n" + kstidXmlInfoMsg102 "Info: Creating new inflectional affix slot with ws=""%<0>S"" and name=""%<1>s"", for POS with abbr=""%<2>s"" and name=""%<3>s"".\n" + kstidXmlInfoMsg103 "Info: Creating new object with ws=""%<0>S"", abbr=""%<1>s"", and name=""%<2>s"" in the %<3>S list.\n" + kstidXmlInfoMsg104 "Warning: The %<0>S list is not supposed to be extensible!\n" + kstidXmlInfoMsg105 "Info: Creating ReversalIndex for the %<0>S (""%<1>S"") language.\n" + kstidXmlInfoMsg106 "Info: Creating ReversalIndexEntry ""%<0>S"" (""%<1>S"") for the %<2>S (""%<3>S"") language.\n" + kstidXmlInfoMsg107 "%<0>s [repeated %<1>d more times in the XML file]\n" + kstidXmlInfoMsg108 "Warning: Truncating string from %<0>d characters to %<1>d characters for the %<2>S field of a %<3>S object.\n" +END + +STRINGTABLE DISCARDABLE +BEGIN + kstidXmlInfoMsg201 "%<0>u custom field %<1>s written.\n" + kstidDefinition "definition" + kstidDefinitions "definitions" + kstidXmlInfoMsg202 "Dumping the XML file from the database took %<0>d %<1>s.\n" + kstidXmlInfoMsg203 "Loading %<0>u %<1>s of Object Ownership Hierarchy data took %<2>d %<3>s.\n" + kstidRow "row" + kstidRows "rows" + kstidXmlInfoMsg206 "Loading %<0>u %<1>s of ""Binary"" data took %<2>d %<3>s.\n" + kstidXmlInfoMsg207 "Loading %<0>u %<1>s of ""Image"" data took %<2>d %<3>s.\n" + kstidXmlInfoMsg210 "Loading %<0>u %<1>s of ""MultiString"" data took %<2>d %<3>s.\n" + kstidXmlInfoMsg211 "Loading %<0>u %<1>s of ""MultiUnicode"" data took %<2>d %<3>s.\n" + kstidXmlInfoMsg212 "Loading %<0>u %<1>s of ""ReferenceAtom"" data took %<2>d %<3>s.\n" + kstidXmlInfoMsg213 "Loading %<0>u %<1>s of ""ReferenceCollection/Sequence"" data took %<2>d %<3>s.\n" + kstidXmlInfoMsg214 "Loading %<0>u %<1>s of ""String"" data took %<2>d %<3>s.\n" + kstidXmlInfoMsg215 "Loading %<0>u %<1>s of ""Unicode"" data took %<2>d %<3>s.\n" + kstidXmlInfoMsg216 "Loading %<0>u %<1>s of basic attribute data took %<2>d %<3>s.\n" + kstidXmlInfoMsg217 "Loading the data from the database took %<0>d SQL %<1>s.\n" + kstidXmlInfoMsg218 "Rebuilding the object hierarchy table took %<0>d %<1>s.\n" + kstidXmlInfoMsg219 "SQL[%<0>d]: %<1>s\n" + kstidXmlInfoMsg220 "Writing the XML file took %<0>d %<1>s.\n" + kstidXmlInfoMsg221 " Reading %<0>d additional characters of string data.\n" + kstidXmlInfoMsg222 " Reading %<0>d additional bytes of format data.\n" + kstidXmlInfoMsg224 "Owner of object %<0>d does not have a name in the default analysis language.\n" + kstidXmlInfoMsg225 "Owner of object %<0>d does not have an abbreviation in the default analysis language.\n" + + kstidXmlErrorMsg201 " %<0>s - %<1>s\n" + kstidXmlErrorMsg202 "BUG/FEATURE - cannot handle Run scalar property code ""%<0>s""\n" + kstidXmlErrorMsg203 "ERROR %<0>s executing SQL command:\n %<1>s\n" + kstidXmlErrorMsg204 "ERROR %<0>s executing SQL function on line %<1>d of %<2>s:\n %<3>s\n" + kstidXmlErrorMsg205 "ERROR - invalid Run scalar property length (%<0>d)\n" + kstidXmlErrorMsg206 "ERROR - invalid Run string property length\n" + kstidXmlErrorMsg207 "ERROR - invalid binary format data for a string: %<0>d run%<1>s, %<2>d byte%<3>s." + kstidRun "run" + kstidRuns "runs" + kstidByte "byte" + kstidBytes "bytes" + kstidXmlErrorMsg208 "ERROR - invalid binary format data for a string: %<0>d run%<1>s." + kstidXmlErrorMsg209 "ERROR - invalid binary format data for a string: only %<0>d byte%<1>s." + kstidXmlErrorMsg210 "ERROR - invalid binary format data for a string: run %<0>d does not start after\nrun %<1>d (min %<2>d <= min %<3>d).\n" + kstidXmlErrorMsg211 "ERROR - invalid binary format data for a string: run %<0>d has invalid internal\noffset (%<1>d)." + kstidXmlErrorMsg212 "ERROR - invalid binary format data for a string: run %<0>d starts after end of\nstring (length = %<1>d <= min = %<2>d)." + kstidXmlErrorMsg213 "ERROR - invalid binary format data for a string: run %<0>d starts before the\nstring (min = %<1>d)." + kstidXmlErrorMsg214 "ERROR - invalid embedded object type in Run string property (%<0>d)\n" + kstidXmlErrorMsg215 "ERROR - invalid writing system of Run string property length\n" + kstidXmlErrorMsg216 "ERROR - invalid internal writing system of Run scalar property code\n" + kstidXmlErrorMsg217 "ERROR - invalid internal writing system of Run string property code\n" + kstidXmlErrorMsg218 "ERROR - unknown Run scalar property code (%<0>d)\n" + kstidXmlErrorMsg219 "ERROR - unknown Run string property code (%<0>d)\n" + kstidXmlErrorMsg220 "ERROR [%<0>d]: Constructed Query overflowed its buffer!\n""%<1>s""\n" + kstidXmlErrorMsg221 "WARNING - invalid binary format data for a string: 0 runs, %<0>d byte%<1>s." + kstidXmlErrorDecoding "ERROR decoding the properties: check the log file for details." + kstidXmlErrorMsg222 "WARNING: no writing system" + kstidXmlErrorMsg223 "Cannot get version number from the database!?\n" + kstidXmlErrorMsg224 "Corrupted database: missing %<0>S object (hobj = %<1>d) for %<2>S (hobj = %<3>d)\n" + kstidXmlErrorMsg225 "Corrupted database: missing integer property for %<1>S style.%n" + kstidXmlErrorMsg226 "Corrupted database: missing %<0>d integer properties for %<1>S style.%n" + kstidXmlErrorMsg227 "Corrupted database: missing integer property in paragraph's style.%n" + kstidXmlErrorMsg228 "Corrupted database: missing %<0>d integer properties in paragraph's style.%n" + kstidXmlErrorMsg229 "Corrupted database: missing string property for %<1>S style.%n" + kstidXmlErrorMsg230 "Corrupted database: missing %<0>d string properties for %<1>S style.%n" + kstidXmlErrorMsg231 "Corrupted database: missing string property in paragraph's style.%n" + kstidXmlErrorMsg232 "Corrupted database: missing %<0>d string properties in paragraph's style.%n" + kstidUNKNOWN "UNKNOWN" +END + +STRINGTABLE DISCARDABLE +BEGIN + kstidXmlErrorMsg301 "Invalid hvoOwner passed to ImportXmlObject method: %<0>d\n" + kstidXmlErrorMsg302 "Unknown clid (%<0>d) retrieved for hvoOwner: SOMETHING IS VERY WRONG!\n" + kstidXmlErrorMsg303 "Unknown flid passed to ImportXmlObject method: %<0>d\n" + kstidXmlErrorMsg304 "Invalid flid passed to ImportXmlObject method: flid = %<0>d, but class = %<1>d\n" + kstidXmlErrorMsg305 "Empty database: THIS SHOULD NEVER HAPPEN!\n" + kstidXmlErrorMsg306 "<%<0>s> must be nested inside <%<1>s>...s>!\n" + kstidXmlErrorMsg307 "DEBUG: Unknown flid for list: %<0>d\n" + kstidXmlInfoMsg223 "Info: Creating new writing system for code ""%<0>s"".\n" + kstidXmlErrorMsg308 "Warning: Picture file ""%<0>s"" does not exist.\n" + kstidXmlErrorMsg309 "Warning: Cannot copy picture file ""%<0>s"" to ""%<1>s"".\n" + kstidXmlErrorMsg310 "DEBUG: Unknown flid for folders: %<0>d" + kstidXmlErrorMsg311 "ERROR - Invalid start tag <%<0>s> for XML file: expected <%<1>s>.\n" + kstidXmlErrorMsg312 "Warning: Media file ""%<0>s"" does not exist.\n" + kstidXmlErrorMsg313 "Warning: Cannot copy media file ""%<0>s"" to ""%<1>s"".\n" + kstidXmlErrorMsg314 "ERROR - Cannot create directory ""%<0>s"".\n" + + kstidXmlErrorMsg315 "Invalid %<0>s attribute value for %<1>s element: not GUID based.\n" + kstidXmlErrorMsg316 "Invalid %<0>s attribute value for %<1>s element: bad GUID value.\n" + kstidXmlErrorMsg317 "Object id being merged (%<0>g) should not appear in the updated list.\n" + kstidXmlErrorMsg318 "Object id being deleted (%<0>g) should not appear in the updated list.\n" + kstidXmlErrorMsg319 "A list update XML file must begin with a field tag, not a class tag!\n" + kstidXmlErrorMsg320 "ERROR in ""%s"" [param=%d].\n" + kstidXmlErrorMsg321 "UNUSED in ""%s"" [param=%d].\n" + kstidXmlErrorMsg322 "UNAVAIL INFO in ""%s"" [param=%d].\n" + kstidXmlErrorMsg323 "Warning: Storing only the first %<0>d of %<1>d characters for this string: ""%<2>s"".\n" + + kstidXmlInfoMsg301 "Initializing from the database before reading the XML file took %<0>d %<1>s.\n" + kstidXmlInfoMsg302 "Processing the update information took %<0>d %<1>s.\n" + kstidXmlInfoMsg303 "Creating new objects took %<0>d %<1>s.\n" + kstidXmlInfoMsg304 "Updating owners and sequence positions took %<0>d %<1>s.\n" + kstidXmlInfoMsg305 "Fixing links to merged or deleted list items took %<0>d %<1>s.\n" + kstidXmlInfoMsg306 "Deleting obsolete database objects took %<0>d %<1>s.\n" + kstidXmlInfoMsg307 "Removing possibly obsolete data from list items took %<0>d %<1>s.\n" + kstidXmlInfoMsg308 "Collecting obsolete database objects to delete took %<0>d %<1>s.\n" + kstidXmlInfoMsg309 "Need to delete %<0>d obsolete database %<1>s.\n" + kstidObject "object" + kstidObjects "objects" + kstidXmlInfoMsg310 "(Special initializing for update alone took %<0>d %<1>s.)\n" + kstidXmlInfoMsg311 "Info: Creating %<0>s Pair Lexical Reference Type with name=""%<1>S"" and abbr=""%<2>S"".\n" + kstidSense "Sense" + kstidEntry "Entry" +END diff --git a/Src/Kernel/FwKernelExtra_GUIDs.cpp b/Src/Kernel/FwKernelExtra_GUIDs.cpp index 2c87e34616..ad94a71ea7 100644 --- a/Src/Kernel/FwKernelExtra_GUIDs.cpp +++ b/Src/Kernel/FwKernelExtra_GUIDs.cpp @@ -11,3 +11,5 @@ DEFINE_UUIDOF(ITsStringRaw,0x2AC0CB90,0xB14B,0x11d2,0xB8,0x1D,0x00,0x40,0x05,0x41,0xF9,0xDA); DEFINE_UUIDOF(ITsTextPropsRaw,0x31BDA5F0,0xD286,0x11d3,0x9B,0xBC,0x00,0x40,0x05,0x41,0xF9,0xE9); +DEFINE_UUIDOF(UniscribeSegment,0x61299C3B,0x54D6,0x4c46,0xAC,0xE5,0x72,0xB9,0x12,0x8F,0x20,0x48); +DEFINE_UUIDOF(RomRenderSegment,0xA124E0C1,0xDD4B,0x11d2,0x80,0x78,0x00,0x00,0xC0,0xFB,0x81,0xB5); \ No newline at end of file diff --git a/Src/Kernel/FwKernelPs.idl b/Src/Kernel/FwKernelPs.idl index 446a291c5d..0f285727f6 100644 --- a/Src/Kernel/FwKernelPs.idl +++ b/Src/Kernel/FwKernelPs.idl @@ -18,5 +18,5 @@ import "ocidl.idl"; #include "FwKernel.idh" #include "TextServ.idh" -#include "Render.idh" // for Language DLL +#include "Render.idh" #include "Language.idh" diff --git a/Src/Kernel/FwKernelTlb.idl b/Src/Kernel/FwKernelTlb.idl index c4010e803a..8438c73c40 100644 --- a/Src/Kernel/FwKernelTlb.idl +++ b/Src/Kernel/FwKernelTlb.idl @@ -19,6 +19,6 @@ DeclareLibrary(FwKernelLib, 1.0, "FieldWorks Kernel", F1EF76E0-BE04-11d3-8D9A-00 { #include "FwKernel.idh" #include "TextServ.idh" - #include "Render.idh" // Language DLL stuff + #include "Render.idh" #include "Language.idh" }; diff --git a/Src/Kernel/Kernel.vcxproj b/Src/Kernel/Kernel.vcxproj index 1a1e884302..9ebb3ac2e1 100644 --- a/Src/Kernel/Kernel.vcxproj +++ b/Src/Kernel/Kernel.vcxproj @@ -1,105 +1,138 @@  - - Debug - Win32 - - - Release - Win32 - + + Debug + Win32 + + + Release + Win32 + - FwKernel - {6396B488-4D34-48B2-8639-EEB90707405B} - FwKernel - - - - MakeFileProj + FwKernel + {6396B488-4D34-48B2-8639-EEB90707405B} + FwKernel + + + + + + + MakeFileProj - Makefile + Makefile - Makefile + Makefile - - + + - - + + - <_ProjectFileVersion>10.0.30319.1 - $(ProjectDir)\..\..\Output\Debug\ - $(ProjectDir)\..\..\obj\Debug\ - ..\..\bin\mkfwk - ..\..\bin\mkfwk cc - - FwKernel.dll - DEBUG;$(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - Release\ - Release\ - ..\..\bin\mkfwk r - ..\..\bin\mkfwk r cc - - Kernel.exe - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) + <_ProjectFileVersion>10.0.30319.1 + $(ProjectDir)\..\..\Output\Debug\ + $(ProjectDir)\..\..\obj\Debug\ + ..\..\bin\mkfwk + ..\..\bin\mkfwk cc + + FwKernel.dll + DEBUG;$(NMakePreprocessorDefinitions) + $(NMakeIncludeSearchPath) + $(NMakeForcedIncludes) + $(NMakeAssemblySearchPath) + $(NMakeForcedUsingAssemblies) + Release\ + Release\ + ..\..\bin\mkfwk r + ..\..\bin\mkfwk r cc + + Kernel.exe + $(NMakePreprocessorDefinitions) + $(NMakeIncludeSearchPath) + $(NMakeForcedIncludes) + $(NMakeAssemblySearchPath) + $(NMakeForcedUsingAssemblies) - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + - - + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/Src/Kernel/Kernel.vcxproj.filters b/Src/Kernel/Kernel.vcxproj.filters index 1d547bc21a..8fcd642314 100644 --- a/Src/Kernel/Kernel.vcxproj.filters +++ b/Src/Kernel/Kernel.vcxproj.filters @@ -1,99 +1,183 @@  - - {398036a2-f52a-482d-9525-33c8406a59a6} - cpp;c;cxx;def;odl;idl;hpj;bat;asm - - - {7bf8133d-ca9d-4250-a953-2eb94f681dd8} - h;hpp;hxx;hm;inl;inc - - - {81fdee2e-c415-401f-80ec-58de44941b8a} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - + + {398036a2-f52a-482d-9525-33c8406a59a6} + cpp;c;cxx;def;odl;idl;hpj;bat;asm + + + {7bf8133d-ca9d-4250-a953-2eb94f681dd8} + h;hpp;hxx;hm;inl;inc + + + {81fdee2e-c415-401f-80ec-58de44941b8a} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + - - Source Files - - - - + + Source Files + + + + + + + - - Source Files - - - Source Files - + + Source Files + + + Source Files + - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + - - Resource Files - + + Resource Files + \ No newline at end of file diff --git a/Src/Language/LangResource.h b/Src/Kernel/LangResource.h similarity index 100% rename from Src/Language/LangResource.h rename to Src/Kernel/LangResource.h diff --git a/Src/Language/Language.idh b/Src/Kernel/Language.idh similarity index 100% rename from Src/Language/Language.idh rename to Src/Kernel/Language.idh diff --git a/Src/Language/LgIcuCharPropEngine.cpp b/Src/Kernel/LgIcuCharPropEngine.cpp similarity index 100% rename from Src/Language/LgIcuCharPropEngine.cpp rename to Src/Kernel/LgIcuCharPropEngine.cpp diff --git a/Src/Language/LgIcuCharPropEngine.h b/Src/Kernel/LgIcuCharPropEngine.h similarity index 100% rename from Src/Language/LgIcuCharPropEngine.h rename to Src/Kernel/LgIcuCharPropEngine.h diff --git a/Src/Language/LgIcuCharPropertyInit.h b/Src/Kernel/LgIcuCharPropertyInit.h similarity index 100% rename from Src/Language/LgIcuCharPropertyInit.h rename to Src/Kernel/LgIcuCharPropertyInit.h diff --git a/Src/Language/LgIcuWrappers.cpp b/Src/Kernel/LgIcuWrappers.cpp similarity index 100% rename from Src/Language/LgIcuWrappers.cpp rename to Src/Kernel/LgIcuWrappers.cpp diff --git a/Src/Language/LgIcuWrappers.h b/Src/Kernel/LgIcuWrappers.h similarity index 100% rename from Src/Language/LgIcuWrappers.h rename to Src/Kernel/LgIcuWrappers.h diff --git a/Src/Language/LgKeymanHandler.cpp b/Src/Kernel/LgKeymanHandler.cpp similarity index 100% rename from Src/Language/LgKeymanHandler.cpp rename to Src/Kernel/LgKeymanHandler.cpp diff --git a/Src/Language/LgKeymanHandler.h b/Src/Kernel/LgKeymanHandler.h similarity index 100% rename from Src/Language/LgKeymanHandler.h rename to Src/Kernel/LgKeymanHandler.h diff --git a/Src/Language/LgNumericEngine.cpp b/Src/Kernel/LgNumericEngine.cpp similarity index 100% rename from Src/Language/LgNumericEngine.cpp rename to Src/Kernel/LgNumericEngine.cpp diff --git a/Src/Language/LgNumericEngine.h b/Src/Kernel/LgNumericEngine.h similarity index 100% rename from Src/Language/LgNumericEngine.h rename to Src/Kernel/LgNumericEngine.h diff --git a/Src/Language/LgSimpleEngines.cpp b/Src/Kernel/LgSimpleEngines.cpp similarity index 100% rename from Src/Language/LgSimpleEngines.cpp rename to Src/Kernel/LgSimpleEngines.cpp diff --git a/Src/Language/LgSimpleEngines.h b/Src/Kernel/LgSimpleEngines.h similarity index 100% rename from Src/Language/LgSimpleEngines.h rename to Src/Kernel/LgSimpleEngines.h diff --git a/Src/Language/LgUnicodeCollateInit.h b/Src/Kernel/LgUnicodeCollateInit.h similarity index 100% rename from Src/Language/LgUnicodeCollateInit.h rename to Src/Kernel/LgUnicodeCollateInit.h diff --git a/Src/Language/LgUnicodeCollater.cpp b/Src/Kernel/LgUnicodeCollater.cpp similarity index 100% rename from Src/Language/LgUnicodeCollater.cpp rename to Src/Kernel/LgUnicodeCollater.cpp diff --git a/Src/Language/LgUnicodeCollater.h b/Src/Kernel/LgUnicodeCollater.h similarity index 100% rename from Src/Language/LgUnicodeCollater.h rename to Src/Kernel/LgUnicodeCollater.h diff --git a/Src/Language/LocaleIndex.cpp b/Src/Kernel/LocaleIndex.cpp similarity index 100% rename from Src/Language/LocaleIndex.cpp rename to Src/Kernel/LocaleIndex.cpp diff --git a/Src/Language/LocaleIndex.h b/Src/Kernel/LocaleIndex.h similarity index 100% rename from Src/Language/LocaleIndex.h rename to Src/Kernel/LocaleIndex.h diff --git a/Src/Kernel/Main.h b/Src/Kernel/Main.h index 43c8be8aff..132f172e72 100644 --- a/Src/Kernel/Main.h +++ b/Src/Kernel/Main.h @@ -15,11 +15,29 @@ Last reviewed: #ifndef Main_H #define Main_H 1 +// If ICU_LINEBREAKING is defined, we use the ICU functions for linebreaking. +// If this is undefined, then we go to JohnT's previous version which doesn't +// use ICU functions. +#ifndef ICU_LINEBREAKING +#define ICU_LINEBREAKING +#endif /*ICU_LINEBREAKING*/ + #include "common.h" //#define kwsLim 0xfffffff9 #include "CellarConstants.h" +#define NO_EXCEPTIONS 1 +#if WIN32 +#include +#endif + +#if !WIN32 +#include +#include "BasicTypes.h" +#include +#endif + using std::min; using std::max; @@ -28,9 +46,94 @@ using std::max; ***********************************************************************************************/ #include "FwKernelTlb.h" +// Special interface mainly used for Graphite engine not defined in an IDH. +#include "../Graphite/GrEngine/ITraceControl.h" +#ifndef ITraceControlPtr // for portability I don't think this header defines this. + DEFINE_COM_PTR(ITraceControl); +#endif + /*********************************************************************************************** Implementations. ***********************************************************************************************/ +#include "LangResource.h" + +// For interfacing with Graphite engines: +namespace gr { +typedef unsigned char utf8; +typedef wchar_t utf16; +typedef unsigned long int utf32; +#define UtfType LgUtfForm +} +// defined in TtSfnt_en.h - but this avoids including all of TtfUtil in the Language.dll +#define tag_Silf 0x666c6953 +#include "GrResult.h" +#include "GrUtil.h" +#include "ITextSource.h" +#include "IGrJustifier.h" +#include "FwGr.h" + +using namespace fwutil; // Rect and Point classes + +// these are a gray area, including aspects of both model and engine +// Todo JohnT: These structs are part of an obsolete approach to overriding character properties. +// Get rid of them and whatever uses them. (Taken from OldLgWritingSystem file.) +/*---------------------------------------------------------------------------------------------- + The CharacterPropertyObject stores all of the data that we allow to be overriden for a + single character (right now, pretty much everything except the Unicode 1.0 name). +----------------------------------------------------------------------------------------------*/ +struct CharacterPropertyObject +{ + UChar32 uch32CodePoint; + StrUni stuCharName; + LgGeneralCharCategory ccGenCategory; + unsigned int nCombiningClass : 8; + LgBidiCategory bicBidiCategory; + LgDecompMapTag dtDecompMapTag; + Vector vuch32Decomp; + unsigned int nDecDigit : 4; + unsigned int nDigit : 4; + int nNumericValue; //numerator stored in the top 16 bits, denominator in the bottom 16 + bool fMirrored : 1; + StrUni stuISOComment; + UChar32 uch32Uppercase; + UChar32 uch32Lowercase; + UChar32 uch32Titlecase; + LgLBP lbpLineBreak; + + void Clear() + { + uch32CodePoint = 0; + stuCharName.Clear(); + ccGenCategory = kccLu; //0 + nCombiningClass = 0; + bicBidiCategory = kbicL; //0 + dtDecompMapTag = kdtNoTag; //0 + vuch32Decomp.Clear(); + nDecDigit = 0; + nDigit = 0; + nNumericValue = 0; + fMirrored = false; + stuISOComment.Clear(); + uch32Uppercase = 0; + uch32Lowercase = 0; + uch32Titlecase = 0; + lbpLineBreak = klbpAI; //0 + } +}; //hungarian cpo +struct CharPropRange +{ + UChar32 iMin; + UChar32 iLim; + Vector vRange; +}; //hungarian cpr +struct OverriddenCharProps +{ + UChar32 iMin; + UChar32 iLim; + Vector * pvcprOverride1; + Vector * pvcpoOverride2; +}; //hungarian ocp + #include "KernelGlobals.h" #include "TsString.h" #include "TsTextProps.h" @@ -39,7 +142,31 @@ using std::max; #include "TextServ.h" #include "TsMultiStr.h" #include "ActionHandler.h" +// Engines +#include "LgIcuCharPropEngine.h" +#include "LgUnicodeCollater.h" +class RomRenderEngine; +DEFINE_COM_PTR(RomRenderEngine); +class UniscribeEngine; +DEFINE_COM_PTR(UniscribeEngine); +#include "RomRenderSegment.h" +#include "RomRenderEngine.h" +#include "LgSimpleEngines.h" +#include "LgNumericEngine.h" +#if !WIN32 +#include "UniscribeLinux.h" +#endif +#include "UniscribeSegment.h" +#include "UniscribeEngine.h" +#include "RegexMatcherWrapper.h" + +// Other tools #include "FwStyledText.h" +#include "StringToNumHelpers.h" +#include "WriteXml.h" // From AppCore. +#include "xmlparse.h" +#include "LgKeymanHandler.h" +#include "LgIcuWrappers.h" #if WIN32 // for parsing XML files; in this DLL, we want the parser to work with wide characters, diff --git a/Src/Kernel/Makefile b/Src/Kernel/Makefile index 6a56c24353..854fe1838c 100644 --- a/Src/Kernel/Makefile +++ b/Src/Kernel/Makefile @@ -23,11 +23,16 @@ else OPTIMIZATIONS = -O3 endif -CELLAR_SRC = $(SRC)/Cellar -DBSERVICES_SRC = $(SRC)/DbServices +GRAPHITE_SRC = $(SRC)/Graphite +GRFW_SRC = $(GRAPHITE_SRC)/FwOnly +GRUTIL_LIB = $(GRAPHITE_SRC)/lib +TTFUTIL_LIB = $(GRAPHITE_SRC)/TtfUtil +VIEWS_LIB = $(VIEWS_SRC)/lib + +PACKAGES = glib-2.0 gtk+-2.0 glibmm-2.4 gtkmm-2.4 cairomm-1.0 pangomm-1.4 INCLUDES := -I$(KERNEL_SRC) -I$(CELLAR_SRC) -I$(GENERIC_SRC) -I$(APPCORE_SRC) $(DEBUG_INCLUDES) -INCLUDES := $(INCLUDES) -I$(LANGUAGE_SRC) -I$(DBACCESS_SRC) -I$(DBSERVICES_SRC) +INCLUDES := $(INCLUDES) -I$(GRUTIL_LIB) -I$(TTFUTIL_LIB) -I$(VIEWS_SRC) -I$(VIEWS_LIB) -I$(GRFW_SRC) INCLUDES := $(shell icu-config --cppflags) \ $(INCLUDES) \ @@ -36,12 +41,13 @@ INCLUDES := $(shell icu-config --cppflags) \ -I$(WIN32MORE_INC) \ -I$(COM_INC) \ -I$(WIN32BASE_INC) \ - + $(shell pkg-config --cflags $(PACKAGES)) \ LDLIBS := $(LDLIBS) \ -L$(WIN32MORE_LIB) -lWin32More \ -L$(COM_LIB) -lcom \ -L$(WIN32BASE_LIB) -lWin32Base \ + $(shell pkg-config --libs $(PACKAGES)) \ $(shell icu-config --ldflags) \ -luuid -lexpat @@ -71,6 +77,18 @@ OBJ_FWKERNEL = \ $(INT_DIR)/TextServ.o \ $(INT_DIR)/ActionHandler.o \ $(INT_DIR)/DebugReport.o \ + $(INT_DIR)/LgIcuWrappers.o \ + $(INT_DIR)/LgSimpleEngines.o \ + $(INT_DIR)/LgIcuCharPropEngine.o \ + $(INT_DIR)/LgUnicodeCollater.o \ + $(INT_DIR)/LgKeymanHandler.o \ + $(INT_DIR)/LocaleIndex.o \ + $(INT_DIR)/UniscribeLinux.o \ + $(INT_DIR)/UniscribeSegment.o \ + $(INT_DIR)/UniscribeEngine.o \ + $(INT_DIR)/RomRenderEngine.o \ + $(INT_DIR)/RomRenderSegment.o \ + $(INT_DIR)/FwXml.o \ OBJ_OTHER = \ $(GENERIC_OBJ)/ModuleEntry.o \ @@ -115,6 +133,10 @@ $(APPCORE_OBJ)/FwStyledText.o $(APPCORE_OBJ)/WriteXml.o: @$(MAKE) -C $(APPCORE_SRC) $@ -q || \ $(MAKE) -C $(APPCORE_SRC) $@ +$(INT_DIR)/%.o: $(CELLAR_SRC)/%.cpp + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ + -c $< -o $@ -MMD -MF $(@:%.o=%.d) + $(GENERIC_OBJ)/main.o: @$(MAKE) -C $(GENERIC_SRC) -q $@ || \ $(MAKE) -C $(GENERIC_SRC) $@ diff --git a/Src/Language/RegexMatcherWrapper.cpp b/Src/Kernel/RegexMatcherWrapper.cpp similarity index 100% rename from Src/Language/RegexMatcherWrapper.cpp rename to Src/Kernel/RegexMatcherWrapper.cpp diff --git a/Src/Language/RegexMatcherWrapper.h b/Src/Kernel/RegexMatcherWrapper.h similarity index 100% rename from Src/Language/RegexMatcherWrapper.h rename to Src/Kernel/RegexMatcherWrapper.h diff --git a/Src/Language/Render.idh b/Src/Kernel/Render.idh similarity index 100% rename from Src/Language/Render.idh rename to Src/Kernel/Render.idh diff --git a/Src/Language/RomRenderEngine.cpp b/Src/Kernel/RomRenderEngine.cpp similarity index 100% rename from Src/Language/RomRenderEngine.cpp rename to Src/Kernel/RomRenderEngine.cpp diff --git a/Src/Language/RomRenderEngine.h b/Src/Kernel/RomRenderEngine.h similarity index 100% rename from Src/Language/RomRenderEngine.h rename to Src/Kernel/RomRenderEngine.h diff --git a/Src/Language/RomRenderSegment.cpp b/Src/Kernel/RomRenderSegment.cpp similarity index 100% rename from Src/Language/RomRenderSegment.cpp rename to Src/Kernel/RomRenderSegment.cpp diff --git a/Src/Language/RomRenderSegment.h b/Src/Kernel/RomRenderSegment.h similarity index 100% rename from Src/Language/RomRenderSegment.h rename to Src/Kernel/RomRenderSegment.h diff --git a/Src/Kernel/Test/Makefile b/Src/Kernel/Test/Makefile index 9fd67ddc10..a336603968 100644 --- a/Src/Kernel/Test/Makefile +++ b/Src/Kernel/Test/Makefile @@ -24,12 +24,16 @@ else OPTIMIZATIONS = -O3 endif -PACKAGES = gdk-2.0 gtkmm-2.4 gdkmm-2.4 cairomm-1.0 pangomm-1.4 +GRAPHITE_SRC = $(SRC)/Graphite +GRFW_SRC = $(GRAPHITE_SRC)/FwOnly +GRUTIL_LIB = $(GRAPHITE_SRC)/lib +TTFUTIL_LIB = $(GRAPHITE_SRC)/TtfUtil +VIEWS_LIB = $(VIEWS_SRC)/lib -LANGUAGETEST_SRC = $(LANGUAGE_SRC)/Test +PACKAGES = gdk-2.0 gtkmm-2.4 gdkmm-2.4 cairomm-1.0 pangomm-1.4 -INCLUDES := -I$(KERNEL_SRC) -I$(KERNEL_SRC)/Test -I$(CELLAR_SRC) \ - -I$(GENERIC_SRC) -I$(APPCORE_SRC) -I$(DEBUGPROCS_SRC) \ +INCLUDES := -I$(KERNEL_SRC) -I$(KERNEL_SRC)/Test -I$(CELLAR_SRC) -I$(GENERIC_SRC) -I$(APPCORE_SRC) -I$(DEBUGPROCS_SRC) +INCLUDES := $(INCLUDES) -I$(GRUTIL_LIB) -I$(TTFUTIL_LIB) -I$(VIEWS_SRC) -I$(VIEWS_LIB) -I$(GRFW_SRC) INCLUDES := \ $(shell icu-config --cppflags) \ @@ -40,7 +44,6 @@ INCLUDES := \ -I$(WIN32MORE_INC) \ -I$(COM_INC) \ -I$(WIN32BASE_INC) \ - -I$(LANGUAGETEST_SRC) \ $(shell pkg-config --cflags $(PACKAGES)) \ LDLIBS := \ @@ -77,8 +80,16 @@ FWKERNEL_OBJ := \ $(KERNEL_OBJ)/TextServ.o \ $(KERNEL_OBJ)/TsMultiStr.o \ $(KERNEL_OBJ)/ActionHandler.o \ + $(KERNEL_OBJ)/LgUnicodeCollater.o \ + $(KERNEL_OBJ)/RomRenderEngine.o \ + $(KERNEL_OBJ)/RomRenderSegment.o \ + $(KERNEL_OBJ)/LgSimpleEngines.o \ + $(KERNEL_OBJ)/LgIcuCharPropEngine.o \ + $(KERNEL_OBJ)/LgKeymanHandler.o \ + $(KERNEL_OBJ)/LocaleIndex.o \ $(GENERIC_OBJ)/ModuleEntry.o \ $(GENERIC_OBJ)/TextProps1.o \ + $(KERNEL_OBJ)/FwXml.o \ #Run make in the directory of each library $(LINK_LIBS) $(FWKERNEL_OBJ):: @@ -108,12 +119,16 @@ COLLECT=$(BUILD_ROOT)/Bin/CollectUnit++Tests.sh Kernel $(INT_DIR)/Collection.cpp: testFwKernel.h \ - $(LANGUAGETEST_SRC)/MockLgWritingSystemFactory.h\ - $(LANGUAGETEST_SRC)/MockLgWritingSystem.h\ TestUndoStack.h \ TestTsStrBldr.h \ TestTsString.h \ TestTsPropsBldr.h \ - TestTsTextProps.h + TestTsTextProps.h \ + MockLgWritingSystemFactory.h \ + MockLgWritingSystem.h \ + TestLgCollatingEngine.h \ + TestLgIcuCharPropEngine.h \ + TestRomRenderEngine.h \ + RenderEngineTestBase.h @echo Collecting tests for testFwKernel $(COLLECT) $^ $@ diff --git a/Src/Language/Test/MockLgWritingSystem.h b/Src/Kernel/Test/MockLgWritingSystem.h similarity index 100% rename from Src/Language/Test/MockLgWritingSystem.h rename to Src/Kernel/Test/MockLgWritingSystem.h diff --git a/Src/Language/Test/MockLgWritingSystemFactory.h b/Src/Kernel/Test/MockLgWritingSystemFactory.h similarity index 100% rename from Src/Language/Test/MockLgWritingSystemFactory.h rename to Src/Kernel/Test/MockLgWritingSystemFactory.h diff --git a/Src/Language/Test/RenderEngineTestBase.h b/Src/Kernel/Test/RenderEngineTestBase.h similarity index 99% rename from Src/Language/Test/RenderEngineTestBase.h rename to Src/Kernel/Test/RenderEngineTestBase.h index e57d15bb00..dcc5784945 100644 --- a/Src/Language/Test/RenderEngineTestBase.h +++ b/Src/Kernel/Test/RenderEngineTestBase.h @@ -14,16 +14,16 @@ Last reviewed: #pragma once -#include "testLanguage.h" +#include "testFwKernel.h" #ifndef WIN32 // on Linux - symbols for for methods of Vector - This include adds them into testLanguage #include "Vector_i.cpp" #endif -namespace TestLanguage +namespace TestFwKernel { // For error reporting: - static DummyFactory g_fact(_T("SIL.TestLanguage.TxtSrc")); + static DummyFactory g_fact(_T("SIL.TestFwKernel.TxtSrc")); /******************************************************************************************* Mock object class for TestUniscribeEngine::testBreakPointing(). diff --git a/Src/Kernel/Test/TestKernel.vcxproj b/Src/Kernel/Test/TestKernel.vcxproj index ac1404878e..8c60edafff 100644 --- a/Src/Kernel/Test/TestKernel.vcxproj +++ b/Src/Kernel/Test/TestKernel.vcxproj @@ -1,82 +1,94 @@  - - Debug - Win32 - - - Release - Win32 - + + Debug + Win32 + + + Release + Win32 + - {4869A8EB-1013-47FB-8FED-53FC532F9125} - - - - MakeFileProj + {4869A8EB-1013-47FB-8FED-53FC532F9125} + + + + + + + MakeFileProj - Makefile + Makefile - Makefile + Makefile - - + + - - + + - <_ProjectFileVersion>10.0.30319.1 - Debug\ - Debug\ - ..\..\..\bin\mkfwk-tst.bat DONTRUN - ..\..\..\bin\mkfwk-tst.bat DONTRUN cc - ..\..\..\bin\mkfwk-tst.bat DONTRUN ec - ..\..\..\output\debug\testFwKernel.exe - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - Release\ - Release\ - - - - Test.exe - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) + <_ProjectFileVersion>10.0.30319.1 + Debug\ + Debug\ + ..\..\..\bin\mkfwk-tst.bat DONTRUN + ..\..\..\bin\mkfwk-tst.bat DONTRUN cc + ..\..\..\bin\mkfwk-tst.bat DONTRUN ec + ..\..\..\output\debug\testFwKernel.exe + $(NMakePreprocessorDefinitions) + $(NMakeIncludeSearchPath) + $(NMakeForcedIncludes) + $(NMakeAssemblySearchPath) + $(NMakeForcedUsingAssemblies) + Release\ + Release\ + + + + Test.exe + $(NMakePreprocessorDefinitions) + $(NMakeIncludeSearchPath) + $(NMakeForcedIncludes) + $(NMakeAssemblySearchPath) + $(NMakeForcedUsingAssemblies) - - + + - - - - - - + + + + + + + + + + + + + + - + + diff --git a/Src/Kernel/Test/TestKernel.vcxproj.filters b/Src/Kernel/Test/TestKernel.vcxproj.filters index 5cfbc64637..03352c3d2d 100644 --- a/Src/Kernel/Test/TestKernel.vcxproj.filters +++ b/Src/Kernel/Test/TestKernel.vcxproj.filters @@ -1,48 +1,73 @@  - - {5623374b-c87b-4ab3-8249-2e420565a567} - cpp;c;cxx;def;odl;idl;hpj;bat;asm - - - {fb936a20-a6fe-4029-878f-768c6cba0d0a} - h;hpp;hxx;hm;inl;inc - - - {70ed67c2-a166-44ac-9670-273d82fe0b04} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - + + {5623374b-c87b-4ab3-8249-2e420565a567} + cpp;c;cxx;def;odl;idl;hpj;bat;asm + + + {fb936a20-a6fe-4029-878f-768c6cba0d0a} + h;hpp;hxx;hm;inl;inc + + + {70ed67c2-a166-44ac-9670-273d82fe0b04} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + - - Source Files - - - Source Files - + + Source Files + + + Source Files + - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + - + + \ No newline at end of file diff --git a/Src/Language/Test/TestLgCollatingEngine.h b/Src/Kernel/Test/TestLgCollatingEngine.h similarity index 98% rename from Src/Language/Test/TestLgCollatingEngine.h rename to Src/Kernel/Test/TestLgCollatingEngine.h index 89517fdc9b..6bb566fb2d 100644 --- a/Src/Language/Test/TestLgCollatingEngine.h +++ b/Src/Kernel/Test/TestLgCollatingEngine.h @@ -14,9 +14,9 @@ Last reviewed: #pragma once -#include "testLanguage.h" +#include "testFwKernel.h" -namespace TestLanguage +namespace TestFwKernel { /******************************************************************************************* Tests for LgCollatingEngine diff --git a/Src/Language/Test/TestLgIcuCharPropEngine.h b/Src/Kernel/Test/TestLgIcuCharPropEngine.h similarity index 99% rename from Src/Language/Test/TestLgIcuCharPropEngine.h rename to Src/Kernel/Test/TestLgIcuCharPropEngine.h index 614cc6ac2a..3d68c661d1 100644 --- a/Src/Language/Test/TestLgIcuCharPropEngine.h +++ b/Src/Kernel/Test/TestLgIcuCharPropEngine.h @@ -14,9 +14,9 @@ Last reviewed: #pragma once -#include "testLanguage.h" +#include "testFwKernel.h" -namespace TestLanguage +namespace TestFwKernel { /******************************************************************************************* Tests for LgCharacterPropertyEngine (ICU based implementation) diff --git a/Src/Language/Test/TestRegexMatcher.h b/Src/Kernel/Test/TestRegexMatcher.h similarity index 98% rename from Src/Language/Test/TestRegexMatcher.h rename to Src/Kernel/Test/TestRegexMatcher.h index 836a974607..0da7c041e0 100644 --- a/Src/Language/Test/TestRegexMatcher.h +++ b/Src/Kernel/Test/TestRegexMatcher.h @@ -14,9 +14,9 @@ Last reviewed: #pragma once -#include "testLanguage.h" +#include "testFwKernel.h" -namespace TestLanguage +namespace TestFwKernel { /******************************************************************************************* Tests for LgCharacterPropertyEngine (ICU based implementation) diff --git a/Src/Language/Test/TestRomRenderEngine.h b/Src/Kernel/Test/TestRomRenderEngine.h similarity index 96% rename from Src/Language/Test/TestRomRenderEngine.h rename to Src/Kernel/Test/TestRomRenderEngine.h index 6765374cdd..422b1a6cdf 100644 --- a/Src/Language/Test/TestRomRenderEngine.h +++ b/Src/Kernel/Test/TestRomRenderEngine.h @@ -14,10 +14,10 @@ Last reviewed: #pragma once -#include "testLanguage.h" +#include "testFwKernel.h" #include "RenderEngineTestBase.h" -namespace TestLanguage +namespace TestFwKernel { /******************************************************************************************* Tests for RomRenderEngine diff --git a/Src/Language/Test/TestUniscribeEngine.h b/Src/Kernel/Test/TestUniscribeEngine.h similarity index 97% rename from Src/Language/Test/TestUniscribeEngine.h rename to Src/Kernel/Test/TestUniscribeEngine.h index d5bc915a0c..6caacc5279 100644 --- a/Src/Language/Test/TestUniscribeEngine.h +++ b/Src/Kernel/Test/TestUniscribeEngine.h @@ -14,10 +14,10 @@ Last reviewed: #pragma once -#include "testLanguage.h" +#include "testFwKernel.h" #include "RenderEngineTestBase.h" -namespace TestLanguage +namespace TestFwKernel { /******************************************************************************************* Tests for TestUniscribeEngine diff --git a/Src/Kernel/Test/testFwKernel.cpp b/Src/Kernel/Test/testFwKernel.cpp index 145911a942..078212dffd 100644 --- a/Src/Kernel/Test/testFwKernel.cpp +++ b/Src/Kernel/Test/testFwKernel.cpp @@ -21,7 +21,7 @@ namespace unitpp #ifdef WIN32 ModuleEntry::DllMain(0, DLL_PROCESS_ATTACH); #endif - CoInitialize(NULL); + CheckHr(::OleInitialize(NULL)); RedirectRegistry(); StrUtil::InitIcuDataDir(); } @@ -30,6 +30,13 @@ namespace unitpp #ifdef WIN32 ModuleEntry::DllMain(0, DLL_PROCESS_DETACH); #endif - CoUninitialize(); + ::OleUninitialize(); } } + +namespace TestFwKernel +{ + int g_wsEng = 0; + int g_wsTest = 0; + int g_wsTest2 = 0; +} diff --git a/Src/Kernel/Test/testFwKernel.h b/Src/Kernel/Test/testFwKernel.h index 760d35ce6e..a6ac047e17 100644 --- a/Src/Kernel/Test/testFwKernel.h +++ b/Src/Kernel/Test/testFwKernel.h @@ -31,6 +31,14 @@ namespace TestFwKernel static const StrUni g_pszTest2(L"TESTING"); static const int g_cchTest2 = 7; + const StrUni kszEng(L"en"); + const StrUni kszTest(L"test"); + const StrUni kszTest2(L"tst2"); + + extern int g_wsEng; + extern int g_wsTest; + extern int g_wsTest2; + enum { // Arbitrary values chosen more or less at random... diff --git a/Src/Kernel/Test/testFwKernel.mak b/Src/Kernel/Test/testFwKernel.mak index 027d702232..55c232e850 100644 --- a/Src/Kernel/Test/testFwKernel.mak +++ b/Src/Kernel/Test/testFwKernel.mak @@ -17,15 +17,19 @@ FWKERNELTEST_SRC=$(BUILD_ROOT)\Src\Kernel\Test GENERIC_SRC=$(BUILD_ROOT)\Src\Generic APPCORE_SRC=$(BUILD_ROOT)\Src\AppCore DEBUGPROCS_SRC=$(BUILD_ROOT)\src\DebugProcs -LANGUAGETEST_SRC=$(BUILD_ROOT)\Src\Language\Test +CELLAR_SRC=$(BUILD_ROOT)\Src\Cellar +GRUTIL_LIB=$(BUILD_ROOT)\Src\Graphite\lib +TTFUTIL_LIB=$(BUILD_ROOT)\Src\Graphite\TtfUtil +VIEWS_LIB=$(BUILD_ROOT)\Src\Views\lib +GRFW_SRC=$(BUILD_ROOT)\Src\Graphite\FwOnly # Set the USER_INCLUDE environment variable. -UI=$(UNITPP_INC);$(FWKERNELTEST_SRC);$(FWKERNEL_SRC);$(GENERIC_SRC);$(APPCORE_SRC);$(DEBUGPROCS_SRC);$(LANGUAGETEST_SRC) +UI=$(UNITPP_INC);$(FWKERNELTEST_SRC);$(FWKERNEL_SRC);$(GENERIC_SRC);$(APPCORE_SRC);$(DEBUGPROCS_SRC);$(CELLAR_SRC) !IF "$(USER_INCLUDE)"!="" -USER_INCLUDE=$(UI);$(USER_INCLUDE) +USER_INCLUDE=$(UI);$(USER_INCLUDE);$(GRUTIL_LIB);$(TTFUTIL_LIB);$(VIEWS_LIB);$(GRFW_SRC) !ELSE -USER_INCLUDE=$(UI) +USER_INCLUDE=$(UI);$(GRUTIL_LIB);$(TTFUTIL_LIB);$(VIEWS_LIB);$(GRFW_SRC) !ENDIF !INCLUDE "$(BUILD_ROOT)\bld\_init.mak" @@ -34,9 +38,11 @@ USER_INCLUDE=$(UI) PATH=$(COM_OUT_DIR);$(PATH) +RCFILE=FwKernel.rc + LINK_OPTS=$(LINK_OPTS:/subsystem:windows=/subsystem:console) /LIBPATH:"$(BUILD_ROOT)\Lib\$(BUILD_CONFIG)" CPPUNIT_LIBS=unit++.lib -LINK_LIBS=$(CPPUNIT_LIBS) Generic.lib xmlparse.lib $(LINK_LIBS) +LINK_LIBS=$(CPPUNIT_LIBS) Generic.lib xmlparse.lib Usp10.lib $(LINK_LIBS) # === Object Lists === @@ -53,8 +59,17 @@ OBJ_KERNELTESTSUITE=\ $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\FwKernel\autopch\TsMultiStr.obj\ $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\FwKernel\usepch\TextProps1.obj\ $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\FwKernel\autopch\ActionHandler.obj\ + $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\FwKernel\autopch\UniscribeEngine.obj\ + $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\FwKernel\autopch\UniscribeSegment.obj\ + $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\FwKernel\autopch\RomRenderEngine.obj\ + $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\FwKernel\autopch\RomRenderSegment.obj\ + $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\FwKernel\autopch\LgSimpleEngines.obj\ + $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\FwKernel\autopch\LgIcuCharPropEngine.obj\ + $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\FwKernel\autopch\LgUnicodeCollater.obj\ + $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\FwKernel\autopch\LgKeymanHandler.obj\ $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\FwKernel\autopch\FwStyledText.obj\ $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\FwKernel\autopch\WriteXml.obj\ + $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\FwKernel\autopch\FwXml.obj\ OBJ_ALL=$(OBJ_KERNELTESTSUITE) @@ -80,12 +95,21 @@ COLLECT=$(BUILD_ROOT)\Bin\CollectUnit++Tests.cmd Kernel $(INT_DIR)\genpch\Collection.obj: $(FWKERNELTEST_SRC)\Collection.cpp $(FWKERNELTEST_SRC)\Collection.cpp: $(FWKERNELTEST_SRC)\testFwKernel.h\ - $(LANGUAGETEST_SRC)\MockLgWritingSystemFactory.h\ - $(LANGUAGETEST_SRC)\MockLgWritingSystem.h\ $(FWKERNELTEST_SRC)\TestUndoStack.h\ $(FWKERNELTEST_SRC)\TestTsStrBldr.h\ $(FWKERNELTEST_SRC)\TestTsString.h\ $(FWKERNELTEST_SRC)\TestTsPropsBldr.h\ - $(FWKERNELTEST_SRC)\TestTsTextProps.h + $(FWKERNELTEST_SRC)\TestTsTextProps.h\ + $(FWKERNELTEST_SRC)\MockLgWritingSystemFactory.h\ + $(FWKERNELTEST_SRC)\MockLgWritingSystem.h\ + $(FWKERNELTEST_SRC)\TestRegexMatcher.h\ + $(FWKERNELTEST_SRC)\TestLgCollatingEngine.h\ + $(FWKERNELTEST_SRC)\TestLgIcuCharPropEngine.h\ + $(FWKERNELTEST_SRC)\TestUniscribeEngine.h\ + $(FWKERNELTEST_SRC)\TestRomRenderEngine.h\ + $(FWKERNELTEST_SRC)\RenderEngineTestBase.h $(DISPLAY) Collecting tests for $(BUILD_PRODUCT).$(BUILD_EXTENSION) $(COLLECT) $** $(FWKERNELTEST_SRC)\Collection.cpp + +$(INT_DIR)\FwKernel.res: $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\FwKernel\FwKernel.res + copy $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\FwKernel\FwKernel.res $(INT_DIR)\FwKernel.res >nul diff --git a/Src/Language/UniscribeEngine.cpp b/Src/Kernel/UniscribeEngine.cpp similarity index 100% rename from Src/Language/UniscribeEngine.cpp rename to Src/Kernel/UniscribeEngine.cpp diff --git a/Src/Language/UniscribeEngine.h b/Src/Kernel/UniscribeEngine.h similarity index 100% rename from Src/Language/UniscribeEngine.h rename to Src/Kernel/UniscribeEngine.h diff --git a/Src/Language/UniscribeLinux.cpp b/Src/Kernel/UniscribeLinux.cpp similarity index 100% rename from Src/Language/UniscribeLinux.cpp rename to Src/Kernel/UniscribeLinux.cpp diff --git a/Src/Language/UniscribeLinux.h b/Src/Kernel/UniscribeLinux.h similarity index 100% rename from Src/Language/UniscribeLinux.h rename to Src/Kernel/UniscribeLinux.h diff --git a/Src/Language/UniscribeSegment.cpp b/Src/Kernel/UniscribeSegment.cpp similarity index 100% rename from Src/Language/UniscribeSegment.cpp rename to Src/Kernel/UniscribeSegment.cpp diff --git a/Src/Language/UniscribeSegment.h b/Src/Kernel/UniscribeSegment.h similarity index 100% rename from Src/Language/UniscribeSegment.h rename to Src/Kernel/UniscribeSegment.h diff --git a/Src/Language/LangInstaller.idl b/Src/Language/LangInstaller.idl deleted file mode 100644 index 7f34f6c633..0000000000 --- a/Src/Language/LangInstaller.idl +++ /dev/null @@ -1,48 +0,0 @@ -import "oaidl.idl"; -import "ocidl.idl"; - -#include "common.idh" // DeclareInterface and similar - -// This idl file was written based upon LangInstaller.cs definition of the interface. -// Its is used by linux as linux can't use #import on a tlb -// This idl file could be run through idlimp and replace the C# definition of the interface. - -DeclareLibrary(LangInstaller, 1.0, "InstallLang", C13F5F35-1FD2-4388-B905-394D18D28EFB) -{ - DeclareInterface(LangInstaller, Unknown, EB5B7CFA-6EC8-4641-97D2-5FE338FF5434) - { - HRESULT Install( - [in] BSTR locale, - [in] VARIANT_BOOL fNewLang, - [in] VARIANT_BOOL fAddPUA, - [out, retval] VARIANT_BOOL *pfSuccess); - - HRESULT AddPUAChars( - [in] BSTR locale, - [out, retval] VARIANT_BOOL *pfSuccess); - - HRESULT Uninstall( - [in] BSTR locale, - [out, retval] VARIANT_BOOL *pfSuccess); - - HRESULT ShowCustomLocales( - [out, retval] VARIANT_BOOL *pfSuccess); - - HRESULT ShowCustomLanguages( - [out, retval] VARIANT_BOOL *pfSuccess); - - HRESULT RestoreOriginalSettings( - [in] VARIANT_BOOL fNewLang, - [out, retval] VARIANT_BOOL *pfSuccess); - - HRESULT get_ErrorCode( - [out, retval] long *pErrorCode); - - HRESULT Cleanup(); - }; - - DeclareCoClass(LangInstaller, 5EDF610A-F38F-4034-8714-76B95FDF70EC) - { - interface ILangInstaller; - }; -} diff --git a/Src/Language/Language.def b/Src/Language/Language.def deleted file mode 100644 index 9f0c9e51ba..0000000000 --- a/Src/Language/Language.def +++ /dev/null @@ -1,8 +0,0 @@ -LIBRARY Language - -EXPORTS - DllGetClassObject PRIVATE - DllRegisterServer PRIVATE - DllUnregisterServer PRIVATE - DllCanUnloadNow PRIVATE - DllInstall PRIVATE diff --git a/Src/Language/Language.mak b/Src/Language/Language.mak deleted file mode 100644 index 0e382e62f2..0000000000 --- a/Src/Language/Language.mak +++ /dev/null @@ -1,135 +0,0 @@ -# Input -# ===== -# BUILD_ROOT: d:\FieldWorks -# BUILD_TYPE: d, r, p -# BUILD_CONFIG: Debug, Release, Profile -# - -BUILD_PRODUCT=Language -BUILD_EXTENSION=dll -BUILD_REGSVR=1 - -# LANG_XML=$(BUILD_ROOT)\src\Services\language\XML - -DEFS=$(DEFS) /DGR_FW /D_MERGE_PROXYSTUB /I"$(COM_OUT_DIR)" /I"$(COM_OUT_DIR_RAW)" - -LANG_SRC=$(BUILD_ROOT)\Src\Language -GENERIC_SRC=$(BUILD_ROOT)\Src\Generic -APPCORE_SRC=$(BUILD_ROOT)\Src\AppCore -TEXT_SRC=$(BUILD_ROOT)\Src\Text -CELLAR_SRC=$(BUILD_ROOT)\Src\Cellar -GRUTIL_LIB=$(BUILD_ROOT)\Src\Graphite\lib -TTFUTIL_LIB=$(BUILD_ROOT)\Src\Graphite\TtfUtil -VIEWS_LIB=$(BUILD_ROOT)\Src\Views\lib -GRFW_SRC=$(BUILD_ROOT)\Src\Graphite\FwOnly -# FWUTILS_SRC=$(BUILD_ROOT)\src\FWUtils - -# Set the USER_INCLUDE environment variable. Make sure Lang is first, as we want -# to get the Main.h from there, not any of the others (e.g., in Views) -UI=$(LANG_SRC);$(GENERIC_SRC);$(APPCORE_SRC);$(TEXT_SRC);$(CELLAR_SRC) - -KERNEL_SRC=$(BUILD_ROOT)\src\Kernel -UI=$(UI);$(KERNEL_SRC) - - -!IF "$(USER_INCLUDE)"!="" -USER_INCLUDE=$(UI);$(USER_INCLUDE);$(GRUTIL_LIB);$(TTFUTIL_LIB);$(VIEWS_LIB);$(GRFW_SRC) -!ELSE -USER_INCLUDE=$(UI);$(GRUTIL_LIB);$(TTFUTIL_LIB);$(VIEWS_LIB);$(GRFW_SRC) -!ENDIF - -# XML_INC=$(CELLAR_XML);$(LANG_XML) - -!INCLUDE "$(BUILD_ROOT)\bld\_init.mak" - -!INCLUDE "$(BUILD_ROOT)\bld\_rule.mak" - -PATH=$(COM_OUT_DIR);$(PATH) - -RCFILE=Language.rc -DEFFILE=Language.def -# add Usp10.lib for Uniscribe. -!IF "$(BUILD_TYPE)"=="d" || "$(BUILD_TYPE)"=="b" -LINK_LIBS=Generic.lib Usp10.lib xmlparse.lib $(LINK_LIBS) -!ELSE -LINK_LIBS=Generic.lib Usp10.lib xmlparse.lib $(LINK_LIBS) -!ENDIF - -# === Object Lists === - -OBJ_LANG=\ - $(INT_DIR)\genpch\RegexMatcherWrapper.obj\ - $(INT_DIR)\autopch\LgIcuWrappers.obj\ - $(INT_DIR)\autopch\UniscribeEngine.obj\ - $(INT_DIR)\autopch\UniscribeSegment.obj\ - $(INT_DIR)\autopch\RomRenderEngine.obj\ - $(INT_DIR)\autopch\RomRenderSegment.obj\ - $(INT_DIR)\autopch\LgSimpleEngines.obj\ - $(INT_DIR)\autopch\LgIcuCharPropEngine.obj\ - $(INT_DIR)\autopch\LgUnicodeCollater.obj\ - $(INT_DIR)\autopch\LgKeymanHandler.obj\ - $(INT_DIR)\autopch\ModuleEntry.obj\ - $(INT_DIR)\autopch\FwStyledText.obj\ - $(INT_DIR)\autopch\WriteXml.obj\ - $(INT_DIR)\usepch\TextProps1.obj\ - $(INT_DIR)\autopch\FwXml.obj\ - $(INT_DIR)\autopch\dlldatax.obj\ - - -OBJ_GRUTIL=\ -## $(INT_DIR)\autopch\TtfUtil.obj\ - $(INT_DIR)\autopch\GrUtil.obj\ - - -IDL_MAIN=$(COM_OUT_DIR)\LanguageTlb.idl - -PS_MAIN=LanguagePs - -OBJ_ALL= $(OBJ_LANG) $(OBJ_GRUTIL) - -OBJECTS_IDH=$(COM_INT_DIR)\Objects.idh - -# ? OBJECTS_H=$(COM_INT_DIR)\Objects.h - -# === Targets === -!INCLUDE "$(BUILD_ROOT)\bld\_targ.mak" - - -# === Rules === -PCHNAME=main - -ARG_SRCDIR=$(CELLAR_XML) -!INCLUDE "$(BUILD_ROOT)\bld\_rule.mak" - -ARG_SRCDIR=$(LANG_XML) -!INCLUDE "$(BUILD_ROOT)\bld\_rule.mak" - -ARG_SRCDIR=$(LANG_SRC) -!INCLUDE "$(BUILD_ROOT)\bld\_rule.mak" - -ARG_SRCDIR=$(CELLAR_SRC) -!INCLUDE "$(BUILD_ROOT)\bld\_rule.mak" - -ARG_SRCDIR=$(GENERIC_SRC) -!INCLUDE "$(BUILD_ROOT)\bld\_rule.mak" - -ARG_SRCDIR=$(APPCORE_SRC) -!INCLUDE "$(BUILD_ROOT)\bld\_rule.mak" - -ARG_SRCDIR=$(FWUTILS_SRC) -!INCLUDE "$(BUILD_ROOT)\bld\_rule.mak" - -ARG_SRCDIR=$(GRUTIL_LIB) -!INCLUDE "$(BUILD_ROOT)\bld\_rule.mak" - -## ARG_SRCDIR=$(TTFUTIL_LIB) -## !INCLUDE "$(BUILD_ROOT)\bld\_rule.mak" - -# === Custom Rules === -$(OBJ_ALL): $(OBJECTS_H) - -$(COM_OUT_DIR)\LanguageTlb.tlb: $(COM_OUT_DIR)\LanguageTlb.idl - -$(COM_OUT_DIR)\LanguageTlb.idl: $(LANG_SRC)\Render.idh - -# === Custom Targets === diff --git a/Src/Language/Language.rc b/Src/Language/Language.rc deleted file mode 100644 index 219a81ed1f..0000000000 --- a/Src/Language/Language.rc +++ /dev/null @@ -1,443 +0,0 @@ -/*--------------------------------------------------------------------*//*:Ignore this sentence. -Copyright (c) 1999-2013 SIL International -This software is licensed under the LGPL, version 2.1 or later -(http://www.gnu.org/licenses/lgpl-2.1.html) - -File: Language.rc -Responsibility: -Last reviewed: Not yet. - -Description: - --------------------------------------------------------------------------------*//*:End Ignore*/ -1 TYPELIB LanguageTlb.tlb -#if WIN32 -#include "winresrc.h" -#endif -#include "LangResource.h" - -///////////////////////////////////////////////////////////////////////////// -// -// Version: bldinc.h holds the current version number and it is created by executing -// bin\mkverrsc.exe from within the bin\mk*.bat file. The major and minor version -// numbers are hard-coded in mk*.bat. -#if WIN32 -#include "..\..\Output\Common\bldinc.h" -#endif -VS_VERSION_INFO VERSIONINFO -// NOTE: These defines are in bldinc.h. - FILEVERSION MAJOR_VERSION,MINOR_VERSION,SUITE_REVISION,NUMBER_OF_DAYS - PRODUCTVERSION MAJOR_VERSION,MINOR_VERSION,SUITE_REVISION,NUMBER_OF_DAYS - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE VFT_DLL - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "\0" - VALUE "CompanyName", "SIL\0" - VALUE "FileDescription", "Fieldworks Language support\0" - VALUE "FileVersion", STR_PRODUCT // Uses FILEVERSION. - VALUE "InternalName", "Language\0" - VALUE "LegalCopyright", COPYRIGHT - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "Language.dll\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "FieldWorks\0" - VALUE "ProductVersion", FWSUITE_VERSION - VALUE "SpecialBuild", "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -STRINGTABLE DISCARDABLE -BEGIN - kstidBufferTooSmall "The buffer passed to this method was too small to hold the result." - kstidFracNumVal "Can't report a fractional numeric value" - kstidNoNumeric "Unicode does not define a numeric value for this character" - kstidInvalidUnicode "Found an invalid Unicode character or sequence" - kstidICUCharName "The ICU code retrieving the Unicode character name found an error." - kstidICUDecomp "The ICU code finding the Unicode decomposition encountered an error." - kstidICUNormalize "The ICU code normalizing the text found an error." - kstidICUCase "The ICU function for changing the case found an error." - kstidICUBrkInit "The ICU function to initialize the BreakIterator returned an error." - kstidICUBrkRange "The line break asked for was out of range of the given text." - kstidLangDefaultCollation "DefaultCollation" - kstidUserWs "en" // unless and until someone translates all our resources and - // fixes up the resulting problems in the code. - kstidKeymanInitFailedCaption "Keyman initialization failed" - kstidKeymanInitUnexpectedFailMsg "Unexpected Keyman failure" - kstidKeymanNotRegisteredMsg "No known version of Keyman is registered." - kstidKeymanRootNotRegisteredMsg "Keyman program is not registered correctly." - kstidKeymanDllLoadFailureMsg "Failed to load Keyman32.dll" -END - -STRINGTABLE DISCARDABLE -BEGIN - kstidLangDefXmlMsg001 "Missing CharDef code attribute value.\n" - kstidLangDefXmlMsg002 "Missing CharDef data attribute value.\n" - kstidLangDefXmlMsg003 "Invalid CharDef code attribute value: ""%<0>s"".\n" - kstidLangDefXmlMsg004 "Missing Font file attribute value.\n" - kstidLangDefXmlMsg005 "Missing LgWritingSystem definition!?\n" - kstidLangDefXmlMsg006 "Unbalanced object stack!?\n" - kstidLangDefXmlMsg007 "Unbalanced property value stack!?\n" - kstidLangDefXmlMsg008 "Cannot put multiple objects in an atomic property.\n" - kstidLangDefXmlMsg009 "Cannot open language definition file ""%<0>s""!?\n" - kstidLangDefXmlMsg010 "Error accessing language definition file ""%<0>s""!?\n" - kstidLangDefXmlMsg011 "XML parser detected an XML syntax error!\n" - kstidLangDefXmlMsg012 "Error detected while parsing XML file!\n" - kstidLangDefXmlMsg013 "Missing EncodingConverter install attribute value.\n" -END - -STRINGTABLE DISCARDABLE -BEGIN - kstidLangDefXmlMsg014 "Problem while opening project" - kstidLangDefXmlMsg015 "The %<0>s writing system could not be installed, possibly due to insufficient user privileges.%nThis may affect sorting, special character definitions, and other aspects of the writing system.%n" -END - -// Message strings for the XML import/export process. These are shared with the Language DLL. - -STRINGTABLE DISCARDABLE -BEGIN - kstidXmlUserWs "en" -END - -STRINGTABLE DISCARDABLE -BEGIN - kstidXmlInfoMsg001 " %<0>d %<1>s processed, %<2>d successful, %<3>d attempted\n" - kstidParameter "Parameter" - kstidParameters "Parameters" - kstidXmlInfoMsg002 "%<0>d custom %<1>s have been added to the database schema.\n" - kstidField "field" - kstidFields "fields" - kstidXmlInfoMsg003 "First pass of reading the XML file took %<0>d %<1>s.\n" - kstidXmlInfoMsg007 "Creating %<0>d objects after the first pass took %<1>d %<2>s.\n" - kstidXmlInfoMsg009 "Second pass of reading the XML file took %d %s.\n" - kstidXmlInfoMsg004 "Storing data after the second pass took %<0>d %<1>s.\n" - kstidXmlInfoMsg006 "Loading the XML file into the database took %<0>d %<1>s.\n" - kstidSecond "second" - kstidSeconds "seconds" - kstidXmlInfoMsg005 "Storing the data into the database took %<0>d SQL %<1>s.\n" - kstidCommand "command" - kstidCommands "commands" - kstidXmlInfoMsg008 "Creating %<0>d empty structured text paragraphs.\n" - kstidXmlInfoMsg010 "d""> does not match the database version (%<1>d).\n" - kstidXmlInfoMsg011 "No version number given with .\n" - - kstidXmlErrorMsg001 "<%<0>s> elements cannot be nested inside either or !\n" - kstidXmlErrorMsg002 "<%<0>s> is improperly nested!\n" - kstidXmlErrorMsg003 "<%<0>s> must be nested inside <%<1>s> or an object attribute element!\n" - kstidXmlErrorMsg004 "<%<0>s> must be nested inside <%<1>s>...s>!\n" - kstidXmlErrorMsg005 "<%<0>s> must be nested inside an object attribute element!\n" - kstidXmlErrorMsg006 "<%<0>s> must be nested inside an object element!\n" - kstidXmlErrorMsg007 "<%<0>s> not recognized nested within either or !\n" - kstidXmlErrorMsg008 " must be a toplevel element inside !?\n" - kstidXmlErrorMsg009 " must be a toplevel element inside !?\n" - kstidXmlErrorMsg010 "<%<0>s> must be the outermost XML element!?\n" - kstidXmlErrorMsg011 "Cannot convert ""%<0>s"" into a Language Writing system code.\n" - kstidXmlErrorMsg012 "Cannot create GUID for object identifier!\n" - kstidXmlErrorMsg013 "Cannot get buffer from the XML parser [pass 1]! (Out of memory?)\n" - kstidXmlErrorMsg014 "Cannot get buffer from the XML parser [pass 2]! (Out of memory?)\n" - kstidXmlErrorMsg015 "Cannot have some ord attribute values missing and some present!\n" - kstidXmlErrorMsg016 "Cannot read the CmObject table in the database!\n" - kstidXmlErrorMsg017 "Invalid list root id '%<0>s' in custom field definition [%<1>S]??\n" - kstidXmlErrorMsg018 "ERROR %<0>s executing SQL command:\n %<1>s\n" - kstidXmlErrorMsg019 "ERROR %<0>s executing SQL function on line %<1>d of %<2>s:\n %<3>s\n" - kstidXmlErrorMsg020 "ERROR creating %<0>S (%<1>d, %<2>g)\n" - kstidXmlErrorMsg021 "ERROR in SetMultiBigStr$ %<0>d,%<1>d,%<2>d,'...',0x...\n" - kstidXmlErrorMsg022 "ERROR in SetMultiBigTxt$ %<0>d,%<1>d,%<2>d,'...'\n" - kstidXmlErrorMsg023 "ERROR in SetMultiStr$ %<0>d,%<1>d,%<2>d,'...',0x...\n" - kstidXmlErrorMsg024 "ERROR in SetMultiTxt$ %<0>d,%<1>d,%<2>d,'...'\n" - kstidXmlErrorMsg025 "ERROR in UPDATE [%<0>S] SET [%<1>S]=? WHERE [Id]=%<2>d\n" - kstidXmlErrorMsg026 "ERROR in UPDATE [%<0>S] SET [%<1>S]=?,%<2>S_Fmt=? WHERE [Id]=%<3>d\n" - kstidXmlErrorMsg027 "ERROR with INSERT %<0>S_%<1>S (Src, Dst) VALUES (%<2>d, %<3>d)\n" - kstidXmlErrorMsg028 "ERROR with INSERT %<0>S_%<1>S (Src, Dst, Ord) VALUES (%<2>d, %<3>d, %<4>d)\n" - kstidXmlErrorMsg029 "ERROR with UPDATE [%<0>S] SET [%<1>S]=%<2>d WHERE [Id]=%<3>d\n" - kstidXmlErrorMsg030 "ERROR! BUG! Invalid field data type storing data?? (%<0>d)\n" - kstidXmlErrorMsg031 "Empty <%<0>s> element?\n" -// kstidXmlErrorMsg032 "Empty element? (cbtext = 0)\n" - kstidXmlErrorMsg033 "Empty element?\n" -// kstidXmlErrorMsg034 "Empty element? (cbtext = 0)\n" - kstidXmlErrorMsg035 "Empty MultiString element? (cbtext = 0)\n" - kstidXmlErrorMsg036 "Empty String element? (cbtext = 0)\n" - kstidXmlErrorMsg037 "Error detected while parsing XML file [pass 1]!\n" - kstidXmlErrorMsg038 "Error detected while parsing XML file [pass 2]!\n" - kstidXmlErrorMsg039 "Found a with identical properties to preceding : these have been merged.\n" - kstidXmlErrorMsg040 "INTERNAL DATA CORRUPTION: unable to get class for field!\n" - kstidXmlErrorMsg041 "INTERNAL XML ELEMENT STACK CORRUPTED!?\n" - kstidXmlErrorMsg042 "Ignoring s=""%<1>s""> in the absence of a %<2>s attribute.\n" -// kstidXmlErrorMsg043 "Ignoring s""> in the absence of a offset attribute.\n" - kstidXmlErrorMsg044 "Ignoring s""> in the absence of a ws attribute.\n" - kstidXmlErrorMsg045 "Ignoring s""> in the absence of a wsBase attribute.\n" - kstidXmlErrorMsg046 "Improperly nested <%<0>s name=""%<1>s""> element!\n" - kstidXmlErrorMsg047 "Improperly nested <%<0>s> element!\n" - kstidXmlErrorMsg048 "Invalid Boolean value for the %<0>S field of a %<1>S object: ""%<2>s"".\n" - kstidXmlErrorMsg049 "Invalid GUID value in s=""%<1>s""> element!\n" - kstidXmlErrorMsg050 "Invalid GenDate value for the %<0>S field of a %<1>S object: ""%<2>s"".\n" - kstidXmlErrorMsg051 "Invalid Integer value for the %<0>S field of a %<1>S object: ""%<2>s"".\n" - kstidXmlErrorMsg052 "Invalid Numeric value for the %<0>S field of a %<1>S object: ""%<2>s"".\n" - kstidXmlErrorMsg053 "Invalid XML Element: unknown class ""%<0>s""\n" - kstidXmlErrorMsg054 "Invalid XML Element: unknown field ""%<0>s""\n" - kstidXmlErrorMsg055 "Invalid bin attribute in Float element: ""%<0>s"".\n" - kstidXmlErrorMsg056 "Invalid character data found between runs: """ - kstidXmlErrorMsg057 "Invalid class attribute for CustomField element: %<0>s\n" - kstidXmlErrorMsg058 "Invalid writing system in s"">!\n" - kstidXmlErrorMsg059 "Invalid writing system in s"">!\n" - kstidXmlErrorMsg060 "Invalid field type containing <%<0>s> element: %<1>d.\n" - kstidXmlErrorMsg061 "Invalid ord attribute in Link element: ""%<0>s"".\n" - kstidXmlErrorMsg062 "Invalid ord attribute value: ""%<0>s""\n" - kstidXmlErrorMsg063 "Invalid target attribute for CustomField element: %<0>s\n" - kstidXmlErrorMsg064 "Invalid type attribute for CustomField element: %<0>s\n" - kstidXmlErrorMsg065 "Invalid Float value for the %<0>S field of a %<1>S object: ""%<2>s"".\n" - kstidXmlErrorMsg066 "Invalid value in s=""%<1>s"">: need on, off or invert\n" - kstidXmlErrorMsg067 "Invalid value in s=""%<1>s"">.\n" - kstidXmlErrorMsg068 "Invalid value in s=""%<1>s"">.\n" -// kstidXmlErrorMsg069 "Invalid value in s"">: need on, off or invert\n" -// kstidXmlErrorMsg070 "Invalid value in s"">.\n" -// kstidXmlErrorMsg071 "Invalid value in s"">.\n" - kstidXmlErrorMsg072 "Invalid value in s"">: need off, super, or sub\n" - kstidXmlErrorMsg073 "Invalid value in s"">: need chars or picture\n" - kstidXmlErrorMsg074 "Invalid value in s"">: need none, single, double, dotted, dashed, or strikethrough\n" - kstidXmlErrorMsg075 "Invalid Guid value for the %<0>S field of a %<1>S object: ""%<2>s"".\n" - kstidXmlErrorMsg076 "Invalid Time value for the %<0>S field of a %<1>S object: ""%<2>s"".\n" - kstidXmlErrorMsg077 "Missing Link target: ""%<0>s""\n" - kstidXmlErrorMsg078 "Missing both bin and val attributes in Float element.\n" - - kstidXmlErrorMsg079 "Missing %<0>s attribute for %<1>s element.\n" - - kstidXmlErrorMsg080 "Missing writing system for element!\n" - kstidXmlErrorMsg081 "Missing writing system for element!\n" -// THE NEXT SEVERAL ITEMS SHOULD BE REPLACED BY THE NEW kstidXmlErrorMsg079 SOMETIME. - kstidXmlErrorMsg089 "Missing val attribute in GenDate element.\n" - kstidXmlErrorMsg090 "Missing val attribute in Guid element.\n" - kstidXmlErrorMsg091 "Missing val attribute in Integer element.\n" - kstidXmlErrorMsg092 "Missing val attribute in Numeric element.\n" - kstidXmlErrorMsg093 "Missing val attribute in Time element.\n" - kstidXmlErrorMsg094 "Out of memory after first pass through XML file!\n" - kstidXmlErrorMsg095 "Out of memory before parsing anything!\n" - kstidXmlErrorMsg096 "Out of memory!\n" - kstidXmlErrorMsg097 "Repeated object GUID\n" - kstidXmlErrorMsg098 "Repeated object ID\n" - kstidXmlErrorMsg099 "SQL_PARAM_DIAG_UNAVAILABLE INFO creating %<0>S (%<1>d, %<2>g, %<3>d, %<4>d, %<5>d)\n" - kstidXmlErrorMsg100 "SQL_PARAM_ERROR creating %<0>S (%<1>d, %<2>g, %<3>d, %<4>d, %<5>d)\n" - kstidXmlErrorMsg101 "SQL_PARAM_UNUSED creating %<0>S (%<1>d, %<2>g, %<3>d, %<4>d, %<5>d)\n" - kstidXmlErrorMsg102 "The database is not empty!\n" - kstidXmlErrorMsg103 "UNAVAIL INFO in SetMultiBigStr$ %<0>d,%<1>d,%<2>d,'...',0x...\n" - kstidXmlErrorMsg104 "UNAVAIL INFO in SetMultiBigTxt$ %<0>d,%<1>d,%<2>d,'...'\n" - kstidXmlErrorMsg105 "UNAVAIL INFO in SetMultiStr$ %<0>d,%<1>d,%<2>d,'...',0x...\n" - kstidXmlErrorMsg106 "UNAVAIL INFO in SetMultiTxt$ %<0>d,%<1>d,%<2>d,'...'\n" - kstidXmlErrorMsg107 "UNAVAIL INFO in UPDATE [%<0>S] SET [%<1>S]=? WHERE [Id]=%<2>d\n" - kstidXmlErrorMsg108 "UNAVAIL INFO in UPDATE [%<0>S] SET [%<1>S]=?,%<2>S_Fmt=? WHERE [Id]=%<3>d\n" - kstidXmlErrorMsg109 "UNAVAILABLE INFO creating %<0>S (%<1>d, %<2>g)\n" - kstidXmlErrorMsg110 "UNAVAILABLE INFO for INSERT %<0>S_%<1>S (Src, Dst) VALUES (%<2>d, %<3>d)\n" - kstidXmlErrorMsg111 "UNAVAILABLE INFO for INSERT (Src, Dst, Ord) %<0>S_%<1>S VALUES (%<2>d, %<3>d, %<4>d)\n" - kstidXmlErrorMsg112 "UNAVAILABLE INFO for UPDATE [%<0>S] SET [%<1>S]=%<2>d WHERE [Id]=%<3>d\n" - kstidXmlErrorMsg113 "UNUSED creating %<0>S (%<1>d, %<2>g)\n" - kstidXmlErrorMsg114 "UNUSED data INSERT %<0>S_%<1>S (Src, Dst) VALUES (%<2>d, %<3>d)\n" - kstidXmlErrorMsg115 "UNUSED data INSERT %<0>S_%<1>S (Src, Dst, Ord) VALUES (%<2>d, %<3>d, %<4>d)\n" - kstidXmlErrorMsg116 "UNUSED data UPDATE [%<0>S] SET [%<1>S]=%<2>d WHERE [Id]=%<3>d\n" - kstidXmlErrorMsg117 "UNUSED in SetMultiBigStr$ %<0>d,%<1>d,%<2>d,'...',0x...\n" - kstidXmlErrorMsg118 "UNUSED in SetMultiBigTxt$ %<0>d,%<1>d,%<2>d,'...'\n" - kstidXmlErrorMsg119 "UNUSED in SetMultiStr$ %<0>d,%<1>d,%<2>d,'...',0x...\n" - kstidXmlErrorMsg120 "UNUSED in SetMultiTxt$ %<0>d,%<1>d,%<2>d,'...'\n" - kstidXmlErrorMsg121 "UNUSED in UPDATE [%<0>S] SET [%<1>S]=? WHERE [Id]=%<2>d\n" - kstidXmlErrorMsg122 "UNUSED in UPDATE [%<0>S] SET [%<1>S]=?,%<2>S_Fmt=? WHERE [Id]=%<3>d\n" - kstidXmlErrorMsg123 "Unbalanced XML element stack!?\n" - kstidXmlErrorMsg124 "Unbalanced element stack!?\n" - kstidXmlErrorMsg125 "Unbalanced object id stack!?\n" - kstidXmlErrorMsg126 "Unbalanced property name stack!?\n" - kstidXmlErrorMsg127 "Unknown XML end tag: ""%<0>s""\n" - kstidXmlErrorMsg128 "Unknown XML start tag: ""%<0>s""\n" - kstidXmlErrorMsg129 "WARNING: GUID-based id strings do not all begin with the same letter!\n" - kstidXmlErrorMsg130 "WARNING: You've got to be kidding: string property length > 1 gigabyte!!!\n" - kstidXmlErrorMsg131 "WARNING: the ownership hierarchy is not properly nested!\n" - kstidXmlErrorMsg132 "Warning: String does not have a writing system!\n" - kstidXmlErrorMsg133 "Warning: ignoring extra character at the end of %<0>s data.\n" - kstidXmlErrorMsg134 "Wrong field type for Link element: %<0>d\n" - kstidXmlErrorMsg135 "XML parser detected an XML syntax error [pass 1]!\n" - kstidXmlErrorMsg136 "XML parser detected an XML syntax error [pass 2]!\n" - kstidXmlErrorMsg137 "<%<0>s> not recognized nested within !\n" - kstidXmlErrorMsg138 "<%<0>s> not recognized nested within !\n" - kstidXmlErrorMsg139 "Invalid value in <%<0>s bold=""%<1>s"">: need on, off or invert\n" - kstidXmlErrorMsg140 "Ignoring <%<0>s fontsizeUnit=""%<1>s""> in the absence of a fontsize attribute.\n" - kstidXmlErrorMsg141 "Invalid value in <%<0>s fontsize=""%<1>s"">.\n" - kstidXmlErrorMsg142 "Invalid value in <%<0>s fontsizeUnit=""%<1>s"">.\n" - kstidXmlErrorMsg143 "Invalid value in <%<0>s align=""%<1>s"">: need leading, left, center, right, trailing, or justify\n" - kstidXmlErrorMsg144 "Ignoring <%<0>s ows=""%<1>s""> in the absence of a ws attribute.\n" - kstidXmlErrorMsg145 "Ignoring <%<0>s owsBase=""%<1>s""> in the absence of a wsBase attribute.\n" - kstidXmlErrorMsg146 "Invalid value in <%<0>s italic=""%<1>s"">: need on, off or invert\n" - kstidXmlErrorMsg147 "Invalid value in <%<0>s lineHeight=""%<1>s"">.\n" - kstidXmlErrorMsg148 "Invalid value in <%<0>s lineHeightUnit=""%<1>s"">.\n" - kstidXmlErrorMsg149 "Ignoring <%<0>s lineHeightUnit=""%<1>s""> in the absence of a lineHeight attribute.\n" - kstidXmlErrorMsg150 "Invalid value in <%<0>s offset=""%<1>s"">.\n" - kstidXmlErrorMsg151 "Invalid value in <%<0>s offsetUnit=""%<1>s"">.\n" - kstidXmlErrorMsg152 "Ignoring <%<0>s offsetUnit=""%<1>s""> in the absence of a offset attribute.\n" - kstidXmlErrorMsg153 "Invalid value in <%<0>s superscript=""%<1>s"">: need off, super, or sub.\n" - kstidXmlErrorMsg154 "Invalid value in <%<0>s underline=""%<1>s"">: need none, single, double, dotted, dashed, or strikethrough.\n" -// kstidXmlErrorMsg155 "Ignoring an empty .\n" - kstidXmlErrorMsg156 "Warning: Invalid GUID-based id string for importing object.\n" - kstidXmlErrorMsg157 "Warning: Invalid writing system in s"" .../>.\n" - kstidXmlErrorMsg158 "Warning: Invalid field for implicit target in a Link element: %<0>S.\n" - kstidXmlErrorMsg159 "Warning: Implicit MoInflAffixSlot target in a Link element is missing the name attribute.\n" - kstidXmlErrorMsg160 "Warning: Implicit %<0>s target in a Link element cannot access the PartOfSpeech list.\n" - kstidXmlErrorMsg161 "Warning: Implicit %<0>s target in Link element cannot find/create a needed PartOfSpeech.\n" - kstidXmlErrorMsg162 "Warning: Implicit %<0>s target in Link element is missing one or more required attributes.\n" - kstidXmlErrorMsg163 "Warning: Implicit ReversalIndexEntry target in a Link element is missing the form attribute.\n" - kstidXmlErrorMsg164 "Warning: Implicit ReversalIndexEntry target in a Link element cannot find/create the ReversalIndex.\n" - kstidXmlErrorMsg165 "Warning: Implicit ReversalIndexEntry target in a Link element has an invalid form attribute.\n" - kstidXmlErrorMsg166 "Error obtaining LexDb id from the database!?\n" - kstidXmlErrorMsg167 "Info: Implicit %<0>s target in a Link element has abbr attribute ""%<1>S"" which matches a Name value.\n" - kstidXmlErrorMsg168 "Info: Implicit %<0>s target in a Link element has name attribute ""%<1>S"" which matches an Abbreviation value.\n" - kstidXmlErrorMsg169 "Implicit MoInflAffixSlot target in a Link element has neither the nameOwner nor the abbrOwner attribute.\n" - kstidXmlErrorMsg170 "Implicit %<0>s target in a Link element is missing the sense or entry attribute.\n" - kstidXmlErrorMsg171 "Implicit %<0>s target in a Link element is missing the name or abbr attribute.\n" - kstidXmlErrorMsg172 "Invalid class for implicit target in Link element: %<0>S.\n" - kstidXmlErrorMsg173 "Warning: Invalid writing system in s"" .../>.\n" - kstidXmlErrorMsg174 "Warning: empty ws attribute found: substituting analysis writing system.\n" - kstidXmlErrorMsg175 "Invalid value in <%<0>s spellcheck=""%<1>s"">: need normal, doNotCheck, or forceCheck.\n" - - kstidXmlDebugMsg001 "DEBUG: External Link target: db=""%<0>s"", target=""%<1>s""\n" - kstidXmlDebugMsg002 "DEBUG: Repeated run properties found: ibProp = %<0>d, Top()->ibProp = %<1>d\n" - kstidXmlDebugMsg003 "ERROR CAUGHT on line %<0>d of %<1>s: %<2>s\n" - kstidXmlDebugMsg004 "SUCCESSFULLY CREATED %<0>S (%<1>d, %<2>g, %<3>d, %<4>d, %<5>d)\n" - kstidXmlDebugMsg005 "UNKNOWN ERROR CAUGHT on line %<0>d of %<1>s\n" - kstidXmlDebugMsg006 "m_vetiOpen[%<0>d].m_elty = %<1>s, m_icls = %<2>d\n" - kstidXmlDebugMsg007 "rpi[%<0>d] = %<1>d, %<2>d, 0x" - kstidXmlDebugMsg008 "run[%<0>d]: ichMin = %<1>d, ibProp = %<2>d; distinct = %<3>d, fMerge = %<4>s\n" -END - -STRINGTABLE DISCARDABLE -BEGIN - kstidXmlInfoMsg101 "Info: Creating new inflection class with ws=""%<0>S"", abbr=""%<1>s"", and name=""%<2>s"".\n" - kstidXmlInfoMsg102 "Info: Creating new inflectional affix slot with ws=""%<0>S"" and name=""%<1>s"", for POS with abbr=""%<2>s"" and name=""%<3>s"".\n" - kstidXmlInfoMsg103 "Info: Creating new object with ws=""%<0>S"", abbr=""%<1>s"", and name=""%<2>s"" in the %<3>S list.\n" - kstidXmlInfoMsg104 "Warning: The %<0>S list is not supposed to be extensible!\n" - kstidXmlInfoMsg105 "Info: Creating ReversalIndex for the %<0>S (""%<1>S"") language.\n" - kstidXmlInfoMsg106 "Info: Creating ReversalIndexEntry ""%<0>S"" (""%<1>S"") for the %<2>S (""%<3>S"") language.\n" - kstidXmlInfoMsg107 "%<0>s [repeated %<1>d more times in the XML file]\n" - kstidXmlInfoMsg108 "Warning: Truncating string from %<0>d characters to %<1>d characters for the %<2>S field of a %<3>S object.\n" -END - -STRINGTABLE DISCARDABLE -BEGIN - kstidXmlInfoMsg201 "%<0>u custom field %<1>s written.\n" - kstidDefinition "definition" - kstidDefinitions "definitions" - kstidXmlInfoMsg202 "Dumping the XML file from the database took %<0>d %<1>s.\n" - kstidXmlInfoMsg203 "Loading %<0>u %<1>s of Object Ownership Hierarchy data took %<2>d %<3>s.\n" - kstidRow "row" - kstidRows "rows" - kstidXmlInfoMsg206 "Loading %<0>u %<1>s of ""Binary"" data took %<2>d %<3>s.\n" - kstidXmlInfoMsg207 "Loading %<0>u %<1>s of ""Image"" data took %<2>d %<3>s.\n" - kstidXmlInfoMsg210 "Loading %<0>u %<1>s of ""MultiString"" data took %<2>d %<3>s.\n" - kstidXmlInfoMsg211 "Loading %<0>u %<1>s of ""MultiUnicode"" data took %<2>d %<3>s.\n" - kstidXmlInfoMsg212 "Loading %<0>u %<1>s of ""ReferenceAtom"" data took %<2>d %<3>s.\n" - kstidXmlInfoMsg213 "Loading %<0>u %<1>s of ""ReferenceCollection/Sequence"" data took %<2>d %<3>s.\n" - kstidXmlInfoMsg214 "Loading %<0>u %<1>s of ""String"" data took %<2>d %<3>s.\n" - kstidXmlInfoMsg215 "Loading %<0>u %<1>s of ""Unicode"" data took %<2>d %<3>s.\n" - kstidXmlInfoMsg216 "Loading %<0>u %<1>s of basic attribute data took %<2>d %<3>s.\n" - kstidXmlInfoMsg217 "Loading the data from the database took %<0>d SQL %<1>s.\n" - kstidXmlInfoMsg218 "Rebuilding the object hierarchy table took %<0>d %<1>s.\n" - kstidXmlInfoMsg219 "SQL[%<0>d]: %<1>s\n" - kstidXmlInfoMsg220 "Writing the XML file took %<0>d %<1>s.\n" - kstidXmlInfoMsg221 " Reading %<0>d additional characters of string data.\n" - kstidXmlInfoMsg222 " Reading %<0>d additional bytes of format data.\n" - kstidXmlInfoMsg224 "Owner of object %<0>d does not have a name in the default analysis language.\n" - kstidXmlInfoMsg225 "Owner of object %<0>d does not have an abbreviation in the default analysis language.\n" - - kstidXmlErrorMsg201 " %<0>s - %<1>s\n" - kstidXmlErrorMsg202 "BUG/FEATURE - cannot handle Run scalar property code ""%<0>s""\n" - kstidXmlErrorMsg203 "ERROR %<0>s executing SQL command:\n %<1>s\n" - kstidXmlErrorMsg204 "ERROR %<0>s executing SQL function on line %<1>d of %<2>s:\n %<3>s\n" - kstidXmlErrorMsg205 "ERROR - invalid Run scalar property length (%<0>d)\n" - kstidXmlErrorMsg206 "ERROR - invalid Run string property length\n" - kstidXmlErrorMsg207 "ERROR - invalid binary format data for a string: %<0>d run%<1>s, %<2>d byte%<3>s." - kstidRun "run" - kstidRuns "runs" - kstidByte "byte" - kstidBytes "bytes" - kstidXmlErrorMsg208 "ERROR - invalid binary format data for a string: %<0>d run%<1>s." - kstidXmlErrorMsg209 "ERROR - invalid binary format data for a string: only %<0>d byte%<1>s." - kstidXmlErrorMsg210 "ERROR - invalid binary format data for a string: run %<0>d does not start after\nrun %<1>d (min %<2>d <= min %<3>d).\n" - kstidXmlErrorMsg211 "ERROR - invalid binary format data for a string: run %<0>d has invalid internal\noffset (%<1>d)." - kstidXmlErrorMsg212 "ERROR - invalid binary format data for a string: run %<0>d starts after end of\nstring (length = %<1>d <= min = %<2>d)." - kstidXmlErrorMsg213 "ERROR - invalid binary format data for a string: run %<0>d starts before the\nstring (min = %<1>d)." - kstidXmlErrorMsg214 "ERROR - invalid embedded object type in Run string property (%<0>d)\n" - kstidXmlErrorMsg215 "ERROR - invalid writing system of Run string property length\n" - kstidXmlErrorMsg216 "ERROR - invalid internal writing system of Run scalar property code\n" - kstidXmlErrorMsg217 "ERROR - invalid internal writing system of Run string property code\n" - kstidXmlErrorMsg218 "ERROR - unknown Run scalar property code (%<0>d)\n" - kstidXmlErrorMsg219 "ERROR - unknown Run string property code (%<0>d)\n" - kstidXmlErrorMsg220 "ERROR [%<0>d]: Constructed Query overflowed its buffer!\n""%<1>s""\n" - kstidXmlErrorMsg221 "WARNING - invalid binary format data for a string: 0 runs, %<0>d byte%<1>s." - kstidXmlErrorDecoding "ERROR decoding the properties: check the log file for details." - kstidXmlErrorMsg222 "WARNING: no writing system" - kstidXmlErrorMsg223 "Cannot get version number from the database!?\n" - kstidXmlErrorMsg224 "Corrupted database: missing %<0>S object (hobj = %<1>d) for %<2>S (hobj = %<3>d)\n" - kstidXmlErrorMsg225 "Corrupted database: missing integer property for %<1>S style.%n" - kstidXmlErrorMsg226 "Corrupted database: missing %<0>d integer properties for %<1>S style.%n" - kstidXmlErrorMsg227 "Corrupted database: missing integer property in paragraph's style.%n" - kstidXmlErrorMsg228 "Corrupted database: missing %<0>d integer properties in paragraph's style.%n" - kstidXmlErrorMsg229 "Corrupted database: missing string property for %<1>S style.%n" - kstidXmlErrorMsg230 "Corrupted database: missing %<0>d string properties for %<1>S style.%n" - kstidXmlErrorMsg231 "Corrupted database: missing string property in paragraph's style.%n" - kstidXmlErrorMsg232 "Corrupted database: missing %<0>d string properties in paragraph's style.%n" - kstidUNKNOWN "UNKNOWN" -END - -STRINGTABLE DISCARDABLE -BEGIN - kstidXmlErrorMsg301 "Invalid hvoOwner passed to ImportXmlObject method: %<0>d\n" - kstidXmlErrorMsg302 "Unknown clid (%<0>d) retrieved for hvoOwner: SOMETHING IS VERY WRONG!\n" - kstidXmlErrorMsg303 "Unknown flid passed to ImportXmlObject method: %<0>d\n" - kstidXmlErrorMsg304 "Invalid flid passed to ImportXmlObject method: flid = %<0>d, but class = %<1>d\n" - kstidXmlErrorMsg305 "Empty database: THIS SHOULD NEVER HAPPEN!\n" - kstidXmlErrorMsg306 "<%<0>s> must be nested inside <%<1>s>...s>!\n" - kstidXmlErrorMsg307 "DEBUG: Unknown flid for list: %<0>d\n" - kstidXmlInfoMsg223 "Info: Creating new writing system for code ""%<0>s"".\n" - kstidXmlErrorMsg308 "Warning: Picture file ""%<0>s"" does not exist.\n" - kstidXmlErrorMsg309 "Warning: Cannot copy picture file ""%<0>s"" to ""%<1>s"".\n" - kstidXmlErrorMsg310 "DEBUG: Unknown flid for folders: %<0>d" - kstidXmlErrorMsg311 "ERROR - Invalid start tag <%<0>s> for XML file: expected <%<1>s>.\n" - kstidXmlErrorMsg312 "Warning: Media file ""%<0>s"" does not exist.\n" - kstidXmlErrorMsg313 "Warning: Cannot copy media file ""%<0>s"" to ""%<1>s"".\n" - kstidXmlErrorMsg314 "ERROR - Cannot create directory ""%<0>s"".\n" - - kstidXmlErrorMsg315 "Invalid %<0>s attribute value for %<1>s element: not GUID based.\n" - kstidXmlErrorMsg316 "Invalid %<0>s attribute value for %<1>s element: bad GUID value.\n" - kstidXmlErrorMsg317 "Object id being merged (%<0>g) should not appear in the updated list.\n" - kstidXmlErrorMsg318 "Object id being deleted (%<0>g) should not appear in the updated list.\n" - kstidXmlErrorMsg319 "A list update XML file must begin with a field tag, not a class tag!\n" - kstidXmlErrorMsg320 "ERROR in ""%s"" [param=%d].\n" - kstidXmlErrorMsg321 "UNUSED in ""%s"" [param=%d].\n" - kstidXmlErrorMsg322 "UNAVAIL INFO in ""%s"" [param=%d].\n" - kstidXmlErrorMsg323 "Warning: Storing only the first %<0>d of %<1>d characters for this string: ""%<2>s"".\n" - - kstidXmlInfoMsg301 "Initializing from the database before reading the XML file took %<0>d %<1>s.\n" - kstidXmlInfoMsg302 "Processing the update information took %<0>d %<1>s.\n" - kstidXmlInfoMsg303 "Creating new objects took %<0>d %<1>s.\n" - kstidXmlInfoMsg304 "Updating owners and sequence positions took %<0>d %<1>s.\n" - kstidXmlInfoMsg305 "Fixing links to merged or deleted list items took %<0>d %<1>s.\n" - kstidXmlInfoMsg306 "Deleting obsolete database objects took %<0>d %<1>s.\n" - kstidXmlInfoMsg307 "Removing possibly obsolete data from list items took %<0>d %<1>s.\n" - kstidXmlInfoMsg308 "Collecting obsolete database objects to delete took %<0>d %<1>s.\n" - kstidXmlInfoMsg309 "Need to delete %<0>d obsolete database %<1>s.\n" - kstidObject "object" - kstidObjects "objects" - kstidXmlInfoMsg310 "(Special initializing for update alone took %<0>d %<1>s.)\n" - kstidXmlInfoMsg311 "Info: Creating %<0>s Pair Lexical Reference Type with name=""%<1>S"" and abbr=""%<2>S"".\n" - kstidSense "Sense" - kstidEntry "Entry" -END diff --git a/Src/Language/Language.vcxproj b/Src/Language/Language.vcxproj deleted file mode 100644 index 847e71362b..0000000000 --- a/Src/Language/Language.vcxproj +++ /dev/null @@ -1,140 +0,0 @@ - - - - - Bounds - Win32 - - - Debug - Win32 - - - Release - Win32 - - - - {C3B9238A-A4F5-48CE-BBCE-313A77D8DABC} - Language - - - - - - - MakeFileProj - - - - Makefile - false - - - Makefile - false - - - Makefile - false - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - .\Release\ - .\Release\ - ..\..\bin\mklg.bat r - ..\..\bin\mklg.bat r cc - - ..\..\output\release\language.dll - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - .\Bounds\ - .\Bounds\ - ..\..\bin\mklg.bat b - ..\..\bin\mklg.bat b cc - - ..\..\output\Bounds\language.dll - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - .\Debug\ - .\Debug\ - ..\..\bin\mklg.bat - ..\..\bin\mklg.bat cc - - ..\..\output\debug\language.dll - $(NMakePreprocessorDefinitions) - ..\..\Output\Common\Raw;..\..\Output\Common;..\Kernel;..\Generic;.;$(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Src/Language/LanguageExtra_GUIDs.cpp b/Src/Language/LanguageExtra_GUIDs.cpp deleted file mode 100644 index b113448168..0000000000 --- a/Src/Language/LanguageExtra_GUIDs.cpp +++ /dev/null @@ -1,10 +0,0 @@ -/* - * This (handmade) file contains GUIDs that are not defined in IDL - * - * Neil Mayhew - 2011-06-07 - */ - -#include - -DEFINE_UUIDOF(UniscribeSegment,0x61299C3B,0x54D6,0x4c46,0xAC,0xE5,0x72,0xB9,0x12,0x8F,0x20,0x48); -DEFINE_UUIDOF(RomRenderSegment,0xA124E0C1,0xDD4B,0x11d2,0x80,0x78,0x00,0x00,0xC0,0xFB,0x81,0xB5); diff --git a/Src/Language/LanguagePs.idl b/Src/Language/LanguagePs.idl deleted file mode 100644 index 0a7b59b669..0000000000 --- a/Src/Language/LanguagePs.idl +++ /dev/null @@ -1,23 +0,0 @@ -/*--------------------------------------------------------------------*//*:Ignore this sentence. -Copyright (c) 1999-2013 SIL International -This software is licensed under the LGPL, version 2.1 or later -(http://www.gnu.org/licenses/lgpl-2.1.html) - -File: LanguagePs.idl -Responsibility: John Thomson -Last reviewed: - - Defines Language Services Interfaces for proxy / stub generation. --------------------------------------------------------------------------------*//*:End Ignore*/ -import "oaidl.idl"; -import "ocidl.idl"; -//import "FwKernelPs.idl"; - -#include "Common.idh" - -#define NO_COCLASSES - -#include "FwKernel.idh" -#include "TextServ.idh" -#include "Render.idh" -#include "Language.idh" diff --git a/Src/Language/LanguageTlb.idl b/Src/Language/LanguageTlb.idl deleted file mode 100644 index 1096388390..0000000000 --- a/Src/Language/LanguageTlb.idl +++ /dev/null @@ -1,33 +0,0 @@ -/*--------------------------------------------------------------------*//*:Ignore this sentence. -Copyright (c) 1999-2013 SIL International -This software is licensed under the LGPL, version 2.1 or later -(http://www.gnu.org/licenses/lgpl-2.1.html) - -File: LanguageTlb.idl -Responsibility: John Thomson -Last reviewed: Not yet. (previous main contents, now language.idh, reviewed mid June 99) - -Description: - Interface descriptions for the Language server. See Language.idh for a fuller description. --------------------------------------------------------------------------------*//*:End Ignore*/ - -/*********************************************************************************************** - Include files -***********************************************************************************************/ -import "oaidl.idl"; -import "ocidl.idl"; -import "objidl.idl"; - -#include "common.idh" // DeclareInterface and similar - -DeclareLibrary(LanguageLib, 1.0, "Language 1.0 Type Library", - b80ee180-c0f1-11d2-8078-0000c0fb81b5) -{ - interface IOleDbEncap; - - #include "FwKernel.idh" - #include "TextServ.idh" - - #include "Render.idh" - #include "Language.idh" -}; diff --git a/Src/Language/Language_GUIDs.cpp b/Src/Language/Language_GUIDs.cpp deleted file mode 100644 index 3678dc48b2..0000000000 --- a/Src/Language/Language_GUIDs.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// Automatically generated from LanguageTlb.h by ExtractIIDs task -#include "LanguageTlb.h" - -DEFINE_UUIDOF(ITsString, 0x295B2E11, 0xB149, 0x49C5, 0x9B, 0xE9, 0x9F, 0x46, 0x18, 0x56, 0x09, 0xAA); -DEFINE_UUIDOF(IUndoGrouper, 0xC38348D3, 0x392C, 0x4e02, 0xBD, 0x50, 0xA0, 0x1D, 0xC4, 0x18, 0x9E, 0x1D); -DEFINE_UUIDOF(IFwMetaDataCache, 0xEDBB1DED, 0x7065, 0x4b56, 0xA2, 0x62, 0x74, 0x64, 0x53, 0x83, 0x54, 0x51); -DEFINE_UUIDOF(IUndoAction, 0xB831F535, 0x0D5F, 0x42c8, 0xBF, 0x9F, 0x7F, 0x5E, 0xCA, 0x2C, 0x46, 0x57); -DEFINE_UUIDOF(IActionHandler, 0x0F8EA3BE, 0xC982, 0x40f8, 0xB6, 0x74, 0x25, 0xB8, 0x48, 0x2E, 0xB2, 0x22); -DEFINE_UUIDOF(ActionHandler, 0x6A46D810, 0x7F14, 0x4151, 0x80, 0xF5, 0x0B, 0x13, 0xFF, 0xC1, 0xF9, 0x17); -DEFINE_UUIDOF(IDebugReportSink, 0xDD9CE7AD, 0x6ECC, 0x4e0c, 0xBB, 0xFC, 0x1D, 0xC5, 0x2E, 0x05, 0x33, 0x54); -DEFINE_UUIDOF(IDebugReport, 0x3D6A0880, 0xD17D, 0x4e4a, 0x9D, 0xE9, 0x86, 0x1A, 0x85, 0xCA, 0x40, 0x46); -DEFINE_UUIDOF(DebugReport, 0x24636FD1, 0xDB8D, 0x4b2c, 0xB4, 0xC0, 0x44, 0xC2, 0x59, 0x2C, 0xA4, 0x82); -DEFINE_UUIDOF(IComDisposable, 0xCA9AAF91, 0x4C34, 0x4c6a, 0x8E, 0x07, 0x97, 0xC1, 0xA7, 0xB3, 0x48, 0x6A); -DEFINE_UUIDOF(ITsTextProps, 0x4FA0B99A, 0x5A56, 0x41A4, 0xBE, 0x8B, 0xB8, 0x9B, 0xC6, 0x22, 0x51, 0xA5); -DEFINE_UUIDOF(ITsStrFactory, 0xC10EA417, 0x8317, 0x4048, 0xAC, 0x90, 0x10, 0x3F, 0x8B, 0xDF, 0xB3, 0x25); -DEFINE_UUIDOF(ITsPropsFactory, 0x8DCE56A6, 0xCFF1, 0x4402, 0x95, 0xFE, 0x2B, 0x57, 0x49, 0x12, 0xB5, 0x4E); -DEFINE_UUIDOF(ITsStrBldr, 0xF1EF76E6, 0xBE04, 0x11d3, 0x8D, 0x9A, 0x00, 0x50, 0x04, 0xDE, 0xFE, 0xC4); -DEFINE_UUIDOF(ITsIncStrBldr, 0xF1EF76E7, 0xBE04, 0x11d3, 0x8D, 0x9A, 0x00, 0x50, 0x04, 0xDE, 0xFE, 0xC4); -DEFINE_UUIDOF(ITsPropsBldr, 0xF1EF76E8, 0xBE04, 0x11d3, 0x8D, 0x9A, 0x00, 0x50, 0x04, 0xDE, 0xFE, 0xC4); -DEFINE_UUIDOF(ITsMultiString, 0xDD409520, 0xC212, 0x11d3, 0x9B, 0xB7, 0x00, 0x40, 0x05, 0x41, 0xF9, 0xE9); -DEFINE_UUIDOF(ILgWritingSystemFactory, 0x22376578, 0xBFEB, 0x4c46, 0x8D, 0x72, 0xC9, 0x15, 0x48, 0x90, 0xDD, 0x16); -DEFINE_UUIDOF(TsStrFactory, 0xF1EF76E9, 0xBE04, 0x11d3, 0x8D, 0x9A, 0x00, 0x50, 0x04, 0xDE, 0xFE, 0xC4); -DEFINE_UUIDOF(TsPropsFactory, 0xF1EF76EA, 0xBE04, 0x11d3, 0x8D, 0x9A, 0x00, 0x50, 0x04, 0xDE, 0xFE, 0xC4); -DEFINE_UUIDOF(TsStrBldr, 0xF1EF76EB, 0xBE04, 0x11d3, 0x8D, 0x9A, 0x00, 0x50, 0x04, 0xDE, 0xFE, 0xC4); -DEFINE_UUIDOF(TsIncStrBldr, 0xF1EF76EC, 0xBE04, 0x11d3, 0x8D, 0x9A, 0x00, 0x50, 0x04, 0xDE, 0xFE, 0xC4); -DEFINE_UUIDOF(TsPropsBldr, 0xF1EF76ED, 0xBE04, 0x11d3, 0x8D, 0x9A, 0x00, 0x50, 0x04, 0xDE, 0xFE, 0xC4); -DEFINE_UUIDOF(TsMultiString, 0x7A1B89C0, 0xC2D6, 0x11d3, 0x9B, 0xB7, 0x00, 0x40, 0x05, 0x41, 0xF9, 0xE9); -DEFINE_UUIDOF(IVwGraphics, 0xF7233278, 0xEA87, 0x4FC9, 0x83, 0xE2, 0xCB, 0x7C, 0xC4, 0x5D, 0xEB, 0xE7); -DEFINE_UUIDOF(IJustifyingRenderer, 0x1141174B, 0x923F, 0x4C43, 0xBA, 0x43, 0x8A, 0x32, 0x6B, 0x76, 0xA3, 0xF2); -DEFINE_UUIDOF(ISimpleInit, 0x6433D19E, 0x2DA2, 0x4041, 0xB2, 0x02, 0xDB, 0x11, 0x8E, 0xE1, 0x69, 0x4D); -DEFINE_UUIDOF(IVwGraphicsWin32, 0xC955E295, 0xA259, 0x47D4, 0x81, 0x58, 0x4C, 0x7A, 0x35, 0x39, 0xD3, 0x5E); -DEFINE_UUIDOF(VwGraphicsWin32, 0xD888DB98, 0x83A9, 0x4592, 0xAA, 0xD2, 0xF1, 0x8F, 0x6F, 0x74, 0xAB, 0x87); -DEFINE_UUIDOF(IVwTextSource, 0x6C0465AC, 0x17C5, 0x4C9C, 0x8A, 0xF3, 0x62, 0x22, 0x1F, 0x2F, 0x77, 0x07); -DEFINE_UUIDOF(IVwJustifier, 0x22D5E030, 0x5239, 0x4924, 0xBF, 0x1B, 0x6B, 0x4F, 0x2C, 0xBB, 0xAB, 0xA5); -DEFINE_UUIDOF(VwJustifier, 0xD3E3ADB7, 0x94CB, 0x443B, 0xBB, 0x8F, 0x82, 0xA0, 0x3B, 0xF8, 0x50, 0xF3); -DEFINE_UUIDOF(ILgSegment, 0x3818E245, 0x6A0B, 0x45A7, 0xA5, 0xD6, 0x52, 0x69, 0x49, 0x31, 0x27, 0x9E); -DEFINE_UUIDOF(IRenderEngine, 0x7F4B8F79, 0x2A40, 0x408C, 0x94, 0x4B, 0x84, 0x8B, 0x14, 0xD6, 0x5D, 0x23); -DEFINE_UUIDOF(RomRenderEngine, 0x6EACAB83, 0x6BDC, 0x49CA, 0x8F, 0x66, 0x8C, 0x11, 0x6D, 0x3E, 0xEB, 0xD8); -DEFINE_UUIDOF(UniscribeEngine, 0x1287735C, 0x3CAD, 0x41CD, 0x98, 0x6C, 0x39, 0xD7, 0xC0, 0xDF, 0x03, 0x14); -DEFINE_UUIDOF(FwGrEngine, 0xF39F9433, 0xF05A, 0x4A19, 0x8D, 0x1E, 0x3C, 0x55, 0xDD, 0x60, 0x76, 0x33); -DEFINE_UUIDOF(IRenderingFeatures, 0x75AFE861, 0x3C17, 0x4F16, 0x85, 0x1F, 0xA3, 0x6F, 0x5F, 0xFA, 0xBC, 0xC6); -DEFINE_UUIDOF(FwGraphiteProcess, 0xB56AEFB9, 0x96B4, 0x4415, 0x84, 0x15, 0x64, 0xCB, 0xF3, 0x82, 0x67, 0x04); -DEFINE_UUIDOF(ILgCharacterPropertyEngine, 0x890C5B18, 0x6E95, 0x438E, 0x8A, 0xDE, 0xA4, 0xFF, 0xAD, 0xDF, 0x06, 0x84); -DEFINE_UUIDOF(ILgStringConverter, 0x8BE2C911, 0x6A81, 0x48B5, 0xA2, 0x7F, 0xB8, 0xCE, 0x63, 0x98, 0x30, 0x82); -DEFINE_UUIDOF(ILgTokenizer, 0x577C6DA1, 0xCFC1, 0x4AFB, 0x82, 0xB2, 0xAF, 0x81, 0x8E, 0xC2, 0xFE, 0x9F); -DEFINE_UUIDOF(ILgSpellCheckFactory, 0x9F9298F5, 0xFD41, 0x44B0, 0x83, 0xBA, 0xBE, 0xD9, 0xF5, 0x6C, 0xF9, 0x74); -DEFINE_UUIDOF(ILgSpellChecker, 0xE3661AF5, 0x26C6, 0x4907, 0x92, 0x43, 0x61, 0x0D, 0xAD, 0x84, 0xD9, 0xD4); -DEFINE_UUIDOF(ILgCollatingEngine, 0xD27A3D8C, 0xD3FE, 0x4E25, 0x90, 0x97, 0x8F, 0x4A, 0x1F, 0xB3, 0x03, 0x61); -DEFINE_UUIDOF(ILgSearchEngine, 0x09FCA8D5, 0x5BF6, 0x4BFF, 0xA3, 0x17, 0xE0, 0x12, 0x64, 0x10, 0xD7, 0x9A); -DEFINE_UUIDOF(ILgWritingSystem, 0x9F74A170, 0xE8BB, 0x466d, 0x88, 0x48, 0x5F, 0xDB, 0x28, 0xAC, 0x5A, 0xF8); -DEFINE_UUIDOF(ILgIcuCharPropEngine, 0xE8689492, 0x7622, 0x427b, 0x85, 0x18, 0x63, 0x39, 0x29, 0x4F, 0xD2, 0x27); -DEFINE_UUIDOF(ILgNumericEngine, 0xCBBF35E1, 0xCE39, 0x4EEC, 0xAE, 0xBD, 0x5B, 0x4A, 0xAA, 0xA5, 0x2B, 0x6C); -DEFINE_UUIDOF(ILgKeymanHandler, 0x3F42144B, 0x509F, 0x4def, 0x8D, 0xD3, 0x6D, 0x8D, 0x26, 0x67, 0x70, 0x01); -DEFINE_UUIDOF(ILgIcuConverterEnumerator, 0x8E6D558E, 0x8755, 0x4EA1, 0x9F, 0xF6, 0x03, 0x9D, 0x37, 0x53, 0x12, 0xE9); -DEFINE_UUIDOF(ILgIcuTransliteratorEnumerator, 0x50F2492C, 0x6C46, 0x48BA, 0x8B, 0x7F, 0x5F, 0x04, 0x15, 0x3A, 0xB2, 0xCC); -DEFINE_UUIDOF(ILgIcuLocaleEnumerator, 0x08F649D0, 0xD8AB, 0x447B, 0xAA, 0xB6, 0x21, 0xF8, 0x5C, 0xFA, 0x74, 0x3C); -DEFINE_UUIDOF(ILgIcuResourceBundle, 0xC243C72A, 0x0D15, 0x44D9, 0xAB, 0xCB, 0xA6, 0xE8, 0x75, 0xA7, 0x65, 0x9A); -DEFINE_UUIDOF(IRegexMatcher, 0x6C62CCF0, 0x4EE1, 0x493C, 0x80, 0x92, 0x31, 0x9B, 0x6C, 0xFB, 0xEE, 0xBC); -DEFINE_UUIDOF(RegexMatcherWrapper, 0x13D5C6D3, 0x39D9, 0x4BDA, 0xA3, 0xF8, 0xA5, 0xCA, 0xF6, 0xA6, 0x94, 0x0A); -DEFINE_UUIDOF(LgSystemCollater, 0xE361F805, 0xC902, 0x4306, 0xA5, 0xD8, 0xF7, 0x80, 0x2B, 0x0E, 0x73, 0x65); -DEFINE_UUIDOF(LgUnicodeCollater, 0x0D9900D2, 0x1693, 0x481F, 0xAA, 0x70, 0x7E, 0xA6, 0x4F, 0x26, 0x4E, 0xC4); -DEFINE_UUIDOF(LgIcuCharPropEngine, 0x30D75676, 0xA10F, 0x48FE, 0x96, 0x27, 0xEB, 0xF4, 0x06, 0x1E, 0xA4, 0x9D); -DEFINE_UUIDOF(LgCPWordTokenizer, 0x7CE7CE94, 0xAC47, 0x42A5, 0x82, 0x3F, 0x2F, 0x8E, 0xF5, 0x1A, 0x90, 0x07); -DEFINE_UUIDOF(LgWfiSpellChecker, 0x818445E2, 0x0282, 0x4688, 0x8B, 0xB7, 0x14, 0x7F, 0xAA, 0xCF, 0xF7, 0x3A); -DEFINE_UUIDOF(LgMSWordSpellChecker, 0x5CF96DA5, 0x299E, 0x4FC5, 0xA9, 0x90, 0x2D, 0x2F, 0xCE, 0xE7, 0x83, 0x4D); -DEFINE_UUIDOF(LgNumericEngine, 0xFF22A7AB, 0x223E, 0x4D04, 0xB6, 0x48, 0x0A, 0xE4, 0x05, 0x88, 0x26, 0x1D); -DEFINE_UUIDOF(LgKeymanHandler, 0x69ACA99C, 0xF852, 0x4C2C, 0x9B, 0x5F, 0xFF, 0x83, 0x23, 0x8A, 0x17, 0xA5); -DEFINE_UUIDOF(LgIcuConverterEnumerator, 0x9E729461, 0xF80D, 0x4796, 0xBA, 0x17, 0x08, 0x6B, 0xC6, 0x19, 0x07, 0xF1); -DEFINE_UUIDOF(LgIcuTransliteratorEnumerator, 0x3F1FD0A4, 0xB2B1, 0x4589, 0xBC, 0x82, 0x9C, 0xEF, 0x5B, 0xA8, 0x4F, 0x4E); -DEFINE_UUIDOF(LgIcuResourceBundle, 0x0DD7FC1A, 0xAB97, 0x4A39, 0x88, 0x2C, 0x26, 0x97, 0x60, 0xD8, 0x66, 0x19); -DEFINE_UUIDOF(LgIcuLocaleEnumerator, 0xE426656C, 0x64F7, 0x480E, 0x92, 0xF4, 0xD4, 0x1A, 0x7B, 0xFF, 0xD0, 0x66); diff --git a/Src/Language/Main.h b/Src/Language/Main.h deleted file mode 100644 index aafa2470a1..0000000000 --- a/Src/Language/Main.h +++ /dev/null @@ -1,199 +0,0 @@ -/*--------------------------------------------------------------------*//*:Ignore this sentence. -Copyright (c) 1999-2013 SIL International -This software is licensed under the LGPL, version 2.1 or later -(http://www.gnu.org/licenses/lgpl-2.1.html) - -File: Main.h -Responsibility: -Last reviewed: - - Main header file for the Language component. --------------------------------------------------------------------------------*//*:End Ignore*/ -#if _MSC_VER -#pragma once -#endif -#ifndef LANGUAGE_H -#define LANGUAGE_H 1 - -// If ICU_LINEBREAKING is defined, we use the ICU functions for linebreaking. -// If this is undefined, then we go to JohnT's previous version which doesn't -// use ICU functions. -#ifndef ICU_LINEBREAKING -#define ICU_LINEBREAKING -#endif /*ICU_LINEBREAKING*/ - -#define NO_EXCEPTIONS 1 -#include "common.h" // Most of generic. -#if WIN32 -#include -#endif - -#if !WIN32 -#include -#include "BasicTypes.h" -#include -#endif - -using std::min; -using std::max; - -//:>********************************************************************************** -//:> Interfaces. -//:>********************************************************************************** -#include "FwKernelTlb.h" -#include "CellarConstants.h" -// Special interface mainly used for Graphite engine not defined in an IDH. -#include "../Graphite/GrEngine/ITraceControl.h" -#ifndef ITraceControlPtr // for portability I don't think this header defines this. - DEFINE_COM_PTR(ITraceControl); -#endif - -//:>********************************************************************************** -//:> Implementations. -//:>********************************************************************************** - -// Forward declarations for unit test friends. -namespace TestLanguage -{ - class TestLgWritingSystem; - class TestLgWritingSystemFactory; - extern void CreateTestWritingSystemFactory(ILgWritingSystemFactory ** ppwsf); - extern HRESULT CreateTestWritingSystem(ILgWritingSystemFactory * pwsf, int ws, - const OLECHAR * pszWs); -}; - -#include "LangResource.h" - -// For interfacing with Graphite engines: -namespace gr { -typedef unsigned char utf8; -typedef wchar_t utf16; -typedef unsigned long int utf32; -#define UtfType LgUtfForm -} -// defined in TtSfnt_en.h - but this avoids including all of TtfUtil in the Language.dll -#define tag_Silf 0x666c6953 -#include "GrResult.h" -#include "GrUtil.h" -#include "ITextSource.h" -#include "IGrJustifier.h" -#include "FwGr.h" - -using namespace fwutil; // Rect and Point classes - -// Conceptual model of an writing system -#ifdef LANG_MODEL -#include "LgSpec.h" -#include "LgCharOverride.h" -#include "LgCharPropSpec.h" -#include "LgCharSpec.h" -#include "LgCollaterSpec.h" -#include "LgComponent.h" -#include "LgConverterSpec.h" -#include "LgConvertStringSpec.h" -#include "LgExternalSpecComponent.h" -#include "LgLineBreakSpec.h" -#include "LgLineBreakSpaceSpec.h" -#include "LgOwnedSpecComponent.h" -#include "LgNumericConverterSpec.h" -#include "LgRenderSpec.h" -#include "LgRomanRendererSpec.h" -#include "LgSpellCheckSpec.h" -#include "LgSysCollaterSpec.h" -#include "LgTokenizerSpec.h" -#include "LgUnicodeCollaterSpec.h" -#include "LgUserClassSpec.h" -#include "LgWfiCheckerSpec.h" -#include "LgWinRendSpec.h" -#include "LgWordBreakSpaceSpec.h" -#endif // LANG_MODEL - -// these are a gray area, including aspects of both model and engine -// Todo JohnT: These structs are part of an obsolete approach to overriding character properties. -// Get rid of them and whatever uses them. (Taken from OldLgWritingSystem file.) -/*---------------------------------------------------------------------------------------------- - The CharacterPropertyObject stores all of the data that we allow to be overriden for a - single character (right now, pretty much everything except the Unicode 1.0 name). -----------------------------------------------------------------------------------------------*/ -struct CharacterPropertyObject -{ - UChar32 uch32CodePoint; - StrUni stuCharName; - LgGeneralCharCategory ccGenCategory; - unsigned int nCombiningClass : 8; - LgBidiCategory bicBidiCategory; - LgDecompMapTag dtDecompMapTag; - Vector vuch32Decomp; - unsigned int nDecDigit : 4; - unsigned int nDigit : 4; - int nNumericValue; //numerator stored in the top 16 bits, denominator in the bottom 16 - bool fMirrored : 1; - StrUni stuISOComment; - UChar32 uch32Uppercase; - UChar32 uch32Lowercase; - UChar32 uch32Titlecase; - LgLBP lbpLineBreak; - - void Clear() - { - uch32CodePoint = 0; - stuCharName.Clear(); - ccGenCategory = kccLu; //0 - nCombiningClass = 0; - bicBidiCategory = kbicL; //0 - dtDecompMapTag = kdtNoTag; //0 - vuch32Decomp.Clear(); - nDecDigit = 0; - nDigit = 0; - nNumericValue = 0; - fMirrored = false; - stuISOComment.Clear(); - uch32Uppercase = 0; - uch32Lowercase = 0; - uch32Titlecase = 0; - lbpLineBreak = klbpAI; //0 - } -}; //hungarian cpo - -struct CharPropRange -{ - UChar32 iMin; - UChar32 iLim; - Vector vRange; -}; //hungarian cpr -struct OverriddenCharProps -{ - UChar32 iMin; - UChar32 iLim; - Vector * pvcprOverride1; - Vector * pvcpoOverride2; -}; //hungarian ocp - -// Engines -#include "LgIcuCharPropEngine.h" -#include "LgUnicodeCollater.h" -class RomRenderEngine; -DEFINE_COM_PTR(RomRenderEngine); -class UniscribeEngine; -DEFINE_COM_PTR(UniscribeEngine); -#include "RomRenderSegment.h" -#include "RomRenderEngine.h" -#include "LgSimpleEngines.h" -#include "LgNumericEngine.h" -#if !WIN32 -#include "UniscribeLinux.h" -#endif -#include "UniscribeSegment.h" -#include "UniscribeEngine.h" - -// Other tools -#include "FwStyledText.h" -#include "StringToNumHelpers.h" -#include "WriteXml.h" // From AppCore. -#include "xmlparse.h" -#include "LgKeymanHandler.h" -#include "LgIcuWrappers.h" - -#include "RegexMatcherWrapper.h" - -#endif //!LANGUAGE_H diff --git a/Src/Language/Makefile b/Src/Language/Makefile deleted file mode 100644 index 884adfa561..0000000000 --- a/Src/Language/Makefile +++ /dev/null @@ -1,193 +0,0 @@ - -# $Id: Makefile 2650 2009-12-15 14:15:18Z beilharz $ -# -# Makefile for FW Language directory -# -# Neil Mayhew - 2007-03-15 -# -# Adapted from Language.mak - - -BUILD_ROOT = ../.. -include $(BUILD_ROOT)/Bld/_names.mak -BUILD_PRODUCT = $(LANGUAGE_NAME) -include $(BUILD_ROOT)/Bld/_init.mak.lnx - -DEFINES := $(DEFINES) -DGR_FW -DSUPPRESS_FW_EXCEPTION_HANDLING -DWIN32_KEY_VALUES=1 - -ifeq ($(BUILD_CONFIG),Debug) - DEBUG_LIBS = $(OUT_DIR)/libDebugProcs.a - DEFINES := $(DEFINES) -D_DEBUG - OPTIMIZATIONS = -O0 -else - OPTIMIZATIONS = -O3 -endif - -CELLAR_SRC = $(SRC)/Cellar -GRAPHITE_SRC = $(SRC)/Graphite -GRFW_SRC = $(GRAPHITE_SRC)/FwOnly -GRUTIL_LIB = $(GRAPHITE_SRC)/lib -TTFUTIL_LIB = $(GRAPHITE_SRC)/TtfUtil -VIEWS_LIB = $(SRC)/views/lib - -PACKAGES = glib-2.0 gtk+-2.0 glibmm-2.4 gtkmm-2.4 cairomm-1.0 pangomm-1.4 - -# Make sure Lang is first, as we want to get the Main.h from there, -# not any of the others (e.g., in Views) -INCLUDES := -I$(LANGUAGE_SRC) -I$(GENERIC_SRC) -I$(APPCORE_SRC) -I$(TEXT_SRC) -INCLUDES := $(INCLUDES) -I$(KERNEL_SRC) -I$(CELLAR_SRC) -I$(DBACCESS_SRC) -INCLUDES := $(INCLUDES) -I$(GRUTIL_LIB) -I$(TTFUTIL_LIB) -I$(VIEWS_SRC) -I$(VIEWS_LIB) -I$(GRFW_SRC) -INCLUDES := $(shell icu-config --cppflags) \ - $(INCLUDES) \ - -I$(FWINCLUDE) \ - -I$(COM_OUT_DIR) \ - -I$(WIN32MORE_INC) \ - -I$(COM_INC) \ - -I$(WIN32BASE_INC) \ - $(shell pkg-config --cflags $(PACKAGES)) \ - - -LDLIBS = \ - -L$(FWINCLUDE) \ - $(DEBUG_LIBS) \ - -L$(WIN32MORE_LIB) -lWin32More \ - -L$(COM_LIB) -lcom \ - -L$(WIN32BASE_LIB) -lWin32Base \ - $(shell pkg-config --libs $(PACKAGES)) \ - $(shell icu-config --ldflags) \ - -luuid -lexpat - -CPPFLAGS = $(DEFINES) $(INCLUDES) -MMD -CXXFLAGS = -g $(OPTIMIZATIONS) -fPIC -fvisibility=hidden -Werror -Waddress -Warray-bounds -Wmissing-field-initializers -Wclobbered -Wreturn-type -fstack-protector-all -Wshadow -rdynamic - -ARFLAGS = -crs - -# XML_INC = $(CELLAR_XML) -I$(LANG_XML) - -#PATH = $(COM_OUT_DIR);$(PATH) - -RCFILE = Language.rc -DEFFILE = Language.def - -LINK_LIBS := \ - $(DEBUG_LIBS) \ - $(OUT_DIR)/libGeneric.a \ - $(COM_OUT_DIR)/libFwKernelTlb.a \ - $(COM_OUT_DIR)/libGraphiteTlb.a \ - $(COM_OUT_DIR)/libViewsTlb.a \ - -# === Object Lists === - -OBJ_LANGSERV = - -OBJ_LANG = \ - $(INT_DIR)/LgIcuWrappers.o \ - $(INT_DIR)/LgSimpleEngines.o \ - $(INT_DIR)/LgIcuCharPropEngine.o \ - $(INT_DIR)/LgUnicodeCollater.o \ - $(INT_DIR)/LgKeymanHandler.o \ - $(INT_DIR)/LocaleIndex.o \ - $(INT_DIR)/FwXml.o \ - $(INT_DIR)/WriteXml.o \ - $(INT_DIR)/FwStyledText.o \ - $(INT_DIR)/UniscribeLinux.o \ - $(INT_DIR)/UniscribeSegment.o \ - $(INT_DIR)/UniscribeEngine.o \ - $(INT_DIR)/RomRenderEngine.o \ - $(INT_DIR)/RomRenderSegment.o \ - - -OBJ_OTHER = \ - $(INT_DIR)/ModuleEntry.o \ - $(INT_DIR)/TextProps1.o \ - -OBJ_LIB = \ - $(INT_DIR)/Language_GUIDs.o \ - $(INT_DIR)/LanguageExtra_GUIDs.o - -#OBJ_GRUTIL = \ -# $(GRUTIL_LIB)/GrUtil.o \ -# $(TTFUTIL_LIB)/TtfUtil.o \ - -# XMO_ALL = $(XMO_LANGSERV) -# -# IDL_MAIN = $(COM_OUT_DIR)/LanguageTlb.idl -# -# PS_MAIN = LanguagePs -# -# OBJECTS_IDH = $(COM_INT_DIR)/Objects.idh -# -# ? OBJECTS_H = $(COM_INT_DIR)/Objects.h - -OBJ_ALL = $(OBJ_LANG) $(OBJ_LANGSERV) $(OBJ_OTHER) $(OBJ_GRUTIL) - -# === Targets === - -all: $(OUT_DIR)/libLanguage.so $(COM_OUT_DIR)/libLanguageTlb.a ComponentsMap link_check - -$(OUT_DIR)/libLanguage.so: $(OBJ_ALL) $(LINK_LIBS) $(COM_OUT_DIR)/libLanguageTlb.a -ifeq "$(GCC46)" "1" - $(LINK.cc) -shared -o $@ -Wl,-whole-archive $(COM_OUT_DIR)/libLanguageTlb.a -Wl,-no-whole-archive $(OBJ_ALL) $(LINK_LIBS) $(LDLIBS) -else - $(LINK.cc) -shared -o $@ $^ $(LDLIBS) -endif - -$(COM_OUT_DIR)/libLanguageTlb.a: $(OBJ_LIB) - $(AR) $(ARFLAGS) $@ $^ - -link_check: $(INT_DIR)/libLanguage - -$(INT_DIR)/libLanguage: $(OBJ_ALL) $(GENERIC_OBJ)/main.o $(LINK_LIBS) $(COM_OUT_DIR)/libLanguageTlb.a - $(LINK.cc) -o $@ -Wl,-whole-archive $(COM_OUT_DIR)/libLanguageTlb.a -Wl,-no-whole-archive $(GENERIC_OBJ)/main.o $(OBJ_ALL) $(LINK_LIBS) $(LDLIBS) - -ComponentsMap: $(OUT_DIR)/libLanguage.so - (export PATH=$(PATH):$(COM_DIR)/build$(ARCH)/bin && cd $(OUT_DIR) && generate-map.sh libLanguage.so > libLanguage.compmap) - -# === Rules === - -PCHNAME = $(INT_DIR)/Main.h.gch - -$(OBJ_LANG) $(OBJ_LANGSERV): $(PCHNAME) - -# ensure object dependies are built. - -$(INT_DIR)/%.o: $(APPCORE_SRC)/%.cpp - $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ - -c $< -o $@ -MMD -MF $(@:%.o=%.d) - -$(INT_DIR)/%.o: $(CELLAR_SRC)/%.cpp - $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ - -c $< -o $@ -MMD -MF $(@:%.o=%.d) - -$(INT_DIR)/%.o: $(GENERIC_SRC)/%.cpp - $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCLUDES) $(TARGET_ARCH) \ - -c $< -o $@ -MMD -MF $(@:%.o=%.d) - -$(OUT_DIR)/libDebugProcs.a: - @$(MAKE) -C $(SRC)/DebugProcs $@ -q || \ - $(MAKE) -C $(SRC)/DebugProcs $@ - -$(OUT_DIR)/libGeneric.a: - @$(MAKE) -C $(SRC)/Generic $@ -q || \ - $(MAKE) -C $(SRC)/Generic $@ - -$(COM_OUT_DIR)/libFwKernelTlb.a: - @$(MAKE) -C $(SRC)/Kernel $@ -q || \ - $(MAKE) -C $(SRC)/Kernel $@ - -$(COM_OUT_DIR)/libGraphiteTlb.a: - @$(MAKE) -C $(GRENGINE_SRC) all -q || \ - $(MAKE) -C $(GRENGINE_SRC) all - -$(COM_OUT_DIR)/libViewsTlb.a: - @$(MAKE) -C $(SRC)/views/ $@ -q || \ - $(MAKE) -C $(SRC)/views/ $@ - -%.h.gch: %.h - $(COMPILE.cc) -o $@ $< - --include $(OBJ_ALL:%.o=%.d) --include $(PCHNAME:%.gch=%.d) - -clean: - $(RM) $(OUT_DIR)/libLanguage.so $(COM_OUT_DIR)/libLanguageTlb.a $(INT_DIR)/libLanguage $(INT_DIR)/*.[od] $(INT_DIR)/*.gch diff --git a/Src/Language/Test/Makefile b/Src/Language/Test/Makefile deleted file mode 100644 index 91201898c6..0000000000 --- a/Src/Language/Test/Makefile +++ /dev/null @@ -1,129 +0,0 @@ - -# $Id: Makefile 1119 2008-04-10 23:23:04Z mccarthy $ -# -# Makefile for FW Kernel directory -# -# Brent McCarthy - 2007-06-22 -# -# Adapted from testLanguage.mak - -BUILD_ROOT = ../../.. -include $(BUILD_ROOT)/Bld/_names.mak -BUILD_PRODUCT = $(LANGUAGE_NAME)Test -include $(BUILD_ROOT)/Bld/_init.mak.lnx - -UNIT = $(FWINCLUDE)/unit++ -LIB_UNIT = $(BUILD_ROOT)/Lib/src/unit++/build$(ARCH) - -GRAPHITE_SRC = $(SRC)/Graphite -GR_LIB_SRC = $(GRAPHITE_SRC)/lib -GR_LIB_OBJ = $(OBJ_DIR)/$(BUILD_CONFIG)/Graphite/lib -GRAPHITE_FW = $(GRAPHITE_SRC)/FwOnly -VIEWS_LIB = $(VIEWS_SRC)/lib - -DEFINES := -DGR_FW -DVIEWSDLL -DSUPPRESS_FW_EXCEPTION_HANDLING -PACKAGES = gdk-2.0 gtkmm-2.4 cairomm-1.0 pangomm-1.4 - -ifeq ($(BUILD_CONFIG),Debug) - DEFINES := $(DEFINES) -D_DEBUG - OPTIMIZATIONS = -O0 -else - OPTIMIZATIONS = -O3 -endif - -# Make sure Lang is first, as we want to get the Main.h from there, -# not any of the others (e.g., in Views) -INCLUDES := -I$(LANGUAGE_SRC) -I$(LANGUAGE_SRC)/Test -I$(KERNEL_SRC) -I$(CELLAR_SRC) \ - -I$(GENERIC_SRC) -I$(APPCORE_SRC) - -INCLUDES := $(INCLUDES) -I$(GRENGINE_SRC) -I$(GR_LIB_SRC) -I$(GRAPHITE_FW) -I$(VIEWS_SRC) -I$(VIEWS_LIB) -INCLUDES := \ - $(shell icu-config --cppflags) \ - $(INCLUDES) \ - -I$(FWINCLUDE) \ - -I$(UNIT) -I$(LIB_UNIT) \ - -I$(COM_OUT_DIR) \ - -I$(WIN32MORE_INC) \ - -I$(COM_INC) \ - -I$(WIN32BASE_INC) \ - $(shell pkg-config --cflags $(PACKAGES)) \ - -#` -L$(FWKERNEL_SRC) -lFwKernel - -LDLIBS = \ - -L$(WIN32MORE_LIB) -lWin32More \ - -L$(COM_LIB) -lcom \ - -L$(WIN32BASE_LIB) -lWin32Base \ - -L$(OUT_DIR) -lDebugProcs \ - -L$(LIB_UNIT) -lunit++ \ - $(shell pkg-config --libs $(PACKAGES)) \ - $(shell icu-config --ldflags) \ - -luuid -lexpat - - -CPPFLAGS = $(DEFINES) $(INCLUDES) -MMD -CXXFLAGS = -g $(OPTIMIZATIONS) -fvisibility=hidden -Werror - -RCFILE = $(LANGUAGE_SRC)/FwLanguage.rc -DEFFILE = $(LANGUAGE_SRC)/FwLanguage.def -LINK_LIBS := \ - $(OUT_DIR)/libGeneric.a \ - $(OUT_DIR)/libAppCore.a \ - $(OUT_DIR)/libDebugProcs.a \ - $(COM_OUT_DIR)/libGraphiteTlb.a \ - $(COM_OUT_DIR)/libViewsTlb.a \ - $(COM_OUT_DIR)/libLanguageTlb.a - -all: $(OUT_DIR)/testLanguage - -FWLANG_OBJ := \ - $(LANGUAGE_OBJ)/LgUnicodeCollater.o \ - $(LANGUAGE_OBJ)/RomRenderEngine.o \ - $(LANGUAGE_OBJ)/RomRenderSegment.o \ - $(LANGUAGE_OBJ)/LgSimpleEngines.o \ - $(LANGUAGE_OBJ)/LgIcuCharPropEngine.o \ - $(LANGUAGE_OBJ)/LgKeymanHandler.o \ - $(LANGUAGE_OBJ)/LocaleIndex.o \ - $(GENERIC_OBJ)/TextProps1.o \ - $(GR_LIB_OBJ)/GrUtil.o \ - $(LANGUAGE_OBJ)/FwXml.o \ - $(GENERIC_OBJ)/ModuleEntry.o \ - -#Run make in the directory of each library -$(LINK_LIBS) $(FWLANG_OBJ):: - @$(MAKE) -C $(@D) $(@F) -q || \ - $(MAKE) -C $(@D) $(@F) - -$(OUT_DIR)/testLanguage: $(INT_DIR)/testLanguage.o $(INT_DIR)/Collection.o $(FWLANG_OBJ) $(LINK_LIBS) -ifeq "$(GCC46)" "1" - $(LINK.cc) -o $@ -Wl,-whole-archive $(LINK_LIBS) -Wl,-no-whole-archive $(INT_DIR)/testLanguage.o $(INT_DIR)/Collection.o $(FWLANG_OBJ) $(LDLIBS) -else - $(LINK.cc) -o $@ $^ $(LDLIBS) -endif - -clean: - $(RM) $(OUT_DIR)/testLanguage $(INT_DIR)/*.[od] $(INT_DIR)/Collection.cpp *.[od] *.gch - -%.i: %.cpp - $(COMPILE.cc) -E -o $@ $< - -# environ needs to be source before running this. -check: all - cd $(OUT_DIR) && ./testLanguage - - -COLLECT=$(BUILD_ROOT)/Bin/CollectUnit++Tests.sh Language - -$(INT_DIR)/Collection.cpp: testLanguage.h \ - MockLgWritingSystemFactory.h \ - MockLgWritingSystem.h \ - TestLgCollatingEngine.h \ - TestLgIcuCharPropEngine.h \ - TestRomRenderEngine.h \ - RenderEngineTestBase.h - @echo Collecting tests for testLanguage - $(COLLECT) $^ $@ - -# TestLgWritingSystemFactoryBuilder.h \ -# RenderEngineTestBase.h \ -# TestUniscribeEngine.h\ diff --git a/Src/Language/Test/TestLanguage.vcxproj b/Src/Language/Test/TestLanguage.vcxproj deleted file mode 100644 index 7c54622b6c..0000000000 --- a/Src/Language/Test/TestLanguage.vcxproj +++ /dev/null @@ -1,90 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {CFCBEA18-3091-45FC-9407-C8C1303D2363} - TestLanguage - - - - - - - MakeFileProj - - - - Makefile - - - Makefile - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - Debug\ - Debug\ - ..\..\..\Bin\mklg-tst.bat DONTRUN - ..\..\..\Bin\mklg-tst.bat DONTRUN cc - ..\..\..\Bin\mklg-tst.bat DONTRUN ec - ..\..\..\Output\debug\TestLanguage.exe - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - Release\ - Release\ - ..\..\..\Bin\mklg-tst.bat DONTRUN r - ..\..\..\Bin\mklg-tst.bat DONTRUN r cc - ..\..\..\Bin\mklg-tst.bat DONTRUN r ec - ..\..\..\Output\release\TestLanguage.exe -v - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Src/Language/Test/TestLanguage.vcxproj.filters b/Src/Language/Test/TestLanguage.vcxproj.filters deleted file mode 100644 index 6643abcf5b..0000000000 --- a/Src/Language/Test/TestLanguage.vcxproj.filters +++ /dev/null @@ -1,52 +0,0 @@ - - - - - {e615eb4d-2caf-43c9-9a0b-24c68c96b443} - cpp;c;cxx;def;odl;idl;hpj;bat;asm - - - {8fe76bbf-550f-4779-886d-3c82abebf37b} - h;hpp;hxx;hm;inl;inc - - - {000be4d4-f7ee-4fd8-8823-24080bca4cc3} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - - - \ No newline at end of file diff --git a/Src/Language/Test/testLanguage.cpp b/Src/Language/Test/testLanguage.cpp deleted file mode 100644 index b85347350e..0000000000 --- a/Src/Language/Test/testLanguage.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/*--------------------------------------------------------------------*//*:Ignore this sentence. -Copyright (c) 2003-2013 SIL International -This software is licensed under the LGPL, version 2.1 or later -(http://www.gnu.org/licenses/lgpl-2.1.html) - -File: testLanguage.cpp -Responsibility: -Last reviewed: - - Global initialization/cleanup for unit testing the Language DLL classes. --------------------------------------------------------------------------------*//*:End Ignore*/ -#include "testLanguage.h" -#include "RedirectHKCU.h" - -#ifndef WIN32 -#include -#include -#endif - -namespace unitpp -{ - void GlobalSetup(bool verbose) - { -#ifdef WIN32 - ModuleEntry::DllMain(0, DLL_PROCESS_ATTACH); -#endif - CheckHr(::OleInitialize(NULL)); - RedirectRegistry(); - StrUtil::InitIcuDataDir(); // needed for the normalize routines (ICU) - } - void GlobalTeardown() - { -#ifdef WIN32 - ModuleEntry::DllMain(0, DLL_PROCESS_DETACH); -#endif - ::OleUninitialize(); - } -} - -namespace TestLanguage -{ - int g_wsEng = 0; - int g_wsTest = 0; - int g_wsTest2 = 0; -} - -#include "Vector_i.cpp" -template class Vector; - -// Local Variables: -// mode:C++ -// compile-command:"cmd.exe /e:4096 /c c:\\FW\\Bin\\mklg-tst.bat DONTRUN" -// End: (These 4 lines are useful to Steve McConnel.) diff --git a/Src/Language/Test/testLanguage.h b/Src/Language/Test/testLanguage.h deleted file mode 100644 index 6cca9d7647..0000000000 --- a/Src/Language/Test/testLanguage.h +++ /dev/null @@ -1,52 +0,0 @@ -/*--------------------------------------------------------------------*//*:Ignore this sentence. -Copyright (c) 2003-2013 SIL International -This software is licensed under the LGPL, version 2.1 or later -(http://www.gnu.org/licenses/lgpl-2.1.html) - -File: testLanguage.h -Responsibility: -Last reviewed: - - Global header for unit testing the Language DLL classes. --------------------------------------------------------------------------------*//*:End Ignore*/ -#ifndef TESTLANGUAGE_H_INCLUDED -#define TESTLANGUAGE_H_INCLUDED - -#pragma once -#include "Main.h" -#include - -#if !WIN32 -// Stream insertion operators for FW string types -namespace std -{ - inline std::ostream& operator << (std::ostream& stream, const OLECHAR* text) - { - return stream << StrAnsi(text).Chars(); - } - - inline std::ostream& operator << (std::ostream& stream, const StrUni& text) - { - return stream << text.Chars(); - } -} -#endif //!WIN32 - -namespace TestLanguage -{ - const StrUni kszEng(L"en"); - const StrUni kszTest(L"test"); - const StrUni kszTest2(L"tst2"); - - extern int g_wsEng; - extern int g_wsTest; - extern int g_wsTest2; -} - - -// Local Variables: -// mode:C++ -// compile-command:"cmd.exe /e:4096 /c c:\\FW\\Bin\\mklg-tst.bat DONTRUN" -// End: (These 4 lines are useful to Steve McConnel.) - -#endif /*TESTLANGUAGE_H_INCLUDED*/ diff --git a/Src/Language/Test/testLanguage.mak b/Src/Language/Test/testLanguage.mak deleted file mode 100644 index 149b253285..0000000000 --- a/Src/Language/Test/testLanguage.mak +++ /dev/null @@ -1,108 +0,0 @@ -# Input -# ===== -# BUILD_ROOT: d:\FieldWorks -# BUILD_TYPE: d, r, p -# BUILD_CONFIG: Debug, Release, Profile -# - -BUILD_PRODUCT=testLanguage -BUILD_EXTENSION=exe -BUILD_REGSVR=0 - -DEFS=$(DEFS) /DGR_FW - -!INCLUDE "$(BUILD_ROOT)\bld\_init.mak" - -UNITPP_INC=$(BUILD_ROOT)\Include\unit++ -LANGUAGE_SRC=$(BUILD_ROOT)\Src\Language -LANGUAGETEST_SRC=$(BUILD_ROOT)\Src\Language\Test -GENERIC_SRC=$(BUILD_ROOT)\Src\Generic -APPCORE_SRC=$(BUILD_ROOT)\Src\AppCore -CELLAR_SRC=$(BUILD_ROOT)\Src\Cellar -GRUTIL_LIB=$(BUILD_ROOT)\Src\Graphite\lib -GRFW_SRC=$(BUILD_ROOT)\Src\Graphite\FwOnly -VIEWS_LIB=$(BUILD_ROOT)\Src\Views\lib - -# Set the USER_INCLUDE environment variable. -UI=$(UNITPP_INC);$(LANGUAGETEST_SRC);$(LANGUAGE_SRC);$(GENERIC_SRC);$(APPCORE_SRC);$(CELLAR_SRC) - -!IF "$(USER_INCLUDE)"!="" -USER_INCLUDE=$(UI);$(USER_INCLUDE);$(GRUTIL_LIB);$(VIEWS_LIB);$(GRFW_SRC) -!ELSE -USER_INCLUDE=$(UI);$(GRUTIL_LIB);$(VIEWS_LIB);$(GRFW_SRC) -!ENDIF - -!INCLUDE "$(BUILD_ROOT)\bld\_init.mak" - -!INCLUDE "$(BUILD_ROOT)\bld\_rule.mak" - -PATH=$(COM_OUT_DIR);$(PATH) - -RCFILE=Language.rc - -LINK_OPTS=$(LINK_OPTS:/subsystem:windows=/subsystem:console) /LIBPATH:"$(BUILD_ROOT)\Lib\$(BUILD_CONFIG)" -CPPUNIT_LIBS=unit++.lib -LINK_LIBS=$(CPPUNIT_LIBS) Generic.lib Usp10.lib xmlparse.lib $(LINK_LIBS) - -# === Object Lists === - -OBJ_LANGUAGETESTSUITE=\ - $(INT_DIR)\genpch\testLanguage.obj\ - $(INT_DIR)\genpch\Collection.obj\ - $(INT_DIR)\ModuleEntry.obj\ - $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\Language\autopch\UniscribeEngine.obj\ - $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\Language\autopch\UniscribeSegment.obj\ - $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\Language\autopch\RomRenderEngine.obj\ - $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\Language\autopch\RomRenderSegment.obj\ - $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\Language\autopch\LgSimpleEngines.obj\ - $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\Language\autopch\LgIcuCharPropEngine.obj\ - $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\Language\autopch\LgUnicodeCollater.obj\ - $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\Language\autopch\LgKeymanHandler.obj\ - $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\Language\autopch\FwStyledText.obj\ - $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\Language\autopch\WriteXml.obj\ - $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\Language\usepch\TextProps1.obj\ - $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\Language\autopch\FwXml.obj\ - -OBJ_GRUTIL=\ - $(INT_DIR)\autopch\GrUtil.obj\ - -OBJ_ALL=$(OBJ_LANGUAGETESTSUITE) $(OBJ_GRUTIL) $(OBJ_CELLAR) - -# === Targets === -!INCLUDE "$(BUILD_ROOT)\bld\_targ.mak" - -# === Rules === -PCHNAME=testLanguage - -ARG_SRCDIR=$(LANGUAGETEST_SRC) -!INCLUDE "$(BUILD_ROOT)\bld\_rule.mak" - -ARG_SRCDIR=$(GRUTIL_LIB) -!INCLUDE "$(BUILD_ROOT)\bld\_rule.mak" - -ARG_SRCDIR=$(GENERIC_SRC) -!INCLUDE "$(BUILD_ROOT)\bld\_rule.mak" - -# === Custom Rules === - - -# === Custom Targets === - -COLLECT=$(BUILD_ROOT)\Bin\CollectUnit++Tests.cmd Language - -$(INT_DIR)\genpch\Collection.obj: $(LANGUAGETEST_SRC)\Collection.cpp - -$(LANGUAGETEST_SRC)\Collection.cpp: $(LANGUAGETEST_SRC)\testLanguage.h\ - $(LANGUAGETEST_SRC)\MockLgWritingSystemFactory.h\ - $(LANGUAGETEST_SRC)\MockLgWritingSystem.h\ - $(LANGUAGETEST_SRC)\TestRegexMatcher.h\ - $(LANGUAGETEST_SRC)\TestLgCollatingEngine.h\ - $(LANGUAGETEST_SRC)\TestLgIcuCharPropEngine.h\ - $(LANGUAGETEST_SRC)\TestUniscribeEngine.h\ - $(LANGUAGETEST_SRC)\TestRomRenderEngine.h\ - $(LANGUAGETEST_SRC)\RenderEngineTestBase.h - $(DISPLAY) Collecting tests for $(BUILD_PRODUCT).$(BUILD_EXTENSION) - $(COLLECT) $** $(LANGUAGETEST_SRC)\Collection.cpp - -$(INT_DIR)\Language.res: $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\Language\Language.res - copy $(BUILD_ROOT)\Obj\$(BUILD_CONFIG)\Language\Language.res $(INT_DIR)\Language.res >nul diff --git a/Src/Language/dlldatax.c b/Src/Language/dlldatax.c deleted file mode 100644 index 296fe27b8c..0000000000 --- a/Src/Language/dlldatax.c +++ /dev/null @@ -1,11 +0,0 @@ -// wrapper for dlldata.c - -#ifdef _MERGE_PROXYSTUB // merge proxy stub DLL - -#include "proxystub.c" // in Generic - -#include "LanguagePs_d.c" // dlldata.c -#include "LanguagePs_p.c" -#include "LanguagePs_i.c" - -#endif //_MERGE_PROXYSTUB diff --git a/Src/Language/mklg.bat b/Src/Language/mklg.bat deleted file mode 100755 index 90efce1231..0000000000 --- a/Src/Language/mklg.bat +++ /dev/null @@ -1,12 +0,0 @@ -@if "%_echo%"=="" echo off - -rem ***** Set BUILD_ROOT to the root of the FieldWorks project. ***** -%0\..\..\..\..\bin\here.exe ".." "set BUILD_ROOT=" > foo.bat -call foo.bat -del foo.bat - -set BUILD_MAKEFILE=%BUILD_ROOT%\Src\Services\Language\Language.mak - -call %BUILD_ROOT%\bld\_mkcore.bat %1 %2 %3 %4 %5 %6 %7 %8 %9 - -set BUILD_MAKEFILE= diff --git a/Src/LexText/Discourse/ConstChartBody.cs b/Src/LexText/Discourse/ConstChartBody.cs index caf4e4095f..8761bb8994 100644 --- a/Src/LexText/Discourse/ConstChartBody.cs +++ b/Src/LexText/Discourse/ConstChartBody.cs @@ -617,7 +617,7 @@ internal ITsString SpaceString private void LoadFormatProps() { var doc = new XmlDocument(); - var path = Path.Combine(DirectoryFinder.FWCodeDirectory, @"Language Explorer/Configuration/ConstituentChartStyleInfo.xml"); + var path = Path.Combine(FwDirectoryFinder.CodeDirectory, @"Language Explorer/Configuration/ConstituentChartStyleInfo.xml"); if (!File.Exists(path)) return; doc.Load(path); diff --git a/Src/LexText/Discourse/Discourse.csproj b/Src/LexText/Discourse/Discourse.csproj index b565a5ebcf..bcc912ca49 100644 --- a/Src/LexText/Discourse/Discourse.csproj +++ b/Src/LexText/Discourse/Discourse.csproj @@ -1,221 +1,227 @@  - Debug - AnyCPU - 9.0.21022 - 2.0 - {28F1B78C-204A-41AF-8BDE-FECAD6559AAD} - Library - Properties - SIL.FieldWorks.Discourse - Discourse - - - 3.5 - v4.0 - - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - + Debug + AnyCPU + 9.0.21022 + 2.0 + {28F1B78C-204A-41AF-8BDE-FECAD6559AAD} + Library + Properties + SIL.FieldWorks.Discourse + Discourse + + + 3.5 + v4.0 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + - true - full - false - 168,169,219,414,649,1635,1702,1701 - ..\..\..\Output\Debug\ - DEBUG;TRACE - prompt - 4 - - - true - AllRules.ruleset - x86 + true + full + false + 168,169,219,414,649,1635,1702,1701 + ..\..\..\Output\Debug\ + DEBUG;TRACE + prompt + 4 + + + true + AllRules.ruleset + x86 - pdbonly - true - 168,169,219,414,649,1635,1702,1701 - ..\..\..\Output\Release\ - TRACE - prompt - 4 - AllRules.ruleset - x86 + pdbonly + true + 168,169,219,414,649,1635,1702,1701 + ..\..\..\Output\Release\ + TRACE + prompt + 4 + AllRules.ruleset + x86 - - False - ..\..\..\Output\Debug\BasicUtils.dll - - - False - ..\..\..\Output\Debug\COMInterfaces.dll - - - False - ..\..\..\Output\Debug\CoreImpl.dll - - - False - ..\..\..\Output\Debug\FDO.dll - - - False - ..\..\..\Output\Debug\Framework.dll - - - False - ..\..\..\Output\Debug\FwControls.dll - - - False - ..\..\..\Output\Debug\FwResources.dll - - - False - ..\..\..\Output\Debug\FwUtils.dll - - - False - ..\..\..\Lib\debug\ICSharpCode.SharpZipLib.dll - - - False - ..\..\..\Output\Debug\ITextDll.dll - - - False - - - False - ..\..\..\Output\Debug\RootSite.dll - - - False - - - False - ..\..\..\Output\Debug\SimpleRootSite.dll - - - - - - - - - False - ..\..\..\Output\Debug\xCore.dll - - - False - ..\..\..\Output\Debug\xCoreInterfaces.dll - - - False - ..\..\..\Output\Debug\XMLUtils.dll - - - False - ..\..\..\Output\Debug\xWorks.dll - + + False + ..\..\..\Output\Debug\BasicUtils.dll + + + False + ..\..\..\Output\Debug\COMInterfaces.dll + + + False + ..\..\..\Output\Debug\CoreImpl.dll + + + False + ..\..\..\Output\Debug\FDO.dll + + + False + ..\..\..\Output\Debug\Framework.dll + + + False + ..\..\..\Output\Debug\FwControls.dll + + + False + ..\..\..\Output\Debug\FwResources.dll + + + False + ..\..\..\Output\Debug\FwUtils.dll + + + False + ..\..\..\Lib\debug\ICSharpCode.SharpZipLib.dll + + + False + ..\..\..\Output\Debug\ITextDll.dll + + + False + + + False + ..\..\..\Output\Debug\RootSite.dll + + + False + + + False + ..\..\..\Output\Debug\SimpleRootSite.dll + + + + + + + + + False + ..\..\..\Output\Debug\xCore.dll + + + False + ..\..\..\Output\Debug\xCoreInterfaces.dll + + + False + ..\..\..\Output\Debug\XMLUtils.dll + + + False + ..\..\..\Output\Debug\xWorks.dll + - - Properties\CommonAssemblyInfo.cs - - - Form - - - AdvancedMTDialog.cs - - - - - - Component - - - ConstituentChart.cs - - - Component - - - - - - - - - DiscourseStrings.resx - True - True - - - Form - - - SelectClausesDialog.cs - + + Properties\CommonAssemblyInfo.cs + + + Form + + + AdvancedMTDialog.cs + + + + UserControl + + + + UserControl + + + ConstituentChart.cs + + + Component + + + Form + + + + UserControl + + + + + + DiscourseStrings.resx + True + True + + + Form + + + SelectClausesDialog.cs + - - AdvancedMTDialog.cs - Designer - - - ConstChartBody.cs - Designer - - - ConstituentChart.cs - Designer - - - Designer - ResXFileCodeGenerator - DiscourseStrings.Designer.cs - - - SelectClausesDialog.cs - Designer - + + AdvancedMTDialog.cs + Designer + + + ConstChartBody.cs + Designer + + + ConstituentChart.cs + Designer + + + Designer + ResXFileCodeGenerator + DiscourseStrings.Designer.cs + + + SelectClausesDialog.cs + Designer + - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Creating {0} + + + error encountered + + + finished + + + The parser gave the following cryptic message (you may need to contact FieldWorks support to know what it means): {0} + + + The phoneme {0} of lexical entry {1} is not defined. Please make sure all phonemes in all allomorphs of all entries have been defined. + + + The phoneme {0} of affix {1} is not defined. Please make sure all phonemes in all allomorphs of all affixes have been defined. + + + There is at least one undefined phoneme in the word '{0}'. The following phonemes were parsed: '{3}'. The problem begins with character/diacritic number {1} – that is, in the part of the word '{2}'. Please make sure all phonemes in the word have been defined. + + + A phonological rule is using a feature variable for feature {0}, but there is no corresponding feature variable in the environment. + + + + + + Automatically generated null affix for the {0} irregularly inflected form + Content used when showing the details of a parse in Try a Word for these inflectional affix slot fillers. {0} is the Name of the irregularly inflected form variant type. + + + ??? + missiing/undefined information + + + Maximum permitted analyses ({0}) reached. + + + Maximum internal buffer size ({0}) reached. + + + started + + + Trying Wordform {0} + + + Unknown CitationForm! + + + Unknown Gloss! + + + Unknown Morpheme! + + + Updating: {0} + + + Updating Grammar and Lexicon + + + {0}: error + + + {0} ({1}): {2} + {0} is the lexical form, {1} is the gloss, {2} is the citation form + + + Unknown Allomorph! + + + Unknown Natural Class! + + \ No newline at end of file diff --git a/Src/LexText/ParserUI/ParserUITests/Failures.xml b/Src/LexText/ParserCore/ParserCoreTests/Failures.xml similarity index 100% rename from Src/LexText/ParserUI/ParserUITests/Failures.xml rename to Src/LexText/ParserCore/ParserCoreTests/Failures.xml diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/WorkerTests.cs b/Src/LexText/ParserCore/ParserCoreTests/HelperTests.cs similarity index 78% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/WorkerTests.cs rename to Src/LexText/ParserCore/ParserCoreTests/HelperTests.cs index b4d8da9679..dc948a1a5d 100644 --- a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/WorkerTests.cs +++ b/Src/LexText/ParserCore/ParserCoreTests/HelperTests.cs @@ -2,10 +2,9 @@ // This software is licensed under the LGPL, version 2.1 or later // (http://www.gnu.org/licenses/lgpl-2.1.html) // -// File: WorkerTests.cs +// File: HelperTests.cs // Responsibility: AndyBlack -using System; using NUnit.Framework; using SIL.FieldWorks.Test.TestUtils; @@ -17,7 +16,7 @@ namespace SIL.FieldWorks.WordWorks.Parser /// /// ---------------------------------------------------------------------------------------- [TestFixture] - public class WorkerTests : BaseTest + public class HelperTests : BaseTest { ///-------------------------------------------------------------------------------------- /// @@ -25,23 +24,23 @@ public class WorkerTests : BaseTest /// ///-------------------------------------------------------------------------------------- [Test] - public void ConvertNameToUseANSICharactersTest() + public void ConvertNameToUseAnsiCharactersTest() { // plain, simple ASCII string name = "abc 123"; - string convertedName = ParserWorker.ConvertNameToUseANSICharacters(name); + string convertedName = ParserHelper.ConvertNameToUseAnsiCharacters(name); Assert.AreEqual("abc 123", convertedName); // Using upper ANSI characters as well as ASCII name = "ÿýúadctl"; - convertedName = ParserWorker.ConvertNameToUseANSICharacters(name); + convertedName = ParserHelper.ConvertNameToUseAnsiCharacters(name); Assert.AreEqual("ÿýúadctl", convertedName); // Using characters just above ANSI as well as ASCII name = "ąćălex"; - convertedName = ParserWorker.ConvertNameToUseANSICharacters(name); + convertedName = ParserHelper.ConvertNameToUseAnsiCharacters(name); Assert.AreEqual("010501070103lex", convertedName); // Using Cyrillic characters as well as ASCII name = "Английский для семинараgram"; - convertedName = ParserWorker.ConvertNameToUseANSICharacters(name); + convertedName = ParserHelper.ConvertNameToUseAnsiCharacters(name); Assert.AreEqual("0410043D0433043B043804390441043A04380439 0434043B044F 04410435043C0438043D043004400430gram", convertedName); } } diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTests.cs b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTests.cs similarity index 76% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTests.cs rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTests.cs index da6a3a32ce..db49ef9f14 100644 --- a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTests.cs +++ b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTests.cs @@ -44,16 +44,12 @@ public class M3ToXAmpleTransformerTests : BaseTest string m_sM3FXTAffixAlloFeatsDump; string m_sM3FXTLatinDump; string m_sM3FXTIrregularlyInflectedFormsDump; - Dictionary m_mapXmlDocs = new Dictionary(); -#if __MonoCS__ - IntPtr m_adTransform; - IntPtr m_lexTransform; - IntPtr m_gramTransform; -#else + readonly Dictionary m_mapXmlDocs = new Dictionary(); + XslCompiledTransform m_adTransform; XslCompiledTransform m_lexTransform; XslCompiledTransform m_gramTransform; -#endif + bool m_fResultMatchesExpected = true; /// @@ -70,40 +66,13 @@ public override void FixtureSetup() { base.FixtureSetup(); - m_sTestPath = Path.Combine(DirectoryFinder.FwSourceDirectory, - Path.Combine("LexText", - Path.Combine("ParserEngine", - Path.Combine("ParserCore", - Path.Combine("ParserCoreTests", "M3ToXAmpleTransformerTestsDataFiles"))))); - m_sTransformPath = Path.Combine(DirectoryFinder.FlexFolder, "Transforms"); + m_sTestPath = Path.Combine(FwDirectoryFinder.SourceDirectory, "LexText", "ParserCore", "ParserCoreTests", "M3ToXAmpleTransformerTestsDataFiles"); + m_sTransformPath = Path.Combine(FwDirectoryFinder.FlexFolder, "Transforms"); SetUpXAmpleTransforms(); SetUpM3FXTDump(); } - [TestFixtureTearDown] - public override void FixtureTeardown() - { -#if __MonoCS__ - if (m_adTransform != IntPtr.Zero) - { - LibXslt.FreeCompiledTransform(m_adTransform); - m_adTransform = IntPtr.Zero; - } - if (m_lexTransform != IntPtr.Zero) - { - LibXslt.FreeCompiledTransform(m_lexTransform); - m_lexTransform = IntPtr.Zero; - } - if (m_gramTransform != IntPtr.Zero) - { - LibXslt.FreeCompiledTransform(m_gramTransform); - m_gramTransform = IntPtr.Zero; - } -#endif - base.FixtureTeardown(); - } - private void SetUpM3FXTDump() { m_sM3FXTDump = Path.Combine(m_sTestPath, "M3FXTDump.xml"); @@ -120,7 +89,7 @@ private void SetUpM3FXTDump() m_sM3FXTAffixAlloFeatsDump = Path.Combine(m_sTestPath, "TestAffixAllomorphFeatsParserFxtResult.xml"); m_sM3FXTLatinDump = Path.Combine(m_sTestPath, "LatinParserFxtResult.xml"); m_sM3FXTIrregularlyInflectedFormsDump = Path.Combine(m_sTestPath, "IrregularlyInflectedFormsParserFxtResult.xml"); -#if !__MonoCS__ + SetupXmlDocument(m_sM3FXTDump); SetupXmlDocument(m_sM3FXTCircumfixDump); SetupXmlDocument(m_sM3FXTCircumfixInfixDump); @@ -135,31 +104,24 @@ private void SetUpM3FXTDump() SetupXmlDocument(m_sM3FXTAffixAlloFeatsDump); SetupXmlDocument(m_sM3FXTLatinDump); SetupXmlDocument(m_sM3FXTIrregularlyInflectedFormsDump); -#endif } private void SetupXmlDocument(string filepath) { - XPathDocument xdoc = new XPathDocument(filepath); + var xdoc = new XPathDocument(filepath); m_mapXmlDocs.Add(filepath, xdoc); } private void SetUpXAmpleTransforms() { - SetUpTransform(ref m_adTransform, "FxtM3ParserToXAmpleADCtl.xsl"); - SetUpTransform(ref m_lexTransform, "FxtM3ParserToXAmpleLex.xsl"); - SetUpTransform(ref m_gramTransform, "FxtM3ParserToToXAmpleGrammar.xsl"); - } - private void SetUpTransform(ref XslCompiledTransform transform, string sName) - { - string sTransformPath = Path.Combine(m_sTransformPath, sName); - transform = new XslCompiledTransform(); - transform.Load(sTransformPath); + SetUpTransform("FxtM3ParserToXAmpleADCtl", out m_adTransform); + SetUpTransform("FxtM3ParserToXAmpleLex", out m_lexTransform); + SetUpTransform("FxtM3ParserToToXAmpleGrammar", out m_gramTransform); } - private void SetUpTransform(ref IntPtr transform, string sName) + + private void SetUpTransform(string name, out XslCompiledTransform transform) { - string sTransformPath = Path.Combine(m_sTransformPath, sName); - transform = LibXslt.CompileTransform(sTransformPath); + transform = XmlUtils.CreateTransform(name, "ApplicationTransforms"); } /// @@ -219,7 +181,7 @@ private void ApplyTransform(string sInput, XslCompiledTransform transform, strin { XPathDocument fxtDump = m_mapXmlDocs[sInput]; string sOutput = FileUtils.GetTempFile("txt"); - using (StreamWriter result = new StreamWriter(sOutput)) + using (var result = new StreamWriter(sOutput)) { transform.Transform(fxtDump, null, result); result.Close(); @@ -229,27 +191,18 @@ private void ApplyTransform(string sInput, XslCompiledTransform transform, strin // by deleting it here instead of a finally block, when it fails, we can see what the result is. File.Delete(sOutput); } - private void ApplyTransform(string sInput, IntPtr transform, string sExpectedOutput) - { - string sOutput = FileUtils.GetTempFile("txt"); - SIL.Utils.LibXslt.TransformFileToFile(transform, sInput, sOutput); - string sExpectedResult = Path.Combine(m_sTestPath, sExpectedOutput); - CheckOutputEquals(sExpectedResult, sOutput); - // by deleting it here instead of a finally block, when it fails, we can see what the result is. - File.Delete(sOutput); - } private void CheckOutputEquals(string sExpectedResultFile, string sActualResultFile) { string sExpected, sActual; - using (StreamReader expected = new StreamReader(sExpectedResultFile)) + using (var expected = new StreamReader(sExpectedResultFile)) sExpected = expected.ReadToEnd(); - using (StreamReader actual = new StreamReader(sActualResultFile)) + using (var actual = new StreamReader(sActualResultFile)) sActual = actual.ReadToEnd(); // A non-empty last line in a file from git always ends with '\n' character if (sActual.Substring(sActual.Length - 1) != "\n") sActual += Environment.NewLine; - StringBuilder sb = new StringBuilder(); + var sb = new StringBuilder(); sb.Append("Expected file was "); sb.AppendLine(sExpectedResultFile); sb.Append("Actual file was "); diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/.gitattributes b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/.gitattributes similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/.gitattributes rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/.gitattributes diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/AffixAlloFeatsAdCtl.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/AffixAlloFeatsAdCtl.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/AffixAlloFeatsAdCtl.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/AffixAlloFeatsAdCtl.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/AffixAlloFeatsLexicon.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/AffixAlloFeatsLexicon.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/AffixAlloFeatsLexicon.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/AffixAlloFeatsLexicon.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/AffixAlloFeatsWordGrammar.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/AffixAlloFeatsWordGrammar.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/AffixAlloFeatsWordGrammar.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/AffixAlloFeatsWordGrammar.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CircumfixInfixLexicon.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CircumfixInfixLexicon.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CircumfixInfixLexicon.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CircumfixInfixLexicon.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CircumfixInfixWordGrammar.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CircumfixInfixWordGrammar.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CircumfixInfixWordGrammar.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CircumfixInfixWordGrammar.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticAdCtl.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticAdCtl.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticAdCtl.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticAdCtl.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticEnvsLexicon.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticEnvsLexicon.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticEnvsLexicon.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticEnvsLexicon.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticEnvsParserFxtResult.xml b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticEnvsParserFxtResult.xml similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticEnvsParserFxtResult.xml rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticEnvsParserFxtResult.xml diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticLexicon.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticLexicon.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticLexicon.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticLexicon.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticParserFxtResult.xml b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticParserFxtResult.xml similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticParserFxtResult.xml rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticParserFxtResult.xml diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticWordGrammar.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticWordGrammar.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticWordGrammar.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/CliticWordGrammar.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/ConceptualIntroTestParserFxtResult.xml b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/ConceptualIntroTestParserFxtResult.xml similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/ConceptualIntroTestParserFxtResult.xml rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/ConceptualIntroTestParserFxtResult.xml diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/ConceptualIntroTestlex.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/ConceptualIntroTestlex.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/ConceptualIntroTestlex.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/ConceptualIntroTestlex.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/FullRedupLexicon.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/FullRedupLexicon.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/FullRedupLexicon.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/FullRedupLexicon.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IndonCircumfixLexicon.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IndonCircumfixLexicon.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IndonCircumfixLexicon.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IndonCircumfixLexicon.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IndonCircumfixWordGrammar.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IndonCircumfixWordGrammar.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IndonCircumfixWordGrammar.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IndonCircumfixWordGrammar.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IrregularlyInflectedFormsAdCtl.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IrregularlyInflectedFormsAdCtl.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IrregularlyInflectedFormsAdCtl.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IrregularlyInflectedFormsAdCtl.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IrregularlyInflectedFormsLexicon.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IrregularlyInflectedFormsLexicon.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IrregularlyInflectedFormsLexicon.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IrregularlyInflectedFormsLexicon.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IrregularlyInflectedFormsParserFxtResult.xml b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IrregularlyInflectedFormsParserFxtResult.xml similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IrregularlyInflectedFormsParserFxtResult.xml rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/IrregularlyInflectedFormsParserFxtResult.xml diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/LatinAdCtl.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/LatinAdCtl.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/LatinAdCtl.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/LatinAdCtl.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/LatinParserFxtResult.xml b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/LatinParserFxtResult.xml similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/LatinParserFxtResult.xml rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/LatinParserFxtResult.xml diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/LatinWordGrammar.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/LatinWordGrammar.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/LatinWordGrammar.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/LatinWordGrammar.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTCircumfixDump.xml b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTCircumfixDump.xml similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTCircumfixDump.xml rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTCircumfixDump.xml diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTCircumfixInfixDump.xml b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTCircumfixInfixDump.xml similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTCircumfixInfixDump.xml rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTCircumfixInfixDump.xml diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTDump.xml b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTDump.xml similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTDump.xml rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTDump.xml diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTFullRedupDump.xml b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTFullRedupDump.xml similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTFullRedupDump.xml rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTFullRedupDump.xml diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTStemNameDump.xml b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTStemNameDump.xml similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTStemNameDump.xml rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/M3FXTStemNameDump.xml diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/OrizabaParserFxtResult.xml b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/OrizabaParserFxtResult.xml similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/OrizabaParserFxtResult.xml rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/OrizabaParserFxtResult.xml diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/Orizabaadctl.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/Orizabaadctl.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/Orizabaadctl.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/Orizabaadctl.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/Orizabagram.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/Orizabagram.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/Orizabagram.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/Orizabagram.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/Orizabalex.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/Orizabalex.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/Orizabalex.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/Orizabalex.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/RootCliticEnvParserFxtResult.xml b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/RootCliticEnvParserFxtResult.xml similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/RootCliticEnvParserFxtResult.xml rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/RootCliticEnvParserFxtResult.xml diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/RootCliticEnvsLexicon.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/RootCliticEnvsLexicon.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/RootCliticEnvsLexicon.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/RootCliticEnvsLexicon.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemName3ParserFxtResult.xml b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemName3ParserFxtResult.xml similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemName3ParserFxtResult.xml rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemName3ParserFxtResult.xml diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemName3adctl.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemName3adctl.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemName3adctl.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemName3adctl.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemName3gram.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemName3gram.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemName3gram.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemName3gram.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemName3lex.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemName3lex.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemName3lex.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemName3lex.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemNameTestAdCtl.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemNameTestAdCtl.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemNameTestAdCtl.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemNameTestAdCtl.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemNameTestlex.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemNameTestlex.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemNameTestlex.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemNameTestlex.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemNameWordGrammar.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemNameWordGrammar.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemNameWordGrammar.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/StemNameWordGrammar.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/TestAdCtl.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/TestAdCtl.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/TestAdCtl.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/TestAdCtl.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/TestAffixAllomorphFeatsParserFxtResult.xml b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/TestAffixAllomorphFeatsParserFxtResult.xml similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/TestAffixAllomorphFeatsParserFxtResult.xml rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/TestAffixAllomorphFeatsParserFxtResult.xml diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/TestLexicon.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/TestLexicon.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/TestLexicon.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/TestLexicon.txt diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/TestWordGrammar.txt b/Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/TestWordGrammar.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/TestWordGrammar.txt rename to Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles/TestWordGrammar.txt diff --git a/Src/LexText/ParserCore/ParserCoreTests/ParseFilerProcessingTests.cs b/Src/LexText/ParserCore/ParserCoreTests/ParseFilerProcessingTests.cs new file mode 100644 index 0000000000..21d9051536 --- /dev/null +++ b/Src/LexText/ParserCore/ParserCoreTests/ParseFilerProcessingTests.cs @@ -0,0 +1,627 @@ +// Copyright (c) 2003-2013 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) +// +// File: ParseFilerProcessingTests.cs +// Responsibility: Randy Regnier +// Last reviewed: +// +// +// Implements the ParseFilerProcessingTests unit tests. +// +// buildtest ParseFiler-nodep + +using System; +using System.Linq; +using NUnit.Framework; +using SIL.CoreImpl; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.FDO.DomainServices; +using SIL.FieldWorks.FDO.Infrastructure; +using SIL.FieldWorks.FDO.FDOTests; +using SIL.Utils; + +namespace SIL.FieldWorks.WordWorks.Parser +{ + /// + /// Summary description for ParseFilerProcessingTests. + /// + [TestFixture] + public class ParseFilerProcessingTests : MemoryOnlyBackendProviderTestBase + { + #region Data Members + + private ParseFiler m_filer; + private IdleQueue m_idleQueue; + private IWritingSystem m_vernacularWS; + private ILexEntryFactory m_entryFactory; + private ILexSenseFactory m_senseFactory; + private IMoStemAllomorphFactory m_stemAlloFactory; + private IMoAffixAllomorphFactory m_afxAlloFactory; + private IMoStemMsaFactory m_stemMsaFactory; + private IMoInflAffMsaFactory m_inflAffMsaFactory; + private ILexEntryRefFactory m_lexEntryRefFactory; + private ILexEntryInflTypeFactory m_lexEntryInflTypeFactory; + + #endregion Data Members + + #region Non-test methods + + protected ICmAgent ParserAgent + { + get + { + return Cache.LanguageProject.DefaultParserAgent; + } + } + + protected ICmAgent HumanAgent + { + get + { + return Cache.LanguageProject.DefaultUserAgent; + } + } + + protected IWfiWordform CheckAnnotationSize(string form, int expectedSize, bool isStarting) + { + IFdoServiceLocator servLoc = Cache.ServiceLocator; + IWfiWordform wf = FindOrCreateWordform(form); + int actualSize = + (from ann in servLoc.GetInstance().AllInstances() + where ann.BeginObjectRA == wf + select ann).Count(); + // wf.RefsFrom_CmBaseAnnotation_BeginObject.Count; + string msg = String.Format("Wrong number of {0} annotations for: {1}", isStarting ? "starting" : "ending", form); + Assert.AreEqual(expectedSize, actualSize, msg); + return wf; + } + + private IWfiWordform FindOrCreateWordform(string form) + { + IFdoServiceLocator servLoc = Cache.ServiceLocator; + IWfiWordform wf = servLoc.GetInstance().GetMatchingWordform(m_vernacularWS.Handle, form); + if (wf == null) + { + UndoableUnitOfWorkHelper.Do("Undo create", "Redo create", m_actionHandler, + () => wf = servLoc.GetInstance().Create(Cache.TsStrFactory.MakeString(form, m_vernacularWS.Handle))); + } + return wf; + } + + protected IWfiWordform CheckAnalysisSize(string form, int expectedSize, bool isStarting) + { + IWfiWordform wf = FindOrCreateWordform(form); + int actualSize = wf.AnalysesOC.Count; + string msg = String.Format("Wrong number of {0} analyses for: {1}", isStarting ? "starting" : "ending", form); + Assert.AreEqual(expectedSize, actualSize, msg); + return wf; + } + + protected void CheckEvaluationSize(IWfiAnalysis analysis, int expectedSize, bool isStarting, string additionalMessage) + { + int actualSize = analysis.EvaluationsRC.Count; + string msg = String.Format("Wrong number of {0} evaluations for analysis: {1} ({2})", isStarting ? "starting" : "ending", analysis.Hvo, additionalMessage); + Assert.AreEqual(expectedSize, actualSize, msg); + } + + protected void ExecuteIdleQueue() + { + foreach (var task in m_idleQueue) + task.Delegate(task.Parameter); + m_idleQueue.Clear(); + } + + #endregion // Non-tests + + #region Setup and TearDown + + public override void FixtureSetup() + { + base.FixtureSetup(); + m_vernacularWS = Cache.ServiceLocator.WritingSystems.DefaultVernacularWritingSystem; + m_idleQueue = new IdleQueue {IsPaused = true}; + m_filer = new ParseFiler(Cache, task => {}, m_idleQueue, Cache.LanguageProject.DefaultParserAgent); + m_entryFactory = Cache.ServiceLocator.GetInstance(); + m_senseFactory = Cache.ServiceLocator.GetInstance(); + m_stemAlloFactory = Cache.ServiceLocator.GetInstance(); + m_afxAlloFactory = Cache.ServiceLocator.GetInstance(); + m_stemMsaFactory = Cache.ServiceLocator.GetInstance(); + m_inflAffMsaFactory = Cache.ServiceLocator.GetInstance(); + m_lexEntryRefFactory = Cache.ServiceLocator.GetInstance(); + m_lexEntryInflTypeFactory = Cache.ServiceLocator.GetInstance(); + } + + public override void FixtureTeardown() + { + m_vernacularWS = null; + m_filer = null; + m_idleQueue.Dispose(); + m_idleQueue = null; + m_entryFactory = null; + m_senseFactory = null; + m_stemAlloFactory = null; + m_afxAlloFactory = null; + m_stemMsaFactory = null; + m_inflAffMsaFactory = null; + m_lexEntryRefFactory = null; + m_lexEntryInflTypeFactory = null; + + base.FixtureTeardown(); + } + + public override void TestTearDown() + { + UndoAll(); + base.TestTearDown(); + } + + /// ------------------------------------------------------------------------------------ + /// + /// End the undoable UOW and Undo everything. + /// + /// ------------------------------------------------------------------------------------ + protected void UndoAll() + { + // Undo the UOW (or more than one of them, if the test made new ones). + while (m_actionHandler.CanUndo()) + m_actionHandler.Undo(); + + // Need to 'Commit' to clear out redo stack, + // since nothing is really saved. + m_actionHandler.Commit(); + } + + #endregion Setup and TearDown + + #region Tests + + [Test] + public void TooManyAnalyses() + { + IWfiWordform bearsTest = CheckAnnotationSize("bearsTEST", 0, true); + var result = new ParseResult("Maximum permitted analyses (448) reached."); + m_filer.ProcessParse(bearsTest, ParserPriority.Low, result); + ExecuteIdleQueue(); + CheckAnnotationSize("bearsTEST", 1, false); + } + + [Test] + public void BufferOverrun() + { + IWfiWordform dogsTest = CheckAnnotationSize("dogsTEST", 0, true); + var result = new ParseResult("Maximum internal buffer size (117) reached."); + m_filer.ProcessParse(dogsTest, ParserPriority.Low, result); + ExecuteIdleQueue(); + CheckAnnotationSize("dogsTEST", 1, false); + } + + [Test] + public void TwoAnalyses() + { + IWfiWordform catsTest = CheckAnalysisSize("catsTEST", 0, true); + ILexDb ldb = Cache.LanguageProject.LexDbOA; + + ParseResult result = null; + UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => + { + // Noun + ILexEntry catN = m_entryFactory.Create(); + IMoStemAllomorph catNForm = m_stemAlloFactory.Create(); + catN.AlternateFormsOS.Add(catNForm); + catNForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("catNTEST", m_vernacularWS.Handle); + IMoStemMsa catNMsa = m_stemMsaFactory.Create(); + catN.MorphoSyntaxAnalysesOC.Add(catNMsa); + + ILexEntry sPl = m_entryFactory.Create(); + IMoAffixAllomorph sPlForm = m_afxAlloFactory.Create(); + sPl.AlternateFormsOS.Add(sPlForm); + sPlForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("sPLTEST", m_vernacularWS.Handle); + IMoInflAffMsa sPlMsa = m_inflAffMsaFactory.Create(); + sPl.MorphoSyntaxAnalysesOC.Add(sPlMsa); + + // Verb + ILexEntry catV = m_entryFactory.Create(); + IMoStemAllomorph catVForm = m_stemAlloFactory.Create(); + catV.AlternateFormsOS.Add(catVForm); + catVForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("catVTEST", m_vernacularWS.Handle); + IMoStemMsa catVMsa = m_stemMsaFactory.Create(); + catV.MorphoSyntaxAnalysesOC.Add(catVMsa); + + ILexEntry sAgr = m_entryFactory.Create(); + IMoAffixAllomorph sAgrForm = m_afxAlloFactory.Create(); + sAgr.AlternateFormsOS.Add(sAgrForm); + sAgrForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("sAGRTEST", m_vernacularWS.Handle); + IMoInflAffMsa sAgrMsa = m_inflAffMsaFactory.Create(); + sAgr.MorphoSyntaxAnalysesOC.Add(sAgrMsa); + + result = new ParseResult(new[] + { + new ParseAnalysis(new[] + { + new ParseMorph(catNForm, catNMsa), + new ParseMorph(sPlForm, sPlMsa) + }), + new ParseAnalysis(new[] + { + new ParseMorph(catVForm, catVMsa), + new ParseMorph(sAgrForm, sAgrMsa) + }) + }); + }); + m_filer.ProcessParse(catsTest, ParserPriority.Low, result); + ExecuteIdleQueue(); + CheckAnalysisSize("catsTEST", 2, false); + } + + [Test] + [Ignore("Is it ever possible for a parser to return more than one wordform parse?")] + public void TwoWordforms() + { + IWfiWordform snake = CheckAnalysisSize("snakeTEST", 0, true); + IWfiWordform bull = CheckAnalysisSize("bullTEST", 0, true); + ILexDb ldb = Cache.LanguageProject.LexDbOA; + + ParseResult result = null; + UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => + { + // Snake + ILexEntry snakeN = m_entryFactory.Create(); + IMoStemAllomorph snakeNForm = m_stemAlloFactory.Create(); + snakeN.AlternateFormsOS.Add(snakeNForm); + snakeNForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("snakeNTEST", m_vernacularWS.Handle); + IMoStemMsa snakeNMsa = m_stemMsaFactory.Create(); + snakeN.MorphoSyntaxAnalysesOC.Add(snakeNMsa); + + // Bull + ILexEntry bullN = m_entryFactory.Create(); + IMoStemAllomorph bullNForm = m_stemAlloFactory.Create(); + bullN.AlternateFormsOS.Add(bullNForm); + bullNForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("bullNTEST", m_vernacularWS.Handle); + IMoStemMsa bullNMsa = m_stemMsaFactory.Create(); + bullN.MorphoSyntaxAnalysesOC.Add(bullNMsa); + + result = new ParseResult(new[] + { + new ParseAnalysis(new[] + { + new ParseMorph(snakeNForm, snakeNMsa) + }), + new ParseAnalysis(new[] + { + new ParseMorph(bullNForm, bullNMsa) + }) + }); + }); + + m_filer.ProcessParse(snake, ParserPriority.Low, result); + ExecuteIdleQueue(); + CheckAnalysisSize("snakeTEST", 1, false); + CheckAnalysisSize("bullTEST", 1, false); + } + + /// + /// Ensure analyses with 'duplicate' analyses are both approved. + /// "Duplicate" means the MSA and MoForm IDs are the same in two different analyses. + /// + [Test] + public void DuplicateAnalysesApproval() + { + IWfiWordform pigs = CheckAnalysisSize("pigsTEST", 0, true); + + ParseResult result = null; + IWfiAnalysis anal1 = null, anal2 = null, anal3 = null; + UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => + { + // Bear entry + ILexEntry pigN = m_entryFactory.Create(); + IMoStemAllomorph pigNForm = m_stemAlloFactory.Create(); + pigN.AlternateFormsOS.Add(pigNForm); + pigNForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("pigNTEST", m_vernacularWS.Handle); + IMoStemMsa pigNMsa = m_stemMsaFactory.Create(); + pigN.MorphoSyntaxAnalysesOC.Add(pigNMsa); + ILexSense pigNSense = Cache.ServiceLocator.GetInstance().Create(); + pigN.SensesOS.Add(pigNSense); + + var analFactory = Cache.ServiceLocator.GetInstance(); + var mbFactory = Cache.ServiceLocator.GetInstance(); + // First of two duplicate analyses + IWfiAnalysis anal = analFactory.Create(); + pigs.AnalysesOC.Add(anal); + anal1 = anal; + IWfiMorphBundle mb = mbFactory.Create(); + anal.MorphBundlesOS.Add(mb); + mb.MorphRA = pigNForm; + mb.MsaRA = pigNMsa; + CheckEvaluationSize(anal1, 0, true, "anal1"); + + // Non-duplicate, to make sure it does not get approved. + anal = analFactory.Create(); + pigs.AnalysesOC.Add(anal); + anal2 = anal; + mb = mbFactory.Create(); + anal.MorphBundlesOS.Add(mb); + mb.SenseRA = pigNSense; + CheckEvaluationSize(anal2, 0, true, "anal2"); + + // Second of two duplicate analyses + anal = analFactory.Create(); + pigs.AnalysesOC.Add(anal); + anal3 = anal; + mb = mbFactory.Create(); + anal.MorphBundlesOS.Add(mb); + mb.MorphRA = pigNForm; + mb.MsaRA = pigNMsa; + CheckEvaluationSize(anal3, 0, true, "anal3"); + CheckAnalysisSize("pigsTEST", 3, false); + + result = new ParseResult(new[] + { + new ParseAnalysis(new[] + { + new ParseMorph(pigNForm, pigNMsa) + }) + }); + }); + + m_filer.ProcessParse(pigs, ParserPriority.Low, result); + ExecuteIdleQueue(); + CheckEvaluationSize(anal1, 1, false, "anal1Hvo"); + Assert.IsFalse(anal2.IsValidObject, "analysis 2 should end up with no evaluations and so be deleted"); + CheckEvaluationSize(anal3, 1, false, "anal3Hvo"); + } + + [Test] + public void HumanApprovedParserPreviouslyApprovedButNowRejectedAnalysisSurvives() + { + IWfiWordform theThreeLittlePigs = CheckAnalysisSize("theThreeLittlePigsTEST", 0, true); + + ParseResult result = null; + IWfiAnalysis anal = null; + UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => + { + // Pig entry + ILexEntry pigN = m_entryFactory.Create(); + IMoStemAllomorph pigNForm = m_stemAlloFactory.Create(); + pigN.AlternateFormsOS.Add(pigNForm); + pigNForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("pigNTEST", m_vernacularWS.Handle); + IMoStemMsa pigNMsa = m_stemMsaFactory.Create(); + pigN.MorphoSyntaxAnalysesOC.Add(pigNMsa); + ILexSense pigNSense = Cache.ServiceLocator.GetInstance().Create(); + pigN.SensesOS.Add(pigNSense); + + // Human approved anal. Start with parser approved, but then it failed. + var analFactory = Cache.ServiceLocator.GetInstance(); + var mbFactory = Cache.ServiceLocator.GetInstance(); + // Only analysis: human approved, previously parser approved but no longer produced. + anal = analFactory.Create(); + theThreeLittlePigs.AnalysesOC.Add(anal); + IWfiMorphBundle mb = mbFactory.Create(); + anal.MorphBundlesOS.Add(mb); + mb.MorphRA = pigNForm; + mb.MsaRA = pigNMsa; + HumanAgent.SetEvaluation(anal, Opinions.approves); + ParserAgent.SetEvaluation(anal, Opinions.approves); + CheckEvaluationSize(anal, 2, true, "anal"); + CheckAnalysisSize("theThreeLittlePigsTEST", 1, true); + + result = new ParseResult(Enumerable.Empty()); + }); + + m_filer.ProcessParse(theThreeLittlePigs, ParserPriority.Low, result); + ExecuteIdleQueue(); + CheckEvaluationSize(anal, 2, false, "analHvo"); + Assert.IsTrue(anal.IsValidObject, "analysis should end up with one evaluation and not be deleted"); + } + + [Test] + public void HumanHasNoopinionParserHadApprovedButNoLongerApprovesRemovesAnalysis() + { + IWfiWordform threeLittlePigs = CheckAnalysisSize("threeLittlePigsTEST", 0, true); + + ParseResult result = null; + IWfiAnalysis anal = null; + UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => + { + // Pig entry + ILexEntry pigN = m_entryFactory.Create(); + IMoStemAllomorph pigNForm = m_stemAlloFactory.Create(); + pigN.AlternateFormsOS.Add(pigNForm); + pigNForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("pigNTEST", m_vernacularWS.Handle); + IMoStemMsa pigNMsa = m_stemMsaFactory.Create(); + pigN.MorphoSyntaxAnalysesOC.Add(pigNMsa); + ILexSense pigNSense = Cache.ServiceLocator.GetInstance().Create(); + pigN.SensesOS.Add(pigNSense); + + // Human no-opinion anal. Parser had approved, but then it failed to produce it. + var analFactory = Cache.ServiceLocator.GetInstance(); + var mbFactory = Cache.ServiceLocator.GetInstance(); + // Human no-opinion anal. Parser had approved, but then it failed to produce it. + anal = analFactory.Create(); + threeLittlePigs.AnalysesOC.Add(anal); + IWfiMorphBundle mb = mbFactory.Create(); + anal.MorphBundlesOS.Add(mb); + mb.MorphRA = pigNForm; + mb.MsaRA = pigNMsa; + HumanAgent.SetEvaluation(anal, Opinions.noopinion); + ParserAgent.SetEvaluation(anal, Opinions.approves); + CheckEvaluationSize(anal, 1, true, "anal"); + CheckAnalysisSize("threeLittlePigsTEST", 1, true); + + result = new ParseResult(Enumerable.Empty()); + }); + + m_filer.ProcessParse(threeLittlePigs, ParserPriority.Low, result); + ExecuteIdleQueue(); + Assert.IsFalse(anal.IsValidObject, "analysis should end up with no evaluations and be deleted."); + } + + [Test] + public void LexEntryInflTypeTwoAnalyses() + { + IWfiWordform creb = CheckAnalysisSize("crebTEST", 0, true); + ILexDb ldb = Cache.LanguageProject.LexDbOA; + + ParseResult result = null; + UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => + { + // Verb creb which is a past tense, plural irregularly inflected form of 'believe' and also 'seek' + // with automatically generated null Tense slot and an automatically generated null Number slot filler + // (This is not supposed to be English, in case you're wondering....) + + ILexEntryInflType pastTenseLexEntryInflType = m_lexEntryInflTypeFactory.Create(); + ILexEntryInflType pluralTenseLexEntryInflType = m_lexEntryInflTypeFactory.Create(); + Cache.LangProject.LexDbOA.VariantEntryTypesOA.PossibilitiesOS.Add(pastTenseLexEntryInflType); + Cache.LangProject.LexDbOA.VariantEntryTypesOA.PossibilitiesOS.Add(pluralTenseLexEntryInflType); + + ILexEntry believeV = m_entryFactory.Create(); + IMoStemAllomorph believeVForm = m_stemAlloFactory.Create(); + believeV.AlternateFormsOS.Add(believeVForm); + believeVForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("believeVTEST", m_vernacularWS.Handle); + IMoStemMsa believeVMsa = m_stemMsaFactory.Create(); + believeV.MorphoSyntaxAnalysesOC.Add(believeVMsa); + ILexSense believeVSense = m_senseFactory.Create(); + believeV.SensesOS.Add(believeVSense); + believeVSense.MorphoSyntaxAnalysisRA = believeVMsa; + + ILexEntry seekV = m_entryFactory.Create(); + IMoStemAllomorph seekVForm = m_stemAlloFactory.Create(); + believeV.AlternateFormsOS.Add(seekVForm); + seekVForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("seekVTEST", m_vernacularWS.Handle); + IMoStemMsa seekVMsa = m_stemMsaFactory.Create(); + seekV.MorphoSyntaxAnalysesOC.Add(seekVMsa); + ILexSense seekVSense = m_senseFactory.Create(); + seekV.SensesOS.Add(seekVSense); + seekVSense.MorphoSyntaxAnalysisRA = seekVMsa; + + ILexEntry crebV = m_entryFactory.Create(); + IMoStemAllomorph crebVForm = m_stemAlloFactory.Create(); + crebV.AlternateFormsOS.Add(crebVForm); + crebVForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("crebVTEST", m_vernacularWS.Handle); + ILexEntryRef lexEntryref = m_lexEntryRefFactory.Create(); + crebV.EntryRefsOS.Add(lexEntryref); + lexEntryref.ComponentLexemesRS.Add(believeV); + lexEntryref.VariantEntryTypesRS.Add(pastTenseLexEntryInflType); + lexEntryref.VariantEntryTypesRS.Add(pluralTenseLexEntryInflType); + lexEntryref = m_lexEntryRefFactory.Create(); + crebV.EntryRefsOS.Add(lexEntryref); + lexEntryref.ComponentLexemesRS.Add(seekV); + lexEntryref.VariantEntryTypesRS.Add(pastTenseLexEntryInflType); + lexEntryref.VariantEntryTypesRS.Add(pluralTenseLexEntryInflType); + + ILexEntry nullPast = m_entryFactory.Create(); + IMoAffixAllomorph nullPastForm = m_afxAlloFactory.Create(); + nullPast.AlternateFormsOS.Add(nullPastForm); + nullPastForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("nullPASTTEST", m_vernacularWS.Handle); + IMoInflAffMsa nullPastMsa = m_inflAffMsaFactory.Create(); + nullPast.MorphoSyntaxAnalysesOC.Add(nullPastMsa); + + ILexEntry nullPlural = m_entryFactory.Create(); + IMoAffixAllomorph nullPluralForm = m_afxAlloFactory.Create(); + nullPlural.AlternateFormsOS.Add(nullPluralForm); + nullPluralForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("nullPLURALTEST", m_vernacularWS.Handle); + IMoInflAffMsa nullPluralMsa = m_inflAffMsaFactory.Create(); + nullPlural.MorphoSyntaxAnalysesOC.Add(nullPluralMsa); + + result = new ParseResult(new[] + { + new ParseAnalysis(new[] + { + new ParseMorph(crebVForm, MorphServices.GetMainOrFirstSenseOfVariant(crebV.EntryRefsOS[1]).MorphoSyntaxAnalysisRA, + (ILexEntryInflType) crebV.EntryRefsOS[1].VariantEntryTypesRS[0]) + }), + new ParseAnalysis(new[] + { + new ParseMorph(crebVForm, MorphServices.GetMainOrFirstSenseOfVariant(crebV.EntryRefsOS[0]).MorphoSyntaxAnalysisRA, + (ILexEntryInflType) crebV.EntryRefsOS[0].VariantEntryTypesRS[0]) + }) + }); + }); + + m_filer.ProcessParse(creb, ParserPriority.Low, result); + ExecuteIdleQueue(); + CheckAnalysisSize("crebTEST", 2, false); + foreach (var analysis in creb.AnalysesOC) + { + Assert.AreEqual(1, analysis.MorphBundlesOS.Count, "Expected only 1 morph in the analysis"); + var morphBundle = analysis.MorphBundlesOS.ElementAt(0); + Assert.IsNotNull(morphBundle.Form, "First bundle: form is not null"); + Assert.IsNotNull(morphBundle.MsaRA, "First bundle: msa is not null"); + Assert.IsNotNull(morphBundle.InflTypeRA, "First bundle: infl type is not null"); + } + } + + [Test] + public void LexEntryInflTypeAnalysisWithNullForSlotFiller() + { + IWfiWordform brubs = CheckAnalysisSize("brubsTEST", 0, true); + ILexDb ldb = Cache.LanguageProject.LexDbOA; + + ParseResult result = null; + UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => + { + // Verb brub which is a present tense irregularly inflected form of 'believe' + // with automatically generated null Tense slot and an -s Plural Number slot filler + // (This is not supposed to be English, in case you're wondering....) + + ILexEntryInflType presentTenseLexEntryInflType = m_lexEntryInflTypeFactory.Create(); + Cache.LangProject.LexDbOA.VariantEntryTypesOA.PossibilitiesOS.Add(presentTenseLexEntryInflType); + + ILexEntry believeV = m_entryFactory.Create(); + IMoStemAllomorph believeVForm = m_stemAlloFactory.Create(); + believeV.AlternateFormsOS.Add(believeVForm); + believeVForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("believeVTEST", m_vernacularWS.Handle); + IMoStemMsa believeVMsa = m_stemMsaFactory.Create(); + believeV.MorphoSyntaxAnalysesOC.Add(believeVMsa); + ILexSense believeVSense = m_senseFactory.Create(); + believeV.SensesOS.Add(believeVSense); + believeVSense.MorphoSyntaxAnalysisRA = believeVMsa; + + ILexEntry brubV = m_entryFactory.Create(); + IMoStemAllomorph brubVForm = m_stemAlloFactory.Create(); + brubV.AlternateFormsOS.Add(brubVForm); + brubVForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("brubVTEST", m_vernacularWS.Handle); + ILexEntryRef lexEntryref = m_lexEntryRefFactory.Create(); + brubV.EntryRefsOS.Add(lexEntryref); + lexEntryref.ComponentLexemesRS.Add(believeV); + lexEntryref.VariantEntryTypesRS.Add(presentTenseLexEntryInflType); + + ILexEntry nullPresent = m_entryFactory.Create(); + IMoAffixAllomorph nullPresentForm = m_afxAlloFactory.Create(); + nullPresent.AlternateFormsOS.Add(nullPresentForm); + nullPresentForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("nullPRESENTTEST", m_vernacularWS.Handle); + IMoInflAffMsa nullPresentMsa = m_inflAffMsaFactory.Create(); + nullPresent.MorphoSyntaxAnalysesOC.Add(nullPresentMsa); + + ILexEntry sPlural = m_entryFactory.Create(); + IMoAffixAllomorph sPluralForm = m_afxAlloFactory.Create(); + sPlural.AlternateFormsOS.Add(sPluralForm); + sPluralForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("sPLURALTEST", m_vernacularWS.Handle); + IMoInflAffMsa sPluralMsa = m_inflAffMsaFactory.Create(); + sPlural.MorphoSyntaxAnalysesOC.Add(sPluralMsa); + + result = new ParseResult(new[] + { + new ParseAnalysis(new[] + { + new ParseMorph(brubVForm, MorphServices.GetMainOrFirstSenseOfVariant(brubV.EntryRefsOS[0]).MorphoSyntaxAnalysisRA, + (ILexEntryInflType) brubV.EntryRefsOS[0].VariantEntryTypesRS[0]), + new ParseMorph(sPluralForm, sPluralMsa) + }) + }); + }); + + m_filer.ProcessParse(brubs, ParserPriority.Low, result); + ExecuteIdleQueue(); + CheckAnalysisSize("brubsTEST", 1, false); + var analysis = brubs.AnalysesOC.ElementAt(0); + Assert.AreEqual(2, analysis.MorphBundlesOS.Count, "Expected only 2 morphs in the analysis"); + var morphBundle = analysis.MorphBundlesOS.ElementAt(0); + Assert.IsNotNull(morphBundle.Form, "First bundle: form is not null"); + Assert.IsNotNull(morphBundle.MsaRA, "First bundle: msa is not null"); + Assert.IsNotNull(morphBundle.InflTypeRA, "First bundle: infl type is not null"); + } + + #endregion // Tests + } +} diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/ParserCoreTests.csproj b/Src/LexText/ParserCore/ParserCoreTests/ParserCoreTests.csproj similarity index 83% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/ParserCoreTests.csproj rename to Src/LexText/ParserCore/ParserCoreTests/ParserCoreTests.csproj index 91ef5d493c..9554d4d3b8 100644 --- a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/ParserCoreTests.csproj +++ b/Src/LexText/ParserCore/ParserCoreTests/ParserCoreTests.csproj @@ -32,7 +32,7 @@ - ..\..\..\..\..\Output\Debug\ + ..\..\..\..\Output\Debug\ false 285212672 false @@ -56,7 +56,7 @@ x86 - ..\..\..\..\..\Output\Release\ + ..\..\..\..\Output\Release\ false 285212672 false @@ -82,47 +82,47 @@ False - ..\..\..\..\..\Output\Debug\BasicUtils.dll + ..\..\..\..\Output\Debug\BasicUtils.dll False - ..\..\..\..\..\Output\Debug\BasicUtilsTests.dll + ..\..\..\..\Output\Debug\BasicUtilsTests.dll False - ..\..\..\..\..\Output\Debug\COMInterfaces.dll + ..\..\..\..\Output\Debug\COMInterfaces.dll False - ..\..\..\..\..\Output\Debug\COMInterfacesTests.dll + ..\..\..\..\Output\Debug\COMInterfacesTests.dll False - ..\..\..\..\..\Output\Debug\CoreImpl.dll + ..\..\..\..\Output\Debug\CoreImpl.dll FDO - ..\..\..\..\..\Output\Debug\FDO.dll + ..\..\..\..\Output\Debug\FDO.dll FDOTests - ..\..\..\..\..\Output\Debug\FDOTests.dll + ..\..\..\..\Output\Debug\FDOTests.dll False - ..\..\..\..\..\Output\Debug\FwUtils.dll + ..\..\..\..\Output\Debug\FwUtils.dll False - ..\..\..\..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll + ..\..\..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll nunit.framework - ..\..\..\..\..\Bin\NUnit\bin\nunit.framework.dll + ..\..\..\..\Bin\NUnit\bin\nunit.framework.dll ParserCore - ..\..\..\..\..\Output\Debug\ParserCore.dll + ..\..\..\..\Output\Debug\ParserCore.dll System @@ -132,21 +132,22 @@ System.XML + False - ..\..\..\..\..\Output\Debug\TestUtils.dll + ..\..\..\..\Output\Debug\TestUtils.dll XMLUtils - ..\..\..\..\..\Output\Debug\XMLUtils.dll + ..\..\..\..\Output\Debug\XMLUtils.dll - - + AssemblyInfoForTests.cs - + + Code diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/UpdateParserDataTests.cs b/Src/LexText/ParserCore/ParserCoreTests/UpdateParserDataTests.cs similarity index 96% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/UpdateParserDataTests.cs rename to Src/LexText/ParserCore/ParserCoreTests/UpdateParserDataTests.cs index 2f32db07df..cff845b504 100644 --- a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/UpdateParserDataTests.cs +++ b/Src/LexText/ParserCore/ParserCoreTests/UpdateParserDataTests.cs @@ -10,18 +10,48 @@ // Implements the UpdateParserDataTests unit tests. // -using System; -using System.Diagnostics; -using System.IO; -using SIL.FieldWorks.Common.COMInterfaces; +using System.Xml.Linq; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.FDOTests; -using System.Xml; using NUnit.Framework; -using SIL.Utils; +using SIL.FieldWorks.FDO.Infrastructure; namespace SIL.FieldWorks.WordWorks.Parser { + [TestFixture] + public class UpdateParserDataTests : MemoryOnlyBackendProviderTestBase + { + private FdoCache m_cache; + private M3ParserModelRetriever m_retriever; + + public override void FixtureSetup() + { + base.FixtureSetup(); + + var projectId = new TestProjectId(FDOBackendProviderType.kMemoryOnly, "Test.fwdata"); + m_cache = FdoCache.CreateCacheWithNewBlankLangProj(projectId, "en", "fr", "en", new DummyFdoUI(), FwDirectoryFinder.FdoDirectories); + NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, + () => m_cache.LangProject.MorphologicalDataOA.ParserParameters = "1515010XAmple"); + m_retriever = new M3ParserModelRetriever(m_cache); + } + + public override void FixtureTeardown() + { + m_retriever.Dispose(); + m_cache.Dispose(); + + base.FixtureTeardown(); + } + + [Test] + public void EmptyLexicon() + { + XDocument model; + Assert.IsTrue(m_retriever.RetrieveModel(out model)); + } + } + #if WANTTESTPORT // Will we even want the updater stuff? Surely, we won't want it to use FXT. [TestFixture] public class UpdateParserDataTests : MemoryOnlyBackendProviderTestBase @@ -31,7 +61,7 @@ public class UpdateParserDataTests : MemoryOnlyBackendProviderTestBase protected SqlConnection m_sqlConnection; private string m_sFxtResultFile; - private string m_sFxtTemplatePath = Path.Combine(DirectoryFinder.FlexFolder, + private string m_sFxtTemplatePath = Path.Combine(FwDirectoryFinder.FlexFolder, Path.Combine("Configuration", Path.Combine("Grammar", "FXTs")))); @@ -88,7 +118,7 @@ private void SetUpDataFiles() Path.Combine("Configuration", Path.Combine("Grammar", "FXTs"))); string sFxtFile = Path.Combine(ksFXTPath, "M3Parser.fxt"); - string sFxtPath = Path.Combine(DirectoryFinder.FWCodeDirectory, sFxtFile); + string sFxtPath = Path.Combine(FwDirectoryFinder.CodeDirectory, sFxtFile); fxtDumper.Go(Cache.LangProject as CmObject, sFxtPath, File.CreateText(m_sFxtResultFile), new IFilterStrategy[] { new ConstraintFilterStrategy() }); } diff --git a/Src/LexText/ParserCore/ParserCoreTests/XAmpleParserTests.cs b/Src/LexText/ParserCore/ParserCoreTests/XAmpleParserTests.cs new file mode 100644 index 0000000000..608662c269 --- /dev/null +++ b/Src/LexText/ParserCore/ParserCoreTests/XAmpleParserTests.cs @@ -0,0 +1,89 @@ +// Copyright (c) 2003-2013 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) +// +// File: XAmpleParserTests.cs +// Responsibility: + +using System.IO; +using System.Linq; +using System.Xml.Linq; +using NUnit.Framework; +using SIL.FieldWorks.Common.FwUtils; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.Test.TestUtils; + +namespace SIL.FieldWorks.WordWorks.Parser +{ + /// + /// Summary description for XAmpleParserTests. + /// + [TestFixture] + public class XAmpleParserTests : BaseTest + { + [Test] + public void ConvertFailures() + { + string testPath = Path.Combine(FwDirectoryFinder.SourceDirectory, "LexText", "ParserCore", "ParserCoreTests", "Failures.xml"); + XDocument doc = XDocument.Load(testPath); + + XElement[] failures = doc.Descendants("failure").ToArray(); + XElement[] anccFailures = failures.Where(e => ((string) e.Attribute("test")).StartsWith("ANCC_FT")).ToArray(); + Assert.That(anccFailures.Length, Is.EqualTo(2), "Two ANCC failures"); + XElement[] mccFailures = failures.Where(e => ((string) e.Attribute("test")).StartsWith("MCC_FT")).ToArray(); + Assert.That(mccFailures.Length, Is.EqualTo(2), "Two MCC failures"); + XElement[] secFailures = failures.Where(e => ((string) e.Attribute("test")).StartsWith("SEC_ST") && ((string) e.Attribute("test")).Contains("[")).ToArray(); + Assert.That(secFailures.Length, Is.EqualTo(8), "Eight SEC failures with classes"); + XElement[] infixFailures = failures.Where(e => ((string) e.Attribute("test")).StartsWith("InfixEnvironment") && ((string) e.Attribute("test")).Contains("[")).ToArray(); + Assert.That(infixFailures.Length, Is.EqualTo(8), "Eight Infix Environment failures with classes"); + + XAmpleParser.ConvertFailures(doc, (classID, hvo) => + { + string className = null; + switch (classID) + { + case MoFormTags.kClassId: + className = "Form"; + break; + case MoMorphSynAnalysisTags.kClassId: + className = "MSA"; + break; + case PhNaturalClassTags.kClassId: + className = "NC"; + break; + } + return string.Format("{0}-{1}", className, hvo); + }); + + AssertTestEquals(anccFailures[0], "ANCC_FT: Form-6213 -/ _ ... Form-6279"); + AssertTestEquals(anccFailures[1], "ANCC_FT: Form-6213 -/ Form-6279 ... _ "); + + AssertTestEquals(mccFailures[0], "MCC_FT: MSA-6331 +/ ~_ MSA-6139"); + AssertTestEquals(mccFailures[1], "MCC_FT: MSA-6331 +/ MSA-6139 ~_"); + + AssertTestEquals(secFailures[0], "SEC_ST: dok __ ra / _ [NC-7405]"); + AssertTestEquals(secFailures[1], "SEC_ST: dok __ ra / _ [NC-7405][NC-7405]"); + AssertTestEquals(secFailures[2], "SEC_ST: migel __ ximura / [NC-7405] _"); + AssertTestEquals(secFailures[3], "SEC_ST: migel __ ximura / [NC-7405][NC-7405] _"); + AssertTestEquals(secFailures[4], "SEC_ST: migel __ ximura / [NC-7405] _ [NC-7405]"); + AssertTestEquals(secFailures[5], "SEC_ST: migel __ ximura / [NC-7405][NC-7405] _ [NC-7405]"); + AssertTestEquals(secFailures[6], "SEC_ST: migel __ ximura / [NC-7405] _ [NC-7405][NC-7405]"); + AssertTestEquals(secFailures[7], "SEC_ST: migel __ ximura / [NC-7405][NC-7405] _ [NC-7405][NC-7405]"); + + AssertTestEquals(infixFailures[0], "InfixEnvironment: dok __ ra / _ [NC-7405]"); + AssertTestEquals(infixFailures[1], "InfixEnvironment: dok __ ra / _ [NC-7405][NC-7405]"); + AssertTestEquals(infixFailures[2], "InfixEnvironment: migel __ ximura / [NC-7405] _"); + AssertTestEquals(infixFailures[3], "InfixEnvironment: migel __ ximura / [NC-7405][NC-7405] _"); + AssertTestEquals(infixFailures[4], "InfixEnvironment: migel __ ximura / [NC-7405] _ [NC-7405]"); + AssertTestEquals(infixFailures[5], "InfixEnvironment: migel __ ximura / [NC-7405][NC-7405] _ [NC-7405]"); + AssertTestEquals(infixFailures[6], "InfixEnvironment: migel __ ximura / [NC-7405] _ [NC-7405][NC-7405]"); + AssertTestEquals(infixFailures[7], "InfixEnvironment: migel __ ximura / [NC-7405][NC-7405] _ [NC-7405][NC-7405]"); + } + + private void AssertTestEquals(XElement elem, string expected) + { + var test = (string) elem.Attribute("test"); + Assert.That(test, Is.EqualTo(expected)); + } + } +} diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/gendarme-ParserCoreTests.ignore b/Src/LexText/ParserCore/ParserCoreTests/gendarme-ParserCoreTests.ignore similarity index 91% rename from Src/LexText/ParserEngine/ParserCore/ParserCoreTests/gendarme-ParserCoreTests.ignore rename to Src/LexText/ParserCore/ParserCoreTests/gendarme-ParserCoreTests.ignore index 8044598111..ee5a0a4fc6 100644 --- a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/gendarme-ParserCoreTests.ignore +++ b/Src/LexText/ParserCore/ParserCoreTests/gendarme-ParserCoreTests.ignore @@ -11,3 +11,4 @@ R: Gendarme.Rules.Design.TypesWithDisposableFieldsShouldBeDisposableRule # Unit test. Object disposed in tear down method. T: SIL.FieldWorks.WordWorks.Parser.ParseFilerProcessingTests +T: SIL.FieldWorks.WordWorks.Parser.UpdateParserDataTests diff --git a/Src/LexText/ParserCore/ParserHelper.cs b/Src/LexText/ParserCore/ParserHelper.cs new file mode 100644 index 0000000000..cc4204f1d4 --- /dev/null +++ b/Src/LexText/ParserCore/ParserHelper.cs @@ -0,0 +1,136 @@ +// Copyright (c) 2014-2014 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) + +using System; +using System.Diagnostics; +using System.Text; +using System.Xml.Linq; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.FDO.DomainServices; + +namespace SIL.FieldWorks.WordWorks.Parser +{ + internal class ParserHelper + { + public static bool TryCreateParseMorph(FdoCache cache, XElement morphElem, out ParseMorph morph) + { + XElement formElement = morphElem.Element("MoForm"); + Debug.Assert(formElement != null); + var hvoForm = (string)formElement.Attribute("DbRef"); + + XElement msiElement = morphElem.Element("MSI"); + Debug.Assert(msiElement != null); + var msaHvoStr = (string)msiElement.Attribute("DbRef"); + + return TryCreateParseMorph(cache, hvoForm, msaHvoStr, out morph); + } + + /// + /// Creates a single ParseMorph object + /// Handles special cases where the MoForm hvo and/or MSI hvos are + /// not actual MoForm or MSA objects. + /// + /// The FDO cache. + /// The form hvo. + /// The msa hvo. + /// a new ParseMorph object or null if the morpheme should be skipped + /// + public static bool TryCreateParseMorph(FdoCache cache, string formHvo, string msaHvo, out ParseMorph morph) + { + // Normally, the hvo for MoForm is a MoForm and the hvo for MSI is an MSA + // There are four exceptions, though, when an irregularly inflected form is involved: + // 1. ().TryGetObject(int.Parse(formHvo), out objForm)) + { + morph = null; + return false; + } + var form = objForm as IMoForm; + if (form == null) + { + morph = null; + return true; + } + + // Irregulary inflected forms can have a combination MSA hvo: the LexEntry hvo, a period, and an index to the LexEntryRef + Tuple msaTuple = ProcessMsaHvo(msaHvo); + ICmObject objMsa; + if (!cache.ServiceLocator.GetInstance().TryGetObject(msaTuple.Item1, out objMsa)) + { + morph = null; + return false; + } + var msa = objMsa as IMoMorphSynAnalysis; + if (msa != null) + { + morph = new ParseMorph(form, msa); + return true; + } + + var msaAsLexEntry = objMsa as ILexEntry; + if (msaAsLexEntry != null) + { + // is an irregularly inflected form + // get the MoStemMsa of its variant + if (msaAsLexEntry.EntryRefsOS.Count > 0) + { + ILexEntryRef lexEntryRef = msaAsLexEntry.EntryRefsOS[msaTuple.Item1]; + ILexSense sense = MorphServices.GetMainOrFirstSenseOfVariant(lexEntryRef); + var inflType = (ILexEntryInflType)lexEntryRef.VariantEntryTypesRS[0]; + morph = new ParseMorph(form, sense.MorphoSyntaxAnalysisRA, inflType); + return true; + } + } + + // if it is anything else, we ignore it + morph = null; + return true; + } + + public static Tuple ProcessMsaHvo(string msaHvo) + { + string[] msaHvoParts = msaHvo.Split('.'); + return Tuple.Create(int.Parse(msaHvoParts[0]), msaHvoParts.Length == 2 ? int.Parse(msaHvoParts[1]) : 0); + } + + /// + /// Convert any characters in the name which are higher than 0x00FF to hex. + /// Neither XAmple nor PC-PATR can read a file name containing letters above 0x00FF. + /// + /// The original name to be converted + /// Converted name + public static string ConvertNameToUseAnsiCharacters(string originalName) + { + var sb = new StringBuilder(); + char[] letters = originalName.ToCharArray(); + foreach (var letter in letters) + { + int value = Convert.ToInt32(letter); + if (value > 255) + { + string hex = value.ToString("X4"); + sb.Append(hex); + } + else + { + sb.Append(letter); + } + } + return sb.ToString(); + } + } +} diff --git a/Src/LexText/ParserEngine/ParserCore/Scheduler.cs b/Src/LexText/ParserCore/ParserScheduler.cs similarity index 84% rename from Src/LexText/ParserEngine/ParserCore/Scheduler.cs rename to Src/LexText/ParserCore/ParserScheduler.cs index 8f4a2fd28f..e9e3e9311f 100644 --- a/Src/LexText/ParserEngine/ParserCore/Scheduler.cs +++ b/Src/LexText/ParserCore/ParserScheduler.cs @@ -11,9 +11,8 @@ // using System; -using System.Diagnostics; using System.Collections.Generic; -using SIL.Utils; // for Win32 message defns. +using SIL.Utils; using SIL.FieldWorks.FDO; namespace SIL.FieldWorks.WordWorks.Parser @@ -129,41 +128,20 @@ public override void DoWork() public event EventHandler ParserUpdateNormal; private readonly ConsumerThread m_thread; - private readonly ParserWorker m_parserWorker; - private readonly FdoCache m_cache; + private ParserWorker m_parserWorker; private readonly object m_syncRoot = new object(); private readonly int[] m_queueCounts = new int[5]; private volatile bool m_tryAWordDialogRunning; private TaskReport m_TaskReport; - private readonly TraceSwitch m_tracingSwitch = new TraceSwitch("ParserCore.TracingSwitch", "Just regular tracking", "Off"); - /// ----------------------------------------------------------------------------------- /// /// Initializes a new instance of the class. /// /// ----------------------------------------------------------------------------------- - public ParserScheduler(FdoCache cache, IdleQueue idleQueue) + public ParserScheduler(FdoCache cache, IdleQueue idleQueue, string dataDir) { - if (cache == null) throw new ArgumentNullException("cache"); - - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "ParserScheduler(): CurrentThreadId = " + Win32.GetCurrentThreadId()); - - m_cache = cache; - - switch (m_cache.LanguageProject.MorphologicalDataOA.ActiveParser) - { - - case "XAmple": - m_parserWorker = new XAmpleParserWorker(cache, HandleTaskUpdate, idleQueue); - break; - case "HC": - m_parserWorker = new HCParserWorker(cache, HandleTaskUpdate, idleQueue); - break; - - default: - throw new InvalidOperationException("The language project is set to use an unrecognized parser."); - } + m_parserWorker = new ParserWorker(cache, HandleTaskUpdate, idleQueue, dataDir); m_parserWorker.ParseFiler.WordformUpdated += ParseFiler_WordformUpdated; m_thread = new ConsumerThread(Work) {IsBackground = true}; @@ -218,14 +196,14 @@ public bool TryAWordDialogIsRunning protected override void DisposeManagedResources() { - if (m_thread.Stop()) - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "==== ParserScheduler thread Successfully shutdown."); - else - Trace.WriteLineIf(m_tracingSwitch.TraceError, "**** ERROR : ParserScheduler Thread didn't shutdown."); m_thread.Dispose(); - m_parserWorker.ParseFiler.WordformUpdated -= ParseFiler_WordformUpdated; - m_parserWorker.Dispose(); + if (m_parserWorker != null) + { + m_parserWorker.ParseFiler.WordformUpdated -= ParseFiler_WordformUpdated; + m_parserWorker.Dispose(); + m_parserWorker = null; + } if (m_TaskReport != null) { @@ -322,8 +300,6 @@ private void HandleTaskUpdate(TaskReport task) { CheckDisposed(); - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "Scheduler.HandleTaskUpdate() " + task.Description + " " + task.PhaseDescription); - if (ParserUpdateNormal != null && ((task.Depth == 0) || (task.NotificationMessage != null))) { //notify any delegates @@ -335,9 +311,6 @@ private void HandleTaskUpdate(TaskReport task) //notify any delegates ParserUpdateVerbose(this, new ParserUpdateEventArgs(task.MostRecentTask)/*not sure this is right*/); } - - - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, " Exiting HandleTaskUpdate()" + task.Description); } private void ParseFiler_WordformUpdated(object sender, WordformUpdatedEventArgs e) diff --git a/Src/LexText/ParserCore/ParserWorker.cs b/Src/LexText/ParserCore/ParserWorker.cs new file mode 100644 index 0000000000..bdf0ad76cf --- /dev/null +++ b/Src/LexText/ParserCore/ParserWorker.cs @@ -0,0 +1,162 @@ +// Copyright (c) 2003-2014 SIL International +// This software is licensed under the LGPL, version 2.1 or later +// (http://www.gnu.org/licenses/lgpl-2.1.html) +// +// File: ParserWorker.cs +// Responsibility: +// +// +// The name here, "worker" would lead one to think that this is the +// class which is the top of the heap of the worker thread. +// However, it is actually the "Scheduler" class which controls the thread and calls this. +// +/* + +throws exception: * One way I recall is that they would create an inflectional template, but not put anything in it yet (i.e. no slots at all). + * This causes XAmple to die because it produces a PC-PATR load error. + * This could be fixed, of course, in the XSLT that generates the grammar file. + * This one's on my TODO list (I've got the sticky note from Dallas)... + + +no exception: Try an adhoc prohibition with only one item in it + +no exception: Create a compound with neither member specified or only one specified. + +no exception: Create an allomorph with an environment that is ill-formed. (Presumably this will result in the same problem as breaking an environment for an existing allomorph.) + +no exception: Create an infl affix slot with no affixes in it and then use this slot in a template (though this just might not cause the parser to fail - it would just be useless!). + +*/ + +using System; +using SIL.Utils; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.FDO.Infrastructure; +using SIL.FieldWorks.Common.COMInterfaces; + +namespace SIL.FieldWorks.WordWorks.Parser +{ + /// + /// Summary description for ParserWorker. + /// + public class ParserWorker : FwDisposableBase + { + private readonly FdoCache m_cache; + private readonly Action m_taskUpdateHandler; + private readonly ParseFiler m_parseFiler; + private int m_numberOfWordForms; + private IParser m_parser; + + /// ----------------------------------------------------------------------------------- + /// + /// Initializes a new instance of the class. + /// + /// ----------------------------------------------------------------------------------- + public ParserWorker(FdoCache cache, Action taskUpdateHandler, IdleQueue idleQueue, string dataDir) + { + m_cache = cache; + m_taskUpdateHandler = taskUpdateHandler; + ICmAgent agent; + switch (m_cache.LanguageProject.MorphologicalDataOA.ActiveParser) + { + case "XAmple": + m_parser = new XAmpleParser(cache, dataDir); + agent = cache.ServiceLocator.GetInstance().GetObject(CmAgentTags.kguidAgentXAmpleParser); + break; + case "HC": + m_parser = new HCParser(cache, dataDir); + agent = cache.ServiceLocator.GetInstance().GetObject(CmAgentTags.kguidAgentHermitCrabParser); + break; + default: + throw new InvalidOperationException("The language project is set to use an unrecognized parser."); + } + m_parseFiler = new ParseFiler(cache, taskUpdateHandler, idleQueue, agent); + } + + protected override void DisposeManagedResources() + { + if (m_parser != null) + { + m_parser.Dispose(); + m_parser = null; + } + } + + public ParseFiler ParseFiler + { + get + { + CheckDisposed(); + return m_parseFiler; + } + } + + /// + /// Try parsing a wordform, optionally getting a trace of the parse + /// + /// the word form to parse + /// whether or not to trace the parse + /// list of msa hvos to limit trace to + public void TryAWord(string sForm, bool fDoTrace, string sSelectTraceMorphs) + { + CheckDisposed(); + + if (sForm == null) + throw new ArgumentNullException("sForm", "TryAWord cannot trace a Null string."); + if (sForm == String.Empty) + throw new ArgumentException("Can't try a word with no content.", "sForm"); + + CheckNeedsUpdate(); + using (var task = new TaskReport(string.Format(ParserCoreStrings.ksTraceWordformX, sForm), m_taskUpdateHandler)) + { + string normForm = Icu.Normalize(sForm, Icu.UNormalizationMode.UNORM_NFD); + task.Details = fDoTrace ? m_parser.TraceWordXml(normForm, sSelectTraceMorphs) : m_parser.ParseWordXml(normForm); + } + } + + public bool UpdateWordform(IWfiWordform wordform, ParserPriority priority) + { + CheckDisposed(); + + int wordformHash = 0; + ITsString form = null; + int hvo = 0; + using (new WorkerThreadReadHelper(m_cache.ServiceLocator.GetInstance())) + { + if (wordform.IsValidObject) + { + wordformHash = wordform.Checksum; + form = wordform.Form.VernacularDefaultWritingSystem; + } + } + // 'form' will now be null, if it could not find the wordform for whatever reason. + // uiCRCWordform will also now be 0, if 'form' is null. + if (form == null || string.IsNullOrEmpty(form.Text)) + return false; + + CheckNeedsUpdate(); + ParseResult result = m_parser.ParseWord(Icu.Normalize(form.Text.Replace(' ', '.'), Icu.UNormalizationMode.UNORM_NFD)); + if (wordformHash == result.GetHashCode()) + return false; + + return m_parseFiler.ProcessParse(wordform, priority, result); + } + + private void CheckNeedsUpdate() + { + using (var task = new TaskReport(ParserCoreStrings.ksUpdatingGrammarAndLexicon, m_taskUpdateHandler)) + { + if (!m_parser.IsUpToDate()) + m_parser.Update(); + } + } + + public void ReloadGrammarAndLexicon() + { + CheckDisposed(); + + m_parser.Reset(); + CheckNeedsUpdate(); + } + } +} diff --git a/Src/LexText/ParserCore/ParserXmlWriterExtensions.cs b/Src/LexText/ParserCore/ParserXmlWriterExtensions.cs new file mode 100644 index 0000000000..1ae602d5ad --- /dev/null +++ b/Src/LexText/ParserCore/ParserXmlWriterExtensions.cs @@ -0,0 +1,569 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Xml; +using SIL.CoreImpl; +using SIL.FieldWorks.Common.COMInterfaces; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.FDO.DomainServices; + +namespace SIL.FieldWorks.WordWorks.Parser +{ + internal static class ParserXmlWriterExtensions + { + public static void WriteMsaElement(this XmlWriter writer, FdoCache cache, string formID, string msaID, string type, string wordType) + { + // Irregulary inflected forms can have a combination MSA hvo: the LexEntry hvo, a period, and an index to the LexEntryRef + Tuple msaTuple = ParserHelper.ProcessMsaHvo(msaID); + ICmObject obj = cache.ServiceLocator.GetInstance().GetObject(msaTuple.Item1); + switch (obj.GetType().Name) + { + default: + throw new ApplicationException(String.Format("Invalid MSA type: {0}.", obj.GetType().Name)); + case "MoStemMsa": + WriteStemMsaXmlElement(writer, (IMoStemMsa) obj, Enumerable.Empty()); + break; + case "MoInflAffMsa": + WriteInflectionClasses(writer, cache, int.Parse(formID, CultureInfo.InvariantCulture)); + WriteInflMsaXmlElement(writer, (IMoInflAffMsa) obj, type); + break; + case "MoDerivAffMsa": + WriteDerivMsaXmlElement(writer, (IMoDerivAffMsa) obj); + break; + case "MoUnclassifiedAffixMsa": + WriteUnclassifedMsaXmlElement(writer, (IMoUnclassifiedAffixMsa) obj); + break; + case "LexEntry": + // is an irregularly inflected form + // get the MoStemMsa of its variant + var entry = (ILexEntry) obj; + if (entry.EntryRefsOS.Count > 0) + { + ILexEntryRef lexEntryRef = entry.EntryRefsOS[msaTuple.Item2]; + ILexSense sense = MorphServices.GetMainOrFirstSenseOfVariant(lexEntryRef); + WriteStemMsaXmlElement(writer, (IMoStemMsa) sense.MorphoSyntaxAnalysisRA, entry.VariantEntryRefs); + } + break; + case "LexEntryInflType": + // This is one of the null allomorphs we create when building the + // input for the parser in order to still get the Word Grammar to have something in any + // required slots in affix templates. + WriteInflMsaForLexEntryInflType(writer, wordType, (ILexEntryInflType) obj); + break; + } + } + + /// + /// Determine if a PartOfSpeech requires inflection. + /// If it or any of its parent POSes have a template, it requires inflection. + /// If it is null we default to not requiring inflection. + /// + /// the Part of Speech + /// true if it does, false otherwise + private static bool RequiresInflection(IPartOfSpeech pos) + { + return pos != null && pos.RequiresInflection; + } + + private static void WriteStemMsaXmlElement(XmlWriter writer, IMoStemMsa stemMsa, IEnumerable variantEntryRefs) + { + writer.WriteStartElement("stemMsa"); + WritePosXmlAttribute(writer, stemMsa.PartOfSpeechRA, "cat"); + IMoInflClass inflClass = stemMsa.InflectionClassRA; + if (inflClass == null) + { // use default inflection class of the POS or + // the first ancestor POS that has a non-zero default inflection class + int inflClassHvo = 0; + IPartOfSpeech pos = stemMsa.PartOfSpeechRA; + while (pos != null && inflClassHvo == 0) + { + if (pos.DefaultInflectionClassRA != null) + inflClassHvo = pos.DefaultInflectionClassRA.Hvo; + else + { + int clsid = stemMsa.Services.GetInstance().GetObject(pos.Owner.Hvo).ClassID; + pos = clsid == PartOfSpeechTags.kClassId ? stemMsa.Services.GetInstance().GetObject(pos.Owner.Hvo) : null; + } + } + if (inflClassHvo != 0) + inflClass = stemMsa.Services.GetInstance().GetObject(inflClassHvo); + } + WriteInflectionClassXmlAttribute(writer, inflClass, "inflClass"); + WriteRequiresInflectionXmlAttribute(writer, stemMsa.PartOfSpeechRA); + WriteFeatureStructureNodes(writer, stemMsa.MsFeaturesOA, stemMsa.Hvo); + WriteProductivityRestrictionNodes(writer, stemMsa.ProdRestrictRC, "productivityRestriction"); + WriteFromPosNodes(writer, stemMsa.FromPartsOfSpeechRC, "fromPartsOfSpeech"); + foreach (ILexEntryRef entryRef in variantEntryRefs) + { + foreach (ILexEntryType lexEntryType in entryRef.VariantEntryTypesRS) + { + var inflEntryType = lexEntryType as ILexEntryInflType; + if (inflEntryType != null) + WriteFeatureStructureNodes(writer, inflEntryType.InflFeatsOA, stemMsa.Hvo); + } + } + writer.WriteEndElement(); //stemMsa + } + + private static void WriteInflectionClasses(XmlWriter writer, FdoCache fdoCache, int allomorphHvo) + { + if (allomorphHvo <= 0) + return; + // use IMoForm instead of IMoAffixForm or IMoAffixAllomorph because it could be an IMoStemAllomorph + IMoForm form = fdoCache.ServiceLocator.GetInstance().GetObject(allomorphHvo); + if (form == null) + return; + if (!(form is IMoAffixForm)) + return; + foreach (IMoInflClass ic in ((IMoAffixForm)form).InflectionClassesRC) + { + writer.WriteStartElement("inflectionClass"); + writer.WriteAttributeString("id", ic.Hvo.ToString(CultureInfo.InvariantCulture)); + writer.WriteAttributeString("abbr", ic.Abbreviation.BestAnalysisAlternative.Text); + writer.WriteEndElement(); //inflectionClass + } + } + + private static void WriteInflMsaXmlElement(XmlWriter writer, IMoInflAffMsa inflMsa, string type) + { + writer.WriteStartElement("inflMsa"); + WritePosXmlAttribute(writer, inflMsa.PartOfSpeechRA, "cat"); + // handle any slot + HandleSlotInfoForInflectionalMsa(writer, inflMsa, type); + WriteFeatureStructureNodes(writer, inflMsa.InflFeatsOA, inflMsa.Hvo); + WriteProductivityRestrictionNodes(writer, inflMsa.FromProdRestrictRC, "fromProductivityRestriction"); + writer.WriteEndElement(); //inflMsa + } + + private static void WriteDerivMsaXmlElement(XmlWriter writer, IMoDerivAffMsa derivMsa) + { + writer.WriteStartElement("derivMsa"); + WritePosXmlAttribute(writer, derivMsa.FromPartOfSpeechRA, "fromCat"); + WritePosXmlAttribute(writer, derivMsa.ToPartOfSpeechRA, "toCat"); + WriteInflectionClassXmlAttribute(writer, derivMsa.FromInflectionClassRA, "fromInflClass"); + WriteInflectionClassXmlAttribute(writer, derivMsa.ToInflectionClassRA, "toInflClass"); + WriteRequiresInflectionXmlAttribute(writer, derivMsa.ToPartOfSpeechRA); + WriteFeatureStructureNodes(writer, derivMsa.FromMsFeaturesOA, derivMsa.Hvo, "fromFS"); + WriteFeatureStructureNodes(writer, derivMsa.ToMsFeaturesOA, derivMsa.Hvo, "toFS"); + WriteProductivityRestrictionNodes(writer, derivMsa.FromProdRestrictRC, "fromProductivityRestriction"); + WriteProductivityRestrictionNodes(writer, derivMsa.ToProdRestrictRC, "toProductivityRestriction"); + writer.WriteEndElement(); //derivMsa + } + + private static void WriteUnclassifedMsaXmlElement(XmlWriter writer, IMoUnclassifiedAffixMsa unclassMsa) + { + writer.WriteStartElement("unclassMsa"); + WritePosXmlAttribute(writer, unclassMsa.PartOfSpeechRA, "fromCat"); + writer.WriteEndElement(); //unclassMsa + } + + private static void WriteInflMsaForLexEntryInflType(XmlWriter writer, string wordType, ILexEntryInflType lexEntryInflType) + { + IMoInflAffixSlot slot; + if (wordType != null) + { + slot = lexEntryInflType.Services.GetInstance().GetObject(Convert.ToInt32(wordType)); + } + else + { + var slots = lexEntryInflType.SlotsRC; + IMoInflAffixSlot firstSlot = slots.FirstOrDefault(); + slot = firstSlot; + } + + if (slot != null) + { + writer.WriteStartElement("inflMsa"); + WritePosXmlAttribute(writer, slot.Owner as IPartOfSpeech, "cat"); + writer.WriteAttributeString("slot", slot.Hvo.ToString(CultureInfo.InvariantCulture)); + writer.WriteAttributeString("slotAbbr", slot.Name.BestAnalysisAlternative.Text); + writer.WriteAttributeString("slotOptional", "false"); + WriteFeatureStructureNodes(writer, lexEntryInflType.InflFeatsOA, lexEntryInflType.Hvo); + writer.WriteEndElement(); //inflMsa + } + } + + private static void WriteInflectionClassXmlAttribute(XmlWriter writer, IMoInflClass inflClass, string sInflClass) + { + if (inflClass != null) + { + writer.WriteAttributeString(sInflClass, inflClass.Hvo.ToString(CultureInfo.InvariantCulture)); + writer.WriteAttributeString(sInflClass + "Abbr", inflClass.Hvo > 0 ? inflClass.Abbreviation.BestAnalysisAlternative.Text : ""); + } + else + writer.WriteAttributeString(sInflClass, "0"); + } + + private static void WriteRequiresInflectionXmlAttribute(XmlWriter writer, IPartOfSpeech pos) + { + writer.WriteAttributeString("requiresInfl", RequiresInflection(pos) ? "+" : "-"); + } + + private static void WriteFeatureStructureNodes(XmlWriter writer, IFsFeatStruc fs, int id, string sFsName = "fs") + { + if (fs == null) + return; + writer.WriteStartElement(sFsName); + writer.WriteAttributeString("id", id.ToString(CultureInfo.InvariantCulture)); + foreach (IFsFeatureSpecification spec in fs.FeatureSpecsOC) + { + writer.WriteStartElement("feature"); + writer.WriteElementString("name", spec.FeatureRA.Abbreviation.BestAnalysisAlternative.Text); + writer.WriteStartElement("value"); + var cv = spec as IFsClosedValue; + if (cv != null) + writer.WriteString(cv.ValueRA.Abbreviation.BestAnalysisAlternative.Text); + else + { + var complex = spec as IFsComplexValue; + if (complex == null) + continue; // skip this one since we're not dealing with it yet + var nestedFs = complex.ValueOA as IFsFeatStruc; + if (nestedFs != null) + WriteFeatureStructureNodes(writer, nestedFs, 0); + } + writer.WriteEndElement(); //value + writer.WriteEndElement(); //feature + } + writer.WriteEndElement(); //sFsName + } + + private static void WriteProductivityRestrictionNodes(XmlWriter writer, IFdoReferenceCollection prodRests, string sElementName) + { + if (prodRests == null || prodRests.Count < 1) + return; + foreach (ICmPossibility pr in prodRests) + { + writer.WriteStartElement(sElementName); + writer.WriteAttributeString("id", pr.Hvo.ToString(CultureInfo.InvariantCulture)); + writer.WriteElementString("name", pr.Name.BestAnalysisAlternative.Text); + writer.WriteEndElement(); //sElementName + } + } + + private static void WriteFromPosNodes(XmlWriter writer, IFdoReferenceCollection fromPoSes, string sElementName) + { + if (fromPoSes == null || fromPoSes.Count < 1) + return; + foreach (IPartOfSpeech pos in fromPoSes) + { + writer.WriteStartElement(sElementName); + writer.WriteAttributeString("fromCat", pos.Hvo.ToString(CultureInfo.InvariantCulture)); + writer.WriteAttributeString("fromCatAbbr", pos.Abbreviation.BestAnalysisAlternative.Text); + writer.WriteEndElement(); //sElementName + } + } + + private static void HandleSlotInfoForInflectionalMsa(XmlWriter writer, IMoInflAffMsa inflMsa, string type) + { + int slotHvo = 0; + int iCount = inflMsa.SlotsRC.Count; + if (iCount > 0) + { + if (iCount > 1) + { // have a circumfix; assume only two slots and assume that the first is prefix and second is suffix + // TODO: ideally would figure out if the slots are prefix or suffix slots and then align the + // o and 1 indices to the appropriate slot. Will just do this for now (hab 2005.08.04). + if (type != null && type != "sfx") + slotHvo = inflMsa.SlotsRC.ToHvoArray()[0]; + else + slotHvo = inflMsa.SlotsRC.ToHvoArray()[1]; + } + else + slotHvo = inflMsa.SlotsRC.ToHvoArray()[0]; + } + writer.WriteAttributeString("slot", slotHvo.ToString(CultureInfo.InvariantCulture)); + string sSlotOptional = "false"; + string sSlotAbbr = "??"; + if (Convert.ToInt32(slotHvo) > 0) + { + var slot = inflMsa.Services.GetInstance().GetObject(Convert.ToInt32(slotHvo)); + if (slot != null) + { + sSlotAbbr = slot.Name.BestAnalysisAlternative.Text; + if (slot.Optional) + sSlotOptional = "true"; + } + } + writer.WriteAttributeString("slotAbbr", sSlotAbbr); + writer.WriteAttributeString("slotOptional", sSlotOptional); + } + + public static void WriteMorphInfoElements(this XmlWriter writer, FdoCache cache, string formID, string msaID, string wordType, string props) + { + ICmObject obj = cache.ServiceLocator.GetInstance().GetObject(int.Parse(formID, CultureInfo.InvariantCulture)); + var form = obj as IMoForm; + if (form == null) + { + // This is one of the null allomorphs we create when building the + // input for the parser in order to still get the Word Grammar to have something in any + // required slots in affix templates. + var lexEntryInflType = obj as ILexEntryInflType; + if (lexEntryInflType != null) + { + WriteLexEntryInflTypeElement(writer, wordType, lexEntryInflType); + return; + } + } + string shortName; + string alloform; + string gloss; + string citationForm; + if (form != null) + { + shortName = form.LongName; + int iFirstSpace = shortName.IndexOf(" (", StringComparison.Ordinal); + int iLastSpace = shortName.LastIndexOf("):", StringComparison.Ordinal) + 2; + alloform = shortName.Substring(0, iFirstSpace); + Tuple msaTuple = ParserHelper.ProcessMsaHvo(msaID); + ICmObject msaObj = cache.ServiceLocator.GetObject(msaTuple.Item1); + if (msaObj.ClassID == LexEntryTags.kClassId) + { + var entry = msaObj as ILexEntry; + Debug.Assert(entry != null); + if (entry.EntryRefsOS.Count > 0) + { + ILexEntryRef lexEntryRef = entry.EntryRefsOS[msaTuple.Item2]; + ITsIncStrBldr sbGlossPrepend; + ITsIncStrBldr sbGlossAppend; + ILexSense sense = MorphServices.GetMainOrFirstSenseOfVariant(lexEntryRef); + IWritingSystem glossWs = cache.ServiceLocator.WritingSystemManager.Get(cache.DefaultAnalWs); + MorphServices.JoinGlossAffixesOfInflVariantTypes(lexEntryRef.VariantEntryTypesRS, + glossWs, out sbGlossPrepend, out sbGlossAppend); + ITsIncStrBldr sbGloss = sbGlossPrepend; + sbGloss.Append(sense.Gloss.BestAnalysisAlternative.Text); + sbGloss.Append(sbGlossAppend.Text); + gloss = sbGloss.Text; + } + else + { + gloss = ParserCoreStrings.ksUnknownGloss; + } + + } + else + { + var msa = msaObj as IMoMorphSynAnalysis; + gloss = msa != null ? msa.GetGlossOfFirstSense() : shortName.Substring(iFirstSpace, iLastSpace - iFirstSpace).Trim(); + } + citationForm = shortName.Substring(iLastSpace).Trim(); + shortName = String.Format(ParserCoreStrings.ksX_Y_Z, alloform, gloss, citationForm); + } + else + { + alloform = ParserCoreStrings.ksUnknownMorpheme; // in case the user continues... + gloss = ParserCoreStrings.ksUnknownGloss; + citationForm = ParserCoreStrings.ksUnknownCitationForm; + shortName = String.Format(ParserCoreStrings.ksX_Y_Z, alloform, gloss, citationForm); + throw new ApplicationException(shortName); + } + writer.WriteElementString("shortName", shortName); + writer.WriteElementString("alloform", alloform); + switch (form.ClassID) + { + case MoStemAllomorphTags.kClassId: + WriteStemNameElement(writer, form, props); + break; + case MoAffixAllomorphTags.kClassId: + WriteAffixAlloFeatsElement(writer, form, props); + WriteStemNameAffixElement(writer, cache, props); + break; + + } + writer.WriteElementString("gloss", gloss); + writer.WriteElementString("citationForm", citationForm); + } + + private static void WriteLexEntryInflTypeElement(XmlWriter writer, string wordType, ILexEntryInflType lexEntryInflType) + { + writer.WriteStartElement("lexEntryInflType"); + writer.WriteEndElement(); + writer.WriteElementString("alloform", "0"); + string sNullGloss = null; + var sbGloss = new StringBuilder(); + if (string.IsNullOrEmpty(lexEntryInflType.GlossPrepend.BestAnalysisAlternative.Text)) + { + sbGloss.Append(lexEntryInflType.GlossPrepend.BestAnalysisAlternative.Text); + sbGloss.Append("..."); + } + sbGloss.Append(lexEntryInflType.GlossAppend.BestAnalysisAlternative.Text); + writer.WriteElementString("gloss", sbGloss.ToString()); + var sMsg = string.Format(ParserCoreStrings.ksIrregularlyInflectedFormNullAffix, lexEntryInflType.ShortName); + writer.WriteElementString("citationForm", sMsg); + WriteInflMsaForLexEntryInflType(writer, wordType, lexEntryInflType); + } + + private static void WriteStemNameElement(XmlWriter writer, IMoForm form, string props) + { + var sallo = form as IMoStemAllomorph; + Debug.Assert(sallo != null); + IMoStemName sn = sallo.StemNameRA; + if (sn != null) + { + writer.WriteStartElement("stemName"); + writer.WriteAttributeString("id", sn.Hvo.ToString(CultureInfo.InvariantCulture)); + writer.WriteString(sn.Name.BestAnalysisAlternative.Text); + writer.WriteEndElement(); //stemName + } + else + { // There's no overt stem name on this allomorph, but there might be overt stem names + // on other allomorphs in this lexical entry. This allomorph, then, cannot bear any + // of the features of these other stem names. If so, there will be a property named + // NotStemNameddd or NotStemNamedddNotStemNamedddd, etc. + WriteNotStemNameElement(writer, props); + } + } + + private static void WriteStemNameAffixElement(XmlWriter writer, FdoCache cache, string props) + { + if (string.IsNullOrEmpty(props)) + return; + + string[] propsArray = props.Trim().Split(' '); + foreach (string prop in propsArray) + { + int i = prop.IndexOf("StemNameAffix", StringComparison.Ordinal); + if (i > -1) + { + string id = (prop.Substring(i + 13)).Trim(); + IMoStemName sn = cache.ServiceLocator.GetInstance().GetObject(Convert.ToInt32(id)); + if (sn != null) + { + writer.WriteStartElement("stemNameAffix"); + writer.WriteAttributeString("id", id); + writer.WriteString(sn.Name.BestAnalysisAlternative.Text); + writer.WriteEndElement(); + } + } + } + } + + private static void WriteNotStemNameElement(XmlWriter writer, string propsText) + { + if (propsText != null) + { + int i = propsText.IndexOf("NotStemName", StringComparison.Ordinal); + if (i > -1) + { + string s = propsText.Substring(i); + int iSpace = s.IndexOf(" ", StringComparison.Ordinal); + string sNotStemName = iSpace > -1 ? s.Substring(0, iSpace - 1) : s; + writer.WriteStartElement("stemName"); + writer.WriteAttributeString("id", sNotStemName); + writer.WriteEndElement(); //stemName + } + } + } + + private static void WriteAffixAlloFeatsElement(XmlWriter writer, IMoForm form, string propsText) + { + var sallo = form as IMoAffixAllomorph; + if (sallo == null) + return; // the form could be an IMoAffixProcess in which case there are no MsEnvFeatures. + IFsFeatStruc fsFeatStruc = sallo.MsEnvFeaturesOA; + if (fsFeatStruc != null && !fsFeatStruc.IsEmpty) + { + writer.WriteStartElement("affixAlloFeats"); + WriteFeatureStructureNodes(writer, fsFeatStruc, fsFeatStruc.Hvo); + writer.WriteEndElement(); //affixAlloFeats + } + else + { // There's no overt stem name on this allomorph, but there might be overt stem names + // on other allomorphs in this lexical entry. This allomorph, then, cannot bear any + // of the features of these other stem names. If so, there will be a property named + // NotStemNameddd or NotStemNamedddNotStemNamedddd, etc. + WriteNotAffixAlloFeatsElement(writer, form.Cache, propsText); + } + } + + private static void WriteNotAffixAlloFeatsElement(XmlWriter writer, FdoCache cache, string propsText) + { + if (propsText != null) + { + int i = propsText.IndexOf("MSEnvFSNot", StringComparison.Ordinal); + if (i > -1) + { + writer.WriteStartElement("affixAlloFeats"); + writer.WriteStartElement("not"); + string s = propsText.Substring(i); + int j = s.IndexOf(' '); + if (j > 0) + s = propsText.Substring(i, j + 1); + int iNot = s.IndexOf("Not", StringComparison.Ordinal) + 3; + while (iNot > 3) + { + int iNextNot = s.IndexOf("Not", iNot, StringComparison.Ordinal); + string sFsHvo; + if (iNextNot > -1) + { + // there are more + sFsHvo = s.Substring(iNot, iNextNot - iNot); + WriteFeatureStructureFromHvoString(writer, cache, sFsHvo); + iNot = iNextNot + 3; + } + else + { + // is the last one + sFsHvo = s.Substring(iNot); + WriteFeatureStructureFromHvoString(writer, cache, sFsHvo); + iNot = 0; + } + } + writer.WriteEndElement(); //not + writer.WriteEndElement(); //affixAlloFeats + } + } + } + + private static void WriteFeatureStructureFromHvoString(XmlWriter writer, FdoCache cache, string sFsHvo) + { + int fsHvo = int.Parse(sFsHvo, CultureInfo.InvariantCulture); + var fsFeatStruc = (IFsFeatStruc) cache.ServiceLocator.GetInstance().GetObject(fsHvo); + if (fsFeatStruc != null) + WriteFeatureStructureNodes(writer, fsFeatStruc, fsHvo); + } + + private static void WritePosXmlAttribute(XmlWriter writer, IPartOfSpeech pos, string sCat) + { + if (pos != null) + { + writer.WriteAttributeString(sCat, pos.Hvo.ToString(CultureInfo.InvariantCulture)); + string sPosAbbr = pos.Hvo > 0 ? pos.Abbreviation.BestAnalysisAlternative.Text : "??"; + writer.WriteAttributeString(sCat + "Abbr", sPosAbbr); + } + else + writer.WriteAttributeString(sCat, "0"); + } + + public static void WriteInflClassesElement(this XmlWriter writer, FdoCache cache, string formID) + { + int hvo = int.Parse(formID, CultureInfo.InvariantCulture); + ICmObject obj = cache.ServiceLocator.GetInstance().GetObject(hvo); + var form = obj as IMoAffixForm; // only for affix forms + if (form != null) + { + if (form.InflectionClassesRC.Count > 0) + { + writer.WriteStartElement("inflClasses"); + WriteInflectionClassesAndSubclassesXmlElement(writer, form.InflectionClassesRC); + writer.WriteEndElement(); + } + } + } + + private static void WriteInflectionClassesAndSubclassesXmlElement(XmlWriter writer, IEnumerable inflectionClasses) + { + foreach (IMoInflClass ic in inflectionClasses) + { + writer.WriteStartElement("inflClass"); + writer.WriteAttributeString("hvo", ic.Hvo.ToString(CultureInfo.InvariantCulture)); + writer.WriteAttributeString("abbr", ic.Abbreviation.BestAnalysisAlternative.Text); + writer.WriteEndElement(); + WriteInflectionClassesAndSubclassesXmlElement(writer, ic.SubclassesOC); + } + } + } +} diff --git a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/BuildInclude.targets b/Src/LexText/ParserCore/PatrParserWrapper/BuildInclude.targets similarity index 94% rename from Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/BuildInclude.targets rename to Src/LexText/ParserCore/PatrParserWrapper/BuildInclude.targets index 613ca38b95..0b2e62114e 100644 --- a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/BuildInclude.targets +++ b/Src/LexText/ParserCore/PatrParserWrapper/BuildInclude.targets @@ -1,7 +1,7 @@ - ../../../../.. + ../../../.. diff --git a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/IPatrParser.cs b/Src/LexText/ParserCore/PatrParserWrapper/IPatrParser.cs similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/IPatrParser.cs rename to Src/LexText/ParserCore/PatrParserWrapper/IPatrParser.cs diff --git a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParser.cs b/Src/LexText/ParserCore/PatrParserWrapper/PatrParser.cs similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParser.cs rename to Src/LexText/ParserCore/PatrParserWrapper/PatrParser.cs diff --git a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapper.csproj b/Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapper.csproj similarity index 95% rename from Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapper.csproj rename to Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapper.csproj index e81b9f095d..bd2d4025b7 100644 --- a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapper.csproj +++ b/Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapper.csproj @@ -37,7 +37,7 @@ true full false - ..\..\..\..\..\Output\Debug\ + ..\..\..\..\Output\Debug\ DEBUG;TRACE prompt 4 @@ -49,7 +49,7 @@ pdbonly true - ..\..\..\..\..\Output\Release\ + ..\..\..\..\Output\Release\ TRACE prompt 4 @@ -67,7 +67,7 @@ - + CommonAssemblyInfo.cs diff --git a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapper.dll.config b/Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapper.dll.config similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapper.dll.config rename to Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapper.dll.config diff --git a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapperTests/Ephtst.ana b/Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapperTests/Ephtst.ana similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapperTests/Ephtst.ana rename to Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapperTests/Ephtst.ana diff --git a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapperTests/MyLex.txt b/Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapperTests/MyLex.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapperTests/MyLex.txt rename to Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapperTests/MyLex.txt diff --git a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapperTests/PatrParserTests.cs b/Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapperTests/PatrParserTests.cs similarity index 99% rename from Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapperTests/PatrParserTests.cs rename to Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapperTests/PatrParserTests.cs index 990fe3dc1a..e38eb29541 100644 --- a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapperTests/PatrParserTests.cs +++ b/Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapperTests/PatrParserTests.cs @@ -11,7 +11,7 @@ namespace PatrParserWrapperTest public class PatrParserInteropTests { protected const string LocationToSrcDirFromOutputDebug = - "../../Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapperTests/"; + "../../Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapperTests/"; protected const string GrammarFileName = LocationToSrcDirFromOutputDebug + "StemNameWordGrammar.txt"; diff --git a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapperTests/PatrParserWrapperTests.csproj b/Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapperTests/PatrParserWrapperTests.csproj similarity index 89% rename from Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapperTests/PatrParserWrapperTests.csproj rename to Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapperTests/PatrParserWrapperTests.csproj index cf64d656cc..b23abe6c54 100644 --- a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapperTests/PatrParserWrapperTests.csproj +++ b/Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapperTests/PatrParserWrapperTests.csproj @@ -39,7 +39,7 @@ true full false - ..\..\..\..\..\..\Output\Debug\ + ..\..\..\..\..\Output\Debug\ DEBUG;TRACE prompt 4 @@ -49,7 +49,7 @@ pdbonly true - ..\..\..\..\..\..\Output\Release\ + ..\..\..\..\..\Output\Release\ TRACE prompt 4 @@ -59,29 +59,29 @@ False - ..\..\..\..\..\..\Output\Debug\BasicUtilsTests.dll + ..\..\..\..\..\Output\Debug\BasicUtilsTests.dll False - ..\..\..\..\..\..\Output\Debug\COMInterfacesTests.dll + ..\..\..\..\..\Output\Debug\COMInterfacesTests.dll False - ..\..\..\..\..\..\Bin\NUnit\bin\nunit.framework.dll + ..\..\..\..\..\Bin\NUnit\bin\nunit.framework.dll False - ..\..\..\..\..\..\Output\Debug\Patr100Interop.dll + ..\..\..\..\..\Output\Debug\Patr100Interop.dll PatrParserWrapper - ..\..\..\..\..\..\Output\Debug\PatrParserWrapper.dll + ..\..\..\..\..\Output\Debug\PatrParserWrapper.dll - + AssemblyInfoForTests.cs diff --git a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapperTests/StemNameWordGrammar.txt b/Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapperTests/StemNameWordGrammar.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapperTests/StemNameWordGrammar.txt rename to Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapperTests/StemNameWordGrammar.txt diff --git a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapperTests/bears.ana b/Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapperTests/bears.ana similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapperTests/bears.ana rename to Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapperTests/bears.ana diff --git a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapperTests/gendarme-PatrParserWrapperTests.ignore b/Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapperTests/gendarme-PatrParserWrapperTests.ignore similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/PatrParserWrapperTests/gendarme-PatrParserWrapperTests.ignore rename to Src/LexText/ParserCore/PatrParserWrapper/PatrParserWrapperTests/gendarme-PatrParserWrapperTests.ignore diff --git a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/Properties/AssemblyInfo.cs b/Src/LexText/ParserCore/PatrParserWrapper/Properties/AssemblyInfo.cs similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/Properties/AssemblyInfo.cs rename to Src/LexText/ParserCore/PatrParserWrapper/Properties/AssemblyInfo.cs diff --git a/Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/gendarme-PatrParserWrapper.ignore b/Src/LexText/ParserCore/PatrParserWrapper/gendarme-PatrParserWrapper.ignore similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/PatrParserWrapper/gendarme-PatrParserWrapper.ignore rename to Src/LexText/ParserCore/PatrParserWrapper/gendarme-PatrParserWrapper.ignore diff --git a/Src/LexText/ParserEngine/ParserCore/TaskReport.cs b/Src/LexText/ParserCore/TaskReport.cs similarity index 99% rename from Src/LexText/ParserEngine/ParserCore/TaskReport.cs rename to Src/LexText/ParserCore/TaskReport.cs index b2d98c7a3e..122e792dbf 100644 --- a/Src/LexText/ParserEngine/ParserCore/TaskReport.cs +++ b/Src/LexText/ParserCore/TaskReport.cs @@ -12,7 +12,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; - +using System.Xml.Linq; using SIL.Utils; namespace SIL.FieldWorks.WordWorks.Parser @@ -36,7 +36,7 @@ public enum TaskPhase {Started, Working, Finished, ErrorEncountered}; /// /// this was added to hold the results of a trace request /// - private string m_details; + private XDocument m_details; /// ----------------------------------------------------------------------------------- /// @@ -220,7 +220,7 @@ public string Description /// /// this is used to hold the results of a trace request /// - public string Details + public XDocument Details { set { diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/ReadMe.txt b/Src/LexText/ParserCore/XAmpleCOMWrapper/ReadMe.txt similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/ReadMe.txt rename to Src/LexText/ParserCore/XAmpleCOMWrapper/ReadMe.txt diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/Resource.h b/Src/LexText/ParserCore/XAmpleCOMWrapper/Resource.h similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/Resource.h rename to Src/LexText/ParserCore/XAmpleCOMWrapper/Resource.h diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.cpp b/Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.cpp similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.cpp rename to Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.cpp diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.rc b/Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.rc similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.rc rename to Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.rc diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.rgs b/Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.rgs similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.rgs rename to Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.rgs diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.vcxproj b/Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.vcxproj similarity index 92% rename from Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.vcxproj rename to Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.vcxproj index 72585850c2..d8ea98386a 100644 --- a/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.vcxproj +++ b/Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.vcxproj @@ -53,15 +53,15 @@ <_ProjectFileVersion>10.0.30319.1 - ..\..\..\..\..\Lib\$(Configuration)\ + ..\..\..\..\Lib\$(Configuration)\ Debug\Obj\ true true - ..\..\..\..\..\Lib\$(Configuration)\ + ..\..\..\..\Lib\$(Configuration)\ Release\Obj\ true false - ..\..\..\..\..\Lib\$(Configuration)\ + ..\..\..\..\Lib\$(Configuration)\ Bounds\ true true @@ -81,7 +81,7 @@ Disabled - ..\..\..\..\..\Include;%(AdditionalIncludeDirectories) + ..\..\..\..\Include;%(AdditionalIncludeDirectories) WIN32;_WINDOWS;_DEBUG;_USRDLL;_ATL_ATTRIBUTES;%(PreprocessorDefinitions) true EnableFastChecks @@ -99,7 +99,7 @@ icudt.lib;icuind.lib;icuucd.lib;%(AdditionalDependencies) $(OutDir)XAmpleCOMWrapper.dll - ..\..\..\..\..\Lib;..\..\..\..\..\Lib\$(Configuration);%(AdditionalLibraryDirectories) + ..\..\..\..\Lib;..\..\..\..\Lib\$(Configuration);%(AdditionalLibraryDirectories) _XAmpleCOMWrapper.idl true Windows @@ -122,7 +122,7 @@ OnlyExplicitInline - ..\..\..\..\..\Include;%(AdditionalIncludeDirectories) + ..\..\..\..\Include;%(AdditionalIncludeDirectories) WIN32;_WINDOWS;NDEBUG;_USRDLL;_ATL_ATTRIBUTES;%(PreprocessorDefinitions) true MultiThreadedDLL @@ -139,7 +139,7 @@ icudt.lib;icuin.lib;icuuc.lib;%(AdditionalDependencies) $(OutDir)XAmpleCOMWrapper.dll - ..\..\..\..\..\Lib;..\..\..\..\..\Lib\$(Configuration);%(AdditionalLibraryDirectories) + ..\..\..\..\Lib;..\..\..\..\Lib\$(Configuration);%(AdditionalLibraryDirectories) _XAmpleCOMWrapper.idl true Windows @@ -174,7 +174,7 @@ Disabled - ..\..\..\..\..\Include;%(AdditionalIncludeDirectories) + ..\..\..\..\Include;%(AdditionalIncludeDirectories) WIN32;_WINDOWS;_DEBUG;_USRDLL;_ATL_ATTRIBUTES;%(PreprocessorDefinitions) true EnableFastChecks @@ -191,7 +191,7 @@ icudt.lib;icuind.lib;icuucd.lib;%(AdditionalDependencies) $(OutDir)XAmpleCOMWrapper.dll - ..\..\..\..\..\Lib;..\..\..\..\..\Lib\$(Configuration);%(AdditionalLibraryDirectories) + ..\..\..\..\Lib;..\..\..\..\Lib\$(Configuration);%(AdditionalLibraryDirectories) _XAmpleCOMWrapper.idl true Windows diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.vcxproj.filters b/Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.vcxproj.filters similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.vcxproj.filters rename to Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.vcxproj.filters diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapperps.def b/Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapperps.def similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapperps.def rename to Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapperps.def diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleWrapper.cpp b/Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleWrapper.cpp similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleWrapper.cpp rename to Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleWrapper.cpp diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleWrapperCore.cpp b/Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleWrapperCore.cpp similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleWrapperCore.cpp rename to Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleWrapperCore.cpp diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleWrapperCore.h b/Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleWrapperCore.h similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleWrapperCore.h rename to Src/LexText/ParserCore/XAmpleCOMWrapper/XAmpleWrapperCore.h diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/stdafx.cpp b/Src/LexText/ParserCore/XAmpleCOMWrapper/stdafx.cpp similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/stdafx.cpp rename to Src/LexText/ParserCore/XAmpleCOMWrapper/stdafx.cpp diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/stdafx.h b/Src/LexText/ParserCore/XAmpleCOMWrapper/stdafx.h similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/stdafx.h rename to Src/LexText/ParserCore/XAmpleCOMWrapper/stdafx.h diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/xamplewrapper.h b/Src/LexText/ParserCore/XAmpleCOMWrapper/xamplewrapper.h similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/xamplewrapper.h rename to Src/LexText/ParserCore/XAmpleCOMWrapper/xamplewrapper.h diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/AmpleOptions.cs b/Src/LexText/ParserCore/XAmpleManagedWrapper/AmpleOptions.cs similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/AmpleOptions.cs rename to Src/LexText/ParserCore/XAmpleManagedWrapper/AmpleOptions.cs diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/AssemblyInfo.cs b/Src/LexText/ParserCore/XAmpleManagedWrapper/AssemblyInfo.cs similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/AssemblyInfo.cs rename to Src/LexText/ParserCore/XAmpleManagedWrapper/AssemblyInfo.cs diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/BuildInclude.targets b/Src/LexText/ParserCore/XAmpleManagedWrapper/BuildInclude.targets similarity index 94% rename from Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/BuildInclude.targets rename to Src/LexText/ParserCore/XAmpleManagedWrapper/BuildInclude.targets index c103de774a..9191714c52 100644 --- a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/BuildInclude.targets +++ b/Src/LexText/ParserCore/XAmpleManagedWrapper/BuildInclude.targets @@ -1,7 +1,7 @@ - ../../../../.. + ../../../.. diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/IXAmpleWrapper.cs b/Src/LexText/ParserCore/XAmpleManagedWrapper/IXAmpleWrapper.cs similarity index 90% rename from Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/IXAmpleWrapper.cs rename to Src/LexText/ParserCore/XAmpleManagedWrapper/IXAmpleWrapper.cs index 50e0caa67d..77b0df1fa0 100644 --- a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/IXAmpleWrapper.cs +++ b/Src/LexText/ParserCore/XAmpleManagedWrapper/IXAmpleWrapper.cs @@ -4,7 +4,7 @@ namespace XAmpleManagedWrapper { public interface IXAmpleWrapper { - void Init(string folderContainingXampleDll); + void Init(); // returns xmlResult string ParseWord(string wordform); diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleDLLWrapper.cs b/Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleDLLWrapper.cs similarity index 97% rename from Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleDLLWrapper.cs rename to Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleDLLWrapper.cs index 4873e4db8d..da65acf8ad 100644 --- a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleDLLWrapper.cs +++ b/Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleDLLWrapper.cs @@ -308,7 +308,7 @@ protected void AssignDelegates () AmpleRemoveSelectiveAnalysisMorphsDelegate = AmpleRemoveSelectiveAnalysisMorphMarshaled; } - public void Init (string lpszFolderContainingXAmpleDll) + public void Init () { // TODO: Currently we are using fixed DllImports. AssignDelegates (); @@ -339,15 +339,15 @@ public void LoadFiles (string lspzFixedFilesDir, string lspzDynamicFilesDir, str // ortho string sResult = m_ampleLoadControlFiles (m_setup, lpszAdCtl, lpszCdTable, null, null); // INTX - ThrowIfError (sResult); + ThrowIfError (sResult, lpszAdCtl, lpszCdTable); //LOAD ROOT DICTIONARIES sResult = m_ampleLoadDictionary (m_setup, lpszDict, "u"); - ThrowIfError (sResult); + ThrowIfError (sResult, lpszDict); //LOAD GRAMMAR FILE sResult = m_ampleLoadGrammarFile (m_setup, lpszGram); - ThrowIfError (sResult); + ThrowIfError (sResult, lpszGram); } public void SetParameter (string lspzName, string lspzValue) @@ -400,7 +400,7 @@ protected void CheckLogForErrors () throw new NotImplementedException (); } - protected void ThrowIfError (string result) + protected void ThrowIfError (string result, params string[] filenames) { // REVIEW JohnH(RandyR): // Isn't the none in the XML supposed to have quote marks around it @@ -414,12 +414,13 @@ protected void ThrowIfError (string result) string t = Path.GetTempFileName (); using (var stream = new StreamWriter(t)) { - stream.Write (result); - stream.Close (); - throw new ApplicationException (result); + stream.Write (result); + stream.Close (); + string message = filenames.Length == 0 ? result : string.Format("{0}; Files: {1}", result, string.Join(",", filenames)); + throw new ApplicationException (message); + } } } - } protected void CheckPtr (IntPtr p) { diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapper.csproj b/Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapper.csproj similarity index 95% rename from Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapper.csproj rename to Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapper.csproj index fe59ec6175..6a5cbb8e8a 100644 --- a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapper.csproj +++ b/Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapper.csproj @@ -36,7 +36,7 @@ full false 168,169,219,414,649,1635,1702,1701 - ..\..\..\..\..\Output\Debug + ..\..\..\..\Output\Debug DEBUG prompt 4 @@ -48,7 +48,7 @@ none false 168,169,219,414,649,1635,1702,1701 - ..\..\..\..\..\Output\Release + ..\..\..\..\Output\Release prompt 4 false @@ -59,7 +59,7 @@ - + CommonAssemblyInfo.cs diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/TestXAmpleDLLWrapper.cs b/Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/TestXAmpleDLLWrapper.cs similarity index 91% rename from Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/TestXAmpleDLLWrapper.cs rename to Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/TestXAmpleDLLWrapper.cs index 3ddcdee166..0f3031c09f 100644 --- a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/TestXAmpleDLLWrapper.cs +++ b/Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/TestXAmpleDLLWrapper.cs @@ -11,13 +11,13 @@ public class TestXAmpleDLLWrapper protected XAmpleDLLWrapper CreateXAmpleDllWrapper() { var xAmple = new XAmpleDLLWrapper(); - xAmple.Init(""); // assume libample.so/XAMPLE.DLL is in the same directory. + xAmple.Init(); return xAmple; } protected void LoadFilesHelper(XAmpleDLLWrapper wrapper) { - string tempPath = "../../Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles"; + string tempPath = "../../Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles"; // TODO: use DirectoryFinder.FWCodeDirectory string xPath = "../../DistFiles/" + "/Language Explorer/Configuration/Grammar"; wrapper.LoadFiles(xPath, tempPath, "StemName3"); diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/TestXAmpleWrapper.cs b/Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/TestXAmpleWrapper.cs similarity index 92% rename from Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/TestXAmpleWrapper.cs rename to Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/TestXAmpleWrapper.cs index 33de1ed829..db35efdc9b 100644 --- a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/TestXAmpleWrapper.cs +++ b/Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/TestXAmpleWrapper.cs @@ -9,13 +9,13 @@ public class TestXAmpleWrapper: SIL.FieldWorks.Test.TestUtils.BaseTest protected XAmpleWrapper InitHelper() { var xAmple = new XAmpleWrapper(); - xAmple.Init(""); + xAmple.Init(); return xAmple; } protected void LoadFilesHelper(XAmpleWrapper wrapper) { - var tempPath = "../../Src/LexText/ParserEngine/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles"; + var tempPath = "../../Src/LexText/ParserCore/ParserCoreTests/M3ToXAmpleTransformerTestsDataFiles"; // TODO: use DirectoryFinder.FWCodeDirectory var xPath = "../../DistFiles/" + "/Language Explorer/Configuration/Grammar"; wrapper.LoadFiles(xPath, tempPath, "StemName3"); diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/XAmpleManagedWrapperTests.csproj b/Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/XAmpleManagedWrapperTests.csproj similarity index 83% rename from Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/XAmpleManagedWrapperTests.csproj rename to Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/XAmpleManagedWrapperTests.csproj index f324842988..2f6f50e913 100644 --- a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/XAmpleManagedWrapperTests.csproj +++ b/Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/XAmpleManagedWrapperTests.csproj @@ -21,7 +21,7 @@ full false 168,169,219,414,649,1635,1702,1701 - ..\..\..\..\..\..\Output\Debug + ..\..\..\..\..\Output\Debug DEBUG prompt 4 @@ -37,7 +37,7 @@ none false 168,169,219,414,649,1635,1702,1701 - ..\..\..\..\..\..\Output\Release + ..\..\..\..\..\Output\Release prompt 4 AllRules.ruleset @@ -46,34 +46,33 @@ False - ..\..\..\..\..\..\Output\Debug\BasicUtilsTests.dll + ..\..\..\..\..\Output\Debug\BasicUtilsTests.dll False - ..\..\..\..\..\..\Output\Debug\COMInterfacesTests.dll + ..\..\..\..\..\Output\Debug\COMInterfacesTests.dll False - ..\..\..\..\..\..\Bin\NUnit\bin\nunit.framework.dll + ..\..\..\..\..\Bin\NUnit\bin\nunit.framework.dll False - ..\..\..\..\..\..\Output\Debug\XAmpleManagedWrapper.dll + ..\..\..\..\..\Output\Debug\XAmpleManagedWrapper.dll TestUtils False - ..\..\..\..\..\..\Output\Debug\TestUtils.dll + ..\..\..\..\..\Output\Debug\TestUtils.dll - + AssemblyInfoForTests.cs - \ No newline at end of file diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleWrapper.cs b/Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleWrapper.cs similarity index 91% rename from Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleWrapper.cs rename to Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleWrapper.cs index 8dd9209cac..07f3f9976d 100644 --- a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleWrapper.cs +++ b/Src/LexText/ParserCore/XAmpleManagedWrapper/XAmpleWrapper.cs @@ -43,10 +43,10 @@ protected virtual void Dispose(bool fDisposing) #endregion #region IXAmpleWrapper implementation - public void Init (string folderContainingXampleDll) + public void Init() { - m_xample = new XAmpleDLLWrapper (); - m_xample.Init (folderContainingXampleDll); + m_xample = new XAmpleDLLWrapper(); + m_xample.Init(); } diff --git a/Src/LexText/ParserCore/XAmpleParser.cs b/Src/LexText/ParserCore/XAmpleParser.cs new file mode 100644 index 0000000000..f8ccad37c8 --- /dev/null +++ b/Src/LexText/ParserCore/XAmpleParser.cs @@ -0,0 +1,315 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Xml; +using System.Xml.Linq; +using SIL.FieldWorks.FDO; +using SIL.FieldWorks.FDO.Infrastructure; +using SIL.Utils; +using XAmpleManagedWrapper; + +namespace SIL.FieldWorks.WordWorks.Parser +{ + public class XAmpleParser : FwDisposableBase, IParser + { + private static readonly char[] Digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + + private XAmpleWrapper m_xample; + private readonly string m_dataDir; + private readonly FdoCache m_cache; + private M3ParserModelRetriever m_retriever; + private readonly M3ToXAmpleTransformer m_transformer; + private readonly string m_database; + + public XAmpleParser(FdoCache cache, string dataDir) + { + m_cache = cache; + m_xample = new XAmpleWrapper(); + m_xample.Init(); + m_dataDir = dataDir; + m_retriever = new M3ParserModelRetriever(m_cache); + m_database = ParserHelper.ConvertNameToUseAnsiCharacters(m_cache.ProjectId.Name); + m_transformer = new M3ToXAmpleTransformer(m_database); + } + + public bool IsUpToDate() + { + return !m_retriever.Updated; + } + + public void Update() + { + CheckDisposed(); + + XDocument model, template; + if (!m_retriever.RetrieveModel(out model, out template)) + return; + + // PrepareTemplatesForXAmpleFiles adds orderclass elements to MoInflAffixSlot elements + m_transformer.PrepareTemplatesForXAmpleFiles(model, template); + + m_transformer.MakeAmpleFiles(model); + + int maxAnalCount = 20; + XElement maxAnalCountElem = model.Elements("M3Dump").Elements("ParserParameters").Elements("XAmple").Elements("MaxAnalysesToReturn").FirstOrDefault(); + if (maxAnalCountElem != null) + { + maxAnalCount = (int) maxAnalCountElem; + if (maxAnalCount < 1) + maxAnalCount = -1; + } + + m_xample.SetParameter("MaxAnalysesToReturn", maxAnalCount.ToString(CultureInfo.InvariantCulture)); + + m_xample.LoadFiles(Path.Combine(m_dataDir, "Configuration", "Grammar"), Path.GetTempPath(), m_database); + } + + public void Reset() + { + CheckDisposed(); + + m_retriever.Reset(); + } + + public ParseResult ParseWord(string word) + { + CheckDisposed(); + + var results = new StringBuilder(m_xample.ParseWord(word)); + results = results.Replace("DB_REF_HERE", "'0'"); + results = results.Replace("<...>", "[...]"); + var wordformElem = XElement.Parse(results.ToString()); + string errorMessage = null; + var exceptionElem = wordformElem.Element("Exception"); + if (exceptionElem != null) + { + var totalAnalysesValue = (string) exceptionElem.Attribute("totalAnalyses"); + switch ((string) exceptionElem.Attribute("code")) + { + case "ReachedMaxAnalyses": + errorMessage = String.Format(ParserCoreStrings.ksReachedMaxAnalysesAllowed, + totalAnalysesValue); + break; + case "ReachedMaxBufferSize": + errorMessage = String.Format(ParserCoreStrings.ksReachedMaxInternalBufferSize, + totalAnalysesValue); + break; + } + } + else + { + errorMessage = (string) wordformElem.Element("Error"); + } + + ParseResult result; + using (new WorkerThreadReadHelper(m_cache.ServiceLocator.GetInstance())) + { + var analyses = new List(); + foreach (XElement analysisElem in wordformElem.Descendants("WfiAnalysis")) + { + var morphs = new List(); + bool skip = false; + foreach (XElement morphElem in analysisElem.Descendants("Morph")) + { + ParseMorph morph; + if (!ParserHelper.TryCreateParseMorph(m_cache, morphElem, out morph)) + { + skip = true; + break; + } + if (morph != null) + morphs.Add(morph); + } + + if (!skip && morphs.Count > 0) + analyses.Add(new ParseAnalysis(morphs)); + } + result = new ParseResult(analyses, errorMessage); + } + + return result; + } + + public XDocument ParseWordXml(string word) + { + CheckDisposed(); + + var sb = new StringBuilder(m_xample.ParseWord(word)); + sb.Replace("DB_REF_HERE", "'0'"); + sb.Replace("<...>", "[...]"); + while (sb[sb.Length - 1] == '\x0') + sb.Remove(sb.Length - 1, 1); + + XDocument doc = XDocument.Parse(sb.ToString()); + using (new WorkerThreadReadHelper(m_cache.ServiceLocator.GetInstance())) + { + foreach (XElement morphElem in doc.Descendants("Morph")) + { + var type = (string) morphElem.Attribute("type"); + var props = (string) morphElem.Element("props"); + + XElement formElem = morphElem.Element("MoForm"); + Debug.Assert(formElem != null); + var formID = (string) formElem.Attribute("DbRef"); + var wordType = (string) formElem.Attribute("wordType"); + + XElement msaElem = morphElem.Element("MSI"); + Debug.Assert(msaElem != null); + var msaID = (string) msaElem.Attribute("DbRef"); + + using (XmlWriter writer = morphElem.CreateWriter()) + writer.WriteMorphInfoElements(m_cache, formID, msaID, wordType, props); + + using (XmlWriter writer = msaElem.CreateWriter()) + writer.WriteMsaElement(m_cache, formID, msaID, type, wordType); + } + } + + return doc; + } + + public XDocument TraceWordXml(string word, string selectTraceMorphs) + { + CheckDisposed(); + + var sb = new StringBuilder(m_xample.TraceWord(word, selectTraceMorphs)); + sb.Remove(0, 47); + sb.Replace("]", "]"); + while (sb[sb.Length - 1] == '\x0') + sb.Remove(sb.Length - 1, 1); + + XDocument doc = XDocument.Parse(sb.ToString()); + using (new WorkerThreadReadHelper(m_cache.ServiceLocator.GetInstance())) + { + foreach (XElement morphElem in doc.Descendants("morph")) + { + var formID = (string) morphElem.Attribute("alloid"); + var msaID = (string) morphElem.Attribute("morphname"); + var type = (string) morphElem.Attribute("type"); + var props = (string) morphElem.Element("props"); + var wordType = (string) morphElem.Attribute("wordType"); + + using (XmlWriter writer = morphElem.CreateWriter()) + { + writer.WriteMorphInfoElements(m_cache, formID, msaID, wordType, props); + writer.WriteMsaElement(m_cache, formID, msaID, type, wordType); + writer.WriteInflClassesElement(m_cache, formID); + } + } + ConvertFailures(doc, GetStrRep); + } + + return doc; + } + + internal static void ConvertFailures(XDocument doc, Func strRepSelector) + { + int wordGrammarFailureCount = 1; + foreach (XElement failureElem in doc.Descendants("failure")) + { + var test = (string) failureElem.Attribute("test"); + + if ((test.StartsWith("SEC_ST") || test.StartsWith("InfixEnvironment")) && test.Contains("[")) + { + int i = test.IndexOf('/'); + string[] sa = test.Substring(i).Split('[', ']'); // split into hunks using brackets + var sb = new StringBuilder(); + foreach (string str in sa) // for each hunk + { + if (str.IndexOfAny(Digits) >= 0) + { + // assume it is an hvo + sb.Append("["); + string sHvo = str; + int hvo = Convert.ToInt32(sHvo); + sb.Append(strRepSelector(PhNaturalClassTags.kClassId, hvo)); + sb.Append("]"); + } + else + { + sb.Append(str); + } + } + failureElem.SetAttributeValue("test", test.Substring(0, i) + sb); + } + else if ((test.StartsWith("ANCC_FT") || test.StartsWith("MCC_FT")) && !test.Contains("ExcpFeat") && !test.Contains("StemName") + && !test.Contains("IrregInflForm")) + { + int index = test.IndexOf(":", StringComparison.Ordinal); + string testName = test.Substring(0, index); + + int iStartingPos = test.IndexOf("::", StringComparison.Ordinal) + 2; // skip to the double colon portion + string[] sa = test.Substring(iStartingPos).Split(' '); + + var sb = new StringBuilder(); + sb.Append(testName); + sb.Append(":"); + foreach (string str in sa) + { + sb.Append(" "); + if (str.IndexOfAny(Digits) >= 0) + { + int hvo = Convert.ToInt32(str); + sb.Append(strRepSelector(testName == "ANCC_FT" ? MoFormTags.kClassId : MoMorphSynAnalysisTags.kClassId, hvo)); + } + else + { + sb.Append(str); + } + } + failureElem.SetAttributeValue("test", sb.ToString()); + } + else if (test.StartsWith("PC-PATR")) + { + failureElem.Add(new XAttribute("id", wordGrammarFailureCount)); + wordGrammarFailureCount++; + } + } + } + + private string GetStrRep(int classID, int hvo) + { + ICmObject obj = m_cache.ServiceLocator.GetInstance().GetObject(hvo); + switch (classID) + { + case MoFormTags.kClassId: + var form = obj as IMoForm; + if (form != null) + return form.ShortName; + throw new ApplicationException(ParserCoreStrings.ksUnknownAllomorph); + + case MoMorphSynAnalysisTags.kClassId: + var msa = obj as IMoMorphSynAnalysis; + if (msa != null) + return msa.LongName; + throw new ApplicationException(ParserCoreStrings.ksUnknownMorpheme); + + case PhNaturalClassTags.kClassId: + var nc = obj as IPhNCSegments; + if (nc != null) + return nc.Name.BestAnalysisAlternative.Text; + throw new ApplicationException(ParserCoreStrings.ksUnknownNaturalClass); + } + return null; + } + + protected override void DisposeManagedResources() + { + if (m_xample != null) + { + m_xample.Dispose(); + m_xample = null; + } + + if (m_retriever != null) + { + m_retriever.Dispose(); + m_retriever = null; + } + } + } +} diff --git a/Src/LexText/ParserEngine/ParserCore/gendarme-ParserCore.ignore b/Src/LexText/ParserCore/gendarme-ParserCore.ignore similarity index 100% rename from Src/LexText/ParserEngine/ParserCore/gendarme-ParserCore.ignore rename to Src/LexText/ParserCore/gendarme-ParserCore.ignore diff --git a/Src/LexText/ParserEngine/Parser Architecture.vsd b/Src/LexText/ParserEngine/Parser Architecture.vsd deleted file mode 100644 index 0ed72aa9ac..0000000000 Binary files a/Src/LexText/ParserEngine/Parser Architecture.vsd and /dev/null differ diff --git a/Src/LexText/ParserEngine/ParserCore/CrcStream.cs b/Src/LexText/ParserEngine/ParserCore/CrcStream.cs deleted file mode 100644 index 9d92deff72..0000000000 --- a/Src/LexText/ParserEngine/ParserCore/CrcStream.cs +++ /dev/null @@ -1,252 +0,0 @@ -// taken verbatim from http://www.codeproject.com/csharp/crcstream.asp -using System; -using System.IO; -using System.Text; - -using SIL.Utils; - -namespace CodeProject.ReiMiyasaka -{ - /// - /// Encapsulates a to calculate the CRC32 checksum on-the-fly as data passes through. - /// - internal class CrcStream : Stream, IFWDisposable - { - Stream stream; - - internal static uint GetCrc(string sResult) - { - UnicodeEncoding enc = new UnicodeEncoding(); - int iCount = enc.GetByteCount(sResult); - using (CrcStream crc = new CrcStream(iCount)) - { - crc.Write(enc.GetBytes(sResult), 0, iCount); - return crc.WriteCrc; - // Closed in the Dispose of 'crc'. - } - } - - /// - /// Encapsulate a . - /// - /// The stream to calculate the checksum for. - private CrcStream(int iCount) - { - this.stream = new MemoryStream(iCount); - } - - private bool m_isDisposed = false; - - public bool IsDisposed - { - get { return m_isDisposed; } - } - - protected override void Dispose(bool disposing) - { - System.Diagnostics.Debug.WriteLineIf(!disposing, "****************** Missing Dispose() call for " + GetType().Name + ". ******************"); - if (IsDisposed) - return; - - if (disposing) - { - if (stream != null) - stream.Close(); - } - stream = null; - - base.Dispose(disposing); - } - - /// - /// Check to see if the object has been disposed. - /// All public Properties and Methods should call this - /// before doing anything else. - /// - public void CheckDisposed() - { - if (IsDisposed) - throw new ObjectDisposedException(String.Format("'{0}' in use after being disposed.", GetType().Name)); - } - - /// - /// Gets the underlying stream. - /// - internal Stream Stream - { - get - { - CheckDisposed(); - return stream; - } - } - - public override bool CanRead - { - get - { - CheckDisposed(); - return stream.CanRead; - } - } - - public override bool CanSeek - { - get - { - CheckDisposed(); - return stream.CanSeek; - } - } - - public override bool CanWrite - { - get - { - CheckDisposed(); - return stream.CanWrite; - } - } - - public override void Flush() - { - CheckDisposed(); - - stream.Flush(); - } - - public override long Length - { - get - { - CheckDisposed(); - return stream.Length; - } - } - - public override long Position - { - get - { - CheckDisposed(); - - return stream.Position; - } - set - { - CheckDisposed(); - - stream.Position = value; - } - } - - public override long Seek(long offset, SeekOrigin origin) - { - CheckDisposed(); - - return stream.Seek(offset, origin); - } - - public override void SetLength(long value) - { - CheckDisposed(); - - stream.SetLength(value); - } - - public override int Read(byte[] buffer, int offset, int count) - { - CheckDisposed(); - - count = stream.Read(buffer, offset, count); - readCrc = CalculateCrc(readCrc, buffer, offset, count); - return count; - } - - public override void Write(byte[] buffer, int offset, int count) - { - CheckDisposed(); - - stream.Write(buffer, offset, count); - - writeCrc = CalculateCrc(writeCrc, buffer, offset, count); - } - - private uint CalculateCrc(uint crc, byte[] buffer, int offset, int count) - { - unchecked - { - for (int i = offset, end = offset + count; i < end; i++) - crc = (crc >> 8) ^ table[(crc ^ buffer[i]) & 0xFF]; - } - return crc; - } - - static private uint[] table = GenerateTable(); - - static private uint[] GenerateTable() - { - unchecked - { - uint[] table = new uint[256]; - - uint crc; - const uint poly = 0xEDB88320; - for (uint i = 0; i < table.Length; i++) - { - crc = i; - for (int j = 8; j > 0; j--) - { - if ((crc & 1) == 1) - crc = (crc >> 1) ^ poly; - else - crc >>= 1; - } - table[i] = crc; - } - - return table; - } - - } - - private uint readCrc = unchecked(0xFFFFFFFF); - - /// - /// Gets the CRC checksum of the data that was read by the stream thus far. - /// - internal uint ReadCrc - { - get - { - CheckDisposed(); - return unchecked(readCrc ^ 0xFFFFFFFF); - } - } - - private uint writeCrc = unchecked(0xFFFFFFFF); - - /// - /// Gets the CRC checksum of the data that was written to the stream thus far. - /// - internal uint WriteCrc - { - get - { - CheckDisposed(); - return unchecked(writeCrc ^ 0xFFFFFFFF); - } - } - - /// - /// Resets the read and write checksums. - /// - internal void ResetChecksum() - { - CheckDisposed(); - - readCrc = unchecked(0xFFFFFFFF); - writeCrc = unchecked(0xFFFFFFFF); - } - } -} diff --git a/Src/LexText/ParserEngine/ParserCore/HCWorker.cs b/Src/LexText/ParserEngine/ParserCore/HCWorker.cs deleted file mode 100644 index fbd3d16a3f..0000000000 --- a/Src/LexText/ParserEngine/ParserCore/HCWorker.cs +++ /dev/null @@ -1,791 +0,0 @@ -// Copyright (c) 2003-2013 SIL International -// This software is licensed under the LGPL, version 2.1 or later -// (http://www.gnu.org/licenses/lgpl-2.1.html) -// -// File: HCWorker.cs -// Responsibility: FLEx Team - -using System; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Linq; -using System.Windows.Forms; -using System.Xml; -using System.Collections.Generic; -using System.Text; -using System.IO; -using System.Xml.Linq; -using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.FDO; -using SIL.Utils; -using SIL.HermitCrab; -using PatrParserWrapper; -using SIL.FieldWorks.Common.FwUtils; -using SIL.FieldWorks.FDO.Validation; - -namespace SIL.FieldWorks.WordWorks.Parser -{ - public class HCParserWorker : ParserWorker - { - class PcPatrMorph - { - public string formId; - public string form; - public string wordType; - public string msaId; - public string featureDescriptors; - public string gloss; - public int formIndex; - - public string Form - { - get - { return String.IsNullOrEmpty(form) ? "0" : form;} - } - } - - class XmlFwResolver : XmlUrlResolver - { - readonly Uri m_baseUri; - - public XmlFwResolver() - { - m_baseUri = new Uri(DirectoryFinder.FWCodeDirectory + Path.DirectorySeparatorChar); - } - - public override Uri ResolveUri(Uri baseUri, string relativeUri) - { - return base.ResolveUri(m_baseUri, relativeUri); - } - } - - [SuppressMessage("Gendarme.Rules.Design", "TypesWithDisposableFieldsShouldBeDisposableRule", - Justification="m_cache is a reference and disposed in the parent class")] - class WordGrammarTrace - { - private readonly IEnumerable m_morphs; - private bool m_fSuccess; - private readonly string m_id; - private readonly FdoCache m_cache; - - public WordGrammarTrace(string id, IEnumerable morphs, FdoCache cache) - { - m_id = id; - m_morphs = morphs; - m_cache = cache; - } - /// - /// Get/set success status of word grammar attempt - /// - public bool Success - { - set - { - m_fSuccess = value; - } - - } - - /// - /// Report trace information as XML - /// - /// - public void ToXml(XmlWriter writer) - { - writer.WriteStartElement("WordGrammarAttempt"); - writer.WriteStartAttribute("success"); - writer.WriteValue(m_fSuccess ? "true" : "false"); - writer.WriteEndAttribute(); - writer.WriteStartElement("Id"); - writer.WriteValue(m_id); - writer.WriteEndElement(); - - string sType = "pfx"; // try to guess morph type based on word type - foreach (PcPatrMorph morph in m_morphs) - { - writer.WriteStartElement("Morphs"); - string sWordType = morph.wordType; - writer.WriteStartAttribute("wordType"); - writer.WriteValue(sWordType); - writer.WriteEndAttribute(); - writer.WriteStartAttribute("type"); - if (sType == "pfx" && - sWordType == "root") - sType = "root"; - else if (sType == "root" && - sWordType != "root") - sType = "sfx"; - writer.WriteValue(sType); - writer.WriteEndAttribute(); - writer.WriteStartAttribute("alloid"); - writer.WriteValue(morph.formId); - writer.WriteEndAttribute(); - writer.WriteStartAttribute("morphname"); - writer.WriteValue(morph.msaId); - writer.WriteEndAttribute(); - - writer.WriteStartElement("alloform"); - writer.WriteValue(morph.form); - writer.WriteEndElement(); // alloform - //writer.WriteStartElement("Msa"); - //writer.WriteEndElement(); // Msa - int hvoForm = Convert.ToInt32(morph.formId); - var obj = m_cache.ServiceLocator.GetObject(hvoForm); - var stemAllo = obj as IMoStemAllomorph; - if (stemAllo != null) - { - var stemName = stemAllo.StemNameRA; - if (stemName != null) - { - writer.WriteStartElement("stemName"); - writer.WriteStartAttribute("id"); - writer.WriteValue(stemName.Hvo); - writer.WriteEndAttribute(); - writer.WriteValue(stemName.Name.BestAnalysisAlternative.Text); - writer.WriteEndElement(); // stemName - } - } - writer.WriteStartElement("gloss"); - writer.WriteValue(morph.gloss); - writer.WriteEndElement(); // gloss - writer.WriteStartElement("citationForm"); - var form = obj as IMoForm; - if (form != null) - { - var entry = form.Owner as ILexEntry; - if (entry != null) - writer.WriteValue(entry.HeadWord.Text); - } - writer.WriteEndElement(); // citationForm - writer.WriteEndElement(); // Morphs - } - writer.WriteEndElement(); - } - - } - - private static int WordTypeIndex(int expectedindex, int wordTypesCount) - { - int wordTypeIndex = expectedindex; - if (wordTypeIndex + 1 > wordTypesCount) - { - // something is wrong (perhaps a missing suffix slot for a circumfix) - // we'll use the same as last time, hoping for a parse failure - wordTypeIndex = wordTypeIndex - 1; - } - return wordTypeIndex; - } - - [SuppressMessage("Gendarme.Rules.Design", "TypesWithDisposableFieldsShouldBeDisposableRule", - Justification = "m_cache is a reference and disposed in the parent class")] - private class ImpliedDataChecker - { - private readonly FdoCache m_cache; - private List m_mismatches = new List(); - - public ImpliedDataChecker(FdoCache cache) - { - m_cache = cache; - } - - /// - /// Check integrity of phoneme-based natural classes (PhNCSegments) - /// when there are phonological features - /// - public void CheckPhonemeBasedNaturalClasses() - { - var feats = m_cache.LangProject.PhFeatureSystemOA.FeaturesOC; - if (!feats.Any()) - return; // no phonological features so nothing to check - foreach (var natClass in m_cache.LangProject.PhonologicalDataOA.NaturalClassesOS.OfType()) - { - IFsFeatStruc fs = natClass.GetImpliedPhonologicalFeatures(); - IEnumerable predictedPhonemes = natClass.GetPredictedPhonemes(fs).OrderBy(ph => ph.Hvo); - if (!predictedPhonemes.SequenceEqual(natClass.SegmentsRC.OrderBy(ph => ph.Hvo))) - { - var mismatch = new PhonemeBasedNaturalClassMismatch(fs, predictedPhonemes, natClass); - m_mismatches.Add(mismatch); - } - } - } - /// - /// Report information as XML - /// - /// - public void ToXml(XmlWriter writer) - { - if (!m_mismatches.Any()) - return; - writer.WriteStartElement("DataIssues"); - foreach (var mismatch in m_mismatches) - { - writer.WriteStartElement("NatClassPhonemeMismatch"); - writer.WriteStartElement("ClassName"); - writer.WriteString(mismatch.NaturalClass.Name.BestAnalysisAlternative.Text); - writer.WriteEndElement(); - writer.WriteStartElement("ClassAbbeviation"); - writer.WriteString(mismatch.NaturalClass.Abbreviation.BestAnalysisAlternative.Text); - writer.WriteEndElement(); - writer.WriteStartElement("ImpliedPhonologicalFeatures"); - writer.WriteString(mismatch.ImpliedPhonologicalFeatures.LongName); - writer.WriteEndElement(); - writer.WriteStartElement("PredictedPhonemes"); - writer.WriteString(mismatch.ListOfPhonemes(mismatch.PredictedPhonemes)); - writer.WriteEndElement(); - writer.WriteStartElement("ActualPhonemes"); - writer.WriteString(mismatch.ListOfPhonemes(mismatch.NaturalClass.SegmentsRC)); - writer.WriteEndElement(); - writer.WriteEndElement(); - } - writer.WriteEndElement(); - } - - [SuppressMessage("Gendarme.Rules.Design", "TypesWithDisposableFieldsShouldBeDisposableRule", - Justification = "All felds are references and are disposed in the parent class")] - private class PhonemeBasedNaturalClassMismatch - { - private IFsFeatStruc m_impliedPhonologicalFeatures; - private IEnumerable m_predictedPhonemes; - private IPhNCSegments m_natClass; - - public PhonemeBasedNaturalClassMismatch(IFsFeatStruc fs, IEnumerable predictedPhonemes, IPhNCSegments natClass) - { - m_impliedPhonologicalFeatures = fs; - m_predictedPhonemes = predictedPhonemes; - m_natClass = natClass; - } - - public IFsFeatStruc ImpliedPhonologicalFeatures - { - get { return m_impliedPhonologicalFeatures; } - } - - public IEnumerable PredictedPhonemes - { - get { return m_predictedPhonemes; } - } - - public IPhNCSegments NaturalClass - { - get { return m_natClass; } - } - public string ListOfPhonemes(IEnumerable list) - { - var sb = new StringBuilder(); - foreach (var phoneme in list) - { - sb.Append(phoneme.Name.BestVernacularAlternative.Text); - sb.Append(" "); - } - return sb.ToString(); - } - } - } - - class FwXmlTraceManager : XmlTraceManager - { - public override void ReportSuccess(WordSynthesis output) - { - if (TraceSuccess) - { - XElement wsElem = Write("Result", output); - wsElem.Add(new XAttribute("id", ((uint) output.GetHashCode()).ToString(CultureInfo.InvariantCulture))); - ((XElement) output.CurrentTraceObject).Add(new XElement("ReportSuccessTrace", wsElem)); - } - } - - public override void MorphologicalRuleNotUnapplied(MorphologicalRule rule, WordAnalysis input) - { - } - - public override void MorphologicalRuleNotApplied(MorphologicalRule rule, WordSynthesis input) - { - } - - protected override XElement Write(string name, Allomorph allomorph) - { - XElement elem = Write(name, (HCObject) allomorph); - - string formIdsStr = allomorph.GetProperty("FormID"); - string msaId = allomorph.GetProperty("MsaID"); - if (!String.IsNullOrEmpty(formIdsStr) || !String.IsNullOrEmpty(msaId)) - { - var morphElem = new XElement("Morph"); - - if (!String.IsNullOrEmpty(formIdsStr)) - { - string[] formIds = formIdsStr.Split(' '); - string[] wordTypes = allomorph.GetProperty("WordCategory").Split(' '); - for (int i = 0; i < formIds.Length; i++) - { - int wordTypeIndex = WordTypeIndex(i, wordTypes.Count()); - morphElem.Add(new XElement("MoForm", new XAttribute("DbRef", formIds[i]), new XAttribute("wordType", wordTypes[wordTypeIndex]))); - string featDesc = allomorph.GetProperty("FeatureDescriptors"); - morphElem.Add(string.IsNullOrEmpty(featDesc) ? new XElement("props") : new XElement("props", featDesc)); - } - } - - if (!String.IsNullOrEmpty(msaId)) - morphElem.Add(new XElement("MSI", new XAttribute("DbRef", msaId))); - elem.Add(morphElem); - } - - return elem; - } - } - - class FwXmlOutput : XmlOutput - { - readonly bool m_fDotrace; - readonly PatrParser m_patr; - readonly string m_patrlexPath; - readonly FdoCache m_cache; - - public FwXmlOutput(XmlWriter writer, bool fDotrace, PatrParser patr, string patrlexPath, FdoCache cache) - : base(writer, new FwXmlTraceManager()) - { - m_fDotrace = fDotrace; - m_patr = patr; - m_patrlexPath = patrlexPath; - m_cache = cache; - } - - public override void MorphAndLookupWord(Morpher morpher, string word, bool prettyPrint, bool printTraceInputs) - { - MorphAndLookupWord(morpher, word, printTraceInputs, null); - } - - public void MorphAndLookupWord(Morpher morpher, string word, bool printTraceInputs, string[] selectTraceMorphs) - { - try - { - ICollection wordGrammarTraces = null; - if (m_fDotrace) - wordGrammarTraces = new HashSet(); - XmlTraceManager.WriteInputs = printTraceInputs; - TraceManager.TraceAll = m_fDotrace; - ICollection synthesisRecs = morpher.MorphAndLookupWord(word, TraceManager, selectTraceMorphs); - foreach (WordSynthesis ws in synthesisRecs) - { - WordGrammarTrace wordGrammarTrace = null; - List morphs = GetMorphs(ws); - if (wordGrammarTraces != null) - { - wordGrammarTrace = new WordGrammarTrace(((uint) ws.GetHashCode()).ToString(CultureInfo.InvariantCulture), morphs, m_cache); - wordGrammarTraces.Add(wordGrammarTrace); - } - if (morphs.Count == 1) - { - PcPatrMorph morph = morphs[0]; - string formid = morph.formId; - IMoForm form = m_cache.ServiceLocator.GetInstance().GetObject(int.Parse(formid)); - var morphtype = form.MorphTypeRA; - if (morphtype.IsBoundType) - { - if (wordGrammarTrace != null) - { - wordGrammarTrace.Success = false; // this is not really true; what other options are there? - } - continue; - } - } - WritePcPatrLexiconFile(m_patrlexPath, morphs); - m_patr.LoadLexiconFile(m_patrlexPath, 0); - string sentence = BuildPcPatrInputSentence(morphs); - try - { - if (m_patr.ParseString(sentence) != null) - { - BuildXmlOutput(morphs); - if (wordGrammarTrace != null) - wordGrammarTrace.Success = true; - } - else if (wordGrammarTrace != null) - { - wordGrammarTrace.Success = false; - } - } - catch (Exception) - { - } - } - if (m_fDotrace) - { - WriteTrace(); - ConvertWordGrammarTraceToXml(wordGrammarTraces); - } - XmlTraceManager.Reset(); - } - catch (MorphException exc) - { - Write(exc); - } - } - - private static string BuildPcPatrInputSentence(IEnumerable morphs) - { - var sentence = new StringBuilder(); - bool firstItem = true; - foreach (PcPatrMorph morph in morphs) - { - if (!firstItem) - sentence.Append(" "); - sentence.Append(morph.Form); - firstItem = false; - } - return sentence.ToString(); - } - - void ConvertWordGrammarTraceToXml(IEnumerable wordGrammarTraces) - { - XmlWriter.WriteStartElement("WordGrammarTrace"); - foreach (WordGrammarTrace trace in wordGrammarTraces) - { - trace.ToXml(XmlWriter); - } - XmlWriter.WriteEndElement(); - } - - static List GetMorphs(WordSynthesis ws) - { - var ppMorphs = new Dictionary(); - var result = new List(); - foreach (Morph morph in ws.Morphs) - { - string[] formIds = morph.Allomorph.GetProperty("FormID").Split(' '); - string[] wordTypes = morph.Allomorph.GetProperty("WordCategory").Split(' '); - string form = ws.Stratum.CharacterDefinitionTable.ToString(morph.Shape, ModeType.SYNTHESIS, false); - PcPatrMorph ppMorph; - if (!ppMorphs.TryGetValue(morph.Allomorph.Morpheme.ID, out ppMorph)) - { - ppMorph = new PcPatrMorph - { - formIndex = 0, - formId = formIds[0], - form = form, - wordType = wordTypes[0] - }; - } - else if (formIds.Length == 1) - { - ppMorph.form += form; - continue; - } - else - { - PcPatrMorph oldMorph = ppMorph; - int wordTypeIndex = WordTypeIndex(oldMorph.formIndex + 1, wordTypes.Count()); - ppMorph = new PcPatrMorph - { - formIndex = oldMorph.formIndex + 1, - formId = formIds[oldMorph.formIndex + 1], - form = form, - wordType = wordTypes[wordTypeIndex] - }; - } - - ppMorph.msaId = morph.Allomorph.GetProperty("MsaID"); - ppMorph.featureDescriptors = morph.Allomorph.GetProperty("FeatureDescriptors"); - ppMorph.gloss = morph.Allomorph.Morpheme.Gloss.Description; - ppMorphs[morph.Allomorph.Morpheme.ID] = ppMorph; - - string morphType = morph.Allomorph.GetProperty("MorphType"); - switch (morphType) - { - case MoMorphTypeTags.kMorphInfix: - case MoMorphTypeTags.kMorphInfixingInterfix: - if (result.Count == 0) - result.Add(ppMorph); - else - result.Insert(result.Count - 1, ppMorph); - break; - - default: - result.Add(ppMorph); - break; - } - } - return result; - } - - static void WritePcPatrLexiconFile(string path, IEnumerable morphs) - { - using (var writer = new StreamWriter(path)) - { - foreach (PcPatrMorph morph in morphs) - { - writer.WriteLine("\\w {0}", morph.Form); - writer.WriteLine("\\c {0}", morph.wordType); - writer.WriteLine("\\g {0}", morph.gloss); - if (!String.IsNullOrEmpty(morph.featureDescriptors)) - { - string lastFeatDesc = ""; - string combinedCFPFeatDescs = ""; - string[] featDescs = morph.featureDescriptors.Split(' '); - if (featDescs.Any()) - writer.Write("\\f"); - foreach (string featDesc in featDescs) - { - if (featDesc.StartsWith("CFP")) - { - combinedCFPFeatDescs += featDesc; - lastFeatDesc = featDesc; - continue; - } - if (lastFeatDesc.StartsWith("CFP")) - writer.Write(" {0}", combinedCFPFeatDescs); - writer.Write(" {0}", featDesc); - } - if (lastFeatDesc.StartsWith("CFP")) - writer.Write(" {0}", combinedCFPFeatDescs); - } - writer.WriteLine(); - writer.WriteLine(); - } - writer.Close(); - } - } - - void BuildXmlOutput(IEnumerable morphs) - { - XmlWriter.WriteStartElement("WfiAnalysis"); - XmlWriter.WriteStartElement("Morphs"); - - foreach (PcPatrMorph morph in morphs) - { - XmlWriter.WriteStartElement("Morph"); - - XmlWriter.WriteStartElement("MoForm"); - XmlWriter.WriteAttributeString("DbRef", morph.formId); - XmlWriter.WriteAttributeString("Label", morph.form); - XmlWriter.WriteAttributeString("wordType", morph.wordType); - XmlWriter.WriteEndElement(); - - XmlWriter.WriteStartElement("MSI"); - XmlWriter.WriteAttributeString("DbRef", morph.msaId); - XmlWriter.WriteEndElement(); - - XmlWriter.WriteEndElement(); - } - - XmlWriter.WriteEndElement(); - XmlWriter.WriteEndElement(); - } - - public override void Write(LoadException le) - { - XmlWriter.WriteStartElement("Error"); - switch (le.ErrorType) - { - case LoadException.LoadErrorType.INVALID_ENTRY_SHAPE: - var entryShape = le.Data["shape"] as string; - var entryId = le.Data["entry"] as string; - LexEntry entry = le.Loader.CurrentMorpher.Lexicon.GetEntry(entryId); - XmlWriter.WriteString(String.Format(ParserCoreStrings.ksHCInvalidEntryShape, entryShape, entry.Description)); - break; - - case LoadException.LoadErrorType.INVALID_RULE_SHAPE: - var ruleShape = le.Data["shape"] as string; - var ruleId = le.Data["rule"] as string; - MorphologicalRule rule = le.Loader.CurrentMorpher.GetMorphologicalRule(ruleId); - XmlWriter.WriteString(String.Format(ParserCoreStrings.ksHCInvalidRuleShape, ruleShape, rule.Description)); - break; - - default: - XmlWriter.WriteString(String.Format(ParserCoreStrings.ksHCDefaultErrorMsg, le.Message)); - break; - } - XmlWriter.WriteEndElement(); - } - - public override void Write(MorphException me) - { - XmlWriter.WriteStartElement("Error"); - switch (me.ErrorType) - { - case MorphException.MorphErrorType.INVALID_SHAPE: - var shape = (string) me.Data["shape"]; - var position = (int) me.Data["position"]; - var phonemesFoundSoFar = (string) me.Data["phonemesFoundSoFar"]; - string rest = shape.Substring(position); - string restToUse = rest; - LgGeneralCharCategory cc = m_cache.ServiceLocator.UnicodeCharProps.get_GeneralCategory(rest[0]); - if (cc == LgGeneralCharCategory.kccMn) - { // the first character is a diacritic, combining type of character - // insert a space so it does not show on top of a single quote in the message string - restToUse = " " + rest; - } - XmlWriter.WriteString(String.Format(ParserCoreStrings.ksHCInvalidWordform, shape, position+1, restToUse, phonemesFoundSoFar)); - break; - - case MorphException.MorphErrorType.UNINSTANTIATED_FEATURE: - var featId = me.Data["feature"] as string; - var feat = me.Morpher.PhoneticFeatureSystem.GetFeature(featId); - XmlWriter.WriteString(String.Format(ParserCoreStrings.ksHCUninstFeature, feat.Description)); - break; - - default: - XmlWriter.WriteString(String.Format(ParserCoreStrings.ksHCDefaultErrorMsg, me.Message)); - break; - } - XmlWriter.WriteEndElement(); - } - } - - private readonly XmlLoader m_loader; - private PatrParser m_patr; - private readonly string m_outputDirectory; - - public HCParserWorker(FdoCache cache, Action taskUpdateHandler, IdleQueue idleQueue) - : base(cache, taskUpdateHandler, idleQueue, - cache.ServiceLocator.GetInstance().GetObject(CmAgentTags.kguidAgentHermitCrabParser)) - { - m_outputDirectory = Path.GetTempPath(); - m_patr = new PatrParser - { - CommentChar = '|', - CodePage = Encoding.UTF8.CodePage - }; - m_loader = new XmlLoader - { - XmlResolver = new XmlFwResolver(), - QuitOnError = false - }; - } - - protected override void Dispose(bool disposing) - { - if (disposing && !IsDisposed) - { - if (m_patr != null) - { - m_patr.Dispose(); - m_patr = null; - } - } - base.Dispose(disposing); - } - - protected override string ParseWord(string form, int hvoWordform) - { - return ParseWordWithHermitCrab(form, hvoWordform, false, null); - } - - protected override string TraceWord(string form, string selectTraceMorphs) - { - string[] selectTraceMorphIds = null; - if (!String.IsNullOrEmpty(selectTraceMorphs)) - { - selectTraceMorphIds = selectTraceMorphs.TrimEnd().Split(' '); - int i = 0; - foreach (string sId in selectTraceMorphIds) - { - IMoMorphSynAnalysis msa = m_cache.ServiceLocator.GetInstance().GetObject(int.Parse(sId)); - if (msa.ClassID == MoStemMsaTags.kClassId) - selectTraceMorphIds.SetValue("lex" + sId, i); - else - selectTraceMorphIds.SetValue("mrule" + sId, i); - i++; - } - - } - return ParseWordWithHermitCrab(form, 0, true, selectTraceMorphIds); - } - - private string ParseWordWithHermitCrab(string form, int hvoWordform, bool fDotrace, string[] selectTraceMorphs) - { - if (!m_loader.IsLoaded) - return ParserCoreStrings.ksDidNotParse; - - var sb = new StringBuilder(); - var settings = new XmlWriterSettings { OmitXmlDeclaration = true }; - using (var writer = XmlWriter.Create(sb, settings)) - { - writer.WriteStartElement("Wordform"); - writer.WriteAttributeString("DbRef", Convert.ToString(hvoWordform)); - writer.WriteAttributeString("Form", form); - var output = new FwXmlOutput(writer, fDotrace, m_patr, - Path.Combine(m_outputDirectory, m_projectName + "patrlex.txt"), m_cache); - output.MorphAndLookupWord(m_loader.CurrentMorpher, form, true, selectTraceMorphs); - if (hvoWordform == 0) - { // we are in TryAWord so we can do some extra checking - AddImpliedDataCheckerInfo(writer); - } - writer.WriteEndElement(); - } - return sb.ToString(); - } - - private void AddImpliedDataCheckerInfo(XmlWriter writer) - { - var impliedDataChecker = new ImpliedDataChecker(m_cache); - impliedDataChecker.CheckPhonemeBasedNaturalClasses(); - impliedDataChecker.ToXml(writer); - } - - public string HcInputPath - { - get { return Path.Combine(m_outputDirectory, m_projectName + "HCInput.xml"); } - } - - public string HcGrammarPath - { - get { return Path.Combine(m_outputDirectory, m_projectName + "gram.txt"); } - } - - protected override void LoadParser(ref XmlDocument model, XmlDocument template) - { - string hcPath = HcInputPath; - File.Delete(hcPath); // In case we don't produce one successfully, don't keep an old one. - // Check for errors that will prevent the transformations working. - foreach (var affix in m_cache.ServiceLocator.GetInstance().AllInstances()) - { - string form = affix.Form.VernacularDefaultWritingSystem.Text; - if (String.IsNullOrEmpty(form) || !form.Contains("[")) - continue; - string environment = "/_" + form; - // A form containing a reduplication expression should look like an environment - var validator = new PhonEnvRecognizer( - m_cache.LangProject.PhonologicalDataOA.AllPhonemes().ToArray(), - m_cache.LangProject.PhonologicalDataOA.AllNaturalClassAbbrs().ToArray()); - if (!validator.Recognize(environment)) - { - string msg = String.Format(ParserCoreStrings.ksHermitCrabReduplicationProblem, form, - validator.ErrorMessage); - m_cache.ThreadHelper.Invoke(() => // We may be running in a background thread - { - MessageBox.Show(Form.ActiveForm, msg, ParserCoreStrings.ksBadAffixForm, - MessageBoxButtons.OK, MessageBoxIcon.Error); - }); - m_loader.Reset(); // make sure nothing thinks it is in a useful state - return; // We can't load the parser, hopefully our caller will realize we failed. - } - } - - var transformer = new M3ToHCTransformer(m_projectName, m_taskUpdateHandler); - transformer.MakeHCFiles(ref model); - - m_patr.LoadGrammarFile(HcGrammarPath); - - LoadHCInfo(hcPath); - - XmlNode delReappsNode = model.SelectSingleNode("/M3Dump/ParserParameters/HC/DelReapps"); - if (delReappsNode != null) - m_loader.CurrentMorpher.DelReapplications = Convert.ToInt32(delReappsNode.InnerText); - } - - private void LoadHCInfo(string hcPath) - { - string loadErrorsFile = Path.Combine(m_outputDirectory, m_projectName + "HCLoadErrors.xml"); - using (XmlWriter writer = new XmlTextWriter(loadErrorsFile, null)) - { - var loadOutput = new XmlOutput(writer); - writer.WriteStartElement("LoadErrors"); - m_loader.Output = loadOutput; - m_loader.Load(hcPath); - writer.WriteEndElement(); - loadOutput.Close(); - } - } - } -} diff --git a/Src/LexText/ParserEngine/ParserCore/M3ModelRetriever.cs b/Src/LexText/ParserEngine/ParserCore/M3ModelRetriever.cs deleted file mode 100644 index 3e283415f3..0000000000 --- a/Src/LexText/ParserEngine/ParserCore/M3ModelRetriever.cs +++ /dev/null @@ -1,214 +0,0 @@ -// Copyright (c) 2003-2013 SIL International -// This software is licensed under the LGPL, version 2.1 or later -// (http://www.gnu.org/licenses/lgpl-2.1.html) -// -// File: M3ParserModelRetriever.cs -// Responsibility: John Hatton -// -// -// this is a MethodObject (see "Refactoring", Fowler). -// - -using System; -using System.Diagnostics; -using System.IO; -using System.Xml; - -using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.FDO; -using SIL.FieldWorks.FDO.DomainServices; -using SIL.FieldWorks.FDO.Infrastructure; -using SIL.Utils; - -namespace SIL.FieldWorks.WordWorks.Parser -{ - /// - /// Summary description for M3ParserModelRetriever. - /// - /// Is public for testing purposes - public class M3ParserModelRetriever : FwDisposableBase, IVwNotifyChange - { - private readonly FdoCache m_cache; - private readonly Action m_taskUpdateHandler; - private readonly string m_modelPath; - private readonly string m_templatePath; - private readonly string m_outputDirectory; - private XmlDocument m_modelDom; - private XmlDocument m_templateDom; - private bool m_loaded; - - private readonly object m_syncRoot = new object(); - - /// ----------------------------------------------------------------------------------- - /// - /// Initializes a new instance of the class. - /// - /// ----------------------------------------------------------------------------------- - public M3ParserModelRetriever(FdoCache cache, Action taskUpdateHandler) - { - if (cache == null) throw new ArgumentNullException("cache"); - - m_cache = cache; - m_taskUpdateHandler = taskUpdateHandler; - m_cache.DomainDataByFlid.AddNotification(this); - - m_outputDirectory = Path.GetTempPath(); - m_modelPath = Path.Combine(m_outputDirectory, m_cache.ProjectId.Name + "ParserFxtResult.xml"); - m_templatePath = Path.Combine(m_outputDirectory, m_cache.ProjectId.Name + "GAFAWSFxtResult.xml"); - } - - protected override void DisposeManagedResources() - { - m_cache.DomainDataByFlid.RemoveNotification(this); - } - - /// - /// - /// - public bool RetrieveModel() - { - lock (m_syncRoot) - { - if (m_loaded) - return false; - m_loaded = true; - } - - // According to the fxt template files, GAFAWS is NFC, all others are NFD. - using (new WorkerThreadReadHelper(m_cache.ServiceLocator.GetInstance())) - { - ILangProject lp = m_cache.LanguageProject; - using (var task = new TaskReport(ParserCoreStrings.ksRetrievingGrammarAndLexicon, m_taskUpdateHandler)) - { - // 1. Export lexicon and/or grammar. - m_modelDom = null; - M3ModelExportServices.ExportGrammarAndLexicon(m_modelPath, lp); - } - - // 2. Export GAFAWS data. - using (var task = new TaskReport(ParserCoreStrings.ksRetrievingTemplateInformation, m_taskUpdateHandler)) - { -// The following needs to be enabled, in order to avoid an exception bieng thrown after the export work, -// but it is such a handy way to get Flex to stop in my profiler. :-) - m_templateDom = null; - M3ModelExportServices.ExportGafaws(m_outputDirectory, m_cache.ProjectId.Name, - lp.PartsOfSpeechOA.PossibilitiesOS); - } - } - return true; - } - - public void Reset() - { - lock (m_syncRoot) - m_loaded = false; - m_modelDom = null; - m_templateDom = null; - } - - /// - /// Get the model (FXT result) DOM - /// - /// Is public for testing only - public XmlDocument ModelDom - { - get - { - Debug.Assert(m_modelPath != null); - Debug.Assert(File.Exists(m_modelPath)); - if (m_modelDom == null) - { - m_modelDom = new XmlDocument(); - m_modelDom.Load(m_modelPath); - } - return m_modelDom; - } - } - - internal XmlDocument TemplateDom - { - get - { - if (m_templateDom == null) - { - Debug.Assert(m_templatePath != null); - Debug.Assert(File.Exists(m_templatePath)); - m_templateDom = new XmlDocument(); - m_templateDom.Load(m_templatePath); - } - return m_templateDom; - - } - } - - #region Implementation of IVwNotifyChange - - void IVwNotifyChange.PropChanged(int hvo, int tag, int ivMin, int cvIns, int cvDel) - { - lock (m_syncRoot) - { - int clsid = m_cache.ServiceLocator.GetObject(hvo).ClassID; - switch (clsid) - { - case LexDbTags.kClassId: - case LexEntryTags.kClassId: - case LexSenseTags.kClassId: - - case FsClosedValueTags.kClassId: - case FsComplexValueTags.kClassId: - case FsFeatStrucTags.kClassId: - case FsFeatStrucTypeTags.kClassId: - case FsClosedFeatureTags.kClassId: - case FsComplexFeatureTags.kClassId: - case FsFeatureSystemTags.kClassId: - case FsSymFeatValTags.kClassId: - - case MoMorphTypeTags.kClassId: - case MoAdhocProhibGrTags.kClassId: - case MoAlloAdhocProhibTags.kClassId: - case MoMorphAdhocProhibTags.kClassId: - case MoEndoCompoundTags.kClassId: - case MoExoCompoundTags.kClassId: - case MoInflAffixSlotTags.kClassId: - case MoInflAffixTemplateTags.kClassId: - case MoInflClassTags.kClassId: - case MoAffixAllomorphTags.kClassId: - case MoStemAllomorphTags.kClassId: - case MoAffixProcessTags.kClassId: - case MoCopyFromInputTags.kClassId: - case MoInsertPhonesTags.kClassId: - case MoInsertNCTags.kClassId: - case MoModifyFromInputTags.kClassId: - case MoDerivAffMsaTags.kClassId: - case MoInflAffMsaTags.kClassId: - case MoUnclassifiedAffixMsaTags.kClassId: - case MoStemMsaTags.kClassId: - case MoMorphDataTags.kClassId: - - case PhCodeTags.kClassId: - case PhIterationContextTags.kClassId: - case PhMetathesisRuleTags.kClassId: - case PhRegularRuleTags.kClassId: - case PhSegRuleRHSTags.kClassId: - case PhPhonemeSetTags.kClassId: - case PartOfSpeechTags.kClassId: - case PhFeatureConstraintTags.kClassId: - case PhNCFeaturesTags.kClassId: - case PhNCSegmentsTags.kClassId: - case PhPhonDataTags.kClassId: - case PhPhonemeTags.kClassId: - case PhSequenceContextTags.kClassId: - case PhSimpleContextBdryTags.kClassId: - case PhSimpleContextNCTags.kClassId: - case PhSimpleContextSegTags.kClassId: - case PhVariableTags.kClassId: - case PhEnvironmentTags.kClassId: - m_loaded = false; - break; - } - } - } - - #endregion - } -} diff --git a/Src/LexText/ParserEngine/ParserCore/M3ToHCTransformer.cs b/Src/LexText/ParserEngine/ParserCore/M3ToHCTransformer.cs deleted file mode 100644 index c2c0932b47..0000000000 --- a/Src/LexText/ParserEngine/ParserCore/M3ToHCTransformer.cs +++ /dev/null @@ -1,59 +0,0 @@ -//#define DumpCleanedMode -// Copyright (c) 2003-2013 SIL International -// This software is licensed under the LGPL, version 2.1 or later -// (http://www.gnu.org/licenses/lgpl-2.1.html) -// -// File: M3ParserTransformer.cs -// Responsibility: John Hatton - -using System; -using System.Xml; -using System.IO; -using System.Diagnostics; - -using SIL.FieldWorks.Common.FwUtils; -using SIL.Utils; - -namespace SIL.FieldWorks.WordWorks.Parser -{ - /// - /// Given an XML file representing an instance of a M3 grammar model, - /// transforms it into the format needed by a parser. - /// - internal class M3ToHCTransformer : M3ToParserTransformerBase - { - - /// ----------------------------------------------------------------------------------- - /// - /// Initializes a new instance of the class. - /// - /// ----------------------------------------------------------------------------------- - public M3ToHCTransformer(string database, Action taskUpdateHandler) - : base(database, taskUpdateHandler) - { - } - - public void MakeHCFiles(ref XmlDocument model) - { - using (var task = new TaskReport(ParserCoreStrings.ksMakingHCFiles, m_taskUpdateHandler)) - { - var startTime = DateTime.Now; - TransformDomToFile("FxtM3ParserToHCInput.xsl", model, m_database + "HCInput.xml", task); - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "Lex XSLT took : " + (DateTime.Now.Ticks - startTime.Ticks)); - - startTime = DateTime.Now; - TransformDomToFile("FxtM3ParserToToXAmpleGrammar.xsl", model, m_database + "gram.txt", task); - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "Grammar XSLTs took : " + (DateTime.Now.Ticks - startTime.Ticks)); - - // TODO: Putting this here is not necessarily efficient because it happens every time - // the parser is run. It would be more efficient to run this only when the user - // is trying a word. But we need the "model" to apply this transform and it is - // available here, so we're doing this for now. - startTime = DateTime.Now; - string sName = m_database + "XAmpleWordGrammarDebugger.xsl"; - TransformDomToFile("FxtM3ParserToXAmpleWordGrammarDebuggingXSLT.xsl", model, sName, task); - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "WordGrammarDebugger XSLT took : " + (DateTime.Now.Ticks - startTime.Ticks)); - } - } - } -} diff --git a/Src/LexText/ParserEngine/ParserCore/M3ToParserTransformerBase.cs b/Src/LexText/ParserEngine/ParserCore/M3ToParserTransformerBase.cs deleted file mode 100644 index f68a35de68..0000000000 --- a/Src/LexText/ParserEngine/ParserCore/M3ToParserTransformerBase.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Xml; -using SIL.FieldWorks.Common.FwUtils; -using SIL.Utils; - -namespace SIL.FieldWorks.WordWorks.Parser -{ - /// - /// Base class for transforming an M3 model to files needed by a parser - /// - abstract internal class M3ToParserTransformerBase - { - protected string m_outputDirectory; - protected string m_database; - protected Action m_taskUpdateHandler; - protected readonly TraceSwitch m_tracingSwitch = new TraceSwitch("ParserCore.TracingSwitch", "Just regular tracking", "Off"); - - /// ----------------------------------------------------------------------------------- - /// - /// Initializes a new instance of the class. - /// - /// ----------------------------------------------------------------------------------- - public M3ToParserTransformerBase(string database, Action taskUpdateHandler) - { - m_database = database; - m_taskUpdateHandler = taskUpdateHandler; - m_outputDirectory = Path.GetTempPath(); - } - - protected void TransformDomToFile(string transformName, XmlDocument inputDOM, string outputName, TaskReport task) - { - using (task.AddSubTask(String.Format(ParserCoreStrings.ksCreatingX, outputName))) - { - XmlUtils.TransformDomToFile(Path.Combine(DirectoryFinder.FWCodeDirectory + "/Language Explorer/Transforms/", transformName), - inputDOM, Path.Combine(m_outputDirectory, outputName)); - } - } - } -} diff --git a/Src/LexText/ParserEngine/ParserCore/M3ToXAmpleTransformer.cs b/Src/LexText/ParserEngine/ParserCore/M3ToXAmpleTransformer.cs deleted file mode 100644 index e2ffcd5c13..0000000000 --- a/Src/LexText/ParserEngine/ParserCore/M3ToXAmpleTransformer.cs +++ /dev/null @@ -1,132 +0,0 @@ -//#define DumpCleanedMode -// Copyright (c) 2003-2013 SIL International -// This software is licensed under the LGPL, version 2.1 or later -// (http://www.gnu.org/licenses/lgpl-2.1.html) -// -// File: M3ToXAmpleTransformer.cs -// Responsibility: John Hatton - -using System; -using System.Diagnostics.CodeAnalysis; -using System.Text; -using System.Xml; -using System.IO; -using System.Diagnostics; -using SIL.Utils; -using SIL.FieldWorks.Common.FwUtils; -using SIL.WordWorks.GAFAWS.PositionAnalysis; - -namespace SIL.FieldWorks.WordWorks.Parser -{ - /// - /// Given an XML file representing an instance of a M3 grammar model, - /// transforms it into the format needed by XAmple. - /// - internal class M3ToXAmpleTransformer : M3ToParserTransformerBase - { - /// ----------------------------------------------------------------------------------- - /// - /// Initializes a new instance of the class. - /// - /// ----------------------------------------------------------------------------------- - public M3ToXAmpleTransformer(string database, Action taskUpdateHandler) - : base(database, taskUpdateHandler) - { - } - - [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", - Justification = "In .NET 4.5 XmlNodeList implements IDisposable, but not in 4.0.")] - internal void PrepareTemplatesForXAmpleFiles(ref XmlDocument domModel, XmlDocument domTemplate) - { - using (var task = new TaskReport(ParserCoreStrings.ksPreparingTemplatesForXAmple, m_taskUpdateHandler)) - { - // get top level POS that has at least one template with slots - XmlNodeList templateNodeList = domTemplate.SelectNodes("//PartsOfSpeech/PartOfSpeech[descendant-or-self::MoInflAffixTemplate[PrefixSlots or SuffixSlots]]"); - foreach (XmlNode templateNode in templateNodeList) - { - // transform the POS that has templates to GAFAWS format - string sGafawsFile = m_database + "gafawsData.xml"; - TransformPOSInfoToGafawsInputFormat(templateNode, sGafawsFile, task); - string sResultFile = ApplyGafawsAlgorithm(sGafawsFile); - //based on results of GAFAWS, modify the model dom by inserting orderclass in slots - InsertOrderclassInfo(ref domModel, sResultFile); - } - } - } - - [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", - Justification = "In .NET 4.5 XmlNodeList implements IDisposable, but not in 4.0.")] - protected void InsertOrderclassInfo(ref XmlDocument domModel, string sResultFile) - { - // Check for a valid filename (see LT-6472). - if (String.IsNullOrEmpty(sResultFile)) - return; - var dom = new XmlDocument(); - dom.Load(sResultFile); - XmlNodeList gafawsNodeList = dom.SelectNodes("//Morpheme"); - foreach (XmlNode gafawsNode in gafawsNodeList) - { - string sMorphemeId = gafawsNode.Attributes.GetNamedItem("MID").InnerText; - if (sMorphemeId == "R") - continue; // skip the stem/root node - string sXpathToMorphemeId = "//MoInflAffixSlot[@Id='" + sMorphemeId + "']"; - XmlNode modelNode = domModel.SelectSingleNode(sXpathToMorphemeId); - StringBuilder sb; - BuildOrderclassElementsString(out sb, gafawsNode); - XmlElement orderclassNode = domModel.CreateElement("orderclass"); - orderclassNode.InnerXml = sb.ToString(); - modelNode.AppendChild(orderclassNode); - } - } - - private static void BuildOrderclassElementsString(out StringBuilder sb, XmlNode gafawsNode) - { - sb = new StringBuilder(); - sb.Append(""); - sb.Append(gafawsNode.Attributes.GetNamedItem("StartCLIDREF").InnerText); - sb.Append(" "); - sb.Append(gafawsNode.Attributes.GetNamedItem("EndCLIDREF").InnerText); - sb.Append(""); - } - - protected string ApplyGafawsAlgorithm(string sGafawsFile) - { - var pa = new PositionAnalyzer(); - string sGafawsInputFile = Path.Combine(m_outputDirectory, sGafawsFile); - return pa.Process(sGafawsInputFile); - } - /// - /// transform the POS that has templates to GAFAWS format - /// - protected void TransformPOSInfoToGafawsInputFormat(XmlNode templateNode, string sGafawsFile, TaskReport task) - { - var dom = new XmlDocument(); - dom.CreateElement("GAFAWSData"); // create root element - dom.InnerXml = templateNode.OuterXml; // copy in POS elements - TransformDomToFile("FxtM3ParserToGAFAWS.xsl", dom, sGafawsFile, task); - } - - internal void MakeAmpleFiles(XmlDocument model) - { - using (var task = new TaskReport(ParserCoreStrings.ksMakingXAmpleFiles, m_taskUpdateHandler)) - { - DateTime startTime = DateTime.Now; - TransformDomToFile("FxtM3ParserToXAmpleADCtl.xsl", model, m_database + "adctl.txt", task); - TransformDomToFile("FxtM3ParserToToXAmpleGrammar.xsl", model, m_database + "gram.txt", task); - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "Grammar XSLTs took : " + (DateTime.Now.Ticks - startTime.Ticks)); - // TODO: Putting this here is not necessarily efficient because it happens every time - // the parser is run. It would be more efficient to run this only when the user - // is trying a word. But we need the "model" to apply this transform an it is - // available here, so we're doing this for now. - startTime = DateTime.Now; - string sName = m_database + "XAmpleWordGrammarDebugger.xsl"; - TransformDomToFile("FxtM3ParserToXAmpleWordGrammarDebuggingXSLT.xsl", model, sName, task); - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "WordGrammarDebugger XSLT took : " + (DateTime.Now.Ticks - startTime.Ticks)); - - startTime = DateTime.Now; - TransformDomToFile("FxtM3ParserToXAmpleLex.xsl", model, m_database + "lex.txt", task); - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "Lex XSLT took : " + (DateTime.Now.Ticks - startTime.Ticks)); - } - } - } -} diff --git a/Src/LexText/ParserEngine/ParserCore/ParseFiler.cs b/Src/LexText/ParserEngine/ParserCore/ParseFiler.cs deleted file mode 100644 index 93c2058f31..0000000000 --- a/Src/LexText/ParserEngine/ParserCore/ParseFiler.cs +++ /dev/null @@ -1,718 +0,0 @@ -// Copyright (c) 2003-2013 SIL International -// This software is licensed under the LGPL, version 2.1 or later -// (http://www.gnu.org/licenses/lgpl-2.1.html) -// -// File: ParseFiler.cs -// Responsibility: Randy Regnier -// Last reviewed: -// -// -// Implements the ParseFiler. -// -// buildtest ParseFiler-nodep - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Xml.Linq; -using System.Diagnostics; -using SIL.FieldWorks.FDO; -using SIL.FieldWorks.FDO.Application; -using SIL.FieldWorks.FDO.Infrastructure; -using SIL.Utils; - -namespace SIL.FieldWorks.WordWorks.Parser -{ - /// - /// The event args for the WordformUpdated event. - /// - public class WordformUpdatedEventArgs : EventArgs - { - public WordformUpdatedEventArgs(IWfiWordform wordform, ParserPriority priority) - { - Wordform = wordform; - Priority = priority; - } - - public IWfiWordform Wordform - { - get; private set; - } - - public ParserPriority Priority - { - get; private set; - } - } - - /// - /// Summary description for ParseFiler. - /// - public class ParseFiler : IFWDisposable - { - /// - /// Occurs when a wordform is updated. - /// - public event EventHandler WordformUpdated; - - #region internal class - - private class ParseResult - { - public ParseResult(IWfiWordform wordform, uint crc, ParserPriority priority, IList analyses, - string errorMessage) - { - Wordform = wordform; - Crc = crc; - Priority = priority; - Analyses = analyses; - ErrorMessage = errorMessage; - } - - public IWfiWordform Wordform - { - get; private set; - } - - public uint Crc - { - get; private set; - } - - public IList Analyses - { - get; private set; - } - - public string ErrorMessage - { - get; private set; - } - - public ParserPriority Priority - { - get; private set; - } - - public bool IsValid - { - get - { - if (!Wordform.IsValidObject) - return false; - return Analyses.All(analysis => analysis.IsValid); - } - } - } - - private class ParseAnalysis - { - public ParseAnalysis(IList morphs) - { - Morphs = morphs; - } - - public IList Morphs - { - get; private set; - } - - public bool IsValid - { - get - { - return Morphs.All(morph => morph.IsValid); - } - } - } - - private class ParseMorph - { - public ParseMorph(IMoForm form, IMoMorphSynAnalysis msa) - { - Form = form; - Msa = msa; - } - - public ParseMorph(IMoForm form, IMoMorphSynAnalysis msa, ILexEntryInflType inflType) - { - Form = form; - Msa = msa; - InflType = inflType; - } - - public IMoForm Form - { - get; private set; - } - - public IMoMorphSynAnalysis Msa - { - get; private set; - } - - public ILexEntryInflType InflType - { - get; private set; - } - - public bool IsValid - { - get - { - return Form.IsValidObject && Msa.IsValidObject; - } - } - } - - #endregion internal class - - #region Data members - - private readonly FdoCache m_cache; - private readonly Action m_taskUpdateHandler; - private readonly IdleQueue m_idleQueue; - private readonly ICmAgent m_parserAgent; - private readonly Queue m_resultQueue; - private readonly object m_syncRoot; - - private readonly IWfiWordformRepository m_wordformRepository; - private readonly IWfiAnalysisFactory m_analysisFactory; - private readonly IWfiMorphBundleFactory m_mbFactory; - private readonly ICmBaseAnnotationRepository m_baseAnnotationRepository; - private readonly ICmBaseAnnotationFactory m_baseAnnotationFactory; - private readonly IMoFormRepository m_moFormRepository; - private readonly IMoMorphSynAnalysisRepository m_msaRepository; - private readonly ICmAgent m_userAgent; - - /// - /// Set of analyses which had a recorded evaluation by this parser agent when the engine was loaded. - /// These evaluations are considered stale until we set a new evaluation, which removes that item from the set. - /// - private readonly HashSet m_analysesWithOldEvaluation; - private readonly TraceSwitch m_tracingSwitch = new TraceSwitch("ParserCore.TracingSwitch", "Just regular tracking", "Off"); - private long m_ticksFiler; - private int m_numberOfWordForms; - - #endregion Data members - - #region Properties - - #endregion Properties - - #region Construction and Disposal - - /// - /// Initializes a new instance of the class. - /// - /// The cache. - /// The task update handler. - /// The idle queue. - /// The parser agent. - public ParseFiler(FdoCache cache, Action taskUpdateHandler, IdleQueue idleQueue, ICmAgent parserAgent) - { - Debug.Assert(cache != null); - Debug.Assert(taskUpdateHandler != null); - Debug.Assert(idleQueue != null); - Debug.Assert(parserAgent != null); - - m_cache = cache; - m_taskUpdateHandler = taskUpdateHandler; - m_idleQueue = idleQueue; - m_parserAgent = parserAgent; - m_resultQueue = new Queue(); - m_syncRoot = new object(); - - var servLoc = cache.ServiceLocator; - m_wordformRepository = servLoc.GetInstance(); - m_analysisFactory = servLoc.GetInstance(); - m_mbFactory = servLoc.GetInstance(); - m_baseAnnotationRepository = servLoc.GetInstance(); - m_baseAnnotationFactory = servLoc.GetInstance(); - m_moFormRepository = servLoc.GetInstance(); - m_msaRepository = servLoc.GetInstance(); - m_userAgent = m_cache.LanguageProject.DefaultUserAgent; - - m_analysesWithOldEvaluation = new HashSet( - m_cache.ServiceLocator.GetInstance().AllInstances().Where( - analysis => analysis.GetAgentOpinion(m_parserAgent) != Opinions.noopinion)); - } - - #region IDisposable & Co. implementation - // Region last reviewed: never - - /// - /// Check to see if the object has been disposed. - /// All public Properties and Methods should call this - /// before doing anything else. - /// - public void CheckDisposed() - { - if (IsDisposed) - throw new ObjectDisposedException(String.Format("'{0}' in use after being disposed.", GetType().Name)); - } - - /// - /// True, if the object has been disposed. - /// - private bool m_isDisposed; - - /// - /// See if the object has been disposed. - /// - public bool IsDisposed - { - get { return m_isDisposed; } - } - - /// - /// Finalizer, in case client doesn't dispose it. - /// Force Dispose(false) if not already called (i.e. m_isDisposed is true) - /// - /// - /// In case some clients forget to dispose it directly. - /// - ~ParseFiler() - { - Dispose(false); - // The base class finalizer is called automatically. - } - - /// - /// - /// - /// Must not be virtual. - public void Dispose() - { - Dispose(true); - // This object will be cleaned up by the Dispose method. - // Therefore, you should call GC.SupressFinalize to - // take this object off the finalization queue - // and prevent finalization code for this object - // from executing a second time. - GC.SuppressFinalize(this); - } - - /// - /// Executes in two distinct scenarios. - /// - /// 1. If disposing is true, the method has been called directly - /// or indirectly by a user's code via the Dispose method. - /// Both managed and unmanaged resources can be disposed. - /// - /// 2. If disposing is false, the method has been called by the - /// runtime from inside the finalizer and you should not reference (access) - /// other managed objects, as they already have been garbage collected. - /// Only unmanaged resources can be disposed. - /// - /// - /// - /// If any exceptions are thrown, that is fine. - /// If the method is being done in a finalizer, it will be ignored. - /// If it is thrown by client code calling Dispose, - /// it needs to be handled by fixing the bug. - /// - /// If subclasses override this method, they should call the base implementation. - /// - protected virtual void Dispose(bool disposing) - { - Debug.WriteLineIf(!disposing, "****************** Missing Dispose() call for " + GetType().Name + ". ******************"); - // Must not be run more than once. - if (m_isDisposed) - return; - - if (disposing) - { - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "Total number of wordforms updated = " + m_numberOfWordForms); - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "Total time for parser filer = " + TimeSpan.FromTicks(m_ticksFiler).TotalMilliseconds); - - if (m_numberOfWordForms != 0) - { - long lAvg = m_ticksFiler / m_numberOfWordForms; - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "Average time for parser filer = " + TimeSpan.FromTicks(lAvg).TotalMilliseconds); - } - } - - // Dispose unmanaged resources here, whether disposing is true or false. - m_isDisposed = true; - } - - #endregion IDisposable & Co. implementation - - #endregion Construction and Disposal - - #region Public methods - /// - /// Process the XML data. - /// - /// The priority. - /// The XML data to process. - /// The CRC. - /// - /// The 'parser' XML string may, or may not, be well formed XML. - /// If there is an Exception node in the XML, then it may not be well-formed XML beyond that node, - /// since the XAmple parser may have choked. - /// This is why we can't use a DOM to get all of the XML, but we have to read it as it goes by in a stream. - /// - /// ENHANCE (DamienD): right now we are not supporting malformed XML - /// - public bool ProcessParse(ParserPriority priority, string parse, uint crc) - { - var wordformElem = XElement.Parse(parse); - string errorMessage = null; - var exceptionElem = wordformElem.Element("Exception"); - if (exceptionElem != null) - { - var totalAnalysesValue = (string) exceptionElem.Attribute("totalAnalyses"); - switch ((string) exceptionElem.Attribute("code")) - { - case "ReachedMaxAnalyses": - errorMessage = String.Format(ParserCoreStrings.ksReachedMaxAnalysesAllowed, - totalAnalysesValue); - break; - case "ReachedMaxBufferSize": - errorMessage = String.Format(ParserCoreStrings.ksReachedMaxInternalBufferSize, - totalAnalysesValue); - break; - } - } - else - { - errorMessage = (string) wordformElem.Element("Error"); - } - - try - { - ParseResult result; - using (new WorkerThreadReadHelper(m_cache.ServiceLocator.GetInstance())) - { - var wordform = m_wordformRepository.GetObject((int) wordformElem.Attribute("DbRef")); - IList analyses = null; - analyses = (from analysisElem in wordformElem.Descendants("WfiAnalysis") - let morphs = from morphElem in analysisElem.Descendants("Morph") - let morph = CreateParseMorph(morphElem) - where morph != null - select morph - where morphs.Any() - select new ParseAnalysis(morphs.ToList())).ToList(); - result = new ParseResult(wordform, crc, priority, analyses, errorMessage); - } - - lock (m_syncRoot) - m_resultQueue.Enqueue(result); - m_idleQueue.Add(IdleQueuePriority.Low, UpdateWordforms); - return true; - } - catch (KeyNotFoundException) - { - // a wordform, form, or MSA no longer exists, so skip this parse result - } - return false; - } - - #endregion Public methods - - #region Private methods - - /// - /// Creates a single ParseMorph object - /// Handles special cases where the MoForm hvo and/or MSI hvos are - /// not actual MoForm or MSA objects. - /// - /// A Morph element returned by one of the automated parsers - /// a new ParseMorph object or null if the morpheme should be skipped - private ParseMorph CreateParseMorph(XElement morphElem) - { - // Normally, the hvo for MoForm is a MoForm and the hvo for MSI is an MSA - // There are four exceptions, though, when an irregularly inflected form is involved: - // 1. ().GetObject(hvoForm); - var form = objForm as IMoForm; - - var msaHvo = morphElem.Element("MSI").Attribute("DbRef"); - string sMsaHvo = msaHvo.Value; - // Irregulary inflected forms can have a combination MSA hvo: the LexEntry hvo, a period, and an index to the LexEntryRef - var indexOfPeriod = IndexOfPeriodInMsaHvo(ref sMsaHvo); - ICmObject objMsa = m_cache.ServiceLocator.GetInstance().GetObject(Convert.ToInt32(sMsaHvo)); - var msa = objMsa as IMoMorphSynAnalysis; - - if (form != null && msa != null) - return new ParseMorph(form, msa); - - var msaAsLexEntry = objMsa as ILexEntry; - if (msaAsLexEntry != null && form != null) - { - // is an irregularly inflected form - // get the MoStemMsa of its variant - if (msaAsLexEntry.EntryRefsOS.Count > 0) - { - var index = IndexOfLexEntryRef(msaHvo.Value, indexOfPeriod); // the value of the int after the period - var lexEntryRef = msaAsLexEntry.EntryRefsOS[index]; - var sense = FDO.DomainServices.MorphServices.GetMainOrFirstSenseOfVariant(lexEntryRef); - var stemMsa = sense.MorphoSyntaxAnalysisRA as IMoStemMsa; - var entryOfForm = form.Owner as ILexEntry; - var inflType = lexEntryRef.VariantEntryTypesRS.ElementAt(0); - return new ParseMorph(form, stemMsa, inflType as ILexEntryInflType); - } - } - // if it is anything else, we ignore it - return null; - } - - /// - /// Updates the wordform. This will be run in the UI thread when the application is idle. If it can't be done right now, - /// it returns false, and the caller should try again later. - /// - /// The parameter. - /// - private bool UpdateWordforms(object parameter) - { - if (IsDisposed) - return true; - // If a UOW is in progress, the application isn't really idle, so try again later. One case where this used - // to be true was the dialog in IText for choosing the writing system of a new text, which was run while - // the UOW was active. - if (!((IActionHandlerExtensions) m_cache.ActionHandlerAccessor).CanStartUow) - return false; - - // update all of the wordforms in a batch, this might slow down the UI thread a little, if it causes too much unresponsiveness - // we can bail out early if there is a message in the Win32 message queue - IEnumerable results; - lock (m_syncRoot) - { - results = m_resultQueue.ToArray(); - m_resultQueue.Clear(); - } - - NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, () => - { - foreach (ParseResult result in results) - { - if (!result.IsValid) - { - // the wordform or the candidate analyses are no longer valid, so just skip this parse - FireWordformUpdated(result.Wordform, result.Priority); - continue; - } - var startTime = DateTime.Now; - string form = result.Wordform.Form.BestVernacularAlternative.Text; - using (new TaskReport(String.Format(ParserCoreStrings.ksUpdateX, form), m_taskUpdateHandler)) - { - // delete old problem annotations - var problemAnnotations = from ann in m_baseAnnotationRepository.AllInstances() - where - ann.BeginObjectRA == result.Wordform && - ann.SourceRA == m_parserAgent - select ann; - foreach (var problem in problemAnnotations) - m_cache.DomainDataByFlid.DeleteObj(problem.Hvo); - - if (result.ErrorMessage != null) - { - // there was an error, so create a problem annotation - var problemReport = m_baseAnnotationFactory.Create(); - m_cache.LangProject.AnnotationsOC.Add(problemReport); - problemReport.CompDetails = result.ErrorMessage; - problemReport.SourceRA = m_parserAgent; - problemReport.AnnotationTypeRA = null; - problemReport.BeginObjectRA = result.Wordform; - FinishWordForm(result.Wordform); - } - else - { - // update the wordform - foreach (var analysis in result.Analyses) - ProcessAnalysis(result.Wordform, analysis); - FinishWordForm(result.Wordform); - RemoveUnlovedParses(result.Wordform); - } - result.Wordform.Checksum = (int)result.Crc; - } - // notify all listeners that the wordform has been updated - FireWordformUpdated(result.Wordform, result.Priority); - long ttlTicks = DateTime.Now.Ticks - startTime.Ticks; - m_ticksFiler += ttlTicks; - m_numberOfWordForms++; - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "parser filer(" + form + ") took : " + TimeSpan.FromTicks(ttlTicks).TotalMilliseconds); - } - }); - return true; - } - - private void FireWordformUpdated(IWfiWordform wordform, ParserPriority priority) - { - if (WordformUpdated != null) - WordformUpdated(this, new WordformUpdatedEventArgs(wordform, priority)); - } - - /// - /// Process an analysis. - /// - /// - /// This method contains the port of the UpdWfiAnalysisAndEval$ SP. - /// The SP was about 220 lines of code (not counting a commetned out section). - /// The C# version is about 60 lines long. - /// - private void ProcessAnalysis(IWfiWordform wordform, ParseAnalysis analysis) - { - /* - Try to find matching analysis(analyses) that already exist. - A "match" is one in which: - (1) the number of morph bundles equal the number of the MoForm and - MorphoSyntaxAnanlysis (MSA) IDs passed in to the stored procedure, and - (2) The objects of each MSA+Form pair match those of the corresponding WfiMorphBundle. - */ - // Find matching analysis/analyses, if any exist. - var matches = new HashSet(); - foreach (var anal in wordform.AnalysesOC) - { - if (anal.MorphBundlesOS.Count == analysis.Morphs.Count) - { - // Meets match condition (1), above. - var mbMatch = false; //Start pessimistically. - var i = 0; - foreach (var mb in anal.MorphBundlesOS) - { - var current = analysis.Morphs[i++]; - if (mb.MorphRA == current.Form && mb.MsaRA == current.Msa && mb.InflTypeRA == current.InflType) - { - // Possibly matches condition (2), above. - mbMatch = true; - } - else - { - // Fails condition (2), above. - mbMatch = false; - break; // No sense in continuing. - } - } - if (mbMatch) - { - // Meets matching condition (2), above. - matches.Add(anal); - } - } - } - if (matches.Count == 0) - { - // Create a new analysis, since there are no matches. - var newAnal = m_analysisFactory.Create(); - wordform.AnalysesOC.Add(newAnal); - // Make WfiMorphBundle(s). - foreach (var morph in analysis.Morphs) - { - var mb = m_mbFactory.Create(); - newAnal.MorphBundlesOS.Add(mb); - mb.MorphRA = morph.Form; - mb.MsaRA = morph.Msa; - if (morph.InflType != null) - mb.InflTypeRA = morph.InflType; - } - matches.Add(newAnal); - } - // (Re)set evaluations. - foreach (var matchingAnal in matches) - { - m_parserAgent.SetEvaluation(matchingAnal, - Opinions.approves); - m_analysesWithOldEvaluation.Remove(matchingAnal); - } - } - - /// - /// - /// - private void RemoveUnlovedParses(IWfiWordform wordform) - { - // Solves LT-1842. - /* - Get all the IDs for Analyses that belong to the wordform, but which don't have an - evaluation belonging to the given agent. These will all be set to FAILED. - */ - foreach (var nobodyCareAboutMeAnalysis in wordform.AnalysesOC.Where(anal => - anal.GetAgentOpinion(m_parserAgent) != Opinions.approves // Parser doesn't like it - && anal.GetAgentOpinion(m_userAgent) == Opinions.noopinion)) // And, Human doesn't care - { - // A parser never has 'Opinions.disapproves' - //m_parserAgent.SetEvaluation(failure, Opinions.disapproves); - m_analysesWithOldEvaluation.Remove(nobodyCareAboutMeAnalysis); - nobodyCareAboutMeAnalysis.Delete(); - } - } - - #region Wordform Preparation methods - - private void FinishWordForm(IWfiWordform wordform) - { - // the following is a port of the SP RemoveUnusedAnalyses - - // Delete stale evaluations on analyses. The only non-stale analyses are new, positive ones, so this - // makes all analyses that are not known to be correct no-opinion. Later any of them that survive at all - // will be changed to failed (if there was no error in parsing the wordform). - var analysesNotUpdated = from analysis in wordform.AnalysesOC where m_analysesWithOldEvaluation.Contains(analysis) select analysis; - foreach (var analysis in analysesNotUpdated) - analysis.SetAgentOpinion(m_parserAgent, Opinions.noopinion); - - // Make sure all analyses have human evaluations, if they, - // or glosses they own, are referred to by an ISegment. - //var annLookup = m_baseAnnotationRepository.AllInstances() - // .Where(ann => ann.AnnotationTypeRA != null && ann.AnnotationTypeRA.Guid == CmAnnotationDefnTags.kguidAnnWordformInContext) - // .ToLookup(ann => ann.InstanceOfRA); - var segmentAnalyses = new HashSet(); - foreach (var seg in wordform.OccurrencesBag) - segmentAnalyses.UnionWith(seg.AnalysesRS.ToArray()); - var analyses = from anal in wordform.AnalysesOC - where segmentAnalyses.Contains(anal) || anal.MeaningsOC.Any(segmentAnalyses.Contains) - select anal; - foreach (var analysis in analyses) - m_userAgent.SetEvaluation(analysis, Opinions.approves); - - // Delete orphan analyses, which have no evaluations (Review JohnT: should we also check for no owned WfiGlosses?) - var orphanedAnalyses = from anal in wordform.AnalysesOC - where anal.EvaluationsRC.Count == 0 - select anal; - foreach (var analysis in orphanedAnalyses) - m_cache.DomainDataByFlid.DeleteObj(analysis.Hvo); - } - - #endregion Wordform Preparation methods - - #endregion Private methods - - public static int IndexOfLexEntryRef(string sHvo, int indexOfPeriod) - { - int index = 0; - if (indexOfPeriod >= 0) - { - string sIndex = sHvo.Substring(indexOfPeriod+1); - index = Convert.ToInt32(sIndex); - } - return index; - } - - public static int IndexOfPeriodInMsaHvo(ref string sObjHvo) - { - // Irregulary inflected forms can a combination MSA hvo: the LexEntry hvo, a period, and an index to the LexEntryRef - int indexOfPeriod = sObjHvo.IndexOf('.'); - if (indexOfPeriod >= 0) - { - sObjHvo = sObjHvo.Substring(0, indexOfPeriod); - } - return indexOfPeriod; - } - } -} diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreStrings.Designer.cs b/Src/LexText/ParserEngine/ParserCore/ParserCoreStrings.Designer.cs deleted file mode 100644 index 269f43edae..0000000000 --- a/Src/LexText/ParserEngine/ParserCore/ParserCoreStrings.Designer.cs +++ /dev/null @@ -1,288 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.269 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace SIL.FieldWorks.WordWorks.Parser { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class ParserCoreStrings { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal ParserCoreStrings() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SIL.FieldWorks.WordWorks.Parser.ParserCoreStrings", typeof(ParserCoreStrings).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to Bad Affix Form. - /// - internal static string ksBadAffixForm { - get { - return ResourceManager.GetString("ksBadAffixForm", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Creating {0}. - /// - internal static string ksCreatingX { - get { - return ResourceManager.GetString("ksCreatingX", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Parse was not attempted because of errors in the lexical data. - /// - internal static string ksDidNotParse { - get { - return ResourceManager.GetString("ksDidNotParse", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to error encountered. - /// - internal static string ksErrorEncountered { - get { - return ResourceManager.GetString("ksErrorEncountered", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to finished. - /// - internal static string ksFinished { - get { - return ResourceManager.GetString("ksFinished", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The parser gave the following cryptic message (you may need to contact FieldWorks support to know what it means): {0}. - /// - internal static string ksHCDefaultErrorMsg { - get { - return ResourceManager.GetString("ksHCDefaultErrorMsg", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The phoneme {0} of lexical entry {1} is not defined. Please make sure all phonemes in all allomorphs of all entries have been defined.. - /// - internal static string ksHCInvalidEntryShape { - get { - return ResourceManager.GetString("ksHCInvalidEntryShape", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The phoneme {0} of affix {1} is not defined. Please make sure all phonemes in all allomorphs of all affixes have been defined.. - /// - internal static string ksHCInvalidRuleShape { - get { - return ResourceManager.GetString("ksHCInvalidRuleShape", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to There is at least one undefined phoneme in the word '{0}'. The following phonemes were parsed: '{3}'. The problem begins with character/diacritic number {1} – that is, in the part of the word '{2}'. Please make sure all phonemes in the word have been defined.. - /// - internal static string ksHCInvalidWordform { - get { - return ResourceManager.GetString("ksHCInvalidWordform", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to A phonological rule is using a feature variable for feature {0}, but there is no corresponding feature variable in the environment.. - /// - internal static string ksHCUninstFeature { - get { - return ResourceManager.GetString("ksHCUninstFeature", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The Hermit Crab parser cannot currently run, because the morpheme "{0}" has an invalid reduplication environment. The problem is {1}.. - /// - internal static string ksHermitCrabReduplicationProblem { - get { - return ResourceManager.GetString("ksHermitCrabReduplicationProblem", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to . - /// - internal static string ksIdle_ { - get { - return ResourceManager.GetString("ksIdle_", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Making HC Files. - /// - internal static string ksMakingHCFiles { - get { - return ResourceManager.GetString("ksMakingHCFiles", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Making XAmple Files. - /// - internal static string ksMakingXAmpleFiles { - get { - return ResourceManager.GetString("ksMakingXAmpleFiles", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Preparing Templates for XAmple Files. - /// - internal static string ksPreparingTemplatesForXAmple { - get { - return ResourceManager.GetString("ksPreparingTemplatesForXAmple", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to ???. - /// - internal static string ksQuestions { - get { - return ResourceManager.GetString("ksQuestions", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Maximum permitted analyses ({0}) reached.. - /// - internal static string ksReachedMaxAnalysesAllowed { - get { - return ResourceManager.GetString("ksReachedMaxAnalysesAllowed", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Maximum internal buffer size ({0}) reached.. - /// - internal static string ksReachedMaxInternalBufferSize { - get { - return ResourceManager.GetString("ksReachedMaxInternalBufferSize", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Retrieving Grammar and Lexicon. - /// - internal static string ksRetrievingGrammarAndLexicon { - get { - return ResourceManager.GetString("ksRetrievingGrammarAndLexicon", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Retrieving Template Information. - /// - internal static string ksRetrievingTemplateInformation { - get { - return ResourceManager.GetString("ksRetrievingTemplateInformation", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to started. - /// - internal static string ksStarted { - get { - return ResourceManager.GetString("ksStarted", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Trying Wordform {0}. - /// - internal static string ksTraceWordformX { - get { - return ResourceManager.GetString("ksTraceWordformX", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Updating: {0}. - /// - internal static string ksUpdateX { - get { - return ResourceManager.GetString("ksUpdateX", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Updating Grammar and Lexicon. - /// - internal static string ksUpdatingGrammarAndLexicon { - get { - return ResourceManager.GetString("ksUpdatingGrammarAndLexicon", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to {0}: error. - /// - internal static string ksX_error { - get { - return ResourceManager.GetString("ksX_error", resourceCulture); - } - } - } -} diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreStrings.resx b/Src/LexText/ParserEngine/ParserCore/ParserCoreStrings.resx deleted file mode 100644 index a12f333673..0000000000 --- a/Src/LexText/ParserEngine/ParserCore/ParserCoreStrings.resx +++ /dev/null @@ -1,197 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Bad Affix Form - Caption that goes with ksHermitCrabReduplicationProblem - - - Creating {0} - - - Parse was not attempted because of errors in the lexical data - - - error encountered - - - finished - - - The parser gave the following cryptic message (you may need to contact FieldWorks support to know what it means): {0} - - - The phoneme {0} of lexical entry {1} is not defined. Please make sure all phonemes in all allomorphs of all entries have been defined. - - - The phoneme {0} of affix {1} is not defined. Please make sure all phonemes in all allomorphs of all affixes have been defined. - - - There is at least one undefined phoneme in the word '{0}'. The following phonemes were parsed: '{3}'. The problem begins with character/diacritic number {1} – that is, in the part of the word '{2}'. Please make sure all phonemes in the word have been defined. - - - A phonological rule is using a feature variable for feature {0}, but there is no corresponding feature variable in the environment. - - - The Hermit Crab parser cannot currently run, because the morpheme "{0}" has an invalid reduplication environment. The problem is {1}. - - - - - - Making HC Files - - - Making XAmple Files - - - Preparing Templates for XAmple Files - - - ??? - missiing/undefined information - - - Maximum permitted analyses ({0}) reached. - - - Maximum internal buffer size ({0}) reached. - - - Retrieving Grammar and Lexicon - - - Retrieving Template Information - - - started - - - Trying Wordform {0} - - - Updating: {0} - - - Updating Grammar and Lexicon - - - {0}: error - - \ No newline at end of file diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/App.config b/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/App.config deleted file mode 100644 index 8d329647ba..0000000000 --- a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/App.config +++ /dev/null @@ -1,22 +0,0 @@ - - - - -
- - - - - - - - - - - - - - - - - diff --git a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/ParseFilerProcessingTests.cs b/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/ParseFilerProcessingTests.cs deleted file mode 100644 index 0eb3d81f69..0000000000 --- a/Src/LexText/ParserEngine/ParserCore/ParserCoreTests/ParseFilerProcessingTests.cs +++ /dev/null @@ -1,703 +0,0 @@ -// Copyright (c) 2003-2013 SIL International -// This software is licensed under the LGPL, version 2.1 or later -// (http://www.gnu.org/licenses/lgpl-2.1.html) -// -// File: ParseFilerProcessingTests.cs -// Responsibility: Randy Regnier -// Last reviewed: -// -// -// Implements the ParseFilerProcessingTests unit tests. -// -// buildtest ParseFiler-nodep - -using System; -using System.Linq; -using NUnit.Framework; -using SIL.CoreImpl; -using SIL.FieldWorks.FDO; -using SIL.FieldWorks.FDO.Infrastructure; -using SIL.FieldWorks.FDO.FDOTests; -using SIL.Utils; - -namespace SIL.FieldWorks.WordWorks.Parser -{ - /// - /// Summary description for ParseFilerProcessingTests. - /// - [TestFixture] - public class ParseFilerProcessingTests : MemoryOnlyBackendProviderTestBase - { - #region Data Members - - private ParseFiler m_filer; - private IdleQueue m_idleQueue; - private IWritingSystem m_vernacularWS; - private ILexEntryFactory m_entryFactory; - private ILexSenseFactory m_senseFactory; - private IMoStemAllomorphFactory m_stemAlloFactory; - private IMoAffixAllomorphFactory m_afxAlloFactory; - private IMoStemMsaFactory m_stemMsaFactory; - private IMoInflAffMsaFactory m_inflAffMsaFactory; - private ILexEntryRefFactory m_lexEntryRefFactory; - private ILexEntryInflTypeFactory m_lexEntryInflTypeFactory; - - #endregion Data Members - - #region Non-test methods - - protected ICmAgent ParserAgent - { - get - { - return Cache.LanguageProject.DefaultParserAgent; - } - } - - protected ICmAgent HumanAgent - { - get - { - return Cache.LanguageProject.DefaultUserAgent; - } - } - - protected IWfiWordform CheckAnnotationSize(string form, int expectedSize, bool isStarting) - { - var servLoc = Cache.ServiceLocator; - var wf = FindOrCreateWordform(form); - var actualSize = - (from ann in servLoc.GetInstance().AllInstances() - where ann.BeginObjectRA == wf - select ann).Count(); - // wf.RefsFrom_CmBaseAnnotation_BeginObject.Count; - var msg = String.Format("Wrong number of {0} annotations for: {1}", isStarting ? "starting" : "ending", form); - Assert.AreEqual(expectedSize, actualSize, msg); - return wf; - } - - private IWfiWordform FindOrCreateWordform(string form) - { - var servLoc = Cache.ServiceLocator; - var wf = servLoc.GetInstance().GetMatchingWordform(m_vernacularWS.Handle, form); - if (wf == null) - { - UndoableUnitOfWorkHelper.Do("Undo create", "Redo create", m_actionHandler, - () => wf = servLoc.GetInstance().Create(Cache.TsStrFactory.MakeString(form, m_vernacularWS.Handle))); - } - return wf; - } - - protected IWfiWordform CheckAnalysisSize(string form, int expectedSize, bool isStarting) - { - var wf = FindOrCreateWordform(form); - var actualSize = wf.AnalysesOC.Count; - var msg = String.Format("Wrong number of {0} analyses for: {1}", isStarting ? "starting" : "ending", form); - Assert.AreEqual(expectedSize, actualSize, msg); - return wf; - } - - protected void CheckEvaluationSize(IWfiAnalysis analysis, int expectedSize, bool isStarting, string additionalMessage) - { - var actualSize = analysis.EvaluationsRC.Count; - var msg = String.Format("Wrong number of {0} evaluations for analysis: {1} ({2})", isStarting ? "starting" : "ending", analysis.Hvo, additionalMessage); - Assert.AreEqual(expectedSize, actualSize, msg); - } - - protected void ExecuteIdleQueue() - { - foreach (var task in m_idleQueue) - task.Delegate(task.Parameter); - m_idleQueue.Clear(); - } - - #endregion // Non-tests - - #region Setup and TearDown - - public override void FixtureSetup() - { - base.FixtureSetup(); - m_vernacularWS = Cache.ServiceLocator.WritingSystems.DefaultVernacularWritingSystem; - m_idleQueue = new IdleQueue {IsPaused = true}; - m_filer = new ParseFiler(Cache, task => {}, m_idleQueue, Cache.LanguageProject.DefaultParserAgent); - m_entryFactory = Cache.ServiceLocator.GetInstance(); - m_senseFactory = Cache.ServiceLocator.GetInstance(); - m_stemAlloFactory = Cache.ServiceLocator.GetInstance(); - m_afxAlloFactory = Cache.ServiceLocator.GetInstance(); - m_stemMsaFactory = Cache.ServiceLocator.GetInstance(); - m_inflAffMsaFactory = Cache.ServiceLocator.GetInstance(); - m_lexEntryRefFactory = Cache.ServiceLocator.GetInstance(); - m_lexEntryInflTypeFactory = Cache.ServiceLocator.GetInstance(); - } - - public override void FixtureTeardown() - { - m_vernacularWS = null; - m_filer.Dispose(); - m_filer = null; - m_idleQueue.Dispose(); - m_idleQueue = null; - m_entryFactory = null; - m_senseFactory = null; - m_stemAlloFactory = null; - m_afxAlloFactory = null; - m_stemMsaFactory = null; - m_inflAffMsaFactory = null; - m_lexEntryRefFactory = null; - m_lexEntryInflTypeFactory = null; - - base.FixtureTeardown(); - } - - public override void TestTearDown() - { - UndoAll(); - base.TestTearDown(); - } - - /// ------------------------------------------------------------------------------------ - /// - /// End the undoable UOW and Undo everything. - /// - /// ------------------------------------------------------------------------------------ - protected void UndoAll() - { - // Undo the UOW (or more than one of them, if the test made new ones). - while (m_actionHandler.CanUndo()) - m_actionHandler.Undo(); - - // Need to 'Commit' to clear out redo stack, - // since nothing is really saved. - m_actionHandler.Commit(); - } - - #endregion Setup and TearDown - - #region Tests - - [Test] - public void TooManyAnalyses() - { - var bearsTEST = CheckAnnotationSize("bearsTEST", 0, true); - var xmlFragment = "" + Environment.NewLine - + "" + Environment.NewLine - + ""; - m_filer.ProcessParse(ParserPriority.Low, xmlFragment, 0); - ExecuteIdleQueue(); - CheckAnnotationSize("bearsTEST", 1, false); - } - - [Test] - public void BufferOverrun() - { - var dogsTEST = CheckAnnotationSize("dogsTEST", 0, true); - var xmlFragment = "" + Environment.NewLine - + "" + Environment.NewLine - + ""; - m_filer.ProcessParse(ParserPriority.Low, xmlFragment, 0); - ExecuteIdleQueue(); - CheckAnnotationSize("dogsTEST", 1, false); - } - - [Test] - public void TwoAnalyses() - { - var catsTEST = CheckAnalysisSize("catsTEST", 0, true); - var ldb = Cache.LanguageProject.LexDbOA; - - string xmlFragment = null; - UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => - { - // Noun - var catN = m_entryFactory.Create(); - var catNForm = m_stemAlloFactory.Create(); - catN.AlternateFormsOS.Add(catNForm); - catNForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("catNTEST", m_vernacularWS.Handle); - var catNMSA = m_stemMsaFactory.Create(); - catN.MorphoSyntaxAnalysesOC.Add(catNMSA); - - var sPL = m_entryFactory.Create(); - var sPLForm = m_afxAlloFactory.Create(); - sPL.AlternateFormsOS.Add(sPLForm); - sPLForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("sPLTEST", m_vernacularWS.Handle); - var sPLMSA = m_inflAffMsaFactory.Create(); - sPL.MorphoSyntaxAnalysesOC.Add(sPLMSA); - - // Verb - var catV = m_entryFactory.Create(); - var catVForm = m_stemAlloFactory.Create(); - catV.AlternateFormsOS.Add(catVForm); - catVForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("catVTEST", m_vernacularWS.Handle); - var catVMSA = m_stemMsaFactory.Create(); - catV.MorphoSyntaxAnalysesOC.Add(catVMSA); - - var sAGR = m_entryFactory.Create(); - var sAGRForm = m_afxAlloFactory.Create(); - sAGR.AlternateFormsOS.Add(sAGRForm); - sAGRForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("sAGRTEST", m_vernacularWS.Handle); - var sAGRMSA = m_inflAffMsaFactory.Create(); - sAGR.MorphoSyntaxAnalysesOC.Add(sAGRMSA); - - xmlFragment = "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine; - }); - - m_filer.ProcessParse(ParserPriority.Low, xmlFragment, 0); - ExecuteIdleQueue(); - CheckAnalysisSize("catsTEST", 2, false); - } - - [Test] - [Ignore("Is it ever possible for a parser to return more than one wordform parse?")] - public void TwoWordforms() - { - var snakeTEST = CheckAnalysisSize("snakeTEST", 0, true); - var bullTEST = CheckAnalysisSize("bullTEST", 0, true); - var ldb = Cache.LanguageProject.LexDbOA; - - string xmlFragment = null; - UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => - { - // Snake - var snakeN = m_entryFactory.Create(); - var snakeNForm = m_stemAlloFactory.Create(); - snakeN.AlternateFormsOS.Add(snakeNForm); - snakeNForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("snakeNTEST", m_vernacularWS.Handle); - var snakeNMSA = m_stemMsaFactory.Create(); - snakeN.MorphoSyntaxAnalysesOC.Add(snakeNMSA); - - // Bull - var bullN = m_entryFactory.Create(); - var bullNForm = m_stemAlloFactory.Create(); - bullN.AlternateFormsOS.Add(bullNForm); - bullNForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("bullNTEST", m_vernacularWS.Handle); - var bullNMSA = m_stemMsaFactory.Create(); - bullN.MorphoSyntaxAnalysesOC.Add(bullNMSA); - - xmlFragment = "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine; - }); - - m_filer.ProcessParse(ParserPriority.Low, xmlFragment, 0); - ExecuteIdleQueue(); - CheckAnalysisSize("snakeTEST", 1, false); - CheckAnalysisSize("bullTEST", 1, false); - } - - /// - /// Ensure analyses with 'duplicate' analyses are both approved. - /// "Duplicate" means the MSA and MoForm IDs are the same in two different analyses. - /// - [Test] - public void DuplicateAnalysesApproval() - { - var pigsTEST = CheckAnalysisSize("pigsTEST", 0, true); - - string xmlFragment = null; - IWfiAnalysis anal1 = null, anal2 = null, anal3 = null; - UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => - { - // Bear entry - var pigN = m_entryFactory.Create(); - var pigNForm = m_stemAlloFactory.Create(); - pigN.AlternateFormsOS.Add(pigNForm); - pigNForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("pigNTEST", m_vernacularWS.Handle); - var pigNMSA = m_stemMsaFactory.Create(); - pigN.MorphoSyntaxAnalysesOC.Add(pigNMSA); - var pigNLS = Cache.ServiceLocator.GetInstance().Create(); - pigN.SensesOS.Add(pigNLS); - - var analFactory = Cache.ServiceLocator.GetInstance(); - var mbFactory = Cache.ServiceLocator.GetInstance(); - // First of two duplicate analyses - var anal = analFactory.Create(); - pigsTEST.AnalysesOC.Add(anal); - anal1 = anal; - var mb = mbFactory.Create(); - anal.MorphBundlesOS.Add(mb); - mb.MorphRA = pigNForm; - mb.MsaRA = pigNMSA; - CheckEvaluationSize(anal1, 0, true, "anal1"); - - // Non-duplicate, to make sure it does not get approved. - anal = analFactory.Create(); - pigsTEST.AnalysesOC.Add(anal); - anal2 = anal; - mb = mbFactory.Create(); - anal.MorphBundlesOS.Add(mb); - mb.SenseRA = pigNLS; - CheckEvaluationSize(anal2, 0, true, "anal2"); - - // Second of two duplicate analyses - anal = analFactory.Create(); - pigsTEST.AnalysesOC.Add(anal); - anal3 = anal; - mb = mbFactory.Create(); - anal.MorphBundlesOS.Add(mb); - mb.MorphRA = pigNForm; - mb.MsaRA = pigNMSA; - CheckEvaluationSize(anal3, 0, true, "anal3"); - CheckAnalysisSize("pigsTEST", 3, false); - - xmlFragment = "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine; - }); - - m_filer.ProcessParse(ParserPriority.Low, xmlFragment, 0); - ExecuteIdleQueue(); - CheckEvaluationSize(anal1, 1, false, "anal1Hvo"); - Assert.IsFalse(anal2.IsValidObject, "analysis 2 should end up with no evaluations and so be deleted"); - CheckEvaluationSize(anal3, 1, false, "anal3Hvo"); - } - - [Test] - public void HumanApprovedParserPreviouslyApprovedButNowRejectedAnalysisSurvives() - { - var theThreeLittlePigsTEST = CheckAnalysisSize("theThreeLittlePigsTEST", 0, true); - - string xmlFragment = null; - IWfiAnalysis anal = null; - UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => - { - // Pig entry - var pigN = m_entryFactory.Create(); - var pigNForm = m_stemAlloFactory.Create(); - pigN.AlternateFormsOS.Add(pigNForm); - pigNForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("pigNTEST", m_vernacularWS.Handle); - var pigNMSA = m_stemMsaFactory.Create(); - pigN.MorphoSyntaxAnalysesOC.Add(pigNMSA); - var pigNLS = Cache.ServiceLocator.GetInstance().Create(); - pigN.SensesOS.Add(pigNLS); - - // Human approved anal. Start with parser approved, but then it failed. - var analFactory = Cache.ServiceLocator.GetInstance(); - var mbFactory = Cache.ServiceLocator.GetInstance(); - // Only analysis: human approved, previously parser approved but no longer produced. - anal = analFactory.Create(); - theThreeLittlePigsTEST.AnalysesOC.Add(anal); - var mb = mbFactory.Create(); - anal.MorphBundlesOS.Add(mb); - mb.MorphRA = pigNForm; - mb.MsaRA = pigNMSA; - HumanAgent.SetEvaluation(anal, Opinions.approves); - ParserAgent.SetEvaluation(anal, Opinions.approves); - CheckEvaluationSize(anal, 2, true, "anal"); - CheckAnalysisSize("theThreeLittlePigsTEST", 1, true); - - xmlFragment = "" + Environment.NewLine - + "" + Environment.NewLine; - }); - - using (var idleQueue = new IdleQueue()) - using (var filer = new ParseFiler(Cache, task => { }, idleQueue, ParserAgent)) - { - idleQueue.IsPaused = true; - filer.ProcessParse(ParserPriority.Low, xmlFragment, 0); - foreach (var task in idleQueue) - task.Delegate(task.Parameter); - idleQueue.Clear(); - } - CheckEvaluationSize(anal, 1, false, "analHvo"); - Assert.IsTrue(anal.IsValidObject, "analysis should end up with one evaluation and not be deleted"); - } - - [Test] - public void HumanHasNoopinionParserHadApprovedButNoLongerApprovesRemovesAnalisys() - { - var threeLittlePigsTEST = CheckAnalysisSize("threeLittlePigsTEST", 0, true); - - string xmlFragment = null; - IWfiAnalysis anal = null; - UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => - { - // Pig entry - var pigN = m_entryFactory.Create(); - var pigNForm = m_stemAlloFactory.Create(); - pigN.AlternateFormsOS.Add(pigNForm); - pigNForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("pigNTEST", m_vernacularWS.Handle); - var pigNMSA = m_stemMsaFactory.Create(); - pigN.MorphoSyntaxAnalysesOC.Add(pigNMSA); - var pigNLS = Cache.ServiceLocator.GetInstance().Create(); - pigN.SensesOS.Add(pigNLS); - - // Human no-opinion anal. Parser had approved, but then it failed to produce it. - var analFactory = Cache.ServiceLocator.GetInstance(); - var mbFactory = Cache.ServiceLocator.GetInstance(); - // Human no-opinion anal. Parser had approved, but then it failed to produce it. - anal = analFactory.Create(); - threeLittlePigsTEST.AnalysesOC.Add(anal); - var mb = mbFactory.Create(); - anal.MorphBundlesOS.Add(mb); - mb.MorphRA = pigNForm; - mb.MsaRA = pigNMSA; - HumanAgent.SetEvaluation(anal, Opinions.noopinion); - ParserAgent.SetEvaluation(anal, Opinions.approves); - CheckEvaluationSize(anal, 1, true, "anal"); - CheckAnalysisSize("threeLittlePigsTEST", 1, true); - - xmlFragment = "" + Environment.NewLine - + "" + Environment.NewLine; - }); - - using (var idleQueue = new IdleQueue()) - using (var filer = new ParseFiler(Cache, task => { }, idleQueue, ParserAgent)) - { - idleQueue.IsPaused = true; - filer.ProcessParse(ParserPriority.Low, xmlFragment, 0); - foreach (var task in idleQueue) - task.Delegate(task.Parameter); - idleQueue.Clear(); - } - //CheckEvaluationSize(anal, 0, false, "analHvo"); - Assert.IsFalse(anal.IsValidObject, "analysis should end up with no evaluations and be deleted."); - } - - [Test] - public void LexEntryInflTypeTwoAnalyses() - { - var crebTEST = CheckAnalysisSize("crebTEST", 0, true); - var ldb = Cache.LanguageProject.LexDbOA; - - string xmlFragment = null; - UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => - { - // Verb creb which is a past tense, plural irregularly inflected form of 'believe' and also 'seek' - // with automatically generated null Tense slot and an automatically generated null Number slot filler - // (This is not supposed to be English, in case you're wondering....) - - var pastTenseLexEntryInflType = m_lexEntryInflTypeFactory.Create(); - var pluralTenseLexEntryInflType = m_lexEntryInflTypeFactory.Create(); - Cache.LangProject.LexDbOA.VariantEntryTypesOA.PossibilitiesOS.Add(pastTenseLexEntryInflType); - Cache.LangProject.LexDbOA.VariantEntryTypesOA.PossibilitiesOS.Add(pluralTenseLexEntryInflType); - - var believeV = m_entryFactory.Create(); - var believeVForm = m_stemAlloFactory.Create(); - believeV.AlternateFormsOS.Add(believeVForm); - believeVForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("believeVTEST", m_vernacularWS.Handle); - var believeVMSA = m_stemMsaFactory.Create(); - believeV.MorphoSyntaxAnalysesOC.Add(believeVMSA); - var believeVSense = m_senseFactory.Create(); - believeV.SensesOS.Add(believeVSense); - believeVSense.MorphoSyntaxAnalysisRA = believeVMSA; - - var seekV = m_entryFactory.Create(); - var seekVForm = m_stemAlloFactory.Create(); - believeV.AlternateFormsOS.Add(seekVForm); - seekVForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("seekVTEST", m_vernacularWS.Handle); - var seekVMSA = m_stemMsaFactory.Create(); - seekV.MorphoSyntaxAnalysesOC.Add(seekVMSA); - var seekVSense = m_senseFactory.Create(); - seekV.SensesOS.Add(seekVSense); - seekVSense.MorphoSyntaxAnalysisRA = seekVMSA; - - var crebV = m_entryFactory.Create(); - var crebVForm = m_stemAlloFactory.Create(); - crebV.AlternateFormsOS.Add(crebVForm); - crebVForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("crebVTEST", m_vernacularWS.Handle); - var lexEntryref = m_lexEntryRefFactory.Create(); - crebV.EntryRefsOS.Add(lexEntryref); - lexEntryref.ComponentLexemesRS.Add(believeV); - lexEntryref.VariantEntryTypesRS.Add(pastTenseLexEntryInflType); - lexEntryref.VariantEntryTypesRS.Add(pluralTenseLexEntryInflType); - lexEntryref = m_lexEntryRefFactory.Create(); - crebV.EntryRefsOS.Add(lexEntryref); - lexEntryref.ComponentLexemesRS.Add(seekV); - lexEntryref.VariantEntryTypesRS.Add(pastTenseLexEntryInflType); - lexEntryref.VariantEntryTypesRS.Add(pluralTenseLexEntryInflType); - - var nullPAST = m_entryFactory.Create(); - var nullPASTForm = m_afxAlloFactory.Create(); - nullPAST.AlternateFormsOS.Add(nullPASTForm); - nullPASTForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("nullPASTTEST", m_vernacularWS.Handle); - var nullPASTMSA = m_inflAffMsaFactory.Create(); - nullPAST.MorphoSyntaxAnalysesOC.Add(nullPASTMSA); - - var nullPLURAL = m_entryFactory.Create(); - var nullPLURALForm = m_afxAlloFactory.Create(); - nullPLURAL.AlternateFormsOS.Add(nullPLURALForm); - nullPLURALForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("nullPLURALTEST", m_vernacularWS.Handle); - var nullPluralMSA = m_inflAffMsaFactory.Create(); - nullPLURAL.MorphoSyntaxAnalysesOC.Add(nullPluralMSA); - - xmlFragment = "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine + "" + Environment.NewLine; - }); - - m_filer.ProcessParse(ParserPriority.Low, xmlFragment, 0); - ExecuteIdleQueue(); - CheckAnalysisSize("crebTEST", 2, false); - foreach (var analysis in crebTEST.AnalysesOC) - { - Assert.AreEqual(1, analysis.MorphBundlesOS.Count, "Expected only 1 morph in the analysis"); - var morphBundle = analysis.MorphBundlesOS.ElementAt(0); - Assert.IsNotNull(morphBundle.Form, "First bundle: form is not null"); - Assert.IsNotNull(morphBundle.MsaRA, "First bundle: msa is not null"); - Assert.IsNotNull(morphBundle.InflTypeRA, "First bundle: infl type is not null"); - } - } - - [Test] - public void LexEntryInflTypeAnalysisWithNullForSlotFiller() - { - var brubsTEST = CheckAnalysisSize("brubsTEST", 0, true); - var ldb = Cache.LanguageProject.LexDbOA; - - string xmlFragment = null; - UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => - { - // Verb brub which is a present tense irregularly inflected form of 'believe' - // with automatically generated null Tense slot and an -s Plural Number slot filler - // (This is not supposed to be English, in case you're wondering....) - - var presentTenseLexEntryInflType = m_lexEntryInflTypeFactory.Create(); - Cache.LangProject.LexDbOA.VariantEntryTypesOA.PossibilitiesOS.Add(presentTenseLexEntryInflType); - - var believeV = m_entryFactory.Create(); - var believeVForm = m_stemAlloFactory.Create(); - believeV.AlternateFormsOS.Add(believeVForm); - believeVForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("believeVTEST", m_vernacularWS.Handle); - var believeVMSA = m_stemMsaFactory.Create(); - believeV.MorphoSyntaxAnalysesOC.Add(believeVMSA); - var believeVSense = m_senseFactory.Create(); - believeV.SensesOS.Add(believeVSense); - believeVSense.MorphoSyntaxAnalysisRA = believeVMSA; - - var brubV = m_entryFactory.Create(); - var brubVForm = m_stemAlloFactory.Create(); - brubV.AlternateFormsOS.Add(brubVForm); - brubVForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("brubVTEST", m_vernacularWS.Handle); - var lexEntryref = m_lexEntryRefFactory.Create(); - brubV.EntryRefsOS.Add(lexEntryref); - lexEntryref.ComponentLexemesRS.Add(believeV); - lexEntryref.VariantEntryTypesRS.Add(presentTenseLexEntryInflType); - - var nullPRESENT = m_entryFactory.Create(); - var nullPRESENTForm = m_afxAlloFactory.Create(); - nullPRESENT.AlternateFormsOS.Add(nullPRESENTForm); - nullPRESENTForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("nullPRESENTTEST", m_vernacularWS.Handle); - var nullPRESENTMSA = m_inflAffMsaFactory.Create(); - nullPRESENT.MorphoSyntaxAnalysesOC.Add(nullPRESENTMSA); - - var sPLURAL = m_entryFactory.Create(); - var sPLURALForm = m_afxAlloFactory.Create(); - sPLURAL.AlternateFormsOS.Add(sPLURALForm); - sPLURALForm.Form.VernacularDefaultWritingSystem = Cache.TsStrFactory.MakeString("sPLURALTEST", m_vernacularWS.Handle); - var sPluralMSA = m_inflAffMsaFactory.Create(); - sPLURAL.MorphoSyntaxAnalysesOC.Add(sPluralMSA); - - xmlFragment = "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine - + "" + Environment.NewLine; - }); - - m_filer.ProcessParse(ParserPriority.Low, xmlFragment, 0); - ExecuteIdleQueue(); - CheckAnalysisSize("brubsTEST", 1, false); - var analysis = brubsTEST.AnalysesOC.ElementAt(0); - Assert.AreEqual(2, analysis.MorphBundlesOS.Count, "Expected only 2 morphs in the analysis"); - var morphBundle = analysis.MorphBundlesOS.ElementAt(0); - Assert.IsNotNull(morphBundle.Form, "First bundle: form is not null"); - Assert.IsNotNull(morphBundle.MsaRA, "First bundle: msa is not null"); - Assert.IsNotNull(morphBundle.InflTypeRA, "First bundle: infl type is not null"); - } - - #endregion // Tests - } -} diff --git a/Src/LexText/ParserEngine/ParserCore/Worker.cs b/Src/LexText/ParserEngine/ParserCore/Worker.cs deleted file mode 100644 index c01b6edd7d..0000000000 --- a/Src/LexText/ParserEngine/ParserCore/Worker.cs +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright (c) 2003-2013 SIL International -// This software is licensed under the LGPL, version 2.1 or later -// (http://www.gnu.org/licenses/lgpl-2.1.html) -// -// File: ParserWorker.cs -// Responsibility: -// -// -// The name here, "worker" would lead one to think that this is the -// class which is the top of the heap of the worker thread. -// However, it is actually the "Scheduler" class which controls the thread and calls this. -// -// -------------------------------------------------------------------------------------------- -/* - -throws exception: * One way I recall is that they would create an inflectional template, but not put anything in it yet (i.e. no slots at all). - * This causes XAmple to die because it produces a PC-PATR load error. - * This could be fixed, of course, in the XSLT that generates the grammar file. - * This one's on my TODO list (I've got the sticky note from Dallas)... - - -no exception: Try an adhoc prohibition with only one item in it - -no exception: Create a compound with neither member specified or only one specified. - -no exception: Create an allomorph with an environment that is ill-formed. (Presumably this will result in the same problem as breaking an environment for an existing allomorph.) - -no exception: Create an infl affix slot with no affixes in it and then use this slot in a template (though this just might not cause the parser to fail - it would just be useless!). - -*/ -using System; -using System.Diagnostics; -using System.Text; -using System.Xml; - -using CodeProject.ReiMiyasaka; - -using SIL.Utils; -using SIL.FieldWorks.FDO; -using SIL.FieldWorks.FDO.Infrastructure; -using SIL.FieldWorks.Common.COMInterfaces; - -namespace SIL.FieldWorks.WordWorks.Parser -{ - /// - /// Summary description for ParserWorker. - /// - public abstract class ParserWorker : FwDisposableBase - { - protected readonly FdoCache m_cache; - protected readonly Action m_taskUpdateHandler; - private readonly ParseFiler m_parseFiler; - private long m_ticksParser; - private int m_numberOfWordForms; - protected readonly M3ParserModelRetriever m_retriever; - - protected string m_projectName; - protected TraceSwitch m_tracingSwitch = new TraceSwitch("ParserCore.TracingSwitch", "Just regular tracking", "Off"); - - /// ----------------------------------------------------------------------------------- - /// - /// Initializes a new instance of the class. - /// - /// ----------------------------------------------------------------------------------- - protected ParserWorker(FdoCache cache, Action taskUpdateHandler, IdleQueue idleQueue, ICmAgent agent) - { - m_cache = cache; - m_taskUpdateHandler = taskUpdateHandler; - m_parseFiler = new ParseFiler(cache, taskUpdateHandler, idleQueue, agent); - // N.B. m_projectName here is only used to create temporary files for the parser to load. - // We convert the name to use strictly ANSI characters so that the parsers (which are or involve - // legacy C programs) can read the file names. - m_projectName = ConvertNameToUseANSICharacters(cache.ProjectId.Name); - m_retriever = new M3ParserModelRetriever(m_cache, m_taskUpdateHandler); - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "ParserWorker(): CurrentThreadId = " + Win32.GetCurrentThreadId()); - } - - /// - /// Convert any characters in the name which are higher than 0x00FF to hex. - /// Neither XAmple nor PC-PATR can read a file name containing letters above 0x00FF. - /// - /// The original name to be converted - /// Converted name - public static string ConvertNameToUseANSICharacters(string originalName) - { - StringBuilder sb = new StringBuilder(); - char[] letters = originalName.ToCharArray(); - foreach (var letter in letters) - { - int value = Convert.ToInt32(letter); - if (value > 255) - { - string hex = value.ToString("X4"); - sb.Append(hex); - } - else - { - sb.Append(letter); - } - } - return sb.ToString(); - } - - protected override void DisposeManagedResources() - { - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "Total number of wordforms parsed = " + m_numberOfWordForms); - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "Total time for parser = " + m_ticksParser); - - if (m_numberOfWordForms != 0) - { - long lAvg = m_ticksParser/m_numberOfWordForms; - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "Average time for parser = " + lAvg); - } - - m_parseFiler.Dispose(); - m_retriever.Dispose(); - } - - public ParseFiler ParseFiler - { - get - { - CheckDisposed(); - return m_parseFiler; - } - } - - protected abstract string ParseWord(string form, int hvoWordform); - protected abstract string TraceWord(string form, string selectTraceMorphs); - - private string GetOneWordformResult(int hvoWordform, string form) - { - Debug.Assert(hvoWordform > 0, "Wordform ID must be greater than zero."); - Debug.Assert(form != null, "Wordform form must not be null."); - - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "GetOneWordformResult(): CurrentThreadId = " + Win32.GetCurrentThreadId()); - var startTime = DateTime.Now; - var results = ParseWord(Icu.Normalize(form, Icu.UNormalizationMode.UNORM_NFD), hvoWordform); - long ttlTicks = DateTime.Now.Ticks - startTime.Ticks; - m_ticksParser += ttlTicks; - m_numberOfWordForms++; - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "ParseWord(" + form + ") took : " + ttlTicks); - return Icu.Normalize(results, Icu.UNormalizationMode.UNORM_NFD); - } - - /// - /// Try parsing a wordform, optionally getting a trace of the parse - /// - /// the word form to parse - /// whether or not to trace the parse - /// list of msa hvos to limit trace to - public void TryAWord(string sForm, bool fDoTrace, string sSelectTraceMorphs) - { - CheckDisposed(); - - if (sForm == null) - throw new ArgumentNullException("sForm", "TryAWord cannot trace a Null string."); - if (sForm == String.Empty) - throw new ArgumentException("Can't try a word with no content.", "sForm"); - - CheckNeedsUpdate(); - using (var task = new TaskReport(string.Format(ParserCoreStrings.ksTraceWordformX, sForm), m_taskUpdateHandler)) - { - var normForm = Icu.Normalize(sForm, Icu.UNormalizationMode.UNORM_NFD); - var result = fDoTrace ? TraceWord(normForm, sSelectTraceMorphs) : ParseWord(normForm, 0); - if (fDoTrace) - task.Details = result; - else - task.Details = Icu.Normalize(result, Icu.UNormalizationMode.UNORM_NFD); - } - } - - public bool UpdateWordform(IWfiWordform wordform, ParserPriority priority) - { - CheckDisposed(); - - uint crcWordform = 0; - ITsString form = null; - int hvo = 0; - using (new WorkerThreadReadHelper(m_cache.ServiceLocator.GetInstance())) - { - if (wordform.IsValidObject) - { - crcWordform = (uint) wordform.Checksum; - form = wordform.Form.VernacularDefaultWritingSystem; - hvo = wordform.Hvo; - } - } - // 'form' will now be null, if it could not find the wordform for whatever reason. - // uiCRCWordform will also now be 0, if 'form' is null. - if (form == null || string.IsNullOrEmpty(form.Text)) - return false; - - CheckNeedsUpdate(); - string result = GetOneWordformResult(hvo, form.Text.Replace(' ', '.')); // LT-7334 to allow for phrases - uint crc = CrcStream.GetCrc(result); - if (crcWordform == crc) - return false; - - return m_parseFiler.ProcessParse(priority, result, crc); - } - - public void ReloadGrammarAndLexicon() - { - CheckDisposed(); - - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "ParserWorker.ReloadGrammarAndLexicon"); - m_retriever.Reset(); - CheckNeedsUpdate(); - } - - private void CheckNeedsUpdate() - { - DateTime startTime = DateTime.Now; - if (m_retriever.RetrieveModel()) - { - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "Model retrieval took : " + (DateTime.Now.Ticks - startTime.Ticks)); - XmlDocument fxtResult = m_retriever.ModelDom; - XmlDocument gafawsFxtResult = m_retriever.TemplateDom; - LoadParser(ref fxtResult, gafawsFxtResult); - } - } - - protected abstract void LoadParser(ref XmlDocument model, XmlDocument template); - } -} diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.sln b/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.sln deleted file mode 100644 index a0b770cfa0..0000000000 --- a/Src/LexText/ParserEngine/ParserCore/XAmpleCOMWrapper/XAmpleCOMWrapper.sln +++ /dev/null @@ -1,63 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XAmpleCOMWrapper", "XAmpleCOMWrapper.vcproj", "{D841AF80-C339-4523-9919-1E645F41D08E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParserCore", "..\ParserCore.csproj", "{116BE16A-B3A0-408C-A5CD-25BCBBDBE327}" -EndProject -Global - GlobalSection(SourceCodeControl) = preSolution - SccNumberOfProjects = 3 - SccProjectName0 = Perforce\u0020Project - SccLocalPath0 = . - SccProvider0 = MSSCCI:Perforce\u0020SCM - CanCheckoutShared = true - SccProjectUniqueName1 = XAmpleCOMWrapper.vcproj - SccLocalPath1 = . - CanCheckoutShared = true - SccProjectUniqueName2 = ..\\ParserCore.csproj - SccLocalPath2 = .. - CanCheckoutShared = true - EndGlobalSection - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Bounds|Any CPU = Bounds|Any CPU - Bounds|Mixed Platforms = Bounds|Mixed Platforms - Bounds|Win32 = Bounds|Win32 - Debug|Any CPU = Debug|Any CPU - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|Win32 = Debug|Win32 - Release|Any CPU = Release|Any CPU - Release|Mixed Platforms = Release|Mixed Platforms - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D841AF80-C339-4523-9919-1E645F41D08E}.Bounds|Any CPU.ActiveCfg = Bounds|Win32 - {D841AF80-C339-4523-9919-1E645F41D08E}.Bounds|Mixed Platforms.ActiveCfg = Bounds|Win32 - {D841AF80-C339-4523-9919-1E645F41D08E}.Bounds|Mixed Platforms.Build.0 = Bounds|Win32 - {D841AF80-C339-4523-9919-1E645F41D08E}.Bounds|Win32.ActiveCfg = Bounds|Win32 - {D841AF80-C339-4523-9919-1E645F41D08E}.Bounds|Win32.Build.0 = Bounds|Win32 - {D841AF80-C339-4523-9919-1E645F41D08E}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {D841AF80-C339-4523-9919-1E645F41D08E}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {D841AF80-C339-4523-9919-1E645F41D08E}.Debug|Win32.ActiveCfg = Debug|Win32 - {D841AF80-C339-4523-9919-1E645F41D08E}.Debug|Win32.Build.0 = Debug|Win32 - {D841AF80-C339-4523-9919-1E645F41D08E}.Release|Any CPU.ActiveCfg = Release|Win32 - {D841AF80-C339-4523-9919-1E645F41D08E}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {D841AF80-C339-4523-9919-1E645F41D08E}.Release|Win32.ActiveCfg = Release|Win32 - {D841AF80-C339-4523-9919-1E645F41D08E}.Release|Win32.Build.0 = Release|Win32 - {116BE16A-B3A0-408C-A5CD-25BCBBDBE327}.Bounds|Any CPU.ActiveCfg = Release|Any CPU - {116BE16A-B3A0-408C-A5CD-25BCBBDBE327}.Bounds|Any CPU.Build.0 = Release|Any CPU - {116BE16A-B3A0-408C-A5CD-25BCBBDBE327}.Bounds|Mixed Platforms.ActiveCfg = Release|Any CPU - {116BE16A-B3A0-408C-A5CD-25BCBBDBE327}.Bounds|Mixed Platforms.Build.0 = Release|Any CPU - {116BE16A-B3A0-408C-A5CD-25BCBBDBE327}.Bounds|Win32.ActiveCfg = Release|Any CPU - {116BE16A-B3A0-408C-A5CD-25BCBBDBE327}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {116BE16A-B3A0-408C-A5CD-25BCBBDBE327}.Debug|Any CPU.Build.0 = Debug|Any CPU - {116BE16A-B3A0-408C-A5CD-25BCBBDBE327}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {116BE16A-B3A0-408C-A5CD-25BCBBDBE327}.Debug|Win32.ActiveCfg = Debug|Any CPU - {116BE16A-B3A0-408C-A5CD-25BCBBDBE327}.Release|Any CPU.ActiveCfg = Release|Any CPU - {116BE16A-B3A0-408C-A5CD-25BCBBDBE327}.Release|Any CPU.Build.0 = Release|Any CPU - {116BE16A-B3A0-408C-A5CD-25BCBBDBE327}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {116BE16A-B3A0-408C-A5CD-25BCBBDBE327}.Release|Win32.ActiveCfg = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/App.config b/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/App.config deleted file mode 100644 index 8d329647ba..0000000000 --- a/Src/LexText/ParserEngine/ParserCore/XAmpleManagedWrapper/XAmpleManagedWrapperTests/App.config +++ /dev/null @@ -1,22 +0,0 @@ - - - - -
- - - - - - - - - - - - - - - - - diff --git a/Src/LexText/ParserEngine/ParserCore/XAmpleWorker.cs b/Src/LexText/ParserEngine/ParserCore/XAmpleWorker.cs deleted file mode 100644 index c016a30e6f..0000000000 --- a/Src/LexText/ParserEngine/ParserCore/XAmpleWorker.cs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) 2003-2013 SIL International -// This software is licensed under the LGPL, version 2.1 or later -// (http://www.gnu.org/licenses/lgpl-2.1.html) -// -// File: XAmpleWorker.cs -// Responsibility: FLEx Team - -using System; -using System.Diagnostics; -using System.Xml; -using System.IO; - -using SIL.FieldWorks.FDO; -using SIL.Utils; -using XAmpleManagedWrapper; -using SIL.FieldWorks.Common.FwUtils; - -namespace SIL.FieldWorks.WordWorks.Parser -{ - public class XAmpleParserWorker : ParserWorker - { - private XAmpleWrapper m_xample; - - public XAmpleParserWorker(FdoCache cache, Action taskUpdateHandler, IdleQueue idleQueue) - : base(cache, taskUpdateHandler, idleQueue, - cache.ServiceLocator.GetInstance().GetObject(CmAgentTags.kguidAgentXAmpleParser)) - { - m_xample = new XAmpleWrapper(); - m_xample.Init(DirectoryFinder.FWCodeDirectory); - } - - protected override string ParseWord(string form, int hvoWordform) - { - return CompleteAmpleResults(m_xample.ParseWord(form), hvoWordform); - } - - protected override string TraceWord(string form, string selectTraceMorphs) - { - return m_xample.TraceWord(form, selectTraceMorphs); - } - - /// - /// XAmple does not know the hvo of the Wordform. - /// Thus it leaves a pattern which we need to replace with the actual hvo. - /// - /// It would be nice if this was done down in the XAmple wrapper. - /// However, I despaired of doing this simple replacement using bstrs, so I am doing it here. - /// - /// - /// - /// - private static string CompleteAmpleResults(string rawAmpleResults, int hvoWordform) - { - // REVIEW Jonh(RandyR): This should probably be a simple assert, - // since it is a programming error in the XAmple COM dll. - if (rawAmpleResults == null) - throw new ApplicationException("XAmpleCOM Dll failed to return any results. " - + "[NOTE: This is a programming error. See WPS-24 in JIRA.]"); - - //find any instance of "<...>" which must be replaced with "[..]" - this indicates full reduplication - const string ksFullRedupMarker = "<...>"; - var sTemp = rawAmpleResults.Replace(ksFullRedupMarker, "[...]"); - //find the "DB_REF_HERE" which must be replaced with the actual hvo - const string kmatch = "DB_REF_HERE"; - Debug.Assert(sTemp.IndexOf(kmatch) > 0, - "There was a problem interpretting the response from XAMPLE. " + kmatch + " was not found."); - return sTemp.Replace(kmatch, "'" + hvoWordform + "'"); - } - - /// - /// Loads the parser. - /// - /// The model. - /// The template. - protected override void LoadParser(ref XmlDocument model, XmlDocument template) - { - var transformer = new M3ToXAmpleTransformer(m_projectName, m_taskUpdateHandler); - var startTime = DateTime.Now; - // PrepareTemplatesForXAmpleFiles adds orderclass elements to MoInflAffixSlot elements - transformer.PrepareTemplatesForXAmpleFiles(ref model, template); - var ttlTicks = DateTime.Now.Ticks - startTime.Ticks; - Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "GAFAWS prep took : " + ttlTicks); - - transformer.MakeAmpleFiles(model); - - int maxAnalCount = 20; - XmlNode maxAnalCountNode = model.SelectSingleNode("/M3Dump/ParserParameters/XAmple/MaxAnalysesToReturn"); - if (maxAnalCountNode != null) - { - maxAnalCount = Convert.ToInt16(maxAnalCountNode.FirstChild.Value); - if (maxAnalCount < 1) - maxAnalCount = -1; - } - - m_xample.SetParameter("MaxAnalysesToReturn", maxAnalCount.ToString()); - - string tempPath = Path.GetTempPath(); - m_xample.LoadFiles(DirectoryFinder.FWCodeDirectory + @"/Language Explorer/Configuration/Grammar", - tempPath, m_projectName); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Override to dispose unmanaged resources. - /// - /// ------------------------------------------------------------------------------------ - protected override void DisposeUnmanagedResources() - { - if (m_xample != null) - { - m_xample.Dispose(); - m_xample = null; - } - } - } -} \ No newline at end of file diff --git a/Src/LexText/ParserUI/HCTrace.cs b/Src/LexText/ParserUI/HCTrace.cs index 53dc3dac2b..4ba70cb2f2 100644 --- a/Src/LexText/ParserUI/HCTrace.cs +++ b/Src/LexText/ParserUI/HCTrace.cs @@ -1,105 +1,58 @@ -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; -using System.Xml; -using SIL.Utils; +using System.Xml.Linq; +using System.Xml.Xsl; +using SIL.FieldWorks.FDO; using XCore; namespace SIL.FieldWorks.LexText.Controls { + [SuppressMessage("Gendarme.Rules.Design", "TypesWithDisposableFieldsShouldBeDisposableRule", + Justification="m_cache and m_mediator are references")] public class HCTrace : ParserTrace { - /// - /// Temp File names - /// - const string m_ksHCParse = "HCParse"; - const string m_ksHCTrace = "HCTrace"; - - /// - /// For testing - /// - public HCTrace() + private static ParserTraceUITransform s_traceTransform; + private static ParserTraceUITransform TraceTransform { + get + { + if (s_traceTransform == null) + s_traceTransform = new ParserTraceUITransform("FormatHCTrace"); + return s_traceTransform; + } } + + private readonly Mediator m_mediator; + private readonly FdoCache m_cache; + /// /// The real deal /// /// public HCTrace(Mediator mediator) - : base(mediator) - { - m_sParse = m_ksHCParse; - m_sTrace = m_ksHCTrace; - m_sFormatParse = "FormatXAmpleParse.xsl"; // the XAmple one works fine with Hermit Crab parse output - m_sFormatTrace = "FormatHCTrace.xsl"; - - } - - /// - /// Initialize what is needed to perform the word grammar debugging and - /// produce an html page showing the results - /// - /// Id of the node to use - /// the wordform being tried - /// - /// temporary html file showing the results of the first step - public override string SetUpWordGrammarDebuggerPage(string sNodeId, string sForm, string sLastURL) { - m_wordGrammarDebugger = new HCWordGrammarDebugger(m_mediator, m_parseResult); - return m_wordGrammarDebugger.SetUpWordGrammarDebuggerPage(sNodeId, sForm, sLastURL); + m_mediator = mediator; + m_cache = (FdoCache) m_mediator.PropertyTable.GetValue("cache"); } - public override string CreateResultPage(string result) + public override string CreateResultPage(XDocument result, bool isTrace) { - bool fIsTrace = result.Contains(""); - - m_parseResult = new XmlDocument(); - m_parseResult.LoadXml(result); - ConvertHvosToStrings(fIsTrace); - - AddMsaNodes(false); - - string sInput = CreateTempFile(m_sTrace, "xml"); - m_parseResult.Save(sInput); - - TransformKind kind = (fIsTrace ? TransformKind.kcptTrace : TransformKind.kcptParse); - string sOutput = TransformToHtml(sInput, kind); - return sOutput; - } - - private void ConvertHvosToStrings(bool fIsTrace) - { - if (fIsTrace) + ParserTraceUITransform transform; + string baseName; + if (isTrace) { - ConvertMorphs(m_parseResult, "//RuleAllomorph/Morph | //RootAllomorph/Morph | //Morphs/Morph | //Others/Allomorph/Morph", false); - //ConvertMorphs(doc, "//WordGrammarAttempt/Morphs", true); + WordGrammarDebugger = new HCWordGrammarDebugger(m_mediator, result); + transform = TraceTransform; + baseName = "HCTrace"; } else { - ConvertMorphs(m_parseResult, "//Morphs/Morph", false); + transform = ParseTransform; + baseName = "HCParse"; } - } - - [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", - Justification = "In .NET 4.5 XmlNodeList implements IDisposable, but not in 4.0.")] - protected override void CreateMorphNodes(XmlDocument doc, XmlNode seqNode, string sNodeId) - { - string s = "//WordGrammarAttempt[Id=\"" + sNodeId + "\"]"; - XmlNode node = m_parseResult.SelectSingleNode(s); - if (node != null) - { - XmlNodeList morphs = node.SelectNodes("Morphs"); - foreach (XmlNode morph in morphs) - { - CreateMorphXmlElement(doc, seqNode, morph); - } - } - } - - protected override void AddParserSpecificArguments(List args) - { - string sLoadErrorFile = Path.Combine(Path.GetTempPath(), m_sDataBaseName + "HCLoadErrors.xml"); - args.Add(new XmlUtils.XSLParameter("prmHCTraceLoadErrorFile", sLoadErrorFile)); + var args = new XsltArgumentList(); + args.AddParam("prmHCTraceLoadErrorFile", "", Path.Combine(Path.GetTempPath(), m_cache.ProjectId.Name + "HCLoadErrors.xml")); + return transform.Transform(m_mediator, result, baseName, args); } } } diff --git a/Src/LexText/ParserUI/HCWordGrammarDebugger.cs b/Src/LexText/ParserUI/HCWordGrammarDebugger.cs index e57ab7279c..652706905b 100644 --- a/Src/LexText/ParserUI/HCWordGrammarDebugger.cs +++ b/Src/LexText/ParserUI/HCWordGrammarDebugger.cs @@ -1,64 +1,30 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Text; +using System.Collections.Generic; +using System.Diagnostics; using System.Xml; +using System.Xml.Linq; +using System.Linq; using XCore; namespace SIL.FieldWorks.LexText.Controls { public class HCWordGrammarDebugger : WordGrammarDebugger { - public HCWordGrammarDebugger() - {} + private readonly Dictionary m_attempts; - public HCWordGrammarDebugger(Mediator mediator, XmlDocument parseResult) + public HCWordGrammarDebugger(Mediator mediator, XDocument parseResult) : base(mediator) { - m_parseResult = parseResult; + Debug.Assert(parseResult.Root != null); + m_attempts = parseResult.Root.Elements("WordGrammarTrace").Elements("WordGrammarAttempt").ToDictionary(e => (string) e.Element("Id"), e => new XElement(e)); } - [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", - Justification = "In .NET 4.5 XmlNodeList implements IDisposable, but not in 4.0.")] - protected override void CreateMorphNodes(XmlDocument doc, XmlNode seqNode, string sNodeId) - { - string s = "//WordGrammarAttempt[Id=\"" + sNodeId + "\"]"; - XmlNode node = m_parseResult.SelectSingleNode(s); - if (node != null) - { - XmlNodeList morphs = node.SelectNodes("Morphs"); - foreach (XmlNode morph in morphs) - { - CreateMorphXmlElement(doc, seqNode, morph); - } - - } - } - protected override void CreateMorphAffixAlloFeatsXmlElement(XmlNode node, XmlNode morphNode) - { - XmlNode alloid = node.SelectSingleNode("@alloid"); - if (alloid != null) - { - XmlNode affixAlloFeatsNode = m_parseResult.SelectSingleNode("//Morph[MoForm/@DbRef='" + alloid.InnerText + "']/affixAlloFeats"); - if (affixAlloFeatsNode != null) - { - morphNode.InnerXml += affixAlloFeatsNode.OuterXml; - } - } - } - protected override void CreateMorphShortNameXmlElement(XmlNode node, XmlNode morphNode) + protected override void WriteMorphNodes(XmlWriter writer, string nodeId) { - XmlNode formNode = node.SelectSingleNode("shortName"); - if (formNode != null) - morphNode.InnerXml = "" + formNode.InnerXml + ""; - else + XElement wordGrammarAttemptElem; + if (m_attempts.TryGetValue(nodeId, out wordGrammarAttemptElem)) { - XmlNode alloFormNode = node.SelectSingleNode("alloform"); - XmlNode glossNode = node.SelectSingleNode("gloss"); - XmlNode citationFormNode = node.SelectSingleNode("citationForm"); - if (alloFormNode != null && glossNode != null && citationFormNode != null) - morphNode.InnerXml = "" + alloFormNode.InnerXml + " (" + glossNode.InnerText + "): " + citationFormNode.InnerText + ""; + foreach (XElement morphElem in wordGrammarAttemptElem.Elements("morph")) + morphElem.WriteTo(writer); } } } diff --git a/Src/LexText/ParserUI/ParserConnection.cs b/Src/LexText/ParserUI/ParserConnection.cs index 1b4927dbb5..66af771da5 100644 --- a/Src/LexText/ParserUI/ParserConnection.cs +++ b/Src/LexText/ParserUI/ParserConnection.cs @@ -7,7 +7,10 @@ using System; using System.Collections.Generic; +using System.IO; using System.Threading; +using System.Xml.Linq; +using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO; using SIL.FieldWorks.WordWorks.Parser; using SIL.Utils; @@ -23,7 +26,7 @@ public sealed class ParserConnection : FwDisposableBase, IAsyncResult private string m_activity; private string m_notificationMessage; - private string m_traceResult; + private XDocument m_traceResult; private readonly ManualResetEvent m_event = new ManualResetEvent(false); private readonly object m_syncRoot = new object(); @@ -35,7 +38,7 @@ public sealed class ParserConnection : FwDisposableBase, IAsyncResult public ParserConnection(FdoCache cache, IdleQueue idleQueue) { m_activity = ""; - m_scheduler = new ParserScheduler(cache, idleQueue); + m_scheduler = new ParserScheduler(cache, idleQueue, Path.Combine(FwDirectoryFinder.CodeDirectory, FwDirectoryFinder.ksFlexFolderName)); m_scheduler.ParserUpdateVerbose += ParserUpdateHandlerForPolling; } @@ -217,7 +220,7 @@ object IAsyncResult.AsyncState { lock (SyncRoot) { - string res = m_traceResult; + XDocument res = m_traceResult; m_traceResult = null; return res; } diff --git a/Src/LexText/ParserUI/ParserListener.cs b/Src/LexText/ParserUI/ParserListener.cs index 01382629a7..aad3ca78dd 100644 --- a/Src/LexText/ParserUI/ParserListener.cs +++ b/Src/LexText/ParserUI/ParserListener.cs @@ -231,9 +231,20 @@ private void UpdateStatusPanelProgress() if (ex != null) { DisconnectFromParser(); - var app = (IApp)m_mediator.PropertyTable.GetValue("App"); - ErrorReporter.ReportException(ex, app.SettingsKey, app.SupportEmailAddress, - app.ActiveMainWindow, false); + var iree = ex as InvalidReduplicationEnvironmentException; + if (iree != null) + { + string msg = String.Format(ParserUIStrings.ksHermitCrabReduplicationProblem, iree.Morpheme, + iree.Message); + MessageBox.Show(Form.ActiveForm, msg, ParserUIStrings.ksBadAffixForm, + MessageBoxButtons.OK, MessageBoxIcon.Error); + } + else + { + var app = (IApp) m_mediator.PropertyTable.GetValue("App"); + ErrorReporter.ReportException(ex, app.SettingsKey, app.SupportEmailAddress, + app.ActiveMainWindow, false); + } } else { @@ -451,8 +462,7 @@ public bool OnClearSelectedWordParserAnalyses(object dummyObj) if (analysis.EvaluationsRC.Count == 0) wf.AnalysesOC.Remove(analysis); - if (parserEvals.Length > 0) - wf.Checksum = 0; + wf.Checksum = 0; } }); return true; //we handled this. diff --git a/Src/LexText/ParserUI/ParserTrace.cs b/Src/LexText/ParserUI/ParserTrace.cs index d7a2dddf76..bc50668e35 100644 --- a/Src/LexText/ParserUI/ParserTrace.cs +++ b/Src/LexText/ParserUI/ParserTrace.cs @@ -1,435 +1,31 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Drawing; -using System.IO; -using System.Text; -using System.Xml; -using System.Xml.XPath; -using System.Xml.Xsl; - -using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; -using SIL.FieldWorks.WordWorks.Parser; -using SIL.Utils; -using SIL.FieldWorks.Common.Widgets; -using SIL.FieldWorks.FDO; -using XCore; +using System.Xml.Linq; namespace SIL.FieldWorks.LexText.Controls { /// /// Base class common to all parser trace processing /// - public abstract class ParserTrace : ParserTraceBase + public abstract class ParserTrace { - protected enum TransformKind + private static ParserTraceUITransform s_traceTransform; + protected static ParserTraceUITransform ParseTransform { - kcptParse = 0, - kcptTrace = 1, - kcptWordGrammarDebugger = 2, + get + { + if (s_traceTransform == null) + s_traceTransform = new ParserTraceUITransform("FormatXAmpleParse"); + return s_traceTransform; + } } - /// - /// Temp File names - /// - protected string m_sParse; - protected string m_sTrace; - - protected WordGrammarDebugger m_wordGrammarDebugger; - /// - /// Transform file names - /// - protected string m_sFormatParse; - protected string m_sFormatTrace; - - protected const string m_ksWordGrammarDebugger = "WordGrammarDebugger"; - /// Testing variables - protected string[] m_saTesting = { "A", "AB", "ABC", "ABCD", "ABCDE", "ABCDEF" }; - protected int m_iTestingCount = 0; - protected char[] m_space = { ' ' }; - protected char[] m_digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; - - /// - /// For testing - /// - public ParserTrace() - : base() - { - } - /// - /// The real deal - /// - /// - protected ParserTrace(Mediator mediator) - : base(mediator) - { - } + public WordGrammarDebugger WordGrammarDebugger { get; protected set; } /// /// Create an HTML page of the results /// - /// XML string of the XAmple trace output + /// XML of the parse trace output + /// /// URL of the resulting HTML page - public abstract string CreateResultPage(string result); - - /// - /// Initialize what is needed to perform the word grammar debugging and - /// produce an html page showing the results - /// - /// Id of the node to use - /// the wordform being tried - /// temporary html file showing the results of the first step - public abstract string SetUpWordGrammarDebuggerPage(string sNodeId, string sForm, string sLastURL); - - /// - /// Perform another step in the word grammar debugging process and - /// produce an html page showing the results - /// - /// Id of the selected node to use - /// temporary html file showing the results of the next step - public string PerformAnotherWordGrammarDebuggerStepPage(string sNodeId, string sForm, string sLastURL) - { - return m_wordGrammarDebugger.PerformAnotherWordGrammarDebuggerStepPage(sNodeId, sForm, sLastURL); - } - - public string PopWordGrammarStack() - { - return m_wordGrammarDebugger.PopWordGrammarStack(); - } - - protected string TransformToHtml(string sInputFile, TransformKind kind) - { - string sOutput = null; - var args = new List(); - - switch (kind) - { - case TransformKind.kcptParse: - sOutput = TransformToHtml(sInputFile, m_sParse, m_sFormatParse, args); - break; - case TransformKind.kcptTrace: - string sIconPath = CreateIconPath(); - args.Add(new XmlUtils.XSLParameter("prmIconPath", sIconPath)); - sOutput = TransformToHtml(sInputFile, m_sTrace, m_sFormatTrace, args); - break; - } - return sOutput; - } - - private string CreateIconPath() - { - StringBuilder sb = new StringBuilder(); - sb.Append("file:///"); - sb.Append(TransformPath.Replace(@"\", "/")); - sb.Append("/"); - return sb.ToString(); - } - - [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", - Justification = "In .NET 4.5 XmlNodeList implements IDisposable, but not in 4.0.")] - protected void ConvertMorphs(XmlDocument doc, string sNodeListToFind, bool fIdsInAttribute) - { - XmlNodeList nl = doc.SelectNodes(sNodeListToFind); - if (nl != null) - { - foreach (XmlNode node in nl) - { - XmlNode alloid; - if (fIdsInAttribute) - alloid = node.Attributes.GetNamedItem("alloid"); - else - alloid = node.SelectSingleNode("MoForm/@DbRef"); - int hvo = Convert.ToInt32(alloid.InnerText); - var obj = m_cache.ServiceLocator.GetInstance().GetObject(hvo); - var form = obj as IMoForm; - if (form == null) - { - // This is one of the null allomorphs we create when building the - // input for the parser in order to still get the Word Grammar to have something in any - // required slots in affix templates. - var lexEntryInflType = obj as ILexEntryInflType; - if (lexEntryInflType != null) - { - ConvertLexEntryInflType(doc, node, lexEntryInflType); - continue; - } - } - string sLongName; - string sForm; - string sGloss; - string sCitationForm; - if (form != null) - { - sLongName = form.LongName; - int iFirstSpace = sLongName.IndexOf(" ("); - int iLastSpace = sLongName.LastIndexOf("):") + 2; - sForm = sLongName.Substring(0, iFirstSpace); - XmlNode msaid; - if (fIdsInAttribute) - msaid = node.Attributes.GetNamedItem("morphname"); - else - msaid = node.SelectSingleNode("MSI/@DbRef"); - string sMsaHvo = msaid.InnerText; - var indexOfPeriod = ParseFiler.IndexOfPeriodInMsaHvo(ref sMsaHvo); - int hvoMsa = Convert.ToInt32(sMsaHvo); - var msaObj = m_cache.ServiceLocator.GetObject(hvoMsa); - if (msaObj.ClassID == LexEntryTags.kClassId) - { - var entry = msaObj as ILexEntry; - if (entry.EntryRefsOS.Count > 0) - { - var index = ParseFiler.IndexOfLexEntryRef(msaid.Value, indexOfPeriod); // the value of the int after the period - var lexEntryRef = entry.EntryRefsOS[index]; - ITsIncStrBldr sbGlossPrepend; - ITsIncStrBldr sbGlossAppend; - var sense = FDO.DomainServices.MorphServices.GetMainOrFirstSenseOfVariant(lexEntryRef); - var glossWs = m_cache.ServiceLocator.WritingSystemManager.Get(m_cache.DefaultAnalWs); - FDO.DomainServices.MorphServices.JoinGlossAffixesOfInflVariantTypes(lexEntryRef.VariantEntryTypesRS, - glossWs, - out sbGlossPrepend, out sbGlossAppend); - ITsIncStrBldr sbGloss = sbGlossPrepend; - sbGloss.Append(sense.Gloss.BestAnalysisAlternative.Text); - sbGloss.Append(sbGlossAppend.Text); - sGloss = sbGloss.Text; - } - else - { - sGloss = ParserUIStrings.ksUnknownGloss; - } - - } - else - { - var msa = msaObj as IMoMorphSynAnalysis; - if (msa != null) - { - sGloss = msa.GetGlossOfFirstSense(); - } - else - { - sGloss = sLongName.Substring(iFirstSpace, iLastSpace - iFirstSpace).Trim(); - } - } - sCitationForm = sLongName.Substring(iLastSpace).Trim(); - sLongName = String.Format(ParserUIStrings.ksX_Y_Z, sForm, sGloss, sCitationForm); - } - else - { - sForm = ParserUIStrings.ksUnknownMorpheme; // in case the user continues... - sGloss = ParserUIStrings.ksUnknownGloss; - sCitationForm = ParserUIStrings.ksUnknownCitationForm; - sLongName = String.Format(ParserUIStrings.ksX_Y_Z, sForm, sGloss, sCitationForm); - throw new ApplicationException(sLongName); - } - XmlNode tempNode = CreateXmlElement(doc, "shortName", node); - tempNode.InnerXml = CreateEntities(sLongName); - tempNode = CreateXmlElement(doc, "alloform", node); - tempNode.InnerXml = CreateEntities(sForm); - switch (form.ClassID) - { - case MoStemAllomorphTags.kClassId: - ConvertStemName(doc, node, form, tempNode); - break; - case MoAffixAllomorphTags.kClassId: - ConvertAffixAlloFeats(doc, node, form, tempNode); - ConvertStemNameAffix(doc, node, tempNode); - break; - - } - tempNode = CreateXmlElement(doc, "gloss", node); - tempNode.InnerXml = CreateEntities(sGloss); - tempNode = CreateXmlElement(doc, "citationForm", node); - tempNode.InnerXml = CreateEntities(sCitationForm); - } - } - } - - private void ConvertLexEntryInflType(XmlDocument doc, XmlNode node, ILexEntryInflType lexEntryInflType) - { - var lexEntryInflTypeNode = CreateXmlElement(doc, "lexEntryInflType", node); - var nullTempNode = CreateXmlElement(doc, "alloform", node); - nullTempNode.InnerText = "0"; - string sNullGloss = null; - StringBuilder sbGloss = new StringBuilder(); - if (string.IsNullOrEmpty(lexEntryInflType.GlossPrepend.BestAnalysisAlternative.Text)) - { - sbGloss.Append(lexEntryInflType.GlossPrepend.BestAnalysisAlternative.Text); - sbGloss.Append("..."); - } - sbGloss.Append(lexEntryInflType.GlossAppend.BestAnalysisAlternative.Text); - nullTempNode = CreateXmlElement(doc, "gloss", node); - nullTempNode.InnerXml = CreateEntities(sbGloss.ToString()); - var sMsg = string.Format(ParserUIStrings.ksIrregularlyInflectedFormNullAffix, lexEntryInflType.ShortName); - nullTempNode = CreateXmlElement(doc, "citationForm", node); - nullTempNode.InnerXml = CreateEntities(sMsg); - CreateInflMsaForLexEntryInflType(doc, node, lexEntryInflType); - } - - protected void CreateNotAffixAlloFeatsElement(XmlDocument doc, XmlNode node, XmlNode tempNode) - { - XmlNode props = node.SelectSingleNode("props"); - if (props != null) - { - int i = props.InnerText.IndexOf("MSEnvFSNot"); - if (i > -1) - { - XmlNode affixAlloFeatsNode = CreateXmlElement(doc, "affixAlloFeats", node); - XmlNode notNode = CreateXmlElement(doc, "not", affixAlloFeatsNode); - string s = props.InnerText.Substring(i); - int j = s.IndexOf(' '); - if (j > 0) - s = props.InnerText.Substring(i, j + 1); - int iNot = s.IndexOf("Not") + 3; - while (iNot > 3) - { - int iNextNot = s.IndexOf("Not", iNot); - string sFsHvo; - if (iNextNot > -1) - { - // there are more - sFsHvo = s.Substring(iNot, iNextNot - iNot); - CreateFeatureStructureFromHvoString(doc, sFsHvo, notNode); - iNot = iNextNot + 3; - } - else - { - // is the last one - sFsHvo = s.Substring(iNot); - CreateFeatureStructureFromHvoString(doc, sFsHvo, notNode); - iNot = 0; - } - } - } - } - } - - private void CreateFeatureStructureFromHvoString(XmlDocument doc, string sFSHvo, XmlNode parentNode) - { - int fsHvo = Convert.ToInt32(sFSHvo); - var fsFeatStruc = (IFsFeatStruc)m_cache.ServiceLocator.GetInstance().GetObject(fsHvo); - if (fsFeatStruc != null) - { - CreateFeatureStructureNodes(doc, parentNode, fsFeatStruc, fsHvo); - } - } - - protected void ConvertStemNameAffix(XmlDocument doc, XmlNode node, XmlNode tempNode) - { - XmlNode props = node.SelectSingleNode("props"); - if (props != null) - { - string sProps = props.InnerText.Trim(); - string[] saProps = sProps.Split(' '); - foreach (string sProp in saProps) - { - int i = sProp.IndexOf("StemNameAffix"); - if (i > -1) - { - string sId = (sProp.Substring(i + 13)).Trim(); - var sn = (IMoStemName)m_cache.ServiceLocator.GetInstance().GetObject(Convert.ToInt32(sId)); - if (sn != null) - { - tempNode = CreateXmlElement(doc, "stemNameAffix", node); - CreateXmlAttribute(doc, "id", sId, tempNode); - tempNode.InnerXml = CreateEntities(sn.Name.BestAnalysisAlternative.Text); - } - } - } - } - } - protected void ConvertStemName(XmlDocument doc, XmlNode node, IMoForm form, XmlNode tempNode) - { - IMoStemAllomorph sallo = form as IMoStemAllomorph; - IMoStemName sn = sallo.StemNameRA; - if (sn != null) - { - tempNode = CreateXmlElement(doc, "stemName", node); - CreateXmlAttribute(doc, "id", sn.Hvo.ToString(), tempNode); - tempNode.InnerXml = CreateEntities(sn.Name.BestAnalysisAlternative.Text); - } - else - { // There's no overt stem name on this allomorph, but there might be overt stem names - // on other allomorphs in this lexical entry. This allomorph, then, cannot bear any - // of the features of these other stem names. If so, there will be a property named - // NotStemNameddd or NotStemNamedddNotStemNamedddd, etc. - tempNode = CreateNotStemNameElement(doc, node, tempNode); - } - } - protected XmlNode CreateNotStemNameElement(XmlDocument doc, XmlNode node, XmlNode tempNode) - { - XmlNode props = node.SelectSingleNode("props"); - if (props != null) - { - int i = props.InnerText.IndexOf("NotStemName"); - if (i > -1) - { - string sNotStemName; - string s = props.InnerText.Substring(i); - int iSpace = s.IndexOf(" "); - if (iSpace > -1) - sNotStemName = s.Substring(0, iSpace - 1); - else - sNotStemName = s; - tempNode = CreateXmlElement(doc, "stemName", node); - CreateXmlAttribute(doc, "id", sNotStemName, tempNode); - } - } - return tempNode; - } - - protected string CreateEntities(string sInput) - { - if (sInput == null) - return ""; - string sResult1 = sInput.Replace("&", "&"); // N.B. Must be ordered first! - string sResult2 = sResult1.Replace("<", "<"); - return sResult2; - } - protected void ConvertAffixAlloFeats(XmlDocument doc, XmlNode node, IMoForm form, XmlNode tempNode) - { - IMoAffixAllomorph sallo = form as IMoAffixAllomorph; - if (sallo == null) - return; // the form could be an IMoAffixProcess in which case there are no MsEnvFeatures. - IFsFeatStruc fsFeatStruc = sallo.MsEnvFeaturesOA; - if (fsFeatStruc != null && !fsFeatStruc.IsEmpty) - { - tempNode = CreateXmlElement(doc, "affixAlloFeats", node); - CreateFeatureStructureNodes(doc, tempNode, fsFeatStruc, fsFeatStruc.Hvo); - } - else - { // There's no overt stem name on this allomorph, but there might be overt stem names - // on other allomorphs in this lexical entry. This allomorph, then, cannot bear any - // of the features of these other stem names. If so, there will be a property named - // NotStemNameddd or NotStemNamedddNotStemNamedddd, etc. - CreateNotAffixAlloFeatsElement(doc, node, tempNode); - } - } - - [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", - Justification = "In .NET 4.5 XmlNodeList implements IDisposable, but not in 4.0.")] - protected void AddMsaNodes(bool fIsTrace) - { - string sXPath; - string sAttrXPath; - if (fIsTrace) - { - sXPath = "//morph[@morphname]"; - sAttrXPath = "@morphname"; - } - else - { - sXPath = "//Morph/MSI"; - sAttrXPath = "@DbRef"; - } - XmlNodeList nl = m_parseResult.SelectNodes(sXPath); - if (nl != null) - { - foreach (XmlNode node in nl) - { - CreateMsaXmlElement(node, m_parseResult, node, sAttrXPath); - } - } - } + public abstract string CreateResultPage(XDocument result, bool isTrace); } } diff --git a/Src/LexText/ParserUI/ParserTraceBase.cs b/Src/LexText/ParserUI/ParserTraceBase.cs deleted file mode 100644 index 14486a099d..0000000000 --- a/Src/LexText/ParserUI/ParserTraceBase.cs +++ /dev/null @@ -1,555 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.IO; -using System.Xml; -using System.Linq; -using System.Xml.XPath; -using System.Xml.Xsl; - -using SIL.CoreImpl; -using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; -using SIL.FieldWorks.Common.Widgets; -using SIL.FieldWorks.FDO; -using SIL.FieldWorks.WordWorks.Parser; -using SIL.Utils; -using XCore; - -namespace SIL.FieldWorks.LexText.Controls -{ - public abstract class ParserTraceBase - { - /// - /// xCore Mediator. - /// - protected Mediator m_mediator; - - protected FdoCache m_cache; - protected string m_sDataBaseName = ""; - /// - /// The parse result xml document - /// - protected XmlDocument m_parseResult; - /// - /// the latest word grammar debugging step xml document - /// - protected string m_sWordGrammarDebuggerXmlFile; - - public ParserTraceBase() - {} - /// - /// The real deal - /// - /// - protected ParserTraceBase(Mediator mediator) - { - m_mediator = mediator; - m_cache = (FdoCache)m_mediator.PropertyTable.GetValue("cache"); - m_sDataBaseName = m_cache.ProjectId.Name; - } - protected void CopyXmlAttribute(XmlDocument doc, XmlNode node, string sAttrName, XmlNode morphNode) - { - XmlNode attr = node.SelectSingleNode("@" + sAttrName); - if (attr != null && sAttrName != null) - CreateXmlAttribute(doc, sAttrName, attr.InnerText, morphNode); - } - - protected void CreateDerivMsaXmlElement(XmlDocument doc, XmlNode morphNode, IMoDerivAffMsa derivMsa) - { - XmlNode derivMsaNode = CreateXmlElement(doc, "derivMsa", morphNode); - CreatePOSXmlAttribute(doc, derivMsaNode, derivMsa.FromPartOfSpeechRA, "fromCat"); - CreatePOSXmlAttribute(doc, derivMsaNode, derivMsa.ToPartOfSpeechRA, "toCat"); - CreateInflectionClassXmlAttribute(doc, derivMsaNode, derivMsa.FromInflectionClassRA, "fromInflClass"); - CreateInflectionClassXmlAttribute(doc, derivMsaNode, derivMsa.ToInflectionClassRA, "toInflClass"); - CreateRequiresInflectionXmlAttribute(doc, derivMsa.ToPartOfSpeechRA, derivMsaNode); - CreateFeatureStructureNodes(doc, derivMsaNode, derivMsa.FromMsFeaturesOA, derivMsa.Hvo, "fromFS"); - CreateFeatureStructureNodes(doc, derivMsaNode, derivMsa.ToMsFeaturesOA, derivMsa.Hvo, "toFS"); - CreateProductivityRestrictionNodes(doc, derivMsaNode, derivMsa.FromProdRestrictRC, "fromProductivityRestriction"); - CreateProductivityRestrictionNodes(doc, derivMsaNode, derivMsa.ToProdRestrictRC, "toProductivityRestriction"); - } - protected void CreateFeatureStructureNodes(XmlDocument doc, XmlNode msaNode, IFsFeatStruc fs, int id) - { - CreateFeatureStructureNodes(doc, msaNode, fs, id, "fs"); - } - protected void CreateFeatureStructureNodes(XmlDocument doc, XmlNode msaNode, IFsFeatStruc fs, int id, string sFSName) - { - if (fs == null) - return; - XmlNode fsNode = CreateXmlElement(doc, sFSName, msaNode); - CreateXmlAttribute(doc, "id", id.ToString(), fsNode); - foreach (IFsFeatureSpecification spec in fs.FeatureSpecsOC) - { - XmlNode feature = CreateXmlElement(doc, "feature", fsNode); - XmlNode name = CreateXmlElement(doc, "name", feature); - name.InnerText = spec.FeatureRA.Abbreviation.BestAnalysisAlternative.Text; - XmlNode fvalue = CreateXmlElement(doc, "value", feature); - IFsClosedValue cv = spec as IFsClosedValue; - if (cv != null) - fvalue.InnerText = cv.ValueRA.Abbreviation.BestAnalysisAlternative.Text; - else - { - IFsComplexValue complex = spec as IFsComplexValue; - if (complex == null) - continue; // skip this one since we're not dealing with it yet - IFsFeatStruc nestedFs = complex.ValueOA as IFsFeatStruc; - if (nestedFs != null) - CreateFeatureStructureNodes(doc, fvalue, nestedFs, 0, "fs"); - } - } - } - protected void CreateFromPOSNodes(XmlDocument doc, XmlNode msaNode, IFdoReferenceCollection fromPOSes, string sElementName) - { - if (fromPOSes == null || fromPOSes.Count < 1) - return; - foreach (IPartOfSpeech pos in fromPOSes) - { - XmlNode posNode = CreateXmlElement(doc, sElementName, msaNode); - CreateXmlAttribute(doc, "fromCat", pos.Hvo.ToString(), posNode); - CreateXmlAttribute(doc, "fromCatAbbr", pos.Abbreviation.BestAnalysisAlternative.Text, posNode); - } - } - protected void CreateInflectionClasses(XmlDocument doc, XmlNode morphNode) - { - string sAlloId = XmlUtils.GetOptionalAttributeValue(morphNode, "alloid"); - if (sAlloId == null) - return; - int hvoAllomorph = Convert.ToInt32(sAlloId); - // use IMoForm instead of IMoAffixForm or IMoAffixAllomorph because it could be an IMoStemAllomorph - IMoForm form = m_cache.ServiceLocator.GetInstance().GetObject(hvoAllomorph); - if (form == null) - return; - if (!(form is IMoAffixForm)) - return; - foreach (IMoInflClass ic in ((IMoAffixForm)form).InflectionClassesRC) - { - XmlNode icNode = CreateXmlElement(doc, "inflectionClass", morphNode); - CreateXmlAttribute(doc, "id", ic.Hvo.ToString(), icNode); - CreateXmlAttribute(doc, "abbr", ic.Abbreviation.BestAnalysisAlternative.Text, icNode); - } - } - private void CreateInflectionClassesAndSubclassesXmlElement(XmlDocument doc, - System.Collections.Generic.IEnumerable inflectionClasses, - XmlNode inflClasses) - { - foreach (IMoInflClass ic in inflectionClasses) - { - XmlNode inflClass = CreateXmlElement(doc, "inflClass", inflClasses); - CreateXmlAttribute(doc, "hvo", ic.Hvo.ToString(), inflClass); - CreateXmlAttribute(doc, "abbr", ic.Abbreviation.BestAnalysisAlternative.Text, inflClass); - CreateInflectionClassesAndSubclassesXmlElement(doc, ic.SubclassesOC, inflClasses); - } - } - protected void CreateInflectionClassXmlAttribute(XmlDocument doc, XmlNode msaNode, IMoInflClass inflClass, string sInflClass) - { - if (inflClass != null) - { - CreateXmlAttribute(doc, sInflClass, inflClass.Hvo.ToString(), msaNode); - string sInflClassAbbr; - if (inflClass.Hvo > 0) - sInflClassAbbr = inflClass.Abbreviation.BestAnalysisAlternative.Text; - else - sInflClassAbbr = ""; - CreateXmlAttribute(doc, sInflClass + "Abbr", sInflClassAbbr, msaNode); - } - else - CreateXmlAttribute(doc, sInflClass, "0", msaNode); - } - - protected void CreateInflMsaXmlElement(XmlDocument doc, XmlNode morphNode, IMoInflAffMsa inflMsa) - { - XmlNode inflMsaNode = CreateXmlElement(doc, "inflMsa", morphNode); - CreatePOSXmlAttribute(doc, inflMsaNode, inflMsa.PartOfSpeechRA, "cat"); - // handle any slot - HandleSlotInfoForInflectionalMsa(inflMsa, doc, inflMsaNode, morphNode); - CreateFeatureStructureNodes(doc, inflMsaNode, inflMsa.InflFeatsOA, inflMsa.Hvo); - CreateProductivityRestrictionNodes(doc, inflMsaNode, inflMsa.FromProdRestrictRC, "fromProductivityRestriction"); - } - protected virtual void CreateMorphAffixAlloFeatsXmlElement(XmlNode node, XmlNode morphNode) - { - XmlNode affixAlloFeatsNode = node.SelectSingleNode("affixAlloFeats"); - if (affixAlloFeatsNode != null) - { - morphNode.InnerXml += affixAlloFeatsNode.OuterXml; - } - } - protected void CreateMorphAlloformXmlElement(XmlNode node, XmlNode morphNode) - { - XmlNode formNode = node.SelectSingleNode("alloform"); - if (formNode != null) - morphNode.InnerXml += "" + formNode.InnerXml + ""; - } - protected void CreateMorphCitationFormXmlElement(XmlNode node, XmlNode morphNode) - { - XmlNode citationFormNode = node.SelectSingleNode("citationForm"); - if (citationFormNode != null) - morphNode.InnerXml += "" + citationFormNode.InnerXml + ""; - } - - protected void CreateMorphGlossXmlElement(XmlNode node, XmlNode morphNode) - { - XmlNode glossNode = node.SelectSingleNode("gloss"); - if (glossNode != null) - morphNode.InnerXml += "" + glossNode.InnerXml + ""; - } - protected void CreateMorphInflectionClassesXmlElement(XmlDocument doc, XmlNode node, XmlNode morphNode) - { - XmlNode attr; - attr = node.SelectSingleNode("@alloid"); - if (attr != null) - { - XmlNode alloid = node.Attributes.GetNamedItem("alloid"); - int hvo = Convert.ToInt32(alloid.InnerText); - ICmObject obj = m_cache.ServiceLocator.GetInstance().GetObject(hvo); - IMoAffixForm form = obj as IMoAffixForm; // only for affix forms - if (form != null) - { - if (form.InflectionClassesRC.Count > 0) - { - XmlNode inflClasses = CreateXmlElement(doc, "inflClasses", morphNode); - IFdoReferenceCollection inflectionClasses = form.InflectionClassesRC; - CreateInflectionClassesAndSubclassesXmlElement(doc, inflectionClasses, inflClasses); - } - } - } - } - - - protected abstract void CreateMorphNodes(XmlDocument doc, XmlNode seqNode, string sNodeId); - - protected virtual void CreateMorphShortNameXmlElement(XmlNode node, XmlNode morphNode) - { - XmlNode formNode = node.SelectSingleNode("shortName"); - if (formNode != null) - morphNode.InnerXml = "" + formNode.InnerXml + ""; - } - protected void CreateMorphStemNameXmlElement(XmlNode node, XmlNode morphNode) - { - XmlNode stemNameNode = node.SelectSingleNode("stemName"); - if (stemNameNode != null) - { - XmlNode idNode = stemNameNode.SelectSingleNode("@id"); - if (idNode != null) - morphNode.InnerXml += "" + stemNameNode.InnerXml + ""; - } - } - - protected void CreateMorphWordTypeXmlAttribute(XmlNode node, XmlDocument doc, XmlNode morphNode) - { - XmlNode attr = node.SelectSingleNode("@type"); - if (attr != null) - CreateXmlAttribute(doc, "type", attr.Value, morphNode); - attr = node.SelectSingleNode("@wordType"); - if (attr != null) - CreateXmlAttribute(doc, "wordType", attr.Value, morphNode); - } - protected void CreateMorphXmlElement(XmlDocument doc, XmlNode seqNode, XmlNode node) - { - XmlNode morphNode = CreateXmlElement(doc, "morph", seqNode); - CopyXmlAttribute(doc, node, "alloid", morphNode); - CopyXmlAttribute(doc, node, "morphname", morphNode); - CreateMorphWordTypeXmlAttribute(node, doc, morphNode); - CreateMorphShortNameXmlElement(node, morphNode); - CreateMorphAlloformXmlElement(node, morphNode); - CreateMorphStemNameXmlElement(node, morphNode); - CreateMorphAffixAlloFeatsXmlElement(node, morphNode); - CreateMorphGlossXmlElement(node, morphNode); - CreateMorphCitationFormXmlElement(node, morphNode); - CreateMorphInflectionClassesXmlElement(doc, node, morphNode); - CreateMsaXmlElement(node, doc, morphNode, "@morphname"); - } - protected void CreateMsaXmlElement(XmlNode node, XmlDocument doc, XmlNode morphNode, string sHvo) - { - XmlNode attr; - // morphname contains the hvo of the msa - attr = node.SelectSingleNode(sHvo); - if (attr != null) - { - string sObjHvo = attr.Value; - // Irregulary inflected forms can have a combination MSA hvo: the LexEntry hvo, a period, and an index to the LexEntryRef - var indexOfPeriod = ParseFiler.IndexOfPeriodInMsaHvo(ref sObjHvo); - ICmObject obj = m_cache.ServiceLocator.GetInstance().GetObject(Convert.ToInt32(sObjHvo)); - switch (obj.GetType().Name) - { - default: - throw new ApplicationException(String.Format("Invalid MSA type: {0}.", obj.GetType().Name)); - case "MoStemMsa": - IMoStemMsa stemMsa = obj as IMoStemMsa; - CreateStemMsaXmlElement(doc, morphNode, stemMsa); - break; - case "MoInflAffMsa": - IMoInflAffMsa inflMsa = obj as IMoInflAffMsa; - CreateInflectionClasses(doc, morphNode); - CreateInflMsaXmlElement(doc, morphNode, inflMsa); - break; - case "MoDerivAffMsa": - IMoDerivAffMsa derivMsa = obj as IMoDerivAffMsa; - CreateDerivMsaXmlElement(doc, morphNode, derivMsa); - break; - case "MoUnclassifiedAffixMsa": - IMoUnclassifiedAffixMsa unclassMsa = obj as IMoUnclassifiedAffixMsa; - CreateUnclassifedMsaXmlElement(doc, morphNode, unclassMsa); - break; - case "LexEntry": - // is an irregularly inflected form - // get the MoStemMsa of its variant - var entry = obj as ILexEntry; - if (entry == null) - break; - if (entry.EntryRefsOS.Count > 0) - { - var index = ParseFiler.IndexOfLexEntryRef(attr.Value, indexOfPeriod); - var lexEntryRef = entry.EntryRefsOS[index]; - var sense = FDO.DomainServices.MorphServices.GetMainOrFirstSenseOfVariant(lexEntryRef); - stemMsa = sense.MorphoSyntaxAnalysisRA as IMoStemMsa; - CreateStemMsaXmlElement(doc, morphNode, stemMsa); - // Handle any features of the variant type - var stemMsaNode = morphNode.SelectSingleNode("stemMsa"); - foreach (var entryRef in entry.VariantEntryRefs) - { - var varTypes = entryRef.VariantEntryTypesRS; - foreach (var lexEntryType in varTypes) - { - var inflEntryType = lexEntryType as ILexEntryInflType; - if (inflEntryType != null) - CreateFeatureStructureNodes(doc, stemMsaNode, inflEntryType.InflFeatsOA, stemMsa.Hvo); - } - } - } - break; - case "LexEntryInflType": - // This is one of the null allomorphs we create when building the - // input for the parser in order to still get the Word Grammar to have something in any - // required slots in affix templates. - CreateInflMsaForLexEntryInflType(doc, morphNode, obj as ILexEntryInflType); - break; - } - } - } - - protected void CreateInflMsaForLexEntryInflType(XmlDocument doc, XmlNode node, ILexEntryInflType lexEntryInflType) - { - /*var slots = lexEntryInflType.SlotsRC; - IMoInflAffixSlot firstSlot = null; - foreach (var slot in slots) - { - if (firstSlot == null) - firstSlot = slot; - }*/ - IMoInflAffixSlot slot; - var slotId = node.SelectSingleNode("MoForm/@wordType"); - if (slotId != null) - slot = m_cache.ServiceLocator.GetInstance().GetObject(Convert.ToInt32(slotId.InnerText)); - else - { - var slots = lexEntryInflType.SlotsRC; - IMoInflAffixSlot firstSlot = null; - foreach (var slot1 in slots) // there's got to be a better way to do this... - { - firstSlot = slot1; - break; - } - slot = firstSlot; - } - XmlNode nullInflMsaNode; - nullInflMsaNode = CreateXmlElement(doc, "inflMsa", node); - CreatePOSXmlAttribute(doc, nullInflMsaNode, slot.Owner as IPartOfSpeech, "cat"); - CreateXmlAttribute(doc, "slot", slot.Hvo.ToString(), nullInflMsaNode); - CreateXmlAttribute(doc, "slotAbbr", slot.Name.BestAnalysisAlternative.Text, nullInflMsaNode); - CreateXmlAttribute(doc, "slotOptional", "false", nullInflMsaNode); - CreateFeatureStructureNodes(doc, nullInflMsaNode, lexEntryInflType.InflFeatsOA, lexEntryInflType.Hvo); - } - - protected void CreatePOSXmlAttribute(XmlDocument doc, XmlNode msaNode, IPartOfSpeech pos, string sCat) - { - if (pos != null) - { - CreateXmlAttribute(doc, sCat, pos.Hvo.ToString(), msaNode); - string sPosAbbr; - if (pos.Hvo > 0) - sPosAbbr = pos.Abbreviation.BestAnalysisAlternative.Text; - else - sPosAbbr = "??"; - CreateXmlAttribute(doc, sCat + "Abbr", sPosAbbr, msaNode); - } - else - CreateXmlAttribute(doc, sCat, "0", msaNode); - } - - protected void CreateProductivityRestrictionNodes(XmlDocument doc, XmlNode msaNode, IFdoReferenceCollection prodRests, string sElementName) - { - if (prodRests == null || prodRests.Count < 1) - return; - foreach (ICmPossibility pr in prodRests) - { - XmlNode prNode = CreateXmlElement(doc, sElementName, msaNode); - CreateXmlAttribute(doc, "id", pr.Hvo.ToString(), prNode); - XmlNode prName = CreateXmlElement(doc, "name", prNode); - prName.InnerText = pr.Name.BestAnalysisAlternative.Text; - } - } - protected void CreateRequiresInflectionXmlAttribute(XmlDocument doc, IPartOfSpeech pos, XmlNode msaNode) - { - string sPlusMinus; - if (RequiresInflection(pos)) - sPlusMinus = "+"; - else - sPlusMinus = "-"; - CreateXmlAttribute(doc, "requiresInfl", sPlusMinus, msaNode); - } - public string CreateTempFile(string sPrefix, string sExtension) - { - string sTempFileName = Path.Combine(Path.GetTempPath(), m_sDataBaseName + sPrefix) + "." + sExtension; - using (StreamWriter sw = File.CreateText(sTempFileName)) - sw.Close(); - return sTempFileName; - } - protected static void CreateXmlAttribute(XmlDocument doc, string sAttrName, string sAttrValue, XmlNode elementNode) - { - XmlNode attr = doc.CreateNode(XmlNodeType.Attribute, sAttrName, null); - attr.Value = sAttrValue; - elementNode.Attributes.SetNamedItem(attr); - } - /// - /// Create an xml element and add it to the tree - /// - /// Xml document containing the element - /// name of the element to create - /// owner of the newly created element - /// newly created element node - protected XmlNode CreateXmlElement(XmlDocument doc, string sElementName, XmlNode parentNode) - { - XmlNode node = doc.CreateNode(XmlNodeType.Element, sElementName, null); - parentNode.AppendChild(node); - return node; - } - protected void HandleSlotInfoForInflectionalMsa(IMoInflAffMsa inflMsa, XmlDocument doc, XmlNode inflMsaNode, XmlNode morphNode) - { - int slotHvo = 0; - int iCount = inflMsa.SlotsRC.Count; - if (iCount > 0) - { - if (iCount > 1) - { // have a circumfix; assume only two slots and assume that the first is prefix and second is suffix - // TODO: ideally would figure out if the slots are prefix or suffix slots and then align the - // o and 1 indices to the appropriate slot. Will just do this for now (hab 2005.08.04). - XmlNode attrType = morphNode.SelectSingleNode("@type"); - if (attrType != null && attrType.InnerText != "sfx") - slotHvo = inflMsa.SlotsRC.ToHvoArray()[0]; - else - slotHvo = inflMsa.SlotsRC.ToHvoArray()[1]; - } - else - slotHvo = inflMsa.SlotsRC.ToHvoArray()[0]; - } - CreateXmlAttribute(doc, "slot", slotHvo.ToString(), inflMsaNode); - string sSlotOptional = "false"; - string sSlotAbbr = "??"; - if (slotHvo > 0) - { - var slot = m_cache.ServiceLocator.GetInstance().GetObject(slotHvo); - if (slot != null) - { - sSlotAbbr = slot.Name.BestAnalysisAlternative.Text; - if (slot.Optional) - sSlotOptional = "true"; - } - } - CreateXmlAttribute(doc, "slotAbbr", sSlotAbbr, inflMsaNode); - CreateXmlAttribute(doc, "slotOptional", sSlotOptional, inflMsaNode); - } - protected void CreateStemMsaXmlElement(XmlDocument doc, XmlNode morphNode, IMoStemMsa stemMsa) - { - XmlNode stemMsaNode = CreateXmlElement(doc, "stemMsa", morphNode); - CreatePOSXmlAttribute(doc, stemMsaNode, stemMsa.PartOfSpeechRA, "cat"); - IMoInflClass inflClass = stemMsa.InflectionClassRA; - if (inflClass == null) - { // use default inflection class of the POS or - // the first ancestor POS that has a non-zero default inflection class - int inflClassHvo = 0; - IPartOfSpeech pos = stemMsa.PartOfSpeechRA; - while (pos != null && inflClassHvo == 0) - { - if (pos.DefaultInflectionClassRA != null) - inflClassHvo = pos.DefaultInflectionClassRA.Hvo; - else - { - int clsid = m_cache.ServiceLocator.GetInstance().GetObject(pos.Owner.Hvo).ClassID; - if (clsid == PartOfSpeechTags.kClassId) - pos = m_cache.ServiceLocator.GetInstance().GetObject(pos.Owner.Hvo); - else - pos = null; - } - } - if (inflClassHvo != 0) - inflClass = m_cache.ServiceLocator.GetInstance().GetObject(inflClassHvo); - } - CreateInflectionClassXmlAttribute(doc, stemMsaNode, inflClass, "inflClass"); - CreateRequiresInflectionXmlAttribute(doc, - stemMsa.PartOfSpeechRA, - stemMsaNode); - CreateFeatureStructureNodes(doc, stemMsaNode, stemMsa.MsFeaturesOA, stemMsa.Hvo); - CreateProductivityRestrictionNodes(doc, stemMsaNode, stemMsa.ProdRestrictRC, "productivityRestriction"); - CreateFromPOSNodes(doc, stemMsaNode, stemMsa.FromPartsOfSpeechRC, "fromPartsOfSpeech"); - } - protected void CreateUnclassifedMsaXmlElement(XmlDocument doc, XmlNode morphNode, IMoUnclassifiedAffixMsa unclassMsa) - { - XmlNode unclassMsaNode = CreateXmlElement(doc, "unclassMsa", morphNode); - CreatePOSXmlAttribute(doc, unclassMsaNode, unclassMsa.PartOfSpeechRA, "fromCat"); - } - /// - /// Determine if a PartOfSpeech requires inflection. - /// If it or any of its parent POSes have a template, it requires inflection. - /// If it is null we default to not requiring inflection. - /// - /// the Part of Speech - /// true if it does, false otherwise - protected bool RequiresInflection(IPartOfSpeech pos) - { - return pos != null && pos.RequiresInflection; - } - /// - /// Path to transforms - /// - protected string TransformPath - { - get { return DirectoryFinder.GetFWCodeSubDirectory(@"Language Explorer/Configuration/Words/Analyses/TraceParse"); } - } - protected string TransformToHtml(string sInputFile, string sTempFileBase, string sTransformFile, List args) - { - string sOutput = CreateTempFile(sTempFileBase, "htm"); - string sTransform = Path.Combine(TransformPath, sTransformFile); - SetWritingSystemBasedArguments(args); - AddParserSpecificArguments(args); - XmlUtils.TransformFileToFile(sTransform, args.ToArray(), sInputFile, sOutput); - return sOutput; - } - - private void SetWritingSystemBasedArguments(List args) - { - ILgWritingSystemFactory wsf = m_cache.WritingSystemFactory; - IWritingSystemContainer wsContainer = m_cache.ServiceLocator.WritingSystems; - IWritingSystem defAnalWs = wsContainer.DefaultAnalysisWritingSystem; - using (var myFont = FontHeightAdjuster.GetFontForNormalStyle(defAnalWs.Handle, m_mediator, wsf)) - { - args.Add(new XmlUtils.XSLParameter("prmAnalysisFont", myFont.FontFamily.Name)); - args.Add(new XmlUtils.XSLParameter("prmAnalysisFontSize", myFont.Size + "pt")); - } - - IWritingSystem defVernWs = wsContainer.DefaultVernacularWritingSystem; - using (var myFont = FontHeightAdjuster.GetFontForNormalStyle(defVernWs.Handle, m_mediator, wsf)) - { - args.Add(new XmlUtils.XSLParameter("prmVernacularFont", myFont.FontFamily.Name)); - args.Add(new XmlUtils.XSLParameter("prmVernacularFontSize", myFont.Size + "pt")); - } - - string sRTL = defVernWs.RightToLeftScript ? "Y" : "N"; - args.Add(new XmlUtils.XSLParameter("prmVernacularRTL", sRTL)); - } - - protected virtual void AddParserSpecificArguments(List args) - { - // default is to do nothing - } - } -} diff --git a/Src/LexText/ParserUI/ParserTraceUITransform.cs b/Src/LexText/ParserUI/ParserTraceUITransform.cs new file mode 100644 index 0000000000..9e9806fbc0 --- /dev/null +++ b/Src/LexText/ParserUI/ParserTraceUITransform.cs @@ -0,0 +1,80 @@ +using System.IO; +using System.Text; +using System.Xml.Linq; +using System.Xml.XPath; +using System.Xml.Xsl; +using SIL.CoreImpl; +using SIL.FieldWorks.Common.COMInterfaces; +using SIL.FieldWorks.Common.FwUtils; +using SIL.FieldWorks.Common.Widgets; +using SIL.FieldWorks.FDO; +using SIL.Utils; +using XCore; + +namespace SIL.FieldWorks.LexText.Controls +{ + public class ParserTraceUITransform + { + private readonly XslCompiledTransform m_transform; + + public ParserTraceUITransform(string xslName) + { + m_transform = XmlUtils.CreateTransform(xslName, "PresentationTransforms"); + } + + public string Transform(Mediator mediator, XDocument doc, string baseName) + { + return Transform(mediator, doc, baseName, new XsltArgumentList()); + } + + public string Transform(Mediator mediator, XDocument doc, string baseName, XsltArgumentList args) + { + var cache = (FdoCache) mediator.PropertyTable.GetValue("cache"); + SetWritingSystemBasedArguments(cache, mediator, args); + args.AddParam("prmIconPath", "", IconPath); + string filePath = Path.Combine(Path.GetTempPath(), cache.ProjectId.Name + baseName + ".htm"); + using (var writer = new StreamWriter(filePath)) + m_transform.Transform(doc.CreateNavigator(), args, writer); + return filePath; + } + + private void SetWritingSystemBasedArguments(FdoCache cache, Mediator mediator, XsltArgumentList argumentList) + { + ILgWritingSystemFactory wsf = cache.WritingSystemFactory; + IWritingSystemContainer wsContainer = cache.ServiceLocator.WritingSystems; + IWritingSystem defAnalWs = wsContainer.DefaultAnalysisWritingSystem; + using (var myFont = FontHeightAdjuster.GetFontForNormalStyle(defAnalWs.Handle, mediator, wsf)) + { + argumentList.AddParam("prmAnalysisFont", "", myFont.FontFamily.Name); + argumentList.AddParam("prmAnalysisFontSize", "", myFont.Size + "pt"); + } + + IWritingSystem defVernWs = wsContainer.DefaultVernacularWritingSystem; + using (var myFont = FontHeightAdjuster.GetFontForNormalStyle(defVernWs.Handle, mediator, wsf)) + { + argumentList.AddParam("prmVernacularFont", "", myFont.FontFamily.Name); + argumentList.AddParam("prmVernacularFontSize", "", myFont.Size + "pt"); + } + + string sRtl = defVernWs.RightToLeftScript ? "Y" : "N"; + argumentList.AddParam("prmVernacularRTL", "", sRtl); + } + + private static string TransformPath + { + get { return FwDirectoryFinder.GetCodeSubDirectory(@"Language Explorer/Configuration/Words/Analyses/TraceParse"); } + } + + private static string IconPath + { + get + { + var sb = new StringBuilder(); + sb.Append("file:///"); + sb.Append(TransformPath.Replace(@"\", "/")); + sb.Append("/"); + return sb.ToString(); + } + } + } +} diff --git a/Src/LexText/ParserUI/ParserUI.csproj b/Src/LexText/ParserUI/ParserUI.csproj index 46d81a8c03..d6db6a4d1f 100644 --- a/Src/LexText/ParserUI/ParserUI.csproj +++ b/Src/LexText/ParserUI/ParserUI.csproj @@ -1,4 +1,4 @@ - + Local @@ -149,6 +149,10 @@ ParserCore ..\..\..\Output\Debug\ParserCore.dll + + False + ..\..\..\Output\Debug\PresentationTransforms.dll + ..\..\..\Output\Debug\Reporting.dll False @@ -159,10 +163,10 @@ \usr\lib\cli\geckofx-14.0.1\geckofx-core-14.dll - + \usr\lib\cli\geckofx-14.0.1\Geckofx-Winforms-14.dll - + PreserveNewest @@ -187,6 +191,7 @@ System.XML + Widgets ..\..\..\Output\Debug\Widgets.dll @@ -235,7 +240,7 @@ Form - + True True diff --git a/Src/LexText/ParserUI/ParserUIStrings.Designer.cs b/Src/LexText/ParserUI/ParserUIStrings.Designer.cs index adac826477..8abdfcd2cc 100644 --- a/Src/LexText/ParserUI/ParserUIStrings.Designer.cs +++ b/Src/LexText/ParserUI/ParserUIStrings.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.18034 +// Runtime Version:4.0.30319.18444 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -69,6 +69,15 @@ internal static string ks_OK { } } + /// + /// Looks up a localized string similar to Bad Affix Form. + /// + internal static string ksBadAffixForm { + get { + return ResourceManager.GetString("ksBadAffixForm", resourceCulture); + } + } + /// /// Looks up a localized string similar to Changed value for {0} from {1} to {2}. The value must be between {3} and {4}, inclusive.. /// @@ -96,6 +105,15 @@ internal static string ksDash { } } + /// + /// Looks up a localized string similar to Parse was not attempted because of errors in the lexical data. + /// + internal static string ksDidNotParse { + get { + return ResourceManager.GetString("ksDidNotParse", resourceCulture); + } + } + /// /// Looks up a localized string similar to NoDefaultCompounding. /// @@ -105,6 +123,15 @@ internal static string ksDoNotUseDefaultCompoundRules { } } + /// + /// Looks up a localized string similar to The Hermit Crab parser cannot currently run, because the morpheme "{0}" has an invalid reduplication environment. The problem is {1}.. + /// + internal static string ksHermitCrabReduplicationProblem { + get { + return ResourceManager.GetString("ksHermitCrabReduplicationProblem", resourceCulture); + } + } + /// /// Looks up a localized string similar to . /// @@ -141,15 +168,6 @@ internal static string ksImportedFromFileX { } } - /// - /// Looks up a localized string similar to Automatically generated null affix for the {0} irregularly inflected form. - /// - internal static string ksIrregularlyInflectedFormNullAffix { - get { - return ResourceManager.GetString("ksIrregularlyInflectedFormNullAffix", resourceCulture); - } - } - /// /// Looks up a localized string similar to Loading Files for Word Set {0}. /// @@ -357,51 +375,6 @@ internal static string ksUnknown { } } - /// - /// Looks up a localized string similar to Unknown Allomorph!. - /// - internal static string ksUnknownAllomorph { - get { - return ResourceManager.GetString("ksUnknownAllomorph", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Unknown CitationForm!. - /// - internal static string ksUnknownCitationForm { - get { - return ResourceManager.GetString("ksUnknownCitationForm", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Unknown Gloss!. - /// - internal static string ksUnknownGloss { - get { - return ResourceManager.GetString("ksUnknownGloss", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Unknown Morpheme!. - /// - internal static string ksUnknownMorpheme { - get { - return ResourceManager.GetString("ksUnknownMorpheme", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Unknown Natural Class!. - /// - internal static string ksUnknownNaturalClass { - get { - return ResourceManager.GetString("ksUnknownNaturalClass", resourceCulture); - } - } - /// /// Looks up a localized string similar to Update. /// @@ -411,15 +384,6 @@ internal static string ksUpdate { } } - /// - /// Looks up a localized string similar to {0} ({1}): {2}. - /// - internal static string ksX_Y_Z { - get { - return ResourceManager.GetString("ksX_Y_Z", resourceCulture); - } - } - /// /// Looks up a localized string similar to The XML is not well-formed; you need to correct it and try again.. /// diff --git a/Src/LexText/ParserUI/ParserUIStrings.resx b/Src/LexText/ParserUI/ParserUIStrings.resx index 69ddb2f25e..46c4eb1c04 100644 --- a/Src/LexText/ParserUI/ParserUIStrings.resx +++ b/Src/LexText/ParserUI/ParserUIStrings.resx @@ -194,29 +194,10 @@ Unknown - - Unknown Allomorph! - - - Unknown CitationForm! - - - Unknown Gloss! - - - Unknown Morpheme! - - - Unknown Natural Class! - Update related to ParserCoreStrings.ksUpdateX - - {0} ({1}): {2} - {0} is the lexical form, {1} is the gloss, {2} is the citation form - The XML is not well-formed; you need to correct it and try again. @@ -251,12 +232,18 @@ , Separator to use between multiple slot names when an irregularly inflected form variant fills two or more inflectional affix slots - - Automatically generated null affix for the {0} irregularly inflected form - Content used when showing the details of a parse in Try a Word for these inflectional affix slot fillers. {0} is the Name of the irregularly inflected form variant type. - NoDefaultCompounding If true, no default compounding rules will be used. (Do Not Localize) + + Bad Affix Form + Caption that goes with ksHermitCrabReduplicationProblem + + + The Hermit Crab parser cannot currently run, because the morpheme "{0}" has an invalid reduplication environment. The problem is {1}. + + + Parse was not attempted because of errors in the lexical data + \ No newline at end of file diff --git a/Src/LexText/ParserUI/ParserUITests/ConvertFailuresTests.cs b/Src/LexText/ParserUI/ParserUITests/ConvertFailuresTests.cs deleted file mode 100644 index a313bd7d93..0000000000 --- a/Src/LexText/ParserUI/ParserUITests/ConvertFailuresTests.cs +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright (c) 2003-2013 SIL International -// This software is licensed under the LGPL, version 2.1 or later -// (http://www.gnu.org/licenses/lgpl-2.1.html) -// -// File: ConvertFailuresTests.cs -// Responsibility: - -using System; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Xml; -using System.Xml.Xsl; - -using SIL.FieldWorks.Common.FwUtils; - -using NUnit.Framework; -using SIL.FieldWorks.Test.TestUtils; - -namespace SIL.FieldWorks.LexText.Controls -{ - /// - /// Summary description for ConvertFailuresTests. - /// - [TestFixture] - public class ConvertFailuresTests: BaseTest - { - private XmlDocument m_doc; - - private XAmpleTrace m_xampleTrace = new XAmpleTrace(); - - /// - /// Location of simple test FXT files - /// - protected string m_sTestPath; - - [TestFixtureSetUp] - public void FixtureInit() - { - m_sTestPath = Path.Combine(DirectoryFinder.FwSourceDirectory, - "LexText/ParserUI/ParserUITests"); - string sFailureDocPath = Path.Combine(m_sTestPath, "Failures.xml"); - m_doc = new XmlDocument(); - m_doc.Load(sFailureDocPath); - } - - - [TestFixtureTearDown] - public void FixtureCleanUp() - { - } - - [Test] - [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", - Justification = "In .NET 4.5 XmlNodeList implements IDisposable, but not in 4.0.")] - public void ConvertANCCFailureStrings() - { - XmlNodeList nl = m_doc.SelectNodes("//failure[contains(@test,'ANCC_FT')]"); - Assert.IsTrue(nl.Count == 2, "Two ANCC failures"); - m_xampleTrace.ConvertANCCFailures(m_doc, true); - int i = 1; - foreach (XmlNode node in nl) - { - XmlNode test = node.Attributes.GetNamedItem("test"); - string s = test.InnerText; - switch (i) - { - case 1: - Assert.AreEqual("ANCC_FT: A -/ _ ... AB", s); - break; - case 2: - Assert.AreEqual("ANCC_FT: ABC -/ ABCD ... _ ", s); - break; - } - i++; - } - } - - [Test] - [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", - Justification = "In .NET 4.5 XmlNodeList implements IDisposable, but not in 4.0.")] - public void ConvertMCCFailureStrings() - { - XmlNodeList nl = m_doc.SelectNodes("//failure[contains(@test,'MCC_FT')]"); - Assert.IsTrue(nl.Count == 2, "Two MCC failures"); - m_xampleTrace.ConvertMCCFailures(m_doc, true); - int i = 1; - foreach (XmlNode node in nl) - { - XmlNode test = node.Attributes.GetNamedItem("test"); - string s = test.InnerText; - switch (i) - { - case 1: - Assert.AreEqual("MCC_FT: A +/ ~_ AB", s); - break; - case 2: - Assert.AreEqual("MCC_FT: ABC +/ ABCD ~_", s); - break; - } - i++; - } - } - - [Test] - [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", - Justification = "In .NET 4.5 XmlNodeList implements IDisposable, but not in 4.0.")] - public void ConvertSECFailureStrings() - { - XmlNodeList nl = m_doc.SelectNodes("//failure[contains(@test,'SEC_ST') and contains(@test,'[')]"); - Assert.IsTrue(nl.Count == 8, "Eight SEC failures with classes"); - m_xampleTrace.ConvertSECFailures(m_doc, true); - int i = 1; - foreach (XmlNode node in nl) - { - XmlNode test = node.Attributes.GetNamedItem("test"); - string s = test.InnerText; - switch (i) - { - case 1: - Assert.AreEqual("SEC_ST: dok __ ra / _ [A]", s); - break; - case 2: - Assert.AreEqual("SEC_ST: dok __ ra / _ [AB][ABC]", s); - break; - case 3: - Assert.AreEqual("SEC_ST: migel __ ximura / [ABCD] _", s); - break; - case 4: - Assert.AreEqual("SEC_ST: migel __ ximura / [ABCDE][ABCDEF] _", s); - break; - case 5: - Assert.AreEqual("SEC_ST: migel __ ximura / [A] _ [AB]", s); - break; - case 6: - Assert.AreEqual("SEC_ST: migel __ ximura / [ABC][ABCD] _ [ABCDE]", s); - break; - case 7: - Assert.AreEqual("SEC_ST: migel __ ximura / [ABCDEF] _ [A][AB]", s); - break; - case 8: - Assert.AreEqual("SEC_ST: migel __ ximura / [ABC][ABCD] _ [ABCDE][ABCDEF]", s); - break; - } - i++; - } - } - [Test] - [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", - Justification = "In .NET 4.5 XmlNodeList implements IDisposable, but not in 4.0.")] - public void ConvertInfixEnvironmentFailureStrings() - { - XmlNodeList nl = m_doc.SelectNodes("//failure[contains(@test,'InfixEnvironment') and contains(@test,'[')]"); - Assert.IsTrue(nl.Count == 8, "Eight Infix Environment failures with classes"); - m_xampleTrace.ConvertInfixEnvironmentFailures(m_doc, true); - int i = 1; - foreach (XmlNode node in nl) - { - XmlNode test = node.Attributes.GetNamedItem("test"); - string s = test.InnerText; - switch (i) - { - case 1: - Assert.AreEqual("InfixEnvironment: dok __ ra / _ [A]", s); - break; - case 2: - Assert.AreEqual("InfixEnvironment: dok __ ra / _ [AB][ABC]", s); - break; - case 3: - Assert.AreEqual("InfixEnvironment: migel __ ximura / [ABCD] _", s); - break; - case 4: - Assert.AreEqual("InfixEnvironment: migel __ ximura / [ABCDE][ABCDEF] _", s); - break; - case 5: - Assert.AreEqual("InfixEnvironment: migel __ ximura / [A] _ [AB]", s); - break; - case 6: - Assert.AreEqual("InfixEnvironment: migel __ ximura / [ABC][ABCD] _ [ABCDE]", s); - break; - case 7: - Assert.AreEqual("InfixEnvironment: migel __ ximura / [ABCDEF] _ [A][AB]", s); - break; - case 8: - Assert.AreEqual("InfixEnvironment: migel __ ximura / [ABC][ABCD] _ [ABCDE][ABCDEF]", s); - break; - } - i++; - } - } - } -} diff --git a/Src/LexText/ParserUI/ParserUITests/ParserUITests.csproj b/Src/LexText/ParserUI/ParserUITests/ParserUITests.csproj index 0668149a84..bca2077f04 100644 --- a/Src/LexText/ParserUI/ParserUITests/ParserUITests.csproj +++ b/Src/LexText/ParserUI/ParserUITests/ParserUITests.csproj @@ -81,6 +81,10 @@ x86 + + False + ..\..\..\..\Output\Debug\ApplicationTransforms.dll + False ..\..\..\..\Output\Debug\BasicUtils.dll @@ -112,7 +116,7 @@ System.XML - + False ..\..\..\..\Output\Debug\TestUtils.dll @@ -126,9 +130,6 @@ AssemblyInfoForTests.cs - - Code - Code @@ -143,4 +144,4 @@ - + \ No newline at end of file diff --git a/Src/LexText/ParserUI/ParserUITests/TestUnificationViaXSLT-Linux.xsl b/Src/LexText/ParserUI/ParserUITests/TestUnificationViaXSLT-Linux.xsl deleted file mode 100644 index 28f50a5f37..0000000000 --- a/Src/LexText/ParserUI/ParserUITests/TestUnificationViaXSLT-Linux.xsl +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - -
- - <xsl:value-of select="title"/> - - - - - - - - - - - - - - - -
-
-
-
-
- diff --git a/Src/LexText/ParserUI/ParserUITests/TestUnificationViaXSLT.xsl b/Src/LexText/ParserUI/ParserUITests/TestUnificationViaXSLT.xsl index f9188448ae..bec93ee9f3 100644 --- a/Src/LexText/ParserUI/ParserUITests/TestUnificationViaXSLT.xsl +++ b/Src/LexText/ParserUI/ParserUITests/TestUnificationViaXSLT.xsl @@ -13,7 +13,7 @@ Revision History is at the end of this file. Preamble - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> - + - -yes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -A root can only be a "Partial" when its category is unknown, but the category here is ' - -'. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -A stem requires an overt category, but this root has an unmarked category. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -In attaching an unclassified circumfix: - - - - - - -category - - - -unclassified - - - - -category - - - -stem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -In attaching an unclassified -: - - - - - -category - - - -unclassified - - - - -category - - - -stem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Try to build a Word analysis node on a - - -Partial - - -Full - - - analysis node. - - - - - - - - - - - - - - -The category ' - -' requires inflection, but there was no inflection. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Only proclitics can be before a Word analysis node. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Only enclitics can be after a Word analysis node. - - - - - - - - - - - - - - - - - - - - - - - - - - - - -In attaching a - -: The category ( - -) of the word is incompatible with any of the categories that the proclitic " - -" must attach to ( - - - -, - - -). - - - - - - - - - - - - - - - - - - - - - - - - - - - - -suffix - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -, - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - -Attaching the derivational - - ( - -) - - - -derivational - - ( - -) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -In attaching a derivational -: - - - - - - -from category - - - -derivational - - - - -category - - - -stem - - - - - - - - - -from inflection class - - - -derivational - - - - -inflection class - - - -stem - - - - - - - - - -environment category - - - -derivational - - - - -category - - - -stem - - - - - - - - - - - -from exception feature - - - - -derivational - - - -exception features - - - stem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -circumfix - - - - - - - - - - - - - - - - - - - - - -prefix - - - - - - - - - - - - -x - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -The - - ( - -) of the - - " - -" is incompatible with the - - - ( - -) - - of the - -. - - - - - - - - - - - - - - - -The - - - ( - -) - - of the - - is incompatible with the - - ( - -) of the - -: - - - - - - - - - - - - - - - - -suffix - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -81 - - - - - - - -73 - - - - - - - - - - -7132 - - - - - -In applying the compound rule "noun-adverb -> intransitive verb, ic:2": - -category - - - -left-hand stem - - - -category - -N - -left-hand member of the compound rule - - - - - -In applying the compound rule "noun-adverb -> intransitive verb, ic:2": - -category - - - -right-hand stem - - - -category - -Adv - -right-hand member of the compound rule - - - - - - - - - - - - - - - - - - - - - - - - - - - -73 - - - - - - - -81 - - - - - - - - - - -7136 - - - - - -In applying the compound rule "adverb-noun --> intransitive verb, ic:2": - -category - - - -left-hand stem - - - -category - -Adv - -left-hand member of the compound rule - - - - - -In applying the compound rule "adverb-noun --> intransitive verb, ic:2": - -category - - - -right-hand stem - - - -category - -N - -right-hand member of the compound rule - - - - - - - - - - - - - - - - - - - - - - - - - - - -70 - - - - - - - -81 - - - - - - - - - - -7141 - - - - - -In applying the compound rule "adj-noun with linker ": - -category - - - -left-hand stem - - - -category - -adj - -left-hand member of the compound rule - - - - - -In applying the compound rule "adj-noun with linker ": - -category - - - -right-hand stem - - - -category - -N - -right-hand member of the compound rule - - - - - - - - - - - - - - - - - - - - - - - - - - - -146 - - - - - - - -73 - - - - - - - - - - -7146 - - - - - -In applying the compound rule "verb-adverb ": - -category - - - -left-hand stem - - - -category - -V - -left-hand member of the compound rule - - - - - -In applying the compound rule "verb-adverb ": - -category - - - -right-hand stem - - - -category - -Adv - -right-hand member of the compound rule - - - - - - - - - - - - - - - - - - - - - - - - - - - -81 - - - - - - - -168 - - - - - - - - - - -7150 - - - - - -In applying the compound rule "noun-transitive verb ": - -category - - - -left-hand stem - - - -category - -N - -left-hand member of the compound rule - - - - - -In applying the compound rule "noun-transitive verb ": - -category - - - -right-hand stem - - - -category - -trans - -right-hand member of the compound rule - - - - - - - - - - - - - - - - - - - - - - - - - - - -81 - - - - - - - -153 - - - - - - - - - - -7154 - - - - - -In applying the compound rule "noun-Intransitive verb ": - -category - - - -left-hand stem - - - -category - -N - -left-hand member of the compound rule - - - - - -In applying the compound rule "noun-Intransitive verb ": - -category - - - -right-hand stem - - - -category - -intrans - -right-hand member of the compound rule - - - - - - - - - - - - - - - - - - - - - -153 - -179 - -+ -- - - -153 - -179 - -+ -- - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - -Tried to make the stem be uninflected, but the stem has been inflected via a non-final template. Therefore, a derivatoinal affix or a compound rule must apply first. - - - - - - - - - - - - - - -0 - - - - - - - - - - -0 - - - - - - - - - - - - - - - -- - - -+ - - - - -81 - - - - - - - - - category - -N - -inflectional template - -Possessed noun - -category - - - -stem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Possessed noun' for category 'noun' - - - - - - - - -The inflectional template named 'Possessed noun' for category 'noun' - - -inflectional prefix ( - -) - - - - - - - - - - - - -The inflectional template named 'Possessed noun' for category 'noun' - - - - - - - - -The inflectional template named 'Possessed noun' for category 'noun' - - -inflectional suffix ( - -) - - - - - - - - - - - - -The inflectional template named 'Possessed noun' for category 'noun' - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Possessed noun' for category 'noun' - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Possessed noun' for category 'noun' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. - - -Partial inflectional template has already been inflected. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -0 - - - - - - - - - - -0 - - - - - - - - -81 - - -N - - -- - - -+ - - -The inflectional template named 'Possessed noun' for category 'noun' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. - - -Partial inflectional template has already been inflected. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -0 - - - - - - - - - - -0 - - - - - - - - -82 - - -comm - - -- - - -+ - - -The inflectional template named 'Possessed noun' for category 'noun' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. - - -Partial inflectional template has already been inflected. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -0 - - - - - - - - - - -0 - - - - - - - - -85 - - -conc - - -- - - -+ - - -The inflectional template named 'Possessed noun' for category 'noun' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. - - -Partial inflectional template has already been inflected. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -0 - - - - - - - - - - -0 - - - - - - - - -88 - - -nom - - -- - - -+ - - -The inflectional template named 'Possessed noun' for category 'noun' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. - - -Partial inflectional template has already been inflected. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -0 - - - - - - - - - - -0 - - - - - - - - -91 - - -poss - - -- - - -+ - - -The inflectional template named 'Possessed noun' for category 'noun' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. - - -Partial inflectional template has already been inflected. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -0 - - - - - - - - - - -0 - - - - - - - - -94 - - -prop - - -- - - -+ - - -The inflectional template named 'Possessed noun' for category 'noun' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. - - -Partial inflectional template has already been inflected. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Possessed noun' for category 'noun' failed because in the optional suffix slot 'Possessor', the inflection class of the stem ( - -) does not match any of the inflection classes of the inflectional affix ( - -). The inflection class - - - of this affix is: - - -es of this affix are: - - - - - -, - - -. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -0 - - - - - - - - - - - - -0 - - - - - - - - - - - - - - - -- - - -+ - - - - -153 - - - - - - - - - category - -intrans - -inflectional template - -Intransitive verb - -category - - - -stem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Intransitive verb' for category 'intransitive verb' - - - - - - - - -The inflectional template named 'Intransitive verb' for category 'intransitive verb' - - -inflectional prefix ( - -) - - - - - - - - - - - - -The inflectional template named 'Intransitive verb' for category 'intransitive verb' - - - - - - - - -The inflectional template named 'Intransitive verb' for category 'intransitive verb' - - -inflectional suffix ( - -) - - - - - - - - - - - - -The inflectional template named 'Intransitive verb' for category 'intransitive verb' - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Intransitive verb' for category 'intransitive verb' - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Intransitive verb' for category 'intransitive verb' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. - - -Partial inflectional template has already been inflected. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -0 - - - - - - - - - - - - -0 - - - - - - - - -153 - - -intrans - - -- - - -+ - - -The inflectional template named 'Intransitive verb' for category 'intransitive verb' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. - - -Partial inflectional template has already been inflected. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Intransitive verb' for category 'intransitive verb' failed because in the optional prefix slot 'Subject', the inflection class of the stem ( - -) does not match any of the inflection classes of the inflectional affix ( - -). The inflection class - - - of this affix is: - - -es of this affix are: - - - - - -, - - -. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Intransitive verb' for category 'intransitive verb' failed because in the required suffix slot 'Tense', the inflection class of the stem ( - -) does not match any of the inflection classes of the inflectional affix ( - -). The inflection class - - - of this affix is: - - -es of this affix are: - - - - - -, - - -. - - - - - - - - - - - - -The inflectional template named 'Intransitive verb' for category 'intransitive verb' failed because the required suffix slot 'Tense' was not found. - - - - - - - - - - - - - - - - -0 - - - - - - - - - - - - -0 - - - - - - - - - - - - - - - -- - - -+ - - - - -163 - - - - - - - - - category - -sta - -inflectional template - -Stative verb - -category - - - -stem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Stative verb' for category 'stative' - - - - - - - - -The inflectional template named 'Stative verb' for category 'stative' - - -inflectional prefix ( - -) - - - - - - - - - - - - -The inflectional template named 'Stative verb' for category 'stative' - - - - - - - - -The inflectional template named 'Stative verb' for category 'stative' - - -inflectional suffix ( - -) - - - - - - - - - - - - -The inflectional template named 'Stative verb' for category 'stative' - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Stative verb' for category 'stative' - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Stative verb' for category 'stative' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. - - -Partial inflectional template has already been inflected. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -0 - - - - - - - - - - - - -0 - - - - - - - - -163 - - -sta - - -- - - -+ - - -The inflectional template named 'Stative verb' for category 'stative' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. - - -Partial inflectional template has already been inflected. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Stative verb' for category 'stative' failed because in the optional prefix slot 'Subject', the inflection class of the stem ( - -) does not match any of the inflection classes of the inflectional affix ( - -). The inflection class - - - of this affix is: - - -es of this affix are: - - - - - -, - - -. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Stative verb' for category 'stative' failed because in the required suffix slot 'Tense', the inflection class of the stem ( - -) does not match any of the inflection classes of the inflectional affix ( - -). The inflection class - - - of this affix is: - - -es of this affix are: - - - - - -, - - -. - - - - - - - - - - - - -The inflectional template named 'Stative verb' for category 'stative' failed because the required suffix slot 'Tense' was not found. - - - - - - - - - - - - - - - - -0 - - - - - - - - - - - - -0 - - - - - - - - - - - - - - - -- - - -+ - - - - -168 - - - - - - - - - category - -trans - -inflectional template - -Transitive verb - -category - - - -stem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Transitive verb' for category 'transitive verb' - - - - - - - - -The inflectional template named 'Transitive verb' for category 'transitive verb' - - -inflectional prefix ( - -) - - - - - - - - - - - - -The inflectional template named 'Transitive verb' for category 'transitive verb' - - - - - - - - -The inflectional template named 'Transitive verb' for category 'transitive verb' - - -inflectional suffix ( - -) - - - - - - - - - - - - -The inflectional template named 'Transitive verb' for category 'transitive verb' - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Transitive verb' for category 'transitive verb' - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Transitive verb' for category 'transitive verb' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. - - -Partial inflectional template has already been inflected. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -0 - - - - - - - - - - - - -0 - - - - - - - - -168 - - -trans - - -- - - -+ - - -The inflectional template named 'Transitive verb' for category 'transitive verb' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. - - -Partial inflectional template has already been inflected. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Transitive verb' for category 'transitive verb' failed because in the required prefix slot 'Object', the inflection class of the stem ( - -) does not match any of the inflection classes of the inflectional affix ( - -). The inflection class - - - of this affix is: - - -es of this affix are: - - - - - -, - - -. - - - - - - - - - - - - - - - -The inflectional template named 'Transitive verb' for category 'transitive verb' failed because the required prefix slot 'Object' was not found. - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Transitive verb' for category 'transitive verb' failed because in the optional prefix slot 'Subject', the inflection class of the stem ( - -) does not match any of the inflection classes of the inflectional affix ( - -). The inflection class - - - of this affix is: - - -es of this affix are: - - - - - -, - - -. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Transitive verb' for category 'transitive verb' failed because in the required suffix slot 'Tense', the inflection class of the stem ( - -) does not match any of the inflection classes of the inflectional affix ( - -). The inflection class - - - of this affix is: - - -es of this affix are: - - - - - -, - - -. - - - - - - - - - - - - -The inflectional template named 'Transitive verb' for category 'transitive verb' failed because the required suffix slot 'Tense' was not found. - - - - - - - - - - - - - - - - -0 - - - - - - - - - - - - -0 - - - - - - - - - - - - - - - -- - - -+ - - - - -172 - - - - - - - - - category - -bitrans - -inflectional template - -Bitransitive verb - -category - - - -stem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Bitransitive verb' for category 'bitransitive verb' - - - - - - - - -The inflectional template named 'Bitransitive verb' for category 'bitransitive verb' - - -inflectional prefix ( - -) - - - - - - - - - - - - -The inflectional template named 'Bitransitive verb' for category 'bitransitive verb' - - - - - - - - -The inflectional template named 'Bitransitive verb' for category 'bitransitive verb' - - -inflectional suffix ( - -) - - - - - - - - - - - - -The inflectional template named 'Bitransitive verb' for category 'bitransitive verb' - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Bitransitive verb' for category 'bitransitive verb' - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Bitransitive verb' for category 'bitransitive verb' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. - - -Partial inflectional template has already been inflected. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -0 - - - - - - - - - - - - -0 - - - - - - - - -172 - - -bitrans - - -- - - -+ - - -The inflectional template named 'Bitransitive verb' for category 'bitransitive verb' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. - - -Partial inflectional template has already been inflected. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Bitransitive verb' for category 'bitransitive verb' failed because in the required prefix slot 'Object', the inflection class of the stem ( - -) does not match any of the inflection classes of the inflectional affix ( - -). The inflection class - - - of this affix is: - - -es of this affix are: - - - - - -, - - -. - - - - - - - - - - - - - - - -The inflectional template named 'Bitransitive verb' for category 'bitransitive verb' failed because the required prefix slot 'Object' was not found. - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Bitransitive verb' for category 'bitransitive verb' failed because in the optional prefix slot 'Subject', the inflection class of the stem ( - -) does not match any of the inflection classes of the inflectional affix ( - -). The inflection class - - - of this affix is: - - -es of this affix are: - - - - - -, - - -. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -The inflectional template named 'Bitransitive verb' for category 'bitransitive verb' failed because in the required suffix slot 'Tense', the inflection class of the stem ( - -) does not match any of the inflection classes of the inflectional affix ( - -). The inflection class - - - of this affix is: - - -es of this affix are: - - - - - -, - - -. - - - - - - - - - - - - -The inflectional template named 'Bitransitive verb' for category 'bitransitive verb' failed because the required suffix slot 'Tense' was not found. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -[ - - - - - -: - - - - - - - - - - - - - -] - - - - - - - - - - - - - - - - - - - - - - -from exception feature - - - - -inflectional - - - -exception features - - - stem - - - - - - - - - - - - - - - - - -inflectional prefix ( - -) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -inflectional suffix ( - -) - - - - - - - - - - - - - - - - - - - - - - - - -Y - - - - -N - - - - - -PriorityUnionOf( - - -UnificationOf( - - - - - - -Empty - -and - - - - -Empty - -) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -N - - - - - - - - - - - - - - - - - - - - - - - - - - - - failed because at least one inflection feature of the is incompatible with the inflection features of the . The incompatibility is for feature . This feature for the has a value of but the corresponding feature for the has a value of . - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Y - - -N - - - - - - - - - - - - - - - - - - - -Y - - -N - - - - -N - - - - - - - - diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/TLPSameSlotTwiceWordGrammarDebugger.xsl b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/TLPSameSlotTwiceWordGrammarDebugger.xsl index c7a9b0ab3d..e3cf1d89dc 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/TLPSameSlotTwiceWordGrammarDebugger.xsl +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/TLPSameSlotTwiceWordGrammarDebugger.xsl @@ -1,5 +1,5 @@ - + - + - + @@ -2103,9 +2103,9 @@ InflectionalTemplate102 - - - + + + The inflectional template named 'Possessed noun' for category 'noun' @@ -2125,7 +2125,7 @@ InflectionalTemplate102 - + The inflectional template named 'Possessed noun' for category 'noun' @@ -2136,17 +2136,17 @@ InflectionalTemplate102 - + - + - - + + The inflectional template named 'Possessed noun' for category 'noun' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. @@ -2890,9 +2890,9 @@ InflectionalTemplate156 - - - + + + The inflectional template named 'Intransitive verb' for category 'intransitive verb' @@ -2912,7 +2912,7 @@ InflectionalTemplate156 - + The inflectional template named 'Intransitive verb' for category 'intransitive verb' @@ -2923,17 +2923,17 @@ InflectionalTemplate156 - + - + - - + + The inflectional template named 'Intransitive verb' for category 'intransitive verb' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. @@ -3341,9 +3341,9 @@ InflectionalTemplate166 - - - + + + The inflectional template named 'Stative verb' for category 'stative' @@ -3363,7 +3363,7 @@ InflectionalTemplate166 - + The inflectional template named 'Stative verb' for category 'stative' @@ -3374,17 +3374,17 @@ InflectionalTemplate166 - + - + - - + + The inflectional template named 'Stative verb' for category 'stative' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. @@ -3792,9 +3792,9 @@ InflectionalTemplate171 - - - + + + The inflectional template named 'Transitive verb' for category 'transitive verb' @@ -3814,7 +3814,7 @@ InflectionalTemplate171 - + The inflectional template named 'Transitive verb' for category 'transitive verb' @@ -3825,17 +3825,17 @@ InflectionalTemplate171 - + - + - - + + The inflectional template named 'Transitive verb' for category 'transitive verb' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. @@ -4307,9 +4307,9 @@ InflectionalTemplate175 - - - + + + The inflectional template named 'Bitransitive verb' for category 'bitransitive verb' @@ -4329,7 +4329,7 @@ InflectionalTemplate175 - + The inflectional template named 'Bitransitive verb' for category 'bitransitive verb' @@ -4340,17 +4340,17 @@ InflectionalTemplate175 - + - + - - + + The inflectional template named 'Bitransitive verb' for category 'bitransitive verb' failed because the stem was built by a non-final template and there was no intervening derivation or compounding. @@ -5515,7 +5515,7 @@ UnifyPrefixSlots - + @@ -5561,7 +5561,7 @@ UnifySuffixSlots - + @@ -5608,14 +5608,14 @@ UnifyTwoFeatureStructures - + Empty and - + Empty @@ -5624,16 +5624,16 @@ UnifyTwoFeatureStructures - + - + - + @@ -5723,13 +5723,13 @@ XSubsumesY N - + - - + + diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep00.xml index 2599af0a5d..d82483730f 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep00.xml @@ -1,7 +1,7 @@ fpfptov - + @@ -82,7 +82,7 @@ - + A root can only be a "Partial" when its category is unknown, but the category here is 'n'. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep00Result.xml index 49705eee58..7104af0209 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep00Result.xml @@ -1,7 +1,7 @@
fpfptov
- + @@ -101,7 +101,7 @@
- + @@ -184,7 +184,7 @@ - + The category (N) of the inflectional template "Possessed noun" is incompatible with the category (n) of the stem. @@ -240,7 +240,7 @@ - + The category (comm) of the inflectional template "test stem name features" is incompatible with the category (n) of the stem. @@ -296,7 +296,7 @@ - + The category (intrans) of the inflectional template "Intransitive verb" is incompatible with the category (n) of the stem. @@ -398,7 +398,7 @@ - + The category (sta) of the inflectional template "Stative verb" is incompatible with the category (n) of the stem. @@ -500,7 +500,7 @@ - + The category (trans) of the inflectional template "Transitive verb" is incompatible with the category (n) of the stem. @@ -603,7 +603,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (n) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep01.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep01.xml index 586c79bfe9..f07bc4d4ca 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep01.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep01.xml @@ -82,7 +82,7 @@ - + @@ -182,7 +182,7 @@ - + @@ -265,7 +265,7 @@ - + @@ -320,7 +320,7 @@ - + @@ -420,7 +420,7 @@ - + The category (v) of the inflectional template "Tense/Aspect" is incompatible with the category (n) of the stem. @@ -521,7 +521,7 @@ - + The category (v) of the inflectional template "Non-final" is incompatible with the category (n) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep01Result.xml index 3ccc0b8e69..c5cc71303d 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep01Result.xml @@ -82,7 +82,7 @@ - + In attaching a derivational suffix: The from category (n) of the derivational suffix "-0 (ForWGD): 0" is incompatible with the category (v) of the stem. @@ -185,7 +185,7 @@ - + @@ -287,7 +287,7 @@ - + The category (N) of the inflectional template "Possessed noun" is incompatible with the category (v) of the stem. @@ -315,7 +315,7 @@ - + The category (comm) of the inflectional template "test stem name features" is incompatible with the category (v) of the stem. @@ -343,7 +343,7 @@ - + The category (intrans) of the inflectional template "Intransitive verb" is incompatible with the category (v) of the stem. @@ -464,7 +464,7 @@ - + The category (sta) of the inflectional template "Stative verb" is incompatible with the category (v) of the stem. @@ -585,7 +585,7 @@ - + The category (trans) of the inflectional template "Transitive verb" is incompatible with the category (v) of the stem. @@ -707,7 +707,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (v) of the stem. @@ -829,7 +829,7 @@ - + The category 'n' requires inflection, but there was no inflection. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep02.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep02.xml index 0b57a4b424..3d8cced89b 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep02.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep02.xml @@ -101,7 +101,7 @@ - + In attaching a derivational suffix: The from category (n) of the derivational suffix "-0 (ForWGD): 0" is incompatible with the category (v) of the stem. @@ -204,7 +204,7 @@ - + @@ -306,7 +306,7 @@ - + The category (n) of the inflectional template "template for test" is incompatible with the category (v) of the stem. @@ -334,7 +334,7 @@ - + The category (n) of the inflectional template "possessed" is incompatible with the category (v) of the stem. @@ -454,7 +454,7 @@ - + @@ -573,7 +573,7 @@ - + diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep02Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep02Result.xml index 22de9e7c59..2aabdb6a8d 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep02Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfptovAffixAlloFeatsStep02Result.xml @@ -101,7 +101,7 @@ - + The category 'v' requires inflection, but there was no inflection. @@ -206,7 +206,7 @@ - + diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfstovAffixAlloFeatsStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfstovAffixAlloFeatsStep00.xml index 62c13a5a1b..a83487dc9d 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfstovAffixAlloFeatsStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfstovAffixAlloFeatsStep00.xml @@ -1,7 +1,7 @@
fpfstov
- + @@ -73,7 +73,7 @@ - + A root can only be a "Partial" when its category is unknown, but the category here is 'n'. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfstovAffixAlloFeatsStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfstovAffixAlloFeatsStep00Result.xml index c65b64d6f8..373a59092a 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfstovAffixAlloFeatsStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfstovAffixAlloFeatsStep00Result.xml @@ -1,7 +1,7 @@
fpfstov
- + @@ -93,7 +93,7 @@
- + @@ -167,7 +167,7 @@ - + The category (N) of the inflectional template "Possessed noun" is incompatible with the category (n) of the stem. @@ -214,7 +214,7 @@ - + The category (comm) of the inflectional template "test stem name features" is incompatible with the category (n) of the stem. @@ -261,7 +261,7 @@ - + The category (intrans) of the inflectional template "Intransitive verb" is incompatible with the category (n) of the stem. @@ -354,7 +354,7 @@ - + The category (sta) of the inflectional template "Stative verb" is incompatible with the category (n) of the stem. @@ -447,7 +447,7 @@ - + The category (trans) of the inflectional template "Transitive verb" is incompatible with the category (n) of the stem. @@ -541,7 +541,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (n) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfstovAffixAlloFeatsStep01.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfstovAffixAlloFeatsStep01.xml index f0766fb9bb..f8564d3643 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfstovAffixAlloFeatsStep01.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfstovAffixAlloFeatsStep01.xml @@ -73,7 +73,7 @@ - + @@ -165,7 +165,7 @@ - + @@ -239,7 +239,7 @@ - + @@ -285,7 +285,7 @@ - + @@ -376,7 +376,7 @@ - + The category (v) of the inflectional template "Tense/Aspect" is incompatible with the category (n) of the stem. @@ -468,7 +468,7 @@ - + The category (v) of the inflectional template "Non-final" is incompatible with the category (n) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfstovAffixAlloFeatsStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfstovAffixAlloFeatsStep01Result.xml index cf2ac16e7f..a05399038d 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfstovAffixAlloFeatsStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fpfstovAffixAlloFeatsStep01Result.xml @@ -73,7 +73,7 @@ - + The category 'n' requires inflection, but there was no inflection. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfptovAffixAlloFeatsStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfptovAffixAlloFeatsStep00.xml index 7d53ecf7b7..8eca3f7b4c 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfptovAffixAlloFeatsStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfptovAffixAlloFeatsStep00.xml @@ -1,7 +1,7 @@
fsfptov
- + @@ -75,7 +75,7 @@ - + A root can only be a "Partial" when its category is unknown, but the category here is 'n'. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfptovAffixAlloFeatsStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfptovAffixAlloFeatsStep00Result.xml index 53a6348445..b0a39b418c 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfptovAffixAlloFeatsStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfptovAffixAlloFeatsStep00Result.xml @@ -1,7 +1,7 @@
fsfptov
- + @@ -95,7 +95,7 @@
- + @@ -171,7 +171,7 @@ - + The category (N) of the inflectional template "Possessed noun" is incompatible with the category (n) of the stem. @@ -220,7 +220,7 @@ - + The category (comm) of the inflectional template "test stem name features" is incompatible with the category (n) of the stem. @@ -269,7 +269,7 @@ - + The category (intrans) of the inflectional template "Intransitive verb" is incompatible with the category (n) of the stem. @@ -364,7 +364,7 @@ - + The category (sta) of the inflectional template "Stative verb" is incompatible with the category (n) of the stem. @@ -459,7 +459,7 @@ - + The category (trans) of the inflectional template "Transitive verb" is incompatible with the category (n) of the stem. @@ -555,7 +555,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (n) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfptovAffixAlloFeatsStep01.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfptovAffixAlloFeatsStep01.xml index eab3ba6f73..759d4acc40 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfptovAffixAlloFeatsStep01.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfptovAffixAlloFeatsStep01.xml @@ -75,7 +75,7 @@ - + @@ -169,7 +169,7 @@ - + @@ -245,7 +245,7 @@ - + @@ -293,7 +293,7 @@ - + @@ -386,7 +386,7 @@ - + The category (v) of the inflectional template "Tense/Aspect" is incompatible with the category (n) of the stem. @@ -480,7 +480,7 @@ - + The category (v) of the inflectional template "Non-final" is incompatible with the category (n) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfptovAffixAlloFeatsStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfptovAffixAlloFeatsStep01Result.xml index f38b3b20b8..458ca152cc 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfptovAffixAlloFeatsStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfptovAffixAlloFeatsStep01Result.xml @@ -75,7 +75,7 @@ - + The category 'n' requires inflection, but there was no inflection. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep00.xml index 4561dd13e0..38775cf9ca 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep00.xml @@ -1,7 +1,7 @@
fsfstov
- + @@ -80,7 +80,7 @@ - + A root can only be a "Partial" when its category is unknown, but the category here is 'n'. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep00Result.xml index 9c0799f0bf..09585023b5 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep00Result.xml @@ -1,7 +1,7 @@
fsfstov
- + @@ -99,7 +99,7 @@
- + @@ -180,7 +180,7 @@ - + The category (N) of the inflectional template "Possessed noun" is incompatible with the category (n) of the stem. @@ -234,7 +234,7 @@ - + The category (comm) of the inflectional template "test stem name features" is incompatible with the category (n) of the stem. @@ -288,7 +288,7 @@ - + The category (intrans) of the inflectional template "Intransitive verb" is incompatible with the category (n) of the stem. @@ -388,7 +388,7 @@ - + The category (sta) of the inflectional template "Stative verb" is incompatible with the category (n) of the stem. @@ -488,7 +488,7 @@ - + The category (trans) of the inflectional template "Transitive verb" is incompatible with the category (n) of the stem. @@ -589,7 +589,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (n) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep01.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep01.xml index 9854242f23..33ac9617fd 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep01.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep01.xml @@ -80,7 +80,7 @@ - + @@ -178,7 +178,7 @@ - + @@ -259,7 +259,7 @@ - + @@ -312,7 +312,7 @@ - + @@ -410,7 +410,7 @@ - + The category (v) of the inflectional template "Tense/Aspect" is incompatible with the category (n) of the stem. @@ -509,7 +509,7 @@ - + The category (v) of the inflectional template "Non-final" is incompatible with the category (n) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep01Result.xml index 8b37b60497..16b98f89c4 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep01Result.xml @@ -80,7 +80,7 @@ - + In attaching a derivational suffix: The from category (n) of the derivational suffix "-0 (ForWGD): 0" is incompatible with the category (v) of the stem. @@ -181,7 +181,7 @@ - + @@ -281,7 +281,7 @@ - + The category (N) of the inflectional template "Possessed noun" is incompatible with the category (v) of the stem. @@ -309,7 +309,7 @@ - + The category (comm) of the inflectional template "test stem name features" is incompatible with the category (v) of the stem. @@ -337,7 +337,7 @@ - + The category (intrans) of the inflectional template "Intransitive verb" is incompatible with the category (v) of the stem. @@ -456,7 +456,7 @@ - + The category (sta) of the inflectional template "Stative verb" is incompatible with the category (v) of the stem. @@ -575,7 +575,7 @@ - + The category (trans) of the inflectional template "Transitive verb" is incompatible with the category (v) of the stem. @@ -695,7 +695,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (v) of the stem. @@ -815,7 +815,7 @@ - + The category 'n' requires inflection, but there was no inflection. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep02.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep02.xml index 754cd075f7..d545cae9cc 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep02.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep02.xml @@ -99,7 +99,7 @@ - + In attaching a derivational suffix: The from category (n) of the derivational suffix "-0 (ForWGD): 0" is incompatible with the category (v) of the stem. @@ -200,7 +200,7 @@ - + @@ -300,7 +300,7 @@ - + The category (n) of the inflectional template "template for test" is incompatible with the category (v) of the stem. @@ -328,7 +328,7 @@ - + The category (n) of the inflectional template "possessed" is incompatible with the category (v) of the stem. @@ -446,7 +446,7 @@ - + @@ -563,7 +563,7 @@ - + diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep02Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep02Result.xml index fb06d0cd31..9340aa4f43 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep02Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsfstovAffixAlloFeatsStep02Result.xml @@ -99,7 +99,7 @@ - + The category 'v' requires inflection, but there was no inflection. @@ -202,7 +202,7 @@ - + diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep00.xml index 6a9f260491..97572ed3f0 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep00.xml @@ -1,7 +1,7 @@
fsinfl
- + @@ -99,7 +99,7 @@ - + A root can only be a "Partial" when its category is unknown, but the category here is 'n'. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep00Result.xml index f58bc3a110..1e8aabe3c8 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep00Result.xml @@ -1,7 +1,7 @@
fsinfl
- + @@ -101,7 +101,7 @@
- + The category (N) of the inflectional template "Possessed noun" is incompatible with the category (n) of the stem. @@ -174,7 +174,7 @@ - + The category (comm) of the inflectional template "test stem name features" is incompatible with the category (n) of the stem. @@ -247,7 +247,7 @@ - + The category (intrans) of the inflectional template "Intransitive verb" is incompatible with the category (n) of the stem. @@ -366,7 +366,7 @@ - + The category (sta) of the inflectional template "Stative verb" is incompatible with the category (n) of the stem. @@ -485,7 +485,7 @@ - + The category (trans) of the inflectional template "Transitive verb" is incompatible with the category (n) of the stem. @@ -605,7 +605,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (n) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep01.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep01.xml index c8c3902742..38ccd0c991 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep01.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep01.xml @@ -99,7 +99,7 @@ - + @@ -199,7 +199,7 @@ - + @@ -226,7 +226,7 @@ - + @@ -343,7 +343,7 @@ - + The category (v) of the inflectional template "Tense/Aspect" is incompatible with the category (n) of the stem. @@ -461,7 +461,7 @@ - + The category (v) of the inflectional template "Non-final" is incompatible with the category (n) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep01Result.xml index cab7c078c2..d024a2da71 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep01Result.xml @@ -99,7 +99,7 @@ - + The category 'n' requires inflection, but there was no inflection. @@ -202,7 +202,7 @@ - + diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep02.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep02.xml index 517a541794..24928710fc 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep02.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep02.xml @@ -118,7 +118,7 @@ - + diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep02Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep02Result.xml index 337fdf39ea..f760929806 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep02Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/fsinflAffixAlloFeatsStep02Result.xml @@ -118,7 +118,7 @@ - + diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/mpmsAffixAlloFeatsStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/mpmsAffixAlloFeatsStep00.xml index 0a51aa2ab0..261bf88c44 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/mpmsAffixAlloFeatsStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/mpmsAffixAlloFeatsStep00.xml @@ -1,7 +1,7 @@
mpms
- + @@ -73,7 +73,7 @@ - + A root can only be a "Partial" when its category is unknown, but the category here is 'n'. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/mpmsAffixAlloFeatsStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/mpmsAffixAlloFeatsStep00Result.xml index 4cfb0f3859..20d54d73d3 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/mpmsAffixAlloFeatsStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/mpmsAffixAlloFeatsStep00Result.xml @@ -1,7 +1,7 @@
mpms
- + @@ -75,7 +75,7 @@
- + The category (N) of the inflectional template "Possessed noun" is incompatible with the category (n) of the stem. @@ -122,7 +122,7 @@ - + The category (comm) of the inflectional template "test stem name features" is incompatible with the category (n) of the stem. @@ -169,7 +169,7 @@ - + The category (intrans) of the inflectional template "Intransitive verb" is incompatible with the category (n) of the stem. @@ -262,7 +262,7 @@ - + The category (sta) of the inflectional template "Stative verb" is incompatible with the category (n) of the stem. @@ -355,7 +355,7 @@ - + The category (trans) of the inflectional template "Transitive verb" is incompatible with the category (n) of the stem. @@ -449,7 +449,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (n) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/mpmsAffixAlloFeatsStep01.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/mpmsAffixAlloFeatsStep01.xml index 83da6ac6e3..9c7cef13d3 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/mpmsAffixAlloFeatsStep01.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/mpmsAffixAlloFeatsStep01.xml @@ -73,7 +73,7 @@ - + @@ -147,7 +147,7 @@ - + The inflectional affix allomorph '-ms (INFL): infl' is conditioned to only occur when the inflected form it attaches to has certain features, but the inflected form does not have them. The required features the affix must be inflected for are: [nagr:[gen:m num:sg]]. The inflected features for this inflected form are: [nagr:[gen:m num:pl]]. @@ -168,7 +168,7 @@
nagrgenmnumplmp (masc.pl): mpmpmasc.plmpnagrgenmnumpl-ms (INFL): infl-msnagrgenmnumsgINFLinfl
- + @@ -259,7 +259,7 @@ - + The category (v) of the inflectional template "Tense/Aspect" is incompatible with the category (n) of the stem. @@ -351,7 +351,7 @@ - + The category (v) of the inflectional template "Non-final" is incompatible with the category (n) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/mpmsAffixAlloFeatsStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/mpmsAffixAlloFeatsStep01Result.xml index c47a6e6b0a..af058db4a3 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/mpmsAffixAlloFeatsStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/mpmsAffixAlloFeatsStep01Result.xml @@ -73,7 +73,7 @@ - + The category 'n' requires inflection, but there was no inflection. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msinflAffixAlloFeatsStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msinflAffixAlloFeatsStep00.xml index d6da6ee1b8..5c0b4acc31 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msinflAffixAlloFeatsStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msinflAffixAlloFeatsStep00.xml @@ -1,7 +1,7 @@
msinfl
- + @@ -92,7 +92,7 @@ - + A root can only be a "Partial" when its category is unknown, but the category here is 'n'. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msinflAffixAlloFeatsStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msinflAffixAlloFeatsStep00Result.xml index 31a5986954..1c18db29c3 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msinflAffixAlloFeatsStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msinflAffixAlloFeatsStep00Result.xml @@ -1,7 +1,7 @@
msinfl
- + @@ -94,7 +94,7 @@
- + The category (N) of the inflectional template "Possessed noun" is incompatible with the category (n) of the stem. @@ -160,7 +160,7 @@ - + The category (comm) of the inflectional template "test stem name features" is incompatible with the category (n) of the stem. @@ -226,7 +226,7 @@ - + The category (intrans) of the inflectional template "Intransitive verb" is incompatible with the category (n) of the stem. @@ -338,7 +338,7 @@ - + The category (sta) of the inflectional template "Stative verb" is incompatible with the category (n) of the stem. @@ -450,7 +450,7 @@ - + The category (trans) of the inflectional template "Transitive verb" is incompatible with the category (n) of the stem. @@ -563,7 +563,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (n) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msinflAffixAlloFeatsStep01.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msinflAffixAlloFeatsStep01.xml index 8b119bd8ed..8999becc6c 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msinflAffixAlloFeatsStep01.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msinflAffixAlloFeatsStep01.xml @@ -92,7 +92,7 @@ - + @@ -185,7 +185,7 @@ - + While the inflectional affix allomorph '-infl (INFL): infl' is not conditioned to occur when the inflected form it attaches to has certain features, there are other allomorphs in the entry that are so conditioned. Thus, the inflected form must not be inflected for certain features, but it is. The features the affix must not be inflected for are: [nagr:[gen:m num:pl]] and also [nagr:[gen:m num:sg]]. The inflected features for this inflected form are: [nagr:[gen:m num:sg]]. @@ -206,7 +206,7 @@ nagrgenmnumsgms (masc.sing): msmsmasc.singmsnagrgenmnumsg-infl (INFL): infl-inflnagrgenmnumplnagrgenmnumsgINFLinfl - + @@ -316,7 +316,7 @@ - + The category (v) of the inflectional template "Tense/Aspect" is incompatible with the category (n) of the stem. @@ -427,7 +427,7 @@ - + The category (v) of the inflectional template "Non-final" is incompatible with the category (n) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msinflAffixAlloFeatsStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msinflAffixAlloFeatsStep01Result.xml index 52177fc9b5..35b162a5be 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msinflAffixAlloFeatsStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msinflAffixAlloFeatsStep01Result.xml @@ -92,7 +92,7 @@ - + The category 'n' requires inflection, but there was no inflection. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep00.xml index c5ea54ed9a..eb1a4a6604 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep00.xml @@ -1,7 +1,7 @@
msms
- + @@ -80,7 +80,7 @@ - + A root can only be a "Partial" when its category is unknown, but the category here is 'n'. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep00Result.xml index 1da162d660..40e18485a1 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep00Result.xml @@ -1,7 +1,7 @@
msms
- + @@ -82,7 +82,7 @@
- + The category (N) of the inflectional template "Possessed noun" is incompatible with the category (n) of the stem. @@ -136,7 +136,7 @@ - + The category (comm) of the inflectional template "test stem name features" is incompatible with the category (n) of the stem. @@ -190,7 +190,7 @@ - + The category (intrans) of the inflectional template "Intransitive verb" is incompatible with the category (n) of the stem. @@ -290,7 +290,7 @@ - + The category (sta) of the inflectional template "Stative verb" is incompatible with the category (n) of the stem. @@ -390,7 +390,7 @@ - + The category (trans) of the inflectional template "Transitive verb" is incompatible with the category (n) of the stem. @@ -491,7 +491,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (n) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep01.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep01.xml index 6a449e8825..a2d3b43e73 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep01.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep01.xml @@ -80,7 +80,7 @@ - + @@ -161,7 +161,7 @@ - + @@ -188,7 +188,7 @@ - + @@ -286,7 +286,7 @@ - + The category (v) of the inflectional template "Tense/Aspect" is incompatible with the category (n) of the stem. @@ -385,7 +385,7 @@ - + The category (v) of the inflectional template "Non-final" is incompatible with the category (n) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep01Result.xml index 4da1e89333..3c8a3b878d 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep01Result.xml @@ -80,7 +80,7 @@ - + The category 'n' requires inflection, but there was no inflection. @@ -164,7 +164,7 @@ - + diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep02.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep02.xml index 29d0f89b45..8a1fde48b4 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep02.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep02.xml @@ -99,7 +99,7 @@ - + diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep02Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep02Result.xml index 526d1066c3..cc6423c161 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep02Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/msmsAffixAlloFeatsStep02Result.xml @@ -99,7 +99,7 @@ - + diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuhohwusaStemNameNotSetFailStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuhohwusaStemNameNotSetFailStep00.xml index f8a6a7b660..11642c363b 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuhohwusaStemNameNotSetFailStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuhohwusaStemNameNotSetFailStep00.xml @@ -1,7 +1,7 @@
niyuhohwusa
- + ni- (1SgSubj): ni ni- @@ -51,7 +51,7 @@
- + ni- (1SgSubj): ni ni- diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuhohwusaStemNameNotSetFailStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuhohwusaStemNameNotSetFailStep00Result.xml index 948fb40a4e..2b00a4f765 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuhohwusaStemNameNotSetFailStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuhohwusaStemNameNotSetFailStep00Result.xml @@ -1,7 +1,7 @@
niyuhohwusa
- + ni- (1SgSubj): ni ni- @@ -54,7 +54,7 @@
- + ni- (1SgSubj): ni ni- @@ -106,7 +106,7 @@
- + ni- (1SgSubj): ni ni- @@ -148,7 +148,7 @@ - + ni- (1SgSubj): ni ni- @@ -190,7 +190,7 @@ - + ni- (1SgSubj): ni ni- @@ -244,7 +244,7 @@ - + ni- (1SgSubj): ni ni- @@ -298,7 +298,7 @@ - + ni- (1SgSubj): ni @@ -351,7 +351,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuhohwusaStemNameNotSetFailStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuhohwusaStemNameNotSetFailStep01Result.xml index fc1676a55b..cc1b3fd2bb 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuhohwusaStemNameNotSetFailStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuhohwusaStemNameNotSetFailStep01Result.xml @@ -51,7 +51,7 @@ - + ni- (1SgSubj): ni ni- @@ -104,7 +104,7 @@ - + ni- (1SgSubj): ni ni- @@ -156,7 +156,7 @@ - + ni- (1SgSubj): ni ni- @@ -198,7 +198,7 @@ - + ni- (1SgSubj): ni ni- @@ -240,7 +240,7 @@ - + ni- (1SgSubj): ni ni- @@ -294,7 +294,7 @@ - + ni- (1SgSubj): ni ni- @@ -348,7 +348,7 @@ - + ni- (1SgSubj): ni @@ -401,7 +401,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuhohwusaStemNameNotSetFailStep02Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuhohwusaStemNameNotSetFailStep02Result.xml index 08977395fa..d5b334a097 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuhohwusaStemNameNotSetFailStep02Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuhohwusaStemNameNotSetFailStep02Result.xml @@ -54,7 +54,7 @@ - + ni- (1SgSubj): ni ni- @@ -109,7 +109,7 @@ - + ni- (1SgSubj): ni ni- @@ -144,7 +144,7 @@ - + ni- (1SgSubj): ni ni- @@ -179,7 +179,7 @@ - + ni- (1SgSubj): ni ni- @@ -241,7 +241,7 @@ - + ni- (1SgSubj): ni ni- @@ -298,7 +298,7 @@ - + @@ -360,7 +360,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyumamwupeStemNameSetNoFsStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyumamwupeStemNameSetNoFsStep00.xml index 5001eba92b..40026135e9 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyumamwupeStemNameSetNoFsStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyumamwupeStemNameSetNoFsStep00.xml @@ -1,7 +1,7 @@
niyumamwupe
- + ni- (1SgSubj): ni ni- @@ -58,7 +58,7 @@ - + ni- (1SgSubj): ni ni- diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyumamwupeStemNameSetNoFsStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyumamwupeStemNameSetNoFsStep00Result.xml index 2859183ae0..76522383f2 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyumamwupeStemNameSetNoFsStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyumamwupeStemNameSetNoFsStep00Result.xml @@ -1,7 +1,7 @@
niyumamwupe
- + ni- (1SgSubj): ni ni- @@ -61,7 +61,7 @@ - + ni- (1SgSubj): ni ni- @@ -120,7 +120,7 @@ - + ni- (1SgSubj): ni ni- @@ -169,7 +169,7 @@ - + ni- (1SgSubj): ni ni- @@ -218,7 +218,7 @@ - + ni- (1SgSubj): ni ni- @@ -279,7 +279,7 @@ - + ni- (1SgSubj): ni ni- @@ -340,7 +340,7 @@ - + ni- (1SgSubj): ni @@ -400,7 +400,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyumamwupeStemNameSetNoFsStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyumamwupeStemNameSetNoFsStep01Result.xml index 22436d078b..27f1241040 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyumamwupeStemNameSetNoFsStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyumamwupeStemNameSetNoFsStep01Result.xml @@ -58,7 +58,7 @@ - + ni- (1SgSubj): ni ni- @@ -118,7 +118,7 @@ - + ni- (1SgSubj): ni ni- @@ -177,7 +177,7 @@ - + ni- (1SgSubj): ni ni- @@ -226,7 +226,7 @@ - + ni- (1SgSubj): ni ni- @@ -275,7 +275,7 @@ - + ni- (1SgSubj): ni ni- @@ -336,7 +336,7 @@ - + ni- (1SgSubj): ni ni- @@ -397,7 +397,7 @@ - + ni- (1SgSubj): ni @@ -457,7 +457,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyumamwupeStemNameSetNoFsStep02Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyumamwupeStemNameSetNoFsStep02Result.xml index c7f4f6074c..1d10055ad8 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyumamwupeStemNameSetNoFsStep02Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyumamwupeStemNameSetNoFsStep02Result.xml @@ -61,7 +61,7 @@ - + ni- (1SgSubj): ni ni- @@ -123,7 +123,7 @@ - + ni- (1SgSubj): ni ni- @@ -165,7 +165,7 @@ - + ni- (1SgSubj): ni ni- @@ -207,7 +207,7 @@ - + ni- (1SgSubj): ni ni- @@ -276,7 +276,7 @@ - + ni- (1SgSubj): ni ni- @@ -340,7 +340,7 @@ - + @@ -408,7 +408,7 @@
- + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwukoStemNameNotSetMultiFailStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwukoStemNameNotSetMultiFailStep00.xml index b8ad270fd5..9dabfa1daf 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwukoStemNameNotSetMultiFailStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwukoStemNameNotSetMultiFailStep00.xml @@ -1,7 +1,7 @@
niyuwowwuko
- + ni- (1SgSubj): ni ni- @@ -51,7 +51,7 @@ - + ni- (1SgSubj): ni ni- diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwukoStemNameNotSetMultiFailStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwukoStemNameNotSetMultiFailStep00Result.xml index f5b4e8712a..febea2bef6 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwukoStemNameNotSetMultiFailStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwukoStemNameNotSetMultiFailStep00Result.xml @@ -1,7 +1,7 @@
niyuwowwuko
- + ni- (1SgSubj): ni ni- @@ -54,7 +54,7 @@ - + ni- (1SgSubj): ni ni- @@ -106,7 +106,7 @@ - + ni- (1SgSubj): ni ni- @@ -148,7 +148,7 @@ - + ni- (1SgSubj): ni ni- @@ -190,7 +190,7 @@ - + ni- (1SgSubj): ni ni- @@ -244,7 +244,7 @@ - + ni- (1SgSubj): ni ni- @@ -298,7 +298,7 @@ - + ni- (1SgSubj): ni @@ -351,7 +351,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwukoStemNameNotSetMultiFailStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwukoStemNameNotSetMultiFailStep01Result.xml index c775c26f7e..821bbfb23e 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwukoStemNameNotSetMultiFailStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwukoStemNameNotSetMultiFailStep01Result.xml @@ -51,7 +51,7 @@ - + ni- (1SgSubj): ni ni- @@ -104,7 +104,7 @@ - + ni- (1SgSubj): ni ni- @@ -156,7 +156,7 @@ - + ni- (1SgSubj): ni ni- @@ -198,7 +198,7 @@ - + ni- (1SgSubj): ni ni- @@ -240,7 +240,7 @@ - + ni- (1SgSubj): ni ni- @@ -294,7 +294,7 @@ - + ni- (1SgSubj): ni ni- @@ -348,7 +348,7 @@ - + ni- (1SgSubj): ni @@ -401,7 +401,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwukoStemNameNotSetMultiFailStep02Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwukoStemNameNotSetMultiFailStep02Result.xml index ab0a0529d3..c744994084 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwukoStemNameNotSetMultiFailStep02Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwukoStemNameNotSetMultiFailStep02Result.xml @@ -54,7 +54,7 @@ - + ni- (1SgSubj): ni ni- @@ -109,7 +109,7 @@ - + ni- (1SgSubj): ni ni- @@ -144,7 +144,7 @@ - + ni- (1SgSubj): ni ni- @@ -179,7 +179,7 @@ - + ni- (1SgSubj): ni ni- @@ -241,7 +241,7 @@ - + ni- (1SgSubj): ni ni- @@ -298,7 +298,7 @@ - + @@ -360,7 +360,7 @@
- + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwupeStemNameNotSetStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwupeStemNameNotSetStep00.xml index e036ed2907..f4596d829c 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwupeStemNameNotSetStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwupeStemNameNotSetStep00.xml @@ -1,7 +1,7 @@
niyuwowwupe
- + ni- (1SgSubj): ni ni- @@ -51,7 +51,7 @@ - + ni- (1SgSubj): ni ni- diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwupeStemNameNotSetStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwupeStemNameNotSetStep00Result.xml index 04f070d93b..55df344e2e 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwupeStemNameNotSetStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwupeStemNameNotSetStep00Result.xml @@ -1,7 +1,7 @@
niyuwowwupe
- + ni- (1SgSubj): ni ni- @@ -54,7 +54,7 @@ - + ni- (1SgSubj): ni ni- @@ -106,7 +106,7 @@ - + ni- (1SgSubj): ni ni- @@ -148,7 +148,7 @@ - + ni- (1SgSubj): ni ni- @@ -190,7 +190,7 @@ - + ni- (1SgSubj): ni ni- @@ -244,7 +244,7 @@ - + ni- (1SgSubj): ni ni- @@ -298,7 +298,7 @@ - + ni- (1SgSubj): ni @@ -351,7 +351,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwupeStemNameNotSetStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwupeStemNameNotSetStep01Result.xml index afe0657162..1f8eb903d1 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwupeStemNameNotSetStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwupeStemNameNotSetStep01Result.xml @@ -51,7 +51,7 @@ - + ni- (1SgSubj): ni ni- @@ -104,7 +104,7 @@ - + ni- (1SgSubj): ni ni- @@ -156,7 +156,7 @@ - + ni- (1SgSubj): ni ni- @@ -198,7 +198,7 @@ - + ni- (1SgSubj): ni ni- @@ -240,7 +240,7 @@ - + ni- (1SgSubj): ni ni- @@ -294,7 +294,7 @@ - + ni- (1SgSubj): ni ni- @@ -348,7 +348,7 @@ - + ni- (1SgSubj): ni @@ -401,7 +401,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwupeStemNameNotSetStep02Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwupeStemNameNotSetStep02Result.xml index 0a23118f92..972a8bd8c6 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwupeStemNameNotSetStep02Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuwowwupeStemNameNotSetStep02Result.xml @@ -54,7 +54,7 @@ - + ni- (1SgSubj): ni ni- @@ -109,7 +109,7 @@ - + ni- (1SgSubj): ni ni- @@ -144,7 +144,7 @@ - + ni- (1SgSubj): ni ni- @@ -179,7 +179,7 @@ - + ni- (1SgSubj): ni ni- @@ -235,7 +235,7 @@ - + ni- (1SgSubj): ni ni- @@ -292,7 +292,7 @@ - + ni- (1SgSubj): ni @@ -347,7 +347,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywupeStemNameFailStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywupeStemNameFailStep00.xml index 4a221692be..061efbf2b2 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywupeStemNameFailStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywupeStemNameFailStep00.xml @@ -1,7 +1,7 @@
niyuyiywupe
- + ni- (1SgSubj): ni ni- @@ -44,7 +44,7 @@ - + ni- (1SgSubj): ni ni- diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywupeStemNameFailStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywupeStemNameFailStep00Result.xml index 66658380d7..9915047072 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywupeStemNameFailStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywupeStemNameFailStep00Result.xml @@ -1,7 +1,7 @@
niyuyiywupe
- + ni- (1SgSubj): ni ni- @@ -47,7 +47,7 @@ - + ni- (1SgSubj): ni ni- @@ -92,7 +92,7 @@ - + ni- (1SgSubj): ni ni- @@ -127,7 +127,7 @@ - + ni- (1SgSubj): ni ni- @@ -162,7 +162,7 @@ - + ni- (1SgSubj): ni ni- @@ -209,7 +209,7 @@ - + ni- (1SgSubj): ni ni- @@ -256,7 +256,7 @@ - + ni- (1SgSubj): ni @@ -302,7 +302,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywupeStemNameFailStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywupeStemNameFailStep01Result.xml index 40cce4affb..3427e1bcde 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywupeStemNameFailStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywupeStemNameFailStep01Result.xml @@ -44,7 +44,7 @@ - + ni- (1SgSubj): ni ni- @@ -90,7 +90,7 @@ - + ni- (1SgSubj): ni ni- @@ -135,7 +135,7 @@ - + ni- (1SgSubj): ni ni- @@ -170,7 +170,7 @@ - + ni- (1SgSubj): ni ni- @@ -205,7 +205,7 @@ - + ni- (1SgSubj): ni ni- @@ -252,7 +252,7 @@ - + ni- (1SgSubj): ni ni- @@ -299,7 +299,7 @@ - + ni- (1SgSubj): ni @@ -345,7 +345,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywupeStemNameFailStep02Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywupeStemNameFailStep02Result.xml index 2d20502bbe..b8eaa8456d 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywupeStemNameFailStep02Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywupeStemNameFailStep02Result.xml @@ -54,7 +54,7 @@ - + ni- (1SgSubj): ni ni- @@ -109,7 +109,7 @@ - + ni- (1SgSubj): ni ni- @@ -144,7 +144,7 @@ - + ni- (1SgSubj): ni ni- @@ -179,7 +179,7 @@ - + ni- (1SgSubj): ni ni- @@ -241,7 +241,7 @@ - + ni- (1SgSubj): ni ni- @@ -298,7 +298,7 @@ - + @@ -360,7 +360,7 @@
- + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywusaStemNameSetStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywusaStemNameSetStep00.xml index fd121c0938..55fab4b21e 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywusaStemNameSetStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywusaStemNameSetStep00.xml @@ -1,7 +1,7 @@
niyuyiywusa
- + ni- (1SgSubj): ni ni- @@ -58,7 +58,7 @@ - + ni- (1SgSubj): ni ni- diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywusaStemNameSetStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywusaStemNameSetStep00Result.xml index d184b6de3c..fa9eeb9e91 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywusaStemNameSetStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywusaStemNameSetStep00Result.xml @@ -1,7 +1,7 @@
niyuyiywusa
- + ni- (1SgSubj): ni ni- @@ -61,7 +61,7 @@ - + ni- (1SgSubj): ni ni- @@ -120,7 +120,7 @@ - + ni- (1SgSubj): ni ni- @@ -169,7 +169,7 @@ - + ni- (1SgSubj): ni ni- @@ -218,7 +218,7 @@ - + ni- (1SgSubj): ni ni- @@ -279,7 +279,7 @@ - + ni- (1SgSubj): ni ni- @@ -340,7 +340,7 @@ - + ni- (1SgSubj): ni @@ -400,7 +400,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywusaStemNameSetStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywusaStemNameSetStep01Result.xml index b976173b30..a486e9fd4d 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywusaStemNameSetStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywusaStemNameSetStep01Result.xml @@ -58,7 +58,7 @@ - + ni- (1SgSubj): ni ni- @@ -118,7 +118,7 @@ - + ni- (1SgSubj): ni ni- @@ -177,7 +177,7 @@ - + ni- (1SgSubj): ni ni- @@ -226,7 +226,7 @@ - + ni- (1SgSubj): ni ni- @@ -275,7 +275,7 @@ - + ni- (1SgSubj): ni ni- @@ -336,7 +336,7 @@ - + ni- (1SgSubj): ni ni- @@ -397,7 +397,7 @@ - + ni- (1SgSubj): ni @@ -457,7 +457,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywusaStemNameSetStep02Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywusaStemNameSetStep02Result.xml index 7a46f60c0f..6b348fd9f4 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywusaStemNameSetStep02Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiywusaStemNameSetStep02Result.xml @@ -61,7 +61,7 @@ - + ni- (1SgSubj): ni ni- @@ -123,7 +123,7 @@ - + ni- (1SgSubj): ni ni- @@ -165,7 +165,7 @@ - + ni- (1SgSubj): ni ni- @@ -207,7 +207,7 @@ - + ni- (1SgSubj): ni ni- @@ -276,7 +276,7 @@ - + ni- (1SgSubj): ni ni- @@ -340,7 +340,7 @@ - + @@ -408,7 +408,7 @@
- + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep00.xml index 2087bee027..72f6100a28 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep00.xml @@ -1,7 +1,7 @@
niyuyiyximuwupe
- + ni- (1SgSubj): ni ni- @@ -58,7 +58,7 @@ - + ni- (1SgSubj): ni ni- @@ -116,7 +116,7 @@ - + ni- (1SgSubj): ni ni- @@ -173,7 +173,7 @@ - + ni- (1SgSubj): ni ni- diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep00Result.xml index 76b4b0a16a..442e6e0af0 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep00Result.xml @@ -1,7 +1,7 @@
niyuyiyximuwupe
- + ni- (1SgSubj): ni ni- @@ -60,7 +60,7 @@ - + ni- (1SgSubj): ni ni- @@ -120,7 +120,7 @@ - + ni- (1SgSubj): ni ni- @@ -180,7 +180,7 @@ - + ni- (1SgSubj): ni ni- @@ -241,7 +241,7 @@ - + ni- (1SgSubj): ni ni- @@ -301,7 +301,7 @@ - + ni- (1SgSubj): ni ni- @@ -361,7 +361,7 @@ - + ni- (1SgSubj): ni ni- @@ -421,7 +421,7 @@ - + ni- (1SgSubj): ni ni- @@ -482,7 +482,7 @@ - + ni- (1SgSubj): ni ni- diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep01Result.xml index 040b345214..c82f66ecb6 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep01Result.xml @@ -58,7 +58,7 @@ - + ni- (1SgSubj): ni ni- @@ -117,7 +117,7 @@ - + ni- (1SgSubj): ni ni- diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep02Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep02Result.xml index d14ff67608..b3fc4f534d 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep02Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep02Result.xml @@ -60,7 +60,7 @@ - + ni- (1SgSubj): ni ni- @@ -120,7 +120,7 @@ - + ni- (1SgSubj): ni ni- @@ -194,7 +194,7 @@ - + ni- (1SgSubj): ni ni- @@ -280,7 +280,7 @@ - + ni- (1SgSubj): ni ni- @@ -366,7 +366,7 @@ - + ni- (1SgSubj): ni ni- @@ -428,7 +428,7 @@ - + ni- (1SgSubj): ni ni- @@ -514,7 +514,7 @@ - + ni- (1SgSubj): ni ni- @@ -600,7 +600,7 @@ - + ni- (1SgSubj): ni ni- diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep03Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep03Result.xml index df58d177cb..5094cd5e1d 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep03Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep03Result.xml @@ -63,7 +63,7 @@ - + ni- (1SgSubj): ni ni- @@ -128,7 +128,7 @@ - + ni- (1SgSubj): ni ni- @@ -192,7 +192,7 @@ - + ni- (1SgSubj): ni ni- @@ -234,7 +234,7 @@ - + ni- (1SgSubj): ni ni- @@ -276,7 +276,7 @@ - + ni- (1SgSubj): ni ni- @@ -342,7 +342,7 @@ - + ni- (1SgSubj): ni ni- @@ -408,7 +408,7 @@ - + A stem allomorph belongs to Stem Name 'Present tense or 2nd Person' so the word must be inflected for certain features, but it is not. The possible feature sets it must be inflected for are: [absolute tense:present tense] or [subject agreement:[person:second person]]. The inflected features for this word are: (none). @@ -474,7 +474,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep04Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep04Result.xml index 4501025379..6f3a6e4734 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep04Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwupeStemNameNotSetCompoundFailStep04Result.xml @@ -66,7 +66,7 @@ - + ni- (1SgSubj): ni ni- @@ -133,7 +133,7 @@ - + ni- (1SgSubj): ni ni- @@ -168,7 +168,7 @@ - + ni- (1SgSubj): ni ni- @@ -203,7 +203,7 @@ - + ni- (1SgSubj): ni ni- @@ -277,7 +277,7 @@ - + ni- (1SgSubj): ni ni- @@ -346,7 +346,7 @@ - + @@ -420,7 +420,7 @@
- + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep00.xml index 907d5d3cae..2c9e693d9a 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep00.xml @@ -1,7 +1,7 @@
niyuyiyximuwusa
- + ni- (1SgSubj): ni ni- @@ -65,7 +65,7 @@ - + ni- (1SgSubj): ni ni- @@ -130,7 +130,7 @@ - + ni- (1SgSubj): ni ni- @@ -194,7 +194,7 @@ - + ni- (1SgSubj): ni ni- diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep00Result.xml index 15b6f4fda4..a7d5881c56 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep00Result.xml @@ -1,7 +1,7 @@
niyuyiyximuwusa
- + ni- (1SgSubj): ni ni- @@ -67,7 +67,7 @@ - + ni- (1SgSubj): ni ni- @@ -134,7 +134,7 @@ - + ni- (1SgSubj): ni ni- @@ -201,7 +201,7 @@ - + ni- (1SgSubj): ni ni- @@ -269,7 +269,7 @@ - + ni- (1SgSubj): ni ni- @@ -336,7 +336,7 @@ - + ni- (1SgSubj): ni ni- @@ -403,7 +403,7 @@ - + ni- (1SgSubj): ni ni- @@ -470,7 +470,7 @@ - + ni- (1SgSubj): ni ni- @@ -538,7 +538,7 @@ - + ni- (1SgSubj): ni ni- diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep01Result.xml index f714690124..a8a9de49bf 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep01Result.xml @@ -65,7 +65,7 @@ - + ni- (1SgSubj): ni ni- @@ -131,7 +131,7 @@ - + ni- (1SgSubj): ni ni- diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep02Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep02Result.xml index 21f34e46cb..60e6def4fa 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep02Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep02Result.xml @@ -67,7 +67,7 @@ - + ni- (1SgSubj): ni ni- @@ -134,7 +134,7 @@ - + ni- (1SgSubj): ni ni- @@ -215,7 +215,7 @@ - + ni- (1SgSubj): ni ni- @@ -308,7 +308,7 @@ - + ni- (1SgSubj): ni ni- @@ -401,7 +401,7 @@ - + ni- (1SgSubj): ni ni- @@ -470,7 +470,7 @@ - + ni- (1SgSubj): ni ni- @@ -563,7 +563,7 @@ - + ni- (1SgSubj): ni ni- @@ -656,7 +656,7 @@ - + ni- (1SgSubj): ni ni- diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep03Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep03Result.xml index 8c8c470d02..663436b0b4 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep03Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep03Result.xml @@ -70,7 +70,7 @@ - + ni- (1SgSubj): ni ni- @@ -142,7 +142,7 @@ - + ni- (1SgSubj): ni ni- @@ -213,7 +213,7 @@ - + ni- (1SgSubj): ni ni- @@ -262,7 +262,7 @@ - + ni- (1SgSubj): ni ni- @@ -311,7 +311,7 @@ - + ni- (1SgSubj): ni ni- @@ -384,7 +384,7 @@ - + ni- (1SgSubj): ni ni- @@ -457,7 +457,7 @@ - + A stem allomorph belongs to Stem Name 'Present tense or 2nd Person' so the word must be inflected for certain features, but it is not. The possible feature sets it must be inflected for are: [absolute tense:present tense] or [subject agreement:[person:second person]]. The inflected features for this word are: (none). @@ -530,7 +530,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep04Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep04Result.xml index a82e3d4fcd..09832e1310 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep04Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/niyuyiyximuwusaStemNameSetCompoundStep04Result.xml @@ -73,7 +73,7 @@ - + ni- (1SgSubj): ni ni- @@ -147,7 +147,7 @@ - + ni- (1SgSubj): ni ni- @@ -189,7 +189,7 @@ - + ni- (1SgSubj): ni ni- @@ -231,7 +231,7 @@ - + ni- (1SgSubj): ni ni- @@ -312,7 +312,7 @@ - + ni- (1SgSubj): ni ni- @@ -388,7 +388,7 @@ - + @@ -468,7 +468,7 @@
- + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwupeStemNameSetMultiFsFailStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwupeStemNameSetMultiFsFailStep00.xml index 297c84fee8..8b155c7394 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwupeStemNameSetMultiFsFailStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwupeStemNameSetMultiFsFailStep00.xml @@ -1,7 +1,7 @@
timikikwupe
- + ti- (2SgSubj): ti ti- @@ -51,7 +51,7 @@ - + ti- (2SgSubj): ti ti- diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwupeStemNameSetMultiFsFailStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwupeStemNameSetMultiFsFailStep00Result.xml index eba840ed4a..a032ae27b3 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwupeStemNameSetMultiFsFailStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwupeStemNameSetMultiFsFailStep00Result.xml @@ -1,7 +1,7 @@
timikikwupe
- + ti- (2SgSubj): ti ti- @@ -54,7 +54,7 @@ - + ti- (2SgSubj): ti ti- @@ -106,7 +106,7 @@ - + ti- (2SgSubj): ti ti- @@ -148,7 +148,7 @@ - + ti- (2SgSubj): ti ti- @@ -190,7 +190,7 @@ - + ti- (2SgSubj): ti ti- @@ -244,7 +244,7 @@ - + ti- (2SgSubj): ti ti- @@ -298,7 +298,7 @@ - + ti- (2SgSubj): ti @@ -351,7 +351,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwupeStemNameSetMultiFsFailStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwupeStemNameSetMultiFsFailStep01Result.xml index 831c3b180b..f191b6bbe3 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwupeStemNameSetMultiFsFailStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwupeStemNameSetMultiFsFailStep01Result.xml @@ -51,7 +51,7 @@ - + ti- (2SgSubj): ti ti- @@ -104,7 +104,7 @@ - + ti- (2SgSubj): ti ti- @@ -156,7 +156,7 @@ - + ti- (2SgSubj): ti ti- @@ -198,7 +198,7 @@ - + ti- (2SgSubj): ti ti- @@ -240,7 +240,7 @@ - + ti- (2SgSubj): ti ti- @@ -294,7 +294,7 @@ - + ti- (2SgSubj): ti ti- @@ -348,7 +348,7 @@ - + ti- (2SgSubj): ti @@ -401,7 +401,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwupeStemNameSetMultiFsFailStep02Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwupeStemNameSetMultiFsFailStep02Result.xml index bbd16a76f9..58fb8c9f82 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwupeStemNameSetMultiFsFailStep02Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwupeStemNameSetMultiFsFailStep02Result.xml @@ -54,7 +54,7 @@ - + ti- (2SgSubj): ti ti- @@ -109,7 +109,7 @@ - + ti- (2SgSubj): ti ti- @@ -144,7 +144,7 @@ - + ti- (2SgSubj): ti ti- @@ -179,7 +179,7 @@ - + ti- (2SgSubj): ti ti- @@ -241,7 +241,7 @@ - + ti- (2SgSubj): ti ti- @@ -298,7 +298,7 @@ - + @@ -360,7 +360,7 @@
- + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwusaStemNameSetMultiFsStep00.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwusaStemNameSetMultiFsStep00.xml index 5738f1f3df..e52ceeffd3 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwusaStemNameSetMultiFsStep00.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwusaStemNameSetMultiFsStep00.xml @@ -1,7 +1,7 @@
timikikwusa
- + ti- (2SgSubj): ti ti- @@ -58,7 +58,7 @@ - + ti- (2SgSubj): ti ti- diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwusaStemNameSetMultiFsStep00Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwusaStemNameSetMultiFsStep00Result.xml index b412a0325d..4b44f9c07e 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwusaStemNameSetMultiFsStep00Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwusaStemNameSetMultiFsStep00Result.xml @@ -1,7 +1,7 @@
timikikwusa
- + ti- (2SgSubj): ti ti- @@ -61,7 +61,7 @@ - + ti- (2SgSubj): ti ti- @@ -120,7 +120,7 @@ - + ti- (2SgSubj): ti ti- @@ -169,7 +169,7 @@ - + ti- (2SgSubj): ti ti- @@ -218,7 +218,7 @@ - + ti- (2SgSubj): ti ti- @@ -279,7 +279,7 @@ - + ti- (2SgSubj): ti ti- @@ -340,7 +340,7 @@ - + ti- (2SgSubj): ti @@ -400,7 +400,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwusaStemNameSetMultiFsStep01Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwusaStemNameSetMultiFsStep01Result.xml index 494d4bd474..0fbd0dad7e 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwusaStemNameSetMultiFsStep01Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwusaStemNameSetMultiFsStep01Result.xml @@ -58,7 +58,7 @@ - + ti- (2SgSubj): ti ti- @@ -118,7 +118,7 @@ - + ti- (2SgSubj): ti ti- @@ -177,7 +177,7 @@ - + ti- (2SgSubj): ti ti- @@ -226,7 +226,7 @@ - + ti- (2SgSubj): ti ti- @@ -275,7 +275,7 @@ - + ti- (2SgSubj): ti ti- @@ -336,7 +336,7 @@ - + ti- (2SgSubj): ti ti- @@ -397,7 +397,7 @@ - + ti- (2SgSubj): ti @@ -457,7 +457,7 @@ - + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwusaStemNameSetMultiFsStep02Result.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwusaStemNameSetMultiFsStep02Result.xml index fb2f16ca1f..0745c95fad 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwusaStemNameSetMultiFsStep02Result.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/timikikwusaStemNameSetMultiFsStep02Result.xml @@ -61,7 +61,7 @@ - + ti- (2SgSubj): ti ti- @@ -123,7 +123,7 @@ - + ti- (2SgSubj): ti ti- @@ -165,7 +165,7 @@ - + ti- (2SgSubj): ti ti- @@ -207,7 +207,7 @@ - + ti- (2SgSubj): ti ti- @@ -276,7 +276,7 @@ - + ti- (2SgSubj): ti ti- @@ -340,7 +340,7 @@ - + @@ -408,7 +408,7 @@
- + The category (bitrans) of the inflectional template "Bitransitive verb" is incompatible with the category (trans) of the stem. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/yalotetuStep01.xml b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/yalotetuStep01.xml index af66f92841..94fa55e02f 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/yalotetuStep01.xml +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults/yalotetuStep01.xml @@ -1,7 +1,7 @@
yalotetu
- + yalo (mat): yalo @@ -41,7 +41,7 @@ - + A root can only be a "Partial" when its category is unknown, but the category here is 'N'. diff --git a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingTests.cs b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingTests.cs index 6fad29d4a3..558a5becc9 100644 --- a/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingTests.cs +++ b/Src/LexText/ParserUI/ParserUITests/WordGrammarDebuggingTests.cs @@ -5,16 +5,11 @@ // File: WordGrammarDebuggingTests.cs // Responsibility: -using System; -using System.Collections.Generic; -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.IO; using System.Text; -using System.Xml; -#if __MonoCS__ using System.Xml.Linq; -#endif using System.Xml.XPath; using System.Xml.Xsl; @@ -37,15 +32,7 @@ namespace SIL.FieldWorks.LexText.Controls public class WordGrammarDebuggingTests : BaseTest { private XPathDocument m_doc; -#if __MonoCS__ - private IntPtr m_masterTransform; - private IntPtr m_resultTransform; - private IntPtr m_resultTransformNoCompoundRules; - private IntPtr m_resultTransformStemNames; - private IntPtr m_resultTransformAffixAlloFeats; - private IntPtr m_UnificationViaXsltTransform; - private IntPtr m_SameSlotTwiceTransform; -#else + private XslCompiledTransform m_masterTransform; private XslCompiledTransform m_resultTransform; private XslCompiledTransform m_resultTransformNoCompoundRules; @@ -53,17 +40,12 @@ public class WordGrammarDebuggingTests : BaseTest private XslCompiledTransform m_resultTransformAffixAlloFeats; private XslCompiledTransform m_UnificationViaXsltTransform; private XslCompiledTransform m_SameSlotTwiceTransform; -#endif /// /// Location of test files /// protected string m_sTestPath; /// - protected string m_sTransformPath; - /// - protected string m_sMasterTransform; - /// protected string m_sResultTransform; /// protected string m_sResultTransformNoCompoundRules; @@ -80,9 +62,9 @@ public class WordGrammarDebuggingTests : BaseTest /// protected string m_sM3FXTDumpAffixAlloFeats; /// Set to true to be able to debug into stylesheets - private bool m_fDebug; + private readonly bool m_fDebug; /// path to the standard directory for temporary files. - private string m_sTempPath; + private readonly string m_sTempPath; /// ------------------------------------------------------------------------------------ /// /// Initializes a new instance of the class. @@ -108,21 +90,19 @@ public WordGrammarDebuggingTests() public override void FixtureSetup() { base.FixtureSetup(); - m_sTestPath = Path.Combine(DirectoryFinder.FwSourceDirectory, + m_sTestPath = Path.Combine(FwDirectoryFinder.SourceDirectory, "LexText/ParserUI/ParserUITests/WordGrammarDebuggingInputsAndResults"); - m_sTransformPath = Path.Combine(DirectoryFinder.FWCodeDirectory, - "Language Explorer/Transforms"); SetUpMasterTransform(); - CreateResultTransform("M3FXTDump.xml", ref m_sResultTransform); + CreateResultTransform("M3FXTDump.xml", out m_sResultTransform); SetUpResultTransform(m_sResultTransform, out m_resultTransform); SetUpUnificationViaXsltTransform(); SetUpSameSlotTwiceTransform(); - CreateResultTransform("M3FXTDumpNoCompoundRules.xml", ref m_sResultTransformNoCompoundRules); + CreateResultTransform("M3FXTDumpNoCompoundRules.xml", out m_sResultTransformNoCompoundRules); SetUpResultTransform(m_sResultTransformNoCompoundRules, out m_resultTransformNoCompoundRules); - CreateResultTransform("M3FXTDumpStemNames.xml", ref m_sResultTransformStemNames); + CreateResultTransform("M3FXTDumpStemNames.xml", out m_sResultTransformStemNames); SetUpResultTransform(m_sResultTransformStemNames, out m_resultTransformStemNames); - CreateResultTransform("M3FXTDumpAffixAlloFeats.xml", ref m_sResultTransformAffixAlloFeats); + CreateResultTransform("M3FXTDumpAffixAlloFeats.xml", out m_sResultTransformAffixAlloFeats); SetUpResultTransform(m_sResultTransformAffixAlloFeats, out m_resultTransformAffixAlloFeats); } @@ -146,43 +126,6 @@ public override void FixtureTeardown() File.Delete(Path.Combine(m_sTempPath, "UnifyTwoFeatureStructures.xsl")); if (File.Exists(Path.Combine(m_sTempPath, "TestUnificationViaXSLT-Linux.xsl"))) File.Delete(Path.Combine(m_sTempPath, "TestUnificationViaXSLT-Linux.xsl")); -#if __MonoCS__ - if (m_masterTransform != IntPtr.Zero) - { - SIL.Utils.LibXslt.FreeCompiledTransform(m_masterTransform); - m_masterTransform = IntPtr.Zero; - } - if (m_resultTransform != IntPtr.Zero) - { - SIL.Utils.LibXslt.FreeCompiledTransform(m_resultTransform); - m_resultTransform = IntPtr.Zero; - } - if (m_resultTransformNoCompoundRules != IntPtr.Zero) - { - SIL.Utils.LibXslt.FreeCompiledTransform(m_resultTransformNoCompoundRules); - m_resultTransformNoCompoundRules = IntPtr.Zero; - } - if (m_resultTransformStemNames != IntPtr.Zero) - { - SIL.Utils.LibXslt.FreeCompiledTransform(m_resultTransformStemNames); - m_resultTransformStemNames = IntPtr.Zero; - } - if (m_resultTransformAffixAlloFeats != IntPtr.Zero) - { - SIL.Utils.LibXslt.FreeCompiledTransform(m_resultTransformAffixAlloFeats); - m_resultTransformAffixAlloFeats = IntPtr.Zero; - } - if (m_UnificationViaXsltTransform != IntPtr.Zero) - { - SIL.Utils.LibXslt.FreeCompiledTransform(m_UnificationViaXsltTransform); - m_UnificationViaXsltTransform = IntPtr.Zero; - } - if (m_SameSlotTwiceTransform != IntPtr.Zero) - { - SIL.Utils.LibXslt.FreeCompiledTransform(m_SameSlotTwiceTransform); - m_SameSlotTwiceTransform = IntPtr.Zero; - } -#endif base.FixtureTeardown(); } @@ -197,10 +140,6 @@ private void SetUpResultTransform(string sResultTransform, out XslCompiledTransf resultTransform = new XslCompiledTransform(m_fDebug); resultTransform.Load(sResultTransform); } - private void SetUpResultTransform(string sResultTransform, out IntPtr resultTransform) - { - resultTransform = SIL.Utils.LibXslt.CompileTransform(sResultTransform); - } /// ------------------------------------------------------------------------------------ /// @@ -209,27 +148,10 @@ private void SetUpResultTransform(string sResultTransform, out IntPtr resultTran /// ------------------------------------------------------------------------------------ private void SetUpUnificationViaXsltTransform() { -#if __MonoCS__ - // TestUnificationViaXSLT.xsl contains an xsl:include href value that chokes libxslt. - // (libxslt apparently doesn't like .. leading off a file path.) - if (!File.Exists(Path.Combine(m_sTempPath, "UnifyTwoFeatureStructures.xsl"))) - { - File.Copy(Path.Combine(m_sTransformPath, "UnifyTwoFeatureStructures.xsl"), - Path.Combine(m_sTempPath, "UnifyTwoFeatureStructures.xsl")); - } - if (!File.Exists(Path.Combine(m_sTempPath, "TestUnificationViaXSLT-Linux.xsl"))) - { - File.Copy(Path.Combine(Path.GetDirectoryName(m_sTestPath), "TestUnificationViaXSLT-Linux.xsl"), - Path.Combine(m_sTempPath, "TestUnificationViaXSLT-Linux.xsl")); - } - string sUnificationViaXsltTransform = Path.Combine(m_sTempPath, "TestUnificationViaXSLT-Linux.xsl"); - SetUpResultTransform(sUnificationViaXsltTransform, out m_UnificationViaXsltTransform); -#else m_UnificationViaXsltTransform = new XslCompiledTransform(m_fDebug); string sUnificationViaXsltTransform = Path.Combine(m_sTestPath, "../TestUnificationViaXSLT.xsl"); m_UnificationViaXsltTransform.Load(sUnificationViaXsltTransform); -#endif } /// ------------------------------------------------------------------------------------ @@ -239,18 +161,10 @@ private void SetUpUnificationViaXsltTransform() /// ------------------------------------------------------------------------------------ private void SetUpSameSlotTwiceTransform() { -#if __MonoCS__ - // TLPSameSlotTwiceWordGrammarDebugger.xsl contains a namespace declaration for - // auto-ns1 that is Microsoft-specific. - string sSameSlotTwiceTransform = Path.Combine(m_sTestPath, - "TLPSameSlotTwiceWordGrammarDebugger-Linux.xsl"); - SetUpResultTransform(sSameSlotTwiceTransform, out m_SameSlotTwiceTransform); -#else - m_SameSlotTwiceTransform = new XslCompiledTransform(m_fDebug); string sSameSlotTwiceTransform = Path.Combine(m_sTestPath, @"TLPSameSlotTwiceWordGrammarDebugger.xsl"); + m_SameSlotTwiceTransform = new XslCompiledTransform(m_fDebug); m_SameSlotTwiceTransform.Load(sSameSlotTwiceTransform); -#endif } /// ------------------------------------------------------------------------------------ @@ -258,12 +172,12 @@ private void SetUpSameSlotTwiceTransform() /// Creates a result transform. /// /// ------------------------------------------------------------------------------------ - private void CreateResultTransform(string sFXTDumpFile, ref string sResultTransform) + private void CreateResultTransform(string fxtDumpFile, out string resultTransform) { - sResultTransform = FileUtils.GetTempFile("xsl"); - string sFXTDump = Path.Combine(m_sTestPath, sFXTDumpFile); - SIL.Utils.XmlUtils.TransformFileToFile(m_sMasterTransform, sFXTDump, - sResultTransform); + resultTransform = FileUtils.GetTempFile("xsl"); + string fxtDump = Path.Combine(m_sTestPath, fxtDumpFile); + using (var writer = new StreamWriter(resultTransform)) + m_masterTransform.Transform(fxtDump, null, writer); } /// ------------------------------------------------------------------------------------ @@ -273,14 +187,7 @@ private void CreateResultTransform(string sFXTDumpFile, ref string sResultTransf /// ------------------------------------------------------------------------------------ private void SetUpMasterTransform() { - m_sMasterTransform = Path.Combine(m_sTransformPath, - "FxtM3ParserToXAmpleWordGrammarDebuggingXSLT.xsl"); -#if __MonoCS__ - m_masterTransform = SIL.Utils.LibXslt.CompileTransform(m_sMasterTransform); -#else - m_masterTransform = new XslCompiledTransform(); - m_masterTransform.Load(m_sMasterTransform); -#endif + m_masterTransform = XmlUtils.CreateTransform("FxtM3ParserToXAmpleWordGrammarDebuggingXSLT", "ApplicationTransforms"); } #endregion @@ -305,53 +212,21 @@ private void ApplyTransform(string sInputFile, string sExpectedOutput) /// The expected output filename. /// The transform. /// ------------------------------------------------------------------------------------ - private void ApplyTransform(string sInputFile, string sExpectedOutput, - XslCompiledTransform transform) - { - ApplyTransform(sInputFile, sExpectedOutput, transform, true); - } - private void ApplyTransform(string sInputFile, string sExpectedOutput, - IntPtr transform) - { - ApplyTransform(sInputFile, sExpectedOutput, transform, true); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Applies the transform. - /// - /// The input file filename. - /// The expected output filename. - /// The transform. - /// remove Msxsl namespace - /// ------------------------------------------------------------------------------------ - private void ApplyTransform(string sInputFile, string sExpectedOutput, - XslCompiledTransform transform, bool fFixMsxslNameSpace) + private void ApplyTransform(string sInputFile, string sExpectedOutput, XslCompiledTransform transform) { string sInput = Path.Combine(m_sTestPath, sInputFile); m_doc = new XPathDocument(sInput); string sOutput = FileUtils.GetTempFile("xml"); - using (StreamWriter result = new StreamWriter(sOutput)) + using (var result = new StreamWriter(sOutput)) { transform.Transform(m_doc, null, result); result.Close(); string sExpectedResult = Path.Combine(m_sTestPath, sExpectedOutput); - CheckXmlEquals(sExpectedResult, sOutput, fFixMsxslNameSpace); + CheckXmlEquals(sExpectedResult, sOutput); // by deleting it here instead of a finally block, when it fails, we can see what the result is. File.Delete(sOutput); } } - private void ApplyTransform(string sInputFile, string sExpectedOutput, - IntPtr transform, bool fFixMsxslNameSpace) - { - string sInput = Path.Combine(m_sTestPath, sInputFile); - string sOutput = FileUtils.GetTempFile("xml"); - SIL.Utils.LibXslt.TransformFileToFile(transform, sInput, sOutput); - string sExpectedResult = Path.Combine(m_sTestPath, sExpectedOutput); - CheckXmlEquals(sExpectedResult, sOutput, fFixMsxslNameSpace); - // by deleting it here instead of a finally block, when it fails, we can see what the result is. - File.Delete(sOutput); - } /// ------------------------------------------------------------------------------------ /// @@ -359,40 +234,24 @@ private void ApplyTransform(string sInputFile, string sExpectedOutput, /// /// The expected result filename. /// The actual result filename. - /// remove Msxsl namespace /// ------------------------------------------------------------------------------------ - private void CheckXmlEquals(string sExpectedResultFile, string sActualResultFile, bool fFixMsxslNameSpace) + private void CheckXmlEquals(string sExpectedResultFile, string sActualResultFile) { string sExpected, sActual; - using (StreamReader expected = new StreamReader(sExpectedResultFile)) + using (var expected = new StreamReader(sExpectedResultFile)) sExpected = expected.ReadToEnd(); - using (StreamReader actual = new StreamReader(sActualResultFile)) + using (var actual = new StreamReader(sActualResultFile)) sActual = actual.ReadToEnd(); - StringBuilder sb = new StringBuilder(); + var sb = new StringBuilder(); sb.Append("Expected file was "); sb.AppendLine(sExpectedResultFile); sb.Append("Actual file was "); sb.AppendLine(sActualResultFile); -#if __MonoCS__ - // REVIEW: Perhaps we should always use the fancy compare method using XElement objects? - if (fFixMsxslNameSpace) - sActual = sActual.Replace(" xmlns:auto-ns1=\"urn:schemas-microsoft-com:xslt\"", ""); + XElement xeActual = XElement.Parse(sActual, LoadOptions.None); XElement xeExpected = XElement.Parse(sExpected, LoadOptions.None); bool ok = XmlHelper.EqualXml(xeExpected, xeActual, sb); Assert.IsTrue(ok, sb.ToString()); -#else - if (fFixMsxslNameSpace) - { - string sFixMsxslNameSpace = - sActual.Replace(" xmlns:auto-ns1=\"urn:schemas-microsoft-com:xslt\"", ""); - Assert.AreEqual(sExpected, sFixMsxslNameSpace, sb.ToString()); - } - else - { - Assert.AreEqual(sExpected, sActual, sb.ToString()); - } -#endif } #endregion @@ -660,21 +519,21 @@ public void RemoveFailuresWhenApplyAgain() public void AffixAllomorphConditionedByFeatures() { // an inflectional affix allomorph has features and parse succeeds - DoWordGrammarDebuggerSteps("msmsAffixAlloFeats", 3, m_resultTransformAffixAlloFeats); + DoWordGrammarDebuggerSteps("msmsAffixAlloFeats", 3); // an inflectional affix allomorph has features and parse fails - DoWordGrammarDebuggerSteps("mpmsAffixAlloFeats", 2, m_resultTransformAffixAlloFeats); + DoWordGrammarDebuggerSteps("mpmsAffixAlloFeats", 2); // an inflectional affix allomorph without features is in an entry that has features and parse succeeds - DoWordGrammarDebuggerSteps("fsinflAffixAlloFeats", 3, m_resultTransformAffixAlloFeats); + DoWordGrammarDebuggerSteps("fsinflAffixAlloFeats", 3); // an inflectional affix allomorph without features is in an entry that has features and parse fails - DoWordGrammarDebuggerSteps("msinflAffixAlloFeats", 2, m_resultTransformAffixAlloFeats); + DoWordGrammarDebuggerSteps("msinflAffixAlloFeats", 2); // a derivational affix allomorph has features and parse succeeds - DoWordGrammarDebuggerSteps("fsfstovAffixAlloFeats", 3, m_resultTransformAffixAlloFeats); + DoWordGrammarDebuggerSteps("fsfstovAffixAlloFeats", 3); // a derivational affix allomorph has features and parse fails - DoWordGrammarDebuggerSteps("fpfstovAffixAlloFeats", 2, m_resultTransformAffixAlloFeats); + DoWordGrammarDebuggerSteps("fpfstovAffixAlloFeats", 2); // a derivational affix allomorph without features is in an entry that has features and parse succeeds - DoWordGrammarDebuggerSteps("fpfptovAffixAlloFeats", 3, m_resultTransformAffixAlloFeats); + DoWordGrammarDebuggerSteps("fpfptovAffixAlloFeats", 3); // a derivational affix allomorph without features is in an entry that has features and parse fails - DoWordGrammarDebuggerSteps("fsfptovAffixAlloFeats", 2, m_resultTransformAffixAlloFeats); + DoWordGrammarDebuggerSteps("fsfptovAffixAlloFeats", 2); } /// ------------------------------------------------------------------------------------ /// @@ -685,44 +544,35 @@ public void AffixAllomorphConditionedByFeatures() public void StemNames() { // stem name is set and parse succeeds - DoWordGrammarDebuggerSteps("niyuyiywusaStemNameSet", 3, m_resultTransformStemNames); + DoWordGrammarDebuggerSteps("niyuyiywusaStemNameSet", 3); // stem name is set but no features in regions and parse succeeds - DoWordGrammarDebuggerSteps("niyumamwupeStemNameSetNoFs", 3, m_resultTransformStemNames); + DoWordGrammarDebuggerSteps("niyumamwupeStemNameSetNoFs", 3); // stem name is set and parse fails - DoWordGrammarDebuggerSteps("niyuyiywupeStemNameFail", 3, m_resultTransformStemNames); + DoWordGrammarDebuggerSteps("niyuyiywupeStemNameFail", 3); // stem name not set (but other allomorph in lex entry is) and it succeeds - DoWordGrammarDebuggerSteps("niyuwowwupeStemNameNotSet", 3, m_resultTransformStemNames); + DoWordGrammarDebuggerSteps("niyuwowwupeStemNameNotSet", 3); // stem name not set (but other allomorph in lex entry is) and it fails - DoWordGrammarDebuggerSteps("niyuhohwusaStemNameNotSetFail", 3, m_resultTransformStemNames); + DoWordGrammarDebuggerSteps("niyuhohwusaStemNameNotSetFail", 3); // stem name not set (but two other allomorps in lex entry are) and it fails - DoWordGrammarDebuggerSteps("niyuwowwukoStemNameNotSetMultiFail", 3, m_resultTransformStemNames); + DoWordGrammarDebuggerSteps("niyuwowwukoStemNameNotSetMultiFail", 3); // stem name set and has two FsFeatStrucs and it succeeds - DoWordGrammarDebuggerSteps("timikikwusaStemNameSetMultiFs", 3, m_resultTransformStemNames); + DoWordGrammarDebuggerSteps("timikikwusaStemNameSetMultiFs", 3); // stem name set and has two FsFeatStrucs and it fails - DoWordGrammarDebuggerSteps("timikikwupeStemNameSetMultiFsFail", 3, m_resultTransformStemNames); + DoWordGrammarDebuggerSteps("timikikwupeStemNameSetMultiFsFail", 3); // stem name is set, has compound and parse succeeds - DoWordGrammarDebuggerSteps("niyuyiyximuwusaStemNameSetCompound", 5, m_resultTransformStemNames); + DoWordGrammarDebuggerSteps("niyuyiyximuwusaStemNameSetCompound", 5); // stem name not set (but other allomorph in lex entry is), has compound and it fails - DoWordGrammarDebuggerSteps("niyuyiyximuwupeStemNameNotSetCompoundFail", 5, m_resultTransformStemNames); + DoWordGrammarDebuggerSteps("niyuyiyximuwupeStemNameNotSetCompoundFail", 5); } // These methods have a seeming bug in them: the transform argument is not used, // but rather a hard-coded transform. However, the test output obviously comes // from applying the hard-coded transform, so fixing this requires knowing what // the proper output is for the given data and the proper (other) transform. - private void DoWordGrammarDebuggerSteps(string sName, int count, XslCompiledTransform transform) - { - for (int i = 0; i < count; i++) - ApplyTransform(sName + "Step0" + i.ToString() + ".xml", sName + "Step0" + i.ToString() + "Result.xml", m_resultTransformStemNames, false); - } - private void DoWordGrammarDebuggerSteps(string sName, int count, IntPtr transform) + private void DoWordGrammarDebuggerSteps(string sName, int count) { for (int i = 0; i < count; i++) - { - var inputName = String.Format("{0}Step0{1}.xml", sName, i); - var outputName = String.Format("{0}Step0{1}Result.xml", sName, i); - ApplyTransform(inputName, outputName, m_resultTransformStemNames, false); - } + ApplyTransform(sName + "Step0" + i.ToString(CultureInfo.InvariantCulture) + ".xml", sName + "Step0" + i.ToString(CultureInfo.InvariantCulture) + "Result.xml", m_resultTransformStemNames); } /// ------------------------------------------------------------------------------------ @@ -731,7 +581,7 @@ private void DoWordGrammarDebuggerSteps(string sName, int count, IntPtr transfor /// /// ------------------------------------------------------------------------------------ [Test] - public void UnificationViaXSLT() + public void UnificationViaXslt() { ApplyTransform("TestFeatureStructureUnification.xml", "TestFeatureStructureUnification.xml", m_UnificationViaXsltTransform); diff --git a/Src/LexText/ParserUI/TryAWordDlg.cs b/Src/LexText/ParserUI/TryAWordDlg.cs index e5213bd593..0095df0dac 100644 --- a/Src/LexText/ParserUI/TryAWordDlg.cs +++ b/Src/LexText/ParserUI/TryAWordDlg.cs @@ -20,9 +20,11 @@ using System.IO; using System.Windows.Forms; using System.Text; +using System.Xml.Linq; using SIL.FieldWorks.Common.RootSites; using SIL.FieldWorks.Common.Widgets; using SIL.FieldWorks.FDO; +using SIL.FieldWorks.WordWorks.Parser; using SIL.Utils; using XCore; using SIL.FieldWorks.Common.FwUtils; @@ -529,16 +531,27 @@ private void m_timer_Tick(object sender, EventArgs e) m_parserListener.DisconnectFromParser(); m_statusLabel.Text = ParserStoppedMessage(); m_tryItButton.Enabled = true; - var app = (IApp) m_mediator.PropertyTable.GetValue("App"); - ErrorReporter.ReportException(ex, app.SettingsKey, app.SupportEmailAddress, this, false); + var iree = ex as InvalidReduplicationEnvironmentException; + if (iree != null) + { + string msg = String.Format(ParserUIStrings.ksHermitCrabReduplicationProblem, iree.Morpheme, + iree.Message); + MessageBox.Show(this, msg, ParserUIStrings.ksBadAffixForm, + MessageBoxButtons.OK, MessageBoxIcon.Error); + } + else + { + var app = (IApp) m_mediator.PropertyTable.GetValue("App"); + ErrorReporter.ReportException(ex, app.SettingsKey, app.SupportEmailAddress, this, false); + } return; } if (m_tryAWordResult != null && m_tryAWordResult.IsCompleted) { - var message = (string) m_tryAWordResult.AsyncState; + var result = (XDocument) m_tryAWordResult.AsyncState; string sOutput; - if (!message.TrimStart().StartsWith("<")) + if (result == null) { // It's an error message. sOutput = Path.GetTempFileName(); @@ -546,15 +559,14 @@ private void m_timer_Tick(object sender, EventArgs e) { writer.WriteLine(""); writer.WriteLine(""); - writer.WriteLine(message); + writer.WriteLine(ParserUIStrings.ksDidNotParse); writer.WriteLine(""); writer.WriteLine(""); - writer.Close(); } } else { - sOutput = m_webPageInteractor.ParserTrace.CreateResultPage(message); + sOutput = m_webPageInteractor.ParserTrace.CreateResultPage(result, DoTrace); } m_htmlControl.URL = sOutput; m_tryAWordResult = null; @@ -598,7 +610,7 @@ private bool DoManualParse /// private static string TransformPath { - get { return DirectoryFinder.GetFWCodeSubDirectory(@"Language Explorer/Configuration/Words/Analyses/TraceParse"); } + get { return FwDirectoryFinder.GetCodeSubDirectory(@"Language Explorer/Configuration/Words/Analyses/TraceParse"); } } private void m_buttonHelp_Click(object sender, EventArgs e) diff --git a/Src/LexText/ParserUI/WebPageInteractor.cs b/Src/LexText/ParserUI/WebPageInteractor.cs index 3a85ccd246..8e2dca522c 100644 --- a/Src/LexText/ParserUI/WebPageInteractor.cs +++ b/Src/LexText/ParserUI/WebPageInteractor.cs @@ -178,7 +178,7 @@ public void MouseMove() public void ShowWordGrammarDetail(string sNodeId) { string sForm = AdjustForm(m_tbWordForm.Text); - m_htmlControl.URL = ParserTrace.SetUpWordGrammarDebuggerPage(sNodeId, sForm, m_htmlControl.URL); + m_htmlControl.URL = ParserTrace.WordGrammarDebugger.SetUpWordGrammarDebuggerPage(sNodeId, sForm, m_htmlControl.URL); } /// /// Try another pass in the Word Grammar Debugger @@ -187,7 +187,7 @@ public void ShowWordGrammarDetail(string sNodeId) public void TryWordGrammarAgain(string sNodeId) { string sForm = AdjustForm(m_tbWordForm.Text); - m_htmlControl.URL = ParserTrace.PerformAnotherWordGrammarDebuggerStepPage(sNodeId, sForm, m_htmlControl.URL); + m_htmlControl.URL = ParserTrace.WordGrammarDebugger.PerformAnotherWordGrammarDebuggerStepPage(sNodeId, sForm, m_htmlControl.URL); } /// /// Back up a page in the Word Grammar Debugger @@ -199,7 +199,7 @@ public void TryWordGrammarAgain(string sNodeId) /// public void GoToPreviousWordGrammarPage() { - m_htmlControl.URL = ParserTrace.PopWordGrammarStack(); + m_htmlControl.URL = ParserTrace.WordGrammarDebugger.PopWordGrammarStack(); } /// /// Modify the content of the form to use entities when needed diff --git a/Src/LexText/ParserUI/WordGrammarDebugger.cs b/Src/LexText/ParserUI/WordGrammarDebugger.cs index 3cb4b8617f..cc4d766176 100644 --- a/Src/LexText/ParserUI/WordGrammarDebugger.cs +++ b/Src/LexText/ParserUI/WordGrammarDebugger.cs @@ -1,165 +1,143 @@ using System; using System.Collections.Generic; -using System.Drawing; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.IO; using System.Linq; -using System.Text; using System.Xml; +using System.Xml.Linq; using System.Xml.XPath; using System.Xml.Xsl; -using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.Common.FwUtils; -using SIL.FieldWorks.Common.Widgets; using SIL.FieldWorks.FDO; -using SIL.Utils; using XCore; namespace SIL.FieldWorks.LexText.Controls { - public abstract class WordGrammarDebugger : ParserTraceBase + [SuppressMessage("Gendarme.Rules.Design", "TypesWithDisposableFieldsShouldBeDisposableRule", + Justification="m_cache and m_mediator are references")] + public abstract class WordGrammarDebugger { + private static ParserTraceUITransform s_pageTransform; + private static ParserTraceUITransform PageTransform + { + get + { + if (s_pageTransform == null) + s_pageTransform = new ParserTraceUITransform("FormatXAmpleWordGrammarDebuggerResult"); + return s_pageTransform; + } + } + /// /// Word Grammar step stack /// - protected Stack m_XmlHtmlStack; - - protected const string m_ksWordGrammarDebugger = "WordGrammarDebugger"; + private readonly Stack> m_xmlHtmlStack; - public WordGrammarDebugger() - { - } /// - /// The real deal + /// the latest word grammar debugging step xml document /// - /// - public WordGrammarDebugger(Mediator mediator) - : base(mediator) + private XDocument m_wordGrammarDebuggerXml; + + private readonly XslCompiledTransform m_intermediateTransform; + private readonly Mediator m_mediator; + private readonly FdoCache m_cache; + + protected WordGrammarDebugger(Mediator mediator) { - m_XmlHtmlStack = new Stack(); + m_mediator = mediator; + m_cache = (FdoCache) m_mediator.PropertyTable.GetValue("cache"); + m_xmlHtmlStack = new Stack>(); + m_intermediateTransform = new XslCompiledTransform(); + m_intermediateTransform.Load(Path.Combine(Path.GetTempPath(), m_cache.ProjectId.Name + "XAmpleWordGrammarDebugger.xsl"), new XsltSettings(true, false), new XmlUrlResolver()); } - /// /// Initialize what is needed to perform the word grammar debugging and /// produce an html page showing the results /// - /// Id of the node to use - /// the wordform being tried + /// Id of the node to use + /// the wordform being tried + /// /// temporary html file showing the results of the first step - public string SetUpWordGrammarDebuggerPage(string sNodeId, string sForm, string sLastURL) + public string SetUpWordGrammarDebuggerPage(string nodeId, string form, string lastUrl) { - m_XmlHtmlStack.Push(new WordGrammarStepPair(null, sLastURL)); - string sInitialAnalysisXml = CreateAnalysisXml(sNodeId, sForm); - string sHtmlPage = CreateWordDebuggerPage(sInitialAnalysisXml); - return sHtmlPage; + m_xmlHtmlStack.Push(Tuple.Create((XDocument) null, lastUrl)); + var doc = new XDocument(); + using (XmlWriter writer = doc.CreateWriter()) + CreateAnalysisXml(writer, nodeId, form); + return CreateWordDebuggerPage(doc); } + /// /// Perform another step in the word grammar debugging process and /// produce an html page showing the results /// - /// Id of the selected node to use + /// Id of the selected node to use + /// + /// /// temporary html file showing the results of the next step - public string PerformAnotherWordGrammarDebuggerStepPage(string sNodeId, string sForm, string sLastURL) + public string PerformAnotherWordGrammarDebuggerStepPage(string nodeId, string form, string lastUrl) { - m_XmlHtmlStack.Push(new WordGrammarStepPair(m_sWordGrammarDebuggerXmlFile, sLastURL)); - string sNextXml = CreateSelectedWordGrammarXml(sNodeId, sForm); - string sHtmlPage = CreateWordDebuggerPage(sNextXml); - return sHtmlPage; + m_xmlHtmlStack.Push(Tuple.Create(m_wordGrammarDebuggerXml, lastUrl)); + var doc = new XDocument(); + using (XmlWriter writer = doc.CreateWriter()) + CreateSelectedWordGrammarXml(writer, nodeId, form); + return CreateWordDebuggerPage(doc); } + public string PopWordGrammarStack() { - WordGrammarStepPair wgsp; - if (m_XmlHtmlStack.Count > 0) + if (m_xmlHtmlStack.Count > 0) { - wgsp = m_XmlHtmlStack.Pop(); // get the previous one - m_sWordGrammarDebuggerXmlFile = wgsp.XmlFile; - return wgsp.HtmlFile; + Tuple wgsp = m_xmlHtmlStack.Pop(); + m_wordGrammarDebuggerXml = wgsp.Item1; + return wgsp.Item2; } return "unknown"; } - protected string CreateAnalysisXml(string sNodeId, string sForm) + + private void CreateAnalysisXml(XmlWriter writer, string nodeId, string form) { - string sResult; - if (m_parseResult != null) - { - XmlDocument doc = new XmlDocument(); - XmlNode wordNode = CreateXmlElement(doc, "word", doc); - XmlNode formNode = CreateXmlElement(doc, "form", wordNode); - formNode.InnerXml = sForm; - XmlNode seqNode = CreateXmlElement(doc, "seq", wordNode); + writer.WriteStartElement("word"); + writer.WriteElementString("form", form); + writer.WriteStartElement("seq"); - // following for debugging as needed - sResult = CreateTempFile("ParseResult", "xml"); - m_parseResult.Save(sResult); - CreateMorphNodes(doc, seqNode, sNodeId); + WriteMorphNodes(writer, nodeId); - sResult = CreateTempFile(CreateWordGrammarDebuggerFileName(), "xml"); - doc.Save(sResult); - } - else - sResult = "error!"; - return sResult; - } - private string CreateSelectedWordGrammarXml(string sNodeId, string sForm) - { - string sResult; - if (m_sWordGrammarDebuggerXmlFile != null) - { - XmlDocument lastDoc = new XmlDocument(); - lastDoc.Load(m_sWordGrammarDebuggerXmlFile); - XmlDocument doc = new XmlDocument(); - XmlNode wordNode = CreateXmlElement(doc, "word", doc); - XmlNode formNode = CreateXmlElement(doc, "form", wordNode); - formNode.InnerXml = sForm; - // Find the sNode'th seq node - string sSelect = "//seq[position()='" + sNodeId + "']"; - XmlNode selectedSeqNode = lastDoc.SelectSingleNode(sSelect); - // create the "result so far node" - XmlNode resultSoFarNode = CreateXmlElement(doc, "resultSoFar", wordNode); - resultSoFarNode.InnerXml = selectedSeqNode.InnerXml; - // create the seq node - XmlNode seqNode = CreateXmlElement(doc, "seq", wordNode); - seqNode.InnerXml = selectedSeqNode.InnerXml; - // save result - sResult = CreateTempFile("SelectedWordGrammarXml", "xml"); - doc.Save(sResult); - } - else - sResult = "error!"; - return sResult; + writer.WriteEndElement(); + writer.WriteEndElement(); } - private string CreateWordDebuggerPage(string sXmlFile) - { - // apply word grammar step transform file - string sXmlOutput = TransformToXml(sXmlFile); - m_sWordGrammarDebuggerXmlFile = sXmlOutput; - // format the result - string sOutput = TransformToHtml(sXmlOutput); - return sOutput; - } + protected abstract void WriteMorphNodes(XmlWriter writer, string nodeId); - private string CreateWordGrammarDebuggerFileName() + private void CreateSelectedWordGrammarXml(XmlWriter writer, string nodeId, string form) { - string sDepthLevel = m_XmlHtmlStack.Count.ToString(); - return m_ksWordGrammarDebugger + sDepthLevel; - } + writer.WriteStartElement("word"); + writer.WriteElementString("form", form); - protected string TransformToHtml(string sInputFile) - { - var args = new List(); - string sOutput = TransformToHtml(sInputFile, CreateWordGrammarDebuggerFileName(), - "FormatXAmpleWordGrammarDebuggerResult.xsl", args); - return sOutput; + // Find the sNode'th seq node + Debug.Assert(m_wordGrammarDebuggerXml.Root != null); + XElement selectedSeqNode = m_wordGrammarDebuggerXml.Root.Elements("seq").ElementAt(int.Parse(nodeId, CultureInfo.InvariantCulture) - 1); + // create the "result so far node" + writer.WriteStartElement("resultSoFar"); + foreach (XElement child in selectedSeqNode.Elements()) + child.WriteTo(writer); + writer.WriteEndElement(); + // create the seq node + selectedSeqNode.WriteTo(writer); + writer.WriteEndElement(); } - private string TransformToXml(string sInputFile) + + private string CreateWordDebuggerPage(XDocument xmlDoc) { - // Don't overwrite the input file before transforming it! (why +"A" on the next line) - string sOutput = CreateTempFile(CreateWordGrammarDebuggerFileName()+"A", "xml"); - string sName = m_sDataBaseName + "XAmpleWordGrammarDebugger" + ".xsl"; - string sTransform = Path.Combine(Path.GetDirectoryName(sOutput), sName); - XmlUtils.TransformFileToFile(sTransform, new XmlUtils.XSLParameter[0], sInputFile, sOutput); - return sOutput; + // apply word grammar step transform file + var output = new XDocument(); + using (XmlWriter writer = output.CreateWriter()) + m_intermediateTransform.Transform(xmlDoc.CreateNavigator(), writer); + m_wordGrammarDebuggerXml = output; + // format the result + return PageTransform.Transform(m_mediator, output, "WordGrammarDebugger" + m_xmlHtmlStack.Count); } } } diff --git a/Src/LexText/ParserUI/XAmpleTrace.cs b/Src/LexText/ParserUI/XAmpleTrace.cs index 23662f1ba3..fbad4bd907 100644 --- a/Src/LexText/ParserUI/XAmpleTrace.cs +++ b/Src/LexText/ParserUI/XAmpleTrace.cs @@ -13,465 +13,63 @@ // XAmpleTrace - Deal with results of an XAmple trace // -using System; using System.Diagnostics.CodeAnalysis; -using System.Text; -using System.Xml; -using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.FDO; +using System.Xml.Linq; using XCore; -using System.Xml.XPath; - namespace SIL.FieldWorks.LexText.Controls { /// /// Summary description for XAmpleTrace. /// + [SuppressMessage("Gendarme.Rules.Design", "TypesWithDisposableFieldsShouldBeDisposableRule", + Justification="m_mediator is a reference")] public class XAmpleTrace : ParserTrace { - - /// - /// Temp File names - /// - const string m_ksXAmpleParse = "XAmpleParse"; - const string m_ksXAmpleTrace = "XAmpleTrace"; - - /// - /// For testing - /// - public XAmpleTrace() + private static ParserTraceUITransform s_traceTransform; + private static ParserTraceUITransform TraceTransform { + get + { + if (s_traceTransform == null) + s_traceTransform = new ParserTraceUITransform("FormatXAmpleTrace"); + return s_traceTransform; + } } + + private readonly Mediator m_mediator; + /// /// The real deal /// /// - public XAmpleTrace(Mediator mediator) : base(mediator) + public XAmpleTrace(Mediator mediator) { - m_sParse = m_ksXAmpleParse; - m_sTrace = m_ksXAmpleTrace; - m_sFormatParse = "FormatXAmpleParse.xsl"; - m_sFormatTrace = "FormatXAmpleTrace.xsl"; - - } - /// - /// Initialize what is needed to perform the word grammar debugging and - /// produce an html page showing the results - /// - /// Id of the node to use - /// the wordform being tried - /// temporary html file showing the results of the first step - public override string SetUpWordGrammarDebuggerPage(string sNodeId, string sForm, string sLastURL) - { - m_wordGrammarDebugger = new XAmpleWordGrammarDebugger(m_mediator, m_parseResult); - return m_wordGrammarDebugger.SetUpWordGrammarDebuggerPage(sNodeId, sForm, sLastURL); + m_mediator = mediator; } /// /// Create an HTML page of the results /// /// XML string of the XAmple trace output + /// /// URL of the resulting HTML page - public override string CreateResultPage(string result) - { - string sAdjusted; - bool fIsTrace; - AdjustResultContent(result, out sAdjusted, out fIsTrace); - - m_parseResult = new XmlDocument(); - m_parseResult.LoadXml(ConvertHvosToStrings(sAdjusted, fIsTrace)); - - AddMsaNodes(fIsTrace); - - string sInput = CreateTempFile(m_ksXAmpleTrace, "xml"); - m_parseResult.Save(sInput); - TransformKind kind = (fIsTrace ? TransformKind.kcptTrace : TransformKind.kcptParse); - string sOutput = TransformToHtml(sInput, kind); - return sOutput; - } - - protected override void CreateMorphNodes(XmlDocument doc, XmlNode seqNode, string sNodeId) - { - string s = "//failure[@id=\"" + sNodeId + "\"]/ancestor::parseNode[morph][1]/morph"; - XmlNode node = m_parseResult.SelectSingleNode(s); - if (node != null) - { - CreateMorphNode(doc, seqNode, node); - } - } - private void CreateMorphNode(XmlDocument doc, XmlNode seqNode, XmlNode node) + public override string CreateResultPage(XDocument result, bool isTrace) { - // get the element closest up the chain to node - XmlNode morph = node.SelectSingleNode("../ancestor::parseNode[morph][1]/morph"); - if (morph != null) + ParserTraceUITransform transform; + string baseName; + if (isTrace) { - CreateMorphNode(doc, seqNode, morph); - } - CreateMorphXmlElement(doc, seqNode, node); - } - - -#if false // CS 169 - private void CreateMorphGenericXmlElement(XmlNode node, XmlNode morphNode, string sName) - { - XmlNode nameNode = node.SelectSingleNode(sName); - if (nameNode != null) - morphNode.InnerXml = "<" + sName +">" + nameNode.InnerXml + ""; - } -#endif - private string ConvertHvosToStrings(string sAdjusted, bool fIsTrace) - { - // When we switched to VS 2005, the result from XAmple had a final trailing null character. - // I'm not sure why (Andy). Remove it. - string sNoFinalNull = RemoveAnyFinalNull(sAdjusted); - XmlDocument doc = new XmlDocument(); - doc.LoadXml(sNoFinalNull); - if (fIsTrace) - { - ConvertMorphs(doc, "//morph", true); - ConvertFailures(doc); - } - else - ConvertMorphs(doc, "//Morph", false); - return doc.InnerXml; - } - - private void AdjustResultContent(string sXml, out string sAdjusted, out bool fIsTrace) - { - - - if (sXml.Contains("", "[...]"); - sAdjusted = sFullRedup.Replace("DbRef=DB_REF_HERE", "DbRef=\"DB_REF_HERE\""); - fIsTrace = false; + transform = ParseTransform; + baseName = "XAmpleParse"; } - } - - private string RemoveAnyFinalNull(string sInput) - { - string sResult; - int i = sInput.LastIndexOf('\x0'); - if (i >= 0) - sResult = sInput.Substring(0, i); - else - sResult = sInput; - return sResult; - } - private string AdjustEntities(string sInput) - { - string sResult = sInput.Replace("]", "]"); // Created by XAmple - return sResult; - } - - - private void ConvertFailures(XmlDocument doc) - { - ConvertSECFailures(doc, false); - ConvertInfixEnvironmentFailures(doc, false); - ConvertANCCFailures(doc, false); - ConvertMCCFailures(doc, false); - ConvertWordGrammarFailures(doc, false); - } - - public void ConvertSECFailures(XmlDocument doc, bool fTesting) - { - const string ksSEC_ST = "SEC_ST"; - ConvertNaturalClasses(ksSEC_ST, doc, fTesting); - ConvertEntities(ksSEC_ST, doc); - } - - [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", - Justification = "In .NET 4.5 XmlNodeList implements IDisposable, but not in 4.0.")] - private void ConvertEntities(string sTestName, XmlDocument doc) - { - StringBuilder sb = new StringBuilder(); - sb.Append("//failure[contains(@test,'"); - sb.Append(sTestName); - sb.Append("') and contains(@test,'&')]"); - XmlNodeList nl = doc.SelectNodes(sb.ToString()); - if (nl != null) - { - foreach (XmlNode node in nl) - { - XmlNode test = node.Attributes.GetNamedItem("test"); - string s = test.InnerText; - test.InnerText = CreateEntities(s); - } - } - } - - [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", - Justification = "In .NET 4.5 XmlNodeList implements IDisposable, but not in 4.0.")] - private void ConvertNaturalClasses(string sTestName, XmlDocument doc, bool fTesting) - { - StringBuilder sbXPath = new StringBuilder(); - sbXPath.Append("//failure[contains(@test,'"); - sbXPath.Append(sTestName); - sbXPath.Append("') and contains(@test,'[')]"); - XmlNodeList nl = doc.SelectNodes(sbXPath.ToString()); - if (nl != null) - { - m_iTestingCount = 0; - - foreach (XmlNode node in nl) - { - XmlNode test = node.Attributes.GetNamedItem("test"); - string s = test.InnerText; - int i = test.InnerText.IndexOf('/'); - string s0 = s.Substring(i); - char[] brackets = {'[', ']'}; - string[] sa = s0.Split(brackets); // split into hunks using brackets - StringBuilder sb = new StringBuilder(); - foreach (string str in sa) // for each hunk - { - if (str.IndexOfAny(m_digits) >= 0) - { // assume it is an hvo - sb.Append("["); - if (fTesting) - { - if (m_iTestingCount > 5) - m_iTestingCount = 0; - sb.Append(m_saTesting[m_iTestingCount++]); - } - else - { - string sHvo = str; - int hvo = Convert.ToInt32(sHvo); - ICmObject obj = m_cache.ServiceLocator.GetInstance().GetObject(hvo); - IPhNCSegments nc = obj as IPhNCSegments; - string sName; - if (nc != null) - sName = nc.Name.BestAnalysisAlternative.Text; - else - { - sName = ParserUIStrings.ksUnknownNaturalClass; // in case the user continues... - throw new ApplicationException(sName); - } - sb.Append(sName); - } - sb.Append("]"); - } - else - sb.Append(str); - } - test.InnerText = s.Substring(0,i) + sb.ToString(); - } - } - } - public void ConvertInfixEnvironmentFailures(XmlDocument doc, bool fTesting) - { - const string ksInfixEnvironment = "InfixEnvironment"; - ConvertNaturalClasses(ksInfixEnvironment, doc, fTesting); - ConvertEntities(ksInfixEnvironment, doc); - } - - public void ConvertMCCFailures(XmlDocument doc, bool fTesting) - { - MCCTraceTest mcc = new MCCTraceTest(); - ConvertAdHocFailures(doc, fTesting, mcc); - } - - public void ConvertANCCFailures(XmlDocument doc, bool fTesting) - { - ANCCTraceTest ancc = new ANCCTraceTest(); - ConvertAdHocFailures(doc, fTesting, ancc); - } - - [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", - Justification = "In .NET 4.5 XmlNodeList implements IDisposable, but not in 4.0.")] - private void ConvertAdHocFailures(XmlDocument doc, bool fTesting, AdhocTraceTest tt) - { - string sXPath = "//failure[contains(@test,'" + tt.Name + - "') and not(contains(@test,'ExcpFeat')) and not(contains(@test,'StemName')) and not(contains(@test,'IrregInflForm'))]"; - XmlNodeList nl = doc.SelectNodes(sXPath); - if (nl != null) - { - m_iTestingCount = 0; - foreach (XmlNode node in nl) - { - XmlNode test = node.Attributes.GetNamedItem("test"); - string s = test.InnerText; - int iStartingPos = s.IndexOf("::") + 2; // skip to the double colon portion - string[] sa = s.Substring(iStartingPos).Split(m_space); - - StringBuilder sb = new StringBuilder(); - sb.Append(tt.Name); - sb.Append(":"); - foreach (string str in sa) - { - sb.Append(" "); - if (str.IndexOfAny(m_digits) >= 0) - { - if (fTesting) - { - if (m_iTestingCount > 5) - m_iTestingCount = 0; - sb.Append(m_saTesting[m_iTestingCount++]); - } - else - { - string sHvo = str; - int hvo = Convert.ToInt32(sHvo); - sb.Append(tt.GetHvoRepresentation(m_cache, hvo)); - // get msa PhNCSegments nc = m_cache.ServiceLocator.GetInstance().GetObject(hvo); - // string name = nc.Name.BestAnalysisAlternative.Text; - } - } - else - sb.Append(str); - } - test.InnerText = sb.ToString(); - } - } - } - - [SuppressMessage("Gendarme.Rules.Correctness", "EnsureLocalDisposalRule", - Justification = "In .NET 4.5 XmlNodeList implements IDisposable, but not in 4.0.")] - private void ConvertWordGrammarFailures(XmlDocument doc, bool fTesting) - { - string sXPath = "//failure[contains(@test,'PC-PATR')]"; - XmlNodeList nl = doc.SelectNodes(sXPath); - if (nl != null) - { - int iCount = 1; - foreach (XmlNode node in nl) - { - CreateXmlAttribute(doc, "id", iCount.ToString(), node); - iCount++; - } - } - } - - - } - public abstract class AdhocTraceTest - { - protected string m_Name; - - public AdhocTraceTest() - { - } - - public virtual string GetHvoRepresentation(FdoCache cache, int hvo) - { - return ""; - } - - public string Name - { - get - { - return m_Name; - } - } - } - public class ANCCTraceTest : AdhocTraceTest - { - public ANCCTraceTest() - { - m_Name = "ANCC_FT"; - } - - public override string GetHvoRepresentation(FdoCache cache, int hvo) - { - ICmObject obj = cache.ServiceLocator.GetInstance().GetObject(hvo); - IMoForm form = obj as IMoForm; - string sResult; - if (form != null) - sResult = form.ShortName; - else - { - sResult = ParserUIStrings.ksUnknownAllomorph; // in case the user continues... - throw new ApplicationException(sResult); - } - return sResult; + return transform.Transform(m_mediator, result, baseName); } } - public class MCCTraceTest : AdhocTraceTest - { - public MCCTraceTest() - { - m_Name = "MCC_FT"; - } - - public override string GetHvoRepresentation(FdoCache cache, int hvo) - { - var obj = cache.ServiceLocator.GetInstance().GetObject(hvo); - IMoMorphSynAnalysis msa = obj as IMoMorphSynAnalysis; - string sResult; - if (msa != null) - sResult = msa.LongName; - else - { - sResult = ParserUIStrings.ksUnknownMorpheme; // in case the user continues... - throw new ApplicationException(sResult); - } - return sResult; - } - } - public class WordGrammarStepPair - { - protected string m_sXmlFile; - protected string m_sHtmlFile; - /// - /// Constructor - /// - /// Xml file - /// Html file - public WordGrammarStepPair(string sXmlFile, string sHtmlFile) - { - m_sXmlFile = sXmlFile; - m_sHtmlFile = sHtmlFile; - } - /// - /// Gete/set XmlFile - /// - public string XmlFile - { - get - { - return m_sXmlFile; - } - set - { - m_sXmlFile = value; - } - } - /// - /// Gete/set HtmlFile - /// - public string HtmlFile - { - get - { - return m_sHtmlFile; - } - set - { - m_sHtmlFile = value; - } - } - - } - } -/// -/// Note for Andy -/// -#if Later -using mshtml; - -IHTMLDocument2 doc; -object boxDoc = m_browser.Document; -doc = (IHTMLDocument2)boxDoc; -string sHtml = doc.body.innerHTML; -#endif diff --git a/Src/LexText/ParserUI/XAmpleWordGrammarDebugger.cs b/Src/LexText/ParserUI/XAmpleWordGrammarDebugger.cs index 122222bbb0..c6f49a1487 100644 --- a/Src/LexText/ParserUI/XAmpleWordGrammarDebugger.cs +++ b/Src/LexText/ParserUI/XAmpleWordGrammarDebugger.cs @@ -1,42 +1,33 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Diagnostics; using System.Xml; +using System.Xml.Linq; +using System.Linq; using XCore; namespace SIL.FieldWorks.LexText.Controls { public class XAmpleWordGrammarDebugger : WordGrammarDebugger { - public XAmpleWordGrammarDebugger() - { } + private readonly XDocument m_parseResult; - public XAmpleWordGrammarDebugger(Mediator mediator, XmlDocument parseResult) + public XAmpleWordGrammarDebugger(Mediator mediator, XDocument parseResult) : base(mediator) { m_parseResult = parseResult; } - protected override void CreateMorphNodes(XmlDocument doc, XmlNode seqNode, string sNodeId) + protected override void WriteMorphNodes(XmlWriter writer, string nodeId) { - string s = "//failure[@id=\"" + sNodeId + "\"]/ancestor::parseNode[morph][1]/morph"; - XmlNode node = m_parseResult.SelectSingleNode(s); - if (node != null) + XElement failureElem = m_parseResult.Descendants("failure").FirstOrDefault(e => ((string) e.Attribute("id")) == nodeId); + if (failureElem != null) { - CreateMorphNode(doc, seqNode, node); + foreach (XElement parseNodeElem in failureElem.Ancestors("parseNode").Where(e => e.Element("morph") != null).Reverse()) + { + XElement morphElem = parseNodeElem.Element("morph"); + Debug.Assert(morphElem != null); + morphElem.WriteTo(writer); + } } } - private void CreateMorphNode(XmlDocument doc, XmlNode seqNode, XmlNode node) - { - // get the element closest up the chain to node - XmlNode morph = node.SelectSingleNode("../ancestor::parseNode[morph][1]/morph"); - if (morph != null) - { - CreateMorphNode(doc, seqNode, morph); - } - CreateMorphXmlElement(doc, seqNode, node); - } - } } diff --git a/Src/LexText/ParserUI/gendarme-ParserUI.ignore b/Src/LexText/ParserUI/gendarme-ParserUI.ignore index 4bd1fb685b..213be44e65 100644 --- a/Src/LexText/ParserUI/gendarme-ParserUI.ignore +++ b/Src/LexText/ParserUI/gendarme-ParserUI.ignore @@ -22,3 +22,12 @@ R: Gendarme.Rules.Design.TypesWithDisposableFieldsShouldBeDisposableRule T: SIL.FieldWorks.LexText.Controls.ParserTraceBase T: SIL.FieldWorks.LexText.Controls.WebPageInteractor T: SIL.FieldWorks.LexText.Controls.WordImporter + +#----------------------------------------------------------------------------------------------- +R: Gendarme.Rules.Portability.NewLineLiteralRule + +#generated code +T: FormatHCTrace +T: FormatXAmpleParse +T: FormatXAmpleTrace +T: FormatXAmpleWordGrammarDebuggerResult \ No newline at end of file diff --git a/Src/ManagedLgIcuCollator/LgIcuCollator.cs b/Src/ManagedLgIcuCollator/LgIcuCollator.cs index f06a774b29..4d6650482c 100644 --- a/Src/ManagedLgIcuCollator/LgIcuCollator.cs +++ b/Src/ManagedLgIcuCollator/LgIcuCollator.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using System.Runtime.InteropServices; using SIL.FieldWorks.Common.COMInterfaces; @@ -9,7 +8,7 @@ namespace SIL.FieldWorks.Language /// /// Direct port of the C++ class LgIcuCollator /// - [Serializable()] + [Serializable] [ClassInterface(ClassInterfaceType.None)] [Guid("e771361c-ff54-4120-9525-98a0b7a9accf")] public class ManagedLgIcuCollator : ILgCollatingEngine, IDisposable @@ -20,8 +19,6 @@ public class ManagedLgIcuCollator : ILgCollatingEngine, IDisposable private string m_stuLocale; private IntPtr m_pCollator; - private const int keysize = 1024; - #endregion #region Disposable stuff @@ -56,80 +53,20 @@ protected virtual void Dispose(bool fDisposing) } #endregion - protected byte[] GetSortKey(string bstrValue, byte[] prgbKey, ref Int32 pcbKey) - { - byte[] pbKey; - Int32 crgbKey = pcbKey; - EnsureCollator(); - pcbKey = Icu.ucol_GetSortKey(m_pCollator, bstrValue, -1, ref prgbKey, prgbKey.Length); - if (pcbKey > crgbKey) - { - pbKey = null; - } - - else - { - pbKey = prgbKey; - } - - return pbKey; - } - - protected byte[] GetSortKey(string bstrValue, byte[] prgbKey, ref Int32 pcbKey, out byte[] vbKey) - { - vbKey = null; - Int32 cbKey = pcbKey; - byte[] pbKey = GetSortKey(bstrValue, prgbKey, ref cbKey); - if (cbKey > pcbKey) - { - Int32 cbKey1 = cbKey + 1; - vbKey = new byte[cbKey]; - pbKey = GetSortKey(bstrValue, vbKey, ref cbKey1); - Debug.Assert(cbKey == cbKey1, "cbKey == cbKey1"); - // As long as it fits assume OK. - Debug.Assert(cbKey1 + 1 <= vbKey.Length, "cbKey1 + 1 <= vbKey.Length"); - // pure paranoia -- it's supposed to be NUL-terminated. - vbKey[cbKey] = 0; - } - pcbKey = cbKey; - return pbKey; - } - protected void EnsureCollator() { if (m_pCollator != IntPtr.Zero) return; - // we already have one. - Icu.UErrorCode uerr = Icu.UErrorCode.U_ZERO_ERROR; - - if (m_stuLocale == String.Empty) - { - m_pCollator = Icu.ucol_Open(null, out uerr); - } - else - { - byte[] rgchLoc = new byte[128]; - Int32 cch = Icu.uloc_GetName(m_stuLocale, ref rgchLoc, rgchLoc.Length, out uerr); - Debug.Assert(cch < rgchLoc.Length, "cch < rgchLoc.Length"); - rgchLoc[cch] = 0; - if (uerr != Icu.UErrorCode.U_ZERO_ERROR) - throw new ApplicationException(string.Format("uloc_GetName returned {0}", uerr)); - - m_pCollator = Icu.ucol_Open(rgchLoc, out uerr); - } - - if (!(uerr == Icu.UErrorCode.U_ZERO_ERROR || uerr == Icu.UErrorCode.U_ERROR_WARNING_START || uerr == Icu.UErrorCode.U_USING_DEFAULT_WARNING)) - { - throw new ApplicationException(string.Format("ucol_Open returned {0}", uerr)); - } + string icuLocale = Icu.GetName(m_stuLocale); + m_pCollator = Icu.OpenCollator(icuLocale); } internal void DoneCleanup() { if (m_pCollator != IntPtr.Zero) { - Icu.ucol_Close(m_pCollator); + Icu.CloseCollator(m_pCollator); m_pCollator = IntPtr.Zero; } } @@ -137,27 +74,20 @@ internal void DoneCleanup() #region ILgCollatingEngine implementation public string get_SortKey(string bstrValue, LgCollatingOptions colopt) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public void SortKeyRgch(string _ch, int cchIn, LgCollatingOptions colopt, int cchMaxOut, ArrayPtr _chKey, out int _cchOut) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public int Compare(string bstrValue1, string bstrValue2, LgCollatingOptions colopt) { EnsureCollator(); - Int32 cbKey1 = keysize; - byte[] rgbKey1 = new byte[keysize + 1]; - byte[] vbKey1 = null; - byte[] pbKey1 = GetSortKey(bstrValue1, rgbKey1, ref cbKey1, out vbKey1); - - Int32 cbKey2 = keysize; - byte[] rgbKey2 = new byte[keysize + 1]; - byte[] vbKey2 = null; - byte[] pbKey2 = GetSortKey(bstrValue2, rgbKey2, ref cbKey2, out vbKey2); + byte[] pbKey1 = Icu.GetSortKey(m_pCollator, bstrValue1); + byte[] pbKey2 = Icu.GetSortKey(m_pCollator, bstrValue2); return CompareVariant(pbKey1, pbKey2, colopt); } @@ -166,11 +96,7 @@ public int Compare(string bstrValue1, string bstrValue2, LgCollatingOptions colo public object get_SortKeyVariant(string bstrValue, LgCollatingOptions colopt) { EnsureCollator(); - - Int32 cbKey = keysize; - byte[] rgbKey = new byte[keysize + 1]; - byte[] vbKey = null; - byte[] pbKey = GetSortKey(bstrValue, rgbKey, ref cbKey, out vbKey); + byte[] pbKey = Icu.GetSortKey(m_pCollator, bstrValue); return pbKey; } diff --git a/Src/MigrateSqlDbs/ExistingProjectDlg.cs b/Src/MigrateSqlDbs/ExistingProjectDlg.cs index 6587892b2c..4d2f6edff3 100644 --- a/Src/MigrateSqlDbs/ExistingProjectDlg.cs +++ b/Src/MigrateSqlDbs/ExistingProjectDlg.cs @@ -52,7 +52,7 @@ public ExistingProjectDlg(string project) m_rdoUseOriginalName.Text = String.Format(m_fmtUseOriginal, project); m_projectName = project; // Generate an unused project name based on the one given. - string destFolder = DirectoryFinder.ProjectsDirectory; + string destFolder = FwDirectoryFinder.ProjectsDirectory; int num = 0; string proj; string folderName; @@ -111,7 +111,7 @@ public string TargetProjectName private void m_btnHelp_Click(object sender, EventArgs e) { - string helpFile = Path.Combine(DirectoryFinder.FWCodeDirectory, + string helpFile = Path.Combine(FwDirectoryFinder.CodeDirectory, "Helps\\FieldWorks_Language_Explorer_Help.chm"); string helpTopic = "/Overview/Migrate_FieldWorks_6.0.4_(or_earlier)_Projects.htm"; Help.ShowHelp(new Label(), helpFile, helpTopic); diff --git a/Src/FDO/DomainServices/DataMigration/FWVersionTooOld.Designer.cs b/Src/MigrateSqlDbs/FWVersionTooOld.Designer.cs similarity index 98% rename from Src/FDO/DomainServices/DataMigration/FWVersionTooOld.Designer.cs rename to Src/MigrateSqlDbs/FWVersionTooOld.Designer.cs index ac3341d828..6a5730a51c 100644 --- a/Src/FDO/DomainServices/DataMigration/FWVersionTooOld.Designer.cs +++ b/Src/MigrateSqlDbs/FWVersionTooOld.Designer.cs @@ -7,7 +7,7 @@ using System.Diagnostics.CodeAnalysis; -namespace SIL.FieldWorks.FDO.DomainServices.DataMigration +namespace SIL.FieldWorks.MigrateSqlDbs.MigrateProjects { partial class FWVersionTooOld { diff --git a/Src/FDO/DomainServices/DataMigration/FWVersionTooOld.cs b/Src/MigrateSqlDbs/FWVersionTooOld.cs similarity index 90% rename from Src/FDO/DomainServices/DataMigration/FWVersionTooOld.cs rename to Src/MigrateSqlDbs/FWVersionTooOld.cs index 9dc6973465..bfaf022899 100644 --- a/Src/FDO/DomainServices/DataMigration/FWVersionTooOld.cs +++ b/Src/MigrateSqlDbs/FWVersionTooOld.cs @@ -6,15 +6,10 @@ // Responsibility: mcconnel using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Text; -using System.Windows.Forms; using System.Diagnostics; +using System.Windows.Forms; -namespace SIL.FieldWorks.FDO.DomainServices.DataMigration +namespace SIL.FieldWorks.MigrateSqlDbs.MigrateProjects { /// ---------------------------------------------------------------------------------------- /// diff --git a/Src/FDO/DomainServices/DataMigration/FWVersionTooOld.resx b/Src/MigrateSqlDbs/FWVersionTooOld.resx similarity index 99% rename from Src/FDO/DomainServices/DataMigration/FWVersionTooOld.resx rename to Src/MigrateSqlDbs/FWVersionTooOld.resx index 13c8915234..0587a27a2d 100644 --- a/Src/FDO/DomainServices/DataMigration/FWVersionTooOld.resx +++ b/Src/MigrateSqlDbs/FWVersionTooOld.resx @@ -1,4 +1,4 @@ - + + 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. + --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - text/microsoft-resx + text/microsoft-resx - 2.0 + 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - The following projects did not migrate successfully: - message heading (list of projects will appear on lines below this message) + The following projects did not migrate successfully: + message heading (list of projects will appear on lines below this message) - Warning - heading for message box + Warning + heading for message box - {0} (migrated) - {0} is a project name + {0} (migrated) + {0} is a project name - {0} (failed migration) - {0} is a project name + {0} (failed migration) + {0} is a project name - Preparing for migration - Creating a temporary copy of {0}. - {0} is a project name + Preparing for migration - Creating a temporary copy of {0}. + {0} is a project name - Creating a temporary copy of {0} failed. The copy process returned error code {1} and error message {2}. - {0} is a project name + Creating a temporary copy of {0} failed. The copy process returned error code {1} and error message {2}. + {0} is a project name - Preparing for migration - Migrating the copy of {0} to FieldWorks 6.0 - {0} is a project name + Preparing for migration - Migrating the copy of {0} to FieldWorks 6.0 + {0} is a project name - Migrating the copy of {0} to FieldWorks 6.0 failed. The migration process returned error code {1} and error message {2}. - {0} is a project name + Migrating the copy of {0} to FieldWorks 6.0 failed. The migration process returned error code {1} and error message {2}. + {0} is a project name - Preparing for migration - Writing {0} as FieldWorks 6.0 XML. - {0} is a project name + Preparing for migration - Writing {0} as FieldWorks 6.0 XML. + {0} is a project name - Writing {0} as FieldWorks 6.0 XML failed. The writing process returned error code {1} and error message {2}. - {0} is a project name + Writing {0} as FieldWorks 6.0 XML failed. The writing process returned error code {1} and error message {2}. + {0} is a project name - Preparing for migration - Writing the copy of {0} as FieldWorks 6.0 XML. - {0} is a project name + Preparing for migration - Writing the copy of {0} as FieldWorks 6.0 XML. + {0} is a project name - Writing the copy of {0} as FieldWorks 6.0 XML failed. The writing process returned error code {1} and error message {2}. - {0} is a project name + Writing the copy of {0} as FieldWorks 6.0 XML failed. The writing process returned error code {1} and error message {2}. + {0} is a project name - Cancel + Cancel - {0} (already exists) - {0} is a project name + {0} (already exists) + {0} is a project name - Skip + Skip + + + Cannot Convert \ No newline at end of file diff --git a/Src/TE/DiffView/BookMerger.cs b/Src/TE/DiffView/BookMerger.cs index 85df9e1634..364fb91352 100644 --- a/Src/TE/DiffView/BookMerger.cs +++ b/Src/TE/DiffView/BookMerger.cs @@ -6692,7 +6692,7 @@ protected virtual bool DisplayUi /// ------------------------------------------------------------------------------------ public void RecalculateDifferences(Form owner) { - using (ProgressDialogWithTask progressDlg = new ProgressDialogWithTask(owner, Cache.ThreadHelper)) + using (var progressDlg = new ProgressDialogWithTask(owner)) { progressDlg.Title = DlgResources.ResourceString("kstidCompareCaption"); progressDlg.Message = TeDiffViewResources.kstidRecalculateDiff; diff --git a/Src/TE/DiffView/Cluster.cs b/Src/TE/DiffView/Cluster.cs index 7f73efd102..9465fc3345 100644 --- a/Src/TE/DiffView/Cluster.cs +++ b/Src/TE/DiffView/Cluster.cs @@ -15,6 +15,7 @@ using System.Linq; using SIL.FieldWorks.FDO; using System.Diagnostics; +using SIL.Utils; using SILUBS.SharedScrUtils; using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FDO.DomainServices; diff --git a/Src/TE/DiffView/DiffDialog.cs b/Src/TE/DiffView/DiffDialog.cs index 6329cb8eb9..5244487265 100644 --- a/Src/TE/DiffView/DiffDialog.cs +++ b/Src/TE/DiffView/DiffDialog.cs @@ -97,7 +97,7 @@ public class DiffDialog : Form, IFWDisposable, IxCoreColleague, ISettings, IMess #region Construction/Destruction /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The book merger. /// The cache. @@ -117,7 +117,7 @@ public DiffDialog(BookMerger bookMerger, FdoCache cache, IVwStylesheet styleshee /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The book merger. /// The cache. @@ -302,7 +302,7 @@ private void CreateMenuAndToolbars() // Use this to initialize combo box items. m_tmAdapter.InitializeComboItem += InitializeToolBarCombos; - string[] def = new string[] {DirectoryFinder.FWCodeDirectory + + string[] def = new string[] {FwDirectoryFinder.CodeDirectory + "/Translation Editor/Configuration/DiffViewTMDefinition.xml"}; m_tmAdapter.AllowUpdates = true; m_tmAdapter.Initialize(this, m_msgMediator, def); @@ -2008,7 +2008,7 @@ public string ZoomString /// User has changed the zoom percentage with the drop down list. /// /// The source of the event. - /// An that contains the event data. + /// An that contains the event data. /// ------------------------------------------------------------------------------------ private void ZoomSelectionChanged(object sender, EventArgs e) { @@ -2020,7 +2020,7 @@ private void ZoomSelectionChanged(object sender, EventArgs e) /// User has pressed a key in the zoom percentage control /// /// The source of the event. - /// An that contains the event data. + /// An that contains the event data. /// ------------------------------------------------------------------------------------ private void ZoomKeyPress(object sender, KeyPressEventArgs e) { @@ -2034,7 +2034,7 @@ private void ZoomKeyPress(object sender, KeyPressEventArgs e) /// The zoom control has lost focus /// /// The source of the event. - /// An that contains the event data. + /// An that contains the event data. /// ------------------------------------------------------------------------------------ private void ZoomLostFocus(object sender, EventArgs e) { @@ -2179,7 +2179,7 @@ private void OnRedoDropDownClicked(object sender, int iClicked) #region Overridden Methods /// ------------------------------------------------------------------------------------ /// - /// Raises the event. + /// Raises the Layout event. /// /// The instance /// containing the event data. diff --git a/Src/TE/DiffView/DiffView.csproj b/Src/TE/DiffView/DiffView.csproj index 962393704e..68122dc605 100644 --- a/Src/TE/DiffView/DiffView.csproj +++ b/Src/TE/DiffView/DiffView.csproj @@ -1,302 +1,305 @@ - + - Local - 9.0.30729 - 2.0 - {12D8342D-1E00-4B53-92DA-4CBB17B63590} - - - - Debug - AnyCPU - - - - - DiffView - - - JScript - Grid - IE50 - false - Library - SIL.FieldWorks.TE - OnBuildSuccess - - - - - - - - - 3.5 - v4.0 - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - + Local + 9.0.30729 + 2.0 + {12D8342D-1E00-4B53-92DA-4CBB17B63590} + + + + + + + Debug + AnyCPU + + + + + DiffView + + + JScript + Grid + IE50 + false + Library + SIL.FieldWorks.TE + OnBuildSuccess + + + + + + + + + 3.5 + v4.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + - ..\..\..\Output\Debug\ - false - 285212672 - false - - - DEBUG;TRACE - ..\..\..\Output\Debug\DiffView.xml - true - 4096 - false - 168,169,219,414,649,1635,1702,1701 - false - false - false - true - 4 - full - prompt - AllRules.ruleset - x86 + ..\..\..\Output\Debug\ + false + 285212672 + false + + + DEBUG;TRACE + ..\..\..\Output\Debug\DiffView.xml + true + 4096 + false + 168,169,219,414,649,1635,1702,1701 + false + false + false + true + 4 + full + prompt + AllRules.ruleset + x86 - ..\..\..\Output\Release\ - false - 285212672 - false - - - TRACE - - - true - 4096 - false - 168,169,219,414,649,1635,1702,1701 - true - false - false - false - 4 - full - prompt - AllRules.ruleset - x86 + ..\..\..\Output\Release\ + false + 285212672 + false + + + TRACE + + + true + 4096 + false + 168,169,219,414,649,1635,1702,1701 + true + false + false + false + 4 + full + prompt + AllRules.ruleset + x86 - - ..\..\..\Output\Debug\BasicUtils.dll - False - - - COMInterfaces - ..\..\..\Output\Debug\COMInterfaces.dll - - - False - ..\..\..\Output\Debug\CoreImpl.dll - - - FDO - ..\..\..\Output\Debug\FDO.dll - - - Framework - ..\..\..\Output\Debug\Framework.dll - - - FwControls - ..\..\..\Output\Debug\FwControls.dll - - - False - ..\..\..\Output\Debug\FwCoreDlgs.dll - - - FwResources - ..\..\..\Output\Debug\FwResources.dll - - - FwUtils - ..\..\..\Output\Debug\FwUtils.dll - - - False - ..\..\..\Output\Debug\ITextDll.dll - - - False - ..\..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll - - - ..\..\..\Output\Debug\PrintLayout.dll - False - - - RootSite - ..\..\..\Output\Debug\RootSite.dll - - - ScriptureUtils - ..\..\..\Output\Debug\ScriptureUtils.dll - - - ScrUtilsInterfaces - ..\..\..\Output\Debug\ScrUtilsInterfaces.dll - - - False - ..\..\..\Output\Debug\SharedScrUtils.dll - - - ..\..\..\Output\Debug\SilUtils.dll - False - - - SimpleRootSite - ..\..\..\Output\Debug\SimpleRootSite.dll - - - False - ..\..\..\Output\Debug\SplitGridView.dll - - - System - - - - System.Data - - - System.Drawing - - - System.Windows.Forms - - - System.XML - - - False - ..\..\..\Output\Debug\TeEditing.dll - - - TeResources - ..\..\..\Output\Debug\TeResources.dll - - - TeViewConstructors - ..\..\..\Output\Debug\TeViewConstructors.dll - - - UIAdapterInterfaces - ..\..\..\Output\Debug\UIAdapterInterfaces.dll - - - xCoreInterfaces - ..\..\..\Output\Debug\xCoreInterfaces.dll - + + ..\..\..\Output\Debug\BasicUtils.dll + False + + + COMInterfaces + ..\..\..\Output\Debug\COMInterfaces.dll + + + False + ..\..\..\Output\Debug\CoreImpl.dll + + + FDO + ..\..\..\Output\Debug\FDO.dll + + + Framework + ..\..\..\Output\Debug\Framework.dll + + + FwControls + ..\..\..\Output\Debug\FwControls.dll + + + False + ..\..\..\Output\Debug\FwCoreDlgs.dll + + + FwResources + ..\..\..\Output\Debug\FwResources.dll + + + FwUtils + ..\..\..\Output\Debug\FwUtils.dll + + + False + ..\..\..\Output\Debug\ITextDll.dll + + + False + ..\..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll + + + ..\..\..\Output\Debug\PrintLayout.dll + False + + + RootSite + ..\..\..\Output\Debug\RootSite.dll + + + ScriptureUtils + ..\..\..\Output\Debug\ScriptureUtils.dll + + + ScrUtilsInterfaces + ..\..\..\Output\Debug\ScrUtilsInterfaces.dll + + + False + ..\..\..\Output\Debug\SharedScrUtils.dll + + + ..\..\..\Output\Debug\SilUtils.dll + False + + + SimpleRootSite + ..\..\..\Output\Debug\SimpleRootSite.dll + + + False + ..\..\..\Output\Debug\SplitGridView.dll + + + System + + + + System.Data + + + System.Drawing + + + System.Windows.Forms + + + System.XML + + + False + ..\..\..\Output\Debug\TeEditing.dll + + + TeResources + ..\..\..\Output\Debug\TeResources.dll + + + TeViewConstructors + ..\..\..\Output\Debug\TeViewConstructors.dll + + + UIAdapterInterfaces + ..\..\..\Output\Debug\UIAdapterInterfaces.dll + + + xCoreInterfaces + ..\..\..\Output\Debug\xCoreInterfaces.dll + - - CommonAssemblyInfo.cs - - - Code - - - Code - - - - - - Form - - - Code - - - Code - - - UserControl - - - UserControl - - - - - Code - - - Component - - - - True - True - TeDiffViewResources.resx - - - Code - - - DiffDialog.cs - Designer - - - Difference.cs - Designer - - - DiffView.cs - Designer - - - Designer - ResXFileCodeGenerator - TeDiffViewResources.Designer.cs - + + CommonAssemblyInfo.cs + + + Code + + + Code + + + + + + Form + + + Code + + + Code + + + UserControl + + + UserControl + + + + + Code + + + Component + + + + True + True + TeDiffViewResources.resx + + + Code + + + DiffDialog.cs + Designer + + + Difference.cs + Designer + + + DiffView.cs + Designer + + + Designer + ResXFileCodeGenerator + TeDiffViewResources.Designer.cs + - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + - - - - + + + + \ No newline at end of file diff --git a/Src/TE/DiffView/DiffViewTests/BookMergerTestsBase.cs b/Src/TE/DiffView/DiffViewTests/BookMergerTestsBase.cs index a3e7ac3811..4a9fb045c7 100644 --- a/Src/TE/DiffView/DiffViewTests/BookMergerTestsBase.cs +++ b/Src/TE/DiffView/DiffViewTests/BookMergerTestsBase.cs @@ -18,6 +18,7 @@ using SIL.FieldWorks.Common.ScriptureUtils; using SIL.FieldWorks.Test.TestUtils; using SILUBS.SharedScrUtils; +using SIL.Utils; namespace SIL.FieldWorks.TE { diff --git a/Src/TE/DiffView/DiffViewTests/DiffDialogTests.cs b/Src/TE/DiffView/DiffViewTests/DiffDialogTests.cs index 4c92b91baf..266aba48f2 100644 --- a/Src/TE/DiffView/DiffViewTests/DiffDialogTests.cs +++ b/Src/TE/DiffView/DiffViewTests/DiffDialogTests.cs @@ -12,6 +12,7 @@ using SIL.FieldWorks.Common.RootSites; using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.FDOTests; +using SIL.FieldWorks.Resources; using SIL.FieldWorks.Test.TestUtils; using SIL.Utils; using SIL.FieldWorks.Common.ScriptureUtils; @@ -602,7 +603,7 @@ private void CompleteInitialize(bool fMakePhilemonChanges, IScrBook bookRev) } m_styleSheet = new FwStyleSheet(); - m_styleSheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles); + m_styleSheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); Debug.Assert(m_dlg == null, "m_dlg is not null."); //if (m_dlg != null) @@ -1599,7 +1600,7 @@ public override void TestSetup() m_bookMerger = new DummyBookMerger(Cache, null, m_philemonRev); m_styleSheet = new FwStyleSheet(); - m_styleSheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles); + m_styleSheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); Debug.Assert(m_dlg == null, "m_dlg is not null."); //if (m_dlg != null) diff --git a/Src/TE/DiffView/DiffViewTests/DiffViewTests.csproj b/Src/TE/DiffView/DiffViewTests/DiffViewTests.csproj index d180a33141..abeb98ff5c 100644 --- a/Src/TE/DiffView/DiffViewTests/DiffViewTests.csproj +++ b/Src/TE/DiffView/DiffViewTests/DiffViewTests.csproj @@ -137,6 +137,10 @@ FwControls ..\..\..\..\Output\Debug\FwControls.dll + + False + ..\..\..\..\Output\Debug\FwResources.dll + FwUtils ..\..\..\..\Output\Debug\FwUtils.dll diff --git a/Src/TE/NotesView/NotesMainWnd.cs b/Src/TE/NotesView/NotesMainWnd.cs index cd848ecb08..7596b40c78 100644 --- a/Src/TE/NotesView/NotesMainWnd.cs +++ b/Src/TE/NotesView/NotesMainWnd.cs @@ -9,8 +9,6 @@ // using System; -using System.Linq; -using System.ComponentModel; using System.Collections.Generic; using System.Diagnostics; using System.Windows.Forms; @@ -18,10 +16,8 @@ using SIL.FieldWorks.FDO; using SIL.FieldWorks.Common.Framework; using SIL.FieldWorks.Common.RootSites; -using SIL.FieldWorks.Common.ScriptureUtils; using SIL.FieldWorks.Common.UIAdapters; using SIL.FieldWorks.Common.COMInterfaces; -using SIL.FieldWorks.FDO.Infrastructure; using SILUBS.SharedScrUtils; using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FwCoreDlgControls; @@ -204,7 +200,7 @@ public void ScrollToScrEditingLocation(object sender, TeEditingHelper editingHel /// ------------------------------------------------------------------------------------ protected override string GetAppSpecificMenuToolBarDefinition() { - return DirectoryFinder.FWCodeDirectory + + return FwDirectoryFinder.CodeDirectory + @"/Translation Editor/Configuration/NotesTMDefinition.xml"; } diff --git a/Src/TE/TeDialogs/ArchiveMaintenanceDialog.cs b/Src/TE/TeDialogs/ArchiveMaintenanceDialog.cs index 7eb6a260d0..2e6cd158eb 100644 --- a/Src/TE/TeDialogs/ArchiveMaintenanceDialog.cs +++ b/Src/TE/TeDialogs/ArchiveMaintenanceDialog.cs @@ -431,7 +431,7 @@ private void m_btnDiff_Click(object sender, System.EventArgs e) using (BookMerger merger = new BookMerger(m_cache, m_styleSheet, bookRev)) { - using (ProgressDialogWithTask progress = new ProgressDialogWithTask(this, m_cache.ThreadHelper)) + using (ProgressDialogWithTask progress = new ProgressDialogWithTask(this)) { progress.Title = DlgResources.ResourceString("kstidCompareCaption"); progress.Message = string.Format( @@ -591,7 +591,7 @@ private void m_btnCopyToCurr_Click(object sender, EventArgs e) // Perform an automerge of the original book and the saved version. using (BookMerger merger = new BookMerger(m_cache, m_styleSheet, savedBook)) { - using (ProgressDialogWithTask progress = new ProgressDialogWithTask(this, m_cache.ThreadHelper)) + using (ProgressDialogWithTask progress = new ProgressDialogWithTask(this)) { progress.Title = DlgResources.ResourceString("kstidOverwriteCaption"); progress.RunTask(merger.DoPartialOverwrite, sectionsToRemove); diff --git a/Src/TE/TeDialogs/ImportedBooks.cs b/Src/TE/TeDialogs/ImportedBooks.cs index fda9158980..bda52534c4 100644 --- a/Src/TE/TeDialogs/ImportedBooks.cs +++ b/Src/TE/TeDialogs/ImportedBooks.cs @@ -422,7 +422,7 @@ public void ShowOrSave(IWin32Window wnd, bool fAutoAcceptChanges) continue; } - using (ProgressDialogWithTask progressDlg = new ProgressDialogWithTask(m_owningForm, m_cache.ThreadHelper)) + using (ProgressDialogWithTask progressDlg = new ProgressDialogWithTask(m_owningForm)) { bookMerger.AttemptAutoMerge = true; bookMerger.BookVersionAgent = this; @@ -1057,7 +1057,7 @@ protected virtual void PartialOverwrite(BookMerger bookMerger, List sectionsToRemove) { Logger.WriteEvent("Performing partial Overwrite of book: " + bookMerger.BookCurr.BookId); - using (ProgressDialogWithTask progress = new ProgressDialogWithTask(this, m_cache.ThreadHelper)) + using (ProgressDialogWithTask progress = new ProgressDialogWithTask(this)) { progress.Title = DlgResources.ResourceString("kstidOverwriteCaption"); progress.RunTask(bookMerger.DoPartialOverwrite, sectionsToRemove); diff --git a/Src/TE/TeDialogs/ScriptureProperties.cs b/Src/TE/TeDialogs/ScriptureProperties.cs index 893a5b260e..a9dbc0770c 100644 --- a/Src/TE/TeDialogs/ScriptureProperties.cs +++ b/Src/TE/TeDialogs/ScriptureProperties.cs @@ -804,7 +804,7 @@ private void UpdateFootnoteTabs() protected void ConvertChapterVerseNumbers() { // Show a progress dialog for this operation - using (ProgressDialogWithTask progressDlg = new ProgressDialogWithTask(this, m_cache.ThreadHelper)) + using (ProgressDialogWithTask progressDlg = new ProgressDialogWithTask(this)) { progressDlg.Minimum = 0; progressDlg.Maximum = m_scr.ScriptureBooksOS.Count; @@ -903,7 +903,7 @@ protected virtual bool ConvertChapterVerseNumbers(IScrTxtPara para, char zeroDig private void UpdateVerseBridges(string oldBridge) { // Show a progress dialog for this operation - using (ProgressDialogWithTask progressDlg = new ProgressDialogWithTask(this, m_cache.ThreadHelper)) + using (ProgressDialogWithTask progressDlg = new ProgressDialogWithTask(this)) { progressDlg.Minimum = 0; progressDlg.Maximum = m_scr.ScriptureBooksOS.Count; diff --git a/Src/TE/TeDialogs/TeDialogsTests/BookPropertiesTests.cs b/Src/TE/TeDialogs/TeDialogsTests/BookPropertiesTests.cs index 06a72dae46..540938315b 100644 --- a/Src/TE/TeDialogs/TeDialogsTests/BookPropertiesTests.cs +++ b/Src/TE/TeDialogs/TeDialogsTests/BookPropertiesTests.cs @@ -19,6 +19,7 @@ using SIL.FieldWorks.FDO.FDOTests; using SIL.FieldWorks.Common.RootSites; using SIL.FieldWorks.FDO.DomainServices; +using SIL.FieldWorks.Resources; namespace SIL.FieldWorks.TE { @@ -99,7 +100,7 @@ protected override void CreateTestData() AddSectionHeadParaToSection(section, "Section Heading", ScrStyleNames.SectionHead); m_stylesheet = new FwStyleSheet(); - m_stylesheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles); + m_stylesheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); } #endregion diff --git a/Src/TE/TeDialogs/TeDialogsTests/ScripturePropertiesTests.cs b/Src/TE/TeDialogs/TeDialogsTests/ScripturePropertiesTests.cs index 93890f04b5..50e38aaf75 100644 --- a/Src/TE/TeDialogs/TeDialogsTests/ScripturePropertiesTests.cs +++ b/Src/TE/TeDialogs/TeDialogsTests/ScripturePropertiesTests.cs @@ -13,6 +13,7 @@ using SIL.FieldWorks.Common.COMInterfaces; using SIL.FieldWorks.Common.ScriptureUtils; using SIL.FieldWorks.FDO.FDOTests; +using SIL.FieldWorks.Resources; using SIL.Utils; using SIL.FieldWorks.FDO.DomainServices; using SIL.FieldWorks.Test.TestUtils; @@ -43,7 +44,7 @@ public class ScripturePropertiesTests : ScrInMemoryFdoTestBase protected override void CreateTestData() { m_stylesheet = new FwStyleSheet(); - m_stylesheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles); + m_stylesheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); m_exodus = AddBookToMockedScripture(2, "Exodus"); AddTitleToMockedBook(m_exodus, "Exodus"); diff --git a/Src/TE/TeDialogs/TeDialogsTests/TeDialogsTests.csproj b/Src/TE/TeDialogs/TeDialogsTests/TeDialogsTests.csproj index 0dcd90cf25..059fe8fee0 100644 --- a/Src/TE/TeDialogs/TeDialogsTests/TeDialogsTests.csproj +++ b/Src/TE/TeDialogs/TeDialogsTests/TeDialogsTests.csproj @@ -1,4 +1,4 @@ - + Local @@ -120,6 +120,10 @@ False ..\..\..\..\Output\Debug\DiffView.dll + + False + ..\..\..\..\Output\Debug\FwResources.dll + False ..\..\..\..\Output\Debug\FwUtils.dll @@ -206,13 +210,21 @@ SetupFixtureClass.cs - - - + + Form + + + Form + + + Form + - + + Form + @@ -233,8 +245,7 @@ - ../../../../DistFiles - + \ No newline at end of file diff --git a/Src/TE/TeDialogs/TeDialogsTests/ToolsOptionsDialogTests.cs b/Src/TE/TeDialogs/TeDialogsTests/ToolsOptionsDialogTests.cs index e4f6292d7a..c519ec09bb 100644 --- a/Src/TE/TeDialogs/TeDialogsTests/ToolsOptionsDialogTests.cs +++ b/Src/TE/TeDialogs/TeDialogsTests/ToolsOptionsDialogTests.cs @@ -13,6 +13,7 @@ using SIL.FieldWorks.Common.RootSites; using NUnit.Framework; using SIL.FieldWorks.Test.TestUtils; +using SIL.Utils; using XCore; using SIL.CoreImpl; using System.Collections.Generic; @@ -99,7 +100,7 @@ public override string ApplicationName /// The progress dialog. /// True if the initialization was successful, false otherwise /// ------------------------------------------------------------------------------------ - public override bool InitCacheForApp(IProgress progressDlg) + public override bool InitCacheForApp(IThreadedProgress progressDlg) { throw new NotImplementedException(); } diff --git a/Src/TE/TeEditing/TeEditingTests/TeEditingHelper_NavigationTests.cs b/Src/TE/TeEditing/TeEditingTests/TeEditingHelper_NavigationTests.cs index 3327a69fe2..ca24641eb8 100644 --- a/Src/TE/TeEditing/TeEditingTests/TeEditingHelper_NavigationTests.cs +++ b/Src/TE/TeEditing/TeEditingTests/TeEditingHelper_NavigationTests.cs @@ -14,6 +14,7 @@ using SIL.FieldWorks.FDO; using SIL.FieldWorks.FDO.FDOTests; using SIL.FieldWorks.FDO.DomainServices; +using SIL.FieldWorks.Resources; using SILUBS.SharedScrUtils; namespace SIL.FieldWorks.TE.TeEditingHelpers @@ -134,7 +135,7 @@ public override void TestSetup() base.TestSetup(); FwStyleSheet styleSheet = new FwStyleSheet(); - styleSheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles); + styleSheet.Init(Cache, m_scr.Hvo, ScriptureTags.kflidStyles, ResourceHelper.DefaultParaCharsStyleName); Debug.Assert(m_draftView == null); m_draftView = new TeDummyBasicView(); diff --git a/Src/TE/TeEditing/TeEditingTests/TeEditingTests.csproj b/Src/TE/TeEditing/TeEditingTests/TeEditingTests.csproj index d78ecb8c4f..53f64d7d42 100644 --- a/Src/TE/TeEditing/TeEditingTests/TeEditingTests.csproj +++ b/Src/TE/TeEditing/TeEditingTests/TeEditingTests.csproj @@ -128,6 +128,10 @@ Framework ..\..\..\..\Output\Debug\Framework.dll + + False + ..\..\..\..\Output\Debug\FwResources.dll + FwUtils ..\..\..\..\Output\Debug\FwUtils.dll @@ -252,4 +256,4 @@ - + \ No newline at end of file diff --git a/Src/TE/TeEditorialChecks/EditorialChecksControl.cs b/Src/TE/TeEditorialChecks/EditorialChecksControl.cs index 2b85d04a55..f89ec8fff8 100644 --- a/Src/TE/TeEditorialChecks/EditorialChecksControl.cs +++ b/Src/TE/TeEditorialChecks/EditorialChecksControl.cs @@ -119,7 +119,7 @@ public EditorialChecksControl(FdoCache cache, IApp app, FilteredScrBooks bookFil pnlButtons.ClientSizeChanged += pnlButtons_ClientSizeChanged; m_cache = cache; - m_chkDataSource = new ScrChecksDataSource(cache, DirectoryFinder.TeStylesPath); + m_chkDataSource = new ScrChecksDataSource(cache, FwDirectoryFinder.TeStylesPath, FwDirectoryFinder.LegacyWordformingCharOverridesFile); m_bookFilter = bookFilter; m_bookFilter.FilterChanged += OnBookFilterChanged; @@ -1118,7 +1118,7 @@ private bool IsValidCharIncomplete { get { - ValidCharacters valChars = ValidCharacters.Load(CurrVernWritingSystem, ReportLoadException); + ValidCharacters valChars = ValidCharacters.Load(CurrVernWritingSystem, ReportLoadException, FwDirectoryFinder.LegacyWordformingCharOverridesFile); return valChars.WordformingLetterCount <= 3; } } diff --git a/Src/TE/TeEditorialChecks/EditorialChecksRenderingsControl.cs b/Src/TE/TeEditorialChecks/EditorialChecksRenderingsControl.cs index 73b0b49d47..0be6325b4a 100644 --- a/Src/TE/TeEditorialChecks/EditorialChecksRenderingsControl.cs +++ b/Src/TE/TeEditorialChecks/EditorialChecksRenderingsControl.cs @@ -600,7 +600,7 @@ private void AddAsValidCharacter(CheckingError addedCharError) using (new WaitCursor(Parent)) { // Get the valid characters from the database - ValidCharacters validChars = ValidCharacters.Load(ws, ValidCharsLoadException); + ValidCharacters validChars = ValidCharacters.Load(ws, ValidCharsLoadException, FwDirectoryFinder.LegacyWordformingCharOverridesFile); if (validChars != null) { validChars.AddCharacter(addedCharError.MyNote.CitedText); @@ -822,7 +822,7 @@ protected bool OnUpdateScrChecksAddAsValidCharacter(object args) private List GetValidCharacters() { IWritingSystem ws = m_cache.ServiceLocator.WritingSystems.DefaultVernacularWritingSystem; - ValidCharacters validChars = ValidCharacters.Load(ws, ValidCharsLoadException); + ValidCharacters validChars = ValidCharacters.Load(ws, ValidCharsLoadException, FwDirectoryFinder.LegacyWordformingCharOverridesFile); return (validChars != null ? validChars.AllCharacters : null); } diff --git a/Src/TE/TeEditorialChecks/InstalledScriptureChecks.cs b/Src/TE/TeEditorialChecks/InstalledScriptureChecks.cs index 0278f3f772..bfe1cb0638 100644 --- a/Src/TE/TeEditorialChecks/InstalledScriptureChecks.cs +++ b/Src/TE/TeEditorialChecks/InstalledScriptureChecks.cs @@ -145,7 +145,7 @@ private static void LoadAvailableChecks() s_scrCheckList = new List(); - string directory = DirectoryFinder.EditorialChecksDirectory; + string directory = FwDirectoryFinder.EditorialChecksDirectory; string[] dllFilenames = Directory.GetFiles(directory, "*.dll"); foreach (string dllFile in dllFilenames) diff --git a/Src/TE/TeEditorialChecks/TeEditorialChecks.csproj b/Src/TE/TeEditorialChecks/TeEditorialChecks.csproj index c3a1bdf99f..891ced7699 100644 --- a/Src/TE/TeEditorialChecks/TeEditorialChecks.csproj +++ b/Src/TE/TeEditorialChecks/TeEditorialChecks.csproj @@ -1,270 +1,270 @@  - Debug - AnyCPU - 9.0.30729 - 2.0 - {1FFFA01D-90D3-43C4-B3E4-B0D4EA9AF104} - Library - Properties - SIL.FieldWorks.TE.TeEditorialChecks - TeEditorialChecks - - - 3.5 - - - false - v4.0 - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - true - + Debug + AnyCPU + 9.0.30729 + 2.0 + {1FFFA01D-90D3-43C4-B3E4-B0D4EA9AF104} + Library + Properties + SIL.FieldWorks.TE.TeEditorialChecks + TeEditorialChecks + + + 3.5 + + + false + v4.0 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + - true - full - false - 168,169,219,414,649,1635,1702,1701 - ..\..\..\Output\Debug\ - DEBUG;TRACE - ..\..\..\Output\Debug\TeEditorialChecks.xml - prompt - 4 - x86 - AllRules.ruleset - x86 + true + full + false + 168,169,219,414,649,1635,1702,1701 + ..\..\..\Output\Debug\ + DEBUG;TRACE + ..\..\..\Output\Debug\TeEditorialChecks.xml + prompt + 4 + x86 + AllRules.ruleset + x86 - pdbonly - true - 168,169,219,414,649,1635,1702,1701 - ..\..\..\Output\Release\ - TRACE - prompt - true - 4 - AllRules.ruleset - x86 + pdbonly + true + 168,169,219,414,649,1635,1702,1701 + ..\..\..\Output\Release\ + TRACE + prompt + true + 4 + AllRules.ruleset + x86 - - False - ..\..\..\Output\Debug\BasicUtils.dll - - - False - ..\..\..\Output\Debug\COMInterfaces.dll - - - False - ..\..\..\Output\Debug\CoreImpl.dll - - - False - ..\..\..\Output\Debug\FDO.dll - - - False - ..\..\..\Output\Debug\Framework.dll - - - False - ..\..\..\Output\Debug\FwControls.dll - - - False - ..\..\..\Output\Debug\FwCoreDlgs.dll - - - False - ..\..\..\Output\Debug\FwResources.dll - - - False - ..\..\..\Output\Debug\FwUtils.dll - - - False - ..\..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll - - - False - ..\..\..\Output\Debug\Reporting.dll - - - False - ..\..\..\Output\Debug\RootSite.dll - - - False - ..\..\..\Output\Debug\ScriptureUtils.dll - - - False - ..\..\..\Output\Debug\ScrUtilsInterfaces.dll - - - False - ..\..\..\Output\Debug\SharedScrUtils.dll - - - ..\..\..\Output\Debug\SilUtils.dll - False - - - False - ..\..\..\Output\Debug\SimpleRootSite.dll - - - False - ..\..\..\Output\Debug\SplitGridView.dll - - - - - - - - - False - ..\..\..\Output\Debug\TeEditing.dll - - - False - ..\..\..\Output\Debug\TeRegistrySettings.dll - - - False - ..\..\..\Output\Debug\TeResources.dll - - - False - ..\..\..\Output\Debug\UIAdapterInterfaces.dll - - - False - ..\..\..\Output\Debug\Widgets.dll - - - False - ..\..\..\Output\Debug\xCoreInterfaces.dll - + + False + ..\..\..\Output\Debug\BasicUtils.dll + + + False + ..\..\..\Output\Debug\COMInterfaces.dll + + + False + ..\..\..\Output\Debug\CoreImpl.dll + + + False + ..\..\..\Output\Debug\FDO.dll + + + False + ..\..\..\Output\Debug\Framework.dll + + + False + ..\..\..\Output\Debug\FwControls.dll + + + False + ..\..\..\Output\Debug\FwCoreDlgs.dll + + + False + ..\..\..\Output\Debug\FwResources.dll + + + False + ..\..\..\Output\Debug\FwUtils.dll + + + False + ..\..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll + + + False + ..\..\..\Output\Debug\Reporting.dll + + + False + ..\..\..\Output\Debug\RootSite.dll + + + False + ..\..\..\Output\Debug\ScriptureUtils.dll + + + False + ..\..\..\Output\Debug\ScrUtilsInterfaces.dll + + + False + ..\..\..\Output\Debug\SharedScrUtils.dll + + + ..\..\..\Output\Debug\SilUtils.dll + False + + + False + ..\..\..\Output\Debug\SimpleRootSite.dll + + + False + ..\..\..\Output\Debug\SplitGridView.dll + + + + + + + + + False + ..\..\..\Output\Debug\TeEditing.dll + + + False + ..\..\..\Output\Debug\TeRegistrySettings.dll + + + False + ..\..\..\Output\Debug\TeResources.dll + + + False + ..\..\..\Output\Debug\UIAdapterInterfaces.dll + + + False + ..\..\..\Output\Debug\Widgets.dll + + + False + ..\..\..\Output\Debug\xCoreInterfaces.dll + - - Properties\CommonAssemblyInfo.cs - - - - UserControl - - - CheckControl.cs - - - Component - - - - - Form - - - CheckingErrorCommentDlg.cs - - - UserControl - - - UserControl - - - UserControl - - - UserControl - - - EditorialChecksControl.cs - - - UserControl - - - EditorialChecksRenderingsControl.cs - - - UserControl - - - - - - + + Properties\CommonAssemblyInfo.cs + + + + UserControl + + + CheckControl.cs + + + Component + + + + + Form + + + CheckingErrorCommentDlg.cs + + + UserControl + + + UserControl + + + UserControl + + + UserControl + + + EditorialChecksControl.cs + + + UserControl + + + EditorialChecksRenderingsControl.cs + + + UserControl + + + + + + - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - - - false - - - False - - - false - - - False - - - false - - - False - .NET Framework 3.5 SP1 - false - + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + + + false + + + False + + + false + + + False + + + false + + + False + .NET Framework 3.5 SP1 + false + - - CheckControl.cs - Designer - - - CheckingErrorCommentDlg.cs - Designer - - - EditorialChecksControl.cs - Designer - - - EditorialChecksRenderingsControl.cs - Designer - + + CheckControl.cs + Designer + + + CheckingErrorCommentDlg.cs + Designer + + + EditorialChecksControl.cs + Designer + + + EditorialChecksRenderingsControl.cs + Designer + - + 1.0 - - - - - - - - - - - + + msxsl xml 1.0 @@ -1346,16 +1334,16 @@ Ignore text template loop through the features of both feature structures at same time, sorted by name - + get name of this feature get this feature if it's in the first feature structure - + get this feature if it's in the second feature structure - + both feature1 and feature2 have this feature name @@ -1436,14 +1424,14 @@ Ignore text template - + Empty and - + Empty @@ -1452,16 +1440,16 @@ Ignore text template loop through the features of both feature structures at same time, sorted by name - + get name of this feature get this feature if it's in the first feature structure - + get this feature if it's in the second feature structure - + both feature1 and feature2 have this feature name @@ -1594,7 +1582,7 @@ Ignore text template - + @@ -1642,7 +1630,7 @@ Ignore text template - + @@ -1812,8 +1800,8 @@ Ignore text template - - + + @@ -1844,7 +1832,7 @@ Ignore text template . The inflected features for this word are: - + @@ -2762,15 +2750,15 @@ Ignore text template - - + + - - + + @@ -2801,7 +2789,7 @@ Ignore text template . The inflected features for this are: - + @@ -2832,7 +2820,7 @@ Ignore text template . The inflected features for this are: - + @@ -2868,18 +2856,18 @@ Ignore text template - + Override those unified features with deriv to features - + - + @@ -3842,7 +3830,7 @@ OutputElsewhereChecksForStemNamesUsedInLexicalEntries . The inflected features for this word are: - + @@ -4025,8 +4013,8 @@ OutputMultipleStemNameRegionsSubsumptionChecks - - + + @@ -4349,9 +4337,9 @@ ProcessInflectionalTemplatePercolationAndConstraints - - - + + + @@ -4375,7 +4363,7 @@ ProcessInflectionalTemplatePercolationAndConstraints - + @@ -4402,7 +4390,7 @@ ProcessInflectionalTemplatePercolationAndConstraints - + @@ -4417,11 +4405,11 @@ ProcessInflectionalTemplatePercolationAndConstraints - + - + diff --git a/DistFiles/Language Explorer/Transforms/MorphTypeGuids.xsl b/Src/Transforms/Application/MorphTypeGuids.xsl similarity index 100% rename from DistFiles/Language Explorer/Transforms/MorphTypeGuids.xsl rename to Src/Transforms/Application/MorphTypeGuids.xsl diff --git a/DistFiles/Language Explorer/Transforms/UnifyTwoFeatureStructures.xsl b/Src/Transforms/Application/UnifyTwoFeatureStructures.xsl similarity index 100% rename from DistFiles/Language Explorer/Transforms/UnifyTwoFeatureStructures.xsl rename to Src/Transforms/Application/UnifyTwoFeatureStructures.xsl diff --git a/DistFiles/Language Explorer/Transforms/XAmpleTemplateVariables.xsl b/Src/Transforms/Application/XAmpleTemplateVariables.xsl similarity index 100% rename from DistFiles/Language Explorer/Transforms/XAmpleTemplateVariables.xsl rename to Src/Transforms/Application/XAmpleTemplateVariables.xsl diff --git a/DistFiles/Language Explorer/Configuration/Words/Analyses/TraceParse/FormatCommon.xsl b/Src/Transforms/Presentation/FormatCommon.xsl similarity index 100% rename from DistFiles/Language Explorer/Configuration/Words/Analyses/TraceParse/FormatCommon.xsl rename to Src/Transforms/Presentation/FormatCommon.xsl diff --git a/DistFiles/Language Explorer/Configuration/Words/Analyses/TraceParse/FormatHCTrace.xsl b/Src/Transforms/Presentation/FormatHCTrace.xsl similarity index 100% rename from DistFiles/Language Explorer/Configuration/Words/Analyses/TraceParse/FormatHCTrace.xsl rename to Src/Transforms/Presentation/FormatHCTrace.xsl diff --git a/DistFiles/Language Explorer/Configuration/Words/Analyses/TraceParse/FormatXAmpleParse.xsl b/Src/Transforms/Presentation/FormatXAmpleParse.xsl similarity index 100% rename from DistFiles/Language Explorer/Configuration/Words/Analyses/TraceParse/FormatXAmpleParse.xsl rename to Src/Transforms/Presentation/FormatXAmpleParse.xsl diff --git a/DistFiles/Language Explorer/Configuration/Words/Analyses/TraceParse/FormatXAmpleTrace.xsl b/Src/Transforms/Presentation/FormatXAmpleTrace.xsl similarity index 100% rename from DistFiles/Language Explorer/Configuration/Words/Analyses/TraceParse/FormatXAmpleTrace.xsl rename to Src/Transforms/Presentation/FormatXAmpleTrace.xsl diff --git a/DistFiles/Language Explorer/Configuration/Words/Analyses/TraceParse/FormatXAmpleWordGrammarDebuggerResult.xsl b/Src/Transforms/Presentation/FormatXAmpleWordGrammarDebuggerResult.xsl similarity index 100% rename from DistFiles/Language Explorer/Configuration/Words/Analyses/TraceParse/FormatXAmpleWordGrammarDebuggerResult.xsl rename to Src/Transforms/Presentation/FormatXAmpleWordGrammarDebuggerResult.xsl diff --git a/DistFiles/Language Explorer/Transforms/XLingPap1.xsl b/Src/Transforms/Presentation/XLingPap1.xsl similarity index 100% rename from DistFiles/Language Explorer/Transforms/XLingPap1.xsl rename to Src/Transforms/Presentation/XLingPap1.xsl diff --git a/Src/UnicodeCharEditor/CharEditorWindow.cs b/Src/UnicodeCharEditor/CharEditorWindow.cs index a90064faa3..f00417fcc0 100644 --- a/Src/UnicodeCharEditor/CharEditorWindow.cs +++ b/Src/UnicodeCharEditor/CharEditorWindow.cs @@ -514,7 +514,7 @@ public string GetHelpString(string sPropName) /// public string HelpFile { - get { return Path.Combine(DirectoryFinder.FWCodeDirectory, GetHelpString("UserHelpFile")); } + get { return Path.Combine(FwDirectoryFinder.CodeDirectory, GetHelpString("UserHelpFile")); } } #endregion diff --git a/Src/UnicodeCharEditor/UnicodeCharEditorTests/PUAInstallerTests.cs b/Src/UnicodeCharEditor/UnicodeCharEditorTests/PUAInstallerTests.cs index af64be694a..0a94a99f43 100644 --- a/Src/UnicodeCharEditor/UnicodeCharEditorTests/PUAInstallerTests.cs +++ b/Src/UnicodeCharEditor/UnicodeCharEditorTests/PUAInstallerTests.cs @@ -49,7 +49,6 @@ public void Setup() { RegistryHelper.CompanyName = "SIL"; RegistryHelper.ProductName = "FieldWorks"; - DirectoryFinder.CompanyName = "SIL"; Assert.IsTrue(InitializeIcuData()); m_sCustomCharsFile = Path.Combine(Icu.DefaultDirectory, "CustomChars.xml"); @@ -306,7 +305,7 @@ private static bool InitializeIcuData() { try { - var baseDir = DirectoryFinder.FWDataDirectory; + var baseDir = FwDirectoryFinder.DataDirectory; zipIn = new ZipInputStream(File.OpenRead(Path.Combine(baseDir, "Icu50.zip"))); } catch (Exception e1) diff --git a/Src/Utilities/BasicUtils/ActivationContextHelper.cs b/Src/Utilities/BasicUtils/ActivationContextHelper.cs new file mode 100644 index 0000000000..5643f953d6 --- /dev/null +++ b/Src/Utilities/BasicUtils/ActivationContextHelper.cs @@ -0,0 +1,122 @@ +using System; +using System.ComponentModel; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Security; + +namespace SIL.Utils +{ + /// + /// Used to create an activation context + /// + [SuppressUnmanagedCodeSecurity] + public class ActivationContextHelper : FwDisposableBase + { +#if !__MonoCS__ + #region Unmanaged structs and methods + [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)] + private struct ActCtx + { + public int cbSize; + public uint dwFlags; + public string lpSource; + public ushort wProcessorArchitecture; + public short wLangId; + public string lpAssemblyDirectory; + public string lpResourceName; + public string lpApplicationName; + public IntPtr hModule; + } + + [DllImport("Kernel32.dll", SetLastError = true, EntryPoint = "CreateActCtxW")] + private static extern IntPtr CreateActCtx(ref ActCtx actCtx); + + [DllImport("Kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool ActivateActCtx(IntPtr hActCtx, out IntPtr lpCookie); + + [DllImport("Kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool DeactivateActCtx(int dwFlags, IntPtr lpCookie); + + [DllImport("Kernel32.dll", SetLastError = true)] + private static extern void ReleaseActCtx(IntPtr hActCtx); + #endregion // Unmanaged structs and methods + + private IntPtr m_activationContext; +#endif + + /// + /// Initializes a new instance of the class. + /// + /// The manifest file. + public ActivationContextHelper(string manifestFile) + { +#if !__MonoCS__ + // Specifying a full path to the manifest file like this allows our unit tests to work even with a + // test runner like Resharper 8 which does not set the current directory to the one containing the DLLs. + // Note that we have to use CodeBase here because NUnit runs the tests from a shadow copy directory + // that doesn't contain the manifest file. + var uri = new Uri(Assembly.GetExecutingAssembly().CodeBase); + string location = Path.GetDirectoryName(uri.AbsolutePath); + var context = new ActCtx + { + cbSize = Marshal.SizeOf(typeof(ActCtx)), + lpSource = Path.Combine(location, manifestFile) + }; + + IntPtr handle = CreateActCtx(ref context); + if (handle == (IntPtr)(-1)) + throw new Win32Exception(Marshal.GetLastWin32Error(), "Error creating activation context"); + m_activationContext = handle; +#endif + } + + /// + /// Override to dispose unmanaged resources. + /// + protected override void DisposeUnmanagedResources() + { +#if !__MonoCS__ + // dispose managed and unmanaged objects + if (m_activationContext != IntPtr.Zero) + ReleaseActCtx(m_activationContext); + m_activationContext = IntPtr.Zero; +#endif + } + + /// + /// Activates this instance. + /// + /// Error activating context + public IDisposable Activate() + { + IntPtr cookie; +#if !__MonoCS__ + if (!ActivateActCtx(m_activationContext, out cookie)) + throw new Win32Exception(Marshal.GetLastWin32Error(), "Error activating context"); +#endif + return new Activation(cookie); + } + + private class Activation : FwDisposableBase + { + private IntPtr m_cookie; + + public Activation(IntPtr cookie) + { + m_cookie = cookie; + } + + protected override void DisposeUnmanagedResources() + { +#if !__MonoCS__ + if (m_cookie != IntPtr.Zero) + DeactivateActCtx(0, m_cookie); + m_cookie = IntPtr.Zero; +#endif + } + } + } +} diff --git a/Src/Utilities/BasicUtils/BasicUtils.csproj b/Src/Utilities/BasicUtils/BasicUtils.csproj index 0c72340599..825d395115 100644 --- a/Src/Utilities/BasicUtils/BasicUtils.csproj +++ b/Src/Utilities/BasicUtils/BasicUtils.csproj @@ -62,6 +62,10 @@ + + False + ..\..\..\DistFiles\Microsoft.Practices.ServiceLocation.dll + False ..\..\..\Output\Debug\SilUtils.dll @@ -80,7 +84,10 @@ Properties\CommonAssemblyInfo.cs - + + + + @@ -101,7 +108,10 @@ + + + @@ -116,9 +126,6 @@ - - Form - @@ -136,6 +143,7 @@ + @@ -150,10 +158,6 @@ ColorStrings.Designer.cs Designer - - FindFileStatusDialog.cs - Designer - Designer @@ -186,4 +190,4 @@ - + \ No newline at end of file diff --git a/Src/Utilities/BasicUtils/BasicUtilsTests/Attributes/CreateComObjectsFromManifestAttribute.cs b/Src/Utilities/BasicUtils/BasicUtilsTests/Attributes/CreateComObjectsFromManifestAttribute.cs index b96e4dc74f..e78a6cbdd7 100644 --- a/Src/Utilities/BasicUtils/BasicUtilsTests/Attributes/CreateComObjectsFromManifestAttribute.cs +++ b/Src/Utilities/BasicUtils/BasicUtilsTests/Attributes/CreateComObjectsFromManifestAttribute.cs @@ -3,6 +3,7 @@ // (http://www.gnu.org/licenses/lgpl-2.1.html) using System; +using System.Diagnostics.CodeAnalysis; using System.Security; using NUnit.Framework; @@ -16,8 +17,15 @@ namespace SIL.Utils.Attributes [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Interface)] [SuppressUnmanagedCodeSecurity] + [SuppressMessage("Gendarme.Rules.Design", "TypesWithDisposableFieldsShouldBeDisposableRule", + Justification="m_activationContext and m_currentActivation are disposed in AfterTest method")] public class CreateComObjectsFromManifestAttribute : TestActionAttribute { +#if !__MonoCS__ + private ActivationContextHelper m_activationContext; + private IDisposable m_currentActivation; +#endif + /// public override ActionTargets Targets { @@ -30,7 +38,8 @@ public override void BeforeTest(TestDetails testDetails) base.BeforeTest(testDetails); #if !__MonoCS__ - ManifestHelper.CreateActivationContext(); + m_activationContext = new ActivationContextHelper("FieldWorks.Tests.manifest"); + m_currentActivation = m_activationContext.Activate(); #endif } @@ -38,7 +47,8 @@ public override void BeforeTest(TestDetails testDetails) public override void AfterTest(TestDetails testDetails) { #if !__MonoCS__ - ManifestHelper.DestroyActivationContext(); + m_currentActivation.Dispose(); + m_activationContext.Dispose(); #endif base.AfterTest(testDetails); diff --git a/Src/Utilities/BasicUtils/FindFileStatusDialog.cs b/Src/Utilities/BasicUtils/FindFileStatusDialog.cs deleted file mode 100644 index 980940f838..0000000000 --- a/Src/Utilities/BasicUtils/FindFileStatusDialog.cs +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (c) 2002-2013 SIL International -// This software is licensed under the LGPL, version 2.1 or later -// (http://www.gnu.org/licenses/lgpl-2.1.html) -// -// File: FindFileStatusDialog.cs -// Responsibility: DavidO -// -------------------------------------------------------------------------------------------- -using System.Windows.Forms; - -namespace SIL.Utils -{ - /// --------------------------------------------------------------------------------------- - /// - /// FindFileStatusDialog provides a dialog box for the FindFile method in DriveUtil. - /// It provides the caller of FindFile the means to display the current path being - /// searched during a file (or file pattern) search operation. It also provides a - /// means via the 'Cancel' button, for the end user to abort the search operation. - /// - /// --------------------------------------------------------------------------------------- - public class FindFileStatusDialog : System.Windows.Forms.Form - { - private System.Windows.Forms.Label lblSearching; - private System.Windows.Forms.Label lblCurrentFolder; - private System.Windows.Forms.Button btnCancel; - /// - /// Required designer variable. - /// - private System.ComponentModel.Container components = null; - - /// ----------------------------------------------------------------------------------- - /// - /// Constructor. - /// - /// ----------------------------------------------------------------------------------- - public FindFileStatusDialog() - { - // - // Required for Windows Form Designer support - // - InitializeComponent(); - - } - - /// ----------------------------------------------------------------------------------- - /// - /// Clean up any resources being used. - /// - /// ----------------------------------------------------------------------------------- - protected override void Dispose( bool disposing ) - { - System.Diagnostics.Debug.WriteLineIf(!disposing, "****** Missing Dispose() call for " + GetType().Name + ". ****** "); - // Must not be run more than once. - if (IsDisposed) - return; - - if( disposing ) - { - if(components != null) - { - components.Dispose(); - } - } - base.Dispose( disposing ); - } - - #region Windows Form Designer generated code - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FindFileStatusDialog)); - this.lblSearching = new System.Windows.Forms.Label(); - this.lblCurrentFolder = new System.Windows.Forms.Label(); - this.btnCancel = new System.Windows.Forms.Button(); - this.SuspendLayout(); - // - // lblSearching - // - resources.ApplyResources(this.lblSearching, "lblSearching"); - this.lblSearching.FlatStyle = System.Windows.Forms.FlatStyle.System; - this.lblSearching.Name = "lblSearching"; - // - // lblCurrentFolder - // - this.lblCurrentFolder.FlatStyle = System.Windows.Forms.FlatStyle.System; - resources.ApplyResources(this.lblCurrentFolder, "lblCurrentFolder"); - this.lblCurrentFolder.Name = "lblCurrentFolder"; - // - // btnCancel - // - this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - resources.ApplyResources(this.btnCancel, "btnCancel"); - this.btnCancel.Name = "btnCancel"; - this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); - // - // FindFileStatusDialog - // - resources.ApplyResources(this, "$this"); - this.CancelButton = this.btnCancel; - this.Controls.Add(this.btnCancel); - this.Controls.Add(this.lblSearching); - this.Controls.Add(this.lblCurrentFolder); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "FindFileStatusDialog"; - this.ShowInTaskbar = false; - this.ResumeLayout(false); - this.PerformLayout(); - - } - #endregion - - /// ----------------------------------------------------------------------------------- - /// - /// Handles the Cancel button's click event. - /// - /// ----------------------------------------------------------------------------------- - private void btnCancel_Click(object sender, System.EventArgs e) - { - this.DialogResult = DialogResult.Cancel; - this.Close(); - } - - /// ----------------------------------------------------------------------------------- - /// - /// Gets or sets the file name and it's path that's displayed in the dialog. - /// - /// - /// ----------------------------------------------------------------------------------- - public string FullFileName - { - get {return lblCurrentFolder.Text;} - set - { - if (lblCurrentFolder.Text != value) - lblCurrentFolder.Text = value; - } - } - } -} diff --git a/Src/Utilities/BasicUtils/FindFileStatusDialog.resx b/Src/Utilities/BasicUtils/FindFileStatusDialog.resx deleted file mode 100644 index d917d56661..0000000000 --- a/Src/Utilities/BasicUtils/FindFileStatusDialog.resx +++ /dev/null @@ -1,234 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - NoControl - - - - 16, 16 - - - 90, 13 - - - 0 - - - Searching Folder: - - - lblSearching - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - NoControl - - - 16, 40 - - - 353, 47 - - - 1 - - - # - - - lblCurrentFolder - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - System - - - NoControl - - - 310, 93 - - - 65, 25 - - - 29 - - - Cancel - - - btnCancel - - - System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - 5, 13 - - - 381, 124 - - - NoControl - - - CenterParent - - - Searching... - - - FindFileStatusDialog - - - System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/Src/Common/FwUtils/IProgress.cs b/Src/Utilities/BasicUtils/IProgress.cs similarity index 83% rename from Src/Common/FwUtils/IProgress.cs rename to Src/Utilities/BasicUtils/IProgress.cs index 5bb6c07b88..3beda9e609 100644 --- a/Src/Common/FwUtils/IProgress.cs +++ b/Src/Utilities/BasicUtils/IProgress.cs @@ -1,13 +1,12 @@ -// Copyright (c) 2011-2013 SIL International +// Copyright (c) 2011-2013 SIL International // This software is licensed under the LGPL, version 2.1 or later // (http://www.gnu.org/licenses/lgpl-2.1.html) // // File: IProgress.cs using System.ComponentModel; -using System.Windows.Forms; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.Utils { /// -------------------------------------------------------------------------------------------- /// @@ -89,18 +88,15 @@ int Maximum } /// - /// Gets the form displaying the progress (used for message box owners, etc). If the progress - /// is not associated with a visible Form, then this returns its owning form, if any. + /// Gets an object to be used for ensuring that required tasks are invoked on the main + /// UI thread. /// - Form Form - { - get; - } + ISynchronizeInvoke SynchronizeInvoke { get; } /// - /// Gets or sets the progress bar style. + /// Gets or sets a value indicating whether this progress is indeterminate. /// - ProgressBarStyle ProgressBarStyle { get; set; } + bool IsIndeterminate { get; set; } /// /// Gets or sets a value indicating whether the opertation executing on the separate thread diff --git a/Src/Common/FwUtils/IServiceLocatorBootstrapper.cs b/Src/Utilities/BasicUtils/IServiceLocatorBootstrapper.cs similarity index 89% rename from Src/Common/FwUtils/IServiceLocatorBootstrapper.cs rename to Src/Utilities/BasicUtils/IServiceLocatorBootstrapper.cs index afd926e2aa..bb348460b8 100644 --- a/Src/Common/FwUtils/IServiceLocatorBootstrapper.cs +++ b/Src/Utilities/BasicUtils/IServiceLocatorBootstrapper.cs @@ -1,6 +1,6 @@ -using Microsoft.Practices.ServiceLocation; +using Microsoft.Practices.ServiceLocation; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.Utils { /// /// Create an IServiceLocator. diff --git a/Src/Common/FwUtils/IThreadedProgress.cs b/Src/Utilities/BasicUtils/IThreadedProgress.cs similarity index 86% rename from Src/Common/FwUtils/IThreadedProgress.cs rename to Src/Utilities/BasicUtils/IThreadedProgress.cs index 00fc438c87..a8cff50b12 100644 --- a/Src/Common/FwUtils/IThreadedProgress.cs +++ b/Src/Utilities/BasicUtils/IThreadedProgress.cs @@ -1,13 +1,12 @@ -// Copyright (c) 2011-2013 SIL International +// Copyright (c) 2011-2013 SIL International // This software is licensed under the LGPL, version 2.1 or later // (http://www.gnu.org/licenses/lgpl-2.1.html) // // File: IThreadedProgress.cs using System; -using SIL.Utils; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.Utils { /// -------------------------------------------------------------------------------------------- /// @@ -17,14 +16,6 @@ namespace SIL.FieldWorks.Common.FwUtils /// -------------------------------------------------------------------------------------------- public interface IThreadedProgress : IProgress { - /// ------------------------------------------------------------------------------------ - /// - /// Gets an object to be used for ensuring that required tasks are invoked on the main - /// UI thread. - /// - /// ------------------------------------------------------------------------------------ - ThreadHelper ThreadHelper { get; } - /// ------------------------------------------------------------------------------------ /// /// Gets a value indicating whether the task has been canceled. @@ -74,7 +65,7 @@ public class WorkerThreadException : Exception { /// ------------------------------------------------------------------------------------ /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The message. /// The inner exception. diff --git a/Src/Utilities/BasicUtils/ManifestHelper.cs b/Src/Utilities/BasicUtils/ManifestHelper.cs deleted file mode 100644 index 45eb73126b..0000000000 --- a/Src/Utilities/BasicUtils/ManifestHelper.cs +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright (c) 2012-2013 SIL International -// This software is licensed under the LGPL, version 2.1 or later -// (http://www.gnu.org/licenses/lgpl-2.1.html) - -using System; -using System.ComponentModel; -using System.Diagnostics; -using System.IO; -using System.Runtime.InteropServices; -using System.Security; - -namespace SIL.Utils -{ - /// ---------------------------------------------------------------------------------------- - /// - /// Allows to create COM objects from a manifest file when running unit tests. - /// - /// Registration-free activation of native COM components reads the information - /// about what COM objects implement which interface etc from a manifest file. This manifest - /// file is usually embedded as a resource in the executable (as we do with the unmanaged - /// tests). However, when running unit tests with NUnit this doesn't work since we can't - /// modify the NUnit executable for each test assembly. Therefore we have to make use - /// of activation contexts which tells the OS which manifest file to use. Note that - /// activation contexts are thread specific. - /// - /// - /// ---------------------------------------------------------------------------------------- - public static class ManifestHelper - { -#if !__MonoCS__ - [SuppressUnmanagedCodeSecurity] - private sealed class ManifestHelperImpl: IDisposable - { - #region Unmanaged structs and methods - [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)] - private struct ActCtx - { - public int cbSize; - public uint dwFlags; - public string lpSource; - public ushort wProcessorArchitecture; - public short wLangId; - public string lpAssemblyDirectory; - public string lpResourceName; - public string lpApplicationName; - public IntPtr hModule; - } - - [DllImport("Kernel32.dll", SetLastError = true, EntryPoint = "CreateActCtxW")] - private static extern IntPtr CreateActCtx(ref ActCtx actCtx); - - [DllImport("Kernel32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool ActivateActCtx(IntPtr hActCtx, out IntPtr lpCookie); - - [DllImport("Kernel32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool DeactivateActCtx(int dwFlags, IntPtr lpCookie); - - [DllImport("Kernel32.dll", SetLastError = true)] - private static extern void ReleaseActCtx(IntPtr hActCtx); - #endregion // Unmanaged structs and methods - - [ThreadStatic] - private static IntPtr m_ActivationContext; - [ThreadStatic] - private static IntPtr m_Cookie; - [ThreadStatic] - private static int m_Count; - - #region Disposable stuff -#if DEBUG - /// - ~ManifestHelperImpl() - { - Dispose(false); - } -#endif - - /// - public bool IsDisposed { get; private set; } - - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - private void Dispose(bool fDisposing) - { - Debug.WriteLineIf(!fDisposing, "****** Missing Dispose() call for " + GetType() + ". *******"); - if (fDisposing && !IsDisposed) - { - // dispose managed and unmanaged objects - m_Count = 0; - DestroyActivationContext(); - } - IsDisposed = true; - } - #endregion - - /// - /// Gets (and creates) the activation context - /// - private IntPtr ActivationContext - { - get - { - if (m_ActivationContext == IntPtr.Zero) - { - // Specifying a full path to the Tests.manifest file like this allows our unit tests to work even with a - // test runner like Resharper 8 which does not set the current directory to the one containing the DLLs. - // Note that we have to use CodeBase here because NUnit runs the tests from a shadow copy directory - // that doesn't contain the manifest file. - var uri = new Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase); - var location = Path.GetDirectoryName(uri.AbsolutePath); - var context = new ActCtx - { - cbSize = Marshal.SizeOf(typeof(ActCtx)), - lpSource = Path.Combine(location, "FieldWorks.Tests.manifest") - }; - - var handle = CreateActCtx(ref context); - if (handle == (IntPtr)(-1)) - throw new Win32Exception(Marshal.GetLastWin32Error(), "Error creating activation context"); - m_ActivationContext = handle; - } - return m_ActivationContext; - } - } - - /// - /// Creates and activates an activation context on the current thread - /// - public void CreateContext() - { - if (m_Cookie == IntPtr.Zero) - { - if (!ActivateActCtx(ActivationContext, out m_Cookie)) - throw new Win32Exception(Marshal.GetLastWin32Error(), "Error activating context"); - } - m_Count++; - } - - /// - /// Releases the current activation context - /// - public void DestroyContext() - { - m_Count--; - if (m_Count <= 0) - { - if (m_Cookie != IntPtr.Zero) - DeactivateActCtx(0, m_Cookie); - m_Cookie = IntPtr.Zero; - - if (m_ActivationContext != IntPtr.Zero) - ReleaseActCtx(m_ActivationContext); - m_ActivationContext = IntPtr.Zero; - } - } - } -#endif - - /// - /// Creates and activates an activation context on the current thread - /// - public static void CreateActivationContext() - { -#if !__MonoCS__ - SingletonsContainer.Get().CreateContext(); -#endif - } - - /// - /// Releases the current activation context - /// - public static void DestroyActivationContext() - { -#if !__MonoCS__ - SingletonsContainer.Get().DestroyContext(); -#endif - } - } -} diff --git a/Src/Utilities/BasicUtils/SingleThreadedSynchronizeInvoke.cs b/Src/Utilities/BasicUtils/SingleThreadedSynchronizeInvoke.cs new file mode 100644 index 0000000000..6d82b688ce --- /dev/null +++ b/Src/Utilities/BasicUtils/SingleThreadedSynchronizeInvoke.cs @@ -0,0 +1,94 @@ +using System; +using System.ComponentModel; +using System.Threading; + +namespace SIL.Utils +{ + /// + /// A simple, single-threaded implementation of ISynchronizeInvoke + /// + public class SingleThreadedSynchronizeInvoke : ISynchronizeInvoke + { + /// + /// Asynchronously executes the delegate on the thread that created this object. + /// + /// A to a method that takes parameters of the same number and type that are contained in . + /// An array of type to pass as arguments to the given method. This can be null if no arguments are needed. + /// + /// An interface that represents the asynchronous operation started by calling this method. + /// + public IAsyncResult BeginInvoke(Delegate method, object[] args) + { + return new AsyncResult(method.DynamicInvoke(args)); + } + + /// + /// Waits until the process started by calling completes, and then returns the value generated by the process. + /// + /// An interface that represents the asynchronous operation started by calling . + /// + /// An that represents the return value generated by the asynchronous operation. + /// + public object EndInvoke(IAsyncResult result) + { + return ((AsyncResult) result).Result; + } + + /// + /// Synchronously executes the delegate on the thread that created this object and marshals the call to the creating thread. + /// + /// A that contains a method to call, in the context of the thread for the control. + /// An array of type that represents the arguments to pass to the given method. This can be null if no arguments are needed. + /// + /// An that represents the return value from the delegate being invoked, or null if the delegate has no return value. + /// + public object Invoke(Delegate method, object[] args) + { + return method.DynamicInvoke(args); + } + + /// + /// Gets a value indicating whether the caller must call when calling an object that implements this interface. + /// + /// true if the caller must call ; otherwise, false. + public bool InvokeRequired + { + get { return false; } + } + + private class AsyncResult : IAsyncResult + { + private readonly object m_result; + + public AsyncResult(object result) + { + m_result = result; + } + + public object Result + { + get { return m_result; } + } + + public bool IsCompleted + { + get { return true; } + } + + public WaitHandle AsyncWaitHandle + { + get { throw new NotSupportedException(); } + } + + public object AsyncState + { + get { return null; } + } + + public bool CompletedSynchronously + { + get { return true; } + } + } + } +} diff --git a/Src/Common/FwUtils/StringIgnoreCaseComparer.cs b/Src/Utilities/BasicUtils/StringIgnoreCaseComparer.cs similarity index 96% rename from Src/Common/FwUtils/StringIgnoreCaseComparer.cs rename to Src/Utilities/BasicUtils/StringIgnoreCaseComparer.cs index 33b53987db..2814f116f3 100644 --- a/Src/Common/FwUtils/StringIgnoreCaseComparer.cs +++ b/Src/Utilities/BasicUtils/StringIgnoreCaseComparer.cs @@ -8,7 +8,7 @@ using System; using System.Collections.Generic; -namespace SIL.FieldWorks.Common.FwUtils +namespace SIL.Utils { /// ---------------------------------------------------------------------------------------- /// diff --git a/Src/Utilities/BasicUtils/SynchronizeInvokeExtensions.cs b/Src/Utilities/BasicUtils/SynchronizeInvokeExtensions.cs new file mode 100644 index 0000000000..cefdc2180d --- /dev/null +++ b/Src/Utilities/BasicUtils/SynchronizeInvokeExtensions.cs @@ -0,0 +1,95 @@ +using System; +using System.ComponentModel; + +namespace SIL.Utils +{ + /// + /// ISynchronizeInvoke extension methods + /// + public static class SynchronizeInvokeExtensions + { + /// + /// Invokes the specified action synchronously on the thread on which this ThreadHelper + /// was created. If the calling thread is the thread on which this ThreadHelper was + /// created, no invoke is performed. + /// + /// The synchronize invoke object. + /// The action. + public static void Invoke(this ISynchronizeInvoke si, Action action) + { + if (si.InvokeRequired) + si.Invoke(action, null); + else + action(); + } + + /// + /// Invokes the specified function synchronously on the thread on which this + /// ThreadHelper was created. If the calling thread is the thread on which this + /// ThreadHelper was created, no invoke is performed. + /// + /// The synchronize invoke object. + /// The function. + public static TResult Invoke(this ISynchronizeInvoke si, Func func) + { + if (si.InvokeRequired) + return (TResult) si.Invoke(func, null); + return func(); + } + + /// + /// Invokes the specified action, asynchronously or not on the thread on which this + /// ThreadHelper was created + /// + /// The synchronize invoke object. + /// if set to true invoke asynchronously. + /// The action to perform. + public static void Invoke(this ISynchronizeInvoke si, bool invokeAsync, Action action) + { + if (invokeAsync) + si.InvokeAsync(action); + else + si.Invoke(action); + } + + /// + /// Executes the specified method asynchronously. The action will typically be called + /// when the the Application.Run() loop regains control or the next call to + /// Application.DoEvents() at some unspecified time in the future. + /// + public static void InvokeAsync(this ISynchronizeInvoke si, Action action) + { + si.BeginInvoke(action, null); + } + + /// + /// Executes the specified method asynchronously. The action will typically be called + /// when the the Application.Run() loop regains control or the next call to + /// Application.DoEvents() at some unspecified time in the future. + /// + public static void InvokeAsync(this ISynchronizeInvoke si, Action action, T param1) + { + si.BeginInvoke(action, new object[] {param1}); + } + + /// + /// Executes the specified method asynchronously. The action will typically be called + /// when the the Application.Run() loop regains control or the next call to + /// Application.DoEvents() at some unspecified time in the future. + /// + public static void InvokeAsync(this ISynchronizeInvoke si, Action action, T1 param1, T2 param2) + { + si.BeginInvoke(action, new object[] {param1, param2}); + } + + /// + /// Executes the specified method asynchronously. The action will typically be called + /// when the the Application.Run() loop regains control or the next call to + /// Application.DoEvents() at some unspecified time in the future. + /// + public static void InvokeAsync(this ISynchronizeInvoke si, Action action, T1 param1, T2 param2, T3 param3) + { + si.BeginInvoke(action, new object[] {param1, param2, param3}); + } + } +} diff --git a/Src/Utilities/BasicUtils/ThreadHelper.cs b/Src/Utilities/BasicUtils/ThreadHelper.cs index 8ef092dfe0..e6936509bc 100644 --- a/Src/Utilities/BasicUtils/ThreadHelper.cs +++ b/Src/Utilities/BasicUtils/ThreadHelper.cs @@ -64,7 +64,7 @@ private void Dispose(bool fDisposing) if (fDisposing && !IsDisposed) { // dispose managed and unmanaged objects - Invoke(() => m_invokeControl.Dispose()); + this.Invoke(() => m_invokeControl.Dispose()); } IsDisposed = true; } @@ -125,114 +125,7 @@ public bool InvokeRequired get { return m_invokeControl.InvokeRequired; } } - /// ------------------------------------------------------------------------------------ - /// - /// Invokes the specified action synchronously on the thread on which this ThreadHelper - /// was created. If the calling thread is the thread on which this ThreadHelper was - /// created, no invoke is performed. - /// - /// The action. - /// ------------------------------------------------------------------------------------ - public void Invoke(Action action) - { - if (m_invokeControl.InvokeRequired) - { - m_invokeControl.Invoke(action); - return; - } - action(); - } - /// ------------------------------------------------------------------------------------ - /// - /// Invokes the specified function synchronously on the thread on which this - /// ThreadHelper was created. If the calling thread is the thread on which this - /// ThreadHelper was created, no invoke is performed. - /// - /// The function. - /// ------------------------------------------------------------------------------------ - public TResult Invoke(Func func) - { - if (m_invokeControl.InvokeRequired) - return (TResult)m_invokeControl.Invoke(func); - return func(); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Invokes the specified action, asynchronously or not on the thread on which this - /// ThreadHelper was created - /// - /// if set to true invoke asynchronously. - /// The action to perform. - /// ------------------------------------------------------------------------------------ - public void Invoke(bool invokeAsync, Action action) - { - if (invokeAsync) - InvokeAsync(action); - else - Invoke(action); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Executes the specified method asynchronously. The action will typically be called - /// when the the Application.Run() loop regains control or the next call to - /// Application.DoEvents() at some unspecified time in the future. - /// - /// ------------------------------------------------------------------------------------ - public void InvokeAsync(Action action) - { - if (m_invokeControl.IsHandleCreated) - m_invokeControl.BeginInvoke(action); - else - { - // not ideal, but better than crashing - action(); - } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Executes the specified method asynchronously. The action will typically be called - /// when the the Application.Run() loop regains control or the next call to - /// Application.DoEvents() at some unspecified time in the future. - /// - /// ------------------------------------------------------------------------------------ - public void InvokeAsync(Action action, T param1) - { - if (m_invokeControl.IsHandleCreated) - m_invokeControl.BeginInvoke(action, param1); - else - { - // not ideal, but better than crashing - action(param1); - } - } - - /// ------------------------------------------------------------------------------------ - /// - /// Executes the specified method asynchronously. The action will typically be called - /// when the the Application.Run() loop regains control or the next call to - /// Application.DoEvents() at some unspecified time in the future. - /// - /// ------------------------------------------------------------------------------------ - public void InvokeAsync(Action action, T1 param1, T2 param2) - { - m_invokeControl.BeginInvoke(action, param1, param2); - } - - /// ------------------------------------------------------------------------------------ - /// - /// Executes the specified method asynchronously. The action will typically be called - /// when the the Application.Run() loop regains control or the next call to - /// Application.DoEvents() at some unspecified time in the future. - /// - /// ------------------------------------------------------------------------------------ - public void InvokeAsync(Action action, T1 param1, T2 param2, T3 param3) - { - m_invokeControl.BeginInvoke(action, param1, param2, param3); - } /// ------------------------------------------------------------------------------------ /// diff --git a/Src/Utilities/BasicUtils/UserActivityMonitor.cs b/Src/Utilities/BasicUtils/UserActivityMonitor.cs new file mode 100644 index 0000000000..68f2e7f23f --- /dev/null +++ b/Src/Utilities/BasicUtils/UserActivityMonitor.cs @@ -0,0 +1,61 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Windows.Forms; + +namespace SIL.Utils +{ + /// + /// This class is a message filter which can be installed in order to track when the user last + /// pressed a key or did any mouse action, including moving the mouse. + /// + [SuppressMessage("Gendarme.Rules.Design", "TypesWithNativeFieldsShouldBeDisposableRule", Justification="No unmanaged resources to release")] + public class UserActivityMonitor : IMessageFilter + { + private IntPtr m_lastMousePosition; + + /// + /// Starts monitoring user activity. + /// + public void StartMonitoring() + { + Application.AddMessageFilter(this); + } + + /// + /// Stops monitoring user activity. + /// + public void StopMonitoring() + { + Application.RemoveMessageFilter(this); + } + + /// + /// Gets the last user activity time. + /// + /// + /// The last activity user time. + /// + public DateTime LastActivityTime { get; private set; } + + bool IMessageFilter.PreFilterMessage(ref Message m) + { + if(m.Msg == (int) Win32.WinMsgs.WM_MOUSEMOVE) + { + // For mouse move, we get spurious ones when it didn't really move. So check the actual position. + if (m.LParam != m_lastMousePosition) + { + LastActivityTime = DateTime.Now; + m_lastMousePosition = m.LParam; + // Enhance JohnT: suppress ones where it doesn't move?? + } + return false; + } + if ((m.Msg >= (int) Win32.WinMsgs.WM_MOUSE_Min && m.Msg <= (int) Win32.WinMsgs.WM_MOUSE_Max) + || (m.Msg >= (int) Win32.WinMsgs.WM_KEY_Min && m.Msg <= (int) Win32.WinMsgs.WM_KEY_Max)) + { + LastActivityTime = DateTime.Now; + } + return false; // don't want to block any messages. + } + } +} diff --git a/Src/Utilities/FixFwData/FixFwData.csproj b/Src/Utilities/FixFwData/FixFwData.csproj index 1bfddac15b..ead71fa31b 100644 --- a/Src/Utilities/FixFwData/FixFwData.csproj +++ b/Src/Utilities/FixFwData/FixFwData.csproj @@ -59,6 +59,10 @@ + + False + ..\..\..\Output\Debug\BasicUtils.dll + False ..\..\..\Output\Debug\FixFwDataDll.dll @@ -119,4 +123,4 @@ - + \ No newline at end of file diff --git a/Src/Utilities/FixFwData/Program.cs b/Src/Utilities/FixFwData/Program.cs index 3646da4ce0..fb6b3ed1c3 100644 --- a/Src/Utilities/FixFwData/Program.cs +++ b/Src/Utilities/FixFwData/Program.cs @@ -10,9 +10,9 @@ using System.Diagnostics.CodeAnalysis; using System.Windows.Forms; using Palaso.Reporting; -using SIL.FieldWorks.Common.FwUtils; using SIL.FieldWorks.FixData; using Palaso.UI.WindowsForms.HotSpot; +using SIL.Utils; namespace FixFwData { @@ -77,11 +77,10 @@ public string Message public int StepSize { get; set; } public int Minimum { get; set; } public int Maximum { get; set; } - public Form Form { get; private set; } - - public ProgressBarStyle ProgressBarStyle + public ISynchronizeInvoke SynchronizeInvoke { get; private set; } + public bool IsIndeterminate { - get { return ProgressBarStyle.Continuous; } + get { return false; } set { } } @@ -110,11 +109,6 @@ public void Dispose() private void Dispose(bool fDisposing) { System.Diagnostics.Debug.WriteLineIf(!fDisposing, "****** Missing Dispose() call for " + GetType() + ". *******"); - - if (Form != null && !Form.IsDisposed) - { - Form.Dispose(); - } } #endregion } diff --git a/Src/Utilities/FixFwDataDll/ErrorFixer.cs b/Src/Utilities/FixFwDataDll/ErrorFixer.cs index 6977fac199..65a10c2c25 100644 --- a/Src/Utilities/FixFwDataDll/ErrorFixer.cs +++ b/Src/Utilities/FixFwDataDll/ErrorFixer.cs @@ -5,10 +5,9 @@ // File: LinkFixer.cs // Responsibility: mcconnel -using System; using System.Collections.Generic; using System.Diagnostics; - +using SIL.FieldWorks.FDO; using SIL.FieldWorks.FwCoreDlgs; using System.Windows.Forms; using System.IO; @@ -99,19 +98,19 @@ public void Process() if (dlg.ShowDialog(m_dlg) == DialogResult.OK) { string pathname = Path.Combine( - Path.Combine(DirectoryFinder.ProjectsDirectory, dlg.SelectedProject), - dlg.SelectedProject + Resources.FwFileExtensions.ksFwDataXmlFileExtension); + Path.Combine(FwDirectoryFinder.ProjectsDirectory, dlg.SelectedProject), + dlg.SelectedProject + FdoFileHelper.ksFwDataXmlFileExtension); if (File.Exists(pathname)) { using (new WaitCursor(m_dlg)) { - using (var progressDlg = new ProgressDialogWithTask(m_dlg, null)) + using (var progressDlg = new ProgressDialogWithTask(m_dlg)) { string fixes = (string)progressDlg.RunTask(true, FixDataFile, pathname); if (fixes.Length > 0) { MessageBox.Show(fixes, Strings.ksErrorsFoundOrFixed); - File.WriteAllText(pathname.Replace(Resources.FwFileExtensions.ksFwDataXmlFileExtension, "fixes"), fixes); + File.WriteAllText(pathname.Replace(FdoFileHelper.ksFwDataXmlFileExtension, "fixes"), fixes); } } } diff --git a/Src/Utilities/FixFwDataDll/FixErrorsDlg.cs b/Src/Utilities/FixFwDataDll/FixErrorsDlg.cs index 155ac252e6..7e493a9993 100644 --- a/Src/Utilities/FixFwDataDll/FixErrorsDlg.cs +++ b/Src/Utilities/FixFwDataDll/FixErrorsDlg.cs @@ -15,6 +15,7 @@ using SIL.FieldWorks.Common.FwUtils; using System.IO; using System.Collections; +using SIL.FieldWorks.FDO; namespace SIL.FieldWorks.FixData { @@ -34,9 +35,9 @@ public FixErrorsDlg() { InitializeComponent(); m_btnFixLinks.Enabled = false; - string ext = Resources.FwFileExtensions.ksFwDataXmlFileExtension; + string ext = FdoFileHelper.ksFwDataXmlFileExtension; string lockext = ext + ".lock"; - foreach (var dir in Directory.GetDirectories(DirectoryFinder.ProjectsDirectory)) + foreach (var dir in Directory.GetDirectories(FwDirectoryFinder.ProjectsDirectory)) { string basename = Path.GetFileName(dir); string datafile = Path.Combine(dir, basename + ext); diff --git a/Src/Utilities/FixFwDataDll/FixFwDataDll.csproj b/Src/Utilities/FixFwDataDll/FixFwDataDll.csproj index 4e6f0c9960..d00b7b2147 100644 --- a/Src/Utilities/FixFwDataDll/FixFwDataDll.csproj +++ b/Src/Utilities/FixFwDataDll/FixFwDataDll.csproj @@ -59,6 +59,10 @@ False + + False + ..\..\..\Output\Debug\FDO.dll + False ..\..\..\Output\Debug\FwControls.dll @@ -144,6 +148,12 @@ true + + + {4C7D6B65-A331-4ED7-9B53-3301E714F8E7} + CoreImpl + +