xref: /aoo42x/main/vcl/source/control/ctrl.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_vcl.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <tools/diagnose_ex.h>
34*cdf0e10cSrcweir #include <tools/rc.h>
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir #include <vcl/svapp.hxx>
37*cdf0e10cSrcweir #include <vcl/event.hxx>
38*cdf0e10cSrcweir #include <vcl/ctrl.hxx>
39*cdf0e10cSrcweir #include <vcl/decoview.hxx>
40*cdf0e10cSrcweir #include <vcl/salnativewidgets.hxx>
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir #include <textlayout.hxx>
43*cdf0e10cSrcweir #include <svdata.hxx>
44*cdf0e10cSrcweir #include <controldata.hxx>
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir 
47*cdf0e10cSrcweir using namespace vcl;
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir // =======================================================================
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir void Control::ImplInitControlData()
52*cdf0e10cSrcweir {
53*cdf0e10cSrcweir     mbHasControlFocus	    = sal_False;
54*cdf0e10cSrcweir     mpControlData   = new ImplControlData;
55*cdf0e10cSrcweir }
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir // -----------------------------------------------------------------------
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir Control::Control( WindowType nType ) :
60*cdf0e10cSrcweir     Window( nType )
61*cdf0e10cSrcweir {
62*cdf0e10cSrcweir     ImplInitControlData();
63*cdf0e10cSrcweir }
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir // -----------------------------------------------------------------------
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir Control::Control( Window* pParent, WinBits nStyle ) :
68*cdf0e10cSrcweir     Window( WINDOW_CONTROL )
69*cdf0e10cSrcweir {
70*cdf0e10cSrcweir     ImplInitControlData();
71*cdf0e10cSrcweir     Window::ImplInit( pParent, nStyle, NULL );
72*cdf0e10cSrcweir }
73*cdf0e10cSrcweir 
74*cdf0e10cSrcweir // -----------------------------------------------------------------------
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir Control::Control( Window* pParent, const ResId& rResId ) :
77*cdf0e10cSrcweir     Window( WINDOW_CONTROL )
78*cdf0e10cSrcweir {
79*cdf0e10cSrcweir     ImplInitControlData();
80*cdf0e10cSrcweir     rResId.SetRT( RSC_CONTROL );
81*cdf0e10cSrcweir     WinBits nStyle = ImplInitRes( rResId );
82*cdf0e10cSrcweir     ImplInit( pParent, nStyle, NULL );
83*cdf0e10cSrcweir     ImplLoadRes( rResId );
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir     if ( !(nStyle & WB_HIDE) )
86*cdf0e10cSrcweir         Show();
87*cdf0e10cSrcweir }
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir // -----------------------------------------------------------------------
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir Control::~Control()
92*cdf0e10cSrcweir {
93*cdf0e10cSrcweir     delete mpControlData, mpControlData = NULL;
94*cdf0e10cSrcweir }
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir // -----------------------------------------------------------------------
97*cdf0e10cSrcweir 
98*cdf0e10cSrcweir void Control::GetFocus()
99*cdf0e10cSrcweir {
100*cdf0e10cSrcweir     Window::GetFocus();
101*cdf0e10cSrcweir }
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir // -----------------------------------------------------------------------
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir void Control::LoseFocus()
106*cdf0e10cSrcweir {
107*cdf0e10cSrcweir     Window::LoseFocus();
108*cdf0e10cSrcweir }
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir // -----------------------------------------------------------------------
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir void Control::Resize()
113*cdf0e10cSrcweir {
114*cdf0e10cSrcweir     ImplClearLayoutData();
115*cdf0e10cSrcweir     Window::Resize();
116*cdf0e10cSrcweir }
117*cdf0e10cSrcweir 
118*cdf0e10cSrcweir // -----------------------------------------------------------------------
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir void Control::FillLayoutData() const
121*cdf0e10cSrcweir {
122*cdf0e10cSrcweir }
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir // -----------------------------------------------------------------------
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir void Control::CreateLayoutData() const
127*cdf0e10cSrcweir {
128*cdf0e10cSrcweir 	DBG_ASSERT( !mpControlData->mpLayoutData, "Control::CreateLayoutData: should be called with non-existent layout data only!" );
129*cdf0e10cSrcweir 	mpControlData->mpLayoutData = new ::vcl::ControlLayoutData();
130*cdf0e10cSrcweir }
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir // -----------------------------------------------------------------------
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir bool Control::HasLayoutData() const
135*cdf0e10cSrcweir {
136*cdf0e10cSrcweir     return mpControlData->mpLayoutData != NULL;
137*cdf0e10cSrcweir }
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir // -----------------------------------------------------------------------
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir ::vcl::ControlLayoutData* Control::GetLayoutData() const
142*cdf0e10cSrcweir {
143*cdf0e10cSrcweir     return mpControlData->mpLayoutData;
144*cdf0e10cSrcweir }
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir // -----------------------------------------------------------------------
147*cdf0e10cSrcweir 
148*cdf0e10cSrcweir void Control::SetText( const String& rStr )
149*cdf0e10cSrcweir {
150*cdf0e10cSrcweir     ImplClearLayoutData();
151*cdf0e10cSrcweir     Window::SetText( rStr );
152*cdf0e10cSrcweir }
153*cdf0e10cSrcweir 
154*cdf0e10cSrcweir // -----------------------------------------------------------------------
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir Rectangle ControlLayoutData::GetCharacterBounds( long nIndex ) const
157*cdf0e10cSrcweir {
158*cdf0e10cSrcweir     return (nIndex >= 0 && nIndex < (long) m_aUnicodeBoundRects.size()) ? m_aUnicodeBoundRects[ nIndex ] : Rectangle();
159*cdf0e10cSrcweir }
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir // -----------------------------------------------------------------------
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir Rectangle Control::GetCharacterBounds( long nIndex ) const
165*cdf0e10cSrcweir {
166*cdf0e10cSrcweir     if( !HasLayoutData() )
167*cdf0e10cSrcweir         FillLayoutData();
168*cdf0e10cSrcweir     return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->GetCharacterBounds( nIndex ) : Rectangle();
169*cdf0e10cSrcweir }
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir // -----------------------------------------------------------------------
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir long ControlLayoutData::GetIndexForPoint( const Point& rPoint ) const
174*cdf0e10cSrcweir {
175*cdf0e10cSrcweir     long nIndex = -1;
176*cdf0e10cSrcweir     for( long i = m_aUnicodeBoundRects.size()-1; i >= 0; i-- )
177*cdf0e10cSrcweir     {
178*cdf0e10cSrcweir         if( m_aUnicodeBoundRects[ i ].IsInside( rPoint ) )
179*cdf0e10cSrcweir         {
180*cdf0e10cSrcweir             nIndex = i;
181*cdf0e10cSrcweir             break;
182*cdf0e10cSrcweir         }
183*cdf0e10cSrcweir     }
184*cdf0e10cSrcweir     return nIndex;
185*cdf0e10cSrcweir }
186*cdf0e10cSrcweir 
187*cdf0e10cSrcweir // -----------------------------------------------------------------------
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir long Control::GetIndexForPoint( const Point& rPoint ) const
190*cdf0e10cSrcweir {
191*cdf0e10cSrcweir     if( ! HasLayoutData() )
192*cdf0e10cSrcweir         FillLayoutData();
193*cdf0e10cSrcweir     return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->GetIndexForPoint( rPoint ) : -1;
194*cdf0e10cSrcweir }
195*cdf0e10cSrcweir 
196*cdf0e10cSrcweir // -----------------------------------------------------------------------
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir long ControlLayoutData::GetLineCount() const
199*cdf0e10cSrcweir {
200*cdf0e10cSrcweir     long nLines = m_aLineIndices.size();
201*cdf0e10cSrcweir     if( nLines == 0 && m_aDisplayText.Len() )
202*cdf0e10cSrcweir         nLines = 1;
203*cdf0e10cSrcweir     return nLines;
204*cdf0e10cSrcweir }
205*cdf0e10cSrcweir 
206*cdf0e10cSrcweir // -----------------------------------------------------------------------
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir long Control::GetLineCount() const
209*cdf0e10cSrcweir {
210*cdf0e10cSrcweir     if( !HasLayoutData() )
211*cdf0e10cSrcweir         FillLayoutData();
212*cdf0e10cSrcweir     return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->GetLineCount() : 0;
213*cdf0e10cSrcweir }
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir // -----------------------------------------------------------------------
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir Pair ControlLayoutData::GetLineStartEnd( long nLine ) const
218*cdf0e10cSrcweir {
219*cdf0e10cSrcweir     Pair aPair( -1, -1 );
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir     int nDisplayLines = m_aLineIndices.size();
222*cdf0e10cSrcweir     if( nLine >= 0 && nLine < nDisplayLines )
223*cdf0e10cSrcweir     {
224*cdf0e10cSrcweir         aPair.A() = m_aLineIndices[nLine];
225*cdf0e10cSrcweir         if( nLine+1 < nDisplayLines )
226*cdf0e10cSrcweir             aPair.B() = m_aLineIndices[nLine+1]-1;
227*cdf0e10cSrcweir         else
228*cdf0e10cSrcweir             aPair.B() = m_aDisplayText.Len()-1;
229*cdf0e10cSrcweir     }
230*cdf0e10cSrcweir     else if( nLine == 0 && nDisplayLines == 0 && m_aDisplayText.Len() )
231*cdf0e10cSrcweir     {
232*cdf0e10cSrcweir         // special case for single line controls so the implementations
233*cdf0e10cSrcweir         // in that case do not have to fill in the line indices
234*cdf0e10cSrcweir         aPair.A() = 0;
235*cdf0e10cSrcweir         aPair.B() = m_aDisplayText.Len()-1;
236*cdf0e10cSrcweir     }
237*cdf0e10cSrcweir     return aPair;
238*cdf0e10cSrcweir }
239*cdf0e10cSrcweir 
240*cdf0e10cSrcweir // -----------------------------------------------------------------------
241*cdf0e10cSrcweir 
242*cdf0e10cSrcweir Pair Control::GetLineStartEnd( long nLine ) const
243*cdf0e10cSrcweir {
244*cdf0e10cSrcweir     if( !HasLayoutData() )
245*cdf0e10cSrcweir         FillLayoutData();
246*cdf0e10cSrcweir     return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->GetLineStartEnd( nLine ) : Pair( -1, -1 );
247*cdf0e10cSrcweir }
248*cdf0e10cSrcweir 
249*cdf0e10cSrcweir // -----------------------------------------------------------------------
250*cdf0e10cSrcweir 
251*cdf0e10cSrcweir long ControlLayoutData::ToRelativeLineIndex( long nIndex ) const
252*cdf0e10cSrcweir {
253*cdf0e10cSrcweir     // is the index sensible at all ?
254*cdf0e10cSrcweir     if( nIndex >= 0 && nIndex < m_aDisplayText.Len() )
255*cdf0e10cSrcweir     {
256*cdf0e10cSrcweir         int nDisplayLines = m_aLineIndices.size();
257*cdf0e10cSrcweir         // if only 1 line exists, then absolute and relative index are
258*cdf0e10cSrcweir         // identical -> do nothing
259*cdf0e10cSrcweir         if( nDisplayLines > 1 )
260*cdf0e10cSrcweir         {
261*cdf0e10cSrcweir             int nLine;
262*cdf0e10cSrcweir             for( nLine = nDisplayLines-1; nLine >= 0; nLine-- )
263*cdf0e10cSrcweir             {
264*cdf0e10cSrcweir                 if( m_aLineIndices[nLine] <= nIndex )
265*cdf0e10cSrcweir                 {
266*cdf0e10cSrcweir                     nIndex -= m_aLineIndices[nLine];
267*cdf0e10cSrcweir                     break;
268*cdf0e10cSrcweir                 }
269*cdf0e10cSrcweir             }
270*cdf0e10cSrcweir             if( nLine < 0 )
271*cdf0e10cSrcweir             {
272*cdf0e10cSrcweir                 DBG_ASSERT( nLine >= 0, "ToRelativeLineIndex failed" );
273*cdf0e10cSrcweir                 nIndex = -1;
274*cdf0e10cSrcweir             }
275*cdf0e10cSrcweir         }
276*cdf0e10cSrcweir     }
277*cdf0e10cSrcweir     else
278*cdf0e10cSrcweir         nIndex = -1;
279*cdf0e10cSrcweir 
280*cdf0e10cSrcweir     return nIndex;
281*cdf0e10cSrcweir }
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir // -----------------------------------------------------------------------
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir long Control::ToRelativeLineIndex( long nIndex ) const
286*cdf0e10cSrcweir {
287*cdf0e10cSrcweir     if( !HasLayoutData() )
288*cdf0e10cSrcweir         FillLayoutData();
289*cdf0e10cSrcweir     return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->ToRelativeLineIndex( nIndex ) : -1;
290*cdf0e10cSrcweir }
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir // -----------------------------------------------------------------------
293*cdf0e10cSrcweir 
294*cdf0e10cSrcweir String Control::GetDisplayText() const
295*cdf0e10cSrcweir {
296*cdf0e10cSrcweir     if( !HasLayoutData() )
297*cdf0e10cSrcweir         FillLayoutData();
298*cdf0e10cSrcweir     return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->m_aDisplayText : GetText();
299*cdf0e10cSrcweir }
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir // -----------------------------------------------------------------------
302*cdf0e10cSrcweir 
303*cdf0e10cSrcweir long Control::Notify( NotifyEvent& rNEvt )
304*cdf0e10cSrcweir {
305*cdf0e10cSrcweir     if ( rNEvt.GetType() == EVENT_GETFOCUS )
306*cdf0e10cSrcweir     {
307*cdf0e10cSrcweir         if ( !mbHasControlFocus )
308*cdf0e10cSrcweir         {
309*cdf0e10cSrcweir             mbHasControlFocus = sal_True;
310*cdf0e10cSrcweir             StateChanged( STATE_CHANGE_CONTROL_FOCUS );
311*cdf0e10cSrcweir             if ( ImplCallEventListenersAndHandler( VCLEVENT_CONTROL_GETFOCUS, maGetFocusHdl, this ) )
312*cdf0e10cSrcweir                 // been destroyed within the handler
313*cdf0e10cSrcweir                 return sal_True;
314*cdf0e10cSrcweir         }
315*cdf0e10cSrcweir     }
316*cdf0e10cSrcweir     else
317*cdf0e10cSrcweir     {
318*cdf0e10cSrcweir         if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
319*cdf0e10cSrcweir         {
320*cdf0e10cSrcweir             Window* pFocusWin = Application::GetFocusWindow();
321*cdf0e10cSrcweir             if ( !pFocusWin || !ImplIsWindowOrChild( pFocusWin ) )
322*cdf0e10cSrcweir             {
323*cdf0e10cSrcweir                 mbHasControlFocus = sal_False;
324*cdf0e10cSrcweir                 StateChanged( STATE_CHANGE_CONTROL_FOCUS );
325*cdf0e10cSrcweir                 if ( ImplCallEventListenersAndHandler( VCLEVENT_CONTROL_LOSEFOCUS, maLoseFocusHdl, this ) )
326*cdf0e10cSrcweir                     // been destroyed within the handler
327*cdf0e10cSrcweir                     return sal_True;
328*cdf0e10cSrcweir             }
329*cdf0e10cSrcweir         }
330*cdf0e10cSrcweir     }
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir     return Window::Notify( rNEvt );
333*cdf0e10cSrcweir }
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir // -----------------------------------------------------------------------
336*cdf0e10cSrcweir 
337*cdf0e10cSrcweir void Control::StateChanged( StateChangedType nStateChange )
338*cdf0e10cSrcweir {
339*cdf0e10cSrcweir     if( nStateChange == STATE_CHANGE_INITSHOW	||
340*cdf0e10cSrcweir         nStateChange == STATE_CHANGE_VISIBLE	||
341*cdf0e10cSrcweir         nStateChange == STATE_CHANGE_FORMAT		||
342*cdf0e10cSrcweir         nStateChange == STATE_CHANGE_ZOOM		||
343*cdf0e10cSrcweir         nStateChange == STATE_CHANGE_BORDER		||
344*cdf0e10cSrcweir         nStateChange == STATE_CHANGE_CONTROLFONT
345*cdf0e10cSrcweir         )
346*cdf0e10cSrcweir     {
347*cdf0e10cSrcweir         ImplClearLayoutData();
348*cdf0e10cSrcweir     }
349*cdf0e10cSrcweir     Window::StateChanged( nStateChange );
350*cdf0e10cSrcweir }
351*cdf0e10cSrcweir 
352*cdf0e10cSrcweir // -----------------------------------------------------------------------
353*cdf0e10cSrcweir 
354*cdf0e10cSrcweir void Control::AppendLayoutData( const Control& rSubControl ) const
355*cdf0e10cSrcweir {
356*cdf0e10cSrcweir     if( !rSubControl.HasLayoutData() )
357*cdf0e10cSrcweir         rSubControl.FillLayoutData();
358*cdf0e10cSrcweir     if( !rSubControl.HasLayoutData() || !rSubControl.mpControlData->mpLayoutData->m_aDisplayText.Len() )
359*cdf0e10cSrcweir         return;
360*cdf0e10cSrcweir 
361*cdf0e10cSrcweir     long nCurrentIndex = mpControlData->mpLayoutData->m_aDisplayText.Len();
362*cdf0e10cSrcweir     mpControlData->mpLayoutData->m_aDisplayText.Append( rSubControl.mpControlData->mpLayoutData->m_aDisplayText );
363*cdf0e10cSrcweir     int nLines = rSubControl.mpControlData->mpLayoutData->m_aLineIndices.size();
364*cdf0e10cSrcweir     int n;
365*cdf0e10cSrcweir     mpControlData->mpLayoutData->m_aLineIndices.push_back( nCurrentIndex );
366*cdf0e10cSrcweir     for( n = 1; n < nLines; n++ )
367*cdf0e10cSrcweir         mpControlData->mpLayoutData->m_aLineIndices.push_back( rSubControl.mpControlData->mpLayoutData->m_aLineIndices[n] + nCurrentIndex );
368*cdf0e10cSrcweir     int nRectangles = rSubControl.mpControlData->mpLayoutData->m_aUnicodeBoundRects.size();
369*cdf0e10cSrcweir         Rectangle aRel = const_cast<Control&>(rSubControl).GetWindowExtentsRelative( const_cast<Control*>(this) );
370*cdf0e10cSrcweir     for( n = 0; n < nRectangles; n++ )
371*cdf0e10cSrcweir     {
372*cdf0e10cSrcweir         Rectangle aRect = rSubControl.mpControlData->mpLayoutData->m_aUnicodeBoundRects[n];
373*cdf0e10cSrcweir         aRect.Move( aRel.Left(), aRel.Top() );
374*cdf0e10cSrcweir         mpControlData->mpLayoutData->m_aUnicodeBoundRects.push_back( aRect );
375*cdf0e10cSrcweir     }
376*cdf0e10cSrcweir }
377*cdf0e10cSrcweir 
378*cdf0e10cSrcweir // -----------------------------------------------------------------
379*cdf0e10cSrcweir 
380*cdf0e10cSrcweir sal_Bool Control::ImplCallEventListenersAndHandler(  sal_uLong nEvent, const Link& rHandler, void* pCaller )
381*cdf0e10cSrcweir {
382*cdf0e10cSrcweir     ImplDelData aCheckDelete;
383*cdf0e10cSrcweir     ImplAddDel( &aCheckDelete );
384*cdf0e10cSrcweir 
385*cdf0e10cSrcweir     ImplCallEventListeners( nEvent );
386*cdf0e10cSrcweir     if ( !aCheckDelete.IsDelete() )
387*cdf0e10cSrcweir     {
388*cdf0e10cSrcweir     	rHandler.Call( pCaller );
389*cdf0e10cSrcweir 
390*cdf0e10cSrcweir         if ( !aCheckDelete.IsDelete() )
391*cdf0e10cSrcweir         {
392*cdf0e10cSrcweir             ImplRemoveDel( &aCheckDelete );
393*cdf0e10cSrcweir             return sal_False;
394*cdf0e10cSrcweir         }
395*cdf0e10cSrcweir     }
396*cdf0e10cSrcweir     return sal_True;
397*cdf0e10cSrcweir }
398*cdf0e10cSrcweir 
399*cdf0e10cSrcweir // -----------------------------------------------------------------
400*cdf0e10cSrcweir 
401*cdf0e10cSrcweir void Control::SetLayoutDataParent( const Control* pParent ) const
402*cdf0e10cSrcweir {
403*cdf0e10cSrcweir     if( HasLayoutData() )
404*cdf0e10cSrcweir         mpControlData->mpLayoutData->m_pParent = pParent;
405*cdf0e10cSrcweir }
406*cdf0e10cSrcweir 
407*cdf0e10cSrcweir // -----------------------------------------------------------------
408*cdf0e10cSrcweir 
409*cdf0e10cSrcweir void Control::ImplClearLayoutData() const
410*cdf0e10cSrcweir {
411*cdf0e10cSrcweir     delete mpControlData->mpLayoutData, mpControlData->mpLayoutData = NULL;
412*cdf0e10cSrcweir }
413*cdf0e10cSrcweir 
414*cdf0e10cSrcweir // -----------------------------------------------------------------------
415*cdf0e10cSrcweir 
416*cdf0e10cSrcweir void Control::ImplDrawFrame( OutputDevice* pDev, Rectangle& rRect )
417*cdf0e10cSrcweir {
418*cdf0e10cSrcweir     // use a deco view to draw the frame
419*cdf0e10cSrcweir     // However, since there happens a lot of magic there, we need to fake some (style) settings
420*cdf0e10cSrcweir     // on the device
421*cdf0e10cSrcweir     AllSettings aOriginalSettings( pDev->GetSettings() );
422*cdf0e10cSrcweir 
423*cdf0e10cSrcweir     AllSettings aNewSettings( aOriginalSettings );
424*cdf0e10cSrcweir     StyleSettings aStyle( aNewSettings.GetStyleSettings() );
425*cdf0e10cSrcweir 
426*cdf0e10cSrcweir     // The *only known* clients of the Draw methods of the various VCL-controls are form controls:
427*cdf0e10cSrcweir     // During print preview, and during printing, Draw is called. Thus, drawing always happens with a
428*cdf0e10cSrcweir     // mono (colored) border
429*cdf0e10cSrcweir     aStyle.SetOptions( aStyle.GetOptions() | STYLE_OPTION_MONO );
430*cdf0e10cSrcweir     aStyle.SetMonoColor( GetSettings().GetStyleSettings().GetMonoColor() );
431*cdf0e10cSrcweir 
432*cdf0e10cSrcweir     aNewSettings.SetStyleSettings( aStyle );
433*cdf0e10cSrcweir     // #i67023# do not call data changed listeners for this fake
434*cdf0e10cSrcweir     // since they may understandably invalidate on settings changed
435*cdf0e10cSrcweir     pDev->OutputDevice::SetSettings( aNewSettings );
436*cdf0e10cSrcweir 
437*cdf0e10cSrcweir     DecorationView aDecoView( pDev );
438*cdf0e10cSrcweir     rRect = aDecoView.DrawFrame( rRect, FRAME_DRAW_WINDOWBORDER );
439*cdf0e10cSrcweir 
440*cdf0e10cSrcweir     pDev->OutputDevice::SetSettings( aOriginalSettings );
441*cdf0e10cSrcweir }
442*cdf0e10cSrcweir 
443*cdf0e10cSrcweir // -----------------------------------------------------------------------
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir void Control::DataChanged( const DataChangedEvent& rDCEvt)
446*cdf0e10cSrcweir {
447*cdf0e10cSrcweir     // we don't want to loose some style settings for controls created with the
448*cdf0e10cSrcweir     // toolkit
449*cdf0e10cSrcweir     if ( IsCreatedWithToolkit() &&
450*cdf0e10cSrcweir          (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
451*cdf0e10cSrcweir          (rDCEvt.GetFlags() & SETTINGS_STYLE) )
452*cdf0e10cSrcweir     {
453*cdf0e10cSrcweir         AllSettings     aSettings = GetSettings();
454*cdf0e10cSrcweir         StyleSettings   aStyleSettings = aSettings.GetStyleSettings();
455*cdf0e10cSrcweir         sal_uLong           nOldOptions = rDCEvt.GetOldSettings()->GetStyleSettings().GetOptions();
456*cdf0e10cSrcweir         sal_uLong           nNewOptions = aStyleSettings.GetOptions();
457*cdf0e10cSrcweir 
458*cdf0e10cSrcweir         if ( !(nNewOptions & STYLE_OPTION_MONO) && ( nOldOptions & STYLE_OPTION_MONO ) )
459*cdf0e10cSrcweir         {
460*cdf0e10cSrcweir             nNewOptions |= STYLE_OPTION_MONO;
461*cdf0e10cSrcweir             aStyleSettings.SetOptions( nNewOptions );
462*cdf0e10cSrcweir             aStyleSettings.SetMonoColor( rDCEvt.GetOldSettings()->GetStyleSettings().GetMonoColor() );
463*cdf0e10cSrcweir             aSettings.SetStyleSettings( aStyleSettings );
464*cdf0e10cSrcweir             SetSettings( aSettings );
465*cdf0e10cSrcweir         }
466*cdf0e10cSrcweir     }
467*cdf0e10cSrcweir }
468*cdf0e10cSrcweir 
469*cdf0e10cSrcweir // -----------------------------------------------------------------
470*cdf0e10cSrcweir 
471*cdf0e10cSrcweir ControlLayoutData::~ControlLayoutData()
472*cdf0e10cSrcweir {
473*cdf0e10cSrcweir     if( m_pParent )
474*cdf0e10cSrcweir         m_pParent->ImplClearLayoutData();
475*cdf0e10cSrcweir }
476*cdf0e10cSrcweir 
477*cdf0e10cSrcweir // -----------------------------------------------------------------
478*cdf0e10cSrcweir 
479*cdf0e10cSrcweir Size Control::GetOptimalSize(WindowSizeType eType) const
480*cdf0e10cSrcweir {
481*cdf0e10cSrcweir     switch (eType) {
482*cdf0e10cSrcweir     case WINDOWSIZE_MINIMUM:
483*cdf0e10cSrcweir         return Size( GetTextWidth( GetText() ) + 2 * 12,
484*cdf0e10cSrcweir                      GetTextHeight() + 2 * 6 );
485*cdf0e10cSrcweir     case WINDOWSIZE_PREFERRED:
486*cdf0e10cSrcweir         return GetOptimalSize( WINDOWSIZE_MINIMUM );
487*cdf0e10cSrcweir     case WINDOWSIZE_MAXIMUM:
488*cdf0e10cSrcweir     default:
489*cdf0e10cSrcweir         return Size( LONG_MAX, LONG_MAX );
490*cdf0e10cSrcweir     }
491*cdf0e10cSrcweir }
492*cdf0e10cSrcweir 
493*cdf0e10cSrcweir // -----------------------------------------------------------------
494*cdf0e10cSrcweir 
495*cdf0e10cSrcweir void Control::SetReferenceDevice( OutputDevice* _referenceDevice )
496*cdf0e10cSrcweir {
497*cdf0e10cSrcweir     if ( mpControlData->mpReferenceDevice == _referenceDevice )
498*cdf0e10cSrcweir         return;
499*cdf0e10cSrcweir 
500*cdf0e10cSrcweir     mpControlData->mpReferenceDevice = _referenceDevice;
501*cdf0e10cSrcweir     Invalidate();
502*cdf0e10cSrcweir }
503*cdf0e10cSrcweir 
504*cdf0e10cSrcweir // -----------------------------------------------------------------
505*cdf0e10cSrcweir 
506*cdf0e10cSrcweir OutputDevice* Control::GetReferenceDevice() const
507*cdf0e10cSrcweir {
508*cdf0e10cSrcweir     return mpControlData->mpReferenceDevice;
509*cdf0e10cSrcweir }
510*cdf0e10cSrcweir 
511*cdf0e10cSrcweir // -----------------------------------------------------------------
512*cdf0e10cSrcweir 
513*cdf0e10cSrcweir const Font& Control::GetCanonicalFont( const StyleSettings& _rStyle ) const
514*cdf0e10cSrcweir {
515*cdf0e10cSrcweir     return _rStyle.GetLabelFont();
516*cdf0e10cSrcweir }
517*cdf0e10cSrcweir 
518*cdf0e10cSrcweir // -----------------------------------------------------------------
519*cdf0e10cSrcweir const Color& Control::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
520*cdf0e10cSrcweir {
521*cdf0e10cSrcweir     return _rStyle.GetLabelTextColor();
522*cdf0e10cSrcweir }
523*cdf0e10cSrcweir 
524*cdf0e10cSrcweir // -----------------------------------------------------------------
525*cdf0e10cSrcweir void Control::ImplInitSettings( const sal_Bool _bFont, const sal_Bool _bForeground )
526*cdf0e10cSrcweir {
527*cdf0e10cSrcweir     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
528*cdf0e10cSrcweir 
529*cdf0e10cSrcweir     if ( _bFont )
530*cdf0e10cSrcweir     {
531*cdf0e10cSrcweir         Font aFont( GetCanonicalFont( rStyleSettings ) );
532*cdf0e10cSrcweir         if ( IsControlFont() )
533*cdf0e10cSrcweir             aFont.Merge( GetControlFont() );
534*cdf0e10cSrcweir         SetZoomedPointFont( aFont );
535*cdf0e10cSrcweir     }
536*cdf0e10cSrcweir 
537*cdf0e10cSrcweir     if ( _bForeground || _bFont )
538*cdf0e10cSrcweir     {
539*cdf0e10cSrcweir         Color aColor;
540*cdf0e10cSrcweir         if ( IsControlForeground() )
541*cdf0e10cSrcweir             aColor = GetControlForeground();
542*cdf0e10cSrcweir         else
543*cdf0e10cSrcweir             aColor = GetCanonicalTextColor( rStyleSettings );
544*cdf0e10cSrcweir         SetTextColor( aColor );
545*cdf0e10cSrcweir         SetTextFillColor();
546*cdf0e10cSrcweir     }
547*cdf0e10cSrcweir }
548*cdf0e10cSrcweir 
549*cdf0e10cSrcweir // -----------------------------------------------------------------
550*cdf0e10cSrcweir 
551*cdf0e10cSrcweir void Control::DrawControlText( OutputDevice& _rTargetDevice, Rectangle& _io_rRect, const XubString& _rStr,
552*cdf0e10cSrcweir     sal_uInt16 _nStyle, MetricVector* _pVector, String* _pDisplayText ) const
553*cdf0e10cSrcweir {
554*cdf0e10cSrcweir #ifdef FS_DEBUG
555*cdf0e10cSrcweir     if ( !_pVector )
556*cdf0e10cSrcweir     {
557*cdf0e10cSrcweir         static MetricVector aCharRects;
558*cdf0e10cSrcweir         static String sDisplayText;
559*cdf0e10cSrcweir         aCharRects.clear();
560*cdf0e10cSrcweir         sDisplayText = String();
561*cdf0e10cSrcweir         _pVector = &aCharRects;
562*cdf0e10cSrcweir         _pDisplayText = &sDisplayText;
563*cdf0e10cSrcweir     }
564*cdf0e10cSrcweir #endif
565*cdf0e10cSrcweir 
566*cdf0e10cSrcweir     if ( !mpControlData->mpReferenceDevice || ( mpControlData->mpReferenceDevice == &_rTargetDevice ) )
567*cdf0e10cSrcweir     {
568*cdf0e10cSrcweir         _io_rRect = _rTargetDevice.GetTextRect( _io_rRect, _rStr, _nStyle );
569*cdf0e10cSrcweir         _rTargetDevice.DrawText( _io_rRect, _rStr, _nStyle, _pVector, _pDisplayText );
570*cdf0e10cSrcweir     }
571*cdf0e10cSrcweir     else
572*cdf0e10cSrcweir     {
573*cdf0e10cSrcweir         ControlTextRenderer aRenderer( *this, _rTargetDevice, *mpControlData->mpReferenceDevice );
574*cdf0e10cSrcweir         _io_rRect = aRenderer.DrawText( _io_rRect, _rStr, _nStyle, _pVector, _pDisplayText );
575*cdf0e10cSrcweir     }
576*cdf0e10cSrcweir 
577*cdf0e10cSrcweir #ifdef FS_DEBUG
578*cdf0e10cSrcweir     _rTargetDevice.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
579*cdf0e10cSrcweir     _rTargetDevice.SetLineColor( COL_LIGHTRED );
580*cdf0e10cSrcweir     _rTargetDevice.SetFillColor();
581*cdf0e10cSrcweir     for (   MetricVector::const_iterator cr = _pVector->begin();
582*cdf0e10cSrcweir             cr != _pVector->end();
583*cdf0e10cSrcweir             ++cr
584*cdf0e10cSrcweir         )
585*cdf0e10cSrcweir     {
586*cdf0e10cSrcweir         _rTargetDevice.DrawRect( *cr );
587*cdf0e10cSrcweir     }
588*cdf0e10cSrcweir     _rTargetDevice.Pop();
589*cdf0e10cSrcweir #endif
590*cdf0e10cSrcweir }
591