1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svtools.hxx"
26 #include <svtools/editbrowsebox.hxx>
27 
28 #ifndef _SVTOOLS_EDITBROWSEBOX_HRC_
29 #include "editbrowsebox.hrc"
30 #endif
31 
32 #ifndef _APP_HXX //autogen
33 #include <vcl/svapp.hxx>
34 #endif
35 #include <tools/debug.hxx>
36 #include <vcl/window.hxx>
37 
38 #ifndef _EDIT_HXX //autogen
39 #include <vcl/edit.hxx>
40 #endif
41 #include <tools/resid.hxx>
42 #include <vcl/spinfld.hxx>
43 #include <svtools/svtdata.hxx>
44 
45 #ifndef _SVTOOLS_HRC
46 #include <svtools/svtools.hrc>
47 #endif
48 
49 #include <algorithm>
50 #include <tools/multisel.hxx>
51 #include "editbrowseboximpl.hxx"
52 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
53 #include <com/sun/star/accessibility/XAccessible.hpp>
54 #include <comphelper/types.hxx>
55 
56 // .......................................................................
57 namespace svt
58 {
59 // .......................................................................
60 	namespace
61 	{
62 		//..............................................................
isHiContrast(Window * _pWindow)63 		sal_Bool isHiContrast(Window* _pWindow)
64 		{
65 			OSL_ENSURE(_pWindow,"Window must be not null!");
66             return _pWindow && _pWindow->GetSettings().GetStyleSettings().GetHighContrastMode();
67 		}
68 
69 		//..............................................................
getRealGetFocusFlags(Window * _pWindow)70 		sal_uInt16 getRealGetFocusFlags( Window* _pWindow )
71 		{
72 			sal_uInt16 nFlags = 0;
73 			while ( _pWindow && !nFlags )
74 			{
75 				nFlags = _pWindow->GetGetFocusFlags( );
76 				_pWindow = _pWindow->GetParent();
77 			}
78 			return nFlags;
79 		}
80 	}
81 
82 	using namespace ::com::sun::star::uno;
83 	using namespace com::sun::star::accessibility::AccessibleEventId;
84 	using  com::sun::star::accessibility::XAccessible;
85 	//==================================================================
86 
87 	#define HANDLE_ID	0
88 
89 	//==================================================================
90 	//= EditBrowserHeader
91 	//==================================================================
92 	//------------------------------------------------------------------------------
DoubleClick()93 	void EditBrowserHeader::DoubleClick()
94 	{
95 		sal_uInt16 nColId = GetCurItemId();
96 		if (nColId)
97 		{
98 			sal_uInt32 nAutoWidth = ((EditBrowseBox*)GetParent())->GetAutoColumnWidth(nColId);
99 			if (nAutoWidth != ((EditBrowseBox*)GetParent())->GetColumnWidth(nColId))
100 			{
101 				((EditBrowseBox*)GetParent())->SetColumnWidth(nColId, nAutoWidth);
102 				((EditBrowseBox*)GetParent())->ColumnResized(nColId);
103 			}
104 		}
105 	}
106 
107 
108 	//==================================================================
109 	//= EditBrowseBox
110 	//==================================================================
111 	//------------------------------------------------------------------------------
Clear()112 	void EditBrowseBox::BrowserMouseEventPtr::Clear()
113 	{
114 		DELETEZ(pEvent);
115 	}
116 
117 	//------------------------------------------------------------------------------
Set(const BrowserMouseEvent * pEvt,sal_Bool bIsDown)118 	void EditBrowseBox::BrowserMouseEventPtr::Set(const BrowserMouseEvent* pEvt, sal_Bool bIsDown)
119 	{
120 		if (pEvt == pEvent)
121 		{
122 			bDown = bIsDown;
123 			return;
124 		}
125 		Clear();
126 		if (pEvt)
127 		{
128 			pEvent = new BrowserMouseEvent(pEvt->GetWindow(),
129 										   *pEvt,
130 										   pEvt->GetRow(),
131 										   pEvt->GetColumn(),
132 										   pEvt->GetColumnId(),
133 										   pEvt->GetRect());
134 			bDown = bIsDown;
135 		}
136 	}
137 
138 	//------------------------------------------------------------------------------
139 	DBG_NAME(EditBrowseBox);
impl_construct()140 	void EditBrowseBox::impl_construct()
141 	{
142 		m_aImpl = ::std::auto_ptr<EditBrowseBoxImpl>(new EditBrowseBoxImpl());
143 		m_aImpl->m_bHiContrast = isHiContrast(&GetDataWindow());
144 
145 		SetCompoundControl(sal_True);
146 		SetGridLineColor( Color( COL_LIGHTGRAY ) );
147 
148 		ImplInitSettings(sal_True, sal_True, sal_True);
149 
150 		pCheckBoxPaint = new CheckBoxControl(&GetDataWindow());
151 		pCheckBoxPaint->SetPaintTransparent( sal_True );
152 		pCheckBoxPaint->SetBackground();
153 	}
154 
155 	//------------------------------------------------------------------------------
EditBrowseBox(Window * pParent,const ResId & rId,sal_Int32 nBrowserFlags,BrowserMode _nMode)156 	EditBrowseBox::EditBrowseBox(Window* pParent, const ResId& rId, sal_Int32 nBrowserFlags, BrowserMode _nMode )
157 				  :BrowseBox( pParent, rId, _nMode )
158 				  ,nStartEvent(0)
159 				  ,nEndEvent(0)
160 				  ,nCellModifiedEvent(0)
161 				  ,nPaintRow(-1)
162 				  ,nEditRow(-1)
163 				  ,nOldEditRow(-1)
164 				  ,nEditCol(0)
165 				  ,nOldEditCol(0)
166 				  ,bHasFocus(sal_False)
167 				  ,bPaintStatus(sal_True)
168                   ,bActiveBeforeTracking( sal_False )
169 				  ,m_nBrowserFlags(nBrowserFlags)
170 	{
171 		DBG_CTOR(EditBrowseBox,NULL);
172 
173 		impl_construct();
174 	}
175 
176 	//==================================================================
EditBrowseBox(Window * pParent,sal_Int32 nBrowserFlags,WinBits nBits,BrowserMode _nMode)177 	EditBrowseBox::EditBrowseBox( Window* pParent, sal_Int32 nBrowserFlags, WinBits nBits, BrowserMode _nMode )
178 				  :BrowseBox( pParent, nBits, _nMode )
179 				  ,nStartEvent(0)
180 				  ,nEndEvent(0)
181 				  ,nCellModifiedEvent(0)
182 				  ,nPaintRow(-1)
183 				  ,nEditRow(-1)
184 				  ,nOldEditRow(-1)
185 				  ,nEditCol(0)
186 				  ,nOldEditCol(0)
187 				  ,bHasFocus(sal_False)
188 				  ,bPaintStatus(sal_True)
189                   ,bActiveBeforeTracking( sal_False )
190 				  ,m_nBrowserFlags(nBrowserFlags)
191 				  ,pHeader(NULL)
192 	{
193 		DBG_CTOR(EditBrowseBox,NULL);
194 
195 		impl_construct();
196 	}
197 
198 	//------------------------------------------------------------------------------
Init()199 	void EditBrowseBox::Init()
200 	{
201 		// spaetes Construieren,
202 	}
203 
204 	//------------------------------------------------------------------------------
~EditBrowseBox()205 	EditBrowseBox::~EditBrowseBox()
206 	{
207 		if (nStartEvent)
208 			Application::RemoveUserEvent(nStartEvent);
209 		if (nEndEvent)
210 			Application::RemoveUserEvent(nEndEvent);
211 		if (nCellModifiedEvent)
212 			Application::RemoveUserEvent(nCellModifiedEvent);
213 
214 		delete pCheckBoxPaint;
215 
216 		DBG_DTOR(EditBrowseBox,NULL);
217 	}
218 
219 	//------------------------------------------------------------------------------
RemoveRows()220 	void EditBrowseBox::RemoveRows()
221 	{
222 		BrowseBox::Clear();
223 		nOldEditRow = nEditRow = nPaintRow = -1;
224 		nEditCol = nOldEditCol = 0;
225 	}
226 
227 	//------------------------------------------------------------------------------
CreateHeaderBar(BrowseBox * pParent)228 	BrowserHeader* EditBrowseBox::CreateHeaderBar(BrowseBox* pParent)
229 	{
230 		pHeader = imp_CreateHeaderBar(pParent);
231 		if (!IsUpdateMode())
232 			pHeader->SetUpdateMode(sal_False);
233 		return pHeader;
234 	}
235 
236 	//------------------------------------------------------------------------------
imp_CreateHeaderBar(BrowseBox * pParent)237 	BrowserHeader* EditBrowseBox::imp_CreateHeaderBar(BrowseBox* pParent)
238 	{
239 		return new EditBrowserHeader(pParent);
240 	}
241 
242 	//------------------------------------------------------------------------------
LoseFocus()243 	void EditBrowseBox::LoseFocus()
244 	{
245 		BrowseBox::LoseFocus();
246 		DetermineFocus( 0 );
247 	}
248 
249 	//------------------------------------------------------------------------------
GetFocus()250 	void EditBrowseBox::GetFocus()
251 	{
252 		BrowseBox::GetFocus();
253 
254 		// This should handle the case that the BrowseBox (or one of it's children)
255 		// gets the focus from outside by pressing Tab
256 		if (IsEditing() && Controller()->GetWindow().IsVisible())
257 			Controller()->GetWindow().GrabFocus();
258 
259 		DetermineFocus( getRealGetFocusFlags( this ) );
260 	}
261 
262 	//------------------------------------------------------------------------------
SeekRow(long nRow)263 	sal_Bool EditBrowseBox::SeekRow(long nRow)
264 	{
265 		nPaintRow = nRow;
266 		return sal_True;
267 	}
268 
269 	//------------------------------------------------------------------------------
IMPL_LINK(EditBrowseBox,StartEditHdl,void *,EMPTYARG)270 	IMPL_LINK(EditBrowseBox, StartEditHdl, void*, EMPTYARG)
271 	{
272 		nStartEvent = 0;
273 		if (IsEditing())
274 		{
275 			EnableAndShow();
276 			if (!aController->GetWindow().HasFocus() && (m_pFocusWhileRequest == Application::GetFocusWindow()))
277 				aController->GetWindow().GrabFocus();
278 		}
279 		return 0;
280 	}
281 
282 	//------------------------------------------------------------------------------
PaintField(OutputDevice & rDev,const Rectangle & rRect,sal_uInt16 nColumnId) const283 	void EditBrowseBox::PaintField( OutputDevice& rDev, const Rectangle& rRect,
284 									sal_uInt16 nColumnId ) const
285 	{
286 		if (nColumnId == HANDLE_ID)
287 		{
288  			if (bPaintStatus)
289 				PaintStatusCell(rDev, rRect);
290 		}
291 		else
292 		{
293 			// don't paint the current cell
294 			if (&rDev == &GetDataWindow())
295 				// but only if we're painting onto our data win (which is the usual painting)
296 				if (nPaintRow == nEditRow)
297 				{
298 					if (IsEditing() && nEditCol == nColumnId && aController->GetWindow().IsVisible())
299 						return;
300 				}
301 			PaintCell(rDev, rRect, nColumnId);
302 		}
303 	}
304 
305 	//------------------------------------------------------------------------------
GetImage(RowStatus eStatus) const306 	Image EditBrowseBox::GetImage(RowStatus eStatus) const
307 	{
308 		sal_Bool bHiContrast = isHiContrast(&GetDataWindow());
309 		if ( !m_aStatusImages.GetImageCount() || (bHiContrast != m_aImpl->m_bHiContrast) )
310 		{
311 			m_aImpl->m_bHiContrast = bHiContrast;
312 			const_cast<EditBrowseBox*>(this)->m_aStatusImages = ImageList(SvtResId(bHiContrast ? RID_SVTOOLS_IMAGELIST_EDITBWSEBOX_H : RID_SVTOOLS_IMAGELIST_EDITBROWSEBOX));
313 		}
314 
315 		Image aImage;
316         bool bNeedMirror = IsRTLEnabled();
317 		switch (eStatus)
318 		{
319 			case CURRENT:
320 				aImage = m_aStatusImages.GetImage(IMG_EBB_CURRENT);
321 				break;
322 			case CURRENTNEW:
323 				aImage = m_aStatusImages.GetImage(IMG_EBB_CURRENTNEW);
324 				break;
325 			case MODIFIED:
326 				aImage = m_aStatusImages.GetImage(IMG_EBB_MODIFIED);
327                 bNeedMirror = false;    // the pen is not mirrored
328 				break;
329 			case NEW:
330 				aImage = m_aStatusImages.GetImage(IMG_EBB_NEW);
331 				break;
332 			case DELETED:
333 				aImage = m_aStatusImages.GetImage(IMG_EBB_DELETED);
334 				break;
335 			case PRIMARYKEY:
336 				aImage = m_aStatusImages.GetImage(IMG_EBB_PRIMARYKEY);
337 				break;
338 			case CURRENT_PRIMARYKEY:
339 				aImage = m_aStatusImages.GetImage(IMG_EBB_CURRENT_PRIMARYKEY);
340 				break;
341 			case FILTER:
342 				aImage = m_aStatusImages.GetImage(IMG_EBB_FILTER);
343 				break;
344 			case HEADERFOOTER:
345 				aImage = m_aStatusImages.GetImage(IMG_EBB_HEADERFOOTER);
346 				break;
347             case CLEAN:
348                 break;
349 		}
350         if ( bNeedMirror )
351         {
352             BitmapEx aBitmap( aImage.GetBitmapEx() );
353             aBitmap.Mirror( BMP_MIRROR_HORZ );
354             aImage = Image( aBitmap );
355         }
356 		return aImage;
357 	}
358 
359 	//------------------------------------------------------------------------------
PaintStatusCell(OutputDevice & rDev,const Rectangle & rRect) const360 	void EditBrowseBox::PaintStatusCell(OutputDevice& rDev, const Rectangle& rRect) const
361 	{
362 		if (nPaintRow < 0)
363 			return;
364 
365         RowStatus eStatus = GetRowStatus( nPaintRow );
366         sal_Int32 nBrowserFlags = GetBrowserFlags();
367 
368 		if (nBrowserFlags & EBBF_NO_HANDLE_COLUMN_CONTENT)
369 			return;
370 
371         // draw the text of the header column
372         if (nBrowserFlags & EBBF_HANDLE_COLUMN_TEXT )
373         {
374             rDev.DrawText( rRect, GetCellText( nPaintRow, 0 ),
375                            TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER | TEXT_DRAW_CLIP );
376         }
377         // draw an image
378         else if (eStatus != CLEAN && rDev.GetOutDevType() == OUTDEV_WINDOW)
379 		{
380 			Image aImage(GetImage(eStatus));
381 			// calc the image position
382 			Size aImageSize(aImage.GetSizePixel());
383 			aImageSize.Width() = CalcZoom(aImageSize.Width());
384 			aImageSize.Height() = CalcZoom(aImageSize.Height());
385 			Point aPos( rRect.TopLeft() );
386 
387 			if ( ( aImageSize.Width() > rRect.GetWidth() ) || ( aImageSize.Height() > rRect.GetHeight() ) )
388 				rDev.SetClipRegion(rRect);
389 
390 			if ( aImageSize.Width() < rRect.GetWidth() )
391 				aPos.X() += ( rRect.GetWidth() - aImageSize.Width() ) / 2;
392 
393             if ( aImageSize.Height() < rRect.GetHeight() )
394 				aPos.Y() += ( rRect.GetHeight() - aImageSize.Height() ) / 2;
395 
396 			if ( IsZoom() )
397 				rDev.DrawImage( aPos, aImageSize, aImage, 0 );
398 			else
399 				rDev.DrawImage( aPos, aImage, 0 );
400 
401 			if (rDev.IsClipRegion())
402 				rDev.SetClipRegion();
403 		}
404 	}
405 
406 	//------------------------------------------------------------------------------
ImplStartTracking()407     void EditBrowseBox::ImplStartTracking()
408     {
409         bActiveBeforeTracking = IsEditing();
410         if ( bActiveBeforeTracking )
411         {
412             DeactivateCell();
413             Update();
414         }
415 
416         BrowseBox::ImplStartTracking();
417     }
418 
419 	//------------------------------------------------------------------------------
ImplTracking()420     void EditBrowseBox::ImplTracking()
421     {
422         BrowseBox::ImplTracking();
423     }
424 
425     //------------------------------------------------------------------------------
ImplEndTracking()426     void EditBrowseBox::ImplEndTracking()
427     {
428         if ( bActiveBeforeTracking )
429             ActivateCell();
430         bActiveBeforeTracking = sal_False;
431 
432         BrowseBox::ImplEndTracking();
433     }
434 
435 	//------------------------------------------------------------------------------
RowHeightChanged()436     void EditBrowseBox::RowHeightChanged()
437     {
438         if ( IsEditing() )
439         {
440 			Rectangle aRect( GetCellRect( nEditRow, nEditCol, sal_False ) );
441 			CellControllerRef aCellController( Controller() );
442 			ResizeController( aCellController, aRect );
443 			aCellController->GetWindow().GrabFocus();
444         }
445 
446         BrowseBox::RowHeightChanged();
447     }
448 
449 	//------------------------------------------------------------------------------
GetRowStatus(long) const450 	EditBrowseBox::RowStatus EditBrowseBox::GetRowStatus(long) const
451 	{
452 		return CLEAN;
453 	}
454 
455 	//------------------------------------------------------------------------------
KeyInput(const KeyEvent & rEvt)456 	void EditBrowseBox::KeyInput( const KeyEvent& rEvt )
457 	{
458 		sal_uInt16 nCode = rEvt.GetKeyCode().GetCode();
459 		sal_Bool   bShift = rEvt.GetKeyCode().IsShift();
460 		sal_Bool   bCtrl = rEvt.GetKeyCode().IsMod1();
461 
462 		switch (nCode)
463 		{
464 			case KEY_RETURN:
465 				if (!bCtrl && !bShift && IsTabAllowed(sal_True))
466 				{
467 					Dispatch(BROWSER_CURSORRIGHT);
468 				}
469 				else
470 					BrowseBox::KeyInput(rEvt);
471 				return;
472 			case KEY_TAB:
473 				if (!bCtrl && !bShift)
474 				{
475 					if (IsTabAllowed(sal_True))
476 						Dispatch(BROWSER_CURSORRIGHT);
477 					else
478 						// do NOT call BrowseBox::KeyInput : this would handle the tab, but we already now
479 						// that tab isn't allowed here. So give the Control class a chance
480 						Control::KeyInput(rEvt);
481 					return;
482 				}
483 				else if (!bCtrl && bShift)
484 				{
485 					if (IsTabAllowed(sal_False))
486 						Dispatch(BROWSER_CURSORLEFT);
487 					else
488 						// do NOT call BrowseBox::KeyInput : this would handle the tab, but we already now
489 						// that tab isn't allowed here. So give the Control class a chance
490 						Control::KeyInput(rEvt);
491 					return;
492 				}
493 			default:
494 				BrowseBox::KeyInput(rEvt);
495 		}
496 	}
497 
498 	//------------------------------------------------------------------------------
MouseButtonDown(const BrowserMouseEvent & rEvt)499 	void EditBrowseBox::MouseButtonDown(const BrowserMouseEvent& rEvt)
500 	{
501 		sal_uInt16  nColPos = GetColumnPos( rEvt.GetColumnId() );
502 		long	nRow	= rEvt.GetRow();
503 
504 		// absorb double clicks
505 		if (rEvt.GetClicks() > 1 && rEvt.GetRow() >= 0)
506 			return;
507 
508 		// change to a new position
509 		if (IsEditing() && (nColPos != nEditCol || nRow != nEditRow) && (nColPos != BROWSER_INVALIDID) && (nRow < GetRowCount()))
510 		{
511             CellControllerRef aCellController(Controller());
512 			HideAndDisable(aCellController);
513 		}
514 
515 		// we are about to leave the current cell. If there is a "this cell has been modified" notification
516 		// pending (asynchronously), this may be deadly -> do it synchronously
517 		// 95826 - 2002-10-14 - fs@openoffice.org
518 		if ( nCellModifiedEvent )
519 		{
520 			Application::RemoveUserEvent( nCellModifiedEvent );
521 			nCellModifiedEvent = 0;
522 			LINK( this, EditBrowseBox, CellModifiedHdl ).Call( NULL );
523 		}
524 
525 		if (0 == rEvt.GetColumnId())
526 		{	// it was the handle column. save the current cell content if necessary
527 			// (clicking on the handle column results in selecting the current row)
528 			// 23.01.2001 - 82797 - FS
529 			if (IsEditing() && aController->IsModified())
530 				SaveModified();
531 		}
532 
533 		aMouseEvent.Set(&rEvt,sal_True);
534 		BrowseBox::MouseButtonDown(rEvt);
535 		aMouseEvent.Clear();
536 
537 		if (0 != (m_nBrowserFlags & EBBF_ACTIVATE_ON_BUTTONDOWN))
538 		{
539 			// the base class does not travel upon MouseButtonDown, but implActivateCellOnMouseEvent assumes we traveled ...
540 			GoToRowColumnId( rEvt.GetRow(), rEvt.GetColumnId() );
541 			if (rEvt.GetRow() >= 0)
542 				implActivateCellOnMouseEvent(rEvt, sal_False);
543 		}
544 	}
545 
546 	//------------------------------------------------------------------------------
MouseButtonUp(const BrowserMouseEvent & rEvt)547 	void EditBrowseBox::MouseButtonUp( const BrowserMouseEvent& rEvt )
548 	{
549 		// absorb double clicks
550 		if (rEvt.GetClicks() > 1 && rEvt.GetRow() >= 0)
551 			return;
552 
553 		aMouseEvent.Set(&rEvt,sal_False);
554 		BrowseBox::MouseButtonUp(rEvt);
555 		aMouseEvent.Clear();
556 
557 		if (0 == (m_nBrowserFlags & EBBF_ACTIVATE_ON_BUTTONDOWN))
558 			if (rEvt.GetRow() >= 0)
559 				implActivateCellOnMouseEvent(rEvt, sal_True);
560 	}
561 
562 	//------------------------------------------------------------------------------
implActivateCellOnMouseEvent(const BrowserMouseEvent & _rEvt,sal_Bool _bUp)563 	void EditBrowseBox::implActivateCellOnMouseEvent(const BrowserMouseEvent& _rEvt, sal_Bool _bUp)
564 	{
565 		if (!IsEditing())
566 			ActivateCell();
567 		else if (IsEditing() && !aController->GetWindow().IsEnabled())
568 			DeactivateCell();
569 		else if (IsEditing() && !aController->GetWindow().HasChildPathFocus())
570 			AsynchGetFocus();
571 
572 		if (IsEditing() && aController->GetWindow().IsEnabled() && aController->WantMouseEvent())
573 		{	// forwards the event to the control
574 
575 			// If the field has been moved previously, we have to adjust the position
576 
577 			aController->GetWindow().GrabFocus();
578 
579 			// the position of the event relative to the controller's window
580 			Point aPos = _rEvt.GetPosPixel() - _rEvt.GetRect().TopLeft();
581 			// the (child) window which should really get the event
582 			Window* pRealHandler = aController->GetWindow().FindWindow(aPos);
583 			if (pRealHandler)
584 				// the coords relative to this real handler
585 				aPos -= pRealHandler->GetPosPixel();
586 			else
587 				pRealHandler = &aController->GetWindow();
588 
589 			// the faked event
590 			MouseEvent aEvent(aPos, _rEvt.GetClicks(), _rEvt.GetMode(),
591 							  _rEvt.GetButtons(),
592 							  _rEvt.GetModifier());
593 
594 			pRealHandler->MouseButtonDown(aEvent);
595 			if (_bUp)
596 				pRealHandler->MouseButtonUp(aEvent);
597 
598 			Window *pWin = &aController->GetWindow();
599 			if (!pWin->IsTracking())
600 			{
601 				for (pWin = pWin->GetWindow(WINDOW_FIRSTCHILD);
602 					 pWin && !pWin->IsTracking();
603 					 pWin = pWin->GetWindow(WINDOW_NEXT))
604 				{
605 				}
606 			}
607 			if (pWin && pWin->IsTracking())
608 				pWin->EndTracking();
609 		}
610 	}
611 
612 	//------------------------------------------------------------------------------
Dispatch(sal_uInt16 _nId)613 	void EditBrowseBox::Dispatch( sal_uInt16 _nId )
614 	{
615 		if ( _nId == BROWSER_ENHANCESELECTION )
616 		{	// this is a workaround for the bug in the base class:
617 			// if the row selection is to be extended (which is what BROWSER_ENHANCESELECTION tells us)
618 			// then the base class does not revert any column selections, while, for doing a "simple"
619 			// selection (BROWSER_SELECT), it does. In fact, it does not only revert the col selection then,
620 			// but also any current row selections.
621 			// This clearly tells me that the both ids are for row selection only - there this behaviour does
622 			// make sense.
623 			// But here, where we have column selection, too, we take care of this ourself.
624 			if ( GetSelectColumnCount( ) )
625 			{
626 				while ( GetSelectColumnCount( ) )
627 					SelectColumnPos(
628                         sal::static_int_cast< sal_uInt16 >(FirstSelectedColumn()),
629                         sal_False );
630 				Select();
631 			}
632 		}
633 		BrowseBox::Dispatch( _nId );
634 	}
635 
636 	//------------------------------------------------------------------------------
PreNotify(NotifyEvent & rEvt)637 	long EditBrowseBox::PreNotify(NotifyEvent& rEvt)
638 	{
639 		switch (rEvt.GetType())
640 		{
641 			case EVENT_KEYINPUT:
642 				if	(	(IsEditing() && Controller()->GetWindow().HasChildPathFocus())
643 					||	rEvt.GetWindow() == &GetDataWindow()
644 					||	(!IsEditing() && HasChildPathFocus())
645 					)
646 				{
647 					const KeyEvent* pKeyEvent =	rEvt.GetKeyEvent();
648 					sal_uInt16 nCode  = pKeyEvent->GetKeyCode().GetCode();
649 					sal_Bool   bShift = pKeyEvent->GetKeyCode().IsShift();
650 					sal_Bool   bCtrl  = pKeyEvent->GetKeyCode().IsMod1();
651 					sal_Bool   bAlt =	pKeyEvent->GetKeyCode().IsMod2();
652 					sal_Bool   bLocalSelect=	sal_False;
653 					sal_Bool   bNonEditOnly =	sal_False;
654 					sal_uInt16 nId = BROWSER_NONE;
655 
656 					if (!bAlt && !bCtrl && !bShift )
657 						switch ( nCode )
658 						{
659 							case KEY_DOWN:          nId = BROWSER_CURSORDOWN; break;
660 							case KEY_UP:            nId = BROWSER_CURSORUP; break;
661 							case KEY_PAGEDOWN:      nId = BROWSER_CURSORPAGEDOWN; break;
662 							case KEY_PAGEUP:        nId = BROWSER_CURSORPAGEUP; break;
663 							case KEY_HOME:          nId = BROWSER_CURSORHOME; break;
664 							case KEY_END:           nId = BROWSER_CURSOREND; break;
665 
666 							case KEY_TAB:
667 								// ask if traveling to the next cell is allowed
668 								if (IsTabAllowed(sal_True))
669 									nId = BROWSER_CURSORRIGHT;
670 								break;
671 
672 							case KEY_RETURN:
673 								// save the cell content (if necessary)
674 								if (IsEditing() && aController->IsModified() && !((EditBrowseBox *) this)->SaveModified())
675 								{
676 									// maybe we're not visible ...
677 									EnableAndShow();
678 									aController->GetWindow().GrabFocus();
679 									return 1;
680 								}
681 								// ask if traveling to the next cell is allowed
682 								if (IsTabAllowed(sal_True))
683 									nId = BROWSER_CURSORRIGHT;
684 
685 								break;
686 							case KEY_RIGHT:         nId = BROWSER_CURSORRIGHT; break;
687 							case KEY_LEFT:          nId = BROWSER_CURSORLEFT; break;
688 							case KEY_SPACE:         nId = BROWSER_SELECT; bNonEditOnly = bLocalSelect = sal_True;break;
689 						}
690 
691 					if ( !bAlt && !bCtrl && bShift )
692 						switch ( nCode )
693 						{
694 							case KEY_DOWN:          nId = BROWSER_SELECTDOWN; bLocalSelect = sal_True;break;
695 							case KEY_UP:            nId = BROWSER_SELECTUP; bLocalSelect = sal_True;break;
696 							case KEY_HOME:          nId = BROWSER_SELECTHOME; bLocalSelect = sal_True;break;
697 							case KEY_END:           nId = BROWSER_SELECTEND; bLocalSelect = sal_True;break;
698 							case KEY_TAB:
699 								if (IsTabAllowed(sal_False))
700 									nId = BROWSER_CURSORLEFT;
701 								break;
702 						}
703 
704                     if ( !bAlt && bCtrl && bShift )
705 						switch ( nCode )
706 						{
707 							case KEY_SPACE:			nId = BROWSER_SELECTCOLUMN; bLocalSelect = sal_True; break;
708 						}
709 
710 
711 					if ( !bAlt && bCtrl && !bShift )
712 						switch ( nCode )
713 						{
714 							case KEY_DOWN:          nId = BROWSER_SCROLLUP; break;
715 							case KEY_UP:            nId = BROWSER_SCROLLDOWN; break;
716 							case KEY_PAGEDOWN:      nId = BROWSER_CURSORENDOFFILE; break;
717 							case KEY_PAGEUP:        nId = BROWSER_CURSORTOPOFFILE; break;
718 							case KEY_HOME:          nId = BROWSER_CURSORTOPOFSCREEN; break;
719 							case KEY_END:           nId = BROWSER_CURSORENDOFSCREEN; break;
720 							case KEY_SPACE:         nId = BROWSER_ENHANCESELECTION; bLocalSelect = sal_True;break;
721 						}
722 
723 
724 					if	(	( nId != BROWSER_NONE )
725 						&&	(	!IsEditing()
726 							||	(	!bNonEditOnly
727 								&&	aController->MoveAllowed( *pKeyEvent )
728 								)
729 							)
730 						)
731 					{
732 						if (nId == BROWSER_SELECT || BROWSER_SELECTCOLUMN == nId )
733 						{
734 							// save the cell content (if necessary)
735 							if (IsEditing() && aController->IsModified() && !((EditBrowseBox *) this)->SaveModified())
736 							{
737 								// maybe we're not visible ...
738 								EnableAndShow();
739 								aController->GetWindow().GrabFocus();
740 								return 1;
741 							}
742 						}
743 
744 						Dispatch(nId);
745 
746 						if (bLocalSelect && (GetSelectRowCount() || GetSelection() != NULL))
747 							DeactivateCell();
748 						return 1;
749 					}
750 				}
751 		}
752 		return BrowseBox::PreNotify(rEvt);
753 	}
754 
755 	//------------------------------------------------------------------------------
IsTabAllowed(sal_Bool) const756 	sal_Bool EditBrowseBox::IsTabAllowed(sal_Bool) const
757 	{
758 		return sal_True;
759 	}
760 
761 	//------------------------------------------------------------------------------
Notify(NotifyEvent & rEvt)762 	long EditBrowseBox::Notify(NotifyEvent& rEvt)
763 	{
764 		switch (rEvt.GetType())
765 		{
766 			case EVENT_GETFOCUS:
767 				DetermineFocus( getRealGetFocusFlags( this ) );
768 				break;
769 
770 			case EVENT_LOSEFOCUS:
771 				DetermineFocus( 0 );
772 				break;
773 		}
774 		return BrowseBox::Notify(rEvt);
775 	}
776 
777 	//------------------------------------------------------------------------------
StateChanged(StateChangedType nType)778 	void EditBrowseBox::StateChanged( StateChangedType nType )
779 	{
780 		BrowseBox::StateChanged( nType );
781 
782         bool bNeedCellReActivation = false;
783 		if ( nType == STATE_CHANGE_MIRRORING )
784 		{
785             bNeedCellReActivation = true;
786         }
787 		else if ( nType == STATE_CHANGE_ZOOM )
788 		{
789 			ImplInitSettings( sal_True, sal_False, sal_False );
790             bNeedCellReActivation = true;
791 		}
792 		else if ( nType == STATE_CHANGE_CONTROLFONT )
793 		{
794 			ImplInitSettings( sal_True, sal_False, sal_False );
795 			Invalidate();
796 		}
797 		else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
798 		{
799 			ImplInitSettings( sal_False, sal_True, sal_False );
800 			Invalidate();
801 		}
802 		else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
803 		{
804 			ImplInitSettings( sal_False, sal_False, sal_True );
805 			Invalidate();
806 		}
807 		else if (nType == STATE_CHANGE_STYLE)
808 		{
809 			WinBits nStyle = GetStyle();
810 			if (!(nStyle & WB_NOTABSTOP) )
811 				nStyle |= WB_TABSTOP;
812 
813 			SetStyle(nStyle);
814 		}
815         if ( bNeedCellReActivation )
816         {
817             if ( IsEditing() )
818             {
819                 DeactivateCell();
820                 ActivateCell();
821             }
822         }
823     }
824 
825 	//------------------------------------------------------------------------------
DataChanged(const DataChangedEvent & rDCEvt)826 	void EditBrowseBox::DataChanged( const DataChangedEvent& rDCEvt )
827 	{
828 		BrowseBox::DataChanged( rDCEvt );
829 
830 		if ((( rDCEvt.GetType() == DATACHANGED_SETTINGS	)	||
831 			( rDCEvt.GetType() == DATACHANGED_DISPLAY	))	&&
832 			( rDCEvt.GetFlags() & SETTINGS_STYLE		))
833 		{
834 			ImplInitSettings( sal_True, sal_True, sal_True );
835 			Invalidate();
836 		}
837 	}
838 
839 	//------------------------------------------------------------------------------
ImplInitSettings(sal_Bool bFont,sal_Bool bForeground,sal_Bool bBackground)840 	void EditBrowseBox::ImplInitSettings( sal_Bool bFont, sal_Bool bForeground, sal_Bool bBackground )
841 	{
842 		const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
843 
844 		if (bFont)
845 		{
846 			Font aFont = rStyleSettings.GetFieldFont();
847 			if (IsControlFont())
848 			{
849 				GetDataWindow().SetControlFont(GetControlFont());
850 				aFont.Merge(GetControlFont());
851 			}
852 			else
853 				GetDataWindow().SetControlFont();
854 
855 			GetDataWindow().SetZoomedPointFont(aFont);
856 		}
857 
858 		if ( bFont || bForeground )
859 		{
860 			Color aTextColor = rStyleSettings.GetFieldTextColor();
861 			if (IsControlForeground())
862 			{
863 				aTextColor = GetControlForeground();
864 				GetDataWindow().SetControlForeground(aTextColor);
865 			}
866 			else
867 				GetDataWindow().SetControlForeground();
868 
869 			GetDataWindow().SetTextColor( aTextColor );
870 		}
871 
872 		if ( bBackground )
873 		{
874 			if (GetDataWindow().IsControlBackground())
875 			{
876 				GetDataWindow().SetControlBackground(GetControlBackground());
877 				GetDataWindow().SetBackground(GetDataWindow().GetControlBackground());
878 				GetDataWindow().SetFillColor(GetDataWindow().GetControlBackground());
879 			}
880 			else
881 			{
882 				GetDataWindow().SetControlBackground();
883 				GetDataWindow().SetBackground( rStyleSettings.GetFieldColor() );
884 				GetDataWindow().SetFillColor( rStyleSettings.GetFieldColor() );
885 			}
886 		}
887 	}
888 
889 	//------------------------------------------------------------------------------
IsCursorMoveAllowed(long nNewRow,sal_uInt16 nNewColId) const890 	sal_Bool EditBrowseBox::IsCursorMoveAllowed(long nNewRow, sal_uInt16 nNewColId) const
891 	{
892 		sal_uInt16 nInfo = 0;
893 
894 		if (GetSelectColumnCount() || (aMouseEvent.Is() && aMouseEvent->GetRow() < 0))
895 			nInfo |= COLSELECT;
896 		if ((GetSelection() != NULL && GetSelectRowCount()) ||
897 			(aMouseEvent.Is() && aMouseEvent->GetColumnId() == HANDLE_ID))
898 			nInfo |= ROWSELECT;
899 		if (!nInfo && nNewRow != nEditRow)
900 			nInfo |= ROWCHANGE;
901 		if (!nInfo && nNewColId != nEditCol)
902 			nInfo |= COLCHANGE;
903 
904 		if (nInfo == 0)	  // nothing happened
905 			return sal_True;
906 
907 		// save the cell content
908 		if (IsEditing() && aController->IsModified() && !((EditBrowseBox *) this)->SaveModified())
909 		{
910 			// maybe we're not visible ...
911 			EnableAndShow();
912 			aController->GetWindow().GrabFocus();
913 			return sal_False;
914 		}
915 
916 		EditBrowseBox * pTHIS = (EditBrowseBox *) this;
917 
918 		// save the cell content if
919 		// a) a selection is being made
920 		// b) the row is changing
921 		if (IsModified() && (nInfo & (ROWCHANGE | COLSELECT | ROWSELECT)) &&
922 			!pTHIS->SaveRow())
923 		{
924 			if (nInfo & COLSELECT ||
925 				nInfo & ROWSELECT)
926 			{
927 				// cancel selected
928 				pTHIS->SetNoSelection();
929 			}
930 
931 			if (IsEditing())
932 			{
933 				if (!Controller()->GetWindow().IsVisible())
934 				{
935 					EnableAndShow();
936 				}
937 				aController->GetWindow().GrabFocus();
938 			}
939 			return sal_False;
940 		}
941 
942 		if (nNewRow != nEditRow)
943 		{
944 			Window& rWindow = GetDataWindow();
945 			// don't paint too much
946 			// update the status immediately if possible
947 			if ((nEditRow >= 0) && (GetBrowserFlags() & EBBF_NO_HANDLE_COLUMN_CONTENT) == 0)
948 			{
949 				Rectangle aRect = GetFieldRectPixel(nEditRow, 0, sal_False );
950                 // status cell should be painted if and only if text is displayed
951                 // note: bPaintStatus is mutable, but Solaris has problems with assigning
952                 // probably because it is part of a bitfield
953                 pTHIS->bPaintStatus = static_cast< sal_Bool >
954                     (( GetBrowserFlags() & EBBF_HANDLE_COLUMN_TEXT ) == EBBF_HANDLE_COLUMN_TEXT );
955 				rWindow.Paint(aRect);
956 				pTHIS->bPaintStatus = sal_True;
957 			}
958 
959 			// don't paint during row change
960 			rWindow.EnablePaint(sal_False);
961 
962 			// the last veto chance for derived classes
963 			if (!pTHIS->CursorMoving(nNewRow, nNewColId))
964 			{
965 				pTHIS->InvalidateStatusCell(nEditRow);
966 				rWindow.EnablePaint(sal_True);
967 				return sal_False;
968 			}
969 			else
970 			{
971 				rWindow.EnablePaint(sal_True);
972 				return sal_True;
973 			}
974 		}
975 		else
976 			return pTHIS->CursorMoving(nNewRow, nNewColId);
977 	}
978 
979 	//------------------------------------------------------------------------------
ColumnMoved(sal_uInt16 nId)980 	void EditBrowseBox::ColumnMoved(sal_uInt16 nId)
981 	{
982 		BrowseBox::ColumnMoved(nId);
983 		if (IsEditing())
984 		{
985 			Rectangle aRect( GetCellRect(nEditRow, nEditCol, sal_False));
986 			CellControllerRef aControllerRef = Controller();
987 			ResizeController(aControllerRef, aRect);
988 			Controller()->GetWindow().GrabFocus();
989 		}
990 	}
991 
992 	//------------------------------------------------------------------------------
SaveRow()993 	sal_Bool EditBrowseBox::SaveRow()
994 	{
995 		return sal_True;
996 	}
997 
998 	//------------------------------------------------------------------------------
CursorMoving(long,sal_uInt16)999 	sal_Bool EditBrowseBox::CursorMoving(long, sal_uInt16)
1000 	{
1001 		((EditBrowseBox *) this)->DeactivateCell(sal_False);
1002 		return sal_True;
1003 	}
1004 
1005 	//------------------------------------------------------------------------------
CursorMoved()1006 	void EditBrowseBox::CursorMoved()
1007 	{
1008 		long nNewRow = GetCurRow();
1009 		if (nEditRow != nNewRow)
1010 		{
1011 			if ((GetBrowserFlags() & EBBF_NO_HANDLE_COLUMN_CONTENT) == 0)
1012 				InvalidateStatusCell(nNewRow);
1013 			nEditRow = nNewRow;
1014 		}
1015 		ActivateCell();
1016 		GetDataWindow().EnablePaint(sal_True);
1017 		// should not be called here because the descant event is not needed here
1018 		//BrowseBox::CursorMoved();
1019 	}
1020 
1021 	//------------------------------------------------------------------------------
EndScroll()1022 	void EditBrowseBox::EndScroll()
1023 	{
1024 		if (IsEditing())
1025 		{
1026 			Rectangle aRect = GetCellRect(nEditRow, nEditCol, sal_False);
1027 			ResizeController(aController,aRect);
1028 			AsynchGetFocus();
1029 		}
1030 		BrowseBox::EndScroll();
1031 	}
1032 
1033 	//------------------------------------------------------------------------------
ActivateCell(long nRow,sal_uInt16 nCol,sal_Bool bCellFocus)1034 	void EditBrowseBox::ActivateCell(long nRow, sal_uInt16 nCol, sal_Bool bCellFocus)
1035 	{
1036 		if (IsEditing())
1037 			return;
1038 
1039 		nEditCol = nCol;
1040 
1041 		if ((GetSelectRowCount() && GetSelection() != NULL) || GetSelectColumnCount() ||
1042 			(aMouseEvent.Is() && (aMouseEvent.IsDown() || aMouseEvent->GetClicks() > 1))) // bei MouseDown passiert noch nichts
1043 		{
1044 			return;
1045 		}
1046 
1047 		if (nEditRow >= 0 && nEditCol > HANDLE_ID)
1048 		{
1049 			aController = GetController(nRow, nCol);
1050 			if (aController.Is())
1051 			{
1052 				Rectangle aRect( GetCellRect(nEditRow, nEditCol, sal_False));
1053 				ResizeController(aController, aRect);
1054 
1055 				InitController(aController, nEditRow, nEditCol);
1056 
1057 				aController->ClearModified();
1058 				aController->SetModifyHdl(LINK(this,EditBrowseBox,ModifyHdl));
1059 				EnableAndShow();
1060 
1061                 if ( isAccessibleAlive() )
1062 					implCreateActiveAccessible();
1063 
1064 				// activate the cell only of the browser has the focus
1065 				if ( bHasFocus && bCellFocus )
1066 					AsynchGetFocus();
1067 			}
1068 			else
1069 			{
1070 				// no controller -> we have a new "active descendant"
1071                 if ( isAccessibleAlive() && HasFocus() )
1072                 {
1073 					commitTableEvent(
1074                         ACTIVE_DESCENDANT_CHANGED,
1075 						makeAny( CreateAccessibleCell( nRow, GetColumnPos( nCol -1) ) ),
1076 						Any()
1077 					);
1078                 }
1079 			}
1080 		}
1081 	}
1082 
1083 	//------------------------------------------------------------------------------
DeactivateCell(sal_Bool bUpdate)1084 	void EditBrowseBox::DeactivateCell(sal_Bool bUpdate)
1085 	{
1086 		if (IsEditing())
1087 		{
1088             if ( isAccessibleAlive() )
1089 			{
1090 				commitBrowseBoxEvent( CHILD, Any(), makeAny( m_aImpl->m_xActiveCell ) );
1091 				m_aImpl->clearActiveCell();
1092 			}
1093 
1094 			aOldController = aController;
1095 			aController.Clear();
1096 
1097 			// reset the modify handler
1098 			aOldController->SetModifyHdl(Link());
1099 
1100 			if (bHasFocus)
1101 				GrabFocus(); // ensure that we have (and keep) the focus
1102 
1103 			HideAndDisable(aOldController);
1104 
1105 			// update if requested
1106 			if (bUpdate)
1107 				Update();
1108 
1109 			nOldEditCol = nEditCol;
1110 			nOldEditRow = nEditRow;
1111 
1112 			// release the controller (asynchronously)
1113 			if (nEndEvent)
1114 				Application::RemoveUserEvent(nEndEvent);
1115 			nEndEvent = Application::PostUserEvent(LINK(this,EditBrowseBox,EndEditHdl));
1116 		}
1117 	}
1118 
1119 	//------------------------------------------------------------------------------
GetCellRect(long nRow,sal_uInt16 nColId,sal_Bool bRel) const1120 	Rectangle EditBrowseBox::GetCellRect(long nRow, sal_uInt16 nColId, sal_Bool bRel) const
1121 	{
1122 		Rectangle aRect( GetFieldRectPixel(nRow, nColId, bRel));
1123 		if ((GetMode()  & BROWSER_CURSOR_WO_FOCUS) == BROWSER_CURSOR_WO_FOCUS)
1124 		{
1125 			aRect.Top() += 1;
1126 			aRect.Bottom() -= 1;
1127 		}
1128 		return aRect;
1129 	}
1130 
1131 	//------------------------------------------------------------------------------
IMPL_LINK(EditBrowseBox,EndEditHdl,void *,EMPTYARG)1132 	IMPL_LINK(EditBrowseBox, EndEditHdl, void*, EMPTYARG)
1133 	{
1134 		nEndEvent = 0;
1135 		ReleaseController(aOldController, nOldEditRow, nOldEditCol);
1136 
1137 		aOldController  = CellControllerRef();
1138 		nOldEditRow		= -1;
1139 		nOldEditCol		=  0;
1140 
1141 		return 0;
1142 	}
1143 
1144 	//------------------------------------------------------------------------------
IMPL_LINK(EditBrowseBox,ModifyHdl,void *,EMPTYARG)1145 	IMPL_LINK(EditBrowseBox, ModifyHdl, void*, EMPTYARG)
1146 	{
1147 		if (nCellModifiedEvent)
1148 			Application::RemoveUserEvent(nCellModifiedEvent);
1149 		nCellModifiedEvent = Application::PostUserEvent(LINK(this,EditBrowseBox,CellModifiedHdl));
1150 		return 0;
1151 	}
1152 
1153 	//------------------------------------------------------------------------------
IMPL_LINK(EditBrowseBox,CellModifiedHdl,void *,EMPTYARG)1154 	IMPL_LINK(EditBrowseBox, CellModifiedHdl, void*, EMPTYARG)
1155 	{
1156 		nCellModifiedEvent = 0;
1157 		CellModified();
1158 		return 0;
1159 	}
1160 
1161 	//------------------------------------------------------------------------------
ColumnResized(sal_uInt16)1162 	void EditBrowseBox::ColumnResized( sal_uInt16 )
1163 	{
1164 		if (IsEditing())
1165 		{
1166 			Rectangle aRect( GetCellRect(nEditRow, nEditCol, sal_False));
1167 			CellControllerRef aControllerRef = Controller();
1168 			ResizeController(aControllerRef, aRect);
1169 			Controller()->GetWindow().GrabFocus();
1170 		}
1171 	}
1172 
1173 	//------------------------------------------------------------------------------
AppendColumn(const String & rName,sal_uInt16 nWidth,sal_uInt16 nPos,sal_uInt16 nId)1174 	sal_uInt16 EditBrowseBox::AppendColumn(const String& rName, sal_uInt16 nWidth, sal_uInt16 nPos, sal_uInt16 nId)
1175 	{
1176 		if (nId == (sal_uInt16)-1)
1177 		{
1178 			// look for the next free id
1179 			for (nId = ColCount(); nId > 0 && GetColumnPos(nId) != BROWSER_INVALIDID; nId--)
1180 				;
1181 
1182 			if (!nId)
1183 			{
1184 				// if there is no handle column
1185 				// increment the id
1186 				if (!ColCount() || GetColumnId(0))
1187 					nId = ColCount() + 1;
1188 			}
1189 		}
1190 
1191 		DBG_ASSERT(nId, "EditBrowseBox::AppendColumn: invalid id!");
1192 
1193         long w = nWidth;
1194 		if (!w)
1195 			w = GetDefaultColumnWidth(rName);
1196 
1197 		InsertDataColumn(nId, rName, w, (HIB_CENTER | HIB_VCENTER | HIB_CLICKABLE), nPos);
1198 		return nId;
1199 	}
1200 
1201 	//------------------------------------------------------------------------------
Resize()1202 	void EditBrowseBox::Resize()
1203 	{
1204 		BrowseBox::Resize();
1205 
1206 		// if the window is smaller than "title line height" + "control area",
1207 		// do nothing
1208 		if (GetOutputSizePixel().Height() <
1209 		   (GetControlArea().GetHeight() + GetDataWindow().GetPosPixel().Y()))
1210 			return;
1211 
1212 		// the size of the control area
1213 		Point aPoint(GetControlArea().TopLeft());
1214 		sal_uInt16 nX = (sal_uInt16)aPoint.X();
1215 
1216 		ArrangeControls(nX, (sal_uInt16)aPoint.Y());
1217 
1218 		if (!nX)
1219 			nX = USHRT_MAX;
1220 		ReserveControlArea((sal_uInt16)nX);
1221 	}
1222 
1223 	//------------------------------------------------------------------------------
ArrangeControls(sal_uInt16 &,sal_uInt16)1224 	void EditBrowseBox::ArrangeControls(sal_uInt16&, sal_uInt16)
1225 	{
1226 	}
1227 
1228 	//------------------------------------------------------------------------------
GetController(long,sal_uInt16)1229 	CellController* EditBrowseBox::GetController(long, sal_uInt16)
1230 	{
1231 		return NULL;
1232 	}
1233 
1234 	//-----------------------------------------------------------------------------
ResizeController(CellControllerRef & rController,const Rectangle & rRect)1235 	void EditBrowseBox::ResizeController(CellControllerRef& rController, const Rectangle& rRect)
1236 	{
1237 		rController->GetWindow().SetPosSizePixel(rRect.TopLeft(), rRect.GetSize());
1238 	}
1239 
1240 	//------------------------------------------------------------------------------
InitController(CellControllerRef &,long,sal_uInt16)1241 	void EditBrowseBox::InitController(CellControllerRef&, long, sal_uInt16)
1242 	{
1243 	}
1244 
1245 	//------------------------------------------------------------------------------
ReleaseController(CellControllerRef &,long,sal_uInt16)1246 	void EditBrowseBox::ReleaseController(CellControllerRef&, long, sal_uInt16)
1247 	{
1248 	}
1249 
1250 	//------------------------------------------------------------------------------
CellModified()1251 	void EditBrowseBox::CellModified()
1252 	{
1253 	}
1254 
1255 
1256 	//------------------------------------------------------------------------------
SaveModified()1257 	sal_Bool EditBrowseBox::SaveModified()
1258 	{
1259 		return sal_True;
1260 	}
1261 
1262 	//------------------------------------------------------------------------------
DoubleClick(const BrowserMouseEvent & rEvt)1263 	void EditBrowseBox::DoubleClick(const BrowserMouseEvent& rEvt)
1264 	{
1265 		// when double clicking on the column, the optimum size will be calculated
1266 		sal_uInt16 nColId = rEvt.GetColumnId();
1267 		if (nColId != HANDLE_ID)
1268 			SetColumnWidth(nColId, GetAutoColumnWidth(nColId));
1269 	}
1270 
1271 	//------------------------------------------------------------------------------
GetAutoColumnWidth(sal_uInt16 nColId)1272 	sal_uInt32 EditBrowseBox::GetAutoColumnWidth(sal_uInt16 nColId)
1273 	{
1274 		sal_uInt32 nCurColWidth  = GetColumnWidth(nColId);
1275 		sal_uInt32 nMinColWidth = CalcZoom(20);	// minimum
1276 		sal_uInt32 nNewColWidth = nMinColWidth;
1277 		long nMaxRows	   = Min(long(GetVisibleRows()), GetRowCount());
1278 		long nLastVisRow   = GetTopRow() + nMaxRows - 1;
1279 
1280 		if (GetTopRow() <= nLastVisRow)	// calc the column with using the cell contents
1281 		{
1282 			for (long i = GetTopRow(); i <= nLastVisRow; ++i)
1283 				nNewColWidth = std::max(nNewColWidth,GetTotalCellWidth(i,nColId) + 12);
1284 
1285 			if (nNewColWidth == nCurColWidth)	// size has not changed
1286 				nNewColWidth = GetDefaultColumnWidth(GetColumnTitle(nColId));
1287 		}
1288 		else
1289 			nNewColWidth = GetDefaultColumnWidth(GetColumnTitle(nColId));
1290 		return nNewColWidth;
1291 	}
1292 
1293 	//------------------------------------------------------------------------------
GetTotalCellWidth(long,sal_uInt16)1294 	sal_uInt32 EditBrowseBox::GetTotalCellWidth(long, sal_uInt16)
1295 	{
1296 		return 0;
1297 	}
1298 
1299 	//------------------------------------------------------------------------------
InvalidateHandleColumn()1300 	void EditBrowseBox::InvalidateHandleColumn()
1301 	{
1302 		Rectangle aHdlFieldRect( GetFieldRectPixel( 0, 0 ));
1303 		Rectangle aInvalidRect( Point(0,0), GetOutputSizePixel() );
1304 		aInvalidRect.Right() = aHdlFieldRect.Right();
1305 		Invalidate( aInvalidRect );
1306 	}
1307 
1308 	//------------------------------------------------------------------------------
PaintTristate(OutputDevice &,const Rectangle & rRect,const TriState & eState,sal_Bool _bEnabled) const1309 	void EditBrowseBox::PaintTristate(OutputDevice&, const Rectangle& rRect,const TriState& eState,sal_Bool _bEnabled) const
1310 	{
1311 		pCheckBoxPaint->GetBox().SetState(eState);
1312 		pCheckBoxPaint->SetPosSizePixel(rRect.TopLeft(), rRect.GetSize());
1313 
1314 		// First update the parent, preventing that while painting this window
1315 		// an update for the parent is done (because it's in the queue already)
1316 		// which may lead to hiding this window immediately
1317 // #95598# comment out OJ
1318 /*		if (pCheckBoxPaint->GetParent())
1319 			pCheckBoxPaint->GetParent()->Update();
1320 */
1321 		pCheckBoxPaint->GetBox().Enable(_bEnabled);
1322 		pCheckBoxPaint->Show();
1323 		pCheckBoxPaint->SetParentUpdateMode( sal_False );
1324 		pCheckBoxPaint->Update();
1325 		pCheckBoxPaint->Hide();
1326 		pCheckBoxPaint->SetParentUpdateMode( sal_True );
1327 	}
1328 
1329 	//------------------------------------------------------------------------------
AsynchGetFocus()1330 	void EditBrowseBox::AsynchGetFocus()
1331 	{
1332 		if (nStartEvent)
1333 			Application::RemoveUserEvent(nStartEvent);
1334 
1335 		m_pFocusWhileRequest = Application::GetFocusWindow();
1336 		nStartEvent = Application::PostUserEvent(LINK(this,EditBrowseBox,StartEditHdl));
1337 	}
1338 
1339 	//------------------------------------------------------------------------------
SetBrowserFlags(sal_Int32 nFlags)1340 	void EditBrowseBox::SetBrowserFlags(sal_Int32 nFlags)
1341 	{
1342 		if (m_nBrowserFlags == nFlags)
1343 			return;
1344 
1345 		sal_Bool RowPicturesChanges = ((m_nBrowserFlags & EBBF_NO_HANDLE_COLUMN_CONTENT) !=
1346                                        (nFlags & EBBF_NO_HANDLE_COLUMN_CONTENT));
1347 		m_nBrowserFlags = nFlags;
1348 
1349 		if (RowPicturesChanges)
1350 			InvalidateStatusCell(GetCurRow());
1351 	}
1352 	//------------------------------------------------------------------------------
HideAndDisable(CellControllerRef & rController)1353 	inline void EditBrowseBox::HideAndDisable(CellControllerRef& rController)
1354 	{
1355 		rController->suspend();
1356 	}
1357 	//------------------------------------------------------------------------------
EnableAndShow() const1358 	inline void EditBrowseBox::EnableAndShow() const
1359 	{
1360 		Controller()->resume();
1361 	}
1362 	//===============================================================================
1363 
1364 	DBG_NAME(CellController);
1365 	//------------------------------------------------------------------------------
CellController(Control * pW)1366 	CellController::CellController(Control* pW)
1367 				   :pWindow( pW )
1368 				   ,bSuspended( sal_True )
1369 	{
1370 		DBG_CTOR(CellController,NULL);
1371 
1372 		DBG_ASSERT(pWindow, "CellController::CellController: missing the window!");
1373 		DBG_ASSERT(!pWindow->IsVisible(), "CellController::CellController: window should not be visible!");
1374 	}
1375 
1376 	//-----------------------------------------------------------------------------
~CellController()1377 	CellController::~CellController()
1378 	{
1379 
1380 		DBG_DTOR(CellController,NULL);
1381 	}
1382 
1383 	//-----------------------------------------------------------------------------
suspend()1384 	void CellController::suspend( )
1385 	{
1386 		DBG_ASSERT( bSuspended == !GetWindow().IsVisible(), "CellController::suspend: inconsistence!" );
1387 		if ( !isSuspended( ) )
1388 		{
1389 			CommitModifications();
1390 			GetWindow().Hide( );
1391 			GetWindow().Disable( );
1392 			bSuspended = sal_True;
1393 		}
1394 	}
1395 
1396 	//-----------------------------------------------------------------------------
resume()1397 	void CellController::resume( )
1398 	{
1399 		DBG_ASSERT( bSuspended == !GetWindow().IsVisible(), "CellController::resume: inconsistence!" );
1400 		if ( isSuspended( ) )
1401 		{
1402 			GetWindow().Enable( );
1403 			GetWindow().Show( );
1404 			bSuspended = sal_False;
1405 		}
1406 	}
1407 
1408 	//-----------------------------------------------------------------------------
CommitModifications()1409 	void CellController::CommitModifications()
1410 	{
1411 		// nothing to do in this base class
1412 	}
1413 
1414 	//-----------------------------------------------------------------------------
WantMouseEvent() const1415 	sal_Bool CellController::WantMouseEvent() const
1416 	{
1417 		return sal_False;
1418 	}
1419 
1420 	//-----------------------------------------------------------------------------
SetModified()1421 	void CellController::SetModified()
1422 	{
1423 	}
1424 
1425 	//-----------------------------------------------------------------------------
MoveAllowed(const KeyEvent &) const1426 	sal_Bool CellController::MoveAllowed(const KeyEvent&) const
1427 	{
1428 		return sal_True;
1429 	}
1430 // .......................................................................
1431 }	// namespace svt
1432 // .......................................................................
1433 
1434