svtools' BrowseBox class (include/svtools/brwbox.hxx; effectively a collection of BrowseColumn via the BrowseBox::pCols member) apparently distinguishes between a column's index/position/number (i.e., the BrowseColumn's position within the BrowseBox::pCols vector) and its ID (i.e., the BrowseColumn::_nId member, svtools/source/brwbox/datwin.hxx).

Columns are inserted into a BrowseBox with (both in svtools/source/brwbox/brwbox1.cxx:) BrowseBox::InsertHandleColumn (inserting a "handle" column at position 0 with ID 0) and BrowseBox::InsertDataColumn (inserting a "data" column with a given nItemId somewhere in the collection).

Historically both column numbers and column IDs have been represented with unsigned 16-bit integers (both sal_uInt16, by now), which doesn't necessarily help in avoiding confusion between the two concepts. (And indeed e.g. BROWSER_INVALIDID = SAL_MAX_UNIT16 appears to be used to represent both "no column ID", BrowseBox::GetColumnId, svtools/source/brwbox/brwbox2.cxx, and "no column number", BrowseBox::GetColumnAtXPosPixel, svtools/source/brwbox/brwbox1.cxx).

Now, BrowseBox::GetColumnAtXPosPixel (svtools/source/brwbox/brwbox1.cxx) apparently always returned a column number (from <https://cgit.freedesktop.org/libreoffice/core/commit/?id=8ab086b6cc054501bfbf7ef6fa509c393691e860> "initial import"),

USHORT BrowseBox::GetColumnAtXPosPixel( long nX, BOOL ) const
{
    DBG_CHKTHIS(BrowseBox,BrowseBoxCheckInvariants);

    // accumulate the withds of the visible columns
    long nColX = 0;
    USHORT nCol;
    for ( nCol = 0; nCol < USHORT(pCols->Count()); ++nCol )
    {
        BrowserColumn *pCol = pCols->GetObject(nCol);
        if ( pCol->IsFrozen() || nCol >= nFirstCol )
            nColX += pCol->Width();

        if ( nColX > nX )
            return nCol;
    }

    return BROWSER_INVALIDID;
}

while DbGridControl::GetModelColumnPos (svx/source/fmcomp/gridctrl.cxx) apparently always expected a column ID as input (from <http://cgit.freedesktop.org/libreoffice/core/commit/?id=fd069bee7e57ad529c3c0974559fd2d84ec3151a> "initial import"),

sal_uInt16 DbGridControl::GetModelColumnPos( sal_uInt16 nId ) const
{
    for (sal_uInt16 i=0; i<m_aColumns.Count(); ++i)
        if (m_aColumns.GetObject(i)->GetId() == nId)
            return i;

    return -1;
}

But there is two occurrences of code in svx/source/fmcomp/gridctrl.cxx that feeds the output of GetColumnAtXPosPixel as input into GetModelColumnPos, i.e., misinterprets a column number as a column ID. Meanwhile that code lives in DbGridControl::StartDrag,

[...]
    sal_uInt16 nColId = GetColumnAtXPosPixel(rPosPixel.X());
    long   nRow = GetRowAtYPosPixel(rPosPixel.Y());
    if (nColId != HandleColumnId && nRow >= 0)
    {
        if (GetDataWindow().IsMouseCaptured())
            GetDataWindow().ReleaseMouse();

        size_t Location = GetModelColumnPos( nColId );
[...]

and DbGridControl::Command,

[...]
            sal_uInt16 nColId = 
GetColumnAtXPosPixel(rEvt.GetMousePosPixel().X());
            long   nRow = GetRowAtYPosPixel(rEvt.GetMousePosPixel().Y());

            if (nColId == HandleColumnId)
            {
                executeRowContextMenu( nRow, rEvt.GetMousePosPixel() );
            }
            else if (canCopyCellText(nRow, nColId))
            {
                ScopedVclPtrInstance<PopupMenu> 
aContextMenu(SVX_RES(RID_SVXMNU_CELL));
                aContextMenu->RemoveDisabledEntries(true, true);
                switch (aContextMenu->Execute(this, rEvt.GetMousePosPixel()))
                {
                    case SID_COPY:
                        copyCellText(nRow, nColId);
[...]

where DbGridControl::copyCellText (svx/source/fmcomp/gridctrl.cxx) calls GetModelColumnPos,

void DbGridControl::copyCellText(sal_Int32 _nRow, sal_uInt16 _nColId)
{
    DBG_ASSERT(canCopyCellText(_nRow, _nColId), "DbGridControl::copyCellText: 
invalid call!");
    DbGridColumn* pColumn = m_aColumns[ GetModelColumnPos(_nColId) ];
    SeekRow(_nRow);
    OStringTransfer::CopyString( GetCurrentRowCellText( pColumn,m_xPaintRow ), 
this );
}

Does anybody (Linoel?) known something about that DbGridControl code? Would this be a bug (if so, any idea how to reproduce it at the GUI?) or is it maybe an invariant of such a DbGridControl that it's columns' ID always match the columns' positions?
_______________________________________________
LibreOffice mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/libreoffice

Reply via email to