/// ------------------------------------------------------------------------------------
/// <summary>
/// Determines whether this reference range overlaps the range specified by the given
/// start and end reference
/// </summary>
/// <param name="start">Start reference</param>
/// <param name="end">End Reference</param>
/// <returns>true if there is any overlap</returns>
/// ------------------------------------------------------------------------------------
public bool OverlapsRange(ScrReference start, ScrReference end)
{
// If the book number is completely contained by the start and end reference
// then it definitely overlaps.
if (Book > start.Book && Book < end.Book)
return true;
int startChapter, endChapter;
if (Book == start.Book)
{
startChapter = start.Chapter;
endChapter = (start.Book == end.Book) ? end.Chapter : start.LastChapter;
}
else if (Book == end.Book)
{
startChapter = 1;
endChapter = end.Chapter;
}
else
return false;
return (StartChapter <= endChapter && EndChapter >= startChapter);
}
/// ------------------------------------------------------------------------------------
/// <summary>
/// Loop through the runs of the given string until a verse or chapter number is
/// found. Update the start and end reference with the found number.
/// </summary>
/// <param name="iStart">Index of run to start search</param>
/// <param name="iLim">Index of run to end search.
/// One exception: if the run at iLim-1 is a chapter, we will go one run further (at the
/// iLim) to check for an adjacent verse number.</param>
/// <param name="tss">The string</param>
/// <param name="fIgnoreErrors"><c>true</c> to ignore runs with errors, <c>false</c>
/// to throw an exception if we encounter a invalid chapter or verse number.</param>
/// <param name="refStart">Start reference</param>
/// <param name="refEnd">End reference</param>
/// <param name="iNext">Index of run after last one processed (i.e. iCurr+1)</param>
/// <exception cref="T:System.ArgumentException">Invalid chapter number</exception>
/// ------------------------------------------------------------------------------------
public static RefRunType GetNextRef(int iStart, int iLim, ITsString tss,
bool fIgnoreErrors, ref ScrReference refStart, ref ScrReference refEnd, out int iNext)
{
Debug.Assert(iStart >= 0 && iStart < iLim);
Debug.Assert(iLim <= tss.RunCount);
// look at all of the text runs in this paragraph starting at
int iRun = iStart;
try
{
for (; iRun < iLim; iRun++)
{
TsRunInfo runInfo;
string style = tss.FetchRunInfo(iRun, out runInfo).Style();
if (style == ScrStyleNames.VerseNumber)
{
// for verse number runs, get the verse range and save it
int startVerse, endVerse;
ScrReference.VerseToInt(tss.get_RunText(iRun), out startVerse, out endVerse);
if (startVerse <= 0)
{
if (fIgnoreErrors)
continue;
throw new InvalidVerseException(tss.get_RunText(iRun), runInfo);
}
if (startVerse <= refStart.LastVerse)
{
refStart.Verse = startVerse;
refEnd.Verse = Math.Min(refEnd.LastVerse, endVerse);
}
iNext = iRun + 1;
return RefRunType.Verse;
}
if (style == ScrStyleNames.ChapterNumber)
{
int chapter = -1;
try
{
// for chapter number runs, get the chapter number and save it
chapter = ScrReference.ChapterToInt(tss.get_RunText(iRun));
}
catch (ArgumentException)
{
if (fIgnoreErrors)
continue;
throw new InvalidChapterException(tss.get_RunText(iRun), runInfo);
}
Debug.Assert(chapter > 0); // should have thrown exception in ScrReference.ChapterToInt
// if chapter is valid for this book...
if (chapter <= refStart.LastChapter)
{
refStart.Chapter = refEnd.Chapter = chapter;
refStart.Verse = refEnd.Verse = 1; // implicit default
}
iNext = iRun + 1; // increment just beyond the chapter
// Because we've found a chapter, check the very next run (if we can)
// to see if it is a verse.
if (iNext < tss.RunCount && iNext < iLim + 1) // it's ok to check at iLim in this special case
{
int dummy;
ScrReference startTemp = new ScrReference(refStart);
ScrReference endTemp = new ScrReference(refEnd);
RefRunType nextItemType = GetNextRef(iNext, iNext + 1, tss, fIgnoreErrors,
ref startTemp, ref endTemp, out dummy);
// if it is a verse, update refStart/refEnd
if (nextItemType == RefRunType.Verse)
{
refStart = startTemp;
refEnd = endTemp;
iNext++;
return RefRunType.ChapterAndVerse;
}
}
// Otherwise, since a verse didn't immediatly follow, verse 1 is implicit
// so use it as the refStart/RefEnd
return RefRunType.Chapter;
}
}
iNext = iLim;
//.........这里部分代码省略.........
/// ------------------------------------------------------------------------------------
/// <summary>
/// Initialize the scripture importer
/// </summary>
/// ------------------------------------------------------------------------------------
protected void Initialize()
{
m_wsAnal = m_cache.DefaultAnalWs;
m_wsVern = m_cache.DefaultVernWs;
m_wsPara = m_cache.DefaultVernWs;
m_scr = m_cache.LangProject.TranslatedScriptureOA;
InitInterpretFootnoteSettings();
ScrImportSet importSettings = (m_settings as ScrImportSet);
// ENHANCE (TomB): Might want to make it possible to end importing in the middle
// of a book someday.
ScrReference endRef = new ScrReference(importSettings.EndRef, m_scr.Versification);
ScrReference startRef = new ScrReference(importSettings.StartRef, m_scr.Versification);
m_nBookNumber = importSettings.StartRef.Book;
importSettings.EndRef = endRef = endRef.LastReferenceForBook;
// Initialize scripture object
InitScriptureObject();
// Load the scripture text project & enum
LoadScriptureProject();
// Display progress if one was supplied
if (m_importCallbacks.IsDisplayingUi)
{
int cChapters = ScrReference.GetNumberOfChaptersInRange(SOWrapper.BooksPresent,
startRef, endRef);
int nMax = m_settings.ImportTranslation ? cChapters : 0;
if (SOWrapper.HasNonInterleavedBT && m_settings.ImportBackTranslation)
nMax += cChapters;
if (SOWrapper.HasNonInterleavedNotes && m_settings.ImportAnnotations)
nMax += cChapters;
m_importCallbacks.Maximum = nMax;
}
// Init our set of style proxies
LoadImportMappingProxies();
// Init member vars special paragraph style proxies, used as fallbacks in case
// import data lacks a paragraph style.
// For now we always use the default vernacular writing system. This may change
// when we are able to import paratext project proxies with multiple
// domains (vern, back transl, notes)
m_BookTitleParaProxy = new ImportStyleProxy(ScrStyleNames.MainBookTitle,
StyleType.kstParagraph, m_wsVern, ContextValues.Title, m_styleSheet);
Debug.Assert(m_BookTitleParaProxy.Context == ContextValues.Title);
m_ScrSectionHeadParaProxy = new ImportStyleProxy(ScrStyleNames.SectionHead,
StyleType.kstParagraph, m_wsVern, ContextValues.Text, m_styleSheet);
m_DefaultIntroSectionHeadParaProxy = new ImportStyleProxy(ScrStyleNames.IntroSectionHead,
StyleType.kstParagraph, m_wsVern, ContextValues.Intro, m_styleSheet);
m_DefaultScrParaProxy = new ImportStyleProxy(ScrStyleNames.NormalParagraph,
StyleType.kstParagraph, m_wsVern, ContextValues.Text, m_styleSheet);
m_DefaultIntroParaProxy = new ImportStyleProxy(ScrStyleNames.IntroParagraph,
StyleType.kstParagraph, m_wsVern, ContextValues.Intro, m_styleSheet);
m_DefaultFootnoteParaProxy = new ImportStyleProxy(ScrStyleNames.NormalFootnoteParagraph,
StyleType.kstParagraph, m_wsVern, ContextValues.Note, m_styleSheet);
m_DefaultAnnotationStyleProxy = new ImportStyleProxy(ScrStyleNames.Remark,
StyleType.kstParagraph, m_wsAnal, ContextValues.Annotation, m_styleSheet);
// Make a paragraph builder. We will keep re-using this every time we build a paragraph.
m_ParaBldr = new StTxtParaBldr(m_cache);
// Handle the case where the very first marker (after the \id line) is a
// character style.
m_ParaBldr.ParaStylePropsProxy = m_DefaultIntroParaProxy;
// Build generic character props for use with different runs of text and analysis
// character properties
ITsPropsBldr tsPropsBldr = TsPropsBldrClass.Create();
// analysis character properties
tsPropsBldr.SetIntPropValues((int)FwTextPropType.ktptWs, 0, m_wsAnal);
m_analTextProps = tsPropsBldr.GetTextProps();
// vernacular character properties
tsPropsBldr.SetIntPropValues((int)FwTextPropType.ktptWs, 0, m_wsVern);
m_vernTextProps = tsPropsBldr.GetTextProps();
// Get a reference to the annotation definition of translator notes (to use as default note type)
m_scrTranslatorAnnotationDef = new CmAnnotationDefn(m_cache, LangProject.kguidAnnTranslatorNote);
}
/// ------------------------------------------------------------------------------------
/// <summary>
/// Attempts to find the specified text in the given verse and return the character
/// offsets (relative to the whole paragraph) to allow it to be selected.
/// </summary>
/// <param name="scr">The scripture.</param>
/// <param name="tssTextToFind">The text to search for</param>
/// <param name="scrRef">The reference of the verse in which to look</param>
/// <param name="fMatchWholeWord">True to match to a whole word, false to just look
/// for the specified text</param>
/// <param name="iSection">Index of the section where the text was found.</param>
/// <param name="iPara">Index of the para in the section contents.</param>
/// <param name="ichStart">if found, the character offset from the start of the para to
/// the start of the sought text</param>
/// <param name="ichEnd">if found, the character offset from the start of the para to
/// the end of the sought text</param>
/// <returns>
/// <c>true</c> if found; <c>false</c> otherwise
/// </returns>
/// ------------------------------------------------------------------------------------
public static bool FindTextInVerse(IScripture scr, ITsString tssTextToFind, ScrReference scrRef,
bool fMatchWholeWord, out int iSection, out int iPara, out int ichStart, out int ichEnd)
{
// Get verse text
int verseStart;
List<VerseTextSubstring> verseTextList = GetVerseText(scr, scrRef, out verseStart);
foreach (VerseTextSubstring verseText in verseTextList)
{
// Search for word form in verse text
if (StringUtils.FindTextInString(tssTextToFind, verseText.Tss,
scr.Cache.LanguageWritingSystemFactoryAccessor, fMatchWholeWord, out ichStart, out ichEnd))
{
ichStart += verseStart;
ichEnd += verseStart;
iSection = verseText.SectionIndex;
iPara = verseText.ParagraphIndex;
return true;
}
verseStart = 0;
}
ichStart = ichEnd = iSection = iPara = -1;
return false;
}
/// ------------------------------------------------------------------------------------
/// <summary>
/// Selects text in the given verse.
/// </summary>
/// <param name="scrRef">The Scripture reference of the verse.</param>
/// <param name="text">The specific text within the verse to look for (<c>null</c> to
/// select the text of the entire verse.</param>
/// <remarks>
/// REVIEW (TE-4218): Do we need to add a parameter to make it possible to do a case-
/// insensitive match?
/// </remarks>
/// ------------------------------------------------------------------------------------
public void SelectVerseText(ScrReference scrRef, ITsString text)
{
SelectVerseText(scrRef, text, true);
}
/// ------------------------------------------------------------------------------------
/// <summary>
/// Look for the given picture's ORC in the given verse.
/// </summary>
/// <param name="targetRef">The verse reference to look for</param>
/// <param name="hvoPict">The hvo of the picture to look for.</param>
/// <param name="iSection">The index of the section where the ORC was found.</param>
/// <param name="iPara">The index of the para where the ORC was found.</param>
/// <param name="ichOrcPos">The character position of the ORC in the paragraph.</param>
/// <returns>
/// <c>true</c> if the given picture is found in the given verse.
/// </returns>
/// ------------------------------------------------------------------------------------
public bool FindPictureInVerse(ScrReference targetRef, int hvoPict, out int iSection,
out int iPara, out int ichOrcPos)
{
CheckDisposed();
iSection = iPara = ichOrcPos = -1;
// Find the book that the reference is in
IScrBook book = ScrBook.FindBookByID(m_scr, targetRef.Book);
if (book == null)
return false;
iSection = 0;
// Look through the sections for the target reference
foreach (ScrSection section in book.SectionsOS)
{
if (section.ContainsReference(targetRef))
{
iPara = 0;
// Look through each paragraph in the section
foreach (StTxtPara para in section.ContentOA.ParagraphsOS)
{
// Search for target reference in the verses in the paragraph
ScrTxtPara scrPara = new ScrTxtPara(m_cache, para.Hvo);
ScrVerseSet verseSet = new ScrVerseSet(scrPara);
foreach (ScrVerse verse in verseSet)
{
if (verse.StartRef <= targetRef && targetRef <= verse.EndRef)
{
// If the paragraph has a chapter number, the verse iterator
// returns this as a separate string with the same reference
// as the following verse.
// We want to return the verse string, not the chapter number
// run, so we skip a string that has only numeric characters.
ITsString tssVerse = verse.Text;
for (int iRun = 0; iRun < tssVerse.RunCount; iRun++)
{
string sRun = tssVerse.get_RunText(iRun);
if (sRun.Length == 1 && sRun[0] == StringUtils.kchObject)
{
string str = tssVerse.get_Properties(iRun).GetStrPropValue(
(int)FwTextPropType.ktptObjData);
if (!String.IsNullOrEmpty(str) && str[0] == (char)(int)FwObjDataTypes.kodtGuidMoveableObjDisp)
{
Guid guid = MiscUtils.GetGuidFromObjData(str.Substring(1));
if (m_cache.GetIdFromGuid(guid) == hvoPict)
{
ichOrcPos = tssVerse.get_MinOfRun(iRun) + verse.VerseStartIndex;
return true;
}
}
}
}
}
}
iPara++;
}
}
iSection++;
}
return false;
}
/// ------------------------------------------------------------------------------------
/// <summary>
/// Find a verse and return the text of the verse in one or more
/// <see cref="VerseTextSubstring"/> objects.
/// </summary>
/// <param name="scr">The scripture.</param>
/// <param name="targetRef">The verse reference to look for</param>
/// <param name="ichStart">The starting character where the (first part of the) verse
/// text is located within the (first) containing paragraph</param>
/// <returns>
/// A list of <see cref="VerseTextSubstring"/> objects, each representing
/// one paragraph worth of verse text (e.g., to deal with poetry)
/// </returns>
/// <remarks>Verses would not normally be split across sections, but there are a few
/// places, such as the end of I Cor. 12, where it can happen.
/// </remarks>
/// ------------------------------------------------------------------------------------
public static List<VerseTextSubstring> GetVerseText(IScripture scr, ScrReference targetRef,
out int ichStart)
{
ichStart = -1;
if (scr.Versification != targetRef.Versification)
targetRef = new ScrReference(targetRef, scr.Versification);
List<VerseTextSubstring> verseText = new List<VerseTextSubstring>();
// Find the book that the reference is in
IScrBook book = ScrBook.FindBookByID(scr, targetRef.Book);
if (book == null)
return verseText;
if (targetRef.IsBookTitle)
{
foreach (StTxtPara para in book.TitleOA.ParagraphsOS)
{
verseText.Add(new VerseTextSubstring(para.Contents.UnderlyingTsString, -1,
para.IndexInOwner, (int)ScrBook.ScrBookTags.kflidTitle));
ichStart = 0;
}
return verseText;
}
int iSection = 0;
// Look through the sections for the target reference
foreach (ScrSection section in book.SectionsOS)
{
if (!section.ContainsReference(targetRef))
{
if (verseText.Count > 0)
return verseText;
}
else
{
int iPara = 0;
// Look through each paragraph in the section
foreach (StTxtPara para in section.ContentOA.ParagraphsOS)
{
// Search for target reference in the verses in the paragraph
ScrTxtPara scrPara = new ScrTxtPara(scr.Cache, para.Hvo);
ScrVerseSet verseSet = new ScrVerseSet(scrPara);
foreach (ScrVerse verse in verseSet)
{
if (verse.StartRef <= targetRef && targetRef <= verse.EndRef)
{
// If the paragraph has a chapter number, the verse iterator
// returns this as a separate string with the same reference
// as the following verse.
// We want to return the verse string, not the chapter number
// run, so we skip a string that has only numeric characters.
ITsString verseTextInPara = verse.Text;
if (verse.Text.RunCount > 0)
{
string styleName = verse.Text.get_PropertiesAt(0).GetStrPropValue(
(int)FwTextPropType.ktptNamedStyle);
if (styleName == ScrStyleNames.VerseNumber)
verseTextInPara = StringUtils.Substring(verseTextInPara, verse.Text.get_LimOfRun(0));
}
if (!IsNumber(verseTextInPara.Text)) // skip chapter number strings
{
if (verseText.Count == 0)
ichStart = verse.TextStartIndex;
verseText.Add(new VerseTextSubstring(verseTextInPara, iSection,
iPara, (int)ScrSection.ScrSectionTags.kflidContent));
break;
}
}
else if (verseText.Count > 0)
return verseText;
}
iPara++;
}
}
iSection++;
}
return verseText;
}
/// ------------------------------------------------------------------------------------
/// <summary>
/// Attempt to set the selection immediately following the desired verse reference.
/// This version of GotoVerse does not issue a synch message, so it is suitable for
/// calling from the
/// </summary>
/// <param name="targetRef">Reference to seek</param>
/// <returns>true if the selection is changed (to the requested verse or one nearby);
/// false otherwise</returns>
/// <remarks>
/// Searching will start at the current selection location and wrap around if necessary.
/// If the verse reference is not included in the range of any sections, then the
/// selection will not be changed. If the reference does not exist but it is in the
/// range of a section, then a best guess will be done.
/// </remarks>
/// ------------------------------------------------------------------------------------
private bool GotoVerse_WithoutSynchMsg(ScrReference targetRef)
{
CheckDisposed();
bool origIgnoreAnySyncMessages = false;
if (m_syncHandler != null)
{
origIgnoreAnySyncMessages = m_syncHandler.IgnoreAnySyncMessages;
m_syncHandler.IgnoreAnySyncMessages = true;
}
try
{
ScrBook bookToLookFor = BookFilter.GetBookByOrd(targetRef.Book);
if (bookToLookFor == null)
return false;
int iBook = BookFilter.GetBookIndex(bookToLookFor.Hvo);
if (targetRef.IsBookTitle)
{
SelectRangeOfChars(iBook, -1, (int)ScrBook.ScrBookTags.kflidTitle, 0, 0, 0,
true, true, false, VwScrollSelOpts.kssoNearTop);
return true;
}
// If the book has no sections, then don't look for any references
Debug.Assert(bookToLookFor.SectionsOS.Count > 0);
if (bookToLookFor.SectionsOS.Count == 0)
return false;
int startingSectionIndex = 0;
int startingParaIndex = 0;
int startingCharIndex = 0;
// Get the current selection
if (CurrentSelection != null)
{
ILocationTracker tracker = ((ITeView)Control).LocationTracker;
// If the selection is in the desired book, we start there.
// Otherwise start at the beginning of the book
if (tracker.GetBookHvo(CurrentSelection,
SelectionHelper.SelLimitType.Anchor) == bookToLookFor.Hvo)
{
int tmpSectionIndex = tracker.GetSectionIndexInBook(
CurrentSelection, SelectionHelper.SelLimitType.Anchor);
if (tmpSectionIndex >= 0)
{
startingSectionIndex = tmpSectionIndex;
SelLevInfo paraInfo;
if (CurrentSelection.GetLevelInfoForTag(
(int)StText.StTextTags.kflidParagraphs, out paraInfo))
{
startingParaIndex = paraInfo.ihvo;
// Start looking 1 character beyond the current selection.
startingCharIndex = CurrentSelection.IchEnd + 1;
}
}
}
}
ScrSection startingSection = bookToLookFor[startingSectionIndex];
ScrSection section;
int paraIndex;
int ichVerseStart;
// Decide which section to start with. If the current selection
// is at the end of the section then start with the next section
StTxtPara lastParaOfSection = startingSection.LastContentParagraph;
if (startingParaIndex >= startingSection.ContentParagraphCount - 1 &&
startingCharIndex >= lastParaOfSection.Contents.Length)
{
startingSection = (startingSection.NextSection ?? bookToLookFor.FirstSection);
startingParaIndex = 0;
startingCharIndex = 0;
}
if (bookToLookFor.GetRefStartFromSection(targetRef, false, startingSection, startingParaIndex,
startingCharIndex, out section, out paraIndex, out ichVerseStart))
{
// We found an exact match, so go there.
GoToPosition(targetRef, iBook, section, paraIndex, ichVerseStart);
}
//.........这里部分代码省略.........
/// ------------------------------------------------------------------------------------
/// <summary>
/// Attempt to set the selection immediately following the desired verse reference.
/// This version of GotoVerse sends a synch message at the end, so it should not be
/// called from within code that is already responding to a synch message.
/// </summary>
/// <param name="targetRef">Reference to seek</param>
/// <returns>true if the selection is changed (to the requested verse or one nearby);
/// false otherwise</returns>
/// <remarks>
/// Searching will start at the current selection location and wrap around if necessary.
/// If the verse reference is not included in the range of any sections, then the
/// selection will not be changed. If the reference does not exist but it is in the
/// range of a section, then a best guess will be done.
/// </remarks>
/// ------------------------------------------------------------------------------------
public virtual bool GotoVerse(ScrReference targetRef)
{
bool retVal = GotoVerse_WithoutSynchMsg(targetRef);
if (m_syncHandler != null)
m_syncHandler.SyncToScrLocation(this, this, false);
return retVal;
}
//.........这里部分代码省略.........
// If the selection is in a user prompt then extend the selection to cover the
// entire prompt.
if (IsSelectionInPrompt(helper))
{
if (vc != null)
vc.SuppressCommentPromptHvo = hvoSelObj;
// If we're not really showing the prompt, but just an incomplete composition that was typed
// over it, we do NOT want to select all of it all the time! (TE-8267).
if (!prootb.IsCompositionInProgress)
vwselNew.ExtendToStringBoundaries();
if (!vwselNew.IsEditable && helper != null)
{
// We somehow got an IP that associates with the non-editable spacer next to the prompt.
// We need to extend in the opposite direction.
helper.AssocPrev = !helper.AssocPrev;
IVwSelection sel = helper.SetSelection(EditedRootBox.Site, false, false);
// Make sure that the new selection is editable before we install it. This keeps us
// from getting here again and again (recursively). (TE-8763)
if (sel.IsEditable)
sel.Install();
return; // We have already been called again as the new selection is installed.
}
SetKeyboardForSelection(vwselNew);
}
// This isn't ideal but it's one of the better of several bad options for dealing
// with simplifying the selection changes in footnote views.
if ((m_viewType & TeViewType.FootnoteView) != 0 ||
(m_viewType & TeViewType.NotesDataEntryView) != 0 || helper == null)
{
// This makes sure the writing system and styles combos get updated.
base.SelectionChanged(prootb, vwselNew);
return;
}
// If selection is IP, don't allow it to be associated with a verse number run.
bool fRangeSelection = vwselNew.IsRange;
if (!fRangeSelection)
PreventIPAssociationWithVerseRun(vwselNew, prootb, ref updatedSelection);
// Need to do this at end since selection may be changed by this method.
// Doing this at top can also cause value of style in StylesComboBox to flash
base.SelectionChanged(prootb, vwselNew);
// If we changed the selection in this method we want to set the viewSelection to
// null so that the next time it is gotten it will have the correct selection.
if (updatedSelection)
m_viewSelection = null;
// Make sure the selection is in a valid Scripture element.
int tagSelection;
int hvoSelection;
if (!vwselNew.IsValid || !GetSelectedScrElement(out tagSelection, out hvoSelection))
{
m_sPrevSelectedText = null;
return;
}
// Determine whether or not the selection changed but is in a different reference.
bool fInSameRef = (m_oldReference == CurrentStartRef);
if (fInSameRef && !fRangeSelection)
{
m_sPrevSelectedText = null;
if (m_syncHandler != null)
m_syncHandler.SyncToScrLocation(this, this, true);
return;
}
ScrReference curStartRef = CurrentStartRef;
if (curStartRef.Chapter == 0)
curStartRef.Chapter = 1;
m_oldReference = CurrentStartRef;
string selectedText = null;
if (fRangeSelection)
{
try
{
ITsString tssSelectedText = GetCleanSelectedText();
selectedText = (tssSelectedText != null ? tssSelectedText.Text : null);
}
catch
{
selectedText = null;
}
}
bool fSameSelectedText = (m_sPrevSelectedText == selectedText);
m_sPrevSelectedText = selectedText;
if (m_syncHandler != null && (!fInSameRef || !fSameSelectedText ||
InBookTitle || InSectionHead || InIntroSection))
{
m_syncHandler.SyncToScrLocation(this, this, fInSameRef);
}
}
/// ------------------------------------------------------------------------------------
/// <summary>
/// Determines next chapter following current reference
/// </summary>
/// <returns></returns>
/// ------------------------------------------------------------------------------------
public ScrReference GetNextChapter()
{
CheckDisposed();
ScrReference curEndRef = CurrentEndRef;
if (curEndRef.Book == 0)
{
// REVIEW BobA(TimS): Something went wrong, let's move to the first verse
// we know of... Alternative is to say oh well, and do nothing at all.
return ScrReference.StartOfBible(curEndRef.Versification);
}
if (curEndRef.Chapter == 0)
{
// Hmmm... we're probably at the beginning of the book already, and in the
// title or intro area. We should move into the previous book.
if (BookIndex >= 0)
{
// We are in the intro section area, we should move to the
// first verse of the first chapter
ScrBook book = BookFilter.GetBook(BookIndex);
return new ScrReference((short)book.CanonicalNum, 1, 1, m_scr.Versification);
}
}
else
{
// Standard yum-cha situation here... move up to the next chapter
// and be happy.
if (BookIndex >= 0 && SectionIndex >= 0)
{
ScrBook book = BookFilter.GetBook(BookIndex);
int lastChapter = 0;
foreach (ScrSection section in book.SectionsOS)
{
ScrReference maxSectionRef =
new ScrReference(section.VerseRefMax, m_scr.Versification);
ScrReference minSectionRef =
new ScrReference(section.VerseRefMin, m_scr.Versification);
if (minSectionRef.Valid && maxSectionRef.Valid &&
maxSectionRef.Chapter > lastChapter)
{
lastChapter = maxSectionRef.Chapter;
}
}
if (BookIndex == BookFilter.BookCount - 1 &&
curEndRef.Chapter == lastChapter)
{
// We're at the end of the book, nowhere to go...
return new ScrReference((short)book.CanonicalNum, lastChapter, 1,
m_scr.Versification);
}
if (curEndRef.Chapter == lastChapter)
{
// We're at the end of the book, nowhere to go...
book = BookFilter.GetBook(BookIndex + 1);
return new ScrReference((short)book.CanonicalNum, 1, 1,
m_scr.Versification);
}
// Otherwise, move on.... we were bored of this part anyhow...
return new ScrReference((short)book.CanonicalNum, curEndRef.Chapter + 1,
1, m_scr.Versification);
}
}
// Splode?
return ScrReference.StartOfBible(curEndRef.Versification);
}
/// ------------------------------------------------------------------------------------
/// <summary>
/// Goes to the text referenced in the ScrScriptureNote. If it does not find the text,
/// it makes the closest selection to the referenced text that it can.
/// </summary>
/// <param name="note">the note containing the Scripture reference to find</param>
/// <param name="sendSyncMsg"><c>true</c> to not send a focus sychronization message
/// when the selection is changed by going to the scripture ref.</param>
/// ------------------------------------------------------------------------------------
public void GoToScrScriptureNoteRef(IScrScriptureNote note, bool sendSyncMsg)
{
// TODO (TE-1729): Use this method correctly from Annotations view.
ScrReference scrRef = new ScrReference(note.BeginRef, m_scr.Versification);
ScrBook book = BookFilter.GetBookByOrd(scrRef.Book);
if (book == null)
return;
int iBook = BookFilter.GetBookIndex(book.Hvo);
bool fOrigIgnoreAnySyncMessages = false;
if (m_syncHandler != null)
{
fOrigIgnoreAnySyncMessages = m_syncHandler.IgnoreAnySyncMessages;
m_syncHandler.IgnoreAnySyncMessages = true;
}
try
{
if (note.Flid == (int)CmPicture.CmPictureTags.kflidCaption)
{
SelectCitedTextInPictureCaption(iBook, note);
return;
}
int ichStart, ichEnd;
string citedText = note.CitedText;
ITsString citedTextTss = note.CitedTextTss;
StTxtPara para = note.BeginObjectRA as StTxtPara;
if (para != null && m_cache.GetOwnerOfObjectOfClass(para.Hvo, ScrDraft.kClassId) == 0)
{
if (para.Owner is StFootnote)
{
// Make selection in footnote.
if (TextAtExpectedLoc(para.Contents.Text, citedText, note.BeginOffset, note.EndOffset))
{
// Select text in footnote.
StFootnote footnote = para.Owner as StFootnote;
if (footnote == null)
return;
SelectionHelper selHelper = new SelectionHelper();
selHelper.AssocPrev = false;
selHelper.NumberOfLevels = 3;
selHelper.LevelInfo[2].tag = BookFilter.Tag;
selHelper.LevelInfo[2].ihvo = iBook;
selHelper.LevelInfo[1].tag = (int)ScrBook.ScrBookTags.kflidFootnotes;
selHelper.LevelInfo[1].ihvo = footnote.IndexInOwner;
selHelper.LevelInfo[0].ihvo = 0;
// Prepare to move the IP to the specified character in the paragraph.
selHelper.IchAnchor = note.BeginOffset;
selHelper.IchEnd = note.EndOffset;
// Now that all the preparation to set the IP is done, set it.
selHelper.SetSelection(Callbacks.EditedRootBox.Site, true, true);
}
return;
}
// Make selection in Scripture text
if (TextAtExpectedLoc(para.Contents.Text, citedText, note.BeginOffset, note.EndOffset))
{
SelectRangeOfChars(iBook, para, note.BeginOffset, note.EndOffset);
return;
}
if (scrRef.Verse == 0)
{
// Either a missing chapter number or something in intro material.
// Not much chance of finding it by reference (even if the chapter number
// has been added, we never find the 0th verse, and 99% of the time that
// chapter number would have been added to the same paragraph where it
// was missing in the first place), so just try to find the text in the
// paragraph, if it still exists.
if (string.IsNullOrEmpty(citedText))
{
SelectRangeOfChars(iBook, para, note.BeginOffset, note.BeginOffset);
return;
}
// The text may be null if the paragraph only contains the prompt. TE-8315
if (para.Contents.Text != null)
{
int i = para.Contents.Text.IndexOf(citedText);
if (i >= 0)
{
SelectRangeOfChars(iBook, para, i, i + citedText.Length);
return;
}
}
//.........这里部分代码省略.........
请发表评论