Example #1
0
        public void ExportVariantTypeInformation_LT9374()
        {
            CheckDisposed();

            m_choices.Add(InterlinLineChoices.kflidWord);
            m_choices.Add(InterlinLineChoices.kflidMorphemes);
            m_choices.Add(InterlinLineChoices.kflidLexEntries);
            m_choices.Add(InterlinLineChoices.kflidLexGloss);
            m_choices.Add(InterlinLineChoices.kflidLexPos);

            XmlDocument exportedDoc = ExportToXml();
            IStTxtPara  para1       = m_text1.ContentsOA.ParagraphsOS[1] as IStTxtPara;

            ValidateExportedParagraph(exportedDoc, m_choices, para1);
            // Set alternate case endings.

            ParagraphAnnotator ta              = new ParagraphAnnotator(para1);
            string             formLexEntry    = "go";
            ITsString          tssLexEntryForm = StringUtils.MakeTss(formLexEntry, Cache.DefaultVernWs);
            int       clsidForm;
            ILexEntry leGo = LexEntry.CreateEntry(Cache,
                                                  MoMorphType.FindMorphType(Cache, new MoMorphTypeCollection(Cache), ref formLexEntry, out clsidForm), tssLexEntryForm,
                                                  "go.pst", null);

            ta.SetVariantOf(0, 1, leGo, "fr. var.");
            exportedDoc = this.ExportToXml();
            ValidateExportedParagraph(exportedDoc, m_choices, para1);
        }
Example #2
0
        /// <summary>
        /// Constructor.
        /// </summary>
        public MoMorphTypeCollection(FdoCache fdoCache)
        {
            Debug.Assert(fdoCache != null);
            m_fdoCache = fdoCache;

            List <IMoMorphType> al = new List <IMoMorphType>();

            foreach (IMoMorphType mt in m_fdoCache.LangProject.LexDbOA.MorphTypesOA.ReallyReallyAllPossibilities)
            {
                al.Add(mt);
            }
            if (al.Count < kmtLimit)
            {
                AddMissingMorphTypes(al, fdoCache);
            }
            Debug.Assert(al.Count == kmtLimit);
            InnerList.Capacity = kmtLimit;
            for (int i = 0; i < kmtLimit; ++i)
            {
                InnerList.Add(null);
            }
            foreach (IMoMorphType mmt in al)
            {
                InnerList[MoMorphType.FindMorphTypeIndex(fdoCache, mmt)] = mmt;
            }
        }
Example #3
0
        protected InterlinearExporter(FdoCache cache, XmlWriter writer, int hvoRoot, InterlinLineChoices lineChoices, InterlinVc vc, ITsString tssTextName, ITsString tssTextAbbreviation)
            : base(null, cache.MainCacheAccessor, hvoRoot)
        {
            m_cache                = cache;
            m_writer               = writer;
            ktagParaSegments       = InterlinVc.ParaSegmentTag(cache);
            ktagSegmentForms       = InterlinVc.SegmentFormsTag(cache);
            m_flidStringValue      = CmBaseAnnotation.StringValuePropId(cache);
            m_lineChoices          = lineChoices;
            m_defaultGlossVirtFlid = BaseVirtualHandler.GetInstalledHandlerTag(m_cache, "WfiMorphBundle", "DefaultSense");
            m_vc = vc;
            m_tssPendingTitle      = tssTextName;
            m_tssTitleAbbreviation = tssTextAbbreviation;

            // Get morphtype information that we need later.  (plus stuff we don't...)  See LT-8288.
            IMoMorphType mmtStem;
            IMoMorphType mmtPrefix;
            IMoMorphType mmtSuffix;
            IMoMorphType mmtInfix;
            IMoMorphType mmtBoundStem;
            IMoMorphType mmtSimulfix;
            IMoMorphType mmtSuprafix;

            MoMorphType.GetMajorMorphTypes(cache, out mmtStem, out mmtPrefix, out mmtSuffix, out mmtInfix,
                                           out mmtBoundStem, out m_mmtProclitic, out m_mmtEnclitic, out mmtSimulfix, out mmtSuprafix);
        }
Example #4
0
 protected override void HandleMatchingSelectionChanged()
 {
     if (m_selEntryID > 0)
     {
         // Make sure that none of the allomorphs of this entry match the original
         // form before we can enable btnOK.
         ILexEntry le = LexEntry.CreateFromDBObject(m_cache, m_selEntryID);
         // true if current list of MoForms contains one with matching form text.
         bool fMatchingForm = false;
         // true if current list of MoForms contains one of correct type
         bool fMatchingType = false;
         // If we don't know a morpheme type, don't restrict by type.
         IMoMorphType mtOrig = null;
         if (m_hvoType == 0)
         {
             fMatchingType = true;
         }
         else
         {
             mtOrig = MoMorphType.CreateFromDBObject(m_cache, m_hvoType);
         }
         foreach (IMoForm mf in le.AllAllomorphs)
         {
             if (mf.Form.VernacularDefaultWritingSystem == m_formOrig)
             {
                 fMatchingForm = true;
                 fMatchingType = false;
             }
             // To prevent confusion, allow any type that is ambiguous with the
             // current type (or, of course, if it is the SAME type, which for some
             // reason is NOT considered ambiguous).
             if (mtOrig != null && mf.MorphTypeRA != null &&
                 (m_hvoType == mf.MorphTypeRA.Hvo ||
                  mtOrig.IsAmbiguousWith(m_cache, m_types, mtOrig, mf.MorphTypeRA)))
             {
                 fMatchingType = true;
             }
             if (fMatchingForm)
             {
                 break;
             }
         }
         m_fInconsistentType = !fMatchingType;
         m_fMatchingForm     = fMatchingForm;
         if (fMatchingForm && fMatchingType)
         {
             btnOK.Text = SIL.FieldWorks.LexText.Controls.LexTextControls.ksUseAllomorph;
         }
         else
         {
             btnOK.Text = SIL.FieldWorks.LexText.Controls.LexTextControls.ksAddAllomorph_;
         }
         btnOK.Enabled = true;
     }
     else
     {
         base.HandleMatchingSelectionChanged();
     }
 }
Example #5
0
        private ILexEntry MakeEntry(string form, string gloss)
        {
            ITsString tssLexEntryForm = Cache.MakeVernTss(form);
            string    form1           = form;
            int       clsidForm;

            return(LexEntry.CreateEntry(Cache,
                                        MoMorphType.FindMorphType(Cache, new MoMorphTypeCollection(Cache), ref form1, out clsidForm), tssLexEntryForm,
                                        gloss, null));
        }
        private void SetupLexEntryAndSense(string formLexEntry, string senseGloss, string partOfSpeech, out ILexEntry lexEntry1_Entry, out ILexSense lexEntry1_Sense1)
        {
            ITsString tssLexEntryForm = StringUtils.MakeTss(formLexEntry, Cache.DefaultVernWs);
            int       clsidForm;
            // create a sense with a matching gloss
            DummyGenericMSA dummyMsa       = new DummyGenericMSA();
            int             hvoSenseMsaPos = m_sandbox.GetComboItemHvo(InterlinLineChoices.kflidWordPos, 0, partOfSpeech);

            dummyMsa.MainPOS = hvoSenseMsaPos;
            lexEntry1_Entry  = LexEntry.CreateEntry(Cache,
                                                    MoMorphType.FindMorphType(Cache, new MoMorphTypeCollection(Cache), ref formLexEntry, out clsidForm), tssLexEntryForm,
                                                    senseGloss, dummyMsa);
            lexEntry1_Sense1 = lexEntry1_Entry.SensesOS[0];
        }
Example #7
0
        private void Init()
        {
            MoMorphType.GetMajorMorphTypes(m_cache, out m_mmtStem, out m_mmtPrefix, out m_mmtSuffix, out m_mmtInfix,
                                           out m_mmtBoundStem, out m_mmtProclitic, out m_mmtEnclitic, out m_mmtSimulfix, out m_mmtSuprafix);

            string sStemExample  = m_stringTable.GetString("EditMorphBreaks-stemExample", "DialogStrings");
            string sAffixExample = m_stringTable.GetString("EditMorphBreaks-affixExample", "DialogStrings");

            string lbl_stemExample = String.Format(sStemExample,
                                                   m_mmtStem.Prefix == null ? "" : m_mmtStem.Prefix,
                                                   m_mmtStem.Postfix == null ? "" : m_mmtStem.Postfix);
            string lbl_boundStemExample = String.Format(sStemExample,
                                                        m_mmtBoundStem.Prefix == null ? "" : m_mmtBoundStem.Prefix,
                                                        m_mmtBoundStem.Postfix == null ? "" : m_mmtBoundStem.Postfix);
            string lbl_prefixExample = String.Format(sAffixExample,
                                                     m_mmtPrefix.Prefix == null ? "" : " " + m_mmtPrefix.Prefix,
                                                     m_mmtPrefix.Postfix == null ? "" : m_mmtPrefix.Postfix + " ");
            string lbl_suffixExample = String.Format(sAffixExample,
                                                     m_mmtSuffix.Prefix == null ? "" : " " + m_mmtSuffix.Prefix,
                                                     m_mmtSuffix.Postfix == null ? "" : m_mmtSuffix.Postfix + " ");
            string lbl_infixExample = String.Format(sAffixExample,
                                                    m_mmtInfix.Prefix == null ? "" : " " + m_mmtInfix.Prefix,
                                                    m_mmtInfix.Postfix == null ? "" : m_mmtInfix.Postfix + " ");
            string lbl_procliticExample = String.Format(sAffixExample,
                                                        m_mmtProclitic.Prefix == null ? "" : " " + m_mmtProclitic.Prefix,
                                                        m_mmtProclitic.Postfix == null ? "" : m_mmtProclitic.Postfix + " ");
            string lbl_encliticExample = String.Format(sAffixExample,
                                                       m_mmtEnclitic.Prefix == null ? "" : " " + m_mmtEnclitic.Prefix,
                                                       m_mmtEnclitic.Postfix == null ? "" : m_mmtEnclitic.Postfix + " ");
            string lbl_simulfixExample = String.Format(sAffixExample,
                                                       m_mmtSimulfix.Prefix == null ? "" : " " + m_mmtSimulfix.Prefix,
                                                       m_mmtSimulfix.Postfix == null ? "" : m_mmtSimulfix.Postfix + " ");
            string lbl_suprafixExample = String.Format(sAffixExample,
                                                       m_mmtSuprafix.Prefix == null ? "" : " " + m_mmtSuprafix.Prefix,
                                                       m_mmtSuprafix.Postfix == null ? "" : m_mmtSuprafix.Postfix + " ");

            MenuItems.Add(String.Format(FwCoreDlgs.ksStemMenuCmd, lbl_stemExample), new EventHandler(stem));
            MenuItems.Add(String.Format(FwCoreDlgs.ksPrefixMenuCmd, lbl_prefixExample), new EventHandler(prefix));
            MenuItems.Add(String.Format(FwCoreDlgs.ksSuffixMenuCmd, lbl_suffixExample), new EventHandler(suffix));
            MenuItems.Add(String.Format(FwCoreDlgs.ksInfixMenuCmd, lbl_infixExample), new EventHandler(infix));
            MenuItems.Add(String.Format(FwCoreDlgs.ksBdStemMenuCmd, lbl_boundStemExample), new EventHandler(boundStem));
            MenuItems.Add(String.Format(FwCoreDlgs.ksProcliticMenuCmd, lbl_procliticExample), new EventHandler(proclitic));
            MenuItems.Add(String.Format(FwCoreDlgs.ksEncliticMenuCmd, lbl_encliticExample), new EventHandler(enclitic));
            MenuItems.Add(String.Format(FwCoreDlgs.ksSimulfixMenuCmd, lbl_simulfixExample), new EventHandler(simulfix));
            MenuItems.Add(String.Format(FwCoreDlgs.ksSuprafixMenuCmd, lbl_suprafixExample), new EventHandler(suprafix));

            MenuItems.Add("-");
            MenuItems.Add(FwCoreDlgs.ksMorphemeBreakHelp, new EventHandler(showHelp));
        }
