Helper for keeping track of our location in the text when switching from and back to the Texts area (cf. LT-1543). It also serves to keep our place when switching between RawTextPane (Baseline), GlossPane, AnalyzePane(Interlinearizer), TaggingPane, PrintPane and ConstChartPane.
Inheritance: IStTextBookmark
Example #1
0
        /// <summary>
        /// Returns hvo of the CmBaseAnnotation corresponding to the given bookmark location in the text.
        /// </summary>
        /// <param name="bookmark"></param>
        /// <param name="fOnlyTWFIC">If true, we only search in TWFIC annotations, otherwise we
        /// search for a match in TextSegments also.</param>
        /// <returns></returns>
        static public int AnnotationHvo(FdoCache cache, IStText stText, InterAreaBookmark bookmark, bool fOnlyTWFIC)
        {
            if (bookmark.IndexOfParagraph < 0 || stText == null ||
                bookmark.IndexOfParagraph >= stText.ParagraphsOS.Count)
            {
                return(0);
            }
            IStTxtPara para        = stText.ParagraphsOS[bookmark.IndexOfParagraph] as IStTxtPara;
            bool       fExactMatch = false;
            int        hvoAnn      = FindAnnotationHvoForStTxtPara(cache, para.Hvo,
                                                                   bookmark.BeginCharOffset, bookmark.EndCharOffset, fOnlyTWFIC, out fExactMatch);

            return(hvoAnn);
        }
Example #2
0
		/// <summary>
		/// Try to get the bookmark from InterlinMaster, if there are rows in the chart.
		/// </summary>
		private void GetAndScrollToBookmark()
		{
			if (m_chart.RowsOS.Count <= 0)
			{
				// Reset bookmark to prevent LT-12666
				if (m_bookmark != null && m_mediator != null)
					m_bookmark.Reset(m_chart.BasedOnRA.IndexInOwner, m_mediator);
				return;
			}
			// no rows in chart; no selection necessary
			m_bookmark = GetAncestorBookmark(this, m_chart.BasedOnRA);
			m_logic.RaiseRibbonChgEvent();
			// This will override bookmark if there is a ChOrph to be inserted first.
			if (m_logic.IsChOrphActive)
				return;
			if (m_bookmark != null && m_bookmark.IndexOfParagraph >= 0)
				m_body.SelectAndScrollToBookmark(m_bookmark);
			else if (!m_logic.IsChartComplete)
				ScrollToEndOfChart();
			// Hopefully the 'otherwise' will automatically display chart at top.
		}
Example #3
0
		/// <summary>
		/// This public version enables call by reflection from InterlinMaster of the internal CCBody
		/// method that selects (and scrolls to) the bookmarked location in the constituent chart.
		/// </summary>
		/// <param name="bookmark"></param>
		public void SelectAndScrollToBookmark(InterAreaBookmark bookmark)
		{
			m_body.SelectAndScrollToBookmark(bookmark);
		}
Example #4
0
		//void m_buttonRow_Layout(object sender, LayoutEventArgs e)
		//{
		//    int numColWidth;
		//    using (Graphics g = m_buttonRow.CreateGraphics())
		//    {
		//        numColWidth = (int)(m_body.NumColWidth * g.DpiX / 72000);
		//    }
		//    int remainingWidth = m_buttonRow.Width - numColWidth;
		//    int remainingButtons = m_buttonRow.Controls.Count;
		//    if (remainingButtons == 0)
		//        return;
		//    // compute column width
		//    int colWidth = remainingWidth / m_allColumns.Length;
		//    int arrowIconWidth = 10;
		//    int widthBtnContextMenu = arrowIconWidth + 10;
		//    int widthBtnMoveHere = colWidth - widthBtnContextMenu;
		//    int ibutton = 0;
		//    int left = numColWidth;
		//    while (remainingButtons > 0)
		//    {
		//        Control c = m_buttonRow.Controls[ibutton];
		//        int widthBtn = 0;
		//        // MoveHere buttons are even, Context Menu's are odd.
		//        if (remainingButtons % 2 == 0)
		//            widthBtn = widthBtnMoveHere;
		//        else
		//            widthBtn = widthBtnContextMenu;
		//        c.Width = widthBtn;
		//        c.Left = left;
		//        left += widthBtn;
		//        remainingWidth -= widthBtn;
		//        ibutton++;
		//        remainingButtons--;
		//    }
		//}

		/// <summary>
		/// Set the root object. This is called by reflection when the InterlinMaster determines that
		/// the root object has changed.
		/// </summary>
		/// <param name="hvoStText"></param>
		public void SetRoot(int hvoStText)
		{
			int oldTemplateHvo = 0;
			if (m_template != null)
				oldTemplateHvo = m_template.Hvo;
			// does it already have a chart? If not make one.
			m_chart = null; // in case of previous call.
			if (m_cache.LangProject.DiscourseDataOA == null)
			{
				m_template = m_cache.LangProject.GetDefaultChartTemplate();
			}
			string sColName; // Holds column name while setting buttons
			if (hvoStText != 0)
			{
				FdoOwningSequence<ICmPossibility> templates = m_cache.LangProject.DiscourseDataOA.ConstChartTemplOA.PossibilitiesOS;
				if (templates.Count == 0 || templates[0].SubPossibilitiesOS.Count == 0)
				{
					MessageBox.Show(this, DiscourseStrings.ksNoColumns, DiscourseStrings.ksWarning,
						MessageBoxButtons.OK, MessageBoxIcon.Warning);
				}
				if (templates.Count != 1)
				{
					MessageBox.Show(this, DiscourseStrings.ksOnlyOneTemplateAllowed, DiscourseStrings.ksWarning,
						MessageBoxButtons.OK, MessageBoxIcon.Warning);
				}
				// Text should already have been parsed. However, for the ribbon to work right,
				// we need all the annotations to be real.
				MakeAllAnnotationsReal(hvoStText);
				// We need to make or set the chart before calling NextUnusedInput.
				FindAndCleanUpMyChart(hvoStText); // Sets m_chart if it finds one for hvoStText
				if (m_chart == null)
				{
					m_chart = new DsConstChart();
					m_cache.LangProject.DiscourseDataOA.ChartsOC.Add(m_chart);
					m_chart.BasedOnRAHvo = hvoStText;
					// set a template.
					m_chart.TemplateRA = m_cache.LangProject.GetDefaultChartTemplate();
				}
				m_logic.Chart = m_chart;
				int[] unchartedAnnotations = DiscourseDbOps.NextUnusedInput(m_cache, hvoStText, 20, m_chart.Hvo);
				m_cache.VwCacheDaAccessor.CacheVecProp(hvoStText, m_ribbon.AnnotationListId, unchartedAnnotations,
					unchartedAnnotations.Length);
				// Don't need PropChanged here, ribbon will reconsruct. That is safer, since clearing
				// cache may have changed old object count.
				if (m_logic.StTextHvo != 0 && hvoStText != m_logic.StTextHvo)
				{
					EnableAllContextButtons();
					EnableAllMoveHereButtons();
					m_logic.ResetRibbonLimits();
					m_logic.CurrHighlightCells = null; // Should reset highlighting (w/PropChanged)
				}
			}
			m_ribbon.SetRoot(hvoStText);
			if (hvoStText != 0)
			{
				if (m_chart.TemplateRA == null) // LT-8700: if original template is deleted we might need this
					m_chart.TemplateRA = m_cache.LangProject.GetDefaultChartTemplate();
				m_template = m_chart.TemplateRA;
				m_logic.StTextHvo = hvoStText;
				m_allColumns = m_logic.AllColumns(m_chart.TemplateRA).ToArray();
			}
			else
			{
				// no text, so no chart
				m_logic.Chart = null;
				m_logic.StTextHvo = 0;
				m_allColumns = new int[0];
			}
			if (m_template != null && m_template.Hvo != oldTemplateHvo)
			{
				m_fInColWidthChanged = true;
				try
				{
					m_logic.MakeMainHeaderCols(m_headerMainCols);
					if (m_allColumns == null)
						return;
					int ccolsWanted = m_allColumns.Length + ConstituentChartLogic.NumberOfExtraColumns;
					m_columnWidths = new int[ccolsWanted];
					m_columnPositions = new int[ccolsWanted + 1]; // one extra for right of last column
					if (!RestoreColumnWidths())
					{
						SetDefaultColumnWidths();
					}
				}
				finally
				{
					m_fInColWidthChanged = false;
				}
			}
			if (m_chart != null)
			{
				m_body.SetRoot(m_chart.Hvo, m_allColumns);

				// Try to get the bookmark from InterlinMaster, if there are rows in the chart.
				if (m_chart.RowsRS.Count > 0)
				{
					m_bookmark = GetAncestorBookmark(this);
					m_logic.RaiseRibbonChgEvent(); // This will override bookmark if there is a ChOrph to be inserted first.
					if (!m_logic.IsChOrphActive)
					{
						if (m_bookmark != null && m_bookmark.IndexOfParagraph >= 0)
						{
							m_body.SelectAndScrollToBookmark(m_bookmark);
						}
						else if (!m_logic.IsChartComplete)
							ScrollToEndOfChart(); // Hopefully the 'otherwise' will automatically display chart at top.
					}
				} // else = no rows in chart; no selection necessary
			} else
				m_body.SetRoot(0, null);

			// If necessary adjust number of buttons
			if (m_MoveHereButtons.Count != m_allColumns.Length)
			{
				m_buttonRow.SuspendLayout();
				while (m_MoveHereButtons.Count > m_allColumns.Length)
				{
					// Remove MoveHere button
					Button lastButton = m_MoveHereButtons[m_MoveHereButtons.Count - 1];
					lastButton.Click -= new EventHandler(btnMoveHere_Click);
					m_buttonRow.Controls.Remove(lastButton);
					m_MoveHereButtons.Remove(lastButton);

					// Remove Context Menu button
					Button lastBtnContextMenu = m_ContextMenuButtons[m_ContextMenuButtons.Count - 1];
					lastBtnContextMenu.Click -= new EventHandler(btnContextMenu_Click);
					m_buttonRow.Controls.Remove(lastBtnContextMenu);
					m_ContextMenuButtons.Remove(lastBtnContextMenu);
				}
				int btnSpace; // useable pixel length on button

				while (m_MoveHereButtons.Count < m_allColumns.Length)
				{
					// Install MoveHere button
					Button newButton = new Button();
					newButton.Click += new EventHandler(btnMoveHere_Click);
					sColName = m_logic.GetColumnLabel(m_MoveHereButtons.Count);
					m_buttonRow.Controls.Add(newButton);
					// Enhance GordonM: This should deal in pixel length, not character length.
					// And column width needs to be known!
					newButton.Image = SIL.FieldWorks.Resources.ResourceHelper.MoveUpArrowIcon;
					newButton.ImageAlign = ContentAlignment.MiddleRight;

					// useable space is button width less (icon width * 2) because of centering
					btnSpace = newButton.Width - (newButton.Image.Size.Width * 2);
					newButton.TextAlign = ContentAlignment.MiddleCenter;
					newButton.Text = GetBtnName(sColName, btnSpace);

					// Set up the ToolTip text for the Button.
					m_toolTip.SetToolTip(newButton, String.Format(DiscourseStrings.ksMoveHereToolTip, sColName));

					m_MoveHereButtons.Add(newButton);

					// Install context menu button
					Button newBtnContextMenu = new Button();
					newBtnContextMenu.Click += new EventHandler(btnContextMenu_Click);
					newBtnContextMenu.Image = SIL.FieldWorks.Resources.ResourceHelper.ButtonMenuArrowIcon;
					m_buttonRow.Controls.Add(newBtnContextMenu);
					m_ContextMenuButtons.Add(newBtnContextMenu);
				}
				// To handle Refresh problem where buttons aren't set to match ChOrph state,
				// raise Ribbon changed event again here
				m_fContextMenuButtonsEnabled = true; // the newly added buttons will be enabled
				m_logic.RaiseRibbonChgEvent();
				m_buttonRow.ResumeLayout();
			}
			SetHeaderColWidths();
		}
Example #5
0
		/// <summary>
		/// Selects and scrolls to the bookmarked location in the constituent chart.
		/// </summary>
		/// <param name="bookmark"></param>
		internal void SelectAndScrollToBookmark(InterAreaBookmark bookmark)
		{
			CheckDisposed();

			Debug.Assert(bookmark != null);
			Debug.Assert(bookmark.IndexOfParagraph >= 0);

			if (m_chart == null || m_logic.Chart.RowsRS.Count < 1)
				return; // nothing to do (and leave the bookmark alone)

			// Gets the Twfic annotation that is closest to the bookmark in the text
			int annHvo = m_logic.FindAnnAtBookmark(bookmark);
			if (annHvo < 1)
			{
				Debug.Assert(annHvo > 0, "Unable to find annotation close to bookmark");
				return;
			}
			ChartLocation chartLoc = m_logic.FindChartLocOfWfic(annHvo);
			if (chartLoc != null && chartLoc.IsValidLocation)
			{
				SelectAndScrollToLoc(chartLoc, true);
				return;
			}
			// Otherwise, Bookmark is for a Twfic that is not yet charted.
			m_chart.ScrollToEndOfChart();
		}
Example #6
0
		/// <summary>
		/// Selects and scrolls to the bookmarked location in the constituent chart.
		/// </summary>
		/// <param name="bookmark"></param>
		internal void SelectAndScrollToBookmark(InterAreaBookmark bookmark)
		{
			CheckDisposed();

			Debug.Assert(bookmark != null);
			Debug.Assert(bookmark.IndexOfParagraph >= 0);

			if (m_chart == null || m_logic.Chart.RowsOS.Count < 1)
				return; // nothing to do (and leave the bookmark alone)

			// Gets the wordform that is closest to the bookmark in the text
			var occurrence = m_logic.FindWordformAtBookmark(bookmark);
			SelectAndScrollToAnalysisOccurrence(occurrence);
		}
Example #7
0
 internal void SelectBookMark(InterAreaBookmark bookmark)
 {
     CheckDisposed();
     MakeTextSelectionAndScrollToView(bookmark.BeginCharOffset, bookmark.EndCharOffset, 0, bookmark.IndexOfParagraph);
 }
Example #8
0
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			//Debug.WriteLineIf(!disposing, "****************** " + GetType().Name + " 'disposing' is false. ******************");
			// Must not be run more than once.
			if (IsDisposed)
				return;

			if( disposing )
			{
				SuspendLayout();	// don't want do trigger OnLayout() when removing controls!
				DestroyTitleContentsPane();
				if (m_tabCtrl != null)
					m_tabCtrl.SelectedIndexChanged -= new System.EventHandler( m_tabCtrl_SelectedIndexChanged);
				DisposeInterlinDocPanes();
				DisposeIfParentNull(m_panelInterlin);
				DisposeIfParentNull(m_rtPane);
				DisposeIfParentNull(m_infoPane);

				if(components != null)
				{
					components.Dispose();
				}
				// LT-5702
				// The Find / Replace dlg can currently only exist in this view, so
				// remove it when the view changes.  This will have to be expanded
				// when the dlg can search and operate on more than one view in Flex
				// as it does in TE.
				if (FwApp.App != null)
					FwApp.App.RemoveFindReplaceDialog();
			}

			m_tcPane = null;
			m_infoPane = null;
			m_rtPane = null;
			m_constChartPane = null;
			ClearInterlinDocPaneVariables();
			m_panelInterlin = null;
			m_panelTagging = null;
			m_panelPrintView = null;
			m_bookmark = null;

			base.Dispose( disposing );
		}
Example #9
0
		protected override void ShowRecord()
		{
			base.ShowRecord ();
			if (Clerk.SuspendLoadingRecordUntilOnJumpToRecord)
				return;
			if (m_bookmark == null)
				m_bookmark = new InterAreaBookmark(this, m_mediator, Cache);
			if (IsPersistedForAnInterlinearTabPage) // can be true from work in another instance
				MakeInterlinPane(); // does nothing if already made.
			// It's important not to do this if there is a filter, as there's a good chance the new
			// record doesn't pass the filter and we get into an infinite loop. Also, if the user
			// is filtering, he probably just wants to see that there are no matching texts, not
			// make a new one.
			if (Clerk.CurrentObject == null && !m_fSuppressAutoCreate && !Clerk.ShouldNotModifyList
				&& Clerk.Filter == null)
			{
				// first clear the views of their knowledge of the previous text.
				// otherwise they could crash trying to access information that is no longer valid. (LT-10024)
				SwitchText(0);

				// Presumably because there are none..make one.
				// This is invisible to the user so it should not be undoable; that is particularly
				// important if the most recent action was to delete the last text, which will
				// not be undoable if we are now showing 'Undo insert text'.
				using (new SuppressSubTasks(Cache))
				{
					bool fWasSuppressed = Clerk.SuppressSaveOnChangeRecord;
					try
					{
						// We don't want to force a Save here if we just deleted the last text;
						// we want to be able to Undo deleting it!
						Clerk.SuppressSaveOnChangeRecord = true;
						Clerk.InsertItemInVector("StText");
					}
					finally
					{
						Clerk.SuppressSaveOnChangeRecord = fWasSuppressed;
					}
				}
			}
			if (Clerk.CurrentObject == null)
			{
				SwitchText(0);		// We no longer have a text.
				return;				// We get another call when there is one.
			}
			int hvoRoot = Clerk.CurrentObject.Hvo;
			int clsid = Cache.GetClassOfObject(hvoRoot);
			int hvoStText = 0;
			if (clsid == CmBaseAnnotation.kClassId)	// RecordClerk is tracking the annotation
			{
				// 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 annHvo = hvoRoot;
				if (!m_fRefreshOccurred)
					m_bookmark.Save(annHvo, false);
				int hvoPara = Cache.MainCacheAccessor.get_ObjectProp(annHvo, kflidBeginObject);
				hvoStText = hvoRoot = Cache.GetOwnerOfObject(hvoPara);
				if (m_rtPane != null)
					m_rtPane.SetRoot(hvoRoot);
				if (m_constChartPane != null)
					SetConstChartRoot(hvoRoot);
			}
			else
			{
				//FDO.IText text = new Text(Cache, hvoRoot);
				//// If the text is empty...typically newly created...make it an StText and an
				//// empty paragraph in the right WS.
				//if (text.ContentsOA == null)
				//    text.ContentsOA = new StText();
				IStText stText = new StText(Cache, hvoRoot);
				if (stText.ParagraphsOS.Count == 0)
				{
					IStTxtPara txtPara = new StTxtPara();
					stText.ParagraphsOS.Append(txtPara);
					int wsText = (Clerk as InterlinearTextsRecordClerk).PrevTextWs;
					if (wsText != 0)
					{
						// Establish the writing system of the new text by filling its first paragraph with
						// an empty string in the proper writing system.
						if (Cache.LangProject.VernWssRC.Count > 1 && !Cache.AddAllActionsForTests)
						{
							using (ChooseTextWritingSystemDlg dlg = new ChooseTextWritingSystemDlg())
							{
								dlg.Initialize(Cache, wsText);
								dlg.ShowDialog();
								wsText = dlg.TextWs;
							}
						}
						(Clerk as InterlinearTextsRecordClerk).PrevTextWs = 0;
					}
					else
					{
						wsText = Cache.DefaultVernWs;
					}
					ITsStrFactory tsf = TsStrFactoryClass.Create();
					Cache.MainCacheAccessor.SetString(txtPara.Hvo,
						(int)StTxtPara.StTxtParaTags.kflidContents,
						tsf.MakeString("", wsText));
					// since we have a new text, we should switch to the Baseline tab.
					// ShowMainView() will adjust the tab control appropriately.
					this.InterlinearTab = TabPageSelection.RawText;
				}

				if (m_tcPane != null)
					m_tcPane.SetRoot(hvoRoot);
				if (m_rtPane != null)
					m_rtPane.SetRoot(hvoRoot);

				if (m_hvoStText == 0)
				{
					// we've just now entered the area, so try to restore a bookmark.
					m_bookmark.Restore();
				}
				else if (m_hvoStText != hvoRoot)
				{
					// we've switched texts, so reset our bookmark.
					m_bookmark.Reset();
				}
			}

			if (m_hvoStText != hvoRoot)
			{
				SwitchText(hvoRoot);
			}
			else
				SelectAnnotation(); // select an annotation in the current text.

			// This takes a lot of time, and the view is never visible by now, and it gets done
			// again when made visible! So don't do it!
			//m_idcPane.SetRoot(hvoRoot);

			// If we're showing the raw text pane make sure it has a selection.
			if (Controls.IndexOf(m_rtPane) >= 0 && m_rtPane.RootBox.Selection == null)
				m_rtPane.RootBox.MakeSimpleSel(true, false, false, true);

			UpdateContextHistory();
			m_fRefreshOccurred = false;	// reset our flag that a refresh occurred.
		}
Example #10
0
		internal void SelectBookMark(InterAreaBookmark bookmark)
		{
			CheckDisposed();
			MakeTextSelectionAndScrollToView(bookmark.BeginCharOffset, bookmark.EndCharOffset, 0, bookmark.IndexOfParagraph);
		}
Example #11
0
		/// <summary>
		/// Returns hvo of the CmBaseAnnotation corresponding to the given bookmark location in the text.
		/// </summary>
		/// <param name="bookmark"></param>
		/// <param name="fOnlyTWFIC">If true, we only search in TWFIC annotations, otherwise we
		/// search for a match in TextSegments also.</param>
		/// <returns></returns>
		static public int AnnotationHvo(FdoCache cache, IStText stText, InterAreaBookmark bookmark, bool fOnlyTWFIC)
		{
			if (bookmark.IndexOfParagraph < 0 || stText == null ||
				bookmark.IndexOfParagraph >= stText.ParagraphsOS.Count)
				return 0;
			IStTxtPara para = stText.ParagraphsOS[bookmark.IndexOfParagraph] as IStTxtPara;
			bool fExactMatch = false;
			int hvoAnn = FindAnnotationHvoForStTxtPara(cache, para.Hvo,
					bookmark.BeginCharOffset, bookmark.EndCharOffset, fOnlyTWFIC, out fExactMatch);
			return hvoAnn;
		}