Exemplo n.º 1
0
        public override void DoIt(Set <int> itemsToChange, ProgressState state)
        {
            CheckDisposed();

            ISilDataAccess sda = m_cache.MainCacheAccessor;
            // Make a hashtable from HVO of entry to list of modified senses.
            Dictionary <int, List <int> > sensesByEntry = new Dictionary <int, List <int> >();
            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();
                }
                int hvoMsa = sda.get_ObjectProp(hvoSense, (int)LexSense.LexSenseTags.kflidMorphoSyntaxAnalysis);
                if (hvoMsa != 0 && m_cache.GetClassOfObject(hvoMsa) != MoStemMsa.kclsidMoStemMsa)
                {
                    continue;                     // can't fix this one, not a stem.
                }
                int        hvoEntry = sda.get_ObjectProp(hvoSense, tagOwningEntry);
                List <int> senses   = null;
                if (!sensesByEntry.TryGetValue(hvoEntry, out senses))
                {
                    senses = new List <int>();
                    sensesByEntry[hvoEntry] = senses;
                }
                senses.Add(hvoSense);
            }
            m_cache.BeginUndoTask(FdoUiStrings.ksUndoBulkEditPOS, FdoUiStrings.ksRedoBulkEditPOS);
            BulkEditBar.ForceRefreshOnUndoRedo(sda);
            i        = 0;
            interval = Math.Min(100, Math.Max(sensesByEntry.Count / 50, 1));
            foreach (KeyValuePair <int, List <int> > kvp in sensesByEntry)
            {
                i++;
                if (i % interval == 0)
                {
                    state.PercentDone = i * 80 / sensesByEntry.Count + 20;
                    state.Breath();
                }
                int        hvoEntry        = kvp.Key;
                List <int> sensesToChange  = kvp.Value;
                int        hvoMsmTarget    = 0;
                int        cmsa            = sda.get_VecSize(hvoEntry, (int)LexEntry.LexEntryTags.kflidMorphoSyntaxAnalyses);
                bool       fAssumeSurvives = true;           // true if we know all old MSAs will survive.
                for (int imsa = 0; imsa < cmsa; imsa++)
                {
                    int hvoMsa = sda.get_VecItem(hvoEntry, (int)LexEntry.LexEntryTags.kflidMorphoSyntaxAnalyses, imsa);
                    if (m_cache.GetClassOfObject(hvoMsa) == MoStemMsa.kclsidMoStemMsa &&
                        sda.get_ObjectProp(hvoMsa, (int)MoStemMsa.MoStemMsaTags.kflidPartOfSpeech) == m_selectedHvo)
                    {
                        // Can reuse this one!
                        hvoMsmTarget    = hvoMsa;
                        fAssumeSurvives = false;                         // old MSA may be redundant.
                        break;
                    }
                }
                if (hvoMsmTarget == 0)
                {
                    // 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.
                    List <int> otherSenses = new List <int>();
                    AddExcludedSenses(sda, hvoEntry, (int)LexEntry.LexEntryTags.kflidSenses, otherSenses, sensesToChange);
                    for (int imsa = 0; imsa < cmsa; imsa++)
                    {
                        int hvoMsa = sda.get_VecItem(hvoEntry, (int)LexEntry.LexEntryTags.kflidMorphoSyntaxAnalyses, imsa);
                        if (m_cache.GetClassOfObject(hvoMsa) != MoStemMsa.kclsidMoStemMsa)
                        {
                            continue;
                        }
                        bool fOk = true;
                        foreach (int hvoOtherSense in otherSenses)
                        {
                            if (sda.get_ObjectProp(hvoOtherSense, (int)LexSense.LexSenseTags.kflidMorphoSyntaxAnalysis) == hvoMsa)
                            {
                                fOk = false;                                 // we can't change it, one of the unchanged senses uses it
                                break;
                            }
                        }
                        if (fOk)
                        {
                            // Can reuse this one! Nothing we don't want to change uses it. Go ahead and set it to the
                            // required POS.
                            hvoMsmTarget = hvoMsa;
                            int hvoOld = sda.get_ObjectProp(hvoMsmTarget, (int)MoStemMsa.MoStemMsaTags.kflidPartOfSpeech);
                            sda.SetObjProp(hvoMsmTarget, (int)MoStemMsa.MoStemMsaTags.kflidPartOfSpeech, m_selectedHvo);
                            sda.PropChanged(null, (int)PropChangeType.kpctNotifyAll,
                                            hvoMsmTarget, (int)MoStemMsa.MoStemMsaTags.kflidPartOfSpeech,
                                            0, 1, hvoOld == 0 ? 1 : 0);
                            // compare MoStemMsa.ResetInflectionClass: changing POS requires us to clear inflection class,
                            // if it is set.
                            if (hvoOld != 0 && sda.get_ObjectProp(hvoMsmTarget, (int)MoStemMsa.MoStemMsaTags.kflidInflectionClass) != 0)
                            {
                                sda.SetObjProp(hvoMsmTarget, (int)MoStemMsa.MoStemMsaTags.kflidInflectionClass, 0);
                                sda.PropChanged(null, (int)PropChangeType.kpctNotifyAll,
                                                hvoMsmTarget, (int)MoStemMsa.MoStemMsaTags.kflidInflectionClass,
                                                0, 0, 1);
                            }
                            break;
                        }
                    }
                }
                if (hvoMsmTarget == 0)
                {
                    // Nothing we can reuse...make a new one.
                    hvoMsmTarget = sda.MakeNewObject((int)MoStemMsa.kclsidMoStemMsa, hvoEntry, (int)LexEntry.LexEntryTags.kflidMorphoSyntaxAnalyses, -1);
                    sda.SetObjProp(hvoMsmTarget, (int)MoStemMsa.MoStemMsaTags.kflidPartOfSpeech, m_selectedHvo);
                    sda.PropChanged(null, (int)PropChangeType.kpctNotifyAll,
                                    hvoMsmTarget, (int)MoStemMsa.MoStemMsaTags.kflidInflectionClass,
                                    m_cache.GetObjIndex(hvoEntry,
                                                        (int)LexEntry.LexEntryTags.kflidMorphoSyntaxAnalyses, hvoMsmTarget),
                                    1, 0);
                }
                // Finally! Make the senses we want to change use it.
                foreach (int hvoSense in sensesToChange)
                {
                    int hvoOld = sda.get_ObjectProp(hvoSense, (int)LexSense.LexSenseTags.kflidMorphoSyntaxAnalysis);
                    if (hvoOld == hvoMsmTarget)
                    {
                        continue;                         // reusing a modified msa.
                    }
                    LexSense.HandleOldMSA(m_cache, hvoSense, hvoMsmTarget, fAssumeSurvives);
                    sda.SetObjProp(hvoSense, (int)LexSense.LexSenseTags.kflidMorphoSyntaxAnalysis, hvoMsmTarget);
                    sda.PropChanged(null, (int)PropChangeType.kpctNotifyAll,
                                    hvoSense, (int)LexSense.LexSenseTags.kflidMorphoSyntaxAnalysis,
                                    0, 1, hvoOld == 0 ? 1 : 0);
                }
            }
            m_cache.EndUndoTask();
        }