bump product version to 4.1.6.2
[LibreOffice.git] / forms / source / richtext / richtextimplcontrol.cxx
blob71a5c7e2cdc16d503375696dfde3d1ad243863d1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
37 #include <memory>
39 #define EMPTY_PAPER_SIZE 0x7FFFFFFF
41 //........................................................................
42 namespace frm
44 //........................................................................
45 //====================================================================
46 //= RichTextControlImpl
47 //====================================================================
48 //--------------------------------------------------------------------
49 RichTextControlImpl::RichTextControlImpl( Control* _pAntiImpl, RichTextEngine* _pEngine, ITextAttributeListener* _pTextAttrListener, ITextSelectionListener* _pSelectionListener )
50 :m_pAntiImpl ( _pAntiImpl )
51 ,m_pViewport ( NULL )
52 ,m_pHScroll ( NULL )
53 ,m_pVScroll ( NULL )
54 ,m_pScrollCorner ( NULL )
55 ,m_pEngine ( _pEngine )
56 ,m_pView ( NULL )
57 ,m_pTextAttrListener ( _pTextAttrListener )
58 ,m_pSelectionListener ( _pSelectionListener )
59 ,m_bHasEverBeenShown ( false )
61 OSL_ENSURE( m_pAntiImpl, "RichTextControlImpl::RichTextControlImpl: invalid window!" );
62 OSL_ENSURE( m_pEngine, "RichTextControlImpl::RichTextControlImpl: invalid edit engine! This will *definitely* crash!" );
64 m_pViewport = new RichTextViewPort( m_pAntiImpl );
65 m_pViewport->setAttributeInvalidationHandler( LINK( this, RichTextControlImpl, OnInvalidateAllAttributes ) );
66 m_pViewport->Show();
68 // ensure that both the window and the reference device have the same map unit
69 MapMode aRefDeviceMapMode( m_pEngine->GetRefDevice()->GetMapMode() );
70 m_pAntiImpl->SetMapMode( aRefDeviceMapMode );
71 m_pViewport->SetMapMode( aRefDeviceMapMode );
73 m_pView = new EditView( m_pEngine, m_pViewport );
74 m_pEngine->InsertView( m_pView );
75 m_pViewport->setView( *m_pView );
77 m_pEngine->registerEngineStatusListener( this );
80 sal_uLong nViewControlWord = m_pView->GetControlWord();
81 nViewControlWord |= EV_CNTRL_AUTOSCROLL;
82 m_pView->SetControlWord( nViewControlWord );
85 // ensure that it's initially scrolled to the upper left
86 m_pView->SetVisArea( Rectangle( Point( ), m_pViewport->GetOutputSize() ) );
88 ensureScrollbars();
90 m_pAntiImpl->SetBackground( Wallpaper( m_pAntiImpl->GetSettings().GetStyleSettings().GetFieldColor() ) );
93 //--------------------------------------------------------------------
94 RichTextControlImpl::~RichTextControlImpl( )
96 m_pEngine->RemoveView( m_pView );
97 m_pEngine->revokeEngineStatusListener( this );
98 delete m_pView;
99 delete m_pViewport;
100 delete m_pHScroll;
101 delete m_pVScroll;
102 delete m_pScrollCorner;
105 //--------------------------------------------------------------------
106 void RichTextControlImpl::implUpdateAttribute( AttributeHandlerPool::const_iterator _pHandler )
108 if ( ( _pHandler->first == SID_ATTR_CHAR_WEIGHT )
109 || ( _pHandler->first == SID_ATTR_CHAR_POSTURE )
110 || ( _pHandler->first == SID_ATTR_CHAR_FONT )
111 || ( _pHandler->first == SID_ATTR_CHAR_FONTHEIGHT )
114 // these are attributes whose value depends on the current script type.
115 // I.e., in real, there are *three* items in the ItemSet: One for each script
116 // type (Latin, Asian, Complex). However, if we have an observer who is interested
117 // in the state of this attribute, we have to kind of *merge* the three attributes
118 // to only one.
119 // This is useful in case the observer is for instance a toolbox which contains only
120 // an, e.g., "bold" slot, and thus not interested in the particular script type of the
121 // current selection.
122 SvxScriptSetItem aNormalizedSet( (WhichId)_pHandler->first, *m_pView->GetAttribs().GetPool() );
123 normalizeScriptDependentAttribute( aNormalizedSet );
125 implCheckUpdateCache( _pHandler->first, _pHandler->second->getState( aNormalizedSet.GetItemSet() ) );
127 else
128 implCheckUpdateCache( _pHandler->first, _pHandler->second->getState( m_pView->GetAttribs() ) );
131 //--------------------------------------------------------------------
132 void RichTextControlImpl::updateAttribute( AttributeId _nAttribute )
134 AttributeHandlerPool::const_iterator pHandler = m_aAttributeHandlers.find( _nAttribute );
135 if ( pHandler != m_aAttributeHandlers.end() )
136 implUpdateAttribute( pHandler );
139 //--------------------------------------------------------------------
140 void RichTextControlImpl::updateAllAttributes( )
142 for ( AttributeHandlerPool::const_iterator pHandler = m_aAttributeHandlers.begin();
143 pHandler != m_aAttributeHandlers.end();
144 ++pHandler
147 implUpdateAttribute( pHandler );
150 // notify changes of the selection, if necessary
151 if ( m_pSelectionListener && m_pView )
153 ESelection aCurrentSelection = m_pView->GetSelection();
154 if ( !aCurrentSelection.IsEqual( m_aLastKnownSelection ) )
156 m_aLastKnownSelection = aCurrentSelection;
157 m_pSelectionListener->onSelectionChanged( m_aLastKnownSelection );
162 //--------------------------------------------------------------------
163 AttributeState RichTextControlImpl::getAttributeState( AttributeId _nAttributeId ) const
165 StateCache::const_iterator aCachedStatePos = m_aLastKnownStates.find( _nAttributeId );
166 if ( aCachedStatePos == m_aLastKnownStates.end() )
168 OSL_FAIL( "RichTextControlImpl::getAttributeState: Don't ask for the state of an attribute which I never encountered!" );
169 return AttributeState( eIndetermined );
171 return aCachedStatePos->second;
174 //--------------------------------------------------------------------
175 bool RichTextControlImpl::executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rAttribs, AttributeId _nAttribute, const SfxPoolItem* _pArgument, ScriptType _nForScriptType )
177 // let's see whether we have a handler for this attribute
178 AttributeHandlerPool::const_iterator aHandlerPos = m_aAttributeHandlers.find( _nAttribute );
179 if ( aHandlerPos != m_aAttributeHandlers.end() )
181 aHandlerPos->second->executeAttribute( _rCurrentAttribs, _rAttribs, _pArgument, _nForScriptType );
182 return true;
184 return false;
187 //--------------------------------------------------------------------
188 void RichTextControlImpl::enableAttributeNotification( AttributeId _nAttributeId, ITextAttributeListener* _pListener )
190 AttributeHandlerPool::const_iterator aHandlerPos = m_aAttributeHandlers.find( _nAttributeId );
191 if ( aHandlerPos == m_aAttributeHandlers.end() )
193 ::rtl::Reference< IAttributeHandler > aHandler = AttributeHandlerFactory::getHandlerFor( _nAttributeId, *m_pEngine->GetEmptyItemSet().GetPool() );
194 OSL_ENSURE( aHandler.is(), "RichTextControlImpl::enableAttributeNotification: no handler available for this attribute!" );
195 if ( !aHandler.is() )
196 return;
197 OSL_POSTCOND( _nAttributeId == aHandler->getAttributeId(), "RichTextControlImpl::enableAttributeNotification: suspicious handler!" );
199 aHandlerPos = m_aAttributeHandlers.insert( AttributeHandlerPool::value_type( _nAttributeId , aHandler ) ).first;
202 // remember the listener
203 if ( _pListener )
204 m_aAttributeListeners.insert( AttributeListenerPool::value_type( _nAttributeId, _pListener ) );
206 // update (and broadcast) the state of this attribute
207 updateAttribute( _nAttributeId );
210 //--------------------------------------------------------------------
211 void RichTextControlImpl::disableAttributeNotification( AttributeId _nAttributeId )
213 // forget the handler for this attribute
214 AttributeHandlerPool::iterator aHandlerPos = m_aAttributeHandlers.find( _nAttributeId );
215 if ( aHandlerPos != m_aAttributeHandlers.end() )
216 m_aAttributeHandlers.erase( aHandlerPos );
218 // as well as the listener
219 AttributeListenerPool::iterator aListenerPos = m_aAttributeListeners.find( _nAttributeId );
220 if ( aListenerPos != m_aAttributeListeners.end() )
221 m_aAttributeListeners.erase( aListenerPos );
224 //--------------------------------------------------------------------
225 void RichTextControlImpl::normalizeScriptDependentAttribute( SvxScriptSetItem& _rScriptSetItem )
227 _rScriptSetItem.GetItemSet().Put( m_pView->GetAttribs(), sal_False );
228 const SfxPoolItem* pNormalizedItem = _rScriptSetItem.GetItemOfScript( getSelectedScriptType() );
230 WhichId nNormalizedWhichId = _rScriptSetItem.GetItemSet().GetPool()->GetWhich( _rScriptSetItem.Which() );
231 if ( pNormalizedItem )
233 SfxPoolItem* pProperWhich = pNormalizedItem->Clone();
234 pProperWhich->SetWhich( nNormalizedWhichId );
235 _rScriptSetItem.GetItemSet().Put( *pProperWhich );
236 DELETEZ( pProperWhich );
238 else
239 _rScriptSetItem.GetItemSet().InvalidateItem( nNormalizedWhichId );
242 //--------------------------------------------------------------------
243 void RichTextControlImpl::implCheckUpdateCache( AttributeId _nAttribute, const AttributeState& _rState )
245 StateCache::iterator aCachePos = m_aLastKnownStates.find( _nAttribute );
246 if ( aCachePos == m_aLastKnownStates.end() )
247 { // nothing known about this attribute, yet
248 m_aLastKnownStates.insert( StateCache::value_type( _nAttribute, _rState ) );
250 else
252 if ( aCachePos->second == _rState )
254 // nothing to do
255 return;
257 aCachePos->second = _rState;
260 // is there a dedicated listener for this particular attribute?
261 AttributeListenerPool::const_iterator aListenerPos = m_aAttributeListeners.find( _nAttribute );
262 if ( aListenerPos != m_aAttributeListeners.end( ) )
263 aListenerPos->second->onAttributeStateChanged( _nAttribute, _rState );
265 // call our global listener, if there is one
266 if ( m_pTextAttrListener )
267 m_pTextAttrListener->onAttributeStateChanged( _nAttribute, _rState );
270 //--------------------------------------------------------------------
271 ScriptType RichTextControlImpl::getSelectedScriptType() const
273 ScriptType nScript = m_pView->GetSelectedScriptType();
274 if ( !nScript )
275 nScript = SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
276 return nScript;
279 //--------------------------------------------------------------------
280 void RichTextControlImpl::EditEngineStatusChanged( const EditStatus& _rStatus )
282 sal_uLong nStatusWord( _rStatus.GetStatusWord() );
283 if ( ( nStatusWord & EE_STAT_TEXTWIDTHCHANGED )
284 || ( nStatusWord & EE_STAT_TEXTHEIGHTCHANGED )
287 if ( ( nStatusWord & EE_STAT_TEXTHEIGHTCHANGED ) && windowHasAutomaticLineBreak() )
288 m_pEngine->SetPaperSize( Size( m_pEngine->GetPaperSize().Width(), m_pEngine->GetTextHeight() ) );
290 updateScrollbars();
293 bool bHScroll = 0 != ( nStatusWord & EE_STAT_HSCROLL );
294 bool bVScroll = 0 != ( nStatusWord & EE_STAT_VSCROLL );
296 // In case of *no* automatic line breaks, we also need to check for the *range* here.
297 // Normally, we would do this only after a EE_STAT_TEXTWIDTHCHANGED. However, due to a bug
298 // in the EditEngine (I believe so) this is not fired when the engine does not have
299 // the AutoPaperSize bits set.
300 // So in order to be properly notified, we would need the AutoPaperSize. But, with
301 // AutoPaperSize, other things do not work anymore: Either, when we set a MaxAutoPaperSize,
302 // then the view does automatic soft line breaks at the paper end - which we definitely do
303 // want. Or, if we did not set a MaxAutoPaperSize, then the view does not automatically scroll
304 // anymore in horizontal direction.
305 // So this is some kind of lose-lose situation ... :(
306 if ( !windowHasAutomaticLineBreak() && bHScroll )
308 updateScrollbars();
309 return;
312 if ( bHScroll && m_pHScroll )
313 m_pHScroll->SetThumbPos( m_pView->GetVisArea().Left() );
314 if ( bVScroll && m_pVScroll )
315 m_pVScroll->SetThumbPos( m_pView->GetVisArea().Top() );
318 //--------------------------------------------------------------------
319 IMPL_LINK( RichTextControlImpl, OnInvalidateAllAttributes, void*, /*_pNotInterestedIn*/ )
321 updateAllAttributes();
322 return 0L;
325 //--------------------------------------------------------------------
326 IMPL_LINK( RichTextControlImpl, OnHScroll, ScrollBar*, _pScrollbar )
328 m_pView->Scroll( -_pScrollbar->GetDelta(), 0, RGCHK_PAPERSZ1 );
329 return 0L;
332 //--------------------------------------------------------------------
333 IMPL_LINK( RichTextControlImpl, OnVScroll, ScrollBar*, _pScrollbar )
335 m_pView->Scroll( 0, -_pScrollbar->GetDelta(), RGCHK_PAPERSZ1 );
336 return 0L;
339 //--------------------------------------------------------------------
340 void RichTextControlImpl::ensureScrollbars()
342 bool bNeedVScroll = 0 != ( m_pAntiImpl->GetStyle() & WB_VSCROLL );
343 bool bNeedHScroll = 0 != ( m_pAntiImpl->GetStyle() & WB_HSCROLL );
345 if ( ( bNeedVScroll == hasVScrollBar() ) && ( bNeedHScroll == hasHScrollBar( ) ) )
346 // nothing to do
347 return;
349 // create or delete the scrollbars, as necessary
350 if ( !bNeedVScroll )
352 delete m_pVScroll;
353 m_pVScroll = NULL;
355 else
357 m_pVScroll = new ScrollBar( m_pAntiImpl, WB_VSCROLL | WB_DRAG | WB_REPEAT );
358 m_pVScroll->SetScrollHdl ( LINK( this, RichTextControlImpl, OnVScroll ) );
359 m_pVScroll->Show();
362 if ( !bNeedHScroll )
364 delete m_pHScroll;
365 m_pHScroll = NULL;
367 else
369 m_pHScroll = new ScrollBar( m_pAntiImpl, WB_HSCROLL | WB_DRAG | WB_REPEAT );
370 m_pHScroll->SetScrollHdl ( LINK( this, RichTextControlImpl, OnHScroll ) );
371 m_pHScroll->Show();
374 if ( m_pHScroll && m_pVScroll )
376 delete m_pScrollCorner;
377 m_pScrollCorner = new ScrollBarBox( m_pAntiImpl );
378 m_pScrollCorner->Show();
380 else
382 delete m_pScrollCorner;
383 m_pScrollCorner = NULL;
386 layoutWindow();
389 //--------------------------------------------------------------------
390 void RichTextControlImpl::ensureLineBreakSetting()
392 if ( !windowHasAutomaticLineBreak() )
393 m_pEngine->SetPaperSize( Size( EMPTY_PAPER_SIZE, EMPTY_PAPER_SIZE ) );
395 layoutWindow();
398 //--------------------------------------------------------------------
399 void RichTextControlImpl::layoutWindow()
401 if ( !m_bHasEverBeenShown )
402 // no need to do anything. Especially, no need to set the paper size on the
403 // EditEngine to anything ....
404 return;
406 const StyleSettings& rStyleSettings = m_pAntiImpl->GetSettings().GetStyleSettings();
408 long nScrollBarWidth = m_pVScroll ? rStyleSettings.GetScrollBarSize() : 0;
409 long nScrollBarHeight = m_pHScroll ? rStyleSettings.GetScrollBarSize() : 0;
411 if ( m_pAntiImpl->IsZoom() )
413 nScrollBarWidth = m_pAntiImpl->CalcZoom( nScrollBarWidth );
414 nScrollBarHeight = m_pAntiImpl->CalcZoom( nScrollBarHeight );
417 // the overall size we can use
418 Size aPlaygroundSizePixel( m_pAntiImpl->GetOutputSizePixel() );
420 // the size of the viewport - note that the viewport does *not* occupy all the place
421 // which is left when subtracting the scrollbar width/height
422 Size aViewportPlaygroundPixel( aPlaygroundSizePixel );
423 aViewportPlaygroundPixel.Width() = ::std::max( long( 10 ), long( aViewportPlaygroundPixel.Width() - nScrollBarWidth ) );
424 aViewportPlaygroundPixel.Height() = ::std::max( long( 10 ), long( aViewportPlaygroundPixel.Height() - nScrollBarHeight ) );
425 Size aViewportPlaygroundLogic( m_pViewport->PixelToLogic( aViewportPlaygroundPixel ) );
427 const long nOffset = 2;
428 Size aViewportSizePixel( aViewportPlaygroundPixel.Width() - 2 * nOffset, aViewportPlaygroundPixel.Height() - 2 * nOffset );
429 Size aViewportSizeLogic( m_pViewport->PixelToLogic( aViewportSizePixel ) );
431 // position the viewport
432 m_pViewport->SetPosSizePixel( Point( nOffset, nOffset ), aViewportSizePixel );
433 // position the scrollbars
434 if ( m_pVScroll )
435 m_pVScroll->SetPosSizePixel( Point( aViewportPlaygroundPixel.Width(), 0 ), Size( nScrollBarWidth, aViewportPlaygroundPixel.Height() ) );
436 if ( m_pHScroll )
437 m_pHScroll->SetPosSizePixel( Point( 0, aViewportPlaygroundPixel.Height() ), Size( aViewportPlaygroundPixel.Width(), nScrollBarHeight ) );
438 if ( m_pScrollCorner )
439 m_pScrollCorner->SetPosSizePixel( Point( aViewportPlaygroundPixel.Width(), aViewportPlaygroundPixel.Height() ), Size( nScrollBarWidth, nScrollBarHeight ) );
441 // paper size
442 if ( windowHasAutomaticLineBreak() )
443 m_pEngine->SetPaperSize( Size( aViewportSizeLogic.Width(), m_pEngine->GetTextHeight() ) );
445 // output area of the view
446 m_pView->SetOutputArea( Rectangle( Point( ), aViewportSizeLogic ) );
447 m_pView->SetVisArea( Rectangle( Point( ), aViewportSizeLogic ) );
449 if ( m_pVScroll )
451 m_pVScroll->SetVisibleSize( aViewportPlaygroundLogic.Height() );
453 // the default height of a text line ....
454 long nFontHeight = m_pEngine->GetStandardFont(0).GetSize().Height();
455 // ... is the scroll size for the vertical scrollbar
456 m_pVScroll->SetLineSize( nFontHeight );
457 // the viewport width, minus one line, is the page scroll size
458 m_pVScroll->SetPageSize( ::std::max( nFontHeight, aViewportPlaygroundLogic.Height() - nFontHeight ) );
461 // the font width
462 if ( m_pHScroll )
464 m_pHScroll->SetVisibleSize( aViewportPlaygroundLogic.Width() );
466 long nFontWidth = m_pEngine->GetStandardFont(0).GetSize().Width();
467 if ( !nFontWidth )
469 m_pViewport->Push( PUSH_FONT );
470 m_pViewport->SetFont( m_pEngine->GetStandardFont(0) );
471 nFontWidth = m_pViewport->GetTextWidth( String( "x" ) );
472 m_pViewport->Pop();
474 // ... is the scroll size for the horizontal scrollbar
475 m_pHScroll->SetLineSize( 5 * nFontWidth );
476 // the viewport height, minus one character, is the page scroll size
477 m_pHScroll->SetPageSize( ::std::max( nFontWidth, aViewportPlaygroundLogic.Width() - nFontWidth ) );
480 // update range and position of the scrollbars
481 updateScrollbars();
484 //--------------------------------------------------------------------
485 void RichTextControlImpl::updateScrollbars()
487 if ( m_pVScroll )
489 long nOverallTextHeight = m_pEngine->GetTextHeight();
490 m_pVScroll->SetRange( Range( 0, nOverallTextHeight ) );
491 m_pVScroll->SetThumbPos( m_pView->GetVisArea().Top() );
494 if ( m_pHScroll )
496 Size aPaperSize( m_pEngine->GetPaperSize() );
497 long nOverallTextWidth = ( aPaperSize.Width() == EMPTY_PAPER_SIZE ) ? m_pEngine->CalcTextWidth() : aPaperSize.Width();
498 m_pHScroll->SetRange( Range( 0, nOverallTextWidth ) );
499 m_pHScroll->SetThumbPos( m_pView->GetVisArea().Left() );
503 //--------------------------------------------------------------------
504 void RichTextControlImpl::notifyInitShow()
506 if ( !m_bHasEverBeenShown )
508 m_bHasEverBeenShown = true;
509 layoutWindow();
513 //--------------------------------------------------------------------
514 void RichTextControlImpl::notifyStyleChanged()
516 ensureScrollbars();
517 ensureLineBreakSetting();
520 //--------------------------------------------------------------------
521 void RichTextControlImpl::notifyZoomChanged()
523 const Fraction& rZoom = m_pAntiImpl->GetZoom();
525 MapMode aMapMode( m_pAntiImpl->GetMapMode() );
526 aMapMode.SetScaleX( rZoom );
527 aMapMode.SetScaleY( rZoom );
528 m_pAntiImpl->SetMapMode( aMapMode );
530 m_pViewport->SetZoom( rZoom );
531 m_pViewport->SetMapMode( aMapMode );
533 layoutWindow();
536 //--------------------------------------------------------------------
537 bool RichTextControlImpl::windowHasAutomaticLineBreak()
539 return ( m_pAntiImpl->GetStyle() & WB_WORDBREAK ) != 0;
542 //--------------------------------------------------------------------
543 void RichTextControlImpl::SetReadOnly( bool _bReadOnly )
545 m_pView->SetReadOnly( _bReadOnly );
548 //--------------------------------------------------------------------
549 bool RichTextControlImpl::IsReadOnly() const
551 return m_pView->IsReadOnly( );
554 //--------------------------------------------------------------------
555 namespace
557 static void lcl_inflate( Rectangle& _rRect, long _nInflateX, long _nInflateY )
559 _rRect.Left() -= _nInflateX;
560 _rRect.Right() += _nInflateX;
561 _rRect.Top() -= _nInflateY;
562 _rRect.Bottom() += _nInflateY;
565 //--------------------------------------------------------------------
566 long RichTextControlImpl::HandleCommand( const CommandEvent& _rEvent )
568 if ( ( _rEvent.GetCommand() == COMMAND_WHEEL )
569 || ( _rEvent.GetCommand() == COMMAND_STARTAUTOSCROLL )
570 || ( _rEvent.GetCommand() == COMMAND_AUTOSCROLL )
573 m_pAntiImpl->HandleScrollCommand( _rEvent, m_pHScroll, m_pVScroll );
574 return 1;
576 return 0;
579 //--------------------------------------------------------------------
580 void RichTextControlImpl::Draw( OutputDevice* _pDev, const Point& _rPos, const Size& _rSize, sal_uLong /*_nFlags*/ )
582 // need to normalize the map mode of the device - every paint operation on any device needs
583 // to use the same map mode
584 _pDev->Push( PUSH_MAPMODE | PUSH_LINECOLOR | PUSH_FILLCOLOR );
586 // enforce our "normalize map mode" on the device
587 MapMode aRefMapMode( m_pEngine->GetRefDevice()->GetMapMode() );
588 MapMode aOriginalMapMode( _pDev->GetMapMode() );
589 MapMode aNormalizedMapMode( aRefMapMode.GetMapUnit(), aRefMapMode.GetOrigin(), aOriginalMapMode.GetScaleX(), aOriginalMapMode.GetScaleY() );
590 _pDev->SetMapMode( aNormalizedMapMode );
592 // translate coordinates
593 Point aPos( _rPos );
594 Size aSize( _rSize );
595 if ( aOriginalMapMode.GetMapUnit() == MAP_PIXEL )
597 aPos = _pDev->PixelToLogic( _rPos, aNormalizedMapMode );
598 aSize = _pDev->PixelToLogic( _rSize, aNormalizedMapMode );
600 else
602 aPos = OutputDevice::LogicToLogic( _rPos, aOriginalMapMode, aNormalizedMapMode );
603 aSize = OutputDevice::LogicToLogic( _rSize, aOriginalMapMode, aNormalizedMapMode );
606 Rectangle aPlayground( aPos, aSize );
607 Size aOnePixel( _pDev->PixelToLogic( Size( 1, 1 ) ) );
608 aPlayground.Right() -= aOnePixel.Width();
609 aPlayground.Bottom() -= aOnePixel.Height();
611 // background
612 _pDev->SetLineColor();
613 _pDev->DrawRect( aPlayground );
615 // do we need to draw a border?
616 bool bBorder = ( m_pAntiImpl->GetStyle() & WB_BORDER );
617 if ( bBorder )
618 _pDev->SetLineColor( m_pAntiImpl->GetSettings().GetStyleSettings().GetMonoColor() );
619 else
620 _pDev->SetLineColor();
621 _pDev->SetFillColor( m_pAntiImpl->GetBackground().GetColor() );
622 _pDev->DrawRect( aPlayground );
624 if ( bBorder )
625 // don't draw the text over the border
626 lcl_inflate( aPlayground, -aOnePixel.Width(), -aOnePixel.Height() );
628 // leave a space of two pixels between the "surroundings" of the control
629 // and the content
630 lcl_inflate( aPlayground, -aOnePixel.Width(), -aOnePixel.Height() );
631 lcl_inflate( aPlayground, -aOnePixel.Width(), -aOnePixel.Height() );
633 // actually draw the content
634 m_pEngine->Draw( _pDev, aPlayground, Point(), sal_True );
636 _pDev->Pop();
639 //--------------------------------------------------------------------
640 void RichTextControlImpl::SetBackgroundColor( )
642 SetBackgroundColor( Application::GetSettings().GetStyleSettings().GetFieldColor() );
645 //--------------------------------------------------------------------
646 void RichTextControlImpl::SetBackgroundColor( const Color& _rColor )
648 Wallpaper aWallpaper( _rColor );
649 m_pAntiImpl->SetBackground( aWallpaper );
650 m_pViewport->SetBackground( aWallpaper );
653 //--------------------------------------------------------------------
654 void RichTextControlImpl::SetHideInactiveSelection( bool _bHide )
656 m_pViewport->SetHideInactiveSelection( _bHide );
659 //--------------------------------------------------------------------
660 bool RichTextControlImpl::GetHideInactiveSelection() const
662 return m_pViewport->GetHideInactiveSelection( );
665 //........................................................................
666 } // namespace frm
667 //........................................................................
669 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */