1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 30 #include "precompiled_editeng.hxx" 31 32 #include <com/sun/star/i18n/WordType.hpp> 33 34 #include <svl/intitem.hxx> 35 #include <editeng/editeng.hxx> 36 #include <editeng/editview.hxx> 37 #include <editeng/editdata.hxx> 38 #include <editeng/eerdll.hxx> 39 #include <editeng/lrspitem.hxx> 40 #include <editeng/fhgtitem.hxx> 41 42 #include <svl/style.hxx> 43 #include <i18npool/mslangid.hxx> 44 45 #define _OUTLINER_CXX 46 #include <editeng/outliner.hxx> 47 #include <outleeng.hxx> 48 #include <paralist.hxx> 49 #include <outlundo.hxx> 50 #include <editeng/outlobj.hxx> 51 #include <editeng/flditem.hxx> 52 #include <editeng/flditem.hxx> 53 #include <editeng/eeitem.hxx> 54 #include <editeng/numitem.hxx> 55 #include <vcl/window.hxx> 56 #include <svl/itemset.hxx> 57 #include <editeng/editstat.hxx> 58 59 60 // Breite der Randzonen innerhalb derer beim D&D gescrollt wird 61 #define OL_SCROLL_LRBORDERWIDTHPIX 10 62 #define OL_SCROLL_TBBORDERWIDTHPIX 10 63 64 // Wert, um den Fensterinhalt beim D&D gescrollt wird 65 #define OL_SCROLL_HOROFFSET 20 /* in % von VisibleSize.Width */ 66 #define OL_SCROLL_VEROFFSET 20 /* in % von VisibleSize.Height */ 67 68 using namespace ::com::sun::star; 69 70 DBG_NAME(OutlinerView) 71 72 73 OutlinerView::OutlinerView( Outliner* pOut, Window* pWin ) 74 { 75 DBG_CTOR( OutlinerView, 0 ); 76 77 pOwner = pOut; 78 bDDCursorVisible = sal_False; 79 bInDragMode = sal_False; 80 nDDScrollLRBorderWidthWin = 0; 81 nDDScrollTBBorderWidthWin = 0; 82 pHorTabArrDoc = 0; 83 84 pEditView = new EditView( pOut->pEditEngine, pWin ); 85 pEditView->SetSelectionMode( EE_SELMODE_TXTONLY ); 86 } 87 88 OutlinerView::~OutlinerView() 89 { 90 DBG_DTOR(OutlinerView,0); 91 delete pEditView; 92 } 93 94 void OutlinerView::Paint( const Rectangle& rRect ) 95 { 96 DBG_CHKTHIS(OutlinerView,0); 97 98 // beim ersten Paint/KeyInput/Drop wird aus einem leeren Outliner ein 99 // Outliner mit genau einem Absatz 100 if( pOwner->bFirstParaIsEmpty ) 101 pOwner->Insert( String() ); 102 103 pEditView->Paint( rRect ); 104 } 105 106 sal_Bool OutlinerView::PostKeyEvent( const KeyEvent& rKEvt ) 107 { 108 DBG_CHKTHIS( OutlinerView, 0 ); 109 110 // beim ersten Paint/KeyInput/Drop wird aus einem leeren Outliner ein 111 // Outliner mit genau einem Absatz 112 if( pOwner->bFirstParaIsEmpty ) 113 pOwner->Insert( String() ); 114 115 116 sal_Bool bKeyProcessed = sal_False; 117 ESelection aSel( pEditView->GetSelection() ); 118 sal_Bool bSelection = aSel.HasRange(); 119 KeyCode aKeyCode = rKEvt.GetKeyCode(); 120 KeyFuncType eFunc = aKeyCode.GetFunction(); 121 sal_uInt16 nCode = aKeyCode.GetCode(); 122 sal_Bool bReadOnly = IsReadOnly(); 123 124 if( bSelection && ( nCode != KEY_TAB ) && EditEngine::DoesKeyChangeText( rKEvt ) ) 125 { 126 if ( ImpCalcSelectedPages( sal_False ) && !pOwner->ImpCanDeleteSelectedPages( this ) ) 127 return sal_True; 128 } 129 130 if ( eFunc != KEYFUNC_DONTKNOW ) 131 { 132 switch ( eFunc ) 133 { 134 case KEYFUNC_CUT: 135 { 136 if ( !bReadOnly ) 137 { 138 Cut(); 139 bKeyProcessed = sal_True; 140 } 141 } 142 break; 143 case KEYFUNC_COPY: 144 { 145 Copy(); 146 bKeyProcessed = sal_True; 147 } 148 break; 149 case KEYFUNC_PASTE: 150 { 151 if ( !bReadOnly ) 152 { 153 PasteSpecial(); 154 bKeyProcessed = sal_True; 155 } 156 } 157 break; 158 case KEYFUNC_DELETE: 159 { 160 if( !bReadOnly && !bSelection && ( pOwner->ImplGetOutlinerMode() != OUTLINERMODE_TEXTOBJECT ) ) 161 { 162 if( aSel.nEndPos == pOwner->pEditEngine->GetTextLen( aSel.nEndPara ) ) 163 { 164 Paragraph* pNext = pOwner->pParaList->GetParagraph( aSel.nEndPara+1 ); 165 if( pNext && pNext->HasFlag(PARAFLAG_ISPAGE) ) 166 { 167 if( !pOwner->ImpCanDeleteSelectedPages( this, aSel.nEndPara, 1 ) ) 168 return sal_False; 169 } 170 } 171 } 172 } 173 break; 174 default: // wird dann evtl. unten bearbeitet. 175 eFunc = KEYFUNC_DONTKNOW; 176 } 177 } 178 if ( eFunc == KEYFUNC_DONTKNOW ) 179 { 180 switch ( nCode ) 181 { 182 case KEY_TAB: 183 { 184 if ( !bReadOnly && !aKeyCode.IsMod1() && !aKeyCode.IsMod2() ) 185 { 186 if ( ( pOwner->ImplGetOutlinerMode() != OUTLINERMODE_TEXTOBJECT ) && 187 ( pOwner->ImplGetOutlinerMode() != OUTLINERMODE_TITLEOBJECT ) && 188 ( bSelection || !aSel.nStartPos ) ) 189 { 190 Indent( aKeyCode.IsShift() ? (-1) : (+1) ); 191 bKeyProcessed = sal_True; 192 } 193 else if ( ( pOwner->ImplGetOutlinerMode() == OUTLINERMODE_TEXTOBJECT ) && 194 !bSelection && !aSel.nEndPos && pOwner->ImplHasBullet( aSel.nEndPara ) ) 195 { 196 Indent( aKeyCode.IsShift() ? (-1) : (+1) ); 197 bKeyProcessed = sal_True; 198 } 199 } 200 } 201 break; 202 case KEY_BACKSPACE: 203 { 204 if( !bReadOnly && !bSelection && aSel.nEndPara && !aSel.nEndPos ) 205 { 206 Paragraph* pPara = pOwner->pParaList->GetParagraph( aSel.nEndPara ); 207 Paragraph* pPrev = pOwner->pParaList->GetParagraph( aSel.nEndPara-1 ); 208 if( !pPrev->IsVisible() ) 209 return sal_True; 210 if( !pPara->GetDepth() ) 211 { 212 if(!pOwner->ImpCanDeleteSelectedPages(this, aSel.nEndPara , 1 ) ) 213 return sal_True; 214 } 215 } 216 } 217 break; 218 case KEY_RETURN: 219 { 220 if ( !bReadOnly ) 221 { 222 // Sonderbehandlung: Hartes Return am Ende eines Absatzes, 223 // der eingeklappte Unterabsaetze besitzt 224 Paragraph* pPara = pOwner->pParaList->GetParagraph( aSel.nEndPara ); 225 226 if( !aKeyCode.IsShift() ) 227 { 228 // Nochmal ImpGetCursor ??? 229 if( !bSelection && 230 aSel.nEndPos == pOwner->pEditEngine->GetTextLen( aSel.nEndPara ) ) 231 { 232 sal_uLong nChilds = pOwner->pParaList->GetChildCount(pPara); 233 if( nChilds && !pOwner->pParaList->HasVisibleChilds(pPara)) 234 { 235 pOwner->UndoActionStart( OLUNDO_INSERT ); 236 sal_uLong nTemp = aSel.nEndPara; 237 nTemp += nChilds; 238 nTemp++; // einfuegen ueber naechstem Non-Child 239 pOwner->Insert( String(),nTemp,pPara->GetDepth()); 240 // Cursor positionieren 241 ESelection aTmpSel((sal_uInt16)nTemp,0,(sal_uInt16)nTemp,0); 242 pEditView->SetSelection( aTmpSel ); 243 pEditView->ShowCursor( sal_True, sal_True ); 244 pOwner->UndoActionEnd( OLUNDO_INSERT ); 245 bKeyProcessed = sal_True; 246 } 247 } 248 } 249 if( !bKeyProcessed && !bSelection && 250 !aKeyCode.IsShift() && aKeyCode.IsMod1() && 251 ( aSel.nEndPos == pOwner->pEditEngine->GetTextLen(aSel.nEndPara) ) ) 252 { 253 pOwner->UndoActionStart( OLUNDO_INSERT ); 254 sal_uLong nTemp = aSel.nEndPara; 255 nTemp++; 256 pOwner->Insert( String(), nTemp, pPara->GetDepth()+1 ); 257 258 // Cursor positionieren 259 ESelection aTmpSel((sal_uInt16)nTemp,0,(sal_uInt16)nTemp,0); 260 pEditView->SetSelection( aTmpSel ); 261 pEditView->ShowCursor( sal_True, sal_True ); 262 pOwner->UndoActionEnd( OLUNDO_INSERT ); 263 bKeyProcessed = sal_True; 264 } 265 } 266 } 267 break; 268 } 269 } 270 271 return bKeyProcessed ? sal_True : pEditView->PostKeyEvent( rKEvt ); 272 } 273 274 275 sal_uLong OutlinerView::ImpCheckMousePos(const Point& rPosPix, MouseTarget& reTarget) 276 { 277 DBG_CHKTHIS(OutlinerView,0); 278 sal_uLong nPara = EE_PARA_NOT_FOUND; 279 280 Point aMousePosWin = pEditView->GetWindow()->PixelToLogic( rPosPix ); 281 if( !pEditView->GetOutputArea().IsInside( aMousePosWin ) ) 282 { 283 reTarget = MouseOutside; 284 } 285 else 286 { 287 reTarget = MouseText; 288 289 Point aPaperPos( aMousePosWin ); 290 Rectangle aOutArea = pEditView->GetOutputArea(); 291 Rectangle aVisArea = pEditView->GetVisArea(); 292 aPaperPos.X() -= aOutArea.Left(); 293 aPaperPos.X() += aVisArea.Left(); 294 aPaperPos.Y() -= aOutArea.Top(); 295 aPaperPos.Y() += aVisArea.Top(); 296 297 sal_Bool bBullet; 298 if ( pOwner->IsTextPos( aPaperPos, 0, &bBullet ) ) 299 { 300 Point aDocPos = pOwner->GetDocPos( aPaperPos ); 301 nPara = pOwner->pEditEngine->FindParagraph( aDocPos.Y() ); 302 303 if ( bBullet ) 304 { 305 reTarget = MouseBullet; 306 } 307 else 308 { 309 // Check for hyperlink 310 const SvxFieldItem* pFieldItem = pEditView->GetField( aMousePosWin ); 311 if ( pFieldItem && pFieldItem->GetField() && pFieldItem->GetField()->ISA( SvxURLField ) ) 312 reTarget = MouseHypertext; 313 } 314 } 315 } 316 return nPara; 317 } 318 319 sal_Bool __EXPORT OutlinerView::MouseMove( const MouseEvent& rMEvt ) 320 { 321 DBG_CHKTHIS(OutlinerView,0); 322 323 if( ( pOwner->ImplGetOutlinerMode() == OUTLINERMODE_TEXTOBJECT ) || pEditView->GetEditEngine()->IsInSelectionMode()) 324 return pEditView->MouseMove( rMEvt ); 325 326 Point aMousePosWin( pEditView->GetWindow()->PixelToLogic( rMEvt.GetPosPixel() ) ); 327 if( !pEditView->GetOutputArea().IsInside( aMousePosWin ) ) 328 return sal_False; 329 330 Pointer aPointer = GetPointer( rMEvt.GetPosPixel() ); 331 pEditView->GetWindow()->SetPointer( aPointer ); 332 return pEditView->MouseMove( rMEvt ); 333 } 334 335 336 sal_Bool __EXPORT OutlinerView::MouseButtonDown( const MouseEvent& rMEvt ) 337 { 338 DBG_CHKTHIS(OutlinerView,0); 339 if ( ( pOwner->ImplGetOutlinerMode() == OUTLINERMODE_TEXTOBJECT ) || pEditView->GetEditEngine()->IsInSelectionMode() ) 340 return pEditView->MouseButtonDown( rMEvt ); 341 342 Point aMousePosWin( pEditView->GetWindow()->PixelToLogic( rMEvt.GetPosPixel() ) ); 343 if( !pEditView->GetOutputArea().IsInside( aMousePosWin ) ) 344 return sal_False; 345 346 Pointer aPointer = GetPointer( rMEvt.GetPosPixel() ); 347 pEditView->GetWindow()->SetPointer( aPointer ); 348 349 MouseTarget eTarget; 350 sal_uLong nPara = ImpCheckMousePos( rMEvt.GetPosPixel(), eTarget ); 351 if ( eTarget == MouseBullet ) 352 { 353 Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara ); 354 sal_Bool bHasChilds = (pPara && pOwner->pParaList->HasChilds(pPara)); 355 if( rMEvt.GetClicks() == 1 ) 356 { 357 sal_uLong nEndPara = nPara; 358 if ( bHasChilds && pOwner->pParaList->HasVisibleChilds(pPara) ) 359 nEndPara += pOwner->pParaList->GetChildCount( pPara ); 360 // umgekehrt rum selektieren, damit EditEngine nicht scrollt 361 ESelection aSel((sal_uInt16)nEndPara, 0xffff,(sal_uInt16)nPara, 0 ); 362 pEditView->SetSelection( aSel ); 363 } 364 else if( rMEvt.GetClicks() == 2 && bHasChilds ) 365 ImpToggleExpand( pPara ); 366 367 aDDStartPosPix = rMEvt.GetPosPixel(); 368 aDDStartPosRef=pEditView->GetWindow()->PixelToLogic( aDDStartPosPix,pOwner->GetRefMapMode()); 369 return sal_True; 370 } 371 372 // special case for outliner view in impress, check if double click hits the page icon for toggle 373 if( (nPara == EE_PARA_NOT_FOUND) && (pOwner->ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEVIEW) && (eTarget == MouseText) && (rMEvt.GetClicks() == 2) ) 374 { 375 ESelection aSel( pEditView->GetSelection() ); 376 nPara = aSel.nStartPara; 377 Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara ); 378 if( (pPara && pOwner->pParaList->HasChilds(pPara)) && pPara->HasFlag(PARAFLAG_ISPAGE) ) 379 { 380 ImpToggleExpand( pPara ); 381 } 382 } 383 return pEditView->MouseButtonDown( rMEvt ); 384 } 385 386 387 sal_Bool __EXPORT OutlinerView::MouseButtonUp( const MouseEvent& rMEvt ) 388 { 389 DBG_CHKTHIS(OutlinerView,0); 390 if ( ( pOwner->ImplGetOutlinerMode() == OUTLINERMODE_TEXTOBJECT ) || pEditView->GetEditEngine()->IsInSelectionMode() ) 391 return pEditView->MouseButtonUp( rMEvt ); 392 393 Point aMousePosWin( pEditView->GetWindow()->PixelToLogic( rMEvt.GetPosPixel() ) ); 394 if( !pEditView->GetOutputArea().IsInside( aMousePosWin ) ) 395 return sal_False; 396 397 Pointer aPointer = GetPointer( rMEvt.GetPosPixel() ); 398 pEditView->GetWindow()->SetPointer( aPointer ); 399 400 return pEditView->MouseButtonUp( rMEvt ); 401 } 402 403 void OutlinerView::ImpHideDDCursor() 404 { 405 DBG_CHKTHIS(OutlinerView,0); 406 if ( bDDCursorVisible ) 407 { 408 bDDCursorVisible = sal_False; 409 ImpPaintDDCursor(); 410 } 411 } 412 413 void OutlinerView::ImpShowDDCursor() 414 { 415 DBG_CHKTHIS(OutlinerView,0); 416 if ( !bDDCursorVisible ) 417 { 418 bDDCursorVisible = sal_True; 419 ImpPaintDDCursor(); 420 } 421 } 422 423 void OutlinerView::ImpPaintDDCursor() 424 { 425 DBG_CHKTHIS(OutlinerView,0); 426 427 Window* pWindow = pEditView->GetWindow(); 428 RasterOp eOldOp = pWindow->GetRasterOp(); 429 pWindow->SetRasterOp( ROP_INVERT ); 430 431 const Color& rOldLineColor = pWindow->GetLineColor(); 432 pWindow->SetLineColor( Color( COL_BLACK ) ); 433 434 Point aStartPointWin, aEndPointWin; 435 Rectangle aOutputArWin = pEditView->GetOutputArea(); 436 Rectangle aVisAreaRef = pEditView->GetVisArea(); 437 438 if( bDDChangingDepth ) 439 { 440 aStartPointWin.X() = pHorTabArrDoc[ nDDCurDepth ]; 441 aStartPointWin.X() += aOutputArWin.Left(); 442 aStartPointWin.Y() = aOutputArWin.Top(); 443 aEndPointWin.X() = aStartPointWin.X(); 444 aEndPointWin.Y() = aOutputArWin.Bottom(); 445 } 446 else 447 { 448 sal_uLong nPara = nDDCurPara; 449 if ( nDDCurPara == LIST_APPEND ) 450 { 451 Paragraph* pTemp = pOwner->pParaList->LastVisible(); 452 nPara = pOwner->pParaList->GetAbsPos( pTemp ); 453 } 454 aStartPointWin = pEditView->GetWindowPosTopLeft((sal_uInt16) nPara ); 455 if ( nDDCurPara == LIST_APPEND ) 456 { 457 long nHeight = pOwner->pEditEngine->GetTextHeight((sal_uInt16)nPara ); 458 aStartPointWin.Y() += nHeight; 459 } 460 aStartPointWin.X() = aOutputArWin.Left(); 461 aEndPointWin.Y() = aStartPointWin.Y(); 462 aEndPointWin.X() = aOutputArWin.Right(); 463 } 464 465 pWindow->DrawLine( aStartPointWin, aEndPointWin ); 466 pWindow->SetLineColor( rOldLineColor ); 467 pWindow->SetRasterOp( eOldOp ); 468 } 469 470 // Berechnet, ueber welchem Absatz eingefuegt werden muss 471 472 sal_uLong OutlinerView::ImpGetInsertionPara( const Point& rPosPixel ) 473 { 474 DBG_CHKTHIS(OutlinerView,0); 475 sal_uLong nCurPara = pEditView->GetParagraph( rPosPixel ); 476 ParagraphList* pParaList = pOwner->pParaList; 477 478 if ( nCurPara == EE_PARA_NOT_FOUND ) 479 nCurPara = LIST_APPEND; 480 else 481 { 482 Point aPosWin = pEditView->GetWindow()->PixelToLogic( rPosPixel ); 483 Point aParaPosWin = pEditView->GetWindowPosTopLeft((sal_uInt16)nCurPara); 484 long nHeightRef = pOwner->pEditEngine->GetTextHeight((sal_uInt16)nCurPara); 485 long nParaYOffs = aPosWin.Y() - aParaPosWin.Y(); 486 487 if ( nParaYOffs > nHeightRef / 2 ) 488 { 489 Paragraph* p = pParaList->GetParagraph( nCurPara ); 490 p = pParaList->NextVisible( p ); 491 nCurPara = p ? pParaList->GetAbsPos( p ) : LIST_APPEND; 492 } 493 } 494 return nCurPara; 495 } 496 497 498 void OutlinerView::ImpToggleExpand( Paragraph* pPara ) 499 { 500 DBG_CHKTHIS(OutlinerView,0); 501 502 sal_uInt16 nPara = (sal_uInt16) pOwner->pParaList->GetAbsPos( pPara ); 503 pEditView->SetSelection( ESelection( nPara, 0, nPara, 0 ) ); 504 ImplExpandOrCollaps( nPara, nPara, !pOwner->pParaList->HasVisibleChilds( pPara ) ); 505 pEditView->ShowCursor(); 506 } 507 508 509 void OutlinerView::SetOutliner( Outliner* pOutliner ) 510 { 511 DBG_CHKTHIS(OutlinerView,0); 512 pOwner = pOutliner; 513 pEditView->SetEditEngine( pOutliner->pEditEngine ); 514 } 515 516 517 518 sal_uLong OutlinerView::Select( Paragraph* pParagraph, sal_Bool bSelect, 519 sal_Bool bWithChilds ) 520 { 521 DBG_CHKTHIS(OutlinerView,0); 522 523 sal_uLong nPara = pOwner->pParaList->GetAbsPos( pParagraph ); 524 sal_uInt16 nEnd = 0; 525 if ( bSelect ) 526 nEnd = 0xffff; 527 528 sal_uLong nChildCount = 0; 529 if ( bWithChilds ) 530 nChildCount = pOwner->pParaList->GetChildCount( pParagraph ); 531 532 ESelection aSel( (sal_uInt16)nPara, 0,(sal_uInt16)(nPara+nChildCount), nEnd ); 533 pEditView->SetSelection( aSel ); 534 return nChildCount+1; 535 } 536 537 538 void OutlinerView::SetAttribs( const SfxItemSet& rAttrs ) 539 { 540 DBG_CHKTHIS(OutlinerView,0); 541 542 sal_Bool bUpdate = pOwner->pEditEngine->GetUpdateMode(); 543 pOwner->pEditEngine->SetUpdateMode( sal_False ); 544 545 if( !pOwner->IsInUndo() && pOwner->IsUndoEnabled() ) 546 pOwner->UndoActionStart( OLUNDO_ATTR ); 547 548 ParaRange aSel = ImpGetSelectedParagraphs( sal_False ); 549 550 pEditView->SetAttribs( rAttrs ); 551 552 // Bullet-Texte aktualisieren 553 for( sal_uInt16 nPara= aSel.nStartPara; nPara <= aSel.nEndPara; nPara++ ) 554 { 555 pOwner->ImplCheckNumBulletItem( nPara ); 556 pOwner->ImplCalcBulletText( nPara, sal_False, sal_False ); 557 558 if( !pOwner->IsInUndo() && pOwner->IsUndoEnabled() ) 559 pOwner->InsertUndo( new OutlinerUndoCheckPara( pOwner, nPara ) ); 560 } 561 562 if( !pOwner->IsInUndo() && pOwner->IsUndoEnabled() ) 563 pOwner->UndoActionEnd( OLUNDO_ATTR ); 564 565 pEditView->SetEditEngineUpdateMode( bUpdate ); 566 } 567 568 ParaRange OutlinerView::ImpGetSelectedParagraphs( sal_Bool bIncludeHiddenChilds ) 569 { 570 DBG_CHKTHIS( OutlinerView, 0 ); 571 572 ESelection aSel = pEditView->GetSelection(); 573 ParaRange aParas( aSel.nStartPara, aSel.nEndPara ); 574 aParas.Adjust(); 575 576 // unsichtbare Childs des letzten Parents in Selektion mit aufnehmen 577 if ( bIncludeHiddenChilds ) 578 { 579 Paragraph* pLast = pOwner->pParaList->GetParagraph( aParas.nEndPara ); 580 if ( pOwner->pParaList->HasHiddenChilds( pLast ) ) 581 aParas.nEndPara = 582 sal::static_int_cast< sal_uInt16 >( 583 aParas.nEndPara + 584 pOwner->pParaList->GetChildCount( pLast ) ); 585 } 586 return aParas; 587 } 588 589 // MT: Name sollte mal geaendert werden! 590 void OutlinerView::AdjustDepth( short nDX ) 591 { 592 Indent( nDX ); 593 } 594 595 void OutlinerView::Indent( short nDiff ) 596 { 597 DBG_CHKTHIS( OutlinerView, 0 ); 598 599 if( !nDiff || ( ( nDiff > 0 ) && ImpCalcSelectedPages( sal_True ) && !pOwner->ImpCanIndentSelectedPages( this ) ) ) 600 return; 601 602 const bool bOutlinerView = pOwner->pEditEngine->GetControlWord() & EE_CNTRL_OUTLINER; 603 sal_Bool bUpdate = pOwner->pEditEngine->GetUpdateMode(); 604 pOwner->pEditEngine->SetUpdateMode( sal_False ); 605 606 sal_Bool bUndo = !pOwner->IsInUndo() && pOwner->IsUndoEnabled(); 607 608 if( bUndo ) 609 pOwner->UndoActionStart( OLUNDO_DEPTH ); 610 611 sal_Int16 nMinDepth = -1; // Optimierung: Nicht unnoetig viele Absatze neu berechnen 612 613 ParaRange aSel = ImpGetSelectedParagraphs( sal_True ); 614 for ( sal_uInt16 nPara = aSel.nStartPara; nPara <= aSel.nEndPara; nPara++ ) 615 { 616 Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara ); 617 618 sal_Int16 nOldDepth = pPara->GetDepth(); 619 sal_Int16 nNewDepth = nOldDepth + nDiff; 620 621 if( bOutlinerView && nPara ) 622 { 623 const bool bPage = pPara->HasFlag(PARAFLAG_ISPAGE); 624 if( (bPage && (nDiff == +1)) || (!bPage && (nDiff == -1) && (nOldDepth <= 0)) ) 625 { 626 // App benachrichtigen 627 pOwner->nDepthChangedHdlPrevDepth = (sal_Int16)nOldDepth; 628 pOwner->mnDepthChangeHdlPrevFlags = pPara->nFlags; 629 pOwner->pHdlParagraph = pPara; 630 631 if( bPage ) 632 pPara->RemoveFlag( PARAFLAG_ISPAGE ); 633 else 634 pPara->SetFlag( PARAFLAG_ISPAGE ); 635 636 pOwner->DepthChangedHdl(); 637 pOwner->pEditEngine->QuickMarkInvalid( ESelection( nPara, 0, nPara, 0 ) ); 638 639 if( bUndo ) 640 pOwner->InsertUndo( new OutlinerUndoChangeParaFlags( pOwner, nPara, pOwner->mnDepthChangeHdlPrevFlags, pPara->nFlags ) ); 641 642 continue; 643 } 644 } 645 646 // do not switch off numeration with tab 647 if( (nOldDepth == 0) && (nNewDepth == -1) ) 648 continue; 649 650 // do not indent if there is no numeration enabled 651 if( nOldDepth == -1 ) 652 continue; 653 654 if ( nNewDepth < pOwner->nMinDepth ) 655 nNewDepth = pOwner->nMinDepth; 656 if ( nNewDepth > pOwner->nMaxDepth ) 657 nNewDepth = pOwner->nMaxDepth; 658 659 if( nOldDepth < nMinDepth ) 660 nMinDepth = nOldDepth; 661 if( nNewDepth < nMinDepth ) 662 nMinDepth = nNewDepth; 663 664 if( nOldDepth != nNewDepth ) 665 { 666 if ( ( nPara == aSel.nStartPara ) && aSel.nStartPara && ( pOwner->ImplGetOutlinerMode() != OUTLINERMODE_TEXTOBJECT )) 667 { 668 // Sonderfall: Der Vorgaenger eines eingerueckten Absatzes ist 669 // unsichtbar und steht jetzt auf der gleichen Ebene wie der 670 // sichtbare Absatz. In diesem Fall wird der naechste sichtbare 671 // Absatz gesucht und aufgeplustert. 672 #ifdef DBG_UTIL 673 Paragraph* _pPara = pOwner->pParaList->GetParagraph( aSel.nStartPara ); 674 DBG_ASSERT(_pPara->IsVisible(),"Selected Paragraph invisible ?!"); 675 #endif 676 Paragraph* pPrev= pOwner->pParaList->GetParagraph( aSel.nStartPara-1 ); 677 678 if( !pPrev->IsVisible() && ( pPrev->GetDepth() == nNewDepth ) ) 679 { 680 // Vorgaenger ist eingeklappt und steht auf gleicher Ebene 681 // => naechsten sichtbaren Absatz suchen und expandieren 682 pPrev = pOwner->pParaList->GetParent( pPrev ); 683 while( !pPrev->IsVisible() ) 684 pPrev = pOwner->pParaList->GetParent( pPrev ); 685 686 pOwner->Expand( pPrev ); 687 pOwner->InvalidateBullet( pPrev, pOwner->pParaList->GetAbsPos( pPrev ) ); 688 } 689 } 690 691 pOwner->nDepthChangedHdlPrevDepth = (sal_Int16)nOldDepth; 692 pOwner->mnDepthChangeHdlPrevFlags = pPara->nFlags; 693 pOwner->pHdlParagraph = pPara; 694 695 pOwner->ImplInitDepth( nPara, nNewDepth, sal_True, sal_False ); 696 pOwner->ImplCalcBulletText( nPara, sal_False, sal_False ); 697 698 if ( pOwner->ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT ) 699 pOwner->ImplSetLevelDependendStyleSheet( nPara ); 700 701 // App benachrichtigen 702 pOwner->DepthChangedHdl(); 703 } 704 else 705 { 706 // Needs at least a repaint... 707 pOwner->pEditEngine->QuickMarkInvalid( ESelection( nPara, 0, nPara, 0 ) ); 708 } 709 } 710 711 // MT 19.08.99: War mal fuer Optimierung (outliner.cxx#1.193), 712 // hat aber zu zuviel Wartungsaufwand / doppelten Funktionen gefuehrt 713 // und zu wenig gebracht: 714 // pOwner->ImpSetBulletTextsFrom( aSel.nStartPara+1, nMinDepth ); 715 // Wird jetzt direkt in Schleife mit ImplCalcBulletText() erledigt. 716 // Jetzt fehlen nur noch die folgenden Ansaetze, die davon betroffen sind. 717 sal_uInt16 nParas = (sal_uInt16)pOwner->pParaList->GetParagraphCount(); 718 for ( sal_uInt16 n = aSel.nEndPara+1; n < nParas; n++ ) 719 { 720 Paragraph* pPara = pOwner->pParaList->GetParagraph( n ); 721 if ( pPara->GetDepth() < nMinDepth ) 722 break; 723 pOwner->ImplCalcBulletText( n, sal_False, sal_False ); 724 } 725 726 if ( bUpdate ) 727 { 728 pEditView->SetEditEngineUpdateMode( sal_True ); 729 pEditView->ShowCursor(); 730 } 731 732 if( bUndo ) 733 pOwner->UndoActionEnd( OLUNDO_DEPTH ); 734 } 735 736 sal_Bool OutlinerView::AdjustHeight( long nDY ) 737 { 738 DBG_CHKTHIS(OutlinerView,0); 739 pEditView->MoveParagraphs( nDY ); 740 return sal_True; // remove return value... 741 } 742 743 void OutlinerView::AdjustDepth( Paragraph* pPara, short nDX, sal_Bool bWithChilds) 744 { 745 DBG_CHKTHIS(OutlinerView,0); 746 sal_uLong nStartPara = pOwner->pParaList->GetAbsPos( pPara ); 747 sal_uLong nEndPara = nStartPara; 748 if ( bWithChilds ) 749 nEndPara += pOwner->pParaList->GetChildCount( pPara ); 750 ESelection aSel((sal_uInt16)nStartPara, 0,(sal_uInt16)nEndPara, 0xffff ); 751 pEditView->SetSelection( aSel ); 752 AdjustDepth( nDX ); 753 } 754 755 void OutlinerView::AdjustHeight( Paragraph* pPara, long nDY, sal_Bool bWithChilds ) 756 { 757 DBG_CHKTHIS(OutlinerView,0); 758 sal_uLong nStartPara = pOwner->pParaList->GetAbsPos( pPara ); 759 sal_uLong nEndPara = nStartPara; 760 if ( bWithChilds ) 761 nEndPara += pOwner->pParaList->GetChildCount( pPara ); 762 ESelection aSel( (sal_uInt16)nStartPara, 0, (sal_uInt16)nEndPara, 0xffff ); 763 pEditView->SetSelection( aSel ); 764 AdjustHeight( nDY ); 765 } 766 767 768 Rectangle OutlinerView::GetVisArea() const 769 { 770 DBG_CHKTHIS(OutlinerView,0); 771 return pEditView->GetVisArea(); 772 } 773 774 775 Point OutlinerView::ImpGetDocPos( const Point& rPosPixel ) 776 { 777 DBG_CHKTHIS(OutlinerView,0); 778 Rectangle aOutArWin = GetOutputArea(); 779 // Position in der OutputArea berechnen 780 Point aCurPosDoc( rPosPixel ); 781 aCurPosDoc = pEditView->GetWindow()->PixelToLogic( aCurPosDoc ); 782 aCurPosDoc -= aOutArWin.TopLeft(); 783 aCurPosDoc += pEditView->GetVisArea().TopLeft(); 784 return aCurPosDoc; 785 } 786 787 // MT 05/00: Wofuer dies ImpXXXScroll, sollte das nicht die EditEngine machen??? 788 789 void OutlinerView::ImpDragScroll( const Point& rPosPix ) 790 { 791 DBG_CHKTHIS(OutlinerView,0); 792 Point aPosWin = pEditView->GetWindow()->PixelToLogic( rPosPix ); 793 Rectangle aOutputArWin = pEditView->GetOutputArea(); 794 if ( aPosWin.X() <= aOutputArWin.Left() + nDDScrollLRBorderWidthWin) 795 ImpScrollLeft(); 796 else if( aPosWin.X() >= aOutputArWin.Right()- nDDScrollLRBorderWidthWin) 797 ImpScrollRight(); 798 else if( aPosWin.Y() <= aOutputArWin.Top() + nDDScrollTBBorderWidthWin) 799 ImpScrollUp(); 800 else if(aPosWin.Y() >= aOutputArWin.Bottom() - nDDScrollTBBorderWidthWin) 801 ImpScrollDown(); 802 } 803 804 805 void OutlinerView::ImpScrollLeft() 806 { 807 DBG_CHKTHIS(OutlinerView,0); 808 Rectangle aVisArea( pEditView->GetVisArea() ); 809 long nMaxScrollOffs = aVisArea.Left(); 810 if ( !nMaxScrollOffs ) 811 return; 812 long nScrollOffsRef = (aVisArea.GetWidth() * OL_SCROLL_HOROFFSET) / 100; 813 if ( !nScrollOffsRef ) 814 nScrollOffsRef = 1; 815 if ( nScrollOffsRef > nMaxScrollOffs ) 816 nScrollOffsRef = nMaxScrollOffs; 817 818 ImpHideDDCursor(); 819 Scroll( -nScrollOffsRef, 0 ); 820 821 EditStatus aScrollStat; 822 aScrollStat.GetStatusWord() = EE_STAT_HSCROLL; 823 pOwner->pEditEngine->GetStatusEventHdl().Call( &aScrollStat ); 824 } 825 826 827 void OutlinerView::ImpScrollRight() 828 { 829 DBG_CHKTHIS(OutlinerView,0); 830 Rectangle aVisArea( pEditView->GetVisArea() ); 831 long nMaxScrollOffs = pOwner->pEditEngine->GetPaperSize().Width() - 832 aVisArea.Right(); 833 if ( !nMaxScrollOffs ) 834 return; 835 long nScrollOffsRef = (aVisArea.GetWidth() * OL_SCROLL_HOROFFSET) / 100; 836 if ( !nScrollOffsRef ) 837 nScrollOffsRef = 1; 838 if ( nScrollOffsRef > nMaxScrollOffs ) 839 nScrollOffsRef = nMaxScrollOffs; 840 841 ImpHideDDCursor(); 842 Scroll( nScrollOffsRef, 0 ); 843 844 EditStatus aScrollStat; 845 aScrollStat.GetStatusWord() = EE_STAT_HSCROLL; 846 pOwner->pEditEngine->GetStatusEventHdl().Call( &aScrollStat ); 847 } 848 849 850 void OutlinerView::ImpScrollDown() 851 { 852 DBG_CHKTHIS(OutlinerView,0); 853 Rectangle aVisArea( pEditView->GetVisArea() ); 854 Size aDocSize( 0, (long)pOwner->pEditEngine->GetTextHeight() ); 855 856 long nMaxScrollOffs = aDocSize.Height(); 857 nMaxScrollOffs -= aVisArea.Top(); 858 nMaxScrollOffs -= aVisArea.GetHeight(); 859 if ( !nMaxScrollOffs ) 860 return; 861 862 long nScrollOffsRef = (aVisArea.GetHeight() * OL_SCROLL_VEROFFSET) / 100; 863 864 if ( nScrollOffsRef > nMaxScrollOffs ) 865 nScrollOffsRef = nMaxScrollOffs; 866 if ( !nScrollOffsRef ) 867 nScrollOffsRef = 1; 868 869 ImpHideDDCursor(); 870 Scroll( 0, -nScrollOffsRef ); 871 872 EditStatus aScrollStat; 873 aScrollStat.GetStatusWord() = EE_STAT_VSCROLL; 874 pOwner->pEditEngine->GetStatusEventHdl().Call( &aScrollStat ); 875 } 876 877 878 void OutlinerView::ImpScrollUp() 879 { 880 DBG_CHKTHIS(OutlinerView,0); 881 Rectangle aVisArea( pEditView->GetVisArea() ); 882 long nMaxScrollOffs = aVisArea.Top(); 883 if ( !nMaxScrollOffs ) 884 return; 885 long nScrollOffsRef = (aVisArea.GetHeight() * OL_SCROLL_VEROFFSET) / 100; 886 887 888 if ( nScrollOffsRef > nMaxScrollOffs ) 889 nScrollOffsRef = nMaxScrollOffs; 890 if ( !nScrollOffsRef ) 891 nScrollOffsRef = 1; 892 893 ImpHideDDCursor(); 894 Scroll( 0, nScrollOffsRef ); 895 896 EditStatus aScrollStat; 897 aScrollStat.GetStatusWord() = EE_STAT_VSCROLL; 898 pOwner->pEditEngine->GetStatusEventHdl().Call( &aScrollStat ); 899 } 900 901 902 void OutlinerView::Expand() 903 { 904 DBG_CHKTHIS( OutlinerView, 0 ); 905 ParaRange aParas = ImpGetSelectedParagraphs( sal_False ); 906 ImplExpandOrCollaps( aParas.nStartPara, aParas.nEndPara, sal_True ); 907 } 908 909 910 void OutlinerView::Collapse() 911 { 912 DBG_CHKTHIS( OutlinerView, 0 ); 913 ParaRange aParas = ImpGetSelectedParagraphs( sal_False ); 914 ImplExpandOrCollaps( aParas.nStartPara, aParas.nEndPara, sal_False ); 915 } 916 917 918 void OutlinerView::ExpandAll() 919 { 920 DBG_CHKTHIS( OutlinerView, 0 ); 921 ImplExpandOrCollaps( 0, (sal_uInt16)(pOwner->pParaList->GetParagraphCount()-1), sal_True ); 922 } 923 924 925 void OutlinerView::CollapseAll() 926 { 927 DBG_CHKTHIS(OutlinerView,0); 928 ImplExpandOrCollaps( 0, (sal_uInt16)(pOwner->pParaList->GetParagraphCount()-1), sal_False ); 929 } 930 931 void OutlinerView::ImplExpandOrCollaps( sal_uInt16 nStartPara, sal_uInt16 nEndPara, sal_Bool bExpand ) 932 { 933 DBG_CHKTHIS( OutlinerView, 0 ); 934 935 sal_Bool bUpdate = pOwner->GetUpdateMode(); 936 pOwner->SetUpdateMode( sal_False ); 937 938 sal_Bool bUndo = !pOwner->IsInUndo() && pOwner->IsUndoEnabled(); 939 if( bUndo ) 940 pOwner->UndoActionStart( bExpand ? OLUNDO_EXPAND : OLUNDO_COLLAPSE ); 941 942 for ( sal_uInt16 nPara = nStartPara; nPara <= nEndPara; nPara++ ) 943 { 944 Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara ); 945 sal_Bool bDone = bExpand ? pOwner->Expand( pPara ) : pOwner->Collapse( pPara ); 946 if( bDone ) 947 { 948 // Der Strich unter dem Absatz muss verschwinden... 949 pOwner->pEditEngine->QuickMarkToBeRepainted( nPara ); 950 } 951 } 952 953 if( bUndo ) 954 pOwner->UndoActionEnd( bExpand ? OLUNDO_EXPAND : OLUNDO_COLLAPSE ); 955 956 if ( bUpdate ) 957 { 958 pOwner->SetUpdateMode( sal_True ); 959 pEditView->ShowCursor(); 960 } 961 } 962 963 964 void OutlinerView::Expand( Paragraph* pPara) 965 { 966 DBG_CHKTHIS(OutlinerView,0); 967 pOwner->Expand( pPara ); 968 } 969 970 971 void OutlinerView::Collapse( Paragraph* pPara) 972 { 973 DBG_CHKTHIS(OutlinerView,0); 974 pOwner->Collapse( pPara ); 975 } 976 977 void OutlinerView::InsertText( const OutlinerParaObject& rParaObj ) 978 { 979 // MT: Wie Paste, nur EditView::Insert, statt EditView::Paste. 980 // Eigentlich nicht ganz richtig, das evtl. Einrueckungen 981 // korrigiert werden muessen, aber das kommt spaeter durch ein 982 // allgemeingueltiges Import. 983 // Dann wird im Inserted gleich ermittelt, was f�r eine Einrueckebene 984 // Moegliche Struktur: 985 // pImportInfo mit DestPara, DestPos, nFormat, pParaObj... 986 // Evtl. Problematisch: 987 // EditEngine, RTF => Absplittung des Bereichs, spaeter 988 // zusammenfuehrung 989 990 DBG_CHKTHIS(OutlinerView,0); 991 992 if ( ImpCalcSelectedPages( sal_False ) && !pOwner->ImpCanDeleteSelectedPages( this ) ) 993 return; 994 995 pOwner->UndoActionStart( OLUNDO_INSERT ); 996 997 pOwner->pEditEngine->SetUpdateMode( sal_False ); 998 sal_uLong nStart, nParaCount; 999 nParaCount = pOwner->pEditEngine->GetParagraphCount(); 1000 sal_uInt16 nSize = ImpInitPaste( nStart ); 1001 pEditView->InsertText( rParaObj.GetTextObject() ); 1002 ImpPasted( nStart, nParaCount, nSize); 1003 pEditView->SetEditEngineUpdateMode( sal_True ); 1004 1005 pOwner->UndoActionEnd( OLUNDO_INSERT ); 1006 1007 pEditView->ShowCursor( sal_True, sal_True ); 1008 } 1009 1010 1011 1012 void OutlinerView::Cut() 1013 { 1014 DBG_CHKTHIS(OutlinerView,0); 1015 if ( !ImpCalcSelectedPages( sal_False ) || pOwner->ImpCanDeleteSelectedPages( this ) ) 1016 pEditView->Cut(); 1017 } 1018 1019 void OutlinerView::Paste() 1020 { 1021 DBG_CHKTHIS(OutlinerView,0); 1022 PasteSpecial(); // HACK(SD ruft nicht PasteSpecial auf) 1023 } 1024 1025 void OutlinerView::PasteSpecial() 1026 { 1027 DBG_CHKTHIS(OutlinerView,0); 1028 if ( !ImpCalcSelectedPages( sal_False ) || pOwner->ImpCanDeleteSelectedPages( this ) ) 1029 { 1030 pOwner->UndoActionStart( OLUNDO_INSERT ); 1031 1032 pOwner->pEditEngine->SetUpdateMode( sal_False ); 1033 pOwner->bPasting = sal_True; 1034 pEditView->PasteSpecial(); 1035 1036 if ( pOwner->ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT ) 1037 { 1038 const sal_uInt16 nParaCount = pOwner->pEditEngine->GetParagraphCount(); 1039 1040 for( sal_uInt16 nPara = 0; nPara < nParaCount; nPara++ ) 1041 pOwner->ImplSetLevelDependendStyleSheet( nPara ); 1042 } 1043 1044 pEditView->SetEditEngineUpdateMode( sal_True ); 1045 pOwner->UndoActionEnd( OLUNDO_INSERT ); 1046 pEditView->ShowCursor( sal_True, sal_True ); 1047 } 1048 } 1049 1050 List* OutlinerView::CreateSelectionList() 1051 { 1052 DBG_CHKTHIS( OutlinerView, 0 ); 1053 1054 ParaRange aParas = ImpGetSelectedParagraphs( sal_True ); 1055 List* pSelList = new List; 1056 for ( sal_uInt16 nPara = aParas.nStartPara; nPara <= aParas.nEndPara; nPara++ ) 1057 { 1058 Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara ); 1059 pSelList->Insert( pPara, LIST_APPEND ); 1060 } 1061 return pSelList; 1062 } 1063 1064 SfxStyleSheet* OutlinerView::GetStyleSheet() const 1065 { 1066 DBG_CHKTHIS(OutlinerView,0); 1067 return pEditView->GetStyleSheet(); 1068 } 1069 1070 void OutlinerView::SetStyleSheet( SfxStyleSheet* pStyle ) 1071 { 1072 DBG_CHKTHIS(OutlinerView,0); 1073 pEditView->SetStyleSheet( pStyle ); 1074 1075 ParaRange aSel = ImpGetSelectedParagraphs( sal_True ); 1076 for( sal_uInt16 nPara = aSel.nStartPara; nPara <= aSel.nEndPara; nPara++ ) 1077 { 1078 pOwner->ImplCheckNumBulletItem( nPara ); 1079 pOwner->ImplCalcBulletText( nPara, sal_False, sal_False ); 1080 } 1081 } 1082 1083 Pointer OutlinerView::GetPointer( const Point& rPosPixel ) 1084 { 1085 DBG_CHKTHIS(OutlinerView,0); 1086 1087 MouseTarget eTarget; 1088 ImpCheckMousePos( rPosPixel, eTarget ); 1089 1090 PointerStyle ePointerStyle = POINTER_ARROW; 1091 if ( eTarget == MouseText ) 1092 { 1093 ePointerStyle = GetOutliner()->IsVertical() ? POINTER_TEXT_VERTICAL : POINTER_TEXT; 1094 } 1095 else if ( eTarget == MouseHypertext ) 1096 { 1097 ePointerStyle = POINTER_REFHAND; 1098 } 1099 else if ( eTarget == MouseBullet ) 1100 { 1101 ePointerStyle = POINTER_MOVE; 1102 } 1103 1104 return Pointer( ePointerStyle ); 1105 } 1106 1107 1108 sal_uInt16 OutlinerView::ImpInitPaste( sal_uLong& rStart ) 1109 { 1110 DBG_CHKTHIS(OutlinerView,0); 1111 pOwner->bPasting = sal_True; 1112 ESelection aSelection( pEditView->GetSelection() ); 1113 aSelection.Adjust(); 1114 rStart = aSelection.nStartPara; 1115 sal_uInt16 nSize = aSelection.nEndPara - aSelection.nStartPara + 1; 1116 return nSize; 1117 } 1118 1119 1120 void OutlinerView::ImpPasted( sal_uLong nStart, sal_uLong nPrevParaCount, sal_uInt16 nSize) 1121 { 1122 DBG_CHKTHIS(OutlinerView,0); 1123 pOwner->bPasting = sal_False; 1124 sal_uLong nCurParaCount = (sal_uLong)pOwner->pEditEngine->GetParagraphCount(); 1125 if( nCurParaCount < nPrevParaCount ) 1126 nSize = sal::static_int_cast< sal_uInt16 >( 1127 nSize - ( nPrevParaCount - nCurParaCount ) ); 1128 else 1129 nSize = sal::static_int_cast< sal_uInt16 >( 1130 nSize + ( nCurParaCount - nPrevParaCount ) ); 1131 pOwner->ImpTextPasted( nStart, nSize ); 1132 } 1133 1134 1135 void OutlinerView::Command( const CommandEvent& rCEvt ) 1136 { 1137 DBG_CHKTHIS(OutlinerView,0); 1138 pEditView->Command( rCEvt ); 1139 } 1140 1141 1142 void OutlinerView::SelectRange( sal_uLong nFirst, sal_uInt16 nCount ) 1143 { 1144 DBG_CHKTHIS(OutlinerView,0); 1145 sal_uLong nLast = nFirst+nCount; 1146 nCount = (sal_uInt16)pOwner->pParaList->GetParagraphCount(); 1147 if( nLast <= nCount ) 1148 nLast = nCount - 1; 1149 ESelection aSel( (sal_uInt16)nFirst, 0, (sal_uInt16)nLast, 0xffff ); 1150 pEditView->SetSelection( aSel ); 1151 } 1152 1153 1154 sal_uInt16 OutlinerView::ImpCalcSelectedPages( sal_Bool bIncludeFirstSelected ) 1155 { 1156 DBG_CHKTHIS(OutlinerView,0); 1157 1158 ESelection aSel( pEditView->GetSelection() ); 1159 aSel.Adjust(); 1160 1161 sal_uInt16 nPages = 0; 1162 sal_uInt16 nFirstPage = 0xFFFF; 1163 sal_uInt16 nStartPara = aSel.nStartPara; 1164 if ( !bIncludeFirstSelected ) 1165 nStartPara++; // alle nach StartPara kommenden Absaetze werden geloescht 1166 for ( sal_uInt16 nPara = nStartPara; nPara <= aSel.nEndPara; nPara++ ) 1167 { 1168 Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara ); 1169 DBG_ASSERT(pPara, "ImpCalcSelectedPages: ungueltige Selection? "); 1170 if( pPara->HasFlag(PARAFLAG_ISPAGE) ) 1171 { 1172 nPages++; 1173 if( nFirstPage == 0xFFFF ) 1174 nFirstPage = nPara; 1175 } 1176 } 1177 1178 if( nPages ) 1179 { 1180 pOwner->nDepthChangedHdlPrevDepth = nPages; 1181 pOwner->pHdlParagraph = 0; 1182 pOwner->mnFirstSelPage = nFirstPage; 1183 } 1184 1185 return nPages; 1186 } 1187 1188 1189 void OutlinerView::ToggleBullets() 1190 { 1191 pOwner->UndoActionStart( OLUNDO_DEPTH ); 1192 1193 ESelection aSel( pEditView->GetSelection() ); 1194 aSel.Adjust(); 1195 1196 const bool bUpdate = pOwner->pEditEngine->GetUpdateMode(); 1197 pOwner->pEditEngine->SetUpdateMode( sal_False ); 1198 1199 sal_Int16 nDepth = -2; 1200 1201 for ( sal_uInt16 nPara = aSel.nStartPara; nPara <= aSel.nEndPara; nPara++ ) 1202 { 1203 Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara ); 1204 DBG_ASSERT(pPara, "OutlinerView::ToggleBullets(), illegal selection?"); 1205 1206 if( pPara ) 1207 { 1208 if( nDepth == -2 ) 1209 nDepth = (pOwner->GetDepth(nPara) == -1) ? 0 : -1; 1210 1211 pOwner->SetDepth( pPara, nDepth ); 1212 1213 if( nDepth == -1 ) 1214 { 1215 const SfxItemSet& rAttrs = pOwner->GetParaAttribs( nPara ); 1216 if(rAttrs.GetItemState( EE_PARA_BULLETSTATE ) == SFX_ITEM_SET) 1217 { 1218 SfxItemSet aAttrs(rAttrs); 1219 aAttrs.ClearItem( EE_PARA_BULLETSTATE ); 1220 pOwner->SetParaAttribs( nPara, aAttrs ); 1221 } 1222 } 1223 } 1224 } 1225 1226 // --> OD 2009-03-10 #i100014# 1227 // It is not a good idea to substract 1 from a count and cast the result 1228 // to sal_uInt16 without check, if the count is 0. 1229 sal_uInt16 nParaCount = (sal_uInt16) (pOwner->pParaList->GetParagraphCount()); 1230 // <-- 1231 pOwner->ImplCheckParagraphs( aSel.nStartPara, nParaCount ); 1232 pOwner->pEditEngine->QuickMarkInvalid( ESelection( aSel.nStartPara, 0, nParaCount, 0 ) ); 1233 1234 pOwner->pEditEngine->SetUpdateMode( bUpdate ); 1235 1236 pOwner->UndoActionEnd( OLUNDO_DEPTH ); 1237 } 1238 1239 void OutlinerView::EnableBullets() 1240 { 1241 pOwner->UndoActionStart( OLUNDO_DEPTH ); 1242 1243 ESelection aSel( pEditView->GetSelection() ); 1244 aSel.Adjust(); 1245 1246 const bool bUpdate = pOwner->pEditEngine->GetUpdateMode(); 1247 pOwner->pEditEngine->SetUpdateMode( sal_False ); 1248 1249 for ( sal_uInt16 nPara = aSel.nStartPara; nPara <= aSel.nEndPara; nPara++ ) 1250 { 1251 Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara ); 1252 DBG_ASSERT(pPara, "OutlinerView::ToggleBullets(), illegal selection?"); 1253 1254 if( pPara && (pOwner->GetDepth(nPara) == -1) ) 1255 { 1256 pOwner->SetDepth( pPara, 0 ); 1257 } 1258 } 1259 1260 // --> OD 2009-03-10 #i100014# 1261 // It is not a good idea to substract 1 from a count and cast the result 1262 // to sal_uInt16 without check, if the count is 0. 1263 sal_uInt16 nParaCount = (sal_uInt16) (pOwner->pParaList->GetParagraphCount()); 1264 // <-- 1265 pOwner->ImplCheckParagraphs( aSel.nStartPara, nParaCount ); 1266 pOwner->pEditEngine->QuickMarkInvalid( ESelection( aSel.nStartPara, 0, nParaCount, 0 ) ); 1267 1268 pOwner->pEditEngine->SetUpdateMode( bUpdate ); 1269 1270 pOwner->UndoActionEnd( OLUNDO_DEPTH ); 1271 } 1272 1273 1274 void OutlinerView::RemoveAttribsKeepLanguages( sal_Bool bRemoveParaAttribs ) 1275 { 1276 RemoveAttribs( bRemoveParaAttribs, 0, sal_True /*keep language attribs*/ ); 1277 } 1278 1279 void OutlinerView::RemoveAttribs( sal_Bool bRemoveParaAttribs, sal_uInt16 nWhich, sal_Bool bKeepLanguages ) 1280 { 1281 DBG_CHKTHIS(OutlinerView,0); 1282 sal_Bool bUpdate = pOwner->GetUpdateMode(); 1283 pOwner->SetUpdateMode( sal_False ); 1284 pOwner->UndoActionStart( OLUNDO_ATTR ); 1285 if (bKeepLanguages) 1286 pEditView->RemoveAttribsKeepLanguages( bRemoveParaAttribs ); 1287 else 1288 pEditView->RemoveAttribs( bRemoveParaAttribs, nWhich ); 1289 if ( bRemoveParaAttribs ) 1290 { 1291 // Ueber alle Absaetze, und Einrueckung und Level einstellen 1292 ESelection aSel = pEditView->GetSelection(); 1293 aSel.Adjust(); 1294 for ( sal_uInt16 nPara = aSel.nStartPara; nPara <= aSel.nEndPara; nPara++ ) 1295 { 1296 Paragraph* pPara = pOwner->pParaList->GetParagraph( nPara ); 1297 pOwner->ImplInitDepth( nPara, pPara->GetDepth(), sal_False, sal_False ); 1298 } 1299 } 1300 pOwner->UndoActionEnd( OLUNDO_ATTR ); 1301 pOwner->SetUpdateMode( bUpdate ); 1302 } 1303 1304 1305 1306 // ===================================================================== 1307 // ====================== Einfache Durchreicher ======================= 1308 // ====================================================================== 1309 1310 1311 void OutlinerView::InsertText( const XubString& rNew, sal_Bool bSelect ) 1312 { 1313 DBG_CHKTHIS(OutlinerView,0); 1314 if( pOwner->bFirstParaIsEmpty ) 1315 pOwner->Insert( String() ); 1316 pEditView->InsertText( rNew, bSelect ); 1317 } 1318 1319 void OutlinerView::SetVisArea( const Rectangle& rRec ) 1320 { 1321 DBG_CHKTHIS(OutlinerView,0); 1322 pEditView->SetVisArea( rRec ); 1323 } 1324 1325 1326 void OutlinerView::SetSelection( const ESelection& rSel ) 1327 { 1328 DBG_CHKTHIS(OutlinerView,0); 1329 pEditView->SetSelection( rSel ); 1330 } 1331 1332 void OutlinerView::SetReadOnly( sal_Bool bReadOnly ) 1333 { 1334 DBG_CHKTHIS(OutlinerView,0); 1335 pEditView->SetReadOnly( bReadOnly ); 1336 } 1337 1338 sal_Bool OutlinerView::IsReadOnly() const 1339 { 1340 DBG_CHKTHIS(OutlinerView,0); 1341 return pEditView->IsReadOnly(); 1342 } 1343 1344 sal_Bool OutlinerView::HasSelection() const 1345 { 1346 DBG_CHKTHIS(OutlinerView,0); 1347 return pEditView->HasSelection(); 1348 } 1349 1350 1351 void OutlinerView::ShowCursor( sal_Bool bGotoCursor ) 1352 { 1353 DBG_CHKTHIS(OutlinerView,0); 1354 pEditView->ShowCursor( bGotoCursor ); 1355 } 1356 1357 1358 void OutlinerView::HideCursor() 1359 { 1360 DBG_CHKTHIS(OutlinerView,0); 1361 pEditView->HideCursor(); 1362 } 1363 1364 1365 void OutlinerView::SetWindow( Window* pWin ) 1366 { 1367 DBG_CHKTHIS(OutlinerView,0); 1368 pEditView->SetWindow( pWin ); 1369 } 1370 1371 1372 Window* OutlinerView::GetWindow() const 1373 { 1374 DBG_CHKTHIS(OutlinerView,0); 1375 return pEditView->GetWindow(); 1376 } 1377 1378 1379 void OutlinerView::SetOutputArea( const Rectangle& rRect ) 1380 { 1381 DBG_CHKTHIS(OutlinerView,0); 1382 pEditView->SetOutputArea( rRect ); 1383 } 1384 1385 1386 Rectangle OutlinerView::GetOutputArea() const 1387 { 1388 DBG_CHKTHIS(OutlinerView,0); 1389 return pEditView->GetOutputArea(); 1390 } 1391 1392 1393 XubString OutlinerView::GetSelected() const 1394 { 1395 DBG_CHKTHIS(OutlinerView,0); 1396 return pEditView->GetSelected(); 1397 } 1398 1399 1400 void OutlinerView::RemoveCharAttribs( sal_uLong nPara, sal_uInt16 nWhich) 1401 { 1402 DBG_CHKTHIS(OutlinerView,0); 1403 pEditView->RemoveCharAttribs( (sal_uInt16)nPara, nWhich); 1404 } 1405 1406 1407 void OutlinerView::CompleteAutoCorrect() 1408 { 1409 DBG_CHKTHIS(OutlinerView,0); 1410 pEditView->CompleteAutoCorrect(); 1411 } 1412 1413 1414 EESpellState OutlinerView::StartSpeller( sal_Bool bMultiDoc ) 1415 { 1416 DBG_CHKTHIS(OutlinerView,0); 1417 return pEditView->StartSpeller( bMultiDoc ); 1418 } 1419 1420 1421 EESpellState OutlinerView::StartThesaurus() 1422 { 1423 DBG_CHKTHIS(OutlinerView,0); 1424 return pEditView->StartThesaurus(); 1425 } 1426 1427 1428 void OutlinerView::StartTextConversion( 1429 LanguageType nSrcLang, LanguageType nDestLang, const Font *pDestFont, 1430 sal_Int32 nOptions, sal_Bool bIsInteractive, sal_Bool bMultipleDoc ) 1431 { 1432 DBG_CHKTHIS(OutlinerView,0); 1433 if ( 1434 (LANGUAGE_KOREAN == nSrcLang && LANGUAGE_KOREAN == nDestLang) || 1435 (LANGUAGE_CHINESE_SIMPLIFIED == nSrcLang && LANGUAGE_CHINESE_TRADITIONAL == nDestLang) || 1436 (LANGUAGE_CHINESE_TRADITIONAL == nSrcLang && LANGUAGE_CHINESE_SIMPLIFIED == nDestLang) 1437 ) 1438 { 1439 pEditView->StartTextConversion( nSrcLang, nDestLang, pDestFont, nOptions, bIsInteractive, bMultipleDoc ); 1440 } 1441 else 1442 { 1443 DBG_ERROR( "unexpected language" ); 1444 } 1445 } 1446 1447 1448 sal_uInt16 OutlinerView::StartSearchAndReplace( const SvxSearchItem& rSearchItem ) 1449 { 1450 DBG_CHKTHIS(OutlinerView,0); 1451 return pEditView->StartSearchAndReplace( rSearchItem ); 1452 } 1453 1454 void OutlinerView::TransliterateText( sal_Int32 nTransliterationMode ) 1455 { 1456 DBG_CHKTHIS(OutlinerView,0); 1457 pEditView->TransliterateText( nTransliterationMode ); 1458 } 1459 1460 1461 1462 ESelection OutlinerView::GetSelection() 1463 { 1464 DBG_CHKTHIS(OutlinerView,0); 1465 return pEditView->GetSelection(); 1466 } 1467 1468 1469 void OutlinerView::Scroll( long nHorzScroll, long nVertScroll ) 1470 { 1471 DBG_CHKTHIS(OutlinerView,0); 1472 pEditView->Scroll( nHorzScroll, nVertScroll ); 1473 } 1474 1475 1476 void OutlinerView::SetControlWord( sal_uLong nWord ) 1477 { 1478 DBG_CHKTHIS(OutlinerView,0); 1479 pEditView->SetControlWord( nWord ); 1480 } 1481 1482 1483 sal_uLong OutlinerView::GetControlWord() const 1484 { 1485 DBG_CHKTHIS(OutlinerView,0); 1486 return pEditView->GetControlWord(); 1487 } 1488 1489 1490 void OutlinerView::SetAnchorMode( EVAnchorMode eMode ) 1491 { 1492 DBG_CHKTHIS(OutlinerView,0); 1493 pEditView->SetAnchorMode( eMode ); 1494 } 1495 1496 1497 EVAnchorMode OutlinerView::GetAnchorMode() const 1498 { 1499 DBG_CHKTHIS(OutlinerView,0); 1500 return pEditView->GetAnchorMode(); 1501 } 1502 1503 1504 void OutlinerView::Undo() 1505 { 1506 DBG_CHKTHIS(OutlinerView,0); 1507 pEditView->Undo(); 1508 } 1509 1510 1511 void OutlinerView::Redo() 1512 { 1513 DBG_CHKTHIS(OutlinerView,0); 1514 pEditView->Redo(); 1515 } 1516 1517 1518 void OutlinerView::EnablePaste( sal_Bool bEnable ) 1519 { 1520 DBG_CHKTHIS(OutlinerView,0); 1521 pEditView->EnablePaste( bEnable ); 1522 } 1523 1524 1525 void OutlinerView::Copy() 1526 { 1527 DBG_CHKTHIS(OutlinerView,0); 1528 pEditView->Copy(); 1529 } 1530 1531 1532 void OutlinerView::InsertField( const SvxFieldItem& rFld ) 1533 { 1534 DBG_CHKTHIS(OutlinerView,0); 1535 pEditView->InsertField( rFld ); 1536 } 1537 1538 1539 const SvxFieldItem* OutlinerView::GetFieldUnderMousePointer() const 1540 { 1541 DBG_CHKTHIS(OutlinerView,0); 1542 return pEditView->GetFieldUnderMousePointer(); 1543 } 1544 1545 1546 const SvxFieldItem* OutlinerView::GetFieldUnderMousePointer( sal_uInt16& nPara, sal_uInt16& nPos ) const 1547 { 1548 DBG_CHKTHIS(OutlinerView,0); 1549 return pEditView->GetFieldUnderMousePointer( nPara, nPos ); 1550 } 1551 1552 1553 const SvxFieldItem* OutlinerView::GetFieldAtSelection() const 1554 { 1555 DBG_CHKTHIS(OutlinerView,0); 1556 return pEditView->GetFieldAtSelection(); 1557 } 1558 1559 void OutlinerView::SetInvalidateMore( sal_uInt16 nPixel ) 1560 { 1561 DBG_CHKTHIS(OutlinerView,0); 1562 pEditView->SetInvalidateMore( nPixel ); 1563 } 1564 1565 1566 sal_uInt16 OutlinerView::GetInvalidateMore() const 1567 { 1568 DBG_CHKTHIS(OutlinerView,0); 1569 return pEditView->GetInvalidateMore(); 1570 } 1571 1572 1573 sal_Bool OutlinerView::IsCursorAtWrongSpelledWord( sal_Bool bMarkIfWrong ) 1574 { 1575 DBG_CHKTHIS(OutlinerView,0); 1576 return pEditView->IsCursorAtWrongSpelledWord( bMarkIfWrong ); 1577 } 1578 1579 1580 sal_Bool OutlinerView::IsWrongSpelledWordAtPos( const Point& rPosPixel, sal_Bool bMarkIfWrong ) 1581 { 1582 DBG_CHKTHIS(OutlinerView,0); 1583 return pEditView->IsWrongSpelledWordAtPos( rPosPixel, bMarkIfWrong ); 1584 } 1585 1586 1587 void OutlinerView::SpellIgnoreWord() 1588 { 1589 DBG_CHKTHIS(OutlinerView,0); 1590 pEditView->SpellIgnoreWord(); 1591 } 1592 1593 1594 void OutlinerView::ExecuteSpellPopup( const Point& rPosPixel, Link* pStartDlg ) 1595 { 1596 DBG_CHKTHIS(OutlinerView,0); 1597 pEditView->ExecuteSpellPopup( rPosPixel, pStartDlg ); 1598 } 1599 1600 sal_uLong OutlinerView::Read( SvStream& rInput, const String& rBaseURL, EETextFormat eFormat, sal_Bool bSelect, SvKeyValueIterator* pHTTPHeaderAttrs ) 1601 { 1602 DBG_CHKTHIS(OutlinerView,0); 1603 sal_uInt16 nOldParaCount = pEditView->GetEditEngine()->GetParagraphCount(); 1604 ESelection aOldSel = pEditView->GetSelection(); 1605 aOldSel.Adjust(); 1606 1607 sal_uLong nRet = pEditView->Read( rInput, rBaseURL, eFormat, bSelect, pHTTPHeaderAttrs ); 1608 1609 // MT 08/00: Hier sollte eigentlich das gleiche wie in PasteSpecial passieren! 1610 // Mal anpassen, wenn dieses ImplInitPaste und ImpPasted-Geraffel ueberarbeitet ist. 1611 1612 long nParaDiff = pEditView->GetEditEngine()->GetParagraphCount() - nOldParaCount; 1613 sal_uInt16 nChangesStart = aOldSel.nStartPara; 1614 sal_uInt16 nChangesEnd = sal::static_int_cast< sal_uInt16 >(nChangesStart + nParaDiff + (aOldSel.nEndPara-aOldSel.nStartPara)); 1615 1616 for ( sal_uInt16 n = nChangesStart; n <= nChangesEnd; n++ ) 1617 { 1618 if ( eFormat == EE_FORMAT_BIN ) 1619 { 1620 sal_uInt16 nDepth = 0; 1621 const SfxItemSet& rAttrs = pOwner->GetParaAttribs( n ); 1622 const SfxInt16Item& rLevel = (const SfxInt16Item&) rAttrs.Get( EE_PARA_OUTLLEVEL ); 1623 nDepth = rLevel.GetValue(); 1624 pOwner->ImplInitDepth( n, nDepth, sal_False ); 1625 } 1626 1627 if ( pOwner->ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT ) 1628 pOwner->ImplSetLevelDependendStyleSheet( n ); 1629 } 1630 1631 if ( eFormat != EE_FORMAT_BIN ) 1632 { 1633 pOwner->ImpFilterIndents( nChangesStart, nChangesEnd ); 1634 } 1635 1636 return nRet; 1637 } 1638 1639 sal_uLong OutlinerView::Write( SvStream& rOutput, EETextFormat eFormat ) 1640 { 1641 DBG_CHKTHIS(OutlinerView,0); 1642 return pEditView->Write( rOutput, eFormat ); 1643 } 1644 1645 void OutlinerView::SetBackgroundColor( const Color& rColor ) 1646 { 1647 DBG_CHKTHIS(OutlinerView,0); 1648 pEditView->SetBackgroundColor( rColor ); 1649 } 1650 1651 1652 Color OutlinerView::GetBackgroundColor() 1653 { 1654 DBG_CHKTHIS(OutlinerView,0); 1655 return pEditView->GetBackgroundColor(); 1656 } 1657 1658 SfxItemSet OutlinerView::GetAttribs() 1659 { 1660 DBG_CHKTHIS(OutlinerView,0); 1661 return pEditView->GetAttribs(); 1662 } 1663 1664 sal_uInt16 OutlinerView::GetSelectedScriptType() const 1665 { 1666 DBG_CHKTHIS(OutlinerView,0); 1667 return pEditView->GetSelectedScriptType(); 1668 } 1669 1670 String OutlinerView::GetSurroundingText() const 1671 { 1672 DBG_CHKTHIS(OutlinerView,0); 1673 return pEditView->GetSurroundingText(); 1674 } 1675 1676 Selection OutlinerView::GetSurroundingTextSelection() const 1677 { 1678 DBG_CHKTHIS(OutlinerView,0); 1679 return pEditView->GetSurroundingTextSelection(); 1680 } 1681 1682 1683 // ====================================================================== 1684 // ===== some code for thesaurus sub menu within context menu 1685 // ====================================================================== 1686 1687 // returns: true if a word for thesaurus look-up was found at the current cursor position. 1688 // The status string will be word + iso language string (e.g. "light#en-US") 1689 bool EDITENG_DLLPUBLIC GetStatusValueForThesaurusFromContext( 1690 String &rStatusVal, 1691 LanguageType &rLang, 1692 const EditView &rEditView ) 1693 { 1694 // get text and locale for thesaurus look up 1695 String aText; 1696 EditEngine *pEditEngine = rEditView.GetEditEngine(); 1697 ESelection aTextSel( rEditView.GetSelection() ); 1698 if (!aTextSel.HasRange()) 1699 aTextSel = pEditEngine->GetWord( aTextSel, i18n::WordType::DICTIONARY_WORD ); 1700 aText = pEditEngine->GetText( aTextSel ); 1701 aTextSel.Adjust(); 1702 LanguageType nLang = pEditEngine->GetLanguage( aTextSel.nStartPara, aTextSel.nStartPos ); 1703 String aLangText( MsLangId::convertLanguageToIsoString( nLang ) ); 1704 1705 // set word and locale to look up as status value 1706 String aStatusVal( aText ); 1707 aStatusVal.AppendAscii( "#" ); 1708 aStatusVal += aLangText; 1709 1710 rStatusVal = aStatusVal; 1711 rLang = nLang; 1712 1713 return aText.Len() > 0; 1714 } 1715 1716 1717 void EDITENG_DLLPUBLIC ReplaceTextWithSynonym( EditView &rEditView, const String &rSynonmText ) 1718 { 1719 // get selection to use 1720 ESelection aCurSel( rEditView.GetSelection() ); 1721 if (!rEditView.HasSelection()) 1722 { 1723 // select the same word that was used in GetStatusValueForThesaurusFromContext by calling GetWord. 1724 // (In the end both functions will call ImpEditEngine::SelectWord) 1725 rEditView.SelectCurrentWord( i18n::WordType::DICTIONARY_WORD ); 1726 aCurSel = rEditView.GetSelection(); 1727 } 1728 1729 // replace word ... 1730 rEditView.InsertText( rSynonmText ); 1731 rEditView.ShowCursor( sal_True, sal_False ); 1732 } 1733 1734 1735