LibreOffice Module lotuswordpro (master) 1
lwprowlayout.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 ************************************************************************/
61#include "lwprowlayout.hxx"
62#include "lwptable.hxx"
63#include <lwpglobalmgr.hxx>
65#include <xfilter/xfrow.hxx>
67#include <xfilter/xftable.hxx>
68#include <xfilter/xfcell.hxx>
70
72 : LwpVirtualLayout(objHdr, pStrm)
73 , crowid(0)
74 , cheight(0)
75 , cLeaderDotCount(0)
76 , cLeaderDotY(0)
77 , cRowFlags(0)
78{
79 m_ConnCellList.clear();
80}
81
83{}
84
93{
94 LwpObjectID *pCellID= &GetChildHead();
95 LwpCellLayout * pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj().get());
96
98 while(pCellLayout)
99 {
100 bool bAlreadySeen = !aSeen.insert(pCellLayout).second;
101 if (bAlreadySeen)
102 throw std::runtime_error("loop in conversion");
103
104 pCellLayout->SetCellMap();
105
106 pCellID = &pCellLayout->GetNext();
107 pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj().get());
108 }
109}
118{
119 // register row style
120 std::unique_ptr<XFRowStyle> pRowStyle(new XFRowStyle());
121
122 if (m_nDirection & 0x0030)
123 {
124 pRowStyle->SetMinRowHeight(static_cast<float>(LwpTools::ConvertFromUnitsToMetric(cheight)));
125 }
126 else
127 {
128 pRowStyle->SetRowHeight(static_cast<float>(LwpTools::ConvertFromUnitsToMetric(cheight)));
129 }
131 m_StyleName = pXFStyleManager->AddStyle(std::move(pRowStyle)).m_pStyle->GetStyleName();
132
133 LwpTableLayout* pTableLayout = GetParentTableLayout();
134 if (pTableLayout)
135 {
136 pTableLayout->GetTable();
137 }
138 // register cells' style
139 LwpObjectID *pCellID= &GetChildHead();
140 LwpCellLayout * pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj().get());
141
143 while (pCellLayout)
144 {
145 bool bAlreadySeen = !aSeen.insert(pCellLayout).second;
146 if (bAlreadySeen)
147 throw std::runtime_error("loop in conversion");
148
149 pCellLayout->SetFoundry(m_pFoundry);
150 pCellLayout->RegisterStyle();
151 pCellID = &pCellLayout->GetNext();
152 pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj().get());
153 }
154
155}
164{
165 #define MAXUNIT (0x7fffffffL) // Highest positive UNIT value
166 LwpObjectStream* pStrm = m_pObjStrm.get();
167
169
170 //skip CLiteLayout data;
171 LwpAtomHolder ContentClass;
172 ContentClass.Read(pStrm);
173 pStrm->SkipExtra();
174
175 // Row layout content
176 crowid = pStrm->QuickReaduInt16();
177 cheight = pStrm->QuickReadInt32();
178 cLeaderDotCount = static_cast<sal_uInt8>(pStrm->QuickReaduInt16()); // was written as lushort.
179 cLeaderDotY = MAXUNIT; // Sentinel meaning "not calculated yet"
180 cRowFlags = static_cast<sal_uInt8>(pStrm->QuickReaduInt16()); // was written as lushort.
181
182 pStrm->SkipExtra();
183}
184
190{
191 LwpTableLayout* pTableLayout = GetParentTableLayout();
192 if (!pTableLayout)
193 throw std::runtime_error("missing TableLayout");
194 LwpTable* pTable = pTableLayout->GetTable();
195 if (!pTable)
196 throw std::runtime_error("missing Table");
197
198 //calculate the connected cell position
199 sal_Int32 nMarkConnCell = FindMarkConnCell(nStartCol,nEndCol);
200
201 //if there is no connected cell
202 if (nMarkConnCell == -1)
203 {
204 ConvertCommonRow(pXFTable,nStartCol,nEndCol);
205 return;
206 }
207
208 //register connect row style
209 sal_uInt16 nRowMark = crowid + GetCurMaxSpannedRows(nStartCol,nEndCol);
210 rtl::Reference<XFRow> xXFRow(new XFRow);
211 RegisterCurRowStyle(xXFRow.get(), nRowMark);
212
213 //if there is connected cell
214 for (sal_uInt8 i=nStartCol; i<nEndCol; )
215 {
217 sal_uInt8 nColMark;
218
219 if (nMarkConnCell == -1)
220 nColMark = nEndCol;
221 else
222 nColMark = m_ConnCellList[nMarkConnCell]->GetColID();
223
224 if (nColMark > i)//create subtable
225 {
226 xXFCell.set(new XFCell);
227 xXFCell->SetColumnSpaned(nColMark-i);
228 rtl::Reference<XFTable> xSubTable(new XFTable);
229 pTableLayout->ConvertTable(xSubTable,crowid,nRowMark,i,nColMark);
230 xXFCell->Add(xSubTable.get());
231 i = nColMark;
232 }
233 else
234 {
235 sal_uInt8 nColID = m_ConnCellList[nMarkConnCell]->GetColID()
236 +m_ConnCellList[nMarkConnCell]->GetNumcols()-1;
237 xXFCell = m_ConnCellList[nMarkConnCell]->DoConvertCell(
238 pTable->GetObjectID(),
239 crowid+m_ConnCellList[nMarkConnCell]->GetNumrows()-1,
240 m_ConnCellList[nMarkConnCell]->GetColID());
241
242 //set all cell in this merge cell to cellsmap
243 pTableLayout->SetCellsMap(crowid, i, nRowMark - 1, nColID, xXFCell.get());
244
245 i += m_ConnCellList[nMarkConnCell]->GetNumcols();
246 nMarkConnCell = FindNextMarkConnCell(static_cast<sal_uInt16>(nMarkConnCell),nEndCol);
247 }
248
249 if (xXFCell)
250 xXFRow->AddCell(xXFCell);
251 }
252 pXFTable->AddRow(xXFRow);
253}
254
260void LwpRowLayout::RegisterCurRowStyle(XFRow* pXFRow,sal_uInt16 nRowMark)
261{
263 XFRowStyle* pRowStyle = static_cast<XFRowStyle*>(pXFStyleManager->FindStyle(m_StyleName));
264 if (!pRowStyle)
265 return;
266 double fHeight = pRowStyle->GetRowHeight();
267
268 std::unique_ptr<XFRowStyle> pNewStyle(new XFRowStyle);
269 *pNewStyle = *pRowStyle;
270 LwpTableLayout* pTableLayout = GetParentTableLayout();
271 if (!pTableLayout)
272 {
273 return;
274 }
275 std::map<sal_uInt16,LwpRowLayout*> RowsMap = pTableLayout->GetRowsMap();
276
277 for (sal_uInt16 i=crowid+1; i<nRowMark;i++)
278 {
279 std::map<sal_uInt16,LwpRowLayout*>::iterator iter = RowsMap.find(i);
280 if (iter == RowsMap.end())
281 {
282 pRowStyle = static_cast<XFRowStyle*>(
283 pXFStyleManager->FindStyle(pTableLayout->GetDefaultRowStyleName()));
284 }
285 else
286 {
287 pRowStyle = static_cast<XFRowStyle*>(
288 pXFStyleManager->FindStyle(iter->second->GetStyleName()));
289 }
290 if (!pRowStyle)
291 throw std::runtime_error("missing RowStyle");
292 fHeight += pRowStyle->GetRowHeight();
293 }
294
295 if (m_nDirection & 0x0030)
296 {
297 pNewStyle->SetMinRowHeight(static_cast<float>(fHeight));
298 }
299 else
300 {
301 pNewStyle->SetRowHeight(static_cast<float>(fHeight));
302 }
303
304 pXFRow->SetStyleName(pXFStyleManager->AddStyle(std::move(pNewStyle)).m_pStyle->GetStyleName());
305}
306
313{
314 if (m_ConnCellList.empty())
315 return -1;
316
317 sal_uInt16 nSpannRows = 1;
318 sal_Int32 nMarkConnCell = -1;
319
320 for (size_t i=0;i<m_ConnCellList.size();i++)
321 {
322 if (m_ConnCellList[i]->GetColID()>=nEndCol)
323 break;
324 if (m_ConnCellList[i]->GetColID()>=nStartCol)
325 {
326 if (m_ConnCellList[i]->GetNumrows()>nSpannRows)
327 {
328 nSpannRows = m_ConnCellList[i]->GetNumrows();
329 nMarkConnCell = i;
330 }
331 }
332 }
333 return nMarkConnCell;
334}
335
341sal_Int32 LwpRowLayout::FindNextMarkConnCell(sal_uInt16 nMarkConnCell,sal_uInt8 nEndCol)
342{
343 sal_uInt16 nMaxRows = m_ConnCellList[nMarkConnCell]->GetNumrows();
344
345 for (size_t i=nMarkConnCell+1;i<m_ConnCellList.size();i++)
346 {
347 if (m_ConnCellList[i]->GetColID()>=nEndCol)
348 break;
349 if (m_ConnCellList[i]->GetNumrows() == nMaxRows)
350 {
351 return i;
352 }
353 }
354 return -1;
355}
362{
363 sal_Int32 nMarkConnCell = FindMarkConnCell(nStartCol,nEndCol);
364 if (nMarkConnCell == -1)
365 return 1;
366 else
367 return m_ConnCellList[nMarkConnCell]->GetNumrows();
368}
376{
377 LwpTableLayout* pTableLayout = GetParentTableLayout();
378 if (!pTableLayout)
379 return;
380 LwpTable* pTable = pTableLayout->GetTable();
381 if (!pTable)
382 return;
383
385 xRow->SetStyleName(m_StyleName);
386
387 sal_uInt8 nCellStartCol,nCellEndCol;
388
389 for (sal_uInt16 i = nStartCol; i < nEndCol; i++)
390 {
391 // add row to table
392 LwpObjectID *pCellID= &GetChildHead();
393 LwpCellLayout * pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj().get());
394 nCellStartCol = i;//mark the begin position of cell
395 nCellEndCol = i;//mark the end position of cell
397 while(pCellLayout)
398 {
399 if (pCellLayout->GetColID() == i)
400 {
401 if (pCellLayout->GetLayoutType() == LWP_CONNECTED_CELL_LAYOUT)
402 {
403 LwpConnectedCellLayout* pConnCell = static_cast<LwpConnectedCellLayout*>(pCellLayout);
404 auto nNumCols = pConnCell->GetNumcols();
405 if (!nNumCols)
406 throw std::runtime_error("loop in conversion");
407 auto nNewEndCol = i + nNumCols - 1;
408 if (nNewEndCol > std::numeric_limits<sal_uInt8>::max())
409 throw std::range_error("column index too large");
410 nCellEndCol = nNewEndCol;
411 i = nCellEndCol;
412 }
413 xCell = pCellLayout->DoConvertCell(pTable->GetObjectID(),crowid,i);
414 break;
415 }
416 pCellID = &pCellLayout->GetNext();
417 pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj().get());
418 }
419 if (!pCellLayout)
420 {
421 // if table has default cell layout, use it to ConvertCell
422 // otherwise use blank cell
423 LwpCellLayout * pDefaultCell = pTableLayout->GetDefaultCellLayout();
424 if (pDefaultCell)
425 {
426 xCell = pDefaultCell->DoConvertCell(
427 pTable->GetObjectID(),crowid, i);
428 }
429 else
430 {
431 xCell.set(new XFCell);
432 }
433 }
434 xRow->AddCell(xCell);
435
436 pTableLayout->SetCellsMap(crowid, nCellStartCol, crowid, nCellEndCol, xCell.get()); //set to cellsmap
437 }
438
439 pXFTable->AddRow(xRow);
440}
445{
446 LwpObjectID *pCellID= &GetChildHead();
447 LwpCellLayout * pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj().get());
448
449 while(pCellLayout)
450 {
451 if (pCellLayout->GetLayoutType() == LWP_CONNECTED_CELL_LAYOUT)
452 {
453 LwpConnectedCellLayout* pConnCell = static_cast<LwpConnectedCellLayout*>(pCellLayout);
454 m_ConnCellList.push_back(pConnCell);
455 }
456 pCellID = &pCellLayout->GetNext();
457 pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj().get());
458 }
459}
464void LwpRowLayout::SetCellSplit(sal_uInt16 nEffectRows)
465{
466 for (LwpConnectedCellLayout* pConnCell : m_ConnCellList)
467 {
468 sal_uInt16 nRowSpan;
469 if (o3tl::checked_add(pConnCell->GetRowID(), pConnCell->GetNumrows(), nRowSpan))
470 throw std::range_error("bad span");
471 if (nRowSpan > nEffectRows)
472 {
473 if (o3tl::checked_sub(nEffectRows, pConnCell->GetRowID(), nRowSpan))
474 throw std::range_error("bad span");
475 pConnCell->SetNumrows(nRowSpan);
476 }
477 }
478}
483{
484 return !m_ConnCellList.empty();
485}
486
488 : LwpRowLayout(objHdr, pStrm)
489{}
490
492{}
494{
496
498 m_pObjStrm->SkipExtra();
499}
500
501/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual OUString GetStyleName()=0
@descr: return the style name.
AtomHolder class of Word Pro to hold a string.
void Read(LwpObjectStream *pStrm)
@descr read atomholder from object stream the default encoding used in Word Pro is 1252
VO_CELLLAYOUT object.
virtual void SetCellMap()
Set current cell layout to cell layout map.
rtl::Reference< XFCell > DoConvertCell(LwpObjectID aTableID, sal_uInt16 nRow, sal_uInt16 nCol)
void RegisterStyle() override
Register 4 types of cell style and register content styles.
sal_uInt8 GetColID() const
virtual LWP_LAYOUT_TYPE GetLayoutType() override
VO_CONNECTEDCELLLAYOUT object.
sal_uInt8 GetNumcols() const
LwpObjectID & GetChildHead()
Definition: lwpdlvlist.hxx:109
LwpObjectID & GetNext()
Definition: lwpdlvlist.hxx:75
XFStyleManager * GetXFStyleManager()
static LwpGlobalMgr * GetInstance(LwpSvStream *pSvStream=nullptr)
Base class of all Lwp VO objects.
Definition: lwpobjhdr.hxx:71
object id class
Definition: lwpobjid.hxx:79
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
stream class for LwpObject body data provide stream like interface to read object data
Definition: lwpobjstrm.hxx:77
sal_uInt16 QuickReaduInt16(bool *pFailure=nullptr)
@descr Quick read sal_uInt32
Definition: lwpobjstrm.cxx:200
void SkipExtra()
@descr skip extra bytes
Definition: lwpobjstrm.cxx:258
sal_Int32 QuickReadInt32()
@descr Quick read sal_Int32
Definition: lwpobjstrm.cxx:211
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
LwpObjectID & GetObjectID()
Definition: lwpobj.hxx:138
LwpRowHeadingLayout(LwpObjectHeader const &objHdr, LwpSvStream *pStrm)
LwpObjectID cRowLayout
virtual ~LwpRowHeadingLayout() override
void Read() override
register row style
VO_ROWLAYOUT obj.
sal_Int32 cheight
void Read() override
register row style
LwpRowLayout(LwpObjectHeader const &objHdr, LwpSvStream *pStrm)
sal_Int32 FindNextMarkConnCell(sal_uInt16 nMarkConnCell, sal_uInt8 nEndCol)
find next merge cell with the same spanned row number with current merge cell
void CollectMergeInfo()
collect merge cell info when register row styles
sal_uInt16 crowid
void SetRowMap()
register row style
void ConvertRow(rtl::Reference< XFTable > const &pXFTable, sal_uInt8 nStartCol, sal_uInt8 nEndCol)
Parse rows with connect cell.
LwpTableLayout * GetParentTableLayout()
void ConvertCommonRow(rtl::Reference< XFTable > const &pXFTable, sal_uInt8 nStartCol, sal_uInt8 nEndCol)
convert row with rowlayout,but no merge cells
void SetCellSplit(sal_uInt16 nEffectRows)
split merge cells in this row
std::vector< LwpConnectedCellLayout * > m_ConnCellList
sal_Int32 FindMarkConnCell(sal_uInt8 nStartCol, sal_uInt8 nEndCol)
find max merge cell in a given column range
sal_uInt8 cRowFlags
sal_Int32 cLeaderDotY
bool GetMergeCellFlag() const
check if the row has merge cell
virtual ~LwpRowLayout() override
void RegisterCurRowStyle(XFRow *pXFRow, sal_uInt16 nRowMark)
register row style in SODC table
sal_uInt8 cLeaderDotCount
virtual void RegisterStyle() override
register row style
sal_uInt16 GetCurMaxSpannedRows(sal_uInt8 nStartCol, sal_uInt8 nEndCol)
get max spanned row numbers in a given column range
encapsulate XInputStream to provide SvStream like interfaces
Definition: lwpsvstream.hxx:69
VO_TABLELAYOUT object and functions for registering styles and converting tables.
void ConvertTable(rtl::Reference< XFTable > const &pXFTable, sal_uInt16 nStartRow, sal_uInt16 nEndRow, sal_uInt8 nStartCol, sal_uInt8 nEndCol)
convert word pro table to SODC table
const std::map< sal_uInt16, LwpRowLayout * > & GetRowsMap() const
void SetCellsMap(sal_uInt16 nRow1, sal_uInt8 nCol1, sal_uInt16 nRow2, sal_uInt8 nCol2, XFCell *pXFCell)
set cell map info
LwpTable * GetTable()
Get table pointer.
LwpCellLayout * GetDefaultCellLayout()
const OUString & GetDefaultRowStyleName() const
VO_TABLE object.
Definition: lwptable.hxx:107
static double ConvertFromUnitsToMetric(sal_Int32 nUnits)
Definition: lwptools.hxx:117
void Read() override
@descr Read name of LwpDLNFVList from object stream
Definition: lwplayout.cxx:101
OUString m_StyleName
Definition: lwplayout.hxx:249
sal_uInt16 m_nDirection
Definition: lwplayout.hxx:245
@descr Table cell object.
Definition: xfcell.hxx:76
virtual void SetStyleName(const OUString &style)
: All content except XFTextContent can have a style.
Definition: xfcontent.hxx:90
double GetRowHeight() const
Definition: xfrowstyle.hxx:94
Definition: xfrow.hxx:69
Style manager for the filter.
IXFStyle * FindStyle(std::u16string_view name)
IXFStyleRet AddStyle(std::unique_ptr< IXFStyle > pStyle)
std::pair< const_iterator, bool > insert(Value &&x)
#define MAXUNIT
For LWP filter architecture prototype - row layouts.
For LWP filter architecture prototype - table object.
int i
std::enable_if< std::is_signed< T >::value, bool >::type checked_add(T a, T b, T &result)
std::enable_if< std::is_signed< T >::value, bool >::type checked_sub(T a, T b, T &result)
IXFStyle * m_pStyle
Definition: xfstylecont.hxx:71
unsigned char sal_uInt8