Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <comphelper/processfactory.hxx>
31 : :
32 : : #include <tools/rc.h>
33 : : #include <vcl/svapp.hxx>
34 : : #include <vcl/event.hxx>
35 : : #include <vcl/ctrl.hxx>
36 : : #include <vcl/decoview.hxx>
37 : : #include <vcl/salnativewidgets.hxx>
38 : :
39 : : #include <textlayout.hxx>
40 : : #include <svdata.hxx>
41 : : #include <controldata.hxx>
42 : :
43 : :
44 : : using namespace vcl;
45 : :
46 : : // =======================================================================
47 : :
48 : 43931 : void Control::ImplInitControlData()
49 : : {
50 : 43931 : mbHasFocus = sal_False;
51 : 43931 : mpControlData = new ImplControlData;
52 : 43931 : }
53 : :
54 : : // -----------------------------------------------------------------------
55 : :
56 : 35027 : Control::Control( WindowType nType ) :
57 [ + - ][ + - ]: 35027 : Window( nType )
58 : : {
59 [ + - ]: 35027 : ImplInitControlData();
60 : 35027 : }
61 : :
62 : : // -----------------------------------------------------------------------
63 : :
64 : 8870 : Control::Control( Window* pParent, WinBits nStyle ) :
65 [ + - ][ + - ]: 8870 : Window( WINDOW_CONTROL )
66 : : {
67 [ + - ]: 8870 : ImplInitControlData();
68 [ + - ]: 8870 : Window::ImplInit( pParent, nStyle, NULL );
69 : 8870 : }
70 : :
71 : : // -----------------------------------------------------------------------
72 : :
73 : 34 : Control::Control( Window* pParent, const ResId& rResId ) :
74 [ + - ][ + - ]: 34 : Window( WINDOW_CONTROL )
75 : : {
76 [ + - ]: 34 : ImplInitControlData();
77 : 34 : rResId.SetRT( RSC_CONTROL );
78 [ + - ]: 34 : WinBits nStyle = ImplInitRes( rResId );
79 [ + - ]: 34 : ImplInit( pParent, nStyle, NULL );
80 [ + - ]: 34 : ImplLoadRes( rResId );
81 : :
82 [ + - ]: 34 : if ( !(nStyle & WB_HIDE) )
83 [ + - ]: 34 : Show();
84 : 34 : }
85 : :
86 : : // -----------------------------------------------------------------------
87 : :
88 : 43222 : Control::~Control()
89 : : {
90 [ + - ][ + - ]: 43222 : delete mpControlData, mpControlData = NULL;
91 [ - + ]: 43222 : }
92 : :
93 : : // -----------------------------------------------------------------------
94 : :
95 : 84 : void Control::GetFocus()
96 : : {
97 : 84 : Window::GetFocus();
98 : 84 : }
99 : :
100 : : // -----------------------------------------------------------------------
101 : :
102 : 46 : void Control::LoseFocus()
103 : : {
104 : 46 : Window::LoseFocus();
105 : 46 : }
106 : :
107 : : // -----------------------------------------------------------------------
108 : :
109 : 67854 : void Control::Resize()
110 : : {
111 : 67854 : ImplClearLayoutData();
112 : 67854 : Window::Resize();
113 : 67854 : }
114 : :
115 : : // -----------------------------------------------------------------------
116 : :
117 : 0 : void Control::FillLayoutData() const
118 : : {
119 : 0 : }
120 : :
121 : : // -----------------------------------------------------------------------
122 : :
123 : 0 : void Control::CreateLayoutData() const
124 : : {
125 : : DBG_ASSERT( !mpControlData->mpLayoutData, "Control::CreateLayoutData: should be called with non-existent layout data only!" );
126 [ # # ]: 0 : mpControlData->mpLayoutData = new ::vcl::ControlLayoutData();
127 : 0 : }
128 : :
129 : : // -----------------------------------------------------------------------
130 : :
131 : 536 : bool Control::HasLayoutData() const
132 : : {
133 : 536 : return mpControlData->mpLayoutData != NULL;
134 : : }
135 : :
136 : : // -----------------------------------------------------------------------
137 : :
138 : 0 : ::vcl::ControlLayoutData* Control::GetLayoutData() const
139 : : {
140 : 0 : return mpControlData->mpLayoutData;
141 : : }
142 : :
143 : : // -----------------------------------------------------------------------
144 : :
145 : 759 : void Control::SetText( const String& rStr )
146 : : {
147 : 759 : ImplClearLayoutData();
148 : 759 : Window::SetText( rStr );
149 : 759 : }
150 : :
151 : : // -----------------------------------------------------------------------
152 : :
153 : 56 : Rectangle ControlLayoutData::GetCharacterBounds( long nIndex ) const
154 : : {
155 [ + - ][ + - ]: 56 : return (nIndex >= 0 && nIndex < (long) m_aUnicodeBoundRects.size()) ? m_aUnicodeBoundRects[ nIndex ] : Rectangle();
156 : : }
157 : :
158 : :
159 : : // -----------------------------------------------------------------------
160 : :
161 : 28 : Rectangle Control::GetCharacterBounds( long nIndex ) const
162 : : {
163 [ + + ]: 28 : if( !HasLayoutData() )
164 : 2 : FillLayoutData();
165 [ + - ]: 28 : return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->GetCharacterBounds( nIndex ) : Rectangle();
166 : : }
167 : :
168 : : // -----------------------------------------------------------------------
169 : :
170 : 60 : long ControlLayoutData::GetIndexForPoint( const Point& rPoint ) const
171 : : {
172 : 60 : long nIndex = -1;
173 [ + + ]: 316 : for( long i = m_aUnicodeBoundRects.size()-1; i >= 0; i-- )
174 : : {
175 [ + - ]: 312 : Point aTopLeft = m_aUnicodeBoundRects[i].TopLeft();
176 [ + - ][ + - ]: 312 : Point aBottomRight = m_aUnicodeBoundRects[i].BottomRight();
177 [ + + ][ + - : 424 : if (rPoint.X() >= aTopLeft.X() && rPoint.Y() >= aTopLeft.Y() &&
+ - + - ]
[ + + ]
178 : 112 : rPoint.X() <= aBottomRight.X() && rPoint.Y() <= aBottomRight.Y())
179 : : {
180 : 56 : nIndex = i;
181 : : break;
182 : : }
183 : : }
184 : 60 : return nIndex;
185 : : }
186 : :
187 : : // -----------------------------------------------------------------------
188 : :
189 : 30 : long Control::GetIndexForPoint( const Point& rPoint ) const
190 : : {
191 [ - + ]: 30 : if( ! HasLayoutData() )
192 : 0 : FillLayoutData();
193 [ + - ]: 30 : return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->GetIndexForPoint( rPoint ) : -1;
194 : : }
195 : :
196 : : // -----------------------------------------------------------------------
197 : :
198 : 0 : long ControlLayoutData::GetLineCount() const
199 : : {
200 : 0 : long nLines = m_aLineIndices.size();
201 [ # # ][ # # ]: 0 : if( nLines == 0 && m_aDisplayText.Len() )
[ # # ]
202 : 0 : nLines = 1;
203 : 0 : return nLines;
204 : : }
205 : :
206 : : // -----------------------------------------------------------------------
207 : :
208 : 0 : Pair ControlLayoutData::GetLineStartEnd( long nLine ) const
209 : : {
210 : 0 : Pair aPair( -1, -1 );
211 : :
212 : 0 : int nDisplayLines = m_aLineIndices.size();
213 [ # # ][ # # ]: 0 : if( nLine >= 0 && nLine < nDisplayLines )
214 : : {
215 : 0 : aPair.A() = m_aLineIndices[nLine];
216 [ # # ]: 0 : if( nLine+1 < nDisplayLines )
217 : 0 : aPair.B() = m_aLineIndices[nLine+1]-1;
218 : : else
219 : 0 : aPair.B() = m_aDisplayText.Len()-1;
220 : : }
221 [ # # ][ # # ]: 0 : else if( nLine == 0 && nDisplayLines == 0 && m_aDisplayText.Len() )
[ # # ][ # # ]
222 : : {
223 : : // special case for single line controls so the implementations
224 : : // in that case do not have to fill in the line indices
225 : 0 : aPair.A() = 0;
226 : 0 : aPair.B() = m_aDisplayText.Len()-1;
227 : : }
228 : 0 : return aPair;
229 : : }
230 : :
231 : : // -----------------------------------------------------------------------
232 : :
233 : 0 : Pair Control::GetLineStartEnd( long nLine ) const
234 : : {
235 [ # # ]: 0 : if( !HasLayoutData() )
236 : 0 : FillLayoutData();
237 [ # # ]: 0 : return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->GetLineStartEnd( nLine ) : Pair( -1, -1 );
238 : : }
239 : :
240 : : // -----------------------------------------------------------------------
241 : :
242 : 0 : long ControlLayoutData::ToRelativeLineIndex( long nIndex ) const
243 : : {
244 : : // is the index sensible at all ?
245 [ # # ][ # # ]: 0 : if( nIndex >= 0 && nIndex < m_aDisplayText.Len() )
[ # # ]
246 : : {
247 : 0 : int nDisplayLines = m_aLineIndices.size();
248 : : // if only 1 line exists, then absolute and relative index are
249 : : // identical -> do nothing
250 [ # # ]: 0 : if( nDisplayLines > 1 )
251 : : {
252 : : int nLine;
253 [ # # ]: 0 : for( nLine = nDisplayLines-1; nLine >= 0; nLine-- )
254 : : {
255 [ # # ]: 0 : if( m_aLineIndices[nLine] <= nIndex )
256 : : {
257 : 0 : nIndex -= m_aLineIndices[nLine];
258 : 0 : break;
259 : : }
260 : : }
261 [ # # ]: 0 : if( nLine < 0 )
262 : : {
263 : : DBG_ASSERT( nLine >= 0, "ToRelativeLineIndex failed" );
264 : 0 : nIndex = -1;
265 : : }
266 : : }
267 : : }
268 : : else
269 : 0 : nIndex = -1;
270 : :
271 : 0 : return nIndex;
272 : : }
273 : :
274 : : // -----------------------------------------------------------------------
275 : :
276 : 0 : long Control::ToRelativeLineIndex( long nIndex ) const
277 : : {
278 [ # # ]: 0 : if( !HasLayoutData() )
279 : 0 : FillLayoutData();
280 [ # # ]: 0 : return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->ToRelativeLineIndex( nIndex ) : -1;
281 : : }
282 : :
283 : : // -----------------------------------------------------------------------
284 : :
285 : 0 : String Control::GetDisplayText() const
286 : : {
287 [ # # ]: 0 : if( !HasLayoutData() )
288 : 0 : FillLayoutData();
289 [ # # ]: 0 : return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->m_aDisplayText : GetText();
290 : : }
291 : :
292 : : // -----------------------------------------------------------------------
293 : :
294 : 13123 : long Control::Notify( NotifyEvent& rNEvt )
295 : : {
296 [ + + ]: 13123 : if ( rNEvt.GetType() == EVENT_GETFOCUS )
297 : : {
298 [ + + ]: 169 : if ( !mbHasFocus )
299 : : {
300 : 110 : mbHasFocus = sal_True;
301 [ - + ]: 110 : if ( ImplCallEventListenersAndHandler( VCLEVENT_CONTROL_GETFOCUS, maGetFocusHdl, this ) )
302 : : // been destroyed within the handler
303 : 0 : return sal_True;
304 : : }
305 : : }
306 : : else
307 : : {
308 [ + + ]: 12954 : if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
309 : : {
310 : 79 : Window* pFocusWin = Application::GetFocusWindow();
311 [ + + ][ + + ]: 79 : if ( !pFocusWin || !ImplIsWindowOrChild( pFocusWin ) )
[ + + ]
312 : : {
313 : 20 : mbHasFocus = sal_False;
314 [ - + ]: 20 : if ( ImplCallEventListenersAndHandler( VCLEVENT_CONTROL_LOSEFOCUS, maLoseFocusHdl, this ) )
315 : : // been destroyed within the handler
316 : 0 : return sal_True;
317 : : }
318 : : }
319 : : }
320 : :
321 : 13123 : return Window::Notify( rNEvt );
322 : : }
323 : :
324 : : // -----------------------------------------------------------------------
325 : :
326 : 574722 : void Control::StateChanged( StateChangedType nStateChange )
327 : : {
328 [ + + ][ + + ]: 574722 : if( nStateChange == STATE_CHANGE_INITSHOW ||
[ + + ][ + - ]
[ + + ]
329 : : nStateChange == STATE_CHANGE_VISIBLE ||
330 : : nStateChange == STATE_CHANGE_ZOOM ||
331 : : nStateChange == STATE_CHANGE_BORDER ||
332 : : nStateChange == STATE_CHANGE_CONTROLFONT
333 : : )
334 : : {
335 : 68459 : ImplClearLayoutData();
336 : : }
337 : 574722 : Window::StateChanged( nStateChange );
338 : 574722 : }
339 : :
340 : : // -----------------------------------------------------------------------
341 : :
342 : 0 : void Control::AppendLayoutData( const Control& rSubControl ) const
343 : : {
344 [ # # ][ # # ]: 0 : if( !rSubControl.HasLayoutData() )
345 [ # # ]: 0 : rSubControl.FillLayoutData();
346 [ # # ][ # # ]: 0 : if( !rSubControl.HasLayoutData() || !rSubControl.mpControlData->mpLayoutData->m_aDisplayText.Len() )
[ # # ][ # # ]
347 : 0 : return;
348 : :
349 : 0 : long nCurrentIndex = mpControlData->mpLayoutData->m_aDisplayText.Len();
350 [ # # ]: 0 : mpControlData->mpLayoutData->m_aDisplayText.Append( rSubControl.mpControlData->mpLayoutData->m_aDisplayText );
351 : 0 : int nLines = rSubControl.mpControlData->mpLayoutData->m_aLineIndices.size();
352 : : int n;
353 [ # # ]: 0 : mpControlData->mpLayoutData->m_aLineIndices.push_back( nCurrentIndex );
354 [ # # ]: 0 : for( n = 1; n < nLines; n++ )
355 [ # # ][ # # ]: 0 : mpControlData->mpLayoutData->m_aLineIndices.push_back( rSubControl.mpControlData->mpLayoutData->m_aLineIndices[n] + nCurrentIndex );
356 : 0 : int nRectangles = rSubControl.mpControlData->mpLayoutData->m_aUnicodeBoundRects.size();
357 [ # # ]: 0 : Rectangle aRel = const_cast<Control&>(rSubControl).GetWindowExtentsRelative( const_cast<Control*>(this) );
358 [ # # ]: 0 : for( n = 0; n < nRectangles; n++ )
359 : : {
360 [ # # ]: 0 : Rectangle aRect = rSubControl.mpControlData->mpLayoutData->m_aUnicodeBoundRects[n];
361 [ # # ]: 0 : aRect.Move( aRel.Left(), aRel.Top() );
362 [ # # ]: 0 : mpControlData->mpLayoutData->m_aUnicodeBoundRects.push_back( aRect );
363 : : }
364 : : }
365 : :
366 : : // -----------------------------------------------------------------
367 : :
368 : 1261 : sal_Bool Control::ImplCallEventListenersAndHandler( sal_uLong nEvent, const Link& rHandler, void* pCaller )
369 : : {
370 [ + - ]: 1261 : ImplDelData aCheckDelete;
371 [ + - ]: 1261 : ImplAddDel( &aCheckDelete );
372 : :
373 [ + - ]: 1261 : ImplCallEventListeners( nEvent );
374 [ + - ]: 1261 : if ( !aCheckDelete.IsDead() )
375 : : {
376 [ + - ]: 1261 : rHandler.Call( pCaller );
377 : :
378 [ + - ]: 1261 : if ( !aCheckDelete.IsDead() )
379 : : {
380 [ + - ]: 1261 : ImplRemoveDel( &aCheckDelete );
381 : 1261 : return sal_False;
382 : : }
383 : : }
384 [ + - ]: 1261 : return sal_True;
385 : : }
386 : :
387 : : // -----------------------------------------------------------------
388 : :
389 : 0 : void Control::SetLayoutDataParent( const Control* pParent ) const
390 : : {
391 [ # # ]: 0 : if( HasLayoutData() )
392 : 0 : mpControlData->mpLayoutData->m_pParent = pParent;
393 : 0 : }
394 : :
395 : : // -----------------------------------------------------------------
396 : :
397 : 552019 : void Control::ImplClearLayoutData() const
398 : : {
399 [ - + ]: 552019 : delete mpControlData->mpLayoutData, mpControlData->mpLayoutData = NULL;
400 : 552019 : }
401 : :
402 : : // -----------------------------------------------------------------------
403 : :
404 : 0 : void Control::ImplDrawFrame( OutputDevice* pDev, Rectangle& rRect )
405 : : {
406 : : // use a deco view to draw the frame
407 : : // However, since there happens a lot of magic there, we need to fake some (style) settings
408 : : // on the device
409 [ # # ]: 0 : AllSettings aOriginalSettings( pDev->GetSettings() );
410 : :
411 [ # # ]: 0 : AllSettings aNewSettings( aOriginalSettings );
412 [ # # ]: 0 : StyleSettings aStyle( aNewSettings.GetStyleSettings() );
413 : :
414 : : // The *only known* clients of the Draw methods of the various VCL-controls are form controls:
415 : : // During print preview, and during printing, Draw is called. Thus, drawing always happens with a
416 : : // mono (colored) border
417 [ # # ]: 0 : aStyle.SetOptions( aStyle.GetOptions() | STYLE_OPTION_MONO );
418 [ # # ]: 0 : aStyle.SetMonoColor( GetSettings().GetStyleSettings().GetMonoColor() );
419 : :
420 [ # # ]: 0 : aNewSettings.SetStyleSettings( aStyle );
421 : : // #i67023# do not call data changed listeners for this fake
422 : : // since they may understandably invalidate on settings changed
423 [ # # ]: 0 : pDev->OutputDevice::SetSettings( aNewSettings );
424 : :
425 : 0 : DecorationView aDecoView( pDev );
426 [ # # ]: 0 : rRect = aDecoView.DrawFrame( rRect, FRAME_DRAW_WINDOWBORDER );
427 : :
428 [ # # ][ # # ]: 0 : pDev->OutputDevice::SetSettings( aOriginalSettings );
[ # # ][ # # ]
429 : 0 : }
430 : :
431 : : // -----------------------------------------------------------------------
432 : :
433 : 9302 : void Control::DataChanged( const DataChangedEvent& rDCEvt)
434 : : {
435 : : // we don't want to loose some style settings for controls created with the
436 : : // toolkit
437 [ + + + - : 16968 : if ( IsCreatedWithToolkit() &&
+ + ][ + + ]
438 : 3833 : (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
439 : 3833 : (rDCEvt.GetFlags() & SETTINGS_STYLE) )
440 : : {
441 [ + - ]: 3287 : AllSettings aSettings = GetSettings();
442 [ + - ]: 3287 : StyleSettings aStyleSettings = aSettings.GetStyleSettings();
443 [ + - ]: 3287 : sal_uLong nOldOptions = rDCEvt.GetOldSettings()->GetStyleSettings().GetOptions();
444 : 3287 : sal_uLong nNewOptions = aStyleSettings.GetOptions();
445 : :
446 [ + + ][ + + ]: 3287 : if ( !(nNewOptions & STYLE_OPTION_MONO) && ( nOldOptions & STYLE_OPTION_MONO ) )
447 : : {
448 : 4 : nNewOptions |= STYLE_OPTION_MONO;
449 [ + - ]: 4 : aStyleSettings.SetOptions( nNewOptions );
450 [ + - ][ + - ]: 4 : aStyleSettings.SetMonoColor( rDCEvt.GetOldSettings()->GetStyleSettings().GetMonoColor() );
451 [ + - ]: 4 : aSettings.SetStyleSettings( aStyleSettings );
452 [ + - ]: 4 : SetSettings( aSettings );
453 [ + - ][ + - ]: 3287 : }
454 : : }
455 : 9302 : }
456 : :
457 : : // -----------------------------------------------------------------
458 : :
459 : 208 : ControlLayoutData::~ControlLayoutData()
460 : : {
461 [ - + ]: 208 : if( m_pParent )
462 [ # # ]: 0 : m_pParent->ImplClearLayoutData();
463 : 208 : }
464 : :
465 : : // -----------------------------------------------------------------
466 : :
467 : 0 : Size Control::GetOptimalSize(WindowSizeType eType) const
468 : : {
469 [ # # # ]: 0 : switch (eType) {
470 : : case WINDOWSIZE_MINIMUM:
471 [ # # ]: 0 : return Size( GetTextWidth( GetText() ) + 2 * 12,
472 : 0 : GetTextHeight() + 2 * 6 );
473 : : case WINDOWSIZE_PREFERRED:
474 : 0 : return GetOptimalSize( WINDOWSIZE_MINIMUM );
475 : : case WINDOWSIZE_MAXIMUM:
476 : : default:
477 : 0 : return Size( LONG_MAX, LONG_MAX );
478 : : }
479 : : }
480 : :
481 : : // -----------------------------------------------------------------
482 : :
483 : 369 : void Control::SetReferenceDevice( OutputDevice* _referenceDevice )
484 : : {
485 [ + + ]: 369 : if ( mpControlData->mpReferenceDevice == _referenceDevice )
486 : 369 : return;
487 : :
488 : 357 : mpControlData->mpReferenceDevice = _referenceDevice;
489 : 357 : Invalidate();
490 : : }
491 : :
492 : : // -----------------------------------------------------------------
493 : :
494 : 0 : OutputDevice* Control::GetReferenceDevice() const
495 : : {
496 : 0 : return mpControlData->mpReferenceDevice;
497 : : }
498 : :
499 : : // -----------------------------------------------------------------
500 : :
501 : 0 : const Font& Control::GetCanonicalFont( const StyleSettings& _rStyle ) const
502 : : {
503 : 0 : return _rStyle.GetLabelFont();
504 : : }
505 : :
506 : : // -----------------------------------------------------------------
507 : 0 : const Color& Control::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
508 : : {
509 : 0 : return _rStyle.GetLabelTextColor();
510 : : }
511 : :
512 : : // -----------------------------------------------------------------
513 : 17381 : void Control::ImplInitSettings( const sal_Bool _bFont, const sal_Bool _bForeground )
514 : : {
515 : 17381 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
516 : :
517 [ + + ]: 17381 : if ( _bFont )
518 : : {
519 [ + - ][ + - ]: 17377 : Font aFont( GetCanonicalFont( rStyleSettings ) );
520 [ + - ][ + + ]: 17377 : if ( IsControlFont() )
521 [ + - ][ + - ]: 1670 : aFont.Merge( GetControlFont() );
[ + - ]
522 [ + - ][ + - ]: 17377 : SetZoomedPointFont( aFont );
523 : : }
524 : :
525 [ + + ][ + + ]: 17381 : if ( _bForeground || _bFont )
526 : : {
527 : 17379 : Color aColor;
528 [ + + ][ + - ]: 17379 : if ( IsControlForeground() )
529 [ + - ]: 4 : aColor = GetControlForeground();
530 : : else
531 [ + - ]: 17375 : aColor = GetCanonicalTextColor( rStyleSettings );
532 [ + - ]: 17379 : SetTextColor( aColor );
533 [ + - ]: 17379 : SetTextFillColor();
534 : : }
535 : 17381 : }
536 : :
537 : : // -----------------------------------------------------------------
538 : :
539 : 1680 : void Control::DrawControlText( OutputDevice& _rTargetDevice, Rectangle& _io_rRect, const XubString& _rStr,
540 : : sal_uInt16 _nStyle, MetricVector* _pVector, String* _pDisplayText ) const
541 : : {
542 : : #ifdef FS_DEBUG
543 : : if ( !_pVector )
544 : : {
545 : : static MetricVector aCharRects;
546 : : static String sDisplayText;
547 : : aCharRects.clear();
548 : : sDisplayText = String();
549 : : _pVector = &aCharRects;
550 : : _pDisplayText = &sDisplayText;
551 : : }
552 : : #endif
553 : :
554 [ + + ][ - + ]: 1680 : if ( !mpControlData->mpReferenceDevice || ( mpControlData->mpReferenceDevice == &_rTargetDevice ) )
555 : : {
556 : 1272 : _io_rRect = _rTargetDevice.GetTextRect( _io_rRect, _rStr, _nStyle );
557 : 1272 : _rTargetDevice.DrawText( _io_rRect, _rStr, _nStyle, _pVector, _pDisplayText );
558 : : }
559 : : else
560 : : {
561 [ + - ]: 408 : ControlTextRenderer aRenderer( *this, _rTargetDevice, *mpControlData->mpReferenceDevice );
562 [ + - ][ + - ]: 408 : _io_rRect = aRenderer.DrawText( _io_rRect, _rStr, _nStyle, _pVector, _pDisplayText );
563 : : }
564 : :
565 : : #ifdef FS_DEBUG
566 : : _rTargetDevice.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
567 : : _rTargetDevice.SetLineColor( COL_LIGHTRED );
568 : : _rTargetDevice.SetFillColor();
569 : : for ( MetricVector::const_iterator cr = _pVector->begin();
570 : : cr != _pVector->end();
571 : : ++cr
572 : : )
573 : : {
574 : : _rTargetDevice.DrawRect( *cr );
575 : : }
576 : : _rTargetDevice.Pop();
577 : : #endif
578 : 1680 : }
579 : :
580 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|