1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_forms.hxx"
26*b1cdbd2cSJim Jagielski #include "richtextimplcontrol.hxx"
27*b1cdbd2cSJim Jagielski #include "textattributelistener.hxx"
28*b1cdbd2cSJim Jagielski #include "richtextengine.hxx"
29*b1cdbd2cSJim Jagielski #include <editeng/editeng.hxx>
30*b1cdbd2cSJim Jagielski #include <editeng/editview.hxx>
31*b1cdbd2cSJim Jagielski #include <editeng/eeitem.hxx>
32*b1cdbd2cSJim Jagielski #include <editeng/editstat.hxx>
33*b1cdbd2cSJim Jagielski #ifndef _SVX_SVXIDS_HRC
34*b1cdbd2cSJim Jagielski #include <svx/svxids.hrc>
35*b1cdbd2cSJim Jagielski #endif
36*b1cdbd2cSJim Jagielski #include <editeng/scripttypeitem.hxx>
37*b1cdbd2cSJim Jagielski 
38*b1cdbd2cSJim Jagielski #include <editeng/editobj.hxx>
39*b1cdbd2cSJim Jagielski #include <svl/itempool.hxx>
40*b1cdbd2cSJim Jagielski #include <svl/itemset.hxx>
41*b1cdbd2cSJim Jagielski #include <tools/mapunit.hxx>
42*b1cdbd2cSJim Jagielski #include <vcl/window.hxx>
43*b1cdbd2cSJim Jagielski #include <vcl/svapp.hxx>
44*b1cdbd2cSJim Jagielski 
45*b1cdbd2cSJim Jagielski #include <memory>
46*b1cdbd2cSJim Jagielski 
47*b1cdbd2cSJim Jagielski #define EMPTY_PAPER_SIZE    0x7FFFFFFF
48*b1cdbd2cSJim Jagielski 
49*b1cdbd2cSJim Jagielski //........................................................................
50*b1cdbd2cSJim Jagielski namespace frm
51*b1cdbd2cSJim Jagielski {
52*b1cdbd2cSJim Jagielski //........................................................................
53*b1cdbd2cSJim Jagielski     //====================================================================
54*b1cdbd2cSJim Jagielski     //= RichTextControlImpl
55*b1cdbd2cSJim Jagielski     //====================================================================
56*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
RichTextControlImpl(Control * _pAntiImpl,RichTextEngine * _pEngine,ITextAttributeListener * _pTextAttrListener,ITextSelectionListener * _pSelectionListener)57*b1cdbd2cSJim Jagielski     RichTextControlImpl::RichTextControlImpl( Control* _pAntiImpl, RichTextEngine* _pEngine, ITextAttributeListener* _pTextAttrListener, ITextSelectionListener* _pSelectionListener )
58*b1cdbd2cSJim Jagielski         :m_pAntiImpl            ( _pAntiImpl          )
59*b1cdbd2cSJim Jagielski         ,m_pViewport            ( NULL                )
60*b1cdbd2cSJim Jagielski         ,m_pHScroll             ( NULL                )
61*b1cdbd2cSJim Jagielski         ,m_pVScroll             ( NULL                )
62*b1cdbd2cSJim Jagielski         ,m_pScrollCorner        ( NULL                )
63*b1cdbd2cSJim Jagielski         ,m_pEngine              ( _pEngine            )
64*b1cdbd2cSJim Jagielski         ,m_pView                ( NULL                )
65*b1cdbd2cSJim Jagielski         ,m_pTextAttrListener    ( _pTextAttrListener  )
66*b1cdbd2cSJim Jagielski         ,m_pSelectionListener   ( _pSelectionListener )
67*b1cdbd2cSJim Jagielski         ,m_bHasEverBeenShown    ( false               )
68*b1cdbd2cSJim Jagielski     {
69*b1cdbd2cSJim Jagielski         OSL_ENSURE( m_pAntiImpl, "RichTextControlImpl::RichTextControlImpl: invalid window!" );
70*b1cdbd2cSJim Jagielski         OSL_ENSURE( m_pEngine,   "RichTextControlImpl::RichTextControlImpl: invalid edit engine! This will *definately* crash!" );
71*b1cdbd2cSJim Jagielski 
72*b1cdbd2cSJim Jagielski         m_pViewport = new RichTextViewPort( m_pAntiImpl );
73*b1cdbd2cSJim Jagielski         m_pViewport->setAttributeInvalidationHandler( LINK( this, RichTextControlImpl, OnInvalidateAllAttributes ) );
74*b1cdbd2cSJim Jagielski         m_pViewport->Show();
75*b1cdbd2cSJim Jagielski 
76*b1cdbd2cSJim Jagielski         // ensure that both the window and the reference device have the same map unit
77*b1cdbd2cSJim Jagielski         MapMode aRefDeviceMapMode( m_pEngine->GetRefDevice()->GetMapMode() );
78*b1cdbd2cSJim Jagielski         m_pAntiImpl->SetMapMode( aRefDeviceMapMode );
79*b1cdbd2cSJim Jagielski         m_pViewport->SetMapMode( aRefDeviceMapMode );
80*b1cdbd2cSJim Jagielski 
81*b1cdbd2cSJim Jagielski         m_pView = new EditView( m_pEngine, m_pViewport );
82*b1cdbd2cSJim Jagielski         m_pEngine->InsertView( m_pView );
83*b1cdbd2cSJim Jagielski         m_pViewport->setView( *m_pView );
84*b1cdbd2cSJim Jagielski 
85*b1cdbd2cSJim Jagielski         m_pEngine->registerEngineStatusListener( this );
86*b1cdbd2cSJim Jagielski 
87*b1cdbd2cSJim Jagielski         {
88*b1cdbd2cSJim Jagielski             sal_uLong nViewControlWord = m_pView->GetControlWord();
89*b1cdbd2cSJim Jagielski             nViewControlWord |= EV_CNTRL_AUTOSCROLL;
90*b1cdbd2cSJim Jagielski             m_pView->SetControlWord( nViewControlWord );
91*b1cdbd2cSJim Jagielski         }
92*b1cdbd2cSJim Jagielski 
93*b1cdbd2cSJim Jagielski         // ensure that it's initially scrolled to the upper left
94*b1cdbd2cSJim Jagielski         m_pView->SetVisArea( Rectangle( Point( ), m_pViewport->GetOutputSize() ) );
95*b1cdbd2cSJim Jagielski 
96*b1cdbd2cSJim Jagielski         ensureScrollbars();
97*b1cdbd2cSJim Jagielski 
98*b1cdbd2cSJim Jagielski         m_pAntiImpl->SetBackground( Wallpaper( m_pAntiImpl->GetSettings().GetStyleSettings().GetFieldColor() ) );
99*b1cdbd2cSJim Jagielski     }
100*b1cdbd2cSJim Jagielski 
101*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
~RichTextControlImpl()102*b1cdbd2cSJim Jagielski     RichTextControlImpl::~RichTextControlImpl( )
103*b1cdbd2cSJim Jagielski     {
104*b1cdbd2cSJim Jagielski         m_pEngine->RemoveView( m_pView );
105*b1cdbd2cSJim Jagielski         m_pEngine->revokeEngineStatusListener( this );
106*b1cdbd2cSJim Jagielski         delete m_pView;
107*b1cdbd2cSJim Jagielski         delete m_pViewport;
108*b1cdbd2cSJim Jagielski         delete m_pHScroll;
109*b1cdbd2cSJim Jagielski         delete m_pVScroll;
110*b1cdbd2cSJim Jagielski         delete m_pScrollCorner;
111*b1cdbd2cSJim Jagielski     }
112*b1cdbd2cSJim Jagielski 
113*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
implUpdateAttribute(AttributeHandlerPool::const_iterator _pHandler)114*b1cdbd2cSJim Jagielski     void RichTextControlImpl::implUpdateAttribute( AttributeHandlerPool::const_iterator _pHandler )
115*b1cdbd2cSJim Jagielski     {
116*b1cdbd2cSJim Jagielski         if  (  ( _pHandler->first == SID_ATTR_CHAR_WEIGHT )
117*b1cdbd2cSJim Jagielski             || ( _pHandler->first == SID_ATTR_CHAR_POSTURE )
118*b1cdbd2cSJim Jagielski             || ( _pHandler->first == SID_ATTR_CHAR_FONT )
119*b1cdbd2cSJim Jagielski             || ( _pHandler->first == SID_ATTR_CHAR_FONTHEIGHT )
120*b1cdbd2cSJim Jagielski             )
121*b1cdbd2cSJim Jagielski         {
122*b1cdbd2cSJim Jagielski             // these are attributes whose value depends on the current script type.
123*b1cdbd2cSJim Jagielski             // I.e., in real, there are *three* items in the ItemSet: One for each script
124*b1cdbd2cSJim Jagielski             // type (Latin, Asian, Complex). However, if we have an observer who is interested
125*b1cdbd2cSJim Jagielski             // in the state of this attribute, we have to kind of *merge* the three attributes
126*b1cdbd2cSJim Jagielski             // to only one.
127*b1cdbd2cSJim Jagielski             // This is usefull in case the observer is for instance a toolbox which contains only
128*b1cdbd2cSJim Jagielski             // an, e.g., "bold" slot, and thus not interested in the particular script type of the
129*b1cdbd2cSJim Jagielski             // current selection.
130*b1cdbd2cSJim Jagielski             SvxScriptSetItem aNormalizedSet( (WhichId)_pHandler->first, *m_pView->GetAttribs().GetPool() );
131*b1cdbd2cSJim Jagielski             normalizeScriptDependentAttribute( aNormalizedSet );
132*b1cdbd2cSJim Jagielski 
133*b1cdbd2cSJim Jagielski             implCheckUpdateCache( _pHandler->first, _pHandler->second->getState( aNormalizedSet.GetItemSet() ) );
134*b1cdbd2cSJim Jagielski         }
135*b1cdbd2cSJim Jagielski         else
136*b1cdbd2cSJim Jagielski             implCheckUpdateCache( _pHandler->first, _pHandler->second->getState( m_pView->GetAttribs() ) );
137*b1cdbd2cSJim Jagielski     }
138*b1cdbd2cSJim Jagielski 
139*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
updateAttribute(AttributeId _nAttribute)140*b1cdbd2cSJim Jagielski     void RichTextControlImpl::updateAttribute( AttributeId _nAttribute )
141*b1cdbd2cSJim Jagielski     {
142*b1cdbd2cSJim Jagielski         AttributeHandlerPool::const_iterator pHandler = m_aAttributeHandlers.find( _nAttribute );
143*b1cdbd2cSJim Jagielski         if ( pHandler != m_aAttributeHandlers.end() )
144*b1cdbd2cSJim Jagielski             implUpdateAttribute( pHandler );
145*b1cdbd2cSJim Jagielski     }
146*b1cdbd2cSJim Jagielski 
147*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
updateAllAttributes()148*b1cdbd2cSJim Jagielski     void RichTextControlImpl::updateAllAttributes( )
149*b1cdbd2cSJim Jagielski     {
150*b1cdbd2cSJim Jagielski         for (   AttributeHandlerPool::const_iterator pHandler = m_aAttributeHandlers.begin();
151*b1cdbd2cSJim Jagielski                 pHandler != m_aAttributeHandlers.end();
152*b1cdbd2cSJim Jagielski                 ++pHandler
153*b1cdbd2cSJim Jagielski             )
154*b1cdbd2cSJim Jagielski         {
155*b1cdbd2cSJim Jagielski             implUpdateAttribute( pHandler );
156*b1cdbd2cSJim Jagielski         }
157*b1cdbd2cSJim Jagielski 
158*b1cdbd2cSJim Jagielski         // notify changes of the selection, if necessary
159*b1cdbd2cSJim Jagielski         if ( m_pSelectionListener && m_pView )
160*b1cdbd2cSJim Jagielski         {
161*b1cdbd2cSJim Jagielski             ESelection aCurrentSelection = m_pView->GetSelection();
162*b1cdbd2cSJim Jagielski             if ( !aCurrentSelection.IsEqual( m_aLastKnownSelection ) )
163*b1cdbd2cSJim Jagielski             {
164*b1cdbd2cSJim Jagielski                 m_aLastKnownSelection = aCurrentSelection;
165*b1cdbd2cSJim Jagielski                 m_pSelectionListener->onSelectionChanged( m_aLastKnownSelection );
166*b1cdbd2cSJim Jagielski             }
167*b1cdbd2cSJim Jagielski         }
168*b1cdbd2cSJim Jagielski     }
169*b1cdbd2cSJim Jagielski 
170*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
getAttributeState(AttributeId _nAttributeId) const171*b1cdbd2cSJim Jagielski     AttributeState RichTextControlImpl::getAttributeState( AttributeId _nAttributeId ) const
172*b1cdbd2cSJim Jagielski     {
173*b1cdbd2cSJim Jagielski         StateCache::const_iterator aCachedStatePos = m_aLastKnownStates.find( _nAttributeId );
174*b1cdbd2cSJim Jagielski         if ( aCachedStatePos == m_aLastKnownStates.end() )
175*b1cdbd2cSJim Jagielski         {
176*b1cdbd2cSJim Jagielski             OSL_ENSURE( sal_False, "RichTextControlImpl::getAttributeState: Don't ask for the state of an attribute which I never encountered!" );
177*b1cdbd2cSJim Jagielski             return AttributeState( eIndetermined );
178*b1cdbd2cSJim Jagielski         }
179*b1cdbd2cSJim Jagielski         return aCachedStatePos->second;
180*b1cdbd2cSJim Jagielski     }
181*b1cdbd2cSJim Jagielski 
182*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
executeAttribute(const SfxItemSet & _rCurrentAttribs,SfxItemSet & _rAttribs,AttributeId _nAttribute,const SfxPoolItem * _pArgument,ScriptType _nForScriptType)183*b1cdbd2cSJim Jagielski     bool RichTextControlImpl::executeAttribute( const SfxItemSet& _rCurrentAttribs, SfxItemSet& _rAttribs, AttributeId _nAttribute, const SfxPoolItem* _pArgument, ScriptType _nForScriptType )
184*b1cdbd2cSJim Jagielski     {
185*b1cdbd2cSJim Jagielski         // let's see whether we have a handler for this attribute
186*b1cdbd2cSJim Jagielski         AttributeHandlerPool::const_iterator aHandlerPos = m_aAttributeHandlers.find( _nAttribute );
187*b1cdbd2cSJim Jagielski         if ( aHandlerPos != m_aAttributeHandlers.end() )
188*b1cdbd2cSJim Jagielski         {
189*b1cdbd2cSJim Jagielski             aHandlerPos->second->executeAttribute( _rCurrentAttribs, _rAttribs, _pArgument, _nForScriptType );
190*b1cdbd2cSJim Jagielski             return true;
191*b1cdbd2cSJim Jagielski         }
192*b1cdbd2cSJim Jagielski         return false;
193*b1cdbd2cSJim Jagielski     }
194*b1cdbd2cSJim Jagielski 
195*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
enableAttributeNotification(AttributeId _nAttributeId,ITextAttributeListener * _pListener)196*b1cdbd2cSJim Jagielski     void RichTextControlImpl::enableAttributeNotification( AttributeId _nAttributeId, ITextAttributeListener* _pListener )
197*b1cdbd2cSJim Jagielski     {
198*b1cdbd2cSJim Jagielski         AttributeHandlerPool::const_iterator aHandlerPos = m_aAttributeHandlers.find( _nAttributeId  );
199*b1cdbd2cSJim Jagielski         if ( aHandlerPos == m_aAttributeHandlers.end() )
200*b1cdbd2cSJim Jagielski         {
201*b1cdbd2cSJim Jagielski             ::rtl::Reference< IAttributeHandler > aHandler = AttributeHandlerFactory::getHandlerFor( _nAttributeId, *m_pEngine->GetEmptyItemSet().GetPool() );
202*b1cdbd2cSJim Jagielski             OSL_ENSURE( aHandler.is(), "RichTextControlImpl::enableAttributeNotification: no handler available for this attribute!" );
203*b1cdbd2cSJim Jagielski             if ( !aHandler.is() )
204*b1cdbd2cSJim Jagielski                 return;
205*b1cdbd2cSJim Jagielski             OSL_POSTCOND( _nAttributeId == aHandler->getAttributeId(), "RichTextControlImpl::enableAttributeNotification: suspicious handler!" );
206*b1cdbd2cSJim Jagielski 
207*b1cdbd2cSJim Jagielski             aHandlerPos = m_aAttributeHandlers.insert( AttributeHandlerPool::value_type( _nAttributeId , aHandler ) ).first;
208*b1cdbd2cSJim Jagielski         }
209*b1cdbd2cSJim Jagielski 
210*b1cdbd2cSJim Jagielski         // remember the listener
211*b1cdbd2cSJim Jagielski         if ( _pListener )
212*b1cdbd2cSJim Jagielski             m_aAttributeListeners.insert( AttributeListenerPool::value_type( _nAttributeId, _pListener ) );
213*b1cdbd2cSJim Jagielski 
214*b1cdbd2cSJim Jagielski         // update (and broadcast) the state of this attribute
215*b1cdbd2cSJim Jagielski         updateAttribute( _nAttributeId );
216*b1cdbd2cSJim Jagielski     }
217*b1cdbd2cSJim Jagielski 
218*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
disableAttributeNotification(AttributeId _nAttributeId)219*b1cdbd2cSJim Jagielski     void RichTextControlImpl::disableAttributeNotification( AttributeId _nAttributeId )
220*b1cdbd2cSJim Jagielski     {
221*b1cdbd2cSJim Jagielski         // forget the handler for this attribute
222*b1cdbd2cSJim Jagielski         AttributeHandlerPool::iterator aHandlerPos = m_aAttributeHandlers.find( _nAttributeId );
223*b1cdbd2cSJim Jagielski         if ( aHandlerPos != m_aAttributeHandlers.end() )
224*b1cdbd2cSJim Jagielski             m_aAttributeHandlers.erase( aHandlerPos );
225*b1cdbd2cSJim Jagielski 
226*b1cdbd2cSJim Jagielski         // as well as the listener
227*b1cdbd2cSJim Jagielski         AttributeListenerPool::iterator aListenerPos = m_aAttributeListeners.find( _nAttributeId );
228*b1cdbd2cSJim Jagielski         if ( aListenerPos != m_aAttributeListeners.end() )
229*b1cdbd2cSJim Jagielski             m_aAttributeListeners.erase( aListenerPos );
230*b1cdbd2cSJim Jagielski     }
231*b1cdbd2cSJim Jagielski 
232*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
normalizeScriptDependentAttribute(SvxScriptSetItem & _rScriptSetItem)233*b1cdbd2cSJim Jagielski     void RichTextControlImpl::normalizeScriptDependentAttribute( SvxScriptSetItem& _rScriptSetItem )
234*b1cdbd2cSJim Jagielski     {
235*b1cdbd2cSJim Jagielski         _rScriptSetItem.GetItemSet().Put( m_pView->GetAttribs(), sal_False );
236*b1cdbd2cSJim Jagielski         const SfxPoolItem* pNormalizedItem = _rScriptSetItem.GetItemOfScript( getSelectedScriptType() );
237*b1cdbd2cSJim Jagielski 
238*b1cdbd2cSJim Jagielski         WhichId nNormalizedWhichId = _rScriptSetItem.GetItemSet().GetPool()->GetWhich( _rScriptSetItem.Which() );
239*b1cdbd2cSJim Jagielski         if ( pNormalizedItem )
240*b1cdbd2cSJim Jagielski         {
241*b1cdbd2cSJim Jagielski             SfxPoolItem* pProperWhich = pNormalizedItem->Clone();
242*b1cdbd2cSJim Jagielski             pProperWhich->SetWhich( nNormalizedWhichId );
243*b1cdbd2cSJim Jagielski             _rScriptSetItem.GetItemSet().Put( *pProperWhich );
244*b1cdbd2cSJim Jagielski             DELETEZ( pProperWhich );
245*b1cdbd2cSJim Jagielski         }
246*b1cdbd2cSJim Jagielski         else
247*b1cdbd2cSJim Jagielski             _rScriptSetItem.GetItemSet().InvalidateItem( nNormalizedWhichId );
248*b1cdbd2cSJim Jagielski     }
249*b1cdbd2cSJim Jagielski 
250*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
implCheckUpdateCache(AttributeId _nAttribute,const AttributeState & _rState)251*b1cdbd2cSJim Jagielski     void RichTextControlImpl::implCheckUpdateCache( AttributeId _nAttribute, const AttributeState& _rState )
252*b1cdbd2cSJim Jagielski     {
253*b1cdbd2cSJim Jagielski         StateCache::iterator aCachePos = m_aLastKnownStates.find( _nAttribute );
254*b1cdbd2cSJim Jagielski         if ( aCachePos == m_aLastKnownStates.end() )
255*b1cdbd2cSJim Jagielski         {   // nothing known about this attribute, yet
256*b1cdbd2cSJim Jagielski             m_aLastKnownStates.insert( StateCache::value_type( _nAttribute, _rState ) );
257*b1cdbd2cSJim Jagielski         }
258*b1cdbd2cSJim Jagielski         else
259*b1cdbd2cSJim Jagielski         {
260*b1cdbd2cSJim Jagielski             if ( aCachePos->second == _rState )
261*b1cdbd2cSJim Jagielski             {
262*b1cdbd2cSJim Jagielski                 // nothing to do
263*b1cdbd2cSJim Jagielski                 return;
264*b1cdbd2cSJim Jagielski             }
265*b1cdbd2cSJim Jagielski             aCachePos->second = _rState;
266*b1cdbd2cSJim Jagielski         }
267*b1cdbd2cSJim Jagielski 
268*b1cdbd2cSJim Jagielski         // is there a dedicated listener for this particular attribute?
269*b1cdbd2cSJim Jagielski         AttributeListenerPool::const_iterator aListenerPos = m_aAttributeListeners.find( _nAttribute );
270*b1cdbd2cSJim Jagielski         if ( aListenerPos != m_aAttributeListeners.end( ) )
271*b1cdbd2cSJim Jagielski             aListenerPos->second->onAttributeStateChanged( _nAttribute, _rState );
272*b1cdbd2cSJim Jagielski 
273*b1cdbd2cSJim Jagielski         // call our global listener, if there is one
274*b1cdbd2cSJim Jagielski         if ( m_pTextAttrListener )
275*b1cdbd2cSJim Jagielski             m_pTextAttrListener->onAttributeStateChanged( _nAttribute, _rState );
276*b1cdbd2cSJim Jagielski     }
277*b1cdbd2cSJim Jagielski 
278*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
getSelectedScriptType() const279*b1cdbd2cSJim Jagielski     ScriptType RichTextControlImpl::getSelectedScriptType() const
280*b1cdbd2cSJim Jagielski     {
281*b1cdbd2cSJim Jagielski         ScriptType nScript = m_pView->GetSelectedScriptType();
282*b1cdbd2cSJim Jagielski         if ( !nScript )
283*b1cdbd2cSJim Jagielski             nScript = SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguage() );
284*b1cdbd2cSJim Jagielski         return nScript;
285*b1cdbd2cSJim Jagielski     }
286*b1cdbd2cSJim Jagielski 
287*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
EditEngineStatusChanged(const EditStatus & _rStatus)288*b1cdbd2cSJim Jagielski     void RichTextControlImpl::EditEngineStatusChanged( const EditStatus& _rStatus )
289*b1cdbd2cSJim Jagielski     {
290*b1cdbd2cSJim Jagielski         sal_uLong nStatusWord( _rStatus.GetStatusWord() );
291*b1cdbd2cSJim Jagielski         if  (   ( nStatusWord & EE_STAT_TEXTWIDTHCHANGED )
292*b1cdbd2cSJim Jagielski             ||  ( nStatusWord & EE_STAT_TEXTHEIGHTCHANGED )
293*b1cdbd2cSJim Jagielski             )
294*b1cdbd2cSJim Jagielski         {
295*b1cdbd2cSJim Jagielski             if ( ( nStatusWord & EE_STAT_TEXTHEIGHTCHANGED ) && windowHasAutomaticLineBreak() )
296*b1cdbd2cSJim Jagielski                 m_pEngine->SetPaperSize( Size( m_pEngine->GetPaperSize().Width(), m_pEngine->GetTextHeight() ) );
297*b1cdbd2cSJim Jagielski 
298*b1cdbd2cSJim Jagielski             updateScrollbars();
299*b1cdbd2cSJim Jagielski         }
300*b1cdbd2cSJim Jagielski 
301*b1cdbd2cSJim Jagielski         bool bHScroll = 0 != ( nStatusWord & EE_STAT_HSCROLL );
302*b1cdbd2cSJim Jagielski         bool bVScroll = 0 != ( nStatusWord & EE_STAT_VSCROLL );
303*b1cdbd2cSJim Jagielski 
304*b1cdbd2cSJim Jagielski         // In case of *no* automatic line breaks, we also need to check for the *range* here.
305*b1cdbd2cSJim Jagielski         // Normally, we would do this only after a EE_STAT_TEXTWIDTHCHANGED. However, due to a bug
306*b1cdbd2cSJim Jagielski         // in the EditEngine (I believe so) this is not fired when the engine does not have
307*b1cdbd2cSJim Jagielski         // the AutoPaperSize bits set.
308*b1cdbd2cSJim Jagielski         // So in order to be properly notified, we would need the AutoPaperSize. But, with
309*b1cdbd2cSJim Jagielski         // AutoPaperSize, other things do not work anymore: Either, when we set a MaxAutoPaperSize,
310*b1cdbd2cSJim Jagielski         // then the view does automatic soft line breaks at the paper end - which we definately do
311*b1cdbd2cSJim Jagielski         // want. Or, if we did not set a MaxAutoPaperSize, then the view does not automatically scroll
312*b1cdbd2cSJim Jagielski         // anymore in horizontal direction.
313*b1cdbd2cSJim Jagielski         // So this is some kind of lose-lose situation ... :(
314*b1cdbd2cSJim Jagielski         if ( !windowHasAutomaticLineBreak() && bHScroll )
315*b1cdbd2cSJim Jagielski         {
316*b1cdbd2cSJim Jagielski             updateScrollbars();
317*b1cdbd2cSJim Jagielski             return;
318*b1cdbd2cSJim Jagielski         }
319*b1cdbd2cSJim Jagielski 
320*b1cdbd2cSJim Jagielski         if ( bHScroll && m_pHScroll )
321*b1cdbd2cSJim Jagielski             m_pHScroll->SetThumbPos( m_pView->GetVisArea().Left() );
322*b1cdbd2cSJim Jagielski         if ( bVScroll && m_pVScroll )
323*b1cdbd2cSJim Jagielski             m_pVScroll->SetThumbPos( m_pView->GetVisArea().Top() );
324*b1cdbd2cSJim Jagielski     }
325*b1cdbd2cSJim Jagielski 
326*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
327*b1cdbd2cSJim Jagielski     IMPL_LINK( RichTextControlImpl, OnInvalidateAllAttributes, void*, /*_pNotInterestedIn*/ )
328*b1cdbd2cSJim Jagielski     {
329*b1cdbd2cSJim Jagielski         updateAllAttributes();
330*b1cdbd2cSJim Jagielski         return 0L;
331*b1cdbd2cSJim Jagielski     }
332*b1cdbd2cSJim Jagielski 
333*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
IMPL_LINK(RichTextControlImpl,OnHScroll,ScrollBar *,_pScrollbar)334*b1cdbd2cSJim Jagielski     IMPL_LINK( RichTextControlImpl, OnHScroll, ScrollBar*, _pScrollbar )
335*b1cdbd2cSJim Jagielski     {
336*b1cdbd2cSJim Jagielski         m_pView->Scroll( -_pScrollbar->GetDelta(), 0, RGCHK_PAPERSZ1 );
337*b1cdbd2cSJim Jagielski         return 0L;
338*b1cdbd2cSJim Jagielski     }
339*b1cdbd2cSJim Jagielski 
340*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
IMPL_LINK(RichTextControlImpl,OnVScroll,ScrollBar *,_pScrollbar)341*b1cdbd2cSJim Jagielski     IMPL_LINK( RichTextControlImpl, OnVScroll, ScrollBar*, _pScrollbar )
342*b1cdbd2cSJim Jagielski     {
343*b1cdbd2cSJim Jagielski         m_pView->Scroll( 0, -_pScrollbar->GetDelta(), RGCHK_PAPERSZ1 );
344*b1cdbd2cSJim Jagielski         return 0L;
345*b1cdbd2cSJim Jagielski     }
346*b1cdbd2cSJim Jagielski 
347*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
ensureScrollbars()348*b1cdbd2cSJim Jagielski     void RichTextControlImpl::ensureScrollbars()
349*b1cdbd2cSJim Jagielski     {
350*b1cdbd2cSJim Jagielski         bool bNeedVScroll = 0 != ( m_pAntiImpl->GetStyle() & WB_VSCROLL );
351*b1cdbd2cSJim Jagielski         bool bNeedHScroll = 0 != ( m_pAntiImpl->GetStyle() & WB_HSCROLL );
352*b1cdbd2cSJim Jagielski 
353*b1cdbd2cSJim Jagielski         if ( ( bNeedVScroll == hasVScrollBar() ) && ( bNeedHScroll == hasHScrollBar( ) ) )
354*b1cdbd2cSJim Jagielski             // nothing to do
355*b1cdbd2cSJim Jagielski             return;
356*b1cdbd2cSJim Jagielski 
357*b1cdbd2cSJim Jagielski         // create or delete the scrollbars, as necessary
358*b1cdbd2cSJim Jagielski         if ( !bNeedVScroll )
359*b1cdbd2cSJim Jagielski         {
360*b1cdbd2cSJim Jagielski             delete m_pVScroll;
361*b1cdbd2cSJim Jagielski             m_pVScroll = NULL;
362*b1cdbd2cSJim Jagielski         }
363*b1cdbd2cSJim Jagielski         else
364*b1cdbd2cSJim Jagielski         {
365*b1cdbd2cSJim Jagielski             m_pVScroll = new ScrollBar( m_pAntiImpl, WB_VSCROLL | WB_DRAG | WB_REPEAT );
366*b1cdbd2cSJim Jagielski             m_pVScroll->SetScrollHdl ( LINK( this, RichTextControlImpl, OnVScroll ) );
367*b1cdbd2cSJim Jagielski             m_pVScroll->Show();
368*b1cdbd2cSJim Jagielski         }
369*b1cdbd2cSJim Jagielski 
370*b1cdbd2cSJim Jagielski         if ( !bNeedHScroll )
371*b1cdbd2cSJim Jagielski         {
372*b1cdbd2cSJim Jagielski             delete m_pHScroll;
373*b1cdbd2cSJim Jagielski             m_pHScroll = NULL;
374*b1cdbd2cSJim Jagielski         }
375*b1cdbd2cSJim Jagielski         else
376*b1cdbd2cSJim Jagielski         {
377*b1cdbd2cSJim Jagielski             m_pHScroll = new ScrollBar( m_pAntiImpl, WB_HSCROLL | WB_DRAG | WB_REPEAT );
378*b1cdbd2cSJim Jagielski             m_pHScroll->SetScrollHdl ( LINK( this, RichTextControlImpl, OnHScroll ) );
379*b1cdbd2cSJim Jagielski             m_pHScroll->Show();
380*b1cdbd2cSJim Jagielski         }
381*b1cdbd2cSJim Jagielski 
382*b1cdbd2cSJim Jagielski         if ( m_pHScroll && m_pVScroll )
383*b1cdbd2cSJim Jagielski         {
384*b1cdbd2cSJim Jagielski             delete m_pScrollCorner;
385*b1cdbd2cSJim Jagielski             m_pScrollCorner = new ScrollBarBox( m_pAntiImpl );
386*b1cdbd2cSJim Jagielski             m_pScrollCorner->Show();
387*b1cdbd2cSJim Jagielski         }
388*b1cdbd2cSJim Jagielski         else
389*b1cdbd2cSJim Jagielski         {
390*b1cdbd2cSJim Jagielski             delete m_pScrollCorner;
391*b1cdbd2cSJim Jagielski             m_pScrollCorner = NULL;
392*b1cdbd2cSJim Jagielski         }
393*b1cdbd2cSJim Jagielski 
394*b1cdbd2cSJim Jagielski         layoutWindow();
395*b1cdbd2cSJim Jagielski     }
396*b1cdbd2cSJim Jagielski 
397*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
ensureLineBreakSetting()398*b1cdbd2cSJim Jagielski     void RichTextControlImpl::ensureLineBreakSetting()
399*b1cdbd2cSJim Jagielski     {
400*b1cdbd2cSJim Jagielski         if ( !windowHasAutomaticLineBreak() )
401*b1cdbd2cSJim Jagielski             m_pEngine->SetPaperSize( Size( EMPTY_PAPER_SIZE, EMPTY_PAPER_SIZE ) );
402*b1cdbd2cSJim Jagielski 
403*b1cdbd2cSJim Jagielski         layoutWindow();
404*b1cdbd2cSJim Jagielski     }
405*b1cdbd2cSJim Jagielski 
406*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
layoutWindow()407*b1cdbd2cSJim Jagielski     void RichTextControlImpl::layoutWindow()
408*b1cdbd2cSJim Jagielski     {
409*b1cdbd2cSJim Jagielski         if ( !m_bHasEverBeenShown )
410*b1cdbd2cSJim Jagielski             // no need to do anything. Especially, no need to set the paper size on the
411*b1cdbd2cSJim Jagielski             // EditEngine to anything ....
412*b1cdbd2cSJim Jagielski             return;
413*b1cdbd2cSJim Jagielski 
414*b1cdbd2cSJim Jagielski         const StyleSettings& rStyleSettings = m_pAntiImpl->GetSettings().GetStyleSettings();
415*b1cdbd2cSJim Jagielski 
416*b1cdbd2cSJim Jagielski         long nScrollBarWidth = m_pVScroll ? rStyleSettings.GetScrollBarSize() : 0;
417*b1cdbd2cSJim Jagielski         long nScrollBarHeight = m_pHScroll ? rStyleSettings.GetScrollBarSize() : 0;
418*b1cdbd2cSJim Jagielski 
419*b1cdbd2cSJim Jagielski         if ( m_pAntiImpl->IsZoom() )
420*b1cdbd2cSJim Jagielski         {
421*b1cdbd2cSJim Jagielski             nScrollBarWidth = m_pAntiImpl->CalcZoom( nScrollBarWidth );
422*b1cdbd2cSJim Jagielski             nScrollBarHeight = m_pAntiImpl->CalcZoom( nScrollBarHeight );
423*b1cdbd2cSJim Jagielski         }
424*b1cdbd2cSJim Jagielski 
425*b1cdbd2cSJim Jagielski         // the overall size we can use
426*b1cdbd2cSJim Jagielski         Size aPlaygroundSizePixel( m_pAntiImpl->GetOutputSizePixel() );
427*b1cdbd2cSJim Jagielski 
428*b1cdbd2cSJim Jagielski         // the size of the viewport - note that the viewport does *not* occupy all the place
429*b1cdbd2cSJim Jagielski         // which is left when subtracting the scrollbar width/height
430*b1cdbd2cSJim Jagielski         Size aViewportPlaygroundPixel( aPlaygroundSizePixel );
431*b1cdbd2cSJim Jagielski         aViewportPlaygroundPixel.Width() = ::std::max( long( 10 ), long( aViewportPlaygroundPixel.Width() - nScrollBarWidth ) );
432*b1cdbd2cSJim Jagielski         aViewportPlaygroundPixel.Height() = ::std::max( long( 10 ), long( aViewportPlaygroundPixel.Height() - nScrollBarHeight ) );
433*b1cdbd2cSJim Jagielski         Size aViewportPlaygroundLogic( m_pViewport->PixelToLogic( aViewportPlaygroundPixel ) );
434*b1cdbd2cSJim Jagielski 
435*b1cdbd2cSJim Jagielski         const long nOffset = 2;
436*b1cdbd2cSJim Jagielski         Size aViewportSizePixel( aViewportPlaygroundPixel.Width() - 2 * nOffset, aViewportPlaygroundPixel.Height() - 2 * nOffset );
437*b1cdbd2cSJim Jagielski         Size aViewportSizeLogic( m_pViewport->PixelToLogic( aViewportSizePixel ) );
438*b1cdbd2cSJim Jagielski 
439*b1cdbd2cSJim Jagielski         // position the viewport
440*b1cdbd2cSJim Jagielski         m_pViewport->SetPosSizePixel( Point( nOffset, nOffset ), aViewportSizePixel );
441*b1cdbd2cSJim Jagielski         // position the scrollbars
442*b1cdbd2cSJim Jagielski         if ( m_pVScroll )
443*b1cdbd2cSJim Jagielski             m_pVScroll->SetPosSizePixel( Point( aViewportPlaygroundPixel.Width(), 0 ), Size( nScrollBarWidth, aViewportPlaygroundPixel.Height() ) );
444*b1cdbd2cSJim Jagielski         if ( m_pHScroll )
445*b1cdbd2cSJim Jagielski             m_pHScroll->SetPosSizePixel( Point( 0, aViewportPlaygroundPixel.Height() ), Size( aViewportPlaygroundPixel.Width(), nScrollBarHeight ) );
446*b1cdbd2cSJim Jagielski         if ( m_pScrollCorner )
447*b1cdbd2cSJim Jagielski             m_pScrollCorner->SetPosSizePixel( Point( aViewportPlaygroundPixel.Width(), aViewportPlaygroundPixel.Height() ), Size( nScrollBarWidth, nScrollBarHeight ) );
448*b1cdbd2cSJim Jagielski 
449*b1cdbd2cSJim Jagielski         // paper size
450*b1cdbd2cSJim Jagielski         if ( windowHasAutomaticLineBreak() )
451*b1cdbd2cSJim Jagielski             m_pEngine->SetPaperSize( Size( aViewportSizeLogic.Width(), m_pEngine->GetTextHeight() ) );
452*b1cdbd2cSJim Jagielski 
453*b1cdbd2cSJim Jagielski         // output area of the view
454*b1cdbd2cSJim Jagielski         m_pView->SetOutputArea( Rectangle( Point( ), aViewportSizeLogic ) );
455*b1cdbd2cSJim Jagielski         m_pView->SetVisArea( Rectangle( Point( ), aViewportSizeLogic ) );
456*b1cdbd2cSJim Jagielski 
457*b1cdbd2cSJim Jagielski         if ( m_pVScroll )
458*b1cdbd2cSJim Jagielski         {
459*b1cdbd2cSJim Jagielski             m_pVScroll->SetVisibleSize( aViewportPlaygroundLogic.Height() );
460*b1cdbd2cSJim Jagielski 
461*b1cdbd2cSJim Jagielski             // the default height of a text line ....
462*b1cdbd2cSJim Jagielski             long nFontHeight = m_pEngine->GetStandardFont(0).GetSize().Height();
463*b1cdbd2cSJim Jagielski             // ... is the scroll size for the vertical scrollbar
464*b1cdbd2cSJim Jagielski             m_pVScroll->SetLineSize( nFontHeight );
465*b1cdbd2cSJim Jagielski             // the viewport width, minus one line, is the page scroll size
466*b1cdbd2cSJim Jagielski             m_pVScroll->SetPageSize( ::std::max( nFontHeight, aViewportPlaygroundLogic.Height() - nFontHeight ) );
467*b1cdbd2cSJim Jagielski         }
468*b1cdbd2cSJim Jagielski 
469*b1cdbd2cSJim Jagielski         // the font width
470*b1cdbd2cSJim Jagielski         if ( m_pHScroll )
471*b1cdbd2cSJim Jagielski         {
472*b1cdbd2cSJim Jagielski             m_pHScroll->SetVisibleSize( aViewportPlaygroundLogic.Width() );
473*b1cdbd2cSJim Jagielski 
474*b1cdbd2cSJim Jagielski             long nFontWidth = m_pEngine->GetStandardFont(0).GetSize().Width();
475*b1cdbd2cSJim Jagielski             if ( !nFontWidth )
476*b1cdbd2cSJim Jagielski             {
477*b1cdbd2cSJim Jagielski                 m_pViewport->Push( PUSH_FONT );
478*b1cdbd2cSJim Jagielski                 m_pViewport->SetFont( m_pEngine->GetStandardFont(0) );
479*b1cdbd2cSJim Jagielski                 nFontWidth = m_pViewport->GetTextWidth( String( RTL_CONSTASCII_USTRINGPARAM( "x" ) ) );
480*b1cdbd2cSJim Jagielski                 m_pViewport->Pop();
481*b1cdbd2cSJim Jagielski             }
482*b1cdbd2cSJim Jagielski             // ... is the scroll size for the horizontal scrollbar
483*b1cdbd2cSJim Jagielski             m_pHScroll->SetLineSize( 5 * nFontWidth );
484*b1cdbd2cSJim Jagielski             // the viewport height, minus one character, is the page scroll size
485*b1cdbd2cSJim Jagielski             m_pHScroll->SetPageSize( ::std::max( nFontWidth, aViewportPlaygroundLogic.Width() - nFontWidth ) );
486*b1cdbd2cSJim Jagielski         }
487*b1cdbd2cSJim Jagielski 
488*b1cdbd2cSJim Jagielski         // update range and position of the scrollbars
489*b1cdbd2cSJim Jagielski         updateScrollbars();
490*b1cdbd2cSJim Jagielski     }
491*b1cdbd2cSJim Jagielski 
492*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
updateScrollbars()493*b1cdbd2cSJim Jagielski     void RichTextControlImpl::updateScrollbars()
494*b1cdbd2cSJim Jagielski     {
495*b1cdbd2cSJim Jagielski         if ( m_pVScroll )
496*b1cdbd2cSJim Jagielski         {
497*b1cdbd2cSJim Jagielski             long nOverallTextHeight = m_pEngine->GetTextHeight();
498*b1cdbd2cSJim Jagielski             m_pVScroll->SetRange( Range( 0, nOverallTextHeight ) );
499*b1cdbd2cSJim Jagielski             m_pVScroll->SetThumbPos( m_pView->GetVisArea().Top() );
500*b1cdbd2cSJim Jagielski         }
501*b1cdbd2cSJim Jagielski 
502*b1cdbd2cSJim Jagielski         if ( m_pHScroll )
503*b1cdbd2cSJim Jagielski         {
504*b1cdbd2cSJim Jagielski             Size aPaperSize( m_pEngine->GetPaperSize() );
505*b1cdbd2cSJim Jagielski             long nOverallTextWidth = ( aPaperSize.Width() == EMPTY_PAPER_SIZE ) ? m_pEngine->CalcTextWidth() : aPaperSize.Width();
506*b1cdbd2cSJim Jagielski             m_pHScroll->SetRange( Range( 0, nOverallTextWidth ) );
507*b1cdbd2cSJim Jagielski             m_pHScroll->SetThumbPos( m_pView->GetVisArea().Left() );
508*b1cdbd2cSJim Jagielski         }
509*b1cdbd2cSJim Jagielski     }
510*b1cdbd2cSJim Jagielski 
511*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
notifyInitShow()512*b1cdbd2cSJim Jagielski     void RichTextControlImpl::notifyInitShow()
513*b1cdbd2cSJim Jagielski     {
514*b1cdbd2cSJim Jagielski         if ( !m_bHasEverBeenShown )
515*b1cdbd2cSJim Jagielski         {
516*b1cdbd2cSJim Jagielski             m_bHasEverBeenShown = true;
517*b1cdbd2cSJim Jagielski             layoutWindow();
518*b1cdbd2cSJim Jagielski         }
519*b1cdbd2cSJim Jagielski     }
520*b1cdbd2cSJim Jagielski 
521*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
notifyStyleChanged()522*b1cdbd2cSJim Jagielski     void RichTextControlImpl::notifyStyleChanged()
523*b1cdbd2cSJim Jagielski     {
524*b1cdbd2cSJim Jagielski         ensureScrollbars();
525*b1cdbd2cSJim Jagielski         ensureLineBreakSetting();
526*b1cdbd2cSJim Jagielski     }
527*b1cdbd2cSJim Jagielski 
528*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
notifyZoomChanged()529*b1cdbd2cSJim Jagielski     void RichTextControlImpl::notifyZoomChanged()
530*b1cdbd2cSJim Jagielski     {
531*b1cdbd2cSJim Jagielski         const Fraction& rZoom = m_pAntiImpl->GetZoom();
532*b1cdbd2cSJim Jagielski 
533*b1cdbd2cSJim Jagielski         MapMode aMapMode( m_pAntiImpl->GetMapMode() );
534*b1cdbd2cSJim Jagielski         aMapMode.SetScaleX( rZoom );
535*b1cdbd2cSJim Jagielski         aMapMode.SetScaleY( rZoom );
536*b1cdbd2cSJim Jagielski         m_pAntiImpl->SetMapMode( aMapMode );
537*b1cdbd2cSJim Jagielski 
538*b1cdbd2cSJim Jagielski         m_pViewport->SetZoom( rZoom );
539*b1cdbd2cSJim Jagielski         m_pViewport->SetMapMode( aMapMode );
540*b1cdbd2cSJim Jagielski 
541*b1cdbd2cSJim Jagielski         layoutWindow();
542*b1cdbd2cSJim Jagielski     }
543*b1cdbd2cSJim Jagielski 
544*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
windowHasAutomaticLineBreak()545*b1cdbd2cSJim Jagielski     bool RichTextControlImpl::windowHasAutomaticLineBreak()
546*b1cdbd2cSJim Jagielski     {
547*b1cdbd2cSJim Jagielski         return ( m_pAntiImpl->GetStyle() & WB_WORDBREAK ) != 0;
548*b1cdbd2cSJim Jagielski     }
549*b1cdbd2cSJim Jagielski 
550*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
SetReadOnly(bool _bReadOnly)551*b1cdbd2cSJim Jagielski     void RichTextControlImpl::SetReadOnly( bool _bReadOnly )
552*b1cdbd2cSJim Jagielski     {
553*b1cdbd2cSJim Jagielski         m_pView->SetReadOnly( _bReadOnly );
554*b1cdbd2cSJim Jagielski     }
555*b1cdbd2cSJim Jagielski 
556*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
IsReadOnly() const557*b1cdbd2cSJim Jagielski     bool RichTextControlImpl::IsReadOnly() const
558*b1cdbd2cSJim Jagielski     {
559*b1cdbd2cSJim Jagielski         return m_pView->IsReadOnly( );
560*b1cdbd2cSJim Jagielski     }
561*b1cdbd2cSJim Jagielski 
562*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
563*b1cdbd2cSJim Jagielski     namespace
564*b1cdbd2cSJim Jagielski     {
lcl_inflate(Rectangle & _rRect,long _nInflateX,long _nInflateY)565*b1cdbd2cSJim Jagielski         static void lcl_inflate( Rectangle& _rRect, long _nInflateX, long _nInflateY )
566*b1cdbd2cSJim Jagielski         {
567*b1cdbd2cSJim Jagielski             _rRect.Left() -= _nInflateX;
568*b1cdbd2cSJim Jagielski             _rRect.Right() += _nInflateX;
569*b1cdbd2cSJim Jagielski             _rRect.Top() -= _nInflateY;
570*b1cdbd2cSJim Jagielski             _rRect.Bottom() += _nInflateY;
571*b1cdbd2cSJim Jagielski         }
572*b1cdbd2cSJim Jagielski     }
573*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
HandleCommand(const CommandEvent & _rEvent)574*b1cdbd2cSJim Jagielski     long RichTextControlImpl::HandleCommand( const CommandEvent& _rEvent )
575*b1cdbd2cSJim Jagielski     {
576*b1cdbd2cSJim Jagielski         if (  ( _rEvent.GetCommand() == COMMAND_WHEEL )
577*b1cdbd2cSJim Jagielski            || ( _rEvent.GetCommand() == COMMAND_STARTAUTOSCROLL )
578*b1cdbd2cSJim Jagielski            || ( _rEvent.GetCommand() == COMMAND_AUTOSCROLL )
579*b1cdbd2cSJim Jagielski            )
580*b1cdbd2cSJim Jagielski         {
581*b1cdbd2cSJim Jagielski             m_pAntiImpl->HandleScrollCommand( _rEvent, m_pHScroll, m_pVScroll );
582*b1cdbd2cSJim Jagielski             return 1;
583*b1cdbd2cSJim Jagielski         }
584*b1cdbd2cSJim Jagielski         return 0;
585*b1cdbd2cSJim Jagielski     }
586*b1cdbd2cSJim Jagielski 
587*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
Draw(OutputDevice * _pDev,const Point & _rPos,const Size & _rSize,sal_uLong)588*b1cdbd2cSJim Jagielski     void RichTextControlImpl::Draw( OutputDevice* _pDev, const Point& _rPos, const Size& _rSize, sal_uLong /*_nFlags*/ )
589*b1cdbd2cSJim Jagielski     {
590*b1cdbd2cSJim Jagielski         // need to normalize the map mode of the device - every paint operation on any device needs
591*b1cdbd2cSJim Jagielski         // to use the same map mode
592*b1cdbd2cSJim Jagielski         _pDev->Push( PUSH_MAPMODE | PUSH_LINECOLOR | PUSH_FILLCOLOR );
593*b1cdbd2cSJim Jagielski 
594*b1cdbd2cSJim Jagielski         // enforce our "normalize map mode" on the device
595*b1cdbd2cSJim Jagielski         MapMode aRefMapMode( m_pEngine->GetRefDevice()->GetMapMode() );
596*b1cdbd2cSJim Jagielski         MapMode aOriginalMapMode( _pDev->GetMapMode() );
597*b1cdbd2cSJim Jagielski         MapMode aNormalizedMapMode( aRefMapMode.GetMapUnit(), aRefMapMode.GetOrigin(), aOriginalMapMode.GetScaleX(), aOriginalMapMode.GetScaleY() );
598*b1cdbd2cSJim Jagielski         _pDev->SetMapMode( aNormalizedMapMode );
599*b1cdbd2cSJim Jagielski 
600*b1cdbd2cSJim Jagielski         // translate coordinates
601*b1cdbd2cSJim Jagielski         Point aPos( _rPos );
602*b1cdbd2cSJim Jagielski         Size aSize( _rSize );
603*b1cdbd2cSJim Jagielski         if ( aOriginalMapMode.GetMapUnit() == MAP_PIXEL )
604*b1cdbd2cSJim Jagielski         {
605*b1cdbd2cSJim Jagielski             aPos = _pDev->PixelToLogic( _rPos, aNormalizedMapMode );
606*b1cdbd2cSJim Jagielski             aSize = _pDev->PixelToLogic( _rSize, aNormalizedMapMode );
607*b1cdbd2cSJim Jagielski         }
608*b1cdbd2cSJim Jagielski         else
609*b1cdbd2cSJim Jagielski         {
610*b1cdbd2cSJim Jagielski             aPos = OutputDevice::LogicToLogic( _rPos, aOriginalMapMode, aNormalizedMapMode );
611*b1cdbd2cSJim Jagielski             aSize = OutputDevice::LogicToLogic( _rSize, aOriginalMapMode, aNormalizedMapMode );
612*b1cdbd2cSJim Jagielski         }
613*b1cdbd2cSJim Jagielski 
614*b1cdbd2cSJim Jagielski         Rectangle aPlayground( aPos, aSize );
615*b1cdbd2cSJim Jagielski         Size aOnePixel( _pDev->PixelToLogic( Size( 1, 1 ) ) );
616*b1cdbd2cSJim Jagielski         aPlayground.Right() -= aOnePixel.Width();
617*b1cdbd2cSJim Jagielski         aPlayground.Bottom() -= aOnePixel.Height();
618*b1cdbd2cSJim Jagielski 
619*b1cdbd2cSJim Jagielski         // background
620*b1cdbd2cSJim Jagielski         _pDev->SetLineColor();
621*b1cdbd2cSJim Jagielski         _pDev->DrawRect( aPlayground );
622*b1cdbd2cSJim Jagielski 
623*b1cdbd2cSJim Jagielski         // do we need to draw a border?
624*b1cdbd2cSJim Jagielski         bool bBorder = ( m_pAntiImpl->GetStyle() & WB_BORDER );
625*b1cdbd2cSJim Jagielski         if ( bBorder )
626*b1cdbd2cSJim Jagielski             _pDev->SetLineColor( m_pAntiImpl->GetSettings().GetStyleSettings().GetMonoColor() );
627*b1cdbd2cSJim Jagielski         else
628*b1cdbd2cSJim Jagielski             _pDev->SetLineColor();
629*b1cdbd2cSJim Jagielski         _pDev->SetFillColor( m_pAntiImpl->GetBackground().GetColor() );
630*b1cdbd2cSJim Jagielski         _pDev->DrawRect( aPlayground );
631*b1cdbd2cSJim Jagielski 
632*b1cdbd2cSJim Jagielski         if ( bBorder )
633*b1cdbd2cSJim Jagielski             // don't draw the text over the border
634*b1cdbd2cSJim Jagielski             lcl_inflate( aPlayground, -aOnePixel.Width(), -aOnePixel.Height() );
635*b1cdbd2cSJim Jagielski 
636*b1cdbd2cSJim Jagielski         // leave a space of one pixel between the "surroundings" of the control
637*b1cdbd2cSJim Jagielski         // and the content
638*b1cdbd2cSJim Jagielski         lcl_inflate( aPlayground, -aOnePixel.Width(), -aOnePixel.Height() );
639*b1cdbd2cSJim Jagielski         lcl_inflate( aPlayground, -aOnePixel.Width(), -aOnePixel.Height() );
640*b1cdbd2cSJim Jagielski 
641*b1cdbd2cSJim Jagielski         // actually draw the content
642*b1cdbd2cSJim Jagielski         m_pEngine->Draw( _pDev, aPlayground, Point(), sal_True );
643*b1cdbd2cSJim Jagielski 
644*b1cdbd2cSJim Jagielski         _pDev->Pop();
645*b1cdbd2cSJim Jagielski     }
646*b1cdbd2cSJim Jagielski 
647*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
SetBackgroundColor()648*b1cdbd2cSJim Jagielski     void RichTextControlImpl::SetBackgroundColor( )
649*b1cdbd2cSJim Jagielski     {
650*b1cdbd2cSJim Jagielski         SetBackgroundColor( Application::GetSettings().GetStyleSettings().GetFieldColor() );
651*b1cdbd2cSJim Jagielski     }
652*b1cdbd2cSJim Jagielski 
653*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
SetBackgroundColor(const Color & _rColor)654*b1cdbd2cSJim Jagielski     void RichTextControlImpl::SetBackgroundColor( const Color& _rColor )
655*b1cdbd2cSJim Jagielski     {
656*b1cdbd2cSJim Jagielski         Wallpaper aWallpaper( _rColor );
657*b1cdbd2cSJim Jagielski         m_pAntiImpl->SetBackground( aWallpaper );
658*b1cdbd2cSJim Jagielski         m_pViewport->SetBackground( aWallpaper );
659*b1cdbd2cSJim Jagielski     }
660*b1cdbd2cSJim Jagielski 
661*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
SetHideInactiveSelection(bool _bHide)662*b1cdbd2cSJim Jagielski     void RichTextControlImpl::SetHideInactiveSelection( bool _bHide )
663*b1cdbd2cSJim Jagielski     {
664*b1cdbd2cSJim Jagielski         m_pViewport->SetHideInactiveSelection( _bHide );
665*b1cdbd2cSJim Jagielski     }
666*b1cdbd2cSJim Jagielski 
667*b1cdbd2cSJim Jagielski     //--------------------------------------------------------------------
GetHideInactiveSelection() const668*b1cdbd2cSJim Jagielski     bool RichTextControlImpl::GetHideInactiveSelection() const
669*b1cdbd2cSJim Jagielski     {
670*b1cdbd2cSJim Jagielski         return m_pViewport->GetHideInactiveSelection( );
671*b1cdbd2cSJim Jagielski     }
672*b1cdbd2cSJim Jagielski 
673*b1cdbd2cSJim Jagielski //........................................................................
674*b1cdbd2cSJim Jagielski }   // namespace frm
675*b1cdbd2cSJim Jagielski //........................................................................
676*b1cdbd2cSJim Jagielski 
677