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 if ( !mbActivePopup ) 946 { 947 sal_Bool bGotoCursor = !mpExtTextView->IsReadOnly(); 948 if ( mbFocusSelectionHide && IsReallyVisible() && !mpExtTextView->IsReadOnly() 949 && ( mbSelectOnTab && 950 (!mbInMBDown || ( GetSettings().GetStyleSettings().GetSelectionOptions() & SELECTION_OPTION_FOCUS ) )) ) 951 { 952 // Alles selektieren, aber nicht scrollen 953 sal_Bool bAutoScroll = mpExtTextView->IsAutoScroll(); 954 mpExtTextView->SetAutoScroll( sal_False ); 955 mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFF, 0xFFFF ) ) ); 956 mpExtTextView->SetAutoScroll( bAutoScroll ); 957 bGotoCursor = sal_False; 958 } 959 mpExtTextView->SetPaintSelection( sal_True ); 960 mpExtTextView->ShowCursor( bGotoCursor ); 961 } 962 } 963 964 void TextWindow::LoseFocus() 965 { 966 Window::LoseFocus(); 967 968 if ( mbFocusSelectionHide && !mbActivePopup ) 969 mpExtTextView->SetPaintSelection( sal_False ); 970 } 971 972 // virtual 973 ::css::uno::Reference< ::css::awt::XWindowPeer > 974 TextWindow::GetComponentInterface(sal_Bool bCreate) 975 { 976 ::css::uno::Reference< ::css::awt::XWindowPeer > xPeer( 977 Window::GetComponentInterface(false)); 978 if (!xPeer.is() && bCreate) 979 { 980 xPeer = new ::svt::TextWindowPeer(*GetTextView(), true); 981 SetComponentInterface(xPeer); 982 } 983 return xPeer; 984 } 985 986 MultiLineEdit::MultiLineEdit( Window* pParent, WinBits nWinStyle ) 987 : Edit( pParent, nWinStyle ) 988 { 989 SetType( WINDOW_MULTILINEEDIT ); 990 pImpSvMEdit = new ImpSvMEdit( this, nWinStyle ); 991 ImplInitSettings( sal_True, sal_True, sal_True ); 992 pUpdateDataTimer = 0; 993 994 SetCompoundControl( sal_True ); 995 SetStyle( ImplInitStyle( nWinStyle ) ); 996 } 997 998 MultiLineEdit::MultiLineEdit( Window* pParent, const ResId& rResId ) 999 : Edit( pParent, rResId.SetRT( RSC_MULTILINEEDIT ) ) 1000 { 1001 SetType( WINDOW_MULTILINEEDIT ); 1002 WinBits nWinStyle = rResId.GetWinBits(); 1003 pImpSvMEdit = new ImpSvMEdit( this, nWinStyle ); 1004 ImplInitSettings( sal_True, sal_True, sal_True ); 1005 pUpdateDataTimer = 0; 1006 1007 sal_uInt16 nMaxLen = Edit::GetMaxTextLen(); 1008 if ( nMaxLen ) 1009 SetMaxTextLen( nMaxLen ); 1010 1011 SetText( Edit::GetText() ); 1012 1013 if ( IsVisible() ) 1014 pImpSvMEdit->Resize(); 1015 1016 SetCompoundControl( sal_True ); 1017 SetStyle( ImplInitStyle( nWinStyle ) ); 1018 1019 // Base Edit ctor could call Show already, but that would cause problems 1020 // with accessibility, as Show might (indirectly) trigger a call to virtual 1021 // GetComponentInterface, which is the Edit's base version instead of the 1022 // MultiLineEdit's version while in the base Edit ctor: 1023 if ((GetStyle() & WB_HIDE) == 0) 1024 Show(); 1025 } 1026 1027 MultiLineEdit::~MultiLineEdit() 1028 { 1029 { 1030 ::std::auto_ptr< ImpSvMEdit > pDelete( pImpSvMEdit ); 1031 pImpSvMEdit = NULL; 1032 } 1033 delete pUpdateDataTimer; 1034 } 1035 1036 WinBits MultiLineEdit::ImplInitStyle( WinBits nStyle ) 1037 { 1038 if ( !(nStyle & WB_NOTABSTOP) ) 1039 nStyle |= WB_TABSTOP; 1040 1041 if ( !(nStyle & WB_NOGROUP) ) 1042 nStyle |= WB_GROUP; 1043 1044 if ( !(nStyle & WB_IGNORETAB )) 1045 nStyle |= WINDOW_DLGCTRL_MOD1TAB; 1046 1047 return nStyle; 1048 } 1049 1050 1051 void MultiLineEdit::ImplInitSettings( sal_Bool /*bFont*/, sal_Bool /*bForeground*/, sal_Bool bBackground ) 1052 { 1053 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 1054 1055 // Der Font muss immer mit manipuliert werden, weil die TextEngine 1056 // sich nicht um TextColor/Background kuemmert 1057 1058 Color aTextColor = rStyleSettings.GetFieldTextColor(); 1059 if ( IsControlForeground() ) 1060 aTextColor = GetControlForeground(); 1061 if ( !IsEnabled() ) 1062 aTextColor = rStyleSettings.GetDisableColor(); 1063 1064 Font aFont = rStyleSettings.GetFieldFont(); 1065 if ( IsControlFont() ) 1066 aFont.Merge( GetControlFont() ); 1067 aFont.SetTransparent( IsPaintTransparent() ); 1068 SetZoomedPointFont( aFont ); 1069 Font TheFont = GetFont(); 1070 TheFont.SetColor( aTextColor ); 1071 if( IsPaintTransparent() ) 1072 TheFont.SetFillColor( Color( COL_TRANSPARENT ) ); 1073 else 1074 TheFont.SetFillColor( IsControlBackground() ? GetControlBackground() : rStyleSettings.GetFieldColor() ); 1075 pImpSvMEdit->GetTextWindow()->SetFont( TheFont ); 1076 pImpSvMEdit->GetTextWindow()->GetTextEngine()->SetFont( TheFont ); 1077 pImpSvMEdit->GetTextWindow()->SetTextColor( aTextColor ); 1078 1079 if ( bBackground ) 1080 { 1081 if( IsPaintTransparent() ) 1082 { 1083 pImpSvMEdit->GetTextWindow()->SetPaintTransparent( sal_True ); 1084 pImpSvMEdit->GetTextWindow()->SetBackground(); 1085 pImpSvMEdit->GetTextWindow()->SetControlBackground(); 1086 SetBackground(); 1087 SetControlBackground(); 1088 } 1089 else 1090 { 1091 if( IsControlBackground() ) 1092 pImpSvMEdit->GetTextWindow()->SetBackground( GetControlBackground() ); 1093 else 1094 pImpSvMEdit->GetTextWindow()->SetBackground( rStyleSettings.GetFieldColor() ); 1095 // Auch am MultiLineEdit einstellen, weil die TextComponent 1096 // ggf. die Scrollbars hidet. 1097 SetBackground( pImpSvMEdit->GetTextWindow()->GetBackground() ); 1098 } 1099 } 1100 } 1101 1102 void MultiLineEdit::Modify() 1103 { 1104 aModifyHdlLink.Call( this ); 1105 1106 CallEventListeners( VCLEVENT_EDIT_MODIFY ); 1107 1108 if ( pUpdateDataTimer ) 1109 pUpdateDataTimer->Start(); 1110 } 1111 1112 IMPL_LINK( MultiLineEdit, ImpUpdateDataHdl, Timer*, EMPTYARG ) 1113 { 1114 UpdateData(); 1115 return 0; 1116 } 1117 1118 void MultiLineEdit::UpdateData() 1119 { 1120 aUpdateDataHdlLink.Call( this ); 1121 } 1122 1123 void MultiLineEdit::SetModifyFlag() 1124 { 1125 pImpSvMEdit->SetModified( sal_True ); 1126 } 1127 1128 void MultiLineEdit::ClearModifyFlag() 1129 { 1130 pImpSvMEdit->SetModified( sal_False ); 1131 } 1132 1133 sal_Bool MultiLineEdit::IsModified() const 1134 { 1135 return pImpSvMEdit->IsModified(); 1136 } 1137 1138 void MultiLineEdit::EnableUpdateData( sal_uLong nTimeout ) 1139 { 1140 if ( !nTimeout ) 1141 DisableUpdateData(); 1142 else 1143 { 1144 if ( !pUpdateDataTimer ) 1145 { 1146 pUpdateDataTimer = new Timer; 1147 pUpdateDataTimer->SetTimeoutHdl( LINK( this, MultiLineEdit, ImpUpdateDataHdl ) ); 1148 } 1149 pUpdateDataTimer->SetTimeout( nTimeout ); 1150 } 1151 } 1152 1153 void MultiLineEdit::SetReadOnly( sal_Bool bReadOnly ) 1154 { 1155 pImpSvMEdit->SetReadOnly( bReadOnly ); 1156 Edit::SetReadOnly( bReadOnly ); 1157 1158 // #94921# ReadOnly can be overwritten in InitFromStyle() when WB not set. 1159 WinBits nStyle = GetStyle(); 1160 if ( bReadOnly ) 1161 nStyle |= WB_READONLY; 1162 else 1163 nStyle &= ~WB_READONLY; 1164 SetStyle( nStyle ); 1165 } 1166 1167 sal_Bool MultiLineEdit::IsReadOnly() const 1168 { 1169 return pImpSvMEdit->IsReadOnly(); 1170 } 1171 1172 void MultiLineEdit::SetMaxTextLen( xub_StrLen nMaxLen ) 1173 { 1174 pImpSvMEdit->SetMaxTextLen( nMaxLen ); 1175 } 1176 1177 xub_StrLen MultiLineEdit::GetMaxTextLen() const 1178 { 1179 return pImpSvMEdit->GetMaxTextLen(); 1180 } 1181 1182 void MultiLineEdit::ReplaceSelected( const String& rStr ) 1183 { 1184 pImpSvMEdit->InsertText( rStr ); 1185 } 1186 1187 void MultiLineEdit::DeleteSelected() 1188 { 1189 pImpSvMEdit->InsertText( String() ); 1190 } 1191 1192 String MultiLineEdit::GetSelected() const 1193 { 1194 return pImpSvMEdit->GetSelected(); 1195 } 1196 1197 String MultiLineEdit::GetSelected( LineEnd aSeparator ) const 1198 { 1199 return pImpSvMEdit->GetSelected( aSeparator ); 1200 } 1201 1202 void MultiLineEdit::Cut() 1203 { 1204 pImpSvMEdit->Cut(); 1205 } 1206 1207 void MultiLineEdit::Copy() 1208 { 1209 pImpSvMEdit->Copy(); 1210 } 1211 1212 void MultiLineEdit::Paste() 1213 { 1214 pImpSvMEdit->Paste(); 1215 } 1216 1217 void MultiLineEdit::SetText( const String& rStr ) 1218 { 1219 pImpSvMEdit->SetText( rStr ); 1220 } 1221 1222 String MultiLineEdit::GetText() const 1223 { 1224 return pImpSvMEdit->GetText(); 1225 } 1226 1227 String MultiLineEdit::GetText( LineEnd aSeparator ) const 1228 { 1229 return pImpSvMEdit->GetText( aSeparator ); 1230 } 1231 1232 String MultiLineEdit::GetTextLines() const 1233 { 1234 return pImpSvMEdit->GetTextLines(); 1235 } 1236 1237 String MultiLineEdit::GetTextLines( LineEnd aSeparator ) const 1238 { 1239 return pImpSvMEdit->GetTextLines( aSeparator ); 1240 } 1241 1242 void MultiLineEdit::Resize() 1243 { 1244 pImpSvMEdit->Resize(); 1245 } 1246 1247 void MultiLineEdit::GetFocus() 1248 { 1249 if ( !pImpSvMEdit ) // might be called from within the dtor, when pImpSvMEdit == NULL is a valid state 1250 return; 1251 //Disable the focused event on scroll pane 1252 //Edit::GetFocus(); 1253 pImpSvMEdit->GetFocus(); 1254 } 1255 1256 void MultiLineEdit::SetSelection( const Selection& rSelection ) 1257 { 1258 pImpSvMEdit->SetSelection( rSelection ); 1259 } 1260 1261 const Selection& MultiLineEdit::GetSelection() const 1262 { 1263 return pImpSvMEdit->GetSelection(); 1264 } 1265 1266 Size MultiLineEdit::CalcMinimumSize() const 1267 { 1268 Size aSz = pImpSvMEdit->CalcMinimumSize(); 1269 1270 sal_Int32 nLeft, nTop, nRight, nBottom; 1271 ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom ); 1272 aSz.Width() += nLeft+nRight; 1273 aSz.Height() += nTop+nBottom; 1274 1275 return aSz; 1276 } 1277 1278 Size MultiLineEdit::CalcAdjustedSize( const Size& rPrefSize ) const 1279 { 1280 Size aSz = rPrefSize; 1281 sal_Int32 nLeft, nTop, nRight, nBottom; 1282 ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom ); 1283 1284 // In der Hoehe auf ganze Zeilen justieren 1285 1286 long nHeight = aSz.Height() - nTop - nBottom; 1287 long nLineHeight = pImpSvMEdit->CalcSize( 1, 1 ).Height(); 1288 long nLines = nHeight / nLineHeight; 1289 if ( nLines < 1 ) 1290 nLines = 1; 1291 1292 aSz.Height() = nLines * nLineHeight; 1293 aSz.Height() += nTop+nBottom; 1294 1295 return aSz; 1296 } 1297 1298 Size MultiLineEdit::CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const 1299 { 1300 Size aSz = pImpSvMEdit->CalcSize( nColumns, nLines ); 1301 1302 sal_Int32 nLeft, nTop, nRight, nBottom; 1303 ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom ); 1304 aSz.Width() += nLeft+nRight; 1305 aSz.Height() += nTop+nBottom; 1306 return aSz; 1307 } 1308 1309 void MultiLineEdit::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const 1310 { 1311 pImpSvMEdit->GetMaxVisColumnsAndLines( rnCols, rnLines ); 1312 } 1313 1314 void MultiLineEdit::StateChanged( StateChangedType nType ) 1315 { 1316 if( nType == STATE_CHANGE_ENABLE ) 1317 { 1318 pImpSvMEdit->Enable( IsEnabled() ); 1319 ImplInitSettings( sal_True, sal_False, sal_False ); 1320 } 1321 else if( nType == STATE_CHANGE_READONLY ) 1322 { 1323 pImpSvMEdit->SetReadOnly( IsReadOnly() ); 1324 } 1325 else if ( nType == STATE_CHANGE_ZOOM ) 1326 { 1327 pImpSvMEdit->GetTextWindow()->SetZoom( GetZoom() ); 1328 ImplInitSettings( sal_True, sal_False, sal_False ); 1329 Resize(); 1330 } 1331 else if ( nType == STATE_CHANGE_CONTROLFONT ) 1332 { 1333 ImplInitSettings( sal_True, sal_False, sal_False ); 1334 Resize(); 1335 Invalidate(); 1336 } 1337 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) 1338 { 1339 ImplInitSettings( sal_False, sal_True, sal_False ); 1340 Invalidate(); 1341 } 1342 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) 1343 { 1344 ImplInitSettings( sal_False, sal_False, sal_True ); 1345 Invalidate(); 1346 } 1347 else if ( nType == STATE_CHANGE_STYLE ) 1348 { 1349 pImpSvMEdit->InitFromStyle( GetStyle() ); 1350 SetStyle( ImplInitStyle( GetStyle() ) ); 1351 } 1352 else if ( nType == STATE_CHANGE_INITSHOW ) 1353 { 1354 if( IsPaintTransparent() ) 1355 { 1356 pImpSvMEdit->GetTextWindow()->SetPaintTransparent( sal_True ); 1357 pImpSvMEdit->GetTextWindow()->SetBackground(); 1358 pImpSvMEdit->GetTextWindow()->SetControlBackground(); 1359 SetBackground(); 1360 SetControlBackground(); 1361 } 1362 } 1363 1364 Control::StateChanged( nType ); 1365 } 1366 1367 void MultiLineEdit::DataChanged( const DataChangedEvent& rDCEvt ) 1368 { 1369 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && 1370 (rDCEvt.GetFlags() & SETTINGS_STYLE) ) 1371 { 1372 ImplInitSettings( sal_True, sal_True, sal_True ); 1373 Resize(); 1374 Invalidate(); 1375 } 1376 else 1377 Control::DataChanged( rDCEvt ); 1378 } 1379 1380 void MultiLineEdit::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags ) 1381 { 1382 ImplInitSettings( sal_True, sal_True, sal_True ); 1383 1384 Point aPos = pDev->LogicToPixel( rPos ); 1385 Size aSize = pDev->LogicToPixel( rSize ); 1386 Font aFont = pImpSvMEdit->GetTextWindow()->GetDrawPixelFont( pDev ); 1387 aFont.SetTransparent( sal_True ); 1388 OutDevType eOutDevType = pDev->GetOutDevType(); 1389 1390 pDev->Push(); 1391 pDev->SetMapMode(); 1392 pDev->SetFont( aFont ); 1393 pDev->SetTextFillColor(); 1394 1395 // Border/Background 1396 pDev->SetLineColor(); 1397 pDev->SetFillColor(); 1398 sal_Bool bBorder = !(nFlags & WINDOW_DRAW_NOBORDER ) && (GetStyle() & WB_BORDER); 1399 sal_Bool bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && IsControlBackground(); 1400 if ( bBorder || bBackground ) 1401 { 1402 Rectangle aRect( aPos, aSize ); 1403 if ( bBorder ) 1404 { 1405 DecorationView aDecoView( pDev ); 1406 aRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN ); 1407 } 1408 if ( bBackground ) 1409 { 1410 pDev->SetFillColor( GetControlBackground() ); 1411 pDev->DrawRect( aRect ); 1412 } 1413 } 1414 1415 // Inhalt 1416 if ( ( nFlags & WINDOW_DRAW_MONO ) || ( eOutDevType == OUTDEV_PRINTER ) ) 1417 pDev->SetTextColor( Color( COL_BLACK ) ); 1418 else 1419 { 1420 if ( !(nFlags & WINDOW_DRAW_NODISABLE ) && !IsEnabled() ) 1421 { 1422 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 1423 pDev->SetTextColor( rStyleSettings.GetDisableColor() ); 1424 } 1425 else 1426 { 1427 pDev->SetTextColor( GetTextColor() ); 1428 } 1429 } 1430 1431 XubString aText = GetText(); 1432 Size aTextSz( pDev->GetTextWidth( aText ), pDev->GetTextHeight() ); 1433 sal_uLong nLines = (sal_uLong) (aSize.Height() / aTextSz.Height()); 1434 if ( !nLines ) 1435 nLines = 1; 1436 aTextSz.Height() = nLines*aTextSz.Height(); 1437 long nOnePixel = GetDrawPixel( pDev, 1 ); 1438 long nOffX = 3*nOnePixel; 1439 long nOffY = 2*nOnePixel; 1440 1441 // Clipping? 1442 if ( ( nOffY < 0 ) || ( (nOffY+aTextSz.Height()) > aSize.Height() ) || ( (nOffX+aTextSz.Width()) > aSize.Width() ) ) 1443 { 1444 Rectangle aClip( aPos, aSize ); 1445 if ( aTextSz.Height() > aSize.Height() ) 1446 aClip.Bottom() += aTextSz.Height() - aSize.Height() + 1; // Damit HP-Drucker nicht 'weg-optimieren' 1447 pDev->IntersectClipRegion( aClip ); 1448 } 1449 1450 TextEngine aTE; 1451 aTE.SetText( GetText() ); 1452 aTE.SetMaxTextWidth( aSize.Width() ); 1453 aTE.SetFont( aFont ); 1454 aTE.SetTextAlign( pImpSvMEdit->GetTextWindow()->GetTextEngine()->GetTextAlign() ); 1455 aTE.Draw( pDev, Point( aPos.X() + nOffX, aPos.Y() + nOffY ) ); 1456 1457 pDev->Pop(); 1458 } 1459 1460 long MultiLineEdit::Notify( NotifyEvent& rNEvt ) 1461 { 1462 long nDone = 0; 1463 if( rNEvt.GetType() == EVENT_COMMAND ) 1464 { 1465 nDone = pImpSvMEdit->HandleCommand( *rNEvt.GetCommandEvent() ); 1466 } 1467 return nDone ? nDone : Edit::Notify( rNEvt ); 1468 } 1469 1470 long MultiLineEdit::PreNotify( NotifyEvent& rNEvt ) 1471 { 1472 long nDone = 0; 1473 1474 #if (OSL_DEBUG_LEVEL > 1) && defined(DBG_UTIL) 1475 if( rNEvt.GetType() == EVENT_KEYINPUT ) 1476 { 1477 const KeyEvent& rKEvent = *rNEvt.GetKeyEvent(); 1478 if ( ( rKEvent.GetKeyCode().GetCode() == KEY_W ) && rKEvent.GetKeyCode().IsMod1() && rKEvent.GetKeyCode().IsMod2() ) 1479 { 1480 SetRightToLeft( !IsRightToLeft() ); 1481 } 1482 } 1483 #endif 1484 1485 if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && ( !GetTextView()->IsCursorEnabled() ) ) 1486 { 1487 const KeyEvent& rKEvent = *rNEvt.GetKeyEvent(); 1488 if ( !rKEvent.GetKeyCode().IsShift() && ( rKEvent.GetKeyCode().GetGroup() == KEYGROUP_CURSOR ) ) 1489 { 1490 nDone = 1; 1491 TextSelection aSel = pImpSvMEdit->GetTextWindow()->GetTextView()->GetSelection(); 1492 if ( aSel.HasRange() ) 1493 { 1494 aSel.GetStart() = aSel.GetEnd(); 1495 pImpSvMEdit->GetTextWindow()->GetTextView()->SetSelection( aSel ); 1496 } 1497 else 1498 { 1499 switch ( rKEvent.GetKeyCode().GetCode() ) 1500 { 1501 case KEY_UP: 1502 { 1503 if ( pImpSvMEdit->GetVScrollBar() ) 1504 pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEUP ); 1505 } 1506 break; 1507 case KEY_DOWN: 1508 { 1509 if ( pImpSvMEdit->GetVScrollBar() ) 1510 pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEDOWN ); 1511 } 1512 break; 1513 case KEY_PAGEUP : 1514 { 1515 if ( pImpSvMEdit->GetVScrollBar() ) 1516 pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEUP ); 1517 } 1518 break; 1519 case KEY_PAGEDOWN: 1520 { 1521 if ( pImpSvMEdit->GetVScrollBar() ) 1522 pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEDOWN ); 1523 } 1524 break; 1525 case KEY_LEFT: 1526 { 1527 if ( pImpSvMEdit->GetHScrollBar() ) 1528 pImpSvMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEUP ); 1529 } 1530 break; 1531 case KEY_RIGHT: 1532 { 1533 if ( pImpSvMEdit->GetHScrollBar() ) 1534 pImpSvMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEDOWN ); 1535 } 1536 break; 1537 case KEY_HOME: 1538 { 1539 if ( rKEvent.GetKeyCode().IsMod1() ) 1540 pImpSvMEdit->GetTextWindow()->GetTextView()-> 1541 SetSelection( TextSelection( TextPaM( 0, 0 ) ) ); 1542 } 1543 break; 1544 case KEY_END: 1545 { 1546 if ( rKEvent.GetKeyCode().IsMod1() ) 1547 pImpSvMEdit->GetTextWindow()->GetTextView()-> 1548 SetSelection( TextSelection( TextPaM( 0xFFFF, 0xFFFF ) ) ); 1549 } 1550 break; 1551 default: 1552 { 1553 nDone = 0; 1554 } 1555 } 1556 } 1557 } 1558 } 1559 1560 return nDone ? nDone : Edit::PreNotify( rNEvt ); 1561 } 1562 1563 // 1564 // Internas fuer abgeleitete Klassen, z.B. TextComponent 1565 1566 ExtTextEngine* MultiLineEdit::GetTextEngine() const 1567 { 1568 return pImpSvMEdit->GetTextWindow()->GetTextEngine(); 1569 } 1570 1571 ExtTextView* MultiLineEdit::GetTextView() const 1572 { 1573 return pImpSvMEdit->GetTextWindow()->GetTextView(); 1574 } 1575 1576 ScrollBar* MultiLineEdit::GetHScrollBar() const 1577 { 1578 return pImpSvMEdit->GetHScrollBar(); 1579 } 1580 1581 1582 ScrollBar* MultiLineEdit::GetVScrollBar() const 1583 { 1584 return pImpSvMEdit->GetVScrollBar(); 1585 } 1586 1587 void MultiLineEdit::EnableFocusSelectionHide( sal_Bool bHide ) 1588 { 1589 pImpSvMEdit->GetTextWindow()->SetAutoFocusHide( bHide ); 1590 } 1591 1592 sal_Bool MultiLineEdit::IsFocusSelectionHideEnabled() const 1593 { 1594 return pImpSvMEdit->GetTextWindow()->IsAutoFocusHide(); 1595 } 1596 1597 1598 void MultiLineEdit::SetLeftMargin( sal_uInt16 n ) 1599 { 1600 if ( GetTextEngine() ) 1601 GetTextEngine()->SetLeftMargin( n ); 1602 } 1603 1604 sal_uInt16 MultiLineEdit::GetLeftMargin() const 1605 { 1606 if ( GetTextEngine() ) 1607 return GetTextEngine()->GetLeftMargin(); 1608 else 1609 return 0; 1610 } 1611 1612 void MultiLineEdit::SetRightToLeft( sal_Bool bRightToLeft ) 1613 { 1614 if ( GetTextEngine() ) 1615 { 1616 GetTextEngine()->SetRightToLeft( bRightToLeft ); 1617 GetTextView()->ShowCursor(); 1618 } 1619 } 1620 1621 sal_Bool MultiLineEdit::IsRightToLeft() const 1622 { 1623 sal_Bool bRightToLeft = sal_False; 1624 1625 if ( GetTextEngine() ) 1626 bRightToLeft = GetTextEngine()->IsRightToLeft(); 1627 1628 return bRightToLeft; 1629 } 1630 1631 // virtual 1632 ::css::uno::Reference< ::css::awt::XWindowPeer > 1633 MultiLineEdit::GetComponentInterface(sal_Bool bCreate) 1634 { 1635 ::css::uno::Reference< ::css::awt::XWindowPeer > xPeer( 1636 Edit::GetComponentInterface(false)); 1637 if (!xPeer.is() && bCreate) 1638 { 1639 ::std::auto_ptr< VCLXMultiLineEdit > xEdit(new VCLXMultiLineEdit()); 1640 xEdit->SetWindow(this); 1641 xPeer = xEdit.release(); 1642 SetComponentInterface(xPeer); 1643 } 1644 return xPeer; 1645 } 1646 /*-- 11.08.2004 11:29:23--------------------------------------------------- 1647 1648 -----------------------------------------------------------------------*/ 1649 void MultiLineEdit::DisableSelectionOnFocus() 1650 { 1651 pImpSvMEdit->GetTextWindow()->DisableSelectionOnFocus(); 1652 } 1653