Exemple #1
0
        /// <summary>
        /// If OK, then make FS have the selected feature value(s).
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PhonologicalFeatureChooserDlg_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (DialogResult == DialogResult.OK)
            {
                Cursor = Cursors.WaitCursor;
                if (m_fs == null)
                {
                    // Didn't have one to begin with. See whether we want to create one.
                    if (m_hvoOwner != 0 && CheckFeatureStructure())
                    {
                        // The last argument is meaningless since we expect this property to be owning
                        // or collection.
                        int hvoFs = m_cache.CreateObject(FsFeatStruc.kClassId, m_hvoOwner, m_owningFlid, 0);
                        m_fs = (IFsFeatStruc)FsFeatStruc.CreateFromDBObject(m_cache, hvoFs, false);
                    }
                }

                if (m_fs != null)
                {
                    // clean out any extant features in the feature structure
                    foreach (IFsFeatureSpecification spec in m_fs.FeatureSpecsOC)
                    {
                        m_fs.FeatureSpecsOC.Remove(spec);
                    }
                    UpdateFeatureStructure();
                }
            }

            if (m_mediator != null)
            {
                m_mediator.PropertyTable.SetProperty("phonFeatListDlgLocation", Location);
                m_mediator.PropertyTable.SetProperty("phonFeatListDlgSize", Size);
            }
            Cursor = Cursors.Default;
        }
        /// <summary>
        /// If OK, then make FS have the selected feature value(s).
        /// JohnT: This is a really ugly kludge, which I have only partly repaired.
        /// We need the dialog to return with m_fs set to an FsFeatStruc (if OK was clicked),
        /// since that is what the bulk edit bar wants to copy to MoStemMsas for any items
        /// it is asked to modify. Also, the new FsFeatStruc needs to be in the ReferenceForms
        /// (which is what m_owningFlid apparently always is, currently) so that it will become
        /// one of the items in the combo list and can be selected. However, Andy says this is
        /// not the intended use of ReferenceForms at all.
        /// A further ugliness is that we always make a new FsFeatStruc (unless one was passed
        /// in to one of the SegDlgInfo methods, but AFAIK that override is never used), but
        /// we then delete it if it turns out to be a duplicate. There is no other straightforward
        /// way to detect that the current choices in the dialog correspond to an existing item.
        /// This may cause problems in the new world, where we can't do this "suppress sub tasks"
        /// trick without losing our Undo stack.
        /// It may be possible in the new world to create an object without initially giving it an
        /// owner, and only persist it if it is NOT a duplicate. But even that we don't really want
        /// to be undoable, nor should it clear the undo stack. Really the list of possible choices
        /// for the combo should not be separately persisted as model data, but it should be persisted
        /// somehow...
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MsaInflectionFeatureListDlg_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (DialogResult == DialogResult.OK)
            {
                using (new SuppressSubTasks(m_cache))                 // making and maybe then deleting the new item for the combo is not undoable
                {
                    if (m_fs == null)
                    {
                        // Didn't have one to begin with. See whether we want to create one.
                        if (CheckFeatureStructure(m_tvMsaFeatureList.Nodes))
                        {
                            // The last argument is meaningless since we expect this property to be owning
                            // or collection.
                            int hvoFs = m_cache.CreateObject(FsFeatStruc.kClassId, m_hvoOwner, m_owningFlid, 0);
                            m_fs = (IFsFeatStruc)FsFeatStruc.CreateFromDBObject(m_cache, hvoFs, false);
                        }
                        else
                        {
                            return;                             // leave it null.
                        }
                    }
                    // clean out any extant features in the feature structure
                    foreach (IFsFeatureSpecification spec in m_fs.FeatureSpecsOC)
                    {
                        m_fs.FeatureSpecsOC.Remove(spec);
                    }
                    UpdateFeatureStructure(m_tvMsaFeatureList.Nodes);
                    // The (usually) newly created one may be a duplicate. If we find a duplicate
                    // delete the one we just made (or were passed) and return the duplicate.
                    int chvo = m_cache.GetVectorSize(m_hvoOwner, m_owningFlid);
                    for (int ihvo = 0; ihvo < chvo; ihvo++)
                    {
                        int hvo = m_cache.GetVectorItem(m_hvoOwner, m_owningFlid, ihvo);
                        if (hvo == m_fs.Hvo)
                        {
                            continue;
                        }
                        IFsFeatStruc fs = CmObject.CreateFromDBObject(m_cache, hvo) as IFsFeatStruc;
                        if (FsFeatStruc.AreEquivalent(fs, m_fs))
                        {
                            m_fs.DeleteUnderlyingObject();
                            m_fs = fs;
                            break;
                        }
                    }
                }
            }

            if (m_mediator != null)
            {
                m_mediator.PropertyTable.SetProperty("msaInflFeatListDlgLocation", Location);
                m_mediator.PropertyTable.SetProperty("msaInflFeatListDlgSize", Size);
            }
        }
        /// <summary>
        /// Execute the change requested by the current selection in the combo.
        /// Basically we want a copy of the FsFeatStruc indicated by m_selectedHvo, (even if 0?? not yet possible),
        /// to become the MsFeatures of each record that is appropriate to change.
        /// We do nothing to records where the check box is turned off,
        /// and nothing to ones that currently have an MSA other than an MoStemMsa,
        /// and nothing to ones that currently have an MSA with the wrong POS.
        /// (a) If the owning entry has an MoStemMsa with a matching MsFeatures (and presumably POS),
        /// set the sense to use it.
        /// (b) If all senses using the current MoStemMsa are to be changed, just update
        /// the MsFeatures of that MoStemMsa.
        /// We could add this...but very probably unused MSAs would have been taken over
        /// when setting the POS.
        /// --(c) If the entry has an MoStemMsa which is not being used at all, change it to
        /// --the required POS and inflection class and use it.
        /// (d) Make a new MoStemMsa in the LexEntry with the required POS and features
        /// and point the sense at it.
        /// </summary>
        public void DoIt(Set <int> itemsToChange, ProgressState state)
        {
            CheckDisposed();

            int hvoPos = GetPOS();
            // Make a Set of eligible parts of speech to use in filtering.
            Set <int> possiblePOS = GetPossiblePartsOfSpeech();
            // Make a Dictionary from HVO of entry to list of modified senses.
            Dictionary <int, Set <ILexSense> > sensesByEntry = new Dictionary <int, Set <ILexSense> >();
            int tagOwningEntry = m_cache.VwCacheDaAccessor.GetVirtualHandlerName("LexSense", "OwningEntry").Tag;
            int i = 0;
            // Report progress 50 times or every 100 items, whichever is more (but no more than once per item!)
            int interval = Math.Min(100, Math.Max(itemsToChange.Count / 50, 1));

            foreach (int hvoSense in itemsToChange)
            {
                i++;
                if (i % interval == 0)
                {
                    state.PercentDone = i * 20 / itemsToChange.Count;
                    state.Breath();
                }
                if (!IsItemEligible(m_cache.MainCacheAccessor, hvoSense, possiblePOS))
                {
                    continue;
                }
                ILexSense           ls  = (ILexSense)CmObject.CreateFromDBObject(m_cache, hvoSense, false);
                IMoMorphSynAnalysis msa = ls.MorphoSyntaxAnalysisRA;
                int hvoEntry            = m_cache.MainCacheAccessor.get_ObjectProp(ls.Hvo, tagOwningEntry);
                if (!sensesByEntry.ContainsKey(hvoEntry))
                {
                    sensesByEntry[hvoEntry] = new Set <ILexSense>();
                }
                sensesByEntry[hvoEntry].Add(ls);
            }
            //REVIEW: Should these really be the same Undo/Redo strings as for InflectionClassEditor.cs?
            m_cache.BeginUndoTask(FdoUiStrings.ksUndoBEInflClass, FdoUiStrings.ksRedoBEInflClass);
            BulkEditBar.ForceRefreshOnUndoRedo(Cache.MainCacheAccessor);
            i        = 0;
            interval = Math.Min(100, Math.Max(sensesByEntry.Count / 50, 1));
            IFsFeatStruc fsTarget = null;

            if (m_selectedHvo != 0)
            {
                fsTarget = FsFeatStruc.CreateFromDBObject(Cache, m_selectedHvo);
            }
            foreach (KeyValuePair <int, Set <ILexSense> > kvp in sensesByEntry)
            {
                i++;
                if (i % interval == 0)
                {
                    state.PercentDone = i * 80 / sensesByEntry.Count + 20;
                    state.Breath();
                }
                ILexEntry       entry          = (ILexEntry)CmObject.CreateFromDBObject(m_cache, kvp.Key, false);
                Set <ILexSense> sensesToChange = kvp.Value;
                IMoStemMsa      msmTarget      = null;
                foreach (IMoMorphSynAnalysis msa in entry.MorphoSyntaxAnalysesOC)
                {
                    IMoStemMsa msm = msa as IMoStemMsa;
                    if (msm != null && MsaMatchesTarget(msm, fsTarget))
                    {
                        // Can reuse this one!
                        msmTarget = msm;
                        break;
                    }
                }
                if (msmTarget == null)
                {
                    // See if we can reuse an existing MoStemMsa by changing it.
                    // This is possible if it is used only by senses in the list, or not used at all.
                    Set <ILexSense> otherSenses = new Set <ILexSense>();
                    Set <ILexSense> senses      = new Set <ILexSense>(entry.AllSenses.ToArray());
                    if (senses.Count != sensesToChange.Count)
                    {
                        foreach (ILexSense ls in senses)
                        {
                            if (!sensesToChange.Contains(ls))
                            {
                                otherSenses.Add(ls);
                            }
                        }
                    }
                    foreach (IMoMorphSynAnalysis msa in entry.MorphoSyntaxAnalysesOC)
                    {
                        IMoStemMsa msm = msa as IMoStemMsa;
                        if (msm == null)
                        {
                            continue;
                        }
                        bool fOk = true;
                        foreach (ILexSense ls in otherSenses)
                        {
                            if (ls.MorphoSyntaxAnalysisRA == msm)
                            {
                                fOk = false;
                                break;
                            }
                        }
                        if (fOk)
                        {
                            // Can reuse this one! Nothing we don't want to change uses it.
                            // Adjust its POS as well as its inflection feature, just to be sure.
                            // Ensure that we don't change the POS!  See LT-6835.
                            msmTarget = msm;
                            InitMsa(msmTarget, msm.PartOfSpeechRAHvo);
                            break;
                        }
                    }
                }
                if (msmTarget == null)
                {
                    // Nothing we can reuse...make a new one.
                    msmTarget = new MoStemMsa();
                    entry.MorphoSyntaxAnalysesOC.Add(msmTarget);
                    InitMsa(msmTarget, hvoPos);
                }
                // Finally! Make the senses we want to change use it.
                foreach (ILexSense ls in sensesToChange)
                {
                    ls.MorphoSyntaxAnalysisRA = msmTarget;
                }
            }
            m_cache.EndUndoTask();
        }