Date: prev next · Thread: first prev next last
2017 Archives by date, by thread · List index


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?

Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.