/// <summary> /// Initialize the required inventories. /// </summary> private void InitializePartInventories(FdoCache cache, bool fLoadUserOverrides) { WriteSplashScreen(LexTextStrings.ksInitializingLayouts_); LayoutCache.InitializePartInventories(false, cache.DatabaseName, fLoadUserOverrides); int flid = BaseVirtualHandler.GetInstalledHandlerTag(cache, "LexDb", "CurrentReversalIndices"); if (flid == 0) flid = (int)LexDb.LexDbTags.kflidReversalIndexes; int[] rghvoIndexes = cache.GetVectorProperty(cache.LangProject.LexDbOA.Hvo, flid, false); foreach (int hvoIndex in rghvoIndexes) { int ws = cache.GetObjProperty(hvoIndex, (int)ReversalIndex.ReversalIndexTags.kflidWritingSystem); string sWs = cache.GetUnicodeProperty(ws, (int)LgWritingSystem.LgWritingSystemTags.kflidICULocale); LayoutCache.InitializeLayoutsForWsTag(sWs, cache.DatabaseName); } }
/// <summary> /// Clean up anything we can find that uses the old dummy wordform. /// For each occurrence of the dummy wordform, update the Twfic's InstanceOf. /// Iterate over the Occurrences property to find them. /// </summary> /// <param name="fdoCache"></param> /// <param name="hvoDummyWordform"></param> /// <param name="hvoRealWordform"></param> internal static void CleanupDummyWordformReferences(FdoCache fdoCache, int hvoDummyWordform, int hvoRealWordform) { ISilDataAccess sda = fdoCache.MainCacheAccessor; int kflidOccurrences = WfiWordform.OccurrencesFlid(fdoCache); IVwCacheDa cda = fdoCache.VwCacheDaAccessor; int[] occurrences = fdoCache.GetVectorProperty(hvoDummyWordform, kflidOccurrences, true); for (int i = 0; i < occurrences.Length; i++) { int hvoDummyOccurrence = occurrences[i]; cda.CacheObjProp(hvoDummyOccurrence, (int)CmAnnotation.CmAnnotationTags.kflidInstanceOf, hvoRealWordform); int ownerPrev = fdoCache.GetObjProperty(hvoDummyOccurrence, (int)CmObjectFields.kflidCmObject_Owner); if (ownerPrev == hvoDummyWordform) cda.CacheObjProp(hvoDummyOccurrence, (int)CmObjectFields.kflidCmObject_Owner, hvoRealWordform); } cda.CacheVecProp(hvoRealWordform, kflidOccurrences, occurrences, occurrences.Length); }
/// <summary> /// Finds the wfiAnalysis the given wfic cba.InstanceOf. If it's an InstanceOf a WfiWordform, /// it'll return the wfiAnalysis of the guess, if found, otherwise it'll return the wfiWordform's first analysis. /// </summary> /// <param name="cache"></param> /// <param name="hvoCba"></param> /// <returns></returns> public static int GetWfiAnalysisFromInstanceOf(FdoCache cache, int hvoCba) { int cbaInstanceOf = cache.GetObjProperty(hvoCba, (int)CmAnnotation.CmAnnotationTags.kflidInstanceOf); Debug.Assert(cbaInstanceOf != 0); int hvoWordform; int hvoWfiAnalysis = GetWfiAnalysisFromWficInstanceOf(cache, cbaInstanceOf, out hvoWordform); if (hvoWfiAnalysis == 0 && hvoWordform != 0) { // we are probably an instance of a wordform. Try to use a guess or else use first analysis. int[] analyses = cache.GetVectorProperty(hvoWordform, (int)WfiWordform.WfiWordformTags.kflidAnalyses, false); if (analyses.Length > 0) { // first see if we have a guess we can use. int ktagTwficDefault = StTxtPara.TwficDefaultFlid(cache); int hvoTwficAnalysisGuess = cache.GetObjProperty(hvoCba, ktagTwficDefault); if (hvoTwficAnalysisGuess != 0) hvoWfiAnalysis = GetWfiAnalysisFromWficInstanceOf(cache, hvoTwficAnalysisGuess, out hvoWordform); if (hvoWfiAnalysis == 0) { if (analyses.Length > 1) { throw new ArgumentException( "Couldn't find a guess for a twfic with multiple analyses. Not sure which analysis to return."); } // since we have more than one Analyses, just return the first one. hvoWfiAnalysis = (int) analyses[0]; } } } return hvoWfiAnalysis; }
/// <summary> /// /// </summary> /// <param name="fdoCache"></param> /// <param name="dummyAnnHvo"></param> /// <returns></returns> public static ICmBaseAnnotation ConvertBaseAnnotationToReal(FdoCache fdoCache, int dummyAnnHvo) { using (SuppressSubTasks supressActionHandler = new SuppressSubTasks(fdoCache, true)) { Debug.Assert(fdoCache.IsDummyObject(dummyAnnHvo)); if (!fdoCache.IsDummyObject(dummyAnnHvo) || fdoCache.GetClassOfObject(dummyAnnHvo) != CmBaseAnnotation.kclsidCmBaseAnnotation) { return null; // indicate no change. } ISilDataAccess sda = fdoCache.MainCacheAccessor; ICmBaseAnnotation cbaDummy = (ICmBaseAnnotation)CmObject.CreateFromDBObject(fdoCache, dummyAnnHvo, false); ICmBaseAnnotation cbaReal = CreateRealAnnotation(fdoCache, cbaDummy.AnnotationTypeRAHvo, cbaDummy.InstanceOfRAHvo, cbaDummy.BeginObjectRAHvo, cbaDummy.Flid, cbaDummy.BeginOffset, cbaDummy.EndOffset); cbaReal.WritingSystemRAHvo = cbaDummy.WritingSystemRAHvo; int hvoRealAnn = cbaReal.Hvo; // transfer any default analysis (guess) int ktagTwficDefault = StTxtPara.TwficDefaultFlid(fdoCache); int hvoTwficAnalysisGuess = fdoCache.GetObjProperty(dummyAnnHvo, ktagTwficDefault); if (hvoTwficAnalysisGuess != 0) { fdoCache.VwCacheDaAccessor.CacheObjProp(hvoRealAnn, ktagTwficDefault, hvoTwficAnalysisGuess); } int textSegType = CmAnnotationDefn.TextSegment(fdoCache).Hvo; int twficType = CmAnnotationDefn.Twfic(fdoCache).Hvo; if (cbaDummy.AnnotationTypeRAHvo == twficType) StTxtPara.CacheReplaceTWFICAnnotation(fdoCache, dummyAnnHvo, hvoRealAnn); else if (cbaDummy.AnnotationTypeRAHvo == textSegType) StTxtPara.CacheReplaceTextSegmentAnnotation(fdoCache, dummyAnnHvo, hvoRealAnn); else Debug.Assert(true, "CacheReplace does not yet support annotation type " + cbaDummy.AnnotationTypeRAHvo); // now clear it from the cache, since we're done with it. if (fdoCache.ActionHandlerAccessor != null) fdoCache.ActionHandlerAccessor.AddAction(new ClearInfoOnCommitUndoAction(fdoCache, dummyAnnHvo)); return cbaReal; } }
/// <summary> /// Try to get a WfiWordform determined by the InstanceOf of a CmBaseAnnotation. /// Returns true if successful. Punctuation, for example, may answer false. /// </summary> /// <returns>true if hvoWordform is nonzero</returns> public static bool TryGetWfiWordformFromInstanceOf(FdoCache cache, int hvoCba, out int hvoWordform) { int cbaInstanceOf = cache.GetObjProperty(hvoCba, (int)CmAnnotation.CmAnnotationTags.kflidInstanceOf); hvoWordform = GetWordformFromWag(cache, cbaInstanceOf); return hvoWordform != 0; }
/// <summary> /// Load the information we need to display a paragraph of free (back) translations: for each paragraph /// load its segments, for each segment load the free translation. We assume the segments /// property of each paragraph already exists, and want the BeginOffset, EndOffset, BeginObject, and Free Translation /// properties of each segment, and the Comment of the FT. /// Also ensures all the segments are real and have an FT annotation. /// </summary> /// <param name="paragraphs"></param> /// <param name="cache"></param> /// <param name="ws"></param> public static void LoadSegmentFreeTranslations(int[] paragraphs, FdoCache cache, int ws) { int kflidSegments = SegmentsFlid(cache); List<int> segments = new List<int>(); foreach (int hvoPara in paragraphs) { int[] segs = cache.GetVectorProperty(hvoPara, kflidSegments, true); int iseg = 0; foreach (int hvoSeg in segs) { int hvoRealSeg = hvoSeg; if (cache.IsDummyObject(hvoSeg)) hvoRealSeg = CmBaseAnnotation.ConvertBaseAnnotationToReal(cache, hvoSeg).Hvo; segments.Add(hvoRealSeg); segs[iseg++] = hvoRealSeg; } // Update the list. cache.VwCacheDaAccessor.CacheVecProp(hvoPara, kflidSegments, segs, segs.Length); } if (segments.Count == 0) return; // somehow we can have none, and then the query fails. int hvoFt = cache.GetIdFromGuid(LangProject.kguidAnnFreeTranslation); string ids = JoinIds(segments.ToArray(), ","); int kflidFT = SegmentFreeTranslationFlid(cache); if (cache.DatabaseAccessor != null) { string sql = @"select seg.id, seg.BeginObject, seg.BeginOffset, seg.EndOffset, ft.id, ft.class$, ft.UpdStmp, ftc.Txt, ftc.Fmt from CmBaseAnnotation seg join CmIndirectAnnotation_AppliesTo ftseg on ftseg.Dst = seg.id join CmIndirectAnnotation_ ft on ft.id = ftseg.Src and ft.AnnotationType = " + hvoFt + @" left outer join CmAnnotation_Comment ftc on ftc.Obj = ft.id and ftc.ws = " + ws + @" where seg.id in (" + ids + ")"; IDbColSpec dcs = DbColSpecClass.Create(); dcs.Push((int) DbColType.koctBaseId, 0, 0, 0); // ID (of segment) dcs.Push((int) DbColType.koctObj, 1, (int) CmBaseAnnotation.CmBaseAnnotationTags.kflidBeginObject, 0); dcs.Push((int) DbColType.koctInt, 1, (int) CmBaseAnnotation.CmBaseAnnotationTags.kflidBeginOffset, 0); dcs.Push((int) DbColType.koctInt, 1, (int) CmBaseAnnotation.CmBaseAnnotationTags.kflidEndOffset, 0); dcs.Push((int) DbColType.koctObj, 1, kflidFT, 0); // Free translation indirect annotation dcs.Push((int) DbColType.koctInt, 5, (int) CmObjectFields.kflidCmObject_Class, 0); // class of FT annotation dcs.Push((int) DbColType.koctTimeStamp, 5, 0, 0); // timestamp of FT annotation dcs.Push((int)DbColType.koctMlsAlt, 5, (int)CmAnnotation.CmAnnotationTags.kflidComment, ws); dcs.Push((int)DbColType.koctFmt, 5, (int)CmAnnotation.CmAnnotationTags.kflidComment, ws); cache.LoadData(sql, dcs, 0); } // Make sure each segment has a free translation. foreach (int hvoSeg in segments) { int hvoFT = cache.GetObjProperty(hvoSeg, kflidFT); if (hvoFT == 0) { ICmIndirectAnnotation ann = CmIndirectAnnotation.CreateUnownedIndirectAnnotation(cache); ann.AppliesToRS.Append(hvoSeg); ann.AnnotationTypeRAHvo = hvoFt; cache.VwCacheDaAccessor.CacheObjProp(hvoSeg, kflidFT, ann.Hvo); } } }
/// <summary> /// get the ws at the twfic's BeginOffset in its paragraph. /// </summary> /// <param name="cache">The cache.</param> /// <param name="hvoTwfic">The hvo twfic.</param> /// <returns></returns> /// ------------------------------------------------------------------------------------ public static int GetTwficWs(FdoCache cache, int hvoTwfic) { Debug.Assert(cache.IsValidObject(hvoTwfic, CmBaseAnnotation.kClassId), String.Format("expected valid hvo({0}).", hvoTwfic)); if (hvoTwfic <= 0 && !cache.IsDummyObject(hvoTwfic)) throw new ArgumentException(String.Format("expected valid hvo({0}).", hvoTwfic)); int hvoPara = cache.GetObjProperty(hvoTwfic, (int)CmBaseAnnotation.CmBaseAnnotationTags.kflidBeginObject); int ichBeginOffset = cache.GetIntProperty(hvoTwfic, (int)CmBaseAnnotation.CmBaseAnnotationTags.kflidBeginOffset); int ws = GetWsAtParaOffset(cache, hvoPara, ichBeginOffset); return ws; }
private static bool WordformHasOccurrenceInParas(FdoCache cache, int wfid, int[] hvoParasInView, FDOSequencePropertyVirtualHandler segmentsVh) { foreach (StTxtPara para in new FdoObjectSet<StTxtPara>(cache, hvoParasInView, false, typeof(StTxtPara))) { // we don't want to reload/parse paragraphs that haven't been loaded in this context. We are just // trying to keep the cached data consistent in the view. if (!segmentsVh.IsPropInCache(cache.MainCacheAccessor, para.Hvo, 0)) continue; foreach (int hvoSeg in para.Segments) { foreach (int hvoSegForm in para.SegmentForms(hvoSeg)) { int hvoInstanceOf = cache.GetObjProperty(hvoSegForm, (int)CmAnnotation.CmAnnotationTags.kflidInstanceOf); if (wfid == hvoInstanceOf) return true; } } } return false; }
// 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(); }
// Generate a suitable string representation of a WfiGloss. // Todo: finish implementing (add the gloss!) static internal ITsString MakeGlossStringRep(int hvoGloss, FdoCache fdoCache, bool fUseStyleSheet) { ITsStrBldr tsb = TsStrBldrClass.Create(); int hvoWa = fdoCache.GetOwnerOfObject(hvoGloss); int hvoCategory = fdoCache.GetObjProperty(hvoWa, (int)WfiAnalysis.WfiAnalysisTags.kflidCategory); if(hvoCategory > 0) { ITsString tssPos = fdoCache.MainCacheAccessor.get_MultiStringAlt(hvoCategory, (int)CmPossibility.CmPossibilityTags.kflidAbbreviation, fdoCache.DefaultAnalWs); tsb.Replace(0, 0, tssPos.Text, PartOfSpeechTextProperties(fdoCache,false, fUseStyleSheet)); } else { tsb.Replace(0, 0, ksMissingString, PartOfSpeechTextProperties(fdoCache,false, fUseStyleSheet)); } tsb.Replace(tsb.Length, tsb.Length, " ", null); tsb.Replace(tsb.Length, tsb.Length, fdoCache.MainCacheAccessor.get_MultiStringAlt(hvoGloss, (int)WfiGloss.WfiGlossTags.kflidForm, fdoCache.DefaultAnalWs).Text, GlossTextProperties(fdoCache, false, fUseStyleSheet)); //indent tsb.Replace(0,0, " ", null); return tsb.GetString(); }