예제 #1
0
		/// <summary>
		/// Requirement is to figure the annotaion before e.Annotation and store it
		/// along with its current annotation in e.
		/// If e.Annotation is 0, go to the very last word of the document.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		public void BackWord(object sender, AdvanceWordArgs e, bool fNeedsAnalysis)
		{
			int[] indexes;
			int[] hvos;
			int[] tags = new int[] { (int)StText.StTextTags.kflidParagraphs,
									   m_vc.ktagParaSegments,
									   m_vc.ktagSegmentForms };
			ISilDataAccess sda = m_rootb.DataAccess;
			if (e.Annotation == 0)
			{
				// Very last word.
				// We set indexes as if the current word was at the very start of the non-existent
				// paragraph after the last one.
				hvos = new int[tags.Length];
				hvos[0] = m_hvoRoot;
				indexes = new int[tags.Length]; // full of zeros.
				indexes[0] = m_fdoCache.MainCacheAccessor.get_VecSize(hvos[0], (int)StText.StTextTags.kflidParagraphs);
			}
			else
			{
				if (IndexOf(m_hvoRoot, tags, e.Annotation, out indexes, out hvos) < 0)
				{
					return; // can't find it at all.
				}
			}

			// This is used for ensuring that paragraphs are loaded.
			SelLevInfo[] rgvsli = new SelLevInfo[1];
			rgvsli[0].tag = (int)StText.StTextTags.kflidParagraphs;
			rgvsli[0].cpropPrevious = 0;
			rgvsli[0].ihvo = 0;
			rgvsli[0].hvo = 0;
			rgvsli[0].ws = 0;
			rgvsli[0].ich = 0;

			// Loop until we can't go back further or find a valid previous word.
			for (; ; )
			{
				int ilev;
				// Work back till we find a non-zero index we can decrement.
				for (ilev = indexes.Length - 1; ilev >= 0 && indexes[ilev] == 0; ilev--)
					;
				if (ilev < 0)
					return; // at start.
				indexes[ilev]--;
				if (ilev == 0)
				{
					// Ensure that the paragraph we're moving back to is not lazy.
					// This may seem a bit of a hack, but should minimize the amount of code
					// exercised by loading the data for a lazy paragraph: we make an object
					// selection of the previous paragraph, which automatically loads things
					// into the cache if needed, but does minimal work if it's already there.
					// Note that indexes[0] is already set to the index of the previous
					// paragraph.
					rgvsli[0].ihvo = indexes[0];
					IVwSelection selNew = m_rootb.MakeTextSelInObj(
						/*[in] int ihvoRoot */ 0,
						/*[in] int cvsli */ rgvsli.Length,
						/*[in, size_is(cvsli)] VwSelLevInfo * */ rgvsli,
						/*[in] int cvsliEnd */ 0,
						/*[in, size_is(cvsliEnd)] VwSelLevInfo * rgvsliEnd */ null,
						/*[in] ComBool fInitial */ false,
						/*[in] ComBool fEdit */ false,
						/*[in] ComBool fRange */ false,
						/*[in] ComBool fWholeObj */ true,
						/*[in] ComBool fInstall */ false
						);
				}
				ilev++;

				// work forward choosing the last item in any higher-level list.
				for (; ilev < indexes.Length; ilev++)
				{
					int chvo = 0;
					// iterate backward thru until we find a list that isn't empty, for example
					// we iterate thru the paragraphs in a text starting from the currently set index and
					// move backwards until we find a paragraph that is not empty.
					for (int offset = 0; offset <= indexes[ilev - 1]; offset++)
					{
						int hvo = sda.get_VecItem(hvos[ilev - 1], tags[ilev - 1], indexes[ilev - 1] - offset);
						hvos[ilev] = hvo;
						chvo = sda.get_VecSize(hvo, tags[ilev]);
						if (chvo > 0)
							// found non-empty list
							break;
					}
					if (chvo == 0)
						return; // something empty; give up
					indexes[ilev] = chvo - 1; // last one
				}
				// Our target is indicated by the last item in the wordforms of the last
				// segment.
				int hvoAnn = sda.get_VecItem(hvos[2], m_vc.ktagSegmentForms,
					indexes[2]);
				int hvoAnalysis = sda.get_ObjectProp(hvoAnn,
					(int)CmAnnotation.CmAnnotationTags.kflidInstanceOf);
				if (hvoAnalysis == 0 || !m_vc.CanBeAnalyzed(hvoAnn))
					continue; // punctuation.
				// If we're looking for a word that needs analysis, skip this one if it doesn't.
				if (fNeedsAnalysis &&
					FullyAnalyzed(m_fdoCache, m_vc.ListManager, hvoAnalysis, hvoAnalysis))
					continue;
				// Otherwise this is it.
				e.Annotation = hvoAnn;
				e.Analysis = hvoAnalysis;
				return;
			}
		}
