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