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