/// ------------------------------------------------------------------------------------ /// <summary> /// Initializes a new instance of the <see cref="FootnoteEditingHelper"/> class. /// </summary> /// <param name="callbacks">implementation of <see cref="IEditingCallbacks"/></param> /// <param name="cache">The cache for the DB connection</param> /// <param name="filterInstance">The special tag for the book filter</param> /// <param name="draftView">The corresponding draftview pane. If we determine that the /// "other pane" is supposed to be the other pane in the split window, then this /// should be used as the other pane as well.</param> /// <param name="viewType">Bit-flags indicating type of view.</param> /// <param name="app">The app.</param> /// ------------------------------------------------------------------------------------ public FootnoteEditingHelper(IEditingCallbacks callbacks, FdoCache cache, int filterInstance, FwRootSite draftView, TeViewType viewType, IApp app) : base(callbacks, cache, filterInstance, viewType, app) { m_draftView = draftView; if (m_draftView != null) // can be null for tests { m_draftViewEditingHelper = m_draftView.EditingHelper as TeEditingHelper; Debug.Assert(m_draftViewEditingHelper != null); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Initializes a new instance of the <see cref="FootnoteEditingHelper"/> class. /// </summary> /// <param name="callbacks">implementation of <see cref="IEditingCallbacks"/></param> /// <param name="cache">The cache for the DB connection</param> /// <param name="filterInstance">The special tag for the book filter</param> /// <param name="draftView">The corresponding draftview pane. If we determine that the /// "other pane" is supposed to be the other pane in the split window, then this /// should be used as the other pane as well.</param> /// <param name="isBacktranslation">if set to <c>true</c> we're dealing with /// backtranslations.</param> /// ------------------------------------------------------------------------------------ public FootnoteEditingHelper(IEditingCallbacks callbacks, FdoCache cache, int filterInstance, FwRootSite draftView, bool isBacktranslation) : base(callbacks, cache, filterInstance, TeViewType.FootnoteView | TeViewType.Horizontal | (isBacktranslation ? TeViewType.BackTranslation : TeViewType.Scripture)) { m_draftView = draftView; if (m_draftView != null) // can be null for tests { m_draftViewEditingHelper = m_draftView.EditingHelper as TeEditingHelper; Debug.Assert(m_draftViewEditingHelper != null); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Attempts to scroll to an annotation whose BeginObjectRAHvo is the same as the hvo /// of the paragraph where the anchor is in the specified editing helper's selection. /// </summary> /// <param name="editingHelper">The TE editing helper with information about the /// selection in the Scripture pane.</param> /// <param name="selectedText">The selected text or the word containing the IP if the /// selection is not a range.</param> /// <param name="fExactMatchOnly">if set to <c>true</c> then only scroll to a found /// note if the cited text is an exact match.</param> /// <returns></returns> /// ------------------------------------------------------------------------------------ private bool ScrollToAnnotationByPara(TeEditingHelper editingHelper, string selectedText, bool fExactMatchOnly) { if (editingHelper == null || editingHelper.CurrentSelection == null) return false; ScrReference scrRef = editingHelper.CurrentStartRef; SelLevInfo[] info = editingHelper.CurrentSelection.GetLevelInfo( SelectionHelper.SelLimitType.Anchor); if (info.Length == 0) return false; int bookHvo = m_scr.BookAnnotationsOS[scrRef.Book - 1].Hvo; int[] annHvos = ((ISilDataAccessManaged)m_rootb.DataAccess).VecProp(bookHvo, kCurrentNotesTag); if (annHvos.Length == 0) return false; int ich = editingHelper.CurrentSelection.IchAnchor; // Go through the annotations for the book and find the one whose // begin object is in the same as the selection's paragraph. for (int i = 0; i < annHvos.Length; i++) { IScrScriptureNote ann = Cache.ServiceLocator.GetInstance<IScrScriptureNoteRepository>().GetObject(annHvos[i]); if (ann.BeginObjectRA != null && ann.BeginObjectRA.Hvo == info[0].hvo) { // When matching on the cited text, allow for the possibility that the // begin offset is off by a little bit since leading spaces and/or ORCs // may have been trimmed and subsequent editing may have messed up the // offsets a little. int adjustedBeginOffset = ann.BeginOffset - (string.IsNullOrEmpty(ann.CitedText) ? 1 : ann.CitedText.Length); if ((!fExactMatchOnly && ich >= ann.BeginOffset && ich <= ann.EndOffset) || (ich >= adjustedBeginOffset && selectedText == ann.CitedText)) { m_vc.SelectedNoteHvo = ann.Hvo; NotesEditingHelper.MakeSelectionInNote(m_vc, scrRef.Book - 1, i, this, m_vc.IsExpanded(ann.Hvo)); return true; } } } return false; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Looks for any annotations in the curtrently filtered set whose reference range /// covers the given Scripture reference. Any such annotations are expanded and the /// first on is scrolled to near the top of the view. /// </summary> /// ------------------------------------------------------------------------------------ internal void ScrollRelevantAnnotationIntoView(TeEditingHelper editingHelper) { CheckDisposed(); Debug.Assert(editingHelper != null); if (editingHelper.BookIndex < 0) return; bool fSaveSendSyncScrollMsg = m_fSendSyncScrollMsg; try { m_fSendSyncScrollMsg = false; ScrReference scrRef = editingHelper.CurrentStartRef; if (!scrRef.Valid) return; // No valid reference to scroll to ITsString tss = editingHelper.GetCleanSelectedText(); string selectedText = (tss != null ? tss.Text : null); // If there's no range selection in scripture and the IP is in the // same reference as that of the current annotation, then don't scroll // to a different annotation, even if there is another one for the // same reference. if (selectedText == null && CurrentAnnotation != null && scrRef == CurrentAnnotation.BeginRef) { return; } selectedText = (selectedText ?? editingHelper.CleanSelectedWord); // Try to find the exact annotation associated with the selection. if (ScrollToAnnotationByPara(editingHelper, selectedText, CurrentAnnotation != null && scrRef == CurrentAnnotation.BeginRef)) { return; } // When the passed editing helper's selection is in a book title, section heading // or intro. material, then find the annotation for that selection's paragraph. if (editingHelper.InBookTitle || editingHelper.InSectionHead || editingHelper.InIntroSection) { if (ScrollToNonScrAnnotationByBook(scrRef.Book, selectedText)) return; } if (CurrentAnnotation == null || scrRef != CurrentAnnotation.BeginRef) ScrollRefIntoView(scrRef, selectedText); } finally { m_fSendSyncScrollMsg = fSaveSendSyncScrollMsg; } }
/// <summary>Constructor for filter object</summary> public InsertVerseMessageFilter(Control ctrl, TeEditingHelper helper) { m_control = ctrl; m_helper = helper; m_cMessageTimeBomb = 0; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Initializes a new instance of the <see cref="FocusMessageHandling"/> class. /// </summary> /// <param name="editingHelper">The editing helper.</param> /// ------------------------------------------------------------------------------------ public FocusMessageHandling(TeEditingHelper editingHelper) { m_editingHelper = editingHelper; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Syncs to location in Scripture. /// </summary> /// <param name="sender">The sender.</param> /// <param name="editingHelper">The editing helper of the scripture view in which /// the IP location changed.</param> /// <param name="fSendInternalOnly"><c>true</c> to indicate that this message should /// not be broadcast to external apps (e.g., Libronix and Santa Fe apps).</param> /// ------------------------------------------------------------------------------------ public void SyncToScrLocation(object sender, TeEditingHelper editingHelper, bool fSendInternalOnly) { Debug.Assert(editingHelper != null); if (m_fIgnoreAnySyncMessages || m_fProcessingSyncMessage) return; if (ScrEditingLocationChanged != null) ScrEditingLocationChanged(sender, editingHelper); ScrReference scrRef = new ScrReference(editingHelper.CurrentStartRef); if (!fSendInternalOnly && (scrRef.Valid || scrRef.IsBookTitle)) { SyncUsfmBrowser(new ScrReference(scrRef)); SendExternalSyncMessage(scrRef); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="fDisposeManagedObjs"><c>true</c> to release both managed and unmanaged /// resources; <c>false</c> to release only unmanaged resources.</param> /// ------------------------------------------------------------------------------------ private void Dispose(bool fDisposeManagedObjs) { if (fDisposeManagedObjs) { if (m_libronixLinker != null) { m_libronixLinker.PositionChanged -= m_eventHandler; m_libronixLinker.Dispose(); } } m_libronixLinker = null; m_eventHandler = null; m_editingHelper = null; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Scrolls to SCR editing location. /// </summary> /// <param name="sender">The sender.</param> /// <param name="editingHelper">The editing helper.</param> /// ------------------------------------------------------------------------------------ public void ScrollToScrEditingLocation(object sender, TeEditingHelper editingHelper) { NotesDataEntryView view = ActiveView as NotesDataEntryView; Debug.Assert(view != null); if (view != null && sender != view) view.ScrollRelevantAnnotationIntoView(editingHelper); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets a instance of the EditingHelper used to process editing requests. /// </summary> /// ------------------------------------------------------------------------------------ protected override EditingHelper GetInternalEditingHelper() { CheckDisposed(); TeEditingHelper result = new TeEditingHelper(this, m_cache, m_filterInstance, m_viewType); result.ContentType = ContentType; return result; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets a instance of the EditingHelper used to process editing requests. /// </summary> /// ------------------------------------------------------------------------------------ protected override RootSiteEditingHelper GetInternalEditingHelper() { TeEditingHelper helper = new TeEditingHelper(this, m_cache, m_filterInstance, m_viewType, m_app); helper.ContentType = ContentType; return helper; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets a non-range selection (i.e., a simple IP) in the vernacular corresponding to /// the current active selection. If the current selection is in the back translation, /// the position in the vernacular will be the begining of the current segment (in the /// vernacular). If the current selection is in a BT but not in a paragraph, this will /// return null. /// </summary> /// ------------------------------------------------------------------------------------ private static bool GetVernPosition(TeEditingHelper activeEditingHelper, out int iBook, out int iSection, out int iPara, out int ich, out int tag) { SelectionHelper selHelper = activeEditingHelper.GetSelectionReducedToIp( SelectionHelper.SelLimitType.Bottom); ILocationTracker tracker = ((ITeView)activeEditingHelper.Control).LocationTracker; iBook = tracker.GetBookIndex(selHelper, SelectionHelper.SelLimitType.Anchor); iSection = tracker.GetSectionIndexInBook(selHelper, SelectionHelper.SelLimitType.Anchor); ich = selHelper.IchAnchor; IStText text; IStTxtPara para = activeEditingHelper.GetPara(selHelper, out text, out iPara, out tag); if (para == null) return false; if (activeEditingHelper.IsBackTranslation) { if (activeEditingHelper.InSegmentedBt) ich = para.SegmentsOS[selHelper.LevelInfo[0].ihvo].BeginOffset; else { ISegment seg = para.GetSegmentForOffsetInFreeTranslation(ich, selHelper.Ws); ich = (seg == null ? 0 : seg.BeginOffset); } } return true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Attempts to navigate to a position in the back translation that closely corresponds /// to a place in the verncaular that has a footnote whose marker has not been inserted /// into the back translation. /// </summary> /// <param name="activeEditingHelper">Editing helper from the active draft view (could /// be either the vern or BT)</param> /// <returns>A value indicating whether or not it found a place to move to.</returns> /// ------------------------------------------------------------------------------------ public bool GoToNextMissingBtFootnoteMkr(TeEditingHelper activeEditingHelper) { int iBook, iSection, iPara, ich, tag; if (!GetVernPosition(activeEditingHelper, out iBook, out iSection, out iPara, out ich, out tag)) { return false; } int wsBt = IsBackTranslation ? ViewConstructorWS : ((IBtAwareView)Control).BackTranslationWS; FootnoteLocationInfo info; do { info = FindNextVernFootnote(iBook, iSection, iPara, ich, tag); if (info == null) return false; IScrBook book = BookFilter.GetBook(info.m_iBook); IStText stText; switch (info.m_tag) { case ScrBookTags.kflidTitle: stText = book.TitleOA; break; case ScrSectionTags.kflidContent: stText = book.SectionsOS[info.m_iSection].ContentOA; break; case ScrSectionTags.kflidHeading: stText = book.SectionsOS[info.m_iSection].HeadingOA; break; default: throw new Exception("Unexpected tag."); } IScrTxtPara para = (IScrTxtPara)stText.ParagraphsOS[info.m_iPara]; bool missingBtOrc = true; ICmTranslation trans = para.GetBT(); ITsString tssBt; if (trans != null && (tssBt = trans.Translation.get_String(wsBt)) != null) { int iRun = 0; int runCount = tssBt.RunCount; while (iRun < runCount) { if (TsStringUtils.GetHotObjectGuidFromProps(tssBt.get_Properties(iRun++)) == info.m_footnote.Guid) { missingBtOrc = false; break; } } } if (missingBtOrc) { if (InSegmentedBt) { int iSegment = GetBtSegIndexForVernChar(para, info.m_ich, wsBt); SelectRangeOfChars(info.m_iBook, info.m_iSection, info.m_tag, info.m_iPara, iSegment, 0, 0, true, true, false, VwScrollSelOpts.kssoDefault); } else { ich = para.GetBtPosition(info.m_ich, wsBt); SelectRangeOfChars(info.m_iBook, info.m_iSection, info.m_tag, info.m_iPara, ich, ich, true, true, false); } Control.Focus(); return true; } iBook = info.m_iBook; iSection = info.m_iSection; iPara = info.m_iPara; ich = info.m_ich; tag = info.m_tag; } while (true); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Syncs to the current Scripture reference location of the given editing helper. /// </summary> /// <param name="editingHelper">The editing helper.</param> /// <param name="fSendInternalOnly">if set to <c>true</c> does not send reference to /// third-party listeners.</param> /// ------------------------------------------------------------------------------------ public void SyncToScrLocation(TeEditingHelper editingHelper, bool fSendInternalOnly) { if (m_syncHandler != null) m_syncHandler.SyncToScrLocation(this, editingHelper, fSendInternalOnly); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Don't do base class initialization /// </summary> /// ------------------------------------------------------------------------------------ protected override void Init() { m_bookFilter = MockRepository.GenerateMock<FilteredScrBooks>(); m_mockedEditingHelper = MockRepository.GenerateMock<TeEditingHelper>(); }