1190118d0SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3190118d0SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4190118d0SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5190118d0SAndrew Rist  * distributed with this work for additional information
6190118d0SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7190118d0SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8190118d0SAndrew Rist  * "License"); you may not use this file except in compliance
9190118d0SAndrew Rist  * with the License.  You may obtain a copy of the License at
10190118d0SAndrew Rist  *
11190118d0SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12190118d0SAndrew Rist  *
13190118d0SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14190118d0SAndrew Rist  * software distributed under the License is distributed on an
15190118d0SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16190118d0SAndrew Rist  * KIND, either express or implied.  See the License for the
17190118d0SAndrew Rist  * specific language governing permissions and limitations
18190118d0SAndrew Rist  * under the License.
19190118d0SAndrew Rist  *
20190118d0SAndrew Rist  *************************************************************/
21190118d0SAndrew Rist 
22190118d0SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_editeng.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <svl/intitem.hxx>
28cdf0e10cSrcweir #include <editeng/editeng.hxx>
29cdf0e10cSrcweir #include <editeng/editview.hxx>
30cdf0e10cSrcweir #include <editeng/editdata.hxx>
31cdf0e10cSrcweir #include <editeng/eerdll.hxx>
32cdf0e10cSrcweir #include <editeng/lrspitem.hxx>
33cdf0e10cSrcweir #include <editeng/fhgtitem.hxx>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include <math.h>
36cdf0e10cSrcweir #include <svl/style.hxx>
37cdf0e10cSrcweir #include <vcl/wrkwin.hxx>
38cdf0e10cSrcweir #define _OUTLINER_CXX
39cdf0e10cSrcweir #include <editeng/outliner.hxx>
40cdf0e10cSrcweir #include <paralist.hxx>
41cdf0e10cSrcweir #include <editeng/outlobj.hxx>
42cdf0e10cSrcweir #include <outleeng.hxx>
43cdf0e10cSrcweir #include <outlundo.hxx>
44cdf0e10cSrcweir #include <editeng/eeitem.hxx>
45cdf0e10cSrcweir #include <editeng/editstat.hxx>
46cdf0e10cSrcweir #include <editeng/scripttypeitem.hxx>
47cdf0e10cSrcweir #include <editeng/editobj.hxx>
48cdf0e10cSrcweir #include <svl/itemset.hxx>
49cdf0e10cSrcweir #include <svl/whiter.hxx>
50cdf0e10cSrcweir #include <vcl/metric.hxx>
51cdf0e10cSrcweir #include <editeng/numitem.hxx>
52cdf0e10cSrcweir #include <editeng/adjitem.hxx>
53cdf0e10cSrcweir #include <vcl/graph.hxx>
54cdf0e10cSrcweir #include <vcl/gdimtf.hxx>
55cdf0e10cSrcweir #include <vcl/metaact.hxx>
56cdf0e10cSrcweir #include <svtools/grfmgr.hxx>
57cdf0e10cSrcweir #include <editeng/svxfont.hxx>
58cdf0e10cSrcweir #include <editeng/brshitem.hxx>
59cdf0e10cSrcweir #include <svl/itempool.hxx>
60cdf0e10cSrcweir 
61cdf0e10cSrcweir // #101498# calculate if it's RTL or not
62cdf0e10cSrcweir #include <unicode/ubidi.h>
63cdf0e10cSrcweir 
64cdf0e10cSrcweir #define DEFAULT_SCALE	75
65cdf0e10cSrcweir 
66cdf0e10cSrcweir static const sal_uInt16 nDefStyles = 3;	// Sonderbehandlung fuer die ersten 3 Ebenen
67cdf0e10cSrcweir static const sal_uInt16 nDefBulletIndent = 800;
68cdf0e10cSrcweir static const sal_uInt16 nDefBulletWidth = 700;
69cdf0e10cSrcweir static const sal_uInt16	pDefBulletIndents[nDefStyles]= 	{ 1400, 800, 800 };
70cdf0e10cSrcweir static const sal_uInt16	pDefBulletWidths[nDefStyles] = 	{ 1000, 850, 700 };
71cdf0e10cSrcweir 
lcl_ImplGetDefBulletWidth(sal_Int16 nDepth)72cdf0e10cSrcweir sal_uInt16 lcl_ImplGetDefBulletWidth( sal_Int16 nDepth )
73cdf0e10cSrcweir {
74cdf0e10cSrcweir 	return ( nDepth < nDefStyles ) ? pDefBulletWidths[nDepth] : nDefBulletWidth;
75cdf0e10cSrcweir }
76cdf0e10cSrcweir 
lcl_ImplGetDefBulletIndent(sal_Int16 nDepth)77cdf0e10cSrcweir sal_uInt16 lcl_ImplGetDefBulletIndent( sal_Int16 nDepth )
78cdf0e10cSrcweir {
79cdf0e10cSrcweir 	sal_uInt16 nI = 0;
80cdf0e10cSrcweir 
81cdf0e10cSrcweir 	if( nDepth >= 0 )
82cdf0e10cSrcweir 	{
83cdf0e10cSrcweir 		for ( sal_Int16 n = 0; n <= nDepth; n++ )
84cdf0e10cSrcweir 			nI = nI +
85cdf0e10cSrcweir 				( ( n < nDefStyles ) ? pDefBulletIndents[n] : nDefBulletIndent );
86cdf0e10cSrcweir 	}
87cdf0e10cSrcweir 	return nI;
88cdf0e10cSrcweir }
89cdf0e10cSrcweir 
90cdf0e10cSrcweir 
91cdf0e10cSrcweir // ----------------------------------------------------------------------
92cdf0e10cSrcweir // Outliner
93cdf0e10cSrcweir // ----------------------------------------------------------------------
94cdf0e10cSrcweir DBG_NAME(Outliner);
95cdf0e10cSrcweir 
ImplCheckDepth(sal_Int16 & rnDepth) const96cdf0e10cSrcweir void Outliner::ImplCheckDepth( sal_Int16& rnDepth ) const
97cdf0e10cSrcweir {
98cdf0e10cSrcweir 	if( rnDepth < nMinDepth )
99cdf0e10cSrcweir 		rnDepth = nMinDepth;
100cdf0e10cSrcweir 	else if( rnDepth > nMaxDepth )
101cdf0e10cSrcweir 		rnDepth = nMaxDepth;
102cdf0e10cSrcweir }
103cdf0e10cSrcweir 
Insert(const XubString & rText,sal_uLong nAbsPos,sal_Int16 nDepth)104cdf0e10cSrcweir Paragraph* Outliner::Insert(const XubString& rText, sal_uLong nAbsPos, sal_Int16 nDepth)
105cdf0e10cSrcweir {
106cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
107cdf0e10cSrcweir 	DBG_ASSERT(pParaList->GetParagraphCount(),"Insert:No Paras");
108cdf0e10cSrcweir 
109cdf0e10cSrcweir 	Paragraph* pPara;
110cdf0e10cSrcweir 
111cdf0e10cSrcweir     ImplCheckDepth( nDepth );
112cdf0e10cSrcweir 
113cdf0e10cSrcweir 	sal_uLong nParagraphCount = pParaList->GetParagraphCount();
114cdf0e10cSrcweir 	if( nAbsPos > nParagraphCount )
115cdf0e10cSrcweir 		nAbsPos = nParagraphCount;
116cdf0e10cSrcweir 
117cdf0e10cSrcweir 	if( bFirstParaIsEmpty )
118cdf0e10cSrcweir 	{
119cdf0e10cSrcweir 		pPara = pParaList->GetParagraph( 0 );
120cdf0e10cSrcweir 		if( pPara->GetDepth() != nDepth )
121cdf0e10cSrcweir 		{
122cdf0e10cSrcweir 			nDepthChangedHdlPrevDepth = pPara->GetDepth();
123cdf0e10cSrcweir 			mnDepthChangeHdlPrevFlags = pPara->nFlags;
124cdf0e10cSrcweir 			pPara->SetDepth( nDepth );
125cdf0e10cSrcweir 			pHdlParagraph = pPara;
126cdf0e10cSrcweir 			DepthChangedHdl();
127cdf0e10cSrcweir 		}
128cdf0e10cSrcweir 		pPara->nFlags |= PARAFLAG_HOLDDEPTH;
129cdf0e10cSrcweir 		SetText( rText, pPara );
130cdf0e10cSrcweir 	}
131cdf0e10cSrcweir 	else
132cdf0e10cSrcweir 	{
133cdf0e10cSrcweir 		sal_Bool bUpdate = pEditEngine->GetUpdateMode();
134cdf0e10cSrcweir 		pEditEngine->SetUpdateMode( sal_False );
135cdf0e10cSrcweir         ImplBlockInsertionCallbacks( sal_True );
136cdf0e10cSrcweir 		pPara = new Paragraph( nDepth );
137cdf0e10cSrcweir 		pParaList->Insert( pPara, nAbsPos );
138cdf0e10cSrcweir 		pEditEngine->InsertParagraph( (sal_uInt16)nAbsPos, String() );
139cdf0e10cSrcweir 		DBG_ASSERT(pPara==pParaList->GetParagraph(nAbsPos),"Insert:Failed");
140cdf0e10cSrcweir 		ImplInitDepth( (sal_uInt16)nAbsPos, nDepth, sal_False );
141cdf0e10cSrcweir 		pHdlParagraph = pPara;
142cdf0e10cSrcweir 		ParagraphInsertedHdl();
143cdf0e10cSrcweir 		pPara->nFlags |= PARAFLAG_HOLDDEPTH;
144cdf0e10cSrcweir 		SetText( rText, pPara );
145cdf0e10cSrcweir 		ImplBlockInsertionCallbacks( sal_False );
146cdf0e10cSrcweir 		pEditEngine->SetUpdateMode( bUpdate );
147cdf0e10cSrcweir 	}
148cdf0e10cSrcweir 	bFirstParaIsEmpty = sal_False;
149cdf0e10cSrcweir 	DBG_ASSERT(pEditEngine->GetParagraphCount()==pParaList->GetParagraphCount(),"SetText failed");
150cdf0e10cSrcweir 	return pPara;
151cdf0e10cSrcweir }
152cdf0e10cSrcweir 
153cdf0e10cSrcweir 
ParagraphInserted(sal_uInt16 nPara)154cdf0e10cSrcweir void Outliner::ParagraphInserted( sal_uInt16 nPara )
155cdf0e10cSrcweir {
156cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
157cdf0e10cSrcweir 
158cdf0e10cSrcweir 	if ( bBlockInsCallback )
159cdf0e10cSrcweir 		return;
160cdf0e10cSrcweir 
161cdf0e10cSrcweir 	if( bPasting || pEditEngine->IsInUndo() )
162cdf0e10cSrcweir 	{
163cdf0e10cSrcweir 		Paragraph* pPara = new Paragraph( -1 );
164cdf0e10cSrcweir 		pParaList->Insert( pPara, nPara );
165cdf0e10cSrcweir 		if( pEditEngine->IsInUndo() )
166cdf0e10cSrcweir 		{
167cdf0e10cSrcweir 			pPara->nFlags = PARAFLAG_SETBULLETTEXT;
168cdf0e10cSrcweir 			pPara->bVisible = sal_True;
169cdf0e10cSrcweir 			const SfxInt16Item& rLevel = (const SfxInt16Item&) pEditEngine->GetParaAttrib( nPara, EE_PARA_OUTLLEVEL );
170cdf0e10cSrcweir 			pPara->SetDepth( rLevel.GetValue() );
171cdf0e10cSrcweir 		}
172cdf0e10cSrcweir 	}
173cdf0e10cSrcweir 	else
174cdf0e10cSrcweir 	{
175cdf0e10cSrcweir 		sal_Int16 nDepth = -1;
176cdf0e10cSrcweir 		Paragraph* pParaBefore = pParaList->GetParagraph( nPara-1 );
177cdf0e10cSrcweir 		if ( pParaBefore )
178cdf0e10cSrcweir 			nDepth = pParaBefore->GetDepth();
179cdf0e10cSrcweir 
180cdf0e10cSrcweir 		Paragraph* pPara = new Paragraph( nDepth );
181cdf0e10cSrcweir 		pParaList->Insert( pPara, nPara );
182cdf0e10cSrcweir 
183cdf0e10cSrcweir 		if( !pEditEngine->IsInUndo() )
184cdf0e10cSrcweir 		{
185cdf0e10cSrcweir 			ImplCalcBulletText( nPara, sal_True, sal_False );
186cdf0e10cSrcweir 			pHdlParagraph = pPara;
187cdf0e10cSrcweir 			ParagraphInsertedHdl();
188cdf0e10cSrcweir 		}
189cdf0e10cSrcweir 	}
190cdf0e10cSrcweir }
191cdf0e10cSrcweir 
ParagraphDeleted(sal_uInt16 nPara)192cdf0e10cSrcweir void Outliner::ParagraphDeleted( sal_uInt16 nPara )
193cdf0e10cSrcweir {
194cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
195cdf0e10cSrcweir 
196cdf0e10cSrcweir 	if ( bBlockInsCallback || ( nPara == EE_PARA_ALL ) )
197cdf0e10cSrcweir 		return;
198cdf0e10cSrcweir 
199cdf0e10cSrcweir 	Paragraph* pPara = pParaList->GetParagraph( nPara );
200cdf0e10cSrcweir         if (!pPara)
201cdf0e10cSrcweir             return;
202cdf0e10cSrcweir 
203cdf0e10cSrcweir 	sal_Int16 nDepth = pPara->GetDepth();
204cdf0e10cSrcweir 
205cdf0e10cSrcweir 	if( !pEditEngine->IsInUndo() )
206cdf0e10cSrcweir 	{
207cdf0e10cSrcweir 		pHdlParagraph = pPara;
208cdf0e10cSrcweir 		ParagraphRemovingHdl();
209cdf0e10cSrcweir 	}
210cdf0e10cSrcweir 
211cdf0e10cSrcweir 	pParaList->Remove( nPara );
212cdf0e10cSrcweir 	delete pPara;
213cdf0e10cSrcweir 
214cdf0e10cSrcweir 	if( !pEditEngine->IsInUndo() && !bPasting )
215cdf0e10cSrcweir 	{
216cdf0e10cSrcweir 		pPara = pParaList->GetParagraph( nPara );
217cdf0e10cSrcweir 		if ( pPara && ( pPara->GetDepth() > nDepth ) )
218cdf0e10cSrcweir 		{
219cdf0e10cSrcweir 			ImplCalcBulletText( nPara, sal_True, sal_False );
220cdf0e10cSrcweir 			// naechsten auf gleicher Ebene suchen...
221cdf0e10cSrcweir 			while ( pPara && pPara->GetDepth() > nDepth )
222cdf0e10cSrcweir 				pPara = pParaList->GetParagraph( ++nPara );
223cdf0e10cSrcweir 		}
224cdf0e10cSrcweir 
225cdf0e10cSrcweir 		if ( pPara && ( pPara->GetDepth() == nDepth ) )
226cdf0e10cSrcweir 			ImplCalcBulletText( nPara, sal_True, sal_False );
227cdf0e10cSrcweir 	}
228cdf0e10cSrcweir }
229cdf0e10cSrcweir 
Init(sal_uInt16 nMode)230cdf0e10cSrcweir void Outliner::Init( sal_uInt16 nMode )
231cdf0e10cSrcweir {
232cdf0e10cSrcweir 	nOutlinerMode = nMode;
233cdf0e10cSrcweir 
234cdf0e10cSrcweir 	Clear();
235cdf0e10cSrcweir 
236cdf0e10cSrcweir 	sal_uLong nCtrl = pEditEngine->GetControlWord();
237cdf0e10cSrcweir 	nCtrl &= ~(EE_CNTRL_OUTLINER|EE_CNTRL_OUTLINER2);
238cdf0e10cSrcweir 
239cdf0e10cSrcweir 	SetMaxDepth( 9 );
240cdf0e10cSrcweir 
241cdf0e10cSrcweir 	switch ( ImplGetOutlinerMode() )
242cdf0e10cSrcweir 	{
243cdf0e10cSrcweir 		case OUTLINERMODE_TEXTOBJECT:
244cdf0e10cSrcweir 		case OUTLINERMODE_TITLEOBJECT:
245cdf0e10cSrcweir 			break;
246cdf0e10cSrcweir 
247cdf0e10cSrcweir 		case OUTLINERMODE_OUTLINEOBJECT:
248cdf0e10cSrcweir 			nCtrl |= EE_CNTRL_OUTLINER2;
249cdf0e10cSrcweir 			break;
250cdf0e10cSrcweir 		case OUTLINERMODE_OUTLINEVIEW:
251cdf0e10cSrcweir 			nCtrl |= EE_CNTRL_OUTLINER;
252cdf0e10cSrcweir 			break;
253cdf0e10cSrcweir 
254cdf0e10cSrcweir 		default: DBG_ERROR( "Outliner::Init - Invalid Mode!" );
255cdf0e10cSrcweir 	}
256cdf0e10cSrcweir 
257cdf0e10cSrcweir 	pEditEngine->SetControlWord( nCtrl );
258cdf0e10cSrcweir 
259f0de6be0SArmin Le Grand     const bool bWasUndoEnabled(IsUndoEnabled());
260801f99ffSArmin Le Grand     EnableUndo(false);
261cdf0e10cSrcweir 	ImplInitDepth( 0, GetMinDepth(), sal_False );
262cdf0e10cSrcweir 	GetUndoManager().Clear();
263f0de6be0SArmin Le Grand     EnableUndo(bWasUndoEnabled);
264cdf0e10cSrcweir }
265cdf0e10cSrcweir 
SetMaxDepth(sal_Int16 nDepth,sal_Bool bCheckParagraphs)266cdf0e10cSrcweir void Outliner::SetMaxDepth( sal_Int16 nDepth, sal_Bool bCheckParagraphs )
267cdf0e10cSrcweir {
268cdf0e10cSrcweir 	if( nMaxDepth != nDepth )
269cdf0e10cSrcweir 	{
270cdf0e10cSrcweir 		nMaxDepth = Min( nDepth, (sal_Int16)(SVX_MAX_NUM-1) );
271cdf0e10cSrcweir 
272cdf0e10cSrcweir 		if( bCheckParagraphs )
273cdf0e10cSrcweir 		{
274cdf0e10cSrcweir 			sal_uInt16 nParagraphs = (sal_uInt16)pParaList->GetParagraphCount();
275cdf0e10cSrcweir 			for ( sal_uInt16 nPara = 0; nPara < nParagraphs; nPara++ )
276cdf0e10cSrcweir 			{
277cdf0e10cSrcweir 				Paragraph* pPara = pParaList->GetParagraph( nPara );
278cdf0e10cSrcweir 				if( pPara && pPara->GetDepth() > nMaxDepth )
279cdf0e10cSrcweir 				{
280cdf0e10cSrcweir 					SetDepth( pPara, nMaxDepth );
281cdf0e10cSrcweir 				}
282cdf0e10cSrcweir 			}
283cdf0e10cSrcweir 		}
284cdf0e10cSrcweir 	}
285cdf0e10cSrcweir }
286cdf0e10cSrcweir 
GetDepth(sal_uLong nPara) const287cdf0e10cSrcweir sal_Int16 Outliner::GetDepth( sal_uLong nPara ) const
288cdf0e10cSrcweir {
289cdf0e10cSrcweir 	Paragraph* pPara = pParaList->GetParagraph( nPara );
290cdf0e10cSrcweir 	DBG_ASSERT( pPara, "Outliner::GetDepth - Paragraph not found!" );
291cdf0e10cSrcweir 	return pPara ? pPara->GetDepth() : -1;
292cdf0e10cSrcweir }
293cdf0e10cSrcweir 
SetDepth(Paragraph * pPara,sal_Int16 nNewDepth)294cdf0e10cSrcweir void Outliner::SetDepth( Paragraph* pPara, sal_Int16 nNewDepth )
295cdf0e10cSrcweir {
296cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
297cdf0e10cSrcweir 
298cdf0e10cSrcweir     ImplCheckDepth( nNewDepth );
299cdf0e10cSrcweir 
300cdf0e10cSrcweir 	if ( nNewDepth != pPara->GetDepth() )
301cdf0e10cSrcweir 	{
302cdf0e10cSrcweir 		nDepthChangedHdlPrevDepth = pPara->GetDepth();
303cdf0e10cSrcweir 		mnDepthChangeHdlPrevFlags = pPara->nFlags;
304cdf0e10cSrcweir 		pHdlParagraph = pPara;
305cdf0e10cSrcweir 
306cdf0e10cSrcweir         sal_uInt16 nPara = (sal_uInt16)GetAbsPos( pPara );
307cdf0e10cSrcweir 		ImplInitDepth( nPara, nNewDepth, sal_True );
308cdf0e10cSrcweir 		ImplCalcBulletText( nPara, sal_False, sal_False );
309cdf0e10cSrcweir 
310cdf0e10cSrcweir 		if ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT )
311cdf0e10cSrcweir 			ImplSetLevelDependendStyleSheet( nPara );
312cdf0e10cSrcweir 
313cdf0e10cSrcweir 		DepthChangedHdl();
314cdf0e10cSrcweir 	}
315cdf0e10cSrcweir }
316cdf0e10cSrcweir 
GetNumberingStartValue(sal_uInt16 nPara)317cdf0e10cSrcweir sal_Int16 Outliner::GetNumberingStartValue( sal_uInt16 nPara )
318cdf0e10cSrcweir {
319cdf0e10cSrcweir 	Paragraph* pPara = pParaList->GetParagraph( nPara );
320cdf0e10cSrcweir 	DBG_ASSERT( pPara, "Outliner::GetNumberingStartValue - Paragraph not found!" );
321cdf0e10cSrcweir 	return pPara ? pPara->GetNumberingStartValue() : -1;
322cdf0e10cSrcweir }
323cdf0e10cSrcweir 
SetNumberingStartValue(sal_uInt16 nPara,sal_Int16 nNumberingStartValue)324cdf0e10cSrcweir void Outliner::SetNumberingStartValue( sal_uInt16 nPara, sal_Int16 nNumberingStartValue )
325cdf0e10cSrcweir {
326cdf0e10cSrcweir 	Paragraph* pPara = pParaList->GetParagraph( nPara );
327cdf0e10cSrcweir 	DBG_ASSERT( pPara, "Outliner::GetNumberingStartValue - Paragraph not found!" );
328cdf0e10cSrcweir 	if( pPara && pPara->GetNumberingStartValue() != nNumberingStartValue )
329cdf0e10cSrcweir     {
330cdf0e10cSrcweir         if( IsUndoEnabled() && !IsInUndo() )
331cdf0e10cSrcweir             InsertUndo( new OutlinerUndoChangeParaNumberingRestart( this, nPara,
332cdf0e10cSrcweir                 pPara->GetNumberingStartValue(), nNumberingStartValue,
333cdf0e10cSrcweir                 pPara->IsParaIsNumberingRestart(), pPara->IsParaIsNumberingRestart() ) );
334cdf0e10cSrcweir 
335cdf0e10cSrcweir         pPara->SetNumberingStartValue( nNumberingStartValue );
336cdf0e10cSrcweir         // --> OD 2009-03-10 #i100014#
337cdf0e10cSrcweir         // It is not a good idea to substract 1 from a count and cast the result
338cdf0e10cSrcweir         // to sal_uInt16 without check, if the count is 0.
339cdf0e10cSrcweir         ImplCheckParagraphs( nPara, (sal_uInt16) (pParaList->GetParagraphCount()) );
340cdf0e10cSrcweir         // <--
341cdf0e10cSrcweir         pEditEngine->SetModified();
342cdf0e10cSrcweir     }
343cdf0e10cSrcweir }
344cdf0e10cSrcweir 
IsParaIsNumberingRestart(sal_uInt16 nPara)345cdf0e10cSrcweir sal_Bool Outliner::IsParaIsNumberingRestart( sal_uInt16 nPara )
346cdf0e10cSrcweir {
347cdf0e10cSrcweir 	Paragraph* pPara = pParaList->GetParagraph( nPara );
348cdf0e10cSrcweir 	DBG_ASSERT( pPara, "Outliner::IsParaIsNumberingRestart - Paragraph not found!" );
349cdf0e10cSrcweir 	return pPara ? pPara->IsParaIsNumberingRestart() : sal_False;
350cdf0e10cSrcweir }
351cdf0e10cSrcweir 
SetParaIsNumberingRestart(sal_uInt16 nPara,sal_Bool bParaIsNumberingRestart)352cdf0e10cSrcweir void Outliner::SetParaIsNumberingRestart( sal_uInt16 nPara, sal_Bool bParaIsNumberingRestart )
353cdf0e10cSrcweir {
354cdf0e10cSrcweir 	Paragraph* pPara = pParaList->GetParagraph( nPara );
355cdf0e10cSrcweir 	DBG_ASSERT( pPara, "Outliner::SetParaIsNumberingRestart - Paragraph not found!" );
356cdf0e10cSrcweir 	if( pPara && (pPara->IsParaIsNumberingRestart() != bParaIsNumberingRestart) )
357cdf0e10cSrcweir     {
358cdf0e10cSrcweir         if( IsUndoEnabled() && !IsInUndo() )
359cdf0e10cSrcweir             InsertUndo( new OutlinerUndoChangeParaNumberingRestart( this, nPara,
360cdf0e10cSrcweir                 pPara->GetNumberingStartValue(), pPara->GetNumberingStartValue(),
361cdf0e10cSrcweir                 pPara->IsParaIsNumberingRestart(), bParaIsNumberingRestart ) );
362cdf0e10cSrcweir 
363cdf0e10cSrcweir         pPara->SetParaIsNumberingRestart( bParaIsNumberingRestart );
364cdf0e10cSrcweir         // --> OD 2009-03-10 #i100014#
365cdf0e10cSrcweir         // It is not a good idea to substract 1 from a count and cast the result
366cdf0e10cSrcweir         // to sal_uInt16 without check, if the count is 0.
367cdf0e10cSrcweir         ImplCheckParagraphs( nPara, (sal_uInt16) (pParaList->GetParagraphCount()) );
368cdf0e10cSrcweir         // <--
369cdf0e10cSrcweir         pEditEngine->SetModified();
370cdf0e10cSrcweir     }
371cdf0e10cSrcweir }
372cdf0e10cSrcweir 
GetBulletsNumberingStatus(const sal_uInt16 nParaStart,const sal_uInt16 nParaEnd) const373*af89ca6eSOliver-Rainer Wittmann sal_Int16 Outliner::GetBulletsNumberingStatus(
374*af89ca6eSOliver-Rainer Wittmann     const sal_uInt16 nParaStart,
375*af89ca6eSOliver-Rainer Wittmann     const sal_uInt16 nParaEnd ) const
376766ce4d0SZheng Fan {
377*af89ca6eSOliver-Rainer Wittmann     if ( nParaStart > nParaEnd
378*af89ca6eSOliver-Rainer Wittmann          || nParaEnd >= pParaList->GetParagraphCount() )
379*af89ca6eSOliver-Rainer Wittmann     {
380*af89ca6eSOliver-Rainer Wittmann         DBG_ASSERT( false,"<Outliner::GetBulletsNumberingStatus> - unexpected parameter values" );
381*af89ca6eSOliver-Rainer Wittmann         return 2;
382*af89ca6eSOliver-Rainer Wittmann     }
383*af89ca6eSOliver-Rainer Wittmann 
384*af89ca6eSOliver-Rainer Wittmann     sal_uInt16 nBulletsCount = 0;
385*af89ca6eSOliver-Rainer Wittmann     sal_uInt16 nNumberingCount = 0;
386*af89ca6eSOliver-Rainer Wittmann     for (sal_uInt16 nPara = nParaStart; nPara <= nParaEnd; nPara++)
387*af89ca6eSOliver-Rainer Wittmann     {
388*af89ca6eSOliver-Rainer Wittmann         if ( !pParaList->GetParagraph(nPara) )
389*af89ca6eSOliver-Rainer Wittmann         {
390*af89ca6eSOliver-Rainer Wittmann             break;
391*af89ca6eSOliver-Rainer Wittmann         }
392*af89ca6eSOliver-Rainer Wittmann         const SvxNumberFormat* pFmt = GetNumberFormat(nPara);
393*af89ca6eSOliver-Rainer Wittmann         if (!pFmt)
394*af89ca6eSOliver-Rainer Wittmann         {
395*af89ca6eSOliver-Rainer Wittmann             // At least, exists one paragraph that has no Bullets/Numbering.
396*af89ca6eSOliver-Rainer Wittmann             break;
397*af89ca6eSOliver-Rainer Wittmann         }
398*af89ca6eSOliver-Rainer Wittmann         else if ((pFmt->GetNumberingType() == SVX_NUM_BITMAP) || (pFmt->GetNumberingType() == SVX_NUM_CHAR_SPECIAL))
399*af89ca6eSOliver-Rainer Wittmann         {
400*af89ca6eSOliver-Rainer Wittmann             // Having Bullets in this paragraph.
401*af89ca6eSOliver-Rainer Wittmann             nBulletsCount++;
402*af89ca6eSOliver-Rainer Wittmann         }
403*af89ca6eSOliver-Rainer Wittmann         else
404*af89ca6eSOliver-Rainer Wittmann         {
405*af89ca6eSOliver-Rainer Wittmann             // Having Numbering in this paragraph.
406*af89ca6eSOliver-Rainer Wittmann             nNumberingCount++;
407*af89ca6eSOliver-Rainer Wittmann         }
408*af89ca6eSOliver-Rainer Wittmann     }
409*af89ca6eSOliver-Rainer Wittmann 
410*af89ca6eSOliver-Rainer Wittmann     const sal_uInt16 nParaCount = nParaEnd - nParaStart + 1;
411*af89ca6eSOliver-Rainer Wittmann     if ( nBulletsCount == nParaCount )
412*af89ca6eSOliver-Rainer Wittmann     {
413*af89ca6eSOliver-Rainer Wittmann         return 0;
414*af89ca6eSOliver-Rainer Wittmann     }
415*af89ca6eSOliver-Rainer Wittmann     else if ( nNumberingCount == nParaCount )
416*af89ca6eSOliver-Rainer Wittmann     {
417*af89ca6eSOliver-Rainer Wittmann         return 1;
418*af89ca6eSOliver-Rainer Wittmann     }
419*af89ca6eSOliver-Rainer Wittmann     return 2;
420*af89ca6eSOliver-Rainer Wittmann }
421*af89ca6eSOliver-Rainer Wittmann 
GetBulletsNumberingStatus() const422*af89ca6eSOliver-Rainer Wittmann sal_Int16 Outliner::GetBulletsNumberingStatus() const
423*af89ca6eSOliver-Rainer Wittmann {
424*af89ca6eSOliver-Rainer Wittmann     return pParaList->GetParagraphCount() > 0
425*af89ca6eSOliver-Rainer Wittmann            ? GetBulletsNumberingStatus( 0, pParaList->GetParagraphCount()-1 )
426*af89ca6eSOliver-Rainer Wittmann            : 2;
427766ce4d0SZheng Fan }
428766ce4d0SZheng Fan 
CreateParaObject(sal_uInt16 nStartPara,sal_uInt16 nCount) const429cdf0e10cSrcweir OutlinerParaObject* Outliner::CreateParaObject( sal_uInt16 nStartPara, sal_uInt16 nCount ) const
430cdf0e10cSrcweir {
431cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
432cdf0e10cSrcweir 
433cdf0e10cSrcweir 	if ( sal::static_int_cast< sal_uLong >( nStartPara + nCount ) >
434cdf0e10cSrcweir          pParaList->GetParagraphCount() )
435cdf0e10cSrcweir 		nCount = sal::static_int_cast< sal_uInt16 >(
436cdf0e10cSrcweir             pParaList->GetParagraphCount() - nStartPara );
437cdf0e10cSrcweir 
438cdf0e10cSrcweir 	// When a new OutlinerParaObject is created because a paragraph is just beeing deleted,
439cdf0e10cSrcweir 	// it can happen that the ParaList is not updated yet...
440cdf0e10cSrcweir 	if ( ( nStartPara + nCount ) > pEditEngine->GetParagraphCount() )
441cdf0e10cSrcweir 		nCount = pEditEngine->GetParagraphCount() - nStartPara;
442cdf0e10cSrcweir 
443cdf0e10cSrcweir 	if( !nCount )
444cdf0e10cSrcweir 		return NULL;
445cdf0e10cSrcweir 
446cdf0e10cSrcweir     EditTextObject* pText = pEditEngine->CreateTextObject( nStartPara, nCount );
447cdf0e10cSrcweir     const bool bIsEditDoc(OUTLINERMODE_TEXTOBJECT == ImplGetOutlinerMode());
448cdf0e10cSrcweir     ParagraphDataVector aParagraphDataVector(nCount);
449cdf0e10cSrcweir 	const sal_uInt16 nLastPara(nStartPara + nCount - 1);
450cdf0e10cSrcweir 
451cdf0e10cSrcweir     for(sal_uInt16 nPara(nStartPara); nPara <= nLastPara; nPara++)
452cdf0e10cSrcweir     {
453cdf0e10cSrcweir         aParagraphDataVector[nPara-nStartPara] = *GetParagraph(nPara);
454cdf0e10cSrcweir     }
455cdf0e10cSrcweir 
456cdf0e10cSrcweir     OutlinerParaObject* pPObj = new OutlinerParaObject(*pText, aParagraphDataVector, bIsEditDoc);
457cdf0e10cSrcweir     pPObj->SetOutlinerMode(GetMode());
458cdf0e10cSrcweir     delete pText;
459cdf0e10cSrcweir 
460cdf0e10cSrcweir 	return pPObj;
461cdf0e10cSrcweir }
462cdf0e10cSrcweir 
SetText(const XubString & rText,Paragraph * pPara)463cdf0e10cSrcweir void Outliner::SetText( const XubString& rText, Paragraph* pPara )
464cdf0e10cSrcweir {
465cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
466cdf0e10cSrcweir 	DBG_ASSERT(pPara,"SetText:No Para");
467cdf0e10cSrcweir 
468cdf0e10cSrcweir 	sal_Bool bUpdate = pEditEngine->GetUpdateMode();
469cdf0e10cSrcweir 	pEditEngine->SetUpdateMode( sal_False );
470cdf0e10cSrcweir 	ImplBlockInsertionCallbacks( sal_True );
471cdf0e10cSrcweir 
472cdf0e10cSrcweir 	sal_uInt16 nPara = (sal_uInt16)pParaList->GetAbsPos( pPara );
473cdf0e10cSrcweir 
474cdf0e10cSrcweir 	if( !rText.Len() )
475cdf0e10cSrcweir 	{
476cdf0e10cSrcweir 		pEditEngine->SetText( nPara, rText );
477cdf0e10cSrcweir 		ImplInitDepth( nPara, pPara->GetDepth(), sal_False );
478cdf0e10cSrcweir 	}
479cdf0e10cSrcweir 	else
480cdf0e10cSrcweir 	{
481cdf0e10cSrcweir 		XubString aText( rText );
482cdf0e10cSrcweir 		aText.ConvertLineEnd( LINEEND_LF );
483cdf0e10cSrcweir 
484cdf0e10cSrcweir 		if( aText.GetChar( aText.Len()-1 ) == '\x0A' )
485cdf0e10cSrcweir 			aText.Erase( aText.Len()-1, 1 ); // letzten Umbruch loeschen
486cdf0e10cSrcweir 
487cdf0e10cSrcweir 		sal_uInt16 nCount = aText.GetTokenCount( '\x0A' );
488cdf0e10cSrcweir 		sal_uInt16 nPos = 0;
489cdf0e10cSrcweir 		sal_uInt16 nInsPos = nPara+1;
490cdf0e10cSrcweir 		while( nCount > nPos )
491cdf0e10cSrcweir 		{
492cdf0e10cSrcweir 			XubString aStr = aText.GetToken( nPos, '\x0A' );
493cdf0e10cSrcweir 
494cdf0e10cSrcweir 			sal_Int16 nCurDepth;
495cdf0e10cSrcweir 			if( nPos )
496cdf0e10cSrcweir 			{
497cdf0e10cSrcweir 				pPara = new Paragraph( -1 );
498cdf0e10cSrcweir 				nCurDepth = -1;
499cdf0e10cSrcweir 			}
500cdf0e10cSrcweir 			else
501cdf0e10cSrcweir 				nCurDepth = pPara->GetDepth();
502cdf0e10cSrcweir 
503cdf0e10cSrcweir 			// Im Outliner-Modus die Tabulatoren filtern und die
504cdf0e10cSrcweir 			// Einrueckung ueber ein LRSpaceItem einstellen
505cdf0e10cSrcweir 			// Im EditEngine-Modus ueber Maltes Tabulatoren einruecken
506cdf0e10cSrcweir 			if( ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT ) ||
507cdf0e10cSrcweir 				( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEVIEW ) )
508cdf0e10cSrcweir 			{
509cdf0e10cSrcweir 				// Tabs raus
510cdf0e10cSrcweir 				sal_uInt16 nTabs = 0;
511cdf0e10cSrcweir 				while ( ( nTabs < aStr.Len() ) && ( aStr.GetChar( nTabs ) == '\t' ) )
512cdf0e10cSrcweir 					nTabs++;
513cdf0e10cSrcweir 				if ( nTabs )
514cdf0e10cSrcweir 					aStr.Erase( 0, nTabs );
515cdf0e10cSrcweir 
516cdf0e10cSrcweir 				// Tiefe beibehalten ?  (siehe Outliner::Insert)
517cdf0e10cSrcweir 				if( !(pPara->nFlags & PARAFLAG_HOLDDEPTH) )
518cdf0e10cSrcweir 				{
519cdf0e10cSrcweir 					nCurDepth = nTabs-1;
520cdf0e10cSrcweir 					ImplCheckDepth( nCurDepth );
521cdf0e10cSrcweir 					pPara->SetDepth( nCurDepth );
522cdf0e10cSrcweir 					pPara->nFlags &= (~PARAFLAG_HOLDDEPTH);
523cdf0e10cSrcweir 				}
524cdf0e10cSrcweir 			}
525cdf0e10cSrcweir 			if( nPos ) // nicht mit dem ersten Absatz
526cdf0e10cSrcweir 			{
527cdf0e10cSrcweir 				pParaList->Insert( pPara, nInsPos );
528cdf0e10cSrcweir 				pEditEngine->InsertParagraph( nInsPos, aStr );
529cdf0e10cSrcweir 				pHdlParagraph = pPara;
530cdf0e10cSrcweir 				ParagraphInsertedHdl();
531cdf0e10cSrcweir 			}
532cdf0e10cSrcweir 			else
533cdf0e10cSrcweir 			{
534cdf0e10cSrcweir 				nInsPos--;
535cdf0e10cSrcweir 				pEditEngine->SetText( nInsPos, aStr );
536cdf0e10cSrcweir 			}
537cdf0e10cSrcweir 			ImplInitDepth( nInsPos, nCurDepth, sal_False );
538cdf0e10cSrcweir 			nInsPos++;
539cdf0e10cSrcweir 			nPos++;
540cdf0e10cSrcweir 		}
541cdf0e10cSrcweir 	}
542cdf0e10cSrcweir 
543cdf0e10cSrcweir 	DBG_ASSERT(pParaList->GetParagraphCount()==pEditEngine->GetParagraphCount(),"SetText failed!");
544cdf0e10cSrcweir 	bFirstParaIsEmpty = sal_False;
545cdf0e10cSrcweir 	ImplBlockInsertionCallbacks( sal_False );
546cdf0e10cSrcweir 	pEditEngine->SetUpdateMode( bUpdate );
547cdf0e10cSrcweir }
548cdf0e10cSrcweir 
549cdf0e10cSrcweir // pView == 0 -> Tabulatoren nicht beachten
550cdf0e10cSrcweir 
ImpConvertEdtToOut(sal_uInt32 nPara,EditView * pView)551cdf0e10cSrcweir bool Outliner::ImpConvertEdtToOut( sal_uInt32 nPara,EditView* pView)
552cdf0e10cSrcweir {
553cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
554cdf0e10cSrcweir 
555cdf0e10cSrcweir 	bool bConverted = false;
556cdf0e10cSrcweir 	sal_uInt16 nTabs = 0;
557cdf0e10cSrcweir 	ESelection aDelSel;
558cdf0e10cSrcweir 
559cdf0e10cSrcweir //	const SfxItemSet& rAttrs = pEditEngine->GetParaAttribs( (sal_uInt16)nPara );
560cdf0e10cSrcweir //	bool bAlreadyOutliner = rAttrs.GetItemState( EE_PARA_OUTLLRSPACE ) == SFX_ITEM_ON ? true : false;
561cdf0e10cSrcweir 
562cdf0e10cSrcweir 	XubString aName;
563cdf0e10cSrcweir 	XubString aHeading_US( RTL_CONSTASCII_USTRINGPARAM( "heading" ) );
564cdf0e10cSrcweir 	XubString aNumber_US( RTL_CONSTASCII_USTRINGPARAM( "Numbering" ) );
565cdf0e10cSrcweir 
566cdf0e10cSrcweir 	XubString aStr( pEditEngine->GetText( (sal_uInt16)nPara ) );
567cdf0e10cSrcweir 	xub_Unicode* pPtr = (xub_Unicode*)aStr.GetBuffer();
568cdf0e10cSrcweir 
569cdf0e10cSrcweir 	sal_uInt16 nHeadingNumberStart = 0;
570cdf0e10cSrcweir 	sal_uInt16 nNumberingNumberStart = 0;
571cdf0e10cSrcweir 	SfxStyleSheet* pStyle= pEditEngine->GetStyleSheet( (sal_uInt16)nPara );
572cdf0e10cSrcweir 	if( pStyle )
573cdf0e10cSrcweir 	{
574cdf0e10cSrcweir 		aName = pStyle->GetName();
575cdf0e10cSrcweir 		sal_uInt16 nSearch;
576cdf0e10cSrcweir 		if ( ( nSearch = aName.Search( aHeading_US ) ) != STRING_NOTFOUND )
577cdf0e10cSrcweir 			nHeadingNumberStart = nSearch + aHeading_US.Len();
578cdf0e10cSrcweir 		else if ( ( nSearch = aName.Search( aNumber_US ) ) != STRING_NOTFOUND )
579cdf0e10cSrcweir 			nNumberingNumberStart = nSearch + aNumber_US.Len();
580cdf0e10cSrcweir 	}
581cdf0e10cSrcweir 
582cdf0e10cSrcweir 	if ( nHeadingNumberStart || nNumberingNumberStart )
583cdf0e10cSrcweir 	{
584cdf0e10cSrcweir 		// PowerPoint-Import ?
585cdf0e10cSrcweir 		if( nHeadingNumberStart && ( aStr.Len() >= 2 ) &&
586cdf0e10cSrcweir 				( pPtr[0] != '\t' ) && ( pPtr[1] == '\t' ) )
587cdf0e10cSrcweir 		{
588cdf0e10cSrcweir 			// Bullet & Tab raus
589cdf0e10cSrcweir 			aDelSel = ESelection( (sal_uInt16)nPara, 0, (sal_uInt16)nPara, 2 );
590cdf0e10cSrcweir 		}
591cdf0e10cSrcweir 
592cdf0e10cSrcweir 		sal_uInt16 nPos = nHeadingNumberStart ? nHeadingNumberStart : nNumberingNumberStart;
593cdf0e10cSrcweir 		String aLevel = aName.Copy( nPos );
594cdf0e10cSrcweir 		aLevel.EraseLeadingChars( ' ' );
595cdf0e10cSrcweir 		nTabs = sal::static_int_cast< sal_uInt16 >(aLevel.ToInt32());
596cdf0e10cSrcweir 		if( nTabs )
597cdf0e10cSrcweir 			nTabs--; // ebene 0 = "heading 1"
598cdf0e10cSrcweir 		bConverted = sal_True;
599cdf0e10cSrcweir 	}
600cdf0e10cSrcweir 	else
601cdf0e10cSrcweir 	{
602cdf0e10cSrcweir 		//  Fuehrende Tabulatoren filtern
603cdf0e10cSrcweir 		while( *pPtr == '\t' )
604cdf0e10cSrcweir 		{
605cdf0e10cSrcweir 			pPtr++;
606cdf0e10cSrcweir 			nTabs++;
607cdf0e10cSrcweir 		}
608cdf0e10cSrcweir 		// Tabulatoren aus dem Text entfernen
609cdf0e10cSrcweir 		if( nTabs )
610cdf0e10cSrcweir 			aDelSel = ESelection( (sal_uInt16)nPara, 0, (sal_uInt16)nPara, nTabs );
611cdf0e10cSrcweir 	}
612cdf0e10cSrcweir 
613cdf0e10cSrcweir 	if ( aDelSel.HasRange() )
614cdf0e10cSrcweir 	{
615cdf0e10cSrcweir 		if ( pView )
616cdf0e10cSrcweir 		{
617cdf0e10cSrcweir 			pView->SetSelection( aDelSel );
618cdf0e10cSrcweir 			pView->DeleteSelected();
619cdf0e10cSrcweir 		}
620cdf0e10cSrcweir 		else
621cdf0e10cSrcweir 			pEditEngine->QuickDelete( aDelSel );
622cdf0e10cSrcweir 	}
623cdf0e10cSrcweir 
624cdf0e10cSrcweir     const SfxInt16Item& rLevel = (const SfxInt16Item&) pEditEngine->GetParaAttrib( sal::static_int_cast< sal_uInt16 >(nPara), EE_PARA_OUTLLEVEL );
625cdf0e10cSrcweir     sal_Int16 nOutlLevel = rLevel.GetValue();
626cdf0e10cSrcweir 
627cdf0e10cSrcweir     ImplCheckDepth( nOutlLevel );
628cdf0e10cSrcweir 	ImplInitDepth( sal::static_int_cast< sal_uInt16 >(nPara), nOutlLevel, sal_False );
629cdf0e10cSrcweir 
630cdf0e10cSrcweir 	return bConverted;
631cdf0e10cSrcweir }
632cdf0e10cSrcweir 
SetText(const OutlinerParaObject & rPObj)633cdf0e10cSrcweir void Outliner::SetText( const OutlinerParaObject& rPObj )
634cdf0e10cSrcweir {
635cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
636cdf0e10cSrcweir 
637cdf0e10cSrcweir 	sal_Bool bUpdate = pEditEngine->GetUpdateMode();
638cdf0e10cSrcweir 	pEditEngine->SetUpdateMode( sal_False );
639cdf0e10cSrcweir 
640cdf0e10cSrcweir 	sal_Bool bUndo = pEditEngine->IsUndoEnabled();
641cdf0e10cSrcweir 	EnableUndo( sal_False );
642cdf0e10cSrcweir 
643cdf0e10cSrcweir 	Init( rPObj.GetOutlinerMode() );
644cdf0e10cSrcweir 
645cdf0e10cSrcweir 	ImplBlockInsertionCallbacks( sal_True );
646cdf0e10cSrcweir 	pEditEngine->SetText(rPObj.GetTextObject());
647cdf0e10cSrcweir 	if( rPObj.Count() != pEditEngine->GetParagraphCount() )
648cdf0e10cSrcweir 	{
649cdf0e10cSrcweir 		int nop=0;nop++;
650cdf0e10cSrcweir 	}
651cdf0e10cSrcweir 
652cdf0e10cSrcweir 	bFirstParaIsEmpty = sal_False;
653cdf0e10cSrcweir 
654cdf0e10cSrcweir 	pParaList->Clear( sal_True );
655cdf0e10cSrcweir 	for( sal_uInt16 nCurPara = 0; nCurPara < rPObj.Count(); nCurPara++ )
656cdf0e10cSrcweir 	{
657cdf0e10cSrcweir 		Paragraph* pPara = new Paragraph( rPObj.GetParagraphData(nCurPara));
658cdf0e10cSrcweir         ImplCheckDepth( pPara->nDepth );
659cdf0e10cSrcweir 
660cdf0e10cSrcweir 		pParaList->Insert( pPara, LIST_APPEND );
661cdf0e10cSrcweir 		ImplCheckNumBulletItem( nCurPara );
662cdf0e10cSrcweir 	}
663cdf0e10cSrcweir 
664cdf0e10cSrcweir     // --> OD 2009-03-10 #i100014#
665cdf0e10cSrcweir     // It is not a good idea to substract 1 from a count and cast the result
666cdf0e10cSrcweir     // to sal_uInt16 without check, if the count is 0.
667cdf0e10cSrcweir     ImplCheckParagraphs( 0, (sal_uInt16) (pParaList->GetParagraphCount()) );
668cdf0e10cSrcweir     // <--
669cdf0e10cSrcweir 
670cdf0e10cSrcweir 	EnableUndo( bUndo );
671cdf0e10cSrcweir 	ImplBlockInsertionCallbacks( sal_False );
672cdf0e10cSrcweir 	pEditEngine->SetUpdateMode( bUpdate );
673cdf0e10cSrcweir 
674cdf0e10cSrcweir 	DBG_ASSERT( pParaList->GetParagraphCount()==rPObj.Count(),"SetText failed");
675cdf0e10cSrcweir 	DBG_ASSERT( pEditEngine->GetParagraphCount()==rPObj.Count(),"SetText failed");
676cdf0e10cSrcweir }
677cdf0e10cSrcweir 
AddText(const OutlinerParaObject & rPObj)678cdf0e10cSrcweir void Outliner::AddText( const OutlinerParaObject& rPObj )
679cdf0e10cSrcweir {
680cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
681cdf0e10cSrcweir 	Paragraph* pPara;
682cdf0e10cSrcweir 
683cdf0e10cSrcweir 	sal_Bool bUpdate = pEditEngine->GetUpdateMode();
684cdf0e10cSrcweir 	pEditEngine->SetUpdateMode( sal_False );
685cdf0e10cSrcweir 
686cdf0e10cSrcweir 	ImplBlockInsertionCallbacks( sal_True );
687cdf0e10cSrcweir 	sal_uLong nPara;
688cdf0e10cSrcweir 	if( bFirstParaIsEmpty )
689cdf0e10cSrcweir 	{
690cdf0e10cSrcweir 		pParaList->Clear( sal_True );
691cdf0e10cSrcweir 		pEditEngine->SetText(rPObj.GetTextObject());
692cdf0e10cSrcweir 		nPara = 0;
693cdf0e10cSrcweir 	}
694cdf0e10cSrcweir 	else
695cdf0e10cSrcweir 	{
696cdf0e10cSrcweir 		nPara = pParaList->GetParagraphCount();
697cdf0e10cSrcweir 		pEditEngine->InsertParagraph( EE_PARA_APPEND, rPObj.GetTextObject() );
698cdf0e10cSrcweir 	}
699cdf0e10cSrcweir 	bFirstParaIsEmpty = sal_False;
700cdf0e10cSrcweir 
701cdf0e10cSrcweir 	for( sal_uInt16 n = 0; n < rPObj.Count(); n++ )
702cdf0e10cSrcweir 	{
703cdf0e10cSrcweir 		pPara = new Paragraph( rPObj.GetParagraphData(n) );
704cdf0e10cSrcweir 		pParaList->Insert( pPara, LIST_APPEND );
705cdf0e10cSrcweir 		sal_uInt16 nP = sal::static_int_cast< sal_uInt16 >(nPara+n);
706cdf0e10cSrcweir 		DBG_ASSERT(pParaList->GetAbsPos(pPara)==nP,"AddText:Out of sync");
707cdf0e10cSrcweir 		ImplInitDepth( nP, pPara->GetDepth(), sal_False );
708cdf0e10cSrcweir 	}
709cdf0e10cSrcweir 	DBG_ASSERT( pEditEngine->GetParagraphCount()==pParaList->GetParagraphCount(), "SetText: OutOfSync" );
710cdf0e10cSrcweir 
711cdf0e10cSrcweir     // --> OD 2009-03-10 #i100014#
712cdf0e10cSrcweir     // It is not a good idea to substract 1 from a count and cast the result
713cdf0e10cSrcweir     // to sal_uInt16 without check, if the count is 0.
714cdf0e10cSrcweir     ImplCheckParagraphs( (sal_uInt16)nPara, (sal_uInt16) (pParaList->GetParagraphCount()) );
715cdf0e10cSrcweir     // <--
716cdf0e10cSrcweir 
717cdf0e10cSrcweir 	ImplBlockInsertionCallbacks( sal_False );
718cdf0e10cSrcweir 	pEditEngine->SetUpdateMode( bUpdate );
719cdf0e10cSrcweir }
720cdf0e10cSrcweir 
FieldClicked(const SvxFieldItem & rField,sal_uInt16 nPara,sal_uInt16 nPos)721cdf0e10cSrcweir void __EXPORT Outliner::FieldClicked( const SvxFieldItem& rField, sal_uInt16 nPara, sal_uInt16 nPos )
722cdf0e10cSrcweir {
723cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
724cdf0e10cSrcweir 
725cdf0e10cSrcweir 	if ( aFieldClickedHdl.IsSet() )
726cdf0e10cSrcweir 	{
727cdf0e10cSrcweir 		EditFieldInfo aFldInfo( this, rField, nPara, nPos );
728cdf0e10cSrcweir 		aFldInfo.SetSimpleClick( sal_True );
729cdf0e10cSrcweir 		aFieldClickedHdl.Call( &aFldInfo );
730cdf0e10cSrcweir 	}
731cdf0e10cSrcweir }
732cdf0e10cSrcweir 
733cdf0e10cSrcweir 
FieldSelected(const SvxFieldItem & rField,sal_uInt16 nPara,sal_uInt16 nPos)734cdf0e10cSrcweir void __EXPORT Outliner::FieldSelected( const SvxFieldItem& rField, sal_uInt16 nPara, sal_uInt16 nPos )
735cdf0e10cSrcweir {
736cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
737cdf0e10cSrcweir 	if ( !aFieldClickedHdl.IsSet() )
738cdf0e10cSrcweir 		return;
739cdf0e10cSrcweir 
740cdf0e10cSrcweir 	EditFieldInfo aFldInfo( this, rField, nPara, nPos );
741cdf0e10cSrcweir 	aFldInfo.SetSimpleClick( sal_False );
742cdf0e10cSrcweir 	aFieldClickedHdl.Call( &aFldInfo );
743cdf0e10cSrcweir }
744cdf0e10cSrcweir 
745cdf0e10cSrcweir 
CalcFieldValue(const SvxFieldItem & rField,sal_uInt16 nPara,sal_uInt16 nPos,Color * & rpTxtColor,Color * & rpFldColor)746cdf0e10cSrcweir XubString __EXPORT Outliner::CalcFieldValue( const SvxFieldItem& rField, sal_uInt16 nPara, sal_uInt16 nPos, Color*& rpTxtColor, Color*& rpFldColor )
747cdf0e10cSrcweir {
748cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
749cdf0e10cSrcweir 	if ( !aCalcFieldValueHdl.IsSet() )
750cdf0e10cSrcweir 		return String( ' ' );
751cdf0e10cSrcweir 
752cdf0e10cSrcweir 	EditFieldInfo aFldInfo( this, rField, nPara, nPos );
753cdf0e10cSrcweir 	// Die FldColor ist mit COL_LIGHTGRAY voreingestellt.
754cdf0e10cSrcweir 	if ( rpFldColor )
755cdf0e10cSrcweir 		aFldInfo.SetFldColor( *rpFldColor );
756cdf0e10cSrcweir 
757cdf0e10cSrcweir 	aCalcFieldValueHdl.Call( &aFldInfo );
758cdf0e10cSrcweir 	if ( aFldInfo.GetTxtColor() )
759cdf0e10cSrcweir 	{
760cdf0e10cSrcweir 		delete rpTxtColor;
761cdf0e10cSrcweir 		rpTxtColor = new Color( *aFldInfo.GetTxtColor() );
762cdf0e10cSrcweir 	}
763cdf0e10cSrcweir 
764cdf0e10cSrcweir 	delete rpFldColor;
765cdf0e10cSrcweir 	rpFldColor = aFldInfo.GetFldColor() ? new Color( *aFldInfo.GetFldColor() ) : 0;
766cdf0e10cSrcweir 
767cdf0e10cSrcweir 	return aFldInfo.GetRepresentation();
768cdf0e10cSrcweir }
769cdf0e10cSrcweir 
SetStyleSheet(sal_uLong nPara,SfxStyleSheet * pStyle)770cdf0e10cSrcweir void Outliner::SetStyleSheet( sal_uLong nPara, SfxStyleSheet* pStyle )
771cdf0e10cSrcweir {
772cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
773cdf0e10cSrcweir 	Paragraph* pPara = pParaList->GetParagraph( nPara );
774cdf0e10cSrcweir         if (pPara)
775cdf0e10cSrcweir         {
776cdf0e10cSrcweir             pEditEngine->SetStyleSheet( (sal_uInt16)nPara, pStyle );
777cdf0e10cSrcweir             pPara->nFlags |= PARAFLAG_SETBULLETTEXT;
778cdf0e10cSrcweir             ImplCheckNumBulletItem( (sal_uInt16) nPara );
779cdf0e10cSrcweir         }
780cdf0e10cSrcweir }
781cdf0e10cSrcweir 
SetVisible(Paragraph * pPara,sal_Bool bVisible)782cdf0e10cSrcweir void Outliner::SetVisible( Paragraph* pPara, sal_Bool bVisible )
783cdf0e10cSrcweir {
784cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
785cdf0e10cSrcweir 	DBG_ASSERT( pPara, "SetVisible: pPara = NULL" );
786cdf0e10cSrcweir 
787cdf0e10cSrcweir         if (pPara)
788cdf0e10cSrcweir         {
789cdf0e10cSrcweir             pPara->bVisible = bVisible;
790cdf0e10cSrcweir             sal_uLong nPara = pParaList->GetAbsPos( pPara );
791cdf0e10cSrcweir             pEditEngine->ShowParagraph( (sal_uInt16)nPara, bVisible );
792cdf0e10cSrcweir         }
793cdf0e10cSrcweir }
794cdf0e10cSrcweir 
ImplCheckNumBulletItem(sal_uInt16 nPara)795cdf0e10cSrcweir void Outliner::ImplCheckNumBulletItem( sal_uInt16 nPara )
796cdf0e10cSrcweir {
797cdf0e10cSrcweir 	Paragraph* pPara = pParaList->GetParagraph( nPara );
798cdf0e10cSrcweir         if (pPara)
799cdf0e10cSrcweir             pPara->aBulSize.Width() = -1;
800cdf0e10cSrcweir }
801cdf0e10cSrcweir 
ImplSetLevelDependendStyleSheet(sal_uInt16 nPara,SfxStyleSheet * pLevelStyle)802cdf0e10cSrcweir void Outliner::ImplSetLevelDependendStyleSheet( sal_uInt16 nPara, SfxStyleSheet* pLevelStyle )
803cdf0e10cSrcweir {
804cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
805cdf0e10cSrcweir 
806cdf0e10cSrcweir 	DBG_ASSERT( ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT ) || ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEVIEW ), "SetLevelDependendStyleSheet: Wrong Mode!" );
807cdf0e10cSrcweir 
808cdf0e10cSrcweir     SfxStyleSheet* pStyle = pLevelStyle;
809cdf0e10cSrcweir     if ( !pStyle )
810cdf0e10cSrcweir         pStyle = GetStyleSheet( nPara );
811cdf0e10cSrcweir 
812cdf0e10cSrcweir 	if ( pStyle )
813cdf0e10cSrcweir 	{
814cdf0e10cSrcweir 		sal_Int16 nDepth = GetDepth( nPara );
815cdf0e10cSrcweir 		if( nDepth < 0 )
816cdf0e10cSrcweir 			nDepth = 0;
817cdf0e10cSrcweir 
818cdf0e10cSrcweir 		String aNewStyleSheetName( pStyle->GetName() );
819cdf0e10cSrcweir 		aNewStyleSheetName.Erase( aNewStyleSheetName.Len()-1, 1 );
820cdf0e10cSrcweir 		aNewStyleSheetName += String::CreateFromInt32( nDepth+1 );
821cdf0e10cSrcweir 		SfxStyleSheet* pNewStyle = (SfxStyleSheet*)GetStyleSheetPool()->Find( aNewStyleSheetName, pStyle->GetFamily() );
822cdf0e10cSrcweir 		DBG_ASSERT( pNewStyle, "AutoStyleSheetName - Style not found!" );
823cdf0e10cSrcweir 		if ( pNewStyle && ( pNewStyle != GetStyleSheet( nPara ) ) )
824cdf0e10cSrcweir 		{
825cdf0e10cSrcweir  			SfxItemSet aOldAttrs( GetParaAttribs( nPara ) );
826cdf0e10cSrcweir 			SetStyleSheet( nPara, pNewStyle );
827cdf0e10cSrcweir 			if ( aOldAttrs.GetItemState( EE_PARA_NUMBULLET ) == SFX_ITEM_ON )
828cdf0e10cSrcweir 			{
829cdf0e10cSrcweir 				SfxItemSet aAttrs( GetParaAttribs( nPara ) );
830cdf0e10cSrcweir 				aAttrs.Put( aOldAttrs.Get( EE_PARA_NUMBULLET ) );
831cdf0e10cSrcweir 				SetParaAttribs( nPara, aAttrs );
832cdf0e10cSrcweir 			}
833cdf0e10cSrcweir 		}
834cdf0e10cSrcweir 	}
835cdf0e10cSrcweir }
836cdf0e10cSrcweir 
ImplInitDepth(sal_uInt16 nPara,sal_Int16 nDepth,sal_Bool bCreateUndo,sal_Bool bUndoAction)837cdf0e10cSrcweir void Outliner::ImplInitDepth( sal_uInt16 nPara, sal_Int16 nDepth, sal_Bool bCreateUndo, sal_Bool bUndoAction )
838cdf0e10cSrcweir {
839cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
840cdf0e10cSrcweir 
841cdf0e10cSrcweir     DBG_ASSERT( ( nDepth >= nMinDepth ) && ( nDepth <= nMaxDepth ), "ImplInitDepth - Depth is invalid!" );
842cdf0e10cSrcweir 
843cdf0e10cSrcweir 	Paragraph* pPara = pParaList->GetParagraph( nPara );
844cdf0e10cSrcweir         if (!pPara)
845cdf0e10cSrcweir             return;
846cdf0e10cSrcweir 	sal_Int16 nOldDepth = pPara->GetDepth();
847cdf0e10cSrcweir 	pPara->SetDepth( nDepth );
848cdf0e10cSrcweir 
849cdf0e10cSrcweir 	// Bei IsInUndo brauchen Attribute und Style nicht eingestellt werden,
850cdf0e10cSrcweir 	// dort werden die alten Werte durch die EditEngine restauriert.
851cdf0e10cSrcweir 
852cdf0e10cSrcweir 	if( !IsInUndo() )
853cdf0e10cSrcweir 	{
854cdf0e10cSrcweir 		sal_Bool bUpdate = pEditEngine->GetUpdateMode();
855cdf0e10cSrcweir 		pEditEngine->SetUpdateMode( sal_False );
856cdf0e10cSrcweir 
857cdf0e10cSrcweir 		sal_Bool bUndo = bCreateUndo && IsUndoEnabled();
858cdf0e10cSrcweir 		if ( bUndo && bUndoAction )
859cdf0e10cSrcweir 			UndoActionStart( OLUNDO_DEPTH );
860cdf0e10cSrcweir 
861cdf0e10cSrcweir 		SfxItemSet aAttrs( pEditEngine->GetParaAttribs( nPara ) );
862cdf0e10cSrcweir 		aAttrs.Put( SfxInt16Item( EE_PARA_OUTLLEVEL, nDepth ) );
863cdf0e10cSrcweir 		pEditEngine->SetParaAttribs( nPara, aAttrs );
864cdf0e10cSrcweir 		ImplCheckNumBulletItem( nPara );
865cdf0e10cSrcweir 		ImplCalcBulletText( nPara, sal_False, sal_False );
866cdf0e10cSrcweir 
867cdf0e10cSrcweir 		if ( bUndo )
868cdf0e10cSrcweir 		{
869cdf0e10cSrcweir 			InsertUndo( new OutlinerUndoChangeDepth( this, nPara, nOldDepth, nDepth ) );
870cdf0e10cSrcweir 			if ( bUndoAction )
871cdf0e10cSrcweir 				UndoActionEnd( OLUNDO_DEPTH );
872cdf0e10cSrcweir 		}
873cdf0e10cSrcweir 
874cdf0e10cSrcweir 		pEditEngine->SetUpdateMode( bUpdate );
875cdf0e10cSrcweir 	}
876cdf0e10cSrcweir }
877cdf0e10cSrcweir 
SetParaAttribs(sal_uInt16 nPara,const SfxItemSet & rSet)878cdf0e10cSrcweir void Outliner::SetParaAttribs( sal_uInt16 nPara, const SfxItemSet& rSet )
879cdf0e10cSrcweir {
880cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
881cdf0e10cSrcweir 
882cdf0e10cSrcweir     pEditEngine->SetParaAttribs( nPara, rSet );
883cdf0e10cSrcweir }
884cdf0e10cSrcweir 
Expand(Paragraph * pPara)885cdf0e10cSrcweir sal_Bool Outliner::Expand( Paragraph* pPara )
886cdf0e10cSrcweir {
887cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
888cdf0e10cSrcweir 
889cdf0e10cSrcweir 	if ( pParaList->HasHiddenChilds( pPara ) )
890cdf0e10cSrcweir 	{
891cdf0e10cSrcweir 		OLUndoExpand* pUndo = 0;
892cdf0e10cSrcweir 		sal_Bool bUndo = IsUndoEnabled() && !IsInUndo();
893cdf0e10cSrcweir 		if( bUndo )
894cdf0e10cSrcweir 		{
895cdf0e10cSrcweir 			UndoActionStart( OLUNDO_EXPAND );
896cdf0e10cSrcweir 			pUndo = new OLUndoExpand( this, OLUNDO_EXPAND );
897cdf0e10cSrcweir 			pUndo->pParas = 0;
898cdf0e10cSrcweir 			pUndo->nCount = (sal_uInt16)pParaList->GetAbsPos( pPara );
899cdf0e10cSrcweir 		}
900cdf0e10cSrcweir 		pHdlParagraph = pPara;
901cdf0e10cSrcweir 		bIsExpanding = sal_True;
902cdf0e10cSrcweir 		pParaList->Expand( pPara );
903cdf0e10cSrcweir 		ExpandHdl();
904cdf0e10cSrcweir 		InvalidateBullet( pPara, pParaList->GetAbsPos(pPara) );
905cdf0e10cSrcweir 		if( bUndo )
906cdf0e10cSrcweir 		{
907cdf0e10cSrcweir 			InsertUndo( pUndo );
908cdf0e10cSrcweir 			UndoActionEnd( OLUNDO_EXPAND );
909cdf0e10cSrcweir 		}
910cdf0e10cSrcweir 		return sal_True;
911cdf0e10cSrcweir 	}
912cdf0e10cSrcweir 	return sal_False;
913cdf0e10cSrcweir }
914cdf0e10cSrcweir 
915cdf0e10cSrcweir 
Collapse(Paragraph * pPara)916cdf0e10cSrcweir sal_Bool Outliner::Collapse( Paragraph* pPara )
917cdf0e10cSrcweir {
918cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
919cdf0e10cSrcweir 	if ( pParaList->HasVisibleChilds( pPara ) )	// expandiert
920cdf0e10cSrcweir 	{
921cdf0e10cSrcweir 		OLUndoExpand* pUndo = 0;
922cdf0e10cSrcweir 		sal_Bool bUndo = sal_False;
923cdf0e10cSrcweir 
924cdf0e10cSrcweir 		if( !IsInUndo() && IsUndoEnabled() )
925cdf0e10cSrcweir 			bUndo = sal_True;
926cdf0e10cSrcweir 		if( bUndo )
927cdf0e10cSrcweir 		{
928cdf0e10cSrcweir 			UndoActionStart( OLUNDO_COLLAPSE );
929cdf0e10cSrcweir 			pUndo = new OLUndoExpand( this, OLUNDO_COLLAPSE );
930cdf0e10cSrcweir 			pUndo->pParas = 0;
931cdf0e10cSrcweir 			pUndo->nCount = (sal_uInt16)pParaList->GetAbsPos( pPara );
932cdf0e10cSrcweir 		}
933cdf0e10cSrcweir 
934cdf0e10cSrcweir 		pHdlParagraph = pPara;
935cdf0e10cSrcweir 		bIsExpanding = sal_False;
936cdf0e10cSrcweir 		pParaList->Collapse( pPara );
937cdf0e10cSrcweir 		ExpandHdl();
938cdf0e10cSrcweir 		InvalidateBullet( pPara, pParaList->GetAbsPos(pPara) );
939cdf0e10cSrcweir 		if( bUndo )
940cdf0e10cSrcweir 		{
941cdf0e10cSrcweir 			InsertUndo( pUndo );
942cdf0e10cSrcweir 			UndoActionEnd( OLUNDO_COLLAPSE );
943cdf0e10cSrcweir 		}
944cdf0e10cSrcweir 		return sal_True;
945cdf0e10cSrcweir 	}
946cdf0e10cSrcweir 	return sal_False;
947cdf0e10cSrcweir }
948cdf0e10cSrcweir 
949cdf0e10cSrcweir 
ImpCalcBulletFont(sal_uInt16 nPara) const950cdf0e10cSrcweir Font Outliner::ImpCalcBulletFont( sal_uInt16 nPara ) const
951cdf0e10cSrcweir {
952cdf0e10cSrcweir     const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
953cdf0e10cSrcweir 	DBG_ASSERT( pFmt && ( pFmt->GetNumberingType() != SVX_NUM_BITMAP ) && ( pFmt->GetNumberingType() != SVX_NUM_NUMBER_NONE ), "ImpCalcBulletFont: Missing or BitmapBullet!" );
954cdf0e10cSrcweir 
955cdf0e10cSrcweir     Font aStdFont;  //#107508#
956cdf0e10cSrcweir     if ( !pEditEngine->IsFlatMode() )
957cdf0e10cSrcweir     {
958cdf0e10cSrcweir         ESelection aSel( nPara, 0, nPara, 0 );
959cdf0e10cSrcweir         aStdFont = EditEngine::CreateFontFromItemSet( pEditEngine->GetAttribs( aSel ), GetScriptType( aSel ) );
960cdf0e10cSrcweir     }
961cdf0e10cSrcweir     else
962cdf0e10cSrcweir     {
963cdf0e10cSrcweir         aStdFont = pEditEngine->GetStandardFont( nPara );
964cdf0e10cSrcweir     }
965cdf0e10cSrcweir 
966cdf0e10cSrcweir 	Font aBulletFont;
967cdf0e10cSrcweir 	if ( pFmt->GetNumberingType() == SVX_NUM_CHAR_SPECIAL )
968cdf0e10cSrcweir     {
969cdf0e10cSrcweir 		aBulletFont = *pFmt->GetBulletFont();
970cdf0e10cSrcweir     }
971cdf0e10cSrcweir 	else
972cdf0e10cSrcweir     {
973cdf0e10cSrcweir 		aBulletFont = aStdFont;
974cdf0e10cSrcweir         aBulletFont.SetUnderline( UNDERLINE_NONE );
975cdf0e10cSrcweir         aBulletFont.SetOverline( UNDERLINE_NONE );
976cdf0e10cSrcweir         aBulletFont.SetStrikeout( STRIKEOUT_NONE );
977cdf0e10cSrcweir         aBulletFont.SetEmphasisMark( EMPHASISMARK_NONE );
978cdf0e10cSrcweir         aBulletFont.SetRelief( RELIEF_NONE );
979cdf0e10cSrcweir     }
980cdf0e10cSrcweir 
981cdf0e10cSrcweir     // #107508# Use original scale...
982cdf0e10cSrcweir 	sal_uInt16 nScale = /* pEditEngine->IsFlatMode() ? DEFAULT_SCALE : */ pFmt->GetBulletRelSize();
983cdf0e10cSrcweir 	sal_uLong nScaledLineHeight = aStdFont.GetSize().Height();
984cdf0e10cSrcweir 	nScaledLineHeight *= nScale*10;
985cdf0e10cSrcweir 	nScaledLineHeight /= 1000;
986cdf0e10cSrcweir 
987cdf0e10cSrcweir     aBulletFont.SetAlign( ALIGN_BOTTOM );
988cdf0e10cSrcweir 	aBulletFont.SetSize( Size( 0, nScaledLineHeight ) );
989cdf0e10cSrcweir 	sal_Bool bVertical = IsVertical();
990cdf0e10cSrcweir     aBulletFont.SetVertical( bVertical );
991cdf0e10cSrcweir     aBulletFont.SetOrientation( bVertical ? 2700 : 0 );
992cdf0e10cSrcweir 
993cdf0e10cSrcweir 	Color aColor( COL_AUTO );
994cdf0e10cSrcweir 	if( !pEditEngine->IsFlatMode() && !( pEditEngine->GetControlWord() & EE_CNTRL_NOCOLORS ) )
995cdf0e10cSrcweir     {
996cdf0e10cSrcweir 		aColor = pFmt->GetBulletColor();
997cdf0e10cSrcweir     }
998cdf0e10cSrcweir 
999cdf0e10cSrcweir     if ( ( aColor == COL_AUTO ) || ( IsForceAutoColor() ) )
1000cdf0e10cSrcweir         aColor = pEditEngine->GetAutoColor();
1001cdf0e10cSrcweir 
1002cdf0e10cSrcweir     aBulletFont.SetColor( aColor );
1003cdf0e10cSrcweir 	return aBulletFont;
1004cdf0e10cSrcweir }
1005cdf0e10cSrcweir 
PaintBullet(sal_uInt16 nPara,const Point & rStartPos,const Point & rOrigin,short nOrientation,OutputDevice * pOutDev)1006cdf0e10cSrcweir void Outliner::PaintBullet( sal_uInt16 nPara, const Point& rStartPos,
1007cdf0e10cSrcweir 	const Point& rOrigin, short nOrientation, OutputDevice* pOutDev )
1008cdf0e10cSrcweir {
1009cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1010cdf0e10cSrcweir 
1011cdf0e10cSrcweir     bool bDrawBullet = false;
1012cdf0e10cSrcweir     if (pEditEngine)
1013cdf0e10cSrcweir     {
1014cdf0e10cSrcweir         const SfxBoolItem& rBulletState = (const SfxBoolItem&) pEditEngine->GetParaAttrib( nPara, EE_PARA_BULLETSTATE );
1015cdf0e10cSrcweir         bDrawBullet = rBulletState.GetValue() ? true : false;
1016cdf0e10cSrcweir     }
1017cdf0e10cSrcweir 
1018*af89ca6eSOliver-Rainer Wittmann     if ( ImplHasNumberFormat( nPara ) && bDrawBullet)
1019cdf0e10cSrcweir 	{
1020cdf0e10cSrcweir 		sal_Bool bVertical = IsVertical();
1021cdf0e10cSrcweir 
1022cdf0e10cSrcweir         sal_Bool bRightToLeftPara = pEditEngine->IsRightToLeft( nPara );
1023cdf0e10cSrcweir 
1024cdf0e10cSrcweir 		Rectangle aBulletArea( ImpCalcBulletArea( nPara, sal_True, sal_False ) );
1025cdf0e10cSrcweir 
1026cdf0e10cSrcweir         Paragraph* pPara = pParaList->GetParagraph( nPara );
1027cdf0e10cSrcweir         const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
1028cdf0e10cSrcweir 		if ( pFmt && ( pFmt->GetNumberingType() != SVX_NUM_NUMBER_NONE ) )
1029cdf0e10cSrcweir 		{
1030cdf0e10cSrcweir 			if( pFmt->GetNumberingType() != SVX_NUM_BITMAP )
1031cdf0e10cSrcweir 			{
1032cdf0e10cSrcweir 				Font aBulletFont( ImpCalcBulletFont( nPara ) );
1033cdf0e10cSrcweir                 // #2338# Use base line
1034cdf0e10cSrcweir                 sal_Bool bSymbol = pFmt->GetNumberingType() == SVX_NUM_CHAR_SPECIAL;
1035cdf0e10cSrcweir                 aBulletFont.SetAlign( bSymbol ? ALIGN_BOTTOM : ALIGN_BASELINE );
1036cdf0e10cSrcweir 				Font aOldFont = pOutDev->GetFont();
1037cdf0e10cSrcweir 				pOutDev->SetFont( aBulletFont );
1038cdf0e10cSrcweir 
1039cdf0e10cSrcweir                 ParagraphInfos 	aParaInfos = pEditEngine->GetParagraphInfos( nPara );
1040cdf0e10cSrcweir 				Point aTextPos;
1041cdf0e10cSrcweir 				if ( !bVertical )
1042cdf0e10cSrcweir                 {
1043cdf0e10cSrcweir //					aTextPos.Y() = rStartPos.Y() + aBulletArea.Bottom();
1044cdf0e10cSrcweir                     aTextPos.Y() = rStartPos.Y() + ( bSymbol ? aBulletArea.Bottom() : aParaInfos.nFirstLineMaxAscent );
1045cdf0e10cSrcweir                     if ( !bRightToLeftPara )
1046cdf0e10cSrcweir 					    aTextPos.X() = rStartPos.X() + aBulletArea.Left();
1047cdf0e10cSrcweir                     else
1048cdf0e10cSrcweir                         aTextPos.X() = rStartPos.X() + GetPaperSize().Width() - aBulletArea.Left();
1049cdf0e10cSrcweir                 }
1050cdf0e10cSrcweir 				else
1051cdf0e10cSrcweir 				{
1052cdf0e10cSrcweir //					aTextPos.X() = rStartPos.X() - aBulletArea.Bottom();
1053cdf0e10cSrcweir 					aTextPos.X() = rStartPos.X() - ( bSymbol ? aBulletArea.Bottom() : aParaInfos.nFirstLineMaxAscent );
1054cdf0e10cSrcweir 					aTextPos.Y() = rStartPos.Y() + aBulletArea.Left();
1055cdf0e10cSrcweir 				}
1056cdf0e10cSrcweir 
1057cdf0e10cSrcweir 				if ( nOrientation )
1058cdf0e10cSrcweir 				{
1059cdf0e10cSrcweir 					// Sowohl TopLeft als auch BottomLeft nicht ganz richtig, da
1060cdf0e10cSrcweir 					// in EditEngine BaseLine...
1061cdf0e10cSrcweir 					double nRealOrientation = nOrientation*F_PI1800;
1062cdf0e10cSrcweir 					double nCos = cos( nRealOrientation );
1063cdf0e10cSrcweir 					double nSin = sin( nRealOrientation );
1064cdf0e10cSrcweir 					Point aRotatedPos;
1065cdf0e10cSrcweir 					// Translation...
1066cdf0e10cSrcweir 					aTextPos -= rOrigin;
1067cdf0e10cSrcweir 					// Rotation...
1068cdf0e10cSrcweir 					aRotatedPos.X()=(long)   (nCos*aTextPos.X() + nSin*aTextPos.Y());
1069cdf0e10cSrcweir 					aRotatedPos.Y()=(long) - (nSin*aTextPos.X() - nCos*aTextPos.Y());
1070cdf0e10cSrcweir 					aTextPos = aRotatedPos;
1071cdf0e10cSrcweir 					// Translation...
1072cdf0e10cSrcweir 					aTextPos += rOrigin;
1073cdf0e10cSrcweir 					Font aRotatedFont( aBulletFont );
1074cdf0e10cSrcweir 					aRotatedFont.SetOrientation( nOrientation );
1075cdf0e10cSrcweir 					pOutDev->SetFont( aRotatedFont );
1076cdf0e10cSrcweir 				}
1077cdf0e10cSrcweir 
1078cdf0e10cSrcweir                 // #105803# VCL will care for brackets and so on...
1079cdf0e10cSrcweir                 sal_uLong nLayoutMode = pOutDev->GetLayoutMode();
1080cdf0e10cSrcweir                 nLayoutMode &= ~(TEXT_LAYOUT_BIDI_RTL|TEXT_LAYOUT_COMPLEX_DISABLED|TEXT_LAYOUT_BIDI_STRONG);
1081cdf0e10cSrcweir                 if ( bRightToLeftPara )
1082cdf0e10cSrcweir                     nLayoutMode |= TEXT_LAYOUT_BIDI_RTL;
1083cdf0e10cSrcweir                 pOutDev->SetLayoutMode( nLayoutMode );
1084cdf0e10cSrcweir 
1085cdf0e10cSrcweir                 if(bStrippingPortions)
1086cdf0e10cSrcweir                 {
1087cdf0e10cSrcweir 				    const Font aSvxFont(pOutDev->GetFont());
1088cdf0e10cSrcweir 				    sal_Int32* pBuf = new sal_Int32[ pPara->GetText().Len() ];
1089cdf0e10cSrcweir 				    pOutDev->GetTextArray( pPara->GetText(), pBuf );
1090cdf0e10cSrcweir 
1091cdf0e10cSrcweir                     if(bSymbol)
1092cdf0e10cSrcweir                     {
1093cdf0e10cSrcweir                 		// aTextPos is Bottom, go to Baseline
1094cdf0e10cSrcweir 			            FontMetric aMetric(pOutDev->GetFontMetric());
1095cdf0e10cSrcweir 			            aTextPos.Y() -= aMetric.GetDescent();
1096cdf0e10cSrcweir                     }
1097cdf0e10cSrcweir 
1098cdf0e10cSrcweir 				    DrawingText(aTextPos, pPara->GetText(), 0, pPara->GetText().Len(), pBuf,
1099cdf0e10cSrcweir                         aSvxFont, nPara, 0xFFFF, 0xFF, 0, 0, false, false, true, 0, Color(), Color());
1100cdf0e10cSrcweir 
1101cdf0e10cSrcweir                     delete[] pBuf;
1102cdf0e10cSrcweir                 }
1103cdf0e10cSrcweir                 else
1104cdf0e10cSrcweir                 {
1105cdf0e10cSrcweir 					pOutDev->DrawText( aTextPos, pPara->GetText() );
1106cdf0e10cSrcweir                 }
1107cdf0e10cSrcweir 
1108cdf0e10cSrcweir                 pOutDev->SetFont( aOldFont );
1109cdf0e10cSrcweir 			}
1110cdf0e10cSrcweir 			else
1111cdf0e10cSrcweir 			{
1112cdf0e10cSrcweir 				if ( pFmt->GetBrush()->GetGraphicObject() )
1113cdf0e10cSrcweir                 {
1114cdf0e10cSrcweir 			        Point aBulletPos;
1115cdf0e10cSrcweir                     if ( !bVertical )
1116cdf0e10cSrcweir                     {
1117cdf0e10cSrcweir 				        aBulletPos.Y() = rStartPos.Y() + aBulletArea.Top();
1118cdf0e10cSrcweir                         if ( !bRightToLeftPara )
1119cdf0e10cSrcweir 				            aBulletPos.X() = rStartPos.X() + aBulletArea.Left();
1120cdf0e10cSrcweir                         else
1121cdf0e10cSrcweir                             aBulletPos.X() = rStartPos.X() + GetPaperSize().Width() - aBulletArea.Right();
1122cdf0e10cSrcweir                     }
1123cdf0e10cSrcweir 			        else
1124cdf0e10cSrcweir 			        {
1125cdf0e10cSrcweir 				        aBulletPos.X() = rStartPos.X() - aBulletArea.Bottom();
1126cdf0e10cSrcweir 				        aBulletPos.Y() = rStartPos.Y() + aBulletArea.Left();
1127cdf0e10cSrcweir 			        }
1128cdf0e10cSrcweir 
1129cdf0e10cSrcweir                     if(bStrippingPortions)
1130cdf0e10cSrcweir                     {
1131cdf0e10cSrcweir                         if(aDrawBulletHdl.IsSet())
1132cdf0e10cSrcweir                         {
1133cdf0e10cSrcweir                             // call something analog to aDrawPortionHdl (if set) and feed it something
1134cdf0e10cSrcweir                             // analog to DrawPortionInfo...
1135cdf0e10cSrcweir                             // created aDrawBulletHdl, Set/GetDrawBulletHdl.
1136cdf0e10cSrcweir                             // created DrawBulletInfo and added handling to sdrtextdecomposition.cxx
1137cdf0e10cSrcweir                             DrawBulletInfo aDrawBulletInfo(
1138cdf0e10cSrcweir                                 *pFmt->GetBrush()->GetGraphicObject(),
1139cdf0e10cSrcweir                                 aBulletPos,
1140cdf0e10cSrcweir                                 pPara->aBulSize);
1141cdf0e10cSrcweir 
1142cdf0e10cSrcweir                             aDrawBulletHdl.Call(&aDrawBulletInfo);
1143cdf0e10cSrcweir                         }
1144cdf0e10cSrcweir                     }
1145cdf0e10cSrcweir                     else
1146cdf0e10cSrcweir                     {
1147cdf0e10cSrcweir                         // MT: Remove CAST when KA made the Draw-Method const
1148cdf0e10cSrcweir     					((GraphicObject*)pFmt->GetBrush()->GetGraphicObject())->Draw( pOutDev, aBulletPos, pPara->aBulSize );
1149cdf0e10cSrcweir                     }
1150cdf0e10cSrcweir                 }
1151cdf0e10cSrcweir 			}
1152cdf0e10cSrcweir 		}
1153cdf0e10cSrcweir 
1154cdf0e10cSrcweir 		// Bei zusammengeklappten Absaetzen einen Strich vor den Text malen.
1155cdf0e10cSrcweir 		if( pParaList->HasChilds(pPara) && !pParaList->HasVisibleChilds(pPara) &&
1156cdf0e10cSrcweir 				!bStrippingPortions && !nOrientation )
1157cdf0e10cSrcweir 		{
1158cdf0e10cSrcweir             long nWidth = pOutDev->PixelToLogic( Size( 10, 0 ) ).Width();
1159cdf0e10cSrcweir 
1160cdf0e10cSrcweir             Point aStartPos, aEndPos;
1161cdf0e10cSrcweir 			if ( !bVertical )
1162cdf0e10cSrcweir             {
1163cdf0e10cSrcweir 				aStartPos.Y() = rStartPos.Y() + aBulletArea.Bottom();
1164cdf0e10cSrcweir                 if ( !bRightToLeftPara )
1165cdf0e10cSrcweir 				    aStartPos.X() = rStartPos.X() + aBulletArea.Right();
1166cdf0e10cSrcweir                 else
1167cdf0e10cSrcweir                     aStartPos.X() = rStartPos.X() + GetPaperSize().Width() - aBulletArea.Left();
1168cdf0e10cSrcweir                 aEndPos = aStartPos;
1169cdf0e10cSrcweir                 aEndPos.X() += nWidth;
1170cdf0e10cSrcweir             }
1171cdf0e10cSrcweir 			else
1172cdf0e10cSrcweir 			{
1173cdf0e10cSrcweir 				aStartPos.X() = rStartPos.X() - aBulletArea.Bottom();
1174cdf0e10cSrcweir 				aStartPos.Y() = rStartPos.Y() + aBulletArea.Right();
1175cdf0e10cSrcweir                 aEndPos = aStartPos;
1176cdf0e10cSrcweir                 aEndPos.Y() += nWidth;
1177cdf0e10cSrcweir 			}
1178cdf0e10cSrcweir 
1179cdf0e10cSrcweir 			const Color& rOldLineColor = pOutDev->GetLineColor();
1180cdf0e10cSrcweir 			pOutDev->SetLineColor( Color( COL_BLACK ) );
1181cdf0e10cSrcweir 			pOutDev->DrawLine( aStartPos, aEndPos );
1182cdf0e10cSrcweir 			pOutDev->SetLineColor( rOldLineColor );
1183cdf0e10cSrcweir 		}
1184cdf0e10cSrcweir 	}
1185cdf0e10cSrcweir }
1186cdf0e10cSrcweir 
InvalidateBullet(Paragraph *,sal_uLong nPara)1187cdf0e10cSrcweir void Outliner::InvalidateBullet( Paragraph* /*pPara*/, sal_uLong nPara )
1188cdf0e10cSrcweir {
1189cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1190cdf0e10cSrcweir 
1191cdf0e10cSrcweir 	long nLineHeight = (long)pEditEngine->GetLineHeight((sal_uInt16)nPara );
1192cdf0e10cSrcweir 	OutlinerView* pView = aViewList.First();
1193cdf0e10cSrcweir 	while( pView )
1194cdf0e10cSrcweir 	{
1195cdf0e10cSrcweir 		Point aPos( pView->pEditView->GetWindowPosTopLeft((sal_uInt16)nPara ) );
1196cdf0e10cSrcweir 		Rectangle aRect( pView->GetOutputArea() );
1197cdf0e10cSrcweir 		aRect.Right() = aPos.X();
1198cdf0e10cSrcweir 		aRect.Top() = aPos.Y();
1199cdf0e10cSrcweir 		aRect.Bottom() = aPos.Y();
1200cdf0e10cSrcweir 		aRect.Bottom() += nLineHeight;
1201cdf0e10cSrcweir 
1202cdf0e10cSrcweir 		pView->GetWindow()->Invalidate( aRect );
1203cdf0e10cSrcweir 		pView = aViewList.Next();
1204cdf0e10cSrcweir 	}
1205cdf0e10cSrcweir }
1206cdf0e10cSrcweir 
Read(SvStream & rInput,const String & rBaseURL,sal_uInt16 eFormat,SvKeyValueIterator * pHTTPHeaderAttrs)1207cdf0e10cSrcweir sal_uLong Outliner::Read( SvStream& rInput, const String& rBaseURL, sal_uInt16 eFormat, SvKeyValueIterator* pHTTPHeaderAttrs )
1208cdf0e10cSrcweir {
1209cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1210cdf0e10cSrcweir 
1211cdf0e10cSrcweir 	sal_Bool bOldUndo = pEditEngine->IsUndoEnabled();
1212cdf0e10cSrcweir 	EnableUndo( sal_False );
1213cdf0e10cSrcweir 
1214cdf0e10cSrcweir 	sal_Bool bUpdate = pEditEngine->GetUpdateMode();
1215cdf0e10cSrcweir 	pEditEngine->SetUpdateMode( sal_False );
1216cdf0e10cSrcweir 
1217cdf0e10cSrcweir 	Clear();
1218cdf0e10cSrcweir 
1219cdf0e10cSrcweir 	ImplBlockInsertionCallbacks( sal_True );
1220cdf0e10cSrcweir     sal_uLong nRet = pEditEngine->Read( rInput, rBaseURL, (EETextFormat)eFormat, pHTTPHeaderAttrs );
1221cdf0e10cSrcweir 
1222cdf0e10cSrcweir 	bFirstParaIsEmpty = sal_False;
1223cdf0e10cSrcweir 
1224cdf0e10cSrcweir 	sal_uInt16 nParas = pEditEngine->GetParagraphCount();
1225cdf0e10cSrcweir  	pParaList->Clear( sal_True );
1226cdf0e10cSrcweir 	sal_uInt16 n;
1227cdf0e10cSrcweir 	for ( n = 0; n < nParas; n++ )
1228cdf0e10cSrcweir 	{
1229cdf0e10cSrcweir 		Paragraph* pPara = new Paragraph( 0 );
1230cdf0e10cSrcweir 		pParaList->Insert( pPara, LIST_APPEND );
1231cdf0e10cSrcweir 
1232cdf0e10cSrcweir 		if ( eFormat == EE_FORMAT_BIN )
1233cdf0e10cSrcweir 		{
1234cdf0e10cSrcweir 			const SfxItemSet& rAttrs = pEditEngine->GetParaAttribs( n );
1235cdf0e10cSrcweir 			const SfxInt16Item& rLevel = (const SfxInt16Item&) rAttrs.Get( EE_PARA_OUTLLEVEL );
1236cdf0e10cSrcweir 			sal_Int16 nDepth = rLevel.GetValue();
1237cdf0e10cSrcweir 			ImplInitDepth( n, nDepth, sal_False );
1238cdf0e10cSrcweir 		}
1239cdf0e10cSrcweir 	}
1240cdf0e10cSrcweir 
1241cdf0e10cSrcweir 	if ( eFormat != EE_FORMAT_BIN )
1242cdf0e10cSrcweir 	{
1243cdf0e10cSrcweir 		ImpFilterIndents( 0, nParas-1 );
1244cdf0e10cSrcweir 	}
1245cdf0e10cSrcweir 
1246cdf0e10cSrcweir     ImplBlockInsertionCallbacks( sal_False );
1247cdf0e10cSrcweir 	pEditEngine->SetUpdateMode( bUpdate );
1248cdf0e10cSrcweir 	EnableUndo( bOldUndo );
1249cdf0e10cSrcweir 
1250cdf0e10cSrcweir 	return nRet;
1251cdf0e10cSrcweir }
1252cdf0e10cSrcweir 
1253cdf0e10cSrcweir 
ImpFilterIndents(sal_uLong nFirstPara,sal_uLong nLastPara)1254cdf0e10cSrcweir void Outliner::ImpFilterIndents( sal_uLong nFirstPara, sal_uLong nLastPara )
1255cdf0e10cSrcweir {
1256cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1257cdf0e10cSrcweir 
1258cdf0e10cSrcweir 	sal_Bool bUpdate = pEditEngine->GetUpdateMode();
1259cdf0e10cSrcweir 	pEditEngine->SetUpdateMode( sal_False );
1260cdf0e10cSrcweir 
1261cdf0e10cSrcweir 	Paragraph* pLastConverted = NULL;
1262cdf0e10cSrcweir 	for( sal_uLong nPara = nFirstPara; nPara <= nLastPara; nPara++ )
1263cdf0e10cSrcweir 	{
1264cdf0e10cSrcweir 		Paragraph* pPara = pParaList->GetParagraph( nPara );
1265cdf0e10cSrcweir                 if (pPara)
1266cdf0e10cSrcweir                 {
1267cdf0e10cSrcweir                     if( ImpConvertEdtToOut( nPara ) )
1268cdf0e10cSrcweir                     {
1269cdf0e10cSrcweir                             pLastConverted = pPara;
1270cdf0e10cSrcweir                     }
1271cdf0e10cSrcweir                     else if ( pLastConverted )
1272cdf0e10cSrcweir                     {
1273cdf0e10cSrcweir                             // Normale Absaetze unter der Ueberschrift anordnen...
1274cdf0e10cSrcweir                             pPara->SetDepth( pLastConverted->GetDepth() );
1275cdf0e10cSrcweir                     }
1276cdf0e10cSrcweir 
1277cdf0e10cSrcweir                     ImplInitDepth( (sal_uInt16)nPara, pPara->GetDepth(), sal_False );
1278cdf0e10cSrcweir 		}
1279cdf0e10cSrcweir 	}
1280cdf0e10cSrcweir 
1281cdf0e10cSrcweir 	pEditEngine->SetUpdateMode( bUpdate );
1282cdf0e10cSrcweir }
1283cdf0e10cSrcweir 
GetUndoManager()1284cdf0e10cSrcweir ::svl::IUndoManager& Outliner::GetUndoManager()
1285cdf0e10cSrcweir {
1286cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1287cdf0e10cSrcweir 	return pEditEngine->GetUndoManager();
1288cdf0e10cSrcweir }
1289cdf0e10cSrcweir 
SetUndoManager(::svl::IUndoManager * pNew)129069ffbee1SArmin Le Grand ::svl::IUndoManager* Outliner::SetUndoManager(::svl::IUndoManager* pNew)
129169ffbee1SArmin Le Grand {
129269ffbee1SArmin Le Grand 	DBG_CHKTHIS(Outliner,0);
129369ffbee1SArmin Le Grand 	return pEditEngine->SetUndoManager(pNew);
129469ffbee1SArmin Le Grand }
129569ffbee1SArmin Le Grand 
ImpTextPasted(sal_uLong nStartPara,sal_uInt16 nCount)1296cdf0e10cSrcweir void Outliner::ImpTextPasted( sal_uLong nStartPara, sal_uInt16 nCount )
1297cdf0e10cSrcweir {
1298cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1299cdf0e10cSrcweir 
1300cdf0e10cSrcweir 	sal_Bool bUpdate = pEditEngine->GetUpdateMode();
1301cdf0e10cSrcweir 	pEditEngine->SetUpdateMode( sal_False );
1302cdf0e10cSrcweir 
1303cdf0e10cSrcweir 	const sal_uLong nStart = nStartPara;
1304cdf0e10cSrcweir 
1305cdf0e10cSrcweir 	Paragraph* pPara = pParaList->GetParagraph( nStartPara );
1306cdf0e10cSrcweir //	Paragraph* pLastConverted = NULL;
1307cdf0e10cSrcweir //    bool bFirst = true;
1308cdf0e10cSrcweir 
1309cdf0e10cSrcweir 	while( nCount && pPara )
1310cdf0e10cSrcweir 	{
1311cdf0e10cSrcweir 		if( ImplGetOutlinerMode() != OUTLINERMODE_TEXTOBJECT )
1312cdf0e10cSrcweir 		{
1313cdf0e10cSrcweir             nDepthChangedHdlPrevDepth = pPara->GetDepth();
1314cdf0e10cSrcweir             mnDepthChangeHdlPrevFlags = pPara->nFlags;
1315cdf0e10cSrcweir 
1316cdf0e10cSrcweir 			ImpConvertEdtToOut( nStartPara );
1317cdf0e10cSrcweir 
1318cdf0e10cSrcweir             pHdlParagraph = pPara;
1319cdf0e10cSrcweir 
1320cdf0e10cSrcweir             if( nStartPara == nStart )
1321cdf0e10cSrcweir             {
1322cdf0e10cSrcweir                 // the existing paragraph has changed depth or flags
1323cdf0e10cSrcweir 				if( (pPara->GetDepth() != nDepthChangedHdlPrevDepth) || (pPara->nFlags != mnDepthChangeHdlPrevFlags) )
1324cdf0e10cSrcweir 					DepthChangedHdl();
1325cdf0e10cSrcweir             }
1326cdf0e10cSrcweir 		}
1327cdf0e10cSrcweir 		else // EditEngine-Modus
1328cdf0e10cSrcweir 		{
1329cdf0e10cSrcweir 			sal_Int16 nDepth = -1;
1330cdf0e10cSrcweir 			const SfxItemSet& rAttrs = pEditEngine->GetParaAttribs( (sal_uInt16)nStartPara );
1331cdf0e10cSrcweir 			if ( rAttrs.GetItemState( EE_PARA_OUTLLEVEL ) == SFX_ITEM_ON )
1332cdf0e10cSrcweir 			{
1333cdf0e10cSrcweir 				const SfxInt16Item& rLevel = (const SfxInt16Item&) rAttrs.Get( EE_PARA_OUTLLEVEL );
1334cdf0e10cSrcweir 				nDepth = rLevel.GetValue();
1335cdf0e10cSrcweir 			}
1336cdf0e10cSrcweir 			if ( nDepth != GetDepth( nStartPara ) )
1337cdf0e10cSrcweir 				ImplInitDepth( (sal_uInt16)nStartPara, nDepth, sal_False );
1338cdf0e10cSrcweir 		}
1339cdf0e10cSrcweir 
1340cdf0e10cSrcweir 		nCount--;
1341cdf0e10cSrcweir 		nStartPara++;
1342cdf0e10cSrcweir 		pPara = pParaList->GetParagraph( nStartPara );
1343cdf0e10cSrcweir 	}
1344cdf0e10cSrcweir 
1345cdf0e10cSrcweir 	pEditEngine->SetUpdateMode( bUpdate );
1346cdf0e10cSrcweir 
1347cdf0e10cSrcweir 	DBG_ASSERT(pParaList->GetParagraphCount()==pEditEngine->GetParagraphCount(),"ImpTextPasted failed");
1348cdf0e10cSrcweir }
1349cdf0e10cSrcweir 
IndentingPagesHdl(OutlinerView * pView)1350cdf0e10cSrcweir long Outliner::IndentingPagesHdl( OutlinerView* pView )
1351cdf0e10cSrcweir {
1352cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1353cdf0e10cSrcweir 	if( !aIndentingPagesHdl.IsSet() )
1354cdf0e10cSrcweir 		return 1;
1355cdf0e10cSrcweir 	return aIndentingPagesHdl.Call( pView );
1356cdf0e10cSrcweir }
1357cdf0e10cSrcweir 
ImpCanIndentSelectedPages(OutlinerView * pCurView)1358cdf0e10cSrcweir sal_Bool Outliner::ImpCanIndentSelectedPages( OutlinerView* pCurView )
1359cdf0e10cSrcweir {
1360cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1361cdf0e10cSrcweir 	// Die selektierten Seiten muessen vorher durch ImpCalcSelectedPages
1362cdf0e10cSrcweir 	// schon eingestellt sein
1363cdf0e10cSrcweir 
1364cdf0e10cSrcweir 	// Wenn der erste Absatz auf Ebene 0 liegt darf er auf keinen Fall
1365cdf0e10cSrcweir 	// eingerueckt werden, evtl folgen aber weitere auf Ebene 0.
1366cdf0e10cSrcweir 	if ( ( mnFirstSelPage == 0 ) && ( ImplGetOutlinerMode() != OUTLINERMODE_TEXTOBJECT ) )
1367cdf0e10cSrcweir 	{
1368cdf0e10cSrcweir 		if ( nDepthChangedHdlPrevDepth == 1 )	// ist die einzige Seite
1369cdf0e10cSrcweir 			return sal_False;
1370cdf0e10cSrcweir 		else
1371cdf0e10cSrcweir 			pCurView->ImpCalcSelectedPages( sal_False );	// ohne die erste
1372cdf0e10cSrcweir 	}
1373cdf0e10cSrcweir 	return (sal_Bool)IndentingPagesHdl( pCurView );
1374cdf0e10cSrcweir }
1375cdf0e10cSrcweir 
1376cdf0e10cSrcweir 
ImpCanDeleteSelectedPages(OutlinerView * pCurView)1377cdf0e10cSrcweir sal_Bool Outliner::ImpCanDeleteSelectedPages( OutlinerView* pCurView )
1378cdf0e10cSrcweir {
1379cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1380cdf0e10cSrcweir 	// Die selektierten Seiten muessen vorher durch ImpCalcSelectedPages
1381cdf0e10cSrcweir 	// schon eingestellt sein
1382cdf0e10cSrcweir 	return (sal_Bool)RemovingPagesHdl( pCurView );
1383cdf0e10cSrcweir }
1384cdf0e10cSrcweir 
Outliner(SfxItemPool * pPool,sal_uInt16 nMode)1385cdf0e10cSrcweir Outliner::Outliner( SfxItemPool* pPool, sal_uInt16 nMode )
1386cdf0e10cSrcweir : nMinDepth( -1 )
1387cdf0e10cSrcweir {
1388cdf0e10cSrcweir 	DBG_CTOR( Outliner, 0 );
1389cdf0e10cSrcweir 
1390cdf0e10cSrcweir 	bStrippingPortions 	= sal_False;
1391cdf0e10cSrcweir 	bPasting			= sal_False;
1392cdf0e10cSrcweir 
1393cdf0e10cSrcweir 	nFirstPage			= 1;
1394cdf0e10cSrcweir 	bBlockInsCallback	= sal_False;
1395cdf0e10cSrcweir 
1396cdf0e10cSrcweir 	nMaxDepth			= 9;
1397cdf0e10cSrcweir 
1398cdf0e10cSrcweir 	pParaList = new ParagraphList;
1399cdf0e10cSrcweir 	pParaList->SetVisibleStateChangedHdl( LINK( this, Outliner, ParaVisibleStateChangedHdl ) );
1400cdf0e10cSrcweir 	Paragraph* pPara = new Paragraph( 0 );
1401cdf0e10cSrcweir 	pParaList->Insert( pPara, LIST_APPEND );
1402cdf0e10cSrcweir 	bFirstParaIsEmpty = sal_True;
1403cdf0e10cSrcweir 
1404cdf0e10cSrcweir 	pEditEngine = new OutlinerEditEng( this, pPool );
1405cdf0e10cSrcweir     pEditEngine->SetBeginMovingParagraphsHdl( LINK( this, Outliner, BeginMovingParagraphsHdl ) );
1406cdf0e10cSrcweir     pEditEngine->SetEndMovingParagraphsHdl( LINK( this, Outliner, EndMovingParagraphsHdl ) );
1407cdf0e10cSrcweir     pEditEngine->SetBeginPasteOrDropHdl( LINK( this, Outliner, BeginPasteOrDropHdl ) );
1408cdf0e10cSrcweir     pEditEngine->SetEndPasteOrDropHdl( LINK( this, Outliner, EndPasteOrDropHdl ) );
1409cdf0e10cSrcweir 
1410cdf0e10cSrcweir 	Init( nMode );
1411cdf0e10cSrcweir }
1412cdf0e10cSrcweir 
~Outliner()1413cdf0e10cSrcweir Outliner::~Outliner()
1414cdf0e10cSrcweir {
1415cdf0e10cSrcweir 	DBG_DTOR(Outliner,0);
1416cdf0e10cSrcweir 
1417cdf0e10cSrcweir 	pParaList->Clear( sal_True );
1418cdf0e10cSrcweir 	delete pParaList;
1419cdf0e10cSrcweir 	delete pEditEngine;
1420cdf0e10cSrcweir }
1421cdf0e10cSrcweir 
InsertView(OutlinerView * pView,sal_uLong nIndex)1422cdf0e10cSrcweir sal_uLong Outliner::InsertView( OutlinerView* pView, sal_uLong nIndex )
1423cdf0e10cSrcweir {
1424cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1425cdf0e10cSrcweir 
1426cdf0e10cSrcweir 	aViewList.Insert( pView, nIndex );
1427cdf0e10cSrcweir 	pEditEngine->InsertView(  pView->pEditView, (sal_uInt16)nIndex );
1428cdf0e10cSrcweir 	return aViewList.GetPos( pView );
1429cdf0e10cSrcweir }
1430cdf0e10cSrcweir 
RemoveView(OutlinerView * pView)1431cdf0e10cSrcweir OutlinerView* Outliner::RemoveView( OutlinerView* pView )
1432cdf0e10cSrcweir {
1433cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1434cdf0e10cSrcweir 
1435cdf0e10cSrcweir 	sal_uLong nPos = aViewList.GetPos( pView );
1436cdf0e10cSrcweir 	if ( nPos != LIST_ENTRY_NOTFOUND )
1437cdf0e10cSrcweir 	{
1438cdf0e10cSrcweir 		pView->pEditView->HideCursor(); // HACK wg. BugId 10006
1439cdf0e10cSrcweir 		pEditEngine->RemoveView(  pView->pEditView );
1440cdf0e10cSrcweir 		aViewList.Remove( nPos );
1441cdf0e10cSrcweir 	}
1442cdf0e10cSrcweir 	return NULL;	// MT: return ueberfluessig
1443cdf0e10cSrcweir }
1444cdf0e10cSrcweir 
RemoveView(sal_uLong nIndex)1445cdf0e10cSrcweir OutlinerView* Outliner::RemoveView( sal_uLong nIndex )
1446cdf0e10cSrcweir {
1447cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1448cdf0e10cSrcweir 
1449cdf0e10cSrcweir 	EditView* pEditView = pEditEngine->GetView( (sal_uInt16)nIndex );
1450cdf0e10cSrcweir 	pEditView->HideCursor(); // HACK wg. BugId 10006
1451cdf0e10cSrcweir 
1452cdf0e10cSrcweir 	pEditEngine->RemoveView( (sal_uInt16)nIndex );
1453cdf0e10cSrcweir 	aViewList.Remove( nIndex );
1454cdf0e10cSrcweir 	return NULL;	// MT: return ueberfluessig
1455cdf0e10cSrcweir }
1456cdf0e10cSrcweir 
1457cdf0e10cSrcweir 
GetView(sal_uLong nIndex) const1458cdf0e10cSrcweir OutlinerView* Outliner::GetView( sal_uLong nIndex ) const
1459cdf0e10cSrcweir {
1460cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1461cdf0e10cSrcweir 	return aViewList.GetObject( nIndex );
1462cdf0e10cSrcweir }
1463cdf0e10cSrcweir 
GetViewCount() const1464cdf0e10cSrcweir sal_uLong Outliner::GetViewCount() const
1465cdf0e10cSrcweir {
1466cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1467cdf0e10cSrcweir 	return aViewList.Count();
1468cdf0e10cSrcweir }
1469cdf0e10cSrcweir 
ParagraphInsertedHdl()1470cdf0e10cSrcweir void Outliner::ParagraphInsertedHdl()
1471cdf0e10cSrcweir {
1472cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1473cdf0e10cSrcweir 	if( !IsInUndo() )
1474cdf0e10cSrcweir 		aParaInsertedHdl.Call( this );
1475cdf0e10cSrcweir }
1476cdf0e10cSrcweir 
1477cdf0e10cSrcweir 
ParagraphRemovingHdl()1478cdf0e10cSrcweir void Outliner::ParagraphRemovingHdl()
1479cdf0e10cSrcweir {
1480cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1481cdf0e10cSrcweir 	if( !IsInUndo() )
1482cdf0e10cSrcweir 		aParaRemovingHdl.Call( this );
1483cdf0e10cSrcweir }
1484cdf0e10cSrcweir 
1485cdf0e10cSrcweir 
DepthChangedHdl()1486cdf0e10cSrcweir void Outliner::DepthChangedHdl()
1487cdf0e10cSrcweir {
1488cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1489cdf0e10cSrcweir 	if( !IsInUndo() )
1490cdf0e10cSrcweir 		aDepthChangedHdl.Call( this );
1491cdf0e10cSrcweir }
1492cdf0e10cSrcweir 
1493cdf0e10cSrcweir 
GetAbsPos(Paragraph * pPara)1494cdf0e10cSrcweir sal_uLong Outliner::GetAbsPos( Paragraph* pPara )
1495cdf0e10cSrcweir {
1496cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1497cdf0e10cSrcweir 	DBG_ASSERT(pPara,"GetAbsPos:No Para");
1498cdf0e10cSrcweir 	return pParaList->GetAbsPos( pPara );
1499cdf0e10cSrcweir }
1500cdf0e10cSrcweir 
GetParagraphCount() const1501cdf0e10cSrcweir sal_uLong Outliner::GetParagraphCount() const
1502cdf0e10cSrcweir {
1503cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1504cdf0e10cSrcweir 	return pParaList->GetParagraphCount();
1505cdf0e10cSrcweir }
1506cdf0e10cSrcweir 
GetParagraph(sal_uLong nAbsPos) const1507cdf0e10cSrcweir Paragraph* Outliner::GetParagraph( sal_uLong nAbsPos ) const
1508cdf0e10cSrcweir {
1509cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1510cdf0e10cSrcweir 	return pParaList->GetParagraph( nAbsPos );
1511cdf0e10cSrcweir }
1512cdf0e10cSrcweir 
HasChilds(Paragraph * pParagraph) const1513cdf0e10cSrcweir sal_Bool Outliner::HasChilds( Paragraph* pParagraph ) const
1514cdf0e10cSrcweir {
1515cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1516cdf0e10cSrcweir 	return pParaList->HasChilds( pParagraph );
1517cdf0e10cSrcweir }
1518cdf0e10cSrcweir 
ImplHasNumberFormat(sal_uInt16 nPara) const1519*af89ca6eSOliver-Rainer Wittmann bool Outliner::ImplHasNumberFormat( sal_uInt16 nPara ) const
1520cdf0e10cSrcweir {
1521cdf0e10cSrcweir     return GetNumberFormat(nPara) != 0;
1522cdf0e10cSrcweir 	if ( GetNumberFormat(nPara) )
1523cdf0e10cSrcweir 	{
1524cdf0e10cSrcweir 		const SfxBoolItem& rBulletState = (const SfxBoolItem&) pEditEngine->GetParaAttrib( nPara, EE_PARA_BULLETSTATE );
1525cdf0e10cSrcweir 		return rBulletState.GetValue();
1526cdf0e10cSrcweir 	}
1527cdf0e10cSrcweir 	else
1528cdf0e10cSrcweir 		return sal_False;
1529cdf0e10cSrcweir }
1530cdf0e10cSrcweir 
GetNumberFormat(sal_uInt16 nPara) const1531cdf0e10cSrcweir const SvxNumberFormat* Outliner::GetNumberFormat( sal_uInt16 nPara ) const
1532cdf0e10cSrcweir {
1533cdf0e10cSrcweir     const SvxNumberFormat* pFmt = NULL;
1534cdf0e10cSrcweir 
1535cdf0e10cSrcweir     Paragraph* pPara = pParaList->GetParagraph( nPara );
1536cdf0e10cSrcweir     if (pPara == NULL)
1537cdf0e10cSrcweir         return NULL;
1538cdf0e10cSrcweir 
1539cdf0e10cSrcweir     sal_Int16 nDepth = pPara? pPara->GetDepth() : -1;
1540cdf0e10cSrcweir 
1541cdf0e10cSrcweir     if( nDepth >= 0 )
1542cdf0e10cSrcweir     {
1543cdf0e10cSrcweir         const SvxNumBulletItem& rNumBullet = (const SvxNumBulletItem&) pEditEngine->GetParaAttrib( nPara, EE_PARA_NUMBULLET );
1544cdf0e10cSrcweir         if ( rNumBullet.GetNumRule()->GetLevelCount() > nDepth )
1545cdf0e10cSrcweir             pFmt = rNumBullet.GetNumRule()->Get( nDepth );
1546cdf0e10cSrcweir     }
1547cdf0e10cSrcweir 
1548cdf0e10cSrcweir     return pFmt;
1549cdf0e10cSrcweir }
1550cdf0e10cSrcweir 
ImplGetBulletSize(sal_uInt16 nPara)1551cdf0e10cSrcweir Size Outliner::ImplGetBulletSize( sal_uInt16 nPara )
1552cdf0e10cSrcweir {
1553cdf0e10cSrcweir 	Paragraph* pPara = pParaList->GetParagraph( nPara );
1554cdf0e10cSrcweir         if (!pPara)
1555cdf0e10cSrcweir             return Size();
1556cdf0e10cSrcweir 
1557cdf0e10cSrcweir 	if( pPara->aBulSize.Width() == -1 )
1558cdf0e10cSrcweir 	{
1559cdf0e10cSrcweir         const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
1560cdf0e10cSrcweir 		DBG_ASSERT( pFmt, "ImplGetBulletSize - no Bullet!" );
1561cdf0e10cSrcweir 
1562cdf0e10cSrcweir 		if ( pFmt->GetNumberingType() == SVX_NUM_NUMBER_NONE )
1563cdf0e10cSrcweir 		{
1564cdf0e10cSrcweir 			pPara->aBulSize = Size( 0, 0 );
1565cdf0e10cSrcweir 		}
1566cdf0e10cSrcweir 		else if( pFmt->GetNumberingType() != SVX_NUM_BITMAP )
1567cdf0e10cSrcweir 		{
1568cdf0e10cSrcweir 			String aBulletText = ImplGetBulletText( nPara );
1569cdf0e10cSrcweir 			OutputDevice* pRefDev = pEditEngine->GetRefDevice();
1570cdf0e10cSrcweir 			Font aBulletFont( ImpCalcBulletFont( nPara ) );
1571cdf0e10cSrcweir 			Font aRefFont( pRefDev->GetFont());
1572cdf0e10cSrcweir 			pRefDev->SetFont( aBulletFont );
1573cdf0e10cSrcweir 			pPara->aBulSize.Width() = pRefDev->GetTextWidth( aBulletText );
1574cdf0e10cSrcweir 			pPara->aBulSize.Height() = pRefDev->GetTextHeight();
1575cdf0e10cSrcweir 			pRefDev->SetFont( aRefFont );
1576cdf0e10cSrcweir 		}
1577cdf0e10cSrcweir 		else
1578cdf0e10cSrcweir 		{
1579cdf0e10cSrcweir 			pPara->aBulSize = OutputDevice::LogicToLogic( pFmt->GetGraphicSize(), MAP_100TH_MM, pEditEngine->GetRefDevice()->GetMapMode() );
1580cdf0e10cSrcweir 		}
1581cdf0e10cSrcweir 	}
1582cdf0e10cSrcweir 
1583cdf0e10cSrcweir 	return pPara->aBulSize;
1584cdf0e10cSrcweir }
1585cdf0e10cSrcweir 
ImplCheckParagraphs(sal_uInt16 nStart,sal_uInt16 nEnd)1586cdf0e10cSrcweir void Outliner::ImplCheckParagraphs( sal_uInt16 nStart, sal_uInt16 nEnd )
1587cdf0e10cSrcweir {
1588cdf0e10cSrcweir 	DBG_CHKTHIS( Outliner, 0 );
1589cdf0e10cSrcweir 
1590cdf0e10cSrcweir     // --> OD 2009-03-10 #i100014#
1591cdf0e10cSrcweir     // assure that the following for-loop does not loop forever
1592cdf0e10cSrcweir     for ( sal_uInt16 n = nStart; n < nEnd; n++ )
1593cdf0e10cSrcweir     // <--
1594cdf0e10cSrcweir 	{
1595cdf0e10cSrcweir 		Paragraph* pPara = pParaList->GetParagraph( n );
1596cdf0e10cSrcweir         if (pPara)
1597cdf0e10cSrcweir         {
1598cdf0e10cSrcweir             pPara->Invalidate();
1599cdf0e10cSrcweir             ImplCalcBulletText( n, sal_False, sal_False );
1600cdf0e10cSrcweir         }
1601cdf0e10cSrcweir 	}
1602cdf0e10cSrcweir }
1603cdf0e10cSrcweir 
SetRefDevice(OutputDevice * pRefDev)1604cdf0e10cSrcweir void Outliner::SetRefDevice( OutputDevice* pRefDev )
1605cdf0e10cSrcweir {
1606cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1607cdf0e10cSrcweir 	pEditEngine->SetRefDevice( pRefDev );
1608cdf0e10cSrcweir 	for ( sal_uInt16 n = (sal_uInt16) pParaList->GetParagraphCount(); n; )
1609cdf0e10cSrcweir 	{
1610cdf0e10cSrcweir 		Paragraph* pPara = pParaList->GetParagraph( --n );
1611cdf0e10cSrcweir 		pPara->Invalidate();
1612cdf0e10cSrcweir 	}
1613cdf0e10cSrcweir }
1614cdf0e10cSrcweir 
ParaAttribsChanged(sal_uInt16 nPara)1615cdf0e10cSrcweir void Outliner::ParaAttribsChanged( sal_uInt16 nPara )
1616cdf0e10cSrcweir {
1617cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1618cdf0e10cSrcweir 
1619cdf0e10cSrcweir 	// Der Outliner hat kein eigenes Undo, wenn Absaetz getrennt/verschmolzen werden.
1620cdf0e10cSrcweir 	// Beim ParagraphInserted ist das Attribut EE_PARA_OUTLLEVEL
1621cdf0e10cSrcweir 	// ggf. noch nicht eingestellt, dies wird aber benoetigt um die Tiefe
1622cdf0e10cSrcweir 	// des Absatzes zu bestimmen.
1623cdf0e10cSrcweir 
1624cdf0e10cSrcweir 	if( pEditEngine->IsInUndo() )
1625cdf0e10cSrcweir 	{
1626cdf0e10cSrcweir 		if ( pParaList->GetParagraphCount() == pEditEngine->GetParagraphCount() )
1627cdf0e10cSrcweir 		{
1628cdf0e10cSrcweir 			Paragraph* pPara = pParaList->GetParagraph( nPara );
1629cdf0e10cSrcweir 			const SfxInt16Item& rLevel = (const SfxInt16Item&) pEditEngine->GetParaAttrib( nPara, EE_PARA_OUTLLEVEL );
1630cdf0e10cSrcweir 			if ( pPara && pPara->GetDepth() != rLevel.GetValue() )
1631cdf0e10cSrcweir 			{
1632cdf0e10cSrcweir 				pPara->SetDepth( rLevel.GetValue() );
1633cdf0e10cSrcweir 				ImplCalcBulletText( nPara, sal_True, sal_True );
1634cdf0e10cSrcweir 			}
1635cdf0e10cSrcweir 		}
1636cdf0e10cSrcweir 	}
1637cdf0e10cSrcweir }
1638cdf0e10cSrcweir 
StyleSheetChanged(SfxStyleSheet * pStyle)1639cdf0e10cSrcweir void Outliner::StyleSheetChanged( SfxStyleSheet* pStyle )
1640cdf0e10cSrcweir {
1641cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1642cdf0e10cSrcweir 
1643cdf0e10cSrcweir 	// Die EditEngine ruft StyleSheetChanged auch fuer abgeleitete Styles.
1644cdf0e10cSrcweir 	// MT: Hier wurde frueher alle Absaetze durch ein ImpRecalcParaAttribs
1645cdf0e10cSrcweir 	// gejagt, die die besagte Vorlage haben, warum?
1646cdf0e10cSrcweir 	// => Eigentlich kann sich nur die Bullet-Repraesentation aendern...
1647cdf0e10cSrcweir 
1648cdf0e10cSrcweir 	sal_uInt16 nParas = (sal_uInt16)pParaList->GetParagraphCount();
1649cdf0e10cSrcweir 	for( sal_uInt16 nPara = 0; nPara < nParas; nPara++ )
1650cdf0e10cSrcweir 	{
1651cdf0e10cSrcweir 		if ( pEditEngine->GetStyleSheet( nPara ) == pStyle )
1652cdf0e10cSrcweir 		{
1653cdf0e10cSrcweir 			ImplCheckNumBulletItem( nPara );
1654cdf0e10cSrcweir 			ImplCalcBulletText( nPara, sal_False, sal_False );
1655cdf0e10cSrcweir             // #97333# EditEngine formats changed paragraphs before calling this method,
1656cdf0e10cSrcweir             // so they are not reformatted now and use wrong bullet indent
1657cdf0e10cSrcweir             pEditEngine->QuickMarkInvalid( ESelection( nPara, 0, nPara, 0 ) );
1658cdf0e10cSrcweir 		}
1659cdf0e10cSrcweir 	}
1660cdf0e10cSrcweir }
1661cdf0e10cSrcweir 
ImpCalcBulletArea(sal_uInt16 nPara,sal_Bool bAdjust,sal_Bool bReturnPaperPos)1662cdf0e10cSrcweir Rectangle Outliner::ImpCalcBulletArea( sal_uInt16 nPara, sal_Bool bAdjust, sal_Bool bReturnPaperPos )
1663cdf0e10cSrcweir {
1664cdf0e10cSrcweir 	// Bullet-Bereich innerhalb des Absatzes...
1665cdf0e10cSrcweir 	Rectangle aBulletArea;
1666cdf0e10cSrcweir 
1667cdf0e10cSrcweir     const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
1668cdf0e10cSrcweir 	if ( pFmt )
1669cdf0e10cSrcweir 	{
1670cdf0e10cSrcweir 		Point aTopLeft;
1671cdf0e10cSrcweir 		Size aBulletSize( ImplGetBulletSize( nPara ) );
1672cdf0e10cSrcweir 
1673cdf0e10cSrcweir         sal_Bool bOutlineMode = ( pEditEngine->GetControlWord() & EE_CNTRL_OUTLINER ) != 0;
1674cdf0e10cSrcweir 
1675cdf0e10cSrcweir         // the ODF attribut text:space-before which holds the spacing to add to the left of the label
1676cdf0e10cSrcweir         const short nSpaceBefore = pFmt->GetAbsLSpace() + pFmt->GetFirstLineOffset();
1677cdf0e10cSrcweir 
1678cdf0e10cSrcweir         const SvxLRSpaceItem& rLR = (const SvxLRSpaceItem&) pEditEngine->GetParaAttrib( nPara, bOutlineMode ? EE_PARA_OUTLLRSPACE : EE_PARA_LRSPACE );
1679cdf0e10cSrcweir         aTopLeft.X() = rLR.GetTxtLeft() + rLR.GetTxtFirstLineOfst() + nSpaceBefore;
1680cdf0e10cSrcweir 
1681cdf0e10cSrcweir 		long nBulletWidth = Max( (long) -rLR.GetTxtFirstLineOfst(), (long) ((-pFmt->GetFirstLineOffset()) + pFmt->GetCharTextDistance()) );
1682cdf0e10cSrcweir 		if ( nBulletWidth < aBulletSize.Width() ) 	// Bullet macht sich Platz
1683cdf0e10cSrcweir 			nBulletWidth = aBulletSize.Width();
1684cdf0e10cSrcweir 
1685cdf0e10cSrcweir 		if ( bAdjust && !bOutlineMode )
1686cdf0e10cSrcweir 		{
1687cdf0e10cSrcweir 			// Bei zentriert/rechtsbuendig anpassen
1688cdf0e10cSrcweir 			const SvxAdjustItem& rItem = (const SvxAdjustItem&)pEditEngine->GetParaAttrib( nPara, EE_PARA_JUST );
1689cdf0e10cSrcweir 			if ( ( !pEditEngine->IsRightToLeft( nPara ) && ( rItem.GetAdjust() != SVX_ADJUST_LEFT ) ) ||
1690cdf0e10cSrcweir 				 ( pEditEngine->IsRightToLeft( nPara ) && ( rItem.GetAdjust() != SVX_ADJUST_RIGHT ) ) )
1691cdf0e10cSrcweir 			{
1692cdf0e10cSrcweir 				aTopLeft.X() = pEditEngine->GetFirstLineStartX( nPara ) - nBulletWidth;
1693cdf0e10cSrcweir 			}
1694cdf0e10cSrcweir 		}
1695cdf0e10cSrcweir 
1696cdf0e10cSrcweir 		// Vertikal:
1697cdf0e10cSrcweir 		ParagraphInfos aInfos = pEditEngine->GetParagraphInfos( nPara );
1698cdf0e10cSrcweir 		if ( aInfos.bValid )
1699cdf0e10cSrcweir 		{
1700cdf0e10cSrcweir 			aTopLeft.Y() = /* aInfos.nFirstLineOffset + */ // #91076# nFirstLineOffset is already added to the StartPos (PaintBullet) from the EditEngine
1701cdf0e10cSrcweir 							aInfos.nFirstLineHeight - aInfos.nFirstLineTextHeight
1702cdf0e10cSrcweir 							+ aInfos.nFirstLineTextHeight / 2
1703cdf0e10cSrcweir 							- aBulletSize.Height() / 2;
1704cdf0e10cSrcweir 			// ggf. lieber auf der Baseline ausgeben...
1705cdf0e10cSrcweir 			if( ( pFmt->GetNumberingType() != SVX_NUM_NUMBER_NONE ) && ( pFmt->GetNumberingType() != SVX_NUM_BITMAP ) && ( pFmt->GetNumberingType() != SVX_NUM_CHAR_SPECIAL ) )
1706cdf0e10cSrcweir 			{
1707cdf0e10cSrcweir 				Font aBulletFont( ImpCalcBulletFont( nPara ) );
1708cdf0e10cSrcweir 				if ( aBulletFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL )
1709cdf0e10cSrcweir 				{
1710cdf0e10cSrcweir 					OutputDevice* pRefDev = pEditEngine->GetRefDevice();
1711cdf0e10cSrcweir 					Font aOldFont = pRefDev->GetFont();
1712cdf0e10cSrcweir 					pRefDev->SetFont( aBulletFont );
1713cdf0e10cSrcweir 					FontMetric aMetric( pRefDev->GetFontMetric() );
1714cdf0e10cSrcweir 					// Leading der ersten Zeile...
1715cdf0e10cSrcweir 					aTopLeft.Y() = /* aInfos.nFirstLineOffset + */ aInfos.nFirstLineMaxAscent;
1716cdf0e10cSrcweir 					aTopLeft.Y() -= aMetric.GetAscent();
1717cdf0e10cSrcweir 					pRefDev->SetFont( aOldFont );
1718cdf0e10cSrcweir 				}
1719cdf0e10cSrcweir 			}
1720cdf0e10cSrcweir 		}
1721cdf0e10cSrcweir 
1722cdf0e10cSrcweir 		// Horizontal:
1723cdf0e10cSrcweir 		if( pFmt->GetNumAdjust() == SVX_ADJUST_RIGHT )
1724cdf0e10cSrcweir 		{
1725cdf0e10cSrcweir 			aTopLeft.X() += nBulletWidth - aBulletSize.Width();
1726cdf0e10cSrcweir 		}
1727cdf0e10cSrcweir 		else if( pFmt->GetNumAdjust() == SVX_ADJUST_CENTER )
1728cdf0e10cSrcweir 		{
1729cdf0e10cSrcweir 			aTopLeft.X() += ( nBulletWidth - aBulletSize.Width() ) / 2;
1730cdf0e10cSrcweir 		}
1731cdf0e10cSrcweir 
1732cdf0e10cSrcweir 		if ( aTopLeft.X() < 0 ) 	// dann draengeln
1733cdf0e10cSrcweir 			aTopLeft.X() = 0;
1734cdf0e10cSrcweir 
1735cdf0e10cSrcweir 		aBulletArea = Rectangle( aTopLeft, aBulletSize );
1736cdf0e10cSrcweir 	}
1737cdf0e10cSrcweir     if ( bReturnPaperPos )
1738cdf0e10cSrcweir     {
1739cdf0e10cSrcweir         Size aBulletSize( aBulletArea.GetSize() );
1740cdf0e10cSrcweir         Point aBulletDocPos( aBulletArea.TopLeft() );
1741cdf0e10cSrcweir         aBulletDocPos.Y() += pEditEngine->GetDocPosTopLeft( nPara ).Y();
1742cdf0e10cSrcweir         Point aBulletPos( aBulletDocPos );
1743cdf0e10cSrcweir 
1744cdf0e10cSrcweir 	    if ( IsVertical() )
1745cdf0e10cSrcweir 	    {
1746cdf0e10cSrcweir             aBulletPos.Y() = aBulletDocPos.X();
1747cdf0e10cSrcweir             aBulletPos.X() = GetPaperSize().Width() - aBulletDocPos.Y();
1748cdf0e10cSrcweir             // Rotate:
1749cdf0e10cSrcweir             aBulletPos.X() -= aBulletSize.Height();
1750cdf0e10cSrcweir             Size aSz( aBulletSize );
1751cdf0e10cSrcweir             aBulletSize.Width() = aSz.Height();
1752cdf0e10cSrcweir             aBulletSize.Height() = aSz.Width();
1753cdf0e10cSrcweir 	    }
1754cdf0e10cSrcweir         else if ( pEditEngine->IsRightToLeft( nPara ) )
1755cdf0e10cSrcweir         {
1756cdf0e10cSrcweir             aBulletPos.X() = GetPaperSize().Width() - aBulletDocPos.X() - aBulletSize.Width();
1757cdf0e10cSrcweir         }
1758cdf0e10cSrcweir 
1759cdf0e10cSrcweir 		aBulletArea = Rectangle( aBulletPos, aBulletSize );
1760cdf0e10cSrcweir     }
1761cdf0e10cSrcweir 	return aBulletArea;
1762cdf0e10cSrcweir }
1763cdf0e10cSrcweir 
ExpandHdl()1764cdf0e10cSrcweir void Outliner::ExpandHdl()
1765cdf0e10cSrcweir {
1766cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1767cdf0e10cSrcweir 	aExpandHdl.Call( this );
1768*af89ca6eSOliver-Rainer Wittmann }
1769cdf0e10cSrcweir 
GetBulletInfo(sal_uInt16 nPara)1770cdf0e10cSrcweir EBulletInfo Outliner::GetBulletInfo( sal_uInt16 nPara )
1771cdf0e10cSrcweir {
1772cdf0e10cSrcweir     EBulletInfo aInfo;
1773cdf0e10cSrcweir 
1774cdf0e10cSrcweir     aInfo.nParagraph = nPara;
1775cdf0e10cSrcweir     aInfo.bVisible = ImplHasNumberFormat( nPara ) ? sal_True : sal_False;
1776cdf0e10cSrcweir 
1777cdf0e10cSrcweir     const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
1778cdf0e10cSrcweir     aInfo.nType = pFmt ? pFmt->GetNumberingType() : 0;
1779cdf0e10cSrcweir 
1780cdf0e10cSrcweir     if( pFmt )
1781cdf0e10cSrcweir     {
1782cdf0e10cSrcweir         if( pFmt->GetNumberingType() != SVX_NUM_BITMAP )
1783cdf0e10cSrcweir         {
1784cdf0e10cSrcweir             aInfo.aText = ImplGetBulletText( nPara );
1785cdf0e10cSrcweir 
1786cdf0e10cSrcweir             if( pFmt->GetBulletFont() )
1787cdf0e10cSrcweir                 aInfo.aFont = *pFmt->GetBulletFont();
1788cdf0e10cSrcweir         }
1789cdf0e10cSrcweir         else if ( pFmt->GetBrush()->GetGraphicObject() )
1790cdf0e10cSrcweir         {
1791cdf0e10cSrcweir             aInfo.aGraphic = pFmt->GetBrush()->GetGraphicObject()->GetGraphic();
1792cdf0e10cSrcweir         }
1793cdf0e10cSrcweir     }
1794cdf0e10cSrcweir 
1795cdf0e10cSrcweir     if ( aInfo.bVisible )
1796cdf0e10cSrcweir     {
1797cdf0e10cSrcweir         aInfo.aBounds = ImpCalcBulletArea( nPara, sal_True, sal_True );
1798cdf0e10cSrcweir     }
1799cdf0e10cSrcweir 
1800cdf0e10cSrcweir     return aInfo;
1801cdf0e10cSrcweir }
1802cdf0e10cSrcweir 
GetText(Paragraph * pParagraph,sal_uLong nCount) const1803cdf0e10cSrcweir XubString Outliner::GetText( Paragraph* pParagraph, sal_uLong nCount ) const
1804cdf0e10cSrcweir {
1805cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1806cdf0e10cSrcweir 
1807cdf0e10cSrcweir 	XubString aText;
1808cdf0e10cSrcweir 	sal_uInt16 nStartPara = (sal_uInt16) pParaList->GetAbsPos( pParagraph );
1809cdf0e10cSrcweir 	for ( sal_uInt16 n = 0; n < nCount; n++ )
1810cdf0e10cSrcweir 	{
1811cdf0e10cSrcweir 		aText += pEditEngine->GetText( nStartPara + n );
1812cdf0e10cSrcweir 		if ( (n+1) < (sal_uInt16)nCount )
1813cdf0e10cSrcweir 			aText += '\n';
1814cdf0e10cSrcweir 	}
1815cdf0e10cSrcweir 	return aText;
1816cdf0e10cSrcweir }
1817cdf0e10cSrcweir 
Remove(Paragraph * pPara,sal_uLong nParaCount)1818cdf0e10cSrcweir void Outliner::Remove( Paragraph* pPara, sal_uLong nParaCount )
1819cdf0e10cSrcweir {
1820cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1821cdf0e10cSrcweir 
1822cdf0e10cSrcweir 	sal_uLong nPos = pParaList->GetAbsPos( pPara );
1823cdf0e10cSrcweir 	if( !nPos && ( nParaCount >= pParaList->GetParagraphCount() ) )
1824cdf0e10cSrcweir 	{
1825cdf0e10cSrcweir 		Clear();
1826cdf0e10cSrcweir 	}
1827cdf0e10cSrcweir 	else
1828cdf0e10cSrcweir 	{
1829cdf0e10cSrcweir 		for( sal_uInt16 n = 0; n < (sal_uInt16)nParaCount; n++ )
1830cdf0e10cSrcweir 			pEditEngine->RemoveParagraph( (sal_uInt16) nPos );
1831cdf0e10cSrcweir 	}
1832cdf0e10cSrcweir }
1833cdf0e10cSrcweir 
StripPortions()1834cdf0e10cSrcweir void Outliner::StripPortions()
1835cdf0e10cSrcweir {
1836cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1837cdf0e10cSrcweir 	bStrippingPortions = sal_True;
1838cdf0e10cSrcweir 	pEditEngine->StripPortions();
1839cdf0e10cSrcweir 	bStrippingPortions = sal_False;
1840cdf0e10cSrcweir }
1841cdf0e10cSrcweir 
1842cdf0e10cSrcweir // #101498#
DrawingText(const Point & rStartPos,const XubString & rText,sal_uInt16 nTextStart,sal_uInt16 nTextLen,const sal_Int32 * pDXArray,const SvxFont & rFont,sal_uInt16 nPara,sal_uInt16 nIndex,sal_uInt8 nRightToLeft,const EEngineData::WrongSpellVector * pWrongSpellVector,const SvxFieldData * pFieldData,bool bEndOfLine,bool bEndOfParagraph,bool bEndOfBullet,const::com::sun::star::lang::Locale * pLocale,const Color & rOverlineColor,const Color & rTextLineColor)1843cdf0e10cSrcweir void Outliner::DrawingText( const Point& rStartPos, const XubString& rText, sal_uInt16 nTextStart, sal_uInt16 nTextLen, const sal_Int32* pDXArray,const SvxFont& rFont,
1844cdf0e10cSrcweir     sal_uInt16 nPara, sal_uInt16 nIndex, sal_uInt8 nRightToLeft,
1845cdf0e10cSrcweir     const EEngineData::WrongSpellVector* pWrongSpellVector,
1846cdf0e10cSrcweir     const SvxFieldData* pFieldData,
1847cdf0e10cSrcweir     bool bEndOfLine,
1848cdf0e10cSrcweir     bool bEndOfParagraph,
1849cdf0e10cSrcweir     bool bEndOfBullet,
1850cdf0e10cSrcweir     const ::com::sun::star::lang::Locale* pLocale,
1851cdf0e10cSrcweir     const Color& rOverlineColor,
1852cdf0e10cSrcweir     const Color& rTextLineColor)
1853cdf0e10cSrcweir {
1854cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1855cdf0e10cSrcweir 
1856cdf0e10cSrcweir 	if(aDrawPortionHdl.IsSet())
1857cdf0e10cSrcweir     {
1858cdf0e10cSrcweir 	    // #101498#
1859cdf0e10cSrcweir 	    DrawPortionInfo aInfo( rStartPos, rText, nTextStart, nTextLen, rFont, nPara, nIndex, pDXArray, pWrongSpellVector,
1860cdf0e10cSrcweir             pFieldData, pLocale, rOverlineColor, rTextLineColor, nRightToLeft, bEndOfLine, bEndOfParagraph, bEndOfBullet);
1861cdf0e10cSrcweir 
1862cdf0e10cSrcweir         aDrawPortionHdl.Call( &aInfo );
1863cdf0e10cSrcweir     }
1864cdf0e10cSrcweir }
1865cdf0e10cSrcweir 
RemovingPagesHdl(OutlinerView * pView)1866cdf0e10cSrcweir long Outliner::RemovingPagesHdl( OutlinerView* pView )
1867cdf0e10cSrcweir {
1868cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1869cdf0e10cSrcweir 	return aRemovingPagesHdl.IsSet() ? aRemovingPagesHdl.Call( pView ) : sal_True;
1870cdf0e10cSrcweir }
1871cdf0e10cSrcweir 
ImpCanDeleteSelectedPages(OutlinerView * pCurView,sal_uInt16 _nFirstPage,sal_uInt16 nPages)1872cdf0e10cSrcweir sal_Bool Outliner::ImpCanDeleteSelectedPages( OutlinerView* pCurView, sal_uInt16 _nFirstPage, sal_uInt16 nPages )
1873cdf0e10cSrcweir {
1874cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1875cdf0e10cSrcweir 
1876cdf0e10cSrcweir 	nDepthChangedHdlPrevDepth = nPages;
1877cdf0e10cSrcweir 	mnFirstSelPage = _nFirstPage;
1878cdf0e10cSrcweir 	pHdlParagraph = 0;
1879cdf0e10cSrcweir 	return (sal_Bool)RemovingPagesHdl( pCurView );
1880cdf0e10cSrcweir }
1881cdf0e10cSrcweir 
GetParaAttribs(sal_uInt16 nPara)1882cdf0e10cSrcweir SfxItemSet Outliner::GetParaAttribs( sal_uInt16 nPara )
1883cdf0e10cSrcweir {
1884cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1885cdf0e10cSrcweir 	return pEditEngine->GetParaAttribs( nPara );
1886cdf0e10cSrcweir }
1887cdf0e10cSrcweir 
IMPL_LINK(Outliner,ParaVisibleStateChangedHdl,Paragraph *,pPara)1888cdf0e10cSrcweir IMPL_LINK( Outliner, ParaVisibleStateChangedHdl, Paragraph*, pPara )
1889cdf0e10cSrcweir {
1890cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1891cdf0e10cSrcweir 
1892cdf0e10cSrcweir 	sal_uLong nPara = pParaList->GetAbsPos( pPara );
1893cdf0e10cSrcweir 	pEditEngine->ShowParagraph( (sal_uInt16)nPara, pPara->IsVisible() );
1894cdf0e10cSrcweir 
1895cdf0e10cSrcweir 	return 0;
1896cdf0e10cSrcweir }
1897cdf0e10cSrcweir 
IMPL_LINK(Outliner,BeginMovingParagraphsHdl,MoveParagraphsInfo *,EMPTYARG)1898cdf0e10cSrcweir IMPL_LINK( Outliner, BeginMovingParagraphsHdl, MoveParagraphsInfo*, EMPTYARG )
1899cdf0e10cSrcweir {
1900cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1901cdf0e10cSrcweir 
1902cdf0e10cSrcweir 	if( !IsInUndo() )
1903cdf0e10cSrcweir 		GetBeginMovingHdl().Call( this );
1904cdf0e10cSrcweir 
1905cdf0e10cSrcweir 	return 0;
1906cdf0e10cSrcweir }
1907cdf0e10cSrcweir 
IMPL_LINK(Outliner,BeginPasteOrDropHdl,PasteOrDropInfos *,pInfos)1908cdf0e10cSrcweir IMPL_LINK( Outliner, BeginPasteOrDropHdl, PasteOrDropInfos*, pInfos )
1909cdf0e10cSrcweir {
1910cdf0e10cSrcweir     UndoActionStart( EDITUNDO_DRAGANDDROP );
1911cdf0e10cSrcweir     maBeginPasteOrDropHdl.Call(pInfos);
1912cdf0e10cSrcweir 	return 0;
1913cdf0e10cSrcweir }
1914cdf0e10cSrcweir 
IMPL_LINK(Outliner,EndPasteOrDropHdl,PasteOrDropInfos *,pInfos)1915cdf0e10cSrcweir IMPL_LINK( Outliner, EndPasteOrDropHdl, PasteOrDropInfos*, pInfos )
1916cdf0e10cSrcweir {
1917cdf0e10cSrcweir 	bPasting = sal_False;
1918cdf0e10cSrcweir 	ImpTextPasted( pInfos->nStartPara, pInfos->nEndPara - pInfos->nStartPara + 1 );
1919cdf0e10cSrcweir     maEndPasteOrDropHdl.Call( pInfos );
1920cdf0e10cSrcweir 	UndoActionEnd( EDITUNDO_DRAGANDDROP );
1921cdf0e10cSrcweir 	return 0;
1922cdf0e10cSrcweir }
1923cdf0e10cSrcweir 
IMPL_LINK(Outliner,EndMovingParagraphsHdl,MoveParagraphsInfo *,pInfos)1924cdf0e10cSrcweir IMPL_LINK( Outliner, EndMovingParagraphsHdl, MoveParagraphsInfo*, pInfos )
1925cdf0e10cSrcweir {
1926cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
1927cdf0e10cSrcweir 
1928cdf0e10cSrcweir 	pParaList->MoveParagraphs( pInfos->nStartPara, pInfos->nDestPara, pInfos->nEndPara - pInfos->nStartPara + 1 );
1929cdf0e10cSrcweir 	sal_uInt16 nChangesStart = Min( pInfos->nStartPara, pInfos->nDestPara );
1930cdf0e10cSrcweir 	sal_uInt16 nParas = (sal_uInt16)pParaList->GetParagraphCount();
1931cdf0e10cSrcweir 	for ( sal_uInt16 n = nChangesStart; n < nParas; n++ )
1932cdf0e10cSrcweir 		ImplCalcBulletText( n, sal_False, sal_False );
1933cdf0e10cSrcweir 
1934cdf0e10cSrcweir 	if( !IsInUndo() )
1935cdf0e10cSrcweir 		aEndMovingHdl.Call( this );
1936cdf0e10cSrcweir 
1937cdf0e10cSrcweir     return 0;
1938cdf0e10cSrcweir }
1939cdf0e10cSrcweir 
isSameNumbering(const SvxNumberFormat & rN1,const SvxNumberFormat & rN2)1940cdf0e10cSrcweir static bool isSameNumbering( const SvxNumberFormat& rN1, const SvxNumberFormat& rN2 )
1941cdf0e10cSrcweir {
1942cdf0e10cSrcweir     if( rN1.GetNumberingType() != rN2.GetNumberingType() )
1943cdf0e10cSrcweir         return false;
1944cdf0e10cSrcweir 
1945cdf0e10cSrcweir     if( rN1.GetNumStr(1) != rN2.GetNumStr(1) )
1946cdf0e10cSrcweir         return false;
1947cdf0e10cSrcweir 
1948cdf0e10cSrcweir     if( (rN1.GetPrefix() != rN2.GetPrefix()) || (rN1.GetSuffix() != rN2.GetSuffix()) )
1949cdf0e10cSrcweir         return false;
1950cdf0e10cSrcweir 
1951cdf0e10cSrcweir     return true;
1952cdf0e10cSrcweir }
1953cdf0e10cSrcweir 
ImplGetNumbering(sal_uInt16 nPara,const SvxNumberFormat * pParaFmt)1954cdf0e10cSrcweir sal_uInt16 Outliner::ImplGetNumbering( sal_uInt16 nPara, const SvxNumberFormat* pParaFmt )
1955cdf0e10cSrcweir {
1956cdf0e10cSrcweir     sal_uInt16 nNumber = pParaFmt->GetStart() - 1;
1957cdf0e10cSrcweir 
1958cdf0e10cSrcweir 	Paragraph* pPara = pParaList->GetParagraph( nPara );
1959cdf0e10cSrcweir     const sal_Int16 nParaDepth = pPara->GetDepth();
1960cdf0e10cSrcweir 
1961cdf0e10cSrcweir     do
1962cdf0e10cSrcweir     {
1963cdf0e10cSrcweir         pPara = pParaList->GetParagraph( nPara );
1964cdf0e10cSrcweir         const sal_Int16 nDepth = pPara->GetDepth();
1965cdf0e10cSrcweir 
1966cdf0e10cSrcweir         // ignore paragraphs that are below our paragraph or have no numbering
1967cdf0e10cSrcweir         if( (nDepth > nParaDepth) || (nDepth == -1) )
1968cdf0e10cSrcweir             continue;
1969cdf0e10cSrcweir 
1970cdf0e10cSrcweir         // stop on paragraphs that are above our paragraph
1971cdf0e10cSrcweir         if( nDepth < nParaDepth )
19721fa2bb83SSun Ying             break;
19731fa2bb83SSun Ying 
1974cdf0e10cSrcweir         const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
1975cdf0e10cSrcweir 
19761fa2bb83SSun Ying         if( pFmt == 0 )
19771fa2bb83SSun Ying             continue; // ignore paragraphs without bullets
19781fa2bb83SSun Ying 
19791fa2bb83SSun Ying         // check if numbering less than or equal to pParaFmt
19801fa2bb83SSun Ying         if( !isSameNumbering( *pFmt, *pParaFmt ) || ( pFmt->GetStart() < pParaFmt->GetStart() ) )
19811fa2bb83SSun Ying             break;
1982cdf0e10cSrcweir 
1983cdf0e10cSrcweir         if (  pFmt->GetStart() > pParaFmt->GetStart() )
1984cdf0e10cSrcweir         {
1985cdf0e10cSrcweir            nNumber += pFmt->GetStart() - pParaFmt->GetStart();
1986cdf0e10cSrcweir            pParaFmt = pFmt;
1987cdf0e10cSrcweir         }
1988cdf0e10cSrcweir 
1989cdf0e10cSrcweir         const SfxBoolItem& rBulletState = (const SfxBoolItem&) pEditEngine->GetParaAttrib( nPara, EE_PARA_BULLETSTATE );
1990cdf0e10cSrcweir 
1991cdf0e10cSrcweir         if( rBulletState.GetValue() )
1992cdf0e10cSrcweir             nNumber += 1;
1993cdf0e10cSrcweir 
1994cdf0e10cSrcweir         // same depth, same number format, check for restart
1995cdf0e10cSrcweir         const sal_Int16 nNumberingStartValue = pPara->GetNumberingStartValue();
1996cdf0e10cSrcweir         if( (nNumberingStartValue != -1) || pPara->IsParaIsNumberingRestart() )
1997cdf0e10cSrcweir         {
1998cdf0e10cSrcweir             if( nNumberingStartValue != -1 )
1999cdf0e10cSrcweir                 nNumber += nNumberingStartValue - 1;
2000cdf0e10cSrcweir             break;
2001cdf0e10cSrcweir         }
2002cdf0e10cSrcweir     }
2003cdf0e10cSrcweir     while( nPara-- );
2004cdf0e10cSrcweir 
2005cdf0e10cSrcweir     return nNumber;
2006cdf0e10cSrcweir }
2007cdf0e10cSrcweir 
ImplCalcBulletText(sal_uInt16 nPara,sal_Bool bRecalcLevel,sal_Bool bRecalcChilds)2008cdf0e10cSrcweir void Outliner::ImplCalcBulletText( sal_uInt16 nPara, sal_Bool bRecalcLevel, sal_Bool bRecalcChilds )
2009cdf0e10cSrcweir {
2010cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
2011cdf0e10cSrcweir 
2012cdf0e10cSrcweir 	Paragraph* pPara = pParaList->GetParagraph( nPara );
2013cdf0e10cSrcweir 	sal_uInt16 nRelPos = 0xFFFF;
2014cdf0e10cSrcweir 
2015cdf0e10cSrcweir 	while ( pPara )
2016cdf0e10cSrcweir 	{
2017cdf0e10cSrcweir 		XubString aBulletText;
2018cdf0e10cSrcweir         const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
2019cdf0e10cSrcweir 		if( pFmt && ( pFmt->GetNumberingType() != SVX_NUM_BITMAP ) )
2020cdf0e10cSrcweir 		{
2021cdf0e10cSrcweir 			aBulletText += pFmt->GetPrefix();
2022cdf0e10cSrcweir 			if( pFmt->GetNumberingType() == SVX_NUM_CHAR_SPECIAL )
2023cdf0e10cSrcweir 			{
2024cdf0e10cSrcweir 				aBulletText += pFmt->GetBulletChar();
2025cdf0e10cSrcweir 			}
2026cdf0e10cSrcweir 			else if( pFmt->GetNumberingType() != SVX_NUM_NUMBER_NONE )
2027cdf0e10cSrcweir 			{
2028cdf0e10cSrcweir 				aBulletText += pFmt->GetNumStr( ImplGetNumbering( nPara, pFmt ) );
2029cdf0e10cSrcweir 			}
2030cdf0e10cSrcweir 			aBulletText += pFmt->GetSuffix();
2031cdf0e10cSrcweir 		}
2032cdf0e10cSrcweir 
2033cdf0e10cSrcweir 		if( aBulletText != pPara->GetText() )
2034cdf0e10cSrcweir 			pPara->SetText( aBulletText );
2035cdf0e10cSrcweir 
2036cdf0e10cSrcweir 		pPara->nFlags &= (~PARAFLAG_SETBULLETTEXT);
2037cdf0e10cSrcweir 
2038cdf0e10cSrcweir 		if ( bRecalcLevel )
2039cdf0e10cSrcweir 		{
2040cdf0e10cSrcweir 			if ( nRelPos != 0xFFFF )
2041cdf0e10cSrcweir 				nRelPos++;
2042cdf0e10cSrcweir 
2043cdf0e10cSrcweir 			sal_Int16 nDepth = pPara->GetDepth();
2044cdf0e10cSrcweir 			pPara = pParaList->GetParagraph( ++nPara );
2045cdf0e10cSrcweir 			if ( !bRecalcChilds )
2046cdf0e10cSrcweir 			{
2047cdf0e10cSrcweir 				while ( pPara && ( pPara->GetDepth() > nDepth ) )
2048cdf0e10cSrcweir 					pPara = pParaList->GetParagraph( ++nPara );
2049cdf0e10cSrcweir 			}
2050cdf0e10cSrcweir 
2051cdf0e10cSrcweir 			if ( pPara && ( pPara->GetDepth() < nDepth ) )
2052cdf0e10cSrcweir 				pPara = NULL;
2053cdf0e10cSrcweir 		}
2054cdf0e10cSrcweir 		else
2055cdf0e10cSrcweir 		{
2056cdf0e10cSrcweir 			pPara = NULL;
2057cdf0e10cSrcweir 		}
2058cdf0e10cSrcweir 	}
2059cdf0e10cSrcweir }
2060cdf0e10cSrcweir 
Clear()2061cdf0e10cSrcweir void Outliner::Clear()
2062cdf0e10cSrcweir {
2063cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
2064cdf0e10cSrcweir 
2065cdf0e10cSrcweir 	if( !bFirstParaIsEmpty )
2066cdf0e10cSrcweir 	{
2067cdf0e10cSrcweir 		ImplBlockInsertionCallbacks( sal_True );
2068cdf0e10cSrcweir 		pEditEngine->Clear();
2069cdf0e10cSrcweir 		pParaList->Clear( sal_True );
2070cdf0e10cSrcweir 		pParaList->Insert( new Paragraph( nMinDepth ), LIST_APPEND );
2071cdf0e10cSrcweir 		bFirstParaIsEmpty = sal_True;
2072cdf0e10cSrcweir 		ImplBlockInsertionCallbacks( sal_False );
2073cdf0e10cSrcweir 	}
2074cdf0e10cSrcweir 	else
2075cdf0e10cSrcweir 	{
2076cdf0e10cSrcweir             Paragraph* pPara = pParaList->GetParagraph( 0 );
2077cdf0e10cSrcweir             if(pPara)
2078cdf0e10cSrcweir                 pPara->SetDepth( nMinDepth );
2079cdf0e10cSrcweir 	}
2080cdf0e10cSrcweir }
2081cdf0e10cSrcweir 
SetFlatMode(sal_Bool bFlat)2082cdf0e10cSrcweir void Outliner::SetFlatMode( sal_Bool bFlat )
2083cdf0e10cSrcweir {
2084cdf0e10cSrcweir 	DBG_CHKTHIS(Outliner,0);
2085cdf0e10cSrcweir 
2086cdf0e10cSrcweir 	if( bFlat != pEditEngine->IsFlatMode() )
2087cdf0e10cSrcweir 	{
2088cdf0e10cSrcweir 		for ( sal_uInt16 nPara = (sal_uInt16)pParaList->GetParagraphCount(); nPara; )
2089cdf0e10cSrcweir 			pParaList->GetParagraph( --nPara )->aBulSize.Width() = -1;
2090cdf0e10cSrcweir 
2091cdf0e10cSrcweir 		pEditEngine->SetFlatMode( bFlat );
2092cdf0e10cSrcweir 	}
2093cdf0e10cSrcweir }
2094cdf0e10cSrcweir 
ImplGetBulletText(sal_uInt16 nPara)2095cdf0e10cSrcweir String Outliner::ImplGetBulletText( sal_uInt16 nPara )
2096cdf0e10cSrcweir {
2097cdf0e10cSrcweir         String aRes;
2098cdf0e10cSrcweir 	Paragraph* pPara = pParaList->GetParagraph( nPara );
2099cdf0e10cSrcweir         if (pPara)
2100cdf0e10cSrcweir         {
2101cdf0e10cSrcweir 	// MT: Optimierung mal wieder aktivieren...
2102cdf0e10cSrcweir //	if( pPara->nFlags & PARAFLAG_SETBULLETTEXT )
2103cdf0e10cSrcweir 		ImplCalcBulletText( nPara, sal_False, sal_False );
2104cdf0e10cSrcweir                 aRes = pPara->GetText();
2105cdf0e10cSrcweir         }
2106cdf0e10cSrcweir 	return aRes;
2107cdf0e10cSrcweir }
2108cdf0e10cSrcweir 
2109cdf0e10cSrcweir // this is needed for StarOffice Api
SetLevelDependendStyleSheet(sal_uInt16 nPara)2110cdf0e10cSrcweir void Outliner::SetLevelDependendStyleSheet( sal_uInt16 nPara )
2111cdf0e10cSrcweir {
2112cdf0e10cSrcweir 	SfxItemSet aOldAttrs( pEditEngine->GetParaAttribs( nPara ) );
2113cdf0e10cSrcweir 	ImplSetLevelDependendStyleSheet( nPara );
2114cdf0e10cSrcweir 	pEditEngine->SetParaAttribs( nPara, aOldAttrs );
2115cdf0e10cSrcweir }
2116cdf0e10cSrcweir 
2117cdf0e10cSrcweir SV_IMPL_PTRARR( NotifyList, EENotifyPtr );
2118cdf0e10cSrcweir 
ImplBlockInsertionCallbacks(sal_Bool b)2119cdf0e10cSrcweir void Outliner::ImplBlockInsertionCallbacks( sal_Bool b )
2120cdf0e10cSrcweir {
2121cdf0e10cSrcweir     if ( b )
2122cdf0e10cSrcweir     {
2123cdf0e10cSrcweir         bBlockInsCallback++;
2124cdf0e10cSrcweir     }
2125cdf0e10cSrcweir     else
2126cdf0e10cSrcweir     {
2127cdf0e10cSrcweir         DBG_ASSERT( bBlockInsCallback, "ImplBlockInsertionCallbacks ?!" );
2128cdf0e10cSrcweir         bBlockInsCallback--;
2129cdf0e10cSrcweir         if ( !bBlockInsCallback )
2130cdf0e10cSrcweir         {
2131cdf0e10cSrcweir             // Call blocked notify events...
2132cdf0e10cSrcweir             while ( pEditEngine->aNotifyCache.Count() )
2133cdf0e10cSrcweir             {
2134cdf0e10cSrcweir                 EENotify* pNotify = pEditEngine->aNotifyCache[0];
2135cdf0e10cSrcweir                 // Remove from list before calling, maybe we enter LeaveBlockNotifications while calling the handler...
2136cdf0e10cSrcweir                 pEditEngine->aNotifyCache.Remove( 0 );
2137cdf0e10cSrcweir                 pEditEngine->aOutlinerNotifyHdl.Call( pNotify );
2138cdf0e10cSrcweir                 delete pNotify;
2139cdf0e10cSrcweir             }
2140cdf0e10cSrcweir         }
2141cdf0e10cSrcweir     }
2142cdf0e10cSrcweir }
2143cdf0e10cSrcweir 
IMPL_LINK(Outliner,EditEngineNotifyHdl,EENotify *,pNotify)2144cdf0e10cSrcweir IMPL_LINK( Outliner, EditEngineNotifyHdl, EENotify*, pNotify )
2145cdf0e10cSrcweir {
2146cdf0e10cSrcweir     if ( !bBlockInsCallback )
2147cdf0e10cSrcweir     {
2148cdf0e10cSrcweir         pEditEngine->aOutlinerNotifyHdl.Call( pNotify );
2149cdf0e10cSrcweir     }
2150cdf0e10cSrcweir     else
2151cdf0e10cSrcweir     {
2152cdf0e10cSrcweir         EENotify* pNewNotify = new EENotify( *pNotify );
2153cdf0e10cSrcweir         pEditEngine->aNotifyCache.Insert( pNewNotify, pEditEngine->aNotifyCache.Count() );
2154cdf0e10cSrcweir     }
2155cdf0e10cSrcweir 
2156cdf0e10cSrcweir     return 0;
2157cdf0e10cSrcweir }
2158cdf0e10cSrcweir 
2159cdf0e10cSrcweir /** sets a link that is called at the beginning of a drag operation at an edit view */
SetBeginDropHdl(const Link & rLink)2160cdf0e10cSrcweir void Outliner::SetBeginDropHdl( const Link& rLink )
2161cdf0e10cSrcweir {
2162cdf0e10cSrcweir 	pEditEngine->SetBeginDropHdl( rLink );
2163cdf0e10cSrcweir }
2164cdf0e10cSrcweir 
GetBeginDropHdl() const2165cdf0e10cSrcweir Link Outliner::GetBeginDropHdl() const
2166cdf0e10cSrcweir {
2167cdf0e10cSrcweir 	return pEditEngine->GetBeginDropHdl();
2168cdf0e10cSrcweir }
2169cdf0e10cSrcweir 
2170cdf0e10cSrcweir /** sets a link that is called at the end of a drag operation at an edit view */
SetEndDropHdl(const Link & rLink)2171cdf0e10cSrcweir void Outliner::SetEndDropHdl( const Link& rLink )
2172cdf0e10cSrcweir {
2173cdf0e10cSrcweir 	pEditEngine->SetEndDropHdl( rLink );
2174cdf0e10cSrcweir }
2175cdf0e10cSrcweir 
GetEndDropHdl() const2176cdf0e10cSrcweir Link Outliner::GetEndDropHdl() const
2177cdf0e10cSrcweir {
2178cdf0e10cSrcweir 	return pEditEngine->GetEndDropHdl();
2179cdf0e10cSrcweir }
2180cdf0e10cSrcweir 
2181cdf0e10cSrcweir /** sets a link that is called before a drop or paste operation. */
SetBeginPasteOrDropHdl(const Link & rLink)2182cdf0e10cSrcweir void Outliner::SetBeginPasteOrDropHdl( const Link& rLink )
2183cdf0e10cSrcweir {
2184cdf0e10cSrcweir     maBeginPasteOrDropHdl = rLink;
2185cdf0e10cSrcweir }
2186cdf0e10cSrcweir 
2187cdf0e10cSrcweir /** sets a link that is called after a drop or paste operation. */
SetEndPasteOrDropHdl(const Link & rLink)2188cdf0e10cSrcweir void Outliner::SetEndPasteOrDropHdl( const Link& rLink )
2189cdf0e10cSrcweir {
2190cdf0e10cSrcweir     maEndPasteOrDropHdl = rLink;
2191cdf0e10cSrcweir }
2192cdf0e10cSrcweir 
SetParaFlag(Paragraph * pPara,sal_uInt16 nFlag)2193cdf0e10cSrcweir void Outliner::SetParaFlag( Paragraph* pPara,  sal_uInt16 nFlag )
2194cdf0e10cSrcweir {
2195cdf0e10cSrcweir     if( pPara && !pPara->HasFlag( nFlag ) )
2196cdf0e10cSrcweir     {
2197cdf0e10cSrcweir         if( IsUndoEnabled() && !IsInUndo() )
2198cdf0e10cSrcweir             InsertUndo( new OutlinerUndoChangeParaFlags( this, (sal_uInt16)GetAbsPos( pPara ), pPara->nFlags, pPara->nFlags|nFlag ) );
2199cdf0e10cSrcweir 
2200cdf0e10cSrcweir         pPara->SetFlag( nFlag );
2201cdf0e10cSrcweir     }
2202cdf0e10cSrcweir }
2203cdf0e10cSrcweir 
RemoveParaFlag(Paragraph * pPara,sal_uInt16 nFlag)2204cdf0e10cSrcweir void Outliner::RemoveParaFlag( Paragraph* pPara, sal_uInt16 nFlag )
2205cdf0e10cSrcweir {
2206cdf0e10cSrcweir     if( pPara && pPara->HasFlag( nFlag ) )
2207cdf0e10cSrcweir     {
2208cdf0e10cSrcweir         if( IsUndoEnabled() && !IsInUndo() )
2209cdf0e10cSrcweir             InsertUndo( new OutlinerUndoChangeParaFlags( this, (sal_uInt16)GetAbsPos( pPara ), pPara->nFlags, pPara->nFlags & ~nFlag ) );
2210cdf0e10cSrcweir 
2211cdf0e10cSrcweir         pPara->RemoveFlag( nFlag );
2212cdf0e10cSrcweir     }
2213cdf0e10cSrcweir }
2214cdf0e10cSrcweir 
HasParaFlag(const Paragraph * pPara,sal_uInt16 nFlag) const2215cdf0e10cSrcweir bool Outliner::HasParaFlag( const Paragraph* pPara, sal_uInt16 nFlag ) const
2216cdf0e10cSrcweir {
2217cdf0e10cSrcweir     return pPara && pPara->HasFlag( nFlag );
2218cdf0e10cSrcweir }
2219cdf0e10cSrcweir 
2220cdf0e10cSrcweir 
IsRTL() const2221cdf0e10cSrcweir sal_Bool DrawPortionInfo::IsRTL() const
2222cdf0e10cSrcweir {
2223cdf0e10cSrcweir 	if(0xFF == mnBiDiLevel)
2224cdf0e10cSrcweir 	{
2225cdf0e10cSrcweir         // Use Bidi functions from icu 2.0 to calculate if this portion
2226cdf0e10cSrcweir 		// is RTL or not.
2227cdf0e10cSrcweir         UErrorCode nError(U_ZERO_ERROR);
2228cdf0e10cSrcweir         UBiDi* pBidi = ubidi_openSized(mrText.Len(), 0, &nError);
2229cdf0e10cSrcweir         nError = U_ZERO_ERROR;
2230cdf0e10cSrcweir 
2231cdf0e10cSrcweir 		// I do not have this info here. Is it necessary? I'll have to ask MT.
2232cdf0e10cSrcweir 	    const sal_uInt8 nDefaultDir = UBIDI_LTR; //IsRightToLeft( nPara ) ? UBIDI_RTL : UBIDI_LTR;
2233cdf0e10cSrcweir 
2234cdf0e10cSrcweir 		ubidi_setPara(pBidi, reinterpret_cast<const UChar *>(mrText.GetBuffer()), mrText.Len(), nDefaultDir, NULL, &nError);	// UChar != sal_Unicode in MinGW
2235cdf0e10cSrcweir         nError = U_ZERO_ERROR;
2236cdf0e10cSrcweir 
2237cdf0e10cSrcweir //        sal_Int32 nCount(ubidi_countRuns(pBidi, &nError));
2238cdf0e10cSrcweir 
2239cdf0e10cSrcweir         int32_t nStart(0);
2240cdf0e10cSrcweir         int32_t nEnd;
2241cdf0e10cSrcweir         UBiDiLevel nCurrDir;
2242cdf0e10cSrcweir 
2243cdf0e10cSrcweir 		ubidi_getLogicalRun(pBidi, nStart, &nEnd, &nCurrDir);
2244cdf0e10cSrcweir 
2245cdf0e10cSrcweir         ubidi_close(pBidi);
2246cdf0e10cSrcweir 
2247cdf0e10cSrcweir 		// remember on-demand calculated state
2248 		((DrawPortionInfo*)this)->mnBiDiLevel = nCurrDir;
2249 	}
2250 
2251 	return (1 == (mnBiDiLevel % 2));
2252 }
2253 
2254 // eof
2255