/// <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); }
/// <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. }
/// <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); }
//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(); }
/// <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(); }
/// <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); }
internal void SelectBookMark(InterAreaBookmark bookmark) { CheckDisposed(); MakeTextSelectionAndScrollToView(bookmark.BeginCharOffset, bookmark.EndCharOffset, 0, bookmark.IndexOfParagraph); }
/// <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 ); }
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. }
internal void SelectBookMark(InterAreaBookmark bookmark) { CheckDisposed(); MakeTextSelectionAndScrollToView(bookmark.BeginCharOffset, bookmark.EndCharOffset, 0, bookmark.IndexOfParagraph); }
/// <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; }