diff options
Diffstat (limited to 'vcl/source/window/menufloatingwindow.cxx')
-rw-r--r-- | vcl/source/window/menufloatingwindow.cxx | 74 |
1 files changed, 45 insertions, 29 deletions
diff --git a/vcl/source/window/menufloatingwindow.cxx b/vcl/source/window/menufloatingwindow.cxx index b6d6c966ded2..cc425346d3e5 100644 --- a/vcl/source/window/menufloatingwindow.cxx +++ b/vcl/source/window/menufloatingwindow.cxx @@ -152,6 +152,12 @@ long MenuFloatingWindow::ImplGetStartY() const long nY = 0; if( pMenu ) { + // avoid crash if somehow menu got disposed, and MenuItemList is empty (workaround for tdf#104686) + if ( nFirstEntry > 0 && !pMenu->GetItemList()->GetDataFromPos(nFirstEntry - 1) ) + { + return 0; + } + for ( sal_uInt16 n = 0; n < nFirstEntry; n++ ) nY += pMenu->GetItemList()->GetDataFromPos( n )->aSz.Height(); nY -= pMenu->GetTitleHeight(); @@ -592,45 +598,55 @@ void MenuFloatingWindow::ImplScroll( bool bUp ) nFirstEntry = pMenu->ImplGetPrevVisible( nFirstEntry ); DBG_ASSERT( nFirstEntry != ITEMPOS_INVALID, "Scroll?!" ); - long nScrollEntryHeight = pMenu->GetItemList()->GetDataFromPos( nFirstEntry )->aSz.Height(); - - if ( !bScrollDown ) + // avoid crash if somehow menu got disposed, and MenuItemList is empty (workaround for tdf#104686) + const auto pItemData = pMenu->GetItemList()->GetDataFromPos( nFirstEntry ); + if ( pItemData ) { - bScrollDown = true; - Invalidate(); - } + long nScrollEntryHeight = pItemData->aSz.Height(); - if ( pMenu->ImplGetPrevVisible( nFirstEntry ) == ITEMPOS_INVALID ) - { - bScrollUp = false; - Invalidate(); - } + if ( !bScrollDown ) + { + bScrollDown = true; + Invalidate(); + } + + if ( pMenu->ImplGetPrevVisible( nFirstEntry ) == ITEMPOS_INVALID ) + { + bScrollUp = false; + Invalidate(); + } - Scroll( 0, nScrollEntryHeight, ImplCalcClipRegion( false ).GetBoundRect(), ScrollFlags::Clip ); + Scroll( 0, nScrollEntryHeight, ImplCalcClipRegion( false ).GetBoundRect(), ScrollFlags::Clip ); + } } else if ( bScrollDown && !bUp ) { - long nScrollEntryHeight = pMenu->GetItemList()->GetDataFromPos( nFirstEntry )->aSz.Height(); + // avoid crash if somehow menu got disposed, and MenuItemList is empty (workaround for tdf#104686) + const auto pItemData = pMenu->GetItemList()->GetDataFromPos( nFirstEntry ); + if ( pItemData ) + { + long nScrollEntryHeight = pItemData->aSz.Height(); - nFirstEntry = pMenu->ImplGetNextVisible( nFirstEntry ); - DBG_ASSERT( nFirstEntry != ITEMPOS_INVALID, "Scroll?!" ); + nFirstEntry = pMenu->ImplGetNextVisible( nFirstEntry ); + DBG_ASSERT( nFirstEntry != ITEMPOS_INVALID, "Scroll?!" ); - if ( !bScrollUp ) - { - bScrollUp = true; - Invalidate(); - } + if ( !bScrollUp ) + { + bScrollUp = true; + Invalidate(); + } - long nHeight = GetOutputSizePixel().Height(); - sal_uInt16 nLastVisible; - static_cast<PopupMenu*>(pMenu)->ImplCalcVisEntries( nHeight, nFirstEntry, &nLastVisible ); - if ( pMenu->ImplGetNextVisible( nLastVisible ) == ITEMPOS_INVALID ) - { - bScrollDown = false; - Invalidate(); - } + long nHeight = GetOutputSizePixel().Height(); + sal_uInt16 nLastVisible; + static_cast<PopupMenu*>(pMenu)->ImplCalcVisEntries( nHeight, nFirstEntry, &nLastVisible ); + if ( pMenu->ImplGetNextVisible( nLastVisible ) == ITEMPOS_INVALID ) + { + bScrollDown = false; + Invalidate(); + } - Scroll( 0, -nScrollEntryHeight, ImplCalcClipRegion( false ).GetBoundRect(), ScrollFlags::Clip ); + Scroll( 0, -nScrollEntryHeight, ImplCalcClipRegion( false ).GetBoundRect(), ScrollFlags::Clip ); + } } Invalidate(); |