Example #8
0
        public void SetGetSingleTsString()
        {
            CheckDisposed();

            m_inMemoryCache.InitializeLexDb();

            int[]       morphTypeHVOs = Cache.LangProject.LexDbOA.MorphTypesOA.PossibilitiesOS.HvoArray;
            MoMorphType mmt           = new MoMorphType(Cache, morphTypeHVOs[0]);

            // TEST WRITE
            mmt.Prefix = "*";

            // TEST READ
            Assert.AreEqual("*", mmt.Prefix);
        }
Example #9
0
        /// <summary>
        /// Make (two) monomorphemic analyses on our favorite wordform, connected to two entries, one with two glosses.
        /// </summary>
        private void MakeMonoAnalyses()
        {
            string    formLexEntry    = "axx";
            ITsString tssLexEntryForm = Cache.MakeVernTss(formLexEntry);
            int       clsidForm;
            ILexEntry entry = LexEntry.CreateEntry(Cache,
                                                   MoMorphType.FindMorphType(Cache, new MoMorphTypeCollection(Cache), ref formLexEntry, out clsidForm), tssLexEntryForm,
                                                   "axe", null);
            ILexSense senseAxe = entry.SensesOS[0];
            IMoForm   form     = entry.LexemeFormOA;

            m_wfaAxe = new WfiAnalysis();
            m_wfAxx.AnalysesOC.Add(m_wfaAxe);
            IWfiMorphBundle bundle = m_wfaAxe.MorphBundlesOS.Append(new WfiMorphBundle());

            bundle.MorphRA = form;
            bundle.SenseRA = senseAxe;

            m_wgAxe = new WfiGloss();
            m_wfaAxe.MeaningsOC.Add(m_wgAxe);
            m_wgAxe.Form.AnalysisDefaultWritingSystem = "axe";

            m_wgChopper = new WfiGloss();
            m_wfaAxe.MeaningsOC.Add(m_wgChopper);
            m_wgChopper.Form.AnalysisDefaultWritingSystem = "chopper";
            m_wfaAxe.SetAgentOpinion(m_fdoCache.LangProject.DefaultUserAgent, Opinions.approves);

            ILexEntry entryCut = LexEntry.CreateEntry(Cache,
                                                      MoMorphType.FindMorphType(Cache, new MoMorphTypeCollection(Cache), ref formLexEntry, out clsidForm), tssLexEntryForm,
                                                      "cut", null);

            m_wfaCut = new WfiAnalysis();
            m_wfAxx.AnalysesOC.Add(m_wfaCut);
            bundle         = m_wfaCut.MorphBundlesOS.Append(new WfiMorphBundle());
            bundle.MorphRA = entryCut.LexemeFormOA;
            bundle.SenseRA = entryCut.SensesOS[0];

            m_wgCut = new WfiGloss();
            m_wfaCut.MeaningsOC.Add(m_wgCut);
            m_wgCut.Form.AnalysisDefaultWritingSystem = "cut";
            m_wfaCut.SetAgentOpinion(m_fdoCache.LangProject.DefaultUserAgent, Opinions.approves);

            m_cAnalyses += 2;
        }
        public void NewGlossExistingLexEntryNewLexSense()
        {
            int hvoCba0_0 = GetCbaHvo(0, 0, 0);

            m_sandbox.SwitchWord(hvoCba0_0, false);
            string    formLexEntry    = "xxxa";
            ITsString tssLexEntryForm = StringUtils.MakeTss(formLexEntry, Cache.DefaultVernWs);
            int       clsidForm;
            ILexEntry lexEntry1_Entry = LexEntry.CreateEntry(Cache,
                                                             MoMorphType.FindMorphType(Cache, new MoMorphTypeCollection(Cache), ref formLexEntry, out clsidForm), tssLexEntryForm,
                                                             "xxxa.existingsense1", null);
            ILexSense lexEntry1_Sense1 = lexEntry1_Entry.SensesOS[0];

            // mark the count of LexEntries
            int cEntriesOrig = Cache.LangProject.LexDbOA.EntriesOC.Count;

            // add a new word gloss
            ITsString   tssWordGlossInSandbox = m_sandbox.SetTssInSandbox(InterlinLineChoices.kflidWordGloss, Cache.DefaultAnalWs, "0.0.xxxa");
            int         hvoWf = WfiWordform.GetWfiWordformFromInstanceOf(Cache, hvoCba0_0);
            WfiWordform wf    = new WfiWordform(Cache, hvoWf);
            // set word pos, to first possibility (e.g. 'adjunct')
            int hvoSbWordPos = m_sandbox.SelectIndexInCombo(InterlinLineChoices.kflidWordPos, 0, 0);

            // confirm the analysis (making a real analysis and a LexSense)
            int      hvoGloss = m_sandbox.ConfirmAnalysis();
            WfiGloss wfiGloss = new WfiGloss(Cache, hvoGloss);

            // make sure we didn't add entries to the Lexicon.
            int cEntriesAfter = Cache.LangProject.LexDbOA.EntriesOC.Count;

            Assert.AreEqual(cEntriesOrig, cEntriesAfter);

            // confirm we have only one analysis and that it is monomorphemic
            WfiAnalysis wfiAnalysis = wfiGloss.Owner as WfiAnalysis;

            Assert.AreEqual(wf.Hvo, wfiAnalysis.OwnerHVO, "Expected confirmed analysis to be owned by the original wordform.");
            Assert.AreEqual(1, wf.AnalysesOC.Count);
            Assert.AreEqual(1, wfiAnalysis.MorphBundlesOS.Count);
            Assert.AreEqual(1, wfiAnalysis.MeaningsOC.Count);

            // make sure the strings of the wfi gloss matches the strings of the lex gloss.
            ValidateSenseWithAnalysis(m_sandbox.GetLexSenseForWord(), wfiGloss, hvoSbWordPos);
        }
Example #11
0
        private Set <int> GetHvoSlots()
        {
            Set <int>     hvoSlots;
            IPartOfSpeech pos = PartOfSpeech.CreateFromDBObject(m_cache, m_selectedMainPOSHvo);

            if (m_morphType == null)
            {             // Not called by InsertEntryDlg; need to figure out the morphtype(s)
                LexEntry lex = m_mediator.PropertyTable.GetValue("ActiveClerkSelectedObject") as LexEntry;
                if (lex != null)
                {
                    hvoSlots = MoInflAffMsa.GetSetOfSlots(m_cache, lex, pos);
                }
                else
                {
                    hvoSlots = new Set <int>(pos.AllAffixSlotIDs);
                }
            }
            else
            {             //  Called by InsertEntryDlg so we know the morphtype
                bool fIsPrefixal = false;
                bool fIsSuffixal = false;
                if (MoMorphType.IsPrefixishType(m_cache, m_morphType.Hvo))
                {
                    fIsPrefixal = true;
                }
                if (MoMorphType.IsSuffixishType(m_cache, m_morphType.Hvo))
                {
                    fIsSuffixal = true;
                }
                if (fIsPrefixal && fIsSuffixal)
                {
                    hvoSlots = new Set <int>(pos.AllAffixSlotIDs);
                }
                else
                {
                    hvoSlots =
                        MoInflAffixTemplate.GetSomeSlots(m_cache, new Set <int>(pos.AllAffixSlotIDs), fIsPrefixal);
                }
            }
            return(hvoSlots);
        }
Example #12
0
        /// <summary>
        /// decide whether to display this tree insert Menu Item
        /// </summary>
        /// <param name="commandObject"></param>
        /// <param name="display"></param>
        /// <returns></returns>
        public override bool OnDisplayDataTreeInsert(object commandObject, ref UIItemDisplayProperties display)
        {
            Slice slice = m_dataEntryForm.CurrentSlice;

            if (slice == null && m_dataEntryForm.Controls.Count > 0)
            {
                slice = m_dataEntryForm.FieldAt(0);
            }
            if (slice == null ||
                (m_dataEntryForm.Mediator.PropertyTable.GetValue("ActiveClerk") as RecordClerk).ListSize == 0)
            {
                // don't display the datatree menu/toolbar items when we don't have a data tree slice.
                display.Visible = false;
                display.Enabled = false;
                return(true);
            }

            base.OnDisplayDataTreeInsert(commandObject, ref display);

            if (!(slice.Object is LexEntry) && !(slice.ContainingDataTree.Root is LexEntry))
            {
                return(false);
            }
            FDO.Ling.LexEntry entry = slice.Object as LexEntry;
            if (entry == null)
            {
                entry = slice.ContainingDataTree.Root as LexEntry;
            }
            XCore.Command command = (XCore.Command)commandObject;

            if (command.Id.EndsWith("AffixProcess"))
            {
                bool enable = MoMorphType.IsAffixType(entry.MorphType);
                display.Enabled = enable;
                display.Visible = enable;
                return(true);
            }

            //if there aren't any alternate forms, go ahead and let the user choose either kind
            if (entry.AlternateFormsOS.Count == 0)
            {
                return(true);
            }

            if (command.Id.EndsWith("AffixAllomorph"))
            {
                if (!(entry.AlternateFormsOS.FirstItem is MoAffixAllomorph))
                {
                    display.Visible = false;
                }
                return(true);
            }

            if (command.Id.EndsWith("StemAllomorph"))
            {
                if (!(entry.AlternateFormsOS.FirstItem is MoStemAllomorph))
                {
                    display.Visible = false;
                }
                return(true);
            }

            return(true);           //we handled this, no need to ask anyone else.
        }
