1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_editeng.hxx"
30 
31 #include <outl_pch.hxx>
32 
33 #define _OUTLINER_CXX
34 #include <editeng/outliner.hxx>
35 #include <editeng/outlobj.hxx>
36 #include <outleeng.hxx>
37 #include <editeng/editobj.hxx>
38 #include <vcl/bitmap.hxx>
39 #include <tools/stream.hxx>
40 
41 //////////////////////////////////////////////////////////////////////////////
42 
43 class ImplOutlinerParaObject
44 {
45 public:
46     // data members
47     EditTextObject*                 mpEditTextObject;
48     ParagraphDataVector             maParagraphDataVector;
49     bool                            mbIsEditDoc;
50 
51     // refcounter
52 	sal_uInt32						mnRefCount;
53 
54     // constuctor
55     ImplOutlinerParaObject(EditTextObject* pEditTextObject, const ParagraphDataVector& rParagraphDataVector, bool bIsEditDoc)
56     :   mpEditTextObject(pEditTextObject),
57         maParagraphDataVector(rParagraphDataVector),
58         mbIsEditDoc(bIsEditDoc),
59         mnRefCount(0)
60     {
61         if( (maParagraphDataVector.size() == 0) && (pEditTextObject->GetParagraphCount() != 0) )
62             maParagraphDataVector.resize(pEditTextObject->GetParagraphCount());
63     }
64 
65     // destructor
66     ~ImplOutlinerParaObject()
67     {
68         delete mpEditTextObject;
69     }
70 
71     bool operator==(const ImplOutlinerParaObject& rCandidate) const
72 	{
73 		return (*mpEditTextObject == *rCandidate.mpEditTextObject
74             && maParagraphDataVector == rCandidate.maParagraphDataVector
75             && mbIsEditDoc == rCandidate.mbIsEditDoc);
76 	}
77 
78     // #i102062#
79     bool isWrongListEqual(const ImplOutlinerParaObject& rCompare) const
80     {
81 		return mpEditTextObject->isWrongListEqual(*rCompare.mpEditTextObject);
82     }
83 };
84 
85 //////////////////////////////////////////////////////////////////////////////
86 
87 void OutlinerParaObject::ImplMakeUnique()
88 {
89     if(mpImplOutlinerParaObject->mnRefCount)
90     {
91         ImplOutlinerParaObject* pNew = new ImplOutlinerParaObject(
92             mpImplOutlinerParaObject->mpEditTextObject->Clone(),
93             mpImplOutlinerParaObject->maParagraphDataVector,
94             mpImplOutlinerParaObject->mbIsEditDoc);
95         mpImplOutlinerParaObject->mnRefCount--;
96         mpImplOutlinerParaObject = pNew;
97     }
98 }
99 
100 OutlinerParaObject::OutlinerParaObject(const EditTextObject& rEditTextObject, const ParagraphDataVector& rParagraphDataVector, bool bIsEditDoc)
101 :   mpImplOutlinerParaObject(new ImplOutlinerParaObject(rEditTextObject.Clone(), rParagraphDataVector, bIsEditDoc))
102 {
103 }
104 
105 OutlinerParaObject::OutlinerParaObject(const OutlinerParaObject& rCandidate)
106 :   mpImplOutlinerParaObject(rCandidate.mpImplOutlinerParaObject)
107 {
108 	mpImplOutlinerParaObject->mnRefCount++;
109 }
110 
111 OutlinerParaObject::~OutlinerParaObject()
112 {
113 	if(mpImplOutlinerParaObject->mnRefCount)
114 	{
115 		mpImplOutlinerParaObject->mnRefCount--;
116 	}
117 	else
118 	{
119 		delete mpImplOutlinerParaObject;
120 	}
121 }
122 
123 OutlinerParaObject& OutlinerParaObject::operator=(const OutlinerParaObject& rCandidate)
124 {
125 	if(rCandidate.mpImplOutlinerParaObject != mpImplOutlinerParaObject)
126 	{
127 		if(mpImplOutlinerParaObject->mnRefCount)
128 		{
129 			mpImplOutlinerParaObject->mnRefCount--;
130 		}
131 		else
132 		{
133 			delete mpImplOutlinerParaObject;
134 		}
135 
136 		mpImplOutlinerParaObject = rCandidate.mpImplOutlinerParaObject;
137 		mpImplOutlinerParaObject->mnRefCount++;
138 	}
139 
140 	return *this;
141 }
142 
143 bool OutlinerParaObject::operator==(const OutlinerParaObject& rCandidate) const
144 {
145 	if(rCandidate.mpImplOutlinerParaObject == mpImplOutlinerParaObject)
146 	{
147 		return true;
148 	}
149 
150     return (*rCandidate.mpImplOutlinerParaObject == *mpImplOutlinerParaObject);
151 }
152 
153 // #i102062#
154 bool OutlinerParaObject::isWrongListEqual(const OutlinerParaObject& rCompare) const
155 {
156 	if(rCompare.mpImplOutlinerParaObject == mpImplOutlinerParaObject)
157 	{
158 		return true;
159 	}
160 
161     return mpImplOutlinerParaObject->isWrongListEqual(*rCompare.mpImplOutlinerParaObject);
162 }
163 
164 sal_uInt16 OutlinerParaObject::GetOutlinerMode() const
165 {
166 	return mpImplOutlinerParaObject->mpEditTextObject->GetUserType();
167 }
168 
169 void OutlinerParaObject::SetOutlinerMode(sal_uInt16 nNew)
170 {
171     if(mpImplOutlinerParaObject->mpEditTextObject->GetUserType() != nNew)
172     {
173         ImplMakeUnique();
174     	mpImplOutlinerParaObject->mpEditTextObject->SetUserType(nNew);
175     }
176 }
177 
178 bool OutlinerParaObject::IsVertical() const
179 {
180 	return mpImplOutlinerParaObject->mpEditTextObject->IsVertical();
181 }
182 
183 void OutlinerParaObject::SetVertical(bool bNew)
184 {
185 	if((bool)mpImplOutlinerParaObject->mpEditTextObject->IsVertical() != bNew)
186     {
187         ImplMakeUnique();
188     	mpImplOutlinerParaObject->mpEditTextObject->SetVertical(bNew);
189     }
190 }
191 
192 sal_uInt32 OutlinerParaObject::Count() const
193 {
194     return mpImplOutlinerParaObject->maParagraphDataVector.size();
195 }
196 
197 sal_Int16 OutlinerParaObject::GetDepth(sal_uInt16 nPara) const
198 {
199     if(nPara < mpImplOutlinerParaObject->maParagraphDataVector.size())
200     {
201         return mpImplOutlinerParaObject->maParagraphDataVector[nPara].getDepth();
202     }
203     else
204     {
205         return -1;
206     }
207 }
208 
209 const EditTextObject& OutlinerParaObject::GetTextObject() const
210 {
211     return *mpImplOutlinerParaObject->mpEditTextObject;
212 }
213 
214 bool OutlinerParaObject::IsEditDoc() const
215 {
216     return mpImplOutlinerParaObject->mbIsEditDoc;
217 }
218 
219 const ParagraphData& OutlinerParaObject::GetParagraphData(sal_uInt32 nIndex) const
220 {
221     if(nIndex < mpImplOutlinerParaObject->maParagraphDataVector.size())
222     {
223         return mpImplOutlinerParaObject->maParagraphDataVector[nIndex];
224     }
225     else
226     {
227         OSL_ENSURE(false, "OutlinerParaObject::GetParagraphData: Access out of range (!)");
228         static ParagraphData aEmptyParagraphData;
229         return aEmptyParagraphData;
230     }
231 }
232 
233 void OutlinerParaObject::ClearPortionInfo()
234 {
235     ImplMakeUnique();
236 	mpImplOutlinerParaObject->mpEditTextObject->ClearPortionInfo();
237 }
238 
239 bool OutlinerParaObject::ChangeStyleSheets(const XubString& rOldName, SfxStyleFamily eOldFamily, const XubString& rNewName, SfxStyleFamily eNewFamily)
240 {
241     ImplMakeUnique();
242 	return mpImplOutlinerParaObject->mpEditTextObject->ChangeStyleSheets(rOldName, eOldFamily, rNewName, eNewFamily);
243 }
244 
245 void OutlinerParaObject::ChangeStyleSheetName(SfxStyleFamily eFamily, const XubString& rOldName, const XubString& rNewName)
246 {
247     ImplMakeUnique();
248 	mpImplOutlinerParaObject->mpEditTextObject->ChangeStyleSheetName(eFamily, rOldName, rNewName);
249 }
250 
251 void OutlinerParaObject::SetStyleSheets(sal_uInt16 nLevel, const XubString rNewName, const SfxStyleFamily& rNewFamily)
252 {
253     const sal_uInt32 nCount(mpImplOutlinerParaObject->maParagraphDataVector.size());
254 
255     if(nCount)
256     {
257         ImplMakeUnique();
258         sal_uInt16 nDecrementer(sal::static_int_cast< sal_uInt16 >(nCount));
259 
260         for(;nDecrementer;)
261         {
262             if(GetDepth(--nDecrementer) == nLevel)
263             {
264                 mpImplOutlinerParaObject->mpEditTextObject->SetStyleSheet(nDecrementer, rNewName, rNewFamily);
265             }
266         }
267     }
268 }
269 
270 //////////////////////////////////////////////////////////////////////////////
271 // eof
272