public void BeginAndEndUndoTask() { ShowForm(); // we need a selection m_basicView.RootBox.MakeSimpleSel(true, true, false, true); // this should begin an outer undo task, so we will have only one undoable task! using (UndoTaskHelper helper = new UndoTaskHelper(m_actionHandler, m_basicView, "kstidUndoStyleChanges")) { IScrBook book = Cache.ServiceLocator.GetInstance <IScrBookFactory>().Create(6); Cache.LanguageProject.TranslatedScriptureOA.ScriptureBooksOS.Add(book); book = Cache.ServiceLocator.GetInstance <IScrBookFactory>().Create(7); Cache.LanguageProject.TranslatedScriptureOA.ScriptureBooksOS.Add(book); helper.RollBack = false; } int nUndoTasks = 0; while (m_actionHandler.CanUndo()) { Assert.AreEqual(UndoResult.kuresSuccess, m_actionHandler.Undo()); nUndoTasks++; } Assert.AreEqual(1, nUndoTasks); }
public void SuppressSubTasks() { CheckDisposed(); ShowForm(); // we need a selection m_basicView.RootBox.MakeSimpleSel(true, true, false, true); using (UndoTaskHelper helper = new UndoTaskHelper(m_basicView, "kstidUndoStyleChanges")) { CheckActionHandlerIsNull(false); using (new SuppressSubTasks(m_fdoCache)) CheckActionHandlerIsNull(true); } CheckActionHandlerIsNull(false); }
public void CreatedUndoSelectionActions() { CheckDisposed(); ShowForm(); // we need a selection - set to start m_basicView.RootBox.MakeSimpleSel(true, true, false, true); IActionHandler acth = m_basicView.Cache.ActionHandlerAccessor; Assert.AreEqual(0, acth.UndoableActionCount, "Undoable actions at start"); using (UndoTaskHelper helper = new UndoTaskHelper(m_basicView, "kstidUndoStyleChanges")) { Assert.AreEqual(1, acth.UndoableActionCount, "Wrong number of undoable actions after beginning task"); acth.AddAction(new DummyUndoAction()); Assert.AreEqual(2, acth.UndoableActionCount, "Wrong number of undoable actions after adding a task"); } Assert.AreEqual(3, acth.UndoableActionCount, "Wrong number of undoable actions after ending task"); }
/// ----------------------------------------------------------------------------------- /// <summary> /// Handle the Edit/Delete menu command. /// </summary> /// <param name="args">The arguments</param> /// <returns><c>true</c> if message handled, otherwise <c>false</c>.</returns> /// <remarks>Formerly <c>AfVwRootSite::CmdEditDel1</c></remarks> /// ----------------------------------------------------------------------------------- protected virtual bool OnEditDelete(object args) { if (DataUpdateMonitor.IsUpdateInProgress()) return true; //discard this event string undo, redo; ResourceHelper.MakeUndoRedoLabels("kstidEditDelete", out undo, out redo); using (UndoTaskHelper undoHelper = new UndoTaskHelper(ActiveView.CastAsIVwRootSite(), undo, redo)) using (new DataUpdateMonitor(this, "DeleteSelection")) { EditingHelper.DeleteSelection(); undoHelper.RollBack = false; return true; } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Handle a click on the Revert To Old button /// </summary> /// ------------------------------------------------------------------------------------ protected void btnRevertToOld_Click(object sender, EventArgs e) { using (new WaitCursor(this)) { Difference diff = m_differences.CurrentDifference; DifferenceType diffType = diff.DiffType; if (m_bookMerger.IsDataLossDifference(diff) && !AllowUseThisVersionToLoseData()) { return; } m_diffViewWrapper.CurrentDiffView.SuspendLayout(); if (m_diffViewWrapper.CurrentDiffFootnoteView != null) m_diffViewWrapper.CurrentDiffFootnoteView.SuspendLayout(); try { string undo; string redo; TeResourceHelper.MakeUndoRedoLabels("kstidDiffDlgRevertToOldUndoRedo", out undo, out redo); using (UndoTaskHelper undoTaskHelper = new UndoTaskHelper( ActiveView.CastAsIVwRootSite(), undo, redo, true)) { m_cache.ActionHandlerAccessor.AddAction(new UndoMajorDifferenceAction(m_bookMerger)); m_bookMerger.ReplaceCurrentWithRevision(diff); } } finally { m_diffViewWrapper.CurrentDiffView.ResumeLayout(); if (m_diffViewWrapper.CurrentDiffFootnoteView != null) m_diffViewWrapper.CurrentDiffFootnoteView.ResumeLayout(); } RefreshStatus(); // ReplaceCurrentWithRevision removes an item from the difference list. // Because of that, the current difference index ends up pointing to the next // difference in the list. Difference newDiff = m_differences.CurrentDifference; DisplayDifference(diff, newDiff); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Start editing the current diff view /// </summary> /// ------------------------------------------------------------------------------------ public void StartEditMode() { CheckDisposed(); m_diffViewWrapper.CurrentDiffView.Editable = true; m_diffViewWrapper.CurrentDiffView.RefreshDisplay(); m_diffViewWrapper.CurrentDiffView.Focus(); if (m_diffViewWrapper.CurrentDiffFootnoteView != null) { m_diffViewWrapper.CurrentDiffFootnoteView.Editable = true; m_diffViewWrapper.CurrentDiffFootnoteView.RefreshDisplay(); } string undo; string redo; TeResourceHelper.MakeUndoRedoLabels("kstidDiffDlgEditUndoRedo", out undo, out redo); m_undoTaskHelper = new UndoTaskHelper(ActiveView.CastAsIVwRootSite(), undo, redo, true); m_cache.ActionHandlerAccessor.AddAction(new UndoMajorDifferenceAction(m_bookMerger)); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Handles the Click event of the m_btnOk control. /// </summary> /// ------------------------------------------------------------------------------------ private void m_btnOk_Click(object sender, EventArgs e) { if (IsRootSiteDisposed()) { MessageBox.Show(FwCoreDlgs.kstidChangesAreLost, FwCoreDlgs.kstidWarning); DialogResult = DialogResult.Cancel; return; } using (new WaitCursor(this)) { using (UndoTaskHelper undoHelper = new UndoTaskHelper(m_cache.ActionHandlerAccessor, m_rootSite, "kstidUndoStyleChanges")) { // This makes sure the style sheet gets reinitialized after an Undo command. if (m_cache.DomainDataByFlid.GetActionHandler() != null) { m_cache.DomainDataByFlid.GetActionHandler().AddAction( new UndoStyleChangesAction(m_app, true)); } // Save any edits from the dialog to the selected style if (m_styleListHelper.SelectedStyle != null) { StyleInfo styleInfo = (StyleInfo)m_styleListHelper.SelectedStyle.StyleInfo; UpdateChanges(styleInfo); } try { // Check to make sure new styles are not going to result in duplicates // in the database m_styleSheet.CheckForDuplicates(m_styleTable); } catch (IncompatibleStyleExistsException isee) { MessageBoxUtils.Show(isee.Message, m_app.ApplicationName); } foreach (StyleInfo style in m_styleTable.Values) { if (style.IsParagraphStyle && !style.IsInternalStyle && (style.Context != style.NextStyle.Context || style.Structure == StructureValues.Body && style.NextStyle.Structure != style.Structure)) { MessageBox.Show(this, string.Format(FwCoreDlgs.kstidStyleContextMismatchMsg, style.NextStyle.Name, style.Name), FwCoreDlgs.kstidStyleContextMismatchCaption, MessageBoxButtons.OK, MessageBoxIcon.Warning); undoHelper.RollBack = true; DialogResult = DialogResult.None; CurrentStyle = style.Name; return; } } // Save any changed styles to the database foreach (StyleInfo style in m_styleTable.Values) { if (style.Dirty && style.IsValid) { // If there is already a real style, then the style has changed if (style.RealStyle != null) { style.SaveToDB(style.RealStyle, true, style.IsModified); m_changeType |= StyleChangeType.DefChanged; } else { // otherwise, the style does not exist - it has been added // REVIEW: Don't we need to make sure some other user hasn't already // added this style before saving it in the DB? var newStyle = m_cache.ServiceLocator.GetInstance<IStStyleRepository>().GetObject(m_styleSheet.MakeNewStyle()); style.SaveToDB(newStyle, false, true); m_changeType |= StyleChangeType.Added; } } } // Save the real styles for based-on and following style. Do this last so // all of the real styles for added styles will have been created. foreach (StyleInfo style in m_styleTable.Values) { if (style.Dirty && style.IsValid) style.SaveBasedOnAndFollowingToDB(); style.Dirty = false; } DeleteAndRenameStylesInDB(); // Has the user modified any of the styles? if (m_changeType > 0) { if ((m_changeType & StyleChangeType.RenOrDel) > 0) { // Styles were renamed or deleted. if (StylesRenamedOrDeleted != null) StylesRenamedOrDeleted(); } else { // This makes sure the style sheet gets reinitialized after a Redo command. if (m_cache.DomainDataByFlid.GetActionHandler() != null) { m_cache.DomainDataByFlid.GetActionHandler().AddAction( new UndoStyleChangesAction(m_app, false)); } } } else { // If nothing changed then we just pretend the user pressed Cancel. DialogResult = DialogResult.Cancel; } undoHelper.RollBack = false; } } SelectedStyle = m_styleListHelper.SelectedStyle == null ? "" : m_styleListHelper.SelectedStyle.Name; }
private void m_btnInsert_Click(object sender, System.EventArgs e) { IVwSelection sel = m_view.RootBox.Selection; if (sel == null) return; string undo; string redo; ResourceHelper.MakeUndoRedoLabels("kstidUndoRedoInsertRelatedWord", out undo, out redo); using (UndoTaskHelper undoTaskHelper = new UndoTaskHelper(m_cache.MainCacheAccessor, m_view.RootBox.Site != null ? m_view.RootBox.Site : null, undo, redo, true)) { ITsString tss; sel.GetSelectionString(out tss, ""); m_sel.ReplaceWithTsString(tss); // TE-5754: The selection is not the installed selection so the commits that happen // as part of the data monitoring process are not committed to the database. We have // to perform an explicit commit on the selection. m_sel.Commit(); } }
/// -------------------------------------------------------------------------------------- /// <summary> /// /// </summary> /// -------------------------------------------------------------------------------------- protected bool OnScrChecksInconsistency(object args) { TMItemProperties itemProps = args as TMItemProperties; if (itemProps == null || itemProps.ParentForm != TopLevelControl) return false; CheckingError error = SelectedCheckingError; if (error != CheckingError.Empty && error.MyNote.ResolutionStatus != NoteStatus.Open) { string undo; string redo; TeResourceHelper.MakeUndoRedoLabels("kstidUndoRedoResolutionStatusChange", out undo, out redo); using (UndoTaskHelper undoHelper = new UndoTaskHelper(m_cache.ActionHandlerAccessor, null, undo, redo)) { error.MyNote.ResolutionStatus = NoteStatus.Open; undoHelper.RollBack = false; } } return true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Inserts a note referencing the currently selected paragraph. /// </summary> /// <param name="noteType">Type of note</param> /// <param name="startRef">reference at beginning of selection</param> /// <param name="endRef">reference at end of selection</param> /// <param name="topObj">The object where quoted text begins.</param> /// <param name="bottomObj">The object where quoted text ends.</param> /// <param name="wsSelector">The writing system selector.</param> /// <param name="startOffset">The starting character offset.</param> /// <param name="endOffset">The ending character offset.</param> /// <param name="tssQuote">The text of the quote.</param> /// <returns>The inserted note</returns> /// ------------------------------------------------------------------------------------ public virtual IScrScriptureNote InsertNote(ICmAnnotationDefn noteType, BCVRef startRef, BCVRef endRef, CmObject topObj, CmObject bottomObj, int wsSelector, int startOffset, int endOffset, ITsString tssQuote) { CheckDisposed(); TeNotesVc notesVc = CurrentNotesVc; IScrScriptureNote annotation; string sUndo, sRedo; int iPos; ScrBookAnnotations annotations = (ScrBookAnnotations)m_scr.BookAnnotationsOS[startRef.Book - 1]; TeResourceHelper.MakeUndoRedoLabels("kstidInsertAnnotation", out sUndo, out sRedo); string sType = noteType.Name.UserDefaultWritingSystem; sUndo = string.Format(sUndo, sType); sRedo = string.Format(sRedo, sType); using (UndoTaskHelper undoTaskHelper = new UndoTaskHelper(m_cache.MainCacheAccessor, Control as IVwRootSite, sUndo, sRedo, false)) { try { StTxtParaBldr quoteParaBldr = new StTxtParaBldr(m_cache); quoteParaBldr.ParaProps = StyleUtils.ParaStyleTextProps(ScrStyleNames.Remark); quoteParaBldr.StringBuilder.ReplaceTsString(0, 0, tssQuote); annotation = annotations.InsertNote(startRef, endRef, topObj, bottomObj, noteType.Guid, wsSelector, startOffset, endOffset, quoteParaBldr, null, null, null, out iPos); if (notesVc != null) { // tell the VC that the newly inserted item should be expanded. That will cause // the view to be updated to show the new note. notesVc.ExpandItem(annotation.Hvo); notesVc.ExpandItem(annotation.DiscussionOAHvo); } } catch { undoTaskHelper.EndUndoTask = false; FwApp.App.RefreshAllViews(m_cache); throw; } } if (Control != null) Control.Focus(); // Make a selection in the discussion so the user can start to type if (notesVc != null && notesVc.NotesSequenceHandler != null) { // Get the corresponding index in the virtual property. iPos = notesVc.NotesSequenceHandler.GetVirtualIndex(annotations.Hvo, iPos); } IVwRootSite rootSite = Control as IVwRootSite; MakeSelectionInNote(notesVc, startRef.Book - 1, iPos, rootSite, true); // REVIEW: Do we need to create a synch record? return annotation; }
/// ------------------------------------------------------------------------------------ /// <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() || !ValidFootnoteSelection) return true; //discard this event string undo; string redo; TeResourceHelper.MakeUndoRedoLabels("kstidUndoDelFootnote", out undo, out redo); using (UndoTaskHelper undoTaskHelper = new UndoTaskHelper(this, undo, redo)) using (new DataUpdateMonitor(this, "DeleteFootnote")) { // Put code to do work in separate method for testing DeleteFootnoteAux(); undoTaskHelper.RollBack = false; } // If there are no more footnotes, then give focus back to the main draft view if (RootBox.Height <= 0 && DraftView != null) DraftView.Focus(); return true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// For the Insert Section menu, if IP at the end of a section, inserts a new section. /// Sets the IP in the new para of the new section. /// </summary> /// <param name="insertIntroSection">True to make the created section an intro section, /// false otherwise</param> /// <returns><c>true</c> if we handle this.</returns> /// ------------------------------------------------------------------------------------ public bool CreateSection(bool insertIntroSection) { CheckDisposed(); if (CurrentSelection == null) return false; // REVIEW: What should be done if user has a range selection? if (CurrentSelection.Selection.IsRange) { SelectionHelper.ReduceSelectionToIp(Callbacks.EditedRootBox.Site, SelectionHelper.SelLimitType.Top, true); } // if someone is updating data don't do the insertion if (DataUpdateMonitor.IsUpdateInProgress(m_cache.MainCacheAccessor)) return true; Debug.Assert(EditedRootBox != null); if (m_cache == null) return false; int iSection = SectionIndex; int iBook = BookIndex; // Verify that IP is in valid location for new section if (iSection == -1 && !InBookTitle) { if (!InTestMode) { MessageBox.Show(Control, TeResourceHelper.GetResourceString("kstidInsertSectionNotAllowed"), TeResourceHelper.GetResourceString("kstidApplicationName")); } return true; } IVwRootSite rootSite = EditedRootBox.Site; // make sure noone else can update the data string undo; string redo; TeResourceHelper.MakeUndoRedoLabels("kstidInsertSection", out undo, out redo); using (UndoTaskHelper undoTaskHelper = new UndoTaskHelper(rootSite, undo, redo, true)) using (new DataUpdateMonitor(Control, m_cache.MainCacheAccessor, rootSite, "Insert Section")) using (new WaitCursor(Control)) { try { ScrBook book = BookFilter.GetBook(iBook); IScrSection section = null; if (iSection >= 0) section = book[iSection]; int ichIP = CurrentSelection.IchAnchor; int iPara = CurrentSelection.LevelInfo[0].ihvo; StTxtPara para = null; if (InBookTitle) { iSection = 0; InsertSectionAtIndex(book, iSection, insertIntroSection); } else if (CurrentSelection.LevelInfo[1].tag == (int)ScrSection.ScrSectionTags.kflidContent) { // if IP is in a content paragraph para = (StTxtPara)section.ContentOA.ParagraphsOS[iPara]; if (ichIP > para.Contents.Length) ichIP = para.Contents.Length; // we insert the new section after the current one, so the current section // moves down iSection++; // Now insert the new section // if IP is at the end of the last paragraph of the section... if (iPara == section.ContentOA.ParagraphsOS.Count - 1 && (para.Contents.Text == null || ichIP == para.Contents.Length)) { InsertSectionAtIndex(book, iSection, insertIntroSection); } else { // Need to create a new section and split the section content between // the new section and the existing section IScrSection newSection = ScrSection.CreateSectionWithHeadingPara(book, iSection, insertIntroSection); StText.MovePartialContents(section.ContentOA, newSection.ContentOA, iPara, ichIP, false); } } else if (CurrentSelection.LevelInfo[1].tag == (int)ScrSection.ScrSectionTags.kflidHeading) { para = (StTxtPara)section.HeadingOA.ParagraphsOS[iPara]; if (ichIP > para.Contents.Length) ichIP = para.Contents.Length; if (iPara == 0 && ichIP == 0) { // Insert an empty section before the current section InsertSectionAtIndex(book, iSection, insertIntroSection); } else { // Need to create a new section and split the section heading between // the new section and the existing section IScrSection newSection = ScrSection.CreateSectionWithContentPara(book, iSection, insertIntroSection); StText.MovePartialContents(section.HeadingOA, newSection.HeadingOA, iPara, ichIP, true); } } m_cache.PropChanged(null, PropChangeType.kpctNotifyAll, book.Hvo, (int)ScrBook.ScrBookTags.kflidSections, iSection, 1, 0); // Set the insertion point at the beg of the new section contents if (iBook > -1) { ScrSection newSection = new ScrSection(m_cache, book[iSection].Hvo); SelectionHelper selHelperIP = null; StTxtPara firstPara = newSection.FirstContentParagraph; // if dividing an existing section... if (firstPara != null && firstPara.Contents.Length > 0) { // otherwise, set the IP in the section heading selHelperIP = SetInsertionPoint( (int)ScrSection.ScrSectionTags.kflidHeading, iBook, iSection); } else { // set the IP in the paragraph content selHelperIP = SetInsertionPoint(iBook, iSection, 0, 0, false); } // Don't set the character props if the selection is a range // selection. This most likely is the case only if the new // selection is in a user prompt. The user prompt consists of // 2 runs which makes the below code fail because we only give // it enough props to replace 1 run. if (selHelperIP != null && selHelperIP.Selection != null && !selHelperIP.Selection.IsRange) { //TODO: Only do this if we're creating a brand new section, not if // we're splitting one ITsTextProps[] rgttp = new ITsTextProps[] { StyleUtils.CharStyleTextProps(null, m_cache.DefaultVernWs) }; selHelperIP.Selection.SetSelectionProps(1, rgttp); } } return true; } catch (Exception) { undoTaskHelper.EndUndoTask = false; if (FwApp.App != null) // can be null when testing FwApp.App.RefreshAllViews(m_cache); throw; } } }
/// ----------------------------------------------------------------------------------- /// <summary> /// Handle the Edit/Cut menu command. /// </summary> /// <param name="args">The arguments</param> /// <returns><c>true</c> if message handled, otherwise <c>false</c>.</returns> /// <remarks>Formerly <c>AfVwRootSite::CmdEditCut1</c></remarks> /// ----------------------------------------------------------------------------------- protected bool OnEditCut(object args) { if (DataUpdateMonitor.IsUpdateInProgress()) return false; string undo, redo; ResourceHelper.MakeUndoRedoLabels("kstidEditCut", out undo, out redo); using (UndoTaskHelper undoHelper = new UndoTaskHelper(ActiveView.CastAsIVwRootSite(), undo, redo)) using (new DataUpdateMonitor(this, "EditCut")) { bool result = EditingHelper.CutSelection(); undoHelper.RollBack = !result; return result; } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Import an Open XML for Exchanging Scripture Annotations (OXESA) file. /// </summary> /// ------------------------------------------------------------------------------------ public bool OnFileImportOXESA(object args) { CheckDisposed(); using (TeImportExportFileDialog dlg = new TeImportExportFileDialog(m_cache.ProjectId.Name, FileType.OXESA)) { if (dlg.ShowOpenDialog(null, this) == DialogResult.OK) { string sUndo, sRedo; TeResourceHelper.MakeUndoRedoLabels("kstidImportAnnotations", out sUndo, out sRedo); using (UndoTaskHelper undoHelper = new UndoTaskHelper(Cache.ActionHandlerAccessor, null, sUndo, sRedo)) { using (WaitCursor waitCursor = new WaitCursor(this)) { Exception e; XmlScrAnnotationsList.LoadFromFile(dlg.FileName, m_cache, m_StyleSheet, out e); if (e != null) { // Something went wrong while importing so let the user know. MessageBox.Show(string.Format(Properties.Resources.kstidOxesaImportFailedMsg, e.Message), Properties.Resources.kstidOxesaImportFailedTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); } undoHelper.RollBack = false; } } } } return true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Adds a reponse to the current annotation. This really appends a response, it doesn't /// insert. /// </summary> /// <param name="args"></param> /// <returns></returns> /// ------------------------------------------------------------------------------------ public bool OnInsertResponse(object args) { CheckDisposed(); IScrScriptureNote ann = CurrentAnnotation; if (ann == null) return false; m_dataEntryView.ExpandAnnotationIfNeeded(ann.Hvo); string sUndo, sRedo; TeResourceHelper.MakeUndoRedoLabels("kstidCreateResponse", out sUndo, out sRedo); using (UndoTaskHelper undoTaskHelper = new UndoTaskHelper(m_cache.ActionHandlerAccessor, null, sUndo, sRedo)) { int iPos = ann.ResponsesOS.Count; // position where response will be inserted ann.CreateResponse(); m_dataEntryView.OpenExpansionBox(ann.ResponsesOS[0].Hvo); m_dataEntryView.Focus(); // Set the selection in the inserted response. int book = BCVRef.GetBookFromBcv(ann.BeginRef) - 1; int index = ann.IndexInOwner; //TODO: We actually want an index in the filtered list m_dataEntryView.NotesEditingHelper.MakeSelectionInNote(book, index, ann.ResponsesOS.Count - 1, ScrScriptureNoteTags.kflidResponses); undoTaskHelper.RollBack = false; } return true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Delete the current annotation. /// </summary> /// <returns>true if we delete an annotation, otherwise false</returns> /// ------------------------------------------------------------------------------------ public bool OnEditDeleteNote(object args) { CheckDisposed(); if (FwEditingHelper == null || FwEditingHelper.CurrentSelection == null) return false; SelectionHelper helper = FwEditingHelper.CurrentSelection; IScrScriptureNote ann = null; IScrBookAnnotations sba = null; foreach (SelLevInfo info in helper.LevelInfo) { if (info.tag == ScriptureTags.kflidBookAnnotations) sba = Cache.ServiceLocator.GetInstance<IScrBookAnnotationsRepository>().GetObject(info.hvo); else if (info.tag == ScrBookAnnotationsTags.kflidNotes) ann = Cache.ServiceLocator.GetInstance<IScrScriptureNoteRepository>().GetObject(info.hvo); } if (sba == null || ann == null) // Didn't find a deletable note... weird! return false; string sUndo, sRedo; TeResourceHelper.MakeUndoRedoLabels("kstidDeleteAnnotation", out sUndo, out sRedo); int index = m_dataEntryView.DataAccess.GetObjIndex(sba.Hvo, ScrBookAnnotationsTags.kflidNotes, ann.Hvo); using (UndoTaskHelper undoTaskHelper = new UndoTaskHelper(Cache.ActionHandlerAccessor, null, sUndo, sRedo)) { m_dataEntryView.ResetPrevNoteHvo(); sba.NotesOS.Remove(ann); undoTaskHelper.RollBack = false; } int numDisplayedNotes = m_dataEntryView.DataAccess.get_VecSize(sba.Hvo, ScrBookAnnotationsTags.kflidNotes); if (numDisplayedNotes > 0) { if (index >= numDisplayedNotes) index = numDisplayedNotes - 1; ((NotesEditingHelper)EditingHelper).MakeSelectionInNote(m_dataEntryView.m_vc, sba.IndexInOwner, index, m_dataEntryView, false); } return true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Handle the Replace All button click event. /// </summary> /// ------------------------------------------------------------------------------------ protected void OnReplaceAll(object sender, System.EventArgs e) { if (DataUpdateMonitor.IsUpdateInProgress(DataAccess)) return; // discard event using (new DataUpdateMonitor(this, DataAccess, m_vwRootsite, "ReplaceAll", true, true)) { Debug.Assert(m_tool != null); int replaceCount = 0; using (new WaitCursor(this, true)) { m_tool.SetAppModalState(true); PrepareToFind(); m_inReplace = true; if (MatchNotFound == null) MatchNotFound += new MatchNotFoundHandler(NoMatchFound); try { using (UndoTaskHelper undoTaskHelper = new UndoTaskHelper(m_vwRootsite, "kstidUndoReplace", true)) { DateTime start = DateTime.Now; // Do the replace all SetupFindPattern(); SaveDialogValues(); if (PatternIsValid()) { m_searchKiller.AbortRequest = false; m_searchKiller.Control = this; // used for redrawing m_searchKiller.StopControl = this.btnClose; // need to know the stop button m_vwPattern.ReplaceWith = ReplaceText; int hvoRoot, frag; IVwViewConstructor vc; IVwStylesheet styleSheet; m_vwRootsite.RootBox.GetRootObject(out hvoRoot, out vc, out frag, out styleSheet); ReplaceAllCollectorEnv replaceAll = new ReplaceAllCollectorEnv(vc, DataAccess, hvoRoot, frag, m_vwPattern, m_searchKiller); replaceCount = replaceAll.ReplaceAll(); Debug.WriteLine("Replace all took " + (DateTime.Now - start)); } } } finally { PostpareToFind(replaceCount > 0); m_tool.SetAppModalState(false); m_inReplace = false; } } // Display a dialog box if the replace all finished or was stopped if (replaceCount > 0) { bool fShowMsg = true; string msg = ""; if (m_searchKiller.AbortRequest) // if it's been aborted, change the msg displayed msg = string.Format(FwCoreDlgs.kstidReplaceAllStopped, replaceCount); else msg = string.Format(FwCoreDlgs.kstidReplaceAllDone, replaceCount); if (MatchNotFound != null) fShowMsg = MatchNotFound(this, msg, MatchType.ReplaceAllFinished); if (fShowMsg) MessageBox.Show(Owner, msg, Application.ProductName); } else if (replaceCount == 0) InternalMatchNotFound(true); } // After a replace, focus the find box and select the text in it. fweditFindText.FocusAndSelectAll(); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Inserts a footnote at the given selection /// </summary> /// <param name="selHelper">Current selection information</param> /// <param name="styleName">style name for created footnote</param> /// <param name="iFootnote">out: If selHelper is in vernacular para, the ihvo of the /// footnote just inserted. If selHelper is in back trans, the ihvo of the footnote /// corresponding to the ref ORC just inserted in the BT, or -1 no corresponding</param> /// <returns>The created/corresponding footnote</returns> /// ------------------------------------------------------------------------------------ public virtual ScrFootnote InsertFootnote(SelectionHelper selHelper, string styleName, out int iFootnote) { CheckDisposed(); // Get any selected text. ITsString tssSelected; IVwSelection vwsel = selHelper.Selection; if (IsSelectionInOneEditableProp(vwsel)) vwsel.GetSelectionString(out tssSelected, string.Empty); else tssSelected = StringUtils.MakeTss(string.Empty, m_cache.DefaultVernWs); int hvoObj; ITsString tssPara; int propTag; int ws; selHelper.ReduceToIp(SelectionHelper.SelLimitType.Bottom, false, false); int ichSel = GetSelectionInfo(selHelper, out hvoObj, out propTag, out tssPara, out ws); if (propTag == (int)StTxtPara.StTxtParaTags.kflidContents) ws = Cache.DefaultVernWs; // get book info IScrBook book = GetCurrentBook(m_cache); // get paragraph info int paraHvo = selHelper.GetLevelInfoForTag((int)StText.StTextTags.kflidParagraphs).hvo; StTxtPara para = new StTxtPara(m_cache, paraHvo); if (tssSelected.Length > 0) { tssSelected = StringUtils.RemoveORCsAndStylesFromTSS(tssSelected, new List<string>(new string[] {ScrStyleNames.ChapterNumber, ScrStyleNames.VerseNumber}), false, m_cache.LanguageWritingSystemFactoryAccessor); if (tssSelected.Length > 0) { ITsStrBldr bldr = tssSelected.GetBldr(); bldr.SetStrPropValue(0, bldr.Length, (int) FwTextPropType.ktptNamedStyle, ScrStyleNames.ReferencedText); bldr.ReplaceRgch(bldr.Length, bldr.Length, " ", 1, StyleUtils.CharStyleTextProps(null, ws)); tssSelected = bldr.GetString(); } } ScrFootnote footnote = null; string undo; string redo; if (styleName == ScrStyleNames.CrossRefFootnoteParagraph) TeResourceHelper.MakeUndoRedoLabels("kstidInsertCrossReference", out undo, out redo); else TeResourceHelper.MakeUndoRedoLabels("kstidInsertFootnote", out undo, out redo); using (UndoTaskHelper undoTaskHelper = new UndoTaskHelper(Callbacks.EditedRootBox.Site, undo, redo, true)) { try { if (propTag == (int)StTxtPara.StTxtParaTags.kflidContents) { // Inserting footnote into the vernacular paragraph iFootnote = FindFootnotePosition(book, selHelper); ITsStrBldr tsStrBldr = para.Contents.UnderlyingTsString.GetBldr(); // create the footnote and insert its marker into the paragraph's string // builder. footnote = ScrFootnote.InsertFootnoteAt(book, styleName, iFootnote, tsStrBldr, ichSel); // BEFORE we insert the ORC in the paragraph, we need to insert an empty // paragraph into the new StFootnote, because the para style is needed to // determine the footnote marker type. StTxtPara footnotePara = new StTxtPara(); footnote.ParagraphsOS.Append(footnotePara); // If we wait for this to be created by the VC, its creation won't be part of the // Undo task, and we won't be able to Undo creating the footnote, because the paragraph // will own something that Undo doesn't know to delete (TE-7988). footnotePara.GetOrCreateBT(); ITsPropsBldr propsBldr = TsPropsBldrClass.Create(); propsBldr.SetStrPropValue((int)FwTextPropType.ktptNamedStyle, styleName); footnotePara.StyleRules = propsBldr.GetTextProps(); // Record information, as if we were typing the footnote caller, that allows // segment boundaries to be adjusted properly. OnAboutToEdit(); // update the paragraph contents to include the footnote marker para.Contents.UnderlyingTsString = tsStrBldr.GetString(); // Finish off any necessary annotation adjustments. m_annotationAdjuster.OnFinishedEdit(); // Insert the selected text (or an empty run) into the footnote paragraph. footnotePara.Contents.UnderlyingTsString = tssSelected; // Do a prop change to get the footnote updated in all views m_cache.PropChanged(null, PropChangeType.kpctNotifyAll, book.Hvo, (int)ScrBook.ScrBookTags.kflidFootnotes, iFootnote, 1, 0); } else { // Inserting footnote reference ORC into a back translation ICmTranslation btParaTrans = para.GetOrCreateBT(); ITsString btTss = btParaTrans.Translation.GetAlternative(ws).UnderlyingTsString; footnote = FindVernParaFootnote(ichSel, btTss, para); if (footnote != null) { // Insert footnote reference ORC into back translation paragraph. ITsStrBldr tssBldr = btTss.GetBldr(); //if reference to footnote already somewhere else in para, delete it first int ichDel = StTxtPara.DeleteBtFootnoteMarker(tssBldr, footnote.Guid); if (ichDel >= 0 && ichSel > ichDel) ichSel -= footnote.FootnoteMarker.Length; footnote.InsertRefORCIntoTrans(tssBldr, ichSel, ws); btParaTrans.Translation.SetAlternative(tssBldr.GetString(), ws); iFootnote = footnote.IndexInOwner; if (tssSelected.Length > 0) { ICmTranslation btFootnoteTrans = ((StTxtPara) footnote.ParagraphsOS[0]).GetOrCreateBT(); ITsString btFootnoteTss = btFootnoteTrans.Translation.GetAlternative(ws).UnderlyingTsString; // Insert any selected text into this back translation for the footnote paragraph. btFootnoteTrans.Translation.SetAlternative(tssSelected, ws); } } else { iFootnote = -1; MiscUtils.ErrorBeep(); // No footnote reference ORC inserted } } } catch { undoTaskHelper.EndUndoTask = false; throw; // rethrow the original exception } } return footnote; }
/// ----------------------------------------------------------------------------------- /// <summary> /// Handle the Edit/Paste menu command. /// </summary> /// <param name="args">The arguments</param> /// <returns><c>true</c> if message handled, otherwise <c>false</c>.</returns> /// <remarks>Formerly <c>AfVwRootSite::CmdEditPaste1</c></remarks> /// ----------------------------------------------------------------------------------- protected bool OnEditPaste(object args) { if (DataUpdateMonitor.IsUpdateInProgress() || EditingHelper == null || !EditingHelper.CanPaste()) return true; //discard this event string stUndo, stRedo; ResourceHelper.MakeUndoRedoLabels("kstidEditPaste", out stUndo, out stRedo); using (UndoTaskHelper undoHelper = new UndoTaskHelper(ActiveView.CastAsIVwRootSite(), stUndo, stRedo)) using (new DataUpdateMonitor(this, "EditPaste")) { if (EditingHelper.PasteClipboard()) undoHelper.RollBack = false; } return true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Insert verse number at the current insertion point, with undo. /// </summary> /// ------------------------------------------------------------------------------------ public void InsertVerseNumber() { CheckDisposed(); // If selection is a range, we reduce it to an IP (top) SelectionHelper selHelper = SelectionHelper.ReduceSelectionToIp(Callbacks.EditedRootBox.Site, SelectionHelper.SelLimitType.Top, false); if (selHelper == null) { MiscUtils.ErrorBeep(); return; } IVwSelection vwselNew = selHelper.SetSelection(false); // If selection is not in ScrSection Content (vern or BT), quit if (!CanInsertNumberInElement || vwselNew == null) { MiscUtils.ErrorBeep(); return; } string undo; string redo; TeResourceHelper.MakeUndoRedoLabels("kstidInsertVerseNumber", out undo, out redo); using(UndoTaskHelper undoTaskHelper = new UndoTaskHelper(Callbacks.EditedRootBox.Site, undo, redo, true)) { InsertVerseNumber(selHelper); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Display the project properties dialog /// </summary> /// <param name="args"></param> /// ------------------------------------------------------------------------------------ protected virtual bool OnFileProjectProperties(object args) { // Disabling the main window circumvents the usual mechanisms for switching keyboards, // so we manually switch to the default keyboard here so that the Project Properties // dialog displays the default keyboard. When we're all done we switch back to the // keyboard we had recently. (TE-4683) var oldWsd = Keyboard.Controller.ActiveKeyboard; Keyboard.Controller.ActivateDefaultKeyboard(); // Disable windows on cache to prevent painting when fonts for writing system are changed m_app.EnableMainWindows(false); bool fDbRenamed = false; bool fFilesMoved = false; string sProject = m_cache.ProjectId.Name; string sOrigLinkedFilesRootDir = m_cache.LangProject.LinkedFilesRootDir; try { using (var dlg = new FwProjPropertiesDlg(m_cache, m_app, m_app, m_StyleSheet)) { if (dlg.ShowDialog(this) != DialogResult.OK) return true; using (new WaitCursor(this)) { fDbRenamed = dlg.ProjectNameChanged(); if (fDbRenamed) sProject = dlg.ProjectName; if (dlg.LinkedFilesChanged()) fFilesMoved = m_app.UpdateExternalLinks(sOrigLinkedFilesRootDir); if (!fDbRenamed) { // rename works only if other programs (like Flex) are not // running. In which case, the Sync operation isn't needed. // Note: We handle this here since Flex does full refresh and we don't want // this happening first. if (dlg.WritingSystemsChanged()) { using (var undoHelper = new UndoTaskHelper(m_cache.ActionHandlerAccessor, null, "kstidUndoRedoProjectProperties")) { var undoAction = new SyncUndoAction(m_app, SyncMsg.ksyncWs); undoAction.Do(); m_cache.DomainDataByFlid.GetActionHandler().AddAction(undoAction); undoHelper.RollBack = false; } } } } } } finally { m_app.EnableMainWindows(true); if (!fDbRenamed && !fFilesMoved) // no need for refresh when total shutdown & reopen { // Make sure windows for this cache are now enabled. // if the dialog merged two writing systems it will close/dispose this FwMainWnd. // if so, don't try to access any properties like EditingHelper or we'll crash (TE-7297). if (!IsDisposed) { // Restore the previous keyboard if (oldWsd != null) oldWsd.Activate(); } } } if (fDbRenamed) m_app.FwManager.RenameProject(sProject, m_app); return true; }
private void EditCheckingErrorComment(CheckingError error, string undoRedoLabel, bool fResolve) { if (StyleSheet == null) return; string undo; string redo; TeResourceHelper.MakeUndoRedoLabels(undoRedoLabel, out undo, out redo); using (UndoTaskHelper undoHelper = new UndoTaskHelper(m_cache.ActionHandlerAccessor, null, undo, redo)) { if (fResolve) error.MyNote.ResolutionStatus = NoteStatus.Closed; using (CheckingErrorCommentDlg dlg = new CheckingErrorCommentDlg(error, StyleSheet, m_helpTopicProvider)) { if (dlg.ShowDialog(FindForm()) == DialogResult.OK) { // Force the cell to repaint so the red corner glyph gets painted. int iRow = m_dataGridView.CurrentCellAddress.Y; m_dataGridView.InvalidateCell(kStatusCol, iRow); undoHelper.RollBack = false; } } } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Handle the Page Setup menu option. /// </summary> /// <param name="args"></param> /// <returns><c>true</c> if this event is handled</returns> /// ------------------------------------------------------------------------------------ public bool OnPageSetup(object args) { CheckDisposed(); IPublication pub; IPubDivision div; IPubPageLayout pgl; if (!PageSetupPreparePublication(out pub, out div, out pgl)) return false; using (IPageSetupDialog dlg = CreatePageSetupDialog(pgl, pub, div)) { // The PageSetup dialog is view specific, so we add the view name to the title. if (CurrentPublicationName != null) { dlg.Text = string.Format(ResourceHelper.GetResourceString( "kstidPageSetupWithViewName"), CurrentPublicationName); } using (UndoTaskHelper undoHelper = new UndoTaskHelper(m_cache.ActionHandlerAccessor, null, "kstidUndoPageSetupChanges")) { if (dlg.ShowDialog() == DialogResult.OK && CurrentPublicationView != null) { CurrentPublicationView.ApplyPubOverrides(dlg.BaseCharacterSize, -dlg.BaseLineSpacing); CurrentPublicationView.RefreshDisplay(); } undoHelper.RollBack = false; } } return true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Shows the category chooser dialog to let the user set the category for the /// specified annotation. /// </summary> /// ------------------------------------------------------------------------------------ private void SetAnnotationCategory(IScrScriptureNote ann) { if (ann == null) return; // Not much we can do m_rootb.DestroySelection(); string sUndo, sRedo; TeResourceHelper.MakeUndoRedoLabels("kstidSetAnnotationCategory", out sUndo, out sRedo); using (new WaitCursor(this)) using (CategoryChooserDlg dlg = new CategoryChooserDlg(m_scr.NoteCategoriesOA, ann.CategoriesRS.ToHvoArray(), m_helpTopicProvider, TheMainWnd.App)) { if (dlg.ShowDialog(ParentForm) == DialogResult.OK) { using (UndoTaskHelper undoHelper = new UndoTaskHelper(this, sUndo, sRedo)) { dlg.GetPossibilities(ann.CategoriesRS); ann.DateModified = DateTime.Now; undoHelper.RollBack = false; } } } }
/// ------------------------------------------------------------------------------------ /// <summary> /// This event is called by the styles combo box when the user chooses a style from the /// combo box. /// </summary> /// <param name="prevStyle">The previously selected style (not used)</param> /// <param name="newStyle">The new style</param> /// ------------------------------------------------------------------------------------ public void StyleChosenFromStylesComboBox(StyleListItem prevStyle, StyleListItem newStyle) { CheckDisposed(); // See TE-4675 for some reasons why newStyle might be null. if (newStyle == null) return; Logger.WriteEvent(string.Format("Applying style {0}", newStyle.Name)); IRootSite rootSite = ActiveView; if (rootSite != null) { Debug.Assert(rootSite.EditingHelper != null); Control ctrl = rootSite as Control; if (ctrl != null) ctrl.Focus(); if (rootSite.EditingHelper.GetParaStyleNameFromSelection() == newStyle.Name) return; using (UndoTaskHelper undoHelper = new UndoTaskHelper(rootSite.CastAsIVwRootSite(), "kstidUndoStyleChanges")) { if (newStyle.IsDefaultParaCharsStyle) rootSite.EditingHelper.RemoveCharFormatting(); else rootSite.EditingHelper.ApplyStyle(newStyle.Name); undoHelper.RollBack = false; } } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Deletes a footnote when the selection is on a footnote marker. /// Called from context menu. /// </summary> /// <param name="args"></param> /// <returns><c>true</c> if we handle this</returns> /// ------------------------------------------------------------------------------------ protected bool OnDeleteFootnote(object args) { if (DataUpdateMonitor.IsUpdateInProgress()) return true; //discard this event string undo; string redo; TeResourceHelper.MakeUndoRedoLabels("kstidUndoDelFootnote", out undo, out redo); using (UndoTaskHelper undoHelper = new UndoTaskHelper(this, undo, redo)) using (new DataUpdateMonitor(this, "DeleteFootnote")) { TeEditingHelper.OnDeleteFootnoteAux(); undoHelper.RollBack = false; } return true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Handles the Click event of the m_btnOk control. /// </summary> /// ------------------------------------------------------------------------------------ private void m_btnOk_Click(object sender, EventArgs e) { if (IsRootSiteDisposed()) { MessageBox.Show(FwCoreDlgs.kstidChangesAreLost, FwCoreDlgs.kstidWarning); DialogResult = DialogResult.Cancel; return; } using (new WaitCursor(this)) { // We can't use using() here because we might have to create a new undo task below. CreateUndoTaskHelper(); try { // This makes sure the style sheet gets reinitialized after an Undo command. if (m_cache.ActionHandlerAccessor != null) { m_cache.ActionHandlerAccessor.AddAction( new UndoStyleChangesAction(m_app, m_cache, true)); } // Save any edits from the dialog to the selected style if (m_styleListHelper.SelectedStyle != null) { StyleInfo styleInfo = (StyleInfo)m_styleListHelper.SelectedStyle.StyleInfo; UpdateChanges(styleInfo); } // Check to make sure new styles are not going to result in duplicates // in the database m_styleSheet.CheckForDuplicates(m_styleTable); // Save any changed styles to the database foreach (StyleInfo style in m_styleTable.Values) { if (style.Dirty && style.IsValid) { // If there is already a real style, then the style has changed if (style.RealStyle != null) { style.SaveToDB(style.RealStyle, true); m_changeType |= StyleChangeType.DefChanged; } else { // otherwise, the style does not exist - it has been added // REVIEW: Don't we need to make sure some other user hasn't already // added this style before saving it in the DB? StStyle newStyle = new StStyle(m_cache, m_styleSheet.MakeNewStyle()); style.SaveToDB(newStyle, false); m_changeType |= StyleChangeType.Added; } } } // Save the real styles for based-on and following style. Do this last so // all of the real styles for added styles will have been created. foreach (StyleInfo style in m_styleTable.Values) { if (style.Dirty && style.IsValid) style.SaveBasedOnAndFollowingToDB(); style.Dirty = false; } DeleteAndRenameStylesInDB(); // Has the user modified any of the styles? if (m_changeType > 0) { if ((m_changeType & StyleChangeType.RenOrDel) > 0) { // Styles were renamed or deleted. // Because this might involve quite a bit of database interaction, the // styles dialog calls Save() before performing the rename/delete. This // ends the undo task (it's not undoable), so we can't end it again or // add new actions to it m_UndoTaskHelper.Dispose(); m_cache.Save(); CreateUndoTaskHelper(); if (StylesRenamedOrDeleted != null) StylesRenamedOrDeleted(); } else { // This makes sure the style sheet gets reinitialized after a Redo command. if (m_cache.ActionHandlerAccessor != null) { m_cache.ActionHandlerAccessor.AddAction( new UndoStyleChangesAction(m_app, m_cache, false)); } } m_app.Synchronize(new SyncInfo(SyncMsg.ksyncStyle, 0, 0), m_cache); } else { // If nothing changed then we just pretend the user pressed Cancel. DialogResult = DialogResult.Cancel; } } finally { m_UndoTaskHelper.Dispose(); m_UndoTaskHelper = null; } } }
/// ----------------------------------------------------------------------------------- /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged /// resources; <c>false</c> to release only unmanaged resources. /// </param> /// ----------------------------------------------------------------------------------- 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) { if (m_messageFilterInstalled) { Application.RemoveMessageFilter(this); m_messageFilterInstalled = false; } // We don't want to call Controls.Clear() here, because that causes the controls // to change size (and fire the events for it...). It causes CreateMenuAndToolbars() // to be called, so we end up with two toolbar adapters, but we dispose only one, // so eventually it tries to access the already disposed mediator. //Controls.Clear(); // No, since m_bookMerger owns it. // if (m_differences != null) // m_differences.Dispose(); if (m_viewHelper != null) m_viewHelper.Dispose(); if (m_msgMediator != null) { m_msgMediator.RemoveColleague(this); // m_msgMediator gets disposed from calling components.Dispose() below } if (m_undoTaskHelper != null) m_undoTaskHelper.Dispose(); if(components != null) { components.Dispose(); } } // Deal with unmanaged stuff here. m_viewHelper = null; m_differences = null; // Just null it, since m_bookMerger owns it and will dispose it. m_msgMediator = null; m_bookMerger = null; // Client gave it, so it has to dispose it. m_cache = null; m_scr = null; m_stylesheet = null; m_undoTaskHelper = null; base.Dispose( disposing ); }
private void CreateUndoTaskHelper() { if (m_rootSite == null) m_UndoTaskHelper = new UndoTaskHelper(m_cache.MainCacheAccessor, null, "kstidUndoStyleChanges", false); else m_UndoTaskHelper = new UndoTaskHelper(m_rootSite, "kstidUndoStyleChanges", false); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Handle a click on the Keep Current button /// </summary> /// ------------------------------------------------------------------------------------ protected void btnKeepCurrent_Click(object sender, EventArgs e) { using (new WaitCursor(this)) { Difference oldDiff = m_differences.CurrentDifference; string undo; string redo; TeResourceHelper.MakeUndoRedoLabels("kstidDiffDlgKeepCurrentUndoRedo", out undo, out redo); using(UndoTaskHelper undoTaskHelper = new UndoTaskHelper( ActiveView.CastAsIVwRootSite(), undo, redo, true)) { m_cache.ActionHandlerAccessor.AddAction(new UndoMajorDifferenceAction(m_bookMerger)); // remove current difference from list and advance to the next difference. m_bookMerger.MarkDifferenceAsReviewed(oldDiff); } RefreshStatus(); // MarkDifferenceAsReviewed removes an item from the difference list. // Because of that, the current difference index ends up pointing to // the next difference in the list. Difference diff = m_differences.CurrentDifference; DisplayDifference(oldDiff, diff); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Applies the given URL as a hotlink to the currently selected text, if any, or /// inserts a link to the URL. /// </summary> /// <param name="clip">The URL.</param> /// <param name="stylesheet">The stylesheet.</param> /// ------------------------------------------------------------------------------------ public void ConvertSelToLink(string clip, FwStyleSheet stylesheet) { CheckDisposed(); var hyperlinkStyle = stylesheet.FindStyle(StyleServices.Hyperlink); if (m_callbacks == null || m_callbacks.EditedRootBox == null || hyperlinkStyle == null) return; IVwSelection sel = m_callbacks.EditedRootBox.Selection; ISilDataAccess sda = m_callbacks.EditedRootBox.DataAccess; var actionHandler = sda.GetActionHandler(); if(actionHandler == null) return; // no way we can do it. ITsString tssLink; bool fGotItAll; sel.GetFirstParaString(out tssLink, " ", out fGotItAll); ITsStrBldr tsb = tssLink.GetBldr(); if (sel.IsRange) { // Use the text of the selection as the text of the link int ich = tssLink.Text.IndexOf(Environment.NewLine); if (!fGotItAll || ich >= 0) { tsb.ReplaceTsString(ich, tsb.Length, null); int ichTop; if (sel.EndBeforeAnchor) ichTop = sel.get_ParagraphOffset(true); else ichTop = sel.get_ParagraphOffset(false); SelectionHelper helper = SelectionHelper.Create(sel, EditedRootBox.Site); helper.IchAnchor = ichTop; helper.IchEnd = ich; sel = helper.Selection; } //sel.GetSelectionString(out tssLink, " "); } if (!sel.IsRange) { ITsStrFactory tsf = TsStrFactoryClass.Create(); tssLink = tsf.MakeString(clip, sda.WritingSystemFactory.UserWs); tsb = tssLink.GetBldr(); } using (UndoTaskHelper undoTaskHelper = new UndoTaskHelper(actionHandler, EditedRootBox.Site, RootSiteStrings.ksUndoInsertLink, RootSiteStrings.ksRedoInsertLink)) { if (m_cache != null && m_cache.ProjectId != null) clip = FwLinkArgs.FixSilfwUrlForCurrentProject(clip, m_cache.ProjectId.Name, m_cache.ProjectId.ServerName); var filename = StringServices.MarkTextInBldrAsHyperlink(tsb, 0, tsb.Length, clip, hyperlinkStyle, m_cache.LanguageProject.LinkedFilesRootDir); if (FileUtils.IsFilePathValid(filename)) { Debug.Assert(m_cache.LangProject.FilePathsInTsStringsOA != null, "Somehow migration #30 did not add the FilePathsInTsStrings CmFolder. Fix by modifying FindOrCreateFolder()"); DomainObjectServices.FindOrCreateFile(m_cache.LangProject.FilePathsInTsStringsOA, filename); } tssLink = tsb.GetString(); sel.ReplaceWithTsString(tssLink); undoTaskHelper.RollBack = false; // Arrange that immediate further typing won't extend link. sel = Callbacks.EditedRootBox.Selection; // may have been changed. if (sel == null) return; ITsPropsBldr pb = tssLink.get_PropertiesAt(0).GetBldr(); pb.SetStrPropValue((int)FwTextPropType.ktptObjData, null); pb.SetStrPropValue((int)FwTextPropType.ktptNamedStyle, null); sel.SetTypingProps(pb.GetTextProps()); } }
/// ------------------------------------------------------------------------------------ /// <summary> /// End editing the current diff view /// </summary> /// ------------------------------------------------------------------------------------ public void EndEditMode() { CheckDisposed(); m_undoTaskHelper.Dispose(); m_undoTaskHelper = null; m_diffViewWrapper.CurrentDiffView.Editable = false; m_diffViewWrapper.CurrentDiffView.RefreshDisplay(); if (m_diffViewWrapper.CurrentDiffFootnoteView != null) { m_diffViewWrapper.CurrentDiffFootnoteView.Editable = false; m_diffViewWrapper.CurrentDiffFootnoteView.RefreshDisplay(); } }
private void m_btnInsert_Click(object sender, System.EventArgs e) { IVwSelection sel = m_view.RootBox.Selection; if (sel == null) return; string undo; string redo; ResourceHelper.MakeUndoRedoLabels("kstidUndoRedoInsertRelatedWord", out undo, out redo); using (UndoTaskHelper undoTaskHelper = new UndoTaskHelper(m_cache.ActionHandlerAccessor, m_view.RootBox.Site, undo, redo)) { ITsString tss; sel.GetSelectionString(out tss, ""); m_sel.ReplaceWithTsString(tss); undoTaskHelper.RollBack = false; } }