Example #13
0
        /// <summary>
        /// If Phrase and Discontiguous Phrase somehow missed getting added by data migration,
        /// add them now.  See LT-5567 for an occurrence of this problem.
        /// Actually, LTB-344 demonstrates that another morphtype might be missing for some
        /// reason, so this is a general fix for any number of missing morphtypes.
        /// </summary>
        /// <param name="morphTypes"></param>
        /// <param name="cache"></param>
        private static void AddMissingMorphTypes(List <IMoMorphType> morphTypes, FdoCache cache)
        {
            List <string> neededTypes = new List <string>(19);

            neededTypes.Add(MoMorphType.kguidMorphBoundRoot);
            neededTypes.Add(MoMorphType.kguidMorphBoundStem);
            neededTypes.Add(MoMorphType.kguidMorphCircumfix);
            neededTypes.Add(MoMorphType.kguidMorphClitic);
            neededTypes.Add(MoMorphType.kguidMorphDiscontiguousPhrase);
            neededTypes.Add(MoMorphType.kguidMorphEnclitic);
            neededTypes.Add(MoMorphType.kguidMorphInfix);
            neededTypes.Add(MoMorphType.kguidMorphInfixingInterfix);
            neededTypes.Add(MoMorphType.kguidMorphParticle);
            neededTypes.Add(MoMorphType.kguidMorphPhrase);
            neededTypes.Add(MoMorphType.kguidMorphPrefix);
            neededTypes.Add(MoMorphType.kguidMorphPrefixingInterfix);
            neededTypes.Add(MoMorphType.kguidMorphProclitic);
            neededTypes.Add(MoMorphType.kguidMorphRoot);
            neededTypes.Add(MoMorphType.kguidMorphSimulfix);
            neededTypes.Add(MoMorphType.kguidMorphStem);
            neededTypes.Add(MoMorphType.kguidMorphSuffix);
            neededTypes.Add(MoMorphType.kguidMorphSuffixingInterfix);
            neededTypes.Add(MoMorphType.kguidMorphSuprafix);
            foreach (IMoMorphType mmt in morphTypes)
            {
                foreach (string sGuid in neededTypes)
                {
                    if (mmt.Guid.ToString().ToLowerInvariant() == sGuid.ToLowerInvariant())
                    {
                        neededTypes.Remove(sGuid);
                        break;
                    }
                }
            }
            int wsEn = cache.LanguageEncodings.GetWsFromIcuLocale("en");

            foreach (string sGuid in neededTypes)
            {
                MoMorphType mmt = new MoMorphType();
                cache.LangProject.LexDbOA.MorphTypesOA.PossibilitiesOS.Append(mmt);
                mmt.Guid        = new Guid(sGuid);
                mmt.ForeColor   = -1073741824;
                mmt.BackColor   = -1073741824;
                mmt.UnderColor  = -1073741824;
                mmt.IsProtected = true;
                switch (sGuid)
                {
                case MoMorphType.kguidMorphBoundRoot:
                    mmt.Name.SetAlternative("bound root", wsEn);
                    mmt.Abbreviation.SetAlternative("bd root", wsEn);
                    mmt.Description.SetAlternative("A bound root is a root which cannot occur as a separate word apart from any other morpheme.", wsEn);
                    mmt.Prefix         = "*";
                    mmt.SecondaryOrder = 10;
                    break;

                case MoMorphType.kguidMorphBoundStem:
                    mmt.Name.SetAlternative("bound stem", wsEn);
                    mmt.Abbreviation.SetAlternative("bd stem", wsEn);
                    mmt.Description.SetAlternative("A bound stem is a stem  which cannot occur as a separate word apart from any other morpheme.", wsEn);
                    mmt.Prefix         = "*";
                    mmt.SecondaryOrder = 10;
                    break;

                case MoMorphType.kguidMorphCircumfix:
                    mmt.Name.SetAlternative("circumfix", wsEn);
                    mmt.Abbreviation.SetAlternative("cfx", wsEn);
                    mmt.Description.SetAlternative("A circumfix is an affix made up of two separate parts which surround and attach to a root or stem.", wsEn);
                    break;

                case MoMorphType.kguidMorphClitic:
                    mmt.Name.SetAlternative("clitic", wsEn);
                    mmt.Abbreviation.SetAlternative("c**t", wsEn);
                    mmt.Description.SetAlternative("A clitic is a morpheme that has syntactic characteristics of a word, but shows evidence of being phonologically bound to another word. Orthographically, it stands alone.", wsEn);
                    break;

                case MoMorphType.kguidMorphDiscontiguousPhrase:
                    mmt.Name.SetAlternative("discontiguous phrase", wsEn);
                    mmt.Abbreviation.SetAlternative("dis phr", wsEn);
                    mmt.Description.SetAlternative("A discontiguous phrase has discontiguous constituents which (a) are separated from each other by one or more intervening constituents, and (b) are considered either (i) syntactically contiguous and unitary, or (ii) realizing the same, single meaning. An example is French ne...pas.", wsEn);
                    break;

                case MoMorphType.kguidMorphEnclitic:
                    mmt.Name.SetAlternative("enclitic", wsEn);
                    mmt.Abbreviation.SetAlternative("enclit", wsEn);
                    mmt.Description.SetAlternative("An enclitic is a clitic that is phonologically joined at the end of a preceding word to form a single unit. Orthographically, it may attach to the preceding word.", wsEn);
                    mmt.Prefix         = "=";
                    mmt.SecondaryOrder = 80;
                    break;

                case MoMorphType.kguidMorphInfix:
                    mmt.Name.SetAlternative("infix", wsEn);
                    mmt.Abbreviation.SetAlternative("ifx", wsEn);
                    mmt.Description.SetAlternative("An infix is an affix that is inserted within a root or stem.", wsEn);
                    mmt.Postfix        = "-";
                    mmt.Prefix         = "-";
                    mmt.SecondaryOrder = 40;
                    break;

                case MoMorphType.kguidMorphInfixingInterfix:
                    mmt.Name.SetAlternative("infixing interfix", wsEn);
                    mmt.Abbreviation.SetAlternative("ifxnfx", wsEn);
                    mmt.Description.SetAlternative("An infixing interfix is an infix that can occur between two roots or stems.", wsEn);
                    mmt.Postfix = "-";
                    mmt.Prefix  = "-";
                    break;

                case MoMorphType.kguidMorphParticle:
                    mmt.Name.SetAlternative("particle", wsEn);
                    mmt.Abbreviation.SetAlternative("part", wsEn);
                    mmt.Description.SetAlternative("A particle is a word that does not belong to one of the main classes of words, is invariable in form, and typically has grammatical or pragmatic meaning.", wsEn);
                    break;

                case MoMorphType.kguidMorphPhrase:
                    mmt.Name.SetAlternative("phrase", wsEn);
                    mmt.Abbreviation.SetAlternative("phr", wsEn);
                    mmt.Description.SetAlternative("A phrase is a syntactic structure that consists of more than one word but lacks the subject-predicate organization of a clause.", wsEn);
                    break;

                case MoMorphType.kguidMorphPrefix:
                    mmt.Name.SetAlternative("prefix", wsEn);
                    mmt.Abbreviation.SetAlternative("pfx", wsEn);
                    mmt.Description.SetAlternative("A prefix is an affix that is joined before a root or stem.", wsEn);
                    mmt.Postfix        = "-";
                    mmt.SecondaryOrder = 20;
                    break;

                case MoMorphType.kguidMorphPrefixingInterfix:
                    mmt.Name.SetAlternative("prefixing interfix", wsEn);
                    mmt.Abbreviation.SetAlternative("pfxnfx", wsEn);
                    mmt.Description.SetAlternative("A prefixing interfix is a prefix that can occur between two roots or stems.", wsEn);
                    mmt.Postfix = "-";
                    break;

                case MoMorphType.kguidMorphProclitic:
                    mmt.Name.SetAlternative("proclitic", wsEn);
                    mmt.Abbreviation.SetAlternative("proclit", wsEn);
                    mmt.Description.SetAlternative("A proclitic is a clitic that precedes the word to which it is phonologically joined. Orthographically, it may attach to the following word.", wsEn);
                    mmt.Postfix        = "=";
                    mmt.SecondaryOrder = 30;
                    break;

                case MoMorphType.kguidMorphRoot:
                    mmt.Name.SetAlternative("root", wsEn);
                    mmt.Abbreviation.SetAlternative("ubd root", wsEn);
                    mmt.Description.SetAlternative("A root is the portion of a word that (i) is common to a set of derived or inflected forms, if any, when all affixes are removed, (ii) is not further analyzable into meaningful elements, being morphologically simple, and, (iii) carries the principle portion of meaning of the words in which it functions.", wsEn);
                    break;

                case MoMorphType.kguidMorphSimulfix:
                    mmt.Name.SetAlternative("simulfix", wsEn);
                    mmt.Abbreviation.SetAlternative("smfx", wsEn);
                    mmt.Description.SetAlternative("A simulfix is a change or replacement of vowels or consonants (usually vowels) which changes the meaning of a word.  (Note: the parser does not currently handle simulfixes.)", wsEn);
                    mmt.Postfix        = "=";
                    mmt.Prefix         = "=";
                    mmt.SecondaryOrder = 60;
                    break;

                case MoMorphType.kguidMorphStem:
                    mmt.Name.SetAlternative("stem", wsEn);
                    mmt.Abbreviation.SetAlternative("ubd stem", wsEn);
                    mmt.Description.SetAlternative("\"A stem is the root or roots of a word, together with any derivational affixes, to which inflectional affixes are added.\" (LinguaLinks Library).  A stem \"may consist solely of a single root morpheme (i.e. a 'simple' stem as in man), or of two root morphemes (e.g. a 'compound' stem, as in blackbird), or of a root morpheme plus a derivational affix (i.e. a 'complex' stem, as in manly, unmanly, manliness).  All have in common the notion that it is to the stem that inflectional affixes are attached.\" (Crystal, 1997:362)", wsEn);
                    break;

                case MoMorphType.kguidMorphSuffix:
                    mmt.Name.SetAlternative("suffix", wsEn);
                    mmt.Abbreviation.SetAlternative("sfx", wsEn);
                    mmt.Description.SetAlternative("A suffix is an affix that is attached to the end of a root or stem.", wsEn);
                    mmt.Prefix         = "-";
                    mmt.SecondaryOrder = 70;
                    break;

                case MoMorphType.kguidMorphSuffixingInterfix:
                    mmt.Name.SetAlternative("suffixing interfix", wsEn);
                    mmt.Abbreviation.SetAlternative("sfxnfx", wsEn);
                    mmt.Description.SetAlternative("A suffixing interfix is an suffix that can occur between two roots or stems.", wsEn);
                    mmt.Prefix = "-";
                    break;

                case MoMorphType.kguidMorphSuprafix:
                    mmt.Name.SetAlternative("suprafix", wsEn);
                    mmt.Abbreviation.SetAlternative("spfx", wsEn);
                    mmt.Description.SetAlternative("A suprafix is a kind of affix in which a suprasegmental is superimposed on one or more syllables of the root or stem, signalling a particular  morphosyntactic operation.  (Note: the parser does not currently handle suprafixes.)", wsEn);
                    mmt.Postfix        = "~";
                    mmt.Prefix         = "~";
                    mmt.SecondaryOrder = 50;
                    break;
                }
                morphTypes.Add(mmt);
            }
        }
        public void ParserDataChanges()
        {
            XmlNode node;

#if !ShowDumpResult
            m_fxtResult.Save(Path.Combine(System.IO.Path.GetTempPath(), "TestFxtUpdateBefore.xml"));
#endif
            // -------------
            // Make data changes
            // -------------
            // Make a change to stem allomorph
            ILangProject lp           = Cache.LangProject;
            ILexDb       lexdb        = lp.LexDbOA;
            int[]        aiLexEntries = lexdb.EntriesOC.HvoArray;
            int          hvoLexEntry  = aiLexEntries[0];
            ILexEntry    lexEntry     = CmObject.CreateFromDBObject(Cache, hvoLexEntry) as ILexEntry;
            Assert.IsNotNull(lexEntry);
            IMoStemAllomorph stemAllomorph = lexEntry.LexemeFormOA as IMoStemAllomorph;
            Assert.IsNotNull(stemAllomorph);
            stemAllomorph.Form.SetAlternative("bili-changed", Cache.DefaultVernWs);
            int hvoStemAllomorph = stemAllomorph.Hvo;
            stemAllomorph.IsAbstract = true;

            // Delete an affix allomorph
            hvoLexEntry = aiLexEntries[3];
            lexEntry    = CmObject.CreateFromDBObject(Cache, hvoLexEntry) as ILexEntry;
            Assert.IsNotNull(lexEntry);
            IMoAffixAllomorph affixAllomorph = lexEntry.AlternateFormsOS[1] as IMoAffixAllomorph;
            Assert.IsNotNull(affixAllomorph);
            int hvoAffixAllomorph = affixAllomorph.Hvo;
            lexEntry.AlternateFormsOS.RemoveAt(1);
            Cache.PropChanged(null, PropChangeType.kpctNotifyAll, hvoLexEntry, (int)LexEntry.LexEntryTags.kflidAlternateForms, 1, 0, 1);

            // Add a new affix allomorph
            IMoAffixAllomorph newAffixAllomorph = new MoAffixAllomorph();
            lexEntry.AlternateFormsOS.Append(newAffixAllomorph);
            newAffixAllomorph.Form.SetAlternative("him-new", Cache.DefaultVernWs);
            int hvoNewAffixAllomorph = newAffixAllomorph.Hvo;
            Cache.PropChanged(null, PropChangeType.kpctNotifyAll, hvoLexEntry, (int)LexEntry.LexEntryTags.kflidAlternateForms, lexEntry.AlternateFormsOS.Count - 1, 1, 0);

            // add a compound rule
            IMoMorphData    morphData   = lp.MorphologicalDataOA;
            IMoEndoCompound compRuleNew = new MoEndoCompound();
            morphData.CompoundRulesOS.Append(compRuleNew);
            string sCompRuleName = "new compound rule";
            compRuleNew.Name.AnalysisDefaultWritingSystem = sCompRuleName;
            compRuleNew.HeadLast = true;
            int hvoPOS = lp.PartsOfSpeechOA.PossibilitiesOS.FirstItem.Hvo;
            compRuleNew.LeftMsaOA.PartOfSpeechRAHvo       = hvoPOS;
            compRuleNew.RightMsaOA.PartOfSpeechRAHvo      = hvoPOS;
            compRuleNew.OverridingMsaOA.PartOfSpeechRAHvo = hvoPOS;
            // Change compound rule description
            const string ksCompRuleDescription = "new description";
            compRuleNew.Description.AnalysisDefaultWritingSystem.Text = ksCompRuleDescription;
            Cache.PropChanged(null, PropChangeType.kpctNotifyAll, morphData.Hvo, (int)MoMorphData.MoMorphDataTags.kflidCompoundRules, morphData.CompoundRulesOS.Count - 1, 1, 0);

            // delete a compound rule
            IMoExoCompound compRuleDeleted            = morphData.CompoundRulesOS.FirstItem as IMoExoCompound;
            int            hvoCompRuleDeletedLeftMsa  = compRuleDeleted.LeftMsaOAHvo;
            int            hvoCompRuleDeletedRightMsa = compRuleDeleted.RightMsaOAHvo;
            int            hvoCompRuleDeletedToMsa    = compRuleDeleted.ToMsaOAHvo;
            morphData.CompoundRulesOS.RemoveAt(0);

            // add an ad hoc co-prohibition
            IMoAlloAdhocProhib alloAdHoc = new MoAlloAdhocProhib();
            morphData.AdhocCoProhibitionsOC.Add(alloAdHoc);
            alloAdHoc.Adjacency           = 2;
            alloAdHoc.FirstAllomorphRAHvo = hvoNewAffixAllomorph;
            alloAdHoc.RestOfAllosRS.Append(hvoNewAffixAllomorph);

            // change a "rest of allos" in extant ad hoc co-prohibition
            int[] hvosAdHocProhibs          = morphData.AdhocCoProhibitionsOC.HvoArray;
            IMoAlloAdhocProhib alloAdHocOld =
                CmObject.CreateFromDBObject(Cache, hvosAdHocProhibs[9]) as IMoAlloAdhocProhib;
            IMoAffixAllomorph alloAdHicOldFirstRestOfAllos = alloAdHocOld.RestOfAllosRS.FirstItem as IMoAffixAllomorph;
            IMoAffixAllomorph affixAllomorph2 = lexEntry.AlternateFormsOS[0] as IMoAffixAllomorph;
            alloAdHocOld.RestOfAllosRS.Append(affixAllomorph2);
            alloAdHocOld.RestOfAllosRS.RemoveAt(0);
            alloAdHocOld.Adjacency = 2;

            //Add a new productivity restriction
            ICmPossibilityList prodRestricts   = morphData.ProdRestrictOA;
            ICmPossibility     prodRestriction = new CmPossibility();
            prodRestricts.PossibilitiesOS.Append(prodRestriction);
            string sNewProdRestrictName = "new exception feature";
            prodRestriction.Name.AnalysisDefaultWritingSystem = sNewProdRestrictName;
            Cache.PropChanged(null, PropChangeType.kpctNotifyAll, prodRestricts.Hvo, (int)CmPossibilityList.CmPossibilityListTags.kflidPossibilities, prodRestricts.PossibilitiesOS.Count - 1, 1, 0);

            // Change a phonological enviroment string representation
            IPhPhonData    phonData       = lp.PhonologicalDataOA;
            IPhEnvironment env            = phonData.EnvironmentsOS.FirstItem;
            const string   ksEnvStringRep = "/ _ [C] [V] a e i o u";
            env.StringRepresentation.Text = ksEnvStringRep;

            // Add a new phonological enviroment string representation
            IPhEnvironment envNew = new PhEnvironment();
            phonData.EnvironmentsOS.Append(envNew);
            envNew.StringRepresentation.Text = "/ _ m";
            int hvoPhonData = phonData.Hvo;
            Cache.PropChanged(null, PropChangeType.kpctNotifyAll, hvoPhonData, (int)PhPhonData.PhPhonDataTags.kflidEnvironments, phonData.EnvironmentsOS.Count - 1, 1, 0);

            // Change parser parameters (to test Unicode string field type)
            string sParserParameters = morphData.ParserParameters.Trim();
            int    i = sParserParameters.IndexOf("</ParserParameters>");
            string sNewParserParameters = sParserParameters.Substring(0, i) + "<HermitCrab><stuff>1</stuff></HermitCrab>" + "</ParserParameters>";
            morphData.ParserParameters = sNewParserParameters;

            // Delete a lex entry
            int[]     hvosEntries                    = lexdb.EntriesOC.HvoArray;
            int       hvoEntryDeleted                = hvosEntries[hvosEntries.Length - 4];
            ILexEntry entryDeleted                   = CmObject.CreateFromDBObject(Cache, hvoEntryDeleted) as ILexEntry;
            int       hvoEntryDeletedLexemeForm      = entryDeleted.LexemeFormOAHvo;
            int[]     hvosEntryDeletedAlternateForms = entryDeleted.AlternateFormsOS.HvoArray;
            int[]     hvosEntryDeletedMSAs           = entryDeleted.MorphoSyntaxAnalysesOC.HvoArray;
            int[]     hvosEntryDeletedSenses         = entryDeleted.SensesOS.HvoArray;
            //entryDeleted.LexemeFormOA.DeleteUnderlyingObject();
            lexdb.EntriesOC.Remove(hvosEntries[hvosEntries.Length - 4]);
            //Cache.PropChanged(null, PropChangeType.kpctNotifyAll, morphData.Hvo, (int)MoMorphData.MoMorphDataTags.kflidParserParameters, 0, 0, 0);

            // Create a new lex entry
            ILexEntry entryNew = new LexEntry();
            lexdb.EntriesOC.Add(entryNew);

            IMoAffixAllomorph alloNew = new MoAffixAllomorph();
            entryNew.LexemeFormOA = alloNew;
            string sNewAlloForm = "dem";
            alloNew.Form.VernacularDefaultWritingSystem = sNewAlloForm;
            alloNew.MorphTypeRA = (IMoMorphType)lexdb.MorphTypesOA.LookupPossibilityByGuid(new Guid(MoMorphType.kguidMorphPrefix));

            IMoAffixAllomorph alloNew2 = new MoAffixAllomorph();
            entryNew.AlternateFormsOS.Append(alloNew2);
            string sNewAlloForm2 = "den";
            alloNew2.Form.VernacularDefaultWritingSystem = sNewAlloForm2;
            alloNew2.MorphTypeRA = (IMoMorphType)lexdb.MorphTypesOA.LookupPossibilityByGuid(new Guid(MoMorphType.kguidMorphPrefix));
            Cache.PropChanged(null, PropChangeType.kpctNotifyAll, entryNew.Hvo, (int)LexEntry.LexEntryTags.kflidAlternateForms, entryNew.AlternateFormsOS.Count - 1, 1, 0);

            ILexSense sense = new LexSense();
            entryNew.SensesOS.Append(sense);
            string sGloss = "MeToo";
            sense.Gloss.AnalysisDefaultWritingSystem = sGloss;

            IMoInflAffMsa inflAffixMsa = new MoInflAffMsa();
            entryNew.MorphoSyntaxAnalysesOC.Add(inflAffixMsa);
            sense.MorphoSyntaxAnalysisRA = inflAffixMsa;
            int[] hvosPOSes = lp.PartsOfSpeechOA.PossibilitiesOS.HvoArray;
            int   hvoVerb   = hvosPOSes[12];
            inflAffixMsa.PartOfSpeechRAHvo = hvoVerb;
            IPartOfSpeech pos     = CmObject.CreateFromDBObject(Cache, hvoVerb) as IPartOfSpeech;
            int           hvoSlot = pos.AffixSlotsOC.HvoArray[2];
            inflAffixMsa.SlotsRC.Add(hvoSlot);
            Cache.PropChanged(null, PropChangeType.kpctNotifyAll, entryNew.Hvo, (int)LexEntry.LexEntryTags.kflidSenses, entryNew.SensesOS.Count - 1, 1, 0);

            // Add an inflectional template
            int[]                hvoVerbSubCats = pos.SubPossibilitiesOS.HvoArray;
            int                  hvoIntransVerb = hvoVerbSubCats[2];
            IPartOfSpeech        posVI          = CmObject.CreateFromDBObject(Cache, hvoIntransVerb) as IPartOfSpeech;
            IMoInflAffixTemplate affixTemplate  = new MoInflAffixTemplate();
            posVI.AffixTemplatesOS.Append(affixTemplate);
            affixTemplate.Name.AnalysisDefaultWritingSystem = "derived verb";
            affixTemplate.Final = false;
            affixTemplate.SuffixSlotsRS.Append(hvoSlot);
            Cache.PropChanged(null, PropChangeType.kpctNotifyAll, posVI.Hvo, (int)PartOfSpeech.PartOfSpeechTags.kflidAffixTemplates, posVI.AffixTemplatesOS.Count - 1, 1, 0);

            // add a phonological feature
            IFsClosedFeature consFeat = new FsClosedFeature();
            Cache.LangProject.PhFeatureSystemOA.FeaturesOC.Add(consFeat);
            consFeat.Name.AnalysisDefaultWritingSystem         = "consonantal";
            consFeat.Abbreviation.AnalysisDefaultWritingSystem = "cons";
            IFsSymFeatVal consPlus = new FsSymFeatVal();
            consFeat.ValuesOC.Add(consPlus);
            consPlus.SimpleInit("+", "positive");
            IFsSymFeatVal consMinus = new FsSymFeatVal();
            consFeat.ValuesOC.Add(consMinus);
            consMinus.SimpleInit("-", "negative");
            IFsFeatStrucType fsType = null;
            if (Cache.LangProject.PhFeatureSystemOA.TypesOC.Count == 0)
            {
                fsType = new FsFeatStrucType();
                Cache.LangProject.PhFeatureSystemOA.TypesOC.Add(fsType);
                fsType.Abbreviation.AnalysisDefaultWritingSystem = "Phon";
            }
            else
            {
                foreach (IFsFeatStrucType type in Cache.LangProject.PhFeatureSystemOA.TypesOC)
                {
                    fsType = type;
                    break;
                }
            }
            fsType.FeaturesRS.Append(consFeat);

            // add a feature-based NC
            IPhNCFeatures featNC = new PhNCFeatures();
            Cache.LangProject.PhonologicalDataOA.NaturalClassesOS.Append(featNC);
            featNC.Name.AnalysisDefaultWritingSystem         = "Consonants (Features)";
            featNC.Abbreviation.AnalysisDefaultWritingSystem = "CF";
            IFsFeatStruc fs = new FsFeatStruc();
            featNC.FeaturesOA = fs;
            IFsClosedValue val = fs.FindOrCreateClosedValue(consFeat.Hvo);
            val.FeatureRA = consFeat;
            val.ValueRA   = consPlus;
            featNC.NotifyNew();

            // add phonological rule
            IPhRegularRule regRule = new PhRegularRule();
            Cache.LangProject.PhonologicalDataOA.PhonRulesOS.Append(regRule);
            regRule.NotifyNew();
            regRule.Name.AnalysisDefaultWritingSystem = "regular rule";
            IPhSimpleContextSeg segCtxt = new PhSimpleContextSeg();
            regRule.RightHandSidesOS[0].StrucChangeOS.Append(segCtxt);
            IPhPhoneme phoneme = null;
            foreach (IPhPhoneme phon in Cache.LangProject.PhonologicalDataOA.PhonemeSetsOS[0].PhonemesOC)
            {
                phoneme = phon;
                break;
            }
            segCtxt.FeatureStructureRA = phoneme;
            segCtxt.NotifyNew();

            IPhSimpleContextNC ncCtxt = new PhSimpleContextNC();
            regRule.RightHandSidesOS[0].LeftContextOA = ncCtxt;
            ncCtxt.FeatureStructureRA = featNC;
            ncCtxt.NotifyNew();

            // add a morphological rule
            IMoAffixProcess affRule = new MoAffixProcess();
            entryNew.AlternateFormsOS.Append(affRule);
            affRule.NotifyNew();
            ncCtxt = new PhSimpleContextNC();
            affRule.InputOS.Append(ncCtxt);
            ncCtxt.FeatureStructureRA = featNC;
            ncCtxt.NotifyNew();
            IMoCopyFromInput copy = new MoCopyFromInput();
            affRule.OutputOS.Append(copy);
            copy.ContentRA = ncCtxt;
            copy.NotifyNew();

            // -----------
            // Update the FXT result
            // -----------
            XmlDocument updatedFxtResult = UpdateFXT();

            // -----------
            // Test the updated results
            // -----------

            // Test changed stem allomorph: checks on MultiUnicode and boolean
            node = updatedFxtResult.SelectSingleNode("//MoStemAllomorph[@Id='" + hvoStemAllomorph + "']");
            Assert.IsNotNull(node);
            Assert.AreEqual(stemAllomorph.Form.VernacularDefaultWritingSystem, node.InnerText, "stem allomorph form change failed");
            XmlNode contentNode = node.SelectSingleNode("@IsAbstract");
            Assert.AreEqual("1", contentNode.InnerText, "stem allomorph is abstract should be true (=1)");

            // Test deleted affix allomorph: checks on owning sequence
            node = updatedFxtResult.SelectSingleNode("//MoAffixAllomorph[@Id='" + hvoAffixAllomorph + "']");
            Assert.IsNull(node, "Deleted affix allomorph should be null");
            node =
                updatedFxtResult.SelectSingleNode("//LexEntry[@id='" + hvoLexEntry + "']/AlternateForms[@dst='" +
                                                  hvoAffixAllomorph + "']");
            Assert.IsNull(node, "LexEntry should no longer have deleted alternate form");

            // Test added new affix allomorph: checks on owning sequence owned by an item with an @Id; also checks on addition of MoAffixAllomorph via AllAllomorphs
            string sXPath = "//LexEntry[@Id='" + hvoLexEntry + "']/AlternateForms[@dst='" +
                            hvoNewAffixAllomorph + "']";
            node = updatedFxtResult.SelectSingleNode(sXPath);
            Assert.IsNotNull(node, "LexEntry should have added alternate form");
            node = updatedFxtResult.SelectSingleNode("//MoAffixAllomorph[@Id='" + hvoNewAffixAllomorph + "']");
            Assert.IsNotNull(node, "Added affix allomorph should be present");
            sXPath = "//LexEntry[@Id='" + hvoLexEntry + "']";
            node   = updatedFxtResult.SelectSingleNode(sXPath);
            XmlNodeList nodes = node.SelectNodes("AlternateForms");
            Assert.AreEqual(3, nodes.Count, "Expected three Alternate forms in lex entry.");

            //Test newly added compound rule: checks on owning sequence owned by an Id-less element; also on multistring
            node = updatedFxtResult.SelectSingleNode("//MoEndoCompound[@Id='" + compRuleNew.Hvo + "']");
            Assert.IsNotNull(node, "did not find newly added compound rule");
            contentNode = node.SelectSingleNode("@HeadLast");
            Assert.IsNotNull(contentNode, "missing headlast attribute for coompound rule");
            Assert.AreEqual("1", contentNode.InnerText, "compound rule headlast value differs");
            contentNode = node.SelectSingleNode("Name");
            Assert.IsNotNull(contentNode, "missing Name for compound rule");
            Assert.AreEqual(sCompRuleName, contentNode.InnerText, "compound rule name differs");
            // check on MultiString
            contentNode = node.SelectSingleNode("Description");
            Assert.AreEqual(ksCompRuleDescription, contentNode.InnerText, "compound rule description differs");
            // check on count
            node  = updatedFxtResult.SelectSingleNode("//CompoundRules");
            nodes = node.SelectNodes("MoExoCompound | MoEndoCompound");
            Assert.AreEqual(6, nodes.Count, "Expected seven compound rules.");
            // check on owningAtom
            node = updatedFxtResult.SelectSingleNode("//MoStemMsa[@Id='" + compRuleNew.LeftMsaOAHvo + "']");
            Assert.IsNotNull(node, "missing real MoStemMsa for LeftMsa of newly added compound rule");
            node = updatedFxtResult.SelectSingleNode("//MoStemMsa[@Id='" + compRuleNew.RightMsaOAHvo + "']");
            Assert.IsNotNull(node, "missing real MoStemMsa for RightMsa of newly added compound rule");
            node = updatedFxtResult.SelectSingleNode("//MoStemMsa[@Id='" + compRuleNew.OverridingMsaOAHvo + "']");
            Assert.IsNotNull(node, "missing real MoStemMsa for OverridingMsa of newly added compound rule");

            // Test deleted compound rule
            node = updatedFxtResult.SelectSingleNode("//MoExoCompound[@Id='" + compRuleDeleted.Hvo + "']");
            Assert.IsNull(node, "compound rule should be deleted");
            node = updatedFxtResult.SelectSingleNode("//MoStemMsa[@Id='" + hvoCompRuleDeletedLeftMsa + "']");
            Assert.IsNull(node, "compound rule left MSA should be deleted");
            node = updatedFxtResult.SelectSingleNode("//MoStemMsa[@Id='" + hvoCompRuleDeletedRightMsa + "']");
            Assert.IsNull(node, "compound rule right MSA should be deleted");
            node = updatedFxtResult.SelectSingleNode("//MoStemMsa[@Id='" + hvoCompRuleDeletedToMsa + "']");
            Assert.IsNull(node, "compound rule to MSA should be deleted");

            //Test newly added allomorph ad hoc rule: checks on owning collection
            node = updatedFxtResult.SelectSingleNode("//MoAlloAdhocProhib[@Id='" + alloAdHoc.Hvo + "']");
            Assert.IsNotNull(node, "did not find newly added allo ad hoc rule");
            contentNode = node.SelectSingleNode("@Adjacency");
            Assert.IsNotNull(contentNode, "missing adjacency attribute for allo ad hoc rule");
            Assert.AreEqual("2", contentNode.InnerText, "allo ad hoc rule adjacency value differs");
            contentNode = node.SelectSingleNode("FirstAllomorph");
            Assert.IsNotNull(contentNode, "missing FirstAllomorph for allo ad hoc rule");
            contentNode = contentNode.SelectSingleNode("@dst");
            Assert.IsNotNull(contentNode, "missing dst attribute of FirstAllomorph for allo ad hoc rule");
            Assert.AreEqual(hvoNewAffixAllomorph.ToString(), contentNode.InnerText, "FirstAllomorph of allo ad hoc rule differs");
            contentNode = node.SelectSingleNode("RestOfAllos");
            Assert.IsNotNull(contentNode, "missing RestOfAllos for allo ad hoc rule");
            contentNode = contentNode.SelectSingleNode("@dst");
            Assert.IsNotNull(contentNode, "missing dst attribute of RestOfAllos for allo ad hoc rule");
            Assert.AreEqual(hvoNewAffixAllomorph.ToString(), contentNode.InnerText, "RestOfAllos of allo ad hoc rule differs");

            // test change of a "rest of allos" in extant ad hoc co-prohibition: check on reference sequence
            node = updatedFxtResult.SelectSingleNode("//MoAlloAdhocProhib[@Id='" + alloAdHocOld.Hvo + "']");
            Assert.IsNotNull(node, "did not find old allo ad hoc rule");
            contentNode = node.SelectSingleNode("RestOfAllos");
            Assert.IsNotNull(contentNode, "missing RestOfAllos for old allo ad hoc rule");
            contentNode = contentNode.SelectSingleNode("@dst");
            Assert.IsNotNull(contentNode, "missing dst attribute of RestOfAllos for old allo ad hoc rule");
            Assert.AreEqual(affixAllomorph2.Hvo.ToString(), contentNode.InnerText, "RestOfAllos of old allo ad hoc rule differs");
            nodes = node.SelectNodes("RestOfAllos");
            Assert.AreEqual(1, nodes.Count, "count of RestOfAllos of old allo ad hoc rule differs");
            // check on integer change
            contentNode = node.SelectSingleNode("@Adjacency");
            Assert.AreEqual("2", contentNode.InnerText, "Adjacency differs");
            node =
                updatedFxtResult.SelectSingleNode("//MoAffixAllomorph[@Id='" + alloAdHicOldFirstRestOfAllos.Hvo + "']");
            Assert.IsNotNull(node, "Original RestOfAllos allomorph should still be present");
            nodes = updatedFxtResult.SelectNodes("//MoAffixAllomorph[@Id='" + affixAllomorph2.Hvo + "']");
            Assert.AreEqual(1, nodes.Count, "Should only be one instance of new allomorph in RestOfAllos");


            // Test added productivity restriction: check on CmPossibilityList
            node = updatedFxtResult.SelectSingleNode("//ProdRestrict/CmPossibility");
            Assert.IsNotNull(node, "Did not find newly added productivity restriction");
            node = node.SelectSingleNode("Name");
            Assert.IsNotNull(node, "Expected Name node in productivity restrictioni");
            Assert.AreEqual(sNewProdRestrictName, node.InnerText, "name of productivity restriction differs");

            // Test phonological environment string representation: check on string
            node = updatedFxtResult.SelectSingleNode("//PhEnvironment[@Id='" + env.Hvo + "']/@StringRepresentation");
            Assert.AreEqual(ksEnvStringRep, node.InnerText, "phonological environment string differs");

            // Test adding a phonological environment string representation:
            // check on case where parent of owner has Id and is class name;
            // also check on case where there is a comment/text node within the result nodes
            node = updatedFxtResult.SelectSingleNode("//PhEnvironment[@Id='" + envNew.Hvo + "']");
            Assert.IsNotNull(node, "missing newly added phonological environment");
            nodes = updatedFxtResult.SelectNodes("//PhEnvironment");
            Assert.AreEqual(11, nodes.Count, "number of PhEnvironments differs");

            // Test Parser Parameters: check on unicode string
            node = updatedFxtResult.SelectSingleNode("//ParserParameters");
            string sResultParseParameters = node.OuterXml.Trim();
            Assert.AreEqual(sNewParserParameters, sResultParseParameters, "Parser Parameters content differs");

            // Test deletion of a lex entry: check on finding LexDb when there is no class LexDb in FXT file
            nodes = updatedFxtResult.SelectNodes("//LexEntry");
            Assert.AreEqual(61, nodes.Count, "number of LexEntries differs");
            node = updatedFxtResult.SelectSingleNode("//LexEntry[@Id='" + hvoEntryDeleted + "']");
            Assert.IsNull(node, "Deleted lex entry should be missing");
            foreach (int hvo in hvosEntryDeletedAlternateForms)
            {
                node = updatedFxtResult.SelectSingleNode("//MoStemAllomorph[@Id='" + hvo + "'] | //MoAffixAllomorph[@Id='" + hvo + "']");
                Assert.IsNull(node, "deleted entry's alternate form should also be gone");
            }
            foreach (int hvo in hvosEntryDeletedMSAs)
            {
                node = updatedFxtResult.SelectSingleNode("//MoStemMsa[@Id='" + hvo + "']");
                Assert.IsNull(node, "deleted entry's msa should also be gone");
            }
            foreach (int hvo in hvosEntryDeletedSenses)
            {
                node = updatedFxtResult.SelectSingleNode("//LexSense[@Id='" + hvo + "']");
                Assert.IsNull(node, "deleted entry's lexsense should also be gone");
            }
            node = updatedFxtResult.SelectSingleNode("//MoStemAllomorph[@Id='" + hvoEntryDeletedLexemeForm + "']");
            Assert.IsNull(node, "deleted entry's lexeme form should also be gone");

            // Test adding new entry
            node = updatedFxtResult.SelectSingleNode("//LexEntry[@Id='" + entryNew.Hvo + "']");
            Assert.IsNotNull(node, "new lex entry is missing");
            contentNode = node.SelectSingleNode("LexemeForm[@dst='" + alloNew.Hvo + "']");
            Assert.IsNotNull(contentNode, "missing lexeme form for new entry");
            contentNode = node.SelectSingleNode("AlternateForms[@dst='" + alloNew2.Hvo + "']");
            Assert.IsNotNull(contentNode, "missing alternate form in new lex entry");
            contentNode = node.SelectSingleNode("Sense[@dst='" + sense.Hvo + "']");
            Assert.IsNotNull(contentNode, "missing sense in new lex entry");
            contentNode = node.SelectSingleNode("MorphoSyntaxAnalysis[@dst='" + inflAffixMsa.Hvo + "']");
            Assert.IsNotNull(contentNode, "missing msa in new lex entry");
            contentNode = node.SelectSingleNode("AlternateForms[@dst='" + affRule.Hvo + "']");
            Assert.IsNotNull(contentNode, "missing affix process rule in new lex entry");

            node = updatedFxtResult.SelectSingleNode("//MoAffixAllomorph[@Id='" + alloNew.Hvo + "']");
            Assert.IsNotNull(node, "new lexeme form affix allomorph for new lex entry is missing");
            contentNode = node.SelectSingleNode("@MorphType");
            Assert.IsNotNull(contentNode, "@MorphType missing for new MoAffixAllomorph in lexeme form of new lex entry");
            IMoMorphType typeNew  = MoMorphType.CreateFromDBObject(Cache, Convert.ToInt32(contentNode.InnerText));
            string       sGuidNew = typeNew.Guid.ToString();
            Assert.AreEqual(MoMorphType.kguidMorphPrefix, sGuidNew, "morph type wrong for new MoAffixAllomorph in lexeme form of new lex entry");
            contentNode = node.SelectSingleNode("Form");
            Assert.IsNotNull(contentNode, "Form missing for new MoAffixAllomorph in lexeme form new lex entry");
            Assert.AreEqual(sNewAlloForm, contentNode.InnerText, "form wrong for new MoAffixAllomorph in lexeme form of new lex entry");

            node = updatedFxtResult.SelectSingleNode("//MoAffixAllomorph[@Id='" + alloNew2.Hvo + "']");
            Assert.IsNotNull(node, "new alternate form affix allomorph for new lex entry is missing");
            contentNode = node.SelectSingleNode("@MorphType");
            Assert.IsNotNull(contentNode, "@MorphType missing for new MoAffixAllomorph in alternate form of new lex entry");
            typeNew  = MoMorphType.CreateFromDBObject(Cache, Convert.ToInt32(contentNode.InnerText));
            sGuidNew = typeNew.Guid.ToString();
            Assert.AreEqual(MoMorphType.kguidMorphPrefix, sGuidNew, "morph type wrong for new MoAffixAllomorph in lexeme form of new lex entry");
            contentNode = node.SelectSingleNode("Form");
            Assert.IsNotNull(contentNode, "Form missing for new MoAffixAllomorph in alternate form new lex entry");
            Assert.AreEqual(sNewAlloForm2, contentNode.InnerText, "form wrong for new MoAffixAllomorph in alternate form of new lex entry");

            node = updatedFxtResult.SelectSingleNode("//LexSense[@Id='" + sense.Hvo + "']");
            Assert.IsNotNull(node, "new sense for new lex entry is missing");
            contentNode = node.SelectSingleNode("Gloss");
            Assert.IsNotNull(contentNode, "Gloss missing for new LexSense in new lex entry");
            Assert.AreEqual(sGloss, contentNode.InnerText, "Gloss wrong for new LexSense in new lex entry");

            node = updatedFxtResult.SelectSingleNode("//MoInflAffMsa[@Id='" + inflAffixMsa.Hvo + "']");
            Assert.IsNotNull(node, "new infl affix msa for new lex entry is missing");
            contentNode = node.SelectSingleNode("@PartOfSpeech");
            Assert.IsNotNull(contentNode, "@PartOfSpeech missing for new MoInflAffMsa in new lex entry");
            Assert.AreEqual(hvoVerb.ToString(), contentNode.InnerText, "part of speech wrong for new MoInflAffMsa in new lex entry");
            contentNode = node.SelectSingleNode("Slots/@dst");
            Assert.IsNotNull(contentNode, "Slots missing for new MoInflAffMsa in new lex entry");
            Assert.AreEqual(hvoSlot.ToString(), contentNode.InnerText, "slot wrong for new MoInflAffMsa in new lex entry");

            // Test adding new template
            node = updatedFxtResult.SelectSingleNode("//MoInflAffixTemplate[@Id='" + affixTemplate.Hvo + "']");
            Assert.IsNotNull(node, "new affix template missing");
            node =
                updatedFxtResult.SelectSingleNode("//PartOfSpeech[@Id='" + hvoIntransVerb +
                                                  "']/AffixTemplates/MoInflAffixTemplate[@Id='" + affixTemplate.Hvo +
                                                  "']");
            Assert.IsNotNull(node, "new affix template is in intransitive verb");

            // Test adding new phonological feature
            node = updatedFxtResult.SelectSingleNode("//PhFeatureSystem/Features/FsClosedFeature[@Id='" + consFeat.Hvo + "']");
            Assert.IsNotNull(node, "new phonological feature is missing");
            contentNode = node.SelectSingleNode("Abbreviation");
            Assert.IsNotNull(contentNode, "Abbreviation missing from new phonological feature");
            Assert.AreEqual(contentNode.InnerText, consFeat.Abbreviation.AnalysisDefaultWritingSystem, "Abbreviation wrong for new phonological feature");
            nodes = node.SelectNodes("Values/FsSymFeatVal");
            Assert.IsNotNull(nodes, "values missing from new phonological feature");
            Assert.AreEqual(nodes.Count, 2, "incorrect number of values in new phonological feature");
            node = updatedFxtResult.SelectSingleNode("//PhFeatureSystem/Types/FsFeatStrucType/Features/Feature[@dst='" + consFeat.Hvo + "']");
            Assert.IsNotNull(node, "reference to new phonological feature is missing from phonological feature system");

            // Test adding new feature-based NC
            node = updatedFxtResult.SelectSingleNode("//PhNCFeatures[@Id='" + featNC.Hvo + "']");
            Assert.IsNotNull(node, "new feature-based NC is missing");
            contentNode = node.SelectSingleNode("Abbreviation");
            Assert.IsNotNull(contentNode, "Abbreviation missing from new feature-based NC");
            Assert.AreEqual(contentNode.InnerText, featNC.Abbreviation.AnalysisDefaultWritingSystem, "Abbreviation wrong for new feature-based NC");
            contentNode = node.SelectSingleNode("FsFeatStruc/FsClosedValue[@Id='" + val.Hvo + "']");
            Assert.IsNotNull(contentNode, "value missing from new feature-based NC");
            Assert.AreEqual((contentNode as XmlElement).GetAttribute("Feature"), consFeat.Hvo.ToString(), "closed value feature is wrong in new feature-based NC");
            Assert.AreEqual((contentNode as XmlElement).GetAttribute("Value"), consPlus.Hvo.ToString(), "closed value is wrong in new feature-based NC");

            // Test adding new phonological rule
            node = updatedFxtResult.SelectSingleNode("//PhRegularRule[@Id='" + regRule.Hvo + "']");
            Assert.IsNotNull(node, "new phonological rule is missing");
            nodes = node.SelectNodes("StrucDesc/*");
            Assert.AreEqual(nodes.Count, 0);
            contentNode = node.SelectSingleNode("RightHandSides/PhSegRuleRHS/StrucChange/PhSimpleContextSeg[@dst='" + phoneme.Hvo + "']");
            Assert.IsNotNull(contentNode, "phoneme simple context missing in new phonological rule");
            contentNode = node.SelectSingleNode("RightHandSides/PhSegRuleRHS/LeftContext/PhSimpleContextNC[@dst='" + featNC.Hvo + "']");
            Assert.IsNotNull(contentNode, "NC simple context missing in new phonological rule");

            // Test adding new morphological rule
            node = updatedFxtResult.SelectSingleNode("//Lexicon/Allomorphs/MoAffixProcess[@Id='" + affRule.Hvo + "']");
            Assert.IsNotNull(node, "new morphological rule is missing");
            contentNode = node.SelectSingleNode("Input/PhSimpleContextNC[@dst='" + featNC.Hvo + "']");
            Assert.IsNotNull(contentNode, "NC simple context missing in new morphological rule");
            contentNode = node.SelectSingleNode("Output/MoCopyFromInput/Content[@dst='" + ncCtxt.Hvo + "']");
            Assert.IsNotNull(contentNode, "copy from input missing in new morphological rule");

            // Modify a phonological rule
            segCtxt = new PhSimpleContextSeg();
            regRule.StrucDescOS.Append(segCtxt);
            segCtxt.FeatureStructureRA = phoneme;
            segCtxt.NotifyNew();
            regRule.RightHandSidesOS[0].StrucChangeOS[0].DeleteUnderlyingObject();
            IPhPhonContext oldCtxt = regRule.RightHandSidesOS[0].LeftContextOA;
            Cache.LangProject.PhonologicalDataOA.ContextsOS.Append(oldCtxt);
            IPhSequenceContext seqCtxt = new PhSequenceContext();
            regRule.RightHandSidesOS[0].LeftContextOA = seqCtxt;
            seqCtxt.MembersRS.Append(oldCtxt);
            seqCtxt.NotifyNew();
            IPhSimpleContextBdry bdryCtxt = new PhSimpleContextBdry();
            Cache.LangProject.PhonologicalDataOA.ContextsOS.Append(bdryCtxt);
            bdryCtxt.FeatureStructureRAHvo = Cache.GetIdFromGuid(LangProject.kguidPhRuleWordBdry);
            bdryCtxt.NotifyNew();
            seqCtxt.MembersRS.Append(bdryCtxt);

            // Modify a morphological rule
            entryNew.LexemeFormOA = affRule;
            IMoInsertPhones insertPhones = new MoInsertPhones();
            affRule.OutputOS.InsertAt(insertPhones, 0);
            insertPhones.ContentRS.Append(phoneme);
            insertPhones.NotifyNew();
            affRule.InputOS[1].DeleteUnderlyingObject();

            // change order of a sequence vector
            lexEntry.AlternateFormsOS.InsertAt(newAffixAllomorph, 0);

            updatedFxtResult = UpdateFXT();

            // Test modifying a phonological rule
            node        = updatedFxtResult.SelectSingleNode("//PhRegularRule[@Id='" + regRule.Hvo + "']");
            contentNode = node.SelectSingleNode("StrucDesc/PhSimpleContextSeg[@dst='" + phoneme.Hvo + "']");
            Assert.IsNotNull(contentNode, "phoneme simple context missing from StrucDesc in modified phonological rule");
            contentNode = node.SelectSingleNode("RightHandSides/PhSegRuleRHS/StrucChange/PhSimpleContextSeg[@dst='" + phoneme.Hvo + "']");
            Assert.IsNull(contentNode, "phoneme simple context is not missing from StrucChange in modified phonological rule");
            contentNode = node.SelectSingleNode("RightHandSides/PhSegRuleRHS/LeftContext/PhSequenceContext[@Id='" + seqCtxt.Hvo + "']");
            Assert.IsNotNull(contentNode, "sequence context missing from modified phonological rule");
            contentNode = contentNode.SelectSingleNode("Members[@dst='" + bdryCtxt.Hvo + "']");
            Assert.IsNotNull(contentNode, "boundary context missing from sequence context in modified phonological rule");
            node = updatedFxtResult.SelectSingleNode("//PhPhonData/Contexts/PhSimpleContextBdry[@Id='" + bdryCtxt.Hvo + "']");
            Assert.IsNotNull(node, "boundary context missing from contexts in phonological data");

            // Test modifying a morphological rule
            node        = updatedFxtResult.SelectSingleNode("//LexEntry[@Id='" + entryNew.Hvo + "']");
            contentNode = node.SelectSingleNode("LexemeForm[@dst='" + affRule.Hvo + "']");
            Assert.IsNotNull(contentNode, "affix process rule is not the lexeme form for the lex entry");
            node        = updatedFxtResult.SelectSingleNode("//Lexicon/Allomorphs/MoAffixProcess[@Id='" + affRule.Hvo + "']");
            contentNode = node.SelectSingleNode("Input/PhSimpleContextNC[@dst='" + featNC.Hvo + "']");
            Assert.IsNull(contentNode, "NC simple context was not removed from morphological rule");
            nodes = node.SelectNodes("Output/*");
            Assert.AreEqual(nodes.Count, 2, "incorrect number of mappings in morphological rule");
            contentNode = node.SelectSingleNode("Output/*[position() = 1 and @Id='" + insertPhones.Hvo + "']");
            Assert.IsNotNull(contentNode, "insert phones missing from morphological rule");

            // Test changing order of a sequence vector
            node        = updatedFxtResult.SelectSingleNode("//LexEntry[@Id='" + lexEntry.Hvo + "']");
            contentNode = node.SelectSingleNode("AlternateForms[@dst='" + lexEntry.AlternateFormsOS[0].Hvo + "']/@ord");
            Assert.AreEqual("0", contentNode.InnerText);
            contentNode = node.SelectSingleNode("AlternateForms[@dst='" + lexEntry.AlternateFormsOS[1].Hvo + "']/@ord");
            Assert.AreEqual("1", contentNode.InnerText);
            contentNode = node.SelectSingleNode("AlternateForms[@dst='" + lexEntry.AlternateFormsOS[2].Hvo + "']/@ord");
            Assert.AreEqual("2", contentNode.InnerText);
        }
