tdf#137105: crash in table with Style Inspector active
[LibreOffice.git] / lotuswordpro / source / filter / lwppara1.cxx
blob4a32be862b5bbe5e1db55c99c364f117adec0001
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * The Contents of this file are made available subject to the terms of
5 * either of the following licenses
7 * - GNU Lesser General Public License Version 2.1
8 * - Sun Industry Standards Source License Version 1.1
10 * Sun Microsystems Inc., October, 2000
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
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.
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.
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
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.
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.
46 * The Initial Developer of the Original Code is: IBM Corporation
48 * Copyright: 2008 by IBM Corporation
50 * All Rights Reserved.
52 * Contributor(s): _______________________________________
55 ************************************************************************/
56 /*************************************************************************
57 * @file
58 * For LWP filter architecture prototype
59 ************************************************************************/
61 #include <memory>
63 #include <boost/cast.hpp>
65 #include "lwppara.hxx"
66 #include <lwpglobalmgr.hxx>
67 #include "lwpparaproperty.hxx"
68 #include "lwpparastyle.hxx"
69 #include <xfilter/xfstylemanager.hxx>
70 #include "lwpfribheader.hxx"
71 #include "lwplayout.hxx"
73 #include "lwpstory.hxx"
74 #include "lwpsilverbullet.hxx"
75 #include "lwpframelayout.hxx"
77 #include <o3tl/sorted_vector.hxx>
79 // boost::polymorphic_downcast checks and reports (using assert), if the
80 // cast is incorrect (in debug builds).
81 using boost::polymorphic_downcast;
83 /**
84 * @short get text of paragraph
86 OUString const & LwpPara::GetContentText(bool bAllText)
88 // rFont = m_FontID;
89 if (bAllText)
91 m_Fribs.SetPara(this);
92 m_Fribs.GatherAllText();
93 return m_AllText;
95 else
96 return m_Content;
99 /**
100 * @short set text of paragraph
102 void LwpPara::SetAllText(const OUString& sText)
104 m_AllText+=sText;
108 * @short set first frib content
110 void LwpPara::SetFirstFrib(const OUString& Content,sal_uInt32 FontID)
112 m_FontID= FontID;
113 m_Content=Content;
116 * @short get paragraph xfstyle
118 XFParaStyle* LwpPara::GetXFParaStyle()
120 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
121 return pXFStyleManager->FindParaStyle(m_StyleName);
124 * @short get drop cap info
126 void LwpPara::GatherDropcapInfo()
128 m_nLines = m_pDropcapLayout->GetLines();
129 m_nChars = m_pDropcapLayout->GetChars();
132 * @short get parent paragraph
134 LwpPara* LwpPara::GetParent()
136 LwpPara* pPara;
137 sal_uInt16 otherlevel;
138 sal_uInt16 level = GetLevel();
140 if (level != 1)
142 pPara = dynamic_cast<LwpPara*>(GetPrevious().obj().get());
143 o3tl::sorted_vector<LwpPara*> aSeen;
144 while (pPara)
146 aSeen.insert(pPara);
147 otherlevel = pPara->GetLevel();
148 if ((otherlevel < level) || (otherlevel && (level == 0)))
149 return pPara;
150 pPara = dynamic_cast<LwpPara*>(pPara->GetPrevious().obj().get());
151 if (aSeen.find(pPara) != aSeen.end())
152 throw std::runtime_error("loop in conversion");
155 return nullptr;
159 * @short: Offer prefix, paranumber and suffix according to position.
160 * @param: nPosition index of wanted paranumbering in the style-list.
161 * @param: pParaNumbering a pointer to the structure which contains prefix, paranumber and
162 * suffix.
164 void LwpPara::GetParaNumber(sal_uInt16 nPosition, ParaNumbering* pParaNumbering)
166 if (nPosition > 9)
168 return;
170 sal_uInt16 nCurrentPos = 0;
172 LwpFrib* pPreFrib = nullptr;
173 LwpFrib* pFrib = m_Fribs.GetFribs();
174 if (!pFrib)
176 return;
179 while (pFrib)
181 sal_uInt8 nFribType = pFrib->GetType();
182 if (nFribType == FRIB_TAG_PARANUMBER)
184 nCurrentPos++;
185 ModifierInfo* pModInfo = pFrib->GetModifiers();
186 if (pModInfo)
188 sal_uInt16 nHideLevels = pModInfo->aTxtAttrOverride.GetHideLevels();
189 if (nCurrentPos == nPosition)
191 //get prefix text frib
192 if (pPreFrib)
194 if ((pPreFrib->GetType() == FRIB_TAG_TEXT) &&
195 (pPreFrib->GetModifiers() && pPreFrib->GetModifiers()->aTxtAttrOverride.GetHideLevels() == nHideLevels))
197 pParaNumbering->pPrefix = static_cast<LwpFribText*>(pPreFrib);
201 //get para numbering
202 pParaNumbering->pParaNumber = static_cast<LwpFribParaNumber*>(pFrib);
203 pParaNumbering->nNumLevel = nHideLevels;
205 //get suffix text frib
206 pFrib = pFrib->GetNext();
207 if ( pFrib )
209 if( pFrib->GetType() == FRIB_TAG_TEXT )
211 if (
212 (pFrib->GetNext() && pFrib->GetNext()->GetType() == FRIB_TAG_TEXT) ||
213 (pFrib->GetModifiers() && pFrib->GetModifiers()->aTxtAttrOverride.GetHideLevels() == nHideLevels)
216 pParaNumbering->pSuffix = static_cast<LwpFribText*>(pFrib);
221 break;
224 else
226 if (nCurrentPos == nPosition)
228 //get prefix text frib
229 if (pPreFrib)
231 if (pPreFrib->GetType() == FRIB_TAG_TEXT)
233 pParaNumbering->pPrefix = static_cast<LwpFribText*>(pPreFrib);
237 //get para numbering
238 pParaNumbering->pParaNumber = static_cast<LwpFribParaNumber*>(pFrib);
240 //get suffix text frib
241 pFrib = pFrib->GetNext();
242 if ( pFrib )
244 if (pFrib->GetType() == FRIB_TAG_TEXT)
246 pParaNumbering->pSuffix = static_cast<LwpFribText*>(pFrib);
253 pPreFrib = pFrib;
254 if (pFrib)
256 pFrib = pFrib->GetNext();
261 * @short override alignment
263 void LwpPara::OverrideAlignment(LwpAlignmentOverride* base,LwpAlignmentOverride* over,XFParaStyle* pOverStyle)
265 if (base)//the latter two parameter never be null
267 over->Override(base);
268 LwpParaStyle::ApplyAlignment(pOverStyle,base);
270 else
271 LwpParaStyle::ApplyAlignment(pOverStyle,over);
274 * @short override indent attribute
276 void LwpPara::OverrideIndent(LwpIndentOverride* base,LwpIndentOverride* over,XFParaStyle* pOverStyle)
278 if (base)//the latter two parameter never be null
280 over->Override(base);
281 LwpParaStyle::ApplyIndent(this,pOverStyle,base);
283 else
285 LwpParaStyle::ApplyIndent(this,pOverStyle,over);
289 * @short override spacing
291 void LwpPara::OverrideSpacing(LwpSpacingOverride* base,LwpSpacingOverride* over,XFParaStyle* pOverStyle)
293 if (base)//the latter two parameter never be null
295 if (over)
296 over->Override(base);
297 LwpParaStyle::ApplySpacing(this,pOverStyle,base);
299 else
300 LwpParaStyle::ApplySpacing(this,pOverStyle,over);
304 * @short: Get parastyle object according to the objID.
305 * @return: pointer to the parastyle.
307 LwpParaStyle* LwpPara::GetParaStyle()
309 return dynamic_cast<LwpParaStyle*>(m_ParaStyle.obj(VO_PARASTYLE).get());
313 * @short: Override paraborder style.
314 * @param: pProps pointer to the LwpParaProperty and we can get local breaks through it.
315 * @param: pOverStyle pointer to XFParaStyle which contains the parastyle for XFilter.
317 void LwpPara::OverrideParaBorder(LwpParaProperty* pProps, XFParaStyle* pOverStyle)
319 // get paraborder in parastyle
320 LwpParaStyle* pParaStyle = GetParaStyle();
321 if (!pParaStyle)
323 return;
326 LwpOverride* pBorder = pParaStyle->GetParaBorder();
327 std::unique_ptr<LwpParaBorderOverride> pFinalBorder(
328 pBorder
329 ? polymorphic_downcast<LwpParaBorderOverride*>(pBorder->clone())
330 : new LwpParaBorderOverride)
333 // get local border
334 pBorder = static_cast<LwpParaBorderProperty*>(pProps)->GetLocalParaBorder();
335 if (pBorder)
337 std::unique_ptr<LwpParaBorderOverride> pLocalBorder(
338 polymorphic_downcast<LwpParaBorderOverride*>(pBorder->clone()));
339 pLocalBorder->Override(pFinalBorder.get());
342 LwpParaStyle::ApplyParaBorder(pOverStyle, pFinalBorder.get());
345 * @short: Override parabreaks style.
346 * @param: pProps pointer to the LwpParaProperty and we can get local breaks through it.
347 * @param: pOverStyle pointer to XFParaStyle which contains the parastyle for XFilter.
349 void LwpPara::OverrideParaBreaks(LwpParaProperty* pProps, XFParaStyle* pOverStyle)
351 // get breaks in parastyle
352 LwpParaStyle* pParaStyle = GetParaStyle();
353 if (!pParaStyle)
355 return;
358 LwpOverride* pBreaks = pParaStyle->GetBreaks();
359 std::unique_ptr<LwpBreaksOverride> pFinalBreaks(
360 pBreaks
361 ? polymorphic_downcast<LwpBreaksOverride*>(pBreaks->clone())
362 : new LwpBreaksOverride)
365 // get local breaks
366 pBreaks = static_cast<LwpParaBreaksProperty*>(pProps)->GetLocalParaBreaks();
367 if (pBreaks)
369 std::unique_ptr<LwpBreaksOverride> const pLocalBreaks(
370 polymorphic_downcast<LwpBreaksOverride*>(pBreaks->clone()));
371 pLocalBreaks->Override(pFinalBreaks.get());
374 // save the breaks
375 m_pBreaks.reset( pFinalBreaks.release() );
377 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
378 if (m_pBreaks->IsKeepWithNext())
380 pOverStyle->SetBreaks(enumXFBreakKeepWithNext);
382 if (m_pBreaks->IsPageBreakBefore())
384 std::unique_ptr<XFParaStyle> pStyle(new XFParaStyle());
385 pStyle->SetBreaks(enumXFBreakAftPage);
386 m_BefPageBreakName = pXFStyleManager->AddStyle(std::move(pStyle)).m_pStyle->GetStyleName();
388 if (m_pBreaks->IsPageBreakAfter())
390 std::unique_ptr<XFParaStyle> pStyle(new XFParaStyle());
391 pStyle->SetBreaks(enumXFBreakAftPage);
392 m_AftPageBreakName = pXFStyleManager->AddStyle(std::move(pStyle)).m_pStyle->GetStyleName();
394 if (m_pBreaks->IsColumnBreakBefore())
396 std::unique_ptr<XFParaStyle> pStyle(new XFParaStyle());
397 pStyle->SetBreaks(enumXFBreakAftColumn);//tmp after, should change when layout read
398 m_BefColumnBreakName = pXFStyleManager->AddStyle(std::move(pStyle)).m_pStyle->GetStyleName();
400 if (m_pBreaks->IsColumnBreakAfter())
402 std::unique_ptr<XFParaStyle> pStyle(new XFParaStyle());
403 pStyle->SetBreaks(enumXFBreakAftColumn);
404 m_AftColumnBreakName = pXFStyleManager->AddStyle(std::move(pStyle)).m_pStyle->GetStyleName();
407 // pParaStyle->ApplyBreaks(pOverStyle, &aFinalBreaks);
411 * @short: Override bullet styles.
412 * @param: pProps pointer to the LwpParaProperty and we can get local bullet through it.
414 void LwpPara::OverrideParaBullet(LwpParaProperty* pProps)
416 // get bulletoverride in parastyle
417 LwpParaStyle* pParaStyle = GetParaStyle();
418 if (!pParaStyle)
420 return;
423 if (pProps)
425 m_xBullOver.reset(new LwpBulletOverride);
426 // get local bulletoverride
427 LwpBulletOverride* pLocalBullet = static_cast<LwpParaBulletProperty*>(pProps)->GetLocalParaBullet();
428 if (!pLocalBullet)
430 return;
433 LwpObjectID aSilverBulletID = pLocalBullet->GetSilverBullet();
434 if (aSilverBulletID.IsNull())
436 return;
438 else
440 m_bHasBullet = true;
442 const LwpBulletOverride& rBullet= pParaStyle->GetBulletOverride();
443 std::unique_ptr<LwpBulletOverride> xFinalBullet(rBullet.clone());
445 std::unique_ptr<LwpBulletOverride> const pLocalBullet2(pLocalBullet->clone());
446 pLocalBullet2->Override(xFinalBullet.get());
448 aSilverBulletID = xFinalBullet->GetSilverBullet();
449 m_xBullOver = std::move(xFinalBullet);
450 if (!aSilverBulletID.IsNull())
452 m_pSilverBullet = dynamic_cast<LwpSilverBullet*>(aSilverBulletID.obj(VO_SILVERBULLET).get());
453 if (m_pSilverBullet)
454 m_pSilverBullet->SetFoundry(m_pFoundry);
457 m_aSilverBulletID = aSilverBulletID;
460 else
462 const LwpBulletOverride& rBullOver = pParaStyle->GetBulletOverride();
463 m_aSilverBulletID = rBullOver.GetSilverBullet();
464 if (!m_aSilverBulletID.IsNull())
466 m_bHasBullet = true;
468 m_pSilverBullet = dynamic_cast<LwpSilverBullet*>(m_aSilverBulletID.obj(VO_SILVERBULLET).get());
469 if (m_pSilverBullet)
470 m_pSilverBullet->SetFoundry(m_pFoundry);
473 m_xBullOver.reset(rBullOver.clone());
477 * @short: Override paranumbering properties.
478 * @param: pProps pointer to the LwpParaProperty and we can get local paranumbering through it.
480 void LwpPara::OverrideParaNumbering(LwpParaProperty const * pProps)
482 // get numbering override in parastyle
483 LwpParaStyle* pParaStyle = GetParaStyle();
484 if (!pParaStyle)
486 return;
489 LwpNumberingOverride* pParaNumbering = pParaStyle->GetNumberingOverride();
490 std::unique_ptr<LwpNumberingOverride> pOver(new LwpNumberingOverride);
491 //Override with the local numbering, if any
492 if (pProps)
494 LwpNumberingOverride* pPropNumbering = static_cast<LwpParaNumberingProperty const *>(pProps)->GetLocalNumbering();
495 if (pPropNumbering)
497 pOver.reset(pPropNumbering->clone());
500 else
502 if (pParaNumbering)
504 pOver.reset(pParaNumbering->clone());
508 if (m_nFlags & VALID_LEVEL)
510 pOver->OverrideLevel(m_nLevel);
513 m_xParaNumbering = std::move(pOver);
516 /**************************************************************************
517 * @descr: Get property according to the property type
518 **************************************************************************/
519 LwpParaProperty* LwpPara::GetProperty(sal_uInt32 nPropType)
521 for (auto & i : m_vProps)
522 if(i->GetType() == nPropType)
524 return i.get();
526 return nullptr;
529 /**************************************************************************
530 * @descr: Get local tab rack
531 **************************************************************************/
532 LwpTabOverride* LwpPara::GetLocalTabOverride()
534 LwpParaProperty* pProp = GetProperty(PP_LOCAL_TABRACK);
535 if(pProp)
537 return static_cast<LwpParaTabRackProperty*>(pProp)->GetTab();
539 return nullptr;
543 * @descr: Determined which para is earlier in position
546 bool LwpPara::operator< (LwpPara const & Other)
548 return m_nOrdinal < Other.m_nOrdinal;
552 * @descr: If the two layouts in the same para, compare which layout is earlied according to frib order
555 bool LwpPara::ComparePagePosition(LwpVirtualLayout const * pPreLayout, LwpVirtualLayout const * pNextLayout)
557 m_Fribs.SetPara(this);
558 return m_Fribs.ComparePagePosition(pPreLayout, pNextLayout);
562 * @short check paragraph in cell or not
564 bool LwpPara::IsInCell()
566 LwpStory *pStory = GetStory();
567 if (!pStory)
568 return false;
569 rtl::Reference<LwpVirtualLayout> xLayout(pStory->GetLayout(nullptr));
570 return xLayout.is() && xLayout->IsCell();
573 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */