/// ------------------------------------------------------------------------------------ /// <summary> /// Sets the current book, particularly picking the right set of annotations /// to add new ones to. Also (and more conspicuously) ends the current Undo task /// and makes a new one for importing the new book. Should therefore be called /// BEFORE setting up the Undo action for the creation of the book. /// </summary> /// <param name="nCanonicalBookNumber">The canonical book number.</param> /// <returns>The action handler</returns> /// ------------------------------------------------------------------------------------ private IActionHandler SetCurrentBookInternal(int nCanonicalBookNumber) { // We temporarily un-suppress our action handler long enough to get it so we can // grab a local copy. m_suppressor.Dispose(); m_suppressor = null; IActionHandler actionHandler = m_cache.ActionHandlerAccessor; m_suppressor = new SuppressSubTasks(m_cache); if ((m_importedSavedVersion != null && m_importedSavedVersion.BooksOS.Count > 0) || (m_savedVersion != null && m_savedVersion.BooksOS.Count > 0)) { // We want a new undo task for each new book, except the first one actionHandler.EndOuterUndoTask(); } // No need to use localizable string from resources because the user will never // see these labels because we collapse to a single undo task when the import // completes. actionHandler.BeginUndoTask("Undo Import Book " + nCanonicalBookNumber, "Redo Import Book " + nCanonicalBookNumber); m_annotations = (ScrBookAnnotations)m_scr.BookAnnotationsOS[nCanonicalBookNumber - 1]; return(actionHandler); }
/// <summary> /// This must be called before starting import. /// </summary> public void StartImportingFiles() { Debug.Assert(m_cache.DomainDataByFlid.GetActionHandler() != null); Debug.Assert(m_cache.DomainDataByFlid.GetActionHandler().CurrentDepth == 0); m_hMark = m_cache.DomainDataByFlid.GetActionHandler().Mark(); IActionHandler actionHandler = m_cache.ActionHandlerAccessor; actionHandler.BeginUndoTask("Create saved version", "Create saved version"); m_backupVersion = GetOrCreateVersion(TeResourceHelper.GetResourceString("kstidSavedVersionDescriptionOriginal")); }
private SelectionHelper SetupForTypingEventHandler(bool checkIfFocused, bool rollBackPreviousTask) { if (AssociatedSimpleRootSite.ReadOnlyView || AssociatedSimpleRootSite.RootBox == null || AssociatedSimpleRootSite.RootBox.Selection == null || (checkIfFocused && (!AssociatedSimpleRootSite.Focused || (AssociatedSimpleRootSite.TopLevelControl != null && !AssociatedSimpleRootSite.TopLevelControl.Enabled)))) { return(null); } var selHelper = new SelectionHelper(AssociatedSimpleRootSite.EditingHelper.CurrentSelection); if (m_ActionHandler == null) { m_ActionHandler = AssociatedSimpleRootSite.DataAccess.GetActionHandler(); } else if (rollBackPreviousTask) { if (m_ActionHandler.get_TasksSinceMark(true)) { m_ActionHandler.Rollback(m_Depth); selHelper = new SelectionHelper(m_InitialSelection.SelectionHelper); } else if (m_InitialSelection.SelectionHelper.IsRange) { return(selHelper); } else { return(new SelectionHelper(m_InitialSelection.SelectionHelper)); } } else { return(selHelper); } if (m_ActionHandler != null) { m_Depth = m_ActionHandler.CurrentDepth; m_ActionHandler.BeginUndoTask(Resources.ksUndoTyping, Resources.ksRedoTyping); } return(selHelper); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Sets the current book, particularly picking the right set of annotations /// to add new ones to. Also (and more conspicuously) ends the current Undo task /// and makes a new one for importing the new book. Should therefore be called /// BEFORE setting up the Undo action for the creation of the book. /// </summary> /// <param name="nCanonicalBookNumber">The canonical book number.</param> /// <param name="fVernacular">if set to <c>true</c> currently importing the vernacular. /// </param> /// <returns>The existing book in the current imported version, if any; otherwise /// <c>null</c></returns> /// <remarks>If importing annotations and/or BTs without importing the vernacular, the /// importer is responsible for calling this directly.</remarks> /// ------------------------------------------------------------------------------------ private IScrBook SetCurrentBook(int nCanonicalBookNumber, bool fVernacular) { if (nCanonicalBookNumber <= 0 || nCanonicalBookNumber > BCVRef.LastBook) { throw new ArgumentOutOfRangeException("nCanonicalBookNumber", nCanonicalBookNumber, "Expected a canonical book number."); } IActionHandler actionHandler = m_cache.DomainDataByFlid.GetActionHandler(); // We want a new undo task for each new book, except the first one if (m_importedBooks.Count > 0) { actionHandler.EndUndoTask(); } if (actionHandler.CurrentDepth == 0) { // No need to use localizable string from resources because the user will never // see these labels because we collapse to a single undo task when the import // completes. actionHandler.BeginUndoTask("Undo Import Book " + nCanonicalBookNumber, "Redo Import Book " + nCanonicalBookNumber); } if (m_importedBooks.ContainsKey(nCanonicalBookNumber)) { m_lastBookAddedToImportedBooks = 0; } else { m_lastBookAddedToImportedBooks = nCanonicalBookNumber; m_importedBooks[nCanonicalBookNumber] = fVernacular; } m_annotations = m_scr.BookAnnotationsOS[nCanonicalBookNumber - 1]; return((m_importedVersion == null) ? null : m_importedVersion.FindBook(nCanonicalBookNumber)); }
/// <summary> /// Handle the CommitText event. Transfer to GUI thread if neccessary. /// </summary> private void CommitTextEventHandler(string text) { if (AssociatedSimpleRootSite.InvokeRequired) { AssociatedSimpleRootSite.SafeBeginInvoke( new CommitDelegate(CommitTextEventHandler), new object[] { text }); return; } IActionHandler actionHandler = AssociatedSimpleRootSite.DataAccess.GetActionHandler(); try { if (actionHandler != null) { actionHandler.BeginUndoTask(Resources.ksUndoTyping, Resources.ksRedoTyping); } // Save existing Preedit Selection and existing left-over preedit string. var preeditSelection = SavePreeditSelection(); ITsString preedit; preeditSelection.Selection.GetSelectionString(out preedit, String.Empty); // Change selection to a insertion point (unless we moved the selection before, // which happens when we come here as part of processing a mouse click) // And insert commit text. var selHelper = new SelectionHelper( m_savedPreeditSelection ?? AssociatedSimpleRootSite.EditingHelper.CurrentSelection); if (m_savedPreeditSelection == null) { selHelper.ReduceToIp(SelectionHelper.SelLimitType.Anchor); } selHelper.SetSelection(true); AssociatedSimpleRootSite.EditingHelper.OnCharAux(text, VwShiftStatus.kfssNone, Keys.None); int deletedChars = TrimBeginningBackspaces(ref text); // Update the saved preedit selection to take account of the inserted text // text is in NFC, but the view uses it in NFD, so we have to convert it. // We don't do this if we moved the selection prior to this method. int textLenNFD = m_savedPreeditSelection != null ? 0 : Icu.Normalize(text, Icu.UNormalizationMode.UNORM_NFD).Length; int anchor = preeditSelection.IchAnchor + textLenNFD - deletedChars; // select the text we just inserted // TODO: underline the text so that it is more obvious that this is just preedit text preeditSelection.SetIch(SelectionHelper.SelLimitType.Anchor, anchor); preeditSelection.SetIch(SelectionHelper.SelLimitType.End, preeditSelection.IchEnd + textLenNFD - deletedChars); // reshow the preedit selection RestorePreeditSelection(preeditSelection); preeditSelection.Selection.ReplaceWithTsString(preedit); preeditSelection.SetSelection(true); } finally { m_savedPreeditSelection = null; if (actionHandler != null) { actionHandler.EndUndoTask(); } } }
/// <summary> /// This method must be called by the GUI thread only. /// It shows the current Preedit as a selection. /// </summary> private void ShowPreedit(string text, bool visible) { // Don't allow modifying the preedit if an undo or redo is in progress. if (m_dataChanging) { return; } if (AssociatedSimpleRootSite.InvokeRequired) { throw new ApplicationException( "Programming Error: ShowPreedit should only be called on GUI thread"); } if (AssociatedSimpleRootSite.RootBox == null) { return; } if (AssociatedSimpleRootSite.RootBox.Selection == null) { return; } // Some IME send a initial empty preedit, which can clear an existing selection // TODO: we could also check the selection is a range if this is neccessary if (string.IsNullOrEmpty(text) && m_ignoreInitialPreedit) { return; } m_ignoreInitialPreedit = false; IActionHandler actionHandler = AssociatedSimpleRootSite.DataAccess.GetActionHandler(); try { if (actionHandler != null) { actionHandler.BeginUndoTask(Resources.ksUndoTyping, Resources.ksRedoTyping); } AssociatedSimpleRootSite.EditingHelper.DeleteRangeIfComplex( AssociatedSimpleRootSite.RootBox); // update the current preedit selection with new preedit text. var selHelper = new SelectionHelper( AssociatedSimpleRootSite.EditingHelper.CurrentSelection); ITsString str = CreateTsStringUsingSelectionProps(text, selHelper); selHelper.Selection.ReplaceWithTsString(str); // make the selection fit the new text selHelper.SetIch(SelectionHelper.SelLimitType.Anchor, selHelper.GetIch(SelectionHelper.SelLimitType.Top)); selHelper.SetIch(SelectionHelper.SelLimitType.End, selHelper.IchAnchor + str.Length); // make the selection visible selHelper.SetSelection(true); } finally { if (actionHandler != null) { actionHandler.EndUndoTask(); } } // Update the position where a preedit window will appear SetImeCursorLocation(); }