/// ------------------------------------------------------------------------------------ /// <summary> /// When the client size changed we have to recalculate the average paragraph height /// </summary> /// <param name="e"></param> /// ------------------------------------------------------------------------------------ protected override void OnSizeChanged(EventArgs e) { base.OnSizeChanged(e); SelectionHelper selHelper = EditingHelper.CurrentSelection; if (selHelper == null) { return; } int paraIndex = selHelper.GetLevelForTag((int)StText.StTextTags.kflidParagraphs); int hvoPara = selHelper.LevelInfo[paraIndex].hvo; if (m_fdoCache.IsRealObject(hvoPara, StTxtPara.kClassId)) { // don't attempt a prop change for an empty paragraph StTxtPara para = new StTxtPara(m_fdoCache, hvoPara); if (para.Contents.Length != 0) { m_fdoCache.PropChanged(null, PropChangeType.kpctNotifyAll, hvoPara, (int)StTxtPara.StParaTags.kflidStyleRules, 0, 1, 1); } } selHelper.SetSelection(this, true, true); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Deletes a footnote /// </summary> /// <param name="args"></param> /// <returns><c>true</c> if we handle this</returns> /// ------------------------------------------------------------------------------------ protected bool OnDeleteFootnote(object args) { if (DataUpdateMonitor.IsUpdateInProgress(DataAccess)) { return(true); //discard this event } if (!ValidFootnoteSelection) { return(true); } string undo; string redo; TeResourceHelper.MakeUndoRedoLabels("kstidUndoDelFootnote", out undo, out redo); using (new UndoTaskHelper(this, undo, redo, false)) using (new DataUpdateMonitor(this, RootBox.DataAccess, this, "DeleteFootnote")) { SelectionHelper helper = SelectionHelper.Create(this); int fnLevel = helper.GetLevelForTag((int)ScrBook.ScrBookTags.kflidFootnotes); if (helper.Selection.IsRange) { DeleteFootnoteRange(helper); } else { // There's no range selection, so delete only one footnote ScrFootnote footnote = new ScrFootnote(m_fdoCache, helper.LevelInfo[fnLevel].hvo); ScrFootnote.DeleteFootnoteAndMarker(footnote); } if (RootBox.Height <= 0) { DraftView.Focus(); } else { int iBook = helper.LevelInfo[fnLevel + 1].ihvo; ScrBook book = m_bookFilter.GetBook(iBook); int iFootnote = helper.LevelInfo[fnLevel].ihvo; // If the last footnote in the book was deleted find a footnote to move to if (iFootnote >= book.FootnotesOS.Count) { FindNearestFootnote(ref iBook, ref iFootnote); } FootnoteEditingHelper.ScrollToFootnote(iBook, iFootnote, 0); } } return(true); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Deletes a footnote or footnotes within a text selection. /// </summary> /// ------------------------------------------------------------------------------------ protected void DeleteFootnoteAux() { SelectionHelper helper = SelectionHelper.Create(this); if (helper == null) { return; // Better then crashing :) } int fnLevel = helper.GetLevelForTag(ScrBookTags.kflidFootnotes); if (helper.Selection.IsRange) { DeleteFootnoteRange(helper); } else { // There's no range selection, so delete only one footnote IScrFootnote footnote = Cache.ServiceLocator.GetInstance <IScrFootnoteRepository>().GetObject(helper.LevelInfo[fnLevel].hvo); ((IScrBook)footnote.Owner).FootnotesOS.Remove(footnote); } if (RootBox.Height <= 0) { DraftView.Focus(); } else { int iBook = helper.LevelInfo[fnLevel + 1].ihvo; IScrBook book = m_bookFilter.GetBook(iBook); int iFootnote = helper.LevelInfo[fnLevel].ihvo; // If the last footnote in the book was deleted find a footnote to move to if (iFootnote >= book.FootnotesOS.Count) { FindNearestFootnote(ref iBook, ref iFootnote); } FootnoteEditingHelper.ScrollToFootnote(iBook, iFootnote, 0); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets Scripture reference for a selection /// </summary> /// <param name="helper">The selection helper that represents the selection</param> /// <param name="fInclusive"><c>true</c> if the reference returned should include the /// reference of the text of the verse where the selection is, even if that selection /// is not at the start of the verse; <c>false</c> if the reference should be that of /// the first full verse at or following the selection</param> /// <param name="scriptureRef">returns the scripture reference found</param> /// <returns>A TsString representing the reference of the selection, or null if the /// selection represents a book title or something weird.</returns> /// ------------------------------------------------------------------------------------ private ITsString GetSelectionReference(SelectionHelper helper, bool fInclusive, out BCVRef scriptureRef) { scriptureRef = new BCVRef(); if (helper != null && m_page.Publication != null && m_page.Publication is ScripturePublication) { int iParaLevel = helper.GetLevelForTag(StTextTags.kflidParagraphs); if (iParaLevel >= 0) { int hvo = helper.LevelInfo[iParaLevel].hvo; IScrTxtPara para = m_cache.ServiceLocator.GetInstance <IScrTxtParaRepository>().GetObject(hvo); // Look through the verses of the paragraph until we pass the location // where the page break occurs. This verse reference will then be the // first one on the page. ScrVerse firstVerseOnPage = null; int ichPageBreak = helper.IchAnchor; foreach (ScrVerse verse in para) { if (!fInclusive) { firstVerseOnPage = verse; } if (verse.VerseStartIndex > ichPageBreak || (verse.VerseStartIndex == ichPageBreak && !fInclusive)) { break; } if (fInclusive) { firstVerseOnPage = verse; } } ITsString tssBookName = GetBookName(helper); if (tssBookName != null) { ITsStrBldr bldr = tssBookName.GetBldr(); int cch = bldr.Length; if (firstVerseOnPage != null) { if (firstVerseOnPage.StartRef.Verse != 0) { bldr.Replace(cch, cch, " " + m_scr.ChapterVerseRefAsString(firstVerseOnPage.StartRef), null); } scriptureRef = firstVerseOnPage.StartRef; } return(bldr.GetString()); } //else //{ // // Probably no verses were found in the paragraph // IVwSelection sel = FindNextPara(helper); // helper = SelectionHelper.Create(sel, helper.RootSite); // return GetSelectionReference(helper, fInclusive, out scriptureRef); //} } } return(null); }
/// ------------------------------------------------------------------------------------ /// <summary> /// This is called by a view when the views code is about to delete a paragraph. We /// need to save the back translations by moving them to whatever paragraph the deleted /// one is merging with. /// </summary> /// <param name="selHelper">The selection helper</param> /// <param name="hvoObject">Paragraph to be deleted</param> /// <param name="hvoOwner">StText that owns the para</param> /// <param name="tag">flid in which para is owned</param> /// <param name="ihvo">index of paragraph in text</param> /// <param name="fMergeNext"><c>true</c> if this paragraph is merging with the /// following paragraph.</param> /// ------------------------------------------------------------------------------------ public virtual void AboutToDelete(SelectionHelper selHelper, int hvoObject, int hvoOwner, int tag, int ihvo, bool fMergeNext) { CheckDisposed(); if (tag != (int)StText.StTextTags.kflidParagraphs) { return; } StTxtPara paraToDelete = new StTxtPara(m_cache, hvoObject); // If the paragraph that is being deleted is empty, then do not attempt to save a back // translation for it. if (paraToDelete.Contents.Text == null) { return; } // ihvoTop is either the paragraph before the IP or the first paragraph in a range selection int ihvoTop = ihvo - 1; int hvoOwnerSurviving = hvoOwner; // Figure out what is being deleted and what is staying. // NOTE: it is possible that the selection is no longer valid. This is ok for our purposes here, // since all information we access here is already retrieved and stored in member variables of // SelectionHelper. if (selHelper.IsRange) { int paraLev = selHelper.GetLevelForTag(tag, SelectionHelper.SelLimitType.Top); SelLevInfo[] rgSelLevInfo = selHelper.GetLevelInfo(SelectionHelper.SelLimitType.Top); ihvoTop = rgSelLevInfo[paraLev].ihvo; if (paraLev + 1 < rgSelLevInfo.Length) { hvoOwnerSurviving = rgSelLevInfo[paraLev + 1].hvo; } int ihvoBottom = selHelper.GetLevelInfoForTag(tag, SelectionHelper.SelLimitType.Bottom).ihvo; // Pretty sure that if we get here top will NEVER equal bottom. Debug.Assert(ihvoTop != ihvoBottom || hvoOwnerSurviving != hvoOwner); if (hvoOwnerSurviving == hvoOwner) { if (ihvoTop == ihvoBottom) { return; } int ichEnd = selHelper.GetIch(SelectionHelper.SelLimitType.Bottom); // No need to merge because entire paragraph (with its contents) is going away. if (ihvo == ihvoBottom && ichEnd == paraToDelete.Contents.Length) { return; } // No need to merge because entire paragraph (with its contents) is going away. if (ihvo > ihvoTop && ihvo < ihvoBottom) { return; } } } // Determine the surviving paragraph. StText text = new StText(m_cache, hvoOwnerSurviving); StTxtPara paraSurviving; if (fMergeNext) { // when merging with next and there are no more paragraphs, then the BT can be discarded. if (text.ParagraphsOS.Count < ihvo + 1) { return; } // The surviving paragraph will be the one following the one that is deleted paraSurviving = (StTxtPara)text.ParagraphsOS[ihvo + 1]; } else { // If we are deleting the first paragraph in the surviving text, the BT should // also be deleted, so we're done. if (ihvo == 0 && hvoOwnerSurviving == hvoOwner) { return; } // The surviving paragraph will be the top one in the selection paraSurviving = (StTxtPara)text.ParagraphsOS[ihvoTop]; } ITsStrBldr bldr; ILgWritingSystemFactory wsf; List <int> writingSystems = GetWsList(out wsf); foreach (ICmTranslation transToDelete in paraToDelete.TranslationsOC) { // Find or create surviving translation of the same type. ICmTranslation transSurviving = paraSurviving.GetOrCreateTrans(transToDelete.TypeRA); // Merge back translations of the surviving and paragraph to be deleted for each writing system foreach (int ws in writingSystems) { TsStringAccessor tssAccToDelete = transToDelete.Translation.GetAlternative(ws); if (tssAccToDelete.Text != null) { TsStringAccessor tssAccSurviving = transSurviving.Translation.GetAlternative(ws); bldr = tssAccSurviving.UnderlyingTsString.GetBldr(); // If the surviving paragraph ends with white space of the paragraph to delete // begins with white space, add white space. string textSurviving = bldr.Text; ILgCharacterPropertyEngine charPropEng = m_cache.UnicodeCharProps; if (textSurviving != null && !charPropEng.get_IsSeparator(textSurviving[textSurviving.Length - 1]) && !charPropEng.get_IsSeparator(tssAccToDelete.Text[0])) { bldr.ReplaceRgch(textSurviving.Length, textSurviving.Length, " ", 1, null); } int cch = bldr.Length; bldr.ReplaceTsString(cch, cch, tssAccToDelete.UnderlyingTsString); tssAccSurviving.UnderlyingTsString = bldr.GetString(); } } } }