| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_vcl.hxx" |
| |
| #include "tools/rc.h" |
| #include "tools/debug.hxx" |
| |
| |
| #include "vcl/decoview.hxx" |
| #include "vcl/event.hxx" |
| #include "vcl/scrbar.hxx" |
| #include "vcl/button.hxx" |
| #include "vcl/edit.hxx" |
| #include "vcl/lstbox.hxx" |
| #include "vcl/combobox.hxx" |
| |
| #include "svdata.hxx" |
| #include "controldata.hxx" |
| #include "subedit.hxx" |
| #include "ilstbox.hxx" |
| #include "dndevdis.hxx" |
| |
| #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp> |
| |
| // ======================================================================= |
| |
| ListBox::ListBox( WindowType nType ) : Control( nType ) |
| { |
| ImplInitListBoxData(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| ListBox::ListBox( Window* pParent, WinBits nStyle ) : Control( WINDOW_LISTBOX ) |
| { |
| ImplInitListBoxData(); |
| ImplInit( pParent, nStyle ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| ListBox::ListBox( Window* pParent, const ResId& rResId ) : |
| Control( WINDOW_LISTBOX ) |
| { |
| ImplInitListBoxData(); |
| rResId.SetRT( RSC_LISTBOX ); |
| WinBits nStyle = ImplInitRes( rResId ); |
| ImplInit( pParent, nStyle ); |
| ImplLoadRes( rResId ); |
| |
| if ( !(nStyle & WB_HIDE ) ) |
| Show(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| ListBox::~ListBox() |
| { |
| //#109201# |
| ImplCallEventListeners( VCLEVENT_OBJECT_DYING ); |
| |
| delete mpImplLB; |
| |
| // Beim zerstoeren des FloatWins macht TH ein GrabFocus auf den Parent, |
| // also diese ListBox => PreNotify()... |
| mpImplLB = NULL; |
| |
| delete mpFloatWin; |
| delete mpImplWin; |
| delete mpBtn; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::ImplInitListBoxData() |
| { |
| mpFloatWin = NULL; |
| mpImplWin = NULL; |
| mpBtn = NULL; |
| mnDDHeight = 0; |
| mnSaveValue = LISTBOX_ENTRY_NOTFOUND; |
| mnLineCount = 0; |
| mbDDAutoSize = true; |
| mbEdgeBlending = false; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::ImplInit( Window* pParent, WinBits nStyle ) |
| { |
| nStyle = ImplInitStyle( nStyle ); |
| if ( !(nStyle & WB_NOBORDER) && ( nStyle & WB_DROPDOWN ) ) |
| nStyle |= WB_BORDER; |
| |
| Control::ImplInit( pParent, nStyle, NULL ); |
| SetBackground(); |
| |
| ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::dnd::XDropTargetListener> xDrop = new DNDEventDispatcher(this); |
| |
| if( nStyle & WB_DROPDOWN ) |
| { |
| sal_Int32 nLeft, nTop, nRight, nBottom; |
| GetBorder( nLeft, nTop, nRight, nBottom ); |
| mnDDHeight = (sal_uInt16)(GetTextHeight() + nTop + nBottom + 4); |
| |
| if( IsNativeWidgetEnabled() && |
| IsNativeControlSupported( CTRL_LISTBOX, PART_ENTIRE_CONTROL ) ) |
| { |
| ImplControlValue aControlValue; |
| Rectangle aCtrlRegion( Point( 0, 0 ), Size( 20, mnDDHeight ) ); |
| Rectangle aBoundingRgn( aCtrlRegion ); |
| Rectangle aContentRgn( aCtrlRegion ); |
| if( GetNativeControlRegion( CTRL_LISTBOX, PART_ENTIRE_CONTROL, aCtrlRegion, |
| CTRL_STATE_ENABLED, aControlValue, rtl::OUString(), |
| aBoundingRgn, aContentRgn ) ) |
| { |
| sal_Int32 nHeight = aBoundingRgn.GetHeight(); |
| if( nHeight > mnDDHeight ) |
| mnDDHeight = static_cast<sal_uInt16>(nHeight); |
| } |
| } |
| |
| mpFloatWin = new ImplListBoxFloatingWindow( this ); |
| mpFloatWin->SetAutoWidth( sal_True ); |
| mpFloatWin->SetPopupModeEndHdl( LINK( this, ListBox, ImplPopupModeEndHdl ) ); |
| mpFloatWin->GetDropTarget()->addDropTargetListener(xDrop); |
| |
| mpImplWin = new ImplWin( this, (nStyle & (WB_LEFT|WB_RIGHT|WB_CENTER))|WB_NOBORDER ); |
| mpImplWin->SetMBDownHdl( LINK( this, ListBox, ImplClickBtnHdl ) ); |
| mpImplWin->SetUserDrawHdl( LINK( this, ListBox, ImplUserDrawHdl ) ); |
| mpImplWin->Show(); |
| mpImplWin->GetDropTarget()->addDropTargetListener(xDrop); |
| mpImplWin->SetEdgeBlending(GetEdgeBlending()); |
| |
| mpBtn = new ImplBtn( this, WB_NOLIGHTBORDER | WB_RECTSTYLE ); |
| ImplInitDropDownButton( mpBtn ); |
| mpBtn->SetMBDownHdl( LINK( this, ListBox, ImplClickBtnHdl ) ); |
| mpBtn->Show(); |
| mpBtn->GetDropTarget()->addDropTargetListener(xDrop); |
| } |
| |
| Window* pLBParent = this; |
| if ( mpFloatWin ) |
| pLBParent = mpFloatWin; |
| mpImplLB = new ImplListBox( pLBParent, nStyle&(~WB_BORDER) ); |
| mpImplLB->SetSelectHdl( LINK( this, ListBox, ImplSelectHdl ) ); |
| mpImplLB->SetScrollHdl( LINK( this, ListBox, ImplScrollHdl ) ); |
| mpImplLB->SetCancelHdl( LINK( this, ListBox, ImplCancelHdl ) ); |
| mpImplLB->SetDoubleClickHdl( LINK( this, ListBox, ImplDoubleClickHdl ) ); |
| mpImplLB->SetUserDrawHdl( LINK( this, ListBox, ImplUserDrawHdl ) ); |
| mpImplLB->SetPosPixel( Point() ); |
| mpImplLB->SetEdgeBlending(GetEdgeBlending()); |
| mpImplLB->Show(); |
| |
| mpImplLB->GetDropTarget()->addDropTargetListener(xDrop); |
| mpImplLB->SetDropTraget(xDrop); |
| |
| if ( mpFloatWin ) |
| { |
| mpFloatWin->SetImplListBox( mpImplLB ); |
| mpImplLB->SetSelectionChangedHdl( LINK( this, ListBox, ImplSelectionChangedHdl ) ); |
| } |
| else |
| mpImplLB->GetMainWindow()->AllowGrabFocus( sal_True ); |
| |
| SetCompoundControl( sal_True ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| WinBits ListBox::ImplInitStyle( WinBits nStyle ) |
| { |
| if ( !(nStyle & WB_NOTABSTOP) ) |
| nStyle |= WB_TABSTOP; |
| if ( !(nStyle & WB_NOGROUP) ) |
| nStyle |= WB_GROUP; |
| return nStyle; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::ImplLoadRes( const ResId& rResId ) |
| { |
| Control::ImplLoadRes( rResId ); |
| |
| sal_uInt16 nSelPos = ReadShortRes(); |
| sal_uInt16 nNumber = sal::static_int_cast<sal_uInt16>(ReadLongRes()); |
| |
| for( sal_uInt16 i = 0; i < nNumber; i++ ) |
| { |
| sal_uInt16 nPos = InsertEntry( ReadStringRes(), LISTBOX_APPEND ); |
| |
| long nId = ReadLongRes(); |
| if( nId ) |
| SetEntryData( nPos, (void *)nId ); // ID als UserData |
| } |
| |
| if( nSelPos < nNumber ) |
| SelectEntryPos( nSelPos ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| IMPL_LINK( ListBox, ImplSelectHdl, void*, EMPTYARG ) |
| { |
| sal_Bool bPopup = IsInDropDown(); |
| if( IsDropDownBox() ) |
| { |
| if( !mpImplLB->IsTravelSelect() ) |
| { |
| mpFloatWin->EndPopupMode(); |
| mpImplWin->GrabFocus(); |
| } |
| |
| mpImplWin->SetItemPos( GetSelectEntryPos() ); |
| mpImplWin->SetString( GetSelectEntry() ); |
| if( mpImplLB->GetEntryList()->HasImages() ) |
| { |
| Image aImage = mpImplLB->GetEntryList()->GetEntryImage( GetSelectEntryPos() ); |
| mpImplWin->SetImage( aImage ); |
| } |
| mpImplWin->Invalidate(); |
| } |
| |
| if ( ( !IsTravelSelect() || mpImplLB->IsSelectionChanged() ) || ( bPopup && !IsMultiSelectionEnabled() ) ) |
| Select(); |
| |
| return 1; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| IMPL_LINK( ListBox, ImplScrollHdl, void*, EMPTYARG ) |
| { |
| ImplCallEventListeners( VCLEVENT_LISTBOX_SCROLLED ); |
| return 1; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| IMPL_LINK( ListBox, ImplCancelHdl, void*, EMPTYARG ) |
| { |
| if( IsInDropDown() ) |
| mpFloatWin->EndPopupMode(); |
| |
| return 1; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| IMPL_LINK( ListBox, ImplSelectionChangedHdl, void*, n ) |
| { |
| if ( !mpImplLB->IsTrackingSelect() ) |
| { |
| sal_uInt16 nChanged = (sal_uInt16)(sal_uLong)n; |
| const ImplEntryList* pEntryList = mpImplLB->GetEntryList(); |
| if ( pEntryList->IsEntryPosSelected( nChanged ) ) |
| { |
| // Sollte mal ein ImplPaintEntry werden... |
| if ( nChanged < pEntryList->GetMRUCount() ) |
| nChanged = pEntryList->FindEntry( pEntryList->GetEntryText( nChanged ) ); |
| mpImplWin->SetItemPos( nChanged ); |
| mpImplWin->SetString( mpImplLB->GetEntryList()->GetEntryText( nChanged ) ); |
| if( mpImplLB->GetEntryList()->HasImages() ) |
| { |
| Image aImage = mpImplLB->GetEntryList()->GetEntryImage( nChanged ); |
| mpImplWin->SetImage( aImage ); |
| } |
| } |
| else |
| { |
| mpImplWin->SetItemPos( LISTBOX_ENTRY_NOTFOUND ); |
| mpImplWin->SetString( ImplGetSVEmptyStr() ); |
| Image aImage; |
| mpImplWin->SetImage( aImage ); |
| } |
| mpImplWin->Invalidate(); |
| } |
| return 1; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| IMPL_LINK( ListBox, ImplDoubleClickHdl, void*, EMPTYARG ) |
| { |
| DoubleClick(); |
| return 1; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| IMPL_LINK( ListBox, ImplClickBtnHdl, void*, EMPTYARG ) |
| { |
| if( !mpFloatWin->IsInPopupMode() ) |
| { |
| ImplCallEventListeners( VCLEVENT_DROPDOWN_PRE_OPEN ); |
| mpImplWin->GrabFocus(); |
| mpBtn->SetPressed( sal_True ); |
| mpFloatWin->StartFloat( sal_True ); |
| ImplCallEventListeners( VCLEVENT_DROPDOWN_OPEN ); |
| |
| ImplClearLayoutData(); |
| if( mpImplLB ) |
| mpImplLB->GetMainWindow()->ImplClearLayoutData(); |
| if( mpImplWin ) |
| mpImplWin->ImplClearLayoutData(); |
| } |
| |
| return 0; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| IMPL_LINK( ListBox, ImplPopupModeEndHdl, void*, EMPTYARG ) |
| { |
| if( mpFloatWin->IsPopupModeCanceled() ) |
| { |
| if ( ( mpFloatWin->GetPopupModeStartSaveSelection() != LISTBOX_ENTRY_NOTFOUND ) |
| && !IsEntryPosSelected( mpFloatWin->GetPopupModeStartSaveSelection() ) ) |
| { |
| mpImplLB->SelectEntry( mpFloatWin->GetPopupModeStartSaveSelection(), sal_True ); |
| sal_Bool bTravelSelect = mpImplLB->IsTravelSelect(); |
| mpImplLB->SetTravelSelect( sal_True ); |
| |
| ImplDelData aCheckDelete; |
| ImplAddDel( &aCheckDelete ); |
| Select(); |
| if ( aCheckDelete.IsDelete() ) |
| return 0; |
| ImplRemoveDel( &aCheckDelete ); |
| |
| mpImplLB->SetTravelSelect( bTravelSelect ); |
| } |
| } |
| |
| ImplClearLayoutData(); |
| if( mpImplLB ) |
| mpImplLB->GetMainWindow()->ImplClearLayoutData(); |
| if( mpImplWin ) |
| mpImplWin->ImplClearLayoutData(); |
| |
| mpBtn->SetPressed( sal_False ); |
| ImplCallEventListeners( VCLEVENT_DROPDOWN_CLOSE ); |
| return 0; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::ToggleDropDown() |
| { |
| if( IsDropDownBox() ) |
| { |
| if( mpFloatWin->IsInPopupMode() ) |
| mpFloatWin->EndPopupMode(); |
| else |
| { |
| ImplCallEventListeners( VCLEVENT_DROPDOWN_PRE_OPEN ); |
| mpImplWin->GrabFocus(); |
| mpBtn->SetPressed( sal_True ); |
| mpFloatWin->StartFloat( sal_True ); |
| ImplCallEventListeners( VCLEVENT_DROPDOWN_OPEN ); |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags ) |
| { |
| mpImplLB->GetMainWindow()->ImplInitSettings( sal_True, sal_True, sal_True ); |
| |
| Point aPos = pDev->LogicToPixel( rPos ); |
| Size aSize = pDev->LogicToPixel( rSize ); |
| Font aFont = mpImplLB->GetMainWindow()->GetDrawPixelFont( pDev ); |
| OutDevType eOutDevType = pDev->GetOutDevType(); |
| |
| pDev->Push(); |
| pDev->SetMapMode(); |
| pDev->SetFont( aFont ); |
| pDev->SetTextFillColor(); |
| |
| // Border/Background |
| pDev->SetLineColor(); |
| pDev->SetFillColor(); |
| sal_Bool bBorder = !(nFlags & WINDOW_DRAW_NOBORDER ) && (GetStyle() & WB_BORDER); |
| sal_Bool bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && IsControlBackground(); |
| if ( bBorder || bBackground ) |
| { |
| Rectangle aRect( aPos, aSize ); |
| if ( bBorder ) |
| { |
| ImplDrawFrame( pDev, aRect ); |
| } |
| if ( bBackground ) |
| { |
| pDev->SetFillColor( GetControlBackground() ); |
| pDev->DrawRect( aRect ); |
| } |
| } |
| |
| // Inhalt |
| if ( ( nFlags & WINDOW_DRAW_MONO ) || ( eOutDevType == OUTDEV_PRINTER ) ) |
| { |
| pDev->SetTextColor( Color( COL_BLACK ) ); |
| } |
| else |
| { |
| if ( !(nFlags & WINDOW_DRAW_NODISABLE ) && !IsEnabled() ) |
| { |
| const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); |
| pDev->SetTextColor( rStyleSettings.GetDisableColor() ); |
| } |
| else |
| { |
| pDev->SetTextColor( GetTextColor() ); |
| } |
| } |
| |
| long nOnePixel = GetDrawPixel( pDev, 1 ); |
| sal_uInt16 nTextStyle = TEXT_DRAW_VCENTER; |
| Rectangle aTextRect( aPos, aSize ); |
| |
| if ( GetStyle() & WB_CENTER ) |
| nTextStyle |= TEXT_DRAW_CENTER; |
| else if ( GetStyle() & WB_RIGHT ) |
| nTextStyle |= TEXT_DRAW_RIGHT; |
| else |
| nTextStyle |= TEXT_DRAW_LEFT; |
| |
| aTextRect.Left() += 3*nOnePixel; |
| aTextRect.Right() -= 3*nOnePixel; |
| |
| if ( IsDropDownBox() ) |
| { |
| XubString aText = GetSelectEntry(); |
| long nTextHeight = pDev->GetTextHeight(); |
| long nTextWidth = pDev->GetTextWidth( aText ); |
| long nOffX = 3*nOnePixel; |
| long nOffY = (aSize.Height()-nTextHeight) / 2; |
| |
| // Clipping? |
| if ( (nOffY < 0) || |
| ((nOffY+nTextHeight) > aSize.Height()) || |
| ((nOffX+nTextWidth) > aSize.Width()) ) |
| { |
| Rectangle aClip( aPos, aSize ); |
| if ( nTextHeight > aSize.Height() ) |
| aClip.Bottom() += nTextHeight-aSize.Height()+1; // Damit HP-Drucker nicht 'weg-optimieren' |
| pDev->IntersectClipRegion( aClip ); |
| } |
| |
| pDev->DrawText( aTextRect, aText, nTextStyle ); |
| } |
| else |
| { |
| long nTextHeight = pDev->GetTextHeight(); |
| sal_uInt16 nLines = (sal_uInt16)(aSize.Height() / nTextHeight); |
| Rectangle aClip( aPos, aSize ); |
| |
| pDev->IntersectClipRegion( aClip ); |
| |
| if ( !nLines ) |
| nLines = 1; |
| |
| for ( sal_uInt16 n = 0; n < nLines; n++ ) |
| { |
| sal_uInt16 nEntry = n+mpImplLB->GetTopEntry(); |
| sal_Bool bSelected = mpImplLB->GetEntryList()->IsEntryPosSelected( nEntry ); |
| if ( bSelected ) |
| { |
| pDev->SetFillColor( COL_BLACK ); |
| pDev->DrawRect( Rectangle( Point( aPos.X(), aPos.Y() + n*nTextHeight ), |
| Point( aPos.X() + aSize.Width(), aPos.Y() + (n+1)*nTextHeight + 2*nOnePixel ) ) ); |
| pDev->SetFillColor(); |
| pDev->SetTextColor( COL_WHITE ); |
| } |
| |
| aTextRect.Top() = aPos.Y() + n*nTextHeight; |
| aTextRect.Bottom() = aTextRect.Top() + nTextHeight; |
| |
| pDev->DrawText( aTextRect, mpImplLB->GetEntryList()->GetEntryText( nEntry ), nTextStyle ); |
| |
| if ( bSelected ) |
| pDev->SetTextColor( COL_BLACK ); |
| } |
| } |
| |
| pDev->Pop(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::GetFocus() |
| { |
| if ( mpImplLB ) |
| { |
| if( IsDropDownBox() ) |
| mpImplWin->GrabFocus(); |
| else |
| mpImplLB->GrabFocus(); |
| } |
| |
| Control::GetFocus(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| Window* ListBox::GetPreferredKeyInputWindow() |
| { |
| if ( mpImplLB ) |
| { |
| if( IsDropDownBox() ) |
| return mpImplWin->GetPreferredKeyInputWindow(); |
| else |
| return mpImplLB->GetPreferredKeyInputWindow(); |
| } |
| |
| return Control::GetPreferredKeyInputWindow(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::LoseFocus() |
| { |
| if( IsDropDownBox() ) |
| mpImplWin->HideFocus(); |
| else |
| mpImplLB->HideFocus(); |
| |
| Control::LoseFocus(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::DataChanged( const DataChangedEvent& rDCEvt ) |
| { |
| Control::DataChanged( rDCEvt ); |
| |
| if ( (rDCEvt.GetType() == DATACHANGED_FONTS) || |
| (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) || |
| ((rDCEvt.GetType() == DATACHANGED_SETTINGS) && |
| (rDCEvt.GetFlags() & SETTINGS_STYLE)) ) |
| { |
| SetBackground(); // due to a hack in Window::UpdateSettings the background must be reset |
| // otherwise it will overpaint NWF drawn listboxes |
| Resize(); |
| mpImplLB->Resize(); // Wird nicht durch ListBox::Resize() gerufen, wenn sich die ImplLB nicht aendert. |
| |
| if ( mpImplWin ) |
| { |
| mpImplWin->SetSettings( GetSettings() ); // Falls noch nicht eingestellt... |
| ImplInitFieldSettings( mpImplWin, sal_True, sal_True, sal_True ); |
| |
| mpBtn->SetSettings( GetSettings() ); |
| ImplInitDropDownButton( mpBtn ); |
| } |
| |
| |
| if ( IsDropDownBox() ) |
| Invalidate(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::EnableAutoSize( bool bAuto ) |
| { |
| mbDDAutoSize = bAuto; |
| if ( mpFloatWin ) |
| { |
| if ( bAuto && !mpFloatWin->GetDropDownLineCount() ) |
| { |
| // use GetListBoxMaximumLineCount here; before, was on fixed number of five |
| AdaptDropDownLineCountToMaximum(); |
| } |
| else if ( !bAuto ) |
| { |
| mpFloatWin->SetDropDownLineCount( 0 ); |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::EnableDDAutoWidth( sal_Bool b ) |
| { |
| if ( mpFloatWin ) |
| mpFloatWin->SetAutoWidth( b ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_Bool ListBox::IsDDAutoWidthEnabled() const |
| { |
| return mpFloatWin ? mpFloatWin->IsAutoWidth() : sal_False; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::SetDropDownLineCount( sal_uInt16 nLines ) |
| { |
| mnLineCount = nLines; |
| if ( mpFloatWin ) |
| mpFloatWin->SetDropDownLineCount( mnLineCount ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::AdaptDropDownLineCountToMaximum() |
| { |
| // adapt to maximum allowed number |
| SetDropDownLineCount(std::min(GetEntryCount(), GetSettings().GetStyleSettings().GetListBoxMaximumLineCount())); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ListBox::GetDropDownLineCount() const |
| { |
| if ( mpFloatWin ) |
| return mpFloatWin->GetDropDownLineCount(); |
| return mnLineCount; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::SetPosSizePixel( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags ) |
| { |
| if( IsDropDownBox() && ( nFlags & WINDOW_POSSIZE_SIZE ) ) |
| { |
| Size aPrefSz = mpFloatWin->GetPrefSize(); |
| if ( ( nFlags & WINDOW_POSSIZE_HEIGHT ) && ( nHeight >= 2*mnDDHeight ) ) |
| aPrefSz.Height() = nHeight-mnDDHeight; |
| if ( nFlags & WINDOW_POSSIZE_WIDTH ) |
| aPrefSz.Width() = nWidth; |
| mpFloatWin->SetPrefSize( aPrefSz ); |
| |
| if ( IsAutoSizeEnabled() && ! (nFlags & WINDOW_POSSIZE_DROPDOWN) ) |
| nHeight = mnDDHeight; |
| } |
| |
| Control::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::Resize() |
| { |
| Size aOutSz = GetOutputSizePixel(); |
| if( IsDropDownBox() ) |
| { |
| // initialize the dropdown button size with the standard scrollbar width |
| long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize(); |
| long nTop = 0; |
| long nBottom = aOutSz.Height(); |
| |
| // note: in case of no border, pBorder will actually be this |
| Window *pBorder = GetWindow( WINDOW_BORDER ); |
| ImplControlValue aControlValue; |
| Point aPoint; |
| Rectangle aContent, aBound; |
| |
| // use the full extent of the control |
| Rectangle aArea( aPoint, pBorder->GetOutputSizePixel() ); |
| |
| if ( GetNativeControlRegion( CTRL_LISTBOX, PART_BUTTON_DOWN, |
| aArea, 0, aControlValue, rtl::OUString(), aBound, aContent) ) |
| { |
| // convert back from border space to local coordinates |
| aPoint = pBorder->ScreenToOutputPixel( OutputToScreenPixel( aPoint ) ); |
| aContent.Move( -aPoint.X(), -aPoint.Y() ); |
| |
| // use the themes drop down size for the button |
| aOutSz.Width() = aContent.Left(); |
| mpBtn->SetPosSizePixel( aContent.Left(), nTop, aContent.Right(), (nBottom-nTop) ); |
| |
| // adjust the size of the edit field |
| if ( GetNativeControlRegion( CTRL_LISTBOX, PART_SUB_EDIT, |
| aArea, 0, aControlValue, rtl::OUString(), aBound, aContent) ) |
| { |
| // convert back from border space to local coordinates |
| aContent.Move( -aPoint.X(), -aPoint.Y() ); |
| |
| // use the themes drop down size |
| if( ! (GetStyle() & WB_BORDER) && ImplGetSVData()->maNWFData.mbNoFocusRects ) |
| { |
| // no border but focus ring behavior -> we have a problem; the |
| // native rect relies on the border to draw the focus |
| // let's do the best we can and center vertically, so it doesn't look |
| // completely wrong. |
| Size aSz( GetOutputSizePixel() ); |
| long nDiff = aContent.Top() - (aSz.Height() - aContent.GetHeight())/2; |
| aContent.Top() -= nDiff; |
| aContent.Bottom() -= nDiff; |
| } |
| mpImplWin->SetPosSizePixel( aContent.TopLeft(), aContent.GetSize() ); |
| } |
| else |
| mpImplWin->SetSizePixel( aOutSz ); |
| } |
| else |
| { |
| nSBWidth = CalcZoom( nSBWidth ); |
| mpImplWin->SetPosSizePixel( 0, 0, aOutSz.Width() - nSBWidth, aOutSz.Height() ); |
| mpBtn->SetPosSizePixel( aOutSz.Width() - nSBWidth, 0, nSBWidth, aOutSz.Height() ); |
| } |
| } |
| else |
| { |
| mpImplLB->SetSizePixel( aOutSz ); |
| } |
| |
| // FloatingWindow-Groesse auch im unsichtbare Zustand auf Stand halten, |
| // weil KEY_PGUP/DOWN ausgewertet wird... |
| if ( mpFloatWin ) |
| mpFloatWin->SetSizePixel( mpFloatWin->CalcFloatSize() ); |
| |
| Control::Resize(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::FillLayoutData() const |
| { |
| mpControlData->mpLayoutData = new vcl::ControlLayoutData(); |
| const Control* pMainWin = mpImplLB->GetMainWindow(); |
| if( mpFloatWin ) |
| { |
| // dropdown mode |
| AppendLayoutData( *mpImplWin ); |
| mpImplWin->SetLayoutDataParent( this ); |
| if( mpFloatWin->IsReallyVisible() ) |
| { |
| AppendLayoutData( *pMainWin ); |
| pMainWin->SetLayoutDataParent( this ); |
| } |
| } |
| else |
| { |
| AppendLayoutData( *pMainWin ); |
| pMainWin->SetLayoutDataParent( this ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| long ListBox::GetIndexForPoint( const Point& rPoint, sal_uInt16& rPos ) const |
| { |
| if( !HasLayoutData() ) |
| FillLayoutData(); |
| |
| // check whether rPoint fits at all |
| long nIndex = Control::GetIndexForPoint( rPoint ); |
| if( nIndex != -1 ) |
| { |
| // point must be either in main list window |
| // or in impl window (dropdown case) |
| ImplListBoxWindow* pMain = mpImplLB->GetMainWindow(); |
| |
| // convert coordinates to ImplListBoxWindow pixel coordinate space |
| Point aConvPoint = LogicToPixel( rPoint ); |
| aConvPoint = OutputToAbsoluteScreenPixel( aConvPoint ); |
| aConvPoint = pMain->AbsoluteScreenToOutputPixel( aConvPoint ); |
| aConvPoint = pMain->PixelToLogic( aConvPoint ); |
| |
| // try to find entry |
| sal_uInt16 nEntry = pMain->GetEntryPosForPoint( aConvPoint ); |
| if( nEntry == LISTBOX_ENTRY_NOTFOUND ) |
| { |
| // not found, maybe dropdown case |
| if( mpImplWin && mpImplWin->IsReallyVisible() ) |
| { |
| // convert to impl window pixel coordinates |
| aConvPoint = LogicToPixel( rPoint ); |
| aConvPoint = OutputToAbsoluteScreenPixel( aConvPoint ); |
| aConvPoint = mpImplWin->AbsoluteScreenToOutputPixel( aConvPoint ); |
| |
| // check whether converted point is inside impl window |
| Size aImplWinSize = mpImplWin->GetOutputSizePixel(); |
| if( aConvPoint.X() >= 0 && aConvPoint.Y() >= 0 && aConvPoint.X() < aImplWinSize.Width() && aConvPoint.Y() < aImplWinSize.Height() ) |
| { |
| // inside the impl window, the position is the current item pos |
| rPos = mpImplWin->GetItemPos(); |
| } |
| else |
| nIndex = -1; |
| } |
| else |
| nIndex = -1; |
| } |
| else |
| rPos = nEntry; |
| |
| DBG_ASSERT( nIndex != -1, "found index for point, but relative index failed" ); |
| } |
| |
| // get line relative index |
| if( nIndex != -1 ) |
| nIndex = ToRelativeLineIndex( nIndex ); |
| |
| return nIndex; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::StateChanged( StateChangedType nType ) |
| { |
| if( nType == STATE_CHANGE_READONLY ) |
| { |
| if( mpImplWin ) |
| mpImplWin->Enable( !IsReadOnly() ); |
| if( mpBtn ) |
| mpBtn->Enable( !IsReadOnly() ); |
| } |
| else if( nType == STATE_CHANGE_ENABLE ) |
| { |
| mpImplLB->Enable( IsEnabled() ); |
| if( mpImplWin ) |
| { |
| mpImplWin->Enable( IsEnabled() ); |
| if ( IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL) |
| && ! IsNativeControlSupported(CTRL_LISTBOX, PART_BUTTON_DOWN) ) |
| { |
| GetWindow( WINDOW_BORDER )->Invalidate( INVALIDATE_NOERASE ); |
| } |
| else |
| mpImplWin->Invalidate(); |
| } |
| if( mpBtn ) |
| mpBtn->Enable( IsEnabled() ); |
| } |
| else if( nType == STATE_CHANGE_UPDATEMODE ) |
| { |
| mpImplLB->SetUpdateMode( IsUpdateMode() ); |
| } |
| else if ( nType == STATE_CHANGE_ZOOM ) |
| { |
| mpImplLB->SetZoom( GetZoom() ); |
| if ( mpImplWin ) |
| { |
| mpImplWin->SetZoom( GetZoom() ); |
| mpImplWin->SetFont( mpImplLB->GetMainWindow()->GetFont() ); |
| mpImplWin->Invalidate(); |
| } |
| Resize(); |
| } |
| else if ( nType == STATE_CHANGE_CONTROLFONT ) |
| { |
| mpImplLB->SetControlFont( GetControlFont() ); |
| if ( mpImplWin ) |
| { |
| mpImplWin->SetControlFont( GetControlFont() ); |
| mpImplWin->SetFont( mpImplLB->GetMainWindow()->GetFont() ); |
| mpImplWin->Invalidate(); |
| } |
| Resize(); |
| } |
| else if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) |
| { |
| mpImplLB->SetControlForeground( GetControlForeground() ); |
| if ( mpImplWin ) |
| { |
| mpImplWin->SetControlForeground( GetControlForeground() ); |
| mpImplWin->SetTextColor( GetControlForeground() ); |
| mpImplWin->SetFont( mpImplLB->GetMainWindow()->GetFont() ); |
| mpImplWin->Invalidate(); |
| } |
| } |
| else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) |
| { |
| mpImplLB->SetControlBackground( GetControlBackground() ); |
| if ( mpImplWin ) |
| { |
| if ( mpImplWin->IsNativeControlSupported(CTRL_LISTBOX, PART_ENTIRE_CONTROL) ) |
| { |
| // Transparent background |
| mpImplWin->SetBackground(); |
| mpImplWin->SetControlBackground(); |
| } |
| else |
| { |
| mpImplWin->SetBackground( mpImplLB->GetMainWindow()->GetControlBackground() ); |
| mpImplWin->SetControlBackground( mpImplLB->GetMainWindow()->GetControlBackground() ); |
| } |
| mpImplWin->SetFont( mpImplLB->GetMainWindow()->GetFont() ); |
| mpImplWin->Invalidate(); |
| } |
| } |
| else if ( nType == STATE_CHANGE_STYLE ) |
| { |
| SetStyle( ImplInitStyle( GetStyle() ) ); |
| mpImplLB->GetMainWindow()->EnableSort( ( GetStyle() & WB_SORT ) ? sal_True : sal_False ); |
| sal_Bool bSimpleMode = ( GetStyle() & WB_SIMPLEMODE ) ? sal_True : sal_False; |
| mpImplLB->SetMultiSelectionSimpleMode( bSimpleMode ); |
| } |
| else if( nType == STATE_CHANGE_MIRRORING ) |
| { |
| if( mpBtn ) |
| { |
| mpBtn->EnableRTL( IsRTLEnabled() ); |
| ImplInitDropDownButton( mpBtn ); |
| } |
| mpImplLB->EnableRTL( IsRTLEnabled() ); |
| if( mpImplWin ) |
| mpImplWin->EnableRTL( IsRTLEnabled() ); |
| Resize(); |
| } |
| |
| Control::StateChanged( nType ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| long ListBox::PreNotify( NotifyEvent& rNEvt ) |
| { |
| long nDone = 0; |
| if ( mpImplLB ) |
| { |
| if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && ( rNEvt.GetWindow() == mpImplWin ) ) |
| { |
| KeyEvent aKeyEvt = *rNEvt.GetKeyEvent(); |
| switch( aKeyEvt.GetKeyCode().GetCode() ) |
| { |
| case KEY_DOWN: |
| { |
| if( mpFloatWin && !mpFloatWin->IsInPopupMode() && |
| aKeyEvt.GetKeyCode().IsMod2() ) |
| { |
| ImplCallEventListeners( VCLEVENT_DROPDOWN_PRE_OPEN ); |
| mpBtn->SetPressed( sal_True ); |
| mpFloatWin->StartFloat( sal_False ); |
| ImplCallEventListeners( VCLEVENT_DROPDOWN_OPEN ); |
| nDone = 1; |
| } |
| else |
| { |
| nDone = mpImplLB->ProcessKeyInput( aKeyEvt ); |
| } |
| } |
| break; |
| case KEY_UP: |
| { |
| if( mpFloatWin && mpFloatWin->IsInPopupMode() && |
| aKeyEvt.GetKeyCode().IsMod2() ) |
| { |
| mpFloatWin->EndPopupMode(); |
| nDone = 1; |
| } |
| else |
| { |
| nDone = mpImplLB->ProcessKeyInput( aKeyEvt ); |
| } |
| } |
| break; |
| case KEY_RETURN: |
| { |
| if( IsInDropDown() ) |
| { |
| mpImplLB->ProcessKeyInput( aKeyEvt ); |
| nDone = 1; |
| } |
| } |
| break; |
| |
| default: |
| { |
| nDone = mpImplLB->ProcessKeyInput( aKeyEvt ); |
| } |
| } |
| } |
| else if ( rNEvt.GetType() == EVENT_LOSEFOCUS ) |
| { |
| if ( IsInDropDown() && !HasChildPathFocus( sal_True ) ) |
| mpFloatWin->EndPopupMode(); |
| } |
| else if ( (rNEvt.GetType() == EVENT_COMMAND) && |
| (rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL) && |
| (rNEvt.GetWindow() == mpImplWin) ) |
| { |
| sal_uInt16 nWheelBehavior( GetSettings().GetMouseSettings().GetWheelBehavior() ); |
| if ( ( nWheelBehavior == MOUSE_WHEEL_ALWAYS ) |
| || ( ( nWheelBehavior == MOUSE_WHEEL_FOCUS_ONLY ) |
| && HasChildPathFocus() |
| ) |
| ) |
| { |
| nDone = mpImplLB->HandleWheelAsCursorTravel( *rNEvt.GetCommandEvent() ); |
| } |
| else |
| { |
| nDone = 0; // don't eat this event, let the default handling happen (i.e. scroll the context) |
| } |
| } |
| } |
| |
| return nDone ? nDone : Control::PreNotify( rNEvt ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::Select() |
| { |
| ImplCallEventListenersAndHandler( VCLEVENT_LISTBOX_SELECT, maSelectHdl, this ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::DoubleClick() |
| { |
| ImplCallEventListenersAndHandler( VCLEVENT_LISTBOX_DOUBLECLICK, maDoubleClickHdl, this ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::Clear() |
| { |
| mpImplLB->Clear(); |
| if( IsDropDownBox() ) |
| { |
| mpImplWin->SetItemPos( LISTBOX_ENTRY_NOTFOUND ); |
| mpImplWin->SetString( ImplGetSVEmptyStr() ); |
| Image aImage; |
| mpImplWin->SetImage( aImage ); |
| mpImplWin->Invalidate(); |
| } |
| CallEventListeners( VCLEVENT_LISTBOX_ITEMREMOVED, (void*) sal_IntPtr(-1) ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::SetNoSelection() |
| { |
| mpImplLB->SetNoSelection(); |
| if( IsDropDownBox() ) |
| { |
| mpImplWin->SetItemPos( LISTBOX_ENTRY_NOTFOUND ); |
| mpImplWin->SetString( ImplGetSVEmptyStr() ); |
| Image aImage; |
| mpImplWin->SetImage( aImage ); |
| mpImplWin->Invalidate(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ListBox::InsertEntry( const XubString& rStr, sal_uInt16 nPos ) |
| { |
| sal_uInt16 nRealPos = mpImplLB->InsertEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), rStr ); |
| nRealPos = sal::static_int_cast<sal_uInt16>(nRealPos - mpImplLB->GetEntryList()->GetMRUCount()); |
| CallEventListeners( VCLEVENT_LISTBOX_ITEMADDED, (void*) sal_IntPtr(nRealPos) ); |
| return nRealPos; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ListBox::InsertEntry( const Image& rImage, sal_uInt16 nPos ) |
| { |
| sal_uInt16 nRealPos = mpImplLB->InsertEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), rImage ); |
| nRealPos = sal::static_int_cast<sal_uInt16>(nRealPos - mpImplLB->GetEntryList()->GetMRUCount()); |
| CallEventListeners( VCLEVENT_LISTBOX_ITEMADDED, (void*) sal_IntPtr(nRealPos) ); |
| return nRealPos; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ListBox::InsertEntry( const XubString& rStr, const Image& rImage, sal_uInt16 nPos ) |
| { |
| sal_uInt16 nRealPos = mpImplLB->InsertEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), rStr, rImage ); |
| nRealPos = sal::static_int_cast<sal_uInt16>(nRealPos - mpImplLB->GetEntryList()->GetMRUCount()); |
| CallEventListeners( VCLEVENT_LISTBOX_ITEMADDED, (void*) sal_IntPtr(nRealPos) ); |
| return nRealPos; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::RemoveEntry( const XubString& rStr ) |
| { |
| RemoveEntry( GetEntryPos( rStr ) ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::RemoveEntry( sal_uInt16 nPos ) |
| { |
| mpImplLB->RemoveEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount() ); |
| CallEventListeners( VCLEVENT_LISTBOX_ITEMREMOVED, (void*) sal_IntPtr(nPos) ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| Image ListBox::GetEntryImage( sal_uInt16 nPos ) const |
| { |
| if ( mpImplLB->GetEntryList()->HasEntryImage( nPos ) ) |
| return mpImplLB->GetEntryList()->GetEntryImage( nPos ); |
| return Image(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ListBox::GetEntryPos( const XubString& rStr ) const |
| { |
| sal_uInt16 nPos = mpImplLB->GetEntryList()->FindEntry( rStr ); |
| if ( nPos != LISTBOX_ENTRY_NOTFOUND ) |
| nPos = sal::static_int_cast<sal_uInt16>(nPos - mpImplLB->GetEntryList()->GetMRUCount()); |
| return nPos; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ListBox::GetEntryPos( const void* pData ) const |
| { |
| sal_uInt16 nPos = mpImplLB->GetEntryList()->FindEntry( pData ); |
| if ( nPos != LISTBOX_ENTRY_NOTFOUND ) |
| nPos = sal::static_int_cast<sal_uInt16>(nPos - mpImplLB->GetEntryList()->GetMRUCount()); |
| return nPos; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| XubString ListBox::GetEntry( sal_uInt16 nPos ) const |
| { |
| return mpImplLB->GetEntryList()->GetEntryText( nPos + mpImplLB->GetEntryList()->GetMRUCount() ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ListBox::GetEntryCount() const |
| { |
| return mpImplLB->GetEntryList()->GetEntryCount() - mpImplLB->GetEntryList()->GetMRUCount(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| XubString ListBox::GetSelectEntry( sal_uInt16 nIndex ) const |
| { |
| return GetEntry( GetSelectEntryPos( nIndex ) ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ListBox::GetSelectEntryCount() const |
| { |
| return mpImplLB->GetEntryList()->GetSelectEntryCount(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ListBox::GetSelectEntryPos( sal_uInt16 nIndex ) const |
| { |
| sal_uInt16 nPos = mpImplLB->GetEntryList()->GetSelectEntryPos( nIndex ); |
| if ( nPos != LISTBOX_ENTRY_NOTFOUND ) |
| { |
| if ( nPos < mpImplLB->GetEntryList()->GetMRUCount() ) |
| nPos = mpImplLB->GetEntryList()->FindEntry( mpImplLB->GetEntryList()->GetEntryText( nPos ) ); |
| nPos = sal::static_int_cast<sal_uInt16>(nPos - mpImplLB->GetEntryList()->GetMRUCount()); |
| } |
| return nPos; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_Bool ListBox::IsEntrySelected( const XubString& rStr ) const |
| { |
| return IsEntryPosSelected( GetEntryPos( rStr ) ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_Bool ListBox::IsEntryPosSelected( sal_uInt16 nPos ) const |
| { |
| return mpImplLB->GetEntryList()->IsEntryPosSelected( nPos + mpImplLB->GetEntryList()->GetMRUCount() ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::SelectEntry( const XubString& rStr, sal_Bool bSelect ) |
| { |
| SelectEntryPos( GetEntryPos( rStr ), bSelect ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::SelectEntryPos( sal_uInt16 nPos, sal_Bool bSelect ) |
| { |
| if ( nPos < mpImplLB->GetEntryList()->GetEntryCount() ) |
| mpImplLB->SelectEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount(), bSelect ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::SetEntryData( sal_uInt16 nPos, void* pNewData ) |
| { |
| mpImplLB->SetEntryData( nPos + mpImplLB->GetEntryList()->GetMRUCount(), pNewData ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void* ListBox::GetEntryData( sal_uInt16 nPos ) const |
| { |
| return mpImplLB->GetEntryList()->GetEntryData( nPos + mpImplLB->GetEntryList()->GetMRUCount() ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::SetEntryFlags( sal_uInt16 nPos, long nFlags ) |
| { |
| mpImplLB->SetEntryFlags( nPos + mpImplLB->GetEntryList()->GetMRUCount(), nFlags ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| long ListBox::GetEntryFlags( sal_uInt16 nPos ) const |
| { |
| return mpImplLB->GetEntryList()->GetEntryFlags( nPos + mpImplLB->GetEntryList()->GetMRUCount() ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::SetTopEntry( sal_uInt16 nPos ) |
| { |
| mpImplLB->SetTopEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount() ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::ShowProminentEntry( sal_uInt16 nPos ) |
| { |
| mpImplLB->ShowProminentEntry( nPos + mpImplLB->GetEntryList()->GetMRUCount() ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ListBox::GetTopEntry() const |
| { |
| sal_uInt16 nPos = GetEntryCount() ? mpImplLB->GetTopEntry() : LISTBOX_ENTRY_NOTFOUND; |
| if ( nPos < mpImplLB->GetEntryList()->GetMRUCount() ) |
| nPos = 0; |
| return nPos; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::SetProminentEntryType( ProminentEntry eType ) |
| { |
| mpImplLB->SetProminentEntryType( eType ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| ProminentEntry ListBox::GetProminentEntryType() const |
| { |
| return mpImplLB->GetProminentEntryType(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_Bool ListBox::IsTravelSelect() const |
| { |
| return mpImplLB->IsTravelSelect(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_Bool ListBox::IsInDropDown() const |
| { |
| return mpFloatWin && mpFloatWin->IsInPopupMode(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| long ListBox::CalcWindowSizePixel( sal_uInt16 nLines ) const |
| { |
| return mpImplLB->GetEntryHeight() * nLines; |
| } |
| |
| Rectangle ListBox::GetBoundingRectangle( sal_uInt16 nItem ) const |
| { |
| Rectangle aRect = mpImplLB->GetMainWindow()->GetBoundingRectangle( nItem ); |
| Rectangle aOffset = mpImplLB->GetMainWindow()->GetWindowExtentsRelative( (Window*)this ); |
| aRect.Move( aOffset.TopLeft().X(), aOffset.TopLeft().Y() ); |
| return aRect; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::EnableMultiSelection( sal_Bool bMulti ) |
| { |
| EnableMultiSelection( bMulti, sal_False ); |
| } |
| |
| void ListBox::EnableMultiSelection( sal_Bool bMulti, sal_Bool bStackSelection ) |
| { |
| mpImplLB->EnableMultiSelection( bMulti, bStackSelection ); |
| |
| // WB_SIMPLEMODE: |
| // Die MultiListBox verh�lt sich wie eine normale ListBox. |
| // Die Mehrfachselektion kann nur �ber entsprechende Zusatztasten erfolgen. |
| |
| sal_Bool bSimpleMode = ( GetStyle() & WB_SIMPLEMODE ) ? sal_True : sal_False; |
| mpImplLB->SetMultiSelectionSimpleMode( bSimpleMode ); |
| |
| // ohne Focus ist das Traveln in einer MultiSelection nicht zu sehen: |
| if ( mpFloatWin ) |
| mpImplLB->GetMainWindow()->AllowGrabFocus( bMulti ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_Bool ListBox::IsMultiSelectionEnabled() const |
| { |
| return mpImplLB->IsMultiSelectionEnabled(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| Size ListBox::CalcMinimumSize() const |
| { |
| Size aSz; |
| if ( !IsDropDownBox() ) |
| aSz = mpImplLB->CalcSize (mnLineCount ? mnLineCount : mpImplLB->GetEntryList()->GetEntryCount()); |
| else |
| { |
| aSz.Height() = mpImplLB->CalcSize( 1 ).Height(); |
| aSz.Height() += 4; // add a space between entry and border |
| // size to maxmimum entry width and add a little breathing space |
| aSz.Width() = mpImplLB->GetMaxEntryWidth() + 4; |
| // do not create ultrathin ListBoxes, it doesn't look good |
| if( aSz.Width() < GetSettings().GetStyleSettings().GetScrollBarSize() ) |
| aSz.Width() = GetSettings().GetStyleSettings().GetScrollBarSize(); |
| |
| // try native borders; scrollbar size may not be a good indicator |
| // see how large the edit area inside is to estimate what is needed for the dropdown |
| ImplControlValue aControlValue; |
| Point aPoint; |
| Rectangle aContent, aBound; |
| Size aTestSize( 100, 20 ); |
| Rectangle aArea( aPoint, aTestSize ); |
| if( const_cast<ListBox*>(this)->GetNativeControlRegion( |
| CTRL_LISTBOX, PART_SUB_EDIT, aArea, 0, aControlValue, rtl::OUString(), aBound, aContent) ) |
| { |
| // use the themes drop down size |
| aSz.Width() += aTestSize.Width() - aContent.GetWidth(); |
| } |
| else |
| aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize(); |
| } |
| |
| aSz = CalcWindowSize( aSz ); |
| |
| if ( IsDropDownBox() ) // check minimum height of dropdown box |
| { |
| ImplControlValue aControlValue; |
| Rectangle aRect( Point( 0, 0 ), aSz ); |
| Rectangle aContent, aBound; |
| if( const_cast<ListBox*>(this)->GetNativeControlRegion( |
| CTRL_LISTBOX, PART_ENTIRE_CONTROL, aRect, 0, aControlValue, rtl::OUString(), aBound, aContent) ) |
| { |
| if( aBound.GetHeight() > aSz.Height() ) |
| aSz.Height() = aBound.GetHeight(); |
| } |
| } |
| |
| return aSz; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| Size ListBox::GetOptimalSize(WindowSizeType eType) const |
| { |
| switch (eType) { |
| case WINDOWSIZE_MINIMUM: |
| return CalcMinimumSize(); |
| default: |
| return Control::GetOptimalSize( eType ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| Size ListBox::CalcAdjustedSize( const Size& rPrefSize ) const |
| { |
| Size aSz = rPrefSize; |
| sal_Int32 nLeft, nTop, nRight, nBottom; |
| ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom ); |
| aSz.Height() -= nTop+nBottom; |
| if ( !IsDropDownBox() ) |
| { |
| long nEntryHeight = CalcSize( 1, 1 ).Height(); |
| long nLines = aSz.Height() / nEntryHeight; |
| if ( nLines < 1 ) |
| nLines = 1; |
| aSz.Height() = nLines * nEntryHeight; |
| } |
| else |
| { |
| aSz.Height() = mnDDHeight; |
| } |
| aSz.Height() += nTop+nBottom; |
| |
| aSz = CalcWindowSize( aSz ); |
| return aSz; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| Size ListBox::CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const |
| { |
| // ggf. werden ScrollBars eingeblendet |
| Size aMinSz = CalcMinimumSize(); |
| // aMinSz = ImplCalcOutSz( aMinSz ); |
| |
| Size aSz; |
| |
| // Hoehe |
| if ( nLines ) |
| { |
| if ( !IsDropDownBox() ) |
| aSz.Height() = mpImplLB->CalcSize( nLines ).Height(); |
| else |
| aSz.Height() = mnDDHeight; |
| } |
| else |
| aSz.Height() = aMinSz.Height(); |
| |
| // Breite |
| if ( nColumns ) |
| aSz.Width() = nColumns * GetTextWidth( XubString( 'X' ) ); |
| else |
| aSz.Width() = aMinSz.Width(); |
| |
| if ( IsDropDownBox() ) |
| aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize(); |
| |
| if ( !IsDropDownBox() ) |
| { |
| if ( aSz.Width() < aMinSz.Width() ) |
| aSz.Height() += GetSettings().GetStyleSettings().GetScrollBarSize(); |
| if ( aSz.Height() < aMinSz.Height() ) |
| aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize(); |
| } |
| |
| aSz = CalcWindowSize( aSz ); |
| return aSz; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const |
| { |
| long nCharWidth = GetTextWidth( UniString( 'x' ) ); |
| if ( !IsDropDownBox() ) |
| { |
| Size aOutSz = mpImplLB->GetMainWindow()->GetOutputSizePixel(); |
| rnCols = (sal_uInt16) (aOutSz.Width()/nCharWidth); |
| rnLines = (sal_uInt16) (aOutSz.Height()/mpImplLB->GetEntryHeight()); |
| } |
| else |
| { |
| Size aOutSz = mpImplWin->GetOutputSizePixel(); |
| rnCols = (sal_uInt16) (aOutSz.Width()/nCharWidth); |
| rnLines = 1; |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| IMPL_LINK( ListBox, ImplUserDrawHdl, UserDrawEvent*, pEvent ) |
| { |
| UserDraw( *pEvent ); |
| return 1; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::UserDraw( const UserDrawEvent& ) |
| { |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::DrawEntry( const UserDrawEvent& rEvt, sal_Bool bDrawImage, sal_Bool bDrawText, sal_Bool bDrawTextAtImagePos ) |
| { |
| if ( rEvt.GetDevice() == mpImplLB->GetMainWindow() ) |
| mpImplLB->GetMainWindow()->DrawEntry( rEvt.GetItemId(), bDrawImage, bDrawText, bDrawTextAtImagePos ); |
| else if ( rEvt.GetDevice() == mpImplWin ) |
| mpImplWin->DrawEntry( bDrawImage, bDrawText, bDrawTextAtImagePos ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::SetUserItemSize( const Size& rSz ) |
| { |
| mpImplLB->GetMainWindow()->SetUserItemSize( rSz ); |
| if ( mpImplWin ) |
| mpImplWin->SetUserItemSize( rSz ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| const Size& ListBox::GetUserItemSize() const |
| { |
| return mpImplLB->GetMainWindow()->GetUserItemSize(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::EnableUserDraw( sal_Bool bUserDraw ) |
| { |
| mpImplLB->GetMainWindow()->EnableUserDraw( bUserDraw ); |
| if ( mpImplWin ) |
| mpImplWin->EnableUserDraw( bUserDraw ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_Bool ListBox::IsUserDrawEnabled() const |
| { |
| return mpImplLB->GetMainWindow()->IsUserDrawEnabled(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::SetReadOnly( sal_Bool bReadOnly ) |
| { |
| if ( mpImplLB->IsReadOnly() != bReadOnly ) |
| { |
| mpImplLB->SetReadOnly( bReadOnly ); |
| StateChanged( STATE_CHANGE_READONLY ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_Bool ListBox::IsReadOnly() const |
| { |
| return mpImplLB->IsReadOnly(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::SetSeparatorPos( sal_uInt16 n ) |
| { |
| mpImplLB->SetSeparatorPos( n ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::SetSeparatorPos() |
| { |
| mpImplLB->SetSeparatorPos( LISTBOX_ENTRY_NOTFOUND ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ListBox::GetSeparatorPos() const |
| { |
| return mpImplLB->GetSeparatorPos(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::SetMRUEntries( const XubString& rEntries, xub_Unicode cSep ) |
| { |
| mpImplLB->SetMRUEntries( rEntries, cSep ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| XubString ListBox::GetMRUEntries( xub_Unicode cSep ) const |
| { |
| return mpImplLB->GetMRUEntries( cSep ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::SetMaxMRUCount( sal_uInt16 n ) |
| { |
| mpImplLB->SetMaxMRUCount( n ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ListBox::GetMaxMRUCount() const |
| { |
| return mpImplLB->GetMaxMRUCount(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ListBox::GetDisplayLineCount() const |
| { |
| return mpImplLB->GetDisplayLineCount(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| // pb: #106948# explicit mirroring for calc |
| |
| void ListBox::EnableMirroring() |
| { |
| mpImplLB->EnableMirroring(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| Rectangle ListBox::GetDropDownPosSizePixel() const |
| { |
| return mpFloatWin ? mpFloatWin->GetWindowExtentsRelative( const_cast<ListBox*>(this) ) : Rectangle(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| const Wallpaper& ListBox::GetDisplayBackground() const |
| { |
| // !!! recursion does not occur because the ImplListBox is default |
| // initialized to a nontransparent color in Window::ImplInitData |
| return mpImplLB->GetDisplayBackground(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ListBox::SetEdgeBlending(bool bNew) |
| { |
| if(mbEdgeBlending != bNew) |
| { |
| mbEdgeBlending = bNew; |
| |
| if(IsDropDownBox()) |
| { |
| mpImplWin->Invalidate(); |
| } |
| else |
| { |
| mpImplLB->Invalidate(); |
| } |
| |
| if(mpImplWin) |
| { |
| mpImplWin->SetEdgeBlending(GetEdgeBlending()); |
| } |
| |
| if(mpImplLB) |
| { |
| mpImplLB->SetEdgeBlending(GetEdgeBlending()); |
| } |
| |
| Invalidate(); |
| } |
| } |
| |
| // ======================================================================= |
| MultiListBox::MultiListBox( Window* pParent, WinBits nStyle ) : |
| ListBox( WINDOW_MULTILISTBOX ) |
| { |
| ImplInit( pParent, nStyle ); |
| EnableMultiSelection( sal_True ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| MultiListBox::MultiListBox( Window* pParent, const ResId& rResId ) : |
| ListBox( WINDOW_MULTILISTBOX ) |
| { |
| rResId.SetRT( RSC_MULTILISTBOX ); |
| WinBits nStyle = ImplInitRes( rResId ); |
| ImplInit( pParent, nStyle ); |
| ImplLoadRes( rResId ); |
| |
| if ( !(nStyle & WB_HIDE ) ) |
| Show(); |
| EnableMultiSelection( sal_True ); |
| } |
| |