예제 #2
0
		/// <summary>
		/// Requirement is to figure the next annotaion after e.Annotation and store it
		/// along with its current annotation in e.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		/// <param name="fNeedsAnalysis">True to advance to a word that needs analysis;
		/// false to just advance to the immediately next word.</param>
		public void AdvanceWord(object sender, AdvanceWordArgs e, bool fNeedsAnalysis)
		{
			int hvoCurrent = e.Annotation;
			ISilDataAccess sda = m_fdoCache.MainCacheAccessor;
			int hvoPara;
			if (CmObject.IsValidObject(m_fdoCache, hvoCurrent))
			{
				int twficType = CmAnnotationDefn.Twfic(Cache).Hvo;
				// We should assert that hvoCurrent is Twfic
				int annoType = sda.get_ObjectProp(hvoCurrent,
					(int)CmBaseAnnotation.CmAnnotationTags.kflidAnnotationType);
				Debug.Assert(annoType == twficType, "Given annotation type should be twfic("
					+ twficType + ") but was " + annoType + ".");
				hvoPara = sda.get_ObjectProp(hvoCurrent,
					(int)CmBaseAnnotation.CmBaseAnnotationTags.kflidBeginObject);
			}
			else
			{
				// Start with first para of text
				if (m_hvoRoot == 0)
					return; // can't do anything.
				int hvoStText = m_hvoRoot;
				if (sda.get_VecSize(hvoStText, (int)StText.StTextTags.kflidParagraphs) == 0)
					return;	// newly created, no contents yet.
				hvoPara = sda.get_VecItem(hvoStText, (int)StText.StTextTags.kflidParagraphs, 0);
			}
			if (hvoPara != 0)
			{
				int cseg = sda.get_VecSize(hvoPara, m_vc.ktagParaSegments);
				// This flag is set if we have found the word we're advancing from...or
				// immediately, if hvoCurrent is zero, which means we're 'advancing' from the
				// start of the text.
				bool prevMatch = (hvoCurrent == 0);
				for (int iseg = 0; iseg < cseg; iseg++)
				{
					int hvoSeg = sda.get_VecItem(hvoPara, m_vc.ktagParaSegments, iseg);
					int cann = sda.get_VecSize(hvoSeg, m_vc.ktagSegmentForms);
					for (int iann = 0; iann < cann; iann++)
					{
						int hvoAnn = sda.get_VecItem(hvoSeg, m_vc.ktagSegmentForms,
							iann);
						if (prevMatch)
						{
							int hvoAnalysis = sda.get_ObjectProp(hvoAnn,
								(int)CmAnnotation.CmAnnotationTags.kflidInstanceOf);
							if (hvoAnalysis == 0 || !m_vc.CanBeAnalyzed(hvoAnn))
								continue; // skip punctuation.
							if (fNeedsAnalysis && FullyAnalyzed(m_fdoCache,
								m_vc.ListManager, hvoAnn, hvoAnalysis))
								continue;
							// Some previous annotation was a match, and this one isn't fully
							// analyzed, so this is the one we want.
							e.Annotation = hvoAnn;
							e.Analysis = hvoAnalysis;
							// if, for some reason, the next annotation is invalid
							// reset these to 0.
							if (!CmObject.IsValidObject(m_fdoCache, hvoAnn))
							{
								e.Annotation = 0;
								e.Analysis = 0;
							}
							return;
						}
						prevMatch = (hvoAnn == hvoCurrent);
					}
				}
				// Didn't find another one in the expected paragraph.
				// If prevmatch is false, something is wrong.
				// if prevMatch is true, hvoCurrent is the last word in the paragraph, and we
				// should move to the next.  But it's complicated: it might be a paragraph we
				// haven't expanded from laziness yet, and which therefore doesn't have all its
				// segment info cached.  For now we'll skip doing that.
				// Sorry, we can't be that lazy about handling laziness!  So here goes ...
				Debug.Assert(prevMatch);
				Debug.Assert(m_rootb != null);

				// In the loop above, we searched the paragraph for the relevant word.  Now we
				// need to search the text for the relevant paragraph, and return the first word
				// in the next paragraph.
				// Start with first para of text
				if (m_hvoRoot == 0)
					return; // can't do anything.
				int hvoStText = m_hvoRoot;
				if (hvoStText == 0)
					return; // newly created text, has no Contents yet.
				int cpara = sda.get_VecSize(hvoStText, (int)StText.StTextTags.kflidParagraphs);
				if (cpara == 0)
					return;

				SelLevInfo[] rgvsli = new SelLevInfo[1];
				rgvsli[0].tag = (int)StText.StTextTags.kflidParagraphs;
				rgvsli[0].cpropPrevious = 0;
				rgvsli[0].ihvo = 0;
				rgvsli[0].hvo = 0;
				rgvsli[0].ws = 0;
				rgvsli[0].ich = 0;
				for (int ipara = 0; ipara < cpara; ++ipara)
				{
					int hvoPara1 = sda.get_VecItem(hvoStText,
						(int)StText.StTextTags.kflidParagraphs, ipara);
					if (hvoPara1 == hvoPara && (ipara + 1) < cpara)
					{
						rgvsli[0].ihvo = ipara + 1;
						hvoPara = sda.get_VecItem(hvoStText,
							(int)StText.StTextTags.kflidParagraphs, ipara + 1);
						if (GetWordInNextPara(hvoPara, rgvsli, e, fNeedsAnalysis))
							return;
					}
				}
			}
		}
