1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svtools.hxx" 30 31 32 #include <memory> 33 34 #include "unoiface.hxx" 35 36 #include <tools/rc.h> 37 38 #include <vcl/decoview.hxx> 39 #include <vcl/svapp.hxx> 40 41 #include <svtools/svmedit.hxx> 42 #include <svtools/xtextedt.hxx> 43 #include <svl/brdcst.hxx> 44 #include <svl/undo.hxx> 45 #include <svtools/textwindowpeer.hxx> 46 #include <svl/lstner.hxx> 47 #include <svl/smplhint.hxx> 48 49 50 // IDs erstmal aus VCL geklaut, muss mal richtig delivert werden... 51 #define SV_MENU_EDIT_UNDO 1 52 #define SV_MENU_EDIT_CUT 2 53 #define SV_MENU_EDIT_COPY 3 54 #define SV_MENU_EDIT_PASTE 4 55 #define SV_MENU_EDIT_DELETE 5 56 #define SV_MENU_EDIT_SELECTALL 6 57 #define SV_MENU_EDIT_INSERTSYMBOL 7 58 #include <vcl/scrbar.hxx> 59 60 namespace css = ::com::sun::star; 61 62 class TextWindow : public Window 63 { 64 private: 65 ExtTextEngine* mpExtTextEngine; 66 ExtTextView* mpExtTextView; 67 68 sal_Bool mbInMBDown; 69 sal_Bool mbFocusSelectionHide; 70 sal_Bool mbIgnoreTab; 71 sal_Bool mbActivePopup; 72 sal_Bool mbSelectOnTab; 73 74 public: 75 TextWindow( Window* pParent ); 76 ~TextWindow(); 77 78 ExtTextEngine* GetTextEngine() const { return mpExtTextEngine; } 79 ExtTextView* GetTextView() const { return mpExtTextView; } 80 81 virtual void MouseMove( const MouseEvent& rMEvt ); 82 virtual void MouseButtonDown( const MouseEvent& rMEvt ); 83 virtual void MouseButtonUp( const MouseEvent& rMEvt ); 84 virtual void KeyInput( const KeyEvent& rKEvent ); 85 86 virtual void Command( const CommandEvent& rCEvt ); 87 88 virtual void Paint( const Rectangle& rRect ); 89 virtual void Resize(); 90 91 virtual void GetFocus(); 92 virtual void LoseFocus(); 93 94 sal_Bool IsAutoFocusHide() const { return mbFocusSelectionHide; } 95 void SetAutoFocusHide( sal_Bool bAutoHide ) { mbFocusSelectionHide = bAutoHide; } 96 97 sal_Bool IsIgnoreTab() const { return mbIgnoreTab; } 98 void SetIgnoreTab( sal_Bool bIgnore ) { mbIgnoreTab = bIgnore; } 99 100 void DisableSelectionOnFocus() {mbSelectOnTab = sal_False;} 101 102 virtual 103 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > 104 GetComponentInterface(sal_Bool bCreate = sal_True); 105 }; 106 107 108 class ImpSvMEdit : public SfxListener 109 { 110 private: 111 MultiLineEdit* pSvMultiLineEdit; 112 113 TextWindow* mpTextWindow; 114 ScrollBar* mpHScrollBar; 115 ScrollBar* mpVScrollBar; 116 ScrollBarBox* mpScrollBox; 117 118 Point maTextWindowOffset; 119 xub_StrLen mnTextWidth; 120 mutable Selection maSelection; 121 122 protected: 123 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); 124 void ImpUpdateSrollBarVis( WinBits nWinStyle ); 125 void ImpInitScrollBars(); 126 void ImpSetScrollBarRanges(); 127 void ImpSetHScrollBarThumbPos(); 128 DECL_LINK( ScrollHdl, ScrollBar* ); 129 130 public: 131 ImpSvMEdit( MultiLineEdit* pSvMultiLineEdit, WinBits nWinStyle ); 132 ~ImpSvMEdit(); 133 134 void SetModified( sal_Bool bMod ); 135 sal_Bool IsModified() const; 136 137 void SetReadOnly( sal_Bool bRdOnly ); 138 sal_Bool IsReadOnly() const; 139 140 void SetMaxTextLen( xub_StrLen nLen ); 141 xub_StrLen GetMaxTextLen() const; 142 143 void SetInsertMode( sal_Bool bInsert ); 144 sal_Bool IsInsertMode() const; 145 146 void InsertText( const String& rStr ); 147 String GetSelected() const; 148 String GetSelected( LineEnd aSeparator ) const; 149 150 void SetSelection( const Selection& rSelection ); 151 const Selection& GetSelection() const; 152 153 void Cut(); 154 void Copy(); 155 void Paste(); 156 157 void SetText( const String& rStr ); 158 String GetText() const; 159 String GetText( LineEnd aSeparator ) const; 160 String GetTextLines() const; 161 String GetTextLines( LineEnd aSeparator ) const; 162 163 void Resize(); 164 void GetFocus(); 165 166 sal_Bool HandleCommand( const CommandEvent& rCEvt ); 167 168 void Enable( sal_Bool bEnable ); 169 170 Size CalcMinimumSize() const; 171 Size CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const; 172 void GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const; 173 174 void SetAlign( WinBits nWinStyle ); 175 176 void InitFromStyle( WinBits nWinStyle ); 177 178 TextWindow* GetTextWindow() { return mpTextWindow; } 179 ScrollBar* GetHScrollBar() { return mpHScrollBar; } 180 ScrollBar* GetVScrollBar() { return mpVScrollBar; } 181 182 void SetTextWindowOffset( const Point& rOffset ); 183 }; 184 185 ImpSvMEdit::ImpSvMEdit( MultiLineEdit* pEdt, WinBits nWinStyle ) 186 :mpHScrollBar(NULL) 187 ,mpVScrollBar(NULL) 188 ,mpScrollBox(NULL) 189 { 190 pSvMultiLineEdit = pEdt; 191 mnTextWidth = 0; 192 mpTextWindow = new TextWindow( pEdt ); 193 mpTextWindow->Show(); 194 InitFromStyle( nWinStyle ); 195 StartListening( *mpTextWindow->GetTextEngine() ); 196 } 197 198 void ImpSvMEdit::ImpUpdateSrollBarVis( WinBits nWinStyle ) 199 { 200 const sal_Bool bHaveVScroll = (NULL != mpVScrollBar); 201 const sal_Bool bHaveHScroll = (NULL != mpHScrollBar); 202 const sal_Bool bHaveScrollBox = (NULL != mpScrollBox); 203 204 sal_Bool bNeedVScroll = ( nWinStyle & WB_VSCROLL ) == WB_VSCROLL; 205 const sal_Bool bNeedHScroll = ( nWinStyle & WB_HSCROLL ) == WB_HSCROLL; 206 207 const sal_Bool bAutoVScroll = ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL; 208 if ( !bNeedVScroll && bAutoVScroll ) 209 { 210 TextEngine& rEngine( *mpTextWindow->GetTextEngine() ); 211 sal_uLong nOverallTextHeight(0); 212 for ( sal_uLong i=0; i<rEngine.GetParagraphCount(); ++i ) 213 nOverallTextHeight += rEngine.GetTextHeight( i ); 214 if ( nOverallTextHeight > (sal_uLong)mpTextWindow->GetOutputSizePixel().Height() ) 215 bNeedVScroll = true; 216 } 217 218 const sal_Bool bNeedScrollBox = bNeedVScroll && bNeedHScroll; 219 220 sal_Bool bScrollbarsChanged = false; 221 if ( bHaveVScroll != bNeedVScroll ) 222 { 223 delete mpVScrollBar; 224 mpVScrollBar = bNeedVScroll ? new ScrollBar( pSvMultiLineEdit, WB_VSCROLL|WB_DRAG ) : NULL; 225 226 if ( bNeedVScroll ) 227 { 228 mpVScrollBar->Show(); 229 mpVScrollBar->SetScrollHdl( LINK( this, ImpSvMEdit, ScrollHdl ) ); 230 } 231 232 bScrollbarsChanged = sal_True; 233 } 234 235 if ( bHaveHScroll != bNeedHScroll ) 236 { 237 delete mpHScrollBar; 238 mpHScrollBar = bNeedHScroll ? new ScrollBar( pSvMultiLineEdit, WB_HSCROLL|WB_DRAG ) : NULL; 239 240 if ( bNeedHScroll ) 241 { 242 mpHScrollBar->Show(); 243 mpHScrollBar->SetScrollHdl( LINK( this, ImpSvMEdit, ScrollHdl ) ); 244 } 245 246 bScrollbarsChanged = sal_True; 247 } 248 249 if ( bHaveScrollBox != bNeedScrollBox ) 250 { 251 delete mpScrollBox; 252 mpScrollBox = bNeedScrollBox ? new ScrollBarBox( pSvMultiLineEdit, WB_SIZEABLE ) : NULL; 253 254 if ( bNeedScrollBox ) 255 mpScrollBox->Show(); 256 } 257 258 if ( bScrollbarsChanged ) 259 { 260 ImpInitScrollBars(); 261 Resize(); 262 } 263 } 264 265 void ImpSvMEdit::InitFromStyle( WinBits nWinStyle ) 266 { 267 ImpUpdateSrollBarVis( nWinStyle ); 268 SetAlign( nWinStyle ); 269 270 if ( nWinStyle & WB_NOHIDESELECTION ) 271 mpTextWindow->SetAutoFocusHide( sal_False ); 272 else 273 mpTextWindow->SetAutoFocusHide( sal_True ); 274 275 if ( nWinStyle & WB_READONLY ) 276 mpTextWindow->GetTextView()->SetReadOnly( sal_True ); 277 else 278 mpTextWindow->GetTextView()->SetReadOnly( sal_False ); 279 280 if ( nWinStyle & WB_IGNORETAB ) 281 { 282 mpTextWindow->SetIgnoreTab( sal_True ); 283 } 284 else 285 { 286 mpTextWindow->SetIgnoreTab( sal_False ); 287 // #103667# MultiLineEdit has the flag, but focusable window also needs this flag 288 WinBits nStyle = mpTextWindow->GetStyle(); 289 nStyle |= WINDOW_DLGCTRL_MOD1TAB; 290 mpTextWindow->SetStyle( nStyle ); 291 } 292 } 293 294 ImpSvMEdit::~ImpSvMEdit() 295 { 296 EndListening( *mpTextWindow->GetTextEngine() ); 297 delete mpTextWindow; 298 delete mpHScrollBar; 299 delete mpVScrollBar; 300 delete mpScrollBox; 301 } 302 303 void ImpSvMEdit::ImpSetScrollBarRanges() 304 { 305 if ( mpVScrollBar ) 306 { 307 sal_uLong nTextHeight = mpTextWindow->GetTextEngine()->GetTextHeight(); 308 mpVScrollBar->SetRange( Range( 0, (long)nTextHeight-1 ) ); 309 } 310 if ( mpHScrollBar ) 311 { 312 // sal_uLong nTextWidth = mpTextWindow->GetTextEngine()->CalcTextWidth(); 313 // Es gibt kein Notify bei Breiten-Aenderung... 314 // sal_uLong nW = Max( (sal_uLong)mpTextWindow->GetOutputSizePixel().Width()*5, (sal_uLong)nTextWidth ); 315 // mpHScrollBar->SetRange( Range( 0, (long)nW ) ); 316 mpHScrollBar->SetRange( Range( 0, (long)mnTextWidth-1 ) ); 317 } 318 } 319 320 void ImpSvMEdit::ImpInitScrollBars() 321 { 322 static const sal_Unicode sampleText[] = { 'x', '\0' }; 323 if ( mpHScrollBar || mpVScrollBar ) 324 { 325 ImpSetScrollBarRanges(); 326 Size aCharBox; 327 aCharBox.Width() = mpTextWindow->GetTextWidth( sampleText ); 328 aCharBox.Height() = mpTextWindow->GetTextHeight(); 329 Size aOutSz = mpTextWindow->GetOutputSizePixel(); 330 if ( mpHScrollBar ) 331 { 332 mpHScrollBar->SetVisibleSize( aOutSz.Width() ); 333 mpHScrollBar->SetPageSize( aOutSz.Width() * 8 / 10 ); 334 mpHScrollBar->SetLineSize( aCharBox.Width()*10 ); 335 ImpSetHScrollBarThumbPos(); 336 } 337 if ( mpVScrollBar ) 338 { 339 mpVScrollBar->SetVisibleSize( aOutSz.Height() ); 340 mpVScrollBar->SetPageSize( aOutSz.Height() * 8 / 10 ); 341 mpVScrollBar->SetLineSize( aCharBox.Height() ); 342 mpVScrollBar->SetThumbPos( mpTextWindow->GetTextView()->GetStartDocPos().Y() ); 343 } 344 } 345 } 346 347 void ImpSvMEdit::ImpSetHScrollBarThumbPos() 348 { 349 long nX = mpTextWindow->GetTextView()->GetStartDocPos().X(); 350 if ( !mpTextWindow->GetTextEngine()->IsRightToLeft() ) 351 mpHScrollBar->SetThumbPos( nX ); 352 else 353 mpHScrollBar->SetThumbPos( mnTextWidth - mpHScrollBar->GetVisibleSize() - nX ); 354 355 } 356 357 IMPL_LINK( ImpSvMEdit, ScrollHdl, ScrollBar*, pCurScrollBar ) 358 { 359 long nDiffX = 0, nDiffY = 0; 360 361 if ( pCurScrollBar == mpVScrollBar ) 362 nDiffY = mpTextWindow->GetTextView()->GetStartDocPos().Y() - pCurScrollBar->GetThumbPos(); 363 else if ( pCurScrollBar == mpHScrollBar ) 364 nDiffX = mpTextWindow->GetTextView()->GetStartDocPos().X() - pCurScrollBar->GetThumbPos(); 365 366 mpTextWindow->GetTextView()->Scroll( nDiffX, nDiffY ); 367 // mpTextWindow->GetTextView()->ShowCursor( sal_False, sal_True ); 368 369 return 0; 370 } 371 372 373 // void ImpSvMEdit::ImpModified() 374 // { 375 // // Wann wird das gerufen ????????????????????? 376 // pSvMultiLineEdit->Modify(); 377 // } 378 379 void ImpSvMEdit::SetAlign( WinBits nWinStyle ) 380 { 381 sal_Bool bRTL = Application::GetSettings().GetLayoutRTL(); 382 mpTextWindow->GetTextEngine()->SetRightToLeft( bRTL ); 383 384 if ( nWinStyle & WB_CENTER ) 385 mpTextWindow->GetTextEngine()->SetTextAlign( TXTALIGN_CENTER ); 386 else if ( nWinStyle & WB_RIGHT ) 387 mpTextWindow->GetTextEngine()->SetTextAlign( !bRTL ? TXTALIGN_RIGHT : TXTALIGN_LEFT ); 388 else if ( nWinStyle & WB_LEFT ) 389 mpTextWindow->GetTextEngine()->SetTextAlign( !bRTL ? TXTALIGN_LEFT : TXTALIGN_RIGHT ); 390 } 391 392 void ImpSvMEdit::SetTextWindowOffset( const Point& rOffset ) 393 { 394 maTextWindowOffset = rOffset; 395 Resize(); 396 } 397 398 void ImpSvMEdit::SetModified( sal_Bool bMod ) 399 { 400 mpTextWindow->GetTextEngine()->SetModified( bMod ); 401 } 402 403 sal_Bool ImpSvMEdit::IsModified() const 404 { 405 return mpTextWindow->GetTextEngine()->IsModified(); 406 } 407 408 void ImpSvMEdit::SetInsertMode( sal_Bool bInsert ) 409 { 410 mpTextWindow->GetTextView()->SetInsertMode( bInsert ); 411 } 412 413 void ImpSvMEdit::SetReadOnly( sal_Bool bRdOnly ) 414 { 415 mpTextWindow->GetTextView()->SetReadOnly( bRdOnly ); 416 // Farbe anpassen ??????????????????????????? 417 } 418 419 sal_Bool ImpSvMEdit::IsReadOnly() const 420 { 421 return mpTextWindow->GetTextView()->IsReadOnly(); 422 } 423 424 void ImpSvMEdit::SetMaxTextLen( xub_StrLen nLen ) 425 { 426 mpTextWindow->GetTextEngine()->SetMaxTextLen( nLen ); 427 } 428 429 xub_StrLen ImpSvMEdit::GetMaxTextLen() const 430 { 431 return sal::static_int_cast< xub_StrLen >( 432 mpTextWindow->GetTextEngine()->GetMaxTextLen()); 433 } 434 435 void ImpSvMEdit::InsertText( const String& rStr ) 436 { 437 mpTextWindow->GetTextView()->InsertText( rStr ); 438 } 439 440 String ImpSvMEdit::GetSelected() const 441 { 442 return mpTextWindow->GetTextView()->GetSelected(); 443 } 444 445 String ImpSvMEdit::GetSelected( LineEnd aSeparator ) const 446 { 447 return mpTextWindow->GetTextView()->GetSelected( aSeparator ); 448 } 449 450 void ImpSvMEdit::Resize() 451 { 452 size_t nIteration = 1; 453 do 454 { 455 WinBits nWinStyle( pSvMultiLineEdit->GetStyle() ); 456 if ( ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL ) 457 ImpUpdateSrollBarVis( nWinStyle ); 458 459 Size aSz = pSvMultiLineEdit->GetOutputSizePixel(); 460 Size aEditSize = aSz; 461 long nSBWidth = pSvMultiLineEdit->GetSettings().GetStyleSettings().GetScrollBarSize(); 462 nSBWidth = pSvMultiLineEdit->CalcZoom( nSBWidth ); 463 464 if ( mpHScrollBar ) 465 aSz.Height() -= nSBWidth+1; 466 if ( mpVScrollBar ) 467 aSz.Width() -= nSBWidth+1; 468 469 if ( !mpHScrollBar ) 470 mpTextWindow->GetTextEngine()->SetMaxTextWidth( aSz.Width() ); 471 else 472 mpHScrollBar->SetPosSizePixel( 0, aEditSize.Height()-nSBWidth, aSz.Width(), nSBWidth ); 473 474 Point aTextWindowPos( maTextWindowOffset ); 475 if ( mpVScrollBar ) 476 { 477 if( Application::GetSettings().GetLayoutRTL() ) 478 { 479 mpVScrollBar->SetPosSizePixel( 0, 0, nSBWidth, aSz.Height() ); 480 aTextWindowPos.X() += nSBWidth; 481 } 482 else 483 mpVScrollBar->SetPosSizePixel( aEditSize.Width()-nSBWidth, 0, nSBWidth, aSz.Height() ); 484 } 485 486 if ( mpScrollBox ) 487 mpScrollBox->SetPosSizePixel( aSz.Width(), aSz.Height(), nSBWidth, nSBWidth ); 488 489 Size aTextWindowSize( aSz ); 490 aTextWindowSize.Width() -= maTextWindowOffset.X(); 491 aTextWindowSize.Height() -= maTextWindowOffset.Y(); 492 if ( aTextWindowSize.Width() < 0 ) 493 aTextWindowSize.Width() = 0; 494 if ( aTextWindowSize.Height() < 0 ) 495 aTextWindowSize.Height() = 0; 496 497 Size aOldTextWindowSize( mpTextWindow->GetSizePixel() ); 498 mpTextWindow->SetPosSizePixel( aTextWindowPos, aTextWindowSize ); 499 if ( aOldTextWindowSize == aTextWindowSize ) 500 break; 501 502 // Changing the text window size might effectively have changed the need for 503 // scrollbars, so do another iteration. 504 ++nIteration; 505 OSL_ENSURE( nIteration < 3, "ImpSvMEdit::Resize: isn't this expected to terminate with the second iteration?" ); 506 507 } while ( nIteration <= 3 ); // artificial break after four iterations 508 509 ImpInitScrollBars(); 510 } 511 512 void ImpSvMEdit::GetFocus() 513 { 514 mpTextWindow->GrabFocus(); 515 } 516 517 void ImpSvMEdit::Cut() 518 { 519 if ( !mpTextWindow->GetTextView()->IsReadOnly() ) 520 mpTextWindow->GetTextView()->Cut(); 521 } 522 523 void ImpSvMEdit::Copy() 524 { 525 mpTextWindow->GetTextView()->Copy(); 526 } 527 528 void ImpSvMEdit::Paste() 529 { 530 if ( !mpTextWindow->GetTextView()->IsReadOnly() ) 531 mpTextWindow->GetTextView()->Paste(); 532 } 533 534 void ImpSvMEdit::SetText( const String& rStr ) 535 { 536 sal_Bool bWasModified = mpTextWindow->GetTextEngine()->IsModified(); 537 mpTextWindow->GetTextEngine()->SetText( rStr ); 538 if ( !bWasModified ) 539 mpTextWindow->GetTextEngine()->SetModified( sal_False ); 540 541 mpTextWindow->GetTextView()->SetSelection( TextSelection() ); 542 543 WinBits nWinStyle( pSvMultiLineEdit->GetStyle() ); 544 if ( ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL ) 545 ImpUpdateSrollBarVis( nWinStyle ); 546 } 547 548 String ImpSvMEdit::GetText() const 549 { 550 return mpTextWindow->GetTextEngine()->GetText(); 551 } 552 553 String ImpSvMEdit::GetText( LineEnd aSeparator ) const 554 { 555 return mpTextWindow->GetTextEngine()->GetText( aSeparator ); 556 } 557 558 String ImpSvMEdit::GetTextLines() const 559 { 560 return mpTextWindow->GetTextEngine()->GetTextLines(); 561 } 562 563 String ImpSvMEdit::GetTextLines( LineEnd aSeparator ) const 564 { 565 return mpTextWindow->GetTextEngine()->GetTextLines( aSeparator ); 566 } 567 568 void ImpSvMEdit::Notify( SfxBroadcaster&, const SfxHint& rHint ) 569 { 570 if ( rHint.ISA( TextHint ) ) 571 { 572 const TextHint& rTextHint = (const TextHint&)rHint; 573 if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED ) 574 { 575 if ( mpHScrollBar ) 576 ImpSetHScrollBarThumbPos(); 577 if ( mpVScrollBar ) 578 mpVScrollBar->SetThumbPos( mpTextWindow->GetTextView()->GetStartDocPos().Y() ); 579 } 580 else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED ) 581 { 582 if ( mpTextWindow->GetTextView()->GetStartDocPos().Y() ) 583 { 584 long nOutHeight = mpTextWindow->GetOutputSizePixel().Height(); 585 long nTextHeight = mpTextWindow->GetTextEngine()->GetTextHeight(); 586 if ( nTextHeight < nOutHeight ) 587 mpTextWindow->GetTextView()->Scroll( 0, mpTextWindow->GetTextView()->GetStartDocPos().Y() ); 588 } 589 590 ImpSetScrollBarRanges(); 591 } 592 else if( rTextHint.GetId() == TEXT_HINT_TEXTFORMATTED ) 593 { 594 if ( mpHScrollBar ) 595 { 596 sal_uLong nWidth = mpTextWindow->GetTextEngine()->CalcTextWidth(); 597 if ( nWidth != mnTextWidth ) 598 { 599 mnTextWidth = sal::static_int_cast< xub_StrLen >(nWidth); 600 mpHScrollBar->SetRange( Range( 0, (long)mnTextWidth-1 ) ); 601 ImpSetHScrollBarThumbPos(); 602 } 603 } 604 } 605 else if( rTextHint.GetId() == TEXT_HINT_MODIFIED ) 606 { 607 pSvMultiLineEdit->Modify(); 608 } 609 } 610 } 611 612 void ImpSvMEdit::SetSelection( const Selection& rSelection ) 613 { 614 String aText = mpTextWindow->GetTextEngine()->GetText(); 615 616 Selection aNewSelection( rSelection ); 617 if ( aNewSelection.Min() < 0 ) 618 aNewSelection.Min() = 0; 619 else if ( aNewSelection.Min() > aText.Len() ) 620 aNewSelection.Min() = aText.Len(); 621 if ( aNewSelection.Max() < 0 ) 622 aNewSelection.Max() = 0; 623 else if ( aNewSelection.Max() > aText.Len() ) 624 aNewSelection.Max() = aText.Len(); 625 626 long nEnd = Max( aNewSelection.Min(), aNewSelection.Max() ); 627 TextSelection aTextSel; 628 sal_uLong nPara = 0; 629 sal_uInt16 nChar = 0; 630 sal_uInt16 x = 0; 631 while ( x <= nEnd ) 632 { 633 if ( x == aNewSelection.Min() ) 634 aTextSel.GetStart() = TextPaM( nPara, nChar ); 635 if ( x == aNewSelection.Max() ) 636 aTextSel.GetEnd() = TextPaM( nPara, nChar ); 637 638 if ( ( x < aText.Len() ) && ( aText.GetChar( x ) == '\n' ) ) 639 { 640 nPara++; 641 nChar = 0; 642 } 643 else 644 nChar++; 645 x++; 646 } 647 mpTextWindow->GetTextView()->SetSelection( aTextSel ); 648 } 649 650 const Selection& ImpSvMEdit::GetSelection() const 651 { 652 maSelection = Selection(); 653 TextSelection aTextSel( mpTextWindow->GetTextView()->GetSelection() ); 654 aTextSel.Justify(); 655 // Selektion flachklopfen => jeder Umbruch ein Zeichen... 656 657 ExtTextEngine* pExtTextEngine = mpTextWindow->GetTextEngine(); 658 // Absaetze davor: 659 sal_uLong n; 660 for ( n = 0; n < aTextSel.GetStart().GetPara(); n++ ) 661 { 662 maSelection.Min() += pExtTextEngine->GetTextLen( n ); 663 maSelection.Min()++; 664 } 665 666 // Erster Absatz mit Selektion: 667 maSelection.Max() = maSelection.Min(); 668 maSelection.Min() += aTextSel.GetStart().GetIndex(); 669 670 for ( n = aTextSel.GetStart().GetPara(); n < aTextSel.GetEnd().GetPara(); n++ ) 671 { 672 maSelection.Max() += pExtTextEngine->GetTextLen( n ); 673 maSelection.Max()++; 674 } 675 676 maSelection.Max() += aTextSel.GetEnd().GetIndex(); 677 678 return maSelection; 679 } 680 681 Size ImpSvMEdit::CalcMinimumSize() const 682 { 683 Size aSz( mpTextWindow->GetTextEngine()->CalcTextWidth(), 684 mpTextWindow->GetTextEngine()->GetTextHeight() ); 685 686 if ( mpHScrollBar ) 687 aSz.Height() += mpHScrollBar->GetSizePixel().Height(); 688 if ( mpVScrollBar ) 689 aSz.Width() += mpVScrollBar->GetSizePixel().Width(); 690 691 return aSz; 692 } 693 694 Size ImpSvMEdit::CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const 695 { 696 static const sal_Unicode sampleText[] = { 'X', '\0' }; 697 698 Size aSz; 699 Size aCharSz; 700 aCharSz.Width() = mpTextWindow->GetTextWidth( sampleText ); 701 aCharSz.Height() = mpTextWindow->GetTextHeight(); 702 703 if ( nLines ) 704 aSz.Height() = nLines*aCharSz.Height(); 705 else 706 aSz.Height() = mpTextWindow->GetTextEngine()->GetTextHeight(); 707 708 if ( nColumns ) 709 aSz.Width() = nColumns*aCharSz.Width(); 710 else 711 aSz.Width() = mpTextWindow->GetTextEngine()->CalcTextWidth(); 712 713 if ( mpHScrollBar ) 714 aSz.Height() += mpHScrollBar->GetSizePixel().Height(); 715 if ( mpVScrollBar ) 716 aSz.Width() += mpVScrollBar->GetSizePixel().Width(); 717 718 return aSz; 719 } 720 721 void ImpSvMEdit::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const 722 { 723 static const sal_Unicode sampleText[] = { 'x', '\0' }; 724 Size aOutSz = mpTextWindow->GetOutputSizePixel(); 725 Size aCharSz( mpTextWindow->GetTextWidth( sampleText ), mpTextWindow->GetTextHeight() ); 726 rnCols = (sal_uInt16) (aOutSz.Width()/aCharSz.Width()); 727 rnLines = (sal_uInt16) (aOutSz.Height()/aCharSz.Height()); 728 } 729 730 void ImpSvMEdit::Enable( sal_Bool bEnable ) 731 { 732 mpTextWindow->Enable( bEnable ); 733 if ( mpHScrollBar ) 734 mpHScrollBar->Enable( bEnable ); 735 if ( mpVScrollBar ) 736 mpVScrollBar->Enable( bEnable ); 737 } 738 739 sal_Bool ImpSvMEdit::HandleCommand( const CommandEvent& rCEvt ) 740 { 741 sal_Bool bDone = sal_False; 742 if ( ( rCEvt.GetCommand() == COMMAND_WHEEL ) || 743 ( rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL ) || 744 ( rCEvt.GetCommand() == COMMAND_AUTOSCROLL ) ) 745 { 746 mpTextWindow->HandleScrollCommand( rCEvt, mpHScrollBar, mpVScrollBar ); 747 bDone = sal_True; 748 } 749 return bDone; 750 } 751 752 753 TextWindow::TextWindow( Window* pParent ) : Window( pParent ) 754 { 755 mbInMBDown = sal_False; 756 mbSelectOnTab = sal_True; 757 mbFocusSelectionHide = sal_False; 758 mbIgnoreTab = sal_False; 759 mbActivePopup = sal_False; 760 mbSelectOnTab = sal_True; 761 762 SetPointer( Pointer( POINTER_TEXT ) ); 763 764 mpExtTextEngine = new ExtTextEngine; 765 mpExtTextEngine->SetMaxTextLen( STRING_MAXLEN ); 766 if( pParent->GetStyle() & WB_BORDER ) 767 mpExtTextEngine->SetLeftMargin( 2 ); 768 mpExtTextEngine->SetLocale( GetSettings().GetLocale() ); 769 mpExtTextView = new ExtTextView( mpExtTextEngine, this ); 770 mpExtTextEngine->InsertView( mpExtTextView ); 771 mpExtTextEngine->EnableUndo( sal_True ); 772 mpExtTextView->ShowCursor(); 773 774 Color aBackgroundColor = GetSettings().GetStyleSettings().GetWorkspaceColor(); 775 SetBackground( aBackgroundColor ); 776 pParent->SetBackground( aBackgroundColor ); 777 } 778 779 TextWindow::~TextWindow() 780 { 781 delete mpExtTextView; 782 delete mpExtTextEngine; 783 } 784 785 void TextWindow::MouseMove( const MouseEvent& rMEvt ) 786 { 787 mpExtTextView->MouseMove( rMEvt ); 788 Window::MouseMove( rMEvt ); 789 } 790 791 void TextWindow::MouseButtonDown( const MouseEvent& rMEvt ) 792 { 793 mbInMBDown = sal_True; // Dann im GetFocus nicht alles selektieren wird 794 mpExtTextView->MouseButtonDown( rMEvt ); 795 Window::MouseButtonDown( rMEvt ); 796 GrabFocus(); 797 mbInMBDown = sal_False; 798 } 799 800 void TextWindow::MouseButtonUp( const MouseEvent& rMEvt ) 801 { 802 mpExtTextView->MouseButtonUp( rMEvt ); 803 Window::MouseButtonUp( rMEvt ); 804 } 805 806 void TextWindow::KeyInput( const KeyEvent& rKEvent ) 807 { 808 sal_Bool bDone = sal_False; 809 sal_uInt16 nCode = rKEvent.GetKeyCode().GetCode(); 810 if ( nCode == com::sun::star::awt::Key::SELECT_ALL || 811 ( (nCode == KEY_A) && rKEvent.GetKeyCode().IsMod1() && !rKEvent.GetKeyCode().IsMod2() ) 812 ) 813 { 814 mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFF, 0xFFFF ) ) ); 815 bDone = sal_True; 816 } 817 else if ( (nCode == KEY_S) && rKEvent.GetKeyCode().IsShift() && rKEvent.GetKeyCode().IsMod1() ) 818 { 819 if ( Edit::GetGetSpecialCharsFunction() ) 820 { 821 // Damit die Selektion erhalten bleibt 822 mbActivePopup = sal_True; 823 XubString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() ); 824 if ( aChars.Len() ) 825 { 826 mpExtTextView->InsertText( aChars ); 827 mpExtTextView->GetTextEngine()->SetModified( sal_True ); 828 } 829 mbActivePopup = sal_False; 830 bDone = sal_True; 831 } 832 } 833 else if ( nCode == KEY_TAB ) 834 { 835 if ( !mbIgnoreTab || rKEvent.GetKeyCode().IsMod1() ) 836 bDone = mpExtTextView->KeyInput( rKEvent ); 837 } 838 else 839 { 840 bDone = mpExtTextView->KeyInput( rKEvent ); 841 } 842 843 if ( !bDone ) 844 Window::KeyInput( rKEvent ); 845 } 846 847 void TextWindow::Paint( const Rectangle& rRect ) 848 { 849 mpExtTextView->Paint( rRect ); 850 } 851 852 void TextWindow::Resize() 853 { 854 } 855 856 void TextWindow::Command( const CommandEvent& rCEvt ) 857 { 858 if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU ) 859 { 860 PopupMenu* pPopup = Edit::CreatePopupMenu(); 861 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 862 if ( rStyleSettings.GetOptions() & STYLE_OPTION_HIDEDISABLED ) 863 pPopup->SetMenuFlags( MENU_FLAG_HIDEDISABLEDENTRIES ); 864 if ( !mpExtTextView->HasSelection() ) 865 { 866 pPopup->EnableItem( SV_MENU_EDIT_CUT, sal_False ); 867 pPopup->EnableItem( SV_MENU_EDIT_COPY, sal_False ); 868 pPopup->EnableItem( SV_MENU_EDIT_DELETE, sal_False ); 869 } 870 if ( mpExtTextView->IsReadOnly() ) 871 { 872 pPopup->EnableItem( SV_MENU_EDIT_CUT, sal_False ); 873 pPopup->EnableItem( SV_MENU_EDIT_PASTE, sal_False ); 874 pPopup->EnableItem( SV_MENU_EDIT_DELETE, sal_False ); 875 pPopup->EnableItem( SV_MENU_EDIT_INSERTSYMBOL, sal_False ); 876 } 877 if ( !mpExtTextView->GetTextEngine()->HasUndoManager() || !mpExtTextView->GetTextEngine()->GetUndoManager().GetUndoActionCount() ) 878 { 879 pPopup->EnableItem( SV_MENU_EDIT_UNDO, sal_False ); 880 } 881 // if ( ( maSelection.Min() == 0 ) && ( maSelection.Max() == maText.Len() ) ) 882 // { 883 // pPopup->EnableItem( SV_MENU_EDIT_SELECTALL, sal_False ); 884 // } 885 if ( !Edit::GetGetSpecialCharsFunction() ) 886 { 887 sal_uInt16 nPos = pPopup->GetItemPos( SV_MENU_EDIT_INSERTSYMBOL ); 888 pPopup->RemoveItem( nPos ); 889 pPopup->RemoveItem( nPos-1 ); 890 } 891 892 mbActivePopup = sal_True; 893 Point aPos = rCEvt.GetMousePosPixel(); 894 if ( !rCEvt.IsMouseEvent() ) 895 { 896 // !!! Irgendwann einmal Menu zentriert in der Selektion anzeigen !!! 897 Size aSize = GetOutputSizePixel(); 898 aPos = Point( aSize.Width()/2, aSize.Height()/2 ); 899 } 900 // pPopup->RemoveDisabledEntries(); 901 sal_uInt16 n = pPopup->Execute( this, aPos ); 902 Edit::DeletePopupMenu( pPopup ); 903 switch ( n ) 904 { 905 case SV_MENU_EDIT_UNDO: mpExtTextView->Undo(); 906 mpExtTextEngine->SetModified( sal_True ); 907 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) ); 908 break; 909 case SV_MENU_EDIT_CUT: mpExtTextView->Cut(); 910 mpExtTextEngine->SetModified( sal_True ); 911 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) ); 912 break; 913 case SV_MENU_EDIT_COPY: mpExtTextView->Copy(); 914 break; 915 case SV_MENU_EDIT_PASTE: mpExtTextView->Paste(); 916 mpExtTextEngine->SetModified( sal_True ); 917 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) ); 918 break; 919 case SV_MENU_EDIT_DELETE: mpExtTextView->DeleteSelected(); 920 mpExtTextEngine->SetModified( sal_True ); 921 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) ); 922 break; 923 case SV_MENU_EDIT_SELECTALL: mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFFFFFF, 0xFFFF ) ) ); 924 break; 925 case SV_MENU_EDIT_INSERTSYMBOL: 926 { 927 XubString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() ); 928 if ( aChars.Len() ) 929 { 930 mpExtTextView->InsertText( aChars ); 931 mpExtTextEngine->SetModified( sal_True ); 932 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) ); 933 } 934 } 935 break; 936 } 937 mbActivePopup = sal_False; 938 } 939 else 940 { 941 mpExtTextView->Command( rCEvt ); 942 } 943 Window::Command( rCEvt ); 944 } 945 946 void TextWindow::GetFocus() 947 { 948 Window::GetFocus(); 949 if ( !mbActivePopup ) 950 { 951 sal_Bool bGotoCursor = !mpExtTextView->IsReadOnly(); 952 if ( mbFocusSelectionHide && IsReallyVisible() && !mpExtTextView->IsReadOnly() 953 && ( mbSelectOnTab && 954 (!mbInMBDown || ( GetSettings().GetStyleSettings().GetSelectionOptions() & SELECTION_OPTION_FOCUS ) )) ) 955 { 956 // Alles selektieren, aber nicht scrollen 957 sal_Bool bAutoScroll = mpExtTextView->IsAutoScroll(); 958 mpExtTextView->SetAutoScroll( sal_False ); 959 mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFF, 0xFFFF ) ) ); 960 mpExtTextView->SetAutoScroll( bAutoScroll ); 961 bGotoCursor = sal_False; 962 } 963 mpExtTextView->SetPaintSelection( sal_True ); 964 mpExtTextView->ShowCursor( bGotoCursor ); 965 } 966 } 967 968 void TextWindow::LoseFocus() 969 { 970 Window::LoseFocus(); 971 972 if ( mbFocusSelectionHide && !mbActivePopup ) 973 mpExtTextView->SetPaintSelection( sal_False ); 974 } 975 976 // virtual 977 ::css::uno::Reference< ::css::awt::XWindowPeer > 978 TextWindow::GetComponentInterface(sal_Bool bCreate) 979 { 980 ::css::uno::Reference< ::css::awt::XWindowPeer > xPeer( 981 Window::GetComponentInterface(false)); 982 if (!xPeer.is() && bCreate) 983 { 984 xPeer = new ::svt::TextWindowPeer(*GetTextView(), true); 985 SetComponentInterface(xPeer); 986 } 987 return xPeer; 988 } 989 990 MultiLineEdit::MultiLineEdit( Window* pParent, WinBits nWinStyle ) 991 : Edit( pParent, nWinStyle ) 992 { 993 SetType( WINDOW_MULTILINEEDIT ); 994 pImpSvMEdit = new ImpSvMEdit( this, nWinStyle ); 995 ImplInitSettings( sal_True, sal_True, sal_True ); 996 pUpdateDataTimer = 0; 997 998 SetCompoundControl( sal_True ); 999 SetStyle( ImplInitStyle( nWinStyle ) ); 1000 } 1001 1002 MultiLineEdit::MultiLineEdit( Window* pParent, const ResId& rResId ) 1003 : Edit( pParent, rResId.SetRT( RSC_MULTILINEEDIT ) ) 1004 { 1005 SetType( WINDOW_MULTILINEEDIT ); 1006 WinBits nWinStyle = rResId.GetWinBits(); 1007 pImpSvMEdit = new ImpSvMEdit( this, nWinStyle ); 1008 ImplInitSettings( sal_True, sal_True, sal_True ); 1009 pUpdateDataTimer = 0; 1010 1011 sal_uInt16 nMaxLen = Edit::GetMaxTextLen(); 1012 if ( nMaxLen ) 1013 SetMaxTextLen( nMaxLen ); 1014 1015 SetText( Edit::GetText() ); 1016 1017 if ( IsVisible() ) 1018 pImpSvMEdit->Resize(); 1019 1020 SetCompoundControl( sal_True ); 1021 SetStyle( ImplInitStyle( nWinStyle ) ); 1022 1023 // Base Edit ctor could call Show already, but that would cause problems 1024 // with accessibility, as Show might (indirectly) trigger a call to virtual 1025 // GetComponentInterface, which is the Edit's base version instead of the 1026 // MultiLineEdit's version while in the base Edit ctor: 1027 if ((GetStyle() & WB_HIDE) == 0) 1028 Show(); 1029 } 1030 1031 MultiLineEdit::~MultiLineEdit() 1032 { 1033 { 1034 ::std::auto_ptr< ImpSvMEdit > pDelete( pImpSvMEdit ); 1035 pImpSvMEdit = NULL; 1036 } 1037 delete pUpdateDataTimer; 1038 } 1039 1040 WinBits MultiLineEdit::ImplInitStyle( WinBits nStyle ) 1041 { 1042 if ( !(nStyle & WB_NOTABSTOP) ) 1043 nStyle |= WB_TABSTOP; 1044 1045 if ( !(nStyle & WB_NOGROUP) ) 1046 nStyle |= WB_GROUP; 1047 1048 if ( !(nStyle & WB_IGNORETAB )) 1049 nStyle |= WINDOW_DLGCTRL_MOD1TAB; 1050 1051 return nStyle; 1052 } 1053 1054 1055 void MultiLineEdit::ImplInitSettings( sal_Bool /*bFont*/, sal_Bool /*bForeground*/, sal_Bool bBackground ) 1056 { 1057 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 1058 1059 // Der Font muss immer mit manipuliert werden, weil die TextEngine 1060 // sich nicht um TextColor/Background kuemmert 1061 1062 Color aTextColor = rStyleSettings.GetFieldTextColor(); 1063 if ( IsControlForeground() ) 1064 aTextColor = GetControlForeground(); 1065 if ( !IsEnabled() ) 1066 aTextColor = rStyleSettings.GetDisableColor(); 1067 1068 Font aFont = rStyleSettings.GetFieldFont(); 1069 if ( IsControlFont() ) 1070 aFont.Merge( GetControlFont() ); 1071 aFont.SetTransparent( IsPaintTransparent() ); 1072 SetZoomedPointFont( aFont ); 1073 Font TheFont = GetFont(); 1074 TheFont.SetColor( aTextColor ); 1075 if( IsPaintTransparent() ) 1076 TheFont.SetFillColor( Color( COL_TRANSPARENT ) ); 1077 else 1078 TheFont.SetFillColor( IsControlBackground() ? GetControlBackground() : rStyleSettings.GetFieldColor() ); 1079 pImpSvMEdit->GetTextWindow()->SetFont( TheFont ); 1080 pImpSvMEdit->GetTextWindow()->GetTextEngine()->SetFont( TheFont ); 1081 pImpSvMEdit->GetTextWindow()->SetTextColor( aTextColor ); 1082 1083 if ( bBackground ) 1084 { 1085 if( IsPaintTransparent() ) 1086 { 1087 pImpSvMEdit->GetTextWindow()->SetPaintTransparent( sal_True ); 1088 pImpSvMEdit->GetTextWindow()->SetBackground(); 1089 pImpSvMEdit->GetTextWindow()->SetControlBackground(); 1090 SetBackground(); 1091 SetControlBackground(); 1092 } 1093 else 1094 { 1095 if( IsControlBackground() ) 1096 pImpSvMEdit->GetTextWindow()->SetBackground( GetControlBackground() ); 1097 else 1098 pImpSvMEdit->GetTextWindow()->SetBackground( rStyleSettings.GetFieldColor() ); 1099 // Auch am MultiLineEdit einstellen, weil die TextComponent 1100 // ggf. die Scrollbars hidet. 1101 SetBackground( pImpSvMEdit->GetTextWindow()->GetBackground() ); 1102 } 1103 } 1104 } 1105 1106 void MultiLineEdit::Modify() 1107 { 1108 aModifyHdlLink.Call( this ); 1109 1110 CallEventListeners( VCLEVENT_EDIT_MODIFY ); 1111 1112 if ( pUpdateDataTimer ) 1113 pUpdateDataTimer->Start(); 1114 } 1115 1116 IMPL_LINK( MultiLineEdit, ImpUpdateDataHdl, Timer*, EMPTYARG ) 1117 { 1118 UpdateData(); 1119 return 0; 1120 } 1121 1122 void MultiLineEdit::UpdateData() 1123 { 1124 aUpdateDataHdlLink.Call( this ); 1125 } 1126 1127 void MultiLineEdit::SetModifyFlag() 1128 { 1129 pImpSvMEdit->SetModified( sal_True ); 1130 } 1131 1132 void MultiLineEdit::ClearModifyFlag() 1133 { 1134 pImpSvMEdit->SetModified( sal_False ); 1135 } 1136 1137 sal_Bool MultiLineEdit::IsModified() const 1138 { 1139 return pImpSvMEdit->IsModified(); 1140 } 1141 1142 void MultiLineEdit::EnableUpdateData( sal_uLong nTimeout ) 1143 { 1144 if ( !nTimeout ) 1145 DisableUpdateData(); 1146 else 1147 { 1148 if ( !pUpdateDataTimer ) 1149 { 1150 pUpdateDataTimer = new Timer; 1151 pUpdateDataTimer->SetTimeoutHdl( LINK( this, MultiLineEdit, ImpUpdateDataHdl ) ); 1152 } 1153 pUpdateDataTimer->SetTimeout( nTimeout ); 1154 } 1155 } 1156 1157 void MultiLineEdit::SetReadOnly( sal_Bool bReadOnly ) 1158 { 1159 pImpSvMEdit->SetReadOnly( bReadOnly ); 1160 Edit::SetReadOnly( bReadOnly ); 1161 1162 // #94921# ReadOnly can be overwritten in InitFromStyle() when WB not set. 1163 WinBits nStyle = GetStyle(); 1164 if ( bReadOnly ) 1165 nStyle |= WB_READONLY; 1166 else 1167 nStyle &= ~WB_READONLY; 1168 SetStyle( nStyle ); 1169 } 1170 1171 sal_Bool MultiLineEdit::IsReadOnly() const 1172 { 1173 return pImpSvMEdit->IsReadOnly(); 1174 } 1175 1176 void MultiLineEdit::SetMaxTextLen( xub_StrLen nMaxLen ) 1177 { 1178 pImpSvMEdit->SetMaxTextLen( nMaxLen ); 1179 } 1180 1181 xub_StrLen MultiLineEdit::GetMaxTextLen() const 1182 { 1183 return pImpSvMEdit->GetMaxTextLen(); 1184 } 1185 1186 void MultiLineEdit::ReplaceSelected( const String& rStr ) 1187 { 1188 pImpSvMEdit->InsertText( rStr ); 1189 } 1190 1191 void MultiLineEdit::DeleteSelected() 1192 { 1193 pImpSvMEdit->InsertText( String() ); 1194 } 1195 1196 String MultiLineEdit::GetSelected() const 1197 { 1198 return pImpSvMEdit->GetSelected(); 1199 } 1200 1201 String MultiLineEdit::GetSelected( LineEnd aSeparator ) const 1202 { 1203 return pImpSvMEdit->GetSelected( aSeparator ); 1204 } 1205 1206 void MultiLineEdit::Cut() 1207 { 1208 pImpSvMEdit->Cut(); 1209 } 1210 1211 void MultiLineEdit::Copy() 1212 { 1213 pImpSvMEdit->Copy(); 1214 } 1215 1216 void MultiLineEdit::Paste() 1217 { 1218 pImpSvMEdit->Paste(); 1219 } 1220 1221 void MultiLineEdit::SetText( const String& rStr ) 1222 { 1223 pImpSvMEdit->SetText( rStr ); 1224 } 1225 1226 String MultiLineEdit::GetText() const 1227 { 1228 return pImpSvMEdit->GetText(); 1229 } 1230 1231 String MultiLineEdit::GetText( LineEnd aSeparator ) const 1232 { 1233 return pImpSvMEdit->GetText( aSeparator ); 1234 } 1235 1236 String MultiLineEdit::GetTextLines() const 1237 { 1238 return pImpSvMEdit->GetTextLines(); 1239 } 1240 1241 String MultiLineEdit::GetTextLines( LineEnd aSeparator ) const 1242 { 1243 return pImpSvMEdit->GetTextLines( aSeparator ); 1244 } 1245 1246 void MultiLineEdit::Resize() 1247 { 1248 pImpSvMEdit->Resize(); 1249 } 1250 1251 void MultiLineEdit::GetFocus() 1252 { 1253 if ( !pImpSvMEdit ) // might be called from within the dtor, when pImpSvMEdit == NULL is a valid state 1254 return; 1255 1256 Edit::GetFocus(); 1257 pImpSvMEdit->GetFocus(); 1258 } 1259 1260 void MultiLineEdit::SetSelection( const Selection& rSelection ) 1261 { 1262 pImpSvMEdit->SetSelection( rSelection ); 1263 } 1264 1265 const Selection& MultiLineEdit::GetSelection() const 1266 { 1267 return pImpSvMEdit->GetSelection(); 1268 } 1269 1270 Size MultiLineEdit::CalcMinimumSize() const 1271 { 1272 Size aSz = pImpSvMEdit->CalcMinimumSize(); 1273 1274 sal_Int32 nLeft, nTop, nRight, nBottom; 1275 ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom ); 1276 aSz.Width() += nLeft+nRight; 1277 aSz.Height() += nTop+nBottom; 1278 1279 return aSz; 1280 } 1281 1282 Size MultiLineEdit::CalcAdjustedSize( const Size& rPrefSize ) const 1283 { 1284 Size aSz = rPrefSize; 1285 sal_Int32 nLeft, nTop, nRight, nBottom; 1286 ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom ); 1287 1288 // In der Hoehe auf ganze Zeilen justieren 1289 1290 long nHeight = aSz.Height() - nTop - nBottom; 1291 long nLineHeight = pImpSvMEdit->CalcSize( 1, 1 ).Height(); 1292 long nLines = nHeight / nLineHeight; 1293 if ( nLines < 1 ) 1294 nLines = 1; 1295 1296 aSz.Height() = nLines * nLineHeight; 1297 aSz.Height() += nTop+nBottom; 1298 1299 return aSz; 1300 } 1301 1302 Size MultiLineEdit::CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const 1303 { 1304 Size aSz = pImpSvMEdit->CalcSize( nColumns, nLines ); 1305 1306 sal_Int32 nLeft, nTop, nRight, nBottom; 1307 ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom ); 1308 aSz.Width() += nLeft+nRight; 1309 aSz.Height() += nTop+nBottom; 1310 return aSz; 1311 } 1312 1313 void MultiLineEdit::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const 1314 { 1315 pImpSvMEdit->GetMaxVisColumnsAndLines( rnCols, rnLines ); 1316 } 1317 1318 void MultiLineEdit::StateChanged( StateChangedType nType ) 1319 { 1320 if( nType == STATE_CHANGE_ENABLE ) 1321 { 1322 pImpSvMEdit->Enable( IsEnabled() ); 1323 ImplInitSettings( sal_True, sal_False, sal_False ); 1324 } 1325 else if( nType == STATE_CHANGE_READONLY ) 1326 { 1327 pImpSvMEdit->SetReadOnly( IsReadOnly() ); 1328 } 1329 else if ( nType == STATE_CHANGE_ZOOM ) 1330 { 1331 pImpSvMEdit->GetTextWindow()->SetZoom( GetZoom() ); 1332 ImplInitSettings( sal_True, sal_False, sal_False ); 1333 Resize(); 1334 } 1335 else if ( nType == STATE_CHANGE_CONTROLFONT ) 1336 { 1337 ImplInitSettings( sal_True, sal_False, sal_False ); 1338 Resize(); 1339 Invalidate(); 1340 } 1341 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) 1342 { 1343 ImplInitSettings( sal_False, sal_True, sal_False ); 1344 Invalidate(); 1345 } 1346 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) 1347 { 1348 ImplInitSettings( sal_False, sal_False, sal_True ); 1349 Invalidate(); 1350 } 1351 else if ( nType == STATE_CHANGE_STYLE ) 1352 { 1353 pImpSvMEdit->InitFromStyle( GetStyle() ); 1354 SetStyle( ImplInitStyle( GetStyle() ) ); 1355 } 1356 else if ( nType == STATE_CHANGE_INITSHOW ) 1357 { 1358 if( IsPaintTransparent() ) 1359 { 1360 pImpSvMEdit->GetTextWindow()->SetPaintTransparent( sal_True ); 1361 pImpSvMEdit->GetTextWindow()->SetBackground(); 1362 pImpSvMEdit->GetTextWindow()->SetControlBackground(); 1363 SetBackground(); 1364 SetControlBackground(); 1365 } 1366 } 1367 1368 Control::StateChanged( nType ); 1369 } 1370 1371 void MultiLineEdit::DataChanged( const DataChangedEvent& rDCEvt ) 1372 { 1373 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && 1374 (rDCEvt.GetFlags() & SETTINGS_STYLE) ) 1375 { 1376 ImplInitSettings( sal_True, sal_True, sal_True ); 1377 Resize(); 1378 Invalidate(); 1379 } 1380 else 1381 Control::DataChanged( rDCEvt ); 1382 } 1383 1384 void MultiLineEdit::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags ) 1385 { 1386 ImplInitSettings( sal_True, sal_True, sal_True ); 1387 1388 Point aPos = pDev->LogicToPixel( rPos ); 1389 Size aSize = pDev->LogicToPixel( rSize ); 1390 Font aFont = pImpSvMEdit->GetTextWindow()->GetDrawPixelFont( pDev ); 1391 aFont.SetTransparent( sal_True ); 1392 OutDevType eOutDevType = pDev->GetOutDevType(); 1393 1394 pDev->Push(); 1395 pDev->SetMapMode(); 1396 pDev->SetFont( aFont ); 1397 pDev->SetTextFillColor(); 1398 1399 // Border/Background 1400 pDev->SetLineColor(); 1401 pDev->SetFillColor(); 1402 sal_Bool bBorder = !(nFlags & WINDOW_DRAW_NOBORDER ) && (GetStyle() & WB_BORDER); 1403 sal_Bool bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && IsControlBackground(); 1404 if ( bBorder || bBackground ) 1405 { 1406 Rectangle aRect( aPos, aSize ); 1407 if ( bBorder ) 1408 { 1409 DecorationView aDecoView( pDev ); 1410 aRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN ); 1411 } 1412 if ( bBackground ) 1413 { 1414 pDev->SetFillColor( GetControlBackground() ); 1415 pDev->DrawRect( aRect ); 1416 } 1417 } 1418 1419 // Inhalt 1420 if ( ( nFlags & WINDOW_DRAW_MONO ) || ( eOutDevType == OUTDEV_PRINTER ) ) 1421 pDev->SetTextColor( Color( COL_BLACK ) ); 1422 else 1423 { 1424 if ( !(nFlags & WINDOW_DRAW_NODISABLE ) && !IsEnabled() ) 1425 { 1426 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 1427 pDev->SetTextColor( rStyleSettings.GetDisableColor() ); 1428 } 1429 else 1430 { 1431 pDev->SetTextColor( GetTextColor() ); 1432 } 1433 } 1434 1435 XubString aText = GetText(); 1436 Size aTextSz( pDev->GetTextWidth( aText ), pDev->GetTextHeight() ); 1437 sal_uLong nLines = (sal_uLong) (aSize.Height() / aTextSz.Height()); 1438 if ( !nLines ) 1439 nLines = 1; 1440 aTextSz.Height() = nLines*aTextSz.Height(); 1441 long nOnePixel = GetDrawPixel( pDev, 1 ); 1442 long nOffX = 3*nOnePixel; 1443 long nOffY = 2*nOnePixel; 1444 1445 // Clipping? 1446 if ( ( nOffY < 0 ) || ( (nOffY+aTextSz.Height()) > aSize.Height() ) || ( (nOffX+aTextSz.Width()) > aSize.Width() ) ) 1447 { 1448 Rectangle aClip( aPos, aSize ); 1449 if ( aTextSz.Height() > aSize.Height() ) 1450 aClip.Bottom() += aTextSz.Height() - aSize.Height() + 1; // Damit HP-Drucker nicht 'weg-optimieren' 1451 pDev->IntersectClipRegion( aClip ); 1452 } 1453 1454 TextEngine aTE; 1455 aTE.SetText( GetText() ); 1456 aTE.SetMaxTextWidth( aSize.Width() ); 1457 aTE.SetFont( aFont ); 1458 aTE.SetTextAlign( pImpSvMEdit->GetTextWindow()->GetTextEngine()->GetTextAlign() ); 1459 aTE.Draw( pDev, Point( aPos.X() + nOffX, aPos.Y() + nOffY ) ); 1460 1461 pDev->Pop(); 1462 } 1463 1464 long MultiLineEdit::Notify( NotifyEvent& rNEvt ) 1465 { 1466 long nDone = 0; 1467 if( rNEvt.GetType() == EVENT_COMMAND ) 1468 { 1469 nDone = pImpSvMEdit->HandleCommand( *rNEvt.GetCommandEvent() ); 1470 } 1471 return nDone ? nDone : Edit::Notify( rNEvt ); 1472 } 1473 1474 long MultiLineEdit::PreNotify( NotifyEvent& rNEvt ) 1475 { 1476 long nDone = 0; 1477 1478 #if (OSL_DEBUG_LEVEL > 1) && defined(DBG_UTIL) 1479 if( rNEvt.GetType() == EVENT_KEYINPUT ) 1480 { 1481 const KeyEvent& rKEvent = *rNEvt.GetKeyEvent(); 1482 if ( ( rKEvent.GetKeyCode().GetCode() == KEY_W ) && rKEvent.GetKeyCode().IsMod1() && rKEvent.GetKeyCode().IsMod2() ) 1483 { 1484 SetRightToLeft( !IsRightToLeft() ); 1485 } 1486 } 1487 #endif 1488 1489 if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && ( !GetTextView()->IsCursorEnabled() ) ) 1490 { 1491 const KeyEvent& rKEvent = *rNEvt.GetKeyEvent(); 1492 if ( !rKEvent.GetKeyCode().IsShift() && ( rKEvent.GetKeyCode().GetGroup() == KEYGROUP_CURSOR ) ) 1493 { 1494 nDone = 1; 1495 TextSelection aSel = pImpSvMEdit->GetTextWindow()->GetTextView()->GetSelection(); 1496 if ( aSel.HasRange() ) 1497 { 1498 aSel.GetStart() = aSel.GetEnd(); 1499 pImpSvMEdit->GetTextWindow()->GetTextView()->SetSelection( aSel ); 1500 } 1501 else 1502 { 1503 switch ( rKEvent.GetKeyCode().GetCode() ) 1504 { 1505 case KEY_UP: 1506 { 1507 if ( pImpSvMEdit->GetVScrollBar() ) 1508 pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEUP ); 1509 } 1510 break; 1511 case KEY_DOWN: 1512 { 1513 if ( pImpSvMEdit->GetVScrollBar() ) 1514 pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEDOWN ); 1515 } 1516 break; 1517 case KEY_PAGEUP : 1518 { 1519 if ( pImpSvMEdit->GetVScrollBar() ) 1520 pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEUP ); 1521 } 1522 break; 1523 case KEY_PAGEDOWN: 1524 { 1525 if ( pImpSvMEdit->GetVScrollBar() ) 1526 pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEDOWN ); 1527 } 1528 break; 1529 case KEY_LEFT: 1530 { 1531 if ( pImpSvMEdit->GetHScrollBar() ) 1532 pImpSvMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEUP ); 1533 } 1534 break; 1535 case KEY_RIGHT: 1536 { 1537 if ( pImpSvMEdit->GetHScrollBar() ) 1538 pImpSvMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEDOWN ); 1539 } 1540 break; 1541 case KEY_HOME: 1542 { 1543 if ( rKEvent.GetKeyCode().IsMod1() ) 1544 pImpSvMEdit->GetTextWindow()->GetTextView()-> 1545 SetSelection( TextSelection( TextPaM( 0, 0 ) ) ); 1546 } 1547 break; 1548 case KEY_END: 1549 { 1550 if ( rKEvent.GetKeyCode().IsMod1() ) 1551 pImpSvMEdit->GetTextWindow()->GetTextView()-> 1552 SetSelection( TextSelection( TextPaM( 0xFFFF, 0xFFFF ) ) ); 1553 } 1554 break; 1555 default: 1556 { 1557 nDone = 0; 1558 } 1559 } 1560 } 1561 } 1562 } 1563 1564 return nDone ? nDone : Edit::PreNotify( rNEvt ); 1565 } 1566 1567 // 1568 // Internas fuer abgeleitete Klassen, z.B. TextComponent 1569 1570 ExtTextEngine* MultiLineEdit::GetTextEngine() const 1571 { 1572 return pImpSvMEdit->GetTextWindow()->GetTextEngine(); 1573 } 1574 1575 ExtTextView* MultiLineEdit::GetTextView() const 1576 { 1577 return pImpSvMEdit->GetTextWindow()->GetTextView(); 1578 } 1579 1580 ScrollBar* MultiLineEdit::GetHScrollBar() const 1581 { 1582 return pImpSvMEdit->GetHScrollBar(); 1583 } 1584 1585 1586 ScrollBar* MultiLineEdit::GetVScrollBar() const 1587 { 1588 return pImpSvMEdit->GetVScrollBar(); 1589 } 1590 1591 void MultiLineEdit::EnableFocusSelectionHide( sal_Bool bHide ) 1592 { 1593 pImpSvMEdit->GetTextWindow()->SetAutoFocusHide( bHide ); 1594 } 1595 1596 sal_Bool MultiLineEdit::IsFocusSelectionHideEnabled() const 1597 { 1598 return pImpSvMEdit->GetTextWindow()->IsAutoFocusHide(); 1599 } 1600 1601 1602 void MultiLineEdit::SetLeftMargin( sal_uInt16 n ) 1603 { 1604 if ( GetTextEngine() ) 1605 GetTextEngine()->SetLeftMargin( n ); 1606 } 1607 1608 sal_uInt16 MultiLineEdit::GetLeftMargin() const 1609 { 1610 if ( GetTextEngine() ) 1611 return GetTextEngine()->GetLeftMargin(); 1612 else 1613 return 0; 1614 } 1615 1616 void MultiLineEdit::SetRightToLeft( sal_Bool bRightToLeft ) 1617 { 1618 if ( GetTextEngine() ) 1619 { 1620 GetTextEngine()->SetRightToLeft( bRightToLeft ); 1621 GetTextView()->ShowCursor(); 1622 } 1623 } 1624 1625 sal_Bool MultiLineEdit::IsRightToLeft() const 1626 { 1627 sal_Bool bRightToLeft = sal_False; 1628 1629 if ( GetTextEngine() ) 1630 bRightToLeft = GetTextEngine()->IsRightToLeft(); 1631 1632 return bRightToLeft; 1633 } 1634 1635 // virtual 1636 ::css::uno::Reference< ::css::awt::XWindowPeer > 1637 MultiLineEdit::GetComponentInterface(sal_Bool bCreate) 1638 { 1639 ::css::uno::Reference< ::css::awt::XWindowPeer > xPeer( 1640 Edit::GetComponentInterface(false)); 1641 if (!xPeer.is() && bCreate) 1642 { 1643 ::std::auto_ptr< VCLXMultiLineEdit > xEdit(new VCLXMultiLineEdit()); 1644 xEdit->SetWindow(this); 1645 xPeer = xEdit.release(); 1646 SetComponentInterface(xPeer); 1647 } 1648 return xPeer; 1649 } 1650 /*-- 11.08.2004 11:29:23--------------------------------------------------- 1651 1652 -----------------------------------------------------------------------*/ 1653 void MultiLineEdit::DisableSelectionOnFocus() 1654 { 1655 pImpSvMEdit->GetTextWindow()->DisableSelectionOnFocus(); 1656 } 1657