Exemple #1
0
        public void MultiStringAlt()
        {
            CheckDisposed();
            ITsString tsStringNew = m_ISilDataAccess.get_MultiStringAlt(1117, 2227, 7);

            Assert.AreEqual(0, tsStringNew.Length);
            Assert.IsFalse(m_ISilDataAccess.IsDirty());

            ITsPropsBldr propsBldr = TsPropsBldrClass.Create();
            ITsStrBldr   strBldr   = TsStrBldrClass.Create();

            propsBldr.SetStrPropValue((int)FwTextPropType.ktptNamedStyle, "Verse");
            strBldr.Replace(0, 0, "Test", propsBldr.GetTextProps());
            ITsString tsString = strBldr.GetString();

            m_ISilDataAccess.SetMultiStringAlt(1117, 2227, 7, tsString);
            tsStringNew = m_ISilDataAccess.get_MultiStringAlt(1117, 2227, 7);
            Assert.AreEqual(tsString, tsStringNew);
            Assert.IsTrue(m_ISilDataAccess.IsDirty());

            strBldr.Replace(0, 0, "SecondTest", propsBldr.GetTextProps());
            tsString = strBldr.GetString();
            m_ISilDataAccess.SetMultiStringAlt(1117, 2227, 7, tsString);
            tsStringNew = m_ISilDataAccess.get_MultiStringAlt(1117, 2227, 7);
            Assert.AreEqual(tsString, tsStringNew);
            Assert.IsTrue(m_ISilDataAccess.IsDirty());

            tsStringNew = m_ISilDataAccess.get_MultiStringAlt(1117, 2227, 8);
            Assert.AreEqual(0, tsStringNew.Length);
            Assert.IsTrue(m_ISilDataAccess.IsDirty());

            CheckProp(1117, 2227, tsString, CellarModuleDefns.kcptMultiString);
        }
Exemple #2
0
        public void MultiStringAlt()
        {
            ITsString tsStringNew = m_ISilDataAccess.get_MultiStringAlt(1117, 2227, 7);

            Assert.IsNotNull(tsStringNew);
            Assert.AreEqual(0, tsStringNew.Length);

            ITsPropsBldr propsBldr = TsStringUtils.MakePropsBldr();
            ITsStrBldr   strBldr   = TsStringUtils.MakeStrBldr();

            propsBldr.SetStrPropValue((int)FwTextPropType.ktptNamedStyle, "Verse");
            strBldr.Replace(0, 0, "Test", propsBldr.GetTextProps());
            ITsString tsString = strBldr.GetString();

            m_IVwCacheDa.CacheStringAlt(1117, 2227, 7, tsString);
            tsStringNew = m_ISilDataAccess.get_MultiStringAlt(1117, 2227, 7);
            Assert.AreEqual(tsString, tsStringNew);

            strBldr.Replace(0, 0, "SecondTest", propsBldr.GetTextProps());
            tsString = strBldr.GetString();
            m_IVwCacheDa.CacheStringAlt(1117, 2227, 7, tsString);
            tsStringNew = m_ISilDataAccess.get_MultiStringAlt(1117, 2227, 7);
            Assert.AreEqual(tsString, tsStringNew);

            tsStringNew = m_ISilDataAccess.get_MultiStringAlt(1117, 2227, 8);
            Assert.IsNotNull(tsStringNew);
            Assert.AreEqual(0, tsStringNew.Length);
        }
        public void MultiStringVirtualHandler()
        {
            CheckDisposed();

            MultiStringVirtualHandler msvh = new MultiStringVirtualHandler("LexDb", "NewString");

            m_fdoCache.InstallVirtualProperty(msvh);
            Assert.IsTrue(msvh.Writeable);
            Assert.AreEqual((int)CellarModuleDefns.kcptMultiString, msvh.Type);
            Assert.IsFalse(msvh.ComputeEveryTime);

            int hvoLexDb = 0;

            if (m_fdoCache.LangProject != null &&
                m_fdoCache.LangProject.LexDbOA != null)
            {
                hvoLexDb = m_fdoCache.LangProject.LexDbOA.Hvo;
            }
            if (hvoLexDb == 0)
            {
                // Rather than try to create a real LexDb, simulate one.
                hvoLexDb = khvoTest;
            }
            ISilDataAccess sda    = m_fdoCache.MainCacheAccessor;
            IVwCacheDa     cda    = sda as IVwCacheDa;
            int            wsVern = m_fdoCache.LangProject.DefaultVernacularWritingSystem;

            msvh.Load(hvoLexDb, msvh.Tag, wsVern, cda);
            ITsStrFactory tsf  = TsStrFactoryClass.Create();
            ITsString     tss  = tsf.MakeString("", wsVern);
            ITsString     tss1 = sda.get_MultiStringAlt(hvoLexDb, msvh.Tag, wsVern);

            Assert.IsTrue(tss.Equals(tss1));
            Assert.IsTrue(msvh.Writeable);
            tss = tsf.MakeString("This is a test", wsVern);
            msvh.WriteObj(hvoLexDb, msvh.Tag, wsVern, tss, sda);
            cda.CacheStringAlt(hvoLexDb, msvh.Tag, wsVern, tss);
            tss1 = sda.get_MultiStringAlt(hvoLexDb, msvh.Tag, wsVern);
            Assert.IsTrue(tss.Equals(tss1));
        }
        /// <summary>
        /// Parse the text in hvoPara.Contents[vc.DestWs] and make words
        /// </summary>
        /// <param name="hvoPara"></param>
        public void Parse(int hvoPara)
        {
            ITsString tssSrc = m_sda.get_MultiStringAlt(hvoPara, ViewSampleVc.ktagParaContents, m_vc.DestWs);
            WordMaker wm = new WordMaker(tssSrc, m_wsf);
            int       ichMin, ichLim;
            int       cbundle = m_sda.get_VecSize(hvoPara, ViewSampleVc.ktagParaBundles);

            // Clean it out. This wouldn't normally be appropriate for an owning property, but we can get away
            // with it for a non-database cache.
            if (cbundle != 0)
            {
                m_sda.Replace(hvoPara, ViewSampleVc.ktagParaBundles, 0, cbundle, new int[0], 0);
            }
            int             ibundle = 0;
            ITsPropsFactory tpf     = (ITsPropsFactory) new FwKernelLib.TsPropsFactoryClass();
            ITsTextProps    ttp     = tpf.MakeProps(null, m_vc.SourceWs, 0);

            for (ITsString tssWord = wm.NextWord(out ichMin, out ichLim); tssWord != null;
                 tssWord = wm.NextWord(out ichMin, out ichLim))
            {
                // 4 is an arbitrary classid; this kind of cache does nothing with it.
                int hvoBundle = m_sda.MakeNewObject(4, hvoPara, ViewSampleVc.ktagParaBundles, ibundle);
                ibundle++;
                m_sda.SetString(hvoBundle, ViewSampleVc.ktagBundleBase, tssWord);
                ITsStrBldr tsb = tssWord.GetBldr();
                tsb.Replace(0, 0, "idiom(", ttp);
                tsb.Replace(tsb.get_Length(), tsb.get_Length(), ")", ttp);
                m_sda.SetString(hvoBundle, ViewSampleVc.ktagBundleIdiom, tsb.GetString());

                tsb = tssWord.GetBldr();
                tsb.Replace(0, 0, "ling(", ttp);
                tsb.Replace(tsb.get_Length(), tsb.get_Length(), ")", ttp);
                m_sda.SetString(hvoBundle, ViewSampleVc.ktagBundleLing, tsb.GetString());
            }
            m_sda.PropChanged(null, (int)FwViews.PropChangeType.kpctNotifyAll, hvoPara, ViewSampleVc.ktagParaBundles, 0, ibundle, cbundle);
        }
