Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / lotuswordpro / source / filter / lwptablelayout.cxx
blob0c8cbb2fbe73f4a9e783ef8761ac83211f5d74b2
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 - table layouts
61 #include "lwpglobalmgr.hxx"
62 #include "lwptablelayout.hxx"
63 #include "lwpfoundry.hxx"
64 #include "lwpobjfactory.hxx"
65 #include "lwpholder.hxx"
66 #include "lwptable.hxx"
67 #include "lwptblcell.hxx"
68 #include "lwpnumericfmt.hxx"
69 #include "lwpdlvlist.hxx"
70 #include "lwppara.hxx"
72 #include "xfilter/xfstylemanager.hxx"
73 #include "xfilter/xftablestyle.hxx"
74 #include "xfilter/xftable.hxx"
75 #include "xfilter/xfrow.hxx"
76 #include "xfilter/xfrowstyle.hxx"
77 #include "xfilter/xfcell.hxx"
78 #include "xfilter/xfcellstyle.hxx"
79 #include "xfilter/xfcolstyle.hxx"
80 #include "xfilter/xfframestyle.hxx"
81 #include "xfilter/xfframe.hxx"
82 #include "xfilter/xffloatframe.hxx"
83 #include "lwpframelayout.hxx"
84 #include "xfilter/xfparastyle.hxx"
86 LwpSuperTableLayout::LwpSuperTableLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
87 : LwpPlacableLayout(objHdr, pStrm)
89 m_pFrame = new LwpFrame(this);
92 LwpSuperTableLayout::~LwpSuperTableLayout()
94 if(m_pFrame)
96 delete m_pFrame;
99 /**
100 * @short Read super table layout record
102 void LwpSuperTableLayout::Read()
104 LwpPlacableLayout::Read();
105 m_pObjStrm->SkipExtra();
109 * @short Get child table layout
110 * @return pointer to table layout
112 LwpTableLayout* LwpSuperTableLayout::GetTableLayout()
114 LwpObjectID& rID = GetChildTail();
116 while(!rID.IsNull())
118 LwpLayout* pLayout = dynamic_cast<LwpLayout*>(rID.obj().get());
119 if (!pLayout)
121 break;
123 if (pLayout->GetLayoutType() == LWP_TABLE_LAYOUT)
125 return dynamic_cast<LwpTableLayout *>(pLayout);
127 rID = pLayout->GetPrevious();
130 return nullptr;
133 * @short Get effective heading table layout, the one just before table layout is the only one which is effective
134 * @return LwpTableHeadingLayout* - pointer to table heading layout
136 LwpTableHeadingLayout* LwpSuperTableLayout::GetTableHeadingLayout()
138 LwpObjectID& rID = GetChildTail();
140 while(!rID.IsNull())
142 LwpLayout * pLayout = dynamic_cast<LwpLayout *>(rID.obj().get());
143 if (!pLayout)
145 break;
148 if (pLayout->GetLayoutType() == LWP_TABLE_HEADING_LAYOUT)
150 return dynamic_cast<LwpTableHeadingLayout *>(pLayout);
152 rID = pLayout->GetPrevious();
155 return nullptr;
158 * @short Register super table layout style
160 void LwpSuperTableLayout::RegisterNewStyle()
162 // if this layout is style of real table entry
163 LwpTableLayout* pTableLayout = GetTableLayout();
164 if (pTableLayout != nullptr)
166 pTableLayout->SetFoundry(m_pFoundry);
167 pTableLayout->RegisterStyle();
171 * @short Judge whether table size is according to content, borrowed from Word Pro code
172 * @param
173 * @return sal_Bool
175 bool LwpSuperTableLayout::IsSizeRightToContent()
177 /* Only "with paragraph above" tables can size right to content. */
178 if (GetRelativeType() == LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE)
179 return LwpPlacableLayout::IsSizeRightToContent();
181 return false;
184 * @short Judge whether table is justifiable, borrowed from Word Pro code
185 * @param
186 * @return sal_Bool
188 bool LwpSuperTableLayout::IsJustifiable()
190 return (GetRelativeType() != LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE || IsSizeRightToContent());
193 * @short Get width of frame outside table
194 * @param pTableStyle - pointer of XFTableStyle
195 * @return double - table width
197 double LwpSuperTableLayout::GetWidth()
199 double dWidth = GetTableWidth();
200 double dLeft = GetMarginsValue(MARGIN_LEFT);
201 double dRight = GetMarginsValue(MARGIN_RIGHT);
203 return (dWidth + dLeft + dRight);
206 * @short Get width of table
207 * @param pTableStyle - pointer of XFTableStyle
208 * @return double - table width
210 double LwpSuperTableLayout::GetTableWidth()
212 sal_Int32 nWidth = 0;
213 if(!IsJustifiable() || ((nWidth = LwpMiddleLayout::GetMinimumWidth()) <= 0))
215 LwpTableLayout* pTableLayout = GetTableLayout();
216 if(!pTableLayout)
218 SAL_WARN("lwp", "missing table layout, early return");
219 return 0;
221 LwpTable *pTable = pTableLayout->GetTable();
222 if(!pTable)
224 SAL_WARN("lwp", "missing table, early return");
225 return 0;
227 double dDefaultWidth = pTable->GetWidth();
228 sal_uInt16 nCol = pTable->GetColumn();
230 double dWidth = 0;
232 for(sal_uInt16 i =0; i< nCol; i++)
234 LwpObjectID& rColumnID = pTableLayout->GetColumnLayoutHead();
235 LwpColumnLayout * pColumnLayout = dynamic_cast<LwpColumnLayout *>(rColumnID.obj().get());
236 double dColumnWidth = dDefaultWidth;
237 while (pColumnLayout)
239 if(pColumnLayout->GetColumnID() == i)
241 dColumnWidth = pColumnLayout->GetWidth();
242 break;
244 rColumnID = pColumnLayout->GetNext();
245 pColumnLayout = dynamic_cast<LwpColumnLayout *>(rColumnID.obj().get());
247 dWidth += dColumnWidth;
250 return dWidth;
253 double dLeft = GetMarginsValue(MARGIN_LEFT);
254 double dRight = GetMarginsValue(MARGIN_RIGHT);
255 return LwpTools::ConvertFromUnitsToMetric(nWidth)-dLeft-dRight;
259 * @short Apply shadow to table
260 * @param pTableStyle - pointer of XFTableStyle
261 * @return
263 void LwpSuperTableLayout::ApplyShadow(XFTableStyle *pTableStyle)
265 // use shadow property of supertable
266 std::unique_ptr<XFShadow> pXFShadow(GetXFShadow());
267 if(pXFShadow)
269 pTableStyle->SetShadow(pXFShadow->GetPosition(), pXFShadow->GetOffset(), pXFShadow->GetColor());
273 * @short Apply pattern fill to table style
274 * @param pTableStyle - pointer of XFTableStyle
275 * @return
277 void LwpSuperTableLayout::ApplyPatternFill(XFTableStyle* pTableStyle)
279 XFBGImage* pXFBGImage = GetFillPattern();
280 if (pXFBGImage)
282 pTableStyle->SetBackImage(pXFBGImage);
287 * @short Apply background to table style
288 * @param pTableStyle - pointer of XFTableStyle
289 * @return
291 void LwpSuperTableLayout::ApplyBackGround(XFTableStyle* pTableStyle)
293 if (IsPatternFill())
295 ApplyPatternFill(pTableStyle);
297 else
299 ApplyBackColor(pTableStyle);
303 * @short Apply back color to table
304 * @param pTableStyle - pointer of XFTableStyle
305 * @return
307 void LwpSuperTableLayout::ApplyBackColor(XFTableStyle *pTableStyle)
309 LwpColor* pColor = GetBackColor();
310 if(pColor && pColor->IsValidColor())
312 XFColor aColor(pColor->To24Color());
313 pTableStyle->SetBackColor(aColor);
317 * @short Apply watermark to table
318 * @param pTableStyle - pointer of XFTableStyle
319 * @return
321 void LwpSuperTableLayout::ApplyWatermark(XFTableStyle *pTableStyle)
323 XFBGImage* pBGImage = GetXFBGImage();
324 if(pBGImage)
326 pTableStyle->SetBackImage(pBGImage);
330 * @short Apply alignment to table
331 * @param pTableStyle - pointer of XFTableStyle
332 * @return
334 void LwpSuperTableLayout::ApplyAlignment(XFTableStyle * pTableStyle)
336 LwpPoint aPoint;
337 if (GetGeometry())
338 aPoint = GetGeometry()->GetOrigin();
339 //LwpPoint aPoint = GetOrigin();
340 double dXOffset = LwpTools::ConvertFromUnitsToMetric(aPoint.GetX());
342 // add left padding to alignment distance
343 double dLeft = GetMarginsValue(MARGIN_LEFT);
345 pTableStyle->SetAlign(enumXFAlignStart, dXOffset+ dLeft);
348 * @short Add table to container
349 * @param pCont - pointer of container
350 * @return pCont
352 void LwpSuperTableLayout::XFConvert(XFContentContainer* pCont)
354 if ( LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE == GetRelativeType()
355 && (!GetContainerLayout().is() || !GetContainerLayout()->IsCell()) )
357 LwpTableLayout * pTableLayout = GetTableLayout();
358 if (pTableLayout)
360 pTableLayout->XFConvert(pCont);
363 else if(IsRelativeAnchored())
365 //anchor to paragraph except "with paragraph above"
366 XFConvertFrame(pCont);
368 else if(m_pFrame)
370 //anchor to page, frame, cell
371 m_pFrame->XFConvert(pCont);
375 * @short convert frame which anchor to page
376 * @param
377 * @return
379 void LwpSuperTableLayout::XFConvertFrame(XFContentContainer* pCont, sal_Int32 nStart, sal_Int32 nEnd, bool bAll)
381 if(m_pFrame)
383 XFFrame* pXFFrame = nullptr;
384 if(nEnd < nStart)
386 pXFFrame = new XFFrame();
388 else
390 pXFFrame = new XFFloatFrame(nStart, nEnd, bAll);
393 m_pFrame->Parse(pXFFrame, static_cast<sal_uInt16>(nStart));
394 //parse table, and add table to frame
395 LwpTableLayout * pTableLayout = GetTableLayout();
396 if (pTableLayout)
398 pTableLayout->XFConvert(pXFFrame);
400 //add frame to the container
401 pCont ->Add(pXFFrame);
406 * @short register frame style
407 * @param
408 * @return
410 void LwpSuperTableLayout::RegisterFrameStyle()
412 XFFrameStyle* pFrameStyle = new XFFrameStyle();
413 m_pFrame->RegisterStyle(pFrameStyle);
416 LwpTableLayout::LwpTableLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
417 : LwpLayout(objHdr, pStrm)
418 , m_nRows(0)
419 , m_nCols(0)
420 , m_pDefaultCellLayout(nullptr)
421 , m_pColumns(nullptr)
423 m_CellsMap.clear();
426 LwpTableLayout::~LwpTableLayout()
428 m_CellsMap.clear();
430 if (m_pColumns)
432 delete [] m_pColumns;
433 m_pColumns = nullptr;
438 * @short Get neighbour cell by specifying ROW+COL
439 * @param nRow
440 * @param nCol
441 * @return LwpCellLayout *
443 LwpCellLayout * LwpTableLayout::GetCellByRowCol(sal_uInt16 nRow, sal_uInt16 nCol)
445 if (nRow >= m_nRows || nCol >= m_nCols)
446 return nullptr;
448 return m_WordProCellsMap[static_cast<size_t>(nRow)*m_nCols + nCol];
452 * @short traverse all table cells
453 * @param
454 * @param
455 * @param
457 void LwpTableLayout::TraverseTable()
459 sal_uInt32 nCount = m_nRows*m_nCols;
461 // new cell map nRow*nCOl and initialize
462 for (sal_uInt32 iLoop = 0; iLoop < nCount; ++iLoop)
464 m_WordProCellsMap.push_back(GetDefaultCellLayout());
467 // set value
468 LwpObjectID& rRowID = GetChildHead();
469 LwpRowLayout * pRowLayout = dynamic_cast<LwpRowLayout *>(rRowID.obj().get());
470 while (pRowLayout)
472 pRowLayout->SetRowMap();
474 // for 's analysis job
475 m_RowsMap[pRowLayout->GetRowID()] = pRowLayout;
476 pRowLayout->CollectMergeInfo();
477 // end for 's analysis
479 rRowID = pRowLayout->GetNext();
480 pRowLayout = dynamic_cast<LwpRowLayout *>(rRowID.obj().get());
485 * @short search the cell map
486 * @param nRow - row id (0 based)
487 * @param nRow - row id (0 based)
488 * @return LwpObjectID * - pointer to cell story object ID
490 LwpObjectID * LwpTableLayout::SearchCellStoryMap(sal_uInt16 nRow, sal_uInt16 nCol)
492 if (nRow >= m_nRows || nCol >= m_nCols )
494 return nullptr;
497 LwpCellLayout * pCell = GetCellByRowCol(nRow, nCol);
498 if (pCell)
500 // maybe connected cell layout
501 // maybe default cell layout
502 if (nRow != pCell->GetRowID() || nCol != pCell->GetColID())
504 return nullptr;
506 return &pCell->GetContent();
509 return nullptr;
513 * @short Get parent super table layout of table layout
514 * @return LwpSuperTableLayout * - pointer of parent super table layout
516 LwpSuperTableLayout * LwpTableLayout::GetSuperTableLayout()
518 return dynamic_cast<LwpSuperTableLayout *>(GetParent().obj().get());
521 * @short Get table pointer
522 * @return LwpTable * - content table pointer
524 LwpTable * LwpTableLayout::GetTable()
526 LwpTable *pTable = dynamic_cast<LwpTable *>(m_Content.obj().get());
527 return pTable;
530 * @short Get column style name by column ID
531 * @param sal_uInt16 -- col id(0 based)
532 * @return OUString - name of column style
534 OUString LwpTableLayout::GetColumnWidth(sal_uInt16 nCol)
536 if (nCol >= m_nCols)
538 assert(false);
539 return m_DefaultColumnStyleName;
542 LwpColumnLayout * pCol = m_pColumns[nCol];
543 if (pCol)
545 return pCol->GetStyleName();
548 return m_DefaultColumnStyleName;
551 * @short analyze all columns to get whole table width and width of all columns
552 * @short and register all column styles
553 * @param none
555 void LwpTableLayout::RegisterColumns()
557 LwpTable * pTable = GetTable();
558 LwpSuperTableLayout * pSuper = GetSuperTableLayout();
560 sal_uInt16 nCols = m_nCols;
562 m_pColumns = new LwpColumnLayout *[nCols];
563 sal_Bool * pWidthCalculated = new sal_Bool[nCols];
564 for(sal_uInt16 i=0;i<nCols; i++)
566 pWidthCalculated[i] = false;
567 m_pColumns[i] = nullptr;
570 double dDefaultColumn = pTable->GetWidth();
571 sal_uInt16 nJustifiableColumn = nCols;
573 double dTableWidth = pSuper->GetTableWidth();
575 // Get total width of justifiable columns
576 // NOTICE: all default columns are regarded as justifiable columns
577 LwpObjectID& rColumnID = GetColumnLayoutHead();
578 LwpColumnLayout * pColumnLayout = dynamic_cast<LwpColumnLayout *>(rColumnID.obj().get());
579 while (pColumnLayout)
581 auto nColId = pColumnLayout->GetColumnID();
582 if (nColId >= nCols)
584 delete [] pWidthCalculated;
585 throw std::range_error("corrupt LwpTableLayout");
587 m_pColumns[nColId] = pColumnLayout;
588 if (!pColumnLayout->IsJustifiable())
590 pWidthCalculated[nColId] = true;
591 dTableWidth -= pColumnLayout->GetWidth();
592 nJustifiableColumn --;
595 rColumnID = pColumnLayout->GetNext();
596 pColumnLayout = dynamic_cast<LwpColumnLayout *>(rColumnID.obj().get());
599 // if all columns are not justifiable, the rightmost column will be changed to justifiable
600 if (nJustifiableColumn == 0 && nCols != 0)
602 nJustifiableColumn ++;
603 if (m_pColumns[nCols - 1])
605 pWidthCalculated[nCols-1] = false;
606 dTableWidth += m_pColumns[nCols-1]->GetWidth();
608 else
610 // this can't happen
611 dTableWidth = dDefaultColumn;
612 assert(false);
616 // justifiable columns will share the remain width averagely
617 dDefaultColumn = nJustifiableColumn ? dTableWidth/nJustifiableColumn : 0;
619 // register default column style
620 XFColStyle *pColStyle = new XFColStyle();
621 pColStyle->SetWidth(static_cast<float>(dDefaultColumn));
623 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
624 m_DefaultColumnStyleName = pXFStyleManager->AddStyle(pColStyle).m_pStyle->GetStyleName();
626 // register existed column style
627 sal_uInt16 i=0;
628 for( i=0;i<nCols; i++)
630 if(m_pColumns[i])
632 m_pColumns[i]->SetFoundry(m_pFoundry);
633 if(!pWidthCalculated[i])
635 // justifiable ----register style with calculated value
636 m_pColumns[i]->SetStyleName(m_DefaultColumnStyleName);
638 else
640 // not justifiable ---- register style with original value
641 m_pColumns[i]->RegisterStyle(m_pColumns[i]->GetWidth());
645 delete [] pWidthCalculated;
648 * @short register all row styles
649 * @param none
651 void LwpTableLayout::RegisterRows()
653 LwpTable * pTable = GetTable();
654 if (pTable == nullptr)
656 assert(false);
657 return;
660 // register default row style
661 XFRowStyle * pRowStyle = new XFRowStyle();
662 if (m_nDirection & 0x0030)
664 pRowStyle->SetMinRowHeight((float)pTable->GetHeight());
666 else
668 pRowStyle->SetRowHeight((float)pTable->GetHeight());
670 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
671 m_DefaultRowStyleName = pXFStyleManager->AddStyle(pRowStyle).m_pStyle->GetStyleName();
673 // register style of rows
674 LwpObjectID& rRowID = GetChildHead();
675 LwpRowLayout * pRowLayout = dynamic_cast<LwpRowLayout *>(rRowID.obj().get());
676 while (pRowLayout)
678 pRowLayout->SetFoundry(m_pFoundry);
679 pRowLayout->RegisterStyle();
681 rRowID = pRowLayout->GetNext();
682 pRowLayout = dynamic_cast<LwpRowLayout *>(rRowID.obj().get());
686 * @short register table style, if needed, including frame style
687 * @param none
689 void LwpTableLayout::RegisterStyle()
691 // get super table layout
692 LwpSuperTableLayout * pSuper = GetSuperTableLayout();
693 if (!pSuper)
694 return;
696 // get table
697 LwpTable * pTable = GetTable();
698 if (pTable == nullptr)
700 SAL_WARN("lwp", "missing table, early return");
701 return;
704 // get row/column number of this table
705 m_nRows = pTable->GetRow();
706 m_nCols = pTable->GetColumn();
708 // get default cell layout of current table
709 LwpObjectID& rID= pTable->GetDefaultCellStyle();
710 m_pDefaultCellLayout = dynamic_cast<LwpCellLayout *>(rID.obj().get());
712 // register columns styles
713 RegisterColumns();
715 // register style of whole table
716 XFTableStyle * pTableStyle = new XFTableStyle();
718 sal_uInt8 nType = pSuper->GetRelativeType();
719 // If the table is not "with paragraph above" placement, create an frame style
720 // by supertable layout
721 if ( LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE == nType
722 && (!pSuper->GetContainerLayout().is() || !pSuper->GetContainerLayout()->IsCell()) )
724 //with para above
725 // pSuper->ApplyBackColor(pTableStyle);
726 pSuper->ApplyBackGround(pTableStyle);
727 pSuper->ApplyWatermark(pTableStyle);
728 pSuper->ApplyShadow(pTableStyle);
729 pSuper->ApplyAlignment(pTableStyle);
730 pTableStyle->SetWidth(pSuper->GetTableWidth());
732 else
734 pSuper->RegisterFrameStyle();
735 pTableStyle->SetAlign(enumXFAlignCenter);
736 pTableStyle->SetWidth(pSuper->GetTableWidth());
738 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
739 m_StyleName = pXFStyleManager->AddStyle(pTableStyle).m_pStyle->GetStyleName();
741 //convert to OO table now and register row style
742 // traverse
743 TraverseTable();
745 SplitConflictCells();
747 // Register rows layouts, it must be after SplitConflictCells
748 RegisterRows();
750 // Parse table
751 ParseTable();
753 //Comment: the old code doesn't check if the LwpFoundry pointer is NULL,
754 // so the NULL pointer cause sodc freeze. Add code to check the
755 // the pointer.
756 //New Code
757 if (GetFoundry() && GetTable())
758 PutCellVals(GetFoundry(), GetTable()->GetObjectID());
761 * @short read table layout
762 * @param none
764 void LwpTableLayout::ParseTable()
766 // get super table layout
767 LwpSuperTableLayout* pSuper = GetSuperTableLayout();
768 if (!pSuper)
770 throw std::runtime_error("missing super table");
773 if (m_pXFTable.get())
775 throw std::runtime_error("this table is already parsed");
778 // set name of object
779 m_pXFTable = new XFTable;
780 m_pXFTable->SetTableName(pSuper->GetName().str());
781 // set table style
782 m_pXFTable->SetStyleName(m_StyleName);
784 sal_uInt16 nRow = m_nRows;
785 sal_uInt8 nCol = (sal_uInt8)m_nCols;
787 //process header rows
788 LwpTableHeadingLayout* pTableHeading;
789 pTableHeading = pSuper->GetTableHeadingLayout();
790 sal_uInt16 nStartHeadRow;
791 sal_uInt16 nEndHeadRow;
792 sal_uInt16 nContentRow;
793 if (pTableHeading)
795 pTableHeading->GetStartEndRow(nStartHeadRow,nEndHeadRow);
796 if (nStartHeadRow != 0)
797 ConvertTable(m_pXFTable,0,nRow,0,nCol);
798 else
800 nContentRow = ConvertHeadingRow(m_pXFTable,nStartHeadRow,nEndHeadRow+1);
801 ConvertTable(m_pXFTable,nContentRow,nRow,0,nCol);
804 else
805 ConvertTable(m_pXFTable,0,nRow,0,nCol);
809 * @short read table layout
810 * @param none
812 void LwpTableLayout::Read()
814 LwpLayout::Read();
816 // before layout hierarchy rework!
817 if(LwpFileHeader::m_nFileRevision < 0x000b)
819 assert(false);
821 m_ColumnLayout.ReadIndexed(m_pObjStrm);
823 m_pObjStrm->SkipExtra();
827 * @short Convert table
828 * @param
829 * @return pCont - container which will contain table
831 void LwpTableLayout::XFConvert(XFContentContainer* pCont)
834 pCont->Add(m_pXFTable.get());
837 * @short convert heading row
838 * @param pXFTable - pointer of table
839 * @param nStartRow - start heading row ID
840 * @param nEndRow - end heading row ID
842 sal_uInt16 LwpTableLayout::ConvertHeadingRow(
843 rtl::Reference<XFTable> const & pXFTable, sal_uInt16 nStartHeadRow, sal_uInt16 nEndHeadRow)
845 sal_uInt16 nContentRow;
846 sal_uInt8 nCol = static_cast<sal_uInt8>(GetTable()->GetColumn());
847 XFTable* pTmpTable = new XFTable;
848 XFRow* pXFRow;
850 ConvertTable(pTmpTable,nStartHeadRow,nEndHeadRow,0,nCol);
852 sal_uInt16 nRowNum = pTmpTable->GetRowCount();
853 sal_uInt8* CellMark = new sal_uInt8[nRowNum];
855 if (nRowNum == 1)
857 pXFRow = pTmpTable->GetRow(1);
858 pXFTable->AddHeaderRow(pXFRow);
859 pTmpTable->RemoveRow(1);
860 nContentRow = nEndHeadRow;
862 else
864 sal_uInt8 nFirstColSpann = 1;
865 const bool bFindFlag = FindSplitColMark(pTmpTable,CellMark,nFirstColSpann);
867 if (bFindFlag)//split to 2 cells
869 SplitRowToCells(pTmpTable,pXFTable,nFirstColSpann,CellMark);
870 nContentRow = nEndHeadRow;
872 else//can not split,the first row will be the heading row,the rest will be content row
874 pXFRow = pTmpTable->GetRow(1);
875 pXFTable->AddHeaderRow(pXFRow);
876 pTmpTable->RemoveRow(1);
877 nContentRow = m_RowsMap[0]->GetCurMaxSpannedRows(0,nCol);
880 delete pTmpTable;
881 delete [] CellMark;
882 return nContentRow;
885 void LwpTableLayout::SplitRowToCells(XFTable* pTmpTable, rtl::Reference<XFTable> const & pXFTable,
886 sal_uInt8 nFirstColSpann,sal_uInt8* pCellMark)
888 sal_uInt16 i;
889 sal_uInt8 j;
890 sal_uInt16 nRowNum = pTmpTable->GetRowCount();
891 sal_uInt8 nCol = static_cast<sal_uInt8>(GetTable()->GetColumn());
893 XFRow* pXFRow = new XFRow;
895 //register style for heading row
896 double fHeight = 0;
897 OUString styleName;
898 XFRowStyle* pRowStyle = new XFRowStyle;
899 styleName = pTmpTable->GetRow(1)->GetStyleName();
901 // get settings of the row and assign them to new row style
902 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
903 XFRowStyle *pTempRowStyle = static_cast<XFRowStyle*>(pXFStyleManager->FindStyle(styleName));
904 if (pTempRowStyle)
905 *pRowStyle = *pTempRowStyle;
907 for (i=1;i<=nRowNum;i++)
909 styleName = pTmpTable->GetRow(i)->GetStyleName();
910 fHeight+=static_cast<XFRowStyle*>(pXFStyleManager->FindStyle(styleName))->GetRowHeight();
912 if (m_nDirection & 0x0030)
914 pRowStyle->SetMinRowHeight((float)fHeight);
916 else
918 pRowStyle->SetRowHeight((float)fHeight);
920 pXFRow->SetStyleName(pXFStyleManager->AddStyle(pRowStyle).m_pStyle->GetStyleName());
922 //construct heading row
923 XFCell* pXFCell1 = new XFCell;
924 XFCell* pXFCell2 = new XFCell;
925 XFTable* pSubTable1 = new XFTable;
926 XFTable* pSubTable2 = new XFTable;
927 XFRow* pNewRow;
928 XFRow* pOldRow;
929 XFCell* pNewCell;
931 for (i=1;i<=nRowNum;i++)
933 pOldRow = pTmpTable->GetRow(i);
934 pNewRow = new XFRow;
935 pNewRow->SetStyleName(pOldRow->GetStyleName());
936 for (j=1;j<=pCellMark[i];j++)
938 pNewCell = pOldRow->GetCell(j);
939 pNewRow->AddCell(pNewCell);
941 pSubTable1->AddRow(pNewRow);
943 ConvertColumn(pSubTable1,0,nFirstColSpann);//add column info
945 pXFCell1->Add(pSubTable1);
946 pXFCell1->SetColumnSpaned(nFirstColSpann);
947 pXFRow->AddCell(pXFCell1);
949 for (i=1;i<=nRowNum;i++)
951 pOldRow = pTmpTable->GetRow(i);
952 pNewRow = new XFRow;
953 pNewRow->SetStyleName(pOldRow->GetStyleName());
954 for(j=pCellMark[i]+1;j<=pOldRow->GetCellCount();j++)
956 pNewCell = pOldRow->GetCell(j);
957 pNewRow->AddCell(pNewCell);
959 pSubTable2->AddRow(pNewRow);
962 ConvertColumn(pSubTable2,nFirstColSpann,nCol);//add column info
963 pXFCell2->Add(pSubTable2);
964 pXFCell2->SetColumnSpaned(nCol-nFirstColSpann);
965 pXFRow->AddCell(pXFCell2);
967 pXFTable->AddHeaderRow(pXFRow);
969 //remove tmp table
970 for (i=1;i<=nRowNum;i++)
972 pOldRow = pTmpTable->GetRow(i);
973 for(j=1;j<=pOldRow->GetCellCount();j++)
974 pOldRow->RemoveCell(j);
975 pTmpTable->RemoveRow(i);
980 * @short find if the heading rows can be split to 2 cells
981 * @param pXFTable - pointer of tmp XFtable
982 * @param CellMark - pointer of cell mark array
984 bool LwpTableLayout::FindSplitColMark(XFTable* pXFTable, sal_uInt8* pCellMark,
985 sal_uInt8& nMaxColSpan)
987 sal_uInt16 nRowNum = pXFTable->GetRowCount();
988 sal_uInt8 nColNum = static_cast<sal_uInt8>(pXFTable->GetColumnCount());
989 sal_uInt8 nCellMark=0;
990 sal_uInt8 nCount;
991 sal_uInt8 nColSpan;
992 bool bFindFlag = false;
993 XFRow* pTmpRow;
995 for(sal_uInt8 i=1;i<=nColNum;i++)
997 sal_uInt16 nRowLoop;
998 sal_uInt8 nCellLoop;
1000 //find current max column span
1001 nMaxColSpan = 1;
1002 for (nRowLoop=1;nRowLoop<=nRowNum;nRowLoop++)
1004 nColSpan = 0;
1005 for(nCellLoop=1; nCellLoop<i+1; nCellLoop++)
1007 pTmpRow = pXFTable->GetRow(nRowLoop);
1008 XFCell* pCell = pTmpRow->GetCell(nCellLoop);
1009 if (pCell)
1010 nColSpan += static_cast<sal_uInt8>(pCell->GetColSpaned());
1011 else
1012 return false;
1014 if (nColSpan > nMaxColSpan)
1015 nMaxColSpan = nColSpan;
1016 pCellMark[nRowLoop] = 0;//reset all cell mark to zero
1019 //find if other row has the same column
1020 for (nRowLoop=1;nRowLoop<=nRowNum;nRowLoop++)
1022 pTmpRow = pXFTable->GetRow(nRowLoop);
1023 nCount = 0;
1024 nCellMark = 0;
1025 for (nCellLoop=1; nCellLoop<=pTmpRow->GetCellCount(); nCellLoop++)
1027 if (nCount>nMaxColSpan)
1028 break;
1029 nCount+= static_cast<sal_uInt8>(pTmpRow->GetCell(nCellLoop)->GetColSpaned());
1030 if (nCount == nMaxColSpan)
1032 nCellMark = nCellLoop;
1033 break;
1036 if (nCellMark == 0)
1037 break;
1038 else
1039 pCellMark[nRowLoop] = nCellMark;
1041 for(nRowLoop=1;nRowLoop<=nRowNum;nRowLoop++)//check if all ==0,break
1043 if (pCellMark[nRowLoop] == 0)
1044 break;
1046 if (nRowLoop == nRowNum+1)
1048 bFindFlag = true;
1049 return bFindFlag;
1053 return bFindFlag;
1057 * @short convert word pro table to SODC table
1058 * @param pXFTable - pointer of table
1059 * @param nStartRow - start row ID
1060 * @param nEndRow - end row ID
1061 * @param nStartCol - start column ID
1062 * @param nEndCol - end column ID
1064 void LwpTableLayout::ConvertTable(rtl::Reference<XFTable> const & pXFTable, sal_uInt16 nStartRow,
1065 sal_uInt16 nEndRow,sal_uInt8 nStartCol,sal_uInt8 nEndCol)
1067 //out put column info TO BE CHANGED
1068 ConvertColumn(pXFTable,nStartCol,nEndCol);
1070 std::map<sal_uInt16,LwpRowLayout*>::iterator iter;
1072 for (sal_uInt16 i=nStartRow; i<nEndRow;)
1074 iter = m_RowsMap.find(i);
1075 if (iter == m_RowsMap.end())
1077 ConvertDefaultRow(pXFTable,nStartCol,nEndCol,i);
1078 i++;
1080 else
1082 LwpRowLayout* pRow = iter->second;
1083 if (pRow->GetCurMaxSpannedRows(nStartCol,nEndCol) == 1)
1085 pRow->ConvertCommonRow(pXFTable,nStartCol,nEndCol);
1086 i++;
1088 else
1090 pRow->ConvertRow(pXFTable,nStartCol,nEndCol);
1091 i += pRow->GetCurMaxSpannedRows(nStartCol,nEndCol);
1098 * @short apply numeric value and formula to cell
1099 * @param pFoundry - pointer of foundry
1100 * @param aTableID - table ID
1102 void LwpTableLayout::PutCellVals(LwpFoundry* pFoundry, LwpObjectID aTableID)
1105 //Comment:The old code doesn't check if the LwpFoundry pointer is NULL,
1106 // So the NULL pointer cause sodc frozen. Add code to check the
1107 // the pointer.
1108 //New Code
1109 if( !pFoundry ) return;
1111 try{
1113 LwpDLVListHeadHolder* pHolder = dynamic_cast<LwpDLVListHeadHolder*>(pFoundry->GetNumberManager().GetTableRangeID().obj().get());
1115 LwpTableRange* pTableRange = pHolder ? dynamic_cast<LwpTableRange*>(pHolder->GetHeadID().obj().get()) : nullptr;
1117 //Look up the table
1118 while (nullptr!=pTableRange)
1120 LwpObjectID aID = pTableRange->GetTableID();
1121 if (aID == aTableID)
1123 break;
1125 pTableRange = pTableRange->GetNext();
1128 if (!pTableRange)
1129 return;
1131 LwpCellRange* pRange = dynamic_cast<LwpCellRange*>(pTableRange->GetCellRangeID().obj().get());
1132 if (!pRange)
1133 return;
1135 LwpFolder* pFolder = dynamic_cast<LwpFolder*>(pRange->GetFolderID().obj().get());
1136 if (!pFolder)
1137 return;
1139 LwpObjectID aRowListID = pFolder->GetChildHeadID();
1140 LwpRowList* pRowList = dynamic_cast<LwpRowList*>(aRowListID.obj().get());
1142 //loop the rowlist
1143 while( nullptr!=pRowList)
1145 sal_uInt16 nRowID = pRowList->GetRowID();
1147 LwpCellList* pCellList = dynamic_cast<LwpCellList*>(pRowList->GetChildHeadID().obj().get());
1148 //loop the cellList
1149 while( nullptr!=pCellList)
1151 {//put cell
1152 sal_uInt16 nColID = pCellList->GetColumnID();
1154 XFCell* pCell = GetCellsMap(nRowID,static_cast<sal_uInt8>(nColID));
1155 if (pCell)
1157 pCellList->Convert(pCell, this);
1159 //process paragraph
1160 PostProcessParagraph(pCell, nRowID, nColID);
1162 else
1164 //Hidden cell would not be in cellsmap
1165 assert(false);
1168 pCellList = dynamic_cast<LwpCellList*>(pCellList->GetNextID().obj().get());
1171 pRowList = dynamic_cast<LwpRowList*>(pRowList->GetNextID().obj().get());
1174 }catch (...) {
1175 assert(false);
1180 * @short 1. set number right alignment to right if number 2. remove tab added before if number
1181 * @param pCell - cell which to be process
1182 * @param nRowID - row number in Word Pro file
1183 * @param nColID - column number in Word Pro file
1185 void LwpTableLayout::PostProcessParagraph(XFCell *pCell, sal_uInt16 nRowID, sal_uInt16 nColID)
1187 // if number right, set alignment to right
1188 LwpCellLayout * pCellLayout = GetCellByRowCol(nRowID, nColID);
1189 if(pCellLayout)
1191 rtl::Reference<XFContent> first(
1192 pCell->FindFirstContent(enumXFContentPara));
1193 XFParagraph * pXFPara = static_cast<XFParagraph*>(first.get());
1194 if (!pXFPara)
1195 return;
1196 XFColor aNullColor = XFColor();
1198 if ( pXFPara)
1200 OUString sNumfmt = pCellLayout->GetNumfmtName();
1201 bool bColorMod = false;
1202 XFNumberStyle* pNumStyle = nullptr;
1203 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
1204 if (!sNumfmt.isEmpty())
1206 pNumStyle = static_cast<XFNumberStyle*>(pXFStyleManager->FindStyle( sNumfmt));
1207 XFColor aColor = pNumStyle->GetColor();
1208 if ( aColor != aNullColor )
1209 bColorMod = true;//end
1212 XFParaStyle * pStyle = pXFStyleManager->FindParaStyle(pXFPara->GetStyleName());
1213 if ((pStyle && pStyle->GetNumberRight()) || bColorMod)
1215 XFParaStyle* pOverStyle = new XFParaStyle;
1217 if (pStyle)
1219 *pOverStyle = *pStyle;
1221 if (pStyle->GetNumberRight())
1222 pOverStyle->SetAlignType(enumXFAlignEnd);
1225 if (bColorMod)
1227 rtl::Reference<XFFont> xFont = pOverStyle->GetFont();
1228 if (xFont.is())
1230 XFColor aColor = xFont->GetColor();
1231 if ( aColor == aNullColor )
1233 rtl::Reference<XFFont> pNewFont = new XFFont;
1234 aColor = pNumStyle->GetColor();
1235 pNewFont->SetColor(aColor);
1236 pOverStyle->SetFont(pNewFont);
1241 pOverStyle->SetStyleName("");
1242 OUString StyleName = pXFStyleManager->AddStyle(pOverStyle).m_pStyle->GetStyleName();
1244 pXFPara->SetStyleName(StyleName);
1251 * @short Parse all cols of table
1252 * @param pXFTable - pointer to created XFTable
1254 void LwpTableLayout::ConvertColumn(rtl::Reference<XFTable> const & pXFTable, sal_uInt8 nStartCol, sal_uInt8 nEndCol)
1256 LwpTable * pTable = GetTable();
1257 if (!pTable)
1259 assert(false);
1260 return;
1263 for (sal_uInt32 iLoop = 0; iLoop < static_cast<sal_uInt32>(nEndCol)-nStartCol; ++iLoop)
1265 // add row to table
1266 LwpObjectID& rColID = GetColumnLayoutHead();
1267 LwpColumnLayout * pColumnLayout = dynamic_cast<LwpColumnLayout *>(rColID.obj().get());
1268 while (pColumnLayout)
1270 if (pColumnLayout->GetColumnID() == (iLoop+nStartCol))
1272 pXFTable->SetColumnStyle(iLoop+1, pColumnLayout->GetStyleName());
1273 break;
1275 rColID = pColumnLayout->GetNext();
1276 pColumnLayout = dynamic_cast<LwpColumnLayout *>(rColID.obj().get());
1278 if (!pColumnLayout)
1280 pXFTable->SetColumnStyle(iLoop+1, m_DefaultColumnStyleName);
1285 * @short split conflict merged cells
1287 void LwpTableLayout::SplitConflictCells()
1289 LwpTable * pTable = GetTable();
1290 if (!pTable)
1291 return;
1292 sal_uInt16 nCol = pTable->GetColumn();
1293 sal_uInt16 nRow = pTable->GetRow();
1295 sal_uInt16 nEffectRows;
1296 std::map<sal_uInt16,LwpRowLayout*>::iterator iter1;
1297 std::map<sal_uInt16,LwpRowLayout*>::iterator iter2;
1298 LwpRowLayout* pRowLayout;
1299 LwpRowLayout* pEffectRow;
1301 for (sal_uInt16 i=0; i<nRow; )
1303 iter1 = m_RowsMap.find(i);
1304 if (iter1 == m_RowsMap.end())//default rows
1306 i++;
1307 continue;
1309 pRowLayout= iter1->second;
1310 if (!pRowLayout->GetMergeCellFlag())
1312 i++;
1313 continue;
1315 else
1317 nEffectRows = i + pRowLayout->GetCurMaxSpannedRows(0,(sal_uInt8)nCol);
1319 for (sal_uInt16 j = i+1; j<nEffectRows; j++)
1321 iter2 = m_RowsMap.find(j);
1322 if (iter2 == m_RowsMap.end())
1323 continue;
1324 pEffectRow = iter2->second;
1325 if (!pEffectRow->GetMergeCellFlag())
1326 continue;
1327 else
1328 pEffectRow->SetCellSplit(nEffectRows);
1330 i = nEffectRows;
1332 }//end for
1336 * @short add default row which are missing in the file
1337 * @param pXFTable - pointer to new created table
1338 * @param nStartCol - starting column
1339 * @param nEndCol - end column
1340 * @return pXFTable
1342 void LwpTableLayout::ConvertDefaultRow(rtl::Reference<XFTable> const & pXFTable, sal_uInt8 nStartCol,
1343 sal_uInt8 nEndCol, sal_uInt16 nRowID)
1345 // current row doesn't exist in the file
1346 XFRow * pRow = new XFRow();
1347 pRow->SetStyleName(m_DefaultRowStyleName);
1349 for (sal_uInt16 j =0;j < nEndCol-nStartCol; j++)
1351 // if table has default cell layout, use it to ConvertCell
1352 // otherwise use blank cell
1353 XFCell * pCell = nullptr;
1354 if (m_pDefaultCellLayout)
1356 pCell = m_pDefaultCellLayout->ConvertCell(
1357 GetTable()->GetObjectID(),nRowID,j+nStartCol);
1359 else
1361 pCell = new XFCell();
1363 pRow->AddCell(pCell);
1366 pXFTable->AddRow(pRow);
1369 * @short set cell map info
1370 * @param pXFCell - pointer to xfcell
1371 * @param nRow - row id
1372 * @param nCol - column id
1374 void LwpTableLayout::SetCellsMap(sal_uInt16 nRow,sal_uInt8 nCol,XFCell* pXFCell)
1376 std::pair<std::pair<sal_uInt16,sal_uInt8>,XFCell*> cell;
1377 std::pair<sal_uInt16,sal_uInt8> pos;
1378 pos.first = nRow;
1379 pos.second = nCol;
1380 cell.first = pos;
1381 cell.second = pXFCell;
1382 m_CellsMap.insert(cell);
1386 * @short get cell map info
1387 * @param nRow - row id
1388 * @param nCol - column id
1389 * @return pXFCell
1391 XFCell* LwpTableLayout::GetCellsMap(sal_uInt16 nRow,sal_uInt8 nCol)
1393 std::pair<sal_uInt16,sal_uInt8> pos;
1394 pos.first = nRow;
1395 pos.second = nCol;
1396 std::map<std::pair<sal_uInt16,sal_uInt8>,XFCell*>::iterator iter;
1397 iter = m_CellsMap.find(pos);
1398 if (iter == m_CellsMap.end())
1399 return nullptr;
1400 return iter->second;
1403 * @descr Get row layout by row id
1404 * @param nRow - row id
1406 LwpRowLayout* LwpTableLayout::GetRowLayout(sal_uInt16 nRow)
1408 LwpObjectID& rRowID = GetChildHead();
1409 LwpRowLayout * pRowLayout = dynamic_cast<LwpRowLayout *>(rRowID.obj().get());
1410 while (pRowLayout)
1412 if(pRowLayout->GetRowID() == nRow)
1413 return pRowLayout;
1415 rRowID = pRowLayout->GetNext();
1416 pRowLayout = dynamic_cast<LwpRowLayout *>(rRowID.obj().get());
1418 return nullptr;
1421 //add end by
1422 LwpColumnLayout::LwpColumnLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
1423 : LwpVirtualLayout(objHdr, pStrm)
1424 , ccolid(0)
1425 , cwidth(0)
1428 LwpColumnLayout::~LwpColumnLayout()
1430 void LwpColumnLayout::Read()
1432 LwpObjectStream* pStrm = m_pObjStrm;
1434 LwpVirtualLayout::Read();
1436 sal_uInt16 colid;
1438 colid = pStrm->QuickReaduInt16(); // forced to lushort
1439 ccolid = (sal_uInt8)colid; // Phillip
1440 cwidth = pStrm->QuickReadInt32();
1442 pStrm->SkipExtra();
1445 void LwpColumnLayout::RegisterStyle(double dCalculatedWidth)
1447 XFColStyle * pColStyle = new XFColStyle();
1448 pColStyle->SetWidth(static_cast<float>(dCalculatedWidth));
1449 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
1450 m_StyleName = pXFStyleManager->AddStyle(pColStyle).m_pStyle->GetStyleName();
1453 LwpTableHeadingLayout::LwpTableHeadingLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
1454 : LwpTableLayout(objHdr, pStrm)
1455 , cStartRow(0)
1456 , cEndRow(0)
1459 LwpTableHeadingLayout::~LwpTableHeadingLayout()
1462 * @short read table heading layout
1463 * @param
1464 * @return
1466 void LwpTableHeadingLayout::Read()
1468 LwpTableLayout::Read();
1470 cStartRow = m_pObjStrm->QuickReaduInt16();
1471 cEndRow = m_pObjStrm->QuickReaduInt16();
1473 m_pObjStrm->SkipExtra();
1477 * @short get start and end row number of table heading
1478 * @param
1479 * @return *pStartRow - starting row number
1480 * @return *pEndRow - end row number
1482 void LwpTableHeadingLayout::GetStartEndRow(sal_uInt16& nStartRow, sal_uInt16& nEndRow)
1484 nStartRow = cStartRow;
1485 nEndRow = cEndRow;
1488 LwpSuperParallelColumnLayout::LwpSuperParallelColumnLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm):LwpSuperTableLayout(objHdr, pStrm)
1491 LwpSuperParallelColumnLayout::~LwpSuperParallelColumnLayout()
1494 void LwpSuperParallelColumnLayout::Read()
1496 LwpSuperTableLayout::Read();
1497 m_pObjStrm->SkipExtra();
1501 LwpSuperGlossaryLayout::LwpSuperGlossaryLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm):LwpSuperTableLayout(objHdr, pStrm)
1505 LwpSuperGlossaryLayout::~LwpSuperGlossaryLayout()
1509 void LwpSuperGlossaryLayout::Read()
1511 LwpSuperTableLayout::Read();
1512 m_pObjStrm->SkipExtra();
1515 LwpParallelColumnsLayout::LwpParallelColumnsLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm):LwpTableLayout(objHdr, pStrm)
1519 LwpParallelColumnsLayout::~LwpParallelColumnsLayout()
1523 void LwpParallelColumnsLayout::Read()
1525 LwpTableLayout::Read();
1526 m_pObjStrm->SkipExtra();
1529 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */