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