Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "richtextcontrol.hxx"
30 : : #include "frm_module.hxx"
31 : : #include "property.hrc"
32 : : #include "services.hxx"
33 : :
34 : : #include "richtextmodel.hxx"
35 : : #include "richtextvclcontrol.hxx"
36 : : #include "clipboarddispatcher.hxx"
37 : : #include "parametrizedattributedispatcher.hxx"
38 : : #include "specialdispatchers.hxx"
39 : :
40 : : #include <com/sun/star/awt/PosSize.hpp>
41 : :
42 : : #include <toolkit/helper/vclunohelper.hxx>
43 : : #include <tools/diagnose_ex.h>
44 : : #include <vcl/svapp.hxx>
45 : :
46 : : #include <svx/svxids.hrc>
47 : : #include <editeng/editview.hxx>
48 : : #include <svl/itemset.hxx>
49 : : #include <svl/itempool.hxx>
50 : : #include <sfx2/msgpool.hxx>
51 : :
52 : : //--------------------------------------------------------------------------
53 : 30 : extern "C" void SAL_CALL createRegistryInfo_ORichTextControl()
54 : : {
55 [ + - ][ + - ]: 30 : static ::frm::OMultiInstanceAutoRegistration< ::frm::ORichTextControl > aAutoRegistration;
[ + - ][ # # ]
56 : 30 : }
57 : :
58 : : //.........................................................................
59 : : namespace frm
60 : : {
61 : : //.........................................................................
62 : :
63 : : using namespace ::com::sun::star::uno;
64 : : using namespace ::com::sun::star::beans;
65 : : using namespace ::com::sun::star::awt;
66 : : using namespace ::com::sun::star::lang;
67 : : using namespace ::com::sun::star::frame;
68 : :
69 : : #define FORWARD_TO_PEER_1( unoInterface, method, param1 ) \
70 : : Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \
71 : : if ( xTypedPeer.is() ) \
72 : : { \
73 : : xTypedPeer->method( param1 ); \
74 : : }
75 : :
76 : : #define FORWARD_TO_PEER_1_RET( returnType, unoInterface, method, param1 ) \
77 : : returnType aReturn; \
78 : : Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \
79 : : if ( xTypedPeer.is() ) \
80 : : { \
81 : : aReturn = xTypedPeer->method( param1 ); \
82 : : } \
83 : : return aReturn;
84 : :
85 : : #define FORWARD_TO_PEER_3( unoInterface, method, param1, param2, param3 ) \
86 : : Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \
87 : : if ( xTypedPeer.is() ) \
88 : : { \
89 : : xTypedPeer->method( param1, param2, param3 ); \
90 : : }
91 : :
92 : : #define FORWARD_TO_PEER_3_RET( returnType, unoInterface, method, param1, param2, param3 ) \
93 : : returnType aReturn; \
94 : : Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \
95 : : if ( xTypedPeer.is() ) \
96 : : { \
97 : : aReturn = xTypedPeer->method( param1, param2, param3 ); \
98 : : } \
99 : : return aReturn;
100 : :
101 : : //==================================================================
102 : : // ORichTextControl
103 : : //==================================================================
104 : : DBG_NAME( ORichTextControl )
105 : : //------------------------------------------------------------------
106 : 80 : ORichTextControl::ORichTextControl( const Reference< XMultiServiceFactory >& _rxORB )
107 : 80 : :UnoEditControl( _rxORB )
108 : : {
109 : : DBG_CTOR( ORichTextControl, NULL );
110 : 80 : }
111 : :
112 : : //------------------------------------------------------------------
113 : 77 : ORichTextControl::~ORichTextControl()
114 : : {
115 : : DBG_DTOR( ORichTextControl, NULL );
116 [ - + ]: 154 : }
117 : :
118 : : //------------------------------------------------------------------
119 [ # # ][ # # ]: 0 : IMPLEMENT_FORWARD_XTYPEPROVIDER2( ORichTextControl, UnoEditControl, ORichTextControl_Base )
[ # # ]
120 : :
121 : : //------------------------------------------------------------------
122 : 2560 : Any SAL_CALL ORichTextControl::queryAggregation( const Type& _rType ) throw ( RuntimeException )
123 : : {
124 : 2560 : Any aReturn = UnoEditControl::queryAggregation( _rType );
125 : :
126 [ + + ]: 2560 : if ( !aReturn.hasValue() )
127 [ + - ]: 201 : aReturn = ORichTextControl_Base::queryInterface( _rType );
128 : :
129 : 2560 : return aReturn;
130 : : }
131 : :
132 : : //------------------------------------------------------------------
133 : : namespace
134 : : {
135 : : //..............................................................
136 : 40 : static void implAdjustTriStateFlag( const Reference< XPropertySet >& _rxProps, const ::rtl::OUString& _rPropertyName,
137 : : WinBits& _rAllBits, WinBits _nPositiveFlag, WinBits nNegativeFlag )
138 : : {
139 : 40 : sal_Bool bFlagValue = sal_False;
140 [ + - ][ + - ]: 40 : if ( _rxProps->getPropertyValue( _rPropertyName ) >>= bFlagValue )
[ - + ]
141 [ # # ]: 0 : _rAllBits |= ( bFlagValue ? _nPositiveFlag : nNegativeFlag );
142 : 40 : }
143 : :
144 : : //..............................................................
145 : 248 : static void implAdjustTwoStateFlag( const Any& _rValue, WinBits& _rAllBits, WinBits _nFlag, bool _bInvert = false )
146 : : {
147 : 248 : sal_Bool bFlagValue = sal_False;
148 [ + - ]: 248 : if ( _rValue >>= bFlagValue )
149 : : {
150 [ + + ]: 248 : if ( _bInvert )
151 : 88 : bFlagValue = !bFlagValue;
152 [ + + ]: 248 : if ( bFlagValue )
153 : 120 : _rAllBits |= _nFlag;
154 : : else
155 : 128 : _rAllBits &= ~_nFlag;
156 : : }
157 : 248 : }
158 : :
159 : : //..............................................................
160 : 120 : static void implAdjustTwoStateFlag( const Reference< XPropertySet >& _rxProps, const ::rtl::OUString& _rPropertyName,
161 : : WinBits& _rAllBits, WinBits _nFlag, bool _bInvert = false )
162 : : {
163 : 120 : implAdjustTwoStateFlag( _rxProps->getPropertyValue( _rPropertyName ), _rAllBits, _nFlag, _bInvert );
164 : 120 : }
165 : :
166 : : //..............................................................
167 : 128 : static void adjustTwoStateWinBit( Window* _pWindow, const Any& _rValue, WinBits _nFlag, bool _bInvert = false )
168 : : {
169 [ + - ]: 128 : WinBits nBits = _pWindow->GetStyle();
170 : 128 : implAdjustTwoStateFlag( _rValue, nBits, _nFlag, _bInvert );
171 [ + - ]: 128 : _pWindow->SetStyle( nBits );
172 : 128 : }
173 : :
174 : : //..............................................................
175 : 40 : static WinBits getWinBits( const Reference< XControlModel >& _rxModel, WinBits nBaseBits = 0 )
176 : : {
177 : 40 : WinBits nBits = nBaseBits;
178 : : try
179 : : {
180 [ + - ]: 40 : Reference< XPropertySet > xProps( _rxModel, UNO_QUERY );
181 [ + - ]: 40 : if ( xProps.is() )
182 : : {
183 : 40 : sal_Int16 nBorder = 0;
184 [ + - ][ + - ]: 40 : xProps->getPropertyValue( PROPERTY_BORDER ) >>= nBorder;
[ + - ]
185 [ + - ]: 40 : if ( nBorder )
186 : 40 : nBits |= WB_BORDER;
187 : :
188 [ + - ][ + - ]: 40 : implAdjustTriStateFlag( xProps, PROPERTY_TABSTOP, nBits, WB_TABSTOP, WB_NOTABSTOP );
189 [ + - ][ + - ]: 40 : implAdjustTwoStateFlag( xProps, PROPERTY_HSCROLL, nBits, WB_HSCROLL );
190 [ + - ][ + - ]: 40 : implAdjustTwoStateFlag( xProps, PROPERTY_VSCROLL, nBits, WB_VSCROLL );
191 [ + - ][ + - ]: 40 : implAdjustTwoStateFlag( xProps, PROPERTY_HARDLINEBREAKS, nBits, WB_WORDBREAK, true );
192 [ # # ]: 40 : }
193 : : }
194 [ # # ]: 0 : catch( const Exception& )
195 : : {
196 : : DBG_UNHANDLED_EXCEPTION();
197 : : }
198 : 40 : return nBits;
199 : : }
200 : : }
201 : :
202 : : //------------------------------------------------------------------
203 : 167 : void SAL_CALL ORichTextControl::createPeer( const Reference< XToolkit >& _rToolkit, const Reference< XWindowPeer >& _rParentPeer ) throw( RuntimeException )
204 : : {
205 : 167 : sal_Bool bReallyActAsRichText = sal_False;
206 : : try
207 : : {
208 [ + - ][ + - ]: 167 : Reference< XPropertySet > xModelProps( getModel(), UNO_QUERY_THROW );
209 [ + - ][ + - ]: 167 : xModelProps->getPropertyValue( PROPERTY_RICH_TEXT ) >>= bReallyActAsRichText;
[ # # ][ + - ]
210 : : }
211 [ # # ]: 0 : catch( const Exception& )
212 : : {
213 : : DBG_UNHANDLED_EXCEPTION();
214 : : }
215 : :
216 [ + + ]: 167 : if ( !bReallyActAsRichText )
217 : : {
218 [ + - ]: 127 : UnoEditControl::createPeer( _rToolkit, _rParentPeer );
219 [ + - ][ + - ]: 127 : OControl::initFormControlPeer( getPeer() );
220 : 167 : return;
221 : : }
222 : :
223 [ + - ]: 40 : SolarMutexGuard aGuard;
224 : :
225 [ + - ][ + - ]: 40 : if (!getPeer().is())
226 : : {
227 : 40 : mbCreatingPeer = sal_True;
228 : :
229 : : // determine the VLC window for the parent
230 : 40 : Window* pParentWin = NULL;
231 [ + - ]: 40 : if ( _rParentPeer.is() )
232 : : {
233 : 40 : VCLXWindow* pParentXWin = VCLXWindow::GetImplementation( _rParentPeer );
234 [ + - ]: 40 : if ( pParentXWin )
235 : 40 : pParentWin = pParentXWin->GetWindow();
236 : : DBG_ASSERT( pParentWin, "ORichTextControl::createPeer: could not obtain the VCL-level parent window!" );
237 : : }
238 : :
239 : : // create the peer
240 [ + - ]: 40 : Reference< XControlModel > xModel( getModel() );
241 [ + - ][ + - ]: 40 : ORichTextPeer* pPeer = ORichTextPeer::Create( xModel, pParentWin, getWinBits( xModel ) );
242 : : DBG_ASSERT( pPeer, "ORichTextControl::createPeer: invalid peer returned!" );
243 [ + - ]: 40 : if ( pPeer )
244 : : {
245 : : // by definition, the returned component is aquired once
246 : 40 : pPeer->release();
247 : :
248 : : // announce the peer to the base class
249 [ + - ][ + - ]: 40 : setPeer( pPeer );
[ + - ]
250 : :
251 : : // initialize ourself (and thus the peer) with the model properties
252 [ + - ]: 40 : updateFromModel();
253 : :
254 [ + - ][ + - ]: 40 : Reference< XView > xPeerView( getPeer(), UNO_QUERY );
255 [ + - ]: 40 : if ( xPeerView.is() )
256 : : {
257 [ + - ][ + - ]: 40 : xPeerView->setZoom( maComponentInfos.nZoomX, maComponentInfos.nZoomY );
258 [ + - ][ + - ]: 40 : xPeerView->setGraphics( mxGraphics );
259 : : }
260 : :
261 : : // a lot of initial settings from our component infos
262 [ + - ]: 40 : setPosSize( maComponentInfos.nX, maComponentInfos.nY, maComponentInfos.nWidth, maComponentInfos.nHeight, PosSize::POSSIZE );
263 : :
264 [ + - ][ - + ]: 40 : pPeer->setVisible ( maComponentInfos.bVisible && !mbDesignMode );
[ + - ]
265 [ + - ]: 40 : pPeer->setEnable ( maComponentInfos.bEnable );
266 [ + - ]: 40 : pPeer->setDesignMode( mbDesignMode );
267 : :
268 [ + - ]: 40 : peerCreated();
269 : : }
270 : :
271 : 40 : mbCreatingPeer = sal_False;
272 : :
273 [ + - ][ + - ]: 40 : OControl::initFormControlPeer( getPeer() );
274 [ + - ]: 40 : }
275 : : }
276 : :
277 : : //------------------------------------------------------------------
278 : 0 : ::rtl::OUString SAL_CALL ORichTextControl::getImplementationName() throw( RuntimeException )
279 : : {
280 : 0 : return getImplementationName_Static();
281 : : }
282 : :
283 : : //------------------------------------------------------------------
284 : 0 : Sequence< ::rtl::OUString > SAL_CALL ORichTextControl::getSupportedServiceNames() throw( RuntimeException )
285 : : {
286 : 0 : return getSupportedServiceNames_Static();
287 : : }
288 : :
289 : : //------------------------------------------------------------------
290 : 60 : ::rtl::OUString SAL_CALL ORichTextControl::getImplementationName_Static()
291 : : {
292 : 60 : return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.form.ORichTextControl" ) );
293 : : }
294 : :
295 : : //------------------------------------------------------------------
296 : 30 : Sequence< ::rtl::OUString > SAL_CALL ORichTextControl::getSupportedServiceNames_Static()
297 : : {
298 : 30 : Sequence< ::rtl::OUString > aServices( 3 );
299 [ + - ][ + - ]: 30 : aServices[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControl" ) );
300 [ + - ][ + - ]: 30 : aServices[ 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlEdit" ) );
301 [ + - ][ + - ]: 30 : aServices[ 2 ] = FRM_SUN_CONTROL_RICHTEXTCONTROL;
302 : 30 : return aServices;
303 : : }
304 : :
305 : : //------------------------------------------------------------------
306 : 80 : Reference< XInterface > SAL_CALL ORichTextControl::Create( const Reference< XMultiServiceFactory >& _rxFactory )
307 : : {
308 [ + - ]: 80 : return *( new ORichTextControl( _rxFactory ) );
309 : : }
310 : :
311 : : //--------------------------------------------------------------------
312 : 0 : Reference< XDispatch > SAL_CALL ORichTextControl::queryDispatch( const ::com::sun::star::util::URL& _rURL, const ::rtl::OUString& _rTargetFrameName, sal_Int32 _nSearchFlags ) throw (RuntimeException)
313 : : {
314 [ # # ][ # # ]: 0 : FORWARD_TO_PEER_3_RET( Reference< XDispatch >, XDispatchProvider, queryDispatch, _rURL, _rTargetFrameName, _nSearchFlags );
[ # # ][ # # ]
[ # # ][ # # ]
315 : : }
316 : :
317 : : //--------------------------------------------------------------------
318 : 0 : Sequence< Reference< XDispatch > > SAL_CALL ORichTextControl::queryDispatches( const Sequence< DispatchDescriptor >& _rRequests ) throw (RuntimeException)
319 : : {
320 [ # # ][ # # ]: 0 : FORWARD_TO_PEER_1_RET( Sequence< Reference< XDispatch > >, XDispatchProvider, queryDispatches, _rRequests );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
321 : : }
322 : :
323 : : //--------------------------------------------------------------------
324 : 178 : sal_Bool ORichTextControl::requiresNewPeer( const ::rtl::OUString& _rPropertyName ) const
325 : : {
326 [ + - ][ + - ]: 178 : return UnoControl::requiresNewPeer( _rPropertyName ) || _rPropertyName.equals( PROPERTY_RICH_TEXT );
[ + - ][ + + ]
[ + - ][ # # ]
327 : : }
328 : :
329 : : //==================================================================
330 : : // ORichTextPeer
331 : : //==================================================================
332 : : DBG_NAME( ORichTextPeer )
333 : : //------------------------------------------------------------------
334 : 40 : ORichTextPeer* ORichTextPeer::Create( const Reference< XControlModel >& _rxModel, Window* _pParentWindow, WinBits _nStyle )
335 : : {
336 : : DBG_TESTSOLARMUTEX();
337 : :
338 : : // the EditEngine of the model
339 : 40 : RichTextEngine* pEngine = ORichTextModel::getEditEngine( _rxModel );
340 : : OSL_ENSURE( pEngine, "ORichTextPeer::Create: could not obtaine the edit engine from the model!" );
341 [ - + ]: 40 : if ( !pEngine )
342 : 0 : return NULL;
343 : :
344 : : // the peer itself
345 [ + - ]: 40 : ORichTextPeer* pPeer = new ORichTextPeer;
346 : 40 : pPeer->acquire(); // by definition, the returned object is aquired once
347 : :
348 : : // the VCL control for the peer
349 [ + - ][ + - ]: 40 : RichTextControl* pRichTextControl = new RichTextControl( pEngine, _pParentWindow, _nStyle, NULL, pPeer );
350 : :
351 : : // some knittings
352 [ + - ][ + - ]: 40 : pRichTextControl->SetComponentInterface( pPeer );
353 : :
354 : : // outta here
355 : 40 : return pPeer;
356 : : }
357 : :
358 : : //------------------------------------------------------------------
359 [ + - ]: 40 : ORichTextPeer::ORichTextPeer()
360 : : {
361 : : DBG_CTOR( ORichTextPeer, NULL );
362 : 40 : }
363 : :
364 : : //------------------------------------------------------------------
365 : 36 : ORichTextPeer::~ORichTextPeer()
366 : : {
367 : : DBG_DTOR( ORichTextPeer, NULL );
368 [ - + ]: 72 : }
369 : :
370 : : //------------------------------------------------------------------
371 : 80 : void ORichTextPeer::dispose( ) throw(RuntimeException)
372 : : {
373 : : {
374 [ + - ]: 80 : SolarMutexGuard aGuard;
375 : 80 : RichTextControl* pRichTextControl = static_cast< RichTextControl* >( GetWindow() );
376 : :
377 [ + + ]: 80 : if ( pRichTextControl )
378 : : {
379 [ - + ]: 80 : for ( AttributeDispatchers::iterator aDisposeLoop = m_aDispatchers.begin();
380 : 40 : aDisposeLoop != m_aDispatchers.end();
381 : : ++aDisposeLoop
382 : : )
383 : : {
384 [ # # ]: 0 : pRichTextControl->disableAttributeNotification( aDisposeLoop->first );
385 [ # # ]: 0 : aDisposeLoop->second->dispose();
386 : : }
387 : : }
388 : :
389 [ + - ]: 80 : AttributeDispatchers aEmpty;
390 [ + - ][ + - ]: 80 : m_aDispatchers.swap( aEmpty );
391 : : }
392 : :
393 : 80 : VCLXWindow::dispose();
394 : 80 : }
395 : :
396 : : //--------------------------------------------------------------------
397 : 106 : void SAL_CALL ORichTextPeer::draw( sal_Int32 _nX, sal_Int32 _nY ) throw(::com::sun::star::uno::RuntimeException)
398 : : {
399 [ + - ]: 106 : SolarMutexGuard aGuard;
400 : :
401 : 106 : RichTextControl* pControl = static_cast< RichTextControl* >( GetWindow() );
402 [ - + ]: 106 : if ( !pControl )
403 : : return;
404 : :
405 [ + - ][ + - ]: 106 : OutputDevice* pTargetDevice = VCLUnoHelper::GetOutputDevice( getGraphics() );
406 : : OSL_ENSURE( pTargetDevice != NULL, "ORichTextPeer::draw: no graphics -> no drawing!" );
407 [ - + ]: 106 : if ( !pTargetDevice )
408 : : return;
409 : :
410 [ + - ]: 106 : ::Size aSize = pControl->GetSizePixel();
411 : 106 : const MapUnit eTargetUnit = pTargetDevice->GetMapMode().GetMapUnit();
412 [ - + ]: 106 : if ( eTargetUnit != MAP_PIXEL )
413 [ # # ][ # # ]: 0 : aSize = pControl->PixelToLogic( aSize, eTargetUnit );
[ # # ]
414 : :
415 : 106 : ::Point aPos( _nX, _nY );
416 : : // the XView::draw API talks about pixels, always ...
417 [ - + ]: 106 : if ( eTargetUnit != MAP_PIXEL )
418 [ # # ]: 0 : aPos = pTargetDevice->PixelToLogic( aPos );
419 : :
420 [ + - ][ + - ]: 106 : pControl->Draw( pTargetDevice, aPos, aSize, WINDOW_DRAW_NOCONTROLS );
[ + - ]
421 : : }
422 : :
423 : : //--------------------------------------------------------------------
424 : 5158 : void SAL_CALL ORichTextPeer::setProperty( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (RuntimeException)
425 : : {
426 [ - + ]: 5158 : if ( !GetWindow() )
427 : : {
428 : 0 : VCLXWindow::setProperty( _rPropertyName, _rValue );
429 : 5158 : return;
430 : : }
431 : :
432 [ + + ]: 5158 : if ( _rPropertyName.equals( PROPERTY_BACKGROUNDCOLOR ) )
433 : : {
434 : 40 : RichTextControl* pControl = static_cast< RichTextControl* >( GetWindow() );
435 [ + - ]: 40 : if ( !_rValue.hasValue() )
436 : : {
437 : 40 : pControl->SetBackgroundColor( );
438 : : }
439 : : else
440 : : {
441 : 0 : sal_Int32 nColor = COL_TRANSPARENT;
442 : 0 : _rValue >>= nColor;
443 [ # # ]: 0 : pControl->SetBackgroundColor( Color( nColor ) );
444 : : }
445 : : }
446 [ + + ]: 5118 : else if ( _rPropertyName.equals( PROPERTY_HSCROLL ) )
447 : : {
448 : 40 : adjustTwoStateWinBit( GetWindow(), _rValue, WB_HSCROLL );
449 : : }
450 [ + + ]: 5078 : else if ( _rPropertyName.equals( PROPERTY_VSCROLL ) )
451 : : {
452 : 40 : adjustTwoStateWinBit( GetWindow(), _rValue, WB_VSCROLL );
453 : : }
454 [ + + ]: 5038 : else if ( _rPropertyName.equals( PROPERTY_HARDLINEBREAKS ) )
455 : : {
456 : 48 : adjustTwoStateWinBit( GetWindow(), _rValue, WB_WORDBREAK, true );
457 : : }
458 [ + + ]: 4990 : else if ( _rPropertyName.equals( PROPERTY_READONLY ) )
459 : : {
460 : 48 : RichTextControl* pControl = static_cast< RichTextControl* >( GetWindow() );
461 [ + - ]: 48 : sal_Bool bReadOnly( pControl->IsReadOnly() );
462 : 48 : OSL_VERIFY( _rValue >>= bReadOnly );
463 [ + - ]: 48 : pControl->SetReadOnly( bReadOnly );
464 : :
465 : : // update the dispatchers
466 [ - + ]: 96 : for ( AttributeDispatchers::iterator aDispatcherLoop = m_aDispatchers.begin();
467 : 48 : aDispatcherLoop != m_aDispatchers.end();
468 : : ++aDispatcherLoop
469 : : )
470 : : {
471 [ # # ]: 0 : aDispatcherLoop->second->invalidate();
472 : : }
473 : : }
474 [ + + ]: 4942 : else if ( _rPropertyName.equals( PROPERTY_HIDEINACTIVESELECTION ) )
475 : : {
476 : 48 : RichTextControl* pRichTextControl = static_cast< RichTextControl* >( GetWindow() );
477 [ + - ]: 48 : sal_Bool bHide = pRichTextControl->GetHideInactiveSelection();
478 : 48 : OSL_VERIFY( _rValue >>= bHide );
479 [ + - ]: 48 : pRichTextControl->SetHideInactiveSelection( bHide );
480 : : }
481 : : else
482 : 4894 : VCLXWindow::setProperty( _rPropertyName, _rValue );
483 : : }
484 : :
485 : : //------------------------------------------------------------------
486 [ + + ][ + - ]: 21312 : IMPLEMENT_FORWARD_XINTERFACE2( ORichTextPeer, VCLXWindow, ORichTextPeer_Base )
487 : :
488 : : //------------------------------------------------------------------
489 [ # # ][ # # ]: 0 : IMPLEMENT_FORWARD_XTYPEPROVIDER2( ORichTextPeer, VCLXWindow, ORichTextPeer_Base )
[ # # ]
490 : :
491 : : //--------------------------------------------------------------------
492 : : namespace
493 : : {
494 : 0 : static SfxSlotId lcl_translateConflictingSlot( SfxSlotId _nIDFromPool )
495 : : {
496 : : // HACK HACK HACK
497 : : // unfortunately, some of our applications have some conflicting slots,
498 : : // i.e. slots which have the same UNO name as an existing other (common)
499 : : // slot.
500 : : // For instance, both the slots SID_SET_SUPER_SCRIPT (from SVX) and FN_SET_SUPER_SCRIPT
501 : : // (from SW) have the UNO name "SuperScript".
502 : : // Now, if the controls lives in a text document, and asks the SfxSlotPool for
503 : : // the id belonging to "SuperScript", it gets the FN_SET_SUPER_SCRIPT - which
504 : : // is completely unknown to the EditEngine.
505 : : // So, we need to translate such conflicting ids.
506 : : //
507 : : // Note that the real solution would be to fix the applications to
508 : : // *not* define conflicting slots. Alternatively, if SFX would provide a slot pool
509 : : // which is *static* (i.e. independent on the active application), then we
510 : : // would also never encounter such a conflict.
511 : 0 : SfxSlotId nReturn( _nIDFromPool );
512 [ # # # ]: 0 : switch ( _nIDFromPool )
513 : : {
514 : : case 20411: /* FM_SET_SUPER_SCRIPT, originating in SW */
515 : 0 : nReturn = SID_SET_SUPER_SCRIPT;
516 : 0 : break;
517 : : case 20412: /* FN_SET_SUB_SCRIPT, originating in SW */
518 : 0 : nReturn = SID_SET_SUB_SCRIPT;
519 : 0 : break;
520 : : }
521 : 0 : return nReturn;
522 : : }
523 : : }
524 : :
525 : : //--------------------------------------------------------------------
526 : 0 : ORichTextPeer::SingleAttributeDispatcher ORichTextPeer::implCreateDispatcher( SfxSlotId _nSlotId, const ::com::sun::star::util::URL& _rURL )
527 : : {
528 : 0 : RichTextControl* pRichTextControl = static_cast< RichTextControl* >( GetWindow() );
529 : : OSL_PRECOND( pRichTextControl, "ORichTextPeer::implCreateDispatcher: invalid window!" );
530 [ # # ]: 0 : if ( !pRichTextControl )
531 [ # # ]: 0 : return SingleAttributeDispatcher( NULL );
532 : :
533 : 0 : ORichTextFeatureDispatcher* pDispatcher = NULL;
534 : 0 : OAttributeDispatcher* pAttributeDispatcher = NULL;
535 [ # # # # : 0 : switch ( _nSlotId )
# # # # ]
536 : : {
537 : : case SID_CUT:
538 [ # # ][ # # ]: 0 : pDispatcher = new OClipboardDispatcher( pRichTextControl->getView(), OClipboardDispatcher::eCut );
539 : 0 : break;
540 : :
541 : : case SID_COPY:
542 [ # # ][ # # ]: 0 : pDispatcher = new OClipboardDispatcher( pRichTextControl->getView(), OClipboardDispatcher::eCopy );
543 : 0 : break;
544 : :
545 : : case SID_PASTE:
546 [ # # ][ # # ]: 0 : pDispatcher = new OPasteClipboardDispatcher( pRichTextControl->getView() );
547 : 0 : break;
548 : :
549 : : case SID_SELECTALL:
550 [ # # ][ # # ]: 0 : pDispatcher = new OSelectAllDispatcher( pRichTextControl->getView(), _rURL );
551 : 0 : break;
552 : :
553 : : case SID_ATTR_PARA_LEFT_TO_RIGHT:
554 : : case SID_ATTR_PARA_RIGHT_TO_LEFT:
555 [ # # ][ # # ]: 0 : pAttributeDispatcher = new OParagraphDirectionDispatcher( pRichTextControl->getView(), _nSlotId, _rURL, pRichTextControl );
[ # # ]
556 : 0 : break;
557 : :
558 : : case SID_TEXTDIRECTION_TOP_TO_BOTTOM:
559 : : case SID_TEXTDIRECTION_LEFT_TO_RIGHT:
560 [ # # ][ # # ]: 0 : pDispatcher = new OTextDirectionDispatcher( pRichTextControl->getView(), _rURL );
561 : 0 : break;
562 : :
563 : : case SID_ATTR_PARA_HANGPUNCTUATION:
564 : : case SID_ATTR_PARA_FORBIDDEN_RULES:
565 : : case SID_ATTR_PARA_SCRIPTSPACE:
566 [ # # ][ # # ]: 0 : pAttributeDispatcher = new OAsianFontLayoutDispatcher( pRichTextControl->getView(), _nSlotId, _rURL, pRichTextControl );
[ # # ]
567 : 0 : break;
568 : :
569 : : default:
570 : : {
571 : : // is it a supported slot?
572 : 0 : bool bSupportedSlot = false;
573 [ # # ]: 0 : if ( !bSupportedSlot )
574 : : {
575 [ # # ][ # # ]: 0 : const SfxItemPool& rPool = *pRichTextControl->getView().GetEmptyItemSet().GetPool();
576 [ # # ][ # # ]: 0 : bSupportedSlot = rPool.IsInRange( rPool.GetWhich( _nSlotId ) );
577 : : }
578 [ # # ]: 0 : if ( !bSupportedSlot )
579 [ # # ]: 0 : bSupportedSlot = RichTextControl::isMappableSlot( _nSlotId );
580 : :
581 [ # # ]: 0 : if ( bSupportedSlot )
582 : : { // it's really a slot which is supported by the EditEngine
583 : :
584 : 0 : bool bNeedParametrizedDispatcher = true;
585 [ # # ][ # # ]: 0 : if ( ( _nSlotId == SID_ATTR_CHAR_POSTURE )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
586 : : || ( _nSlotId == SID_ATTR_CHAR_CJK_POSTURE )
587 : : || ( _nSlotId == SID_ATTR_CHAR_CTL_POSTURE )
588 : : || ( _nSlotId == SID_ATTR_CHAR_LATIN_POSTURE )
589 : : || ( _nSlotId == SID_ATTR_CHAR_WEIGHT )
590 : : || ( _nSlotId == SID_ATTR_CHAR_CJK_WEIGHT )
591 : : || ( _nSlotId == SID_ATTR_CHAR_CTL_WEIGHT )
592 : : || ( _nSlotId == SID_ATTR_CHAR_LATIN_WEIGHT )
593 : : || ( _nSlotId == SID_ATTR_CHAR_LANGUAGE )
594 : : || ( _nSlotId == SID_ATTR_CHAR_CJK_LANGUAGE )
595 : : || ( _nSlotId == SID_ATTR_CHAR_CTL_LANGUAGE )
596 : : || ( _nSlotId == SID_ATTR_CHAR_LATIN_LANGUAGE )
597 : : || ( _nSlotId == SID_ATTR_CHAR_CONTOUR )
598 : : || ( _nSlotId == SID_ATTR_CHAR_SHADOWED )
599 : : || ( _nSlotId == SID_ATTR_CHAR_WORDLINEMODE )
600 : : || ( _nSlotId == SID_ATTR_CHAR_COLOR )
601 : : || ( _nSlotId == SID_ATTR_CHAR_RELIEF )
602 : : || ( _nSlotId == SID_ATTR_CHAR_KERNING )
603 : : || ( _nSlotId == SID_ATTR_CHAR_AUTOKERN )
604 : : || ( _nSlotId == SID_ATTR_CHAR_SCALEWIDTH )
605 : : )
606 : : {
607 : 0 : bNeedParametrizedDispatcher = true;
608 : : }
609 [ # # ][ # # ]: 0 : else if ( ( _nSlotId == SID_ATTR_PARA_HANGPUNCTUATION )
[ # # ]
610 : : || ( _nSlotId == SID_ATTR_PARA_FORBIDDEN_RULES )
611 : : || ( _nSlotId == SID_ATTR_PARA_SCRIPTSPACE )
612 : : )
613 : : {
614 : 0 : bNeedParametrizedDispatcher = false;
615 : : }
616 : : else
617 : : {
618 [ # # ]: 0 : SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool( NULL );
619 [ # # ]: 0 : const SfxSlot* pSlot = rSlotPool.GetSlot( _nSlotId );
620 [ # # ]: 0 : const SfxType* pType = pSlot ? pSlot->GetType() : NULL;
621 [ # # ]: 0 : if ( pType )
622 : : {
623 : 0 : bNeedParametrizedDispatcher = ( pType->nAttribs > 0 );
624 : : }
625 : : }
626 : :
627 [ # # ]: 0 : if ( bNeedParametrizedDispatcher )
628 : : {
629 : : #if OSL_DEBUG_LEVEL > 0
630 : : ::rtl::OString sTrace( "ORichTextPeer::implCreateDispatcher: creating *parametrized* dispatcher for " );
631 : : sTrace += ::rtl::OString( _rURL.Complete.getStr(), _rURL.Complete.getLength(), RTL_TEXTENCODING_ASCII_US );
632 : : OSL_TRACE( "%s", sTrace.getStr() );
633 : : #endif
634 [ # # ][ # # ]: 0 : pAttributeDispatcher = new OParametrizedAttributeDispatcher( pRichTextControl->getView(), _nSlotId, _rURL, pRichTextControl );
[ # # ]
635 : : }
636 : : else
637 : : {
638 : : #if OSL_DEBUG_LEVEL > 0
639 : : ::rtl::OString sTrace( "ORichTextPeer::implCreateDispatcher: creating *normal* dispatcher for " );
640 : : sTrace += ::rtl::OString( _rURL.Complete.getStr(), _rURL.Complete.getLength(), RTL_TEXTENCODING_ASCII_US );
641 : : OSL_TRACE( "%s", sTrace.getStr() );
642 : : #endif
643 [ # # ][ # # ]: 0 : pAttributeDispatcher = new OAttributeDispatcher( pRichTextControl->getView(), _nSlotId, _rURL, pRichTextControl );
[ # # ]
644 : : }
645 : : }
646 : : #if OSL_DEBUG_LEVEL > 0
647 : : else
648 : : {
649 : : ::rtl::OString sTrace( "ORichTextPeer::implCreateDispatcher: not creating dispatcher (unsupported slot) for " );
650 : : sTrace += ::rtl::OString( _rURL.Complete.getStr(), _rURL.Complete.getLength(), RTL_TEXTENCODING_ASCII_US );
651 : : OSL_TRACE( "%s", sTrace.getStr() );
652 : : }
653 : : #endif
654 : : }
655 : 0 : break;
656 : : }
657 : :
658 [ # # ]: 0 : SingleAttributeDispatcher xDispatcher( pDispatcher );
659 [ # # ]: 0 : if ( pAttributeDispatcher )
660 : : {
661 [ # # ][ # # ]: 0 : xDispatcher = SingleAttributeDispatcher( pAttributeDispatcher );
[ # # ]
662 [ # # ][ # # ]: 0 : pRichTextControl->enableAttributeNotification( _nSlotId, pAttributeDispatcher );
663 : : }
664 : :
665 [ # # ][ # # ]: 0 : return xDispatcher;
666 : : }
667 : :
668 : : //--------------------------------------------------------------------
669 : : namespace
670 : : {
671 : 0 : SfxSlotId lcl_getSlotFromUnoName( SfxSlotPool& _rSlotPool, const ::rtl::OUString& _rUnoSlotName )
672 : : {
673 [ # # ]: 0 : const SfxSlot* pSlot = _rSlotPool.GetUnoSlot( _rUnoSlotName );
674 [ # # ]: 0 : if ( pSlot )
675 : : {
676 : : // okay, there's a slot with the given UNO name
677 : 0 : return lcl_translateConflictingSlot( pSlot->GetSlotId() );
678 : : }
679 : :
680 : : // some hard-coded slots, which do not have a UNO name at SFX level, but which
681 : : // we nevertheless need to transport via UNO mechanisms, so we need a name
682 [ # # ]: 0 : if ( _rUnoSlotName == "AllowHangingPunctuation" )
683 : 0 : return SID_ATTR_PARA_HANGPUNCTUATION;
684 [ # # ]: 0 : if ( _rUnoSlotName == "ApplyForbiddenCharacterRules" )
685 : 0 : return SID_ATTR_PARA_FORBIDDEN_RULES;
686 [ # # ]: 0 : if ( _rUnoSlotName == "UseScriptSpacing" )
687 : 0 : return SID_ATTR_PARA_SCRIPTSPACE;
688 : :
689 : : OSL_ENSURE( pSlot, "lcl_getSlotFromUnoName: unknown UNO slot name!" );
690 : 0 : return 0;
691 : : }
692 : : }
693 : :
694 : : //--------------------------------------------------------------------
695 : 0 : Reference< XDispatch > SAL_CALL ORichTextPeer::queryDispatch( const ::com::sun::star::util::URL& _rURL, const ::rtl::OUString& /*_rTargetFrameName*/, sal_Int32 /*_nSearchFlags*/ ) throw (RuntimeException)
696 : : {
697 : 0 : Reference< XDispatch > xReturn;
698 [ # # ]: 0 : if ( !GetWindow() )
699 : : {
700 : : OSL_FAIL( "ORichTextPeer::queryDispatch: already disposed?" );
701 : : return xReturn;
702 : : }
703 : :
704 : : // is it an UNO slot?
705 [ # # ]: 0 : ::rtl::OUString sUnoProtocolPrefix( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ) );
706 [ # # ]: 0 : if ( 0 == _rURL.Complete.compareTo( sUnoProtocolPrefix, sUnoProtocolPrefix.getLength() ) )
707 : : {
708 : 0 : ::rtl::OUString sUnoSlotName = _rURL.Complete.copy( sUnoProtocolPrefix.getLength() );
709 [ # # ][ # # ]: 0 : SfxSlotId nSlotId = lcl_getSlotFromUnoName( SfxSlotPool::GetSlotPool( NULL ), sUnoSlotName );
710 [ # # ]: 0 : if ( nSlotId > 0 )
711 : : {
712 : : // do we already have a dispatcher for this?
713 [ # # ]: 0 : AttributeDispatchers::const_iterator aDispatcherPos = m_aDispatchers.find( nSlotId );
714 [ # # ]: 0 : if ( aDispatcherPos == m_aDispatchers.end() )
715 : : {
716 [ # # ]: 0 : SingleAttributeDispatcher pDispatcher = implCreateDispatcher( nSlotId, _rURL );
717 [ # # ]: 0 : if ( pDispatcher.is() )
718 : : {
719 [ # # ][ # # ]: 0 : aDispatcherPos = m_aDispatchers.insert( AttributeDispatchers::value_type( nSlotId, pDispatcher ) ).first;
[ # # ]
720 [ # # ]: 0 : }
721 : : }
722 : :
723 [ # # ]: 0 : if ( aDispatcherPos != m_aDispatchers.end() )
724 [ # # ]: 0 : xReturn = aDispatcherPos->second.getRef();
725 : 0 : }
726 : : }
727 : :
728 : 0 : return xReturn;
729 : : }
730 : :
731 : : //--------------------------------------------------------------------
732 : 0 : Sequence< Reference< XDispatch > > SAL_CALL ORichTextPeer::queryDispatches( const Sequence< DispatchDescriptor >& _rRequests ) throw (RuntimeException)
733 : : {
734 : 0 : Sequence< Reference< XDispatch > > aReturn( _rRequests.getLength() );
735 [ # # ]: 0 : Reference< XDispatch >* pReturn = aReturn.getArray();
736 : :
737 : 0 : const DispatchDescriptor* pRequest = _rRequests.getConstArray();
738 : 0 : const DispatchDescriptor* pRequestEnd = pRequest + _rRequests.getLength();
739 [ # # ]: 0 : for ( ; pRequest != pRequestEnd; ++pRequest, ++pReturn )
740 : : {
741 [ # # ][ # # ]: 0 : *pReturn = queryDispatch( pRequest->FeatureURL, pRequest->FrameName, pRequest->SearchFlags );
742 : : }
743 : 0 : return aReturn;
744 : : }
745 : :
746 : : //--------------------------------------------------------------------
747 : 0 : void ORichTextPeer::onSelectionChanged( const ESelection& /*_rSelection*/ )
748 : : {
749 [ # # ]: 0 : AttributeDispatchers::iterator aDispatcherPos = m_aDispatchers.find( SID_COPY );
750 [ # # ]: 0 : if ( aDispatcherPos != m_aDispatchers.end() )
751 [ # # ]: 0 : aDispatcherPos->second.get()->invalidate();
752 : :
753 [ # # ]: 0 : aDispatcherPos = m_aDispatchers.find( SID_CUT );
754 [ # # ]: 0 : if ( aDispatcherPos != m_aDispatchers.end() )
755 [ # # ]: 0 : aDispatcherPos->second.get()->invalidate();
756 : 0 : }
757 : :
758 : : //........................................................................
759 : : } // namespace frm
760 : : //........................................................................
761 : :
762 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|