tdf#137105: crash in table with Style Inspector active
[LibreOffice.git] / lotuswordpro / source / filter / lwptoc.cxx
blob30de25746d6c458376dc9832477b0100fb3ad078
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 - TOC related object
61 #include "lwptoc.hxx"
62 #include <lwpfoundry.hxx>
63 #include "lwpdoc.hxx"
64 #include "lwpframelayout.hxx"
65 #include <lwpglobalmgr.hxx>
67 #include <xfilter/xftextstyle.hxx>
68 #include <xfilter/xfstylemanager.hxx>
69 #include <xfilter/xfparastyle.hxx>
70 #include <xfilter/xfindex.hxx>
71 #include <xfilter/xffloatframe.hxx>
72 #include <xfilter/xfframe.hxx>
74 LwpTocSuperLayout::LwpTocSuperLayout(LwpObjectHeader const &objHdr, LwpSvStream* pStrm)
75 : LwpSuperTableLayout(objHdr, pStrm)
76 , m_nFrom(0)
77 , m_pCont(nullptr)
81 LwpTocSuperLayout::~LwpTocSuperLayout()
85 /**
86 * @short Read TOCSUPERTABLELAYOUT object
87 * @return none
89 void LwpTocSuperLayout::Read()
91 LwpSuperTableLayout::Read();
92 m_TextMarker.Read(m_pObjStrm.get());
93 m_ParentName.Read(m_pObjStrm.get());
94 m_DivisionName.Read(m_pObjStrm.get());
95 m_SectionName.Read(m_pObjStrm.get());
96 m_nFrom = m_pObjStrm->QuickReaduInt16();
98 m_SearchItems.Read(m_pObjStrm.get());
100 sal_uInt16 count = m_pObjStrm->QuickReaduInt16();
101 if (count > MAX_LEVELS)
102 throw std::range_error("corrupt LwpTocSuperLayout");
103 for (sal_uInt16 i = 0; i < count; ++i)
104 m_DestName[i].Read(m_pObjStrm.get());
106 count = m_pObjStrm->QuickReaduInt16();
107 if (count > MAX_LEVELS)
108 throw std::range_error("corrupt LwpTocSuperLayout");
109 for (sal_uInt16 i = 0; i < count; ++i)
110 m_DestPGName[i].Read(m_pObjStrm.get());
112 count = m_pObjStrm->QuickReaduInt16();
113 if (count > MAX_LEVELS)
114 throw std::range_error("corrupt LwpTocSuperLayout");
115 for (sal_uInt16 i = 0; i < count; ++i)
116 m_nFlags[i] = m_pObjStrm->QuickReaduInt32();
118 m_pObjStrm->SkipExtra();
121 * @short Register style of TOC
122 * @return none
124 void LwpTocSuperLayout::RegisterStyle()
126 LwpSuperTableLayout::RegisterStyle();
128 // Get font info of default text style and set into tab style
129 const LwpObjectID *pDefaultTextStyle = m_pFoundry ? m_pFoundry->GetDefaultTextStyle() : nullptr;
130 XFParaStyle* pBaseStyle = pDefaultTextStyle ? dynamic_cast<XFParaStyle*>(m_pFoundry->GetStyleManager()->GetStyle(*pDefaultTextStyle)) : nullptr;
131 std::unique_ptr<XFTextStyle> pTextStyle(new XFTextStyle);
132 if (pBaseStyle)
133 pTextStyle->SetFont(pBaseStyle->GetFont()); // who delete this font?????
134 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
135 m_TabStyleName = pXFStyleManager->AddStyle(std::move(pTextStyle)).m_pStyle->GetStyleName();
139 * @short Convert TOC
140 * @param pCont - container
141 * @return none
143 void LwpTocSuperLayout::XFConvert(XFContentContainer* pCont)
145 rtl::Reference<XFIndex> xToc(new XFIndex);
147 xToc->SetProtected(false);
148 xToc->SetIndexType(enumXFIndexTOC);
150 // add TOC template
151 for (sal_uInt16 i = 1; i<= MAX_LEVELS; i++)
153 LwpTocLevelData * pLevel = GetSearchLevelPtr(i);
154 XFIndexTemplate * pTemplate = new XFIndexTemplate();
156 if(!pLevel)
158 // add a blank template so that SODC won't add default style to this level
159 xToc->AddTemplate(OUString::number(i), OUString(), pTemplate);
160 continue;
163 bool bInserted = false;
166 // One level has 1 template
167 if (!bInserted)
169 pTemplate->SetLevel(OUString::number(i));
170 if(pLevel->GetUseLeadingText())
172 pTemplate->AddEntry(enumXFIndexTemplateChapter, pLevel->GetSearchStyle());
174 if(pLevel->GetUseText())
176 pTemplate->AddEntry(enumXFIndexTemplateText, pLevel->GetSearchStyle());
178 if(GetUsePageNumber(i))
180 sal_uInt16 nLeaderType = GetSeparatorType(i);
181 if (GetRightAlignPageNumber(i))
183 char cSep = ' ';
184 switch(nLeaderType)
186 default: // go through
187 case NONE: // no leaders
188 cSep = ' ';
189 break;
190 case LEADERDOTS:
191 cSep = '.';
192 break;
193 case LEADERDASHES:
194 cSep = '-';
195 break;
196 case LEADERUNDERLINE:
197 cSep = '_';
198 break;
201 pTemplate->AddTabEntry(enumXFTabRight, 0, cSep, 'd', m_TabStyleName);
203 else
205 OUString sSep;
206 switch(nLeaderType)
208 default: // go through
209 case NONE: // no leaders
210 sSep = " ";
211 break;
212 case SEPARATORCOMMA:
213 sSep = ", ";
214 break;
215 case SEPARATORDOTS:
216 sSep = "...";
217 break;
219 pTemplate->AddTextEntry(sSep, m_TabStyleName);
221 //"TOC Page Number Text Style" style always exists in Word Pro file
222 pTemplate->AddEntry(enumXFIndexTemplatePage, "TOC Page Number Text Style");
225 xToc->AddTemplate(OUString::number(static_cast<sal_Int32>(i)), m_pFoundry->FindActuralStyleName(pLevel->GetSearchStyle()), pTemplate);
226 bInserted = true;
229 // 1 style in WordPro may be mapped to several styles in SODC
230 LwpDocument * pDocument = m_pFoundry->GetDocument()->GetRootDocument();
231 AddSourceStyle(xToc.get(), pLevel, pDocument->GetFoundry());
233 // one level may have several corresponding Styles
234 pLevel = GetNextSearchLevelPtr(i, pLevel); // find next LwpTocLevelData which is same index
235 }while (pLevel != nullptr);
238 m_pCont = pCont;
239 // add TOC content
240 LwpSuperTableLayout::XFConvert(xToc.get());
242 rtl::Reference<LwpVirtualLayout> xContainer(GetContainerLayout());
243 if (!xContainer.is())
244 return;
246 // if current TOC is located in a cell, we must add a frame between upper level container and TOC
247 if (!xContainer->IsCell())
249 pCont->Add(xToc.get());
254 * @short convert frame which anchor to page
255 * @param pCont -
256 * @return
258 void LwpTocSuperLayout::XFConvertFrame(XFContentContainer* pCont, sal_Int32 nStart, sal_Int32 nEnd, bool bAll)
260 if (!m_pFrame)
261 return;
263 rtl::Reference<XFFrame> xXFFrame;
264 if(nEnd < nStart)
266 xXFFrame.set(new XFFrame);
268 else
270 xXFFrame.set(new XFFloatFrame(nStart, nEnd, bAll));
273 m_pFrame->Parse(xXFFrame.get(), static_cast<sal_uInt16>(nStart));
275 //parse table, and add table to frame or TOC
276 LwpTableLayout * pTableLayout = GetTableLayout();
277 if (!pTableLayout)
278 return;
280 XFContentContainer* pTableContainer = xXFFrame.get();
281 // if *this is a TOCSuperTableLayout and it's located in a cell
282 // add the frame to upper level and add TOCSuperTableLayout into the frame
283 rtl::Reference<LwpVirtualLayout> xContainer(GetContainerLayout());
284 if (!xContainer.is())
285 return;
286 if (xContainer->IsCell())
288 pTableContainer = pCont; // TOC contain table directly
289 xXFFrame->Add(pCont);
290 m_pCont->Add(xXFFrame.get());
292 else
294 //add frame to the container
295 pCont->Add(xXFFrame.get());
297 pTableLayout->XFConvert(pTableContainer);
302 * @short Add source style into TOC
303 * @param pToc - TOC pointer
304 * @param pLevel - TOC level data
305 * @param pFoundry - foundry pointer
306 * @return sal_Bool
308 void LwpTocSuperLayout::AddSourceStyle(XFIndex* pToc, LwpTocLevelData * pLevel, LwpFoundry * pFoundry)
310 if (!pLevel)
312 return;
315 OUString sLwpStyleName = pLevel->GetSearchStyle();
317 if (!pFoundry)
318 return;
320 LwpDocument * pDoc = pFoundry->GetDocument();
321 if (pDoc && pDoc->IsChildDoc())
323 OUString sSodcStyleName = pFoundry->FindActuralStyleName(sLwpStyleName);
324 pToc->AddTocSource(pLevel->GetLevel(), sSodcStyleName);
326 else
328 pDoc = pDoc->GetFirstDivision();
329 while (pDoc)
331 AddSourceStyle(pToc, pLevel, pDoc->GetFoundry() );
332 pDoc = pDoc->GetNextDivision();
338 * @short Get whether page number is right alignment
339 * @param index - TOC level
340 * @return sal_Bool
342 bool LwpTocSuperLayout::GetRightAlignPageNumber(sal_uInt16 index)
344 if (index < MAX_LEVELS)
345 return (m_nFlags[index] & TS_RIGHTALIGN) != 0;
346 return false;
349 * @short Get whether page number is used in TOC entries
350 * @param index - TOC level
351 * @return sal_Bool
353 bool LwpTocSuperLayout::GetUsePageNumber(sal_uInt16 index)
355 if (index < MAX_LEVELS)
356 return (m_nFlags[index] & TS_PAGENUMBER) != 0;
357 return false;
360 * @short Get what is used for separator
361 * @param index - TOC level
362 * @return sal_uInt16 - separator type
364 sal_uInt16 LwpTocSuperLayout::GetSeparatorType(sal_uInt16 index)
366 if (index >= MAX_LEVELS)
367 return NONE;
369 sal_uInt16 Flag = static_cast<sal_uInt16>(m_nFlags[index]);
371 if (Flag & TS_LEADERDOTS)
372 return LEADERDOTS;
373 else if (Flag & TS_LEADERDASHES)
374 return LEADERDASHES;
375 else if (Flag & TS_LEADERUNDERLINE)
376 return LEADERUNDERLINE;
377 else if (Flag & TS_SEPARATORCOMMA)
378 return SEPARATORCOMMA;
379 else if (Flag & TS_SEPARATORDOTS)
380 return SEPARATORDOTS;
381 else
382 return NONE;
386 * @short Get TOCLEVELDATA obj
387 * @param index - TOC level
388 * @return LwpTocLevelData * - pointer to TOCLEVELDATA obj
390 LwpTocLevelData * LwpTocSuperLayout::GetSearchLevelPtr(sal_uInt16 index)
392 LwpObjectID * pID = &m_SearchItems.GetHead(); // not necessary to check pID NULL or not
393 LwpTocLevelData * pObj = dynamic_cast<LwpTocLevelData *>(pID->obj().get());
395 while(pObj)
397 if(pObj->GetLevel()== index)
399 return pObj;
402 pID = &pObj->GetNext(); // not necessary to check pID NULL or not
403 pObj = dynamic_cast<LwpTocLevelData *>(pID->obj().get());
406 return nullptr;
409 * @short Get next TOCLEVELDATA obj from current position
410 * @param index - TOC level
411 * @param pCurData - current LwpTocLevelData
412 * @return LwpTocLevelData * - pointer to TOCLEVELDATA obj
414 LwpTocLevelData * LwpTocSuperLayout::GetNextSearchLevelPtr(sal_uInt16 index, LwpTocLevelData * pCurData)
416 LwpObjectID * pID = &pCurData->GetNext();
417 LwpTocLevelData * pObj = dynamic_cast<LwpTocLevelData *>(pID->obj().get());
419 while(pObj)
421 if(pObj->GetLevel()== index)
423 return pObj;
426 pID = &pObj->GetNext(); // not necessary to check pID NULL or not
427 pObj = dynamic_cast<LwpTocLevelData *>(pID->obj().get());
430 return nullptr;
433 LwpTocLevelData::LwpTocLevelData(LwpObjectHeader const &objHdr, LwpSvStream* pStrm)
434 : LwpDLVList(objHdr, pStrm), m_nFlags(0), m_nLevel(0)
437 LwpTocLevelData::~LwpTocLevelData()
441 * @short Register style
442 * @param
443 * @return
445 void LwpTocLevelData::RegisterStyle()
449 * @short Convert
450 * @param pCont - container
451 * @return none
453 void LwpTocLevelData::XFConvert(XFContentContainer* /*pCont*/)
457 * @short Read TOCLEVELDATA obj
458 * @param
459 * @return
461 void LwpTocLevelData::Read()
463 LwpDLVList::Read();
464 m_nFlags = m_pObjStrm->QuickReaduInt16();
465 m_nLevel = m_pObjStrm->QuickReaduInt16();
466 m_SearchName.Read(m_pObjStrm.get());
468 m_pObjStrm->SkipExtra();
471 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */