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:
Michael Weghorn
2026-04-26 18:10:39 +02:00
parent b7516f2002
commit 89b69964db
2 changed files with 7 additions and 62 deletions
+1 -4
View File
@@ -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:
+6 -58
View File
@@ -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;
}