private void CopyAnalysesToNewWordform(ICollection<ISegment> originalOccurencesInTexts, IWfiWordform wfOld, IWfiWordform wfNew) { var shiftedSegments = new List<ISegment>(originalOccurencesInTexts.Count); foreach (IWfiAnalysis oldAnalysis in wfOld.AnalysesOC) { // Only copy approved analyses. if (oldAnalysis.GetAgentOpinion(m_cache.LangProject.DefaultUserAgent) != Opinions.approves) continue; IWfiAnalysis newAnalysis = FactWfiAnal.Create(); wfNew.AnalysesOC.Add(newAnalysis); foreach (var segment in originalOccurencesInTexts) { if (!m_changedParas.ContainsKey(segment.Owner.Hvo)) continue; // Skip shifting it for items that were not checked var analysisIdx = segment.AnalysesRS.IndexOf(oldAnalysis); while (analysisIdx > -1) { shiftedSegments.Add(segment); segment.AnalysesRS.RemoveAt(analysisIdx); segment.AnalysesRS.Insert(analysisIdx, newAnalysis); analysisIdx = segment.AnalysesRS.IndexOf(oldAnalysis); } } foreach (var shiftedSegment in shiftedSegments) { originalOccurencesInTexts.Remove(shiftedSegment); } shiftedSegments.Clear(); foreach (IWfiGloss oldGloss in oldAnalysis.MeaningsOC) { IWfiGloss newGloss = FactWfiGloss.Create(); newAnalysis.MeaningsOC.Add(newGloss); newGloss.Form.CopyAlternatives(oldGloss.Form); foreach (var segment in originalOccurencesInTexts) { if (!m_changedParas.ContainsKey(segment.Owner.Hvo)) continue; // Skip shifting it for items that were not checked var glossIdx = segment.AnalysesRS.IndexOf(oldGloss); while (glossIdx > -1) { shiftedSegments.Add(segment); segment.AnalysesRS.RemoveAt(glossIdx); segment.AnalysesRS.Insert(glossIdx, newGloss); glossIdx = segment.AnalysesRS.IndexOf(oldGloss); } } } foreach (var shiftedSegment in shiftedSegments) { originalOccurencesInTexts.Remove(shiftedSegment); } foreach (IWfiMorphBundle bundle in oldAnalysis.MorphBundlesOS) { IWfiMorphBundle newBundle = FactWfiMB.Create(); newAnalysis.MorphBundlesOS.Add(newBundle); newBundle.Form.CopyAlternatives(bundle.Form); newBundle.SenseRA = bundle.SenseRA; newBundle.MorphRA = bundle.MorphRA; newBundle.MsaRA = bundle.MsaRA; } } }
private void ProcessAnalysesAndLexEntries(ProgressDialogWorkingOn progress, IWfiWordform wfOld, IWfiWordform wfNew) { wfOld.SpellingStatus = (int)SpellingStatusStates.incorrect; //if (UpdateLexicalEntries) //{ // foreach (IWfiAnalysis wa in wfOld.AnalysesOC) // { // if (wa.MorphBundlesOS.Count == 1) // { // } // } //} if (!KeepAnalyses) { // Remove multi-morpheme anals in src wf. List<IWfiAnalysis> goners = new List<IWfiAnalysis>(); foreach (IWfiAnalysis goner in wfOld.AnalysesOC) { if (goner.MorphBundlesOS.Count > 1) { goners.Add(goner); } } foreach (IWfiAnalysis goner in goners) { IWfiWordform wf = goner.OwnerOfClass<IWfiWordform>(); wf.AnalysesOC.Remove(goner); } goners.Clear(); } if (UpdateLexicalEntries) { // Change LE allo on single morpheme anals. foreach (IWfiAnalysis update in wfOld.AnalysesOC) { if (update.MorphBundlesOS.Count != 1) continue; // Skip any with zero or more than one. IWfiMorphBundle mb = update.MorphBundlesOS[0]; ITsString tss = mb.Form.get_String(m_vernWs); string srcForm = tss.Text; if (srcForm != null) { // Change morph bundle form. mb.Form.set_String(m_vernWs, NewSpelling); } IMoForm mf = mb.MorphRA; if (mf != null) { mf.Form.set_String(m_vernWs, NewSpelling); } } } // Move remaining anals from src wf to new wf. // This changes the owners of the remaining ones, // since it is an owning property. var analyses = new List<IWfiAnalysis>(); analyses.AddRange(wfOld.AnalysesOC); foreach (var anal in analyses) wfNew.AnalysesOC.Add(anal); }
/// <summary> /// Set up the referring lexical entries of an entry /// </summary> /// <param name="lexicalRelationHvos">an array of lexical relation HVOs</param> private void SetupLexRelsForEntry(int[] lexicalRelationHvos) { m_cdaTemp.CacheVecProp(m_hvoEntry, RelatedWordsVc.ktagLexRels, lexicalRelationHvos, lexicalRelationHvos.Length); var references = new List<int>(); var lexRefRepository = m_cache.ServiceLocator.GetInstance<ILexReferenceRepository>(); var lexEntry = m_cache.ServiceLocator.GetInstance<ILexEntryRepository>().GetObject(m_hvoEntry); var targets = new HashSet<ICmObject>(lexEntry.AllSenses.Cast<ICmObject>()) { lexEntry }; foreach (var hvoLexRel in lexicalRelationHvos) { var lexReference = lexRefRepository.GetObject(hvoLexRel); foreach (ICmObject target in lexReference.TargetsRS) { // If at least one target is the lex entry or one of its senses. if ((from t in lexReference.TargetsRS where targets.Contains(t) select t).FirstOrDefault() != null && (from t in lexReference.TargetsRS where !targets.Contains(t) select t).FirstOrDefault() != null) { ILexEntry targetEntry = target is ILexSense ? target.OwnerOfClass(LexEntryTags.kClassId) as ILexEntry : target as ILexEntry; if (targetEntry != null && targetEntry.Hvo != m_hvoEntry && targetEntry.LexemeFormOA != null && targetEntry.LexemeFormOA.Form != null) { references.Add(targetEntry.Hvo); m_cdaTemp.CacheStringProp(targetEntry.Hvo, RelatedWordsVc.ktagName, targetEntry.HeadWord); } } } if (references.Count > 0) { m_cdaTemp.CacheVecProp(hvoLexRel, RelatedWordsVc.ktagWords, references.ToArray(), references.Count); references.Clear(); } } }
/// <summary> /// Set up the referring semantic domains for the domains found of an entry /// </summary> /// <param name="semanticDomainHvos">an array of semantic domain HVOs</param> void SetupDomainsForEntry(int[] semanticDomainHvos) { m_cdaTemp.CacheVecProp(m_hvoEntry, RelatedWordsVc.ktagDomains, semanticDomainHvos, semanticDomainHvos.Length); var entries = new List<int>(); var semanticDomainRepository = m_cache.ServiceLocator.GetInstance<ICmSemanticDomainRepository>(); foreach (var semanticDomainhvo in semanticDomainHvos) { var semanticDomain = semanticDomainRepository.GetObject(semanticDomainhvo); foreach (ICmObject obj in semanticDomain.ReferringObjects) { if (obj is ILexSense && (obj as ILexSense).SemanticDomainsRC.Contains(semanticDomain)) { var entry = obj.OwnerOfClass(LexEntryTags.kClassId) as ILexEntry; if (entry != null && entry.LexemeFormOA != null && entry.LexemeFormOA.Form != null) { entries.Add(entry.Hvo); m_cdaTemp.CacheStringProp(entry.Hvo, RelatedWordsVc.ktagName, entry.LexemeFormOA.Form.VernacularDefaultWritingSystem); } } } if (entries.Count > 0) { m_cdaTemp.CacheVecProp(semanticDomainhvo, RelatedWordsVc.ktagWords, entries.ToArray(), entries.Count); entries.Clear(); } } }
/// <summary> /// Core of the DoIt method, may be called with or without progress dialog. /// </summary> /// <param name="dlg"></param> private void CoreDoIt(ProgressDialogWorkingOn dlg) { // While we do the changes which we can much more efficiently Undo/Redo in this action, // we don't want the various changes we make generating masses of SqlUndoActions. IActionHandler handler = m_cache.ActionHandlerAccessor; m_cache.MainCacheAccessor.SetActionHandler(null); m_hvoNewWf = WfiWordform.FindOrCreateWordform(m_cache, m_newSpelling, m_vernWs, true); try { foreach (KeyValuePair<int, ParaChangeInfo> pair in m_changedParas) { UpdateOffsets(pair.Key, pair.Value); // Review JohnT: should we do the PropChanged, or not?? If not, we should force // a Refresh when the dialog closes. if (!pair.Value.OldContents.Equals(pair.Value.NewContents)) pair.Value.SetString(m_cache, pair.Value.NewContents, true); UpdateProgress(dlg); } UpdateInstanceOf(m_hvoNewWf, dlg); } finally { m_cache.MainCacheAccessor.SetActionHandler(handler); } if (dlg != null) dlg.WorkingOnText = MEStrings.ksDealingAnalyses; m_cache.BeginUndoTask(string.Format(MEStrings.ksUndoChangeSpelling, m_oldSpelling, m_newSpelling), string.Format(MEStrings.ksRedoChangeSpelling, m_oldSpelling, m_newSpelling)); m_cache.ActionHandlerAccessor.AddAction(this); UpdateProgress(dlg); // The destination wordform really exists and should be marked correct. IWfiWordform wf = WfiWordform.CreateFromDBObject(m_cache, m_hvoNewWf); m_oldOccurrencesNewWf = wf.OccurrencesInTexts.ToArray(); m_fWasNewSpellingCorrect = wf.SpellingStatus == (int)SpellingStatusStates.correct; wf.SpellingStatus = (int)SpellingStatusStates.correct; EnchantHelper.SetSpellingStatus(m_newSpelling, m_vernWs, m_cache.LanguageWritingSystemFactoryAccessor, true); UpdateProgress(dlg); m_hvoOldWf = WfiWordform.FindOrCreateWordform(m_cache, m_oldSpelling, m_vernWs, true); IWfiWordform wfOld = WfiWordform.CreateFromDBObject(m_cache, m_hvoOldWf); m_oldOccurrencesOldWf = wfOld.OccurrencesInTexts.ToArray(); m_fWasOldSpellingCorrect = wfOld.SpellingStatus == (int)SpellingStatusStates.correct; UpdateProgress(dlg); // Compute new occurrence lists, save and cache Set<int> changes = new Set<int>(); foreach (ParaChangeInfo info in m_changedParas.Values) changes.AddRange(info.Changes); if (AllChanged) { m_newOccurrencesOldWf = new int[0]; // no remaining occurrences } else { // Only some changed, need to figure m_newOccurrences List<int> newOccurrencesOldWf = new List<int>(); foreach (int hvo in m_oldOccurrencesOldWf) if (!changes.Contains(hvo)) newOccurrencesOldWf.Add(hvo); m_newOccurrencesOldWf = newOccurrencesOldWf.ToArray(); } UpdateProgress(dlg); List<int> newOccurrences = new List<int>(m_oldOccurrencesNewWf.Length + changes.Count); newOccurrences.AddRange(m_oldOccurrencesNewWf); foreach (int hvo in changes) { if (m_cache.IsDummyObject(hvo)) // if this is a dummy annotation, make sure we update the owner m_cache.VwCacheDaAccessor.CacheObjProp(hvo, (int)CmObjectFields.kflidCmObject_Owner, m_hvoNewWf); newOccurrences.Add(hvo); } m_newOccurrencesNewWf = newOccurrences.ToArray(); int vhId = BaseVirtualHandler.GetInstalledHandlerTag(m_cache, "WfiWordform", "OccurrencesInTexts"); m_cache.VwCacheDaAccessor.CacheVecProp(m_hvoOldWf, vhId, m_newOccurrencesOldWf, m_newOccurrencesOldWf.Length); m_cache.VwCacheDaAccessor.CacheVecProp(m_hvoNewWf, vhId, m_newOccurrencesNewWf, m_newOccurrencesNewWf.Length); SendCountVirtualPropChanged(m_hvoNewWf); SendCountVirtualPropChanged(m_hvoOldWf); UpdateProgress(dlg); // Deal with analyses. if (CopyAnalyses) { foreach (WfiAnalysis analysis in wfOld.AnalysesOC) { // Only copy approved analyses. if (analysis.GetAgentOpinion(m_cache.LangProject.DefaultUserAgent) != Opinions.approves) continue; IWfiAnalysis newAnalysis = wf.AnalysesOC.Add(new WfiAnalysis()); foreach (WfiGloss gloss in analysis.MeaningsOC) { IWfiGloss newGloss = newAnalysis.MeaningsOC.Add(new WfiGloss()); newGloss.Form.CopyAlternatives(gloss.Form); } foreach (WfiMorphBundle bundle in analysis.MorphBundlesOS) { IWfiMorphBundle newBundle = newAnalysis.MorphBundlesOS.Append(new WfiMorphBundle()); newBundle.Form.CopyAlternatives(bundle.Form); newBundle.SenseRA = bundle.SenseRA; newBundle.MorphRA = bundle.MorphRA; newBundle.MsaRA = bundle.MsaRA; } } } UpdateProgress(dlg); if (AllChanged) { wfOld.SpellingStatus = (int)SpellingStatusStates.incorrect; EnchantHelper.SetSpellingStatus(m_oldSpelling, m_vernWs, m_cache.LanguageWritingSystemFactoryAccessor, false); if (UpdateLexicalEntries) { foreach (WfiAnalysis wa in wfOld.AnalysesOC) { if (wa.MorphBundlesOS.Count == 1) { } } } if (!KeepAnalyses) { // Remove multi-morpheme anals in src wf. List<IWfiAnalysis> goners = new List<IWfiAnalysis>(); foreach (IWfiAnalysis goner in wfOld.AnalysesOC) { if (goner.MorphBundlesOS.Count > 1) goners.Add(goner); } foreach (IWfiAnalysis goner in goners) { goner.DeleteUnderlyingObject(); // This will shift twfic pointers up to wordform, if needed. } goners.Clear(); } if (UpdateLexicalEntries) { // Change LE allo on single morpheme anals. foreach (IWfiAnalysis update in wfOld.AnalysesOC) { if (update.MorphBundlesOS.Count == 1) { IWfiMorphBundle mb = update.MorphBundlesOS[0]; TsStringAccessor tsa = mb.Form.GetAlternative(m_vernWs); string srcForm = tsa.Text; if (srcForm != null) { // Change morph bundle form. mb.Form.SetAlternative(m_newSpelling, m_vernWs); } IMoForm mf = mb.MorphRA; if (mf != null) { mf.Form.SetAlternative(m_newSpelling, m_vernWs); } } } } // Move remaining anals from src wf to new wf. // This changes the owners of the remaining ones, // since it is an owning property. wf.AnalysesOC.Add(wfOld.AnalysesOC.HvoArray); SendAnalysisVirtualPropChanged(m_hvoNewWf); SendAnalysisVirtualPropChanged(m_hvoOldWf); UpdateProgress(dlg); } m_cache.EndUndoTask(); }
private List<int> CollectSegmentForms(int ichMinCurSeg, int ichLimCurSeg, ref int ichLimLast, ref ITsString tssFirstWordOfNextSegment) { List<int> formsInSegment = new List<int>(); List<int> punctuationAnnotations = new List<int>(); int ichMin, ichLim; m_wordMaker.CurrentCharOffset = ichMinCurSeg; ITsString tssWord; if (tssFirstWordOfNextSegment != null) { tssWord = tssFirstWordOfNextSegment; // back up by this word. ichLim = ichMinCurSeg; ichMin = ichLim - tssWord.Length; } else { tssWord = m_wordMaker.NextWord(out ichMin, out ichLim); } int ctwfics = 0; do { if (tssWord == null) { // we've run out of twfics. collect the last remaining punctuation annotations. //Debug.Assert(m_tssPara.Length == ichLimCurSeg); CreatePunctAnnotations(ichLimLast, ichLimCurSeg, punctuationAnnotations); break; } if (ichLimLast != ichMin) { // we need to add punctuations to the current segment. CreatePunctAnnotations(ichLimLast, Math.Min(ichMin, ichLimCurSeg), punctuationAnnotations); formsInSegment.AddRange(punctuationAnnotations); punctuationAnnotations.Clear(); if (ichMin >= ichLimCurSeg) { // we need to add this twfic to the next segment. tssFirstWordOfNextSegment = tssWord; ichLimLast = ichLimCurSeg; break; } } // Create (or reuse if possible) twfic annotations. ITsString tssWordAnn; formsInSegment.Add(CreateOrReuseAnnotation(tssWord, ichMin, ichLim, ctwfics, out tssWordAnn)); if (tssWordAnn != null && tssWord.Length < tssWordAnn.Length) { // this must be a phrase, so advance appropriately in the text. ichLimLast = ichMin + tssWordAnn.Length; m_wordMaker.CurrentCharOffset = ichLimLast; } else { // still stepping by the word boundary. ichLimLast = ichLim; } ctwfics++; tssWord = m_wordMaker.NextWord(out ichMin, out ichLim); } while (true); formsInSegment.AddRange(punctuationAnnotations); return formsInSegment; }
private void ExportRecord(TextWriter writer, IRnGenericRec record, int level) { writer.WriteLine( "<Entry level=\"{0}\" dateCreated=\"{1}\" dateModified=\"{2}\" guid=\"{3}\">", level, record.DateCreated.ToString("yyyy-MM-ddThh:mm:ss"), record.DateModified.ToString("yyyy-MM-ddThh:mm:ss"), record.Guid); ExportString(writer, record.Title, "Title"); ExportAtomicReference(writer, record.TypeRA, "Type", "CmPossibility"); List<ICmPossibility> collection = new List<ICmPossibility>(); collection.AddRange(record.RestrictionsRC); ExportReferenceList(writer, collection, "Restrictions", "CmPossibility", CellarPropertyType.ReferenceCollection); collection.Clear(); if (!record.DateOfEvent.IsEmpty) { writer.WriteLine("<Field name=\"DateOfEvent\" type=\"GenDate\" card=\"atomic\">"); writer.WriteLine("<Item ws=\"{0}\">{1}</Item>", UserWsTag, XmlUtils.MakeSafeXml(record.DateOfEvent.ToXMLExportShortString())); writer.WriteLine("</Field>"); } collection.AddRange(record.TimeOfEventRC); ExportReferenceList(writer, collection, "TimeOfEvent", "CmPossibility", CellarPropertyType.ReferenceCollection); collection.Clear(); collection.AddRange(record.ResearchersRC.ToArray()); ExportReferenceList(writer, collection, "Researchers", "CmPerson", CellarPropertyType.ReferenceCollection); collection.Clear(); collection.AddRange(record.SourcesRC.ToArray()); ExportReferenceList(writer, collection, "Sources", "CmPerson", CellarPropertyType.ReferenceCollection); collection.Clear(); ExportAtomicReference(writer, record.ConfidenceRA, "Confidence", "CmPossibility"); if (record.ParticipantsOC != null && record.ParticipantsOC.Count > 0) { foreach (var part in record.ParticipantsOC) { collection.AddRange(part.ParticipantsRC.ToArray()); if (part.RoleRA != null) { int wsRole; ITsString tssRole = part.RoleRA.Name.GetAlternativeOrBestTss(m_cache.DefaultAnalWs, out wsRole); ExportReferenceList(writer, collection, tssRole.Text, "RnRoledPartic", CellarPropertyType.ReferenceCollection); } else { ExportReferenceList(writer, collection, "Participants", "RnRoledPartic", CellarPropertyType.ReferenceCollection); } collection.Clear(); } } if (record.LocationsRC != null && record.LocationsRC.Count > 0) { collection.AddRange(record.LocationsRC.ToArray()); ExportReferenceList(writer, collection, "Locations", "CmLocation", CellarPropertyType.ReferenceCollection); collection.Clear(); } ExportStText(writer, record.DescriptionOA, "Description"); ExportStText(writer, record.HypothesisOA, "Hypothesis"); ExportAtomicReference(writer, record.StatusRA, "Status", "CmPossibility"); ExportStText(writer, record.DiscussionOA, "Discussion"); if (record.AnthroCodesRC != null && record.AnthroCodesRC.Count > 0) { writer.WriteLine("<Field name=\"AnthroCodes\" type=\"CmAnthroItem\" card=\"collection\">"); foreach (var item in record.AnthroCodesRC) writer.WriteLine("<Item ws=\"{0}\">{1}</Item>", AnalWsTag, XmlUtils.MakeSafeXml(item.AbbrAndName)); writer.WriteLine("</Field>"); } ExportStText(writer, record.ConclusionsOA, "Conclusions"); if (record.SupportingEvidenceRS != null && record.SupportingEvidenceRS.Count > 0) { writer.WriteLine("<Field name=\"SupportingEvidence\" type=\"RnGenericRec\" card=\"sequence\">"); foreach (var item in record.SupportingEvidenceRS) { writer.WriteLine("<Item guid=\"{0}\" ws=\"{1}\">{2}</Item>", item.Guid, AnalWsTag, GetLinkLabelForRecord(item)); } writer.WriteLine("</Field>"); } if (record.CounterEvidenceRS != null && record.CounterEvidenceRS.Count > 0) { writer.WriteLine("<Field name=\"CounterEvidence\" type=\"RnGenericRec\" card=\"sequence\">"); foreach (var item in record.CounterEvidenceRS) { writer.WriteLine("<Item guid=\"{0}\" ws=\"{1}\">{2}</Item>", item.Guid, AnalWsTag, GetLinkLabelForRecord(item)); } writer.WriteLine("</Field>"); } if (record.SupersededByRC != null && record.SupersededByRC.Count > 0) { writer.WriteLine("<Field name=\"SupersededBy\" type=\"RnGenericRec\" card=\"collection\">"); foreach (var item in record.SupersededByRC) { writer.WriteLine("<Item guid=\"{0}\" ws=\"{1}\">{2}</Item>", item.Guid, AnalWsTag, GetLinkLabelForRecord(item)); } writer.WriteLine("</Field>"); } if (record.SeeAlsoRC != null && record.SeeAlsoRC.Count > 0) { writer.WriteLine("<Field name=\"SeeAlso\" type=\"RnGenericRec\" card=\"collection\">"); foreach (var item in record.SeeAlsoRC) { writer.WriteLine("<Item guid=\"{0}\" ws=\"{1}\">{2}</Item>", item.Guid, AnalWsTag, GetLinkLabelForRecord(item)); } writer.WriteLine("</Field>"); } ExportStText(writer, record.ExternalMaterialsOA, "ExternalMaterials"); ExportStText(writer, record.FurtherQuestionsOA, "FurtherQuestions"); ExportStText(writer, record.ResearchPlanOA, "ResearchPlan"); ExportStText(writer, record.PersonalNotesOA, "PersonalNotes"); // The following are in the model, but not used in practice. //ExportStText(writer, record.VersionHistoryOA, "VersionHistory"); //if (record.RemindersRC != null && record.RemindersRC.Count > 0) // MessageBox.Show("Cannot export Reminders from RnGenericRec", "Not yet implemented"); //if (record.CrossReferencesRC != null && record.CrossReferencesRC.Count > 0) // MessageBox.Show("Cannot export CrossReferences from RnGenericRec", "Not yet implemented"); ExportCustomFields(writer, record); if (record.SubRecordsOS != null && record.SubRecordsOS.Count > 0) { writer.WriteLine("<Field name=\"Subentries\" type=\"RnGenericRec\" card=\"sequence\">"); foreach (var subrec in record.SubRecordsOS) ExportRecord(writer, subrec, level + 1); writer.WriteLine("</Field>"); } writer.WriteLine("</Entry>"); }