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 <sal/log.hxx>
24 #include <osl/diagnose.h>
25 #include <i18nlangtag/languagetag.hxx>
26 #include <editeng/editids.hrc>
27 #include <editeng/editview.hxx>
28 #include <editeng/editstat.hxx>
29 #include <editeng/scripttypeitem.hxx>
31 #include <svl/itempool.hxx>
32 #include <svl/itemset.hxx>
33 #include <tools/mapunit.hxx>
34 #include <vcl/svapp.hxx>
35 #include <vcl/settings.hxx>
36 #include <vcl/commandevent.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
)
51 ,m_pTextAttrListener ( _pTextAttrListener
)
52 ,m_pSelectionListener ( _pSelectionListener
)
53 ,m_bHasEverBeenShown ( false )
55 OSL_ENSURE( m_pAntiImpl
, "RichTextControlImpl::RichTextControlImpl: invalid window!" );
56 OSL_ENSURE( m_pEngine
, "RichTextControlImpl::RichTextControlImpl: invalid edit engine! This will *definitely* crash!" );
58 m_pViewport
= VclPtr
<RichTextViewPort
>::Create( m_pAntiImpl
);
59 m_pViewport
->setAttributeInvalidationHandler( LINK( this, RichTextControlImpl
, OnInvalidateAllAttributes
) );
62 // ensure that both the window and the reference device have the same map unit
63 MapMode
aRefDeviceMapMode( m_pEngine
->GetRefDevice()->GetMapMode() );
64 m_pAntiImpl
->SetMapMode( aRefDeviceMapMode
);
65 m_pViewport
->SetMapMode( aRefDeviceMapMode
);
67 m_pView
.reset(new EditView( m_pEngine
, m_pViewport
));
68 m_pEngine
->InsertView( m_pView
.get() );
69 m_pViewport
->setView( *m_pView
);
71 m_pEngine
->registerEngineStatusListener( this );
74 EVControlBits nViewControlWord
= m_pView
->GetControlWord();
75 nViewControlWord
|= EVControlBits::AUTOSCROLL
;
76 m_pView
->SetControlWord( nViewControlWord
);
79 // ensure that it's initially scrolled to the upper left
80 m_pView
->SetVisArea( tools::Rectangle( Point( ), m_pViewport
->GetOutDev()->GetOutputSize() ) );
84 m_pAntiImpl
->SetBackground( Wallpaper( m_pAntiImpl
->GetSettings().GetStyleSettings().GetFieldColor() ) );
88 RichTextControlImpl::~RichTextControlImpl( )
90 m_pEngine
->RemoveView( m_pView
.get() );
91 m_pEngine
->revokeEngineStatusListener( this );
93 m_pViewport
.disposeAndClear();
94 m_pHScroll
.disposeAndClear();
95 m_pVScroll
.disposeAndClear();
96 m_pScrollCorner
.disposeAndClear();
100 void RichTextControlImpl::implUpdateAttribute( const AttributeHandlerPool::const_iterator
& _pHandler
)
102 if ( ( _pHandler
->first
== SID_ATTR_CHAR_WEIGHT
)
103 || ( _pHandler
->first
== SID_ATTR_CHAR_POSTURE
)
104 || ( _pHandler
->first
== SID_ATTR_CHAR_FONT
)
105 || ( _pHandler
->first
== SID_ATTR_CHAR_FONTHEIGHT
)
108 // these are attributes whose value depends on the current script type.
109 // I.e., in real, there are *three* items in the ItemSet: One for each script
110 // type (Latin, Asian, Complex). However, if we have an observer who is interested
111 // in the state of this attribute, we have to kind of *merge* the three attributes
113 // This is useful in case the observer is for instance a toolbox which contains only
114 // an, e.g., "bold" slot, and thus not interested in the particular script type of the
115 // current selection.
116 SvxScriptSetItem
aNormalizedSet( static_cast<WhichId
>(_pHandler
->first
), *m_pView
->GetAttribs().GetPool() );
117 normalizeScriptDependentAttribute( aNormalizedSet
);
119 implCheckUpdateCache( _pHandler
->first
, _pHandler
->second
->getState( aNormalizedSet
.GetItemSet() ) );
122 implCheckUpdateCache( _pHandler
->first
, _pHandler
->second
->getState( m_pView
->GetAttribs() ) );
126 void RichTextControlImpl::updateAttribute( AttributeId _nAttribute
)
128 AttributeHandlerPool::const_iterator pHandler
= m_aAttributeHandlers
.find( _nAttribute
);
129 if ( pHandler
!= m_aAttributeHandlers
.end() )
130 implUpdateAttribute( pHandler
);
134 void RichTextControlImpl::updateAllAttributes( )
136 for ( AttributeHandlerPool::const_iterator pHandler
= m_aAttributeHandlers
.begin();
137 pHandler
!= m_aAttributeHandlers
.end();
141 implUpdateAttribute( pHandler
);
144 // notify changes of the selection, if necessary
145 if ( m_pSelectionListener
&& m_pView
)
147 ESelection aCurrentSelection
= m_pView
->GetSelection();
148 if ( aCurrentSelection
!= m_aLastKnownSelection
)
150 m_aLastKnownSelection
= aCurrentSelection
;
151 m_pSelectionListener
->onSelectionChanged();
157 AttributeState
RichTextControlImpl::getAttributeState( AttributeId _nAttributeId
) const
159 StateCache::const_iterator aCachedStatePos
= m_aLastKnownStates
.find( _nAttributeId
);
160 if ( aCachedStatePos
== m_aLastKnownStates
.end() )
162 OSL_FAIL( "RichTextControlImpl::getAttributeState: Don't ask for the state of an attribute which I never encountered!" );
163 return AttributeState( eIndetermined
);
165 return aCachedStatePos
->second
;
169 bool RichTextControlImpl::executeAttribute( const SfxItemSet
& _rCurrentAttribs
, SfxItemSet
& _rAttribs
, AttributeId _nAttribute
, const SfxPoolItem
* _pArgument
, SvtScriptType _nForScriptType
)
171 // let's see whether we have a handler for this attribute
172 AttributeHandlerPool::const_iterator aHandlerPos
= m_aAttributeHandlers
.find( _nAttribute
);
173 if ( aHandlerPos
!= m_aAttributeHandlers
.end() )
175 aHandlerPos
->second
->executeAttribute( _rCurrentAttribs
, _rAttribs
, _pArgument
, _nForScriptType
);
182 void RichTextControlImpl::enableAttributeNotification( AttributeId _nAttributeId
, ITextAttributeListener
* _pListener
)
184 AttributeHandlerPool::const_iterator aHandlerPos
= m_aAttributeHandlers
.find( _nAttributeId
);
185 if ( aHandlerPos
== m_aAttributeHandlers
.end() )
187 ::rtl::Reference
< AttributeHandler
> aHandler
= AttributeHandlerFactory::getHandlerFor( _nAttributeId
, *m_pEngine
->GetEmptyItemSet().GetPool() );
188 OSL_ENSURE( aHandler
.is(), "RichTextControlImpl::enableAttributeNotification: no handler available for this attribute!" );
189 if ( !aHandler
.is() )
191 SAL_WARN_IF( _nAttributeId
!= aHandler
->getAttributeId(), "forms.richtext", "RichTextControlImpl::enableAttributeNotification: suspicious handler!" );
193 aHandlerPos
= m_aAttributeHandlers
.emplace( _nAttributeId
, aHandler
).first
;
196 // remember the listener
198 m_aAttributeListeners
.emplace( _nAttributeId
, _pListener
);
200 // update (and broadcast) the state of this attribute
201 updateAttribute( _nAttributeId
);
205 void RichTextControlImpl::disableAttributeNotification( AttributeId _nAttributeId
)
207 // forget the handler for this attribute
208 AttributeHandlerPool::iterator aHandlerPos
= m_aAttributeHandlers
.find( _nAttributeId
);
209 if ( aHandlerPos
!= m_aAttributeHandlers
.end() )
210 m_aAttributeHandlers
.erase( aHandlerPos
);
212 // as well as the listener
213 AttributeListenerPool::iterator aListenerPos
= m_aAttributeListeners
.find( _nAttributeId
);
214 if ( aListenerPos
!= m_aAttributeListeners
.end() )
215 m_aAttributeListeners
.erase( aListenerPos
);
219 void RichTextControlImpl::normalizeScriptDependentAttribute( SvxScriptSetItem
& _rScriptSetItem
)
221 _rScriptSetItem
.GetItemSet().Put( m_pView
->GetAttribs(), false );
222 const SfxPoolItem
* pNormalizedItem
= _rScriptSetItem
.GetItemOfScript( getSelectedScriptType() );
224 WhichId nNormalizedWhichId
= _rScriptSetItem
.GetItemSet().GetPool()->GetWhich( _rScriptSetItem
.Which() );
225 if ( pNormalizedItem
)
227 _rScriptSetItem
.GetItemSet().Put( pNormalizedItem
->CloneSetWhich(nNormalizedWhichId
) );
230 _rScriptSetItem
.GetItemSet().InvalidateItem( nNormalizedWhichId
);
234 void RichTextControlImpl::implCheckUpdateCache( AttributeId _nAttribute
, const AttributeState
& _rState
)
236 StateCache::iterator aCachePos
= m_aLastKnownStates
.find( _nAttribute
);
237 if ( aCachePos
== m_aLastKnownStates
.end() )
238 { // nothing known about this attribute, yet
239 m_aLastKnownStates
.emplace( _nAttribute
, _rState
);
243 if ( aCachePos
->second
== _rState
)
248 aCachePos
->second
= _rState
;
251 // is there a dedicated listener for this particular attribute?
252 AttributeListenerPool::const_iterator aListenerPos
= m_aAttributeListeners
.find( _nAttribute
);
253 if ( aListenerPos
!= m_aAttributeListeners
.end( ) )
254 aListenerPos
->second
->onAttributeStateChanged( _nAttribute
);
256 // call our global listener, if there is one
257 if ( m_pTextAttrListener
)
258 m_pTextAttrListener
->onAttributeStateChanged( _nAttribute
);
262 SvtScriptType
RichTextControlImpl::getSelectedScriptType() const
264 SvtScriptType nScript
= m_pView
->GetSelectedScriptType();
265 if ( nScript
== SvtScriptType::NONE
)
266 nScript
= SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
271 void RichTextControlImpl::EditEngineStatusChanged( const EditStatus
& _rStatus
)
273 EditStatusFlags
nStatusWord( _rStatus
.GetStatusWord() );
274 if ( ( nStatusWord
& EditStatusFlags::TEXTWIDTHCHANGED
)
275 || ( nStatusWord
& EditStatusFlags::TextHeightChanged
)
278 if ( ( nStatusWord
& EditStatusFlags::TextHeightChanged
) && windowHasAutomaticLineBreak() )
279 m_pEngine
->SetPaperSize( Size( m_pEngine
->GetPaperSize().Width(), m_pEngine
->GetTextHeight() ) );
284 bool bHScroll
= bool( nStatusWord
& EditStatusFlags::HSCROLL
);
285 bool bVScroll
= bool( nStatusWord
& EditStatusFlags::VSCROLL
);
287 // In case of *no* automatic line breaks, we also need to check for the *range* here.
288 // Normally, we would do this only after an EditStatusFlags::TEXTWIDTHCHANGED. However, due to a bug
289 // in the EditEngine (I believe so) this is not fired when the engine does not have
290 // the AutoPaperSize bits set.
291 // So in order to be properly notified, we would need the AutoPaperSize. But, with
292 // AutoPaperSize, other things do not work anymore: Either, when we set a MaxAutoPaperSize,
293 // then the view does automatic soft line breaks at the paper end - which we definitely do
294 // want. Or, if we did not set a MaxAutoPaperSize, then the view does not automatically scroll
295 // anymore in horizontal direction.
296 // So this is some kind of lose-lose situation ... :(
297 if ( !windowHasAutomaticLineBreak() && bHScroll
)
303 if ( bHScroll
&& m_pHScroll
)
304 m_pHScroll
->SetThumbPos( m_pView
->GetVisArea().Left() );
305 if ( bVScroll
&& m_pVScroll
)
306 m_pVScroll
->SetThumbPos( m_pView
->GetVisArea().Top() );
310 IMPL_LINK_NOARG( RichTextControlImpl
, OnInvalidateAllAttributes
, LinkParamNone
*, void )
312 updateAllAttributes();
316 IMPL_LINK( RichTextControlImpl
, OnHScroll
, ScrollBar
*, _pScrollbar
, void )
318 m_pView
->Scroll( -_pScrollbar
->GetDelta(), 0, ScrollRangeCheck::PaperWidthTextSize
);
322 IMPL_LINK( RichTextControlImpl
, OnVScroll
, ScrollBar
*, _pScrollbar
, void )
324 m_pView
->Scroll( 0, -_pScrollbar
->GetDelta(), ScrollRangeCheck::PaperWidthTextSize
);
328 void RichTextControlImpl::ensureScrollbars()
330 bool bNeedVScroll
= 0 != ( m_pAntiImpl
->GetStyle() & WB_VSCROLL
);
331 bool bNeedHScroll
= 0 != ( m_pAntiImpl
->GetStyle() & WB_HSCROLL
);
333 if ( ( bNeedVScroll
== hasVScrollBar() ) && ( bNeedHScroll
== hasHScrollBar( ) ) )
337 // create or delete the scrollbars, as necessary
340 m_pVScroll
.disposeAndClear();
344 m_pVScroll
= VclPtr
<ScrollBar
>::Create( m_pAntiImpl
, WB_VSCROLL
| WB_DRAG
| WB_REPEAT
);
345 m_pVScroll
->SetScrollHdl ( LINK( this, RichTextControlImpl
, OnVScroll
) );
351 m_pHScroll
.disposeAndClear();
355 m_pHScroll
= VclPtr
<ScrollBar
>::Create( m_pAntiImpl
, WB_HSCROLL
| WB_DRAG
| WB_REPEAT
);
356 m_pHScroll
->SetScrollHdl ( LINK( this, RichTextControlImpl
, OnHScroll
) );
360 if ( m_pHScroll
&& m_pVScroll
)
362 m_pScrollCorner
.disposeAndClear();
363 m_pScrollCorner
= VclPtr
<ScrollBarBox
>::Create( m_pAntiImpl
);
364 m_pScrollCorner
->Show();
368 m_pScrollCorner
.disposeAndClear();
375 void RichTextControlImpl::ensureLineBreakSetting()
377 if ( !windowHasAutomaticLineBreak() )
378 m_pEngine
->SetPaperSize( Size( EMPTY_PAPER_SIZE
, EMPTY_PAPER_SIZE
) );
384 void RichTextControlImpl::layoutWindow()
386 if ( !m_bHasEverBeenShown
)
387 // no need to do anything. Especially, no need to set the paper size on the
388 // EditEngine to anything...
391 const StyleSettings
& rStyleSettings
= m_pAntiImpl
->GetSettings().GetStyleSettings();
393 tools::Long nScrollBarWidth
= m_pVScroll
? rStyleSettings
.GetScrollBarSize() : 0;
394 tools::Long nScrollBarHeight
= m_pHScroll
? rStyleSettings
.GetScrollBarSize() : 0;
396 if ( m_pAntiImpl
->IsZoom() )
398 nScrollBarWidth
= m_pAntiImpl
->CalcZoom( nScrollBarWidth
);
399 nScrollBarHeight
= m_pAntiImpl
->CalcZoom( nScrollBarHeight
);
402 // the overall size we can use
403 Size
aPlaygroundSizePixel( m_pAntiImpl
->GetOutputSizePixel() );
405 // the size of the viewport - note that the viewport does *not* occupy all the place
406 // which is left when subtracting the scrollbar width/height
407 Size
aViewportPlaygroundPixel( aPlaygroundSizePixel
);
408 aViewportPlaygroundPixel
.setWidth( ::std::max( tools::Long( 10 ), tools::Long( aViewportPlaygroundPixel
.Width() - nScrollBarWidth
) ) );
409 aViewportPlaygroundPixel
.setHeight( ::std::max( tools::Long( 10 ), tools::Long( aViewportPlaygroundPixel
.Height() - nScrollBarHeight
) ) );
410 Size
aViewportPlaygroundLogic( m_pViewport
->PixelToLogic( aViewportPlaygroundPixel
) );
412 const tools::Long nOffset
= 2;
413 Size
aViewportSizePixel( aViewportPlaygroundPixel
.Width() - 2 * nOffset
, aViewportPlaygroundPixel
.Height() - 2 * nOffset
);
414 Size
aViewportSizeLogic( m_pViewport
->PixelToLogic( aViewportSizePixel
) );
416 // position the viewport
417 m_pViewport
->SetPosSizePixel( Point( nOffset
, nOffset
), aViewportSizePixel
);
418 // position the scrollbars
420 m_pVScroll
->SetPosSizePixel( Point( aViewportPlaygroundPixel
.Width(), 0 ), Size( nScrollBarWidth
, aViewportPlaygroundPixel
.Height() ) );
422 m_pHScroll
->SetPosSizePixel( Point( 0, aViewportPlaygroundPixel
.Height() ), Size( aViewportPlaygroundPixel
.Width(), nScrollBarHeight
) );
423 if ( m_pScrollCorner
)
424 m_pScrollCorner
->SetPosSizePixel( Point( aViewportPlaygroundPixel
.Width(), aViewportPlaygroundPixel
.Height() ), Size( nScrollBarWidth
, nScrollBarHeight
) );
427 if ( windowHasAutomaticLineBreak() )
428 m_pEngine
->SetPaperSize( Size( aViewportSizeLogic
.Width(), m_pEngine
->GetTextHeight() ) );
430 // output area of the view
431 m_pView
->SetOutputArea( tools::Rectangle( Point( ), aViewportSizeLogic
) );
432 m_pView
->SetVisArea( tools::Rectangle( Point( ), aViewportSizeLogic
) );
436 m_pVScroll
->SetVisibleSize( aViewportPlaygroundLogic
.Height() );
438 // the default height of a text line...
439 tools::Long nFontHeight
= m_pEngine
->GetStandardFont(0).GetFontSize().Height();
440 // ... is the scroll size for the vertical scrollbar
441 m_pVScroll
->SetLineSize( nFontHeight
);
442 // the viewport width, minus one line, is the page scroll size
443 m_pVScroll
->SetPageSize( ::std::max( nFontHeight
, aViewportPlaygroundLogic
.Height() - nFontHeight
) );
449 m_pHScroll
->SetVisibleSize( aViewportPlaygroundLogic
.Width() );
451 tools::Long nFontWidth
= m_pEngine
->GetStandardFont(0).GetFontSize().Width();
454 m_pViewport
->GetOutDev()->Push( vcl::PushFlags::FONT
);
455 m_pViewport
->SetFont( m_pEngine
->GetStandardFont(0) );
456 nFontWidth
= m_pViewport
->GetTextWidth( "x" );
457 m_pViewport
->GetOutDev()->Pop();
459 // ... is the scroll size for the horizontal scrollbar
460 m_pHScroll
->SetLineSize( 5 * nFontWidth
);
461 // the viewport height, minus one character, is the page scroll size
462 m_pHScroll
->SetPageSize( ::std::max( nFontWidth
, aViewportPlaygroundLogic
.Width() - nFontWidth
) );
465 // update range and position of the scrollbars
470 void RichTextControlImpl::updateScrollbars()
474 tools::Long nOverallTextHeight
= m_pEngine
->GetTextHeight();
475 m_pVScroll
->SetRange( Range( 0, nOverallTextHeight
) );
476 m_pVScroll
->SetThumbPos( m_pView
->GetVisArea().Top() );
481 Size
aPaperSize( m_pEngine
->GetPaperSize() );
482 tools::Long nOverallTextWidth
= ( aPaperSize
.Width() == EMPTY_PAPER_SIZE
) ? m_pEngine
->CalcTextWidth() : aPaperSize
.Width();
483 m_pHScroll
->SetRange( Range( 0, nOverallTextWidth
) );
484 m_pHScroll
->SetThumbPos( m_pView
->GetVisArea().Left() );
489 void RichTextControlImpl::notifyInitShow()
491 if ( !m_bHasEverBeenShown
)
493 m_bHasEverBeenShown
= true;
499 void RichTextControlImpl::notifyStyleChanged()
502 ensureLineBreakSetting();
506 void RichTextControlImpl::notifyZoomChanged()
508 const Fraction
& rZoom
= m_pAntiImpl
->GetZoom();
510 MapMode
aMapMode( m_pAntiImpl
->GetMapMode() );
511 aMapMode
.SetScaleX( rZoom
);
512 aMapMode
.SetScaleY( rZoom
);
513 m_pAntiImpl
->SetMapMode( aMapMode
);
515 m_pViewport
->SetZoom( rZoom
);
516 m_pViewport
->SetMapMode( aMapMode
);
522 bool RichTextControlImpl::windowHasAutomaticLineBreak()
524 return ( m_pAntiImpl
->GetStyle() & WB_WORDBREAK
) != 0;
528 void RichTextControlImpl::SetReadOnly( bool _bReadOnly
)
530 m_pView
->SetReadOnly( _bReadOnly
);
534 bool RichTextControlImpl::IsReadOnly() const
536 return m_pView
->IsReadOnly( );
542 void lcl_inflate( tools::Rectangle
& _rRect
, tools::Long _nInflateX
, tools::Long _nInflateY
)
544 _rRect
.AdjustLeft( -_nInflateX
);
545 _rRect
.AdjustRight(_nInflateX
);
546 _rRect
.AdjustTop( -_nInflateY
);
547 _rRect
.AdjustBottom(_nInflateY
);
551 bool RichTextControlImpl::HandleCommand( const CommandEvent
& _rEvent
)
553 if ( ( _rEvent
.GetCommand() == CommandEventId::Wheel
)
554 || ( _rEvent
.GetCommand() == CommandEventId::StartAutoScroll
)
555 || ( _rEvent
.GetCommand() == CommandEventId::AutoScroll
)
558 m_pAntiImpl
->HandleScrollCommand( _rEvent
, m_pHScroll
, m_pVScroll
);
565 void RichTextControlImpl::Draw( OutputDevice
* _pDev
, const Point
& _rPos
, const Size
& _rSize
)
567 // need to normalize the map mode of the device - every paint operation on any device needs
568 // to use the same map mode
569 _pDev
->Push( vcl::PushFlags::MAPMODE
| vcl::PushFlags::LINECOLOR
| vcl::PushFlags::FILLCOLOR
);
571 // enforce our "normalize map mode" on the device
572 MapMode
aRefMapMode( m_pEngine
->GetRefDevice()->GetMapMode() );
573 MapMode
aOriginalMapMode( _pDev
->GetMapMode() );
574 MapMode
aNormalizedMapMode( aRefMapMode
.GetMapUnit(), aRefMapMode
.GetOrigin(), aOriginalMapMode
.GetScaleX(), aOriginalMapMode
.GetScaleY() );
575 _pDev
->SetMapMode( aNormalizedMapMode
);
577 // translate coordinates
579 Size
aSize( _rSize
);
580 if ( aOriginalMapMode
.GetMapUnit() == MapUnit::MapPixel
)
582 aPos
= _pDev
->PixelToLogic( _rPos
, aNormalizedMapMode
);
583 aSize
= _pDev
->PixelToLogic( _rSize
, aNormalizedMapMode
);
587 aPos
= OutputDevice::LogicToLogic( _rPos
, aOriginalMapMode
, aNormalizedMapMode
);
588 aSize
= OutputDevice::LogicToLogic( _rSize
, aOriginalMapMode
, aNormalizedMapMode
);
591 tools::Rectangle
aPlayground( aPos
, aSize
);
592 Size
aOnePixel( _pDev
->PixelToLogic( Size( 1, 1 ) ) );
593 aPlayground
.AdjustRight( -(aOnePixel
.Width()) );
594 aPlayground
.AdjustBottom( -(aOnePixel
.Height()) );
597 _pDev
->SetLineColor();
598 _pDev
->DrawRect( aPlayground
);
600 // do we need to draw a border?
601 bool bBorder
= ( m_pAntiImpl
->GetStyle() & WB_BORDER
);
603 _pDev
->SetLineColor( m_pAntiImpl
->GetSettings().GetStyleSettings().GetMonoColor() );
605 _pDev
->SetLineColor();
606 _pDev
->SetFillColor( m_pAntiImpl
->GetBackground().GetColor() );
607 _pDev
->DrawRect( aPlayground
);
610 // don't draw the text over the border
611 lcl_inflate( aPlayground
, -aOnePixel
.Width(), -aOnePixel
.Height() );
613 // leave a space of two pixels between the "surroundings" of the control
615 lcl_inflate( aPlayground
, -aOnePixel
.Width(), -aOnePixel
.Height() );
616 lcl_inflate( aPlayground
, -aOnePixel
.Width(), -aOnePixel
.Height() );
618 // actually draw the content
619 m_pEngine
->Draw(*_pDev
, aPlayground
, Point(), true);
625 void RichTextControlImpl::SetBackgroundColor( )
627 SetBackgroundColor( Application::GetSettings().GetStyleSettings().GetFieldColor() );
631 void RichTextControlImpl::SetBackgroundColor( const Color
& _rColor
)
633 Wallpaper
aWallpaper( _rColor
);
634 m_pAntiImpl
->SetBackground( aWallpaper
);
635 m_pViewport
->SetBackground( aWallpaper
);
639 void RichTextControlImpl::SetHideInactiveSelection( bool _bHide
)
641 m_pViewport
->SetHideInactiveSelection( _bHide
);
645 bool RichTextControlImpl::GetHideInactiveSelection() const
647 return m_pViewport
->GetHideInactiveSelection( );
654 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */