protected override void HandleSelectionChange(IVwRootBox prootb, IVwSelection vwselNew)
{
if (m_fInSelectionChanged)
return; // don't need to reprocess our own changes.
m_fInSelectionChanged = true;
try
{
base.HandleSelectionChange(prootb, vwselNew);
IVwSelection sel = vwselNew;
if (!sel.IsValid)
sel = prootb.Selection;
if (sel == null)
return;
SelectionHelper helper = SelectionHelper.Create(sel, prootb.Site);
// Check whether the selection is on the proper line of a multilingual
// annotation and, if not, fix it. See LT-9421.
if (m_cpropPrevForInsert > 0 && !sel.IsRange &&
(helper.GetNumberOfPreviousProps(SelectionHelper.SelLimitType.Anchor) == 0 ||
helper.GetNumberOfPreviousProps(SelectionHelper.SelLimitType.End) == 0))
{
try
{
helper.SetNumberOfPreviousProps(SelectionHelper.SelLimitType.Anchor, m_cpropPrevForInsert);
helper.SetNumberOfPreviousProps(SelectionHelper.SelLimitType.End, m_cpropPrevForInsert);
helper.MakeBest(true);
m_cpropPrevForInsert = -1; // we've used this the one time it was needed.
}
catch (Exception exc)
{
if (exc != null)
Debug.WriteLine(String.Format(
"InterlinDocChild.SelectionChanged() trying to display prompt in proper line of annotation: {0}", exc.Message));
}
}
int flid = helper.GetTextPropId(SelectionHelper.SelLimitType.Anchor);
//If the flid is -2 and it is an insertion point then we may have encountered a case where the selection has landed at the boundary between our (possibly empty)
//translation field and a literal string containing our magic Bidi marker character that helps keep things in the right order.
//Sometimes AssocPrev gets set so that we read the (non-existent) flid of the literal string and miss the fact that on the other side
//of the insertion point is the field we're looking for. The following code will attempt to make a selection that associates in
//the other direction to see if the flid we want is on the other side. [LT-10568]
if (flid == -2 && !sel.IsRange && sel.SelType == VwSelType.kstText)
{
helper.AssocPrev = !helper.AssocPrev;
try
{
var newSel = helper.MakeRangeSelection(this.RootBox, false);
helper = SelectionHelper.Create(newSel, this);
flid = helper.GetTextPropId(SelectionHelper.SelLimitType.Anchor);
}
catch (COMException)
{
// Ignore HResult E_Fail caused by Extended Keys (PgUp/PgDown) in non-editable text (LT-13500)
}
}
//Fixes LT-9884 Crash when clicking on the blank space in Text & Words--->Print view area!
if (helper.LevelInfo.Length == 0)
return;
int hvo = helper.LevelInfo[0].hvo;
// If the selection is in a freeform or literal translation that is empty, display the prompt.
if (SelIsInEmptyTranslation(helper, flid, hvo) && !m_rootb.IsCompositionInProgress)
{
var handlerExtensions = Cache.ActionHandlerAccessor as IActionHandlerExtensions;
if (handlerExtensions != null && handlerExtensions.IsUndoTaskActive)
{
// Wait to make the changes until the task (typically typing backspace) completes.
m_setupPromptHelper = helper;
m_setupPromptFlid = flid;
handlerExtensions.DoAtEndOfPropChanged(handlerExtensions_PropChangedCompleted);
}
else
{
// No undo task to tag on the end of, so do it now.
SetupTranslationPrompt(helper, flid);
}
}
else if (flid != kTagUserPrompt)
{
m_vc.SetActiveFreeform(0, 0, 0, 0); // clear any current prompt.
}
// do not extend the selection for a user prompt if the user is currently entering an IME composition,
// since we are about to switch the prompt to a real comment field
else if (helper.GetTextPropId(SelectionHelper.SelLimitType.End) == SimpleRootSite.kTagUserPrompt
&& !m_rootb.IsCompositionInProgress)
{
// If the selection is entirely in a user prompt then extend the selection to cover the
// entire prompt. This covers changes within the prompt, like clicking within it or continuing
// a drag while making it.
sel.ExtendToStringBoundaries();
EditingHelper.SetKeyboardForSelection(sel);
}
}
finally
{
m_fInSelectionChanged = false;
}
}