1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_editeng.hxx"
26 
27 #include <outl_pch.hxx>
28 
29 #define _OUTLINER_CXX
30 #include <editeng/outliner.hxx>
31 #include <editeng/outlobj.hxx>
32 #include <outleeng.hxx>
33 #include <editeng/editobj.hxx>
34 #include <vcl/bitmap.hxx>
35 #include <tools/stream.hxx>
36 
37 //////////////////////////////////////////////////////////////////////////////
38 
39 class ImplOutlinerParaObject
40 {
41 public:
42     // data members
43     EditTextObject*                 mpEditTextObject;
44     ParagraphDataVector             maParagraphDataVector;
45     bool                            mbIsEditDoc;
46 
47     // refcounter
48 	sal_uInt32						mnRefCount;
49 
50     // constuctor
51     ImplOutlinerParaObject(EditTextObject* pEditTextObject, const ParagraphDataVector& rParagraphDataVector, bool bIsEditDoc)
52     :   mpEditTextObject(pEditTextObject),
53         maParagraphDataVector(rParagraphDataVector),
54         mbIsEditDoc(bIsEditDoc),
55         mnRefCount(0)
56     {
57         if( (maParagraphDataVector.size() == 0) && (pEditTextObject->GetParagraphCount() != 0) )
58             maParagraphDataVector.resize(pEditTextObject->GetParagraphCount());
59     }
60 
61     // destructor
62     ~ImplOutlinerParaObject()
63     {
64         delete mpEditTextObject;
65     }
66 
67     bool operator==(const ImplOutlinerParaObject& rCandidate) const
68 	{
69 		return (*mpEditTextObject == *rCandidate.mpEditTextObject
70             && maParagraphDataVector == rCandidate.maParagraphDataVector
71             && mbIsEditDoc == rCandidate.mbIsEditDoc);
72 	}
73 
74     // #i102062#
75     bool isWrongListEqual(const ImplOutlinerParaObject& rCompare) const
76     {
77 		return mpEditTextObject->isWrongListEqual(*rCompare.mpEditTextObject);
78     }
79 };
80 
81 //////////////////////////////////////////////////////////////////////////////
82 
83 void OutlinerParaObject::ImplMakeUnique()
84 {
85     if(mpImplOutlinerParaObject->mnRefCount)
86     {
87         ImplOutlinerParaObject* pNew = new ImplOutlinerParaObject(
88             mpImplOutlinerParaObject->mpEditTextObject->Clone(),
89             mpImplOutlinerParaObject->maParagraphDataVector,
90             mpImplOutlinerParaObject->mbIsEditDoc);
91         mpImplOutlinerParaObject->mnRefCount--;
92         mpImplOutlinerParaObject = pNew;
93     }
94 }
95 
96 OutlinerParaObject::OutlinerParaObject(const EditTextObject& rEditTextObject, const ParagraphDataVector& rParagraphDataVector, bool bIsEditDoc)
97 :   mpImplOutlinerParaObject(new ImplOutlinerParaObject(rEditTextObject.Clone(), rParagraphDataVector, bIsEditDoc))
98 {
99 }
100 
101 OutlinerParaObject::OutlinerParaObject(const OutlinerParaObject& rCandidate)
102 :   mpImplOutlinerParaObject(rCandidate.mpImplOutlinerParaObject)
103 {
104 	mpImplOutlinerParaObject->mnRefCount++;
105 }
106 
107 OutlinerParaObject::~OutlinerParaObject()
108 {
109 	if(mpImplOutlinerParaObject->mnRefCount)
110 	{
111 		mpImplOutlinerParaObject->mnRefCount--;
112 	}
113 	else
114 	{
115 		delete mpImplOutlinerParaObject;
116 	}
117 }
118 
119 OutlinerParaObject& OutlinerParaObject::operator=(const OutlinerParaObject& rCandidate)
120 {
121 	if(rCandidate.mpImplOutlinerParaObject != mpImplOutlinerParaObject)
122 	{
123 		if(mpImplOutlinerParaObject->mnRefCount)
124 		{
125 			mpImplOutlinerParaObject->mnRefCount--;
126 		}
127 		else
128 		{
129 			delete mpImplOutlinerParaObject;
130 		}
131 
132 		mpImplOutlinerParaObject = rCandidate.mpImplOutlinerParaObject;
133 		mpImplOutlinerParaObject->mnRefCount++;
134 	}
135 
136 	return *this;
137 }
138 
139 bool OutlinerParaObject::operator==(const OutlinerParaObject& rCandidate) const
140 {
141 	if(rCandidate.mpImplOutlinerParaObject == mpImplOutlinerParaObject)
142 	{
143 		return true;
144 	}
145 
146     return (*rCandidate.mpImplOutlinerParaObject == *mpImplOutlinerParaObject);
147 }
148 
149 // #i102062#
150 bool OutlinerParaObject::isWrongListEqual(const OutlinerParaObject& rCompare) const
151 {
152 	if(rCompare.mpImplOutlinerParaObject == mpImplOutlinerParaObject)
153 	{
154 		return true;
155 	}
156 
157     return mpImplOutlinerParaObject->isWrongListEqual(*rCompare.mpImplOutlinerParaObject);
158 }
159 
160 sal_uInt16 OutlinerParaObject::GetOutlinerMode() const
161 {
162 	return mpImplOutlinerParaObject->mpEditTextObject->GetUserType();
163 }
164 
165 void OutlinerParaObject::SetOutlinerMode(sal_uInt16 nNew)
166 {
167     if(mpImplOutlinerParaObject->mpEditTextObject->GetUserType() != nNew)
168     {
169         ImplMakeUnique();
170     	mpImplOutlinerParaObject->mpEditTextObject->SetUserType(nNew);
171     }
172 }
173 
174 bool OutlinerParaObject::IsVertical() const
175 {
176 	return mpImplOutlinerParaObject->mpEditTextObject->IsVertical();
177 }
178 
179 void OutlinerParaObject::SetVertical(bool bNew)
180 {
181 	if((bool)mpImplOutlinerParaObject->mpEditTextObject->IsVertical() != bNew)
182     {
183         ImplMakeUnique();
184     	mpImplOutlinerParaObject->mpEditTextObject->SetVertical(bNew);
185     }
186 }
187 
188 sal_uInt32 OutlinerParaObject::Count() const
189 {
190     return mpImplOutlinerParaObject->maParagraphDataVector.size();
191 }
192 
193 sal_Int16 OutlinerParaObject::GetDepth(sal_uInt16 nPara) const
194 {
195     if(nPara < mpImplOutlinerParaObject->maParagraphDataVector.size())
196     {
197         return mpImplOutlinerParaObject->maParagraphDataVector[nPara].getDepth();
198     }
199     else
200     {
201         return -1;
202     }
203 }
204 
205 const EditTextObject& OutlinerParaObject::GetTextObject() const
206 {
207     return *mpImplOutlinerParaObject->mpEditTextObject;
208 }
209 
210 bool OutlinerParaObject::IsEditDoc() const
211 {
212     return mpImplOutlinerParaObject->mbIsEditDoc;
213 }
214 
215 const ParagraphData& OutlinerParaObject::GetParagraphData(sal_uInt32 nIndex) const
216 {
217     if(nIndex < mpImplOutlinerParaObject->maParagraphDataVector.size())
218     {
219         return mpImplOutlinerParaObject->maParagraphDataVector[nIndex];
220     }
221     else
222     {
223         OSL_ENSURE(false, "OutlinerParaObject::GetParagraphData: Access out of range (!)");
224         static ParagraphData aEmptyParagraphData;
225         return aEmptyParagraphData;
226     }
227 }
228 
229 void OutlinerParaObject::ClearPortionInfo()
230 {
231     ImplMakeUnique();
232 	mpImplOutlinerParaObject->mpEditTextObject->ClearPortionInfo();
233 }
234 
235 bool OutlinerParaObject::ChangeStyleSheets(const XubString& rOldName, SfxStyleFamily eOldFamily, const XubString& rNewName, SfxStyleFamily eNewFamily)
236 {
237     ImplMakeUnique();
238 	return mpImplOutlinerParaObject->mpEditTextObject->ChangeStyleSheets(rOldName, eOldFamily, rNewName, eNewFamily);
239 }
240 
241 void OutlinerParaObject::ChangeStyleSheetName(SfxStyleFamily eFamily, const XubString& rOldName, const XubString& rNewName)
242 {
243     ImplMakeUnique();
244 	mpImplOutlinerParaObject->mpEditTextObject->ChangeStyleSheetName(eFamily, rOldName, rNewName);
245 }
246 
247 void OutlinerParaObject::SetStyleSheets(sal_uInt16 nLevel, const XubString rNewName, const SfxStyleFamily& rNewFamily)
248 {
249     const sal_uInt32 nCount(mpImplOutlinerParaObject->maParagraphDataVector.size());
250 
251     if(nCount)
252     {
253         ImplMakeUnique();
254         sal_uInt16 nDecrementer(sal::static_int_cast< sal_uInt16 >(nCount));
255 
256         for(;nDecrementer;)
257         {
258             if(GetDepth(--nDecrementer) == nLevel)
259             {
260                 mpImplOutlinerParaObject->mpEditTextObject->SetStyleSheet(nDecrementer, rNewName, rNewFamily);
261             }
262         }
263     }
264 }
265 
266 //////////////////////////////////////////////////////////////////////////////
267 // eof
268