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