/// <summary> /// If we are in ReadOnlySelect mode, intercept the click, and select the appropriate row /// without installing a normal selection. /// </summary> /// <param name="e"></param> protected override void OnMouseUp(MouseEventArgs e) { //If XmlBrouseView did not receive a mouse down event then we do not want to //do anything on the mouseUp because the mouseUp would have come from clicking //somewhere else. LT-8939 if (!m_fMouseUpEnabled) { return; } try { if (m_selectedIndex == -1) { return; // Can't do much in an empty list, so quit. } m_fHandlingMouseUp = true; #pragma warning disable 219 int oldSelectedIndex = m_selectedIndex; #pragma warning restore 219 // Note all the stuff we might want to know about what was clicked that we will // use later. We want to get this now before anything changes, because there can // be scrolling effects from converting dummy objects to real. IVwSelection vwsel = MakeSelectionAt(e); int newSelectedIndex = GetRowIndexFromSelection(vwsel, true); // If we're changing records, we need to do some tricks to keep the selection in the place // clicked and the focus here. Save the information we will need. SelectionHelper clickSel = null; if (newSelectedIndex != SelectedIndex && vwsel != null && SelectionHelper.IsEditable(vwsel)) { clickSel = SelectionHelper.Create(vwsel, this); } ITsString tssWord = null; // word clicked for click copy ITsString tssSource = null; // whole source string of clicked cell for click copy int hvoNewSelRow = 0; // hvo of new selected row (only for click copy) int ichStart = 0; // of tssWord in tssSource if (ClickCopy != null && e.Button == MouseButtons.Left && newSelectedIndex >= 0) { if (vwsel != null && vwsel.SelType == VwSelType.kstText) { int icol = vwsel.get_BoxIndex(false, 3); if (icol != Vc.OverrideAllowEditColumn + 1) { IVwSelection vwSelWord = vwsel.GrowToWord(); // GrowToWord() can return a null -- see LT-9163 and LT-9349. if (vwSelWord != null) { vwSelWord.GetSelectionString(out tssWord, " "); tssWord = StripTrailingNewLine(tssWord); hvoNewSelRow = m_sda.get_VecItem(m_hvoRoot, m_fakeFlid, newSelectedIndex); int hvoObj, tag, ws; bool fAssocPrev; vwSelWord.TextSelInfo(false, out tssSource, out ichStart, out fAssocPrev, out hvoObj, out tag, out ws); } } } } // We need to manually change the index for ReadOnly views. // SimpleRootSite delegates RightMouseClickEvent to our RecordBrowseView parent, // which also makes the selection for us.. if (ReadOnlySelect && e.Button != MouseButtons.Right) { if (this.m_xbvvc.HasSelectColumn && e.X < m_xbvvc.SelectColumnWidth) { base.OnMouseUp(e); // allows check box to operate. } } else { // If we leave this set, the base method call's side effects like updating the WS combo // don't happen. m_fHandlingMouseUp = false; base.OnMouseUp(e); // normal behavior. m_fHandlingMouseUp = true; } SetSelectedIndex(newSelectedIndex); if (tssWord != null) { // We're doing click copies; generate an event. // Do this AFTER other actions which may change the current line. ClickCopy(this, new ClickCopyEventArgs(tssWord, hvoNewSelRow, tssSource, ichStart)); } if (clickSel != null) { IVwSelection finalSel = null; // There seem to be some cases where the selection helper can't restore the selection. // One that came up in FWR-3666 was clicking on a check box. // If we can't re-establish an editiable selection just let the default behavior continue. try { finalSel = clickSel.MakeRangeSelection(RootBox, false); } catch (Exception) { } if (finalSel != null && SelectionHelper.IsEditable(finalSel)) { finalSel.Install(); FocusMe(); } } } finally { m_fHandlingMouseUp = false; m_fMouseUpEnabled = false; } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets the row/cell information of the current selection. /// </summary> /// <param name="vwsel"></param> /// <param name="iLevel"></param> /// <param name="iBox"></param> /// <param name="iTableBox"></param> /// <param name="cTableBoxes"></param> /// <param name="iTableLevel"></param> /// <param name="iCellBox"></param> /// <param name="cCellBoxes"></param> /// <param name="iCellLevel"></param> /// ------------------------------------------------------------------------------------ internal static void GetCurrentTableCellInfo(IVwSelection vwsel, out int iLevel, out int iBox, out int iTableBox, out int cTableBoxes, out int iTableLevel, out int iCellBox, out int cCellBoxes, out int iCellLevel) { int cBoxes = -1; iBox = -1; iTableBox = -1; cTableBoxes = -1; iTableLevel = -1; int iRowBox = -1; int cRowBoxes = -1; int iRowLevel = -1; iCellBox = -1; cCellBoxes = -1; iCellLevel = -1; // Find the current table cell and advance to the next one, possibly on the // next or previous row. int cLevels = vwsel.get_BoxDepth(true); VwBoxType vbt = VwBoxType.kvbtUnknown; for (iLevel = 0; iLevel < cLevels; ++iLevel) { cBoxes = vwsel.get_BoxCount(true, iLevel); iBox = vwsel.get_BoxIndex(true, iLevel); vbt = vwsel.get_BoxType(true, iLevel); switch (vbt) { case VwBoxType.kvbtTable: // Note that the layout should one (visible) row per "table", and // stacks the "table" boxes to form the visual table. See JohnT // for an explanation of this nonintuitive use of tables and rows. // At least, i think JohnT knows why -- maybe it's RandyR? iTableBox = iBox; cTableBoxes = cBoxes; iTableLevel = iLevel; break; case VwBoxType.kvbtTableRow: iRowBox = iBox; cRowBoxes = cBoxes; iRowLevel = iLevel; break; case VwBoxType.kvbtTableCell: iCellBox = iBox; cCellBoxes = cBoxes; iCellLevel = iLevel; break; } } // Some simple sanity checking. Debug.Assert(cBoxes != -1); Debug.Assert(iBox != -1); Debug.Assert(iTableBox != -1); Debug.Assert(cTableBoxes != -1); Debug.Assert(iTableLevel != -1); Debug.Assert(iRowBox != -1); Debug.Assert(cRowBoxes != -1); Debug.Assert(iRowLevel != -1); Debug.Assert(iCellBox != -1); Debug.Assert(cCellBoxes != -1); Debug.Assert(iCellLevel != -1); }