예제 #3
0
		/// <summary>
		///
		///
		/// </summary>
		/// <param name="hvoPara"></param>
		/// <param name="rgvsli"></param>
		/// <param name="e"></param>
		/// <param name="fNeedsAnalysis"></param>
		private bool GetWordInNextPara(int hvoPara, SelLevInfo[] rgvsli, AdvanceWordArgs e,
			bool fNeedsAnalysis)
		{
			// This may seem a bit of a hack, but should minimize the amount of code exercised
			// by loading the data for a lazy paragraph: we make an object selection of the next
			// paragraph, which automatically loads things into the cache if needed, but does
			// minimal work if it's already there.
			IVwSelection selNew = m_rootb.MakeTextSelInObj(
				/*[in] int ihvoRoot */ 0,
				/*[in] int cvsli */ rgvsli.Length,
				/*[in, size_is(cvsli)] VwSelLevInfo * */ rgvsli,
				/*[in] int cvsliEnd */ 0,
				/*[in, size_is(cvsliEnd)] VwSelLevInfo * rgvsliEnd */ null,
				/*[in] ComBool fInitial */ false,
				/*[in] ComBool fEdit */ false,
				/*[in] ComBool fRange */ false,
				/*[in] ComBool fWholeObj */ true,
				/*[in] ComBool fInstall */ false
				);
			if (selNew == null)
			{
				// If we can't even make a selection, assume there's nothing there.
				return false;
			}
			ISilDataAccess sda = m_fdoCache.MainCacheAccessor;
			int cseg = sda.get_VecSize(hvoPara, m_vc.ktagParaSegments);
			for (int iseg = 0; iseg < cseg; iseg++)
			{
				int hvoSeg = sda.get_VecItem(hvoPara, m_vc.ktagParaSegments, iseg);
				int cann = sda.get_VecSize(hvoSeg, m_vc.ktagSegmentForms);
				for (int iann = 0; iann < cann; iann++)
				{
					int hvoAnn = sda.get_VecItem(hvoSeg, m_vc.ktagSegmentForms,
						iann);
					int hvoAnalysis = sda.get_ObjectProp(hvoAnn,
						(int)CmAnnotation.CmAnnotationTags.kflidInstanceOf);
					if (hvoAnalysis == 0)
						continue;	// skip punctuation.
					if (fNeedsAnalysis && FullyAnalyzed(m_fdoCache,
						m_vc.ListManager, hvoAnn, hvoAnalysis))
						continue;	// conditionally skip analyzed words.
					// This is the one we want.
					e.Annotation = hvoAnn;
					e.Analysis = hvoAnalysis;
					return true;
				}
			}
			// Nothing valid in this paragraph: either no words or no unanalyzed words.
			return false;
		}
