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