tdf#130857 starmath matrix creator a11y: Use col index newly passed to callback
Since previous commit
Change-Id: I36fa296d72ef2ff853da03037151cc060634d2a5
Author: Michael Weghorn <m.weghorn@posteo.de>
Date: Fri Apr 24 14:59:16 2026 +0200
weld: Pass col index in TreeView::signal_editing_done
, the column index of the edited column is now
passed in the callback. Use that one directly
and drop custom logic to try to identify/keep track
of which column/cell was clicked and must therefore be
the cell being edited, using mouse click events.
Besides being fairly complicated, relying on mouse click
positions also doesn't work when keyboard-only interaction
is used, e.g. pressing F2 in a QTreeView to enter edit mode
for the currently focused cell.
The dialog can be triggered like this:
* start Math
* right-click into the formula editor to open context menu
* select the "Format" -> "matrix {...}" menu entry
Change-Id: Ib8c99b31566070e5c8acb699d4481da50597ba44
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/204307
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
This commit is contained in:
@@ -521,10 +521,7 @@ class MatrixCreatorDialog final : public weld::GenericDialogController
|
||||
OUString mOldName;
|
||||
DECL_LINK(SpinButtonModifyHdl, weld::SpinButton&, void);
|
||||
DECL_LINK(RadioButtonModifyHdl, weld::Toggleable&, void);
|
||||
DECL_LINK(MousePressHdl, const MouseEvent&, bool);
|
||||
int mClickedColumn;
|
||||
int mEditedColumn;
|
||||
DECL_LINK(EditingEntryHdl, const weld::TreeIter&, bool);
|
||||
DECL_STATIC_LINK(MatrixCreatorDialog, EditingEntryHdl, const weld::TreeIter&, bool);
|
||||
DECL_LINK(EditedEntryHdl, const weld::TreeView::IterColText&, bool);
|
||||
|
||||
public:
|
||||
|
||||
@@ -2200,8 +2200,6 @@ MatrixCreatorDialog::MatrixCreatorDialog(weld::Window* pParent)
|
||||
, mxFullMatrix(m_xBuilder->weld_radio_button("fullmatrix"))
|
||||
, mxMatrix(m_xBuilder->weld_tree_view("matrix"))
|
||||
, mOldName("x")
|
||||
, mClickedColumn(-1)
|
||||
, mEditedColumn(-1)
|
||||
, mMatrixText("MATRIX{ x_11 # x_12 # x_13 ## x_21 # x_22 # x_23 ## x_31 # x_32 # x_33}")
|
||||
{
|
||||
mxOk->connect_clicked(LINK(this, MatrixCreatorDialog, ButtonOkHdl));
|
||||
@@ -2213,7 +2211,6 @@ MatrixCreatorDialog::MatrixCreatorDialog(weld::Window* pParent)
|
||||
mxDiagMatrix->connect_toggled(LINK(this, MatrixCreatorDialog, RadioButtonModifyHdl));
|
||||
mxSymmetricMatrix->connect_toggled(LINK(this, MatrixCreatorDialog, RadioButtonModifyHdl));
|
||||
mxFullMatrix->connect_toggled(LINK(this, MatrixCreatorDialog, RadioButtonModifyHdl));
|
||||
mxMatrix->connect_mouse_press(LINK(this, MatrixCreatorDialog, MousePressHdl));
|
||||
mxMatrix->connect_editing(LINK(this, MatrixCreatorDialog, EditingEntryHdl), LINK(this, MatrixCreatorDialog, EditedEntryHdl));
|
||||
|
||||
mxCols->set_value(3);
|
||||
@@ -2448,70 +2445,21 @@ IMPL_LINK_NOARG(MatrixCreatorDialog, RadioButtonModifyHdl, weld::Toggleable&, vo
|
||||
shapeMatrix();
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Note: The mouse event coordinates are relative to the treeview
|
||||
int getClickedCell(std::unique_ptr<weld::TreeView>& treeview, const MouseEvent& rMEvt, weld::TreeIter& rIter, const int lastColumn) {
|
||||
Point mousePos = rMEvt.GetPosPixel();
|
||||
int column = -1;
|
||||
bool found = false;
|
||||
|
||||
if (treeview->get_iter_first(rIter))
|
||||
{
|
||||
do
|
||||
{
|
||||
tools::Rectangle rowArea = treeview->get_row_area(rIter);
|
||||
if ((found = rowArea.Contains(mousePos)))
|
||||
break;
|
||||
} while (treeview->iter_next(rIter));
|
||||
}
|
||||
else
|
||||
return -1; // User clicked somewhere else
|
||||
if (!found)
|
||||
return -1;
|
||||
|
||||
for (int col = 0; col < lastColumn; ++col)
|
||||
{
|
||||
tools::Rectangle cellArea = treeview->get_cell_area(rIter, col);
|
||||
if (cellArea.Contains(mousePos))
|
||||
{
|
||||
column = col;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return column;
|
||||
}
|
||||
}
|
||||
|
||||
IMPL_LINK(MatrixCreatorDialog, MousePressHdl, const MouseEvent&, rMEvt, bool)
|
||||
IMPL_STATIC_LINK_NOARG(MatrixCreatorDialog, EditingEntryHdl, const weld::TreeIter&, bool)
|
||||
{
|
||||
if (mEditedColumn > 0)
|
||||
return false; // Ignore mouse clicks when a cell is being edited
|
||||
|
||||
auto xIter = mxMatrix->make_iterator();
|
||||
mClickedColumn = getClickedCell(mxMatrix, rMEvt, *xIter, mxCols->get_value());
|
||||
|
||||
return false; // We don't handle the mouse click, just find the column
|
||||
}
|
||||
|
||||
IMPL_LINK_NOARG(MatrixCreatorDialog, EditingEntryHdl, const weld::TreeIter&, bool)
|
||||
{
|
||||
mEditedColumn = mClickedColumn;
|
||||
return true;
|
||||
}
|
||||
|
||||
IMPL_LINK(MatrixCreatorDialog, EditedEntryHdl, const weld::TreeView::IterColText&, rIterColText,
|
||||
bool)
|
||||
{
|
||||
if (mEditedColumn < 0)
|
||||
return false; // Sometimes there is a double call and since we set mEditedColumn to -1 at the end we can avoid that
|
||||
|
||||
if (mxSymmetricMatrix->get_active() && mClickedColumn >= 0 && mClickedColumn < mxCols->get_value())
|
||||
if (mxSymmetricMatrix->get_active() && rIterColText.m_nColumn >= 0
|
||||
&& rIterColText.m_nColumn < mxCols->get_value())
|
||||
{
|
||||
// Sort of complicated, because set_text(row, column, value) seems to have no effect
|
||||
auto xIter = mxMatrix->make_iterator();
|
||||
bool bValidIter = mxMatrix->get_iter_first(*xIter);
|
||||
for (int row = 0; row < mClickedColumn && bValidIter; ++row)
|
||||
for (int row = 0; row < rIterColText.m_nColumn && bValidIter; ++row)
|
||||
bValidIter = mxMatrix->iter_next(*xIter);
|
||||
|
||||
if (bValidIter)
|
||||
@@ -2521,9 +2469,9 @@ IMPL_LINK(MatrixCreatorDialog, EditedEntryHdl, const weld::TreeView::IterColText
|
||||
}
|
||||
}
|
||||
|
||||
mxMatrix->set_text(rIterColText.m_rIter, rIterColText.m_sText, mEditedColumn); // Required for EditingCanceledHdl()
|
||||
// Required for EditingCanceledHdl()
|
||||
mxMatrix->set_text(rIterColText.m_rIter, rIterColText.m_sText, rIterColText.m_nColumn);
|
||||
|
||||
mEditedColumn = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user