예제 #4
0
		/// <summary>
		/// Move to the first bundle
		/// </summary>
		/// <param name="arg"></param>
		/// <returns></returns>
		public bool OnFirstBundle(object arg)
		{
			AdvanceWordArgs args = new AdvanceWordArgs(0, 0);
			AdvanceWord(this, args, false);
			if (args.Annotation != 0)
				TriggerAnnotationSelected(args.Annotation, args.Analysis, true);
			return true;
		}
예제 #5
0
		internal bool OnDisplayShowLinkWords(int hvoAnnotation, int hvoAnalysis)
		{
			AdvanceWordArgs argsForNextAnnotation = new AdvanceWordArgs(hvoAnnotation, hvoAnalysis);
			AdvanceWord(this, argsForNextAnnotation, false);
			return CanExtendAnnotation(hvoAnnotation, argsForNextAnnotation.Annotation);
		}
예제 #6
0
		private AdvanceWordArgs GetArgsForAdjacentAnnotation(int hvoAnnotation, int hvoAnalysis, bool fNeedsAnalysis, bool fAdvance)
		{
			AdvanceWordArgs args = new AdvanceWordArgs(hvoAnnotation, hvoAnalysis);
			if (fAdvance)
				AdvanceWord(this, args, fNeedsAnalysis);
			else
				BackWord(this, args, fNeedsAnalysis);
			return args;
		}
예제 #7
0
		private int SelectFirstThingNeedingAnnotation(InterlinDocChild pane)
		{
			int hvoAnn = 0;
			AdvanceWordArgs args = new AdvanceWordArgs(0, 0);
			pane.AdvanceWord(this, args, true);
			if (args.Annotation != 0)
				hvoAnn = args.Annotation;
			return hvoAnn;
		}
