/// ------------------------------------------------------------------------------------ /// <summary> /// Updates the book section group label. /// </summary> /// ------------------------------------------------------------------------------------ private void UpdateBookSectionGroupLabel() { IScrBook book = m_scr.FindBook(m_nBookForSections); m_grpSectionRange.Text = string.Format(m_sRangeBookFmt, book.Name.BestAnalysisVernacularAlternative.Text); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Loads the texts for each Scripture book title, section, footnote, etc. /// </summary> /// ------------------------------------------------------------------------------------ public void LoadScriptureTexts(FdoCache cache, IBookImporter bookImporter) { m_bookImporter = bookImporter; m_associatedPtText = bookImporter != null?ParatextHelper.GetAssociatedProject(cache.ProjectId) : null; m_scr = cache.LanguageProject.TranslatedScriptureOA; if (m_scr == null) { return; } List <TreeNode> otBooks = new List <TreeNode>(); List <TreeNode> ntBooks = new List <TreeNode>(); for (int bookNum = 1; bookNum <= BCVRef.LastBook; bookNum++) { var bookName = cache.ServiceLocator.GetInstance <IScrRefSystemRepository>().Singleton.BooksOS[bookNum - 1].UIBookName; object book = m_scr.FindBook(bookNum); if (book == null) { if (m_associatedPtText != null && m_associatedPtText.BookPresent(bookNum)) { book = bookNum; } else { continue; } } TreeNode node = new TreeNode(bookName); node.Tag = book; node.Name = "Book"; // help us query for books. if (bookNum < ScriptureTags.kiNtMin) { otBooks.Add(node); } else { ntBooks.Add(node); } } TreeNode bibleNode = new TreeNode(FwControls.kstidBibleNode); bibleNode.Name = "Bible"; if (otBooks.Count > 0) { TreeNode testamentNode = new TreeNode(FwControls.kstidOtNode, otBooks.ToArray()); testamentNode.Name = "Testament"; // help us query for Testaments bibleNode.Nodes.Add(testamentNode); } if (ntBooks.Count > 0) { TreeNode testamentNode = new TreeNode(FwControls.kstidNtNode, ntBooks.ToArray()); testamentNode.Name = "Testament"; // help us query for Testaments bibleNode.Nodes.Add(testamentNode); } Nodes.Add(bibleNode); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets the Scripture reference of the specified annotation as string. /// </summary> /// <param name="ann">The specified annotation.</param> /// ------------------------------------------------------------------------------------ private string GetRefAsString(IScrScriptureNote ann) { BCVRef startRef = new BCVRef(ann.BeginRef); IScrBook book = m_scr.FindBook(startRef.Book); string bookName; // Book for note may not be in the project. if (book != null) { bookName = book.BestUIName; } else { IScrBookRef bookRef = Cache.ServiceLocator.GetInstance <IScrRefSystemRepository>().Singleton.BooksOS[startRef.Book - 1]; ITsString tsName = bookRef.BookName.get_String(Cache.DefaultUserWs); if (tsName.Length == 0) { tsName = bookRef.BookName.BestAnalysisAlternative; } bookName = tsName.Text; } string titleText = ResourceHelper.GetResourceString("kstidScriptureTitle"); string introText = ResourceHelper.GetResourceString("kstidScriptureIntro"); return(BCVRef.MakeReferenceString(bookName, startRef, new BCVRef(ann.EndRef), m_scr.ChapterVerseSepr, m_scr.Bridge, titleText, introText)); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Exports the scripture. /// </summary> /// <param name="progressDlg">The progress dialog.</param> /// <param name="parameters">The parameters. (ignored)</param> /// <returns>always <c>null</c></returns> /// ------------------------------------------------------------------------------------ private object ExportScripture(IAdvInd4 progressDlg, params object[] parameters) { switch (m_what) { case ExportWhat.AllBooks: // Export all of the Scripture books in the project. for (int i = 0; i < m_scr.ScriptureBooksOS.Count && !m_cancel; ++i) { ExportBook(m_scr.ScriptureBooksOS[i], progressDlg); } break; case ExportWhat.FilteredBooks: // Export all of the Scripture books in the filter for (int bookIndex = 0; bookIndex < m_bookFilter.BookCount && !m_cancel; bookIndex++) { ExportBook(m_bookFilter.GetBook(bookIndex), progressDlg); } break; case ExportWhat.SingleBook: // Export a single book. ExportBook(m_scr.FindBook(m_nBookSingle), progressDlg); break; } return(null); }
/// -------------------------------------------------------------------------------- /// <summary> /// Initializes a new instance of the <see cref="T:ImportedBooks"/> class. /// </summary> /// <param name="cache">The cache.</param> /// <param name="importVersion">The ScrDraft containing the imported books.</param> /// <param name="backupVersion">where to store stuff overwritten or merged.</param> /// <param name="booksImported">The canonical numbers of the books which were /// imported (unordered).</param> /// <param name="helpTopicProvider">The help topic provider.</param> /// <param name="app">The application.</param> /// -------------------------------------------------------------------------------- public ImportedBooks(LcmCache cache, IScrDraft importVersion, IScrDraft backupVersion, IEnumerable <int> booksImported, IHelpTopicProvider helpTopicProvider, IApp app) : this(cache, importVersion, backupVersion, helpTopicProvider, app) { foreach (int bookId in booksImported) { IScrBook rev = importVersion.FindBook(bookId); ListViewItem item = new ListViewItem( new[] { rev.Name.UserDefaultWritingSystem.Text, GetBookInfo(rev) }); item.SubItems.Add(Properties.Resources.kstidUnknown); IScrBook curBook = m_scr.FindBook(rev.CanonicalNum); if (curBook == null) { SetItemStatus(item, ImportedBookStatus.New); // User should not see this undo task so we don't need to localize the strings. UndoableUnitOfWorkHelper.Do("Add book", "Add book", m_cache.ServiceLocator.GetInstance <IActionHandler>(), () => { OnBookAdded(m_scr.CopyBookToCurrent(rev)); }); } else { item.Tag = new BookMerger(m_cache, rev); } lstImportedBooks.Items.Add(item); } lstImportedBooks.Items[0].Selected = true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Attaches the annotated objects to the specifed annotation. /// </summary> /// ------------------------------------------------------------------------------------ private static void AttachAnnotatedObjects(IScripture scr, int bookNum, IScrScriptureNote scrNote) { int iSection, iPara, ichStart, ichEnd; ScrReference scrRef = new ScrReference(scrNote.BeginRef, scr.Versification); if (TeEditingHelper.FindTextInVerse(scr, scrNote.CitedTextTss, scrRef, true, out iSection, out iPara, out ichStart, out ichEnd)) { IScrBook book = scr.FindBook(bookNum); Debug.Assert(book != null); scrNote.BeginOffset = ichStart; scrNote.EndOffset = ichEnd; if (iSection == -1) { scrNote.BeginObjectRA = scrNote.EndObjectRA = book.TitleOA.ParagraphsOS[iPara]; } else { scrNote.BeginObjectRA = scrNote.EndObjectRA = book.SectionsOS[iSection].ContentOA.ParagraphsOS[iPara]; } } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Read the text for the specified book number. /// ENHANCE: For our initial implementation, we'll see how it performs if we don't /// do the parsing ahead of time. We'll just set up the enumerators...Parse into Tokens. /// The tokens are accessed via the TextTokens() method. /// We split this operation into two parts since we often want to create /// the tokens list once and then present them to several different checks. /// </summary> /// <param name="bookNum">Canonical number of book, as returned in list from call to /// BooksPresent.</param> /// <param name="chapterNum">0=read whole book, else specified chapter number</param> /// <returns><c>true</c></returns> /// ------------------------------------------------------------------------------------ public bool GetText(int bookNum, int chapterNum) { m_bookBeingChecked = (IScrBook)m_scr.FindBook(bookNum); SetParameterValue("Book ID", m_bookBeingChecked.BookId); SetParameterValue("Chapter Number", chapterNum.ToString()); return(m_bookBeingChecked.GetTextToCheck(chapterNum)); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Get the ScrBook object from the DB corresponding to the specified book index. /// </summary> /// <param name="nBook">one-based index of the book (Genesis = 1).</param> /// <returns>The ScrBook DB object corresponding to a book index.</returns> /// ------------------------------------------------------------------------------------ public IScrBook GetBookFromDB(int nBook) { if (m_scripture == null) { return(null); } return(m_scripture.FindBook(nBook)); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets the Scripture reference of the specified annotation as string. /// </summary> /// <param name="ann">The specified annotation.</param> /// ------------------------------------------------------------------------------------ private string GetRefAsString(ScrScriptureNote ann) { BCVRef startRef = new BCVRef(ann.BeginRef); IScrBook book = m_scr.FindBook(startRef.Book); string titleText = ResourceHelper.GetResourceString("kstidScriptureTitle"); string introText = ResourceHelper.GetResourceString("kstidScriptureIntro"); return(ScrReference.MakeReferenceString(book.BestUIName, startRef, new BCVRef(ann.EndRef), m_scr.ChapterVerseSepr, m_scr.Bridge, titleText, introText)); }
/// <summary> /// This class creates text, it must delete it here when UNDO is commanded /// so it can update InterestingTexts. /// </summary> /* public override void PropChanged(int hvo, int tag, int ivMin, int cvIns, int cvDel) * { * if (cvDel != 1) * return; * SaveOnChangeRecord(); * SuppressSaveOnChangeRecord = true; * try * { * m_list.DeleteCurrentObject(); * } * finally * { * SuppressSaveOnChangeRecord = false; * } * GetInterestingTextList().UpdateInterestingTexts(); * } */ #region IBookImporter Members /// ------------------------------------------------------------------------------------ /// <summary> /// Imports the specified book. /// </summary> /// <param name="bookNum">The canonical book number.</param> /// <param name="owningForm">Form that can be used as the owner of progress dialogs and /// message boxes.</param> /// <param name="importBt">True to import only the back translation, false to import /// only the main translation</param> /// <returns> /// The ScrBook created to hold the imported data /// </returns> /// ------------------------------------------------------------------------------------ public IScrBook Import(int bookNum, Form owningForm, bool importBt) { IScripture scr = Cache.LangProject.TranslatedScriptureOA; bool haveSomethingToImport = NonUndoableUnitOfWorkHelper.Do(Cache.ActionHandlerAccessor, () => { IScrImportSet importSettings = scr.FindOrCreateDefaultImportSettings(TypeOfImport.Paratext6); importSettings.StyleSheet = ScriptureStylesheet; IScrText paratextProj = ParatextHelper.GetAssociatedProject(Cache.ProjectId); importSettings.ParatextScrProj = paratextProj.Name; importSettings.StartRef = new BCVRef(bookNum, 0, 0); int chapter = paratextProj.Versification.LastChapter(bookNum); importSettings.EndRef = new BCVRef(bookNum, chapter, paratextProj.Versification.LastVerse(bookNum, chapter)); if (!importBt) { importSettings.ImportTranslation = true; importSettings.ImportBackTranslation = false; } else { List <IScrText> btProjects = ParatextHelper.GetBtsForProject(paratextProj).ToList(); if (btProjects.Count > 0 && (string.IsNullOrEmpty(importSettings.ParatextBTProj) || !btProjects.Any(st => st.Name == importSettings.ParatextBTProj))) { importSettings.ParatextBTProj = btProjects[0].Name; } if (string.IsNullOrEmpty(importSettings.ParatextBTProj)) { return(false); } importSettings.ImportTranslation = false; importSettings.ImportBackTranslation = true; } ParatextHelper.LoadProjectMappings(importSettings); ScrMappingList importMap = importSettings.GetMappingListForDomain(ImportDomain.Main); ImportMappingInfo figureInfo = importMap[@"\fig"]; if (figureInfo != null) { figureInfo.IsExcluded = true; } importSettings.SaveSettings(); return(true); }); if (haveSomethingToImport && ReflectionHelper.GetBoolResult(ReflectionHelper.GetType("TeImportExport.dll", "SIL.FieldWorks.TE.TeImportManager"), "ImportParatext", owningForm, ScriptureStylesheet, (FwApp)m_mediator.PropertyTable.GetValue("App"))) { return(scr.FindBook(bookNum)); } return(null); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Handle a selection change in the tree view. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> /// ------------------------------------------------------------------------------------ protected void m_treeArchives_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e) { bool enableCompare = false; // Enable the Delete, Diff and Copy to Current buttons based on whether the selection is on // a book node and whether the corresponding book is present in the current version. TreeNode node = m_treeArchives.SelectedNode; m_btnDelete.Enabled = (node != null); if (node != null && node.Tag is IScrBook) { m_btnDelete.Enabled = m_btnCopyToCurr.Enabled = true; int bookId = ((IScrBook)node.Tag).CanonicalNum; IScrBook sameBookInDB = m_scr.FindBook(bookId); enableCompare = (sameBookInDB != null); } else { m_btnCopyToCurr.Enabled = false; } m_btnDiff.Enabled = enableCompare; }
/// <summary> /// This class creates text, it must delete it here when UNDO is commanded /// so it can update InterestingTexts. /// </summary> /* public override void PropChanged(int hvo, int tag, int ivMin, int cvIns, int cvDel) * { * if (cvDel != 1) * return; * SaveOnChangeRecord(); * SuppressSaveOnChangeRecord = true; * try * { * m_list.DeleteCurrentObject(); * } * finally * { * SuppressSaveOnChangeRecord = false; * } * GetInterestingTextList().UpdateInterestingTexts(); * } */ #region IBookImporter Members /// ------------------------------------------------------------------------------------ /// <summary> /// Imports the specified book. /// </summary> /// <param name="bookNum">The canonical book number.</param> /// <param name="owningForm">Form that can be used as the owner of progress dialogs and /// message boxes.</param> /// <param name="importBt">True to import only the back translation, false to import /// only the main translation</param> /// <returns> /// The ScrBook created to hold the imported data /// </returns> /// ------------------------------------------------------------------------------------ public IScrBook Import(int bookNum, Form owningForm, bool importBt) { IScripture scr = Cache.LangProject.TranslatedScriptureOA; bool haveSomethingToImport = NonUndoableUnitOfWorkHelper.Do(Cache.ActionHandlerAccessor, () => { IScrImportSet importSettings = scr.FindOrCreateDefaultImportSettings(TypeOfImport.Paratext6); ScrText paratextProj = ParatextHelper.GetAssociatedProject(Cache.ProjectId); importSettings.ParatextScrProj = paratextProj.Name; importSettings.IncludeBooks(bookNum, bookNum, paratextProj.Versification); if (!importBt) { importSettings.ImportTranslation = true; importSettings.ImportBackTranslation = false; } else { List <ScrText> btProjects = ParatextHelper.GetBtsForProject(paratextProj).ToList(); if (btProjects.Count > 0 && (string.IsNullOrEmpty(importSettings.ParatextBTProj) || !btProjects.Any(st => st.Name == importSettings.ParatextBTProj))) { importSettings.ParatextBTProj = btProjects[0].Name; } if (string.IsNullOrEmpty(importSettings.ParatextBTProj)) { return(false); } importSettings.ImportTranslation = false; importSettings.ImportBackTranslation = true; } return(true); }); if (haveSomethingToImport && ReflectionHelper.GetBoolResult(ReflectionHelper.GetType("TeImportExport.dll", "SIL.FieldWorks.TE.TeImportManager"), "ImportParatext", owningForm, ScriptureStylesheet, (FwApp)m_mediator.PropertyTable.GetValue("App"))) { return(scr.FindBook(bookNum)); } return(null); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Called when we are about to import a book but are not importing the main translation. /// </summary> /// <param name="nCanonicalBookNumber"></param> /// <param name="fMakeBackup">This should be true if we are importing a back /// translation.</param> /// <returns>The version of the book in the imported version if available; otherwise /// the current version of the book (in which case a backup will be made first if /// <c>fMakeBackup</c> is <c>true</c>.</returns> /// ------------------------------------------------------------------------------------ public IScrBook PrepareBookNotImportingVern(int nCanonicalBookNumber, bool fMakeBackup) { IActionHandler actionHandler = SetCurrentBookInternal(nCanonicalBookNumber); IScrBook cvBook = m_scr.FindBook(nCanonicalBookNumber); if (ImportedSavedVersion != null) { IScrBook isvBook = ImportedSavedVersion.FindBook(nCanonicalBookNumber); if (isvBook != null) { // We won't make a new undo action in this case. The import of a BT for an // imported book will be undone if the import of the book is undone. return(isvBook); } } if (cvBook != null && fMakeBackup && m_savedVersion.FindBook(nCanonicalBookNumber) == null) { actionHandler.AddAction(new UndoImportModifiedBookAction(this, cvBook)); } return(cvBook); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Called when we are about to import a book but are not importing the main translation. /// </summary> /// <param name="nCanonicalBookNumber"></param> /// <param name="fMakeBackup">This should be true if we are importing a back /// translation.</param> /// <returns>The version of the book in the imported version if available; otherwise /// the current version of the book (in which case a backup will be made first if /// <c>fMakeBackup</c> is <c>true</c>.</returns> /// ------------------------------------------------------------------------------------ public IScrBook PrepareBookNotImportingVern(int nCanonicalBookNumber, bool fMakeBackup) { IScrBook isvBook = SetCurrentBook(nCanonicalBookNumber, false); if (isvBook != null && m_importedBooks.ContainsKey(nCanonicalBookNumber)) { return(isvBook); } IScrBook cvBook = m_scr.FindBook(nCanonicalBookNumber); if (cvBook != null && fMakeBackup) { // Replace any existing book with the imported one. IScrBook oldBook = m_backupVersion.FindBook(nCanonicalBookNumber); if (oldBook != null) { m_backupVersion.BooksOS.Remove(oldBook); } m_backupVersion.AddBookCopy(cvBook); } return(cvBook); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Attaches the annotated objects to the specifed annotation. /// </summary> /// ------------------------------------------------------------------------------------ private static void AttachAnnotatedObjects(IScripture scr, int bookNum, IScrScriptureNote scrNote) { int iSection, iPara, ichStart, ichEnd; ScrReference scrRef = new ScrReference(scrNote.BeginRef, scr.Versification); if (TeEditingHelper.FindTextInVerse(scr, scrNote.CitedTextTss, scrRef, true, out iSection, out iPara, out ichStart, out ichEnd)) { IScrBook book = scr.FindBook(bookNum); Debug.Assert(book != null); scrNote.BeginOffset = ichStart; scrNote.EndOffset = ichEnd; if (iSection == -1) scrNote.BeginObjectRA = scrNote.EndObjectRA = book.TitleOA.ParagraphsOS[iPara]; else { scrNote.BeginObjectRA = scrNote.EndObjectRA = book.SectionsOS[iSection].ContentOA.ParagraphsOS[iPara]; } } }
/// ------------------------------------------------------------------------------------ /// <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> /// <returns> /// The <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. /// ENHANCE: Logicially, this method probably really belongs on Scripture, but currently /// that FDO doesn't reference ScrUtils (which is where ScrReference is). It probably /// could reference it, if we wanted it to. Another option would be to create an /// extension method for it, but I'm not sure where it would go. /// </remarks> /// ------------------------------------------------------------------------------------ public static IEnumerable<VerseTextSubstring> GetVerseText(IScripture scr, ScrReference targetRef) { 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 = scr.FindBook(targetRef.Book); if (book == null) return verseText; if (targetRef.IsBookTitle) { foreach (IStTxtPara para in book.TitleOA.ParagraphsOS) { verseText.Add(new VerseTextSubstring(para.Contents, -1, para.IndexInOwner, 0, ScrBookTags.kflidTitle)); } return verseText; } int iSection = 0; // Look through the sections for the target reference foreach (IScrSection 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 (IScrTxtPara para in section.ContentOA.ParagraphsOS) { // Search for target reference in the verses in the paragraph using (ScrVerseSet verseSet = new ScrVerseSet(para)) { 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 && verse.Text.Style(0) == ScrStyleNames.VerseNumber) { verseTextInPara = verseTextInPara.Substring(verse.Text.get_LimOfRun(0)); } if (!IsNumber(verseTextInPara.Text)) // skip chapter number strings { int ichStart = (verseText.Count == 0) ? verse.TextStartIndex : 0; verseText.Add(new VerseTextSubstring(verseTextInPara, iSection, iPara, ichStart, ScrSectionTags.kflidContent)); break; } } else if (verseText.Count > 0) return verseText; } } iPara++; } } iSection++; } return verseText; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Loads the texts for each Scripture book title, section, footnote, etc. /// </summary> /// ------------------------------------------------------------------------------------ private void LoadScriptureTexts() { if (!m_cache.ServiceLocator.GetInstance <IScrBookRepository>().AllInstances().Any() && (m_associatedPtText == null || !m_associatedPtText.AssociatedLexicalProject.ProjectId.Any())) { return; // Nobody home, so skip them. } var otBooks = new List <TreeNode>(); var ntBooks = new List <TreeNode>(); for (var bookNum = 1; bookNum <= BCVRef.LastBook; bookNum++) { var bookName = m_cache.ServiceLocator.GetInstance <IScrRefSystemRepository>().Singleton.BooksOS[bookNum - 1].UIBookName; object book = m_scr.FindBook(bookNum); if (book == null) { if (m_associatedPtText != null && m_associatedPtText.BookPresent(bookNum)) { book = bookNum; } else { continue; } } var node = new TreeNode(bookName) { Tag = book, Name = "Book" }; // help us query for books. if (bookNum < ScriptureTags.kiNtMin) { otBooks.Add(node); } else { ntBooks.Add(node); } } var bibleNode = new TreeNode(ITextStrings.kstidBibleNode) { Name = "Bible" }; if (otBooks.Count > 0) { var testamentNode = new TreeNode(ITextStrings.kstidOtNode, otBooks.ToArray()) { Name = "Testament" }; // help us query for Testaments bibleNode.Nodes.Add(testamentNode); } if (ntBooks.Count > 0) { var testamentNode = new TreeNode(ITextStrings.kstidNtNode, ntBooks.ToArray()) { Name = "Testament" }; // help us query for Testaments bibleNode.Nodes.Add(testamentNode); } Nodes.Add(bibleNode); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Handles the Click event of the m_btnCopyToCurr control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event /// data.</param> /// ------------------------------------------------------------------------------------ private void m_btnCopyToCurr_Click(object sender, EventArgs e) { // If nothing or a complete archive is selected, do nothing. TreeNode node = m_treeArchives.SelectedNode; if (node == null || !(node.Tag is ScrBook)) { return; } ScrBook savedBook = node.Tag as ScrBook; ScrBook originalBook = (ScrBook)m_scr.FindBook(savedBook.CanonicalNum); TreeNode parentNode = node.Parent; ScrDraft archive = parentNode.Tag as ScrDraft; OverwriteType typeOfOverwrite = OverwriteType.FullNoDataLoss; List <IScrSection> sectionsToRemove = null; if (originalBook != null) { string sDetails; List <int> missingBtWs; typeOfOverwrite = originalBook.DetermineOverwritability(savedBook, out sDetails, out sectionsToRemove, out missingBtWs); if (typeOfOverwrite == OverwriteType.DataLoss) { // There will be data loss if the user overwrites so we don't allow them // to continue. ImportedBooks.ReportDataLoss(originalBook, ScrDraftType.SavedVersion, this, sDetails); return; } if (missingBtWs != null && !ImportedBooks.ConfirmBtOverwrite(originalBook, ScrDraftType.SavedVersion, sectionsToRemove, missingBtWs, this)) { // The user might lose back translation(s) if they proceed and they decided // against it. return; } } string stUndo; string stRedo; TeResourceHelper.MakeUndoRedoLabels("kstidOverwriteCurrentWithSaved", out stUndo, out stRedo); using (new WaitCursor(this)) using (UndoTaskHelper helper = new UndoTaskHelper(m_cache.MainCacheAccessor, null, stUndo, stRedo, true)) { try { if (typeOfOverwrite == OverwriteType.Partial) { // Perform an automerge of the original book and the saved version. using (BookMerger merger = new BookMerger(m_cache, m_styleSheet, savedBook)) { using (ProgressDialogWithTask progress = new ProgressDialogWithTask(this)) { progress.Title = DlgResources.ResourceString("kstidOverwriteCaption"); progress.RunTask(true, new BackgroundTaskInvoker(merger.DoPartialOverwrite), sectionsToRemove); } if (!merger.AutoMerged) { throw new Exception("Partial Overwrite was not successful."); } } } else { if (originalBook != null) { if (m_cache.ActionHandlerAccessor != null) { // When Undoing, we need to first resurrect the deleted book, then // put it back in the book filter...so we need a RIFF in the sequence // BEFORE the delete. ReplaceInFilterFixer fixer1 = new ReplaceInFilterFixer(originalBook.Hvo, 0, m_cache); m_cache.ActionHandlerAccessor.AddAction(fixer1); } originalBook.DeleteUnderlyingObject(); } int hvoNew = (m_scr as Scripture).CopyBookToCurrent(savedBook); ReplaceInFilterFixer fixer = new ReplaceInFilterFixer(0, hvoNew, m_cache); fixer.Redo(false); if (m_cache.ActionHandlerAccessor != null) { m_cache.ActionHandlerAccessor.AddAction(fixer); } } } catch { helper.EndUndoTask = false; throw; } } }