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 10cdf0e10cSrcweir * 11*9f62ea84SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 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. 19cdf0e10cSrcweir * 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 47cdf0e10cSrcweir void Control::ImplInitControlData() 48cdf0e10cSrcweir { 49cdf0e10cSrcweir mbHasControlFocus = sal_False; 50cdf0e10cSrcweir mpControlData = new ImplControlData; 51cdf0e10cSrcweir } 52cdf0e10cSrcweir 53cdf0e10cSrcweir // ----------------------------------------------------------------------- 54cdf0e10cSrcweir 55cdf0e10cSrcweir Control::Control( WindowType nType ) : 56cdf0e10cSrcweir Window( nType ) 57cdf0e10cSrcweir { 58cdf0e10cSrcweir ImplInitControlData(); 59cdf0e10cSrcweir } 60cdf0e10cSrcweir 61cdf0e10cSrcweir // ----------------------------------------------------------------------- 62cdf0e10cSrcweir 63cdf0e10cSrcweir Control::Control( Window* pParent, WinBits nStyle ) : 64cdf0e10cSrcweir Window( WINDOW_CONTROL ) 65cdf0e10cSrcweir { 66cdf0e10cSrcweir ImplInitControlData(); 67cdf0e10cSrcweir Window::ImplInit( pParent, nStyle, NULL ); 68cdf0e10cSrcweir } 69cdf0e10cSrcweir 70cdf0e10cSrcweir // ----------------------------------------------------------------------- 71cdf0e10cSrcweir 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 87cdf0e10cSrcweir Control::~Control() 88cdf0e10cSrcweir { 89cdf0e10cSrcweir delete mpControlData, mpControlData = NULL; 90cdf0e10cSrcweir } 91cdf0e10cSrcweir 92cdf0e10cSrcweir // ----------------------------------------------------------------------- 93cdf0e10cSrcweir 94cdf0e10cSrcweir void Control::GetFocus() 95cdf0e10cSrcweir { 96cdf0e10cSrcweir Window::GetFocus(); 97cdf0e10cSrcweir } 98cdf0e10cSrcweir 99cdf0e10cSrcweir // ----------------------------------------------------------------------- 100cdf0e10cSrcweir 101cdf0e10cSrcweir void Control::LoseFocus() 102cdf0e10cSrcweir { 103cdf0e10cSrcweir Window::LoseFocus(); 104cdf0e10cSrcweir } 105cdf0e10cSrcweir 106cdf0e10cSrcweir // ----------------------------------------------------------------------- 107cdf0e10cSrcweir 108cdf0e10cSrcweir void Control::Resize() 109cdf0e10cSrcweir { 110cdf0e10cSrcweir ImplClearLayoutData(); 111cdf0e10cSrcweir Window::Resize(); 112cdf0e10cSrcweir } 113cdf0e10cSrcweir 114cdf0e10cSrcweir // ----------------------------------------------------------------------- 115cdf0e10cSrcweir 116cdf0e10cSrcweir void Control::FillLayoutData() const 117cdf0e10cSrcweir { 118cdf0e10cSrcweir } 119cdf0e10cSrcweir 120cdf0e10cSrcweir // ----------------------------------------------------------------------- 121cdf0e10cSrcweir 122cdf0e10cSrcweir 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 130cdf0e10cSrcweir bool Control::HasLayoutData() const 131cdf0e10cSrcweir { 132cdf0e10cSrcweir return mpControlData->mpLayoutData != NULL; 133cdf0e10cSrcweir } 134cdf0e10cSrcweir 135cdf0e10cSrcweir // ----------------------------------------------------------------------- 136cdf0e10cSrcweir 137cdf0e10cSrcweir ::vcl::ControlLayoutData* Control::GetLayoutData() const 138cdf0e10cSrcweir { 139cdf0e10cSrcweir return mpControlData->mpLayoutData; 140cdf0e10cSrcweir } 141cdf0e10cSrcweir 142cdf0e10cSrcweir // ----------------------------------------------------------------------- 143cdf0e10cSrcweir 144cdf0e10cSrcweir void Control::SetText( const String& rStr ) 145cdf0e10cSrcweir { 146cdf0e10cSrcweir ImplClearLayoutData(); 147cdf0e10cSrcweir Window::SetText( rStr ); 148cdf0e10cSrcweir } 149cdf0e10cSrcweir 150cdf0e10cSrcweir // ----------------------------------------------------------------------- 151cdf0e10cSrcweir 152cdf0e10cSrcweir 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 160cdf0e10cSrcweir 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 169cdf0e10cSrcweir 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 185cdf0e10cSrcweir 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 194cdf0e10cSrcweir 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 204cdf0e10cSrcweir long Control::GetLineCount() const 205cdf0e10cSrcweir { 206cdf0e10cSrcweir if( !HasLayoutData() ) 207cdf0e10cSrcweir FillLayoutData(); 208cdf0e10cSrcweir return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->GetLineCount() : 0; 209cdf0e10cSrcweir } 210cdf0e10cSrcweir 211cdf0e10cSrcweir // ----------------------------------------------------------------------- 212cdf0e10cSrcweir 213cdf0e10cSrcweir 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 238cdf0e10cSrcweir 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 247cdf0e10cSrcweir 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 281cdf0e10cSrcweir 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 290cdf0e10cSrcweir String Control::GetDisplayText() const 291cdf0e10cSrcweir { 292cdf0e10cSrcweir if( !HasLayoutData() ) 293cdf0e10cSrcweir FillLayoutData(); 294cdf0e10cSrcweir return mpControlData->mpLayoutData ? mpControlData->mpLayoutData->m_aDisplayText : GetText(); 295cdf0e10cSrcweir } 296cdf0e10cSrcweir 297cdf0e10cSrcweir // ----------------------------------------------------------------------- 298cdf0e10cSrcweir 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 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 350cdf0e10cSrcweir 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 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 397cdf0e10cSrcweir void Control::SetLayoutDataParent( const Control* pParent ) const 398cdf0e10cSrcweir { 399cdf0e10cSrcweir if( HasLayoutData() ) 400cdf0e10cSrcweir mpControlData->mpLayoutData->m_pParent = pParent; 401cdf0e10cSrcweir } 402cdf0e10cSrcweir 403cdf0e10cSrcweir // ----------------------------------------------------------------- 404cdf0e10cSrcweir 405cdf0e10cSrcweir void Control::ImplClearLayoutData() const 406cdf0e10cSrcweir { 407cdf0e10cSrcweir delete mpControlData->mpLayoutData, mpControlData->mpLayoutData = NULL; 408cdf0e10cSrcweir } 409cdf0e10cSrcweir 410cdf0e10cSrcweir // ----------------------------------------------------------------------- 411cdf0e10cSrcweir 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 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 467cdf0e10cSrcweir ControlLayoutData::~ControlLayoutData() 468cdf0e10cSrcweir { 469cdf0e10cSrcweir if( m_pParent ) 470cdf0e10cSrcweir m_pParent->ImplClearLayoutData(); 471cdf0e10cSrcweir } 472cdf0e10cSrcweir 473cdf0e10cSrcweir // ----------------------------------------------------------------- 474cdf0e10cSrcweir 475cdf0e10cSrcweir 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 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 502cdf0e10cSrcweir OutputDevice* Control::GetReferenceDevice() const 503cdf0e10cSrcweir { 504cdf0e10cSrcweir return mpControlData->mpReferenceDevice; 505cdf0e10cSrcweir } 506cdf0e10cSrcweir 507cdf0e10cSrcweir // ----------------------------------------------------------------- 508cdf0e10cSrcweir 509cdf0e10cSrcweir const Font& Control::GetCanonicalFont( const StyleSettings& _rStyle ) const 510cdf0e10cSrcweir { 511cdf0e10cSrcweir return _rStyle.GetLabelFont(); 512cdf0e10cSrcweir } 513cdf0e10cSrcweir 514cdf0e10cSrcweir // ----------------------------------------------------------------- 515cdf0e10cSrcweir const Color& Control::GetCanonicalTextColor( const StyleSettings& _rStyle ) const 516cdf0e10cSrcweir { 517cdf0e10cSrcweir return _rStyle.GetLabelTextColor(); 518cdf0e10cSrcweir } 519cdf0e10cSrcweir 520cdf0e10cSrcweir // ----------------------------------------------------------------- 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 547cdf0e10cSrcweir 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