예제 #8
0
		// If the Clerk's object is an annotation, select the corresponding thing in whatever pane
		// is active. Or, if we have a bookmark, restore it.
		private void SelectAnnotation()
		{
			if (Clerk.CurrentObject == null || Clerk.SuspendLoadingRecordUntilOnJumpToRecord)
				return;
			ISilDataAccess sda = Cache.MainCacheAccessor;
			int annHvo = 0;
			// Use a bookmark, if we've set one.
			if (m_bookmark.IndexOfParagraph >= 0)
			{
				// Interlinear and Chart SelectAnnotation() must take TWFIC, but RawTextPane can
				// also handle text segments.
				// Chart and PrintView SelectAnnotation() don't need to worry about Sandbox.
				switch (m_tabCtrl.SelectedIndex)
				{
					case ktpsAnalyze:
					case ktpsGloss:
						annHvo = HandleBookmark(m_idcPane);
						break;

					case ktpsTagging:
						annHvo = HandleBookmark(m_taggingViewPane);
						break;

					case ktpsPrint:
						annHvo = HandleBookmark(m_printViewPane);
						break;

					case ktpsCChart:
						// Call Constituent Chart SelectBookmark() by reflection
						System.Type type = m_constChartPane.GetType();
						MethodInfo info = type.GetMethod("SelectAndScrollToBookmark");
						Debug.Assert(info != null, "Couldn't find 'SelectAndScrollToBookmark()' in CChart");
						info.Invoke(m_constChartPane, new object[] { m_bookmark });
						break;

					case ktpsRawText:
						m_rtPane.SelectBookMark(m_bookmark);
						break;

					case ktpsInfo:
						break;

					default:
						Debug.Fail("Unhandled tab index.");
						break;
				}
			}
			else
			{
				// This pane, as well as knowing how to work with a record list of Texts, knows
				// how to work with one of CmBaseAnnotations, that is, a list of occurrences of
				// a word.
				int clsid = Cache.GetClassOfObject(Clerk.CurrentObject.Hvo);
				if (clsid == CmBaseAnnotation.kClassId)
					annHvo = Clerk.CurrentObject.Hvo;
			}

			if (IsPersistedForAnInterlinearTabPage && InterlinearTabPageIsSelected())
			{
				if (annHvo == 0)
				{
					// Select the first word needing attention.
					AdvanceWordArgs args = new AdvanceWordArgs(0, 0);
					m_idcPane.AdvanceWord(this, args, true);
					if (args.Annotation != 0)
						annHvo = args.Annotation;
					else
						return;		// Can't select nothing, so return.
				}

				// Try our best not to select an annotation we know won't work.
				int twficType = CmAnnotationDefn.Twfic(Cache).Hvo;
				int annoType = sda.get_ObjectProp(annHvo, kflidAnnotationType);
				int annInstanceOfRAHvo = sda.get_ObjectProp(annHvo, kflidInstanceOf);
				if (annInstanceOfRAHvo == 0 || annoType != twficType)
				{
					// if we didn't set annHvo by our marker or Clerk.CurrentObject,
					// then we must have already tried the first word.
					if (m_bookmark.IndexOfParagraph < 0 && Clerk.CurrentObject.Hvo == 0)
						return;
					// reset our marker and return to avoid trying to reuse an "orphan annotation"
					// resulting from an Undo(). (cf. LT-2663).
					m_bookmark.Reset();

					// See if we can at least select the first word.
					AdvanceWordArgs args = new AdvanceWordArgs(0, 0);
					m_idcPane.AdvanceWord(this, args, false);
					if (args.Annotation != 0)
						annHvo = args.Annotation;
					else
						return;		// Can't select nothing, so return.

					annoType = sda.get_ObjectProp(annHvo, kflidAnnotationType);
					annInstanceOfRAHvo = sda.get_ObjectProp(annHvo, kflidInstanceOf);
					// If we still haven't found a good analysis, return.
					if (annInstanceOfRAHvo == 0 || annoType != twficType)
						return;
				}
				m_idcPane.SelectAnnotation(annHvo);
			}
			else if (m_tabCtrl.SelectedIndex == ktpsRawText)
			{
				if (annHvo == 0)
					return;		// Can't select nothing, so return;

				// Select something in the RawTextPane
				m_bookmark.Save(annHvo, false);
				int hvoPara = sda.get_ObjectProp(annHvo, kflidBeginObject);
				int hvoStText = Cache.GetOwnerOfObject(hvoPara);
				m_rtPane.SelectAnnotation(hvoStText, hvoPara, annHvo);
			}
			else if (m_tabCtrl.SelectedIndex == ktpsTagging)
			{
				if (annHvo == 0)
					return;		// Can't select nothing, so return;

				TrySelectAnnotation(sda, m_taggingViewPane, annHvo);
			}
			else if (m_tabCtrl.SelectedIndex == ktpsPrint)
			{
				if (annHvo == 0)
					return;		// Can't select nothing, so return;

				TrySelectAnnotation(sda, m_printViewPane, annHvo);
			}
		}