Exemple #1
0
		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));
			}
		}
Exemple #2
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++;
			}
		}
Exemple #3
0
		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));
			}
		}
Exemple #4
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);
					}
				}
			});
		}
Exemple #5
0
		/// <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();
		}
Exemple #6
0
		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));
				}
			}
		}
Exemple #7
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));
			}
		}
Exemple #10
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));
		}
Exemple #11
0
		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;
				}
			}
		}
Exemple #12
0
		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();
		}
Exemple #14
0
		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);
			}
		}
Exemple #15
0
		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();
		}
Exemple #17
0
		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();
		}
Exemple #19
0
		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();
		}
Exemple #21
0
		/// <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));
			}
		}
Exemple #23
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));
			}
		}
Exemple #24
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();
			}
		}
Exemple #25
0
		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);
						}
					});
		}
Exemple #26
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">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));
			}
		}
Exemple #27
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();
				}
			}
		}
Exemple #28
0
		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();
		}
Exemple #29
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();
		}
Exemple #30
0
		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);
				}
			}
		}