Example #15
0
        /// <summary>
        /// This sets the original wordform and morph-broken word into the dialog.
        /// </summary>
        /// <param name="sWord"></param>
        /// <param name="sMorphs"></param>
        public void Initialize(ITsString tssWord, string sMorphs, ILgWritingSystemFactory wsf,
                               FdoCache cache, SIL.Utils.StringTable stringTable, IVwStylesheet stylesheet)
        {
            CheckDisposed();

            Debug.Assert(tssWord != null);
            Debug.Assert(wsf != null);
            ITsTextProps ttp = tssWord.get_Properties(0);

            Debug.Assert(ttp != null);
            int var;
            int ws = ttp.GetIntPropValues((int)FwTextPropType.ktptWs, out var);

            Debug.Assert(ws != 0);
            IWritingSystem wsVern = wsf.get_EngineOrNull(ws);

            Debug.Assert(wsVern != null);
            // The following is needed for Graphite fonts.
            string sFontVar = wsVern.FontVariation;

            if (sFontVar == null)
            {
                sFontVar = "";
            }

            this.m_txtMorphs.WritingSystemFactory = wsf;
            this.m_txtMorphs.WritingSystemCode    = ws;
            this.m_txtMorphs.Text = sMorphs;
            m_sMorphs             = sMorphs;

            // Fix the help strings to use the actual MorphType markers.
            IMoMorphType mmtStem      = null;
            IMoMorphType mmtPrefix    = null;
            IMoMorphType mmtSuffix    = null;
            IMoMorphType mmtInfix     = null;
            IMoMorphType mmtBoundStem = null;
            IMoMorphType mmtProclitic = null;
            IMoMorphType mmtEnclitic  = null;
            IMoMorphType mmtSimulfix  = null;
            IMoMorphType mmtSuprafix  = null;

            MoMorphType.GetMajorMorphTypes(cache, out mmtStem, out mmtPrefix, out mmtSuffix, out mmtInfix,
                                           out mmtBoundStem, out mmtProclitic, out mmtEnclitic, out mmtSimulfix, out mmtSuprafix);
            // Format the labels according to the MoMorphType Prefix/Postfix values.
            string sExample1     = stringTable.GetString("EditMorphBreaks-Example1", "DialogStrings");
            string sExample2     = stringTable.GetString("EditMorphBreaks-Example2", "DialogStrings");
            string sStemExample  = stringTable.GetString("EditMorphBreaks-stemExample", "DialogStrings");
            string sAffixExample = stringTable.GetString("EditMorphBreaks-affixExample", "DialogStrings");

            lblHelp2_Example1.Text = String.Format(sExample1,
                                                   mmtStem.Prefix == null ? "" : mmtStem.Prefix,
                                                   mmtStem.Postfix == null ? "" : mmtStem.Postfix);
            lblHelp2_Example2.Text = String.Format(sExample2,
                                                   mmtSuffix.Prefix == null ? "" : mmtSuffix.Prefix,
                                                   mmtSuffix.Postfix == null ? "" : mmtSuffix.Postfix);
            lblBreak_stemExample.Text = String.Format(sStemExample,
                                                      mmtStem.Prefix == null ? "" : mmtStem.Prefix,
                                                      mmtStem.Postfix == null ? "" : mmtStem.Postfix);
            lblBreak_boundStemExample.Text = String.Format(sStemExample,
                                                           mmtBoundStem.Prefix == null ? "" : mmtBoundStem.Prefix,
                                                           mmtBoundStem.Postfix == null ? "" : mmtBoundStem.Postfix);
            lblBreak_prefixExample.Text = String.Format(sAffixExample,
                                                        mmtPrefix.Prefix == null ? "" : " " + mmtPrefix.Prefix,
                                                        mmtPrefix.Postfix == null ? "" : mmtPrefix.Postfix + " ");
            lblBreak_suffixExample.Text = String.Format(sAffixExample,
                                                        mmtSuffix.Prefix == null ? "" : " " + mmtSuffix.Prefix,
                                                        mmtSuffix.Postfix == null ? "" : mmtSuffix.Postfix + " ");
            lblBreak_infixExample.Text = String.Format(sAffixExample,
                                                       mmtInfix.Prefix == null ? "" : " " + mmtInfix.Prefix,
                                                       mmtInfix.Postfix == null ? "" : mmtInfix.Postfix + " ");
            lblBreak_procliticExample.Text = String.Format(sAffixExample,
                                                           mmtProclitic.Prefix == null ? "" : " " + mmtProclitic.Prefix,
                                                           mmtProclitic.Postfix == null ? "" : mmtProclitic.Postfix + " ");
            lblBreak_encliticExample.Text = String.Format(sAffixExample,
                                                          mmtEnclitic.Prefix == null ? "" : " " + mmtEnclitic.Prefix,
                                                          mmtEnclitic.Postfix == null ? "" : mmtEnclitic.Postfix + " ");
            lblBreak_simulfixExample.Text = String.Format(sAffixExample,
                                                          mmtSimulfix.Prefix == null ? "" : " " + mmtSimulfix.Prefix,
                                                          mmtSimulfix.Postfix == null ? "" : mmtSimulfix.Postfix + " ");
            lblBreak_suprafixExample.Text = String.Format(sAffixExample,
                                                          mmtSuprafix.Prefix == null ? "" : " " + mmtSuprafix.Prefix,
                                                          mmtSuprafix.Postfix == null ? "" : mmtSuprafix.Postfix + " ");

            morphBreakContextMenu = new MorphBreakHelperMenu(m_txtMorphs, FwApp.App, cache, stringTable);
            m_txtMorphs.AdjustForStyleSheet(this, null, stylesheet);
        }
