Update ooo320-m1
[ooovba.git] / forms / source / richtext / richtextimplcontrol.cxx
blob39e8b15eaa740086f76652d46388f4b64086a9ab
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: richtextimplcontrol.cxx,v $
10 * $Revision: 1.8 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_forms.hxx"
33 #include "richtextimplcontrol.hxx"
34 #include "textattributelistener.hxx"
35 #include "richtextengine.hxx"
36 #include <svx/editeng.hxx>
37 #include <svx/editview.hxx>
38 #include <svx/eeitem.hxx>
39 #include <svx/editstat.hxx>
40 #ifndef _SVX_SVXIDS_HRC
41 #include <svx/svxids.hrc>
42 #endif
43 #include <svx/scripttypeitem.hxx>
45 #include <svx/editobj.hxx>
46 #include <svtools/itempool.hxx>
47 #include <svtools/itemset.hxx>
48 #include <vcl/mapunit.hxx>
49 #include <vcl/window.hxx>
50 #include <vcl/svapp.hxx>
52 #include <memory>
54 #define EMPTY_PAPER_SIZE 0x7FFFFFFF
56 //........................................................................
57 namespace frm
59 //........................................................................
60 //====================================================================
61 //= RichTextControlImpl
62 //====================================================================
63 //--------------------------------------------------------------------
64 RichTextControlImpl::RichTextControlImpl( Control* _pAntiImpl, RichTextEngine* _pEngine, ITextAttributeListener* _pTextAttrListener, ITextSelectionListener* _pSelectionListener )
65 :m_pAntiImpl ( _pAntiImpl )
66 ,m_pViewport ( NULL )
67 ,m_pHScroll ( NULL )
68 ,m_pVScroll ( NULL )
69 ,m_pScrollCorner ( NULL )
70 ,m_pEngine ( _pEngine )
71 ,m_pView ( NULL )
72 ,m_pTextAttrListener ( _pTextAttrListener )
73 ,m_pSelectionListener ( _pSelectionListener )
74 ,m_bHasEverBeenShown ( false )
76 OSL_ENSURE( m_pAntiImpl, "RichTextControlImpl::RichTextControlImpl: invalid window!" );
77 OSL_ENSURE( m_pEngine, "RichTextControlImpl::RichTextControlImpl: invalid edit engine! This will *definately* crash!" );
79 m_pViewport = new RichTextViewPort( m_pAntiImpl );
80 m_pViewport->setAttributeInvalidationHandler( LINK( this, RichTextControlImpl, OnInvalidateAllAttributes ) );
81 m_pViewport->Show();
83 // ensure that both the window and the reference device have the same map unit
84 MapMode aRefDeviceMapMode( m_pEngine->GetRefDevice()->GetMapMode() );
85 m_pAntiImpl->SetMapMode( aRefDeviceMapMode );
86 m_pViewport->SetMapMode( aRefDeviceMapMode );
88 m_pView = new EditView( m_pEngine, m_pViewport );
89 m_pEngine->InsertView( m_pView );
90 m_pViewport->setView( *m_pView );
92 m_pEngine->registerEngineStatusListener( this );
95 ULONG nViewControlWord = m_pView->GetControlWord();
96 nViewControlWord |= EV_CNTRL_AUTOSCROLL;
97 m_pView->SetControlWord( nViewControlWord );
100 // ensure that it's initially scrolled to the upper left
101 m_pView->SetVisArea( Rectangle( Point( ), m_pViewport->GetOutputSize() ) );
103 ensureScrollbars();
105 m_pAntiImpl->SetBackground( Wallpaper( m_pAntiImpl->GetSettings().GetStyleSettings().GetFieldColor() ) );
108 //--------------------------------------------------------------------
109 RichTextControlImpl::~RichTextControlImpl( )
111 m_pEngine->RemoveView( m_pView );
112 m_pEngine->revokeEngineStatusListener( this );
113 delete m_pView;
114 delete m_pViewport;
115 delete m_pHScroll;
116 delete m_pVScroll;
117 delete m_pScrollCorner;
120 //--------------------------------------------------------------------
121 void RichTextControlImpl::implUpdateAttribute( AttributeHandlerPool::const_iterator _pHandler )
123 if ( ( _pHandler->first == SID_ATTR_CHAR_WEIGHT )
124 || ( _pHandler->first == SID_ATTR_CHAR_POSTURE )
125 || ( _pHandler->first == SID_ATTR_CHAR_FONT )
126 || ( _pHandler->first == SID_ATTR_CHAR_FONTHEIGHT )
129 // these are attributes whose value depends on the current script type.
130 // I.e., in real, there are *three* items in the ItemSet: One for each script
131 // type (Latin, Asian, Complex). However, if we have an observer who is interested
132 // in the state of this attribute, we have to kind of *merge* the three attributes
133 // to only one.
134 // This is usefull in case the observer is for instance a toolbox which contains only
135 // an, e.g., "bold" slot, and thus not interested in the particular script type of the
136 // current selection.
137 SvxScriptSetItem aNormalizedSet( (WhichId)_pHandler->first, *m_pView->GetAttribs().GetPool() );
138 normalizeScriptDependentAttribute( aNormalizedSet );
140 implCheckUpdateCache( _pHandler->first, _pHandler->second->getState( aNormalizedSet.GetItemSet() ) );
142 else
143 implCheckUpdateCache( _pHandler->first, _pHandler->second->getState( m_pView->GetAttribs() ) );
146 //--------------------------------------------------------------------
147 void RichTextControlImpl::updateAttribute( AttributeId _nAttribute )
149 AttributeHandlerPool::const_iterator pHandler = m_aAttributeHandlers.find( _nAttribute );
150 if ( pHandler != m_aAttributeHandlers.end() )
151 implUpdateAttribute( pHandler );
154 //--------------------------------------------------------------------
155 void RichTextControlImpl::updateAllAttributes( )
157 for ( AttributeHandlerPool::const_iterator pHandler = m_aAttributeHandlers.begin();
158 pHandler != m_aAttributeHandlers.end();
159 ++pHandler
162 implUpdateAttribute( pHandler );
165 // notify changes of the selection, if necessary
166 if ( m_pSelectionListener && m_pView )
168 ESelection aCurrentSelection = m_pView->GetSelection();
169 if ( !aCurrentSelection.IsEqual( m_aLastKnownSelection ) )
171 m_aLastKnownSelection = aCurrentSelection;
172 m_pSelectionListener->onSelectionChanged( m_aLastKnownSelection );
177 //--------------------------------------------------------------------
178 AttributeState RichTextControlImpl::getAttributeState( AttributeId _nAttributeId ) const
180 StateCache::const_iterator aCachedStatePos = m_aLastKnownStates.find( _nAttributeId );
181 if ( aCachedStatePos == m_aLastKnownStates.end() )
183 OSL_ENSURE( sal_False, "RichTextControlImpl::getAttributeState: Don't ask for the state of an attribute which I never encountered!" );
184 return AttributeState( eIndetermined );
186 return aCachedStatePos->second;
189 //--------------------------------------------------------------------
190 bool RichTextControlImpl::executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rAttribs, AttributeId _nAttribute, const SfxPoolItem* _pArgument, ScriptType _nForScriptType )
192 // let's see whether we have a handler for this attribute
193 AttributeHandlerPool::const_iterator aHandlerPos = m_aAttributeHandlers.find( _nAttribute );
194 if ( aHandlerPos != m_aAttributeHandlers.end() )
196 aHandlerPos->second->executeAttribute( _rCurrentAttribs, _rAttribs, _pArgument, _nForScriptType );
197 return true;
199 return false;
202 //--------------------------------------------------------------------
203 void RichTextControlImpl::enableAttributeNotification( AttributeId _nAttributeId, ITextAttributeListener* _pListener )
205 AttributeHandlerPool::const_iterator aHandlerPos = m_aAttributeHandlers.find( _nAttributeId );
206 if ( aHandlerPos == m_aAttributeHandlers.end() )
208 ::rtl::Reference< IAttributeHandler > aHandler = AttributeHandlerFactory::getHandlerFor( _nAttributeId, *m_pEngine->GetEmptyItemSet().GetPool() );
209 OSL_ENSURE( aHandler.is(), "RichTextControlImpl::enableAttributeNotification: no handler available for this attribute!" );
210 if ( !aHandler.is() )
211 return;
212 OSL_POSTCOND( _nAttributeId == aHandler->getAttributeId(), "RichTextControlImpl::enableAttributeNotification: suspicious handler!" );
214 aHandlerPos = m_aAttributeHandlers.insert( AttributeHandlerPool::value_type( _nAttributeId , aHandler ) ).first;
217 // remember the listener
218 if ( _pListener )
219 m_aAttributeListeners.insert( AttributeListenerPool::value_type( _nAttributeId, _pListener ) );
221 // update (and broadcast) the state of this attribute
222 updateAttribute( _nAttributeId );
225 //--------------------------------------------------------------------
226 void RichTextControlImpl::disableAttributeNotification( AttributeId _nAttributeId )
228 // forget the handler for this attribute
229 AttributeHandlerPool::iterator aHandlerPos = m_aAttributeHandlers.find( _nAttributeId );
230 if ( aHandlerPos != m_aAttributeHandlers.end() )
231 m_aAttributeHandlers.erase( aHandlerPos );
233 // as well as the listener
234 AttributeListenerPool::iterator aListenerPos = m_aAttributeListeners.find( _nAttributeId );
235 if ( aListenerPos != m_aAttributeListeners.end() )
236 m_aAttributeListeners.erase( aListenerPos );
239 //--------------------------------------------------------------------
240 void RichTextControlImpl::normalizeScriptDependentAttribute( SvxScriptSetItem& _rScriptSetItem )
242 _rScriptSetItem.GetItemSet().Put( m_pView->GetAttribs(), FALSE );
243 const SfxPoolItem* pNormalizedItem = _rScriptSetItem.GetItemOfScript( getSelectedScriptType() );
245 WhichId nNormalizedWhichId = _rScriptSetItem.GetItemSet().GetPool()->GetWhich( _rScriptSetItem.Which() );
246 if ( pNormalizedItem )
248 SfxPoolItem* pProperWhich = pNormalizedItem->Clone();
249 pProperWhich->SetWhich( nNormalizedWhichId );
250 _rScriptSetItem.GetItemSet().Put( *pProperWhich );
251 DELETEZ( pProperWhich );
253 else
254 _rScriptSetItem.GetItemSet().InvalidateItem( nNormalizedWhichId );
257 //--------------------------------------------------------------------
258 void RichTextControlImpl::implCheckUpdateCache( AttributeId _nAttribute, const AttributeState& _rState )
260 StateCache::iterator aCachePos = m_aLastKnownStates.find( _nAttribute );
261 if ( aCachePos == m_aLastKnownStates.end() )
262 { // nothing known about this attribute, yet
263 m_aLastKnownStates.insert( StateCache::value_type( _nAttribute, _rState ) );
265 else
267 if ( aCachePos->second == _rState )
269 // nothing to do
270 return;
272 aCachePos->second = _rState;
275 // is there a dedicated listener for this particular attribute?
276 AttributeListenerPool::const_iterator aListenerPos = m_aAttributeListeners.find( _nAttribute );
277 if ( aListenerPos != m_aAttributeListeners.end( ) )
278 aListenerPos->second->onAttributeStateChanged( _nAttribute, _rState );
280 // call our global listener, if there is one
281 if ( m_pTextAttrListener )
282 m_pTextAttrListener->onAttributeStateChanged( _nAttribute, _rState );
285 //--------------------------------------------------------------------
286 ScriptType RichTextControlImpl::getSelectedScriptType() const
288 ScriptType nScript = m_pView->GetSelectedScriptType();
289 if ( !nScript )
290 nScript = SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguage() );
291 return nScript;
294 //--------------------------------------------------------------------
295 void RichTextControlImpl::EditEngineStatusChanged( const EditStatus& _rStatus )
297 ULONG nStatusWord( _rStatus.GetStatusWord() );
298 if ( ( nStatusWord & EE_STAT_TEXTWIDTHCHANGED )
299 || ( nStatusWord & EE_STAT_TEXTHEIGHTCHANGED )
302 if ( ( nStatusWord & EE_STAT_TEXTHEIGHTCHANGED ) && windowHasAutomaticLineBreak() )
303 m_pEngine->SetPaperSize( Size( m_pEngine->GetPaperSize().Width(), m_pEngine->GetTextHeight() ) );
305 updateScrollbars();
308 bool bHScroll = 0 != ( nStatusWord & EE_STAT_HSCROLL );
309 bool bVScroll = 0 != ( nStatusWord & EE_STAT_VSCROLL );
311 // In case of *no* automatic line breaks, we also need to check for the *range* here.
312 // Normally, we would do this only after a EE_STAT_TEXTWIDTHCHANGED. However, due to a bug
313 // in the EditEngine (I believe so) this is not fired when the engine does not have
314 // the AutoPaperSize bits set.
315 // So in order to be properly notified, we would need the AutoPaperSize. But, with
316 // AutoPaperSize, other things do not work anymore: Either, when we set a MaxAutoPaperSize,
317 // then the view does automatic soft line breaks at the paper end - which we definately do
318 // want. Or, if we did not set a MaxAutoPaperSize, then the view does not automatically scroll
319 // anymore in horizontal direction.
320 // So this is some kind of lose-lose situation ... :(
321 if ( !windowHasAutomaticLineBreak() && bHScroll )
323 updateScrollbars();
324 return;
327 if ( bHScroll && m_pHScroll )
328 m_pHScroll->SetThumbPos( m_pView->GetVisArea().Left() );
329 if ( bVScroll && m_pVScroll )
330 m_pVScroll->SetThumbPos( m_pView->GetVisArea().Top() );
333 //--------------------------------------------------------------------
334 IMPL_LINK( RichTextControlImpl, OnInvalidateAllAttributes, void*, /*_pNotInterestedIn*/ )
336 updateAllAttributes();
337 return 0L;
340 //--------------------------------------------------------------------
341 IMPL_LINK( RichTextControlImpl, OnHScroll, ScrollBar*, _pScrollbar )
343 m_pView->Scroll( -_pScrollbar->GetDelta(), 0, RGCHK_PAPERSZ1 );
344 return 0L;
347 //--------------------------------------------------------------------
348 IMPL_LINK( RichTextControlImpl, OnVScroll, ScrollBar*, _pScrollbar )
350 m_pView->Scroll( 0, -_pScrollbar->GetDelta(), RGCHK_PAPERSZ1 );
351 return 0L;
354 //--------------------------------------------------------------------
355 void RichTextControlImpl::ensureScrollbars()
357 bool bNeedVScroll = 0 != ( m_pAntiImpl->GetStyle() & WB_VSCROLL );
358 bool bNeedHScroll = 0 != ( m_pAntiImpl->GetStyle() & WB_HSCROLL );
360 if ( ( bNeedVScroll == hasVScrollBar() ) && ( bNeedHScroll == hasHScrollBar( ) ) )
361 // nothing to do
362 return;
364 // create or delete the scrollbars, as necessary
365 if ( !bNeedVScroll )
367 delete m_pVScroll;
368 m_pVScroll = NULL;
370 else
372 m_pVScroll = new ScrollBar( m_pAntiImpl, WB_VSCROLL | WB_DRAG | WB_REPEAT );
373 m_pVScroll->SetScrollHdl ( LINK( this, RichTextControlImpl, OnVScroll ) );
374 m_pVScroll->Show();
377 if ( !bNeedHScroll )
379 delete m_pHScroll;
380 m_pHScroll = NULL;
382 else
384 m_pHScroll = new ScrollBar( m_pAntiImpl, WB_HSCROLL | WB_DRAG | WB_REPEAT );
385 m_pHScroll->SetScrollHdl ( LINK( this, RichTextControlImpl, OnHScroll ) );
386 m_pHScroll->Show();
389 if ( m_pHScroll && m_pVScroll )
391 delete m_pScrollCorner;
392 m_pScrollCorner = new ScrollBarBox( m_pAntiImpl );
393 m_pScrollCorner->Show();
395 else
397 delete m_pScrollCorner;
398 m_pScrollCorner = NULL;
401 layoutWindow();
404 //--------------------------------------------------------------------
405 void RichTextControlImpl::ensureLineBreakSetting()
407 if ( !windowHasAutomaticLineBreak() )
408 m_pEngine->SetPaperSize( Size( EMPTY_PAPER_SIZE, EMPTY_PAPER_SIZE ) );
410 layoutWindow();
413 //--------------------------------------------------------------------
414 void RichTextControlImpl::layoutWindow()
416 if ( !m_bHasEverBeenShown )
417 // no need to do anything. Especially, no need to set the paper size on the
418 // EditEngine to anything ....
419 return;
421 const StyleSettings& rStyleSettings = m_pAntiImpl->GetSettings().GetStyleSettings();
423 long nScrollBarWidth = m_pVScroll ? rStyleSettings.GetScrollBarSize() : 0;
424 long nScrollBarHeight = m_pHScroll ? rStyleSettings.GetScrollBarSize() : 0;
426 if ( m_pAntiImpl->IsZoom() )
428 nScrollBarWidth = m_pAntiImpl->CalcZoom( nScrollBarWidth );
429 nScrollBarHeight = m_pAntiImpl->CalcZoom( nScrollBarHeight );
432 // the overall size we can use
433 Size aPlaygroundSizePixel( m_pAntiImpl->GetOutputSizePixel() );
435 // the size of the viewport - note that the viewport does *not* occupy all the place
436 // which is left when subtracting the scrollbar width/height
437 Size aViewportPlaygroundPixel( aPlaygroundSizePixel );
438 aViewportPlaygroundPixel.Width() = ::std::max( long( 10 ), long( aViewportPlaygroundPixel.Width() - nScrollBarWidth ) );
439 aViewportPlaygroundPixel.Height() = ::std::max( long( 10 ), long( aViewportPlaygroundPixel.Height() - nScrollBarHeight ) );
440 Size aViewportPlaygroundLogic( m_pViewport->PixelToLogic( aViewportPlaygroundPixel ) );
442 const long nOffset = 2;
443 Size aViewportSizePixel( aViewportPlaygroundPixel.Width() - 2 * nOffset, aViewportPlaygroundPixel.Height() - 2 * nOffset );
444 Size aViewportSizeLogic( m_pViewport->PixelToLogic( aViewportSizePixel ) );
446 // position the viewport
447 m_pViewport->SetPosSizePixel( Point( nOffset, nOffset ), aViewportSizePixel );
448 // position the scrollbars
449 if ( m_pVScroll )
450 m_pVScroll->SetPosSizePixel( Point( aViewportPlaygroundPixel.Width(), 0 ), Size( nScrollBarWidth, aViewportPlaygroundPixel.Height() ) );
451 if ( m_pHScroll )
452 m_pHScroll->SetPosSizePixel( Point( 0, aViewportPlaygroundPixel.Height() ), Size( aViewportPlaygroundPixel.Width(), nScrollBarHeight ) );
453 if ( m_pScrollCorner )
454 m_pScrollCorner->SetPosSizePixel( Point( aViewportPlaygroundPixel.Width(), aViewportPlaygroundPixel.Height() ), Size( nScrollBarWidth, nScrollBarHeight ) );
456 // paper size
457 if ( windowHasAutomaticLineBreak() )
458 m_pEngine->SetPaperSize( Size( aViewportSizeLogic.Width(), m_pEngine->GetTextHeight() ) );
460 // output area of the view
461 m_pView->SetOutputArea( Rectangle( Point( ), aViewportSizeLogic ) );
462 m_pView->SetVisArea( Rectangle( Point( ), aViewportSizeLogic ) );
464 if ( m_pVScroll )
466 m_pVScroll->SetVisibleSize( aViewportPlaygroundLogic.Height() );
468 // the default height of a text line ....
469 long nFontHeight = m_pEngine->GetStandardFont(0).GetSize().Height();
470 // ... is the scroll size for the vertical scrollbar
471 m_pVScroll->SetLineSize( nFontHeight );
472 // the viewport width, minus one line, is the page scroll size
473 m_pVScroll->SetPageSize( ::std::max( nFontHeight, aViewportPlaygroundLogic.Height() - nFontHeight ) );
476 // the font width
477 if ( m_pHScroll )
479 m_pHScroll->SetVisibleSize( aViewportPlaygroundLogic.Width() );
481 long nFontWidth = m_pEngine->GetStandardFont(0).GetSize().Width();
482 if ( !nFontWidth )
484 m_pViewport->Push( PUSH_FONT );
485 m_pViewport->SetFont( m_pEngine->GetStandardFont(0) );
486 nFontWidth = m_pViewport->GetTextWidth( String( RTL_CONSTASCII_USTRINGPARAM( "x" ) ) );
487 m_pViewport->Pop();
489 // ... is the scroll size for the horizontal scrollbar
490 m_pHScroll->SetLineSize( 5 * nFontWidth );
491 // the viewport height, minus one character, is the page scroll size
492 m_pHScroll->SetPageSize( ::std::max( nFontWidth, aViewportPlaygroundLogic.Width() - nFontWidth ) );
495 // update range and position of the scrollbars
496 updateScrollbars();
499 //--------------------------------------------------------------------
500 void RichTextControlImpl::updateScrollbars()
502 if ( m_pVScroll )
504 long nOverallTextHeight = m_pEngine->GetTextHeight();
505 m_pVScroll->SetRange( Range( 0, nOverallTextHeight ) );
506 m_pVScroll->SetThumbPos( m_pView->GetVisArea().Top() );
509 if ( m_pHScroll )
511 Size aPaperSize( m_pEngine->GetPaperSize() );
512 long nOverallTextWidth = ( aPaperSize.Width() == EMPTY_PAPER_SIZE ) ? m_pEngine->CalcTextWidth() : aPaperSize.Width();
513 m_pHScroll->SetRange( Range( 0, nOverallTextWidth ) );
514 m_pHScroll->SetThumbPos( m_pView->GetVisArea().Left() );
518 //--------------------------------------------------------------------
519 void RichTextControlImpl::notifyInitShow()
521 if ( !m_bHasEverBeenShown )
523 m_bHasEverBeenShown = true;
524 layoutWindow();
528 //--------------------------------------------------------------------
529 void RichTextControlImpl::notifyStyleChanged()
531 ensureScrollbars();
532 ensureLineBreakSetting();
535 //--------------------------------------------------------------------
536 void RichTextControlImpl::notifyZoomChanged()
538 const Fraction& rZoom = m_pAntiImpl->GetZoom();
540 MapMode aMapMode( m_pAntiImpl->GetMapMode() );
541 aMapMode.SetScaleX( rZoom );
542 aMapMode.SetScaleY( rZoom );
543 m_pAntiImpl->SetMapMode( aMapMode );
545 m_pViewport->SetZoom( rZoom );
546 m_pViewport->SetMapMode( aMapMode );
548 layoutWindow();
551 //--------------------------------------------------------------------
552 bool RichTextControlImpl::windowHasAutomaticLineBreak()
554 return ( m_pAntiImpl->GetStyle() & WB_WORDBREAK ) != 0;
557 //--------------------------------------------------------------------
558 void RichTextControlImpl::SetReadOnly( bool _bReadOnly )
560 m_pView->SetReadOnly( _bReadOnly );
563 //--------------------------------------------------------------------
564 bool RichTextControlImpl::IsReadOnly() const
566 return m_pView->IsReadOnly( );
569 //--------------------------------------------------------------------
570 namespace
572 static void lcl_inflate( Rectangle& _rRect, long _nInflateX, long _nInflateY )
574 _rRect.Left() -= _nInflateX;
575 _rRect.Right() += _nInflateX;
576 _rRect.Top() -= _nInflateY;
577 _rRect.Bottom() += _nInflateY;
580 //--------------------------------------------------------------------
581 long RichTextControlImpl::HandleCommand( const CommandEvent& _rEvent )
583 if ( ( _rEvent.GetCommand() == COMMAND_WHEEL )
584 || ( _rEvent.GetCommand() == COMMAND_STARTAUTOSCROLL )
585 || ( _rEvent.GetCommand() == COMMAND_AUTOSCROLL )
588 m_pAntiImpl->HandleScrollCommand( _rEvent, m_pHScroll, m_pVScroll );
589 return 1;
591 return 0;
594 //--------------------------------------------------------------------
595 void RichTextControlImpl::Draw( OutputDevice* _pDev, const Point& _rPos, const Size& _rSize, ULONG /*_nFlags*/ )
597 // need to normalize the map mode of the device - every paint operation on any device needs
598 // to use the same map mode
599 _pDev->Push( PUSH_MAPMODE | PUSH_LINECOLOR | PUSH_FILLCOLOR );
601 // enforce our "normalize map mode" on the device
602 MapMode aRefMapMode( m_pEngine->GetRefDevice()->GetMapMode() );
603 MapMode aOriginalMapMode( _pDev->GetMapMode() );
604 MapMode aNormalizedMapMode( aRefMapMode.GetMapUnit(), aRefMapMode.GetOrigin(), aOriginalMapMode.GetScaleX(), aOriginalMapMode.GetScaleY() );
605 _pDev->SetMapMode( aNormalizedMapMode );
607 // translate coordinates
608 Point aPos( OutputDevice::LogicToLogic( _rPos, aOriginalMapMode, aNormalizedMapMode ) );
609 Size aSize( OutputDevice::LogicToLogic( _rSize, aOriginalMapMode, aNormalizedMapMode ) );
611 Rectangle aPlayground( aPos, aSize );
612 Size aOnePixel( _pDev->PixelToLogic( Size( 1, 1 ) ) );
614 // background
615 _pDev->SetLineColor();
616 _pDev->DrawRect( Rectangle( aPlayground.TopLeft(), m_pEngine->GetPaperSize()) );
618 // possibly with border
619 bool bBorder = ( m_pAntiImpl->GetStyle() & WB_BORDER );
620 if ( bBorder )
621 // let's draw a border
622 _pDev->SetLineColor( COL_BLACK );
623 else
624 _pDev->SetLineColor();
625 _pDev->SetFillColor( m_pAntiImpl->GetBackground().GetColor() );
626 _pDev->DrawRect( aPlayground );
628 if ( bBorder )
629 // don't draw the text over the border
630 lcl_inflate( aPlayground, -aOnePixel.Width(), -aOnePixel.Height() );
632 // leave a space of one pixel between the "surroundings" of the control
633 // and the content
634 lcl_inflate( aPlayground, -aOnePixel.Width(), -aOnePixel.Height() );
636 m_pEngine->Draw( _pDev, aPlayground, Point(), TRUE );
638 _pDev->Pop();
641 //--------------------------------------------------------------------
642 void RichTextControlImpl::SetBackgroundColor( )
644 SetBackgroundColor( Application::GetSettings().GetStyleSettings().GetFieldColor() );
647 //--------------------------------------------------------------------
648 void RichTextControlImpl::SetBackgroundColor( const Color& _rColor )
650 Wallpaper aWallpaper( _rColor );
651 m_pAntiImpl->SetBackground( aWallpaper );
652 m_pViewport->SetBackground( aWallpaper );
655 //--------------------------------------------------------------------
656 void RichTextControlImpl::SetHideInactiveSelection( bool _bHide )
658 m_pViewport->SetHideInactiveSelection( _bHide );
661 //--------------------------------------------------------------------
662 bool RichTextControlImpl::GetHideInactiveSelection() const
664 return m_pViewport->GetHideInactiveSelection( );
667 //........................................................................
668 } // namespace frm
669 //........................................................................