private void CreateReversalIndexDlg_FormClosing(object sender, FormClosingEventArgs e) { switch (DialogResult) { default: { Debug.Assert(false, "Unexpected DialogResult."); break; } case DialogResult.Cancel: { if (!m_btnCancel.Visible) { e.Cancel = true; MessageBox.Show(LexEdStrings.ksMustSelectOne); } break; } case DialogResult.OK: { var wsObj = m_cbWritingSystems.SelectedItem as IWritingSystem; if (wsObj != null) { UndoableUnitOfWorkHelper.Do(LexEdStrings.ksUndoCreateReversalIndex, LexEdStrings.ksRedoCreateReversalIndex, m_cache.ActionHandlerAccessor, () => { var riRepo = m_cache.ServiceLocator.GetInstance <IReversalIndexRepository>(); m_hvoRevIdx = riRepo.FindOrCreateIndexForWs(wsObj.Handle).Hvo; }); } break; } } }
public void AllReferencedObjects() { UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { var entry1 = MakeEntry("kick", "strike with foot"); var sense1 = entry1.SensesOS[0]; var referencedObjectCollector = new List <ICmObject>(); entry1.AllReferencedObjects(referencedObjectCollector); Assert.That(referencedObjectCollector, Is.Empty); // atomic var mb = MakeBundle("kick", sense1); mb.AllReferencedObjects(referencedObjectCollector); Assert.That(referencedObjectCollector, Has.Member(sense1).And.Count.EqualTo(1)); // sequence. var entry2 = MakeEntry("punch", "strike with fist"); entry2.MainEntriesOrSensesRS.Add(entry1); entry2.AllReferencedObjects(referencedObjectCollector); Assert.That(referencedObjectCollector, Has.Member(sense1), "still there...checks it adds things"); Assert.That(referencedObjectCollector, Has.Member(entry1).And.Count.EqualTo(2)); // colletion var dtList = Cache.LangProject.LexDbOA.DomainTypesOA; if (dtList == null) { dtList = Cache.ServiceLocator.GetInstance <ICmPossibilityListFactory>().Create(); Cache.LangProject.LexDbOA.DomainTypesOA = dtList; } var item = Cache.ServiceLocator.GetInstance <ICmPossibilityFactory>().Create(); dtList.PossibilitiesOS.Add(item); sense1.DomainTypesRC.Add(item); referencedObjectCollector.Clear(); sense1.AllReferencedObjects(referencedObjectCollector); Assert.That(referencedObjectCollector, Has.Member(item).And.Count.EqualTo(1)); }); }
private void SetNewStatus(IWfiAnalysis anal, int newStatus) { int currentStatus = anal.ApprovalStatusIcon; if (currentStatus == newStatus) { return; } UndoableUnitOfWorkHelper.Do(MEStrings.ksUndoChangingApprovalStatus, MEStrings.ksRedoChangingApprovalStatus, Cache.ActionHandlerAccessor, () => { if (currentStatus == 1) { anal.MoveConcAnnotationsToWordform(); } anal.ApprovalStatusIcon = newStatus; if (newStatus == 1) { // make sure default senses are set to be real values, // since the user has seen the defaults, and approved the analysis based on them. foreach (var mb in anal.MorphBundlesOS) { var currentSense = mb.SenseRA; if (currentSense == null) { mb.SenseRA = mb.DefaultSense; } } } }); // Wipe all of the old slices out, so we get new numbers and newly placed objects. // This fixes LT-5935. Also removes the need to somehow make the virtual properties like HumanApprovedAnalyses update. m_dataEntryForm.RefreshList(true); }
public override ObjectLabel Execute() { ObjectLabel result = null; if (m_lexEntry != null) { using (var dlg = new EntryGoDlg()) { dlg.SetDlgInfo(m_cache, null, m_mediator); dlg.SetHelpTopic("khtpChooseLexicalEntryOrSense"); // TODO: When LT-11318 is fixed, use its help topic ID. dlg.SetOkButtonText(LexEdStrings.ksMakeComponentOf); if (dlg.ShowDialog(m_parentWindow) == DialogResult.OK) { try { if (m_lexSense != null) { UndoableUnitOfWorkHelper.Do(LexEdStrings.ksUndoAddComplexForm, LexEdStrings.ksRedoAddComplexForm, m_lexEntry.Cache.ActionHandlerAccessor, () => ((ILexEntry)dlg.SelectedObject).AddComponent((ICmObject)m_lexSense ?? m_lexEntry)); } else { UndoableUnitOfWorkHelper.Do(LexEdStrings.ksUndoAddComplexForm, LexEdStrings.ksRedoAddComplexForm, m_lexEntry.Cache.ActionHandlerAccessor, () => ((ILexEntry)dlg.SelectedObject).AddComponent(m_lexEntry)); } } catch (ArgumentException) { MessageBoxes.ReportLexEntryCircularReference((ILexEntry)dlg.SelectedObject, m_lexEntry, false); } } } } return(result); }
public void AtomicItemTests() { var lp = Cache.ServiceLocator.GetInstance <ILangProjectRepository>().AllInstances().First(); // Delete current value. UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => lp.AnthroListOA = null); CheckChanges(1, 0, lp.Hvo, LangProjectTags.kflidAnthroList, 0, 0, 1); ClearChanges(); m_actionHandler.Undo(); CheckChanges(1, 0, lp.Hvo, LangProjectTags.kflidAnthroList, 0, 1, 0); m_actionHandler.Redo(); ClearChanges(); // Insert new value. UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { lp.AnthroListOA = Cache.ServiceLocator.GetInstance <ICmPossibilityListFactory>().Create(); }); CheckChanges(1, 0, lp.Hvo, LangProjectTags.kflidAnthroList, 0, 1, 0); ClearChanges(); m_actionHandler.Undo(); CheckChanges(1, 0, lp.Hvo, LangProjectTags.kflidAnthroList, 0, 0, 1); m_actionHandler.Redo(); ClearChanges(); // Replace current non-null value. UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { lp.AnthroListOA = Cache.ServiceLocator.GetInstance <ICmPossibilityListFactory>().Create(); }); CheckChanges(1, 0, lp.Hvo, LangProjectTags.kflidAnthroList, 0, 1, 1); ClearChanges(); m_actionHandler.Undo(); CheckChanges(1, 0, lp.Hvo, LangProjectTags.kflidAnthroList, 0, 1, 1); m_actionHandler.Redo(); ClearChanges(); }
public void OnChanged(Object obj, EventArgs args) { CheckDisposed(); if (!Object.IsValidObject) { return; } UndoableUnitOfWorkHelper.Do(string.Format(DetailControlsStrings.ksUndoChange, m_fieldName), string.Format(DetailControlsStrings.ksRedoChange, m_fieldName), Object, () => { var fValue = ((CheckBox)obj).Checked; if (m_fToggleValue) { fValue = !fValue; } IntBoolPropertyConverter.SetValueFromBoolean( m_cache.ServiceLocator.GetInstance <ISilDataAccessManaged>(), Object.Hvo, m_flid, fValue); }); }
public bool OnPromoteReversalSubPOS(object cmd) { Slice slice = m_dataEntryForm.CurrentSlice; Debug.Assert(slice != null, "No slice was current"); if (slice != null) { FdoCache cache = m_dataEntryForm.Cache; var sliceObj = slice.Object as ICmPossibility; var newOwner = sliceObj.Owner.Owner; switch (newOwner.ClassID) { default: throw new ArgumentException("Illegal class."); case PartOfSpeechTags.kClassId: { var pos = (IPartOfSpeech)newOwner; UndoableUnitOfWorkHelper.Do(LexEdStrings.ksUndoPromote, LexEdStrings.ksRedoPromote, pos.Cache.ActionHandlerAccessor, () => pos.SubPossibilitiesOS.Add(sliceObj)); break; } case CmPossibilityListTags.kClassId: { var posList = (ICmPossibilityList)newOwner; UndoableUnitOfWorkHelper.Do(LexEdStrings.ksUndoPromote, LexEdStrings.ksRedoPromote, posList.Cache.ActionHandlerAccessor, () => posList.PossibilitiesOS.Add(sliceObj)); break; } } } return(true); }
public void MergeWritingSystem_ConvertsLiftResidue() { CoreWritingSystemDefinition fromWs; WritingSystemServices.FindOrCreateWritingSystem(Cache, null, "en-NO", true, false, out fromWs); CoreWritingSystemDefinition toWs; WritingSystemServices.FindOrCreateWritingSystem(Cache, null, "en-SO", true, false, out toWs); EnsureAnalysisWs(new[] { fromWs, toWs }); var entry1 = Cache.ServiceLocator.GetInstance <ILexEntryFactory>().Create(); entry1.LiftResidue = "<lift-residue id=\"aj1_8ef13061-21ae-480f-b3a9-6b694e1ec3c4\" dateCreated=\"2005-11-09T02:57:45Z\" dateModified=\"2010-07-03T08:15:00Z\"><field type=\"Source Language\">" + "<form lang=\"en\"><text>Proto-Tai</text></form>" + "<form lang=\"en-NO\"><text>¥ポ¥ᄃヒ¥マᄚ│ᆵᆳ</text></form>" + "</field>" + "</lift-residue>"; m_actionHandler.EndUndoTask(); UndoableUnitOfWorkHelper.Do("doit", "undoit", m_actionHandler, () => WritingSystemServices.MergeWritingSystems(Cache, fromWs, toWs)); Assert.That(entry1.LiftResidue.Contains("lang=\"en-SO\"")); }
public void SenseSearch_2WordDefinitionUsed() { //Setup const string searchString = "sky, God"; const string expectedNum1 = "1.1"; // bucket0 match 'sky' const string expectedNum2 = "8.3.3"; // bucket0 match 'Light' const string expectedNum3 = "1.1.8"; // bucket1 match 'solar', under 'Sun' This does not exist const string expectedNum4 = "4.9.6"; // bucket1 match 'God', under 'Heaven, Hell' IEnumerable <ICmSemanticDomain> partialMatches; var entry = CreateLexEntry("waas", searchString); var sense = entry.SensesOS[0]; UndoableUnitOfWorkHelper.Do("Undo def", "Redo def", Cache.ActionHandlerAccessor, () => sense.Definition.SetAnalysisDefaultWritingSystem("Solar light")); // SUT var result = m_semdomRepo.FindDomainsThatMatchWordsIn(sense, out partialMatches); // Verification var resultList = result.ToList(); var partialsList = partialMatches.ToList(); var cresult = resultList.Count; var cpartials = partialsList.Count; Assert.AreEqual(4, cresult, WRONG_NUMBER_OF_MATCHES); Assert.AreEqual(0, cpartials, WRONG_NUMBER_OF_MATCHES); Assert.AreEqual(expectedNum1, resultList[0].Abbreviation.AnalysisDefaultWritingSystem.Text, WRONG_SEMDOM_NUMBER); Assert.AreEqual(expectedNum2, resultList[1].Abbreviation.AnalysisDefaultWritingSystem.Text, WRONG_SEMDOM_NUMBER); Assert.AreEqual(expectedNum3, resultList[2].Abbreviation.AnalysisDefaultWritingSystem.Text, WRONG_SEMDOM_NUMBER); Assert.AreEqual(expectedNum4, resultList[3].Abbreviation.AnalysisDefaultWritingSystem.Text, WRONG_SEMDOM_NUMBER); }
public void MakeContextMenu_CheckedStates_SelFirstOfTag() { // Provide hvoTagPoss and SelectedWordforms, create a markup tag and examine it. // Setup the SelectedWordforms property var tempList = new List <AnalysisOccurrence> { m_occurrences[0], m_occurrences[1], m_occurrences[2] }; m_tagChild.SelectedWordforms = tempList; // Make a tag for selection const int itestItem = 0; // first tag in list UndoableUnitOfWorkHelper.Do("UndoTagTest", "RedoTagTest", Cache.ActionHandlerAccessor, () => m_tagChild.CallMakeTextTagInstance(m_possTags[itestItem])); // Reduce selection to first word tempList.Remove(m_occurrences[1]); tempList.Remove(m_occurrences[2]); m_tagChild.SelectedWordforms = tempList; // SUT using (var menu = new ContextMenuStrip()) { m_tagChild.CallMakeContextMenuForTags(menu, m_textMarkupTags); // Verification of SUT; Only one should be checked and that in a submenu var subList = AssertHasMenuWithText(menu.Items, kFTO_RRG_Semantics, 3); Assert.IsNotNull(subList, "No " + kFTO_RRG_Semantics + " menu!?"); var subMenu = subList.DropDownItems; var expectedStates = new bool[subMenu.Count]; expectedStates[itestItem] = true; AssertMenuCheckState(expectedStates, subMenu); } }
public void AddToDatabase(FdoCache cache, ICmPossibilityList posList, MasterCategory parent, IPartOfSpeech subItemOwner) { if (m_pos != null) { return; // It's already in the database, so nothing more can be done. } UndoableUnitOfWorkHelper.Do(LexTextControls.ksUndoCreateCategory, LexTextControls.ksRedoCreateCategory, cache.ServiceLocator.GetInstance <IActionHandler>(), () => { int newOwningFlid; int insertLocation; int newOwner = DeterminePOSLocationInfo(cache, subItemOwner, parent, posList, out newOwningFlid, out insertLocation); ILgWritingSystemFactory wsf = cache.WritingSystemFactory; Debug.Assert(m_pos != null); int termWs = wsf.GetWsFromStr(m_termWs); int abbrevWs = wsf.GetWsFromStr(m_abbrevWs); int defWs = wsf.GetWsFromStr(m_defWs); ITsStrFactory tsf = cache.TsStrFactory; if (m_node == null) { // should not happen, but just in case... we still get something useful m_pos.Name.set_String(termWs, tsf.MakeString(m_term, termWs)); m_pos.Abbreviation.set_String(abbrevWs, tsf.MakeString(m_abbrev, abbrevWs)); m_pos.Description.set_String(defWs, tsf.MakeString(m_def, defWs)); } else { SetContentFromNode(cache, "abbrev", false, m_pos.Abbreviation); SetContentFromNode(cache, "term", true, m_pos.Name); SetContentFromNode(cache, "def", false, m_pos.Description); } m_pos.CatalogSourceId = m_id; }); }
public void MakeTagAnnot_MultipleExistTags_Overlap() { // This test will need changing when we allow multiple lines of tagging. // Setup the SelectedWordforms property for first (existing) tag var tempList = new List <AnalysisOccurrence> { m_occurrences[1], m_occurrences[2] }; m_tagChild.SelectedWordforms = tempList; var hvoTag1 = -1; UndoableUnitOfWorkHelper.Do("UndoTagTest", "RedoTagTest", Cache.ActionHandlerAccessor, () => { var oldTag1 = m_tagChild.CallMakeTextTagInstance(m_possTags[0]); if (oldTag1 != null) { hvoTag1 = oldTag1.Hvo; } }); // Setup the SelectedWordforms property for second (existing) tag var tempList1 = new List <AnalysisOccurrence> { m_occurrences[3], m_occurrences[4] }; m_tagChild.SelectedWordforms = tempList1; var hvoTag2 = -1; UndoableUnitOfWorkHelper.Do("UndoTagTest", "RedoTagTest", Cache.ActionHandlerAccessor, () => { var oldTag2 = m_tagChild.CallMakeTextTagInstance(m_possTags[1]); if (oldTag2 != null) { hvoTag2 = oldTag2.Hvo; } }); // Setup the SelectedWordforms property for SUT tag // These overlap with both existing tags var tempList2 = new List <AnalysisOccurrence> { m_occurrences[2], m_occurrences[3] }; m_tagChild.SelectedWordforms = tempList2; // SUT // Make a third tag annotation with a different possibility pointing to the new Wordforms ITextTag tagSUT = null; var hvoSUTTag = -1; UndoableUnitOfWorkHelper.Do("UndoTagTest", "RedoTagTest", Cache.ActionHandlerAccessor, () => { tagSUT = m_tagChild.CallMakeTextTagInstance(m_possTags[2]); if (tagSUT != null) { hvoSUTTag = tagSUT.Hvo; } }); // Verification // Verify new tag AssertTagExists(hvoSUTTag, "Should have created second tag."); VerifyTextTag(tagSUT, m_possTags[2], tempList2[0], tempList2[1]); // The old tags (2) should no longer exist in the Cache AssertTagDoesntExist(hvoTag1, "Should have deleted the first pre-existing tag."); AssertTagDoesntExist(hvoTag2, "Should have deleted the second pre-existing tag."); }
private void DoDeleteCustomListCmd(ICmPossibilityList curList) { UndoableUnitOfWorkHelper.Do(xWorksStrings.ksUndoDeleteCustomList, xWorksStrings.ksRedoDeleteCustomList, Cache.ActionHandlerAccessor, () => new DeleteCustomList(Cache).Run(curList)); }
public void MonomorphemicMorphData() { var kick = MakeEntry("kick", "strike with foot"); var morphRepo = (MoStemAllomorphRepository)Cache.ServiceLocator.GetInstance <IMoStemAllomorphRepository>(); var morphData = morphRepo.MonomorphemicMorphData(); var kickKey = new Tuple <int, string>(Cache.DefaultVernWs, "kick"); Assert.That(morphData.ContainsKey(kickKey), Is.False, "morph with no type is not included"); var kickMorph = kick.LexemeFormOA; var morphTypeRepo = Cache.ServiceLocator.GetInstance <IMoMorphTypeRepository>(); kickMorph.MorphTypeRA = morphTypeRepo.GetObject(MoMorphTypeTags.kguidMorphBoundRoot); morphData = morphRepo.MonomorphemicMorphData(); Assert.That(morphData.ContainsKey(kickKey), Is.False, "bound root is not included"); kickMorph.MorphTypeRA = morphTypeRepo.GetObject(MoMorphTypeTags.kguidMorphRoot); morphData = morphRepo.MonomorphemicMorphData(); Assert.That(morphData[kickKey], Is.EqualTo(kickMorph), "root should be included"); var bug = MakeEntry("bug", "detestable monster"); var bugMorph = bug.LexemeFormOA; bugMorph.MorphTypeRA = morphTypeRepo.GetObject(MoMorphTypeTags.kguidMorphBoundStem); morphData = morphRepo.MonomorphemicMorphData(); var bugKey = new Tuple <int, string>(Cache.DefaultVernWs, "bug"); Assert.That(morphData[kickKey], Is.EqualTo(kickMorph), "root should be included"); Assert.That(morphData.ContainsKey(bugKey), Is.False, "bound stem is not included"); bugMorph.MorphTypeRA = morphTypeRepo.GetObject(MoMorphTypeTags.kguidMorphStem); morphData = morphRepo.MonomorphemicMorphData(); Assert.That(morphData[bugKey], Is.EqualTo(bugMorph), "stem should be included"); var bugAltA = MakeAllomorph(bug, "bugA", MoMorphTypeTags.kguidMorphPrefix); var bugAltAKey = new Tuple <int, string>(Cache.DefaultVernWs, "bugA"); morphData = morphRepo.MonomorphemicMorphData(); Assert.That(morphData.ContainsKey(bugAltAKey), Is.False, "prefix is not included"); bugAltA.MorphTypeRA = morphTypeRepo.GetObject(MoMorphTypeTags.kguidMorphEnclitic); morphData = morphRepo.MonomorphemicMorphData(); Assert.That(morphData[bugAltAKey], Is.EqualTo(bugAltA), "enclitic allomorph should be included"); var bugAltB = MakeAllomorph(bug, "bugB", MoMorphTypeTags.kguidMorphSuffix); var bugAltBKey = new Tuple <int, string>(Cache.DefaultVernWs, "bugB"); morphData = morphRepo.MonomorphemicMorphData(); Assert.That(morphData.ContainsKey(bugAltBKey), Is.False, "suffix is not included"); bugAltB.MorphTypeRA = morphTypeRepo.GetObject(MoMorphTypeTags.kguidMorphProclitic); morphData = morphRepo.MonomorphemicMorphData(); Assert.That(morphData[bugAltBKey], Is.EqualTo(bugAltB), "proclitic allomorph should be included"); kick.Delete(); morphData = morphRepo.MonomorphemicMorphData(); Assert.That(morphData.ContainsKey(kickKey), Is.False, "deleted morpheme is no longer included"); bugAltA.MorphTypeRA = morphTypeRepo.GetObject(MoMorphTypeTags.kguidMorphPrefix); morphData = morphRepo.MonomorphemicMorphData(); Assert.That(morphData.ContainsKey(bugAltAKey), Is.False, "changing back to prefix causes exclusion"); m_actionHandler.EndUndoTask(); UndoableUnitOfWorkHelper.Do("undo it", "redo it", m_actionHandler, () => bugAltB.Form.VernacularDefaultWritingSystem = TsStringUtils.MakeString("bugBB", Cache.DefaultVernWs)); morphData = morphRepo.MonomorphemicMorphData(); Assert.That(morphData.ContainsKey(bugAltBKey), Is.False, "changing form causes exclusion"); var bugAltBBKey = new Tuple <int, string>(Cache.DefaultVernWs, "bugBB"); Assert.That(morphData[bugAltBBKey], Is.EqualTo(bugAltB), "changing form causes new key to be included"); m_actionHandler.Undo(); morphData = morphRepo.MonomorphemicMorphData(); Assert.That(morphData[bugAltBKey], Is.EqualTo(bugAltB), "Undo should reinstate things"); m_actionHandler.Redo(); morphData = morphRepo.MonomorphemicMorphData(); Assert.That(morphData.ContainsKey(bugAltBKey), Is.False, "Redo should re-change things"); }
private void m_MSAPopupTreeManager_AfterSelect(object sender, TreeViewEventArgs e) { // unless we get a mouse click or simulated mouse click (e.g. by ENTER or TAB), // do not treat as an actual selection. if (m_handlingMessage || e.Action != TreeViewAction.ByMouse) { return; } HvoTreeNode htn = e.Node as HvoTreeNode; if (htn == null) { return; } // Don't try changing values on a deleted object! See LT-8656 and LT-9119. if (!m_obj.IsValidObject) { return; } int hvoSel = htn.Hvo; // if hvoSel is negative, then MSAPopupTreeManager's AfterSelect has handled it, // except possibly for refresh. if (hvoSel < 0) { ContainingDataTree.RefreshList(false); return; } var sense = m_obj as ILexSense; // Setting sense.DummyMSA can cause the DataTree to want to refresh. Don't // let this happen until after we're through! See LT-9713 and LT-9714. bool fOldDoNotRefresh = ContainingDataTree.DoNotRefresh; try { m_handlingMessage = true; if (hvoSel > 0) { ICmObject obj = m_cache.ServiceLocator.GetInstance <ICmObjectRepository>().GetObject(hvoSel); if (obj.ClassID == PartOfSpeechTags.kClassId) { ContainingDataTree.DoNotRefresh = true; var sandoxMSA = new SandboxGenericMSA(); sandoxMSA.MsaType = sense.GetDesiredMsaType(); sandoxMSA.MainPOS = obj as IPartOfSpeech; var stemMsa = sense.MorphoSyntaxAnalysisRA as IMoStemMsa; if (stemMsa != null) { sandoxMSA.FromPartsOfSpeech = stemMsa.FromPartsOfSpeechRC; } UndoableUnitOfWorkHelper.Do(String.Format(DetailControlsStrings.ksUndoSet, m_fieldName), String.Format(DetailControlsStrings.ksRedoSet, m_fieldName), sense, () => { sense.SandboxMSA = sandoxMSA; }); } else if (sense.MorphoSyntaxAnalysisRA != obj) { ContainingDataTree.DoNotRefresh = true; UndoableUnitOfWorkHelper.Do(String.Format(DetailControlsStrings.ksUndoSet, m_fieldName), String.Format(DetailControlsStrings.ksRedoSet, m_fieldName), sense, () => { sense.MorphoSyntaxAnalysisRA = obj as IMoMorphSynAnalysis; }); } } } finally { m_handlingMessage = false; // We still can't refresh the data at this point without causing a crash due to // a pending Windows message. See LT-9713 and LT-9714. if (ContainingDataTree.DoNotRefresh != fOldDoNotRefresh) { Mediator.BroadcastMessage("DelayedRefreshList", fOldDoNotRefresh); } } }
public void UpdateWritingSystemTag_ChangesWsContent() { var entry0 = Cache.ServiceLocator.GetInstance <ILexEntryFactory>().Create(); CoreWritingSystemDefinition newWs; WritingSystemServices.FindOrCreateWritingSystem(Cache, null, "en-SU", true, false, out newWs); // A string property NOT using the WS we will change. entry0.ImportResidue = TsStringUtils.MakeString("hello", Cache.DefaultAnalWs); // A multilingual one using the WS. entry0.LiteralMeaning.set_String(Cache.DefaultAnalWs, TsStringUtils.MakeString("whatever", Cache.DefaultAnalWs)); var entry1 = Cache.ServiceLocator.GetInstance <ILexEntryFactory>().Create(); var sense1 = Cache.ServiceLocator.GetInstance <ILexSenseFactory>().Create(); entry1.SensesOS.Add(sense1); // Sense1 should be dirty: it has a gloss in the changing WS. sense1.Gloss.set_String(newWs.Handle, TsStringUtils.MakeString("whatever", newWs.Handle)); // Entry2 should be dirty: it has a string property with a run in the changing WS. var entry2 = Cache.ServiceLocator.GetInstance <ILexEntryFactory>().Create(); var bldr = TsStringUtils.MakeString("abc ", Cache.DefaultAnalWs).GetBldr(); bldr.ReplaceTsString(bldr.Length, bldr.Length, TsStringUtils.MakeString("def", newWs.Handle)); var stringWithNewWs = bldr.GetString(); entry2.ImportResidue = stringWithNewWs; // Sense3 should be dirty: it has a multistring string property with a run in the changing WS. var entry3 = Cache.ServiceLocator.GetInstance <ILexEntryFactory>().Create(); var sense3 = Cache.ServiceLocator.GetInstance <ILexSenseFactory>().Create(); entry3.SensesOS.Add(sense3); var styledAndNormalRunInChangingWs = TsStringUtils.MakeString("changing", newWs.Handle); styledAndNormalRunInChangingWs.Insert(0, TsStringUtils.MakeString("8", newWs.Handle, "Verse Number")); sense3.Definition.set_String(newWs.Handle, styledAndNormalRunInChangingWs); Cache.LangProject.AnalysisWss = "en en-SU"; // Add Free Translation in the changing ws var paraBldr = Cache.ServiceLocator.GetInstance <StTxtParaBldr>(); var stText = Cache.ServiceLocator.GetInstance <IStTextFactory>().Create(); Cache.ServiceLocator.GetInstance <ITextFactory>().Create().ContentsOA = stText; // needed to put a Cache in stText var para = paraBldr.CreateParagraph(stText); para.Contents = TsStringUtils.MakeString("vernacular", Cache.DefaultVernWs); para.SegmentsOS[0].FreeTranslation.set_String(newWs.Handle, "Free Willy!"); m_actionHandler.EndUndoTask(); var undoManager = Cache.ServiceLocator.GetInstance <IUndoStackManager>(); undoManager.Save(); // makes everything non-dirty. var newbies = new HashSet <ICmObjectId>(); var dirtballs = new HashSet <ICmObjectOrSurrogate>(new ObjectSurrogateEquater()); var goners = new HashSet <ICmObjectId>(); var uowServices = Cache.ServiceLocator.GetInstance <IUnitOfWorkService>(); Assert.That(dirtballs.Count, Is.EqualTo(0)); // After save nothing should be dirty. uowServices.GatherChanges(newbies, dirtballs, goners); int oldWsHandle = newWs.Handle; var tempWs = new CoreWritingSystemDefinition("en-GB"); newWs.Copy(tempWs); Cache.ServiceLocator.GetInstance <WritingSystemManager>().Set(newWs); UndoableUnitOfWorkHelper.Do("doit", "undoit", m_actionHandler, () => WritingSystemServices.UpdateWritingSystemId(Cache, newWs, oldWsHandle, "en-SU")); newbies = new HashSet <ICmObjectId>(); dirtballs = new HashSet <ICmObjectOrSurrogate>(new ObjectSurrogateEquater()); goners = new HashSet <ICmObjectId>(); uowServices.GatherChanges(newbies, dirtballs, goners); Assert.That(dirtballs.Contains((ICmObjectOrSurrogate)sense1)); Assert.That(!dirtballs.Contains((ICmObjectOrSurrogate)entry0)); // make sure the implementation doesn't just dirty everything. Assert.That(dirtballs.Contains((ICmObjectOrSurrogate)entry2)); Assert.That(dirtballs.Contains((ICmObjectOrSurrogate)sense3)); Assert.That(dirtballs.Contains((ICmObjectOrSurrogate)para.SegmentsOS[0])); Assert.That(Cache.LangProject.AnalysisWss, Is.EqualTo("en en-GB"), "should have updated WS lists"); }
internal void RemoveOrdering() { UndoableUnitOfWorkHelper.Do(DetailControlsStrings.ksUndoAlphabeticalOrder, DetailControlsStrings.ksRedoAlphabeticalOrder, Cache.ActionHandlerAccessor, () => VirtualOrderingServices.ResetVO(m_rootObj, m_rootFlid)); }
public void HandleCreateMenuItem(object sender, EventArgs ea) { CheckDisposed(); var tsItem = sender as ToolStripItem; int itemIndex = (tsItem.Owner as ContextMenuStrip).Items.IndexOf(tsItem); var lrt = m_refTypesAvailable[itemIndex]; bool fReverseRef = m_rgfReversedRefType[itemIndex]; ILexReference newRef = null; ICmObject first = null; if (fReverseRef) { // When creating a tree Lexical Relation and the user is choosing // the root of the tree, first see if the user selects a lexical entry. // If they do not select anything (hvoFirst==0) return and do not create the slice. first = GetRootObject(lrt); if (first == null) { return; // the user cancelled out of the operation. } if (lrt.MappingType == (int)LexRefTypeTags.MappingTypes.kmtSenseTree || lrt.MappingType == (int)LexRefTypeTags.MappingTypes.kmtEntryTree || lrt.MappingType == (int)LexRefTypeTags.MappingTypes.kmtEntryOrSenseTree) { // Use an existing ILexReference if one exists. foreach (var lr in lrt.MembersOC) { if (lr.TargetsRS.Count > 0 && lr.TargetsRS[0] == first) { newRef = lr; break; } } } } else { // Launch the dialog that allows the user to choose a lexical entry. // If they choose an entry, it is returned in hvoFirst so go ahead and // create the lexical relation and add this lexical entry to that relation. first = GetChildObject(lrt); if (first == null) { return; // the user cancelled out of the operation. } } UndoableUnitOfWorkHelper.Do(string.Format(LexEdStrings.ksUndoInsertRelation, tsItem.Text), string.Format(LexEdStrings.ksRedoInsertRelation, tsItem.Text), m_obj, () => { if (newRef != null) { newRef.TargetsRS.Add(m_obj); } else { newRef = m_cache.ServiceLocator.GetInstance <ILexReferenceFactory>().Create(); lrt.MembersOC.Add(newRef); if (fReverseRef) { newRef.TargetsRS.Insert(0, first); newRef.TargetsRS.Insert(1, m_obj); } else { //When creating a lexical relation slice, //add the current lexical entry to the lexical relation as the first item newRef.TargetsRS.Insert(0, m_obj); //then also add the lexical entry that the user selected in the chooser dialog. newRef.TargetsRS.Insert(1, first); } } m_refs.Add(newRef); }); }
public void SetMappingFeatures() { SelectionHelper.Create(m_view); bool reconstruct = false; int index = -1; UndoableUnitOfWorkHelper.Do(MEStrings.ksAffixRuleUndoSetMappingFeatures, MEStrings.ksAffixRuleRedoSetMappingFeatures, m_cache.ActionHandlerAccessor, () => { using (var featChooser = new SIL.FieldWorks.LexText.Controls.PhonologicalFeatureChooserDlg()) { var obj = CurrentObject; switch (obj.ClassID) { case MoCopyFromInputTags.kClassId: featChooser.SetDlgInfo(m_cache, m_mediator, m_propertyTable); if (featChooser.ShowDialog() == DialogResult.OK) { // create a new natural class behind the scenes var featNC = m_cache.ServiceLocator.GetInstance <IPhNCFeaturesFactory>().Create(); m_cache.LangProject.PhonologicalDataOA.NaturalClassesOS.Add(featNC); featNC.Name.SetUserWritingSystem(string.Format(MEStrings.ksRuleNCFeatsName, Rule.Form.BestVernacularAnalysisAlternative.Text)); featNC.FeaturesOA = m_cache.ServiceLocator.GetInstance <IFsFeatStrucFactory>().Create(); featChooser.FS = featNC.FeaturesOA; featChooser.UpdateFeatureStructure(); var copy = (IMoCopyFromInput)obj; var newModify = m_cache.ServiceLocator.GetInstance <IMoModifyFromInputFactory>().Create(); Rule.OutputOS.Insert(copy.IndexInOwner, newModify); newModify.ModificationRA = featNC; newModify.ContentRA = copy.ContentRA; index = newModify.IndexInOwner; Rule.OutputOS.Remove(copy); reconstruct = true; } break; case MoModifyFromInputTags.kClassId: var modify = (IMoModifyFromInput)obj; featChooser.SetDlgInfo(m_cache, m_mediator, m_propertyTable, modify.ModificationRA.FeaturesOA); if (featChooser.ShowDialog() == DialogResult.OK) { if (modify.ModificationRA.FeaturesOA.FeatureSpecsOC.Count == 0) { var newCopy = m_cache.ServiceLocator.GetInstance <IMoCopyFromInputFactory>().Create(); Rule.OutputOS.Insert(modify.IndexInOwner, newCopy); newCopy.ContentRA = modify.ContentRA; index = newCopy.IndexInOwner; Rule.OutputOS.Remove(modify); } else { index = modify.IndexInOwner; } reconstruct = true; } break; } } }); m_view.Select(); if (reconstruct) { ReconstructView(MoAffixProcessTags.kflidOutput, index, true); } }
public void UndoRedoIncomingRefs() { var servLoc = Cache.ServiceLocator; var leFact = servLoc.GetInstance <ILexEntryFactory>(); var le1 = leFact.Create(); var lsFact = servLoc.GetInstance <ILexSenseFactory>(); var ls1 = lsFact.Create(); le1.SensesOS.Add(ls1); if (Cache.LangProject.StatusOA == null) { Cache.LangProject.StatusOA = servLoc.GetInstance <ICmPossibilityListFactory>().Create(); } var possFact = servLoc.GetInstance <ICmPossibilityFactory>(); var status1 = possFact.Create(); Cache.LangProject.StatusOA.PossibilitiesOS.Add(status1); Cache.ActionHandlerAccessor.EndUndoTask(); // so we can have our own units of work to test Undo // Atomic UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => ls1.StatusRA = status1); Assert.AreEqual(1, status1.ReferringObjects.Count); m_actionHandler.Undo(); Assert.AreEqual(0, status1.ReferringObjects.Count); m_actionHandler.Redo(); Assert.AreEqual(1, status1.ReferringObjects.Count); m_actionHandler.Undo(); // leave it Undone so it doesn't affect the ref collection test below. Assert.AreEqual(0, status1.ReferringObjects.Count); // Ref sequence UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => le1.MainEntriesOrSensesRS.Add(ls1)); Assert.AreEqual(1, ls1.ReferringObjects.Count); m_actionHandler.Undo(); Assert.AreEqual(0, ls1.ReferringObjects.Count); m_actionHandler.Redo(); Assert.AreEqual(1, ls1.ReferringObjects.Count); m_actionHandler.Undo(); // cleanup Assert.AreEqual(0, ls1.ReferringObjects.Count); // Ref collection UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => ls1.DomainTypesRC.Add(status1)); Assert.AreEqual(1, status1.ReferringObjects.Count); m_actionHandler.Undo(); Assert.AreEqual(0, status1.ReferringObjects.Count); m_actionHandler.Redo(); Assert.AreEqual(1, status1.ReferringObjects.Count); m_actionHandler.Undo(); // cleanup Assert.AreEqual(0, status1.ReferringObjects.Count); ILexSense ls2 = null; // Now see if it happens properly when we Undo and Redo object creation and deletion. // Atomic UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { ls2 = lsFact.Create(); le1.SensesOS.Add(ls2); ls2.StatusRA = status1; }); Assert.AreEqual(1, status1.ReferringObjects.Count); m_actionHandler.Undo(); Assert.AreEqual(0, status1.ReferringObjects.Count); m_actionHandler.Redo(); Assert.AreEqual(1, status1.ReferringObjects.Count); UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => le1.SensesOS.Remove(ls2)); Assert.AreEqual(0, status1.ReferringObjects.Count); m_actionHandler.Undo(); Assert.AreEqual(1, status1.ReferringObjects.Count, "incoming ref should come back on undoing delete"); m_actionHandler.Redo(); Assert.AreEqual(0, status1.ReferringObjects.Count, "incoming ref should go away on redoing delete"); // collection UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { ls2 = lsFact.Create(); le1.SensesOS.Add(ls2); ls2.DomainTypesRC.Add(status1); }); Assert.AreEqual(1, status1.ReferringObjects.Count); m_actionHandler.Undo(); Assert.AreEqual(0, status1.ReferringObjects.Count); m_actionHandler.Redo(); Assert.AreEqual(1, status1.ReferringObjects.Count); UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => le1.SensesOS.Remove(ls2)); Assert.AreEqual(0, status1.ReferringObjects.Count); m_actionHandler.Undo(); Assert.AreEqual(1, status1.ReferringObjects.Count, "incoming ref should come back on undoing delete"); m_actionHandler.Redo(); Assert.AreEqual(0, status1.ReferringObjects.Count, "incoming ref should go away on redoing delete"); // sequence ILexEntry le2 = null; UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { le2 = leFact.Create(); le2.MainEntriesOrSensesRS.Add(ls1); }); Assert.AreEqual(1, ls1.ReferringObjects.Count); m_actionHandler.Undo(); Assert.AreEqual(0, ls1.ReferringObjects.Count); m_actionHandler.Redo(); Assert.AreEqual(1, ls1.ReferringObjects.Count); UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => le2.Delete()); Assert.AreEqual(0, ls1.ReferringObjects.Count); m_actionHandler.Undo(); Assert.AreEqual(1, ls1.ReferringObjects.Count, "incoming ref should come back on undoing delete"); m_actionHandler.Redo(); Assert.AreEqual(0, ls1.ReferringObjects.Count, "incoming ref should go away on redoing delete"); // The base class for this group of tests expects to end an Undo task after the test is over. Cache.ActionHandlerAccessor.BeginUndoTask("undo something", "redo something"); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Overridden to set the new values selected from the chooser dialog. /// </summary> /// <param name="chosenObjs">The chosen objs.</param> /// ------------------------------------------------------------------------------------ public override void SetItems(IEnumerable <ICmObject> chosenObjs) { CheckDisposed(); // null indicates that we cancelled out of the chooser dialog -- we shouldn't get // here with that value, but just in case... if (chosenObjs == null) { return; } int h1 = m_phoneEnvRefView.RootBox.Height; ICollection <IPhEnvironment> envs; if (m_flid == MoAffixAllomorphTags.kflidPosition) { envs = ((IMoAffixAllomorph)m_obj).PositionRS; } else { if (m_obj is IMoAffixAllomorph) { envs = ((IMoAffixAllomorph)m_obj).PhoneEnvRC; } else { envs = ((IMoStemAllomorph)m_obj).PhoneEnvRC; } } // First, we need a list of hvos added and a list of hvos deleted. HashSet <IPhEnvironment> newEnvs = new HashSet <IPhEnvironment>(chosenObjs.Cast <IPhEnvironment>()); HashSet <IPhEnvironment> delEnvs = new HashSet <IPhEnvironment>(); foreach (IPhEnvironment env in envs) { if (newEnvs.Contains(env)) { newEnvs.Remove(env); } else { delEnvs.Add(env); } } // Add all the new environments. UndoableUnitOfWorkHelper.Do(string.Format(DetailControlsStrings.ksUndoSet, m_fieldName), string.Format(DetailControlsStrings.ksRedoSet, m_fieldName), m_obj, () => { foreach (IPhEnvironment env in newEnvs) { m_phoneEnvRefView.AddNewItem(env); envs.Add(env); } foreach (IPhEnvironment env in delEnvs) { m_phoneEnvRefView.RemoveItem(env); envs.Remove(env); } }); int h2 = m_phoneEnvRefView.RootBox.Height; if (h1 != h2 && ViewSizeChanged != null) { ViewSizeChanged(this, new FwViewSizeEventArgs(h2, m_phoneEnvRefView.RootBox.Width)); } }
/// <summary> /// Insert breaks for the text in the indicated range of the indicate StTxtPara /// </summary> /// <param name="start"></param> /// <param name="limit"></param> /// <param name="hvoPara"></param> public void Guess(int start, int limit, int hvoPara) { Setup(hvoPara); ITsString tss = m_sda.get_StringProp(hvoPara, StTxtParaTags.kflidContents); ITsStrBldr bldr = tss.GetBldr(); //Guessing wordbreaks in a string that isn't there is not a good idea. if (tss.Text == null) { return; } string txt = tss.Text.Substring(start, limit > start && limit < tss.Length ? limit - start : tss.Length - start); int offset = 0; // offset in tsb caused by previously introduced spaces. //Attempt to handle the problem of invalid words being introduced accounting for punctuation //replace every kind of punctuation character in the writing system with ., then split on . // //just grab the system from the first run, seems unlikely you'll be guessing wordbreaks on strings with runs in different writing systems var wsID = tss.get_WritingSystem(0); //get the writing system from the cache IWritingSystem ws = (IWritingSystem)m_cache.WritingSystemFactory.get_EngineOrNull(wsID); //get the ValidCharacters for the writing system. ValidCharacters vc = ws != null?ValidCharacters.Load(ws, e => { }, FwDirectoryFinder.CodeDirectory) : null; //split the text on everything found in the OtherCharacters section string[] distinctPhrases = vc != null?txt.Split(vc.OtherCharacters.ToArray(), StringSplitOptions.None) //ws info was good, use it : Regex.Replace(txt, "\\p{P}", ".").Split('.'); //bad ws info, replace all punct with . and split on . Set <WordLoc> allWords = new Set <WordLoc>(); int adjustment = 0; foreach (var distinctPhrase in distinctPhrases) { if (distinctPhrase.Length > 0) //split will give us an empty string wherever there was a punctuation { Set <WordLoc> foundWords = FindAllMatches(0, distinctPhrase.Length, distinctPhrase); foreach (var foundWord in foundWords) { foundWord.Start += adjustment; } allWords.AddRange(foundWords); adjustment += distinctPhrase.Length; } ++adjustment; //rather than just adding 1 to the adjustment above adjust here. This will handle oddities like ,, or ". } List <WordLoc> bestWords = BestMatches(txt, allWords); foreach (var word in bestWords) //for each word in our list of the best result { //unless the word starts at the beginning of the input or the word starts right after the end of the last word we found //insert a space before the word. if (word.Start != 0) { //insert a space before the word. if (!SpaceAt(bldr, start + word.Start + offset - 1)) //if there isn't already a space { InsertSpace(bldr, start + word.Start + offset); ++offset; } } if (word.Start + word.Length != txt.Length) //unless the word ends at the end of our input { if (!SpaceAt(bldr, start + word.Start + word.Length + offset)) //if there isn't already a space { InsertSpace(bldr, start + word.Start + word.Length + offset); //insert a space at the end of the word ++offset; } } } if (offset > 0) { UndoableUnitOfWorkHelper.Do(ITextStrings.ksUndoGuessWordBreaks, ITextStrings.ksRedoGuessWordBreaks, m_cache.ActionHandlerAccessor, () => m_sda.SetString(hvoPara, StTxtParaTags.kflidContents, bldr.GetString())); } }
public void FindOrCreateReversalEntry() { int wsEn = Cache.DefaultAnalWs; IReversalIndex revIndex = null; UndoableUnitOfWorkHelper.Do("undo make index", "redo make index", m_actionHandler, () => { revIndex = Cache.ServiceLocator.GetInstance <IReversalIndexRepository>().FindOrCreateIndexForWs(wsEn); }); IReversalIndexEntry empty = null; UndoableUnitOfWorkHelper.Do("undo make rie", "redo make rie", m_actionHandler, () => { empty = revIndex.FindOrCreateReversalEntry(""); }); IReversalIndexEntry bank = null; UndoableUnitOfWorkHelper.Do("undo make rie", "redo make rie", m_actionHandler, () => { bank = revIndex.FindOrCreateReversalEntry("bank"); }); Assert.IsNotNull(bank); Assert.AreEqual("bank", bank.LongName); m_actionHandler.Undo(); // deletes bank IReversalIndexEntry bank2 = null; UndoableUnitOfWorkHelper.Do("undo make rie", "redo make rie", m_actionHandler, () => { bank2 = revIndex.FindOrCreateReversalEntry("bank"); }); Assert.AreNotEqual(bank, bank2, "should make a new rie after Undo deletes old one"); // Enhance JohnT: if we could look for one without creating it, we should test that Redo will // reinstate the old object. But we can't Redo that action, because we've made new actions since. bank = bank2; // treat that as the base from here on. UndoableUnitOfWorkHelper.Do("undo make rie", "redo make rie", m_actionHandler, () => { bank2 = revIndex.FindOrCreateReversalEntry("bank"); }); Assert.AreEqual(bank, bank2, "should find the same RIE for the same name"); IReversalIndexEntry moneybank = null; UndoableUnitOfWorkHelper.Do("undo set rie name", "redo set rie name", m_actionHandler, () => { bank.ReversalForm.set_String(wsEn, bank.Cache.TsStrFactory.MakeString("moneybank", wsEn)); moneybank = revIndex.FindOrCreateReversalEntry("moneybank"); }); Assert.AreEqual(bank, moneybank, "changing existing name should allow us to find old one under new name"); m_actionHandler.Undo(); // name is back to 'bank' bank = revIndex.FindOrCreateReversalEntry("bank"); // should not need UOW Assert.AreEqual(bank, moneybank, "after Undo should find same item under original name"); m_actionHandler.Redo(); moneybank = revIndex.FindOrCreateReversalEntry("moneybank"); Assert.AreEqual(bank, moneybank, "after Redodo should find same item under new name"); UndoableUnitOfWorkHelper.Do("undo rest of stuff", "redo rest of stuff", m_actionHandler, () => { bank = revIndex.FindOrCreateReversalEntry("bank"); Assert.IsNotNull(bank); Assert.AreNotEqual(bank, moneybank, "after rename, should make new object when looking up old name"); var riverbank = revIndex.FindOrCreateReversalEntry("bank:of river"); Assert.AreEqual("of river", riverbank.ShortName); Assert.AreEqual("bank: of river", riverbank.LongName); Assert.AreEqual(bank, riverbank.Owner); var riverbank2 = revIndex.FindOrCreateReversalEntry("bank: of river"); Assert.AreEqual(riverbank, riverbank2); moneybank = revIndex.FindOrCreateReversalEntry("bank: for money"); Assert.IsNotNull(moneybank); Assert.AreNotEqual(riverbank, moneybank); Assert.AreEqual("bank: for money", moneybank.LongName); var planebank = revIndex.FindOrCreateReversalEntry("bank: tilt:plane"); Assert.AreEqual("bank: tilt: plane", planebank.LongName); Assert.AreEqual(bank, planebank.Owner.Owner); }); }
private void btnAdd_Click(object sender, EventArgs e) { // Get the checked occurrences; List <int> occurrences = m_rbv.CheckedItems; if (occurrences == null || occurrences.Count == 0) { // do nothing. return; } List <int> uniqueSegments = (from fake in occurrences select m_clerk.VirtualListPublisher.get_ObjectProp(fake, ConcDecorator.kflidSegment)).Distinct().ToList (); int insertIndex = m_owningSense.ExamplesOS.Count; // by default, insert at the end. if (m_les != null) { // we were given a LexExampleSentence, so set our insertion index after the given one. insertIndex = m_owningSense.ExamplesOS.IndexOf(m_les) + 1; } UndoableUnitOfWorkHelper.Do(LexEdStrings.ksUndoAddExamples, LexEdStrings.ksRedoAddExamples, m_cache.ActionHandlerAccessor, () => { int cNewExamples = 0; ILexExampleSentence newLexExample = null; foreach (int segHvo in uniqueSegments) { var seg = m_cache.ServiceLocator.GetObject(segHvo) as ISegment; if (cNewExamples == 0 && m_les != null && m_les.Example.BestVernacularAlternative.Text == "***" && (m_les.TranslationsOC == null || m_les.TranslationsOC.Count == 0) && m_les.Reference.Length == 0) { // we were given an empty LexExampleSentence, so use this one for our first new Example. newLexExample = m_les; } else { // create a new example sentence. newLexExample = m_cache.ServiceLocator.GetInstance <ILexExampleSentenceFactory>().Create(); m_owningSense.ExamplesOS.Insert(insertIndex + cNewExamples, newLexExample); cNewExamples++; } // copy the segment string into the new LexExampleSentence // Enhance: bold the relevant occurrence(s). // LT-11388 Make sure baseline text gets copied into correct ws var baseWs = GetBestVernWsForNewExample(seg); newLexExample.Example.set_String(baseWs, seg.BaselineText); if (seg.FreeTranslation.AvailableWritingSystemIds.Length > 0) { var trans = m_cache.ServiceLocator.GetInstance <ICmTranslationFactory>().Create(newLexExample, m_cache.ServiceLocator.GetInstance <ICmPossibilityRepository>().GetObject( CmPossibilityTags.kguidTranFreeTranslation)); trans.Translation.CopyAlternatives(seg.FreeTranslation); } if (seg.LiteralTranslation.AvailableWritingSystemIds.Length > 0) { var trans = m_cache.ServiceLocator.GetInstance <ICmTranslationFactory>().Create(newLexExample, m_cache.ServiceLocator.GetInstance <ICmPossibilityRepository>().GetObject( CmPossibilityTags.kguidTranLiteralTranslation)); trans.Translation.CopyAlternatives(seg.LiteralTranslation); } // copy the reference. ITsString tssRef = seg.Paragraph.Reference(seg, seg.BeginOffset); // convert the plain reference string into a link. ITsStrBldr tsb = tssRef.GetBldr(); FwLinkArgs fwl = new FwLinkArgs("interlinearEdit", seg.Owner.Owner.Guid); // It's not clear how to focus in on something smaller than the text when following // a link. //fwl.PropertyTableEntries.Add(new Property("LinkSegmentGuid", seg.Guid.ToString())); tsb.SetStrPropValue(0, tsb.Length, (int)FwTextPropType.ktptObjData, (char)FwObjDataTypes.kodtExternalPathName + fwl.ToString()); tsb.SetStrPropValue(0, tsb.Length, (int)FwTextPropType.ktptNamedStyle, "Hyperlink"); newLexExample.Reference = tsb.GetString(); } }); }
/// <summary> /// Override method to handle launching of a chooser for selecting lexical entries or senses. /// </summary> protected override void HandleChooser() { if (m_flid == LexEntryRefTags.kflidComponentLexemes) { using (LinkEntryOrSenseDlg dlg = new LinkEntryOrSenseDlg()) { ILexEntry le = null; if (m_obj.ClassID == LexEntryTags.kClassId) { // filter this entry from the list. le = m_obj as ILexEntry; } else { // assume the owner is the entry (e.g. owner of LexEntryRef) le = m_obj.OwnerOfClass <ILexEntry>(); } dlg.SetDlgInfo(m_cache, m_mediator, m_propertyTable, le); String str = ShowHelp.RemoveSpaces(this.Slice.Label); dlg.SetHelpTopic("khtpChooseLexicalEntryOrSense-" + str); if (dlg.ShowDialog(FindForm()) == DialogResult.OK) { AddItem(dlg.SelectedObject); } } } else if (m_flid == LexEntryRefTags.kflidPrimaryLexemes) { string displayWs = "analysis vernacular"; if (m_configurationNode != null) { XmlNode node = m_configurationNode.SelectSingleNode("deParams"); if (node != null) { displayWs = XmlUtils.GetAttributeValue(node, "ws", "analysis vernacular").ToLower(); } } ILexEntryRef ler = m_obj as ILexEntryRef; Debug.Assert(ler != null); var labels = ObjectLabel.CreateObjectLabels(m_cache, ler.ComponentLexemesRS.Cast <ICmObject>(), m_displayNameProperty, displayWs); using (ReallySimpleListChooser chooser = new ReallySimpleListChooser(null, labels, "PrimaryLexemes", m_cache, ler.PrimaryLexemesRS.Cast <ICmObject>(), false, m_propertyTable.GetValue <IHelpTopicProvider>("HelpTopicProvider"))) { chooser.HideDisplayUsageCheckBox(); chooser.SetObjectAndFlid(m_obj.Hvo, m_flid); // may set TextParamHvo chooser.Text = LexEdStrings.ksChooseWhereToShowSubentry; chooser.SetHelpTopic(Slice.GetChooserHelpTopicID()); chooser.InitializeExtras(null, Mediator, m_propertyTable); chooser.AddLink(LexEdStrings.ksAddAComponent, ReallySimpleListChooser.LinkType.kDialogLink, new AddPrimaryLexemeChooserCommand(m_cache, false, null, m_mediator, m_propertyTable, m_obj, FindForm())); DialogResult res = chooser.ShowDialog(); if (DialogResult.Cancel == res) { return; } if (chooser.ChosenObjects != null) { SetItems(chooser.ChosenObjects); } } } else { string fieldName = m_obj.Cache.MetaDataCacheAccessor.GetFieldName(m_flid); Debug.Assert(m_obj is ILexEntry || m_obj is ILexSense); switch (fieldName) { case "ComplexFormEntries": using (var dlg = new EntryGoDlg()) { dlg.StartingEntry = m_obj as ILexEntry ?? (m_obj as ILexSense).Entry; dlg.SetDlgInfo(m_cache, null, m_mediator, m_propertyTable); String str = ShowHelp.RemoveSpaces(Slice.Label); dlg.SetHelpTopic("khtpChooseComplexFormEntryOrSense-" + str); dlg.SetOkButtonText(LexEdStrings.ksMakeComponentOf); if (dlg.ShowDialog(FindForm()) == DialogResult.OK) { try { UndoableUnitOfWorkHelper.Do(LexEdStrings.ksUndoAddComplexForm, LexEdStrings.ksRedoAddComplexForm, m_obj.Cache.ActionHandlerAccessor, () => ((ILexEntry)dlg.SelectedObject).AddComponent(m_obj)); } catch (ArgumentException) { MessageBoxes.ReportLexEntryCircularReference(dlg.SelectedObject, m_obj, false); } } } break; case "VisibleComplexFormEntries": // obsolete? case "Subentries": HandleChooserForBackRefs(fieldName, false); break; case "VisibleComplexFormBackRefs": HandleChooserForBackRefs(fieldName, true); break; default: Debug.Fail("EntrySequenceReferenceLauncher should only be used for variants, components, or complex forms"); break; } } }
void link_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { RuleInsertType type = (RuleInsertType)e.Link.LinkData; string optStr = GetOptionString(type); var undo = string.Format(MEStrings.ksRuleUndoInsert, optStr); var redo = string.Format(MEStrings.ksRuleRedoInsert, optStr); object data = null; switch (type) { case RuleInsertType.PHONEME: var phonemes = m_cache.LangProject.PhonologicalDataOA.PhonemeSetsOS[0].PhonemesOC.Cast <ICmObject>(); data = DisplayChooser(MEStrings.ksRulePhonemeOpt, MEStrings.ksRulePhonemeChooserLink, "phonemeEdit", "RulePhonemeFlatList", phonemes); break; case RuleInsertType.NATURAL_CLASS: var natClasses = m_cache.LangProject.PhonologicalDataOA.NaturalClassesOS.Cast <ICmObject>(); data = DisplayChooser(MEStrings.ksRuleNCOpt, MEStrings.ksRuleNCChooserLink, "naturalClassedit", "RuleNaturalClassFlatList", natClasses); break; case RuleInsertType.FEATURES: using (var featChooser = new PhonologicalFeatureChooserDlg()) { featChooser.SetDlgInfo(m_cache, m_mediator); if (this.Parent is SIL.FieldWorks.XWorks.MorphologyEditor.RegRuleFormulaControl) { featChooser.SetHelpTopic("khtpChoose-Grammar-PhonFeats-RegRuleFormulaControl"); } else if (this.Parent is SIL.FieldWorks.XWorks.MorphologyEditor.MetaRuleFormulaControl) { featChooser.SetHelpTopic("khtpChoose-Grammar-PhonFeats-MetaRuleFormulaControl"); } else if (this.Parent is SIL.FieldWorks.XWorks.MorphologyEditor.AffixRuleFormulaControl) { featChooser.SetHelpTopic("khtpChoose-LexiconEdit-PhonFeats-AffixRuleFormulaControl"); } DialogResult res = featChooser.ShowDialog(); if (res == DialogResult.OK) { UndoableUnitOfWorkHelper.Do(undo, redo, m_cache.ActionHandlerAccessor, () => { var featNC = m_cache.ServiceLocator.GetInstance <IPhNCFeaturesFactory>().Create(); m_cache.LangProject.PhonologicalDataOA.NaturalClassesOS.Add(featNC); featNC.Name.SetUserWritingSystem(string.Format(MEStrings.ksRuleNCFeatsName, m_ruleName)); featNC.FeaturesOA = m_cache.ServiceLocator.GetInstance <IFsFeatStrucFactory>().Create(); featChooser.FS = featNC.FeaturesOA; featChooser.UpdateFeatureStructure(); data = featNC; }); } else if (res != DialogResult.Cancel) { featChooser.HandleJump(); } } break; case RuleInsertType.WORD_BOUNDARY: data = m_cache.ServiceLocator.GetInstance <IPhBdryMarkerRepository>().GetObject(LangProjectTags.kguidPhRuleWordBdry); break; case RuleInsertType.MORPHEME_BOUNDARY: data = m_cache.ServiceLocator.GetInstance <IPhBdryMarkerRepository>().GetObject(LangProjectTags.kguidPhRuleMorphBdry); break; case RuleInsertType.INDEX: // put the clicked index in the data field data = (int)e.Link.Tag; break; } // Some cases will do nothing (and so make an empty UOW) if data is empty. However, other cases // (such as inserting X Variable, LT-11136) need the event even if data is empty, and the empty UOW // is discarded harmlessly. Insert(this, new RuleInsertEventArgs(type, data, undo, redo)); }
/// <summary> /// This method is called when a user selects Delete Relation on a Lexical Relation slice. /// For: sequence relations (eg. Calendar) /// collection relations (eg. Synonym) /// tree relation (parts/whole when deleting a Whole slice) /// </summary> /// <param name="hvo"></param> public void DeleteFromReference(ILexReference lr) { CheckDisposed(); if (lr == null) { throw new ConfigurationException("Slice:GetObjectHvoForMenusToOperateOn is either messed up or should not have been called, because it could not find the object to be deleted.", m_configurationNode); } else { var mainWindow = (Form)Mediator.PropertyTable.GetValue("window"); using (new WaitCursor(mainWindow)) { using (var dlg = new ConfirmDeleteObjectDlg(m_mediator.HelpTopicProvider)) { var ui = CmObjectUi.MakeUi(m_cache, lr.Hvo); //We need this to determine which kind of relation we are deleting var lrtOwner = (ILexRefType)lr.Owner; var analWs = lrtOwner.Services.WritingSystems.DefaultAnalysisWritingSystem.Handle; var userWs = m_cache.WritingSystemFactory.UserWs; var tisb = TsIncStrBldrClass.Create(); tisb.SetIntPropValues((int)FwTextPropType.ktptWs, 0, userWs); switch ((LexRefTypeTags.MappingTypes)lrtOwner.MappingType) { case LexRefTypeTags.MappingTypes.kmtSenseSequence: case LexRefTypeTags.MappingTypes.kmtEntrySequence: case LexRefTypeTags.MappingTypes.kmtEntryOrSenseSequence: case LexRefTypeTags.MappingTypes.kmtEntryOrSenseCollection: case LexRefTypeTags.MappingTypes.kmtEntryCollection: case LexRefTypeTags.MappingTypes.kmtSenseCollection: if (lr.TargetsRS.Count > 2) { tisb.SetIntPropValues((int)FwTextPropType.ktptWs, 0, userWs); tisb.Append(String.Format(LexEdStrings.ksDeleteSequenceCollectionA, StringUtils.kChHardLB.ToString())); tisb.SetIntPropValues((int)FwTextPropType.ktptWs, 0, analWs); tisb.Append(lrtOwner.ShortName); tisb.SetIntPropValues((int)FwTextPropType.ktptWs, 0, userWs); tisb.Append(LexEdStrings.ksDeleteSequenceCollectionB); dlg.SetDlgInfo(ui, m_cache, Mediator, tisb.GetString()); } else { dlg.SetDlgInfo(ui, m_cache, Mediator); } break; default: dlg.SetDlgInfo(ui, m_cache, Mediator); break; } if (DialogResult.Yes == dlg.ShowDialog(mainWindow)) { UndoableUnitOfWorkHelper.Do(LexEdStrings.ksUndoDeleteRelation, LexEdStrings.ksRedoDeleteRelation, m_obj, () => { //If the user selected Yes, then we need to delete 'this' sense or entry lr.TargetsRS.Remove(m_obj); }); //Update the display because we have removed this slice from the Lexical entry. UpdateForDelete(lr); } } } } }
protected override void HandleChooser() { string displayWs = "analysis vernacular"; #pragma warning disable 219 string postDialogMessageTrigger = null; #pragma warning restore 219 if (m_configurationNode != null) { XmlNode node = m_configurationNode.SelectSingleNode("deParams"); if (node != null) { displayWs = XmlUtils.GetAttributeValue(node, "ws", "analysis vernacular").ToLower(); postDialogMessageTrigger = XmlUtils.GetAttributeValue(node, "postChangeMessageTrigger", null); } } var labels = ObjectLabel.CreateObjectLabels(m_cache, m_obj.ReferenceTargetCandidates(m_flid), m_displayNameProperty, displayWs); using (MorphTypeChooser chooser = GetChooser(labels)) { bool fMadeMorphTypeChange = false; var entry = (ILexEntry)m_obj.Owner; chooser.InitializeExtras(m_configurationNode, Mediator); chooser.SetObjectAndFlid(m_obj.Hvo, m_flid); chooser.SetHelpTopic(Slice.GetChooserHelpTopicID()); var hvoType = m_cache.DomainDataByFlid.get_ObjectProp(m_obj.Hvo, m_flid); var morphTypeRep = m_cache.ServiceLocator.GetInstance <IMoMorphTypeRepository>(); var type = hvoType != 0 ? morphTypeRep.GetObject(hvoType) : null; chooser.MakeSelection(type); // LT-4433 changed the Alternate Forms to choose between Stem and Affix automatically // when inserting. Thus, we need the check box in that environment as well. //if (m_obj.OwningFlid != (int)LexEntry.LexEntryTags.kflidLexemeForm) // chooser.ShowAllTypesCheckBoxVisible = false; if (chooser.ShowDialog() == DialogResult.OK) { var selected = (IMoMorphType)chooser.ChosenOne.Object; var original = Target as IMoMorphType; string sUndo = m_mediator.StringTbl.GetStringWithXPath("ChangeLexemeMorphTypeUndo", m_ksPath); string sRedo = m_mediator.StringTbl.GetStringWithXPath("ChangeLexemeMorphTypeRedo", m_ksPath); bool fRemoveComponents = false; if (selected.Guid == MoMorphTypeTags.kguidMorphRoot || selected.Guid == MoMorphTypeTags.kguidMorphBoundRoot) { // changing to root...not allowed to have complex forms. foreach (ILexEntryRef ler in entry.EntryRefsOS) { if (ler.RefType == LexEntryRefTags.krtComplexForm) { fRemoveComponents = true; // If there are no components we will delete without asking...but must then check for more // complex forms that DO have components. if (ler.ComponentLexemesRS.Count > 0) { // TODO-Linux: Help is not implemented in Mono if (MessageBox.Show(FindForm(), DetailControlsStrings.ksRootNoComponentsMessage, DetailControlsStrings.ksRootNoComponentsCaption, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1, 0, m_mediator.HelpTopicProvider.HelpFile, HelpNavigator.Topic, "/Using_Tools/Lexicon_tools/Lexicon_Edit/change_the_morph_type.htm") != DialogResult.Yes) { return; } break; } } } } UndoableUnitOfWorkHelper.Do(sUndo, sRedo, entry, () => { if (fRemoveComponents) { foreach (var ler in entry.EntryRefsOS.Where(entryRef => entryRef.RefType == LexEntryRefTags.krtComplexForm)) { entry.EntryRefsOS.Remove(ler); } } if (IsStemType(original) || m_obj is IMoStemAllomorph) { if (IsStemType(selected)) { Target = selected; } else { //have to switch from stem to affix fMadeMorphTypeChange = ChangeStemToAffix(entry, selected); } } else { // original is affix variety if (IsStemType(selected)) { //have to switch from affix to stem fMadeMorphTypeChange = ChangeAffixToStem(entry, selected); } else { Target = selected; } } if (selected.Guid == MoMorphTypeTags.kguidMorphPhrase) { ILexEntryRef ler = m_cache.ServiceLocator.GetInstance <ILexEntryRefFactory>().Create(); entry.EntryRefsOS.Add(ler); ler.RefType = LexEntryRefTags.krtComplexForm; ler.HideMinorEntry = 1; } }); } } }
public void UpdateWritingSystemTag_MarksObjectsAsDirty() { var entry0 = Cache.ServiceLocator.GetInstance <ILexEntryFactory>().Create(); CoreWritingSystemDefinition newWs; WritingSystemServices.FindOrCreateWritingSystem(Cache, null, "en-NO", true, false, out newWs); // A string property NOT using the WS we will change. entry0.ImportResidue = TsStringUtils.MakeString("hello", Cache.DefaultAnalWs); // A multilingual one using the WS. entry0.LiteralMeaning.set_String(Cache.DefaultAnalWs, TsStringUtils.MakeString("whatever", Cache.DefaultAnalWs)); var entry1 = Cache.ServiceLocator.GetInstance <ILexEntryFactory>().Create(); var sense1 = Cache.ServiceLocator.GetInstance <ILexSenseFactory>().Create(); entry1.SensesOS.Add(sense1); // Sense1 should be dirty: it has a gloss in the changing WS. sense1.Gloss.set_String(newWs.Handle, TsStringUtils.MakeString("whatever", newWs.Handle)); // Entry2 should be dirty: it has a string property with a run in the changing WS. var entry2 = Cache.ServiceLocator.GetInstance <ILexEntryFactory>().Create(); var bldr = TsStringUtils.MakeString("abc ", Cache.DefaultAnalWs).GetBldr(); bldr.ReplaceTsString(bldr.Length, bldr.Length, TsStringUtils.MakeString("def", newWs.Handle)); var stringWithNewWs = bldr.GetString(); entry2.ImportResidue = stringWithNewWs; // Sense3 should be dirty: it has a multistring string property with a run in the changing WS. var entry3 = Cache.ServiceLocator.GetInstance <ILexEntryFactory>().Create(); var sense3 = Cache.ServiceLocator.GetInstance <ILexSenseFactory>().Create(); entry3.SensesOS.Add(sense3); sense3.Definition.set_String(Cache.DefaultAnalWs, stringWithNewWs); Cache.LangProject.AnalysisWss = "en en-SU"; m_actionHandler.EndUndoTask(); var undoManager = Cache.ServiceLocator.GetInstance <IUndoStackManager>(); undoManager.Save(); // makes everything non-dirty. var newbies = new HashSet <ICmObjectId>(); var dirtballs = new HashSet <ICmObjectOrSurrogate>(new ObjectSurrogateEquater()); var goners = new HashSet <ICmObjectId>(); Assert.That(dirtballs.Count, Is.EqualTo(0)); // After save nothing should be dirty. var uowServices = Cache.ServiceLocator.GetInstance <IUnitOfWorkService>(); uowServices.GatherChanges(newbies, dirtballs, goners); UndoableUnitOfWorkHelper.Do("doit", "undoit", m_actionHandler, () => WritingSystemServices.UpdateWritingSystemId(Cache, newWs, "en-SU")); newbies = new HashSet <ICmObjectId>(); dirtballs = new HashSet <ICmObjectOrSurrogate>(new ObjectSurrogateEquater()); goners = new HashSet <ICmObjectId>(); uowServices.GatherChanges(newbies, dirtballs, goners); Assert.That(dirtballs.Contains((ICmObjectOrSurrogate)sense1)); Assert.That(!dirtballs.Contains((ICmObjectOrSurrogate)entry0)); // make sure the implementation doesn't just dirty everything. Assert.That(dirtballs.Contains((ICmObjectOrSurrogate)entry2)); Assert.That(dirtballs.Contains((ICmObjectOrSurrogate)sense3)); Assert.That(Cache.LangProject.AnalysisWss, Is.EqualTo("en en-NO"), "should have updated WS lists"); }
public void VectorPropertyTests() { var servLoc = Cache.ServiceLocator; var entryFactory = servLoc.GetInstance <ILexEntryFactory>(); var resourceFactory = servLoc.GetInstance <ICmResourceFactory>(); var lexDb = Cache.LanguageProject.LexDbOA; ILexEntry le2 = null; // The following tests assume one resource originally exists. We also need le2, to be the owner // of the senses. UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { lexDb.ResourcesOC.Add(resourceFactory.Create()); le2 = entryFactory.Create(); }); // 1 ClearChanges(); UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => lexDb.ResourcesOC.Clear()); // Check the Resources vector prop. CheckChanges(1, -1, lexDb.Hvo, LexDbTags.kflidResources, 0, 1, 0); ClearChanges(); m_actionHandler.Undo(); CheckChanges(1, -1, lexDb.Hvo, LexDbTags.kflidResources, 0, 0, 0); m_actionHandler.Redo(); ClearChanges(); // 2 // Test a collection property. ICmResource res1 = null; UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { // Add one item. res1 = resourceFactory.Create(); lexDb.ResourcesOC.Add(res1); }); // Check the Entries vector prop. CheckChanges(1, 0, lexDb.Hvo, LexDbTags.kflidResources, 0, 1, 0); ClearChanges(); m_actionHandler.Undo(); CheckChanges(1, 0, lexDb.Hvo, LexDbTags.kflidResources, 0, 0, 1); m_actionHandler.Redo(); ClearChanges(); // 3 ICmResource res2 = null; UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { // Add another item. res2 = resourceFactory.Create(); lexDb.ResourcesOC.Add(res2); }); // Check the Resources vector prop. CheckChanges(1, 0, lexDb.Hvo, LexDbTags.kflidResources, 1, 1, 0); ClearChanges(); m_actionHandler.Undo(); CheckChanges(1, 0, lexDb.Hvo, LexDbTags.kflidResources, 1, 0, 1); m_actionHandler.Redo(); SetLexeme(le2, "second"); ClearChanges(); // 4 ICmResource res3 = null; ICmResource res4 = null; UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { // Add two new items. res3 = resourceFactory.Create(); lexDb.ResourcesOC.Add(res3); res4 = resourceFactory.Create(); lexDb.ResourcesOC.Add(res4); }); // Check the Entries vector prop. CheckChanges(1, 0, lexDb.Hvo, LexDbTags.kflidResources, 2, 2, 0); ClearChanges(); m_actionHandler.Undo(); CheckChanges(1, 0, lexDb.Hvo, LexDbTags.kflidResources, 2, 0, 2); m_actionHandler.Redo(); ClearChanges(); // 5 UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { // Remove a couple of non-contiguous items. res1.Delete(); res3.Delete(); }); // Check the Entries vector prop. CheckChanges(1, 0, lexDb.Hvo, LexDbTags.kflidResources, 0, 1, 3); ClearChanges(); m_actionHandler.Undo(); CheckChanges(1, 0, lexDb.Hvo, LexDbTags.kflidResources, 0, 3, 1); m_actionHandler.Redo(); ClearChanges(); // 6 UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => res4.Delete()); // Check the Entries vector prop. CheckChanges(1, 0, lexDb.Hvo, LexDbTags.kflidResources, 1, 0, 1); ClearChanges(); m_actionHandler.Undo(); CheckChanges(1, 0, lexDb.Hvo, LexDbTags.kflidResources, 1, 1, 0); m_actionHandler.Redo(); ClearChanges(); // 7 // Test a sequence property. // By this point only le2 is still there, // which is fine, since we are moving to test senses, // and they can all go into le2. var senseFactory = servLoc.GetInstance <ILexSenseFactory>(); UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { // Add one item. var se1 = senseFactory.Create(); le2.SensesOS.Add(se1); }); // Check the Senses vector prop. CheckChanges(le2.Hvo, LexEntryTags.kflidSenses, 0, 1, 0); ClearChanges(); m_actionHandler.Undo(); CheckChanges(le2.Hvo, LexEntryTags.kflidSenses, 0, 0, 1); m_actionHandler.Redo(); ClearChanges(); // 8 UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { // Add another item, but before the other sense. var se2 = senseFactory.Create(); le2.SensesOS.Insert(0, se2); }); // Check the Senses vector prop. CheckChanges(le2.Hvo, LexEntryTags.kflidSenses, 0, 1, 0); ClearChanges(); m_actionHandler.Undo(); CheckChanges(le2.Hvo, LexEntryTags.kflidSenses, 0, 0, 1); m_actionHandler.Redo(); ClearChanges(); // 9 UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { // Add another item, but between the other two senses. var se3 = senseFactory.Create(); le2.SensesOS.Insert(1, se3); }); // Check the Senses vector prop. CheckChanges(le2.Hvo, LexEntryTags.kflidSenses, 1, 1, 0); ClearChanges(); m_actionHandler.Undo(); CheckChanges(le2.Hvo, LexEntryTags.kflidSenses, 1, 0, 1); m_actionHandler.Redo(); ClearChanges(); // 10 UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => { // Add another item, but between two senses. var se4 = senseFactory.Create(); le2.SensesOS.Insert(2, se4); // Add yet another one at the end. var se5 = senseFactory.Create(); le2.SensesOS.Add(se5); }); // Check the Senses vector prop. CheckChanges(le2.Hvo, LexEntryTags.kflidSenses, 2, 3, 1); ClearChanges(); m_actionHandler.Undo(); CheckChanges(le2.Hvo, LexEntryTags.kflidSenses, 2, 1, 3); m_actionHandler.Redo(); ClearChanges(); // 11 // Clear Entries prop var resourcesCount = lexDb.ResourcesOC.Count(); UndoableUnitOfWorkHelper.Do("Undo stuff", "Redo stuff", m_actionHandler, () => lexDb.ResourcesOC.Clear()); // Check the Entries vector prop. CheckChanges(1, 0, lexDb.Hvo, LexDbTags.kflidResources, 0, 0, resourcesCount); ClearChanges(); m_actionHandler.Undo(); CheckChanges(lexDb.Hvo, LexDbTags.kflidResources, 0, resourcesCount, 0); m_actionHandler.Redo(); ClearChanges(); }