Exemple #5
0
 internal ITsString Value(int ws)
 {
     return(m_sda.get_MultiStringAlt(khvoRoot, kflid, ws));
 }
Exemple #6
0
		private static void CacheStringAltForAllCurrentWs(IEnumerable<int> currentWsList, IVwCacheDa cda, int hvoSec, int flidSec,
			ISilDataAccess sdaMain, int hvoMain, int flidMain)
		{
			CacheStringAltForAllCurrentWs(currentWsList, cda, hvoSec, flidSec,
				delegate(int ws1)
				{
					ITsString tssMain;
					if (hvoMain != 0)
						tssMain = sdaMain.get_MultiStringAlt(hvoMain, flidMain, ws1);
					else
						tssMain = TsStringUtils.MakeTss("", ws1);
					return tssMain;
				});
		}
Exemple #7
0
		private void CopyStringsToSecondary(IList<int> writingSystems, ISilDataAccess sdaMain, int hvoMain,
			int flidMain, IVwCacheDa cda, int hvoSec, int flidSec, ITsStrFactory tsf)
		{
			CheckDisposed();
			foreach (int ws in writingSystems)
			{
				int wsActual = 0;
				ITsString tss;
				if (ws > 0)
				{
					wsActual = ws;
				}
				else if (ws == WritingSystemServices.kwsFirstAnal)
				{
					IList<int> currentAnalysisWsList = m_caches.MainCache.ServiceLocator.WritingSystems.CurrentAnalysisWritingSystems.Select(wsObj => wsObj.Handle).ToArray();
					CacheStringAltForAllCurrentWs(currentAnalysisWsList, cda, hvoSec, flidSec, sdaMain, hvoMain, flidMain);
					continue;
				}
				else if (ws == WritingSystemServices.kwsFirstVern)
				{
					IList<int> currentVernWsList = m_caches.MainCache.ServiceLocator.WritingSystems.CurrentVernacularWritingSystems.Select(wsObj => wsObj.Handle).ToArray();
					CacheStringAltForAllCurrentWs(currentVernWsList, cda, hvoSec, flidSec, sdaMain, hvoMain, flidMain);
					continue;
				}
				else if (ws == WritingSystemServices.kwsVernInParagraph)
				{
					wsActual = RawWordformWs;
				}
				if (wsActual <= 0)
					throw new ArgumentException(String.Format("magic ws {0} not yet supported.", ws));

				if (hvoMain == 0)
				{
					tss = MakeTss("", wsActual, tsf);
				}
				else
				{
					tss = sdaMain.get_MultiStringAlt(hvoMain, flidMain, wsActual);
				}
				cda.CacheStringAlt(hvoSec, flidSec, wsActual, tss);
			}
		}
Exemple #8
0
		/// <summary>
		/// Returns an array of string values (keys) for the objects under this layout node.
		/// </summary>
		/// <param name="fdoCache">The fdo cache.</param>
		/// <param name="sda">The sda.</param>
		/// <param name="layout">The layout.</param>
		/// <param name="hvo">The hvo.</param>
		/// <param name="layoutCache">The layout cache.</param>
		/// <param name="caller">where layout is a component of a 'part' element, caller
		/// is the 'part ref' that invoked it.</param>
		/// <param name="stringTbl">The string TBL.</param>
		/// <param name="wsForce">if non-zero, "string" elements are forced to use that writing system for multistrings.</param>
		/// <returns></returns>
		static public string[] StringsFor(FdoCache fdoCache, ISilDataAccess sda, XmlNode layout, int hvo,
			LayoutCache layoutCache, XmlNode caller, StringTable stringTbl, int wsForce)
		{
			// Some nodes are known to be uninteresting.
			if (XmlVc.CanSkipNode(layout))
				return new string[0]; // don't know how to sort, treat as empty key.

			switch (layout.Name)
			{
				case "string":
				{
					int hvoTarget = hvo;
					XmlVc.GetActualTarget(layout, ref hvoTarget, sda);	// modify the hvo if needed
					if (hvo != hvoTarget)
					{
						return AddStringFromOtherObj(layout, hvoTarget, fdoCache, sda);
					}
					int flid = GetFlid(sda, layout, hvo);
					if (wsForce != 0)
					{
						// If we are forcing a writing system, and it's a multistring, get the forced alternative.
						int itype = sda.MetaDataCache.GetFieldType(flid);
						itype = itype & (int)CellarPropertyTypeFilter.VirtualMask;
						switch (itype)
						{
							case (int) CellarPropertyType.MultiUnicode:
							case (int) CellarPropertyType.MultiString:
								if (wsForce < 0)
								{
									int wsActual;
									var tss = WritingSystemServices.GetMagicStringAlt(fdoCache, sda, wsForce, hvo, flid, true, out wsActual);
									return new[] {tss == null ? "" : tss.Text };
								}
								return new[]
										   {sda.get_MultiStringAlt(hvo, flid, wsForce).Text};
						}
					}
					bool fFoundType;
					var strValue = fdoCache.GetText(hvo, flid, layout, out fFoundType);
					if (fFoundType)
						return new[] {strValue};

					throw new Exception("Bad property type (" + strValue + " for hvo " + hvo +
												" found for string property "
							+ flid + " in " + layout.OuterXml);
				}
				case "configureMlString":
				{
					int flid = GetFlid(sda, layout, hvo);
					// The Ws info specified in the part ref node
					HashSet<int> wsIds = WritingSystemServices.GetAllWritingSystems(fdoCache, caller, null, hvo, flid);
					if (wsIds.Count == 1)
					{
						var strValue = sda.get_MultiStringAlt(hvo, flid, wsIds.First()).Text;
						return new[] {strValue};
					}
					return new[] {AddMultipleAlternatives(fdoCache, sda, wsIds, hvo, flid, caller)};
				}
				case "multiling":
					return ProcessMultiLingualChildren(fdoCache, sda, layout, hvo, layoutCache, caller, stringTbl, wsForce);
				case "layout":
					// "layout" can occur when GetNodeToUseForColumn returns a phony 'layout'
					// formed by unifying a layout with child nodes. Assemble its children.
					// (arguably, we should treat that like div if current flow is a pile.
					// but we can't tell that and it rarely makes a difference.)
				case "para":
				case "span":
				{
					return AssembleChildKeys(fdoCache, sda, layout, hvo, layoutCache, caller, stringTbl, wsForce);
				}
				case "column":
					// top-level node for whole column; concatenate children as for "para"
					// if multipara is false, otherwise as for "div"
					if (XmlUtils.GetOptionalBooleanAttributeValue(layout, "multipara", false))
						return ChildKeys(fdoCache, sda, layout, hvo, layoutCache, caller, stringTbl, wsForce);
					else
						return AssembleChildKeys(fdoCache, sda, layout, hvo, layoutCache, caller, stringTbl, wsForce);

				case "part":
				{
					string partref = XmlUtils.GetOptionalAttributeValue(layout, "ref");
					if (partref == null)
						return ChildKeys(fdoCache, sda, layout, hvo, layoutCache, caller, stringTbl, wsForce); // an actual part, made up of its pieces
					XmlNode part = XmlVc.GetNodeForPart(hvo, partref, false, sda, layoutCache);
					// This is the critical place where we introduce a caller. The 'layout' is really a 'part ref' which is the
					// 'caller' for all embedded nodes in the called part.
					return StringsFor(fdoCache, sda, part, hvo, layoutCache, layout, stringTbl, wsForce);
				}
				case "div":
				case "innerpile":
				{
					// Concatenate keys for child nodes (as distinct strings)
					return ChildKeys(fdoCache, sda, layout, hvo, layoutCache, caller, stringTbl, wsForce);
				}
				case "obj":
				{
					// Follow the property, get the object, look up the layout to use,
					// invoke recursively.
					int flid = GetFlid(sda, layout, hvo);
					int hvoTarget = sda.get_ObjectProp(hvo, flid);
					if (hvoTarget == 0)
						break; // return empty key
					string targetLayoutName = XmlUtils.GetOptionalAttributeValue(layout, "layout"); // uses 'default' if missing.
					XmlNode layoutTarget = GetLayoutNodeForChild(sda, hvoTarget, flid, targetLayoutName, layout, layoutCache);
					if (layoutTarget == null)
						break;
					return ChildKeys(fdoCache, sda, layoutTarget, hvoTarget, layoutCache, caller, stringTbl, wsForce);
				}
				case "seq":
				{
					// Follow the property. For each object, look up the layout to use,
					// invoke recursively, concatenate
					int flid = GetFlid(sda, layout, hvo);
					int[] contents;
					int ctarget = sda.get_VecSize(hvo, flid);
					using (ArrayPtr arrayPtr = MarshalEx.ArrayToNative<int>(ctarget))
					{
						int chvo;
						sda.VecProp(hvo, flid, ctarget, out chvo, arrayPtr);
						contents = MarshalEx.NativeToArray<int>(arrayPtr, chvo);
					}

					string[] result = null;
					string targetLayoutName = XmlVc.GetLayoutName(layout, caller); // also allows for finding "param" attr in caller, if not null
					int i = 0;
					foreach (int hvoTarget in contents)
					{
						int prevResultLength = GetArrayLength(result);
						XmlNode layoutTarget = GetLayoutNodeForChild(sda, hvoTarget, flid, targetLayoutName, layout, layoutCache);
						if (layoutTarget == null)
							continue; // should not happen, but best recovery we can make
						result = Concatenate(result, ChildKeys(fdoCache, sda, layoutTarget, hvoTarget, layoutCache, caller, stringTbl, wsForce));
						// add a separator between the new childkey group and the previous childkey group
						if (i > 0 && prevResultLength != GetArrayLength(result) && prevResultLength > 0)
						{
							int ichIns = 0;
							if (result[prevResultLength - 1] != null)
								ichIns = result[prevResultLength - 1].Length;
							AddSeparator(ref result[prevResultLength - 1],  ichIns, layout);
						}
						++i;
					}

					return result;
				}
				case "choice":
				{
					foreach(XmlNode whereNode in layout.ChildNodes)
					{
						if (whereNode.Name != "where")
						{
							if (whereNode.Name == "otherwise")
								return StringsFor(fdoCache, sda, XmlUtils.GetFirstNonCommentChild(whereNode), hvo, layoutCache, caller, stringTbl, wsForce);
							continue; // ignore any other nodes,typically comments
						}
						// OK, it's a where node.
						if (XmlVc.ConditionPasses(whereNode, hvo, fdoCache, sda, caller))
							return StringsFor(fdoCache, sda, XmlUtils.GetFirstNonCommentChild(whereNode), hvo, layoutCache, caller, stringTbl, wsForce);
					}
					break; // if no condition passes and no otherwise, return null.
				}
				case "if":
				{
					if (XmlVc.ConditionPasses(layout, hvo, fdoCache, sda, caller))
						return StringsFor(fdoCache, sda, XmlUtils.GetFirstNonCommentChild(layout), hvo, layoutCache, caller, stringTbl, wsForce);
					break;
				}
				case "ifnot":
				{
					if (!XmlVc.ConditionPasses(layout, hvo, fdoCache, sda, caller))
						return StringsFor(fdoCache, sda, XmlUtils.GetFirstNonCommentChild(layout), hvo, layoutCache, caller, stringTbl, wsForce);
					break;
				}
				case "lit":
				{
					string literal = layout.InnerText;
					if (stringTbl != null)
					{
						string sTranslate = XmlUtils.GetOptionalAttributeValue(layout, "translate", "");
						if (sTranslate.Trim().ToLower() != "do not translate")
							literal = stringTbl.LocalizeLiteralValue(literal);
					}
					return new[] { literal };
				}
				case "int":
				{
					int flid = GetFlid(sda, layout, hvo);
					int val = sda.get_IntProp(hvo, flid);
					return new[] {AlphaCompNumberString(val)};
				}
				case "datetime":
				{
					int flid = GetFlid(sda, layout, hvo);
					CellarPropertyType itype = (CellarPropertyType)sda.MetaDataCache.GetFieldType(flid);
					if (itype == CellarPropertyType.Time)
					{
						DateTime dt = SilTime.GetTimeProperty(sda, hvo, flid);
						return new[] {DateTimeCompString(dt)};
					}
					else
					{
						string stFieldName = XmlUtils.GetManditoryAttributeValue(layout, "field");
						throw new Exception("Bad field type (" + stFieldName + " for hvo " + hvo + " found for " +
							layout.Name + "  property "	+ flid + " in " + layout.OuterXml);
					}
				}
				case "picture":
					// Treat a picture as a non-empty string for purposes of deciding whether something is empty.
					// This string seems as good as anything for other purposes.
					return new[] {"a picture"};
				default: // unknown or comment node, adds nothing
					Debug.Assert(false, "unrecognized XML node.");
					break;
			}
			return new string[0]; // don't know how to sort, treat as empty key.
		}
Exemple #9
0
		internal static string[] AddStringFromOtherObj(XmlNode frag, int hvoTarget, FdoCache cache, ISilDataAccess sda)
		{
			int flid = XmlVc.GetFlid(frag, hvoTarget, sda);
			ITsStrFactory tsf = cache.TsStrFactory;
			CellarPropertyType itype = (CellarPropertyType)sda.MetaDataCache.GetFieldType(flid);
			if (itype == CellarPropertyType.Unicode)
			{
				return new[] { sda.get_UnicodeProp(hvoTarget, flid) };
			}
			else if (itype == CellarPropertyType.String)
			{
				return new[] { sda.get_StringProp(hvoTarget, flid).Text };
			}
			else // multistring of some type
			{
				int wsid = 0;
				string sep = "";
				if (s_cwsMulti > 1)
				{
					string sLabelWs = XmlUtils.GetOptionalAttributeValue(frag, "ws");
					if (sLabelWs != null && sLabelWs == "current")
					{
						sep = DisplayMultiSep(frag)
							+ DisplayWsLabel(s_qwsCurrent, cache);
						wsid = s_qwsCurrent.Handle;
					}
				}
				if (wsid == 0)
					wsid = WritingSystemServices.GetWritingSystem(cache,
						frag, null, WritingSystemServices.kwsAnal).Handle;
				if (itype == CellarPropertyType.MultiUnicode)
				{
					return new[] { sep, sda.get_MultiStringAlt(hvoTarget, flid, wsid).Text };
				}
				else
				{
					return new[] { sep, sda.get_MultiStringAlt(hvoTarget, flid, wsid).Text };
				}
			}
		}