Example #16
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="argument">The xCore Command object.</param>
        /// <returns>true</returns>
        public bool OnAddApprovedAnalysis(object argument)
        {
            using (EditMorphBreaksDlg dlg = new EditMorphBreaksDlg())
            {
                IWfiWordform wf = Wordform;
                if (wf == null)
                {
                    return(true);
                }
                ITsString tssWord = Wordform.Form.BestVernacularAlternative;
                string    morphs  = tssWord.Text;
                FdoCache  cache   = Cache;
                dlg.Initialize(tssWord, morphs, cache.MainCacheAccessor.WritingSystemFactory,
                               cache, m_dataEntryForm.Mediator.StringTbl, m_dataEntryForm.StyleSheet);
                Form mainWnd = m_dataEntryForm.FindForm();
                // Making the form active fixes problems like LT-2619.
                // I'm (RandyR) not sure what adverse impact might show up by doing this.
                mainWnd.Activate();
                if (dlg.ShowDialog(mainWnd) == DialogResult.OK)
                {
                    morphs = dlg.GetMorphs().Trim();
                    if (morphs.Length == 0)
                    {
                        return(true);
                    }

                    string[] prefixMarkers  = MoMorphType.PrefixMarkers(cache);
                    string[] postfixMarkers = MoMorphType.PostfixMarkers(cache);

                    List <string> allMarkers = new List <string>();
                    foreach (string s in prefixMarkers)
                    {
                        allMarkers.Add(s);
                    }

                    foreach (string s in postfixMarkers)
                    {
                        if (!allMarkers.Contains(s))
                        {
                            allMarkers.Add(s);
                        }
                    }
                    allMarkers.Add(" ");

                    string[] breakMarkers = new string[allMarkers.Count];
                    for (int i = 0; i < allMarkers.Count; ++i)
                    {
                        breakMarkers[i] = allMarkers[i];
                    }

                    string fullForm = SandboxBase.MorphemeBreaker.DoBasicFinding(morphs, breakMarkers, prefixMarkers, postfixMarkers);

                    using (UndoRedoCommandHelper undoRedoTask = new UndoRedoCommandHelper(Cache,
                                                                                          argument as Command))
                    {
                        IWfiAnalysis newAnalysis = Wordform.AnalysesOC.Add(new WfiAnalysis());
                        newAnalysis.ApprovalStatusIcon = 1;                         // Make it human approved.
                        int vernWS = StringUtils.GetWsAtOffset(tssWord, 0);
                        foreach (string morph in fullForm.Split(Unicode.SpaceChars))
                        {
                            if (morph != null && morph.Length != 0)
                            {
                                IWfiMorphBundle mb = newAnalysis.MorphBundlesOS.Append(new WfiMorphBundle());
                                mb.Form.SetAlternative(morph, vernWS);
                            }
                        }
                        int outlineFlid = BaseVirtualHandler.GetInstalledHandlerTag(cache, "WfiAnalysis", "HumanApprovedNumber");
                        foreach (int haaHvo in Wordform.HumanApprovedAnalyses)
                        {
                            // Do PropChanged for the outline number for all of them.
                            // This fixes LT-5007, as the older ones kept their old number,
                            // which could have been a duplicate number.
                            cache.PropChanged(
                                null,
                                PropChangeType.kpctNotifyAll,
                                haaHvo,
                                outlineFlid,
                                0, 0, 0);
                        }
                        cache.PropChanged(
                            null,
                            PropChangeType.kpctNotifyAll,
                            Wordform.Hvo,
                            BaseVirtualHandler.GetInstalledHandlerTag(cache, "WfiWordform", "HumanApprovedAnalyses"),
                            0, 1, 0);
                    }
                }
            }

            return(true);
        }