LibreOffice Module lotuswordpro (master) 1
lwpstory.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*************************************************************************
3 *
4 * The Contents of this file are made available subject to the terms of
5 * either of the following licenses
6 *
7 * - GNU Lesser General Public License Version 2.1
8 * - Sun Industry Standards Source License Version 1.1
9 *
10 * Sun Microsystems Inc., October, 2000
11 *
12 * GNU Lesser General Public License Version 2.1
13 * =============================================
14 * Copyright 2000 by Sun Microsystems, Inc.
15 * 901 San Antonio Road, Palo Alto, CA 94303, USA
16 *
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License version 2.1, as published by the Free Software Foundation.
20 *
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
25 *
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 * MA 02111-1307 USA
30 *
31 *
32 * Sun Industry Standards Source License Version 1.1
33 * =================================================
34 * The contents of this file are subject to the Sun Industry Standards
35 * Source License Version 1.1 (the "License"); You may not use this file
36 * except in compliance with the License. You may obtain a copy of the
37 * License at http://www.openoffice.org/license.html.
38 *
39 * Software provided under this License is provided on an "AS IS" basis,
40 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
41 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
42 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
43 * See the License for the specific provisions governing your rights and
44 * obligations concerning the Software.
45 *
46 * The Initial Developer of the Original Code is: IBM Corporation
47 *
48 * Copyright: 2008 by IBM Corporation
49 *
50 * All Rights Reserved.
51 *
52 * Contributor(s): _______________________________________
53 *
54 *
55 ************************************************************************/
56/*************************************************************************
57 * @file
58 * LwpStory:
59 1. Word Pro object for paragraph list;
60 2. the content of layout object
61 ************************************************************************/
62
63#include <lwpglobalmgr.hxx>
64#include "lwpstory.hxx"
67#include "lwppara.hxx"
68#include <lwpobjfactory.hxx>
69#include "lwppagelayout.hxx"
70#include <rtl/ustrbuf.hxx>
71
72#include <algorithm>
74
75
77 : LwpContent(objHdr, pStrm)
78 , m_bPMModified(false)
79 , m_pCurrentLayout(nullptr)
80 , m_pTabLayout(nullptr)
81 , m_bDropcap(false)
82 , m_pHyperlinkMgr(new LwpHyperlinkMgr)
83{
84}
85
87{
88}
89
91{
95 m_pObjStrm->SkipExtra();
96}
97
98/**************************************************************************
99 * @descr: Convert all the contents in current story
100**************************************************************************/
102{
103 //process frame which anchor frame
105 //process para list
106 XFContentContainer* pParaCont = pCont;
107 rtl::Reference<LwpPara> xPara(dynamic_cast<LwpPara*>(GetFirstPara().obj().get()));
109 while (xPara.is())
110 {
111 bool bAlreadySeen = !aSeen.insert(xPara.get()).second;
112 if (bAlreadySeen)
113 throw std::runtime_error("loop in conversion");
114
115 xPara->SetFoundry(m_pFoundry);
116 xPara->XFConvert(pParaCont);
117
118 //Get the xfcontainer for the next para
119 pParaCont = xPara->GetXFContainer();
120 rtl::Reference<LwpPara> xNext(dynamic_cast<LwpPara*>(xPara->GetNext().obj().get()));
121 xPara = xNext;
122 }
123
124 //process frame which anchor is to cell after converter all the para
127
128 //Release Lwp Objects
129 rtl::Reference<LwpPara> xCur(dynamic_cast<LwpPara*>(GetFirstPara().obj().get()));
131 while (xCur.is())
132 {
133 xNext.set(dynamic_cast<LwpPara*>(xCur->GetNext().obj().get()));
135 LwpObjectFactory* pObjMgr = pGlobal->GetLwpObjFactory();
136 pObjMgr->ReleaseObject(xCur->GetObjectID());
137 xCur = xNext;
138 }
139}
140
142{
143 rtl::Reference<LwpPara> xPara(dynamic_cast<LwpPara*>(GetFirstPara().obj().get()));
145 while (xPara.is())
146 {
147 bool bAlreadySeen = !aSeen.insert(xPara.get()).second;
148 if (bAlreadySeen)
149 throw std::runtime_error("loop in register style");
150 xPara->SetFoundry(m_pFoundry);
151 xPara->DoRegisterStyle();
152 xPara.set(dynamic_cast<LwpPara*>(xPara->GetNext().obj().get()));
153 }
154}
155
156void LwpStory::Parse(IXFStream* pOutputStream)
157{
160 m_xXFContainer->ToXml(pOutputStream);
161 m_xXFContainer.clear();
162}
163
164/**************************************************************************
165 * @descr: Set current page layout. If pPageLayout is a mirror page layout,
166 use odd child page layout as current page layout.
167**************************************************************************/
169{
170 LwpPageLayout* pLayout = pPageLayout->GetOddChildLayout();
171 if(pLayout)
172 {
173 m_pCurrentLayout = pLayout;
174 m_pTabLayout = pLayout;
175 }
176 else
177 {
178 m_pCurrentLayout = pPageLayout;
179 m_pTabLayout = pPageLayout;
180 }
181 m_bPMModified = true;
182}
183
184/**************************************************************************
185 * @descr: Get the next page layout relative to m_pCurrentLayout
186**************************************************************************/
188{
189 std::vector<LwpPageLayout*>::iterator it = std::find(m_LayoutList.begin(), m_LayoutList.end(), m_pCurrentLayout);
190 if (it != m_LayoutList.end() && (it+1) != m_LayoutList.end())
191 return *(it+1);
192 return nullptr;
193}
194/**************************************************************************
195 * @descr: Sort the pagelayout according to their position
196**************************************************************************/
198{
199 //Get all the pagelayout and store in list
200 std::vector<LwpPageLayout*> aLayoutList;
202 while (xLayout)
203 {
204 LwpPageLayout *pLayout = xLayout->IsPage()
205 ? dynamic_cast<LwpPageLayout*>(xLayout.get())
206 : nullptr;
207 if (pLayout)
208 {
209 LwpLayout::UseWhenType eSectionType = pLayout->GetUseWhenType();
210 //for mirror page, the child is pagelayout
211 rtl::Reference<LwpVirtualLayout> xParent = xLayout->GetParentLayout();
212 if(eSectionType != LwpLayout::StartWithinColume && xParent.is() && !xParent->IsPage())
213 {
214 aLayoutList.push_back(pLayout);
215 }
216 }
217 xLayout = GetLayout(xLayout.get());
218 }
219 // sort the pagelayout according to their position
220 if (!aLayoutList.empty())
221 {
222 for( std::vector<LwpPageLayout*>::iterator aIt = aLayoutList.begin(); aIt != aLayoutList.end() -1; ++aIt)
223 {
224 for( std::vector<LwpPageLayout*>::iterator bIt = aIt +1; bIt != aLayoutList.end(); ++bIt )
225 {
226 if(!(**aIt < **bIt))
227 {
228 std::swap(*aIt, *bIt);
229 }
230 }
231 }
232 }
233
234 //put all the sorted layouts into list
235 m_LayoutList.clear();
236
237 for (auto const& layout : aLayoutList)
238 {
239 m_LayoutList.push_back(layout);
240 }
241}
242
243/**************************************************************************
244 * @descr: whether need create a new section and reset column in current page layout
245**************************************************************************/
247{
248 bool bNewSection = false;
250 {
252 {
253 //get the following pagelayout and its type
254 bool bColumns = true;
255 LwpPageLayout* pNextLayout = GetNextPageLayout();
256 if(pNextLayout)
257 {
258 //get layout type
259 LwpLayout::UseWhenType eWhenType = pNextLayout->GetUseWhenType();
260 switch(eWhenType)
261 {
262 case LwpLayout::StartWithinColume://not support now
264 {
265 bColumns =false;
266 bNewSection = true;
267 break;
268 }
270 case LwpLayout::StartOnOddPage://not support now
271 case LwpLayout::StartOnEvenPage://not support now
272 {
273 bColumns =true;
274 bNewSection = false;
275 break;
276 }
277 default:
278 break;
279 }
280 }
281
282 //if bColumns is true, the page layout doesn't need columns, set the xfcolumns to NULL in page master
283 if(!bColumns)
284 {
286 }
287 }
288 SetPMModified(false);
289 }
290 return bNewSection;
291}
292/**************************************************************************
293 * @descr: process frame which anchor type is to cell
294**************************************************************************/
296{
298 while (xLayout.is())
299 {
300 rtl::Reference<LwpVirtualLayout> xFrameLayout(dynamic_cast<LwpVirtualLayout*>(xLayout->GetChildHead().obj().get()));
301 while (xFrameLayout.is())
302 {
303 if (xFrameLayout->IsAnchorCell() && xFrameLayout->HasContent())
304 {
305 //get the first xfpara
308 XFContentContainer* pXFFirtPara = static_cast<XFContentContainer*>(first.get());
309 if(pXFFirtPara)
310 xFrameLayout->DoXFConvert(pXFFirtPara);
311 }
312 xFrameLayout.set(dynamic_cast<LwpVirtualLayout*>(xFrameLayout->GetNext().obj().get()));
313 }
314 xLayout = GetLayout(xLayout.get());
315 }
316}
317
318/**************************************************************************
319 * @descr: process frame which anchor type is to page
320**************************************************************************/
322{
324 while (xLayout.is())
325 {
326 rtl::Reference<LwpVirtualLayout> xFrameLayout(dynamic_cast<LwpVirtualLayout*>(xLayout->GetChildHead().obj().get()));
328 while (xFrameLayout.is())
329 {
330 bool bAlreadySeen = !aSeen.insert(xFrameLayout.get()).second;
331 if (bAlreadySeen)
332 throw std::runtime_error("loop in conversion");
333 if( xFrameLayout->IsAnchorPage()
334 && (xFrameLayout->IsFrame()
335 || xFrameLayout->IsSuperTable()
336 || xFrameLayout->IsGroupHead()) )
337 {
338 xFrameLayout->DoXFConvert(pCont);
339 }
340 xFrameLayout.set(dynamic_cast<LwpVirtualLayout*>(xFrameLayout->GetNext().obj().get()));
341 }
342 xLayout = GetLayout(xLayout.get());
343 }
344}
345/**************************************************************************
346 * @descr: process frame which anchor type is to frame
347**************************************************************************/
349{
351 while (xLayout)
352 {
353 rtl::Reference<LwpVirtualLayout> xFrameLayout(dynamic_cast<LwpVirtualLayout*>(xLayout->GetChildHead().obj().get()));
355 while (xFrameLayout.is())
356 {
357 bool bAlreadySeen = !aSeen.insert(xFrameLayout.get()).second;
358 if (bAlreadySeen)
359 throw std::runtime_error("loop in register style");
360 if (xFrameLayout->IsAnchorFrame())
361 {
362 xFrameLayout->DoXFConvert(pCont);
363 }
364 xFrameLayout.set(dynamic_cast<LwpVirtualLayout*>(xFrameLayout->GetNext().obj().get()));
365 }
366 xLayout = GetLayout(xLayout.get());
367 }
368}
369/**************************************************************************
370 * @descr: process frame which anchor type is to page and the frame is contained by header or footer
371**************************************************************************/
373{
375 while (xLayout.is())
376 {
377 rtl::Reference<LwpVirtualLayout> xFrameLayout(dynamic_cast<LwpVirtualLayout*>(xLayout->GetChildHead().obj().get()));
378 while (xFrameLayout.is())
379 {
380 if (xFrameLayout->IsAnchorPage() && (xLayout->IsHeader() || xLayout->IsFooter()))
381 {
382 //The frame must be included by <text:p>
385 XFContentContainer* pXFFirtPara = static_cast<XFContentContainer*>(first.get());
386 if(pXFFirtPara)
387 xFrameLayout->DoXFConvert(pXFFirtPara);
388 }
389 xFrameLayout.set(dynamic_cast<LwpVirtualLayout*>(xFrameLayout->GetNext().obj().get()));
390 }
391 xLayout = GetLayout(xLayout.get());
392 }
393}
394
396{
397 if (m_xXFContainer)
398 m_xXFContainer->Add(pContent);
399}
400
402{
403 return m_xXFContainer.get();
404}
405
407{
409 if (xVLayout.is())
410 {
411 return xVLayout->GetLastParaOfPreviousStory();
412 }
413
414 return nullptr;
415}
416/**************************************************************************
417 * @descr: get text from story
418**************************************************************************/
419OUString LwpStory::GetContentText(bool bAllText)
420{
421 if (bAllText)//convert all text fribs
422 {
423 OUStringBuffer sText;
424 //process para list
425 LwpPara* pPara = dynamic_cast<LwpPara*>(GetFirstPara().obj().get());
426 while (pPara)
427 {
428 pPara->SetFoundry(m_pFoundry);
429 sText.append(pPara->GetContentText(true));
430 pPara = dynamic_cast<LwpPara*>(pPara->GetNext().obj().get());
431 }
432 return sText.makeStringAndClear();
433 }
434 else //only the first text frib
435 {
437 if(pObj.is())
438 {
439 LwpPara* pPara = dynamic_cast<LwpPara*>(pObj.get());
440 if (!pPara || pPara->GetNext().obj() != nullptr)
441 return OUString();
442 pPara->SetFoundry(m_pFoundry);
443 return pPara->GetContentText();
444 }
445 return OUString();
446 }
447
448}
450{
451 LwpPara* pPara = dynamic_cast<LwpPara*>(GetFirstPara().obj().get());
452 if (!pPara)
453 return OUString();
454 pPara->SetFoundry(m_pFoundry);
455 LwpFribPtr& rFribs = pPara->GetFribs();
456 LwpFrib* pFirstFrib = rFribs.GetFribs();
457 pFirstFrib->RegisterStyle(m_pFoundry);
459 XFTextStyle* pBaseStyle = pXFStyleManager->FindTextStyle(pFirstFrib->GetStyleName());
460 if (pBaseStyle == nullptr)
461 return OUString();
462 std::unique_ptr<XFTextStyle> pStyle(new XFTextStyle);
463 *pStyle = *pBaseStyle;
464 OUString sName = "Ruby" + pFirstFrib->GetStyleName();
465 pStyle->SetStyleName(sName);
466 pXFStyleManager->AddStyle(std::move(pStyle));
467 return sName;
468}
469
470bool LwpStory::IsBullStyleUsedBefore(const OUString& rStyleName, sal_uInt8 nPos)
471{
472 return std::any_of(m_vBulletStyleNameList.rbegin(), m_vBulletStyleNameList.rend(),
473 [&rStyleName, &nPos](const NamePosPair& rPair) { return rPair.first == rStyleName && rPair.second == nPos; });
474}
475
476/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Stream wrapper for sax writer.
Definition: ixfstream.hxx:72
Base class of all Lwp content objects.
Definition: lwpcontent.hxx:74
void Read() override
@descr default read function
Definition: lwpcontent.cxx:81
rtl::Reference< LwpVirtualLayout > GetLayout(LwpVirtualLayout const *pStartLayout)
Definition: lwpcontent.cxx:124
void Read(LwpObjectStream *pObjStrm)
@descr Read head id and tail id
Definition: lwpdlvlist.cxx:160
LwpObjectID & GetNext()
Definition: lwpdlvlist.hxx:75
LwpFrib * GetFribs()
Definition: lwpfribptr.hxx:89
const OUString & GetStyleName() const
Definition: lwpfrib.hxx:112
virtual void RegisterStyle(LwpFoundry *pFoundry)
Definition: lwpfrib.cxx:223
XFStyleManager * GetXFStyleManager()
static LwpGlobalMgr * GetInstance(LwpSvStream *pSvStream=nullptr)
LwpObjectFactory * GetLwpObjFactory()
UseWhenType GetUseWhenType()
@descr: Get use when type
Definition: lwplayout.cxx:1651
@ StartWithinPage
Definition: lwplayout.hxx:439
@ StartWithinColume
Definition: lwplayout.hxx:438
@ StartOnNextPage
Definition: lwplayout.hxx:440
@ StartOnEvenPage
Definition: lwplayout.hxx:442
@ StartOnOddPage
Definition: lwplayout.hxx:441
object factory used for lwp object creation and maintenance
void ReleaseObject(const LwpObjectID &objID)
@descr release object in the factory per the object id
Base class of all Lwp VO objects.
Definition: lwpobjhdr.hxx:71
void ReadIndexed(LwpSvStream *pStrm)
@descr Read object id with indexed format from stream if index>0, lowid is get from time table per th...
Definition: lwpobjid.cxx:96
rtl::Reference< LwpObject > obj(VO_TYPE tag=VO_INVALID) const
@descr get object from object factory per the object id
Definition: lwpobjid.cxx:183
void SetFoundry(LwpFoundry *pFoundry)
Definition: lwpobj.hxx:137
LwpFoundry * m_pFoundry
Definition: lwpobj.hxx:91
std::unique_ptr< LwpObjectStream > m_pObjStrm
Definition: lwpobj.hxx:90
bool HasColumns()
@descr: Whether current page layout has columns
LwpPageLayout * GetOddChildLayout()
@descr: Get the odd layout if current page layout is mirror page
void ResetXFColumns()
@descr: Clear columns style in page layout
LwpFribPtr & GetFribs()
Definition: lwppara.hxx:303
OUString const & GetContentText(bool bAllText=false)
get text of paragraph
Definition: lwppara1.cxx:86
rtl::Reference< XFContentContainer > m_xXFContainer
Definition: lwpstory.hxx:96
bool m_bPMModified
Definition: lwpstory.hxx:87
void XFConvertFrameInHeaderFooter(XFContentContainer *pCont)
Definition: lwpstory.cxx:372
bool IsBullStyleUsedBefore(const OUString &rStyleName, sal_uInt8 nPos)
Definition: lwpstory.cxx:470
virtual void XFConvert(XFContentContainer *pCont) override
@descr default XFConvert function pCont is the XFContentContainer for the object conversion
Definition: lwpstory.cxx:101
void XFConvertFrameInCell(XFContentContainer *pCont)
Definition: lwpstory.cxx:295
LwpStory(LwpObjectHeader const &objHdr, LwpSvStream *pStrm)
Definition: lwpstory.cxx:76
bool IsNeedSection()
Definition: lwpstory.cxx:246
void SortPageLayout()
Definition: lwpstory.cxx:197
LwpDLVListHeadTail m_ParaList
Definition: lwpstory.hxx:79
LwpPageLayout * m_pCurrentLayout
Definition: lwpstory.hxx:88
LwpLayout * m_pTabLayout
Definition: lwpstory.hxx:90
XFContentContainer * GetXFContent()
Definition: lwpstory.cxx:401
void Read() override
@descr default read function
Definition: lwpstory.cxx:90
void SetCurrentLayout(LwpPageLayout *pPageLayout)
Definition: lwpstory.cxx:168
void RegisterStyle() override
@descr default register style function
Definition: lwpstory.cxx:141
LwpObjectID m_FirstParaStyle
Definition: lwpstory.hxx:80
void SetPMModified(bool bPMModified)
Definition: lwpstory.hxx:147
void AddXFContent(XFContent *pContent)
Definition: lwpstory.cxx:395
OUString RegisterFirstFribStyle()
Definition: lwpstory.cxx:449
void Parse(IXFStream *pOutputStream) override
@descr default parse function
Definition: lwpstory.cxx:156
LwpObjectID & GetFirstPara()
Definition: lwpstory.hxx:139
OUString GetContentText(bool bAllText=false)
Definition: lwpstory.cxx:419
void XFConvertFrameInFrame(XFContentContainer *pCont)
Definition: lwpstory.cxx:348
std::vector< LwpPageLayout * > m_LayoutList
Definition: lwpstory.hxx:89
virtual ~LwpStory() override
Definition: lwpstory.cxx:86
std::pair< OUString, sal_uInt8 > NamePosPair
Definition: lwpstory.hxx:83
LwpPara * GetLastParaOfPreviousStory()
Definition: lwpstory.cxx:406
LwpPageLayout * GetNextPageLayout()
Definition: lwpstory.cxx:187
std::vector< NamePosPair > m_vBulletStyleNameList
Definition: lwpstory.hxx:84
void XFConvertFrameInPage(XFContentContainer *pCont)
Definition: lwpstory.cxx:321
encapsulate XInputStream to provide SvStream like interfaces
Definition: lwpsvstream.hxx:69
A container for content.
rtl::Reference< XFContent > FindFirstContent(enumXFContent type)
@descr helper function, find first content by type.
@descr Base class for all content object.
Definition: xfcontent.hxx:80
Style manager for the filter.
IXFStyleRet AddStyle(std::unique_ptr< IXFStyle > pStyle)
XFTextStyle * FindTextStyle(std::u16string_view name)
std::pair< const_iterator, bool > insert(Value &&x)
OUString sName
sal_uInt16 nPos
constexpr OUStringLiteral first
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
unsigned char sal_uInt8
@ enumXFContentPara
Definition: xfdefs.hxx:68