Exemple #10
0
		private void CopyStringsToSecondary(List<int> writingSystems, ISilDataAccess sdaMain, int hvoMain,
			int flidMain, IVwCacheDa cda, int hvoSec, int flidSec, ITsStrFactory tsf)
		{
			CheckDisposed();
			foreach (int ws in writingSystems)
			{
				int wsActual = 0;
				ITsString tss;
				if (ws > 0)
				{
					wsActual = ws;
				}
				else if (ws == LangProject.kwsFirstAnal)
				{
					int[] currentAnalysisWsList = m_caches.MainCache.LangProject.CurAnalysisWssRS.HvoArray;
					CacheStringAltForAllCurrentWs(currentAnalysisWsList, cda, hvoSec, flidSec, sdaMain, hvoMain, flidMain);
					continue;
				}
				else if (ws == LangProject.kwsFirstVern)
				{
					int[] currentVernWsList = m_caches.MainCache.LangProject.CurVernWssRS.HvoArray;
					CacheStringAltForAllCurrentWs(currentVernWsList, cda, hvoSec, flidSec, sdaMain, hvoMain, flidMain);
					continue;
				}
				else if (ws == LangProject.kwsVernInParagraph)
				{
					wsActual = this.RawWordformWs;
				}
				if (wsActual <= 0)
					throw new ArgumentException(String.Format("magic ws {0} not yet supported.", ws));

				if (hvoMain == 0)
				{
					tss = MakeTss("", wsActual, tsf);
				}
				else
				{
					tss = sdaMain.get_MultiStringAlt(hvoMain, flidMain, wsActual);
				}
				cda.CacheStringAlt(hvoSec, flidSec, wsActual, tss);
			}
		}
Exemple #11
0
		private ITsString FirstAlternativeName(ISilDataAccess sda, int hvoText, int[] rgws)
		{
			ITsString tss;
			for (int i = 0; i < rgws.Length; ++i)
			{
				tss = sda.get_MultiStringAlt(hvoText,
					(int)CmMajorObject.CmMajorObjectTags.kflidName, rgws[i]);
				if (tss.Length > 0)
					return tss;
			}
			return null;
		}
        public void Setup()
        {
            // Create the following:
            // - part and layout inventories
            // - metadata cache
            // - DataAccess cache
            // - collection of columns to display.

            // We want a MetaDataCache that knows about
            // - LexEntry.Senses, Msas, CitationForm, Bibliography, Etymology
            // - LexSense.SemanticDomains, SenseType, Status, gloss
            // - CmPossibility Name, abbr
            // - MoMorphSynAnalysis
            // - MoStemMsa
            // - MoDerivationalMsa
            string m_sTestPath = Path.Combine(DirectoryFinder.FwSourceDirectory,
                                              Path.Combine("Common",
                                                           Path.Combine("Controls",
                                                                        Path.Combine("XMLViews",
                                                                                     Path.Combine("XMLViewsTests", "SampleCm.xml")))));

            m_mdc = MetaDataCache.CreateMetaDataCache(m_sTestPath);

            // We want ISilDataAccess with:
            // - LexEntry (1) with no senses and one MSA (2)
            // - LexEntry (4) with one sense (5) and no MSA
            // - LexEntry (6) with three senses (7, 8, 9) and two MSAs (10, 11)
            // - sense(5) with no semantic domains
            // - senses with one SD (7->30, 8->31)
            // - sense with three SDs, one the same as the first (9->30, 31, 32)
            // - MoStemMsa (2, 11)
            // - MoDerivationalMsa (10)
            m_cda       = VwCacheDaClass.Create();
            m_sda       = m_cda as ISilDataAccess;
            m_wsManager = new PalasoWritingSystemManager();
            m_sda.WritingSystemFactory = m_wsManager;
            var parser = new SimpleDataParser(m_mdc, m_cda);

            parser.Parse(Path.Combine(DirectoryFinder.FwSourceDirectory,
                                      Path.Combine("Common",
                                                   Path.Combine("Controls",
                                                                Path.Combine("XMLViews",
                                                                             Path.Combine("XMLViewsTests", "SampleData.xml"))))));
            int wsEn = m_wsManager.GetWsFromStr("en");

            // These are mainly to check out the parser.
            Assert.AreEqual(3, m_sda.get_ObjectProp(2, 23011), "part of speech of an MoStemMsa");
            Assert.AreEqual(2, m_sda.get_VecItem(1, 2009, 0), "owned msa");
            Assert.AreEqual("noun", m_sda.get_MultiStringAlt(3, 7003, wsEn).Text, "got ms property");
            Assert.AreEqual(9, m_sda.get_VecItem(6, 2010, 2), "3rd sense");
            Assert.AreEqual(31, m_sda.get_VecItem(9, 21016, 1), "2nd semantic domain");

            // Columns includes
            // - CitationForm (string inside span)
            // - Bibliography (string not in span)
            // - Sense glosses (string in para in seq, nested in column element)
            // - Semantic domains (pair of strings in para in seq in seq, using layout refs)
            // - MSAs (simplified, but polymorphic with one having <choice> and one <obj> to CmPossibility
            XmlDocument docColumns = new XmlDocument();

            docColumns.Load(Path.Combine(DirectoryFinder.FwSourceDirectory,
                                         Path.Combine("Common",
                                                      Path.Combine("Controls",
                                                                   Path.Combine("XMLViews",
                                                                                Path.Combine("XMLViewsTests", "TestColumns.xml"))))));
            m_columnList = docColumns.DocumentElement.ChildNodes;

            // Parts just has what those columns need.
            string partDirectory = Path.Combine(DirectoryFinder.FwSourceDirectory,
                                                Path.Combine("Common",
                                                             Path.Combine("Controls",
                                                                          Path.Combine("XMLViews", "XMLViewsTests"))));
            Dictionary <string, string[]> keyAttrs = new Dictionary <string, string[]>();

            keyAttrs["layout"] = new string[] { "class", "type", "name" };
            keyAttrs["group"]  = new string[] { "label" };
            keyAttrs["part"]   = new string[] { "ref" };


            // Currently there are no specialized layout files that match.
            m_layoutInventory = new Inventory(new string[] { partDirectory },
                                              "*.fwlayout", "/LayoutInventory/*", keyAttrs, "TestManyOneBrowse", "ProjectPath");

            keyAttrs         = new Dictionary <string, string[]>();
            keyAttrs["part"] = new string[] { "id" };

            m_partInventory = new Inventory(new string[] { partDirectory },
                                            "TestParts.xml", "/PartInventory/bin/*", keyAttrs, "TestManyOneBrowse", "ProjectPath");
            m_layouts = new LayoutCache(m_mdc, m_layoutInventory, m_partInventory);
        }
