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