1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "richtextimplcontrol.hxx"
21 #include "textattributelistener.hxx"
22 #include "richtextengine.hxx"
23 #include <editeng/editeng.hxx>
24 #include <editeng/editview.hxx>
25 #include <editeng/eeitem.hxx>
26 #include <editeng/editstat.hxx>
27 #include <svx/svxids.hrc>
28 #include <editeng/scripttypeitem.hxx>
30 #include <editeng/editobj.hxx>
31 #include <svl/itempool.hxx>
32 #include <svl/itemset.hxx>
33 #include <tools/mapunit.hxx>
34 #include <vcl/window.hxx>
35 #include <vcl/svapp.hxx>
36 #include <vcl/settings.hxx>
38 #define EMPTY_PAPER_SIZE 0x7FFFFFFF
44 RichTextControlImpl::RichTextControlImpl( Control
* _pAntiImpl
, RichTextEngine
* _pEngine
, ITextAttributeListener
* _pTextAttrListener
, ITextSelectionListener
* _pSelectionListener
)
45 :m_pAntiImpl ( _pAntiImpl
)
46 ,m_pViewport ( nullptr )
47 ,m_pHScroll ( nullptr )
48 ,m_pVScroll ( nullptr )
49 ,m_pScrollCorner ( nullptr )
50 ,m_pEngine ( _pEngine
)
52 ,m_pTextAttrListener ( _pTextAttrListener
)
53 ,m_pSelectionListener ( _pSelectionListener
)
54 ,m_bHasEverBeenShown ( false )
56 OSL_ENSURE( m_pAntiImpl
, "RichTextControlImpl::RichTextControlImpl: invalid window!" );
57 OSL_ENSURE( m_pEngine
, "RichTextControlImpl::RichTextControlImpl: invalid edit engine! This will *definitely* crash!" );
59 m_pViewport
= VclPtr
<RichTextViewPort
>::Create( m_pAntiImpl
);
60 m_pViewport
->setAttributeInvalidationHandler( LINK( this, RichTextControlImpl
, OnInvalidateAllAttributes
) );
63 // ensure that both the window and the reference device have the same map unit
64 MapMode
aRefDeviceMapMode( m_pEngine
->GetRefDevice()->GetMapMode() );
65 m_pAntiImpl
->SetMapMode( aRefDeviceMapMode
);
66 m_pViewport
->SetMapMode( aRefDeviceMapMode
);
68 m_pView
= new EditView( m_pEngine
, m_pViewport
);
69 m_pEngine
->InsertView( m_pView
);
70 m_pViewport
->setView( *m_pView
);
72 m_pEngine
->registerEngineStatusListener( this );
75 EVControlBits nViewControlWord
= m_pView
->GetControlWord();
76 nViewControlWord
|= EVControlBits::AUTOSCROLL
;
77 m_pView
->SetControlWord( nViewControlWord
);
80 // ensure that it's initially scrolled to the upper left
81 m_pView
->SetVisArea( Rectangle( Point( ), m_pViewport
->GetOutputSize() ) );
85 m_pAntiImpl
->SetBackground( Wallpaper( m_pAntiImpl
->GetSettings().GetStyleSettings().GetFieldColor() ) );
89 RichTextControlImpl::~RichTextControlImpl( )
91 m_pEngine
->RemoveView( m_pView
);
92 m_pEngine
->revokeEngineStatusListener( this );
94 m_pViewport
.disposeAndClear();
95 m_pHScroll
.disposeAndClear();
96 m_pVScroll
.disposeAndClear();
97 m_pScrollCorner
.disposeAndClear();
101 void RichTextControlImpl::implUpdateAttribute( const AttributeHandlerPool::const_iterator
& _pHandler
)
103 if ( ( _pHandler
->first
== SID_ATTR_CHAR_WEIGHT
)
104 || ( _pHandler
->first
== SID_ATTR_CHAR_POSTURE
)
105 || ( _pHandler
->first
== SID_ATTR_CHAR_FONT
)
106 || ( _pHandler
->first
== SID_ATTR_CHAR_FONTHEIGHT
)
109 // these are attributes whose value depends on the current script type.
110 // I.e., in real, there are *three* items in the ItemSet: One for each script
111 // type (Latin, Asian, Complex). However, if we have an observer who is interested
112 // in the state of this attribute, we have to kind of *merge* the three attributes
114 // This is useful in case the observer is for instance a toolbox which contains only
115 // an, e.g., "bold" slot, and thus not interested in the particular script type of the
116 // current selection.
117 SvxScriptSetItem
aNormalizedSet( (WhichId
)_pHandler
->first
, *m_pView
->GetAttribs().GetPool() );
118 normalizeScriptDependentAttribute( aNormalizedSet
);
120 implCheckUpdateCache( _pHandler
->first
, _pHandler
->second
->getState( aNormalizedSet
.GetItemSet() ) );
123 implCheckUpdateCache( _pHandler
->first
, _pHandler
->second
->getState( m_pView
->GetAttribs() ) );
127 void RichTextControlImpl::updateAttribute( AttributeId _nAttribute
)
129 AttributeHandlerPool::const_iterator pHandler
= m_aAttributeHandlers
.find( _nAttribute
);
130 if ( pHandler
!= m_aAttributeHandlers
.end() )
131 implUpdateAttribute( pHandler
);
135 void RichTextControlImpl::updateAllAttributes( )
137 for ( AttributeHandlerPool::const_iterator pHandler
= m_aAttributeHandlers
.begin();
138 pHandler
!= m_aAttributeHandlers
.end();
142 implUpdateAttribute( pHandler
);
145 // notify changes of the selection, if necessary
146 if ( m_pSelectionListener
&& m_pView
)
148 ESelection aCurrentSelection
= m_pView
->GetSelection();
149 if ( !aCurrentSelection
.IsEqual( m_aLastKnownSelection
) )
151 m_aLastKnownSelection
= aCurrentSelection
;
152 m_pSelectionListener
->onSelectionChanged( m_aLastKnownSelection
);
158 AttributeState
RichTextControlImpl::getAttributeState( AttributeId _nAttributeId
) const
160 StateCache::const_iterator aCachedStatePos
= m_aLastKnownStates
.find( _nAttributeId
);
161 if ( aCachedStatePos
== m_aLastKnownStates
.end() )
163 OSL_FAIL( "RichTextControlImpl::getAttributeState: Don't ask for the state of an attribute which I never encountered!" );
164 return AttributeState( eIndetermined
);
166 return aCachedStatePos
->second
;
170 bool RichTextControlImpl::executeAttribute( const SfxItemSet
& _rCurrentAttribs
, SfxItemSet
& _rAttribs
, AttributeId _nAttribute
, const SfxPoolItem
* _pArgument
, SvtScriptType _nForScriptType
)
172 // let's see whether we have a handler for this attribute
173 AttributeHandlerPool::const_iterator aHandlerPos
= m_aAttributeHandlers
.find( _nAttribute
);
174 if ( aHandlerPos
!= m_aAttributeHandlers
.end() )
176 aHandlerPos
->second
->executeAttribute( _rCurrentAttribs
, _rAttribs
, _pArgument
, _nForScriptType
);
183 void RichTextControlImpl::enableAttributeNotification( AttributeId _nAttributeId
, ITextAttributeListener
* _pListener
)
185 AttributeHandlerPool::const_iterator aHandlerPos
= m_aAttributeHandlers
.find( _nAttributeId
);
186 if ( aHandlerPos
== m_aAttributeHandlers
.end() )
188 ::rtl::Reference
< AttributeHandler
> aHandler
= AttributeHandlerFactory::getHandlerFor( _nAttributeId
, *m_pEngine
->GetEmptyItemSet().GetPool() );
189 OSL_ENSURE( aHandler
.is(), "RichTextControlImpl::enableAttributeNotification: no handler available for this attribute!" );
190 if ( !aHandler
.is() )
192 SAL_WARN_IF( _nAttributeId
!= aHandler
->getAttributeId(), "forms.richtext", "RichTextControlImpl::enableAttributeNotification: suspicious handler!" );
194 aHandlerPos
= m_aAttributeHandlers
.insert( AttributeHandlerPool::value_type( _nAttributeId
, aHandler
) ).first
;
197 // remember the listener
199 m_aAttributeListeners
.insert( AttributeListenerPool::value_type( _nAttributeId
, _pListener
) );
201 // update (and broadcast) the state of this attribute
202 updateAttribute( _nAttributeId
);
206 void RichTextControlImpl::disableAttributeNotification( AttributeId _nAttributeId
)
208 // forget the handler for this attribute
209 AttributeHandlerPool::iterator aHandlerPos
= m_aAttributeHandlers
.find( _nAttributeId
);
210 if ( aHandlerPos
!= m_aAttributeHandlers
.end() )
211 m_aAttributeHandlers
.erase( aHandlerPos
);
213 // as well as the listener
214 AttributeListenerPool::iterator aListenerPos
= m_aAttributeListeners
.find( _nAttributeId
);
215 if ( aListenerPos
!= m_aAttributeListeners
.end() )
216 m_aAttributeListeners
.erase( aListenerPos
);
220 void RichTextControlImpl::normalizeScriptDependentAttribute( SvxScriptSetItem
& _rScriptSetItem
)
222 _rScriptSetItem
.GetItemSet().Put( m_pView
->GetAttribs(), false );
223 const SfxPoolItem
* pNormalizedItem
= _rScriptSetItem
.GetItemOfScript( getSelectedScriptType() );
225 WhichId nNormalizedWhichId
= _rScriptSetItem
.GetItemSet().GetPool()->GetWhich( _rScriptSetItem
.Which() );
226 if ( pNormalizedItem
)
228 SfxPoolItem
* pProperWhich
= pNormalizedItem
->Clone();
229 pProperWhich
->SetWhich( nNormalizedWhichId
);
230 _rScriptSetItem
.GetItemSet().Put( *pProperWhich
);
231 DELETEZ( pProperWhich
);
234 _rScriptSetItem
.GetItemSet().InvalidateItem( nNormalizedWhichId
);
238 void RichTextControlImpl::implCheckUpdateCache( AttributeId _nAttribute
, const AttributeState
& _rState
)
240 StateCache::iterator aCachePos
= m_aLastKnownStates
.find( _nAttribute
);
241 if ( aCachePos
== m_aLastKnownStates
.end() )
242 { // nothing known about this attribute, yet
243 m_aLastKnownStates
.insert( StateCache::value_type( _nAttribute
, _rState
) );
247 if ( aCachePos
->second
== _rState
)
252 aCachePos
->second
= _rState
;
255 // is there a dedicated listener for this particular attribute?
256 AttributeListenerPool::const_iterator aListenerPos
= m_aAttributeListeners
.find( _nAttribute
);
257 if ( aListenerPos
!= m_aAttributeListeners
.end( ) )
258 aListenerPos
->second
->onAttributeStateChanged( _nAttribute
, _rState
);
260 // call our global listener, if there is one
261 if ( m_pTextAttrListener
)
262 m_pTextAttrListener
->onAttributeStateChanged( _nAttribute
, _rState
);
266 SvtScriptType
RichTextControlImpl::getSelectedScriptType() const
268 SvtScriptType nScript
= m_pView
->GetSelectedScriptType();
269 if ( nScript
== SvtScriptType::NONE
)
270 nScript
= SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
275 void RichTextControlImpl::EditEngineStatusChanged( const EditStatus
& _rStatus
)
277 EditStatusFlags
nStatusWord( _rStatus
.GetStatusWord() );
278 if ( ( nStatusWord
& EditStatusFlags::TEXTWIDTHCHANGED
)
279 || ( nStatusWord
& EditStatusFlags::TEXTHEIGHTCHANGED
)
282 if ( ( nStatusWord
& EditStatusFlags::TEXTHEIGHTCHANGED
) && windowHasAutomaticLineBreak() )
283 m_pEngine
->SetPaperSize( Size( m_pEngine
->GetPaperSize().Width(), m_pEngine
->GetTextHeight() ) );
288 bool bHScroll
= bool( nStatusWord
& EditStatusFlags::HSCROLL
);
289 bool bVScroll
= bool( nStatusWord
& EditStatusFlags::VSCROLL
);
291 // In case of *no* automatic line breaks, we also need to check for the *range* here.
292 // Normally, we would do this only after a EditStatusFlags::TEXTWIDTHCHANGED. However, due to a bug
293 // in the EditEngine (I believe so) this is not fired when the engine does not have
294 // the AutoPaperSize bits set.
295 // So in order to be properly notified, we would need the AutoPaperSize. But, with
296 // AutoPaperSize, other things do not work anymore: Either, when we set a MaxAutoPaperSize,
297 // then the view does automatic soft line breaks at the paper end - which we definitely do
298 // want. Or, if we did not set a MaxAutoPaperSize, then the view does not automatically scroll
299 // anymore in horizontal direction.
300 // So this is some kind of lose-lose situation ... :(
301 if ( !windowHasAutomaticLineBreak() && bHScroll
)
307 if ( bHScroll
&& m_pHScroll
)
308 m_pHScroll
->SetThumbPos( m_pView
->GetVisArea().Left() );
309 if ( bVScroll
&& m_pVScroll
)
310 m_pVScroll
->SetThumbPos( m_pView
->GetVisArea().Top() );
314 IMPL_LINK_NOARG_TYPED( RichTextControlImpl
, OnInvalidateAllAttributes
, LinkParamNone
*, void )
316 updateAllAttributes();
320 IMPL_LINK_TYPED( RichTextControlImpl
, OnHScroll
, ScrollBar
*, _pScrollbar
, void )
322 m_pView
->Scroll( -_pScrollbar
->GetDelta(), 0, ScrollRangeCheck::PaperWidthTextSize
);
326 IMPL_LINK_TYPED( RichTextControlImpl
, OnVScroll
, ScrollBar
*, _pScrollbar
, void )
328 m_pView
->Scroll( 0, -_pScrollbar
->GetDelta(), ScrollRangeCheck::PaperWidthTextSize
);
332 void RichTextControlImpl::ensureScrollbars()
334 bool bNeedVScroll
= 0 != ( m_pAntiImpl
->GetStyle() & WB_VSCROLL
);
335 bool bNeedHScroll
= 0 != ( m_pAntiImpl
->GetStyle() & WB_HSCROLL
);
337 if ( ( bNeedVScroll
== hasVScrollBar() ) && ( bNeedHScroll
== hasHScrollBar( ) ) )
341 // create or delete the scrollbars, as necessary
344 m_pVScroll
.disposeAndClear();
348 m_pVScroll
= VclPtr
<ScrollBar
>::Create( m_pAntiImpl
, WB_VSCROLL
| WB_DRAG
| WB_REPEAT
);
349 m_pVScroll
->SetScrollHdl ( LINK( this, RichTextControlImpl
, OnVScroll
) );
355 m_pHScroll
.disposeAndClear();
359 m_pHScroll
= VclPtr
<ScrollBar
>::Create( m_pAntiImpl
, WB_HSCROLL
| WB_DRAG
| WB_REPEAT
);
360 m_pHScroll
->SetScrollHdl ( LINK( this, RichTextControlImpl
, OnHScroll
) );
364 if ( m_pHScroll
&& m_pVScroll
)
366 m_pScrollCorner
.disposeAndClear();
367 m_pScrollCorner
= VclPtr
<ScrollBarBox
>::Create( m_pAntiImpl
);
368 m_pScrollCorner
->Show();
372 m_pScrollCorner
.disposeAndClear();
379 void RichTextControlImpl::ensureLineBreakSetting()
381 if ( !windowHasAutomaticLineBreak() )
382 m_pEngine
->SetPaperSize( Size( EMPTY_PAPER_SIZE
, EMPTY_PAPER_SIZE
) );
388 void RichTextControlImpl::layoutWindow()
390 if ( !m_bHasEverBeenShown
)
391 // no need to do anything. Especially, no need to set the paper size on the
392 // EditEngine to anything ....
395 const StyleSettings
& rStyleSettings
= m_pAntiImpl
->GetSettings().GetStyleSettings();
397 long nScrollBarWidth
= m_pVScroll
? rStyleSettings
.GetScrollBarSize() : 0;
398 long nScrollBarHeight
= m_pHScroll
? rStyleSettings
.GetScrollBarSize() : 0;
400 if ( m_pAntiImpl
->IsZoom() )
402 nScrollBarWidth
= m_pAntiImpl
->CalcZoom( nScrollBarWidth
);
403 nScrollBarHeight
= m_pAntiImpl
->CalcZoom( nScrollBarHeight
);
406 // the overall size we can use
407 Size
aPlaygroundSizePixel( m_pAntiImpl
->GetOutputSizePixel() );
409 // the size of the viewport - note that the viewport does *not* occupy all the place
410 // which is left when subtracting the scrollbar width/height
411 Size
aViewportPlaygroundPixel( aPlaygroundSizePixel
);
412 aViewportPlaygroundPixel
.Width() = ::std::max( long( 10 ), long( aViewportPlaygroundPixel
.Width() - nScrollBarWidth
) );
413 aViewportPlaygroundPixel
.Height() = ::std::max( long( 10 ), long( aViewportPlaygroundPixel
.Height() - nScrollBarHeight
) );
414 Size
aViewportPlaygroundLogic( m_pViewport
->PixelToLogic( aViewportPlaygroundPixel
) );
416 const long nOffset
= 2;
417 Size
aViewportSizePixel( aViewportPlaygroundPixel
.Width() - 2 * nOffset
, aViewportPlaygroundPixel
.Height() - 2 * nOffset
);
418 Size
aViewportSizeLogic( m_pViewport
->PixelToLogic( aViewportSizePixel
) );
420 // position the viewport
421 m_pViewport
->SetPosSizePixel( Point( nOffset
, nOffset
), aViewportSizePixel
);
422 // position the scrollbars
424 m_pVScroll
->SetPosSizePixel( Point( aViewportPlaygroundPixel
.Width(), 0 ), Size( nScrollBarWidth
, aViewportPlaygroundPixel
.Height() ) );
426 m_pHScroll
->SetPosSizePixel( Point( 0, aViewportPlaygroundPixel
.Height() ), Size( aViewportPlaygroundPixel
.Width(), nScrollBarHeight
) );
427 if ( m_pScrollCorner
)
428 m_pScrollCorner
->SetPosSizePixel( Point( aViewportPlaygroundPixel
.Width(), aViewportPlaygroundPixel
.Height() ), Size( nScrollBarWidth
, nScrollBarHeight
) );
431 if ( windowHasAutomaticLineBreak() )
432 m_pEngine
->SetPaperSize( Size( aViewportSizeLogic
.Width(), m_pEngine
->GetTextHeight() ) );
434 // output area of the view
435 m_pView
->SetOutputArea( Rectangle( Point( ), aViewportSizeLogic
) );
436 m_pView
->SetVisArea( Rectangle( Point( ), aViewportSizeLogic
) );
440 m_pVScroll
->SetVisibleSize( aViewportPlaygroundLogic
.Height() );
442 // the default height of a text line ....
443 long nFontHeight
= m_pEngine
->GetStandardFont(0).GetFontSize().Height();
444 // ... is the scroll size for the vertical scrollbar
445 m_pVScroll
->SetLineSize( nFontHeight
);
446 // the viewport width, minus one line, is the page scroll size
447 m_pVScroll
->SetPageSize( ::std::max( nFontHeight
, aViewportPlaygroundLogic
.Height() - nFontHeight
) );
453 m_pHScroll
->SetVisibleSize( aViewportPlaygroundLogic
.Width() );
455 long nFontWidth
= m_pEngine
->GetStandardFont(0).GetFontSize().Width();
458 m_pViewport
->Push( PushFlags::FONT
);
459 m_pViewport
->SetFont( m_pEngine
->GetStandardFont(0) );
460 nFontWidth
= m_pViewport
->GetTextWidth( "x" );
463 // ... is the scroll size for the horizontal scrollbar
464 m_pHScroll
->SetLineSize( 5 * nFontWidth
);
465 // the viewport height, minus one character, is the page scroll size
466 m_pHScroll
->SetPageSize( ::std::max( nFontWidth
, aViewportPlaygroundLogic
.Width() - nFontWidth
) );
469 // update range and position of the scrollbars
474 void RichTextControlImpl::updateScrollbars()
478 long nOverallTextHeight
= m_pEngine
->GetTextHeight();
479 m_pVScroll
->SetRange( Range( 0, nOverallTextHeight
) );
480 m_pVScroll
->SetThumbPos( m_pView
->GetVisArea().Top() );
485 Size
aPaperSize( m_pEngine
->GetPaperSize() );
486 long nOverallTextWidth
= ( aPaperSize
.Width() == EMPTY_PAPER_SIZE
) ? m_pEngine
->CalcTextWidth() : aPaperSize
.Width();
487 m_pHScroll
->SetRange( Range( 0, nOverallTextWidth
) );
488 m_pHScroll
->SetThumbPos( m_pView
->GetVisArea().Left() );
493 void RichTextControlImpl::notifyInitShow()
495 if ( !m_bHasEverBeenShown
)
497 m_bHasEverBeenShown
= true;
503 void RichTextControlImpl::notifyStyleChanged()
506 ensureLineBreakSetting();
510 void RichTextControlImpl::notifyZoomChanged()
512 const Fraction
& rZoom
= m_pAntiImpl
->GetZoom();
514 MapMode
aMapMode( m_pAntiImpl
->GetMapMode() );
515 aMapMode
.SetScaleX( rZoom
);
516 aMapMode
.SetScaleY( rZoom
);
517 m_pAntiImpl
->SetMapMode( aMapMode
);
519 m_pViewport
->SetZoom( rZoom
);
520 m_pViewport
->SetMapMode( aMapMode
);
526 bool RichTextControlImpl::windowHasAutomaticLineBreak()
528 return ( m_pAntiImpl
->GetStyle() & WB_WORDBREAK
) != 0;
532 void RichTextControlImpl::SetReadOnly( bool _bReadOnly
)
534 m_pView
->SetReadOnly( _bReadOnly
);
538 bool RichTextControlImpl::IsReadOnly() const
540 return m_pView
->IsReadOnly( );
546 void lcl_inflate( Rectangle
& _rRect
, long _nInflateX
, long _nInflateY
)
548 _rRect
.Left() -= _nInflateX
;
549 _rRect
.Right() += _nInflateX
;
550 _rRect
.Top() -= _nInflateY
;
551 _rRect
.Bottom() += _nInflateY
;
555 long RichTextControlImpl::HandleCommand( const CommandEvent
& _rEvent
)
557 if ( ( _rEvent
.GetCommand() == CommandEventId::Wheel
)
558 || ( _rEvent
.GetCommand() == CommandEventId::StartAutoScroll
)
559 || ( _rEvent
.GetCommand() == CommandEventId::AutoScroll
)
562 m_pAntiImpl
->HandleScrollCommand( _rEvent
, m_pHScroll
, m_pVScroll
);
569 void RichTextControlImpl::Draw( OutputDevice
* _pDev
, const Point
& _rPos
, const Size
& _rSize
, DrawFlags
/*_nFlags*/ )
571 // need to normalize the map mode of the device - every paint operation on any device needs
572 // to use the same map mode
573 _pDev
->Push( PushFlags::MAPMODE
| PushFlags::LINECOLOR
| PushFlags::FILLCOLOR
);
575 // enforce our "normalize map mode" on the device
576 MapMode
aRefMapMode( m_pEngine
->GetRefDevice()->GetMapMode() );
577 MapMode
aOriginalMapMode( _pDev
->GetMapMode() );
578 MapMode
aNormalizedMapMode( aRefMapMode
.GetMapUnit(), aRefMapMode
.GetOrigin(), aOriginalMapMode
.GetScaleX(), aOriginalMapMode
.GetScaleY() );
579 _pDev
->SetMapMode( aNormalizedMapMode
);
581 // translate coordinates
583 Size
aSize( _rSize
);
584 if ( aOriginalMapMode
.GetMapUnit() == MAP_PIXEL
)
586 aPos
= _pDev
->PixelToLogic( _rPos
, aNormalizedMapMode
);
587 aSize
= _pDev
->PixelToLogic( _rSize
, aNormalizedMapMode
);
591 aPos
= OutputDevice::LogicToLogic( _rPos
, aOriginalMapMode
, aNormalizedMapMode
);
592 aSize
= OutputDevice::LogicToLogic( _rSize
, aOriginalMapMode
, aNormalizedMapMode
);
595 Rectangle
aPlayground( aPos
, aSize
);
596 Size
aOnePixel( _pDev
->PixelToLogic( Size( 1, 1 ) ) );
597 aPlayground
.Right() -= aOnePixel
.Width();
598 aPlayground
.Bottom() -= aOnePixel
.Height();
601 _pDev
->SetLineColor();
602 _pDev
->DrawRect( aPlayground
);
604 // do we need to draw a border?
605 bool bBorder
= ( m_pAntiImpl
->GetStyle() & WB_BORDER
);
607 _pDev
->SetLineColor( m_pAntiImpl
->GetSettings().GetStyleSettings().GetMonoColor() );
609 _pDev
->SetLineColor();
610 _pDev
->SetFillColor( m_pAntiImpl
->GetBackground().GetColor() );
611 _pDev
->DrawRect( aPlayground
);
614 // don't draw the text over the border
615 lcl_inflate( aPlayground
, -aOnePixel
.Width(), -aOnePixel
.Height() );
617 // leave a space of two pixels between the "surroundings" of the control
619 lcl_inflate( aPlayground
, -aOnePixel
.Width(), -aOnePixel
.Height() );
620 lcl_inflate( aPlayground
, -aOnePixel
.Width(), -aOnePixel
.Height() );
622 // actually draw the content
623 m_pEngine
->Draw( _pDev
, aPlayground
, Point(), true );
629 void RichTextControlImpl::SetBackgroundColor( )
631 SetBackgroundColor( Application::GetSettings().GetStyleSettings().GetFieldColor() );
635 void RichTextControlImpl::SetBackgroundColor( const Color
& _rColor
)
637 Wallpaper
aWallpaper( _rColor
);
638 m_pAntiImpl
->SetBackground( aWallpaper
);
639 m_pViewport
->SetBackground( aWallpaper
);
643 void RichTextControlImpl::SetHideInactiveSelection( bool _bHide
)
645 m_pViewport
->SetHideInactiveSelection( _bHide
);
649 bool RichTextControlImpl::GetHideInactiveSelection() const
651 return m_pViewport
->GetHideInactiveSelection( );
658 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */