/// <summary> /// Determines whether the specified dummy MSA is equal to the current MSA. /// </summary> /// <param name="msa">The MoStemMsa to compare with the current MoStemMsa.</param> /// <returns>true if the specified MoStemMsa is equal to the current MoStemMsa; otherwise, false.</returns> public virtual bool EqualsMsa(DummyGenericMSA msa) { throw new ApplicationException("Subclasses must override this method."); }
/// <summary> /// Update an extant MSA to the new values in the dummy MSA, /// or make a new MSA with the values in the dummy msa. /// </summary> /// <param name="dummyMsa"></param> /// <remarks> /// Subclasses should override this method to do same-class updates, /// but then call this method to handle class changing activities. /// </remarks> public virtual IMoMorphSynAnalysis UpdateOrReplace(DummyGenericMSA dummyMsa) { ILexEntry le = LexEntry.CreateFromDBObject(m_cache, OwnerHVO); foreach (MoMorphSynAnalysis msa in le.MorphoSyntaxAnalysesOC) { // Check other extant MSAs to see if they match the updated one. if (msa != this && msa.EqualsMsa(dummyMsa)) { msa.MergeObject(this); return msa; } } // Make a new MSA. IMoMorphSynAnalysis newMsa = null; switch (dummyMsa.MsaType) { default: throw new ApplicationException("Cannot create any other kind of MSA here."); case MsaType.kRoot: // Fall through. case MsaType.kStem: newMsa = MoStemMsa.CreateFromDummy(le, dummyMsa); break; case MsaType.kDeriv: newMsa = MoDerivAffMsa.CreateFromDummy(le, dummyMsa); break; case MsaType.kInfl: newMsa = MoInflAffMsa.CreateFromDummy(le, dummyMsa); break; case MsaType.kUnclassified: newMsa = MoUnclassifiedAffixMsa.CreateFromDummy(le, dummyMsa); break; } newMsa.SwitchReferences(this); DeleteUnderlyingObject(); return newMsa; }
/// <summary> /// Initialize the control. /// </summary> /// <param name="cache"></param> /// <param name="mediator"></param> /// <param name="parentForm"></param> public void Initialize(FdoCache cache, Mediator mediator, Form parentForm, DummyGenericMSA dummyMSA) { CheckDisposed(); m_parentForm = parentForm; m_mediator = mediator; m_tsf = TsStrFactoryClass.Create(); m_cache = cache; IVwStylesheet stylesheet = FontHeightAdjuster.StyleSheetFromMediator(mediator); m_fwcbAffixTypes.WritingSystemFactory = m_cache.LanguageWritingSystemFactoryAccessor; m_fwcbAffixTypes.WritingSystemCode = m_cache.LangProject.DefaultAnalysisWritingSystem; m_fwcbAffixTypes.Items.Add(m_tsf.MakeString(LexTextControls.ksNotSure, m_cache.LangProject.DefaultUserWritingSystem)); m_fwcbAffixTypes.Items.Add(m_tsf.MakeString(LexTextControls.ksInflectional, m_cache.LangProject.DefaultUserWritingSystem)); m_fwcbAffixTypes.Items.Add(m_tsf.MakeString(LexTextControls.ksDerivational, m_cache.LangProject.DefaultUserWritingSystem)); m_fwcbAffixTypes.StyleSheet = stylesheet; m_fwcbAffixTypes.AdjustStringHeight = false; m_fwcbSlots.Font = new System.Drawing.Font(cache.LangProject.DefaultAnalysisWritingSystemFont, 10); m_fwcbSlots.WritingSystemFactory = m_cache.LanguageWritingSystemFactoryAccessor; m_fwcbSlots.WritingSystemCode = m_cache.LangProject.DefaultAnalysisWritingSystem; m_fwcbSlots.StyleSheet = stylesheet; m_fwcbSlots.AdjustStringHeight = false; m_tcMainPOS.Font = new System.Drawing.Font(cache.LangProject.DefaultAnalysisWritingSystemFont, 10); m_tcMainPOS.WritingSystemFactory = m_cache.LanguageWritingSystemFactoryAccessor; m_tcMainPOS.WritingSystemCode = m_cache.LangProject.DefaultAnalysisWritingSystem; m_tcMainPOS.StyleSheet = stylesheet; m_tcMainPOS.AdjustStringHeight = false; m_tcSecondaryPOS.Font = new System.Drawing.Font(cache.LangProject.DefaultAnalysisWritingSystemFont, 10); m_tcSecondaryPOS.WritingSystemFactory = m_cache.LanguageWritingSystemFactoryAccessor; m_tcSecondaryPOS.WritingSystemCode = m_cache.LangProject.DefaultAnalysisWritingSystem; m_tcSecondaryPOS.StyleSheet = stylesheet; m_tcSecondaryPOS.AdjustStringHeight = false; m_selectedMainPOSHvo = dummyMSA.MainPOS; m_fwcbAffixTypes.SelectedIndex = 0; m_fwcbAffixTypes.SelectedIndexChanged += new EventHandler( HandleComboMSATypesChange); m_mainPOSPopupTreeManager = new POSPopupTreeManager(m_tcMainPOS, m_cache, m_cache.LangProject.PartsOfSpeechOA, m_cache.LangProject.DefaultAnalysisWritingSystem, false, m_mediator, m_parentForm); m_mainPOSPopupTreeManager.NotSureIsAny = true; m_mainPOSPopupTreeManager.LoadPopupTree(m_selectedMainPOSHvo); m_mainPOSPopupTreeManager.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(m_mainPOSPopupTreeManager_AfterSelect); m_fwcbSlots.SelectedIndexChanged += new EventHandler( HandleComboSlotChange); m_secPOSPopupTreeManager = new POSPopupTreeManager(m_tcSecondaryPOS, m_cache, m_cache.LangProject.PartsOfSpeechOA, m_cache.LangProject.DefaultAnalysisWritingSystem, false, m_mediator, m_parentForm); m_secPOSPopupTreeManager.NotSureIsAny = true; // only used for affixes. m_selectedSecondaryPOSHvo = dummyMSA.SecondaryPOS; m_secPOSPopupTreeManager.LoadPopupTree(m_selectedSecondaryPOSHvo); m_secPOSPopupTreeManager.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(m_secPOSPopupTreeManager_AfterSelect); // Relocate the m_tcSecondaryPOS control to overlay the m_fwcbSlots. // In the designer, they are offset to see them, and edit them. // In running code they are in the same spot, but only one is visible at a time. m_tcSecondaryPOS.Location = m_fwcbSlots.Location; if (m_selectedMainPOSHvo > 0 && dummyMSA.MsaType == MsaType.kInfl) { // This fixes LT-4677, LT-6048, and LT-6201. ResetSlotCombo(); } MSAType = dummyMSA.MsaType; }
/// <summary> /// Determines whether the specified dummy MSA is equal to the current MSA. /// </summary> /// <param name="msa">The MoStemMsa to compare with the current MoStemMsa.</param> /// <returns>true if the specified MoStemMsa is equal to the current MoStemMsa; otherwise, false.</returns> public override bool EqualsMsa(DummyGenericMSA msa) { // This is the behavior defined by Object.Equals(). if (msa == null) return false; // Make sure that we can cast this object to a MoStemMsa. if (msa.MsaType != MsaType.kInfl) return false; if (PartOfSpeechRAHvo != msa.MainPOS) return false; // Can't set these two from the dialog, if non-null, we are not equal. if (FromProdRestrictRC.Count != 0) return false; if (InflFeatsOAHvo != 0 && !InflFeatsOA.IsEmpty) return false; // TODO: Add checks for other properties, when we support using them. if (msa.Slot == 0) return (SlotsRC.Count == 0); else return SlotsRC.Count == 1 && SlotsRC.Contains(msa.Slot); }
/// <summary> /// Create a new sense and add it to the given entry. /// </summary> /// <param name="entry"></param> /// <param name="dummyMSA"></param> /// <param name="gloss"></param> /// <returns></returns> public static ILexSense CreateSense(ILexEntry entry, DummyGenericMSA dummyMSA, string gloss) { ILexSense sense = (ILexSense)entry.SensesOS.Append(new LexSense()); (sense as LexSense).DummyMSA = dummyMSA; // Handle gloss. if (gloss != null && gloss.Length > 0) { if (gloss.Length > 256) { System.Windows.Forms.MessageBox.Show(Strings.ksTruncatingGloss, Strings.ksWarning, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning); gloss = gloss.Substring(0, 256); } sense.Gloss.AnalysisDefaultWritingSystem = gloss; } return sense; }
/// <summary> /// This is invoked (using reflection) by an XmlRDEBrowseView when the user presses /// "Enter" in an RDE view that is displaying lexeme form and definition. /// (Maybe also on loss of focus, switch domain, etc?) /// It creates a new entry, lexeme form, and sense that are linked to the specified domain. /// Typically, later, a call to RDEMergeSense will be made to see whether this /// new entry should be merged into some existing sense. /// Note that this method is NOT responsible to insert the new sense into /// the fake property tagList of hvoDomain. (The caller will do that.) /// </summary> /// <param name="hvoDomain">database id of the semantic domain</param> /// <param name="tagList">id of the inverse relation for the senses that belong to the /// domain</param> /// <param name="columns"></param> /// <param name="rgtss"></param> /// <param name="cache"></param> /// <param name="stringTbl"></param> public static int RDENewSense(int hvoDomain, int tagList, List<XmlNode> columns, ITsString[] rgtss, FdoCache cache, StringTable stringTbl) { Debug.Assert(hvoDomain != 0); Debug.Assert(rgtss.Length == columns.Count); // Make a new sense in a new entry. ILexEntry le = cache.LangProject.LexDbOA.EntriesOC.Add( new LexEntry()); IMoForm morph = null; // create a LexSense that has the given definition and semantic domain // Needs to be LexSense, since later calls use non-interface methods. LexSense ls = (LexSense)le.SensesOS.Append(new LexSense()); ILgWritingSystemFactory wsf = cache.LanguageWritingSystemFactoryAccessor; // go through each column and store the appropriate information. for (int i = 0; i < columns.Count; ++i) { // Review: Currently we key off the column labels to determine which columns // correspond to CitationForm and which correspond to Definition. // Ideally we'd like to get at the flids used to build the column display strings. // Instead of passing in only ITsStrings, we could pass in a structure containing // an index of strings with any corresponding flids. Here we'd expect strings // based upon either LexemeForm.Form or LexSense.Definition. We could probably // do this as part of the solution to handling duplicate columns in LT-3763. XmlNode column = columns[i] as XmlNode; string columnLabel = XmlUtils.GetManditoryAttributeValue(column, "label"); string[] columnLabelComponents = columnLabel.Split(new char[] {' ', ':'}); // get column label without writing system or extraneous information. string columnBasicLabel = columnLabelComponents[0]; if (!String.IsNullOrEmpty(columnBasicLabel) && stringTbl != null) columnBasicLabel = stringTbl.LocalizeAttributeValue(columnBasicLabel); ITsTextProps ttp = rgtss[i].get_PropertiesAt(0); int var; int ws = ttp.GetIntPropValues((int)FwTextPropType.ktptWs, out var); Debug.Assert(ws != 0); ITsString tssStr = rgtss[i]; string sStr = tssStr.Text; if (sStr == null) sStr = ""; // otherwise Trim below blows up. sStr = sStr.Trim(); if (columnBasicLabel == Strings.ksWord) { // This is a lexeme form. if (morph == null) morph = MoForm.MakeMorph(cache, le, tssStr); Debug.Assert(le.LexemeFormOAHvo != 0); if (morph is IMoStemAllomorph) { // Make sure we have a proper allomorph and MSA for this new entry and sense. // (See LT-1318 for details and justification.) MoMorphTypeCollection typesCol = new MoMorphTypeCollection(cache); if (sStr.IndexOf(' ') > 0) morph.MorphTypeRA = typesCol.Item(MoMorphType.kmtPhrase); else morph.MorphTypeRA = typesCol.Item(MoMorphType.kmtStem); morph.Form.SetAlternative(sStr, ws); } } else if (columnBasicLabel == Strings.ksDefinition) { // This is a Definition. if (sStr != "") ls.Definition.SetAlternative(sStr, ws); } else { Debug.Fail("column (" + columnLabel + ") not supported."); } } if (morph == null) morph = le.LexemeFormOA = new MoStemAllomorph(); ls.RDEAddDomain(hvoDomain, tagList, cache); if (le.MorphoSyntaxAnalysesOC.Count == 0) { // Commonly, it's a new entry with no MSAs; make sure it has at least one. // This way of doing it allows a good bit of code to be shared with the normal // creation path, as if the user made a stem but didn't fill in any grammatical // information. DummyGenericMSA dummyMsa = new DummyGenericMSA(); if (morph != null && morph is IMoAffixForm) dummyMsa.MsaType = MsaType.kUnclassified; else dummyMsa.MsaType = MsaType.kStem; ls.DummyMSA = dummyMsa; } // We don't want a partial MSA created, so don't bother doing anything // about setting ls.MorphoSyntaxAnalysisRA // LT-1731: adding to make sure new entries are added to the lexicon // record list (full edit,...) cache.PropChanged(null, PropChangeType.kpctNotifyAll, cache.LangProject.LexDbOA.Hvo, (int)LexDb.LexDbTags.kflidEntries, 0, 1, 0); return ls.Hvo; }
/// <summary> /// Create a new MoDerivAffMsa, based on the given dummy MSA. /// </summary> /// <param name="entry"></param> /// <param name="dummyMsa"></param> /// <returns></returns> public static IMoDerivAffMsa CreateFromDummy(ILexEntry entry, DummyGenericMSA dummyMsa) { Debug.Assert(dummyMsa.MsaType == MsaType.kDeriv); IMoDerivAffMsa derivMsa = (IMoDerivAffMsa)entry.MorphoSyntaxAnalysesOC.Add(new MoDerivAffMsa()); derivMsa.FromPartOfSpeechRAHvo = dummyMsa.MainPOS; derivMsa.ToPartOfSpeechRAHvo = dummyMsa.SecondaryPOS; return derivMsa; }
/// <summary> /// Create a new MoStemMsa, based on the given dummy MSA. /// </summary> /// <param name="entry"></param> /// <param name="dummyMsa"></param> /// <returns></returns> public static IMoStemMsa CreateFromDummy(ILexEntry entry, DummyGenericMSA dummyMsa) { Debug.Assert(dummyMsa.MsaType == MsaType.kRoot || dummyMsa.MsaType == MsaType.kStem); IMoStemMsa stemMsa = (IMoStemMsa)entry.MorphoSyntaxAnalysesOC.Add(new MoStemMsa()); stemMsa.PartOfSpeechRAHvo = dummyMsa.MainPOS; return stemMsa; }
/// <summary> /// Determines whether the specified dummy MSA is equal to the current MSA. /// </summary> /// <param name="msa">The MoDerivAffMsa to compare with the current MoDerivAffMsa.</param> /// <returns>true if the specified MoDerivAffMsa is equal to the current MoDerivAffMsa; otherwise, false.</returns> public override bool EqualsMsa(DummyGenericMSA msa) { // This is the behavior defined by Object.Equals(). if (msa == null) return false; if (msa.MsaType != MsaType.kDeriv) return false; // Check the two properties we get from the DLG match, and the others we care about are missing. return FromPartOfSpeechRAHvo == msa.MainPOS && ToPartOfSpeechRAHvo == msa.SecondaryPOS && FromInflectionClassRAHvo == 0 && FromStemNameRAHvo == 0 && ToInflectionClassRAHvo == 0 && FromProdRestrictRC.Count == 0 && ToProdRestrictRC.Count == 0 && (ToMsFeaturesOAHvo == 0 || ToMsFeaturesOA.IsEmpty) && (FromMsFeaturesOAHvo == 0 || FromMsFeaturesOA.IsEmpty); }
/// <summary> /// Update an extant MSA to the new values in the dummy MSA, /// or make a new MSA with the values in the dummy msa. /// </summary> /// <param name="dummyMsa"></param> public override IMoMorphSynAnalysis UpdateOrReplace(DummyGenericMSA dummyMsa) { if (dummyMsa.MsaType == MsaType.kDeriv) { if (FromPartOfSpeechRAHvo != dummyMsa.MainPOS) FromPartOfSpeechRAHvo = dummyMsa.MainPOS; if (ToPartOfSpeechRAHvo != dummyMsa.SecondaryPOS) ToPartOfSpeechRAHvo = dummyMsa.SecondaryPOS; return this; } return base.UpdateOrReplace(dummyMsa); }
private bool AddNewMsa() { PopupTree pt = GetPopupTree(); // Force the PopupTree to Hide() to trigger popupTree_PopupTreeClosed(). // This will effectively revert the list selection to a previous confirmed state. // Whatever happens below, we don't want to actually leave the "Specify ..." node selected! // This is at least required if the user selects "Cancel" from the dialog below. pt.Hide(); using (MsaCreatorDlg dlg = new MsaCreatorDlg()) { DummyGenericMSA dummyMsa = new DummyGenericMSA(); dummyMsa.MsaType = m_sense.GetDesiredMsaType(); dlg.SetDlgInfo(Cache, m_persistProvider, m_mediator, m_sense.Entry, dummyMsa, 0, false, null); if (dlg.ShowDialog(ParentForm) == DialogResult.OK) { Cache.BeginUndoTask(String.Format(LexTextControls.ksUndoSetX, FieldName), String.Format(LexTextControls.ksRedoSetX, FieldName)); (m_sense as LexSense).DummyMSA = dlg.DummyMSA; Cache.EndUndoTask(); LoadPopupTree(m_sense.MorphoSyntaxAnalysisRAHvo); return true; } } return false; }
private bool ChooseFromMasterCategoryList() { PopupTree pt = GetPopupTree(); // Force the PopupTree to Hide() to trigger popupTree_PopupTreeClosed(). // This will effectively revert the list selection to a previous confirmed state. // Whatever happens below, we don't want to actually leave the "More..." node selected! // This is at least required if the user selects "Cancel" from the dialog below. pt.Hide(); using (MasterCategoryListDlg dlg = new MasterCategoryListDlg()) { dlg.SetDlginfo(List, m_mediator, false, null); switch (dlg.ShowDialog(ParentForm)) { case DialogResult.OK: DummyGenericMSA dummyMSA = new DummyGenericMSA(); dummyMSA.MainPOS = dlg.SelectedPOS.Hvo; dummyMSA.MsaType = m_sense.GetDesiredMsaType(); Cache.BeginUndoTask(String.Format(LexTextControls.ksUndoSetX, FieldName), String.Format(LexTextControls.ksRedoSetX, FieldName)); (m_sense as LexSense).DummyMSA = dummyMSA; Cache.EndUndoTask(); LoadPopupTree(m_sense.MorphoSyntaxAnalysisRAHvo); // everything should be setup with new node selected, so return. return true; case DialogResult.Yes: // Post a message so that we jump to Grammar(area)/Categories tool. // Do this before we close any parent dialog in case // the parent wants to check to see if such a Jump is pending. // NOTE: We use PostMessage here, rather than SendMessage which // disposes of the PopupTree before we and/or our parents might // be finished using it (cf. LT-2563). m_mediator.PostMessage("FollowLink", SIL.FieldWorks.FdoUi.FwLink.Create("posEdit", Cache.GetGuidFromId(dlg.SelectedPOS.Hvo), Cache.ServerName, Cache.DatabaseName)); if (ParentForm != null && ParentForm.Modal) { // Close the dlg that opened the master POS dlg, // since its hotlink was used to close it, // and a new POS has been created. ParentForm.DialogResult = DialogResult.Cancel; ParentForm.Close(); } return false; default: // NOTE: If the user has selected "Cancel", then don't change // our m_lastConfirmedNode to the "More..." node. Keep it // the value set by popupTree_PopupTreeClosed() when we // called pt.Hide() above. (cf. comments in LT-2522) return false; } } }
private void CreateEmptyMsa() { DummyGenericMSA dummyMsa = new DummyGenericMSA(); dummyMsa.MsaType = m_sense.GetDesiredMsaType(); // To make it fully 'not sure' we must discard knowledge of affix type. if (dummyMsa.MsaType == MsaType.kInfl || dummyMsa.MsaType == MsaType.kDeriv) dummyMsa.MsaType = MsaType.kUnclassified; Cache.BeginUndoTask(String.Format(LexTextControls.ksUndoSetX, FieldName), String.Format(LexTextControls.ksRedoSetX, FieldName)); (m_sense as LexSense).DummyMSA = dummyMsa; Cache.EndUndoTask(); }
/// <summary> /// Determines whether the specified dummy MSA is equal to the current MSA. /// </summary> /// <param name="msa">The MoStemMsa to compare with the current MoStemMsa.</param> /// <returns>true if the specified MoStemMsa is equal to the current MoStemMsa; otherwise, false.</returns> public override bool EqualsMsa(DummyGenericMSA msa) { // This is the behavior defined by Object.Equals(). if (msa == null) return false; // Make sure that we can cast this object to a MoStemMsa. if (msa.MsaType != MsaType.kStem) return false; // The dummy generic currently can't have any of these, so if this does, they don't match. if (InflectionClassRAHvo != 0 || (MsFeaturesOAHvo != 0 && !MsFeaturesOA.IsEmpty) || (ProdRestrictRC.Count != 0) || (FromPartsOfSpeechRC.Count != 0)) return false; // TODO: Add checks for other properties, when we support using them. return PartOfSpeechRAHvo == msa.MainPOS; }
/// <summary> /// Determines whether the specified dummy MSA is equal to the current MSA. /// </summary> /// <param name="msa">The MoUnclassifiedAffixMsa to compare with the current MoUnclassifiedAffixMsa.</param> /// <returns>true if the specified MoUnclassifiedAffixMsa is equal to the current MoUnclassifiedAffixMsa; otherwise, false.</returns> public override bool EqualsMsa(DummyGenericMSA msa) { // This is the behavior defined by Object.Equals(). if (msa == null) return false; // Make sure that we can cast this object to a MoStemMsa. if (msa.MsaType != MsaType.kUnclassified) return false; // TODO: Add checks for other properties, when we support using them. return PartOfSpeechRAHvo == msa.MainPOS; }
/// <summary> /// Update an extant MSA to the new values in the dummy MSA, /// or make a new MSA with the values in the dummy msa. /// </summary> /// <param name="dummyMsa"></param> public override IMoMorphSynAnalysis UpdateOrReplace(DummyGenericMSA dummyMsa) { if (dummyMsa.MsaType == MsaType.kStem || dummyMsa.MsaType == MsaType.kRoot) { if (PartOfSpeechRAHvo != dummyMsa.MainPOS) PartOfSpeechRAHvo = dummyMsa.MainPOS; return this; } return base.UpdateOrReplace(dummyMsa); }
/// <summary> /// Create a new MoUnclassifiedAffixMsa, based on the given dummy MSA. /// </summary> /// <param name="entry"></param> /// <param name="dummyMsa"></param> /// <returns></returns> public static IMoUnclassifiedAffixMsa CreateFromDummy(ILexEntry entry, DummyGenericMSA dummyMsa) { Debug.Assert(dummyMsa.MsaType == MsaType.kUnclassified); IMoUnclassifiedAffixMsa uncMsa = (IMoUnclassifiedAffixMsa)entry.MorphoSyntaxAnalysesOC.Add(new MoUnclassifiedAffixMsa()); uncMsa.PartOfSpeechRAHvo = dummyMsa.MainPOS; return uncMsa; }
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_cache.VerifyValidObject(m_obj)) 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; } LexSense sense = m_obj as LexSense; // 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; int clidSel = 0; if (hvoSel > 0) clidSel = m_cache.GetClassOfObject(hvoSel); bool didChange = false; if (clidSel == PartOfSpeech.kclsidPartOfSpeech) { ContainingDataTree.DoNotRefresh = true; m_cache.BeginUndoTask( String.Format(DetailControlsStrings.ksUndoSet, m_fieldName), String.Format(DetailControlsStrings.ksRedoSet, m_fieldName)); DummyGenericMSA dummyMSA = new DummyGenericMSA(); dummyMSA.MsaType = sense.GetDesiredMsaType(); dummyMSA.MainPOS = hvoSel; MoStemMsa stemMsa = sense.MorphoSyntaxAnalysisRA as MoStemMsa; if (stemMsa != null) dummyMSA.FromPartsOfSpeech = stemMsa.FromPartsOfSpeechRC; sense.DummyMSA = dummyMSA; didChange = true; } else if (sense.MorphoSyntaxAnalysisRAHvo != hvoSel) { ContainingDataTree.DoNotRefresh = true; m_cache.BeginUndoTask( String.Format(DetailControlsStrings.ksUndoSet, m_fieldName), String.Format(DetailControlsStrings.ksRedoSet, m_fieldName)); sense.MorphoSyntaxAnalysisRAHvo = hvoSel; didChange = true; } if (didChange) m_cache.EndUndoTask(); if (!ContainingDataTree.RefreshListNeeded) { m_MSAPopupTreeManager.LoadPopupTree(sense.MorphoSyntaxAnalysisRAHvo); // Don't refresh the datatree unless the popup has actually been loaded. // It could be setting the selection in the process of loading! See LT-9191. if (m_MSAPopupTreeManager.IsTreeLoaded) ContainingDataTree.RefreshList(false); } } 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); } }
/// <summary> /// Update an extant MSA to the new values in the dummy MSA, /// or make a new MSA with the values in the dummy msa. /// </summary> /// <param name="dummyMsa"></param> public override IMoMorphSynAnalysis UpdateOrReplace(DummyGenericMSA dummyMsa) { if (dummyMsa.MsaType == MsaType.kInfl) { if (PartOfSpeechRAHvo != dummyMsa.MainPOS) PartOfSpeechRAHvo = dummyMsa.MainPOS; if (dummyMsa.Slot > 0 && !SlotsRC.Contains(dummyMsa.Slot)) SlotsRC.Add(dummyMsa.Slot); // Remove any slots that are not legal for the current POS. List<int> allSlots; if (PartOfSpeechRAHvo == 0) allSlots = new List<int>(0); else allSlots = PartOfSpeechRA.AllAffixSlotIDs; int[] slots = SlotsRC.HvoArray; foreach (int slotHvo in slots) { if (!allSlots.Contains(slotHvo)) SlotsRC.Remove(slotHvo); } return this; } return base.UpdateOrReplace(dummyMsa); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Create a new entry. /// The caller is expected to call PropChanged on the cache to notify the record /// list of the new record. /// </summary> /// <param name="cache">The cache.</param> /// <param name="morphType">Type of the morph.</param> /// <param name="tssLexemeForm">The TSS lexeme form.</param> /// <param name="gloss">The gloss.</param> /// <param name="dummyMSA">The dummy MSA.</param> /// <returns></returns> /// ------------------------------------------------------------------------------------ public static ILexEntry CreateEntry(FdoCache cache, IMoMorphType morphType, ITsString tssLexemeForm, string gloss, DummyGenericMSA dummyMSA) { using (new UndoRedoTaskHelper(cache, Strings.ksUndoCreateEntry, Strings.ksRedoCreateEntry)) { ILexEntry entry = null; // NO: Since this fires a PropChanged, and we do it ourselves later on. // entry = (LexEntry)entries.Add(new LexEntry()); // CreateObject creates the entry without a PropChanged. int entryHvo = cache.CreateObject(LexEntry.kClassId, cache.LangProject.LexDbOAHvo, (int)LexDb.LexDbTags.kflidEntries, 0); // 0 is fine, since the entries prop is not a sequence. entry = LexEntry.CreateFromDBObject(cache, entryHvo); ILexSense sense = LexSense.CreateSense(entry, dummyMSA, gloss); if (morphType.Guid.ToString() == MoMorphType.kguidMorphCircumfix) { // Set Lexeme form to lexeme form and circumfix SetCircumfixLexemeForm(cache, entry, tssLexemeForm, morphType); // Create two allomorphs, one for the left member and one for the right member. SplitCircumfixIntoLeftAndRightAllomorphs(cache, entry, tssLexemeForm, sense); } else { IMoForm allomorph = MoForm.CreateAllomorph(entry, sense.MorphoSyntaxAnalysisRA, tssLexemeForm, morphType, true); } (entry as LexEntry).UpdateHomographNumbersAccountingForNewEntry(); return entry; } }
/// <summary> /// Create a new MoInflAffMsa, based on the given dummy MSA. /// </summary> /// <param name="entry"></param> /// <param name="dummyMsa"></param> /// <returns></returns> public static IMoInflAffMsa CreateFromDummy(ILexEntry entry, DummyGenericMSA dummyMsa) { Debug.Assert(dummyMsa.MsaType == MsaType.kInfl); IMoInflAffMsa inflMsa = (IMoInflAffMsa)entry.MorphoSyntaxAnalysesOC.Add(new MoInflAffMsa()); inflMsa.PartOfSpeechRAHvo = dummyMsa.MainPOS; if (dummyMsa.Slot > 0) inflMsa.SlotsRC.Add(dummyMsa.Slot); return inflMsa; }
/// <summary> /// Initialize the dialog before showing it. /// </summary> /// <param name="cache"></param> /// <param name="entry"></param> /// <param name="titleForEdit">Edit title appropriate to the button's context.</param> public void SetDlgInfo(FdoCache cache, IPersistenceProvider persistProvider, Mediator mediator, ILexEntry entry, DummyGenericMSA dummyMsa, int hvoOriginalMsa, bool useForEdit, string titleForEdit) { CheckDisposed(); Debug.Assert(m_cache == null); MsaType msaType = dummyMsa.MsaType; m_cache = cache; m_mediator = mediator; if (useForEdit) { // Change the window title and the OK button text. Text = titleForEdit; s_helpTopic = "khtpEditGrammaticalFunction"; this.helpProvider.SetHelpKeyword(this, FwApp.App.GetHelpString(s_helpTopic, 0)); btnOk.Text = LexText.Controls.LexTextControls.ks_OK; } // Set font, writing system factory, and code for the edit box. float fntSize = label1.Font.Size * 2.0F; m_fwtbCitationForm.Font = new Font(m_cache.LangProject.DefaultVernacularWritingSystemFont, fntSize); m_fwtbCitationForm.WritingSystemFactory = m_cache.LanguageWritingSystemFactoryAccessor; m_fwtbCitationForm.WritingSystemCode = m_cache.LangProject.DefaultVernacularWritingSystem; m_fwtbCitationForm.AdjustForStyleSheet(this, null, mediator); m_fwtbCitationForm.AdjustStringHeight = false; m_fwtbCitationForm.Tss = entry.HeadWord; m_fwtbCitationForm.HasBorder = false; m_fwtbSenses.Font = new Font(m_cache.LangProject.DefaultVernacularWritingSystemFont, fntSize); m_fwtbSenses.WritingSystemFactory = m_cache.LanguageWritingSystemFactoryAccessor; m_fwtbSenses.WritingSystemCode = m_cache.LangProject.DefaultVernacularWritingSystem; m_fwtbSenses.AdjustForStyleSheet(this, null, mediator); m_fwtbSenses.AdjustStringHeight = false; string sSenses = string.Empty; ITsIncStrBldr tisb = TsIncStrBldrClass.Create(); foreach (ILexSense sense in entry.AllSenses) { if (sense.MorphoSyntaxAnalysisRA != null) { if (sense.MorphoSyntaxAnalysisRAHvo == hvoOriginalMsa) { if (tisb.Text != null) tisb.Append(", "); // REVIEW: IS LOCALIZATION NEEDED FOR BUILDING THIS LIST? tisb.AppendTsString(sense.ShortNameTSS); } } } m_fwtbSenses.Tss = tisb.GetString(); m_fwtbSenses.HasBorder = false; m_msaGroupBox.Initialize(m_cache, m_mediator, this, dummyMsa); int oldHeight = m_msaGroupBox.Height; int newHeight = Math.Max(oldHeight, m_msaGroupBox.PreferredHeight); int delta = newHeight - oldHeight; if (delta > 0) { m_msaGroupBox.AdjustInternalControlsAndGrow(); Debug.Assert(m_msaGroupBox.Height == m_msaGroupBox.PreferredHeight); FontHeightAdjuster.GrowDialogAndAdjustControls(this, delta, m_msaGroupBox); } if (mediator != null) { // Reset window location. // Get location to the stored values, if any. object locWnd = m_mediator.PropertyTable.GetValue("msaCreatorDlgLocation"); // JohnT: this dialog can't be resized. So it doesn't make sense to // remember a size. If we do, we need to override OnLoad (as in SimpleListChooser) // to prevent the dialog growing every time at 120 dpi. But such an override // makes it too small to show all the controls at the default size. // It's better just to use the default size until it's resizeable for some reason. //m_mediator.PropertyTable.GetValue("msaCreatorDlgSize"); object szWnd = this.Size; if (locWnd != null && szWnd != null) { Rectangle rect = new Rectangle((Point)locWnd, (Size)szWnd); ScreenUtils.EnsureVisibleRect(ref rect); DesktopBounds = rect; StartPosition = FormStartPosition.Manual; } } }
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]; }