public static LfMultiText FromMultiITsString(ITsMultiString value, ILgWritingSystemFactory wsManager) { if (value == null || value.StringCount == 0) { return(null); } LfMultiText mt = new LfMultiText(); for (int index = 0; index < value.StringCount; index++) { int wsId; ITsString tss = value.GetStringFromIndex(index, out wsId); string wsStr = wsManager.GetStrFromWs(wsId); if (!string.IsNullOrEmpty(wsStr)) { string valueStr = LfMerge.Core.DataConverters.ConvertLcmToMongoTsStrings.TextFromTsString(tss, wsManager); LfStringField field = LfStringField.FromString(valueStr); if (field != null) { mt.Add(wsStr, field); } } //MainClass.Logger.Warning("Adding multistring ws: {0}, str {1}", wsStr, valueStr); } return(mt); }
/// <summary> /// Append to the PaMultiString the contents of the tsMultiString. /// For each writing system the contents will end up in a comma seperated list /// </summary> public static void Append(PaMultiString paMultiString, ITsMultiString tsMultiString, ILcmServiceLocator svcloc) { for (int i = 0; i < tsMultiString.StringCount; ++i) { int hvoWs; var tss = tsMultiString.GetStringFromIndex(i, out hvoWs); // hvoWs should *always* be found in AllWritingSystems. var ws = svcloc.WritingSystems.AllWritingSystems.SingleOrDefault(w => w.Handle == hvoWs); paMultiString.AddString(ws == null ? null : ws.Id, tss.Text); } }
/// ------------------------------------------------------------------------------------ private PaMultiString(ITsMultiString msa, ILcmServiceLocator svcloc) { Texts = new List <string>(msa.StringCount); WsIds = new List <string>(msa.StringCount); for (int i = 0; i < msa.StringCount; i++) { int hvoWs; ITsString tss = msa.GetStringFromIndex(i, out hvoWs); Texts.Add(tss.Text); // hvoWs should *always* be found in AllWritingSystems. var ws = svcloc.WritingSystems.AllWritingSystems.SingleOrDefault(w => w.Handle == hvoWs); WsIds.Add(ws == null ? null : ws.Id); } }
/// ------------------------------------------------------------------------------------ private PaMultiString(ITsMultiString msa, IFdoServiceLocator svcloc) { Texts = new List<string>(msa.StringCount); WsIds = new List<string>(msa.StringCount); for (int i = 0; i < msa.StringCount; i++) { int hvoWs; ITsString tss = msa.GetStringFromIndex(i, out hvoWs); Texts.Add(tss.Text); // hvoWs should *always* be found in AllWritingSystems. var ws = svcloc.WritingSystems.AllWritingSystems.SingleOrDefault(w => w.Handle == hvoWs); WsIds.Add(ws == null ? null : ws.Id); } }
public void AllMultiStringPropTest() { CheckDisposed(); // Set class first, or it will throw an exception. int hvo = 1; uint clid = SilDataAccess.MetaDataCache.GetClassId("CmPossibility"); SilDataAccess.SetInt(hvo, (int)CmObjectFields.kflidCmObject_Class, (int)clid); int tag = (int)SilDataAccess.MetaDataCache.GetFieldId("CmPossibility", "Name", false); ITsStrFactory tsf = TsStrFactoryClass.Create(); ITsString tss = tsf.MakeString("Verb", 1); SilDataAccess.SetMultiStringAlt(hvo, tag, 1, tss); tss = tsf.MakeString("Verbo", 2); SilDataAccess.SetMultiStringAlt(hvo, tag, 2, tss); ITsMultiString tsms = SilDataAccess.get_MultiStringProp(hvo, tag); Assert.AreEqual(tsms.StringCount, 2); }
private void PopulateSecondListView(ITsMultiString mainObject) { m_lvDetails.Clear(); m_lvDetails.View = View.Details; m_lvDetails.Sorting = SortOrder.Ascending; m_lvDetails.SmallImageList = null; m_lvDetails.SuspendLayout(); m_lvDetails.Columns.Add("WS", 50); m_lvDetails.Columns.Add("Text", 200); ListViewItem[] lvis = new ListViewItem[mainObject.StringCount]; for (int i = 0; i < mainObject.StringCount; ++i) { int ws; ITsString tss = mainObject.GetStringFromIndex(i, out ws); uint wsLocalFlid = MetaDataCache.GetFieldId("LgWritingSystem", "ICULocale", false); string wsLabel = SilDataAccess.get_UnicodeProp(ws, (int)wsLocalFlid); ListViewItem lvi = new ListViewItem(wsLabel); lvi.Tag = ws; lvi.SubItems.Add(tss.Text); lvis[i] = lvi; } m_lvDetails.Items.AddRange(lvis); m_lvDetails.ResumeLayout(); }
private void SetContentFromNode(FdoCache cache, string sNodeName, bool fFixName, ITsMultiString item) { ILgWritingSystemFactory wsf = cache.WritingSystemFactory; ITsStrFactory tsf = cache.TsStrFactory; int iWS; XmlNode nd; bool fContentFound = false; // be pessimistic foreach (IWritingSystem ws in cache.ServiceLocator.WritingSystems.CurrentAnalysisWritingSystems) { string sWS = ws.Id; nd = m_node.SelectSingleNode(sNodeName + "[@ws='" + sWS + "']"); if (nd == null || nd.InnerText.Length == 0) { continue; } fContentFound = true; string sNodeContent; if (fFixName) { sNodeContent = NameFixer(nd.InnerText); } else { sNodeContent = nd.InnerText; } iWS = wsf.GetWsFromStr(sWS); item.set_String(iWS, (tsf.MakeString(sNodeContent, iWS))); } if (!fContentFound) { iWS = cache.ServiceLocator.WritingSystems.DefaultAnalysisWritingSystem.Handle; item.set_String(iWS, tsf.MakeString("", iWS)); } }
private void PopulateListView(ListView listView, SelectedObject selObj) { SuspendLayout(); // Get all fields from mdc. uint[] uflids; // First find out how many there are. int flidSize = MetaDataCache.GetFields(selObj.m_clid, true, (int)CellarModuleDefns.kgrfcptAll, 0, null); // Now get them for real. using (ArrayPtr flids = MarshalEx.ArrayToNative(flidSize, typeof(uint))) { flidSize = MetaDataCache.GetFields(selObj.m_clid, true, (int)CellarModuleDefns.kgrfcptAll, flidSize, flids); uflids = (uint[])MarshalEx.NativeToArray(flids, flidSize, typeof(uint)); } List <ListViewItem> list = new List <ListViewItem>(); foreach (uint flid in uflids) { if (flid > 0) { string classname; string fieldname = MetaDataCache.GetFieldName(flid); ListViewItem lvi = new ListViewItem(fieldname, 0); // listView.Items.Add(fieldname); list.Add(lvi); lvi.Tag = flid; // TODO: Show some kind of data in the second column of the lvi. // For basic data types, just show the data, if it exists (NA, if not). // Selecting a basic data type field, will clear the right panel. // For objects, we need to distinguish between owning/reference and atomic/seq/coll: // Just use the FDO 'standard' of OA, OS, OC, RA, RS, and RC, plus: // atomic: Object class. Selection of the lvi will then show the object in the right pane. // seq/coll: Maybe size of vector. Selection shows basic list of items in the vector in the right pane. string data = "*N/A"; object obj = SilDataAccess.get_Prop(selObj.m_hvo, (int)flid); if (obj != null) { int flidType = MetaDataCache.GetFieldType(flid); switch (flidType) { case (int)CellarModuleDefns.kcptOwningCollection: case (int)CellarModuleDefns.kcptOwningSequence: case (int)CellarModuleDefns.kcptReferenceSequence: case (int)CellarModuleDefns.kcptReferenceCollection: string pfx = String.Empty; switch (flidType) { case (int)CellarModuleDefns.kcptOwningCollection: pfx = "OC"; break; case (int)CellarModuleDefns.kcptOwningSequence: pfx = "OS"; break; case (int)CellarModuleDefns.kcptReferenceSequence: pfx = "RS"; break; case (int)CellarModuleDefns.kcptReferenceCollection: pfx = "RC"; break; } int vecSize = m_cache.get_VecSize(selObj.m_hvo, (int)flid); List <int> hvos = (List <int>)m_cache.get_Prop(selObj.m_hvo, (int)flid); data = String.Format("{0}: {1} items", pfx, vecSize); lvi.Tag = new SelectedVector(selObj.m_hvo, flid, hvos); break; case (int)CellarModuleDefns.kcptInteger: if (flid == (int)CmObjectFields.kflidCmObject_Class) { classname = MetaDataCache.GetClassName(selObj.m_clid); data = String.Format("{0}: {1}", obj.ToString(), classname); } else { data = obj.ToString(); } break; case (int)CellarModuleDefns.kcptTime: DateTime dt = new DateTime((long)obj); data = dt.ToString(); break; case (int)CellarModuleDefns.kcptOwningAtom: // Fall through. case (int)CellarModuleDefns.kcptReferenceAtom: int objId = (int)obj; int clid = SilDataAccess.get_IntProp(objId, (int)CmObjectFields.kflidCmObject_Class); classname = MetaDataCache.GetClassName((uint)clid); data = String.Format("{0}: a(n) {1}", (flidType == (int)CellarModuleDefns.kcptOwningAtom) ? "OA" : "RA", classname); lvi.Tag = new SelectedObject(flid, objId, (uint)clid); break; case (int)CellarModuleDefns.kcptString: // Fall through. case (int)CellarModuleDefns.kcptBigString: ITsString tssString = (ITsString)obj; data = tssString.Text; break; case (int)CellarModuleDefns.kcptMultiUnicode: // Fall through. case (int)CellarModuleDefns.kcptMultiBigUnicode: // Fall through. case (int)CellarModuleDefns.kcptMultiString: // Fall through. case (int)CellarModuleDefns.kcptMultiBigString: if (obj is ITsMultiString) { ITsMultiString tsms = obj as ITsMultiString; uint wsLocalFlid = MetaDataCache.GetFieldId("LgWritingSystem", "ICULocale", false); if (tsms.StringCount > 0) { int ws; ITsString tss = tsms.GetStringFromIndex(0, out ws); string wsLabel = SilDataAccess.get_UnicodeProp(ws, (int)wsLocalFlid); data = String.Format("{0}: {1}", wsLabel, tss.Text); } lvi.Tag = tsms; } break; case (int)CellarModuleDefns.kcptUnicode: // Fall through. case (int)CellarModuleDefns.kcptBigUnicode: data = (string)obj; break; default: data = obj.ToString(); break; } } lvi.SubItems.Add(data); } } listView.Items.AddRange(list.ToArray()); listView.Sorting = SortOrder.Ascending; listView.Sort(); ResumeLayout(); }
private void SetContentFromNode(FdoCache cache, string sNodeName, bool fFixName, ITsMultiString item) { ILgWritingSystemFactory wsf = cache.WritingSystemFactory; ITsStrFactory tsf = cache.TsStrFactory; int iWS; XmlNode nd; bool fContentFound = false; // be pessimistic foreach (IWritingSystem ws in cache.ServiceLocator.WritingSystems.CurrentAnalysisWritingSystems) { string sWS = ws.Id; nd = m_node.SelectSingleNode(sNodeName + "[@ws='" + sWS + "']"); if (nd == null || nd.InnerText.Length == 0) continue; fContentFound = true; string sNodeContent; if (fFixName) sNodeContent = NameFixer(nd.InnerText); else sNodeContent = nd.InnerText; iWS = wsf.GetWsFromStr(sWS); item.set_String(iWS, (tsf.MakeString(sNodeContent, iWS))); } if (!fContentFound) { iWS = cache.ServiceLocator.WritingSystems.DefaultAnalysisWritingSystem.Handle; item.set_String(iWS, tsf.MakeString("", iWS)); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Handles the flids for basic data (bool, string, int, etc.) /// </summary> /// <param name="thisFlid">The object type flid.</param> /// <param name="flidType">The owning flid type.</param> /// <param name="hvoSrc">The hvo of the source object.</param> /// <param name="hvoNew">The hvo of the new object.</param> /// ------------------------------------------------------------------------------------ private void HandleBasicOrStringFlid(int thisFlid, int flidType, int hvoSrc, int hvoNew) { // Basic and String properties are copied switch (flidType) { // Basic Properties follow case (int)CellarPropertyType.Binary: string flidName = m_mdc.GetFieldName(thisFlid); if (flidName == "Rules" || flidName == "StyleRules") { CopyBinaryAsTextProps(thisFlid, hvoSrc, hvoNew); } else { CopyBinaryAsBinary(thisFlid, hvoSrc, hvoNew); } break; case (int)CellarPropertyType.Boolean: // Copy boolean value m_sda.SetBoolean(hvoNew, thisFlid, m_sda.get_BooleanProp(hvoSrc, thisFlid)); break; case (int)CellarPropertyType.Guid: // Copy guid value // These are currently used as the ID for an application, or a version number, or a Scripture Check ID) m_sda.SetGuid(hvoNew, thisFlid, m_sda.get_GuidProp(hvoSrc, thisFlid)); break; case (int)CellarPropertyType.GenDate: // Fall through, since a GenDate is an int. case (int)CellarPropertyType.Integer: // Copy integer value m_sda.SetInt(hvoNew, thisFlid, m_sda.get_IntProp(hvoSrc, thisFlid)); break; case (int)CellarPropertyType.Time: // Copy time value m_sda.SetTime(hvoNew, thisFlid, m_sda.get_TimeProp(hvoSrc, thisFlid)); break; // String Properties follow case (int)CellarPropertyType.String: // Copy string value // Review: Please check these next three! m_sda.SetString(hvoNew, thisFlid, m_sda.get_StringProp(hvoSrc, thisFlid)); break; case (int)CellarPropertyType.Unicode: // Copy Unicode string m_sda.set_UnicodeProp(hvoNew, thisFlid, m_sda.get_UnicodeProp(hvoSrc, thisFlid)); break; case (int)CellarPropertyType.MultiString: // Fall through case (int)CellarPropertyType.MultiUnicode: ITsMultiString sMulti = m_sda.get_MultiStringProp(hvoSrc, thisFlid); for (int i = 0; i < sMulti.StringCount; i++) { int ws; ITsString tss = sMulti.GetStringFromIndex(i, out ws); m_sda.SetMultiStringAlt(hvoNew, thisFlid, ws, tss); } break; default: throw new FDOInvalidFieldTypeException(String.Format("CopyObject: Unsupported field type {0}.", flidType)); } }
/// ------------------------------------------------------------------------------------ public static PaMultiString Create(ITsMultiString msa, ILcmServiceLocator svcloc) { return(msa == null || msa.StringCount == 0 ? null : new PaMultiString(msa, svcloc)); }
/// ------------------------------------------------------------------------------------ public static PaMultiString Create(ITsMultiString msa, IFdoServiceLocator svcloc) { return (msa == null || msa.StringCount == 0 ? null : new PaMultiString(msa, svcloc)); }
private static void SetContentFromNode(LcmCache cache, XmlNode posNode, string sNodeName, bool fFixName, ITsMultiString item) { var wsf = cache.WritingSystemFactory; int iWS; var fContentFound = false; // be pessimistic foreach (var ws in cache.ServiceLocator.WritingSystems.AnalysisWritingSystems) { var sWS = ws.Id; var nd = posNode.SelectSingleNode(sNodeName + "[@ws='" + sWS + "']"); if (nd == null || nd.InnerText.Length == 0) { continue; } fContentFound = true; var sNodeContent = fFixName ? NameFixer(nd.InnerText) : nd.InnerText; iWS = wsf.GetWsFromStr(sWS); item.set_String(iWS, TsStringUtils.MakeString(sNodeContent, iWS)); } if (!fContentFound) { iWS = cache.ServiceLocator.WritingSystems.DefaultAnalysisWritingSystem.Handle; item.set_String(iWS, TsStringUtils.EmptyString(iWS)); } }
/// <summary> /// Gets the data for one custom field, and any relevant GUIDs. /// </summary> /// <param name="hvo">Hvo of object we're getting the field for.</param> /// <param name="flid">Flid for this field.</param> /// <param name="fieldSourceType">Either "entry", "senses" or "examples". Could also be "allomorphs", eventually.</param> /// <param name="bsonForThisField">Output of a BsonDocument with the following structure: <br /> /// { fieldName: { "value": BsonValue, "guid": "some-guid-as-a-string" } } <br /> /// -OR- <br /> /// { fieldName: { "value": BsonValue, "guid": ["guid1", "guid2", "guid3"] } } <br /> /// The format of the fieldName key will be "customField_FOO_field_name_with_underscores", /// where FOO is one of "entry", "senses", or "examples". <br /> /// The type of the "guid" value (array or string) will determine whether there is a single GUID, /// or a list of GUIDs that happens to contain only one entry. /// If there is no "guid" key, that field has no need for a GUID. (E.g., a number). /// </param> /// <param name="listConverters">Dictionary of ConvertLcmToMongoOptionList instances, keyed by list code</param> private BsonDocument GetCustomFieldData(int hvo, int flid, string fieldSourceType, IDictionary <string, ConvertLcmToMongoOptionList> listConverters) { BsonValue fieldValue = null; BsonValue fieldGuid = null; // Might be a single value, might be a list (as a BsonArray) ISilDataAccessManaged data = (ISilDataAccessManaged)cache.DomainDataByFlid; CellarPropertyType LcmFieldType = (CellarPropertyType)LcmMetaData.GetFieldType(flid); var dataGuids = new List <Guid>(); // Valid field types in Lcm are GenDate, Integer, String, OwningAtomic, ReferenceAtomic, and ReferenceCollection, so that's all we implement. switch (LcmFieldType) { case CellarPropertyType.GenDate: GenDate genDate = data.get_GenDateProp(hvo, flid); string genDateStr = genDate.ToLongString(); // LF wants single-string fields in the format { "ws": { "value": "contents" } } fieldValue = String.IsNullOrEmpty(genDateStr) ? null : LfMultiText.FromSingleStringMapping( MagicStrings.LanguageCodeForGenDateFields, genDateStr).AsBsonDocument(); break; // When parsing, will use GenDate.TryParse(str, out genDate) case CellarPropertyType.Integer: fieldValue = new BsonInt32(data.get_IntProp(hvo, flid)); if (fieldValue.AsInt32 == default(Int32)) { fieldValue = null; // Suppress int fields with 0 in them, to save Mongo DB space } else { // LF wants single-string fields in the format { "ws": { "value": "contents" } } fieldValue = LfMultiText.FromSingleStringMapping( MagicStrings.LanguageCodeForIntFields, fieldValue.AsInt32.ToString()).AsBsonDocument(); } break; case CellarPropertyType.OwningAtomic: case CellarPropertyType.ReferenceAtomic: int ownedHvo = data.get_ObjectProp(hvo, flid); fieldValue = GetCustomReferencedObject(ownedHvo, flid, listConverters, ref dataGuids); if (fieldValue != null && LcmFieldType == CellarPropertyType.ReferenceAtomic) { // Single CmPossiblity reference - LF expects format like { "value": "key of possibility" } fieldValue = new BsonDocument("value", fieldValue); } fieldGuid = new BsonString(dataGuids.FirstOrDefault().ToString()); break; case CellarPropertyType.MultiUnicode: ITsMultiString tss = data.get_MultiStringProp(hvo, flid); if (tss != null && tss.StringCount > 0) { fieldValue = LfMultiText.FromMultiITsString(tss, servLoc.WritingSystemManager).AsBsonDocument(); } break; case CellarPropertyType.OwningCollection: case CellarPropertyType.OwningSequence: case CellarPropertyType.ReferenceCollection: case CellarPropertyType.ReferenceSequence: int[] listHvos = data.VecProp(hvo, flid); var innerValues = new BsonArray(listHvos.Select(listHvo => GetCustomReferencedObject(listHvo, flid, listConverters, ref dataGuids)).Where(x => x != null)); if (innerValues.Count == 0) { fieldValue = null; } else { fieldValue = new BsonDocument("values", innerValues); fieldGuid = new BsonArray(dataGuids.Select(guid => guid.ToString())); } break; case CellarPropertyType.String: ITsString iTsValue = data.get_StringProp(hvo, flid); if (iTsValue == null || String.IsNullOrEmpty(iTsValue.Text)) { fieldValue = null; } else { fieldValue = LfMultiText.FromSingleITsString(iTsValue, servLoc.WritingSystemManager).AsBsonDocument(); } break; default: fieldValue = null; if (logger != null) { logger.Warning("Lcm CellarPropertyType.{0} not recognized for LF custom field", LcmFieldType.ToString()); } break; } if (fieldValue == null) { return(null); } else { var result = new BsonDocument(); result.Add("value", fieldValue ?? BsonNull.Value); // BsonValues aren't allowed to have C# nulls; they have their own null representation if (fieldGuid is BsonArray) { result.Add("guid", fieldGuid, ((BsonArray)fieldGuid).Count > 0); } else { result.Add("guid", fieldGuid, fieldGuid != null); } return(result); } }
private void ExportCustomFields(TextWriter writer, IRnGenericRec record) { ISilDataAccessManaged sda = m_cache.DomainDataByFlid as ISilDataAccessManaged; Debug.Assert(sda != null); foreach (int flid in m_customFlids) { string fieldName = m_mdc.GetFieldName(flid); bool fHandled = false; ITsString tss; string s; CellarPropertyType cpt = (CellarPropertyType)m_mdc.GetFieldType(flid); switch (cpt) { case CellarPropertyType.Boolean: break; case CellarPropertyType.Integer: break; case CellarPropertyType.Numeric: break; case CellarPropertyType.Float: break; case CellarPropertyType.Time: break; case CellarPropertyType.Guid: break; case CellarPropertyType.Image: case CellarPropertyType.Binary: break; case CellarPropertyType.GenDate: break; case CellarPropertyType.String: tss = sda.get_StringProp(record.Hvo, flid); if (tss != null && tss.Text != null) { ExportString(writer, tss, fieldName); } fHandled = true; break; case CellarPropertyType.MultiString: case CellarPropertyType.MultiUnicode: ITsMultiString tms = sda.get_MultiStringProp(record.Hvo, flid); int cch = 0; for (int i = 0; i < tms.StringCount; ++i) { int ws; tss = tms.GetStringFromIndex(i, out ws); cch += tss.Length; if (cch > 0) { break; } } if (cch > 0) { writer.WriteLine("<Field name=\"{0}\" type=\"MultiString\">", fieldName); for (int i = 0; i < tms.StringCount; ++i) { int ws; tss = tms.GetStringFromIndex(i, out ws); if (tss != null && tss.Length > 0) { if (cpt == CellarPropertyType.MultiString) { writer.WriteLine(TsStringUtils.GetXmlRep(tss, m_cache.WritingSystemFactory, ws, true)); } else { writer.WriteLine("<AUni ws=\"{0}\">{1}</AUni>", m_cache.WritingSystemFactory.GetStrFromWs(ws), XmlUtils.MakeSafeXml(tss.Text)); } } } writer.WriteLine("</Field>"); } fHandled = true; break; case CellarPropertyType.Unicode: break; case CellarPropertyType.ReferenceAtomic: case CellarPropertyType.ReferenceCollection: case CellarPropertyType.ReferenceSequence: { int destClid = m_mdc.GetDstClsId(flid); List <int> rghvoDest = new List <int>(); if (cpt == CellarPropertyType.ReferenceAtomic) { int hvo = sda.get_ObjectProp(record.Hvo, flid); if (hvo != 0) { if (destClid == CmPossibilityTags.kClassId) { ICmPossibility poss = PossibilityRepository.GetObject(hvo); ExportAtomicReference(writer, poss, fieldName, "CmPossibility"); fHandled = true; } else { rghvoDest.Add(hvo); } } else { fHandled = true; } } else { int[] hvos = sda.VecProp(record.Hvo, flid); if (hvos.Length > 0) { if (destClid == CmPossibilityTags.kClassId) { List <ICmPossibility> collection = new List <ICmPossibility>(); foreach (int hvo in hvos) { collection.Add(PossibilityRepository.GetObject(hvo)); } ExportReferenceList(writer, collection, fieldName, "CmPossibility", cpt); fHandled = true; } else { rghvoDest.AddRange(hvos); } } else { fHandled = true; } } if (rghvoDest.Count > 0) { } } break; case CellarPropertyType.OwningAtomic: case CellarPropertyType.OwningCollection: case CellarPropertyType.OwningSequence: { int destClid = m_mdc.GetDstClsId(flid); List <int> rghvoDest = new List <int>(); if (cpt == CellarPropertyType.OwningAtomic) { int hvo = sda.get_ObjectProp(record.Hvo, flid); if (hvo != 0) { if (destClid == StTextTags.kClassId) { IStText text = StTextRepository.GetObject(hvo); ExportStText(writer, text, fieldName); fHandled = true; } else { rghvoDest.Add(hvo); } } else { fHandled = true; } } else { } } break; } if (!fHandled) { } } }
//HACK: m_odde.MultiStringProp is not implemented, so this won't be too useful: public TsMultiString(FdoCache cache, ITsMultiString tms) { Debug.Assert(cache != null); m_cache = cache; Debug.Assert(tms != null); m_tms = tms; }