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();
}