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