Пример #1
0
		private void Parse(IStText text, ProgressState progress)
		{
			progress.SetMilestone(ITextStrings.ksPreparingInterlinear1);
			progress.Breath();

			m_ihvoPara = 0;
			m_hvoText = text.Hvo;
			m_cparas = text.ParagraphsOS.Count;
#if DEBUG
			//TimeRecorder.End("setup");
			//TimeRecorder.Begin("parse");
#endif
			progress.SetMilestone(ITextStrings.ksPreparingInterlinear2);
			progress.Breath();
			// we only need to load our real database information once, since it's for all paragraphs.
			if (!m_fFinishedBuildAnalysisList)
			{
				BuildAnalysisList(progress);
			}

			progress.SetMilestone(ITextStrings.ksPreparingInterlinear3);
			progress.Breath();
			Cache.PreloadIfMissing(text.ParagraphsOS.HvoArray, (int)StTxtPara.StTxtParaTags.kflidContents, 0, false);
			foreach (StTxtPara para in text.ParagraphsOS)
			{
				Setup(para);
				Parse();
				m_ihvoPara++;
				//progress.Breath();
			}

#if DEBUG
			//TimeRecorder.End("parse");
			//TimeRecorder.End("parse text");
#endif
			progress.SetMilestone(ITextStrings.ksPreparingInterlinear4);
			progress.Breath();

#if DEBUG
			//TimeRecorder.Begin("note parse times");
#endif
			// If we didn't have to make any dummy annotations, this text is sufficiently analyzed not to need
			// any. Therefore we can record a time when this was done, and won't have to run the parser on it
			// again until it gets modified. If we made dummy ones, they will get thrown away when the
			// program exits or the cache is cleared, so we need to reparse the text the next time we see it
			// in order to make a new set of dummy annotations to display.
			// Enhance JohnT: possibly we could record a time in the cache to avoid reparsing if we come back
			// to this text and have NOT modified it and the dummy annotations are still in memory.
			// Enhance JohnT: currently nothing ever makes real punctuation annotations. Therefore hardly any
			// text will ever be fully annotated (no dummy annotations). We may want to enhance so that
			// if the only dummy annotations in a text are punctuation, we make real punctuation annotations
			// so we can record a complete annotation timestamp.
			// But: currently we need to parse every text when first brought into memory, because that is
			// what makes the dummy TwficRealForm property values that let us get case right. Unless we change
			// that, the whole mechanism for tracking whether it is up to date in the database is irrelevant.
			IOleDbCommand odc = null;
			try
			{
				text.Cache.DatabaseAccessor.CreateCommand(out odc);
				if (!m_fMadeDummyAnnotations)
				{
					string sql2 = string.Format("declare @res nvarchar(4000);" +
						" exec NoteInterlinProcessTime {0}, {1}, @res OUTPUT; select @res",
						CmAnnotationDefn.ProcessTime(text.Cache).Hvo, text.Hvo);
					uint cbSpaceTaken;
					bool fMoreRows;
					bool fIsNull;
					byte[] rgbTemp = null;
					using (ArrayPtr rgchMarshalled = MarshalEx.ArrayToNative(4000, typeof(char)))
					{
						progress.Breath();
						odc.ExecCommand(sql2, (int)SqlStmtType.knSqlStmtStoredProcedure);
						odc.GetRowset(0);
						// We need to update the cache if one or more CmBaseAnnotation objects were
						// created in LangProject_Annotations by the NoteInterlinProcessTime stored
						// procedure.
						odc.NextRow(out fMoreRows);
						odc.GetColValue(1, rgchMarshalled, rgchMarshalled.Size, out cbSpaceTaken, out fIsNull, 0);
						rgbTemp = (byte[])MarshalEx.NativeToArray(rgchMarshalled,
							(int)cbSpaceTaken, typeof(byte));
					}
					char[] delim = { ',' };
					string[] sVals = Encoding.Unicode.GetString(rgbTemp).Split(delim);
					List<int> newAnns = new List<int>();
					for (int i = 0; i < sVals.Length; ++i)
					{
						if (sVals[i].Length != 0)
						{
							int hvo = Convert.ToInt32(sVals[i]);
							newAnns.Add(hvo);
						}
					}
					int[] newAnnotations = DbOps.ListToIntArray(newAnns);
					if (newAnnotations.Length != 0)
					{
						progress.Breath();
						// update the cache.
						IVwCacheDa csda = text.Cache.MainCacheAccessor as IVwCacheDa;
						Debug.Assert(csda != null);
						int hvoObj = text.Cache.LangProject.Hvo;
						int ihvoLim = text.Cache.LangProject.AnnotationsOC.Count;
						csda.CacheReplace(hvoObj,
							(int)LangProject.LangProjectTags.kflidAnnotations,
							ihvoLim, ihvoLim,
							newAnnotations, newAnnotations.Length);
					}
				}
			}
			finally
			{
				DbOps.ShutdownODC(ref odc);
				progress.Breath();
			}
			progress.SetMilestone(ITextStrings.ksPreparingInterlinear5);
			progress.Breath();
		}
Пример #2
0
		protected virtual void CleanupLeftoverRealAnnotations(ProgressState progress)
		{
			if (m_matcher != null)
				return;		// we're just doing a partial parse, so keep all real annotations.
			Set<int> idsToDel = new Set<int>();

			// Add to the document all the things we want to delete.
			// (For each paragraph we've parsed...)
			// Any existing annotations we haven't reused need to be done away with.
			// Instead of deleting unused twfics, we'll simply reserve them to be reused later.
			CmBaseAnnotation.ReserveAnnotations(m_cache, m_unusedTwficAnnotations, false);
			// AddIdsToDel(progress, ref idsToDel, m_unusedTwficAnnotations);
			AddIdsToDel(progress, idsToDel, m_unusedPunctuationAnnotations);
			AddIdsToDel(progress, idsToDel, m_unusedSegmentAnnotations);

			if (idsToDel.Count > 0)
			{
				if (progress is MilestoneProgressState)
				{
					MilestoneProgressState mp = progress as MilestoneProgressState;
					mp.AddMilestone(1);
				}
				Debug.WriteLine("Removing leftover annotations: " + CmObject.JoinIds(idsToDel.ToArray(), ","));
				// Enhance JohnT: should we do something (delete or move?) about any freeform annotations
				// attached to these segments? For now they will become orphans...
				CmObject.DeleteObjects(idsToDel, Cache, VwClearInfoAction.kciaRemoveObjectInfoOnly);
				progress.SetMilestone();
				progress.Breath();
			}

			m_unusedTwficAnnotations.Clear();
			m_unusedPunctuationAnnotations.Clear();
			m_unusedSegmentAnnotations.Clear();
		}
Пример #3
0
		internal static List<int> ConcordParagraphs(FdoCache cache, int[] hvosStTxtPara, ProgressState progress,
			IMatcher matcher, ConcordanceControl.ConcordanceLines line)
		{
			using (ParagraphParser pp = new ParagraphParser(cache))
			{
				// this will effectively clear ConcordanceWordforms, which seems overkill, but
				// since we are changing the occurrences on those wordforms,
				// and also possibly adding many new wordforms, we should just allow RecordLists that use
				// ConcordanceWordforms to reload the list.
				// (Enhance: is there any way we can make those lists be smart about when they need to reload,
				// rather than forcing them to?)
				(pp.m_wfi as WordformInventory).SuspendUpdatingConcordanceWordforms = true;
				pp.CreateDummyWordforms = true;
				pp.m_hvosStTxtPara = hvosStTxtPara;
				if (matcher != null)
					pp.m_matchingAnnotations = new List<int>();
				ParagraphParser.ResetParseSessionDependentStaticData();

				// Estimate the number of total number of milestones we'll set.
				// Enhance: we could construct a way to set percentage done based upon
				// number of texts and paragraphs in each text.
				if (progress is MilestoneProgressState)
				{
					MilestoneProgressState mp = progress as SIL.FieldWorks.Common.Controls.MilestoneProgressState;
					for (int i = 0; i < pp.m_hvosStTxtPara.Length; ++i)
					{
						mp.AddMilestone(1);
					}
				}

				// Preload all the paragraphs.
				cache.PreloadIfMissing(hvosStTxtPara, (int)StTxtPara.StTxtParaTags.kflidContents, 0, false);

				// Parse each text to load our paragraph and wordform segment annotations.
				int cPara = 0;
				using (SuppressSubTasks suppressor = new SuppressSubTasks(cache, true))
				{
					foreach (IStTxtPara para in new FdoObjectSet<IStTxtPara>(cache, pp.m_hvosStTxtPara, false))
					{
						++cPara;
						pp.Parse(para, matcher, line);
						progress.SetMilestone();
						progress.Breath();
						if (pp.m_matchingAnnotations != null &&
							pp.m_matchingAnnotations.Count >= ConcordanceControl.MaxConcordanceMatches())
						{
							MessageBox.Show(String.Format(ITextStrings.ksShowingOnlyTheFirstXXXMatches,
								pp.m_matchingAnnotations.Count, cPara, pp.m_hvosStTxtPara.Length),
								ITextStrings.ksNotice, MessageBoxButtons.OK, MessageBoxIcon.Information);
							break;
						}
					}
					pp.CleanupLeftoverAnnotations(progress);
				}
				progress.SetMilestone();
				progress.Breath();
				(pp.m_wfi as WordformInventory).SuspendUpdatingConcordanceWordforms = false;
				return pp.m_matchingAnnotations;
			}
		}
Пример #4
0
		/// <summary>
		/// Delete the underlying object. Note that this is deliberatly NOT virtual. Special delete
		/// behaviors should be implemented on DeleteObjectSideEffects.
		/// </summary>
		public void DeleteUnderlyingObject(ProgressState state)
		{
			Set<int> idsToDelete = new Set<int>();
			FdoCache cache = m_cache; // BEFORE DeleteObjectSideEffects, which erases it!
			state.SetMilestone(Strings.ksGatheringInfo);
			state.Breath();
			DeleteObjectSideEffects(idsToDelete, state);
			state.SetMilestone(Strings.ksActualDelete);
			DeleteObjects(idsToDelete, cache);
		}