override public IWfiWordform SetAlternateCase(int iSegment, int iSegForm, StringCaseStatus targetState, out string alternateCaseForm)
			{
				IWfiWordform wfAlternateCase = base.SetAlternateCase(iSegment, iSegForm, targetState, out alternateCaseForm);
				m_pb.SetExpectedValuesForAnalysis(m_pb.SegmentFormNode(iSegment, iSegForm), wfAlternateCase.Hvo);
				return wfAlternateCase;
			}
			virtual public IWfiWordform SetAlternateCase(int iSegment, int iSegForm, StringCaseStatus targetState, out string alternateCaseForm)
			{
				// Get actual segment form.
				var analysisActual = GetAnalysis(iSegment, iSegForm);
				int hvoActualInstanceOf;
				IWfiWordform actualWordform;
				GetRealWordformInfo(analysisActual, out hvoActualInstanceOf, out actualWordform);
				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);
				string locale = m_cache.ServiceLocator.WritingSystemManager.Get(ws).IcuLocale;
				var cf = new CaseFunctions(locale);
				switch (targetState)
				{
					case StringCaseStatus.allLower:
						alternateCaseForm = cf.ToLower(actualWordform.Form.get_String(ws).Text);
						break;
					default:
						throw new ArgumentException("target StringCaseStatus(" + targetState + ") not yet supported.");
				}

				// Find or create the new wordform.
				IWfiWordform wfAlternateCase = WfiWordformServices.FindOrCreateWordform(m_cache, TsStringUtils.MakeTss(alternateCaseForm, ws));

				// Set the annotation to this wordform.
				SetAnalysis(iSegment, iSegForm, wfAlternateCase);
				return wfAlternateCase;
			}
			override internal IWfiWordform SetAlternateCase(string wordform, int iOccurrenceInParagraph, StringCaseStatus targetState)
			{
				int iSegment = -1;
				int iSegForm = -1;
				m_pb.GetSegmentFormInfo(wordform, iOccurrenceInParagraph, out iSegment, out iSegForm);
				string alternateWordform;
				return SetAlternateCase(iSegment, iSegForm, targetState, out alternateWordform);
			}
Example #4
0
		/// <summary>
		///
		/// </summary>
		/// <param name="hvoSbWord">either m_hvoSbWord, m_hvoPrevSbWordb, or m_hvoNextSbWord
		/// </param>
		/// <param name="fAdjustCase">If true, may adjust case of morpheme when
		/// proposing whole word as default morpheme breakdown.</param>
		/// <returns>true if any guessing is involved.</returns>
		private bool LoadRealDataIntoSec1(int hvoSbWord, bool fLookForDefaults, bool fAdjustCase)
		{
			ITsStrFactory tsf = TsStrFactoryClass.Create();
			IVwCacheDa cda = (IVwCacheDa)m_caches.DataAccess;
			if (CurrentAnalysisTree.Analysis == null)
			{
				// should we empty the cache of any stale data?
				return false;
			}
			m_hvoLastSelEntry = 0;	// forget last Lex Entry user selection. We're resync'ing everything.
			IWfiAnalysis analysis = CurrentAnalysisTree.WfiAnalysis;
			IWfiGloss gloss = CurrentAnalysisTree.Gloss;
			m_hvoWordGloss = gloss != null ? gloss.Hvo : 0;
			int fGuessing = 0;  // Use 0 or 1, as we store it in an int dummy property.

			RawWordform = null; // recompute based upon wordform.
			int wsVern = RawWordformWs;
			m_caches.Map(hvoSbWord, CurrentAnalysisTree.Wordform.Hvo); // Review: any reason to map these?
			ISilDataAccess sdaMain = m_caches.MainCache.MainCacheAccessor;
			CopyStringsToSecondary(InterlinLineChoices.kflidWord, sdaMain, CurrentAnalysisTree.Wordform.Hvo,
				WfiWordformTags.kflidForm, cda, hvoSbWord, ktagSbWordForm, tsf);
			CaseFunctions cf = VernCaseFuncs(RawWordform);
			m_case = cf.StringCase(RawWordform.Text);
			// empty it in case we're redoing after choose from combo.
			cda.CacheVecProp(hvoSbWord, ktagSbWordMorphs, new int[0], 0);
			if (analysis == null)
			{
				if (fLookForDefaults)
				{
					GetDefaults(CurrentAnalysisTree.Wordform, out analysis, out gloss, fAdjustCase);
					m_hvoWordGloss = gloss != null ? gloss.Hvo : 0;
					// Make sure the wordform ID is consistent with the analysis we located.
					if (analysis != null)
					{
						//set the color before we fidle with our the wordform, it right for this purpose now.
						if (GetHasMultipleRelevantAnalyses(CurrentAnalysisTree.Wordform))
						{
							MultipleAnalysisColor = InterlinVc.MultipleApprovedGuessColor;
						}
						var fixedWordform = analysis.Owner as IWfiWordform;
						if (fixedWordform != CurrentAnalysisTree.Wordform)
						{
							CurrentAnalysisTree.Analysis = fixedWordform;
							// Update the actual form.
							// Enhance: may NOT want to do this, when we get the baseline consistently
							// keeping original case.
							CopyStringsToSecondary(InterlinLineChoices.kflidWord, sdaMain, CurrentAnalysisTree.Wordform.Hvo,
								WfiWordformTags.kflidForm, cda, hvoSbWord, ktagSbWordForm, tsf);
						}
					}
					// Hide the analysis combo if there's no default analysis (which means there are
					// no options to list).
					m_fShowAnalysisCombo = (analysis != null);
					fGuessing = 1;
				}
				else if (CurrentAnalysisTree.Wordform != null)
				{
					// Need to check whether there are any options to list.
					m_fShowAnalysisCombo = CurrentAnalysisTree.Wordform.AnalysesOC.Count > 0;
				}
			}
			else
			{
				m_fShowAnalysisCombo = true; // there's a real analysis!
			}
			m_hvoAnalysisGuess = analysis != null ? analysis.Hvo : 0;
			if (m_hvoWordGloss != 0)
				m_hvoAnalysisGuess = m_hvoWordGloss;

			// make the wordform corresponding to the baseline ws, match RawWordform
			m_caches.DataAccess.SetMultiStringAlt(kSbWord, ktagSbWordForm, this.RawWordformWs, RawWordform);
			// Set every alternative of the word gloss, whether or not we have one...this
			// ensures clearing it out if we once had something but do no longer.
			CopyStringsToSecondary(InterlinLineChoices.kflidWordGloss, sdaMain, m_hvoWordGloss,
				WfiGlossTags.kflidForm, cda, hvoSbWord, ktagSbWordGloss, tsf);
			cda.CacheIntProp(hvoSbWord, ktagSbWordGlossGuess, fGuessing);
			cda.CacheObjProp(hvoSbWord, ktagSbWordPos, 0); // default.
			if (analysis != null) // Might still be, if no default is available.
			{
				var category = analysis.CategoryRA;
				if (category != null)
				{
					int hvoWordPos = CreateSecondaryAndCopyStrings(InterlinLineChoices.kflidWordPos, category.Hvo,
																   CmPossibilityTags.kflidAbbreviation, hvoSbWord, sdaMain, cda, tsf);
					cda.CacheObjProp(hvoSbWord, ktagSbWordPos, hvoWordPos);
					cda.CacheIntProp(hvoWordPos, ktagSbNamedObjGuess, fGuessing);
				}
				if (this.ShowMorphBundles)
				{
					var bldrError = new StringBuilder();
					foreach (var mb in analysis.MorphBundlesOS)
					{
						// Create the corresponding SbMorph.
						int hvoMbSec = m_caches.DataAccess.MakeNewObject(kclsidSbMorph, hvoSbWord,
																		 ktagSbWordMorphs, mb.IndexInOwner);
						m_caches.Map(hvoMbSec, mb.Hvo);

						// Get the real MoForm, if any.
						var mf = mb.MorphRA;
						// Get the text we will display on the first line of the morpheme bundle.
						// Taken from the MoForm if any, otherwise the form of the MB.
						int hvoMorphForm;
						string sPrefix = null;
						string sPostfix = null;
						if (mf == null)
						{
							// Create the secondary object corresponding to the MoForm. We create one
							// even though there isn't a real MoForm. It doesn't correspond to anything
							// in the real database.
							hvoMorphForm = m_caches.DataAccess.MakeNewObject(kclsidSbNamedObj, mb.Hvo,
																			 ktagSbMorphForm, -2); // -2 for atomic
							CopyStringsToSecondary(InterlinLineChoices.kflidMorphemes, sdaMain, mb.Hvo,
												   WfiMorphBundleTags.kflidForm, cda, hvoMorphForm, ktagSbNamedObjName, tsf);
							// We will slightly adjust the form we display in the default vernacular WS.
							InterlinLineSpec specMorphemes = m_choices.GetPrimarySpec(InterlinLineChoices.kflidMorphemes);
							int wsForm;
							if (specMorphemes == null || !mb.Form.TryWs(specMorphemes.WritingSystem, out wsForm))
								wsForm = RawWordformWs;
							ITsString tssForm = sdaMain.get_MultiStringAlt(mb.Hvo,
																		   WfiMorphBundleTags.kflidForm,
																		   wsForm);
							string realForm = tssForm.Text;
							// currently (unfortunately) Text returns 'null' from COM for empty strings.
							if (realForm == null)
								realForm = string.Empty;

							// if it's not an empty string, then we can find its form type, and separate the
							// morpheme markers into separate properties.
							if (realForm != string.Empty)
							{
								IMoMorphType mmt = null;
								try
								{
									int clsidForm;
									mmt = MorphServices.FindMorphType(m_caches.MainCache, ref realForm, out clsidForm);
									sPrefix = mmt.Prefix;
									sPostfix = mmt.Postfix;
								}
								catch (Exception e)
								{
									bldrError.AppendLine(e.Message);
								}
							}
							tssForm = TsStringUtils.MakeTss(realForm, RawWordformWs);
							cda.CacheStringAlt(hvoMorphForm, ktagSbNamedObjName, wsVern, tssForm);
						}
						else
						{
							// Create the secondary object corresponding to the MoForm in the usual way from the form object.
							hvoMorphForm = CreateSecondaryAndCopyStrings(InterlinLineChoices.kflidMorphemes, mf.Hvo,
																		 MoFormTags.kflidForm, hvoSbWord, sdaMain, cda, tsf);
							// Store the prefix and postfix markers from the MoMorphType object.
							int hvoMorphType = sdaMain.get_ObjectProp(mf.Hvo,
																	  MoFormTags.kflidMorphType);
							if (hvoMorphType != 0)
							{
								sPrefix = sdaMain.get_UnicodeProp(hvoMorphType,
																  MoMorphTypeTags.kflidPrefix);
								sPostfix = sdaMain.get_UnicodeProp(hvoMorphType,
																   MoMorphTypeTags.kflidPostfix);
							}
						}
						if (!String.IsNullOrEmpty(sPrefix))
							cda.CacheStringProp(hvoMbSec, ktagSbMorphPrefix,
												tsf.MakeString(sPrefix, wsVern));
						if (!String.IsNullOrEmpty(sPostfix))
							cda.CacheStringProp(hvoMbSec, ktagSbMorphPostfix,
												tsf.MakeString(sPostfix, wsVern));

						// Link the SbMorph to its form object, noting if it is a guess.
						cda.CacheObjProp(hvoMbSec, ktagSbMorphForm, hvoMorphForm);
						cda.CacheIntProp(hvoMorphForm, ktagSbNamedObjGuess, fGuessing);

						// Get the real Sense that supplies the gloss, if any.
						var senseReal = mb.SenseRA;
						if (senseReal == null && fGuessing != 0)
						{
							// Guess a default
							senseReal = mb.DefaultSense;
						}
						if (senseReal != null) // either all-the-way real, or default.
						{
							// Create the corresponding dummy.
							int hvoLexSenseSec;
							// Add any irregularly inflected form type info to the LexGloss.
							ILexEntryRef lerTest;
							ILexEntry possibleVariant = null;
							if (mf != null)
								possibleVariant = mf.Owner as ILexEntry;
							if (possibleVariant != null && possibleVariant.IsVariantOfSenseOrOwnerEntry(senseReal, out lerTest))
							{
								hvoLexSenseSec = m_caches.FindOrCreateSec(senseReal.Hvo, kclsidSbNamedObj, hvoSbWord, ktagSbWordDummy);
								CacheLexGlossWithInflTypeForAllCurrentWs(possibleVariant, hvoLexSenseSec, wsVern, cda, mb.InflTypeRA);
							}
							else
							{
								// add normal LexGloss without variant info
								hvoLexSenseSec = CreateSecondaryAndCopyStrings(InterlinLineChoices.kflidLexGloss, senseReal.Hvo,
											 LexSenseTags.kflidGloss, hvoSbWord, sdaMain, cda, tsf);
							}
							cda.CacheObjProp(hvoMbSec, ktagSbMorphGloss, hvoLexSenseSec);
							cda.CacheIntProp(hvoLexSenseSec, ktagSbNamedObjGuess, fGuessing);

							int hvoInflType = 0;
							if (mb.InflTypeRA != null)
							{
								hvoInflType = m_caches.FindOrCreateSec(mb.InflTypeRA.Hvo,
														 kclsidSbNamedObj, hvoSbWord, ktagSbWordDummy);
							}
							cda.CacheObjProp(hvoMbSec, ktagSbNamedObjInflType, hvoInflType);
						}

						// Get the MSA, if any.
						var msaReal = mb.MsaRA;
						if (msaReal != null)
						{
							int hvoPos = m_caches.FindOrCreateSec(msaReal.Hvo,
																  kclsidSbNamedObj, hvoSbWord, ktagSbWordDummy);

							foreach (int ws in m_choices.WritingSystemsForFlid(InterlinLineChoices.kflidLexPos, true))
							{
								// Since ws maybe ksFirstAnal/ksFirstVern, we need to get what is actually
								// used in order to retrieve the data in Vc.Display().  See LT_7976.
								// Use InterlinAbbrTss to get an appropriate different name for each ws
								ITsString tssLexPos = msaReal.InterlinAbbrTSS(ws);
								int wsActual = TsStringUtils.GetWsAtOffset(tssLexPos, 0);
								cda.CacheStringAlt(hvoPos, ktagSbNamedObjName, wsActual, tssLexPos);
							}
							cda.CacheObjProp(hvoMbSec, ktagSbMorphPos, hvoPos);
							cda.CacheIntProp(hvoPos, ktagSbNamedObjGuess, fGuessing);
						}

						// If we have a form, we can get its owner and set the info for the Entry
						// line.
						// Enhance JohnT: attempt a guess if we have a form but no entry.
						if (mf != null)
						{
							var entryReal = mf.Owner as ILexEntry;
							// We can assume the owner is a LexEntry as that is the only type of object
							// that can own MoForms. We don't actually create the LexEntry, to
							// improve performance. All the relevant data should already have
							// been loaded while creating the main interlinear view.
							LoadSecDataForEntry(entryReal, senseReal, hvoSbWord, cda, wsVern, hvoMbSec, fGuessing, sdaMain, tsf);
						}
					}
					if (bldrError.Length > 0)
					{
						var msg = bldrError.ToString().Trim();
						var wnd = (FindForm() ?? Mediator.PropertyTable.GetValue("window")) as IWin32Window;
						MessageBox.Show(wnd, msg, ITextStrings.ksWarning, MessageBoxButtons.OK, MessageBoxIcon.Warning);
					}
				}
			}
			else
			{
				// No analysis, default or otherwise. We immediately, however, fill in a single
				// dummy morpheme, if showing morphology.
				fGuessing = 0;	// distinguish between a 'guess' (defaults) and courtesy filler info (cf. LT-5858).
				if (ShowMorphBundles)
				{
					int hvoMbSec = m_caches.DataAccess.MakeNewObject(kclsidSbMorph, hvoSbWord,
						ktagSbWordMorphs, 0);
					ITsString tssForm = m_caches.DataAccess.get_MultiStringAlt(hvoSbWord, ktagSbWordForm, this.RawWordformWs);
					// Possibly adjust case of tssForm.
					if (fAdjustCase && CaseStatus == StringCaseStatus.title &&
						tssForm != null && tssForm.Length > 0)
					{
						tssForm = TsStringUtils.MakeTss(cf.ToLower(tssForm.Text), this.RawWordformWs);
						m_tssWordform = tssForm; // need this to be set in case hvoWordformRef set to zero.
						// If we adjust the case of the form, we must adjust the hvo as well,
						// or any analyses created will go to the wrong WfiWordform.
						CurrentAnalysisTree.Analysis = GetWordform(tssForm);
						if (CurrentAnalysisTree.Wordform != null)
							m_fShowAnalysisCombo = CurrentAnalysisTree.Wordform.AnalysesOC.Count > 0;
					}
					else
					{
						// just use the wfi wordform form for our dummy morph form.
						tssForm = CurrentAnalysisTree.Wordform.Form.get_String(this.RawWordformWs);
					}
					int hvoMorphForm = m_caches.FindOrCreateSec(0, kclsidSbNamedObj,
						hvoSbWord, ktagSbWordDummy);
					cda.CacheStringAlt(hvoMorphForm, ktagSbNamedObjName, wsVern, tssForm);
					cda.CacheObjProp(hvoMbSec, ktagSbMorphForm, hvoMorphForm);
					cda.CacheIntProp(hvoMorphForm, ktagSbNamedObjGuess, fGuessing);
				}
			}
			return fGuessing != 0;
		}
			virtual internal IWfiWordform SetAlternateCase(string wordform, int iOccurrenceInParagraph, StringCaseStatus targetState)
			{
				return null; // override
			}
Example #6
0
		/// <summary>
		/// Load the real data into the secondary cache.
		/// </summary>
		/// <param name="fAdjustCase">If true, may adjust case of morpheme when
		/// proposing whole word as default morpheme breakdown.</param>
		/// <param name="fLookForDefaults">If true, will try to guess most likely analysis.</param>
		/// <param name="fClearDirty">if true, establishes the loaded cache state for the sandbox,
		/// so that subsequent changes can be undone or saved with respect to this initial state.</param>
		private void LoadRealDataIntoSec(bool fLookForDefaults, bool fAdjustCase, bool fClearDirty)
		{
			IVwCacheDa cda = (IVwCacheDa)m_caches.DataAccess;
			cda.ClearAllData();
			m_caches.ClearMaps();

			// If we don't have a real root object yet, we can't set anything up.
			if (CurrentAnalysisTree.Analysis == null)
			{
				// This probably paranoid, but it's safe.
				Debug.WriteLine("loading Sandbox for missing analysis");
				m_wordformOriginal = null;
				m_case = StringCaseStatus.allLower;
				return;
			}

			// stop monitoring cache since we are about to make some drastic changes.
			using (new SandboxEditMonitorHelper(m_editMonitor, true))
			{
				UsingGuess = LoadRealDataIntoSec1(kSbWord, fLookForDefaults, fAdjustCase);
				Debug.Assert(CurrentAnalysisTree.Wordform != null || m_tssWordform != null);

				// At this point the only reason to force the current displayed analysis
				// to be returned instead of the original is if we're guessing.
				//m_fForceReturnNewAnalysis = fGuessing;

				// Treat initial state (including guessing) as something you can leave without saving.
				// Make sure it doesn't think any edits have happened, even if reusing from some other word.
				if (fClearDirty)
					MarkAsInitialState();
			}
		}
			override internal int SetAlternateCase(int iSegment, int iSegForm, StringCaseStatus targetState, out string alternateCaseForm)
			{
				int hvoWfAlternateCase = base.SetAlternateCase(iSegment, iSegForm, targetState, out alternateCaseForm);
				int hvoCbaExpected = GetExpectedSegmentForm(iSegment, iSegForm);
				SetInstanceOf(hvoCbaExpected, hvoWfAlternateCase, false);
				return hvoWfAlternateCase;
			}
			virtual internal int SetAlternateCase(int iSegment, int iSegForm, StringCaseStatus targetState, out string alternateCaseForm)
			{
				// Get actual segment form.
				int hvoCbaActual = GetSegmentForm(iSegment, iSegForm);
				int hvoActualInstanceOf;
				IWfiWordform actualCbaWordform;
				GetRealWordformInfo(hvoCbaActual, out hvoActualInstanceOf, out actualCbaWordform);
				ITsString tssWordformBaseline = GetBaselineText(hvoCbaActual);
				// Add any relevant 'other case' forms.
				int nvar;
				int ws = tssWordformBaseline.get_Properties(0).GetIntPropValues((int)FwTextPropType.ktptWs, out nvar); ;
				string locale = m_cache.LanguageWritingSystemFactoryAccessor.get_EngineOrNull(ws).IcuLocale;
				CaseFunctions cf = new CaseFunctions(locale);
				switch (targetState)
				{
					case StringCaseStatus.allLower:
						alternateCaseForm = cf.ToLower(actualCbaWordform.Form.GetAlternative(ws));
						break;
					default:
						throw new ArgumentException("target StringCaseStatus(" + targetState.ToString() + ") not yet supported.");
				}

				// Find or create the new wordform.
				IWfiWordform wfAlternateCase = WfiWordform.FindOrCreateWordform(m_cache, alternateCaseForm, ws);

				// Set the annotation to this wordform.
				int hvoCbaReal = SetInstanceOf(hvoCbaActual, wfAlternateCase.Hvo, true);

				if (!tssWordformBaseline.Equals(wfAlternateCase.Form.BestVernacularAlternative))
				{
					// Cache the real form.
					m_cache.VwCacheDaAccessor.CacheStringProp(hvoCbaReal, InterlinVc.TwficRealFormTag(m_cache), tssWordformBaseline);
				}
				return wfAlternateCase.Hvo;
			}
Example #9
0
		/// <summary>
		///
		/// </summary>
		/// <param name="hvoAnalysisIn">either m_hvoAnalysis, m_hvoPrevAnal, or m_hvoNextAnal
		/// </param>
		/// <param name="hvoWordformRef">reference to either m_hvoWordform, m_hvoPrevWordform,
		/// or m_hvoNextWordform</param>
		/// <param name="hvoSbWord">either m_hvoSbWord, m_hvoPrevSbWordb, or m_hvoNextSbWord
		/// </param>
		/// <param name="fAdjustCase">If true, may adjust case of morpheme when
		/// proposing whole word as default morpheme breakdown.</param>
		/// <returns>true if any guessing is involved.</returns>
		private bool LoadRealDataIntoSec1(ref int hvoAnalysisRef, out int hvoWordformRef,
			int hvoSbWord, bool fLookForDefaults, bool fAdjustCase)
		{
			int wsAnalysis = m_caches.MainCache.DefaultAnalWs;
			ITsStrFactory tsf = TsStrFactoryClass.Create();
			IVwCacheDa cda = (IVwCacheDa)m_caches.DataAccess;
			if (hvoAnalysisRef == 0)
			{
				hvoWordformRef = 0;
				// should we empty the cache of any stale data?
				return false;
			}
			m_hvoLastSelEntry = 0;	// forget last Lex Entry user selection. We're resync'ing everything.
			int hvoAnalysis = 0;
			m_hvoWordGloss = 0;
			int fGuessing = 0;  // Use 0 or 1, as we store it in an int dummy property.


			switch (m_caches.MainCache.GetClassOfObject(hvoAnalysisRef))
			{
				case WfiWordform.kclsidWfiWordform:
					hvoWordformRef = hvoAnalysisRef;
					break;
				case WfiAnalysis.kclsidWfiAnalysis:
					hvoAnalysis = hvoAnalysisRef;
					hvoWordformRef = m_caches.MainCache.GetOwnerOfObject(hvoAnalysis);
					break;
				case WfiGloss.kclsidWfiGloss:
					m_hvoWordGloss = hvoAnalysisRef;
					hvoAnalysis = m_caches.MainCache.GetOwnerOfObject(m_hvoWordGloss);
					hvoWordformRef = m_caches.MainCache.GetOwnerOfObject(hvoAnalysis);
					break;
				default:
					Debug.Assert(false, "analysis must be wordform, wfianalysis, or wfigloss");
					hvoWordformRef = 0;
					break;
			}
			RawWordform = null; // recompute based upon wordform.
			int wsVern = RawWordformWs;
			m_caches.Map(hvoSbWord, hvoWordformRef); // Review: any reason to map these?
			ISilDataAccess sdaMain = m_caches.MainCache.MainCacheAccessor;
			CopyStringsToSecondary(InterlinLineChoices.kflidWord, sdaMain, hvoWordformRef,
				(int)WfiWordform.WfiWordformTags.kflidForm, cda, hvoSbWord, ktagSbWordForm, tsf);
			CaseFunctions cf = VernCaseFuncs(RawWordform);
			m_case = cf.StringCase(RawWordform.Text);
			// empty it in case we're redoing after choose from combo.
			cda.CacheVecProp(hvoSbWord, ktagSbWordMorphs, new int[0], 0);
			if (hvoAnalysis == 0)
			{
				if (fLookForDefaults)
				{
					GetDefaults(hvoWordformRef, out hvoAnalysis, out m_hvoWordGloss, fAdjustCase);
					// Make sure the wordform ID is consistent with the analysis we located.
					if (hvoAnalysis != 0)
					{
						int hvoFixedWordform = m_caches.MainCache.GetOwnerOfObject(hvoAnalysis);
						if (hvoFixedWordform != hvoWordformRef)
						{
							hvoWordformRef = hvoFixedWordform;
							// Update the actual form.
							// Enhance: may NOT want to do this, when we get the baseline consistently
							// keeping original case.
							CopyStringsToSecondary(InterlinLineChoices.kflidWord, sdaMain, hvoWordformRef,
								(int)WfiWordform.WfiWordformTags.kflidForm, cda, hvoSbWord, ktagSbWordForm, tsf);
							hvoAnalysisRef = hvoFixedWordform;
						}
					}
					// Hide the analysis combo if there's no default analysis (which means there are
					// no options to list).
					m_fShowAnalysisCombo = (hvoAnalysis != 0);
					fGuessing = 1;
					// If we found a word gloss treat as human-approved.
					bool fHumanApproved = (m_hvoWordGloss != 0);
					if (!fHumanApproved)
					{
						// Human may have approved the analysis anyway.
						string sql = string.Format("select count(ag.id) " +
							"from CmAgentEvaluation_ ae " +
							"join CmAgent ag on ae.owner$ = ag.id and ae.target = {0} and ag.human = 1",
							hvoAnalysis);
						int nHumanApprovals;
						DbOps.ReadOneIntFromCommand(m_caches.MainCache, sql, null, out nHumanApprovals);
						fHumanApproved = (nHumanApprovals != 0);
					}
					this.GuessColor = fHumanApproved ? InterlinVc.ApprovedGuessColor : InterlinVc.MachineGuessColor;
				}
				else if (hvoWordformRef != 0)
				{
					// Need to check whether there are any options to list.
					m_fShowAnalysisCombo = m_caches.MainCache.GetVectorSize(hvoWordformRef,
						(int)WfiWordform.WfiWordformTags.kflidAnalyses) > 0;
				}
			}
			else
			{
				// If we got a definite analysis, at most we're guessing a gloss, which is always human-approved.
				this.GuessColor = InterlinVc.ApprovedGuessColor;
				m_fShowAnalysisCombo = true; // there's a real analysis!
			}
			m_hvoAnalysisGuess = hvoAnalysis;
			if (m_hvoWordGloss != 0)
				m_hvoAnalysisGuess = m_hvoWordGloss;

			// make the wordform corresponding to the baseline ws, match RawWordform
			m_caches.DataAccess.SetMultiStringAlt(kSbWord, ktagSbWordForm, this.RawWordformWs, RawWordform);
			// Set every alternative of the word gloss, whether or not we have one...this
			// ensures clearing it out if we once had something but do no longer.
			CopyStringsToSecondary(InterlinLineChoices.kflidWordGloss, sdaMain, m_hvoWordGloss,
				(int)WfiGloss.WfiGlossTags.kflidForm, cda, hvoSbWord, ktagSbWordGloss, tsf);
			cda.CacheIntProp(hvoSbWord, ktagSbWordGlossGuess, fGuessing);
			cda.CacheObjProp(hvoSbWord, ktagSbWordPos, 0); // default.
			if (hvoAnalysis != 0) // Might still be, if no default is available.
			{
				int hvoCategory = sdaMain.get_ObjectProp(hvoAnalysis,
					(int)WfiAnalysis.WfiAnalysisTags.kflidCategory);
				if (hvoCategory != 0)
				{
					int hvoWordPos = CreateSecondaryAndCopyStrings(InterlinLineChoices.kflidWordPos, hvoCategory,
						(int)CmPossibility.CmPossibilityTags.kflidAbbreviation, hvoSbWord, sdaMain, cda, tsf);
					cda.CacheObjProp(hvoSbWord, ktagSbWordPos, hvoWordPos);
					cda.CacheIntProp(hvoWordPos, ktagSbNamedObjGuess, fGuessing);
				}
				int cmorphs = 0;
				if (this.ShowMorphBundles)
					cmorphs = sdaMain.get_VecSize(hvoAnalysis,
						(int)WfiAnalysis.WfiAnalysisTags.kflidMorphBundles);
				MoMorphTypeCollection morphtypes = new MoMorphTypeCollection(m_caches.MainCache);
				for (int imorph = 0; imorph < cmorphs; ++imorph)
				{
					// Get the real morpheme bundle.
					int hvoMb = sdaMain.get_VecItem(hvoAnalysis,
						(int)WfiAnalysis.WfiAnalysisTags.kflidMorphBundles, imorph);
					// Create the corresponding SbMorph.
					int hvoMbSec = m_caches.DataAccess.MakeNewObject(kclsidSbMorph, hvoSbWord,
						ktagSbWordMorphs, imorph);
					m_caches.Map(hvoMbSec, hvoMb);

					// Get the real MoForm, if any.
					int hvoMorphReal = sdaMain.get_ObjectProp(hvoMb,
						(int)WfiMorphBundle.WfiMorphBundleTags.kflidMorph);
					// Get the text we will display on the first line of the morpheme bundle.
					// Taken from the MoForm if any, otherwise the form of the MB.
					int hvoMorphForm;
					string sPrefix = null;
					string sPostfix = null;
					if (hvoMorphReal == 0)
					{
						// Create the secondary object corresponding to the MoForm. We create one
						// even though there isn't a real MoForm. It doesn't correspond to anything
						// in the real database.
						hvoMorphForm = m_caches.DataAccess.MakeNewObject(kclsidSbNamedObj, hvoMb,
							ktagSbMorphForm, -2); // -2 for atomic
						CopyStringsToSecondary(InterlinLineChoices.kflidMorphemes, sdaMain, hvoMb,
							(int)WfiMorphBundle.WfiMorphBundleTags.kflidForm, cda, hvoMorphForm, ktagSbNamedObjName, tsf);
						// We will slightly adjust the form we display in the default vernacular WS.
						InterlinLineSpec specMorphemes = m_choices.GetPrimarySpec(InterlinLineChoices.kflidMorphemes);
						int wsForm = RawWordformWs;
						if (specMorphemes != null)
							wsForm = specMorphemes.GetActualWs(Cache, hvoMb, wsForm);
						ITsString tssForm = sdaMain.get_MultiStringAlt(hvoMb,
							(int)WfiMorphBundle.WfiMorphBundleTags.kflidForm,
							wsForm);
						string realForm = tssForm.Text;
						// currently (unfortunately) Text returns 'null' from COM for empty strings.
						if (realForm == null)
							realForm = string.Empty;

						// if it's not an empty string, then we can find its form type, and separate the
						// morpheme markers into separate properties.
						if (realForm != string.Empty)
						{
							IMoMorphType mmt = null;
							try
							{
								int clsidForm;
								mmt = MoMorphType.FindMorphType(m_caches.MainCache, morphtypes,
									ref realForm, out clsidForm);
								sPrefix = mmt.Prefix;
								sPostfix = mmt.Postfix;
							}
							catch (Exception e)
							{
								MessageBox.Show(null, e.Message, ITextStrings.ksWarning,
									MessageBoxButtons.OK);
							}
						}
						tssForm = StringUtils.MakeTss(realForm, RawWordformWs);
						cda.CacheStringAlt(hvoMorphForm, ktagSbNamedObjName, wsVern, tssForm);
					}
					else
					{
						// Create the secondary object corresponding to the MoForm in the usual way from the form object.
						hvoMorphForm = CreateSecondaryAndCopyStrings(InterlinLineChoices.kflidMorphemes, hvoMorphReal,
							(int)MoForm.MoFormTags.kflidForm, hvoSbWord, sdaMain, cda, tsf);
						// Store the prefix and postfix markers from the MoMorphType object.
						int hvoMorphType = sdaMain.get_ObjectProp(hvoMorphReal,
							(int)MoForm.MoFormTags.kflidMorphType);
						if (hvoMorphType != 0)
						{
							sPrefix = sdaMain.get_UnicodeProp(hvoMorphType,
								(int)MoMorphType.MoMorphTypeTags.kflidPrefix);
							sPostfix = sdaMain.get_UnicodeProp(hvoMorphType,
								(int)MoMorphType.MoMorphTypeTags.kflidPostfix);
						}
					}
					if (sPrefix != null && sPrefix != "")
						cda.CacheStringProp(hvoMbSec, ktagSbMorphPrefix,
							tsf.MakeString(sPrefix, wsVern));
					if (sPostfix != null && sPostfix != "")
						cda.CacheStringProp(hvoMbSec, ktagSbMorphPostfix,
							tsf.MakeString(sPostfix, wsVern));

					// Link the SbMorph to its form object, noting if it is a guess.
					cda.CacheObjProp(hvoMbSec, ktagSbMorphForm, hvoMorphForm);
					cda.CacheIntProp(hvoMorphForm, ktagSbNamedObjGuess, fGuessing);

					// Get the real Sense that supplies the gloss, if any.
					int hvoSenseReal = sdaMain.get_ObjectProp(hvoMb,
						(int)WfiMorphBundle.WfiMorphBundleTags.kflidSense);
					if (hvoSenseReal == 0)
					{
						// Guess a default
						int virtFlid = BaseVirtualHandler.GetInstalledHandlerTag(m_caches.MainCache, "WfiMorphBundle", "DefaultSense");
						hvoSenseReal = sdaMain.get_ObjectProp(hvoMb, virtFlid);
						this.GuessColor = InterlinVc.MachineGuessColor;
					}
					if (hvoSenseReal != 0) // either all-the-way real, or default.
					{
						// Create the corresponding dummy.
						int hvoSense = CreateSecondaryAndCopyStrings(InterlinLineChoices.kflidLexGloss, hvoSenseReal,
							(int)LexSense.LexSenseTags.kflidGloss, hvoSbWord, sdaMain, cda, tsf);
						cda.CacheObjProp(hvoMbSec, ktagSbMorphGloss, hvoSense);
						cda.CacheIntProp(hvoSense, ktagSbNamedObjGuess, fGuessing);
					}

					// Get the MSA, if any.
					int hvoMsaReal = sdaMain.get_ObjectProp(hvoMb,
						(int)WfiMorphBundle.WfiMorphBundleTags.kflidMsa);
					if (hvoMsaReal != 0)
					{
						MoMorphSynAnalysis msa = ((MoMorphSynAnalysis)CmObject.CreateFromDBObject(
							m_caches.MainCache, hvoMsaReal, false));
						int hvoPos = m_caches.FindOrCreateSec(hvoMsaReal,
							kclsidSbNamedObj, hvoSbWord, ktagSbWordDummy);

						// Enhance JohnT: we'd really rather be able to get an appropriate different name
						// for each ws, but not possible yet.
						// Enhancement RickM: now we can do this with InterlinAbbrTSS(ws)
						foreach (int ws in m_choices.WritingSystemsForFlid(InterlinLineChoices.kflidLexPos, true))
						{
							// Since ws maybe ksFirstAnal/ksFirstVern, we need to get what is actually
							// used in order to retrieve the data in Vc.Display().  See LT_7976.
							ITsString tssLexPos = msa.InterlinAbbrTSS(ws);
							int wsActual = StringUtils.GetWsAtOffset(tssLexPos, 0);
							cda.CacheStringAlt(hvoPos, ktagSbNamedObjName, wsActual, tssLexPos);
						}
						cda.CacheObjProp(hvoMbSec, ktagSbMorphPos, hvoPos);
						cda.CacheIntProp(hvoPos, ktagSbNamedObjGuess, fGuessing);
					}

					// If we have a form, we can get its owner and set the info for the Entry
					// line.
					// Enhance JohnT: attempt a guess if we have a form but no entry.
					if (hvoMorphReal != 0)
					{
						int hvoEntryReal = m_caches.MainCache.GetOwnerOfObject(hvoMorphReal);
						// We can assume the owner is a LexEntry as that is the only type of object
						// that can own MoForms. We don't actually create the LexEntry, to
						// improve performance. All the relevant data should already have
						// been loaded while creating the main interlinear view.
						LoadSecDataForEntry(hvoEntryReal, hvoSenseReal, hvoSbWord, cda, wsVern, hvoMbSec, fGuessing, sdaMain, tsf);
					}
				}
			}
			else
			{
				// No analysis, default or otherwise. We immediately, however, fill in a single
				// dummy morpheme, if showing morphology.
				fGuessing = 0;	// distinguish between a 'guess' (defaults) and courtesy filler info (cf. LT-5858).
				GuessColor = NoGuessColor;
				if (ShowMorphBundles)
				{
					int hvoMbSec = m_caches.DataAccess.MakeNewObject(kclsidSbMorph, hvoSbWord,
						ktagSbWordMorphs, 0);
					ITsString tssForm = m_caches.DataAccess.get_MultiStringAlt(hvoSbWord, ktagSbWordForm, this.RawWordformWs);
					// Possibly adjust case of tssForm.
					if (fAdjustCase && CaseStatus == StringCaseStatus.title &&
						tssForm != null && tssForm.Length > 0)
					{
						tssForm = StringUtils.MakeTss(cf.ToLower(tssForm.Text), this.RawWordformWs);
						if (m_tssWordform != null)
							Marshal.ReleaseComObject(m_tssWordform);
						m_tssWordform = tssForm; // need this to be set in case hvoWordformRef set to zero.
						// If we adjust the case of the form, we must adjust the hvo as well,
						// or any analyses created will go to the wrong WfiWordform.
						hvoWordformRef = GetWordform(tssForm);
						if (hvoWordformRef != 0)
							m_fShowAnalysisCombo = m_caches.MainCache.GetVectorSize(hvoWordformRef,
								(int)WfiWordform.WfiWordformTags.kflidAnalyses) > 0;
					}
					else
					{
						// just use the wfi wordform form for our dummy morph form.
						tssForm = m_caches.MainCache.GetMultiStringAlt(hvoWordformRef, (int)WfiWordform.WfiWordformTags.kflidForm, this.RawWordformWs);
					}
					int hvoMorphForm = m_caches.FindOrCreateSec(0, kclsidSbNamedObj,
						hvoSbWord, ktagSbWordDummy);
					cda.CacheStringAlt(hvoMorphForm, ktagSbNamedObjName, wsVern, tssForm);
					cda.CacheObjProp(hvoMbSec, ktagSbMorphForm, hvoMorphForm);
					cda.CacheIntProp(hvoMorphForm, ktagSbNamedObjGuess, fGuessing);
				}
			}
			return fGuessing != 0;
		}
Example #10
0
		/// <summary>
		/// Load the real data into the secondary cache.
		/// </summary>
		/// <param name="fAdjustCase">If true, may adjust case of morpheme when
		/// proposing whole word as default morpheme breakdown.</param>
		/// <param name="fLookForDefaults">If true, will try to guess most likely analysis.</param>
		/// <param name="fClearDirty">if true, establishes the loaded cache state for the sandbox,
		/// so that subsequent changes can be undone or saved with respect to this initial state.</param>
		private void LoadRealDataIntoSec(bool fLookForDefaults, bool fAdjustCase, bool fClearDirty)
		{
			IVwCacheDa cda = (IVwCacheDa)m_caches.DataAccess;
			cda.ClearAllData();
			m_caches.ClearMaps();

			// If we don't have a real root object yet, we can't set anything up.
			if (m_hvoAnalysis == 0)
			{
				// This probably paranoid, but it's safe.
				Debug.WriteLine("loading Sandbox for missing analysis");
				m_hvoWordform = 0;
				m_hvoWordformOriginal = 0;
				m_case = StringCaseStatus.allLower;
				return;
			}

			m_fGuessing = LoadRealDataIntoSec1(ref m_hvoAnalysis, out m_hvoWordform,
				kSbWord, fLookForDefaults, fAdjustCase);
			Debug.Assert(m_hvoWordform != 0 || m_tssWordform != null);

			// At this point the only reason to force the current displayed analysis
			// to be returned instead of the original is if we're guessing.
			//m_fForceReturnNewAnalysis = fGuessing;

			// Treat initial state (including guessing) as something you can leave without saving.
			if (fClearDirty)
				MarkAsInitialState(); // Make sure it doesn't think any edits have happened, even if reusing from some other word.
		}