1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #include <memory> 21 #include <utility> 22 23 #include <comphelper/lok.hxx> 24 #include <config_global.h> 25 #include <vcl/weld.hxx> 26 #include <vcl/svapp.hxx> 27 28 #include <svtools/ctrltool.hxx> 29 #include <tools/stream.hxx> 30 31 #include <editeng/svxfont.hxx> 32 #include "impedit.hxx" 33 #include <editeng/editeng.hxx> 34 #include <editeng/editview.hxx> 35 #include <editeng/editstat.hxx> 36 #include "editdbg.hxx" 37 #include <eerdll2.hxx> 38 #include <editeng/eerdll.hxx> 39 #include <editeng/editrids.hrc> 40 #include <editeng.hxx> 41 #include <editeng/acorrcfg.hxx> 42 #include <editeng/flditem.hxx> 43 #include <editeng/txtrange.hxx> 44 #include <editeng/cmapitem.hxx> 45 #include <vcl/graph.hxx> 46 47 #include <editeng/autokernitem.hxx> 48 #include <editeng/contouritem.hxx> 49 #include <editeng/colritem.hxx> 50 #include <editeng/crossedoutitem.hxx> 51 #include <editeng/escapementitem.hxx> 52 #include <editeng/fhgtitem.hxx> 53 #include <editeng/fontitem.hxx> 54 #include <editeng/kernitem.hxx> 55 #include <editeng/lrspitem.hxx> 56 #include <editeng/postitem.hxx> 57 #include <editeng/shdditem.hxx> 58 #include <editeng/udlnitem.hxx> 59 #include <editeng/wghtitem.hxx> 60 #include <editeng/wrlmitem.hxx> 61 #include <editeng/brushitem.hxx> 62 #include <editeng/langitem.hxx> 63 #include <editeng/emphasismarkitem.hxx> 64 #include <editeng/charscaleitem.hxx> 65 #include <editeng/charreliefitem.hxx> 66 67 #include <sot/exchange.hxx> 68 #include <sot/formats.hxx> 69 70 #include <editeng/numitem.hxx> 71 #include <editeng/bulletitem.hxx> 72 #include <editeng/unolingu.hxx> 73 #include <linguistic/lngprops.hxx> 74 #include <i18nlangtag/mslangid.hxx> 75 #include <rtl/strbuf.hxx> 76 #include <sal/log.hxx> 77 #include <vcl/help.hxx> 78 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp> 79 #include <com/sun/star/i18n/InputSequenceCheckMode.hpp> 80 81 #include <svl/srchdefs.hxx> 82 83 #if OSL_DEBUG_LEVEL > 1 84 #include <editeng/frmdiritem.hxx> 85 #endif 86 #include <basegfx/polygon/b2dpolygon.hxx> 87 88 using namespace ::com::sun::star; 89 using namespace ::com::sun::star::uno; 90 using namespace ::com::sun::star::linguistic2; 91 92 93 #if (OSL_DEBUG_LEVEL > 1) || defined ( DBG_UTIL ) 94 static bool bDebugPaint = false; 95 #endif 96 97 static SfxItemPool* pGlobalPool=nullptr; 98 99 EditEngine::EditEngine( SfxItemPool* pItemPool ) 100 { 101 pImpEditEngine.reset( new ImpEditEngine( this, pItemPool ) ); 102 } 103 104 EditEngine::~EditEngine() 105 { 106 } 107 108 void EditEngine::EnableUndo( bool bEnable ) 109 { 110 pImpEditEngine->EnableUndo( bEnable ); 111 } 112 113 bool EditEngine::IsUndoEnabled() const 114 { 115 return pImpEditEngine->IsUndoEnabled(); 116 } 117 118 bool EditEngine::IsInUndo() const 119 { 120 return pImpEditEngine->IsInUndo(); 121 } 122 123 SfxUndoManager& EditEngine::GetUndoManager() 124 { 125 return pImpEditEngine->GetUndoManager(); 126 } 127 128 SfxUndoManager* EditEngine::SetUndoManager(SfxUndoManager* pNew) 129 { 130 return pImpEditEngine->SetUndoManager(pNew); 131 } 132 133 void EditEngine::UndoActionStart( sal_uInt16 nId ) 134 { 135 DBG_ASSERT( !pImpEditEngine->IsInUndo(), "Calling UndoActionStart in Undomode!" ); 136 if ( !pImpEditEngine->IsInUndo() ) 137 pImpEditEngine->UndoActionStart( nId ); 138 } 139 140 void EditEngine::UndoActionStart(sal_uInt16 nId, const ESelection& rSel) 141 { 142 pImpEditEngine->UndoActionStart(nId, rSel); 143 } 144 145 void EditEngine::UndoActionEnd() 146 { 147 DBG_ASSERT( !pImpEditEngine->IsInUndo(), "Calling UndoActionEnd in Undomode!" ); 148 if ( !pImpEditEngine->IsInUndo() ) 149 pImpEditEngine->UndoActionEnd(); 150 } 151 152 bool EditEngine::HasTriedMergeOnLastAddUndo() const 153 { 154 return pImpEditEngine->mbLastTryMerge; 155 } 156 157 void EditEngine::SetRefDevice( OutputDevice* pRefDev ) 158 { 159 pImpEditEngine->SetRefDevice( pRefDev ); 160 } 161 162 OutputDevice* EditEngine::GetRefDevice() const 163 { 164 return pImpEditEngine->GetRefDevice(); 165 } 166 167 void EditEngine::SetRefMapMode( const MapMode& rMapMode ) 168 { 169 pImpEditEngine->SetRefMapMode( rMapMode ); 170 } 171 172 MapMode const & EditEngine::GetRefMapMode() const 173 { 174 return pImpEditEngine->GetRefMapMode(); 175 } 176 177 void EditEngine::SetBackgroundColor( const Color& rColor ) 178 { 179 pImpEditEngine->SetBackgroundColor( rColor ); 180 } 181 182 Color const & EditEngine::GetBackgroundColor() const 183 { 184 return pImpEditEngine->GetBackgroundColor(); 185 } 186 187 Color EditEngine::GetAutoColor() const 188 { 189 return pImpEditEngine->GetAutoColor(); 190 } 191 192 void EditEngine::EnableAutoColor( bool b ) 193 { 194 pImpEditEngine->EnableAutoColor( b ); 195 } 196 197 void EditEngine::ForceAutoColor( bool b ) 198 { 199 pImpEditEngine->ForceAutoColor( b ); 200 } 201 202 bool EditEngine::IsForceAutoColor() const 203 { 204 return pImpEditEngine->IsForceAutoColor(); 205 } 206 207 const SfxItemSet& EditEngine::GetEmptyItemSet() 208 { 209 return pImpEditEngine->GetEmptyItemSet(); 210 } 211 212 void EditEngine::Draw( OutputDevice* pOutDev, const tools::Rectangle& rOutRect ) 213 { 214 Draw( pOutDev, rOutRect, Point( 0, 0 ) ); 215 } 216 217 void EditEngine::Draw( OutputDevice* pOutDev, const Point& rStartPos, short nOrientation ) 218 { 219 // Create with 2 points, as with positive points it will end up with 220 // LONGMAX as Size, Bottom and Right in the range > LONGMAX. 221 tools::Rectangle aBigRect( -0x3FFFFFFF, -0x3FFFFFFF, 0x3FFFFFFF, 0x3FFFFFFF ); 222 if( pOutDev->GetConnectMetaFile() ) 223 pOutDev->Push(); 224 Point aStartPos( rStartPos ); 225 if ( IsVertical() ) 226 { 227 aStartPos.AdjustX(GetPaperSize().Width() ); 228 aStartPos = Rotate( aStartPos, nOrientation, rStartPos ); 229 } 230 pImpEditEngine->Paint( pOutDev, aBigRect, aStartPos, false, nOrientation ); 231 if( pOutDev->GetConnectMetaFile() ) 232 pOutDev->Pop(); 233 } 234 235 void EditEngine::Draw( OutputDevice* pOutDev, const tools::Rectangle& rOutRect, const Point& rStartDocPos ) 236 { 237 Draw( pOutDev, rOutRect, rStartDocPos, true ); 238 } 239 240 void EditEngine::Draw( OutputDevice* pOutDev, const tools::Rectangle& rOutRect, const Point& rStartDocPos, bool bClip ) 241 { 242 #if defined( DBG_UTIL ) || (OSL_DEBUG_LEVEL > 1) 243 if ( bDebugPaint ) 244 EditDbg::ShowEditEngineData( this, false ); 245 #endif 246 247 // Align to the pixel boundary, so that it becomes exactly the same 248 // as Paint () 249 tools::Rectangle aOutRect( pOutDev->LogicToPixel( rOutRect ) ); 250 aOutRect = pOutDev->PixelToLogic( aOutRect ); 251 252 Point aStartPos; 253 if ( !IsVertical() ) 254 { 255 aStartPos.setX( aOutRect.Left() - rStartDocPos.X() ); 256 aStartPos.setY( aOutRect.Top() - rStartDocPos.Y() ); 257 } 258 else 259 { 260 aStartPos.setX( aOutRect.Right() + rStartDocPos.Y() ); 261 aStartPos.setY( aOutRect.Top() - rStartDocPos.X() ); 262 } 263 264 bool bClipRegion = pOutDev->IsClipRegion(); 265 bool bMetafile = pOutDev->GetConnectMetaFile(); 266 vcl::Region aOldRegion = pOutDev->GetClipRegion(); 267 268 // If one existed => intersection! 269 // Use Push/pop for creating the Meta file 270 if ( bMetafile ) 271 pOutDev->Push(); 272 273 // Always use the Intersect method, it is a must for Metafile! 274 if ( bClip ) 275 { 276 // Clip only if necessary... 277 if ( rStartDocPos.X() || rStartDocPos.Y() || 278 ( rOutRect.GetHeight() < static_cast<long>(GetTextHeight()) ) || 279 ( rOutRect.GetWidth() < static_cast<long>(CalcTextWidth()) ) ) 280 { 281 // Some printer drivers cause problems if characters graze the 282 // ClipRegion, therefore rather add a pixel more ... 283 tools::Rectangle aClipRect( aOutRect ); 284 if ( pOutDev->GetOutDevType() == OUTDEV_PRINTER ) 285 { 286 Size aPixSz( 1, 0 ); 287 aPixSz = pOutDev->PixelToLogic( aPixSz ); 288 aClipRect.AdjustRight(aPixSz.Width() ); 289 aClipRect.AdjustBottom(aPixSz.Width() ); 290 } 291 pOutDev->IntersectClipRegion( aClipRect ); 292 } 293 } 294 295 pImpEditEngine->Paint( pOutDev, aOutRect, aStartPos ); 296 297 if ( bMetafile ) 298 pOutDev->Pop(); 299 else if ( bClipRegion ) 300 pOutDev->SetClipRegion( aOldRegion ); 301 else 302 pOutDev->SetClipRegion(); 303 } 304 305 void EditEngine::InsertView(EditView* pEditView, size_t nIndex) 306 { 307 308 if ( nIndex > pImpEditEngine->GetEditViews().size() ) 309 nIndex = pImpEditEngine->GetEditViews().size(); 310 311 ImpEditEngine::ViewsType& rViews = pImpEditEngine->GetEditViews(); 312 rViews.insert(rViews.begin()+nIndex, pEditView); 313 314 EditSelection aStartSel = pImpEditEngine->GetEditDoc().GetStartPaM(); 315 pEditView->pImpEditView->SetEditSelection( aStartSel ); 316 if ( !pImpEditEngine->GetActiveView() ) 317 pImpEditEngine->SetActiveView( pEditView ); 318 319 pEditView->pImpEditView->AddDragAndDropListeners(); 320 } 321 322 EditView* EditEngine::RemoveView( EditView* pView ) 323 { 324 325 pView->HideCursor(); 326 EditView* pRemoved = nullptr; 327 ImpEditEngine::ViewsType& rViews = pImpEditEngine->GetEditViews(); 328 ImpEditEngine::ViewsType::iterator it = std::find(rViews.begin(), rViews.end(), pView); 329 330 DBG_ASSERT( it != rViews.end(), "RemoveView with invalid index" ); 331 if (it != rViews.end()) 332 { 333 pRemoved = *it; 334 rViews.erase(it); 335 if ( pImpEditEngine->GetActiveView() == pView ) 336 { 337 pImpEditEngine->SetActiveView( nullptr ); 338 pImpEditEngine->GetSelEngine().SetCurView( nullptr ); 339 } 340 pView->pImpEditView->RemoveDragAndDropListeners(); 341 342 } 343 return pRemoved; 344 } 345 346 void EditEngine::RemoveView(size_t nIndex) 347 { 348 ImpEditEngine::ViewsType& rViews = pImpEditEngine->GetEditViews(); 349 if (nIndex >= rViews.size()) 350 return; 351 352 EditView* pView = rViews[nIndex]; 353 if ( pView ) 354 RemoveView( pView ); 355 } 356 357 EditView* EditEngine::GetView(size_t nIndex) const 358 { 359 return pImpEditEngine->GetEditViews()[nIndex]; 360 } 361 362 size_t EditEngine::GetViewCount() const 363 { 364 return pImpEditEngine->GetEditViews().size(); 365 } 366 367 bool EditEngine::HasView( EditView* pView ) const 368 { 369 ImpEditEngine::ViewsType& rViews = pImpEditEngine->GetEditViews(); 370 return std::find(rViews.begin(), rViews.end(), pView) != rViews.end(); 371 } 372 373 EditView* EditEngine::GetActiveView() const 374 { 375 return pImpEditEngine->GetActiveView(); 376 } 377 378 void EditEngine::SetActiveView(EditView* pView) 379 { 380 pImpEditEngine->SetActiveView(pView); 381 } 382 383 void EditEngine::SetDefTab( sal_uInt16 nDefTab ) 384 { 385 pImpEditEngine->GetEditDoc().SetDefTab( nDefTab ); 386 if ( pImpEditEngine->IsFormatted() ) 387 { 388 pImpEditEngine->FormatFullDoc(); 389 pImpEditEngine->UpdateViews(); 390 } 391 } 392 393 void EditEngine::SetPaperSize( const Size& rNewSize ) 394 { 395 396 Size aOldSize( pImpEditEngine->GetPaperSize() ); 397 pImpEditEngine->SetValidPaperSize( rNewSize ); 398 Size aNewSize( pImpEditEngine->GetPaperSize() ); 399 400 bool bAutoPageSize = pImpEditEngine->GetStatus().AutoPageSize(); 401 if ( bAutoPageSize || ( aNewSize.Width() != aOldSize.Width() ) ) 402 { 403 for (EditView* pView : pImpEditEngine->aEditViews) 404 { 405 if ( bAutoPageSize ) 406 pView->pImpEditView->RecalcOutputArea(); 407 else if ( pView->pImpEditView->DoAutoSize() ) 408 { 409 pView->pImpEditView->ResetOutputArea( tools::Rectangle( 410 pView->pImpEditView->GetOutputArea().TopLeft(), aNewSize ) ); 411 } 412 } 413 414 if ( bAutoPageSize || pImpEditEngine->IsFormatted() ) 415 { 416 // Changing the width has no effect for AutoPageSize, as this is 417 // determined by the text width. 418 // Optimization first after Vobis delivery was enabled ... 419 pImpEditEngine->FormatFullDoc(); 420 421 pImpEditEngine->UpdateViews( pImpEditEngine->GetActiveView() ); 422 423 if ( pImpEditEngine->GetUpdateMode() && pImpEditEngine->GetActiveView() ) 424 pImpEditEngine->pActiveView->ShowCursor( false, false ); 425 } 426 } 427 } 428 429 const Size& EditEngine::GetPaperSize() const 430 { 431 return pImpEditEngine->GetPaperSize(); 432 } 433 434 void EditEngine::SetVertical( bool bVertical, bool bTopToBottom ) 435 { 436 pImpEditEngine->SetVertical( bVertical, bTopToBottom); 437 } 438 439 bool EditEngine::IsVertical() const 440 { 441 return pImpEditEngine->IsVertical(); 442 } 443 444 bool EditEngine::IsTopToBottom() const 445 { 446 return pImpEditEngine->IsTopToBottom(); 447 } 448 449 void EditEngine::SetFixedCellHeight( bool bUseFixedCellHeight ) 450 { 451 pImpEditEngine->SetFixedCellHeight( bUseFixedCellHeight ); 452 } 453 454 void EditEngine::SetDefaultHorizontalTextDirection( EEHorizontalTextDirection eHTextDir ) 455 { 456 pImpEditEngine->SetDefaultHorizontalTextDirection( eHTextDir ); 457 } 458 459 EEHorizontalTextDirection EditEngine::GetDefaultHorizontalTextDirection() const 460 { 461 return pImpEditEngine->GetDefaultHorizontalTextDirection(); 462 } 463 464 SvtScriptType EditEngine::GetScriptType( const ESelection& rSelection ) const 465 { 466 EditSelection aSel( pImpEditEngine->CreateSel( rSelection ) ); 467 return pImpEditEngine->GetItemScriptType( aSel ); 468 } 469 470 LanguageType EditEngine::GetLanguage(const EditPaM& rPaM) const 471 { 472 return pImpEditEngine->GetLanguage(rPaM); 473 } 474 475 LanguageType EditEngine::GetLanguage( sal_Int32 nPara, sal_Int32 nPos ) const 476 { 477 ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( nPara ); 478 DBG_ASSERT( pNode, "GetLanguage - nPara is invalid!" ); 479 return pNode ? pImpEditEngine->GetLanguage( EditPaM( pNode, nPos ) ) : LANGUAGE_DONTKNOW; 480 } 481 482 483 void EditEngine::TransliterateText( const ESelection& rSelection, TransliterationFlags nTransliterationMode ) 484 { 485 pImpEditEngine->TransliterateText( pImpEditEngine->CreateSel( rSelection ), nTransliterationMode ); 486 } 487 488 EditSelection EditEngine::TransliterateText(const EditSelection& rSelection, TransliterationFlags nTransliterationMode) 489 { 490 return pImpEditEngine->TransliterateText(rSelection, nTransliterationMode); 491 } 492 493 void EditEngine::SetAsianCompressionMode( CharCompressType n ) 494 { 495 pImpEditEngine->SetAsianCompressionMode( n ); 496 } 497 498 void EditEngine::SetKernAsianPunctuation( bool b ) 499 { 500 pImpEditEngine->SetKernAsianPunctuation( b ); 501 } 502 503 void EditEngine::SetAddExtLeading( bool b ) 504 { 505 pImpEditEngine->SetAddExtLeading( b ); 506 } 507 508 void EditEngine::SetPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon ) 509 { 510 SetPolygon( rPolyPolygon, nullptr ); 511 } 512 513 void EditEngine::SetPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon, const basegfx::B2DPolyPolygon* pLinePolyPolygon) 514 { 515 bool bSimple(false); 516 517 if(pLinePolyPolygon && 1 == rPolyPolygon.count()) 518 { 519 if(rPolyPolygon.getB2DPolygon(0).isClosed()) 520 { 521 // open polygon 522 bSimple = true; 523 } 524 } 525 526 TextRanger* pRanger = new TextRanger( rPolyPolygon, pLinePolyPolygon, 30, 2, 2, bSimple, true ); 527 pImpEditEngine->SetTextRanger( std::unique_ptr<TextRanger>(pRanger) ); 528 pImpEditEngine->SetPaperSize( pRanger->GetBoundRect().GetSize() ); 529 } 530 531 void EditEngine::ClearPolygon() 532 { 533 pImpEditEngine->SetTextRanger( nullptr ); 534 } 535 536 const Size& EditEngine::GetMinAutoPaperSize() const 537 { 538 return pImpEditEngine->GetMinAutoPaperSize(); 539 } 540 541 void EditEngine::SetMinAutoPaperSize( const Size& rSz ) 542 { 543 pImpEditEngine->SetMinAutoPaperSize( rSz ); 544 } 545 546 const Size& EditEngine::GetMaxAutoPaperSize() const 547 { 548 return pImpEditEngine->GetMaxAutoPaperSize(); 549 } 550 551 void EditEngine::SetMaxAutoPaperSize( const Size& rSz ) 552 { 553 pImpEditEngine->SetMaxAutoPaperSize( rSz ); 554 } 555 556 OUString EditEngine::GetText( LineEnd eEnd ) const 557 { 558 return pImpEditEngine->GetEditDoc().GetText( eEnd ); 559 } 560 561 OUString EditEngine::GetText( const ESelection& rESelection ) const 562 { 563 EditSelection aSel( pImpEditEngine->CreateSel( rESelection ) ); 564 return pImpEditEngine->GetSelected( aSel ); 565 } 566 567 sal_uInt32 EditEngine::GetTextLen() const 568 { 569 return pImpEditEngine->GetEditDoc().GetTextLen(); 570 } 571 572 sal_Int32 EditEngine::GetParagraphCount() const 573 { 574 return pImpEditEngine->aEditDoc.Count(); 575 } 576 577 sal_Int32 EditEngine::GetLineCount( sal_Int32 nParagraph ) const 578 { 579 if ( !pImpEditEngine->IsFormatted() ) 580 pImpEditEngine->FormatDoc(); 581 return pImpEditEngine->GetLineCount( nParagraph ); 582 } 583 584 sal_Int32 EditEngine::GetLineLen( sal_Int32 nParagraph, sal_Int32 nLine ) const 585 { 586 if ( !pImpEditEngine->IsFormatted() ) 587 pImpEditEngine->FormatDoc(); 588 return pImpEditEngine->GetLineLen( nParagraph, nLine ); 589 } 590 591 void EditEngine::GetLineBoundaries( /*out*/sal_Int32& rStart, /*out*/sal_Int32& rEnd, sal_Int32 nParagraph, sal_Int32 nLine ) const 592 { 593 if ( !pImpEditEngine->IsFormatted() ) 594 pImpEditEngine->FormatDoc(); 595 return pImpEditEngine->GetLineBoundaries( rStart, rEnd, nParagraph, nLine ); 596 } 597 598 sal_Int32 EditEngine::GetLineNumberAtIndex( sal_Int32 nPara, sal_Int32 nIndex ) const 599 { 600 if ( !pImpEditEngine->IsFormatted() ) 601 pImpEditEngine->FormatDoc(); 602 return pImpEditEngine->GetLineNumberAtIndex( nPara, nIndex ); 603 } 604 605 sal_uInt32 EditEngine::GetLineHeight( sal_Int32 nParagraph ) 606 { 607 // If someone calls GetLineHeight() with an empty Engine. 608 if ( !pImpEditEngine->IsFormatted() ) 609 pImpEditEngine->FormatDoc(); 610 return pImpEditEngine->GetLineHeight( nParagraph, 0 ); 611 } 612 613 tools::Rectangle EditEngine::GetParaBounds( sal_Int32 nPara ) 614 { 615 if ( !pImpEditEngine->IsFormatted() ) 616 pImpEditEngine->FormatDoc(); 617 618 Point aPnt = GetDocPosTopLeft( nPara ); 619 620 if( IsVertical() ) 621 { 622 sal_Int32 nTextHeight = pImpEditEngine->GetTextHeight(); 623 sal_Int32 nParaWidth = pImpEditEngine->CalcParaWidth( nPara, true ); 624 sal_uLong nParaHeight = pImpEditEngine->GetParaHeight( nPara ); 625 626 return tools::Rectangle( nTextHeight - aPnt.Y() - nParaHeight, 0, nTextHeight - aPnt.Y(), nParaWidth ); 627 } 628 else 629 { 630 sal_Int32 nParaWidth = pImpEditEngine->CalcParaWidth( nPara, true ); 631 sal_uLong nParaHeight = pImpEditEngine->GetParaHeight( nPara ); 632 633 return tools::Rectangle( 0, aPnt.Y(), nParaWidth, aPnt.Y() + nParaHeight ); 634 } 635 } 636 637 sal_uInt32 EditEngine::GetTextHeight( sal_Int32 nParagraph ) const 638 { 639 if ( !pImpEditEngine->IsFormatted() ) 640 pImpEditEngine->FormatDoc(); 641 642 sal_uInt32 nHeight = pImpEditEngine->GetParaHeight( nParagraph ); 643 return nHeight; 644 } 645 646 OUString EditEngine::GetWord( sal_Int32 nPara, sal_Int32 nIndex ) 647 { 648 ESelection aESel( nPara, nIndex, nPara, nIndex ); 649 EditSelection aSel( pImpEditEngine->CreateSel( aESel ) ); 650 aSel = pImpEditEngine->SelectWord( aSel ); 651 return pImpEditEngine->GetSelected( aSel ); 652 } 653 654 ESelection EditEngine::GetWord( const ESelection& rSelection, sal_uInt16 nWordType ) const 655 { 656 // ImpEditEngine-Iteration-Methods should be const! 657 EditEngine* pE = const_cast<EditEngine*>(this); 658 659 EditSelection aSel( pE->pImpEditEngine->CreateSel( rSelection ) ); 660 aSel = pE->pImpEditEngine->SelectWord( aSel, nWordType ); 661 return pE->pImpEditEngine->CreateESel( aSel ); 662 } 663 664 void EditEngine::CursorMoved(const ContentNode* pPrevNode) 665 { 666 pImpEditEngine->CursorMoved(pPrevNode); 667 } 668 669 void EditEngine::CheckIdleFormatter() 670 { 671 pImpEditEngine->CheckIdleFormatter(); 672 } 673 674 bool EditEngine::IsIdleFormatterActive() const 675 { 676 return pImpEditEngine->aIdleFormatter.IsActive(); 677 } 678 679 ParaPortion* EditEngine::FindParaPortion(ContentNode const * pNode) 680 { 681 return pImpEditEngine->FindParaPortion(pNode); 682 } 683 684 const ParaPortion* EditEngine::FindParaPortion(ContentNode const * pNode) const 685 { 686 return pImpEditEngine->FindParaPortion(pNode); 687 } 688 689 const ParaPortion* EditEngine::GetPrevVisPortion(const ParaPortion* pCurPortion) const 690 { 691 return pImpEditEngine->GetPrevVisPortion(pCurPortion); 692 } 693 694 SvtScriptType EditEngine::GetScriptType(const EditSelection& rSel) const 695 { 696 return pImpEditEngine->GetItemScriptType(rSel); 697 } 698 699 void EditEngine::RemoveParaPortion(sal_Int32 nNode) 700 { 701 pImpEditEngine->GetParaPortions().Remove(nNode); 702 } 703 704 void EditEngine::SetCallParaInsertedOrDeleted(bool b) 705 { 706 pImpEditEngine->SetCallParaInsertedOrDeleted(b); 707 } 708 709 bool EditEngine::IsCallParaInsertedOrDeleted() const 710 { 711 return pImpEditEngine->IsCallParaInsertedOrDeleted(); 712 } 713 714 void EditEngine::AppendDeletedNodeInfo(DeletedNodeInfo* pInfo) 715 { 716 pImpEditEngine->aDeletedNodes.push_back(std::unique_ptr<DeletedNodeInfo>(pInfo)); 717 } 718 719 void EditEngine::UpdateSelections() 720 { 721 pImpEditEngine->UpdateSelections(); 722 } 723 724 void EditEngine::InsertContent(ContentNode* pNode, sal_Int32 nPos) 725 { 726 pImpEditEngine->InsertContent(pNode, nPos); 727 } 728 729 EditPaM EditEngine::SplitContent(sal_Int32 nNode, sal_Int32 nSepPos) 730 { 731 return pImpEditEngine->SplitContent(nNode, nSepPos); 732 } 733 734 EditPaM EditEngine::ConnectContents(sal_Int32 nLeftNode, bool bBackward) 735 { 736 return pImpEditEngine->ConnectContents(nLeftNode, bBackward); 737 } 738 739 void EditEngine::InsertFeature(const EditSelection& rEditSelection, const SfxPoolItem& rItem) 740 { 741 pImpEditEngine->ImpInsertFeature(rEditSelection, rItem); 742 } 743 744 EditSelection EditEngine::MoveParagraphs(const Range& rParagraphs, sal_Int32 nNewPos) 745 { 746 return pImpEditEngine->MoveParagraphs(rParagraphs, nNewPos, nullptr); 747 } 748 749 void EditEngine::RemoveCharAttribs(sal_Int32 nPara, sal_uInt16 nWhich, bool bRemoveFeatures) 750 { 751 pImpEditEngine->RemoveCharAttribs(nPara, nWhich, bRemoveFeatures); 752 } 753 754 void EditEngine::RemoveCharAttribs(const EditSelection& rSel, bool bRemoveParaAttribs, sal_uInt16 nWhich) 755 { 756 pImpEditEngine->RemoveCharAttribs(rSel, bRemoveParaAttribs, nWhich); 757 } 758 759 EditEngine::ViewsType& EditEngine::GetEditViews() 760 { 761 return pImpEditEngine->GetEditViews(); 762 } 763 764 const EditEngine::ViewsType& EditEngine::GetEditViews() const 765 { 766 return pImpEditEngine->GetEditViews(); 767 } 768 769 void EditEngine::SetUndoMode(bool b) 770 { 771 pImpEditEngine->SetUndoMode(b); 772 } 773 774 void EditEngine::FormatAndUpdate(EditView* pCurView, bool bCalledFromUndo) 775 { 776 pImpEditEngine->FormatAndUpdate(pCurView, bCalledFromUndo); 777 } 778 779 void EditEngine::Undo(EditView* pView) 780 { 781 pImpEditEngine->Undo(pView); 782 } 783 784 void EditEngine::Redo(EditView* pView) 785 { 786 pImpEditEngine->Redo(pView); 787 } 788 789 uno::Reference<datatransfer::XTransferable> EditEngine::CreateTransferable(const EditSelection& rSelection) 790 { 791 return pImpEditEngine->CreateTransferable(rSelection); 792 } 793 794 void EditEngine::ParaAttribsToCharAttribs(ContentNode* pNode) 795 { 796 pImpEditEngine->ParaAttribsToCharAttribs(pNode); 797 } 798 799 EditPaM EditEngine::CreateEditPaM(const EPaM& rEPaM) 800 { 801 return pImpEditEngine->CreateEditPaM(rEPaM); 802 } 803 804 EditPaM EditEngine::ConnectParagraphs( 805 ContentNode* pLeft, ContentNode* pRight, bool bBackward) 806 { 807 return pImpEditEngine->ImpConnectParagraphs(pLeft, pRight, bBackward); 808 } 809 810 EditPaM EditEngine::InsertField(const EditSelection& rEditSelection, const SvxFieldItem& rFld) 811 { 812 return pImpEditEngine->InsertField(rEditSelection, rFld); 813 } 814 815 EditPaM EditEngine::InsertText(const EditSelection& aCurEditSelection, const OUString& rStr) 816 { 817 return pImpEditEngine->InsertText(aCurEditSelection, rStr); 818 } 819 820 EditSelection EditEngine::InsertText(const EditTextObject& rTextObject, const EditSelection& rSel) 821 { 822 return pImpEditEngine->InsertText(rTextObject, rSel); 823 } 824 825 EditSelection EditEngine::InsertText( 826 uno::Reference<datatransfer::XTransferable > const & rxDataObj, 827 const OUString& rBaseURL, const EditPaM& rPaM, bool bUseSpecial) 828 { 829 return pImpEditEngine->PasteText(rxDataObj, rBaseURL, rPaM, bUseSpecial); 830 } 831 832 EditPaM EditEngine::EndOfWord(const EditPaM& rPaM) 833 { 834 return pImpEditEngine->EndOfWord(rPaM); 835 } 836 837 EditPaM EditEngine::GetPaM(const Point& aDocPos, bool bSmart) 838 { 839 return pImpEditEngine->GetPaM(aDocPos, bSmart); 840 } 841 842 EditSelection EditEngine::SelectWord( 843 const EditSelection& rCurSelection, sal_Int16 nWordType) 844 { 845 return pImpEditEngine->SelectWord(rCurSelection, nWordType); 846 } 847 848 long EditEngine::GetXPos( 849 const ParaPortion* pParaPortion, const EditLine* pLine, sal_Int32 nIndex, bool bPreferPortionStart) const 850 { 851 return pImpEditEngine->GetXPos(pParaPortion, pLine, nIndex, bPreferPortionStart); 852 } 853 854 Range EditEngine::GetLineXPosStartEnd( 855 const ParaPortion* pParaPortion, const EditLine* pLine) const 856 { 857 return pImpEditEngine->GetLineXPosStartEnd(pParaPortion, pLine); 858 } 859 860 bool EditEngine::IsFormatted() const 861 { 862 return pImpEditEngine->IsFormatted(); 863 } 864 865 EditPaM EditEngine::CursorLeft(const EditPaM& rPaM, sal_uInt16 nCharacterIteratorMode) 866 { 867 return pImpEditEngine->CursorLeft(rPaM, nCharacterIteratorMode); 868 } 869 870 EditPaM EditEngine::CursorRight(const EditPaM& rPaM, sal_uInt16 nCharacterIteratorMode) 871 { 872 return pImpEditEngine->CursorRight(rPaM, nCharacterIteratorMode); 873 } 874 875 InternalEditStatus& EditEngine::GetInternalEditStatus() 876 { 877 return pImpEditEngine->GetStatus(); 878 } 879 880 EditDoc& EditEngine::GetEditDoc() 881 { 882 return pImpEditEngine->GetEditDoc(); 883 } 884 885 const EditDoc& EditEngine::GetEditDoc() const 886 { 887 return pImpEditEngine->GetEditDoc(); 888 } 889 890 void EditEngine::dumpAsXmlEditDoc(xmlTextWriterPtr pWriter) const 891 { 892 pImpEditEngine->GetEditDoc().dumpAsXml(pWriter); 893 } 894 895 ParaPortionList& EditEngine::GetParaPortions() 896 { 897 return pImpEditEngine->GetParaPortions(); 898 } 899 900 const ParaPortionList& EditEngine::GetParaPortions() const 901 { 902 return pImpEditEngine->GetParaPortions(); 903 } 904 905 void EditEngine::SeekCursor(ContentNode* pNode, sal_Int32 nPos, SvxFont& rFont) 906 { 907 pImpEditEngine->SeekCursor(pNode, nPos, rFont); 908 } 909 910 EditPaM EditEngine::DeleteSelection(const EditSelection& rSel) 911 { 912 return pImpEditEngine->ImpDeleteSelection(rSel); 913 } 914 915 ESelection EditEngine::CreateESelection(const EditSelection& rSel) 916 { 917 return pImpEditEngine->CreateESel(rSel); 918 } 919 920 EditSelection EditEngine::CreateSelection(const ESelection& rSel) 921 { 922 return pImpEditEngine->CreateSel(rSel); 923 } 924 925 const SfxItemSet& EditEngine::GetBaseParaAttribs(sal_Int32 nPara) const 926 { 927 return pImpEditEngine->GetParaAttribs(nPara); 928 } 929 930 void EditEngine::SetParaAttribsOnly(sal_Int32 nPara, const SfxItemSet& rSet) 931 { 932 pImpEditEngine->SetParaAttribs(nPara, rSet); 933 } 934 935 void EditEngine::SetAttribs(const EditSelection& rSel, const SfxItemSet& rSet, SetAttribsMode nSpecial) 936 { 937 pImpEditEngine->SetAttribs(rSel, rSet, nSpecial); 938 } 939 940 OUString EditEngine::GetSelected(const EditSelection& rSel) const 941 { 942 return pImpEditEngine->GetSelected(rSel); 943 } 944 945 EditPaM EditEngine::DeleteSelected(const EditSelection& rSel) 946 { 947 return pImpEditEngine->DeleteSelected(rSel); 948 } 949 950 void EditEngine::HandleBeginPasteOrDrop(PasteOrDropInfos& rInfos) 951 { 952 pImpEditEngine->aBeginPasteOrDropHdl.Call(rInfos); 953 } 954 955 void EditEngine::HandleEndPasteOrDrop(PasteOrDropInfos& rInfos) 956 { 957 pImpEditEngine->aEndPasteOrDropHdl.Call(rInfos); 958 } 959 960 bool EditEngine::HasText() const 961 { 962 return pImpEditEngine->ImplHasText(); 963 } 964 965 const EditSelectionEngine& EditEngine::GetSelectionEngine() const 966 { 967 return pImpEditEngine->aSelEngine; 968 } 969 970 void EditEngine::SetInSelectionMode(bool b) 971 { 972 pImpEditEngine->bInSelection = b; 973 } 974 975 bool EditEngine::PostKeyEvent( const KeyEvent& rKeyEvent, EditView* pEditView, vcl::Window const * pFrameWin ) 976 { 977 DBG_ASSERT( pEditView, "no View - no cookie !" ); 978 979 bool bDone = true; 980 981 bool bModified = false; 982 bool bMoved = false; 983 bool bAllowIdle = true; 984 bool bReadOnly = pEditView->IsReadOnly(); 985 986 GetCursorFlags nNewCursorFlags = GetCursorFlags::NONE; 987 bool bSetCursorFlags = true; 988 989 EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() ); 990 DBG_ASSERT( !aCurSel.IsInvalid(), "Blinde Selection in EditEngine::PostKeyEvent" ); 991 992 OUString aAutoText( pImpEditEngine->GetAutoCompleteText() ); 993 if (!pImpEditEngine->GetAutoCompleteText().isEmpty()) 994 pImpEditEngine->SetAutoCompleteText(OUString(), true); 995 996 sal_uInt16 nCode = rKeyEvent.GetKeyCode().GetCode(); 997 KeyFuncType eFunc = rKeyEvent.GetKeyCode().GetFunction(); 998 if ( eFunc != KeyFuncType::DONTKNOW ) 999 { 1000 switch ( eFunc ) 1001 { 1002 case KeyFuncType::UNDO: 1003 { 1004 if ( !bReadOnly ) 1005 pEditView->Undo(); 1006 return true; 1007 } 1008 case KeyFuncType::REDO: 1009 { 1010 if ( !bReadOnly ) 1011 pEditView->Redo(); 1012 return true; 1013 } 1014 1015 default: // is then possible edited below. 1016 eFunc = KeyFuncType::DONTKNOW; 1017 } 1018 } 1019 1020 if ( eFunc == KeyFuncType::DONTKNOW ) 1021 { 1022 switch ( nCode ) 1023 { 1024 #if defined( DBG_UTIL ) || (OSL_DEBUG_LEVEL > 1) 1025 case KEY_F1: 1026 { 1027 if ( rKeyEvent.GetKeyCode().IsMod1() && rKeyEvent.GetKeyCode().IsMod2() ) 1028 { 1029 sal_Int32 nParas = GetParagraphCount(); 1030 Point aPos; 1031 Point aViewStart( pEditView->GetOutputArea().TopLeft() ); 1032 long n20 = 40 * pImpEditEngine->nOnePixelInRef; 1033 for ( sal_Int32 n = 0; n < nParas; n++ ) 1034 { 1035 long nH = GetTextHeight( n ); 1036 Point P1( aViewStart.X() + n20 + n20*(n%2), aViewStart.Y() + aPos.Y() ); 1037 Point P2( P1 ); 1038 P2.AdjustX(n20 ); 1039 P2.AdjustY(nH ); 1040 pEditView->GetWindow()->SetLineColor(); 1041 pEditView->GetWindow()->SetFillColor( (n%2) ? COL_YELLOW : COL_LIGHTGREEN ); 1042 pEditView->GetWindow()->DrawRect( tools::Rectangle( P1, P2 ) ); 1043 aPos.AdjustY(nH ); 1044 } 1045 } 1046 bDone = false; 1047 } 1048 break; 1049 case KEY_F11: 1050 { 1051 if ( rKeyEvent.GetKeyCode().IsMod1() && rKeyEvent.GetKeyCode().IsMod2() ) 1052 { 1053 bDebugPaint = !bDebugPaint; 1054 OStringBuffer aInfo("DebugPaint: "); 1055 aInfo.append(bDebugPaint ? "On" : "Off"); 1056 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(pEditView->GetWindow()->GetFrameWeld(), 1057 VclMessageType::Info, VclButtonsType::Ok, 1058 OStringToOUString(aInfo.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US))); 1059 xInfoBox->run(); 1060 1061 } 1062 bDone = false; 1063 } 1064 break; 1065 case KEY_F12: 1066 { 1067 if ( rKeyEvent.GetKeyCode().IsMod1() && rKeyEvent.GetKeyCode().IsMod2() ) 1068 { 1069 EditDbg::ShowEditEngineData( this ); 1070 } 1071 bDone = false; 1072 } 1073 break; 1074 #endif 1075 case KEY_UP: 1076 case KEY_DOWN: 1077 case KEY_LEFT: 1078 case KEY_RIGHT: 1079 case KEY_HOME: 1080 case KEY_END: 1081 case KEY_PAGEUP: 1082 case KEY_PAGEDOWN: 1083 case css::awt::Key::MOVE_WORD_FORWARD: 1084 case css::awt::Key::SELECT_WORD_FORWARD: 1085 case css::awt::Key::MOVE_WORD_BACKWARD: 1086 case css::awt::Key::SELECT_WORD_BACKWARD: 1087 case css::awt::Key::MOVE_TO_BEGIN_OF_LINE: 1088 case css::awt::Key::MOVE_TO_END_OF_LINE: 1089 case css::awt::Key::SELECT_TO_BEGIN_OF_LINE: 1090 case css::awt::Key::SELECT_TO_END_OF_LINE: 1091 case css::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH: 1092 case css::awt::Key::MOVE_TO_END_OF_PARAGRAPH: 1093 case css::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH: 1094 case css::awt::Key::SELECT_TO_END_OF_PARAGRAPH: 1095 case css::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT: 1096 case css::awt::Key::MOVE_TO_END_OF_DOCUMENT: 1097 case css::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT: 1098 case css::awt::Key::SELECT_TO_END_OF_DOCUMENT: 1099 { 1100 if ( !rKeyEvent.GetKeyCode().IsMod2() || ( nCode == KEY_LEFT ) || ( nCode == KEY_RIGHT ) ) 1101 { 1102 if ( pImpEditEngine->DoVisualCursorTraveling() && ( ( nCode == KEY_LEFT ) || ( nCode == KEY_RIGHT ) /* || ( nCode == KEY_HOME ) || ( nCode == KEY_END ) */ ) ) 1103 bSetCursorFlags = false; // Will be manipulated within visual cursor move 1104 1105 aCurSel = pImpEditEngine->MoveCursor( rKeyEvent, pEditView ); 1106 1107 if ( aCurSel.HasRange() ) { 1108 if (vcl::Window* pWindow = pEditView->GetWindow()) { 1109 Reference<css::datatransfer::clipboard::XClipboard> aSelection(pWindow->GetPrimarySelection()); 1110 pEditView->pImpEditView->CutCopy( aSelection, false ); 1111 } 1112 } 1113 1114 bMoved = true; 1115 if ( nCode == KEY_HOME ) 1116 nNewCursorFlags |= GetCursorFlags::StartOfLine; 1117 else if ( nCode == KEY_END ) 1118 nNewCursorFlags |= GetCursorFlags::EndOfLine; 1119 1120 } 1121 #if OSL_DEBUG_LEVEL > 1 1122 GetLanguage( pImpEditEngine->GetEditDoc().GetPos( aCurSel.Max().GetNode() ), aCurSel.Max().GetIndex() ); 1123 #endif 1124 } 1125 break; 1126 case KEY_BACKSPACE: 1127 case KEY_DELETE: 1128 case css::awt::Key::DELETE_WORD_BACKWARD: 1129 case css::awt::Key::DELETE_WORD_FORWARD: 1130 case css::awt::Key::DELETE_TO_BEGIN_OF_PARAGRAPH: 1131 case css::awt::Key::DELETE_TO_END_OF_PARAGRAPH: 1132 { 1133 if ( !bReadOnly && !rKeyEvent.GetKeyCode().IsMod2() ) 1134 { 1135 // check if we are behind a bullet and using the backspace key 1136 ContentNode *pNode = aCurSel.Min().GetNode(); 1137 const SvxNumberFormat *pFmt = pImpEditEngine->GetNumberFormat( pNode ); 1138 if (pFmt && nCode == KEY_BACKSPACE && 1139 !aCurSel.HasRange() && aCurSel.Min().GetIndex() == 0) 1140 { 1141 // if the bullet is still visible, just make it invisible. 1142 // Otherwise continue as usual. 1143 1144 1145 sal_Int32 nPara = pImpEditEngine->GetEditDoc().GetPos( pNode ); 1146 SfxBoolItem aBulletState( pImpEditEngine->GetParaAttrib( nPara, EE_PARA_BULLETSTATE ) ); 1147 1148 if ( aBulletState.GetValue() ) 1149 { 1150 1151 aBulletState.SetValue( false ); 1152 SfxItemSet aSet( pImpEditEngine->GetParaAttribs( nPara ) ); 1153 aSet.Put( aBulletState ); 1154 pImpEditEngine->SetParaAttribs( nPara, aSet ); 1155 1156 // have this and the following paragraphs formatted and repainted. 1157 // (not painting a numbering in the list may cause the following 1158 // numberings to have different numbers than before and thus the 1159 // length may have changed as well ) 1160 pImpEditEngine->FormatAndUpdate( pImpEditEngine->GetActiveView() ); 1161 1162 break; 1163 } 1164 } 1165 1166 sal_uInt8 nDel = 0; 1167 DeleteMode nMode = DeleteMode::Simple; 1168 switch( nCode ) 1169 { 1170 case css::awt::Key::DELETE_WORD_BACKWARD: 1171 nMode = DeleteMode::RestOfWord; 1172 nDel = DEL_LEFT; 1173 break; 1174 case css::awt::Key::DELETE_WORD_FORWARD: 1175 nMode = DeleteMode::RestOfWord; 1176 nDel = DEL_RIGHT; 1177 break; 1178 case css::awt::Key::DELETE_TO_BEGIN_OF_PARAGRAPH: 1179 nMode = DeleteMode::RestOfContent; 1180 nDel = DEL_LEFT; 1181 break; 1182 case css::awt::Key::DELETE_TO_END_OF_PARAGRAPH: 1183 nMode = DeleteMode::RestOfContent; 1184 nDel = DEL_RIGHT; 1185 break; 1186 default: 1187 nDel = ( nCode == KEY_DELETE ) ? DEL_RIGHT : DEL_LEFT; 1188 nMode = rKeyEvent.GetKeyCode().IsMod1() ? DeleteMode::RestOfWord : DeleteMode::Simple; 1189 if ( ( nMode == DeleteMode::RestOfWord ) && rKeyEvent.GetKeyCode().IsShift() ) 1190 nMode = DeleteMode::RestOfContent; 1191 break; 1192 } 1193 1194 pEditView->pImpEditView->DrawSelectionXOR(); 1195 pImpEditEngine->UndoActionStart( EDITUNDO_DELETE ); 1196 aCurSel = pImpEditEngine->DeleteLeftOrRight( aCurSel, nDel, nMode ); 1197 pImpEditEngine->UndoActionEnd(); 1198 bModified = true; 1199 bAllowIdle = false; 1200 } 1201 } 1202 break; 1203 case KEY_TAB: 1204 { 1205 if ( !bReadOnly && !rKeyEvent.GetKeyCode().IsMod1() && !rKeyEvent.GetKeyCode().IsMod2() ) 1206 { 1207 bool bShift = rKeyEvent.GetKeyCode().IsShift(); 1208 if ( !bShift ) 1209 { 1210 bool bSel = pEditView->HasSelection(); 1211 if ( bSel ) 1212 pImpEditEngine->UndoActionStart( EDITUNDO_INSERT ); 1213 if ( pImpEditEngine->GetStatus().DoAutoCorrect() ) 1214 aCurSel = pImpEditEngine->AutoCorrect( aCurSel, 0, !pEditView->IsInsertMode(), pFrameWin ); 1215 aCurSel = pImpEditEngine->InsertTab( aCurSel ); 1216 if ( bSel ) 1217 pImpEditEngine->UndoActionEnd(); 1218 bModified = true; 1219 } 1220 } 1221 else 1222 bDone = false; 1223 } 1224 break; 1225 case KEY_RETURN: 1226 { 1227 if ( !bReadOnly ) 1228 { 1229 pEditView->pImpEditView->DrawSelectionXOR(); 1230 if ( !rKeyEvent.GetKeyCode().IsMod1() && !rKeyEvent.GetKeyCode().IsMod2() ) 1231 { 1232 pImpEditEngine->UndoActionStart( EDITUNDO_INSERT ); 1233 if ( rKeyEvent.GetKeyCode().IsShift() ) 1234 { 1235 aCurSel = pImpEditEngine->AutoCorrect( aCurSel, 0, !pEditView->IsInsertMode(), pFrameWin ); 1236 aCurSel = pImpEditEngine->InsertLineBreak( aCurSel ); 1237 } 1238 else 1239 { 1240 if (aAutoText.isEmpty()) 1241 { 1242 if ( pImpEditEngine->GetStatus().DoAutoCorrect() ) 1243 aCurSel = pImpEditEngine->AutoCorrect( aCurSel, 0, !pEditView->IsInsertMode(), pFrameWin ); 1244 aCurSel = pImpEditEngine->InsertParaBreak( aCurSel ); 1245 } 1246 else 1247 { 1248 DBG_ASSERT( !aCurSel.HasRange(), "Selection on complete?!" ); 1249 EditPaM aStart( pImpEditEngine->WordLeft( aCurSel.Max() ) ); 1250 aCurSel = pImpEditEngine->InsertText( 1251 EditSelection( aStart, aCurSel.Max() ), aAutoText ); 1252 pImpEditEngine->SetAutoCompleteText( OUString(), true ); 1253 } 1254 } 1255 pImpEditEngine->UndoActionEnd(); 1256 bModified = true; 1257 } 1258 } 1259 } 1260 break; 1261 case KEY_INSERT: 1262 { 1263 if ( !rKeyEvent.GetKeyCode().IsMod1() && !rKeyEvent.GetKeyCode().IsMod2() ) 1264 pEditView->SetInsertMode( !pEditView->IsInsertMode() ); 1265 } 1266 break; 1267 default: 1268 { 1269 #if (OSL_DEBUG_LEVEL > 1) && defined(DBG_UTIL) 1270 if ( ( nCode == KEY_W ) && rKeyEvent.GetKeyCode().IsMod1() && rKeyEvent.GetKeyCode().IsMod2() ) 1271 { 1272 SfxItemSet aAttribs = pEditView->GetAttribs(); 1273 const SvxFrameDirectionItem& rCurrentWritingMode = (const SvxFrameDirectionItem&)aAttribs.Get( EE_PARA_WRITINGDIR ); 1274 SvxFrameDirectionItem aNewItem( SvxFrameDirection::Horizontal_LR_TB, EE_PARA_WRITINGDIR ); 1275 if ( rCurrentWritingMode.GetValue() != SvxFrameDirection::Horizontal_RL_TB ) 1276 aNewItem.SetValue( SvxFrameDirection::Horizontal_RL_TB ); 1277 aAttribs.Put( aNewItem ); 1278 pEditView->SetAttribs( aAttribs ); 1279 } 1280 #endif 1281 if ( !bReadOnly && IsSimpleCharInput( rKeyEvent ) ) 1282 { 1283 sal_Unicode nCharCode = rKeyEvent.GetCharCode(); 1284 pEditView->pImpEditView->DrawSelectionXOR(); 1285 // Autocorrection? 1286 if ( ( pImpEditEngine->GetStatus().DoAutoCorrect() ) && 1287 ( SvxAutoCorrect::IsAutoCorrectChar( nCharCode ) || 1288 pImpEditEngine->IsNbspRunNext() ) ) 1289 { 1290 aCurSel = pImpEditEngine->AutoCorrect( 1291 aCurSel, nCharCode, !pEditView->IsInsertMode(), pFrameWin ); 1292 } 1293 else 1294 { 1295 aCurSel = pImpEditEngine->InsertTextUserInput( aCurSel, nCharCode, !pEditView->IsInsertMode() ); 1296 } 1297 // AutoComplete ??? 1298 if ( pImpEditEngine->GetStatus().DoAutoComplete() && ( nCharCode != ' ' ) ) 1299 { 1300 // Only at end of word... 1301 sal_Int32 nIndex = aCurSel.Max().GetIndex(); 1302 if ( ( nIndex >= aCurSel.Max().GetNode()->Len() ) || 1303 ( pImpEditEngine->aWordDelimiters.indexOf( aCurSel.Max().GetNode()->GetChar( nIndex ) ) != -1 ) ) 1304 { 1305 EditPaM aStart( pImpEditEngine->WordLeft( aCurSel.Max() ) ); 1306 OUString aWord = pImpEditEngine->GetSelected( EditSelection( aStart, aCurSel.Max() ) ); 1307 if ( aWord.getLength() >= 3 ) 1308 { 1309 OUString aComplete; 1310 1311 LanguageType eLang = pImpEditEngine->GetLanguage( EditPaM( aStart.GetNode(), aStart.GetIndex()+1)); 1312 LanguageTag aLanguageTag( eLang); 1313 1314 if (!pImpEditEngine->xLocaleDataWrapper.isInitialized()) 1315 pImpEditEngine->xLocaleDataWrapper.init( SvtSysLocale().GetLocaleData().getComponentContext(), aLanguageTag); 1316 else 1317 pImpEditEngine->xLocaleDataWrapper.changeLocale( aLanguageTag); 1318 1319 if (!pImpEditEngine->xTransliterationWrapper.isInitialized()) 1320 pImpEditEngine->xTransliterationWrapper.init( SvtSysLocale().GetLocaleData().getComponentContext(), eLang); 1321 else 1322 pImpEditEngine->xTransliterationWrapper.changeLocale( eLang); 1323 1324 const ::utl::TransliterationWrapper* pTransliteration = pImpEditEngine->xTransliterationWrapper.get(); 1325 Sequence< i18n::CalendarItem2 > xItem = pImpEditEngine->xLocaleDataWrapper->getDefaultCalendarDays(); 1326 sal_Int32 nCount = xItem.getLength(); 1327 const i18n::CalendarItem2* pArr = xItem.getArray(); 1328 for( sal_Int32 n = 0; n <= nCount; ++n ) 1329 { 1330 const OUString& rDay = pArr[n].FullName; 1331 if( pTransliteration->isMatch( aWord, rDay) ) 1332 { 1333 aComplete = rDay; 1334 break; 1335 } 1336 } 1337 1338 if ( aComplete.isEmpty() ) 1339 { 1340 xItem = pImpEditEngine->xLocaleDataWrapper->getDefaultCalendarMonths(); 1341 sal_Int32 nMonthCount = xItem.getLength(); 1342 const i18n::CalendarItem2* pMonthArr = xItem.getArray(); 1343 for( sal_Int32 n = 0; n <= nMonthCount; ++n ) 1344 { 1345 const OUString& rMon = pMonthArr[n].FullName; 1346 if( pTransliteration->isMatch( aWord, rMon) ) 1347 { 1348 aComplete = rMon; 1349 break; 1350 } 1351 } 1352 } 1353 1354 if( !aComplete.isEmpty() && ( ( aWord.getLength() + 1 ) < aComplete.getLength() ) ) 1355 { 1356 pImpEditEngine->SetAutoCompleteText( aComplete, false ); 1357 Point aPos = pImpEditEngine->PaMtoEditCursor( aCurSel.Max() ).TopLeft(); 1358 aPos = pEditView->pImpEditView->GetWindowPos( aPos ); 1359 aPos = pEditView->pImpEditView->GetWindow()->LogicToPixel( aPos ); 1360 aPos = pEditView->GetWindow()->OutputToScreenPixel( aPos ); 1361 aPos.AdjustY( -3 ); 1362 Help::ShowQuickHelp( pEditView->GetWindow(), tools::Rectangle( aPos, Size( 1, 1 ) ), aComplete, QuickHelpFlags::Bottom|QuickHelpFlags::Left ); 1363 } 1364 } 1365 } 1366 } 1367 bModified = true; 1368 } 1369 else 1370 bDone = false; 1371 } 1372 } 1373 } 1374 1375 pEditView->pImpEditView->SetEditSelection( aCurSel ); 1376 if (comphelper::LibreOfficeKit::isActive()) 1377 { 1378 pEditView->pImpEditView->DrawSelectionXOR(); 1379 } 1380 pImpEditEngine->UpdateSelections(); 1381 1382 if ( ( !IsVertical() && ( nCode != KEY_UP ) && ( nCode != KEY_DOWN ) ) || 1383 ( IsVertical() && ( nCode != KEY_LEFT ) && ( nCode != KEY_RIGHT ) )) 1384 { 1385 pEditView->pImpEditView->nTravelXPos = TRAVEL_X_DONTKNOW; 1386 } 1387 1388 if ( /* ( nCode != KEY_HOME ) && ( nCode != KEY_END ) && */ 1389 ( !IsVertical() && ( nCode != KEY_LEFT ) && ( nCode != KEY_RIGHT ) ) || 1390 ( IsVertical() && ( nCode != KEY_UP ) && ( nCode != KEY_DOWN ) )) 1391 { 1392 pEditView->pImpEditView->SetCursorBidiLevel( CURSOR_BIDILEVEL_DONTKNOW ); 1393 } 1394 1395 if ( bSetCursorFlags ) 1396 pEditView->pImpEditView->nExtraCursorFlags = nNewCursorFlags; 1397 1398 if ( bModified ) 1399 { 1400 DBG_ASSERT( !bReadOnly, "ReadOnly but modified???" ); 1401 // Idle-Formatter only when AnyInput. 1402 if ( bAllowIdle && pImpEditEngine->GetStatus().UseIdleFormatter() 1403 && Application::AnyInput( VclInputFlags::KEYBOARD) ) 1404 pImpEditEngine->IdleFormatAndUpdate( pEditView ); 1405 else 1406 pImpEditEngine->FormatAndUpdate( pEditView ); 1407 } 1408 else if ( bMoved ) 1409 { 1410 bool bGotoCursor = pEditView->pImpEditView->DoAutoScroll(); 1411 pEditView->pImpEditView->ShowCursor( bGotoCursor, true ); 1412 pImpEditEngine->CallStatusHdl(); 1413 } 1414 1415 return bDone; 1416 } 1417 1418 sal_uInt32 EditEngine::GetTextHeight() const 1419 { 1420 1421 if ( !pImpEditEngine->IsFormatted() ) 1422 pImpEditEngine->FormatDoc(); 1423 1424 sal_uInt32 nHeight = !IsVertical() ? pImpEditEngine->GetTextHeight() : pImpEditEngine->CalcTextWidth( true ); 1425 return nHeight; 1426 } 1427 1428 sal_uInt32 EditEngine::GetTextHeightNTP() const 1429 { 1430 1431 if ( !pImpEditEngine->IsFormatted() ) 1432 pImpEditEngine->FormatDoc(); 1433 1434 if ( IsVertical() ) 1435 return pImpEditEngine->CalcTextWidth( true ); 1436 1437 return pImpEditEngine->GetTextHeightNTP(); 1438 } 1439 1440 sal_uInt32 EditEngine::CalcTextWidth() 1441 { 1442 1443 if ( !pImpEditEngine->IsFormatted() ) 1444 pImpEditEngine->FormatDoc(); 1445 1446 sal_uInt32 nWidth = !IsVertical() ? pImpEditEngine->CalcTextWidth( true ) : pImpEditEngine->GetTextHeight(); 1447 return nWidth; 1448 } 1449 1450 void EditEngine::SetUpdateMode( bool bUpdate ) 1451 { 1452 pImpEditEngine->SetUpdateMode( bUpdate ); 1453 if ( pImpEditEngine->pActiveView ) 1454 pImpEditEngine->pActiveView->ShowCursor( false, false, /*bActivate=*/true ); 1455 } 1456 1457 bool EditEngine::GetUpdateMode() const 1458 { 1459 return pImpEditEngine->GetUpdateMode(); 1460 } 1461 1462 void EditEngine::Clear() 1463 { 1464 pImpEditEngine->Clear(); 1465 } 1466 1467 void EditEngine::SetText( const OUString& rText ) 1468 { 1469 pImpEditEngine->SetText( rText ); 1470 if ( !rText.isEmpty() ) 1471 pImpEditEngine->FormatAndUpdate(); 1472 } 1473 1474 ErrCode EditEngine::Read( SvStream& rInput, const OUString& rBaseURL, EETextFormat eFormat, SvKeyValueIterator* pHTTPHeaderAttrs /* = NULL */ ) 1475 { 1476 bool bUndoEnabled = pImpEditEngine->IsUndoEnabled(); 1477 pImpEditEngine->EnableUndo( false ); 1478 pImpEditEngine->SetText( OUString() ); 1479 EditPaM aPaM( pImpEditEngine->GetEditDoc().GetStartPaM() ); 1480 pImpEditEngine->Read( rInput, rBaseURL, eFormat, EditSelection( aPaM, aPaM ), pHTTPHeaderAttrs ); 1481 pImpEditEngine->EnableUndo( bUndoEnabled ); 1482 return rInput.GetError(); 1483 } 1484 1485 void EditEngine::Write( SvStream& rOutput, EETextFormat eFormat ) 1486 { 1487 EditPaM aStartPaM( pImpEditEngine->GetEditDoc().GetStartPaM() ); 1488 EditPaM aEndPaM( pImpEditEngine->GetEditDoc().GetEndPaM() ); 1489 pImpEditEngine->Write( rOutput, eFormat, EditSelection( aStartPaM, aEndPaM ) ); 1490 } 1491 1492 std::unique_ptr<EditTextObject> EditEngine::CreateTextObject() 1493 { 1494 return pImpEditEngine->CreateTextObject(); 1495 } 1496 1497 std::unique_ptr<EditTextObject> EditEngine::CreateTextObject( const ESelection& rESelection ) 1498 { 1499 EditSelection aSel( pImpEditEngine->CreateSel( rESelection ) ); 1500 return pImpEditEngine->CreateTextObject( aSel ); 1501 } 1502 1503 std::unique_ptr<EditTextObject> EditEngine::GetEmptyTextObject() const 1504 { 1505 return pImpEditEngine->GetEmptyTextObject(); 1506 } 1507 1508 1509 void EditEngine::SetText( const EditTextObject& rTextObject ) 1510 { 1511 pImpEditEngine->SetText( rTextObject ); 1512 pImpEditEngine->FormatAndUpdate(); 1513 } 1514 1515 void EditEngine::ShowParagraph( sal_Int32 nParagraph, bool bShow ) 1516 { 1517 pImpEditEngine->ShowParagraph( nParagraph, bShow ); 1518 } 1519 1520 void EditEngine::SetNotifyHdl( const Link<EENotify&,void>& rLink ) 1521 { 1522 pImpEditEngine->SetNotifyHdl( rLink ); 1523 } 1524 1525 Link<EENotify&,void> const & EditEngine::GetNotifyHdl() const 1526 { 1527 return pImpEditEngine->GetNotifyHdl(); 1528 } 1529 1530 void EditEngine::SetStatusEventHdl( const Link<EditStatus&, void>& rLink ) 1531 { 1532 pImpEditEngine->SetStatusEventHdl( rLink ); 1533 } 1534 1535 Link<EditStatus&, void> const & EditEngine::GetStatusEventHdl() const 1536 { 1537 return pImpEditEngine->GetStatusEventHdl(); 1538 } 1539 1540 void EditEngine::SetHtmlImportHdl( const Link<HtmlImportInfo&,void>& rLink ) 1541 { 1542 pImpEditEngine->aHtmlImportHdl = rLink; 1543 } 1544 1545 const Link<HtmlImportInfo&,void>& EditEngine::GetHtmlImportHdl() const 1546 { 1547 return pImpEditEngine->aHtmlImportHdl; 1548 } 1549 1550 void EditEngine::SetRtfImportHdl( const Link<RtfImportInfo&,void>& rLink ) 1551 { 1552 pImpEditEngine->aRtfImportHdl = rLink; 1553 } 1554 1555 const Link<RtfImportInfo&,void>& EditEngine::GetRtfImportHdl() const 1556 { 1557 return pImpEditEngine->aRtfImportHdl; 1558 } 1559 1560 void EditEngine::SetBeginMovingParagraphsHdl( const Link<MoveParagraphsInfo&,void>& rLink ) 1561 { 1562 pImpEditEngine->aBeginMovingParagraphsHdl = rLink; 1563 } 1564 1565 void EditEngine::SetEndMovingParagraphsHdl( const Link<MoveParagraphsInfo&,void>& rLink ) 1566 { 1567 pImpEditEngine->aEndMovingParagraphsHdl = rLink; 1568 } 1569 1570 void EditEngine::SetBeginPasteOrDropHdl( const Link<PasteOrDropInfos&,void>& rLink ) 1571 { 1572 1573 pImpEditEngine->aBeginPasteOrDropHdl = rLink; 1574 } 1575 1576 void EditEngine::SetEndPasteOrDropHdl( const Link<PasteOrDropInfos&,void>& rLink ) 1577 { 1578 pImpEditEngine->aEndPasteOrDropHdl = rLink; 1579 } 1580 1581 std::unique_ptr<EditTextObject> EditEngine::CreateTextObject( sal_Int32 nPara, sal_Int32 nParas ) 1582 { 1583 DBG_ASSERT( 0 <= nPara && nPara < pImpEditEngine->GetEditDoc().Count(), "CreateTextObject: Startpara out of Range" ); 1584 DBG_ASSERT( nParas <= pImpEditEngine->GetEditDoc().Count() - nPara, "CreateTextObject: Endpara out of Range" ); 1585 1586 ContentNode* pStartNode = pImpEditEngine->GetEditDoc().GetObject( nPara ); 1587 ContentNode* pEndNode = pImpEditEngine->GetEditDoc().GetObject( nPara+nParas-1 ); 1588 DBG_ASSERT( pStartNode, "Start-Paragraph does not exist: CreateTextObject" ); 1589 DBG_ASSERT( pEndNode, "End-Paragraph does not exist: CreateTextObject" ); 1590 1591 if ( pStartNode && pEndNode ) 1592 { 1593 EditSelection aTmpSel; 1594 aTmpSel.Min() = EditPaM( pStartNode, 0 ); 1595 aTmpSel.Max() = EditPaM( pEndNode, pEndNode->Len() ); 1596 return pImpEditEngine->CreateTextObject( aTmpSel ); 1597 } 1598 return nullptr; 1599 } 1600 1601 void EditEngine::RemoveParagraph( sal_Int32 nPara ) 1602 { 1603 DBG_ASSERT( pImpEditEngine->GetEditDoc().Count() > 1, "The first paragraph should not be deleted!" ); 1604 if( pImpEditEngine->GetEditDoc().Count() <= 1 ) 1605 return; 1606 1607 ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( nPara ); 1608 const ParaPortion* pPortion = pImpEditEngine->GetParaPortions().SafeGetObject( nPara ); 1609 DBG_ASSERT( pPortion && pNode, "Paragraph not found: RemoveParagraph" ); 1610 if ( pNode && pPortion ) 1611 { 1612 // No Undo encapsulation needed. 1613 pImpEditEngine->ImpRemoveParagraph( nPara ); 1614 pImpEditEngine->InvalidateFromParagraph( nPara ); 1615 pImpEditEngine->UpdateSelections(); 1616 pImpEditEngine->FormatAndUpdate(); 1617 } 1618 } 1619 1620 sal_Int32 EditEngine::GetTextLen( sal_Int32 nPara ) const 1621 { 1622 ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( nPara ); 1623 DBG_ASSERT( pNode, "Paragraph not found: GetTextLen" ); 1624 if ( pNode ) 1625 return pNode->Len(); 1626 return 0; 1627 } 1628 1629 OUString EditEngine::GetText( sal_Int32 nPara ) const 1630 { 1631 OUString aStr; 1632 if ( 0 <= nPara && nPara < pImpEditEngine->GetEditDoc().Count() ) 1633 aStr = pImpEditEngine->GetEditDoc().GetParaAsString( nPara ); 1634 return aStr; 1635 } 1636 1637 void EditEngine::SetModifyHdl( const Link<LinkParamNone*,void>& rLink ) 1638 { 1639 pImpEditEngine->SetModifyHdl( rLink ); 1640 } 1641 1642 Link<LinkParamNone*,void> const & EditEngine::GetModifyHdl() const 1643 { 1644 return pImpEditEngine->GetModifyHdl(); 1645 } 1646 1647 1648 void EditEngine::ClearModifyFlag() 1649 { 1650 pImpEditEngine->SetModifyFlag( false ); 1651 } 1652 1653 void EditEngine::SetModified() 1654 { 1655 pImpEditEngine->SetModifyFlag( true ); 1656 } 1657 1658 bool EditEngine::IsModified() const 1659 { 1660 return pImpEditEngine->IsModified(); 1661 } 1662 1663 bool EditEngine::IsInSelectionMode() const 1664 { 1665 return ( pImpEditEngine->IsInSelectionMode() || 1666 pImpEditEngine->GetSelEngine().IsInSelection() ); 1667 } 1668 1669 void EditEngine::InsertParagraph( sal_Int32 nPara, const EditTextObject& rTxtObj, bool bAppend ) 1670 { 1671 if ( nPara > GetParagraphCount() ) 1672 { 1673 SAL_WARN_IF( nPara != EE_PARA_APPEND, "editeng", "Paragraph number too large, but not EE_PARA_APPEND!" ); 1674 nPara = GetParagraphCount(); 1675 } 1676 1677 pImpEditEngine->UndoActionStart( EDITUNDO_INSERT ); 1678 1679 // No Undo compounding needed. 1680 EditPaM aPaM( pImpEditEngine->InsertParagraph( nPara ) ); 1681 // When InsertParagraph from the outside, no hard attributes 1682 // should be taken over! 1683 pImpEditEngine->RemoveCharAttribs( nPara ); 1684 pImpEditEngine->InsertText( rTxtObj, EditSelection( aPaM, aPaM ) ); 1685 1686 if ( bAppend && nPara ) 1687 pImpEditEngine->ConnectContents( nPara-1, /*bBackwards=*/false ); 1688 1689 pImpEditEngine->UndoActionEnd(); 1690 1691 pImpEditEngine->FormatAndUpdate(); 1692 } 1693 1694 void EditEngine::InsertParagraph(sal_Int32 nPara, const OUString& rTxt) 1695 { 1696 if ( nPara > GetParagraphCount() ) 1697 { 1698 SAL_WARN_IF( nPara != EE_PARA_APPEND, "editeng", "Paragraph number too large, but not EE_PARA_APPEND!" ); 1699 nPara = GetParagraphCount(); 1700 } 1701 1702 pImpEditEngine->UndoActionStart( EDITUNDO_INSERT ); 1703 EditPaM aPaM( pImpEditEngine->InsertParagraph( nPara ) ); 1704 // When InsertParagraph from the outside, no hard attributes 1705 // should be taken over! 1706 pImpEditEngine->RemoveCharAttribs( nPara ); 1707 pImpEditEngine->UndoActionEnd(); 1708 pImpEditEngine->ImpInsertText( EditSelection( aPaM, aPaM ), rTxt ); 1709 pImpEditEngine->FormatAndUpdate(); 1710 } 1711 1712 void EditEngine::SetText(sal_Int32 nPara, const OUString& rTxt) 1713 { 1714 std::unique_ptr<EditSelection> pSel = pImpEditEngine->SelectParagraph( nPara ); 1715 if ( pSel ) 1716 { 1717 pImpEditEngine->UndoActionStart( EDITUNDO_INSERT ); 1718 pImpEditEngine->ImpInsertText( *pSel, rTxt ); 1719 pImpEditEngine->UndoActionEnd(); 1720 pImpEditEngine->FormatAndUpdate(); 1721 } 1722 } 1723 1724 void EditEngine::SetParaAttribs( sal_Int32 nPara, const SfxItemSet& rSet ) 1725 { 1726 pImpEditEngine->SetParaAttribs( nPara, rSet ); 1727 pImpEditEngine->FormatAndUpdate(); 1728 } 1729 1730 const SfxItemSet& EditEngine::GetParaAttribs( sal_Int32 nPara ) const 1731 { 1732 return pImpEditEngine->GetParaAttribs( nPara ); 1733 } 1734 1735 bool EditEngine::HasParaAttrib( sal_Int32 nPara, sal_uInt16 nWhich ) const 1736 { 1737 return pImpEditEngine->HasParaAttrib( nPara, nWhich ); 1738 } 1739 1740 const SfxPoolItem& EditEngine::GetParaAttrib( sal_Int32 nPara, sal_uInt16 nWhich ) 1741 { 1742 return pImpEditEngine->GetParaAttrib( nPara, nWhich ); 1743 } 1744 1745 void EditEngine::SetCharAttribs(sal_Int32 nPara, const SfxItemSet& rSet) 1746 { 1747 EditSelection aSel(pImpEditEngine->ConvertSelection(nPara, 0, nPara, GetTextLen(nPara))); 1748 pImpEditEngine->SetAttribs(aSel, rSet); 1749 pImpEditEngine->FormatAndUpdate(); 1750 } 1751 1752 void EditEngine::GetCharAttribs( sal_Int32 nPara, std::vector<EECharAttrib>& rLst ) const 1753 { 1754 pImpEditEngine->GetCharAttribs( nPara, rLst ); 1755 } 1756 1757 SfxItemSet EditEngine::GetAttribs( const ESelection& rSel, EditEngineAttribs nOnlyHardAttrib ) 1758 { 1759 EditSelection aSel( pImpEditEngine-> 1760 ConvertSelection( rSel.nStartPara, rSel.nStartPos, rSel.nEndPara, rSel.nEndPos ) ); 1761 return pImpEditEngine->GetAttribs( aSel, nOnlyHardAttrib ); 1762 } 1763 1764 SfxItemSet EditEngine::GetAttribs( sal_Int32 nPara, sal_Int32 nStart, sal_Int32 nEnd, GetAttribsFlags nFlags ) const 1765 { 1766 return pImpEditEngine->GetAttribs( nPara, nStart, nEnd, nFlags ); 1767 } 1768 1769 void EditEngine::RemoveAttribs( const ESelection& rSelection, bool bRemoveParaAttribs, sal_uInt16 nWhich ) 1770 { 1771 1772 pImpEditEngine->UndoActionStart( EDITUNDO_RESETATTRIBS ); 1773 EditSelection aSel( pImpEditEngine->ConvertSelection( rSelection.nStartPara, rSelection.nStartPos, rSelection.nEndPara, rSelection.nEndPos ) ); 1774 pImpEditEngine->RemoveCharAttribs( aSel, bRemoveParaAttribs, nWhich ); 1775 pImpEditEngine->UndoActionEnd(); 1776 pImpEditEngine->FormatAndUpdate(); 1777 } 1778 1779 vcl::Font EditEngine::GetStandardFont( sal_Int32 nPara ) 1780 { 1781 return GetStandardSvxFont( nPara ); 1782 } 1783 1784 SvxFont EditEngine::GetStandardSvxFont( sal_Int32 nPara ) 1785 { 1786 ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( nPara ); 1787 return pNode->GetCharAttribs().GetDefFont(); 1788 } 1789 1790 void EditEngine::StripPortions() 1791 { 1792 ScopedVclPtrInstance< VirtualDevice > aTmpDev; 1793 tools::Rectangle aBigRect( Point( 0, 0 ), Size( 0x7FFFFFFF, 0x7FFFFFFF ) ); 1794 if ( IsVertical() ) 1795 { 1796 if( IsTopToBottom() ) 1797 { 1798 aBigRect.SetRight( 0 ); 1799 aBigRect.SetLeft( -0x7FFFFFFF ); 1800 } 1801 else 1802 { 1803 aBigRect.SetTop( -0x7FFFFFFF ); 1804 aBigRect.SetBottom( 0 ); 1805 } 1806 } 1807 pImpEditEngine->Paint( aTmpDev.get(), aBigRect, Point(), true ); 1808 } 1809 1810 void EditEngine::GetPortions( sal_Int32 nPara, std::vector<sal_Int32>& rList ) 1811 { 1812 if ( !pImpEditEngine->IsFormatted() ) 1813 pImpEditEngine->FormatFullDoc(); 1814 1815 const ParaPortion* pParaPortion = pImpEditEngine->GetParaPortions().SafeGetObject( nPara ); 1816 if ( pParaPortion ) 1817 { 1818 sal_Int32 nEnd = 0; 1819 sal_Int32 nTextPortions = pParaPortion->GetTextPortions().Count(); 1820 for ( sal_Int32 n = 0; n < nTextPortions; n++ ) 1821 { 1822 nEnd = nEnd + pParaPortion->GetTextPortions()[n].GetLen(); 1823 rList.push_back( nEnd ); 1824 } 1825 } 1826 } 1827 1828 void EditEngine::SetFlatMode( bool bFlat) 1829 { 1830 pImpEditEngine->SetFlatMode( bFlat ); 1831 } 1832 1833 bool EditEngine::IsFlatMode() const 1834 { 1835 return !( pImpEditEngine->aStatus.UseCharAttribs() ); 1836 } 1837 1838 void EditEngine::SetControlWord( EEControlBits nWord ) 1839 { 1840 1841 if ( nWord != pImpEditEngine->aStatus.GetControlWord() ) 1842 { 1843 EEControlBits nPrev = pImpEditEngine->aStatus.GetControlWord(); 1844 pImpEditEngine->aStatus.GetControlWord() = nWord; 1845 1846 EEControlBits nChanges = nPrev ^ nWord; 1847 if ( pImpEditEngine->IsFormatted() ) 1848 { 1849 // possibly reformat: 1850 if ( ( nChanges & EEControlBits::USECHARATTRIBS ) || 1851 ( nChanges & EEControlBits::ONECHARPERLINE ) || 1852 ( nChanges & EEControlBits::STRETCHING ) || 1853 ( nChanges & EEControlBits::OUTLINER ) || 1854 ( nChanges & EEControlBits::NOCOLORS ) || 1855 ( nChanges & EEControlBits::OUTLINER2 ) ) 1856 { 1857 if ( nChanges & EEControlBits::USECHARATTRIBS ) 1858 { 1859 pImpEditEngine->GetEditDoc().CreateDefFont( true ); 1860 } 1861 1862 pImpEditEngine->FormatFullDoc(); 1863 pImpEditEngine->UpdateViews( pImpEditEngine->GetActiveView() ); 1864 } 1865 } 1866 1867 bool bSpellingChanged = bool(nChanges & EEControlBits::ONLINESPELLING); 1868 1869 if ( bSpellingChanged ) 1870 { 1871 pImpEditEngine->StopOnlineSpellTimer(); 1872 if (nWord & EEControlBits::ONLINESPELLING) 1873 { 1874 // Create WrongList, start timer... 1875 sal_Int32 nNodes = pImpEditEngine->GetEditDoc().Count(); 1876 for ( sal_Int32 n = 0; n < nNodes; n++ ) 1877 { 1878 ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( n ); 1879 pNode->CreateWrongList(); 1880 } 1881 if (pImpEditEngine->IsFormatted()) 1882 pImpEditEngine->StartOnlineSpellTimer(); 1883 } 1884 else 1885 { 1886 long nY = 0; 1887 sal_Int32 nNodes = pImpEditEngine->GetEditDoc().Count(); 1888 for ( sal_Int32 n = 0; n < nNodes; n++ ) 1889 { 1890 ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( n ); 1891 const ParaPortion* pPortion = pImpEditEngine->GetParaPortions()[n]; 1892 bool bWrongs = false; 1893 if (pNode->GetWrongList() != nullptr) 1894 bWrongs = !pNode->GetWrongList()->empty(); 1895 pNode->DestroyWrongList(); 1896 if ( bWrongs ) 1897 { 1898 pImpEditEngine->aInvalidRect.SetLeft( 0 ); 1899 pImpEditEngine->aInvalidRect.SetRight( pImpEditEngine->GetPaperSize().Width() ); 1900 pImpEditEngine->aInvalidRect.SetTop( nY+1 ); 1901 pImpEditEngine->aInvalidRect.SetBottom( nY+pPortion->GetHeight()-1 ); 1902 pImpEditEngine->UpdateViews( pImpEditEngine->pActiveView ); 1903 } 1904 nY += pPortion->GetHeight(); 1905 } 1906 } 1907 } 1908 } 1909 } 1910 1911 EEControlBits EditEngine::GetControlWord() const 1912 { 1913 return pImpEditEngine->aStatus.GetControlWord(); 1914 } 1915 1916 long EditEngine::GetFirstLineStartX( sal_Int32 nParagraph ) 1917 { 1918 1919 long nX = 0; 1920 const ParaPortion* pPPortion = pImpEditEngine->GetParaPortions().SafeGetObject( nParagraph ); 1921 if ( pPPortion ) 1922 { 1923 DBG_ASSERT( pImpEditEngine->IsFormatted() || !pImpEditEngine->IsFormatting(), "GetFirstLineStartX: Doc not formatted - unable to format!" ); 1924 if ( !pImpEditEngine->IsFormatted() ) 1925 pImpEditEngine->FormatDoc(); 1926 const EditLine& rFirstLine = pPPortion->GetLines()[0]; 1927 nX = rFirstLine.GetStartPosX(); 1928 } 1929 return nX; 1930 } 1931 1932 Point EditEngine::GetDocPos( const Point& rPaperPos ) const 1933 { 1934 Point aDocPos( rPaperPos ); 1935 if ( IsVertical() ) 1936 { 1937 if ( IsTopToBottom() ) 1938 { 1939 aDocPos.setX( rPaperPos.Y() ); 1940 aDocPos.setY( GetPaperSize().Width() - rPaperPos.X() ); 1941 } 1942 else 1943 { 1944 aDocPos.setX( rPaperPos.Y() ); 1945 aDocPos.setY( rPaperPos.X() ); 1946 } 1947 } 1948 return aDocPos; 1949 } 1950 1951 Point EditEngine::GetDocPosTopLeft( sal_Int32 nParagraph ) 1952 { 1953 const ParaPortion* pPPortion = pImpEditEngine->GetParaPortions().SafeGetObject( nParagraph ); 1954 DBG_ASSERT( pPPortion, "Paragraph not found: GetWindowPosTopLeft" ); 1955 Point aPoint; 1956 if ( pPPortion ) 1957 { 1958 1959 // If someone calls GetLineHeight() with an empty Engine. 1960 DBG_ASSERT( pImpEditEngine->IsFormatted() || !pImpEditEngine->IsFormatting(), "GetDocPosTopLeft: Doc not formatted - unable to format!" ); 1961 if ( !pImpEditEngine->IsFormatted() ) 1962 pImpEditEngine->FormatAndUpdate(); 1963 if ( pPPortion->GetLines().Count() ) 1964 { 1965 // Correct it if large Bullet. 1966 const EditLine& rFirstLine = pPPortion->GetLines()[0]; 1967 aPoint.setX( rFirstLine.GetStartPosX() ); 1968 } 1969 else 1970 { 1971 const SvxLRSpaceItem& rLRItem = pImpEditEngine->GetLRSpaceItem( pPPortion->GetNode() ); 1972 // TL_NF_LR aPoint.X() = pImpEditEngine->GetXValue( (short)(rLRItem.GetTextLeft() + rLRItem.GetTextFirstLineOfst()) ); 1973 sal_Int32 nSpaceBefore = 0; 1974 pImpEditEngine->GetSpaceBeforeAndMinLabelWidth( pPPortion->GetNode(), &nSpaceBefore ); 1975 short nX = static_cast<short>(rLRItem.GetTextLeft() 1976 + rLRItem.GetTextFirstLineOfst() 1977 + nSpaceBefore); 1978 aPoint.setX( pImpEditEngine->GetXValue( nX 1979 ) ); 1980 } 1981 aPoint.setY( pImpEditEngine->GetParaPortions().GetYOffset( pPPortion ) ); 1982 } 1983 return aPoint; 1984 } 1985 1986 const SvxNumberFormat* EditEngine::GetNumberFormat( sal_Int32 ) const 1987 { 1988 // derived objects may override this function to give access to 1989 // bullet information (see Outliner) 1990 return nullptr; 1991 } 1992 1993 bool EditEngine::IsRightToLeft( sal_Int32 nPara ) const 1994 { 1995 return pImpEditEngine->IsRightToLeft( nPara ); 1996 } 1997 1998 bool EditEngine::IsTextPos( const Point& rPaperPos, sal_uInt16 nBorder ) 1999 { 2000 2001 if ( !pImpEditEngine->IsFormatted() ) 2002 pImpEditEngine->FormatDoc(); 2003 2004 bool bTextPos = false; 2005 // take unrotated positions for calculation here 2006 Point aDocPos = GetDocPos( rPaperPos ); 2007 2008 if ( ( aDocPos.Y() > 0 ) && ( aDocPos.Y() < static_cast<long>(pImpEditEngine->GetTextHeight()) ) ) 2009 { 2010 EditPaM aPaM = pImpEditEngine->GetPaM( aDocPos, false ); 2011 if ( aPaM.GetNode() ) 2012 { 2013 const ParaPortion* pParaPortion = pImpEditEngine->FindParaPortion( aPaM.GetNode() ); 2014 DBG_ASSERT( pParaPortion, "ParaPortion?" ); 2015 2016 sal_Int32 nLine = pParaPortion->GetLineNumber( aPaM.GetIndex() ); 2017 const EditLine& rLine = pParaPortion->GetLines()[nLine]; 2018 Range aLineXPosStartEnd = pImpEditEngine->GetLineXPosStartEnd( pParaPortion, &rLine ); 2019 if ( ( aDocPos.X() >= aLineXPosStartEnd.Min() - nBorder ) && 2020 ( aDocPos.X() <= aLineXPosStartEnd.Max() + nBorder ) ) 2021 { 2022 bTextPos = true; 2023 } 2024 } 2025 } 2026 return bTextPos; 2027 } 2028 2029 void EditEngine::SetEditTextObjectPool( SfxItemPool* pPool ) 2030 { 2031 pImpEditEngine->SetEditTextObjectPool( pPool ); 2032 } 2033 2034 SfxItemPool* EditEngine::GetEditTextObjectPool() const 2035 { 2036 return pImpEditEngine->GetEditTextObjectPool(); 2037 } 2038 2039 void EditEngine::QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel ) 2040 { 2041 2042 EditSelection aSel( pImpEditEngine-> 2043 ConvertSelection( rSel.nStartPara, rSel.nStartPos, rSel.nEndPara, rSel.nEndPos ) ); 2044 2045 pImpEditEngine->SetAttribs( aSel, rSet ); 2046 } 2047 2048 void EditEngine::QuickMarkInvalid( const ESelection& rSel ) 2049 { 2050 DBG_ASSERT( rSel.nStartPara < pImpEditEngine->GetEditDoc().Count(), "MarkInvalid: Start out of Range!" ); 2051 DBG_ASSERT( rSel.nEndPara < pImpEditEngine->GetEditDoc().Count(), "MarkInvalid: End out of Range!" ); 2052 for ( sal_Int32 nPara = rSel.nStartPara; nPara <= rSel.nEndPara; nPara++ ) 2053 { 2054 ParaPortion* pPortion = pImpEditEngine->GetParaPortions().SafeGetObject( nPara ); 2055 if ( pPortion ) 2056 pPortion->MarkSelectionInvalid( 0 ); 2057 } 2058 } 2059 2060 void EditEngine::QuickInsertText(const OUString& rText, const ESelection& rSel) 2061 { 2062 2063 EditSelection aSel( pImpEditEngine-> 2064 ConvertSelection( rSel.nStartPara, rSel.nStartPos, rSel.nEndPara, rSel.nEndPos ) ); 2065 2066 pImpEditEngine->ImpInsertText( aSel, rText ); 2067 } 2068 2069 void EditEngine::QuickDelete( const ESelection& rSel ) 2070 { 2071 2072 EditSelection aSel( pImpEditEngine-> 2073 ConvertSelection( rSel.nStartPara, rSel.nStartPos, rSel.nEndPara, rSel.nEndPos ) ); 2074 2075 pImpEditEngine->ImpDeleteSelection( aSel ); 2076 } 2077 2078 void EditEngine::QuickMarkToBeRepainted( sal_Int32 nPara ) 2079 { 2080 ParaPortion* pPortion = pImpEditEngine->GetParaPortions().SafeGetObject( nPara ); 2081 if ( pPortion ) 2082 pPortion->SetMustRepaint( true ); 2083 } 2084 2085 void EditEngine::QuickInsertLineBreak( const ESelection& rSel ) 2086 { 2087 2088 EditSelection aSel( pImpEditEngine-> 2089 ConvertSelection( rSel.nStartPara, rSel.nStartPos, rSel.nEndPara, rSel.nEndPos ) ); 2090 2091 pImpEditEngine->InsertLineBreak( aSel ); 2092 } 2093 2094 void EditEngine::QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel ) 2095 { 2096 2097 EditSelection aSel( pImpEditEngine-> 2098 ConvertSelection( rSel.nStartPara, rSel.nStartPos, rSel.nEndPara, rSel.nEndPos ) ); 2099 2100 pImpEditEngine->ImpInsertFeature( aSel, rFld ); 2101 } 2102 2103 void EditEngine::QuickFormatDoc( bool bFull ) 2104 { 2105 if ( bFull ) 2106 pImpEditEngine->FormatFullDoc(); 2107 else 2108 pImpEditEngine->FormatDoc(); 2109 2110 // Don't pass active view, maybe selection is not updated yet... 2111 pImpEditEngine->UpdateViews(); 2112 } 2113 2114 void EditEngine::SetStyleSheet(const EditSelection& aSel, SfxStyleSheet* pStyle) 2115 { 2116 pImpEditEngine->SetStyleSheet(aSel, pStyle); 2117 } 2118 2119 void EditEngine::SetStyleSheet( sal_Int32 nPara, SfxStyleSheet* pStyle ) 2120 { 2121 pImpEditEngine->SetStyleSheet( nPara, pStyle ); 2122 } 2123 2124 const SfxStyleSheet* EditEngine::GetStyleSheet( sal_Int32 nPara ) const 2125 { 2126 return pImpEditEngine->GetStyleSheet( nPara ); 2127 } 2128 2129 SfxStyleSheet* EditEngine::GetStyleSheet( sal_Int32 nPara ) 2130 { 2131 return pImpEditEngine->GetStyleSheet( nPara ); 2132 } 2133 2134 void EditEngine::SetStyleSheetPool( SfxStyleSheetPool* pSPool ) 2135 { 2136 pImpEditEngine->SetStyleSheetPool( pSPool ); 2137 } 2138 2139 SfxStyleSheetPool* EditEngine::GetStyleSheetPool() 2140 { 2141 return pImpEditEngine->GetStyleSheetPool(); 2142 } 2143 2144 void EditEngine::SetWordDelimiters( const OUString& rDelimiters ) 2145 { 2146 pImpEditEngine->aWordDelimiters = rDelimiters; 2147 if (pImpEditEngine->aWordDelimiters.indexOf(CH_FEATURE) == -1) 2148 pImpEditEngine->aWordDelimiters += OUStringLiteral1(CH_FEATURE); 2149 } 2150 2151 const OUString& EditEngine::GetWordDelimiters() const 2152 { 2153 return pImpEditEngine->aWordDelimiters; 2154 } 2155 2156 void EditEngine::EraseVirtualDevice() 2157 { 2158 pImpEditEngine->EraseVirtualDevice(); 2159 } 2160 2161 void EditEngine::SetSpeller( Reference< XSpellChecker1 > const &xSpeller ) 2162 { 2163 pImpEditEngine->SetSpeller( xSpeller ); 2164 } 2165 2166 Reference< XSpellChecker1 > const & EditEngine::GetSpeller() 2167 { 2168 return pImpEditEngine->GetSpeller(); 2169 } 2170 2171 void EditEngine::SetHyphenator( Reference< XHyphenator > const & xHyph ) 2172 { 2173 pImpEditEngine->SetHyphenator( xHyph ); 2174 } 2175 2176 void EditEngine::GetAllMisspellRanges( std::vector<editeng::MisspellRanges>& rRanges ) const 2177 { 2178 pImpEditEngine->GetAllMisspellRanges(rRanges); 2179 } 2180 2181 void EditEngine::SetAllMisspellRanges( const std::vector<editeng::MisspellRanges>& rRanges ) 2182 { 2183 pImpEditEngine->SetAllMisspellRanges(rRanges); 2184 } 2185 2186 void EditEngine::SetForbiddenCharsTable(const std::shared_ptr<SvxForbiddenCharactersTable>& xForbiddenChars) 2187 { 2188 ImpEditEngine::SetForbiddenCharsTable( xForbiddenChars ); 2189 } 2190 2191 void EditEngine::SetDefaultLanguage( LanguageType eLang ) 2192 { 2193 pImpEditEngine->SetDefaultLanguage( eLang ); 2194 } 2195 2196 LanguageType EditEngine::GetDefaultLanguage() const 2197 { 2198 return pImpEditEngine->GetDefaultLanguage(); 2199 } 2200 2201 bool EditEngine::SpellNextDocument() 2202 { 2203 return false; 2204 } 2205 2206 EESpellState EditEngine::HasSpellErrors() 2207 { 2208 if ( !pImpEditEngine->GetSpeller().is() ) 2209 return EESpellState::NoSpeller; 2210 2211 return pImpEditEngine->HasSpellErrors(); 2212 } 2213 2214 void EditEngine::ClearSpellErrors() 2215 { 2216 pImpEditEngine->ClearSpellErrors(); 2217 } 2218 2219 bool EditEngine::SpellSentence(EditView const & rView, svx::SpellPortions& rToFill ) 2220 { 2221 return pImpEditEngine->SpellSentence( rView, rToFill ); 2222 } 2223 2224 void EditEngine::PutSpellingToSentenceStart( EditView const & rEditView ) 2225 { 2226 pImpEditEngine->PutSpellingToSentenceStart( rEditView ); 2227 } 2228 2229 void EditEngine::ApplyChangedSentence(EditView const & rEditView, const svx::SpellPortions& rNewPortions, bool bRecheck ) 2230 { 2231 pImpEditEngine->ApplyChangedSentence( rEditView, rNewPortions, bRecheck ); 2232 } 2233 2234 bool EditEngine::HasConvertibleTextPortion( LanguageType nLang ) 2235 { 2236 return pImpEditEngine->HasConvertibleTextPortion( nLang ); 2237 } 2238 2239 bool EditEngine::ConvertNextDocument() 2240 { 2241 return false; 2242 } 2243 2244 bool EditEngine::HasText( const SvxSearchItem& rSearchItem ) 2245 { 2246 return pImpEditEngine->HasText( rSearchItem ); 2247 } 2248 2249 void EditEngine::SetGlobalCharStretching( sal_uInt16 nX, sal_uInt16 nY ) 2250 { 2251 pImpEditEngine->SetCharStretching( nX, nY ); 2252 } 2253 2254 void EditEngine::GetGlobalCharStretching( sal_uInt16& rX, sal_uInt16& rY ) const 2255 { 2256 pImpEditEngine->GetCharStretching( rX, rY ); 2257 } 2258 2259 bool EditEngine::ShouldCreateBigTextObject() const 2260 { 2261 sal_Int32 nTextPortions = 0; 2262 sal_Int32 nParas = pImpEditEngine->GetEditDoc().Count(); 2263 for ( sal_Int32 nPara = 0; nPara < nParas; nPara++ ) 2264 { 2265 ParaPortion* pParaPortion = pImpEditEngine->GetParaPortions()[nPara]; 2266 nTextPortions = nTextPortions + pParaPortion->GetTextPortions().Count(); 2267 } 2268 return nTextPortions >= pImpEditEngine->GetBigTextObjectStart(); 2269 } 2270 2271 sal_uInt16 EditEngine::GetFieldCount( sal_Int32 nPara ) const 2272 { 2273 sal_uInt16 nFields = 0; 2274 ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( nPara ); 2275 if ( pNode ) 2276 { 2277 for (auto const& attrib : pNode->GetCharAttribs().GetAttribs()) 2278 { 2279 if (attrib->Which() == EE_FEATURE_FIELD) 2280 ++nFields; 2281 } 2282 } 2283 2284 return nFields; 2285 } 2286 2287 EFieldInfo EditEngine::GetFieldInfo( sal_Int32 nPara, sal_uInt16 nField ) const 2288 { 2289 ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( nPara ); 2290 if ( pNode ) 2291 { 2292 sal_uInt16 nCurrentField = 0; 2293 for (auto const& attrib : pNode->GetCharAttribs().GetAttribs()) 2294 { 2295 const EditCharAttrib& rAttr = *attrib; 2296 if (rAttr.Which() == EE_FEATURE_FIELD) 2297 { 2298 if ( nCurrentField == nField ) 2299 { 2300 const SvxFieldItem* p = static_cast<const SvxFieldItem*>(rAttr.GetItem()); 2301 EFieldInfo aInfo(*p, nPara, rAttr.GetStart()); 2302 aInfo.aCurrentText = static_cast<const EditCharAttribField&>(rAttr).GetFieldValue(); 2303 return aInfo; 2304 } 2305 2306 ++nCurrentField; 2307 } 2308 } 2309 } 2310 return EFieldInfo(); 2311 } 2312 2313 2314 bool EditEngine::UpdateFields() 2315 { 2316 bool bChanges = pImpEditEngine->UpdateFields(); 2317 if ( bChanges ) 2318 pImpEditEngine->FormatAndUpdate(); 2319 return bChanges; 2320 } 2321 2322 bool EditEngine::UpdateFieldsOnly() 2323 { 2324 return pImpEditEngine->UpdateFields(); 2325 } 2326 2327 void EditEngine::RemoveFields( const std::function<bool ( const SvxFieldData* )>& isFieldData ) 2328 { 2329 pImpEditEngine->UpdateFields(); 2330 2331 sal_Int32 nParas = pImpEditEngine->GetEditDoc().Count(); 2332 for ( sal_Int32 nPara = 0; nPara < nParas; nPara++ ) 2333 { 2334 ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( nPara ); 2335 const CharAttribList::AttribsType& rAttrs = pNode->GetCharAttribs().GetAttribs(); 2336 for (size_t nAttr = rAttrs.size(); nAttr; ) 2337 { 2338 const EditCharAttrib& rAttr = *rAttrs[--nAttr].get(); 2339 if (rAttr.Which() == EE_FEATURE_FIELD) 2340 { 2341 const SvxFieldData* pFldData = static_cast<const SvxFieldItem*>(rAttr.GetItem())->GetField(); 2342 if ( pFldData && ( isFieldData( pFldData ) ) ) 2343 { 2344 DBG_ASSERT( dynamic_cast<const SvxFieldItem*>(rAttr.GetItem()), "no field item..." ); 2345 EditSelection aSel( EditPaM(pNode, rAttr.GetStart()), EditPaM(pNode, rAttr.GetEnd()) ); 2346 OUString aFieldText = static_cast<const EditCharAttribField&>(rAttr).GetFieldValue(); 2347 pImpEditEngine->ImpInsertText( aSel, aFieldText ); 2348 } 2349 } 2350 } 2351 } 2352 } 2353 2354 bool EditEngine::HasOnlineSpellErrors() const 2355 { 2356 sal_Int32 nNodes = pImpEditEngine->GetEditDoc().Count(); 2357 for ( sal_Int32 n = 0; n < nNodes; n++ ) 2358 { 2359 ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( n ); 2360 if ( pNode->GetWrongList() && !pNode->GetWrongList()->empty() ) 2361 return true; 2362 } 2363 return false; 2364 } 2365 2366 void EditEngine::CompleteOnlineSpelling() 2367 { 2368 if ( pImpEditEngine->GetStatus().DoOnlineSpelling() ) 2369 { 2370 if( !pImpEditEngine->IsFormatted() ) 2371 pImpEditEngine->FormatAndUpdate(); 2372 2373 pImpEditEngine->StopOnlineSpellTimer(); 2374 pImpEditEngine->DoOnlineSpelling( nullptr, true, false ); 2375 } 2376 } 2377 2378 sal_Int32 EditEngine::FindParagraph( long nDocPosY ) 2379 { 2380 return pImpEditEngine->GetParaPortions().FindParagraph( nDocPosY ); 2381 } 2382 2383 EPosition EditEngine::FindDocPosition( const Point& rDocPos ) const 2384 { 2385 EPosition aPos; 2386 // From the point of the API, this is const... 2387 EditPaM aPaM = const_cast<EditEngine*>(this)->pImpEditEngine->GetPaM( rDocPos, false ); 2388 if ( aPaM.GetNode() ) 2389 { 2390 aPos.nPara = pImpEditEngine->aEditDoc.GetPos( aPaM.GetNode() ); 2391 aPos.nIndex = aPaM.GetIndex(); 2392 } 2393 return aPos; 2394 } 2395 2396 tools::Rectangle EditEngine::GetCharacterBounds( const EPosition& rPos ) const 2397 { 2398 tools::Rectangle aBounds; 2399 ContentNode* pNode = pImpEditEngine->GetEditDoc().GetObject( rPos.nPara ); 2400 2401 // Check against index, not paragraph 2402 if ( pNode && ( rPos.nIndex < pNode->Len() ) ) 2403 { 2404 aBounds = pImpEditEngine->PaMtoEditCursor( EditPaM( pNode, rPos.nIndex ), GetCursorFlags::TextOnly ); 2405 tools::Rectangle aR2 = pImpEditEngine->PaMtoEditCursor( EditPaM( pNode, rPos.nIndex+1 ), GetCursorFlags::TextOnly|GetCursorFlags::EndOfLine ); 2406 if ( aR2.Right() > aBounds.Right() ) 2407 aBounds.SetRight( aR2.Right() ); 2408 } 2409 return aBounds; 2410 } 2411 2412 ParagraphInfos EditEngine::GetParagraphInfos( sal_Int32 nPara ) 2413 { 2414 2415 // This only works if not already in the format ... 2416 if ( !pImpEditEngine->IsFormatted() ) 2417 pImpEditEngine->FormatDoc(); 2418 2419 ParagraphInfos aInfos; 2420 aInfos.bValid = pImpEditEngine->IsFormatted(); 2421 if ( pImpEditEngine->IsFormatted() ) 2422 { 2423 const ParaPortion* pParaPortion = pImpEditEngine->GetParaPortions()[nPara]; 2424 const EditLine* pLine = (pParaPortion && pParaPortion->GetLines().Count()) ? 2425 &pParaPortion->GetLines()[0] : nullptr; 2426 DBG_ASSERT( pParaPortion && pLine, "GetParagraphInfos - Paragraph out of range" ); 2427 if ( pParaPortion && pLine ) 2428 { 2429 aInfos.nFirstLineHeight = pLine->GetHeight(); 2430 aInfos.nFirstLineTextHeight = pLine->GetTxtHeight(); 2431 aInfos.nFirstLineMaxAscent = pLine->GetMaxAscent(); 2432 } 2433 } 2434 return aInfos; 2435 } 2436 2437 css::uno::Reference< css::datatransfer::XTransferable > 2438 EditEngine::CreateTransferable( const ESelection& rSelection ) const 2439 { 2440 EditSelection aSel( pImpEditEngine->CreateSel( rSelection ) ); 2441 return pImpEditEngine->CreateTransferable( aSel ); 2442 } 2443 2444 2445 // ====================== Virtual Methods ======================== 2446 2447 void EditEngine::DrawingText( const Point&, const OUString&, sal_Int32, sal_Int32, 2448 const long*, const SvxFont&, sal_Int32 /*nPara*/, sal_uInt8 /*nRightToLeft*/, 2449 const EEngineData::WrongSpellVector*, const SvxFieldData*, bool, bool, 2450 const css::lang::Locale*, const Color&, const Color&) 2451 2452 { 2453 } 2454 2455 void EditEngine::DrawingTab( const Point& /*rStartPos*/, long /*nWidth*/, 2456 const OUString& /*rChar*/, const SvxFont& /*rFont*/, 2457 sal_Int32 /*nPara*/, sal_uInt8 /*nRightToLeft*/, bool /*bEndOfLine*/, 2458 bool /*bEndOfParagraph*/, const Color& /*rOverlineColor*/, 2459 const Color& /*rTextLineColor*/) 2460 { 2461 } 2462 2463 void EditEngine::PaintingFirstLine( sal_Int32, const Point&, long, const Point&, short, OutputDevice* ) 2464 { 2465 } 2466 2467 void EditEngine::ParagraphInserted( sal_Int32 nPara ) 2468 { 2469 2470 if ( GetNotifyHdl().IsSet() ) 2471 { 2472 EENotify aNotify( EE_NOTIFY_PARAGRAPHINSERTED ); 2473 aNotify.nParagraph = nPara; 2474 pImpEditEngine->GetNotifyHdl().Call( aNotify ); 2475 } 2476 } 2477 2478 void EditEngine::ParagraphDeleted( sal_Int32 nPara ) 2479 { 2480 2481 if ( GetNotifyHdl().IsSet() ) 2482 { 2483 EENotify aNotify( EE_NOTIFY_PARAGRAPHREMOVED ); 2484 aNotify.nParagraph = nPara; 2485 pImpEditEngine->GetNotifyHdl().Call( aNotify ); 2486 } 2487 } 2488 void EditEngine::ParagraphConnected( sal_Int32 /*nLeftParagraph*/, sal_Int32 /*nRightParagraph*/ ) 2489 { 2490 } 2491 2492 void EditEngine::ParaAttribsChanged( sal_Int32 /* nParagraph */ ) 2493 { 2494 } 2495 2496 void EditEngine::StyleSheetChanged( SfxStyleSheet* /* pStyle */ ) 2497 { 2498 } 2499 2500 void EditEngine::ParagraphHeightChanged( sal_Int32 nPara ) 2501 { 2502 2503 if ( GetNotifyHdl().IsSet() ) 2504 { 2505 EENotify aNotify( EE_NOTIFY_TextHeightChanged ); 2506 aNotify.nParagraph = nPara; 2507 pImpEditEngine->GetNotifyHdl().Call( aNotify ); 2508 } 2509 } 2510 2511 OUString EditEngine::GetUndoComment( sal_uInt16 nId ) const 2512 { 2513 OUString aComment; 2514 switch ( nId ) 2515 { 2516 case EDITUNDO_REMOVECHARS: 2517 case EDITUNDO_CONNECTPARAS: 2518 case EDITUNDO_DELCONTENT: 2519 case EDITUNDO_DELETE: 2520 case EDITUNDO_CUT: 2521 aComment = EditResId(RID_EDITUNDO_DEL); 2522 break; 2523 case EDITUNDO_MOVEPARAGRAPHS: 2524 case EDITUNDO_MOVEPARAS: 2525 case EDITUNDO_DRAGANDDROP: 2526 aComment = EditResId(RID_EDITUNDO_MOVE); 2527 break; 2528 case EDITUNDO_INSERTFEATURE: 2529 case EDITUNDO_SPLITPARA: 2530 case EDITUNDO_INSERTCHARS: 2531 case EDITUNDO_PASTE: 2532 case EDITUNDO_INSERT: 2533 case EDITUNDO_READ: 2534 aComment = EditResId(RID_EDITUNDO_INSERT); 2535 break; 2536 case EDITUNDO_REPLACEALL: 2537 aComment = EditResId(RID_EDITUNDO_REPLACE); 2538 break; 2539 case EDITUNDO_ATTRIBS: 2540 case EDITUNDO_PARAATTRIBS: 2541 aComment = EditResId(RID_EDITUNDO_SETATTRIBS); 2542 break; 2543 case EDITUNDO_RESETATTRIBS: 2544 aComment = EditResId(RID_EDITUNDO_RESETATTRIBS); 2545 break; 2546 case EDITUNDO_STYLESHEET: 2547 aComment = EditResId(RID_EDITUNDO_SETSTYLE); 2548 break; 2549 case EDITUNDO_TRANSLITERATE: 2550 aComment = EditResId(RID_EDITUNDO_TRANSLITERATE); 2551 break; 2552 case EDITUNDO_INDENTBLOCK: 2553 case EDITUNDO_UNINDENTBLOCK: 2554 aComment = EditResId(RID_EDITUNDO_INDENT); 2555 break; 2556 } 2557 return aComment; 2558 } 2559 2560 tools::Rectangle EditEngine::GetBulletArea( sal_Int32 ) 2561 { 2562 return tools::Rectangle( Point(), Point() ); 2563 } 2564 2565 OUString EditEngine::CalcFieldValue( const SvxFieldItem&, sal_Int32, sal_Int32, boost::optional<Color>&, boost::optional<Color>& ) 2566 { 2567 return OUString(' '); 2568 } 2569 2570 void EditEngine::FieldClicked( const SvxFieldItem&, sal_Int32, sal_Int32 ) 2571 { 2572 } 2573 2574 2575 // ====================== Static Methods ======================= 2576 2577 SfxItemPool* EditEngine::CreatePool() 2578 { 2579 SfxItemPool* pPool = new EditEngineItemPool(); 2580 return pPool; 2581 } 2582 2583 SfxItemPool& EditEngine::GetGlobalItemPool() 2584 { 2585 if ( !pGlobalPool ) 2586 pGlobalPool = CreatePool(); 2587 return *pGlobalPool; 2588 } 2589 2590 void EditEngine::SetFontInfoInItemSet( SfxItemSet& rSet, const vcl::Font& rFont ) 2591 { 2592 SvxFont aSvxFont( rFont ); 2593 SetFontInfoInItemSet( rSet, aSvxFont ); 2594 2595 } 2596 2597 void EditEngine::SetFontInfoInItemSet( SfxItemSet& rSet, const SvxFont& rFont ) 2598 { 2599 rSet.Put( SvxLanguageItem( rFont.GetLanguage(), EE_CHAR_LANGUAGE ) ); 2600 rSet.Put( SvxFontItem( rFont.GetFamilyType(), rFont.GetFamilyName(), OUString(), rFont.GetPitch(), rFont.GetCharSet(), EE_CHAR_FONTINFO ) ); 2601 rSet.Put( SvxFontHeightItem( rFont.GetFontSize().Height(), 100, EE_CHAR_FONTHEIGHT ) ); 2602 rSet.Put( SvxCharScaleWidthItem( 100, EE_CHAR_FONTWIDTH ) ); 2603 rSet.Put( SvxShadowedItem( rFont.IsShadow(), EE_CHAR_SHADOW ) ); 2604 rSet.Put( SvxEscapementItem( rFont.GetEscapement(), rFont.GetPropr(), EE_CHAR_ESCAPEMENT ) ); 2605 rSet.Put( SvxWeightItem( rFont.GetWeight(), EE_CHAR_WEIGHT ) ); 2606 rSet.Put( SvxColorItem( rFont.GetColor(), EE_CHAR_COLOR ) ); 2607 rSet.Put( SvxBackgroundColorItem( rFont.GetFillColor(), EE_CHAR_BKGCOLOR ) ); 2608 rSet.Put( SvxUnderlineItem( rFont.GetUnderline(), EE_CHAR_UNDERLINE ) ); 2609 rSet.Put( SvxOverlineItem( rFont.GetOverline(), EE_CHAR_OVERLINE ) ); 2610 rSet.Put( SvxCrossedOutItem( rFont.GetStrikeout(), EE_CHAR_STRIKEOUT ) ); 2611 rSet.Put( SvxCaseMapItem( rFont.GetCaseMap(), EE_CHAR_CASEMAP ) ); 2612 rSet.Put( SvxPostureItem( rFont.GetItalic(), EE_CHAR_ITALIC ) ); 2613 rSet.Put( SvxContourItem( rFont.IsOutline(), EE_CHAR_OUTLINE ) ); 2614 rSet.Put( SvxAutoKernItem( rFont.IsKerning(), EE_CHAR_PAIRKERNING ) ); 2615 rSet.Put( SvxKerningItem( rFont.GetFixKerning(), EE_CHAR_KERNING ) ); 2616 rSet.Put( SvxWordLineModeItem( rFont.IsWordLineMode(), EE_CHAR_WLM ) ); 2617 rSet.Put( SvxEmphasisMarkItem( rFont.GetEmphasisMark(), EE_CHAR_EMPHASISMARK ) ); 2618 rSet.Put( SvxCharReliefItem( rFont.GetRelief(), EE_CHAR_RELIEF ) ); 2619 } 2620 2621 vcl::Font EditEngine::CreateFontFromItemSet( const SfxItemSet& rItemSet, SvtScriptType nScriptType ) 2622 { 2623 SvxFont aFont; 2624 CreateFont( aFont, rItemSet, true, nScriptType ); 2625 #if HAVE_GCC_BUG_87150 2626 return aFont; 2627 #else 2628 return std::move(aFont); 2629 #endif 2630 } 2631 2632 SvxFont EditEngine::CreateSvxFontFromItemSet( const SfxItemSet& rItemSet ) 2633 { 2634 SvxFont aFont; 2635 CreateFont( aFont, rItemSet ); 2636 return aFont; 2637 } 2638 2639 bool EditEngine::DoesKeyMoveCursor( const KeyEvent& rKeyEvent ) 2640 { 2641 bool bDoesMove = false; 2642 2643 switch ( rKeyEvent.GetKeyCode().GetCode() ) 2644 { 2645 case KEY_UP: 2646 case KEY_DOWN: 2647 case KEY_LEFT: 2648 case KEY_RIGHT: 2649 case KEY_HOME: 2650 case KEY_END: 2651 case KEY_PAGEUP: 2652 case KEY_PAGEDOWN: 2653 { 2654 if ( !rKeyEvent.GetKeyCode().IsMod2() ) 2655 bDoesMove = true; 2656 } 2657 break; 2658 } 2659 return bDoesMove; 2660 } 2661 2662 bool EditEngine::DoesKeyChangeText( const KeyEvent& rKeyEvent ) 2663 { 2664 bool bDoesChange = false; 2665 2666 KeyFuncType eFunc = rKeyEvent.GetKeyCode().GetFunction(); 2667 if ( eFunc != KeyFuncType::DONTKNOW ) 2668 { 2669 switch ( eFunc ) 2670 { 2671 case KeyFuncType::UNDO: 2672 case KeyFuncType::REDO: 2673 case KeyFuncType::CUT: 2674 case KeyFuncType::PASTE: bDoesChange = true; 2675 break; 2676 default: // is then possibly edited below. 2677 eFunc = KeyFuncType::DONTKNOW; 2678 } 2679 } 2680 if ( eFunc == KeyFuncType::DONTKNOW ) 2681 { 2682 switch ( rKeyEvent.GetKeyCode().GetCode() ) 2683 { 2684 case KEY_DELETE: 2685 case KEY_BACKSPACE: bDoesChange = true; 2686 break; 2687 case KEY_RETURN: 2688 case KEY_TAB: 2689 { 2690 if ( !rKeyEvent.GetKeyCode().IsMod1() && !rKeyEvent.GetKeyCode().IsMod2() ) 2691 bDoesChange = true; 2692 } 2693 break; 2694 default: 2695 { 2696 bDoesChange = IsSimpleCharInput( rKeyEvent ); 2697 } 2698 } 2699 } 2700 return bDoesChange; 2701 } 2702 2703 bool EditEngine::IsSimpleCharInput( const KeyEvent& rKeyEvent ) 2704 { 2705 return EditEngine::IsPrintable( rKeyEvent.GetCharCode() ) && 2706 ( KEY_MOD2 != (rKeyEvent.GetKeyCode().GetModifier() & ~KEY_SHIFT ) ) && 2707 ( KEY_MOD1 != (rKeyEvent.GetKeyCode().GetModifier() & ~KEY_SHIFT ) ); 2708 } 2709 2710 bool EditEngine::HasValidData( const css::uno::Reference< css::datatransfer::XTransferable >& rTransferable ) 2711 { 2712 bool bValidData = false; 2713 2714 if ( comphelper::LibreOfficeKit::isActive()) 2715 return true; 2716 2717 if ( rTransferable.is() ) 2718 { 2719 // Every application that copies rtf or any other text format also copies plain text into the clipboard... 2720 datatransfer::DataFlavor aFlavor; 2721 SotExchange::GetFormatDataFlavor( SotClipboardFormatId::STRING, aFlavor ); 2722 bValidData = rTransferable->isDataFlavorSupported( aFlavor ); 2723 } 2724 2725 return bValidData; 2726 } 2727 2728 /** sets a link that is called at the beginning of a drag operation at an edit view */ 2729 void EditEngine::SetBeginDropHdl( const Link<EditView*,void>& rLink ) 2730 { 2731 pImpEditEngine->SetBeginDropHdl( rLink ); 2732 } 2733 2734 Link<EditView*,void> const & EditEngine::GetBeginDropHdl() const 2735 { 2736 return pImpEditEngine->GetBeginDropHdl(); 2737 } 2738 2739 /** sets a link that is called at the end of a drag operation at an edit view */ 2740 void EditEngine::SetEndDropHdl( const Link<EditView*,void>& rLink ) 2741 { 2742 pImpEditEngine->SetEndDropHdl( rLink ); 2743 } 2744 2745 Link<EditView*,void> const & EditEngine::GetEndDropHdl() const 2746 { 2747 return pImpEditEngine->GetEndDropHdl(); 2748 } 2749 2750 void EditEngine::SetFirstWordCapitalization( bool bCapitalize ) 2751 { 2752 pImpEditEngine->SetFirstWordCapitalization( bCapitalize ); 2753 } 2754 2755 void EditEngine::SetReplaceLeadingSingleQuotationMark( bool bReplace ) 2756 { 2757 pImpEditEngine->SetReplaceLeadingSingleQuotationMark( bReplace ); 2758 } 2759 2760 bool EditEngine::IsHtmlImportHandlerSet() const 2761 { 2762 return pImpEditEngine->aHtmlImportHdl.IsSet(); 2763 } 2764 2765 bool EditEngine::IsRtfImportHandlerSet() const 2766 { 2767 return pImpEditEngine->aRtfImportHdl.IsSet(); 2768 } 2769 2770 bool EditEngine::IsImportRTFStyleSheetsSet() const 2771 { 2772 return pImpEditEngine->GetStatus().DoImportRTFStyleSheets(); 2773 } 2774 2775 void EditEngine::CallHtmlImportHandler(HtmlImportInfo& rInfo) 2776 { 2777 pImpEditEngine->aHtmlImportHdl.Call(rInfo); 2778 } 2779 2780 void EditEngine::CallRtfImportHandler(RtfImportInfo& rInfo) 2781 { 2782 pImpEditEngine->aRtfImportHdl.Call(rInfo); 2783 } 2784 2785 EditPaM EditEngine::InsertParaBreak(const EditSelection& rEditSelection) 2786 { 2787 return pImpEditEngine->ImpInsertParaBreak(rEditSelection); 2788 } 2789 2790 EditPaM EditEngine::InsertLineBreak(const EditSelection& rEditSelection) 2791 { 2792 return pImpEditEngine->InsertLineBreak(rEditSelection); 2793 } 2794 2795 sal_Int32 EditEngine::GetOverflowingParaNum() const { 2796 return pImpEditEngine->GetOverflowingParaNum(); 2797 } 2798 2799 sal_Int32 EditEngine::GetOverflowingLineNum() const { 2800 return pImpEditEngine->GetOverflowingLineNum(); 2801 } 2802 2803 void EditEngine::ClearOverflowingParaNum() { 2804 pImpEditEngine->ClearOverflowingParaNum(); 2805 } 2806 2807 bool EditEngine::IsPageOverflow() { 2808 pImpEditEngine->CheckPageOverflow(); 2809 return pImpEditEngine->IsPageOverflow(); 2810 } 2811 2812 EFieldInfo::EFieldInfo() 2813 { 2814 } 2815 2816 2817 EFieldInfo::EFieldInfo( const SvxFieldItem& rFieldItem, sal_Int32 nPara, sal_Int32 nPos ) : 2818 pFieldItem( new SvxFieldItem( rFieldItem ) ), 2819 aPosition( nPara, nPos ) 2820 { 2821 } 2822 2823 EFieldInfo::~EFieldInfo() 2824 { 2825 } 2826 2827 EFieldInfo::EFieldInfo( const EFieldInfo& rFldInfo ) 2828 { 2829 *this = rFldInfo; 2830 } 2831 2832 EFieldInfo& EFieldInfo::operator= ( const EFieldInfo& rFldInfo ) 2833 { 2834 if( this == &rFldInfo ) 2835 return *this; 2836 2837 pFieldItem.reset( rFldInfo.pFieldItem ? new SvxFieldItem( *rFldInfo.pFieldItem ) : nullptr ); 2838 aCurrentText = rFldInfo.aCurrentText; 2839 aPosition = rFldInfo.aPosition; 2840 2841 return *this; 2842 } 2843 2844 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 2845
