public virtual void FakeDoit(Set<int> itemsToChange, int tagFakeFlid, int tagEnabled, ProgressState state) { ISilDataAccess sda = m_cache.MainCacheAccessor; int[] chosenHvos = m_chosenHvos; 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)); ITsString tssChosenVal = BuildValueString(chosenHvos); IVwCacheDa cda = m_cache.VwCacheDaAccessor; foreach (int hvoItem in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count; state.Breath(); } ITsString tssVal = tssChosenVal; int[] oldVals; int[] newVal; bool fEnable = false; if (!DisableItem(hvoItem)) { ComputeValue(chosenHvos, hvoItem, out oldVals, out newVal); fEnable = !EqualIntArrays(oldVals, newVal); if (fEnable) { if (newVal != chosenHvos) tssVal = BuildValueString(newVal); cda.CacheStringProp(hvoItem, tagFakeFlid, tssVal); } } cda.CacheIntProp(hvoItem, tagEnabled, (fEnable ? 1 : 0)); } }
public override void FakeDoit(IEnumerable<int> itemsToChange, int tagFakeFlid, int tagEnabled, ProgressState state) { ISilDataAccess sda = m_cache.DomainDataByFlid; HvoTssComboItem item = m_combo.SelectedItem as HvoTssComboItem; if (item == null) return; int hvoSelMorphType = item.Hvo; // 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)); int i = 0; foreach (int hvoLexEntry in itemsToChange) { if ((i + 1) % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count(); state.Breath(); } int hvoLexemeForm = sda.get_ObjectProp(hvoLexEntry, m_flidParent); if (hvoLexemeForm == 0) continue; int hvoMorphType = sda.get_ObjectProp(hvoLexemeForm, m_flidAtomicProp); if (hvoMorphType == 0) continue; bool fAffix = MorphServices.IsAffixType(m_cache, hvoMorphType); // Per LT-5305, OK to switch types. //bool fEnable = fAffix == fSelAffix && hvoMorphType != hvoSelMorphType; bool fEnable = hvoMorphType != hvoSelMorphType; if (fEnable) m_sda.SetString(hvoLexEntry, tagFakeFlid, item.AsTss); m_sda.SetInt(hvoLexEntry, tagEnabled, (fEnable ? 1 : 0)); i++; } }
public void FakeDoit(Set<int> itemsToChange, int tagFakeFlid, int tagEnable, ProgressState state) { CheckDisposed(); IVwCacheDa cda = m_cache.VwCacheDaAccessor; ISilDataAccess sda = m_cache.MainCacheAccessor; ITsString tss = m_cache.MakeAnalysisTss(m_selectedLabel); 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 hvo in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count; state.Breath(); } bool fEnable = CanFakeIt(hvo); if (fEnable) cda.CacheStringProp(hvo, tagFakeFlid, tss); cda.CacheIntProp(hvo, tagEnable, (fEnable ? 1 : 0)); } }
public virtual void DoIt(IEnumerable<int> itemsToChange, ProgressState state) { UndoableUnitOfWorkHelper.Do(XMLViewsStrings.ksUndoBulkEdit, XMLViewsStrings.ksRedoBulkEdit, m_cache.ServiceLocator.GetInstance<IActionHandler>(), () => { //ISilDataAccess sda = m_cache.DomainDataByFlid; // used DataAccess, is that okay? var chosenObjs = m_chosenObjs; 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 hvoItem in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count(); state.Breath(); } if (DisableItem(hvoItem)) continue; List<ICmObject> oldVals, newVal; ComputeValue(chosenObjs, hvoItem, out oldVals, out newVal); if (oldVals.SequenceEqual(newVal)) continue; var newHvos = (from obj in newVal select obj.Hvo).ToArray(); var realTarget = hvoItem; if (m_ghostParentHelper != null) { realTarget = m_ghostParentHelper.FindOrCreateOwnerOfTargetProp(hvoItem, m_flid); } if (Atomic) { var newHvo = newHvos.Length > 0 ? newHvos[0] : 0; DataAccess.SetObjProp(realTarget, m_flid, newHvo); } else { DataAccess.Replace(realTarget, m_flid, 0, oldVals.Count, newHvos, newHvos.Length); } } }); }
/// <summary> /// Tells SemanticDomainChooserBEditControl to make suggestions and then call FakeDoIt /// </summary> public override void MakeSuggestions(IEnumerable<int> itemsToChange, int tagFakeFlid, int tagEnabled, ProgressState state) { m_doingSuggest = true; ChosenObjects = new List<ICmObject>(0); // Unfortunately ProgressState is from FwControls which depends on FDO, so passing it as a parameter // to the searchCache's InitializeCache method would result in a circular dependency. state.PercentDone = 15; state.Breath(); // give the user a LITTLE hope that things are happening! // Should be the only time we need to loop through all the Semantic Domains m_searchCache.InitializeCache(); m_suggestionCache = new Dictionary<int, List<ICmObject>>(); base.FakeDoit(itemsToChange, tagFakeFlid, tagEnabled, state); if (SomeChangesAreWaiting(itemsToChange, tagEnabled)) EnableButtonsIfChangesWaiting(); }
public override void FakeDoit(IEnumerable<int> itemsToChange, int tagFakeFlid, int tagEnabled, ProgressState state) { int val = (m_combo.SelectedItem as IntComboItem).Value; ITsString tssVal = TsStringUtils.MakeTss(m_combo.SelectedItem.ToString(), m_cache.DefaultUserWs); 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)); if (m_flidSub == LexEntryRefTags.kflidHideMinorEntry) { // we present this to the user as "Show" instead of "Hide" if (val == 0) val = 1; else val = 0; foreach (int hvoItem in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count(); state.Breath(); } Debug.Assert(m_sda.get_IntProp(hvoItem, CmObjectTags.kflidClass) == LexEntryRefTags.kClassId); int valOld = m_sda.get_IntProp(hvoItem, m_flidSub); bool fEnable = valOld != val; if (fEnable) m_sda.SetString(hvoItem, tagFakeFlid, tssVal); m_sda.SetInt(hvoItem, tagEnabled, (fEnable ? 1 : 0)); } } else { foreach (int hvoItem in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count(); state.Breath(); } int hvoField = m_sda.get_ObjectProp(hvoItem, m_flid); if (hvoField == 0) continue; int valOld = GetValueOfField(m_sda, hvoField); bool fEnable = valOld != val; if (fEnable) m_sda.SetString(hvoItem, tagFakeFlid, tssVal); m_sda.SetInt(hvoItem, tagEnabled, (fEnable ? 1 : 0)); } } }
public virtual void DoIt(IEnumerable<int> itemsToChange, ProgressState state) { UndoableUnitOfWorkHelper.Do(XMLViewsStrings.ksUndoBulkEdit, XMLViewsStrings.ksRedoBulkEdit, m_cache.ActionHandlerAccessor, () => { ISilDataAccess sda = m_cache.DomainDataByFlid; HvoTssComboItem item = m_combo.SelectedItem as HvoTssComboItem; if (item == null) return; int hvoSel = item.Hvo; var mdcManaged = m_cache.ServiceLocator.GetInstance<IFwMetaDataCacheManaged>(); 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 hvoItem in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count(); state.Breath(); } // If the field is on an owned object that might not exist, the hvoItem might // refer to the owner, which is likely of a different class. In such cases, // we don't want to try getting the field value, since that produces a pretty // green dialog box for the user. See FWR-3199. int clid = m_sda.get_IntProp(hvoItem, CmObjectTags.kflidClass); var flids = mdcManaged.GetFields(clid, true, (int)CellarPropertyTypeFilter.All); if (!flids.Contains(m_flidAtomicProp)) continue; int hvoOld = GetOriginalListValue(sda, hvoItem); if (hvoOld == hvoSel) continue; UpdateListItemToNewValue(sda, hvoItem, hvoSel, hvoOld); } }); }
/// <summary> /// Execute the change requested by the current selection in the combo. /// Basically we want the MoInflClass indicated by m_selectedHvo, (even if 0?? not yet possible), /// to become the InflectionClass 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 the right inflection class (and presumably POS), /// set the sense to use it. /// (b) If all senses using the current MoStemMsa are to be changed, just update /// the inflection class 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 inflection class /// and point the sense at it. /// </summary> public void DoIt(IEnumerable<int> itemsToChange, ProgressState state) { CheckDisposed(); var pos = GetPOS(); // 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. var sensesByEntryAndPos = new Dictionary<Tuple<ILexEntry, IPartOfSpeech>, List<ILexSense>>(); 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.DomainDataByFlid, hvoSense, possiblePOS)) continue; var ls = m_cache.ServiceLocator.GetInstance<ILexSenseRepository>().GetObject(hvoSense); var msa = (IMoStemMsa)ls.MorphoSyntaxAnalysisRA; var entry1 = ls.Entry; var key = new Tuple<ILexEntry, IPartOfSpeech>(entry1, msa.PartOfSpeechRA); if (!sensesByEntryAndPos.ContainsKey(key)) sensesByEntryAndPos[key] = new List<ILexSense>(); sensesByEntryAndPos[key].Add(ls); } m_cache.DomainDataByFlid.BeginUndoTask(FdoUiStrings.ksUndoBEInflClass, FdoUiStrings.ksRedoBEInflClass); i = 0; interval = Math.Min(100, Math.Max(sensesByEntryAndPos.Count / 50, 1)); foreach (var kvp in sensesByEntryAndPos) { i++; if (i % interval == 0) { state.PercentDone = i * 80 / sensesByEntryAndPos.Count + 20; state.Breath(); } var entry = kvp.Key.Item1; var sensesToChange = kvp.Value; IMoStemMsa msmTarget = null; foreach (var msa in entry.MorphoSyntaxAnalysesOC) { var msm = msa as IMoStemMsa; if (msm != null && msm.InflectionClassRA != null && msm.InflectionClassRA.Hvo == m_selectedHvo) { // 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. var otherSenses = new List<ILexSense>(); if (entry.SensesOS.Count != sensesToChange.Count) { foreach (var ls in entry.SensesOS) if (!sensesToChange.Contains(ls)) otherSenses.Add(ls); } foreach (var msa in entry.MorphoSyntaxAnalysesOC) { var msm = msa as IMoStemMsa; if (msm == null) continue; bool fOk = true; foreach (var 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 class, just to be sure. msmTarget = msm; msmTarget.PartOfSpeechRA = kvp.Key.Item2; msmTarget.InflectionClassRA = m_cache.ServiceLocator.GetInstance<IMoInflClassRepository>().GetObject(m_selectedHvo); break; } } } if (msmTarget == null) { // Nothing we can reuse...make a new one. msmTarget = m_cache.ServiceLocator.GetInstance<IMoStemMsaFactory>().Create(); entry.MorphoSyntaxAnalysesOC.Add(msmTarget); msmTarget.PartOfSpeechRA = kvp.Key.Item2; msmTarget.InflectionClassRA = m_cache.ServiceLocator.GetInstance<IMoInflClassRepository>().GetObject(m_selectedHvo); } // Finally! Make the senses we want to change use it. foreach (var ls in sensesToChange) { ls.MorphoSyntaxAnalysisRA = msmTarget; } } m_cache.DomainDataByFlid.EndUndoTask(); }
/// <summary> /// Fake doing the change by setting the specified property to the appropriate value /// for each item in the list. Disable items that can't be set. /// </summary> /// <param name="itemsToChange"></param> /// <param name="ktagFakeFlid"></param> public void FakeDoit(IEnumerable<int> itemsToChange, int tagFakeFlid, int tagEnable, ProgressState state) { CheckDisposed(); ITsString tss = TsStringUtils.MakeTss(m_selectedLabel, m_cache.DefaultAnalWs); // Build a Set of parts of speech that can take this class. Set<int> possiblePOS = GetPossiblePartsOfSpeech(); 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 hvo in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count(); state.Breath(); } bool fEnable = IsItemEligible(m_sda, hvo, possiblePOS); if (fEnable) m_sda.SetString(hvo, tagFakeFlid, tss); m_sda.SetInt(hvo, tagEnable, (fEnable ? 1 : 0)); } }
public override void DoIt(IEnumerable<int> itemsToChange, ProgressState state) { CheckDisposed(); var senseRepo = m_cache.ServiceLocator.GetInstance<ILexSenseRepository>(); // FWR-2781 should be able to bulk edit entries to POS <Not sure>. IPartOfSpeech posWanted = null; if (m_selectedHvo > 0) posWanted = (IPartOfSpeech) m_cache.ServiceLocator.GetObject(m_selectedHvo); // Make a hashtable from entry to list of modified senses. var sensesByEntry = new Dictionary<ILexEntry, List<ILexSense>>(); 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(); } var sense = senseRepo.GetObject(hvoSense); var msa = sense.MorphoSyntaxAnalysisRA; if (msa != null && msa.ClassID != MoStemMsaTags.kClassId) continue; // can't fix this one, not a stem. var entry = sense.OwnerOfClass(LexEntryTags.kClassId) as ILexEntry; List<ILexSense> senses; if (!sensesByEntry.TryGetValue(entry, out senses)) { senses = new List<ILexSense>(); sensesByEntry[entry] = senses; } senses.Add(sense); } UndoableUnitOfWorkHelper.Do(FdoUiStrings.ksUndoBulkEditPOS, FdoUiStrings.ksRedoBulkEditPOS, m_cache.ActionHandlerAccessor, ()=>DoUpdatePos(state, sensesByEntry, posWanted)); }
private void DoUpdatePos(ProgressState state, Dictionary<ILexEntry, List<ILexSense>> sensesByEntry, IPartOfSpeech posWanted) { int i; int interval; i = 0; interval = Math.Min(100, Math.Max(sensesByEntry.Count / 50, 1)); foreach (var kvp in sensesByEntry) { i++; if (i % interval == 0) { state.PercentDone = i * 80 / sensesByEntry.Count + 20; state.Breath(); } var entry = kvp.Key; var sensesToChange = kvp.Value; // Try to find an existing MSA with the right POS. var msmTarget = (from msa in entry.MorphoSyntaxAnalysesOC where msa.ClassID == (uint) MoStemMsaTags.kClassId && ((IMoStemMsa)msa).PartOfSpeechRA == posWanted select (IMoStemMsa) msa).FirstOrDefault(); if (msmTarget == null) { // No existing MSA has the desired POS. // 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. var otherSenses = new List<ILexSense>(); AddExcludedSenses(entry, otherSenses, sensesToChange); // Get all the unchanged senses of the entry. foreach (var msa in entry.MorphoSyntaxAnalysesOC) { if (msa.ClassID != MoStemMsaTags.kClassId) continue; bool fOk = true; foreach (var otherSense in otherSenses) { if (otherSense.MorphoSyntaxAnalysisRA == msa) { 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. msmTarget = (IMoStemMsa)msa; var oldPOS = msmTarget.PartOfSpeechRA; msmTarget.PartOfSpeechRA = posWanted; // compare MoStemMsa.ResetInflectionClass: changing POS requires us to clear inflection class, // if it is set. if (oldPOS != null && msmTarget.InflectionClassRA != null) msmTarget.InflectionClassRA = null; break; } } } if (msmTarget == null) { // Nothing we can reuse...make a new one. msmTarget = m_cache.ServiceLocator.GetInstance<IMoStemMsaFactory>().Create(); entry.MorphoSyntaxAnalysesOC.Add(msmTarget); msmTarget.PartOfSpeechRA = posWanted; } // Finally! Make the senses we want to change use it. foreach (var sense in sensesToChange) { if (sense.MorphoSyntaxAnalysisRA == msmTarget) continue; // reusing a modified msa. sense.MorphoSyntaxAnalysisRA = msmTarget; } } }
public void FakeDoit(IEnumerable<int> itemsToChange, int tagFakeFlid, int tagEnable, ProgressState state) { CheckDisposed(); ITsString tss = TsStringUtils.MakeTss(m_selectedLabel, m_cache.DefaultAnalWs); 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 hvo in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count(); state.Breath(); } bool fEnable = CanFakeIt(hvo); if (fEnable) m_sda.SetString(hvo, tagFakeFlid, tss); m_sda.SetInt(hvo, tagEnable, (fEnable ? 1 : 0)); } }
/// <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(IEnumerable<int> itemsToChange, ProgressState state) { CheckDisposed(); var pos = 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. var sensesByEntry = new Dictionary<int, Set<ILexSense>>(); 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.DomainDataByFlid, hvoSense, possiblePOS)) continue; var ls = m_cache.ServiceLocator.GetInstance<ILexSenseRepository>().GetObject(hvoSense); var msa = ls.MorphoSyntaxAnalysisRA; int hvoEntry = ls.EntryID; 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.DomainDataByFlid.BeginUndoTask(FdoUiStrings.ksUndoBEInflClass, FdoUiStrings.ksRedoBEInflClass); i = 0; interval = Math.Min(100, Math.Max(sensesByEntry.Count / 50, 1)); IFsFeatStruc fsTarget = null; if (m_selectedHvo != 0) fsTarget = Cache.ServiceLocator.GetInstance<IFsFeatStrucRepository>().GetObject(m_selectedHvo); foreach (var kvp in sensesByEntry) { i++; if (i % interval == 0) { state.PercentDone = i * 80 / sensesByEntry.Count + 20; state.Breath(); } var entry = m_cache.ServiceLocator.GetInstance<ILexEntryRepository>().GetObject(kvp.Key); var sensesToChange = kvp.Value; IMoStemMsa msmTarget = null; foreach (var msa in entry.MorphoSyntaxAnalysesOC) { var 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. var otherSenses = new Set<ILexSense>(); var senses = new Set<ILexSense>(entry.AllSenses.ToArray()); if (senses.Count != sensesToChange.Count) { foreach (var ls in senses) { if (!sensesToChange.Contains(ls)) otherSenses.Add(ls); } } foreach (var msa in entry.MorphoSyntaxAnalysesOC) { var msm = msa as IMoStemMsa; if (msm == null) continue; bool fOk = true; foreach (var 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.PartOfSpeechRA.Hvo); break; } } } if (msmTarget == null) { // Nothing we can reuse...make a new one. msmTarget = m_cache.ServiceLocator.GetInstance<IMoStemMsaFactory>().Create(); entry.MorphoSyntaxAnalysesOC.Add(msmTarget); InitMsa(msmTarget, pos.Hvo); } // Finally! Make the senses we want to change use it. foreach (var ls in sensesToChange) { ls.MorphoSyntaxAnalysisRA = msmTarget; } } m_cache.DomainDataByFlid.EndUndoTask(); }
public override void DoIt(Set<int> itemsToChange, ProgressState state) { m_cache.BeginUndoTask(XMLViewsStrings.ksUndoBulkEdit, XMLViewsStrings.ksRedoBulkEdit); ISilDataAccess sda = m_cache.MainCacheAccessor; BulkEditBar.ForceRefreshOnUndoRedo(sda); HvoTssComboItem item = m_combo.SelectedItem as HvoTssComboItem; if (item == null) return; int hvoSelMorphType = item.Hvo; bool fSelAffix = MoMorphType.IsAffixType(m_cache, hvoSelMorphType); bool fAnyFundamentalChanges = false; // Preliminary check and warning if changing fundamental type. foreach (int hvoLexEntry in itemsToChange) { int hvoLexemeForm = sda.get_ObjectProp(hvoLexEntry, m_flidParent); if (hvoLexemeForm == 0) continue; int hvoMorphType = sda.get_ObjectProp(hvoLexemeForm, m_flidAtomicProp); if (hvoMorphType == 0) continue; bool fAffix = MoMorphType.IsAffixType(m_cache, hvoMorphType); if (fAffix != fSelAffix) { string msg = String.Format(XMLViewsStrings.ksMorphTypeChangesSlow, (fAffix ? XMLViewsStrings.ksAffixes : XMLViewsStrings.ksStems), (fAffix ? XMLViewsStrings.ksStems : XMLViewsStrings.ksAffixes)); if (MessageBox.Show(this.m_combo, msg, XMLViewsStrings.ksChangingMorphType, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK) { return; } fAnyFundamentalChanges = true; break; // user OKd it, no need to check further. } } if (fAnyFundamentalChanges) { m_containingViewer.SetListModificationInProgress(true); } try { // Report progress 50 times or every 100 items, whichever is more // (but no more than once per item!) Set<int> idsToDel = new Set<int>(); Dictionary<IMoForm, ILexEntry> newForms = new Dictionary<IMoForm, ILexEntry>(); int interval = Math.Min(80, Math.Max(itemsToChange.Count / 50, 1)); int i = 0; foreach (int hvoLexEntry in itemsToChange) { // Guess we're 80% done when through all but deleting leftover objects and moving // new MoForms to LexemeForm slot. if ((i + 1) % interval == 0) { state.PercentDone = i * 80 / itemsToChange.Count; state.Breath(); i++; } int hvoLexemeForm = sda.get_ObjectProp(hvoLexEntry, m_flidParent); if (hvoLexemeForm == 0) continue; int hvoMorphType = sda.get_ObjectProp(hvoLexemeForm, m_flidAtomicProp); if (hvoMorphType == 0) continue; bool fAffix = MoMorphType.IsAffixType(m_cache, hvoMorphType); if (fAffix == fSelAffix) { if (hvoMorphType != hvoSelMorphType) { sda.SetObjProp(hvoLexemeForm, m_flidAtomicProp, hvoSelMorphType); sda.PropChanged(null, (int)PropChangeType.kpctNotifyAll, hvoLexemeForm, m_flidAtomicProp, 0, (hvoSelMorphType == 0 ? 0 : 1), (hvoMorphType == 0 ? 0 : 1)); } else if (fAffix) { ILexEntry entry = LexEntry.CreateFromDBObject(m_cache, hvoLexEntry); IMoAffixAllomorph affix = MoAffixAllomorph.CreateFromDBObject(m_cache, hvoLexemeForm); MoStemAllomorph stem = new MoStemAllomorph(); int[] envs = affix.PhoneEnvRC.HvoArray; SwapFormValues(entry, affix, stem, hvoSelMorphType, idsToDel); foreach (int hvo in envs) stem.PhoneEnvRC.Add(hvo); newForms[stem] = entry; //entry.ChangeAffixToStem(hvoSelMorphType, affix); } else { ILexEntry entry = LexEntry.CreateFromDBObject(m_cache, hvoLexEntry); IMoStemAllomorph stem = MoStemAllomorph.CreateFromDBObject(m_cache, hvoLexemeForm); MoAffixAllomorph affix = new MoAffixAllomorph(); int[] envs = stem.PhoneEnvRC.HvoArray; SwapFormValues(entry, stem, affix, hvoSelMorphType, idsToDel); foreach (int hvo in envs) affix.PhoneEnvRC.Add(hvo); newForms[affix] = entry; //entry.ChangeStemToAffix(hvoSelMorphType, stem); } } else if (fAffix) { ILexEntry entry = LexEntry.CreateFromDBObject(m_cache, hvoLexEntry); IMoAffixAllomorph affix = MoAffixAllomorph.CreateFromDBObject(m_cache, hvoLexemeForm); MoStemAllomorph stem = new MoStemAllomorph(); int[] envs = affix.PhoneEnvRC.HvoArray; SwapFormValues(entry, affix, stem, hvoSelMorphType, idsToDel); foreach (int hvo in envs) stem.PhoneEnvRC.Add(hvo); newForms[stem] = entry; //entry.ChangeAffixToStem(hvoSelMorphType, affix); } else if (fAffix) { ILexEntry entry = LexEntry.CreateFromDBObject(m_cache, hvoLexEntry); IMoAffixAllomorph affix = MoAffixAllomorph.CreateFromDBObject(m_cache, hvoLexemeForm); IMoForm stem = new MoStemAllomorph(); int[] envs = affix.PhoneEnvRC.HvoArray; SwapFormValues(entry, affix, stem, hvoSelMorphType, idsToDel); (stem as IMoStemAllomorph).PhoneEnvRC.Add(envs); newForms[stem] = entry; //entry.ChangeAffixToStem(hvoSelMorphType, affix); } else { ILexEntry entry = LexEntry.CreateFromDBObject(m_cache, hvoLexEntry); IMoStemAllomorph stem = MoStemAllomorph.CreateFromDBObject(m_cache, hvoLexemeForm); IMoForm affix = new MoAffixAllomorph(); int[] envs = stem.PhoneEnvRC.HvoArray; SwapFormValues(entry, stem, affix, hvoSelMorphType, idsToDel); (affix as MoAffixAllomorph).PhoneEnvRC.Add(envs); newForms[affix] = entry; //entry.ChangeStemToAffix(hvoSelMorphType, stem); } } if (fAnyFundamentalChanges) { CmObject.DeleteObjects(idsToDel, m_cache); // Get rid of all the old lexeme forms in one go. state.PercentDone = 90; state.Breath(); foreach (KeyValuePair<IMoForm, ILexEntry> pair in newForms) { pair.Value.LexemeFormOA = pair.Key; } state.PercentDone = 100; state.Breath(); } m_cache.EndUndoTask(); } finally { if (fAnyFundamentalChanges) m_containingViewer.SetListModificationInProgress(false); } }
public override void DoIt(IEnumerable<int> itemsToChange, ProgressState state) { m_cache.DomainDataByFlid.BeginUndoTask(XMLViewsStrings.ksUndoBulkEdit, XMLViewsStrings.ksRedoBulkEdit); ISilDataAccess sda = m_cache.DomainDataByFlid; m_replacedObjects.Clear(); int val = (m_combo.SelectedItem as IntComboItem).Value; 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)); var mdcManaged = m_cache.ServiceLocator.GetInstance<IFwMetaDataCacheManaged>(); foreach (int hvoItem in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count(); state.Breath(); } // If the field is on an owned object that might not exist, we don't want to create // that owned object just because we're changing the values involved. // (See FWR-3199 for an example of such a situation.) int clid = m_sda.get_IntProp(hvoItem, CmObjectTags.kflidClass); var flids = mdcManaged.GetFields(clid, true, (int)CellarPropertyTypeFilter.All); if (!flids.Contains(m_flid)) continue; int valOld; if (TryGetOriginalListValue(sda, hvoItem, out valOld) && valOld == val) continue; UpdateListItemToNewValue(sda, hvoItem, val, valOld); } // Enhance JohnT: maybe eventually we will want to make a more general mechanism for doing this, // e.g., specify a method to call using the XML configuration for the column? // Note that resetting them all at the end of the edit is much more efficient than // adding an override for each word, which rewrites the exceptions file each time. // (This code runs before the code at the end of the UOW which also tries to update the spelling // status. That code will find it is already correct and not write the exc file.) if (m_flid == WfiWordformTags.kflidSpellingStatus) WfiWordformServices.ConformOneSpellingDictToWordforms(m_cache.DefaultVernWs, m_cache); m_cache.DomainDataByFlid.EndUndoTask(); }
/// <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(); }
public override void FakeDoit(IEnumerable<int> itemsToChange, int tagFakeFlid, int tagEnabled, ProgressState state) { int val = ((IntComboItem) m_combo.SelectedItem).Value; ITsString tssVal = m_cache.TsStrFactory.MakeString(m_combo.SelectedItem.ToString(), m_cache.ServiceLocator.WritingSystemManager.UserWs); 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)); var mdcManaged = m_cache.ServiceLocator.GetInstance<IFwMetaDataCacheManaged>(); int type = m_sda.MetaDataCache.GetFieldType(m_flid); foreach (int hvoItem in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count(); state.Breath(); } bool fEnable; // If the field is on an owned object that might not exist, the hvoItem might // refer to the owner, which is likely of a different class. In such cases, // we don't want to try getting the field value, since that produces a pretty // green dialog box for the user. See FWR-3199. int clid = m_sda.get_IntProp(hvoItem, CmObjectTags.kflidClass); var flids = mdcManaged.GetFields(clid, true, (int)CellarPropertyTypeFilter.All); if (!flids.Contains(m_flid)) fEnable = false; else if (type == (int)CellarPropertyType.Boolean) fEnable = m_sda.get_BooleanProp(hvoItem, m_flid) != (val != 0); else fEnable = m_sda.get_IntProp(hvoItem, m_flid) != val; if (fEnable) m_sda.SetString(hvoItem, tagFakeFlid, tssVal); m_sda.SetInt(hvoItem, tagEnabled, (fEnable ? 1 : 0)); } }
/// <summary> /// Execute the change requested by the current selection in the combo. /// Basically we want the PartOfSpeech indicated by m_selectedHvo, even if 0, /// to become the POS 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 IMoStemMsa. /// (a) If the owning entry has an IMoStemMsa with the /// right POS, set the sense to use it. /// (b) If the sense already refers to an IMoStemMsa, and any other senses /// of that entry which point at it are also to be changed, change the POS /// of the MSA. /// (c) If the entry has an IMoStemMsa which is not used at all, change it to the /// required POS and use it. /// (d) Make a new IMoStemMsa in the ILexEntry with the required POS and point the sense at it. /// </summary> public override void DoIt(IEnumerable<int> itemsToChange, ProgressState state) { CheckDisposed(); m_cache.DomainDataByFlid.BeginUndoTask(LexEdStrings.ksUndoBulkEditRevPOS, LexEdStrings.ksRedoBulkEditRevPOS); int i = 0; int interval = Math.Min(100, Math.Max(itemsToChange.Count() / 50, 1)); foreach (int entryId in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 80 / itemsToChange.Count() + 20; state.Breath(); } IReversalIndexEntry entry = m_cache.ServiceLocator.GetInstance<IReversalIndexEntryRepository>().GetObject(entryId); if (m_selectedHvo == 0) entry.PartOfSpeechRA = null; else entry.PartOfSpeechRA = m_cache.ServiceLocator.GetInstance<IPartOfSpeechRepository>().GetObject(m_selectedHvo); } m_cache.DomainDataByFlid.EndUndoTask(); }
public override void DoIt(IEnumerable<int> itemsToChange, ProgressState state) { m_cache.DomainDataByFlid.BeginUndoTask(XMLViewsStrings.ksUndoBulkEdit, XMLViewsStrings.ksRedoBulkEdit); ISilDataAccess sda = m_cache.DomainDataByFlid; int val = (m_combo.SelectedItem as IntComboItem).Value; 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)); if (m_flidSub == LexEntryRefTags.kflidHideMinorEntry) { // we present this to the user as "Show" instead of "Hide" if (val == 0) val = 1; else val = 0; foreach (int hvoItem in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count(); state.Breath(); } Debug.Assert(m_sda.get_IntProp(hvoItem, CmObjectTags.kflidClass) == LexEntryRefTags.kClassId); int valOld = m_sda.get_IntProp(hvoItem, m_flidSub); if (valOld != val) sda.SetInt(hvoItem, m_flidSub, val); } } else { foreach (int hvoItem in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count(); state.Breath(); } int hvoField = sda.get_ObjectProp(hvoItem, m_flid); if (hvoField == 0) continue; int valOld = GetValueOfField(sda, hvoField); if (valOld == val) continue; SetValueOfField(sda, hvoField, val); } } m_cache.DomainDataByFlid.EndUndoTask(); }
/// <summary> /// Execute the change requested by the current selection in the combo. /// There are two main cases: /// 1. The user is removing a feature. /// 2. The user is using priority union to include the values of a feature structure. /// The latter has two subcases: /// a. The user has selected a value for the targeted feature and we have put that value in a FsFeatStruc. /// b. The user has employed the chooser to build a FsFeatStruc with the value(s) to change. These values /// may or may not be for the targeted feature. /// We do nothing to (phoneme) records where the check box is turned off. /// For phonemes with the check box on, we either /// 1. remove the specified feature from the phoneme or /// 2. use priority union to set the value(s) in the FsFeatStruc. /// </summary> public void DoIt(IEnumerable<int> itemsToChange, ProgressState state) { CheckDisposed(); string labelToShow = SelectedLabel; var selectedObject = m_cache.ServiceLocator.GetInstance<ICmObjectRepository>().GetObject(SelectedHvo); 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)); m_cache.DomainDataByFlid.BeginUndoTask(FdoUiStrings.ksUndoBEPhonemeFeatures, FdoUiStrings.ksRedoBEPhonemeFeatures); if (SelectedHvo != 0) { IFsFeatStruc fsTarget = GetTargetFsFeatStruc(); foreach (var hvoPhoneme in itemsToChange) { i++; if (i%interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count() + 20; state.Breath(); } var phoneme = m_cache.ServiceLocator.GetInstance<IPhPhonemeRepository>().GetObject(hvoPhoneme); if (phoneme.FeaturesOA == null) phoneme.FeaturesOA = Cache.ServiceLocator.GetInstance<IFsFeatStrucFactory>().Create(); if (fsTarget == null && selectedObject is IFsClosedFeature) { // it's the remove option var closedValues = from s in phoneme.FeaturesOA.FeatureSpecsOC where s.FeatureRA == selectedObject select s; if (closedValues.Any()) phoneme.FeaturesOA.FeatureSpecsOC.Remove(closedValues.First()); } else { phoneme.FeaturesOA.PriorityUnion(fsTarget); } } } m_cache.DomainDataByFlid.EndUndoTask(); }
/// <summary> /// This is called when the preview button is clicked. The control is passed /// the list of currently active (filtered and checked) items. It should cache /// tagEnabled to zero for any objects that can't be /// modified. For ones that can, it should set the string property tagFakeFlid /// to the value to show in the 'modified' fields. /// </summary> /// <param name="itemsToChange">The items to change.</param> /// <param name="tagFakeFlid">The tag fake flid.</param> /// <param name="tagEnabled">The tag enabled.</param> /// <param name="state">The state.</param> /// ------------------------------------------------------------------------------------ /// ------------------------------------------------------------------------------------ public virtual void FakeDoit(IEnumerable<int> itemsToChange, int tagFakeFlid, int tagEnabled, ProgressState state) { ISilDataAccess sda = m_cache.DomainDataByFlid; HvoTssComboItem item = m_combo.SelectedItem as HvoTssComboItem; if (item == null) return; int hvoSel = item.Hvo; var mdcManaged = m_cache.ServiceLocator.GetInstance<IFwMetaDataCacheManaged>(); 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 hvoItem in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count(); state.Breath(); } bool fEnable; // If the field is on an owned object that might not exist, the hvoItem might // refer to the owner, which is likely of a different class. In such cases, // we don't want to try getting the field value, since that produces a pretty // green dialog box for the user. See FWR-3199. int clid = m_sda.get_IntProp(hvoItem, CmObjectTags.kflidClass); var flids = mdcManaged.GetFields(clid, true, (int)CellarPropertyTypeFilter.All); if (!flids.Contains(m_flidAtomicProp)) { fEnable = false; } else { int hvoOld = GetOriginalListValue(sda, hvoItem); fEnable = hvoOld != hvoSel; } if (fEnable) m_sda.SetString(hvoItem, tagFakeFlid, item.AsTss); m_sda.SetInt(hvoItem, tagEnabled, (fEnable ? 1 : 0)); } }
/// <summary> /// Fake doing the change by setting the specified property to the appropriate value /// for each item in the set. Disable items that can't be set. /// </summary> /// <param name="itemsToChange"></param> /// <param name="tagFakeFlid"></param> /// <param name="tagEnable"></param> /// <param name="state"></param> public void FakeDoit(IEnumerable<int> itemsToChange, int tagFakeFlid, int tagEnable, ProgressState state) { CheckDisposed(); string labelToShow = SelectedLabel; // selectedHvo refers to either a FsFeatStruc we've made or the targeted feature var selectedObject = m_cache.ServiceLocator.GetInstance<ICmObjectRepository>().GetObject(SelectedHvo); if (selectedObject is IFsFeatStruc) { labelToShow = GetLabelToShow(); // get the value for the targeted feature from the FsFeatStruc } else if (selectedObject is IFsClosedFeature) { labelToShow = " "; // it is the remove option so we just show nothing after the arrow } ITsString tss = TsStringUtils.MakeTss(labelToShow, m_cache.DefaultAnalWs); 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 hvo in itemsToChange) { i++; if (i%interval == 0) { state.PercentDone = i*100/itemsToChange.Count(); state.Breath(); } bool fEnable = IsItemEligible(m_sda, hvo, selectedObject, labelToShow); if (fEnable) m_sda.SetString(hvo, tagFakeFlid, tss); m_sda.SetInt(hvo, tagEnable, (fEnable ? 1 : 0)); } }
public virtual void FakeDoit(IEnumerable<int> itemsToChange, int tagFakeFlid, int tagEnabled, ProgressState state) { var chosenObjs = m_chosenObjs; 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)); ITsString tssChosenVal = BuildValueString(chosenObjs); foreach (int hvoItem in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count(); state.Breath(); } ITsString tssVal = tssChosenVal; List<ICmObject> oldVals, newVal; bool fEnable = false; if (!DisableItem(hvoItem)) { ComputeValue(chosenObjs, hvoItem, out oldVals, out newVal); fEnable = !oldVals.SequenceEqual(newVal); if (fEnable) { if (newVal != chosenObjs) tssVal = BuildValueString(newVal); m_sda.SetString(hvoItem, tagFakeFlid, tssVal); } } m_sda.SetInt(hvoItem, tagEnabled, (fEnable ? 1 : 0)); } }
/// <summary> /// Delete ALL the checked objects!! /// </summary> private void DeleteSelectedObjects(ProgressState state) { Set<int> idsToDelete = new Set<int>(); UpdateCurrentGhostParentHelper(); // needed for code below. foreach (int hvo in ItemsToChange(true)) { if (m_bv.SpecialCache.get_IntProp(hvo, XMLViewsDataCache.ktagItemEnabled) != 0) { if (VerifyRowDeleteAllowable(hvo)) { //allow deletion for the class we expect to be bulk editing. int hvoToDelete = 0; if (DomainObjectServices.IsSameOrSubclassOf(m_cache.DomainDataByFlid.MetaDataCache, m_cache.ServiceLocator.GetInstance<ICmObjectRepository>().GetObject(hvo).ClassID, m_expectedListItemsClassId)) hvoToDelete = hvo; else if (m_ghostParentHelper != null) hvoToDelete = m_ghostParentHelper.GetOwnerOfTargetProperty(hvo); if (hvoToDelete != 0) idsToDelete.Add(hvoToDelete); } } } bool fUndo; if (!CheckMultiDeleteConditionsAndReport(idsToDelete, out fUndo)) return; try { state.PercentDone = 10; state.Breath(); m_bv.SetListModificationInProgress(true); int total = idsToDelete.Count; int interval = Math.Min(100, Math.Max(idsToDelete.Count / 90, 1)); int i = 0; UndoableUnitOfWorkHelper.Do(XMLViewsStrings.ksUndoBulkDelete, XMLViewsStrings.ksRedoBulkDelete, m_cache.ActionHandlerAccessor, () => { foreach (int hvo in idsToDelete) { if ((i + 1) % interval == 0) { state.PercentDone = i * 90 / idsToDelete.Count + 10; state.Breath(); } i++; ICmObject obj; if (m_cache.ServiceLocator.ObjectRepository.TryGetObject(hvo, out obj)) m_bv.SpecialCache.DeleteObj(hvo); } if (m_expectedListItemsClassId == LexEntryTags.kClassId || m_expectedListItemsClassId == LexSenseTags.kClassId) { #if WANTPPORT CmObject.DeleteOrphanedObjects(m_cache, fUndo, state); #endif } }); m_bv.SetListModificationInProgress(false); ResumeRecordListRowChanges(); // need to show the updated list of rows! state.PercentDone = 100; state.Breath(); } finally { // need to recompute what needs to be enabled after the deletion. m_items.Clear(); } }
public override void DoIt(IEnumerable<int> itemsToChange, ProgressState state) { UndoableUnitOfWorkHelper.Do(XMLViewsStrings.ksUndoBulkEdit, XMLViewsStrings.ksRedoBulkEdit, m_cache.ActionHandlerAccessor, () => { ISilDataAccess sda = m_cache.DomainDataByFlid; HvoTssComboItem item = m_combo.SelectedItem as HvoTssComboItem; if (item == null) return; int hvoSelMorphType = item.Hvo; bool fSelAffix = false; if (hvoSelMorphType != 0) fSelAffix = MorphServices.IsAffixType(m_cache, hvoSelMorphType); bool fAnyFundamentalChanges = false; // Preliminary check and warning if changing fundamental type. foreach (int hvoLexEntry in itemsToChange) { int hvoLexemeForm = sda.get_ObjectProp(hvoLexEntry, m_flidParent); if (hvoLexemeForm == 0) continue; int hvoMorphType = sda.get_ObjectProp(hvoLexemeForm, m_flidAtomicProp); if (hvoMorphType == 0) continue; bool fAffix = MorphServices.IsAffixType(m_cache, hvoMorphType); if (fAffix != fSelAffix && hvoSelMorphType != 0) { string msg = String.Format(XMLViewsStrings.ksMorphTypeChangesSlow, (fAffix ? XMLViewsStrings.ksAffixes : XMLViewsStrings.ksStems), (fAffix ? XMLViewsStrings.ksStems : XMLViewsStrings.ksAffixes)); if (MessageBox.Show(this.m_combo, msg, XMLViewsStrings.ksChangingMorphType, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK) { return; } fAnyFundamentalChanges = true; break; // user OKd it, no need to check further. } } if (fAnyFundamentalChanges) { m_containingViewer.SetListModificationInProgress(true); } try { // Report progress 50 times or every 100 items, whichever is more // (but no more than once per item!) Set<int> idsToDel = new Set<int>(); var newForms = new Dictionary<IMoForm, ILexEntry>(); int interval = Math.Min(80, Math.Max(itemsToChange.Count()/50, 1)); int i = 0; foreach (int hvoLexEntry in itemsToChange) { // Guess we're 80% done when through all but deleting leftover objects and moving // new MoForms to LexemeForm slot. if ((i + 1)%interval == 0) { state.PercentDone = i*80/itemsToChange.Count(); state.Breath(); } i++; int hvoLexemeForm = sda.get_ObjectProp(hvoLexEntry, m_flidParent); if (hvoLexemeForm == 0) continue; int hvoMorphType = sda.get_ObjectProp(hvoLexemeForm, m_flidAtomicProp); if (hvoMorphType == 0) continue; bool fAffix = MorphServices.IsAffixType(m_cache, hvoMorphType); var stemAlloFactory = m_cache.ServiceLocator.GetInstance<IMoStemAllomorphFactory>(); var afxAlloFactory = m_cache.ServiceLocator.GetInstance<IMoAffixAllomorphFactory>(); if (fAffix == fSelAffix) { // Not changing C# type of allomorph object, just set the morph type. if (hvoMorphType != hvoSelMorphType) { sda.SetObjProp(hvoLexemeForm, m_flidAtomicProp, hvoSelMorphType); } } else if (fAffix) { // Changing from affix to stem, need a new allomorph object. var entry = m_cache.ServiceLocator.GetInstance<ILexEntryRepository>().GetObject(hvoLexEntry); var affix = m_cache.ServiceLocator.GetInstance<IMoAffixAllomorphRepository>().GetObject(hvoLexemeForm); var stem = stemAlloFactory.Create(); SwapFormValues(entry, affix, stem, hvoSelMorphType, idsToDel); foreach (var env in affix.PhoneEnvRC) stem.PhoneEnvRC.Add(env); newForms[stem] = entry; } else { // Changing from stem to affix, need a new allomorph object. var entry = m_cache.ServiceLocator.GetInstance<ILexEntryRepository>().GetObject(hvoLexEntry); var stem = m_cache.ServiceLocator.GetInstance<IMoStemAllomorphRepository>().GetObject(hvoLexemeForm); var affix = afxAlloFactory.Create(); SwapFormValues(entry, stem, affix, hvoSelMorphType, idsToDel); foreach (var env in stem.PhoneEnvRC) affix.PhoneEnvRC.Add(env); newForms[affix] = entry; } } if (fAnyFundamentalChanges) { foreach (int hvo in idsToDel) { sda.DeleteObj(hvo); } state.PercentDone = 90; state.Breath(); foreach (var pair in newForms) { pair.Value.LexemeFormOA = pair.Key; } state.PercentDone = 100; state.Breath(); } } finally { if (fAnyFundamentalChanges) m_containingViewer.SetListModificationInProgress(false); } }); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Fake doing the change by setting the specified property to the appropriate value /// for each item in the set. Disable items that can't be set. /// </summary> /// <param name="itemsToChange">The items to change.</param> /// <param name="tagFakeFlid">The tag fake flid.</param> /// <param name="tagEnable">The tag enable.</param> /// <param name="state">The state.</param> /// ------------------------------------------------------------------------------------ public void FakeDoit(IEnumerable<int> itemsToChange, int tagFakeFlid, int tagEnable, ProgressState state) { 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 hvo in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count(); state.Breath(); } bool fEnable = OkToChange(hvo); if (fEnable) m_sda.SetString(hvo, tagFakeFlid, NewValue(hvo)); m_sda.SetInt(hvo, tagEnable, (fEnable ? 1 : 0)); } }
/// <summary> /// Despite being public where the other SetDlgInfo is internal, this is a "special-case" /// initialization method not used in Flex, but in TE, where there is not a pre-existing mediator /// for each main window. This initializer obtains the configuration parameters and sets up a /// suitable mediator. In doing so it duplicates knowledge from various places: /// 1. Along with the code that initializes xWindow and various other places, it 'knows' where /// to find the configuration node for the respeller dialog. /// 2. It duplicates some of the logic in FwXWindow.InitMediatorValues and RestoreProperties, /// knowing the LocalSettingsId and how to use it to restore mediator properties, and what items /// must be in the mediator. Also logic in xWindow for restoring global settings. /// 3. It knows how to initialize a number of virtual properties normally created as part of /// FLEx's startup code. /// 4. It knows how to set up the string table that Flex uses. /// 5. It knows how to initialize the Flex part inventories. /// </summary> public bool SetDlgInfo(IWfiWordform wf, Form parent, IApp app) { if (wf == null) throw new ArgumentNullException("wf"); if (parent == null) throw new ArgumentNullException("parent"); if (app == null) throw new ArgumentNullException("app"); using (var dlg = new ProgressDialogWorkingOn()) { dlg.Owner = parent; dlg.Text = MEStrings.ksFindingOccurrences; dlg.WorkingOnText = MEStrings.ksSearchingOccurrences; dlg.ProgressLabel = MEStrings.ksProgress; dlg.Show(ActiveForm); dlg.Update(); dlg.BringToFront(); //var progressState = new MilestoneProgressState(dlg.ProgressDisplayer); try { m_cache = wf.Cache; m_srcwfiWordform = wf; // Get the parameter node. var path = Path.Combine(FwDirectoryFinder.GetCodeSubDirectory( Path.Combine(FwUtils.ksFlexAppName, Path.Combine("Configuration", "Words"))), "areaConfiguration.xml"); var doc = XWindow.LoadConfigurationWithIncludes(path, true); var paramNode = doc.DocumentElement.SelectSingleNode("listeners/listener[@class=\"SIL.FieldWorks.XWorks.MorphologyEditor.RespellerDlgListener\"]/parameters"); Debug.Assert(paramNode != null); // Initialize a mediator. var mediator = new Mediator(); m_fDisposeMediator = true; // Copied from FwXWindow.InitMediatorValues mediator.PropertyTable.LocalSettingsId = "local"; mediator.PropertyTable.SetProperty("cache", m_cache); mediator.PropertyTable.SetPropertyPersistence("cache", false); string userPath = DirectoryFinder.UserAppDataFolder(app.ApplicationName); Directory.CreateDirectory(userPath); mediator.PropertyTable.UserSettingDirectory = userPath; //// Enhance JohnT: possibly these three lines (also copied) are not needed. //mediator.PropertyTable.SetProperty("DocumentName", GetMainWindowCaption(cache)); //mediator.PropertyTable.SetPropertyPersistence("DocumentName", false); mediator.PathVariables["{DISTFILES}"] = FwDirectoryFinder.CodeDirectory; mediator.PropertyTable.RestoreFromFile(mediator.PropertyTable.GlobalSettingsId); mediator.PropertyTable.RestoreFromFile(mediator.PropertyTable.LocalSettingsId); //progressState.SetMilestone(); // Set this AFTER the restore! Otherwise it goes away! mediator.PropertyTable.SetProperty("window", dlg.Owner); mediator.PropertyTable.SetPropertyPersistence("window", false); string directoryContainingConfiguration = Path.Combine(FwDirectoryFinder.FlexFolder, "Configuration"); StringTable table = new StringTable(directoryContainingConfiguration); mediator.StringTbl = table; mediator.FeedbackInfoProvider = (IFeedbackInfoProvider)app; //progressState.SetMilestone(); //progressState.SetMilestone(); LayoutCache.InitializePartInventories(m_cache.ProjectId.Name, app, m_cache.ProjectId.ProjectFolder); //progressState.SetMilestone(); // Get all the scripture texts. // Review: should we include IText ones too? // NB: The ownership check is designed to exclude archived drafts. // The second half collects footnotes and the title of the book. var stTextRepos = m_cache.ServiceLocator.GetInstance<IStTextRepository>(); var unarchivedScriptureTexts = m_cache.LangProject.TranslatedScriptureOA.StTexts.ToList(); //progressState.SetMilestone(); // Build concordance info, including the occurrence list for our wordform. ProgressState state = new ProgressState(dlg.ProgressDisplayer); // This is an ugly way of getting the state to the RespellingSda method mediator.PropertyTable.SetProperty("SpellingPrepState", state); mediator.PropertyTable.SetPropertyPersistence("SpellingPrepState", false); NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, () => { int done = 0; int total = unarchivedScriptureTexts.Count; foreach (var txt in unarchivedScriptureTexts) { done++; foreach (IStTxtPara para in txt.ParagraphsOS) { if (para.ParseIsCurrent) continue; ParagraphParser.ParseParagraph(para, true); } state.PercentDone = 50*done/total; state.Breath(); } }); // Make sure we will include all of Scripture in the occurrences list. InterestingTextList.SetScriptureTextsInPropertyTable(mediator.PropertyTable, unarchivedScriptureTexts); return SetDlgInfoPrivate(mediator, paramNode); } finally { dlg.Close(); } } }
public void Doit(IEnumerable<int> itemsToChange, ProgressState state) { m_sda.BeginUndoTask(XMLViewsStrings.ksUndoBulkEdit, XMLViewsStrings.ksRedoBulkEdit); string commitChanges = XmlUtils.GetOptionalAttributeValue(m_nodeSpec, "commitChanges"); 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 hvo in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count(); state.Breath(); } Doit(hvo); BulkEditBar.CommitChanges(hvo, commitChanges, m_cache, m_accessor.WritingSystem); } m_sda.EndUndoTask(); }
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(); }
public virtual void DoIt(Set<int> itemsToChange, ProgressState state) { using (new UndoRedoTaskHelper(m_cache, XMLViewsStrings.ksUndoBulkEdit, XMLViewsStrings.ksRedoBulkEdit)) { ISilDataAccess sda = m_cache.MainCacheAccessor; BulkEditBar.ForceRefreshOnUndoRedo(sda); int[] chosenHvos = m_chosenHvos; 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 hvoItem in itemsToChange) { i++; if (i % interval == 0) { state.PercentDone = i * 100 / itemsToChange.Count; state.Breath(); } if (DisableItem(hvoItem)) continue; int[] oldVals; int[] newVal; ComputeValue(chosenHvos, hvoItem, out oldVals, out newVal); if (EqualIntArrays(oldVals, newVal)) continue; sda.Replace(hvoItem, m_flid, 0, oldVals.Length, newVal, newVal.Length); sda.PropChanged(null, (int)PropChangeType.kpctNotifyAll, hvoItem, m_flid, 0, newVal.Length, oldVals.Length); } } }