1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: editbrowsebox.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
33 #include <svtools/editbrowsebox.hxx>
35 #ifndef _SVTOOLS_EDITBROWSEBOX_HRC_
36 #include "editbrowsebox.hrc"
39 #ifndef _APP_HXX //autogen
40 #include <vcl/svapp.hxx>
42 #include <tools/debug.hxx>
43 #include <vcl/window.hxx>
45 #ifndef _EDIT_HXX //autogen
46 #include <vcl/edit.hxx>
48 #include <tools/resid.hxx>
49 #include <vcl/spinfld.hxx>
50 #include <svtools/svtdata.hxx>
53 #include <svtools/svtools.hrc>
57 #include <tools/multisel.hxx>
58 #include "editbrowseboximpl.hxx"
59 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
60 #include <com/sun/star/accessibility/XAccessible.hpp>
61 #include <comphelper/types.hxx>
63 // .......................................................................
66 // .......................................................................
69 //..............................................................
70 sal_Bool
isHiContrast(Window
* _pWindow
)
72 OSL_ENSURE(_pWindow
,"Window must be not null!");
73 Window
* pIter
= _pWindow
;
74 // while( pIter && pIter->GetBackground().GetColor().GetColor() == COL_TRANSPARENT )
77 const Color
& aColor
= pIter
->GetBackground().GetColor();
78 if ( aColor
.GetColor() == COL_TRANSPARENT
)
79 pIter
= pIter
->GetParent();
83 return pIter
&& pIter
->GetBackground().GetColor().IsDark();
86 //..............................................................
87 sal_uInt16
getRealGetFocusFlags( Window
* _pWindow
)
89 sal_uInt16 nFlags
= 0;
90 while ( _pWindow
&& !nFlags
)
92 nFlags
= _pWindow
->GetGetFocusFlags( );
93 _pWindow
= _pWindow
->GetParent();
99 using namespace ::com::sun::star::uno
;
100 using namespace com::sun::star::accessibility::AccessibleEventId
;
101 using com::sun::star::accessibility::XAccessible
;
102 //==================================================================
106 //==================================================================
107 //= EditBrowserHeader
108 //==================================================================
109 //------------------------------------------------------------------------------
110 void EditBrowserHeader::DoubleClick()
112 sal_uInt16 nColId
= GetCurItemId();
115 sal_uInt32 nAutoWidth
= ((EditBrowseBox
*)GetParent())->GetAutoColumnWidth(nColId
);
116 if (nAutoWidth
!= ((EditBrowseBox
*)GetParent())->GetColumnWidth(nColId
))
118 ((EditBrowseBox
*)GetParent())->SetColumnWidth(nColId
, nAutoWidth
);
119 ((EditBrowseBox
*)GetParent())->ColumnResized(nColId
);
125 //==================================================================
127 //==================================================================
128 //------------------------------------------------------------------------------
129 void EditBrowseBox::BrowserMouseEventPtr::Clear()
134 //------------------------------------------------------------------------------
135 void EditBrowseBox::BrowserMouseEventPtr::Set(const BrowserMouseEvent
* pEvt
, sal_Bool bIsDown
)
145 pEvent
= new BrowserMouseEvent(pEvt
->GetWindow(),
155 //------------------------------------------------------------------------------
156 DBG_NAME(EditBrowseBox
);
157 void EditBrowseBox::impl_construct()
159 m_aImpl
= ::std::auto_ptr
<EditBrowseBoxImpl
>(new EditBrowseBoxImpl());
160 m_aImpl
->m_bHiContrast
= isHiContrast(&GetDataWindow());
162 SetCompoundControl(sal_True
);
163 SetGridLineColor( Color( COL_LIGHTGRAY
) );
165 ImplInitSettings(sal_True
, sal_True
, sal_True
);
167 pCheckBoxPaint
= new CheckBoxControl(&GetDataWindow());
168 pCheckBoxPaint
->SetPaintTransparent( sal_True
);
169 pCheckBoxPaint
->SetBackground();
172 //------------------------------------------------------------------------------
173 EditBrowseBox::EditBrowseBox(Window
* pParent
, const ResId
& rId
, sal_Int32 nBrowserFlags
, BrowserMode _nMode
)
174 :BrowseBox( pParent
, rId
, _nMode
)
177 ,nCellModifiedEvent(0)
183 ,bHasFocus(sal_False
)
184 ,bPaintStatus(sal_True
)
185 ,bActiveBeforeTracking( sal_False
)
186 ,m_nBrowserFlags(nBrowserFlags
)
188 DBG_CTOR(EditBrowseBox
,NULL
);
193 //==================================================================
194 EditBrowseBox::EditBrowseBox( Window
* pParent
, sal_Int32 nBrowserFlags
, WinBits nBits
, BrowserMode _nMode
)
195 :BrowseBox( pParent
, nBits
, _nMode
)
198 ,nCellModifiedEvent(0)
204 ,bHasFocus(sal_False
)
205 ,bPaintStatus(sal_True
)
206 ,bActiveBeforeTracking( sal_False
)
207 ,m_nBrowserFlags(nBrowserFlags
)
210 DBG_CTOR(EditBrowseBox
,NULL
);
215 //------------------------------------------------------------------------------
216 void EditBrowseBox::Init()
218 // spaetes Construieren,
221 //------------------------------------------------------------------------------
222 EditBrowseBox::~EditBrowseBox()
225 Application::RemoveUserEvent(nStartEvent
);
227 Application::RemoveUserEvent(nEndEvent
);
228 if (nCellModifiedEvent
)
229 Application::RemoveUserEvent(nCellModifiedEvent
);
231 delete pCheckBoxPaint
;
233 DBG_DTOR(EditBrowseBox
,NULL
);
236 //------------------------------------------------------------------------------
237 void EditBrowseBox::RemoveRows()
240 nOldEditRow
= nEditRow
= nPaintRow
= -1;
241 nEditCol
= nOldEditCol
= 0;
244 //------------------------------------------------------------------------------
245 BrowserHeader
* EditBrowseBox::CreateHeaderBar(BrowseBox
* pParent
)
247 pHeader
= imp_CreateHeaderBar(pParent
);
249 pHeader
->SetUpdateMode(sal_False
);
253 //------------------------------------------------------------------------------
254 BrowserHeader
* EditBrowseBox::imp_CreateHeaderBar(BrowseBox
* pParent
)
256 return new EditBrowserHeader(pParent
);
259 //------------------------------------------------------------------------------
260 void EditBrowseBox::LoseFocus()
262 BrowseBox::LoseFocus();
266 //------------------------------------------------------------------------------
267 void EditBrowseBox::GetFocus()
269 BrowseBox::GetFocus();
271 // This should handle the case that the BrowseBox (or one of it's children)
272 // gets the focus from outside by pressing Tab
273 if (IsEditing() && Controller()->GetWindow().IsVisible())
274 Controller()->GetWindow().GrabFocus();
276 DetermineFocus( getRealGetFocusFlags( this ) );
279 //------------------------------------------------------------------------------
280 sal_Bool
EditBrowseBox::SeekRow(long nRow
)
286 //------------------------------------------------------------------------------
287 IMPL_LINK(EditBrowseBox
, StartEditHdl
, void*, EMPTYARG
)
293 if (!aController
->GetWindow().HasFocus() && (m_pFocusWhileRequest
== Application::GetFocusWindow()))
294 aController
->GetWindow().GrabFocus();
299 //------------------------------------------------------------------------------
300 void EditBrowseBox::PaintField( OutputDevice
& rDev
, const Rectangle
& rRect
,
301 sal_uInt16 nColumnId
) const
303 if (nColumnId
== HANDLE_ID
)
306 PaintStatusCell(rDev
, rRect
);
310 // don't paint the current cell
311 if (&rDev
== &GetDataWindow())
312 // but only if we're painting onto our data win (which is the usual painting)
313 if (nPaintRow
== nEditRow
)
315 if (IsEditing() && nEditCol
== nColumnId
&& aController
->GetWindow().IsVisible())
318 PaintCell(rDev
, rRect
, nColumnId
);
322 //------------------------------------------------------------------------------
323 Image
EditBrowseBox::GetImage(RowStatus eStatus
) const
325 sal_Bool bHiContrast
= isHiContrast(&GetDataWindow());
326 if ( !m_aStatusImages
.GetImageCount() || (bHiContrast
!= m_aImpl
->m_bHiContrast
) )
328 m_aImpl
->m_bHiContrast
= bHiContrast
;
329 const_cast<EditBrowseBox
*>(this)->m_aStatusImages
= ImageList(SvtResId(bHiContrast
? RID_SVTOOLS_IMAGELIST_EDITBWSEBOX_H
: RID_SVTOOLS_IMAGELIST_EDITBROWSEBOX
));
333 bool bNeedMirror
= IsRTLEnabled();
337 aImage
= m_aStatusImages
.GetImage(IMG_EBB_CURRENT
);
340 aImage
= m_aStatusImages
.GetImage(IMG_EBB_CURRENTNEW
);
343 aImage
= m_aStatusImages
.GetImage(IMG_EBB_MODIFIED
);
344 bNeedMirror
= false; // the pen is not mirrored
347 aImage
= m_aStatusImages
.GetImage(IMG_EBB_NEW
);
350 aImage
= m_aStatusImages
.GetImage(IMG_EBB_DELETED
);
353 aImage
= m_aStatusImages
.GetImage(IMG_EBB_PRIMARYKEY
);
355 case CURRENT_PRIMARYKEY
:
356 aImage
= m_aStatusImages
.GetImage(IMG_EBB_CURRENT_PRIMARYKEY
);
359 aImage
= m_aStatusImages
.GetImage(IMG_EBB_FILTER
);
362 aImage
= m_aStatusImages
.GetImage(IMG_EBB_HEADERFOOTER
);
369 BitmapEx
aBitmap( aImage
.GetBitmapEx() );
370 aBitmap
.Mirror( BMP_MIRROR_HORZ
);
371 aImage
= Image( aBitmap
);
376 //------------------------------------------------------------------------------
377 void EditBrowseBox::PaintStatusCell(OutputDevice
& rDev
, const Rectangle
& rRect
) const
382 RowStatus eStatus
= GetRowStatus( nPaintRow
);
383 sal_Int32 nBrowserFlags
= GetBrowserFlags();
385 if (nBrowserFlags
& EBBF_NO_HANDLE_COLUMN_CONTENT
)
388 // draw the text of the header column
389 if (nBrowserFlags
& EBBF_HANDLE_COLUMN_TEXT
)
391 rDev
.DrawText( rRect
, GetCellText( nPaintRow
, 0 ),
392 TEXT_DRAW_CENTER
| TEXT_DRAW_VCENTER
| TEXT_DRAW_CLIP
);
395 else if (eStatus
!= CLEAN
&& rDev
.GetOutDevType() == OUTDEV_WINDOW
)
397 Image
aImage(GetImage(eStatus
));
398 // calc the image position
399 Size
aImageSize(aImage
.GetSizePixel());
400 aImageSize
.Width() = CalcZoom(aImageSize
.Width());
401 aImageSize
.Height() = CalcZoom(aImageSize
.Height());
402 Point
aPos( rRect
.TopLeft() );
404 if ( ( aImageSize
.Width() > rRect
.GetWidth() ) || ( aImageSize
.Height() > rRect
.GetHeight() ) )
405 rDev
.SetClipRegion(rRect
);
407 if ( aImageSize
.Width() < rRect
.GetWidth() )
408 aPos
.X() += ( rRect
.GetWidth() - aImageSize
.Width() ) / 2;
410 if ( aImageSize
.Height() < rRect
.GetHeight() )
411 aPos
.Y() += ( rRect
.GetHeight() - aImageSize
.Height() ) / 2;
414 rDev
.DrawImage( aPos
, aImageSize
, aImage
, 0 );
416 rDev
.DrawImage( aPos
, aImage
, 0 );
418 if (rDev
.IsClipRegion())
419 rDev
.SetClipRegion();
423 //------------------------------------------------------------------------------
424 void EditBrowseBox::ImplStartTracking()
426 bActiveBeforeTracking
= IsEditing();
427 if ( bActiveBeforeTracking
)
433 BrowseBox::ImplStartTracking();
436 //------------------------------------------------------------------------------
437 void EditBrowseBox::ImplTracking()
439 BrowseBox::ImplTracking();
442 //------------------------------------------------------------------------------
443 void EditBrowseBox::ImplEndTracking()
445 if ( bActiveBeforeTracking
)
447 bActiveBeforeTracking
= sal_False
;
449 BrowseBox::ImplEndTracking();
452 //------------------------------------------------------------------------------
453 void EditBrowseBox::RowHeightChanged()
457 Rectangle
aRect( GetCellRect( nEditRow
, nEditCol
, sal_False
) );
458 CellControllerRef
aCellController( Controller() );
459 ResizeController( aCellController
, aRect
);
460 aCellController
->GetWindow().GrabFocus();
463 BrowseBox::RowHeightChanged();
466 //------------------------------------------------------------------------------
467 EditBrowseBox::RowStatus
EditBrowseBox::GetRowStatus(long) const
472 //------------------------------------------------------------------------------
473 void EditBrowseBox::KeyInput( const KeyEvent
& rEvt
)
475 sal_uInt16 nCode
= rEvt
.GetKeyCode().GetCode();
476 sal_Bool bShift
= rEvt
.GetKeyCode().IsShift();
477 sal_Bool bCtrl
= rEvt
.GetKeyCode().IsMod1();
482 if (!bCtrl
&& !bShift
&& IsTabAllowed(sal_True
))
484 Dispatch(BROWSER_CURSORRIGHT
);
487 BrowseBox::KeyInput(rEvt
);
490 if (!bCtrl
&& !bShift
)
492 if (IsTabAllowed(sal_True
))
493 Dispatch(BROWSER_CURSORRIGHT
);
495 // do NOT call BrowseBox::KeyInput : this would handle the tab, but we already now
496 // that tab isn't allowed here. So give the Control class a chance
497 Control::KeyInput(rEvt
);
500 else if (!bCtrl
&& bShift
)
502 if (IsTabAllowed(sal_False
))
503 Dispatch(BROWSER_CURSORLEFT
);
505 // do NOT call BrowseBox::KeyInput : this would handle the tab, but we already now
506 // that tab isn't allowed here. So give the Control class a chance
507 Control::KeyInput(rEvt
);
511 BrowseBox::KeyInput(rEvt
);
515 //------------------------------------------------------------------------------
516 void EditBrowseBox::MouseButtonDown(const BrowserMouseEvent
& rEvt
)
518 sal_uInt16 nColPos
= GetColumnPos( rEvt
.GetColumnId() );
519 long nRow
= rEvt
.GetRow();
521 // absorb double clicks
522 if (rEvt
.GetClicks() > 1 && rEvt
.GetRow() >= 0)
525 // change to a new position
526 if (IsEditing() && (nColPos
!= nEditCol
|| nRow
!= nEditRow
) && (nColPos
!= BROWSER_INVALIDID
) && (nRow
< GetRowCount()))
528 CellControllerRef
aCellController(Controller());
529 HideAndDisable(aCellController
);
532 // we are about to leave the current cell. If there is a "this cell has been modified" notification
533 // pending (asynchronously), this may be deadly -> do it synchronously
534 // 95826 - 2002-10-14 - fs@openoffice.org
535 if ( nCellModifiedEvent
)
537 Application::RemoveUserEvent( nCellModifiedEvent
);
538 nCellModifiedEvent
= 0;
539 LINK( this, EditBrowseBox
, CellModifiedHdl
).Call( NULL
);
542 if (0 == rEvt
.GetColumnId())
543 { // it was the handle column. save the current cell content if necessary
544 // (clicking on the handle column results in selecting the current row)
545 // 23.01.2001 - 82797 - FS
546 if (IsEditing() && aController
->IsModified())
550 aMouseEvent
.Set(&rEvt
,sal_True
);
551 BrowseBox::MouseButtonDown(rEvt
);
554 if (0 != (m_nBrowserFlags
& EBBF_ACTIVATE_ON_BUTTONDOWN
))
556 // the base class does not travel upon MouseButtonDown, but implActivateCellOnMouseEvent assumes we traveled ...
557 GoToRowColumnId( rEvt
.GetRow(), rEvt
.GetColumnId() );
558 if (rEvt
.GetRow() >= 0)
559 implActivateCellOnMouseEvent(rEvt
, sal_False
);
563 //------------------------------------------------------------------------------
564 void EditBrowseBox::MouseButtonUp( const BrowserMouseEvent
& rEvt
)
566 // absorb double clicks
567 if (rEvt
.GetClicks() > 1 && rEvt
.GetRow() >= 0)
570 aMouseEvent
.Set(&rEvt
,sal_False
);
571 BrowseBox::MouseButtonUp(rEvt
);
574 if (0 == (m_nBrowserFlags
& EBBF_ACTIVATE_ON_BUTTONDOWN
))
575 if (rEvt
.GetRow() >= 0)
576 implActivateCellOnMouseEvent(rEvt
, sal_True
);
579 //------------------------------------------------------------------------------
580 void EditBrowseBox::implActivateCellOnMouseEvent(const BrowserMouseEvent
& _rEvt
, sal_Bool _bUp
)
584 else if (IsEditing() && !aController
->GetWindow().IsEnabled())
586 else if (IsEditing() && !aController
->GetWindow().HasChildPathFocus())
589 if (IsEditing() && aController
->GetWindow().IsEnabled() && aController
->WantMouseEvent())
590 { // forwards the event to the control
592 // If the field has been moved previously, we have to adjust the position
594 aController
->GetWindow().GrabFocus();
596 // the position of the event relative to the controller's window
597 Point aPos
= _rEvt
.GetPosPixel() - _rEvt
.GetRect().TopLeft();
598 // the (child) window which should really get the event
599 Window
* pRealHandler
= aController
->GetWindow().FindWindow(aPos
);
601 // the coords relative to this real handler
602 aPos
-= pRealHandler
->GetPosPixel();
604 pRealHandler
= &aController
->GetWindow();
607 MouseEvent
aEvent(aPos
, _rEvt
.GetClicks(), _rEvt
.GetMode(),
609 _rEvt
.GetModifier());
611 pRealHandler
->MouseButtonDown(aEvent
);
613 pRealHandler
->MouseButtonUp(aEvent
);
615 Window
*pWin
= &aController
->GetWindow();
616 if (!pWin
->IsTracking())
618 for (pWin
= pWin
->GetWindow(WINDOW_FIRSTCHILD
);
619 pWin
&& !pWin
->IsTracking();
620 pWin
= pWin
->GetWindow(WINDOW_NEXT
))
624 if (pWin
&& pWin
->IsTracking())
629 //------------------------------------------------------------------------------
630 void EditBrowseBox::Dispatch( sal_uInt16 _nId
)
632 if ( _nId
== BROWSER_ENHANCESELECTION
)
633 { // this is a workaround for the bug in the base class:
634 // if the row selection is to be extended (which is what BROWSER_ENHANCESELECTION tells us)
635 // then the base class does not revert any column selections, while, for doing a "simple"
636 // selection (BROWSER_SELECT), it does. In fact, it does not only revert the col selection then,
637 // but also any current row selections.
638 // This clearly tells me that the both ids are for row selection only - there this behaviour does
640 // But here, where we have column selection, too, we take care of this ourself.
641 if ( GetSelectColumnCount( ) )
643 while ( GetSelectColumnCount( ) )
645 sal::static_int_cast
< USHORT
>(FirstSelectedColumn()),
650 BrowseBox::Dispatch( _nId
);
653 //------------------------------------------------------------------------------
654 long EditBrowseBox::PreNotify(NotifyEvent
& rEvt
)
656 switch (rEvt
.GetType())
659 if ( (IsEditing() && Controller()->GetWindow().HasChildPathFocus())
660 || rEvt
.GetWindow() == &GetDataWindow()
661 || (!IsEditing() && HasChildPathFocus())
664 const KeyEvent
* pKeyEvent
= rEvt
.GetKeyEvent();
665 sal_uInt16 nCode
= pKeyEvent
->GetKeyCode().GetCode();
666 sal_Bool bShift
= pKeyEvent
->GetKeyCode().IsShift();
667 sal_Bool bCtrl
= pKeyEvent
->GetKeyCode().IsMod1();
668 sal_Bool bAlt
= pKeyEvent
->GetKeyCode().IsMod2();
669 sal_Bool bLocalSelect
= sal_False
;
670 sal_Bool bNonEditOnly
= sal_False
;
671 sal_uInt16 nId
= BROWSER_NONE
;
673 if (!bAlt
&& !bCtrl
&& !bShift
)
676 case KEY_DOWN
: nId
= BROWSER_CURSORDOWN
; break;
677 case KEY_UP
: nId
= BROWSER_CURSORUP
; break;
678 case KEY_PAGEDOWN
: nId
= BROWSER_CURSORPAGEDOWN
; break;
679 case KEY_PAGEUP
: nId
= BROWSER_CURSORPAGEUP
; break;
680 case KEY_HOME
: nId
= BROWSER_CURSORHOME
; break;
681 case KEY_END
: nId
= BROWSER_CURSOREND
; break;
684 // ask if traveling to the next cell is allowed
685 if (IsTabAllowed(sal_True
))
686 nId
= BROWSER_CURSORRIGHT
;
690 // save the cell content (if necessary)
691 if (IsEditing() && aController
->IsModified() && !((EditBrowseBox
*) this)->SaveModified())
693 // maybe we're not visible ...
695 aController
->GetWindow().GrabFocus();
698 // ask if traveling to the next cell is allowed
699 if (IsTabAllowed(sal_True
))
700 nId
= BROWSER_CURSORRIGHT
;
703 case KEY_RIGHT
: nId
= BROWSER_CURSORRIGHT
; break;
704 case KEY_LEFT
: nId
= BROWSER_CURSORLEFT
; break;
705 case KEY_SPACE
: nId
= BROWSER_SELECT
; bNonEditOnly
= bLocalSelect
= sal_True
;break;
708 if ( !bAlt
&& !bCtrl
&& bShift
)
711 case KEY_DOWN
: nId
= BROWSER_SELECTDOWN
; bLocalSelect
= sal_True
;break;
712 case KEY_UP
: nId
= BROWSER_SELECTUP
; bLocalSelect
= sal_True
;break;
713 case KEY_HOME
: nId
= BROWSER_SELECTHOME
; bLocalSelect
= sal_True
;break;
714 case KEY_END
: nId
= BROWSER_SELECTEND
; bLocalSelect
= sal_True
;break;
716 if (IsTabAllowed(sal_False
))
717 nId
= BROWSER_CURSORLEFT
;
721 if ( !bAlt
&& bCtrl
&& bShift
)
724 case KEY_SPACE
: nId
= BROWSER_SELECTCOLUMN
; bLocalSelect
= sal_True
; break;
728 if ( !bAlt
&& bCtrl
&& !bShift
)
731 case KEY_DOWN
: nId
= BROWSER_SCROLLUP
; break;
732 case KEY_UP
: nId
= BROWSER_SCROLLDOWN
; break;
733 case KEY_PAGEDOWN
: nId
= BROWSER_CURSORENDOFFILE
; break;
734 case KEY_PAGEUP
: nId
= BROWSER_CURSORTOPOFFILE
; break;
735 case KEY_HOME
: nId
= BROWSER_CURSORTOPOFSCREEN
; break;
736 case KEY_END
: nId
= BROWSER_CURSORENDOFSCREEN
; break;
737 case KEY_SPACE
: nId
= BROWSER_ENHANCESELECTION
; bLocalSelect
= sal_True
;break;
741 if ( ( nId
!= BROWSER_NONE
)
744 && aController
->MoveAllowed( *pKeyEvent
)
749 if (nId
== BROWSER_SELECT
|| BROWSER_SELECTCOLUMN
== nId
)
751 // save the cell content (if necessary)
752 if (IsEditing() && aController
->IsModified() && !((EditBrowseBox
*) this)->SaveModified())
754 // maybe we're not visible ...
756 aController
->GetWindow().GrabFocus();
763 if (bLocalSelect
&& (GetSelectRowCount() || GetSelection() != NULL
))
769 return BrowseBox::PreNotify(rEvt
);
772 //------------------------------------------------------------------------------
773 sal_Bool
EditBrowseBox::IsTabAllowed(sal_Bool
) const
778 //------------------------------------------------------------------------------
779 long EditBrowseBox::Notify(NotifyEvent
& rEvt
)
781 switch (rEvt
.GetType())
784 DetermineFocus( getRealGetFocusFlags( this ) );
787 case EVENT_LOSEFOCUS
:
791 return BrowseBox::Notify(rEvt
);
794 //------------------------------------------------------------------------------
795 void EditBrowseBox::StateChanged( StateChangedType nType
)
797 BrowseBox::StateChanged( nType
);
799 bool bNeedCellReActivation
= false;
800 if ( nType
== STATE_CHANGE_MIRRORING
)
802 bNeedCellReActivation
= true;
804 else if ( nType
== STATE_CHANGE_ZOOM
)
806 ImplInitSettings( sal_True
, sal_False
, sal_False
);
807 bNeedCellReActivation
= true;
809 else if ( nType
== STATE_CHANGE_CONTROLFONT
)
811 ImplInitSettings( sal_True
, sal_False
, sal_False
);
814 else if ( nType
== STATE_CHANGE_CONTROLFOREGROUND
)
816 ImplInitSettings( sal_False
, sal_True
, sal_False
);
819 else if ( nType
== STATE_CHANGE_CONTROLBACKGROUND
)
821 ImplInitSettings( sal_False
, sal_False
, sal_True
);
824 else if (nType
== STATE_CHANGE_STYLE
)
826 WinBits nStyle
= GetStyle();
827 if (!(nStyle
& WB_NOTABSTOP
) )
828 nStyle
|= WB_TABSTOP
;
832 if ( bNeedCellReActivation
)
842 //------------------------------------------------------------------------------
843 void EditBrowseBox::DataChanged( const DataChangedEvent
& rDCEvt
)
845 BrowseBox::DataChanged( rDCEvt
);
847 if ((( rDCEvt
.GetType() == DATACHANGED_SETTINGS
) ||
848 ( rDCEvt
.GetType() == DATACHANGED_DISPLAY
)) &&
849 ( rDCEvt
.GetFlags() & SETTINGS_STYLE
))
851 ImplInitSettings( sal_True
, sal_True
, sal_True
);
856 //------------------------------------------------------------------------------
857 void EditBrowseBox::ImplInitSettings( sal_Bool bFont
, sal_Bool bForeground
, sal_Bool bBackground
)
859 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
863 Font aFont
= rStyleSettings
.GetFieldFont();
866 GetDataWindow().SetControlFont(GetControlFont());
867 aFont
.Merge(GetControlFont());
870 GetDataWindow().SetControlFont();
872 GetDataWindow().SetZoomedPointFont(aFont
);
875 if ( bFont
|| bForeground
)
877 Color aTextColor
= rStyleSettings
.GetFieldTextColor();
878 if (IsControlForeground())
880 aTextColor
= GetControlForeground();
881 GetDataWindow().SetControlForeground(aTextColor
);
884 GetDataWindow().SetControlForeground();
886 GetDataWindow().SetTextColor( aTextColor
);
891 if (GetDataWindow().IsControlBackground())
893 GetDataWindow().SetControlBackground(GetControlBackground());
894 GetDataWindow().SetBackground(GetDataWindow().GetControlBackground());
895 GetDataWindow().SetFillColor(GetDataWindow().GetControlBackground());
899 GetDataWindow().SetControlBackground();
900 GetDataWindow().SetBackground( rStyleSettings
.GetFieldColor() );
901 GetDataWindow().SetFillColor( rStyleSettings
.GetFieldColor() );
906 //------------------------------------------------------------------------------
907 sal_Bool
EditBrowseBox::IsCursorMoveAllowed(long nNewRow
, sal_uInt16 nNewColId
) const
909 sal_uInt16 nInfo
= 0;
911 if (GetSelectColumnCount() || (aMouseEvent
.Is() && aMouseEvent
->GetRow() < 0))
913 if ((GetSelection() != NULL
&& GetSelectRowCount()) ||
914 (aMouseEvent
.Is() && aMouseEvent
->GetColumnId() == HANDLE_ID
))
916 if (!nInfo
&& nNewRow
!= nEditRow
)
918 if (!nInfo
&& nNewColId
!= nEditCol
)
921 if (nInfo
== 0) // nothing happened
924 // save the cell content
925 if (IsEditing() && aController
->IsModified() && !((EditBrowseBox
*) this)->SaveModified())
927 // maybe we're not visible ...
929 aController
->GetWindow().GrabFocus();
933 EditBrowseBox
* pTHIS
= (EditBrowseBox
*) this;
935 // save the cell content if
936 // a) a selection is beeing made
937 // b) the row is changing
938 if (IsModified() && (nInfo
& (ROWCHANGE
| COLSELECT
| ROWSELECT
)) &&
941 if (nInfo
& COLSELECT
||
945 pTHIS
->SetNoSelection();
950 if (!Controller()->GetWindow().IsVisible())
954 aController
->GetWindow().GrabFocus();
959 if (nNewRow
!= nEditRow
)
961 Window
& rWindow
= GetDataWindow();
962 // don't paint too much
963 // update the status immediatly if possible
964 if ((nEditRow
>= 0) && (GetBrowserFlags() & EBBF_NO_HANDLE_COLUMN_CONTENT
) == 0)
966 Rectangle aRect
= GetFieldRectPixel(nEditRow
, 0, sal_False
);
967 // status cell should be painted if and only if text is displayed
968 // note: bPaintStatus is mutable, but Solaris has problems with assigning
969 // probably because it is part of a bitfield
970 pTHIS
->bPaintStatus
= static_cast< sal_Bool
>
971 (( GetBrowserFlags() & EBBF_HANDLE_COLUMN_TEXT
) == EBBF_HANDLE_COLUMN_TEXT
);
972 rWindow
.Paint(aRect
);
973 pTHIS
->bPaintStatus
= sal_True
;
976 // don't paint during row change
977 rWindow
.EnablePaint(sal_False
);
979 // the last veto chance for derived classes
980 if (!pTHIS
->CursorMoving(nNewRow
, nNewColId
))
982 pTHIS
->InvalidateStatusCell(nEditRow
);
983 rWindow
.EnablePaint(sal_True
);
988 rWindow
.EnablePaint(sal_True
);
993 return pTHIS
->CursorMoving(nNewRow
, nNewColId
);
996 //------------------------------------------------------------------------------
997 void EditBrowseBox::ColumnMoved(sal_uInt16 nId
)
999 BrowseBox::ColumnMoved(nId
);
1002 Rectangle
aRect( GetCellRect(nEditRow
, nEditCol
, sal_False
));
1003 CellControllerRef aControllerRef
= Controller();
1004 ResizeController(aControllerRef
, aRect
);
1005 Controller()->GetWindow().GrabFocus();
1009 //------------------------------------------------------------------------------
1010 sal_Bool
EditBrowseBox::SaveRow()
1015 //------------------------------------------------------------------------------
1016 sal_Bool
EditBrowseBox::CursorMoving(long, sal_uInt16
)
1018 ((EditBrowseBox
*) this)->DeactivateCell(sal_False
);
1022 //------------------------------------------------------------------------------
1023 void EditBrowseBox::CursorMoved()
1025 long nNewRow
= GetCurRow();
1026 if (nEditRow
!= nNewRow
)
1028 if ((GetBrowserFlags() & EBBF_NO_HANDLE_COLUMN_CONTENT
) == 0)
1029 InvalidateStatusCell(nNewRow
);
1033 GetDataWindow().EnablePaint(sal_True
);
1034 // should not be called here because the descant event is not needed here
1035 //BrowseBox::CursorMoved();
1038 //------------------------------------------------------------------------------
1039 void EditBrowseBox::EndScroll()
1043 Rectangle aRect
= GetCellRect(nEditRow
, nEditCol
, sal_False
);
1044 ResizeController(aController
,aRect
);
1047 BrowseBox::EndScroll();
1050 //------------------------------------------------------------------------------
1051 void EditBrowseBox::ActivateCell(long nRow
, sal_uInt16 nCol
, sal_Bool bCellFocus
)
1058 if ((GetSelectRowCount() && GetSelection() != NULL
) || GetSelectColumnCount() ||
1059 (aMouseEvent
.Is() && (aMouseEvent
.IsDown() || aMouseEvent
->GetClicks() > 1))) // bei MouseDown passiert noch nichts
1064 if (nEditRow
>= 0 && nEditCol
> HANDLE_ID
)
1066 aController
= GetController(nRow
, nCol
);
1067 if (aController
.Is())
1069 Rectangle
aRect( GetCellRect(nEditRow
, nEditCol
, sal_False
));
1070 ResizeController(aController
, aRect
);
1072 InitController(aController
, nEditRow
, nEditCol
);
1074 aController
->ClearModified();
1075 aController
->SetModifyHdl(LINK(this,EditBrowseBox
,ModifyHdl
));
1078 if ( isAccessibleAlive() )
1079 implCreateActiveAccessible();
1081 // activate the cell only of the browser has the focus
1082 if ( bHasFocus
&& bCellFocus
)
1087 // no controller -> we have a new "active descendant"
1088 if ( isAccessibleAlive() && HasFocus() )
1091 ACTIVE_DESCENDANT_CHANGED
,
1092 makeAny( CreateAccessibleCell( nRow
, GetColumnPos( nCol
) ) ),
1100 //------------------------------------------------------------------------------
1101 void EditBrowseBox::DeactivateCell(sal_Bool bUpdate
)
1105 if ( isAccessibleAlive() )
1107 commitBrowseBoxEvent( CHILD
, Any(), makeAny( m_aImpl
->m_xActiveCell
) );
1108 m_aImpl
->clearActiveCell();
1111 aOldController
= aController
;
1112 aController
.Clear();
1114 // reset the modify handler
1115 aOldController
->SetModifyHdl(Link());
1118 GrabFocus(); // ensure that we have (and keep) the focus
1120 HideAndDisable(aOldController
);
1122 // update if requested
1126 nOldEditCol
= nEditCol
;
1127 nOldEditRow
= nEditRow
;
1129 // release the controller (asynchronously)
1131 Application::RemoveUserEvent(nEndEvent
);
1132 nEndEvent
= Application::PostUserEvent(LINK(this,EditBrowseBox
,EndEditHdl
));
1136 //------------------------------------------------------------------------------
1137 Rectangle
EditBrowseBox::GetCellRect(long nRow
, sal_uInt16 nColId
, sal_Bool bRel
) const
1139 Rectangle
aRect( GetFieldRectPixel(nRow
, nColId
, bRel
));
1140 if ((GetMode() & BROWSER_CURSOR_WO_FOCUS
) == BROWSER_CURSOR_WO_FOCUS
)
1143 aRect
.Bottom() -= 1;
1148 //------------------------------------------------------------------------------
1149 IMPL_LINK(EditBrowseBox
, EndEditHdl
, void*, EMPTYARG
)
1152 ReleaseController(aOldController
, nOldEditRow
, nOldEditCol
);
1154 aOldController
= CellControllerRef();
1161 //------------------------------------------------------------------------------
1162 IMPL_LINK(EditBrowseBox
, ModifyHdl
, void*, EMPTYARG
)
1164 if (nCellModifiedEvent
)
1165 Application::RemoveUserEvent(nCellModifiedEvent
);
1166 nCellModifiedEvent
= Application::PostUserEvent(LINK(this,EditBrowseBox
,CellModifiedHdl
));
1170 //------------------------------------------------------------------------------
1171 IMPL_LINK(EditBrowseBox
, CellModifiedHdl
, void*, EMPTYARG
)
1173 nCellModifiedEvent
= 0;
1178 //------------------------------------------------------------------------------
1179 void EditBrowseBox::ColumnResized( sal_uInt16
)
1183 Rectangle
aRect( GetCellRect(nEditRow
, nEditCol
, sal_False
));
1184 CellControllerRef aControllerRef
= Controller();
1185 ResizeController(aControllerRef
, aRect
);
1186 Controller()->GetWindow().GrabFocus();
1190 //------------------------------------------------------------------------------
1191 sal_uInt16
EditBrowseBox::AppendColumn(const String
& rName
, sal_uInt16 nWidth
, sal_uInt16 nPos
, sal_uInt16 nId
)
1193 if (nId
== (sal_uInt16
)-1)
1195 // look for the next free id
1196 for (nId
= ColCount(); nId
> 0 && GetColumnPos(nId
) != BROWSER_INVALIDID
; nId
--)
1201 // if there is no handle column
1203 if (!ColCount() || GetColumnId(0))
1204 nId
= ColCount() + 1;
1208 DBG_ASSERT(nId
, "EditBrowseBox::AppendColumn: invalid id!");
1212 w
= GetDefaultColumnWidth(rName
);
1214 InsertDataColumn(nId
, rName
, w
, (HIB_CENTER
| HIB_VCENTER
| HIB_CLICKABLE
), nPos
);
1218 //------------------------------------------------------------------------------
1219 void EditBrowseBox::Resize()
1221 BrowseBox::Resize();
1223 // if the window is smaller than "title line height" + "control area",
1225 if (GetOutputSizePixel().Height() <
1226 (GetControlArea().GetHeight() + GetDataWindow().GetPosPixel().Y()))
1229 // the size of the control area
1230 Point
aPoint(GetControlArea().TopLeft());
1231 sal_uInt16 nX
= (sal_uInt16
)aPoint
.X();
1233 ArrangeControls(nX
, (sal_uInt16
)aPoint
.Y());
1237 ReserveControlArea((sal_uInt16
)nX
);
1240 //------------------------------------------------------------------------------
1241 void EditBrowseBox::ArrangeControls(sal_uInt16
&, sal_uInt16
)
1245 //------------------------------------------------------------------------------
1246 CellController
* EditBrowseBox::GetController(long, sal_uInt16
)
1251 //-----------------------------------------------------------------------------
1252 void EditBrowseBox::ResizeController(CellControllerRef
& rController
, const Rectangle
& rRect
)
1254 rController
->GetWindow().SetPosSizePixel(rRect
.TopLeft(), rRect
.GetSize());
1257 //------------------------------------------------------------------------------
1258 void EditBrowseBox::InitController(CellControllerRef
&, long, sal_uInt16
)
1262 //------------------------------------------------------------------------------
1263 void EditBrowseBox::ReleaseController(CellControllerRef
&, long, sal_uInt16
)
1267 //------------------------------------------------------------------------------
1268 void EditBrowseBox::CellModified()
1273 //------------------------------------------------------------------------------
1274 sal_Bool
EditBrowseBox::SaveModified()
1279 //------------------------------------------------------------------------------
1280 void EditBrowseBox::DoubleClick(const BrowserMouseEvent
& rEvt
)
1282 // when double clicking on the column, the optimum size will be calculated
1283 sal_uInt16 nColId
= rEvt
.GetColumnId();
1284 if (nColId
!= HANDLE_ID
)
1285 SetColumnWidth(nColId
, GetAutoColumnWidth(nColId
));
1288 //------------------------------------------------------------------------------
1289 sal_uInt32
EditBrowseBox::GetAutoColumnWidth(sal_uInt16 nColId
)
1291 sal_uInt32 nCurColWidth
= GetColumnWidth(nColId
);
1292 sal_uInt32 nMinColWidth
= CalcZoom(20); // minimum
1293 sal_uInt32 nNewColWidth
= nMinColWidth
;
1294 long nMaxRows
= Min(long(GetVisibleRows()), GetRowCount());
1295 long nLastVisRow
= GetTopRow() + nMaxRows
- 1;
1297 if (GetTopRow() <= nLastVisRow
) // calc the column with using the cell contents
1299 for (long i
= GetTopRow(); i
<= nLastVisRow
; ++i
)
1300 nNewColWidth
= std::max(nNewColWidth
,GetTotalCellWidth(i
,nColId
) + 12);
1302 if (nNewColWidth
== nCurColWidth
) // size has not changed
1303 nNewColWidth
= GetDefaultColumnWidth(GetColumnTitle(nColId
));
1306 nNewColWidth
= GetDefaultColumnWidth(GetColumnTitle(nColId
));
1307 return nNewColWidth
;
1310 //------------------------------------------------------------------------------
1311 sal_uInt32
EditBrowseBox::GetTotalCellWidth(long, sal_uInt16
)
1316 //------------------------------------------------------------------------------
1317 void EditBrowseBox::InvalidateHandleColumn()
1319 Rectangle
aHdlFieldRect( GetFieldRectPixel( 0, 0 ));
1320 Rectangle
aInvalidRect( Point(0,0), GetOutputSizePixel() );
1321 aInvalidRect
.Right() = aHdlFieldRect
.Right();
1322 Invalidate( aInvalidRect
);
1325 //------------------------------------------------------------------------------
1326 void EditBrowseBox::PaintTristate(OutputDevice
&, const Rectangle
& rRect
,const TriState
& eState
,sal_Bool _bEnabled
) const
1328 pCheckBoxPaint
->GetBox().SetState(eState
);
1329 pCheckBoxPaint
->SetPosSizePixel(rRect
.TopLeft(), rRect
.GetSize());
1331 // First update the parent, preventing that while painting this window
1332 // an update for the parent is done (because it's in the queue already)
1333 // which may lead to hiding this window immediately
1334 // #95598# comment out OJ
1335 /* if (pCheckBoxPaint->GetParent())
1336 pCheckBoxPaint->GetParent()->Update();
1338 pCheckBoxPaint
->GetBox().Enable(_bEnabled
);
1339 pCheckBoxPaint
->Show();
1340 pCheckBoxPaint
->SetParentUpdateMode( sal_False
);
1341 pCheckBoxPaint
->Update();
1342 pCheckBoxPaint
->Hide();
1343 pCheckBoxPaint
->SetParentUpdateMode( sal_True
);
1346 //------------------------------------------------------------------------------
1347 void EditBrowseBox::AsynchGetFocus()
1350 Application::RemoveUserEvent(nStartEvent
);
1352 m_pFocusWhileRequest
= Application::GetFocusWindow();
1353 nStartEvent
= Application::PostUserEvent(LINK(this,EditBrowseBox
,StartEditHdl
));
1356 //------------------------------------------------------------------------------
1357 void EditBrowseBox::SetBrowserFlags(sal_Int32 nFlags
)
1359 if (m_nBrowserFlags
== nFlags
)
1362 sal_Bool RowPicturesChanges
= ((m_nBrowserFlags
& EBBF_NO_HANDLE_COLUMN_CONTENT
) !=
1363 (nFlags
& EBBF_NO_HANDLE_COLUMN_CONTENT
));
1364 m_nBrowserFlags
= nFlags
;
1366 if (RowPicturesChanges
)
1367 InvalidateStatusCell(GetCurRow());
1369 //------------------------------------------------------------------------------
1370 inline void EditBrowseBox::HideAndDisable(CellControllerRef
& rController
)
1372 rController
->suspend();
1374 //------------------------------------------------------------------------------
1375 inline void EditBrowseBox::EnableAndShow() const
1377 Controller()->resume();
1379 //===============================================================================
1381 DBG_NAME(CellController
);
1382 //------------------------------------------------------------------------------
1383 CellController::CellController(Control
* pW
)
1385 ,bSuspended( sal_True
)
1387 DBG_CTOR(CellController
,NULL
);
1389 DBG_ASSERT(pWindow
, "CellController::CellController: missing the window!");
1390 DBG_ASSERT(!pWindow
->IsVisible(), "CellController::CellController: window should not be visible!");
1393 //-----------------------------------------------------------------------------
1394 CellController::~CellController()
1397 DBG_DTOR(CellController
,NULL
);
1400 //-----------------------------------------------------------------------------
1401 void CellController::suspend( )
1403 DBG_ASSERT( bSuspended
== !GetWindow().IsVisible(), "CellController::suspend: inconsistence!" );
1404 if ( !isSuspended( ) )
1406 CommitModifications();
1407 GetWindow().Hide( );
1408 GetWindow().Disable( );
1409 bSuspended
= sal_True
;
1413 //-----------------------------------------------------------------------------
1414 void CellController::resume( )
1416 DBG_ASSERT( bSuspended
== !GetWindow().IsVisible(), "CellController::resume: inconsistence!" );
1417 if ( isSuspended( ) )
1419 GetWindow().Enable( );
1420 GetWindow().Show( );
1421 bSuspended
= sal_False
;
1425 //-----------------------------------------------------------------------------
1426 void CellController::CommitModifications()
1428 // nothing to do in this base class
1431 //-----------------------------------------------------------------------------
1432 sal_Bool
CellController::WantMouseEvent() const
1437 //-----------------------------------------------------------------------------
1438 void CellController::SetModified()
1442 //-----------------------------------------------------------------------------
1443 sal_Bool
CellController::MoveAllowed(const KeyEvent
&) const
1447 // .......................................................................
1449 // .......................................................................