Exemple #13
0
		/// <summary>
		/// the tss of the wordform form of the given hvoMatchingWordform in the ws we are querying for.
		/// </summary>
		/// <param name="sda"></param>
		/// <param name="tssTxtWord">the tss of the baseline at current word boundaries</param>
		/// <param name="tssWordAnn">the tss of the wordform form (in the baseline ws) of the annotation.</param>
		/// <param name="hvoMatchingWordform"></param>
		/// <param name="wsMatchQuery">the ws of the wordform we're looking for</param>
		/// <returns></returns>
		private ITsString GetTssWffCandidate(ISilDataAccess sda, ITsString tssTxtWord, ITsString tssWordAnn,
			int hvoMatchingWordform, int wsMatchQuery)
		{
			ITsString tssWff = tssWordAnn;
			int wsTxtWord = StringUtils.GetWsAtOffset(tssTxtWord, 0);
			if (hvoMatchingWordform == 0)
			{
				// return a candidate if it matches the ws we're trying to query.
				return wsMatchQuery == wsTxtWord ? tssWordAnn : null;
			}
			// if the ws of the matcher doesn't match the ws of the baseline
			// find the wordform in an alternative ws.
			if (wsMatchQuery != wsTxtWord)
			{
				try
				{
					// bulk load wordform forms in the alternative ws if we get any misses.
					m_cache.EnableBulkLoadingIfPossible(true);
					tssWff = sda.get_MultiStringAlt(hvoMatchingWordform, (int)WfiWordform.WfiWordformTags.kflidForm, wsMatchQuery);
				}
				finally
				{
					m_cache.EnableBulkLoadingIfPossible(false);
				}
			}
			return tssWff;
		}
		public void Setup()
		{
			// Create the following:
			// - part and layout inventories
			// - metadata cache
			// - DataAccess cache
			// - collection of columns to display.

			// We want a MetaDataCache that knows about
			// - LexEntry.Senses, Msas, CitationForm, Bibliography, Etymology
			// - LexSense.SemanticDomains, SenseType, Status, gloss
			// - CmPossibility Name, abbr
			// - MoMorphSynAnalysis
			// - MoStemMsa
			// - MoDerivationalMsa
			m_mdc = FwMetaDataCacheClass.Create();
			string m_sTestPath = Path.Combine(DirectoryFinder.FwSourceDirectory,
				@"Common\Controls\XmlViews\XmlViewsTests\SampleCm.xml");
			m_mdc.InitXml(m_sTestPath, true);

			// We want ISilDataAccess with:
			// - LexEntry (1) with no senses and one MSA (2)
			// - LexEntry (4) with one sense (5) and no MSA
			// - LexEntry (6) with three senses (7, 8, 9) and two MSAs (10, 11)
			// - sense(5) with no semantic domains
			// - senses with one SD (7->30, 8->31)
			// - sense with three SDs, one the same as the first (9->30, 31, 32)
			// - MoStemMsa (2, 11)
			// - MoDerivationalMsa (10)
			m_cda = VwCacheDaClass.Create();
			m_sda = m_cda as ISilDataAccess;
			m_wsf = LgWritingSystemFactoryClass.Create();
			m_sda.WritingSystemFactory = m_wsf;
			SimpleDataParser parser = new SimpleDataParser(m_mdc, m_cda);

			parser.Parse(Path.Combine(DirectoryFinder.FwSourceDirectory,
				@"Common\Controls\XmlViews\XmlViewsTests\SampleData.xml"));
			int wsEn = m_wsf.GetWsFromStr("en");
			// These are mainly to check out the parser.
			Assert.AreEqual(3, m_sda.get_ObjectProp(2, 23011), "part of speech of an MoStemMsa");
			Assert.AreEqual(2, m_sda.get_VecItem(1, 2009, 0), "owned msa");
			Assert.AreEqual("noun", m_sda.get_MultiStringAlt(3, 7003, wsEn).Text, "got ms property");
			Assert.AreEqual(9, m_sda.get_VecItem(6, 2010, 2), "3rd sense");
			Assert.AreEqual(31, m_sda.get_VecItem(9, 21016, 1), "2nd semantic domain");

			// Columns includes
			// - CitationForm (string inside span)
			// - Bibliography (string not in span)
			// - Sense glosses (string in para in seq, nested in column element)
			// - Semantic domains (pair of strings in para in seq in seq, using layout refs)
			// - MSAs (simplified, but polymorphic with one having <choice> and one <obj> to CmPossibility
			XmlDocument docColumns = new XmlDocument();
			docColumns.Load(Path.Combine(DirectoryFinder.FwSourceDirectory,
				@"Common\Controls\XmlViews\XmlViewsTests\TestColumns.xml"));
			m_columnList = docColumns.DocumentElement.ChildNodes;

			// Parts just has what those columns need.
			string partDirectory = Path.Combine(DirectoryFinder.FwSourceDirectory,
				@"Common\Controls\XmlViews\XmlViewsTests");
			Dictionary<string, string[]> keyAttrs = new Dictionary<string, string[]>();
			keyAttrs["layout"] = new string[] {"class", "type", "name" };
			keyAttrs["group"] = new string[] {"label"};
			keyAttrs["part"] = new string[] {"ref"};


			// Currently there are no specialized layout files that match.
			m_layoutInventory = new Inventory(new string[] {partDirectory},
				"*Layouts.xml", "/LayoutInventory/*", keyAttrs);

			keyAttrs = new Dictionary<string, string[]>();
			keyAttrs["part"] = new string[] {"id"};

			m_partInventory = new Inventory(new string[] {partDirectory},
				"TestParts.xml", "/PartInventory/bin/*", keyAttrs);
			if (m_layouts != null)
				m_layouts.Dispose();
			m_layouts = new LayoutCache(m_mdc, m_layoutInventory, m_partInventory);
		}
Exemple #15
0
 /// <summary>
 /// Get the value of one alternative of a Multilingual alternation.
 /// an empty string in the correct writing system if no value recorded.
 ///</summary>
 /// <param name='hvo'> </param>
 /// <param name='tag'> </param>
 /// <param name='ws'> </param>
 /// <returns></returns>
 public virtual ITsString get_MultiStringAlt(int hvo, int tag, int ws)
 {
     return(m_baseSda.get_MultiStringAlt(hvo, tag, ws));
 }
        // Make a string representing a WfiAnalysis, suitable for use in a combo box item.
        static internal ITsString MakeAnalysisStringRep(int hvoWa, FdoCache fdoCache, bool fUseStyleSheet, int wsVern)
        {
            //			ITsTextProps boldItalicAnalysis = BoldItalicAnalysis(fdoCache);
            //			ITsTextProps italicAnalysis = ItalicAnalysis(fdoCache, Sandbox.SandboxVc.krgbRed);
            ITsTextProps   posTextProperties   = PartOfSpeechTextProperties(fdoCache, true, fUseStyleSheet);
            ITsTextProps   formTextProperties  = FormTextProperties(fdoCache, fUseStyleSheet, wsVern);
            ITsTextProps   glossTextProperties = GlossTextProperties(fdoCache, true, fUseStyleSheet);
            ITsStrBldr     tsb    = TsStrBldrClass.Create();
            ISilDataAccess sda    = fdoCache.MainCacheAccessor;
            int            cmorph = fdoCache.GetVectorSize(hvoWa,
                                                           (int)WfiAnalysis.WfiAnalysisTags.kflidMorphBundles);

            if (cmorph == 0)
            {
                return(fdoCache.MakeUserTss(ITextStrings.ksNoMorphemes));
            }
            bool fRtl      = fdoCache.LanguageWritingSystemFactoryAccessor.get_EngineOrNull(wsVern).RightToLeft;
            int  start     = 0;
            int  lim       = cmorph;
            int  increment = 1;

            if (fRtl)
            {
                start     = cmorph - 1;
                lim       = -1;
                increment = -1;
            }
            for (int i = start; i != lim; i += increment)
            {
                int hvoMb = fdoCache.GetVectorItem(hvoWa,
                                                   (int)WfiAnalysis.WfiAnalysisTags.kflidMorphBundles, i);
                int hvoMf = fdoCache.GetObjProperty(hvoMb,
                                                    (int)WfiMorphBundle.WfiMorphBundleTags.kflidMorph);
                ITsString tssForm = null;
                if (hvoMf != 0)
                {
                    int hvoEntry      = fdoCache.GetOwnerOfObject(hvoMf);
                    int hvoLexemeForm = sda.get_ObjectProp(hvoEntry, (int)LexEntry.LexEntryTags.kflidLexemeForm);
                    if (hvoLexemeForm != 0)
                    {
                        tssForm = sda.get_MultiStringAlt(hvoLexemeForm, (int)MoForm.MoFormTags.kflidForm, wsVern);
                    }
                    if (tssForm == null || tssForm.Length == 0)
                    {
                        tssForm = fdoCache.MainCacheAccessor.get_MultiStringAlt(hvoEntry,
                                                                                (int)LexEntry.LexEntryTags.kflidCitationForm, wsVern);
                    }
                    if (tssForm.Length == 0)
                    {
                        // If there isn't a lexeme form OR citation form use the form of the morph.
                        tssForm = fdoCache.MainCacheAccessor.get_MultiStringAlt(hvoMf,
                                                                                (int)MoForm.MoFormTags.kflidForm, wsVern);
                    }
                }
                else                 // no MoForm linked to this bundle, use its own form.
                {
                    tssForm = fdoCache.MainCacheAccessor.get_MultiStringAlt(hvoMb,
                                                                            (int)WfiMorphBundle.WfiMorphBundleTags.kflidForm, wsVern);
                }
                int ichForm = tsb.Length;
                tsb.ReplaceTsString(ichForm, ichForm, tssForm);
                tsb.SetProperties(ichForm, tsb.Length, formTextProperties);

                // add category (part of speech)
                int hvoMsa = fdoCache.GetObjProperty(hvoMb,
                                                     (int)WfiMorphBundle.WfiMorphBundleTags.kflidMsa);
                tsb.Replace(tsb.Length, tsb.Length, " ", null);
                int    ichMinMsa    = tsb.Length;
                string interlinName = ksMissingString;
                if (hvoMsa != 0)
                {
                    IMoMorphSynAnalysis msa =
                        MoMorphSynAnalysis.CreateFromDBObject(fdoCache, hvoMsa);
                    interlinName = msa.InterlinearAbbr;
                }
                tsb.Replace(ichMinMsa, ichMinMsa, interlinName, posTextProperties);

                //add sense
                int hvoSense = fdoCache.GetObjProperty(hvoMb,
                                                       (int)WfiMorphBundle.WfiMorphBundleTags.kflidSense);
                tsb.Replace(tsb.Length, tsb.Length, " ", null);
                int ichMinSense = tsb.Length;
                if (hvoSense != 0)
                {
                    ITsString tssGloss = fdoCache.MainCacheAccessor.get_MultiStringAlt(hvoSense,
                                                                                       (int)LexSense.LexSenseTags.kflidGloss, fdoCache.DefaultAnalWs);
                    tsb.Replace(ichMinSense, ichMinSense, tssGloss.Text, glossTextProperties);
                }
                else
                {
                    tsb.Replace(ichMinSense, ichMinSense, ksMissingString, glossTextProperties);
                }

                // Enhance JohnT: use proper seps.
                tsb.Replace(tsb.Length, tsb.Length, ksPartSeparator, null);
            }
            // Delete the final separator. (Enhance JohnT: this needs to get smarter when we do
            // real seps.)
            int ichFrom = tsb.Length - ksPartSeparator.Length;

            if (ichFrom < 0)
            {
                ichFrom = 0;
            }
            tsb.Replace(ichFrom, tsb.Length, "", null);
            return(tsb.GetString());
        }
Exemple #17
0
		/// <summary>
		/// the tss of the wordform form of the given hvoMatchingWordform in the ws we are querying for.
		/// </summary>
		/// <param name="sda"></param>
		/// <param name="tssTxtWord">the tss of the baseline at current word boundaries</param>
		/// <param name="tssWordAnn">the tss of the wordform form (in the baseline ws) of the annotation.</param>
		/// <param name="hvoMatchingWordform"></param>
		/// <param name="wsMatchQuery">the ws of the wordform we're looking for</param>
		/// <returns></returns>
		private ITsString GetTssWffCandidate(ISilDataAccess sda, ITsString tssTxtWord, ITsString tssWordAnn,
											 int hvoMatchingWordform, int wsMatchQuery)
		{
			ITsString tssWff = tssWordAnn;
			int wsTxtWord = TsStringUtils.GetWsAtOffset(tssTxtWord, 0);
			if (hvoMatchingWordform == 0)
			{
				// return a candidate if it matches the ws we're trying to query.
				return wsMatchQuery == wsTxtWord ? tssWordAnn : null;
			}
			// if the ws of the matcher doesn't match the ws of the baseline
			// find the wordform in an alternative ws.
			if (wsMatchQuery != wsTxtWord)
			{
				tssWff = sda.get_MultiStringAlt(hvoMatchingWordform, WfiWordformTags.kflidForm, wsMatchQuery);
			}
			return tssWff;
		}
 /// <summary>
 ///
 /// </summary>
 /// <param name="hvo"></param>
 /// <param name="tag"></param>
 /// <param name="ws"></param>
 /// <returns></returns>
 public ITsString get_MultiStringAlt(int hvo, int tag, int ws)
 {
     return(m_sda.get_MultiStringAlt(hvo, tag, ws));
 }
Exemple #19
0
		private void CacheStringAltForAllCurrentWs(int[] currentWsList, IVwCacheDa cda, int hvoSec, int flidSec,
			ISilDataAccess sdaMain, int hvoMain, int flidMain)
		{
			foreach (int ws1 in currentWsList)
				cda.CacheStringAlt(hvoSec, flidSec, ws1, sdaMain.get_MultiStringAlt(hvoMain, flidMain, ws1));
		}
			/// <summary>
			/// Get the most appropriate WfiGloss from among those belonging to the given WfiAnalysis.
			/// The goal is to match as closely as possible the strings found in sda.get_MultiStringAlt(hvoWord, ktagSbWordGloss, ws)
			/// for each ws in wsIds. Ideally we find an alternative where all writing systems match exactly.
			/// Failing that, one where as many as possible match, and the others are blank.
			/// </summary>
			/// <param name="wfiAnalysis"></param>
			/// <param name="wsIds"></param>
			/// <param name="sda"></param>
			/// <param name="hvoWord"></param>
			/// <returns></returns>
			internal static IWfiGloss GetBestGloss(IWfiAnalysis wfiAnalysis, List<int> wsIds, ISilDataAccess sda, int hvoWord)
			{
				IWfiGloss best = null;
				int cBestMatch = 0;
				int cBestBlanks = 0; // number of non-matching alternatives that are blank, in the best match so far
				foreach (IWfiGloss possibleGloss in wfiAnalysis.MeaningsOC)
				{
					int cMatch = 0;
					int cBlanks = 0; // number of non-matching alternatives that are blank, in the current item.
					foreach (int wsId in wsIds)
					{
						ITsString tssGloss = sda.get_MultiStringAlt(hvoWord, ktagSbWordGloss, wsId);
						ITsString tssMainGloss = possibleGloss.Form.get_String(wsId);
						string sdaGloss = tssGloss.Text;
						string smainGloss = tssMainGloss.Text;

						if (tssGloss.Equals(tssMainGloss))
							cMatch++;
						else if (tssMainGloss.Length == 0)
							cBlanks++;
						else
						{
							cMatch = int.MinValue; // non-matching alternative on the WfiGloss, this one is no good for sure
							cBlanks = int.MinValue;
						}
					}
					// This one is better if:
					// - it has more matches
					// - it has as many matches and more relevant empty alternatives
					// - it is as good otherwise and has fewer non-relevant alternatives.
					if (cMatch > cBestMatch
						|| (cMatch == cBestMatch && cBlanks > cBestBlanks)
						|| (cMatch == cBestMatch && cBlanks == cBestBlanks && best != null && AdditionalAlternatives(possibleGloss, wsIds) < AdditionalAlternatives(best, wsIds)))
					{
						cBestMatch = cMatch;
						cBestBlanks = cBlanks;
						best = possibleGloss;
					}
				}
				// we won't return something where nothing matched, just because it had a blank alternative
				return cBestMatch > 0 ? best : null;
			}
        public static void UpdateMainTransFromSegmented(StTxtPara para, int[] wss)
        {
            if (!para.IsValidObject())
            {
                return;                 // in merge, paragraph may be modified then deleted.
            }
            FdoCache cache = para.Cache;

            BtConverter.EnsureMainParaSegments(para, wss[0]);
            ISilDataAccess sda         = cache.MainCacheAccessor;
            List <int>     segments    = para.Segments;
            int            kflidFT     = StTxtPara.SegmentFreeTranslationFlid(cache);
            ITsString      tssContents = para.Contents.UnderlyingTsString;
            IScripture     scr         = para.Cache.LangProject.TranslatedScriptureOA;
            ICmTranslation originalBT  = para.GetBT();            // Can be null
            string         sUnfinished = BackTranslationStatus.Unfinished.ToString();

            foreach (int ws in wss)
            {
                ITsStrBldr bldr          = TsStrBldrClass.Create();
                bool       wantNextSpace = false;        // suppresses space before the first thing we add.
                bool       haveBtText    = false;        // Text that isn't segment label text
                foreach (int hvoSeg in segments)
                {
                    // If it's a label, insert it directly. Suppress following space.
                    int       beginOffset = sda.get_IntProp(hvoSeg, (int)CmBaseAnnotation.CmBaseAnnotationTags.kflidBeginOffset);
                    int       endOffset   = sda.get_IntProp(hvoSeg, (int)CmBaseAnnotation.CmBaseAnnotationTags.kflidEndOffset);
                    ITsString tssFt;
                    // Whether we want to insert a space before the current segment is determined by the previous one.
                    // Save that value so we can set wantSpace appropriately for the following one.
                    bool wantSpace = wantNextSpace;
                    if (SegmentBreaker.HasLabelText(tssContents, beginOffset, endOffset))
                    {
                        tssFt         = (new CmBaseAnnotation(cache, hvoSeg)).TextAnnotated;
                        tssFt         = scr.ConvertCVNumbersInStringForBT(CorrectFootnotes(tssFt), ws);
                        wantNextSpace = false;
                    }
                    else
                    {
                        int hvoFt = sda.get_ObjectProp(hvoSeg, kflidFT);
                        tssFt         = sda.get_MultiStringAlt(hvoFt, (int)CmAnnotation.CmAnnotationTags.kflidComment, ws);
                        haveBtText   |= (tssFt.Length > 0);
                        wantNextSpace = EndsWithNonSpace(tssFt);
                    }
                    if (tssFt.Length > 0)
                    {
                        if (wantSpace)
                        {
                            // The preceding segment should typically be followed by a space.
                            if (!StartsWithSpaceOrOrc(tssFt))
                            {
                                bldr.Replace(bldr.Length, bldr.Length, " ", null);
                            }
                        }
                        bldr.ReplaceTsString(bldr.Length, bldr.Length, tssFt);
                    }
                }

                // If the back translation doesn't have text, we don't want to create verse
                // segment labels. This prevents the problem where the book thinks it has a
                // back translation because of automatically generated verse labels (TE-8283).
                if (!haveBtText)
                {
                    // This check might not be needed, but it shouldn't hurt anything.
                    if (originalBT != null)
                    {
                        if (originalBT.Translation.GetAlternative(ws).Length > 0)
                        {
                            string origStatus = originalBT.Status.GetAlternative(ws);
                            if (!String.IsNullOrEmpty(origStatus) && origStatus != sUnfinished)
                            {
                                originalBT.Status.SetAlternative(sUnfinished, ws);
                            }
                        }
                    }
                    continue;
                }

                ITsString      newFt = bldr.GetString();
                ICmTranslation trans;
                if (newFt.Length == 0)
                {
                    trans = para.GetBT();
                    if (trans == null)
                    {
                        return;                         // don't bother creating one to store an empty translation!
                    }
                }
                else
                {
                    trans = para.GetOrCreateBT();
                }
                // Don't write unless it changed...PropChanged can be expensive.
                if (!trans.Translation.GetAlternative(ws).UnderlyingTsString.Equals(newFt))
                {
                    trans.Translation.SetAlternative(newFt, ws);
                    trans.Status.SetAlternative(sUnfinished, ws);
                }
            }
        }
        public override void Display(IVwEnv vwenv, int hvo, int frag)
        {
            CheckDisposed();

            ITsStrFactory tsf = null;

            switch (frag)
            {
            case kfragStText:                     // The whole text, root object for the InterlinDocChild.
                if (hvo == 0)
                {
                    return;                                     // What if the user deleted all the texts?  See LT-6727.
                }
                vwenv.set_IntProperty((int)FwTextPropType.ktptEditable,
                                      (int)FwTextPropVar.ktpvDefault,
                                      (int)TptEditable.ktptNotEditable);
                vwenv.OpenDiv();
                StText stText = new StText(m_cache, hvo);
                vwenv.set_IntProperty((int)FwTextPropType.ktptMarginBottom,
                                      (int)FwTextPropVar.ktpvMilliPoint, 6000);
                vwenv.set_IntProperty((int)FwTextPropType.ktptFontSize,
                                      (int)FwTextPropVar.ktpvMilliPoint, 24000);
                // Add both vernacular and analysis if we have them (LT-5561).
                bool fAddedVernacular = false;
                int  wsVernTitle      = 0;
                //
                if (stText.Title.TryWs(LangProject.kwsFirstVern, out wsVernTitle))
                {
                    vwenv.OpenParagraph();
                    vwenv.AddStringAltMember(vtagStTextTitle, wsVernTitle, this);
                    vwenv.CloseParagraph();
                    fAddedVernacular = true;
                }
                int wsAnalysisTitle = 0;
                vwenv.set_IntProperty((int)FwTextPropType.ktptMarginBottom,
                                      (int)FwTextPropVar.ktpvMilliPoint, 10000);
                vwenv.OpenParagraph();
                ITsString tssAnal;
                if (stText.Title.TryWs(LangProject.kwsFirstAnal, out wsAnalysisTitle, out tssAnal) &&
                    !tssAnal.Equals(stText.Title.BestVernacularAlternative))
                {
                    if (fAddedVernacular)
                    {
                        // display analysis title at smaller font size.
                        vwenv.set_IntProperty((int)FwTextPropType.ktptFontSize,
                                              (int)FwTextPropVar.ktpvMilliPoint, 12000);
                    }
                    vwenv.AddStringAltMember(vtagStTextTitle, wsAnalysisTitle, this);
                }
                else
                {
                    // just add a blank title.
                    tsf = TsStrFactoryClass.Create();
                    ITsString blankTitle = tsf.MakeString("", m_wsAnalysis);
                    vwenv.AddString(blankTitle);
                }
                vwenv.CloseParagraph();
                int       wsSource  = 0;
                ITsString tssSource = stText.SourceOfTextForWs(m_wsVernForDisplay);
                if (tssSource == null || tssSource.Length == 0)
                {
                    tssSource = stText.SourceOfTextForWs(m_wsAnalysis);
                    if (tssSource != null && tssSource.Length > 0)
                    {
                        wsSource = m_wsAnalysis;
                    }
                }
                else
                {
                    wsSource = m_wsVernForDisplay;
                }
                vwenv.set_IntProperty((int)FwTextPropType.ktptMarginBottom,
                                      (int)FwTextPropVar.ktpvMilliPoint, 10000);
                if (tssSource != null && tssSource.Length > 0)
                {
                    vwenv.OpenParagraph();
                    vwenv.set_IntProperty((int)FwTextPropType.ktptFontSize,
                                          (int)FwTextPropVar.ktpvMilliPoint, 12000);
                    vwenv.AddStringAltMember(vtagStTextSource, wsSource, this);
                    vwenv.CloseParagraph();
                }
                else
                {
                    // just add a blank source.
                    tsf = TsStrFactoryClass.Create();
                    ITsString tssBlank = tsf.MakeString("", m_wsAnalysis);
                    vwenv.AddString(tssBlank);
                }
                vwenv.set_IntProperty((int)FwTextPropType.ktptMarginBottom,
                                      (int)FwTextPropVar.ktpvMilliPoint, 10000);
                vwenv.OpenParagraph();
                if (stText.OwningFlid == (int)Text.TextTags.kflidContents)
                {
                    vwenv.AddObjProp((int)CmObjectFields.kflidCmObject_Owner, this, kfragTextDescription);
                }
                vwenv.CloseParagraph();
                base.Display(vwenv, hvo, frag);
                vwenv.CloseDiv();
                break;

            case kfragTextDescription:
                vwenv.AddStringAltMember((int)CmMajorObject.CmMajorObjectTags.kflidDescription, m_wsAnalysis, this);
                break;

            case kfragSegFf:                     // One freeform annotation.
                int[] wssAnalysis = m_WsList.AnalysisWsIds;
                if (wssAnalysis.Length == 0)
                {
                    break;                             // This is bizarre, but for the sake of paranoia...
                }
                tsf = TsStrFactoryClass.Create();
                int    hvoType = m_cache.MainCacheAccessor.get_ObjectProp(hvo, (int)CmAnnotation.CmAnnotationTags.kflidAnnotationType);
                string label   = "";
                if (hvoType == NoteSegmentDefn)
                {
                    label = ITextStrings.ksNt;
                }
                else if (hvoType == FtSegmentDefn)
                {
                    label = ITextStrings.ksFT;
                }
                else if (hvoType == LtSegmentDefn)
                {
                    label = ITextStrings.ksLT;
                }
                else
                {
                    throw new Exception("Unexpected FF annotation type");
                }
                ITsString      tssLabel = tsf.MakeString(label, m_cache.DefaultUserWs);
                ISilDataAccess sda      = vwenv.DataAccess;
                if (wssAnalysis.Length == 1)
                {
                    ITsString tss = sda.get_MultiStringAlt(hvo, (int)CmAnnotation.CmAnnotationTags.kflidComment, m_cache.DefaultAnalWs);
                    if (tss.Length == 0)
                    {
                        break;
                    }
                    vwenv.OpenParagraph();
                    vwenv.AddString(tssLabel);
                    vwenv.AddStringAltMember((int)CmAnnotation.CmAnnotationTags.kflidComment, m_cache.DefaultAnalWs, this);
                    vwenv.CloseParagraph();
                }
                else
                {
                    int labelWidth, labelHeight;
                    vwenv.get_StringWidth(tssLabel, null, out labelWidth, out labelHeight);
                    // This roughly corresponds to the width of the space at the end of FT.
                    // The nice way to do it (here and in the base class) would be a table or 'interlinear' paragraph.
                    labelWidth += 3000;
                    int cNonBlank = 0;
                    for (int i = 0; i < wssAnalysis.Length; i++)
                    {
                        ITsString tss = sda.get_MultiStringAlt(hvo, (int)CmAnnotation.CmAnnotationTags.kflidComment, wssAnalysis[i]);
                        if (tss.Length == 0)
                        {
                            continue;
                        }
                        if (cNonBlank != 0)
                        {
                            // Indent subsequent paragraphs by the width of the main label.
                            vwenv.set_IntProperty((int)FwTextPropType.ktptLeadingIndent,
                                                  (int)FwTextPropVar.ktpvMilliPoint, labelWidth);
                        }
                        vwenv.OpenParagraph();
                        if (cNonBlank == 0)
                        {
                            vwenv.AddString(tssLabel);
                        }
                        cNonBlank++;                                 // after tests above!
                        m_WsList.AddWsLabel(vwenv, i);
                        vwenv.AddStringAltMember((int)CmAnnotation.CmAnnotationTags.kflidComment, wssAnalysis[i], this);
                        vwenv.CloseParagraph();
                    }
                }
                break;

            default:
                base.Display(vwenv, hvo, frag);
                break;
            }
        }
Exemple #23
0
		static string AddMultipleAlternatives(FdoCache cache, ISilDataAccess sda, IEnumerable<int> wsIds, int hvo, int flid, XmlNode frag)
		{
			string sep = XmlUtils.GetOptionalAttributeValue(frag, "sep", null);
			bool fLabel = XmlUtils.GetOptionalBooleanAttributeValue(frag, "showLabels", false); // true to 'separate' using multistring labels.
			string result = "";
			bool fFirst = true;
			foreach (int ws in wsIds)
			{
				string val = sda.get_MultiStringAlt(hvo, flid, ws).Text;
				if (string.IsNullOrEmpty(val))
					continue; // doesn't even count as 'first'
				if (fLabel)
				{
					IWritingSystem wsObj = cache.ServiceLocator.WritingSystemManager.Get(ws);
					result += DisplayWsLabel(wsObj, cache);
				}
				if (fFirst)
				{
					fFirst = false;
				}
				else if (sep != null)
				{
					result = result + sep;
				}
				result += val;
			}
			return result;
		}