xref: /trunk/main/editeng/source/outliner/outlvw.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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