fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / lotuswordpro / source / filter / lwptablelayout.cxx
blobe2edf492bda4d441acbd45e198fcd1917e0d6ad2
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
60 /*************************************************************************
61 * Change History
62 Mar 2005 Created
63 ************************************************************************/
64 #include "lwpglobalmgr.hxx"
65 #include "lwptablelayout.hxx"
66 #include "lwpfoundry.hxx"
67 #include "lwpobjfactory.hxx"
68 #include "lwpholder.hxx"
69 #include "lwptable.hxx"
70 #include "lwptblcell.hxx"
71 #include "lwpnumericfmt.hxx"
72 #include "lwpdlvlist.hxx"
73 #include "lwppara.hxx"
75 #include "xfilter/xfstylemanager.hxx"
76 #include "xfilter/xftablestyle.hxx"
77 #include "xfilter/xftable.hxx"
78 #include "xfilter/xfrow.hxx"
79 #include "xfilter/xfrowstyle.hxx"
80 #include "xfilter/xfcell.hxx"
81 #include "xfilter/xfcellstyle.hxx"
82 #include "xfilter/xfcolstyle.hxx"
83 #include "xfilter/xfframestyle.hxx"
84 #include "xfilter/xfframe.hxx"
85 #include "xfilter/xffloatframe.hxx"
86 #include "lwpframelayout.hxx"
87 #include "xfilter/xfparastyle.hxx"
89 LwpSuperTableLayout::LwpSuperTableLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
90 : LwpPlacableLayout(objHdr, pStrm)
92 m_pFrame = new LwpFrame(this);
95 LwpSuperTableLayout::~LwpSuperTableLayout()
97 if(m_pFrame)
99 delete m_pFrame;
103 * @short Read super table layout record
105 void LwpSuperTableLayout::Read()
107 LwpPlacableLayout::Read();
108 m_pObjStrm->SkipExtra();
112 * @short Get child table layout
113 * @return pointer to table layout
115 LwpTableLayout* LwpSuperTableLayout::GetTableLayout()
117 LwpObjectID& rID = GetChildTail();
119 while(!rID.IsNull())
121 LwpLayout* pLayout = dynamic_cast<LwpLayout*>(rID.obj().get());
122 if (!pLayout)
124 break;
126 if (pLayout->GetLayoutType() == LWP_TABLE_LAYOUT)
128 return dynamic_cast<LwpTableLayout *>(pLayout);
130 rID = pLayout->GetPrevious();
133 return NULL;
136 * @short Get effective heading table layout, the one just before table layout is the only one which is effective
137 * @return LwpTableHeadingLayout* - pointer to table heading layout
139 LwpTableHeadingLayout* LwpSuperTableLayout::GetTableHeadingLayout()
141 LwpObjectID& rID = GetChildTail();
143 while(!rID.IsNull())
145 LwpLayout * pLayout = dynamic_cast<LwpLayout *>(rID.obj().get());
146 if (!pLayout)
148 break;
151 if (pLayout->GetLayoutType() == LWP_TABLE_HEADING_LAYOUT)
153 return dynamic_cast<LwpTableHeadingLayout *>(pLayout);
155 rID = pLayout->GetPrevious();
158 return NULL;
161 * @short Register super table layout style
163 void LwpSuperTableLayout::RegisterNewStyle()
165 // if this layout is style of real table entry
166 LwpTableLayout* pTableLayout = GetTableLayout();
167 if (pTableLayout != NULL)
169 pTableLayout->SetFoundry(m_pFoundry);
170 pTableLayout->RegisterStyle();
174 * @short Judge whether table size is according to content, borrowed from Word Pro code
175 * @param
176 * @return sal_Bool
178 bool LwpSuperTableLayout::IsSizeRightToContent()
180 /* Only "with paragraph above" tables can size right to content. */
181 if (GetRelativeType() == LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE)
182 return LwpPlacableLayout::IsSizeRightToContent();
184 return false;
187 * @short Judge whether table is justifiable, borrowed from Word Pro code
188 * @param
189 * @return sal_Bool
191 bool LwpSuperTableLayout::IsJustifiable()
193 return (GetRelativeType() != LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE || IsSizeRightToContent());
196 * @short Get width of frame outside table
197 * @param pTableStyle - pointer of XFTableStyle
198 * @return double - table width
200 double LwpSuperTableLayout::GetWidth()
202 double dWidth = GetTableWidth();
203 double dLeft = GetMarginsValue(MARGIN_LEFT);
204 double dRight = GetMarginsValue(MARGIN_RIGHT);
206 return (dWidth + dLeft + dRight);
209 * @short Get width of table
210 * @param pTableStyle - pointer of XFTableStyle
211 * @return double - table width
213 double LwpSuperTableLayout::GetTableWidth()
215 sal_Int32 nWidth = 0;
216 if(!IsJustifiable() || ((nWidth = LwpMiddleLayout::GetMinimumWidth()) <= 0))
218 LwpTableLayout* pTableLayout = GetTableLayout();
219 if(!pTableLayout)
221 assert(false);
222 return 0;
224 LwpTable *pTable = pTableLayout->GetTable();
225 if(!pTable)
227 assert(false);
228 return 0;
230 double dDefaultWidth = pTable->GetWidth();
231 sal_uInt16 nCol = pTable->GetColumn();
233 double dWidth = 0;
235 for(sal_uInt16 i =0; i< nCol; i++)
237 LwpObjectID& rColumnID = pTableLayout->GetColumnLayoutHead();
238 LwpColumnLayout * pColumnLayout = dynamic_cast<LwpColumnLayout *>(rColumnID.obj().get());
239 double dColumnWidth = dDefaultWidth;
240 while (pColumnLayout)
242 if(pColumnLayout->GetColumnID() == i)
244 dColumnWidth = pColumnLayout->GetWidth();
245 break;
247 rColumnID = pColumnLayout->GetNext();
248 pColumnLayout = dynamic_cast<LwpColumnLayout *>(rColumnID.obj().get());
250 dWidth += dColumnWidth;
253 return dWidth;
256 double dLeft = GetMarginsValue(MARGIN_LEFT);
257 double dRight = GetMarginsValue(MARGIN_RIGHT);
258 return LwpTools::ConvertFromUnitsToMetric(nWidth)-dLeft-dRight;
262 * @short Apply shadow to table
263 * @param pTableStyle - pointer of XFTableStyle
264 * @return
266 void LwpSuperTableLayout::ApplyShadow(XFTableStyle *pTableStyle)
268 // use shadow property of supertable
269 boost::scoped_ptr<XFShadow> pXFShadow(GetXFShadow());
270 if(pXFShadow)
272 pTableStyle->SetShadow(pXFShadow->GetPosition(), pXFShadow->GetOffset(), pXFShadow->GetColor());
276 * @short Apply pattern fill to table style
277 * @param pTableStyle - pointer of XFTableStyle
278 * @return
280 void LwpSuperTableLayout::ApplyPatternFill(XFTableStyle* pTableStyle)
282 XFBGImage* pXFBGImage = this->GetFillPattern();
283 if (pXFBGImage)
285 pTableStyle->SetBackImage(pXFBGImage);
290 * @short Apply background to table style
291 * @param pTableStyle - pointer of XFTableStyle
292 * @return
294 void LwpSuperTableLayout::ApplyBackGround(XFTableStyle* pTableStyle)
296 if (this->IsPatternFill())
298 ApplyPatternFill(pTableStyle);
300 else
302 ApplyBackColor(pTableStyle);
306 * @short Apply back color to table
307 * @param pTableStyle - pointer of XFTableStyle
308 * @return
310 void LwpSuperTableLayout::ApplyBackColor(XFTableStyle *pTableStyle)
312 LwpColor* pColor = GetBackColor();
313 if(pColor && pColor->IsValidColor())
315 XFColor aColor(pColor->To24Color());
316 pTableStyle->SetBackColor(aColor);
320 * @short Apply watermark to table
321 * @param pTableStyle - pointer of XFTableStyle
322 * @return
324 void LwpSuperTableLayout::ApplyWatermark(XFTableStyle *pTableStyle)
326 XFBGImage* pBGImage = GetXFBGImage();
327 if(pBGImage)
329 pTableStyle->SetBackImage(pBGImage);
333 * @short Apply alignment to table
334 * @param pTableStyle - pointer of XFTableStyle
335 * @return
337 void LwpSuperTableLayout::ApplyAlignment(XFTableStyle * pTableStyle)
339 LwpPoint aPoint;
340 if (GetGeometry())
341 aPoint = GetGeometry()->GetOrigin();
342 //LwpPoint aPoint = GetOrigin();
343 double dXOffset = LwpTools::ConvertFromUnitsToMetric(aPoint.GetX());
345 // add left padding to alignment distance
346 double dLeft = GetMarginsValue(MARGIN_LEFT);
348 pTableStyle->SetAlign(enumXFAlignStart, dXOffset+ dLeft);
351 * @short Add table to container
352 * @param pCont - pointer of container
353 * @return pCont
355 void LwpSuperTableLayout::XFConvert(XFContentContainer* pCont)
357 if ( LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE == GetRelativeType()
358 && !GetContainerLayout()->IsCell())
360 LwpTableLayout * pTableLayout = GetTableLayout();
361 if (pTableLayout)
363 pTableLayout->XFConvert(pCont);
366 else if(IsRelativeAnchored())
368 //anchor to paragraph except "with paragraph above"
369 XFConvertFrame(pCont);
371 else if(m_pFrame)
373 //anchor to page, frame, cell
374 m_pFrame->XFConvert(pCont);
378 * @short convert frame which anchor to page
379 * @param
380 * @return
382 void LwpSuperTableLayout::XFConvertFrame(XFContentContainer* pCont, sal_Int32 nStart, sal_Int32 nEnd, bool bAll)
384 if(m_pFrame)
386 XFFrame* pXFFrame = NULL;
387 if(nEnd < nStart)
389 pXFFrame = new XFFrame();
391 else
393 pXFFrame = new XFFloatFrame(nStart, nEnd, bAll);
396 m_pFrame->Parse(pXFFrame, static_cast<sal_uInt16>(nStart));
397 //parse table, and add table to frame
398 LwpTableLayout * pTableLayout = GetTableLayout();
399 if (pTableLayout)
401 pTableLayout->XFConvert(pXFFrame);
403 //add frame to the container
404 pCont ->Add(pXFFrame);
409 * @short register frame style
410 * @param
411 * @return
413 void LwpSuperTableLayout::RegisterFrameStyle()
415 XFFrameStyle* pFrameStyle = new XFFrameStyle();
416 m_pFrame->RegisterStyle(pFrameStyle);
419 LwpTableLayout::LwpTableLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
420 : LwpLayout(objHdr, pStrm)
421 , m_nRows(0)
422 , m_nCols(0)
423 , m_pDefaultCellLayout(NULL)
424 , m_pColumns(NULL)
425 , m_pXFTable(NULL)
427 m_CellsMap.clear();
430 LwpTableLayout::~LwpTableLayout()
432 m_CellsMap.clear();
434 if (m_pColumns)
436 delete [] m_pColumns;
437 m_pColumns = NULL;
442 * @short Get neighbour cell by specifying ROW+COL
443 * @param nRow
444 * @param nCol
445 * @return LwpCellLayout *
447 LwpCellLayout * LwpTableLayout::GetCellByRowCol(sal_uInt16 nRow, sal_uInt16 nCol)
449 if (nRow >= m_nRows || nCol >= m_nCols)
450 return NULL;
452 return m_WordProCellsMap[static_cast<size_t>(nRow)*m_nCols + nCol];
455 * @short traverse all table cells
456 * @param
457 * @param
458 * @param
460 void LwpTableLayout::TraverseTable()
462 sal_uInt32 nCount = m_nRows*m_nCols;
464 // new cell map nRow*nCOl and initialize
465 for (sal_uInt32 iLoop = 0; iLoop < nCount; ++iLoop)
467 m_WordProCellsMap.push_back(GetDefaultCellLayout());
470 // set value
471 LwpObjectID& rRowID = GetChildHead();
472 LwpRowLayout * pRowLayout = dynamic_cast<LwpRowLayout *>(rRowID.obj().get());
473 while (pRowLayout)
475 pRowLayout->SetRowMap();
477 // for 's analysis job
478 m_RowsMap[pRowLayout->GetRowID()] = pRowLayout;
479 pRowLayout->CollectMergeInfo();
480 // end for 's analysis
482 rRowID = pRowLayout->GetNext();
483 pRowLayout = dynamic_cast<LwpRowLayout *>(rRowID.obj().get());
488 * @short search the cell map
489 * @param nRow - row id (0 based)
490 * @param nRow - row id (0 based)
491 * @return LwpObjectID * - pointer to cell story object ID
493 LwpObjectID * LwpTableLayout::SearchCellStoryMap(sal_uInt16 nRow, sal_uInt16 nCol)
495 if (nRow >= m_nRows || nCol >= m_nCols )
497 return NULL;
500 LwpCellLayout * pCell = GetCellByRowCol(nRow, nCol);
501 if (pCell)
503 // maybe connected cell layout
504 // maybe default cell layout
505 if (nRow != pCell->GetRowID() || nCol != pCell->GetColID())
507 return NULL;
509 return &pCell->GetContent();
512 return NULL;
516 * @short Get parent super table layout of table layout
517 * @return LwpSuperTableLayout * - pointer of parent super table layout
519 LwpSuperTableLayout * LwpTableLayout::GetSuperTableLayout()
521 return dynamic_cast<LwpSuperTableLayout *>(GetParent().obj().get());
524 * @short Get table pointer
525 * @return LwpTable * - content table pointer
527 LwpTable * LwpTableLayout::GetTable()
529 LwpTable *pTable = dynamic_cast<LwpTable *>(m_Content.obj().get());
530 return pTable;
533 * @short Get column style name by column ID
534 * @param sal_uInt16 -- col id(0 based)
535 * @return OUString - name of column style
537 OUString LwpTableLayout::GetColumnWidth(sal_uInt16 nCol)
539 if (nCol >= m_nCols)
541 assert(false);
542 return m_DefaultColumnStyleName;
545 LwpColumnLayout * pCol = m_pColumns[nCol];
546 if (pCol)
548 return pCol->GetStyleName();
551 return m_DefaultColumnStyleName;
554 * @short analyze all columns to get whole table width and width of all columns
555 * @short and register all column styles
556 * @param none
558 void LwpTableLayout::RegisterColumns()
560 LwpTable * pTable = GetTable();
561 LwpSuperTableLayout * pSuper = GetSuperTableLayout();
563 sal_uInt16 nCols = m_nCols;
565 m_pColumns = new LwpColumnLayout *[nCols];
566 sal_Bool * pWidthCalculated = new sal_Bool[nCols];
567 for(sal_uInt16 i=0;i<nCols; i++)
569 pWidthCalculated[i] = sal_False;
570 m_pColumns[i] = NULL;
573 double dDefaultColumn = pTable->GetWidth();
574 sal_uInt16 nJustifiableColumn = nCols;
576 double dTableWidth = pSuper->GetTableWidth();
578 // Get total width of justifiable columns
579 // NOTICE: all default columns are regarded as justifiable columns
580 LwpObjectID& rColumnID = GetColumnLayoutHead();
581 LwpColumnLayout * pColumnLayout = dynamic_cast<LwpColumnLayout *>(rColumnID.obj().get());
582 while (pColumnLayout)
584 m_pColumns[pColumnLayout->GetColumnID()] = pColumnLayout;
585 if (!pColumnLayout->IsJustifiable())
587 pWidthCalculated[pColumnLayout->GetColumnID()] = sal_True;
588 dTableWidth -= pColumnLayout->GetWidth();
589 nJustifiableColumn --;
592 rColumnID = pColumnLayout->GetNext();
593 pColumnLayout = dynamic_cast<LwpColumnLayout *>(rColumnID.obj().get());
596 // if all columns are not justifiable, the rightmost column will be changed to justifiable
597 if(nJustifiableColumn == 0)
599 nJustifiableColumn ++;
600 if (m_pColumns[nCols - 1])
602 pWidthCalculated[nCols-1] = sal_False;
603 dTableWidth += m_pColumns[nCols-1]->GetWidth();
605 else
607 // this can't happen
608 dTableWidth = dDefaultColumn;
609 assert(false);
613 // justifiable columns will share the remain width averagely
614 dDefaultColumn = dTableWidth/nJustifiableColumn;
616 // register default column style
617 XFColStyle *pColStyle = new XFColStyle();
618 pColStyle->SetWidth(static_cast<float>(dDefaultColumn));
620 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
621 m_DefaultColumnStyleName = pXFStyleManager->AddStyle(pColStyle).m_pStyle->GetStyleName();
623 // register existed column style
624 sal_uInt16 i=0;
625 for( i=0;i<nCols; i++)
627 if(m_pColumns[i])
629 m_pColumns[i]->SetFoundry(m_pFoundry);
630 if(!pWidthCalculated[i])
632 // justifiable ----register style with calculated value
633 m_pColumns[i]->SetStyleName(m_DefaultColumnStyleName);
635 else
637 // not justifiable ---- register style with original value
638 m_pColumns[i]->RegisterStyle(m_pColumns[i]->GetWidth());
642 delete [] pWidthCalculated;
645 * @short register all row styles
646 * @param none
648 void LwpTableLayout::RegisterRows()
650 LwpTable * pTable = GetTable();
651 if (pTable == NULL)
653 assert(false);
654 return;
657 // register default row style
658 XFRowStyle * pRowStyle = new XFRowStyle();
659 if (m_nDirection & 0x0030)
661 pRowStyle->SetMinRowHeight((float)pTable->GetHeight());
663 else
665 pRowStyle->SetRowHeight((float)pTable->GetHeight());
667 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
668 m_DefaultRowStyleName = pXFStyleManager->AddStyle(pRowStyle).m_pStyle->GetStyleName();
670 // register style of rows
671 LwpObjectID& rRowID = GetChildHead();
672 LwpRowLayout * pRowLayout = dynamic_cast<LwpRowLayout *>(rRowID.obj().get());
673 while (pRowLayout)
675 pRowLayout->SetFoundry(m_pFoundry);
676 pRowLayout->RegisterStyle();
678 rRowID = pRowLayout->GetNext();
679 pRowLayout = dynamic_cast<LwpRowLayout *>(rRowID.obj().get());
683 * @short register table style, if needed, including frame style
684 * @param none
686 void LwpTableLayout::RegisterStyle()
688 // get super table layout
689 LwpSuperTableLayout * pSuper = GetSuperTableLayout();
690 if(!pSuper)
692 assert(false);
693 return;
696 // get table
697 LwpTable * pTable = GetTable();
698 if (pTable == NULL)
700 assert(false);
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()->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 stle
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 frozee. Add code to check the
755 // the pointer.
756 //New Code
757 if( GetFoundry() && GetTable() )
759 PutCellVals( GetFoundry(),GetTable()->GetObjectID() );
762 * @short read table layout
763 * @param none
765 void LwpTableLayout::ParseTable()
767 // get super table layout
768 LwpSuperTableLayout * pSuper = GetSuperTableLayout();
769 if(!pSuper)
771 assert(false);
772 return;
775 // set name of object
776 m_pXFTable = new XFTable;
777 m_pXFTable->SetTableName(pSuper->GetName().str());
778 // set table style
779 m_pXFTable->SetStyleName(m_StyleName);
781 sal_uInt16 nRow = m_nRows;
782 sal_uInt8 nCol = (sal_uInt8)m_nCols;
784 //process header rows
785 LwpTableHeadingLayout* pTableHeading;
786 pTableHeading = pSuper->GetTableHeadingLayout();
787 sal_uInt16 nStartHeadRow;
788 sal_uInt16 nEndHeadRow;
789 sal_uInt16 nContentRow;
790 if (pTableHeading)
792 pTableHeading->GetStartEndRow(nStartHeadRow,nEndHeadRow);
793 if (nStartHeadRow != 0)
794 ConvertTable(m_pXFTable,0,nRow,0,nCol);
795 else
797 nContentRow = ConvertHeadingRow(m_pXFTable,nStartHeadRow,nEndHeadRow+1);
798 ConvertTable(m_pXFTable,nContentRow,nRow,0,nCol);
801 else
802 ConvertTable(m_pXFTable,0,nRow,0,nCol);
806 * @short read table layout
807 * @param none
809 void LwpTableLayout::Read()
811 LwpLayout::Read();
813 // before layout hierarchy rework!
814 if(LwpFileHeader::m_nFileRevision < 0x000b)
816 assert(false);
818 m_ColumnLayout.ReadIndexed(m_pObjStrm);
820 m_pObjStrm->SkipExtra();
824 * @short Convert table
825 * @param
826 * @return pCont - container which will contain table
828 void LwpTableLayout::XFConvert(XFContentContainer* pCont)
831 pCont->Add(m_pXFTable);
834 * @short convert heading row
835 * @param pXFTable - pointer of table
836 * @param nStartRow - start heading row ID
837 * @param nEndRow - end heading row ID
839 sal_uInt16 LwpTableLayout::ConvertHeadingRow(
840 XFTable* pXFTable,sal_uInt16 nStartHeadRow,sal_uInt16 nEndHeadRow)
842 sal_uInt16 nContentRow;
843 sal_uInt8 nCol = static_cast<sal_uInt8>(GetTable()->GetColumn());
844 XFTable* pTmpTable = new XFTable;
845 XFRow* pXFRow;
847 ConvertTable(pTmpTable,nStartHeadRow,nEndHeadRow,0,nCol);
849 sal_uInt16 nRowNum = pTmpTable->GetRowCount();
850 sal_uInt8* CellMark = new sal_uInt8[nRowNum];
852 if (nRowNum == 1)
854 pXFRow = pTmpTable->GetRow(1);
855 pXFTable->AddHeaderRow(pXFRow);
856 pTmpTable->RemoveRow(1);
857 nContentRow = nEndHeadRow;
859 else
861 sal_uInt8 nFirstColSpann = 1;
862 const bool bFindFlag = FindSplitColMark(pTmpTable,CellMark,nFirstColSpann);
864 if (bFindFlag)//split to 2 cells
866 SplitRowToCells(pTmpTable,pXFTable,nFirstColSpann,CellMark);
867 nContentRow = nEndHeadRow;
869 else//can not split,the first row will be the heading row,the rest will be content row
871 pXFRow = pTmpTable->GetRow(1);
872 pXFTable->AddHeaderRow(pXFRow);
873 pTmpTable->RemoveRow(1);
874 nContentRow = m_RowsMap[0]->GetCurMaxSpannedRows(0,nCol);
877 delete pTmpTable;
878 delete [] CellMark;
879 return nContentRow;
882 void LwpTableLayout::SplitRowToCells(XFTable* pTmpTable,XFTable* pXFTable,
883 sal_uInt8 nFirstColSpann,sal_uInt8* pCellMark)
885 sal_uInt16 i;
886 sal_uInt8 j;
887 sal_uInt16 nRowNum = pTmpTable->GetRowCount();
888 sal_uInt8 nCol = static_cast<sal_uInt8>(GetTable()->GetColumn());
890 XFRow* pXFRow = new XFRow;
892 //register style for heading row
893 double fHeight = 0;
894 OUString styleName;
895 XFRowStyle* pRowStyle = new XFRowStyle;
896 styleName = pTmpTable->GetRow(1)->GetStyleName();
898 // get settings of the row and assign them to new row style
899 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
900 XFRowStyle *pTempRowStyle = static_cast<XFRowStyle*>(pXFStyleManager->FindStyle(styleName));
901 if (pTempRowStyle)
902 *pRowStyle = *pTempRowStyle;
904 for (i=1;i<=nRowNum;i++)
906 styleName = pTmpTable->GetRow(i)->GetStyleName();
907 fHeight+=static_cast<XFRowStyle*>(pXFStyleManager->FindStyle(styleName))->GetRowHeight();
909 if (m_nDirection & 0x0030)
911 pRowStyle->SetMinRowHeight((float)fHeight);
913 else
915 pRowStyle->SetRowHeight((float)fHeight);
917 pXFRow->SetStyleName(pXFStyleManager->AddStyle(pRowStyle).m_pStyle->GetStyleName());
919 //construct headong row
920 XFCell* pXFCell1 = new XFCell;
921 XFCell* pXFCell2 = new XFCell;
922 XFTable* pSubTable1 = new XFTable;
923 XFTable* pSubTable2 = new XFTable;
924 XFRow* pNewRow;
925 XFRow* pOldRow;
926 XFCell* pNewCell;
928 for (i=1;i<=nRowNum;i++)
930 pOldRow = pTmpTable->GetRow(i);
931 pNewRow = new XFRow;
932 pNewRow->SetStyleName(pOldRow->GetStyleName());
933 for (j=1;j<=pCellMark[i];j++)
935 pNewCell = pOldRow->GetCell(j);
936 pNewRow->AddCell(pNewCell);
938 pSubTable1->AddRow(pNewRow);
940 ConvertColumn(pSubTable1,0,nFirstColSpann);//add column info
942 pXFCell1->Add(pSubTable1);
943 pXFCell1->SetColumnSpaned(nFirstColSpann);
944 pXFRow->AddCell(pXFCell1);
946 for (i=1;i<=nRowNum;i++)
948 pOldRow = pTmpTable->GetRow(i);
949 pNewRow = new XFRow;
950 pNewRow->SetStyleName(pOldRow->GetStyleName());
951 for(j=pCellMark[i]+1;j<=pOldRow->GetCellCount();j++)
953 pNewCell = pOldRow->GetCell(j);
954 pNewRow->AddCell(pNewCell);
956 pSubTable2->AddRow(pNewRow);
959 ConvertColumn(pSubTable2,nFirstColSpann,nCol);//add column info
960 pXFCell2->Add(pSubTable2);
961 pXFCell2->SetColumnSpaned(nCol-nFirstColSpann);
962 pXFRow->AddCell(pXFCell2);
964 pXFTable->AddHeaderRow(pXFRow);
966 //remove tmp table
967 for (i=1;i<=nRowNum;i++)
969 pOldRow = pTmpTable->GetRow(i);
970 for(j=1;j<=pOldRow->GetCellCount();j++)
971 pOldRow->RemoveCell(j);
972 pTmpTable->RemoveRow(i);
977 * @short find if the heading rows can be split to 2 cells
978 * @param pXFTable - pointer of tmp XFtable
979 * @param CellMark - pointer of cell mark array
981 bool LwpTableLayout::FindSplitColMark(XFTable* pXFTable, sal_uInt8* pCellMark,
982 sal_uInt8& nMaxColSpan)
984 sal_uInt16 nRowNum = pXFTable->GetRowCount();
985 sal_uInt8 nColNum = static_cast<sal_uInt8>(pXFTable->GetColumnCount());
986 sal_uInt8 nCellMark=0;
987 sal_uInt8 nCount;
988 sal_uInt8 nColSpan;
989 bool bFindFlag = false;
990 XFRow* pTmpRow;
992 for(sal_uInt8 i=1;i<=nColNum;i++)
994 sal_uInt16 nRowLoop;
995 sal_uInt8 nCellLoop;
997 //find current max column span
998 nMaxColSpan = 1;
999 for (nRowLoop=1;nRowLoop<=nRowNum;nRowLoop++)
1001 nColSpan = 0;
1002 for(nCellLoop=1; nCellLoop<i+1; nCellLoop++)
1004 pTmpRow = pXFTable->GetRow(nRowLoop);
1005 XFCell* pCell = pTmpRow->GetCell(nCellLoop);
1006 if (pCell)
1007 nColSpan += static_cast<sal_uInt8>(pCell->GetColSpaned());
1008 else
1009 return false;
1011 if (nColSpan > nMaxColSpan)
1012 nMaxColSpan = nColSpan;
1013 pCellMark[nRowLoop] = 0;//reset all cell mark to zero
1016 //find if other row has the same column
1017 for (nRowLoop=1;nRowLoop<=nRowNum;nRowLoop++)
1019 pTmpRow = pXFTable->GetRow(nRowLoop);
1020 nCount = 0;
1021 nCellMark = 0;
1022 for (nCellLoop=1; nCellLoop<=pTmpRow->GetCellCount(); nCellLoop++)
1024 if (nCount>nMaxColSpan)
1025 break;
1026 nCount+= static_cast<sal_uInt8>(pTmpRow->GetCell(nCellLoop)->GetColSpaned());
1027 if (nCount == nMaxColSpan)
1029 nCellMark = nCellLoop;
1030 break;
1033 if (nCellMark == 0)
1034 break;
1035 else
1036 pCellMark[nRowLoop] = nCellMark;
1038 for(nRowLoop=1;nRowLoop<=nRowNum;nRowLoop++)//check if all ==0,break
1040 if (pCellMark[nRowLoop] == 0)
1041 break;
1043 if (nRowLoop == nRowNum+1)
1045 bFindFlag = true;
1046 return bFindFlag;
1050 return bFindFlag;
1054 * @short convert word pro table to SODC table
1055 * @param pXFTable - pointer of table
1056 * @param nStartRow - start row ID
1057 * @param nEndRow - end row ID
1058 * @param nStartCol - start column ID
1059 * @param nEndCol - end column ID
1061 void LwpTableLayout::ConvertTable(XFTable* pXFTable,sal_uInt16 nStartRow,
1062 sal_uInt16 nEndRow,sal_uInt8 nStartCol,sal_uInt8 nEndCol)
1064 //out put column info TO BE CHANGED
1065 ConvertColumn(pXFTable,nStartCol,nEndCol);
1067 std::map<sal_uInt16,LwpRowLayout*>::iterator iter;
1069 for (sal_uInt16 i=nStartRow; i<nEndRow;)
1071 iter = m_RowsMap.find(i);
1072 if (iter == m_RowsMap.end())
1074 ConvertDefaultRow(pXFTable,nStartCol,nEndCol,i);
1075 i++;
1077 else
1079 LwpRowLayout* pRow = iter->second;
1080 if (pRow->GetCurMaxSpannedRows(nStartCol,nEndCol) == 1)
1082 pRow->ConvertCommonRow(pXFTable,nStartCol,nEndCol);
1083 i++;
1085 else
1087 pRow->ConvertRow(pXFTable,nStartCol,nEndCol);
1088 i += pRow->GetCurMaxSpannedRows(nStartCol,nEndCol);
1095 * @short apply numeric value and formula to cell
1096 * @param pFoundry - pointer of foundry
1097 * @param aTableID - table ID
1099 void LwpTableLayout::PutCellVals(LwpFoundry* pFoundry, LwpObjectID aTableID)
1102 //Comment:The old code doesn't check if the LwpFoundry pointer is NULL,
1103 // So the NULL pointer cause sodc frozee. Add code to check the
1104 // the pointer.
1105 //New Code
1106 if( !pFoundry ) return;
1108 try{
1110 LwpDLVListHeadHolder* pHolder = static_cast<LwpDLVListHeadHolder*>(pFoundry->GetNumberManager().GetTableRangeID().obj().get());
1112 LwpTableRange* pTableRange = static_cast<LwpTableRange*>(pHolder->GetHeadID().obj().get());
1114 //Look up the table
1115 while (NULL!=pTableRange)
1117 LwpObjectID aID = pTableRange->GetTableID();
1118 if (aID == aTableID)
1120 break;
1122 pTableRange = pTableRange->GetNext();
1125 if (pTableRange)
1127 LwpCellRange* pRange = static_cast<LwpCellRange*>(pTableRange->GetCellRangeID().obj().get());
1128 LwpFolder* pFolder = static_cast<LwpFolder*>(pRange->GetFolderID().obj().get());
1129 LwpObjectID aRowListID = pFolder->GetChildHeadID();
1130 LwpRowList* pRowList = static_cast<LwpRowList*>(aRowListID.obj().get());
1132 //loop the rowlist
1133 while( NULL!=pRowList)
1135 sal_uInt16 nRowID = pRowList->GetRowID();
1137 LwpCellList* pCellList = static_cast<LwpCellList*>(pRowList->GetChildHeadID().obj().get());
1138 //loop the celllist
1139 while( NULL!=pCellList)
1141 {//put cell
1142 sal_uInt16 nColID = pCellList->GetColumnID();
1144 XFCell* pCell = GetCellsMap(nRowID,static_cast<sal_uInt8>(nColID));
1145 if (pCell)
1147 pCellList->Convert(pCell, this);
1149 //process paragraph
1150 PostProcessParagraph(pCell, nRowID, nColID);
1152 else
1154 //Hidden cell would not be in cellsmap
1155 assert(false);
1158 pCellList = static_cast<LwpCellList*>(pCellList->GetNextID().obj().get());
1161 pRowList = static_cast<LwpRowList*>(pRowList->GetNextID().obj().get());
1165 }catch (...) {
1166 assert(false);
1171 * @short 1. set number right alignment to right if number 2. remove tab added before if number
1172 * @param pCell - cell which to be process
1173 * @param nRowID - row number in Word Pro file
1174 * @param nColID - column number in Word Pro file
1176 void LwpTableLayout::PostProcessParagraph(XFCell *pCell, sal_uInt16 nRowID, sal_uInt16 nColID)
1178 // if number right, set alignment to right
1179 LwpCellLayout * pCellLayout = GetCellByRowCol(nRowID, nColID);
1180 if(pCellLayout)
1182 rtl::Reference<XFContent> first(
1183 pCell->FindFirstContent(enumXFContentPara));
1184 XFParagraph * pXFPara = static_cast<XFParagraph*>(first.get());
1185 if (!pXFPara)
1186 return;
1187 XFColor aNullColor = XFColor();
1189 if ( pXFPara)
1191 OUString sNumfmt = pCellLayout->GetNumfmtName();
1192 bool bColorMod = false;
1193 XFNumberStyle* pNumStyle = NULL;
1194 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
1195 if (!sNumfmt.isEmpty())
1197 pNumStyle = static_cast<XFNumberStyle*>(pXFStyleManager->FindStyle( sNumfmt));
1198 XFColor aColor = pNumStyle->GetColor();
1199 if ( aColor != aNullColor )
1200 bColorMod = true;//end
1203 XFParaStyle * pStyle = pXFStyleManager->FindParaStyle(pXFPara->GetStyleName());
1204 if ((pStyle && pStyle->GetNumberRight()) || bColorMod)
1206 XFParaStyle* pOverStyle = new XFParaStyle;
1208 if (pStyle)
1210 *pOverStyle = *pStyle;
1212 if (pStyle->GetNumberRight())
1213 pOverStyle->SetAlignType(enumXFAlignEnd);
1216 if (bColorMod)
1218 rtl::Reference<XFFont> pFont = pOverStyle->GetFont();
1219 XFColor aColor = pFont->GetColor();
1220 if ( aColor == aNullColor )
1222 rtl::Reference<XFFont> pNewFont = new XFFont;
1223 aColor = pNumStyle->GetColor();
1224 pNewFont->SetColor(aColor);
1225 pOverStyle->SetFont(pNewFont);
1229 pOverStyle->SetStyleName("");
1230 OUString StyleName = pXFStyleManager->AddStyle(pOverStyle).m_pStyle->GetStyleName();
1232 pXFPara->SetStyleName(StyleName);
1239 * @short Parse all cols of table
1240 * @param pXFTable - pointer to created XFTable
1242 void LwpTableLayout::ConvertColumn(XFTable *pXFTable,sal_uInt8 nStartCol,sal_uInt8 nEndCol)
1244 LwpTable * pTable = GetTable();
1245 if (!pTable)
1247 assert(false);
1248 return;
1251 for (sal_uInt32 iLoop = 0; iLoop < static_cast<sal_uInt32>(nEndCol)-nStartCol; ++iLoop)
1253 // add row to table
1254 LwpObjectID& rColID = GetColumnLayoutHead();
1255 LwpColumnLayout * pColumnLayout = dynamic_cast<LwpColumnLayout *>(rColID.obj().get());
1256 while (pColumnLayout)
1258 if (pColumnLayout->GetColumnID() == (iLoop+nStartCol))
1260 pXFTable->SetColumnStyle(iLoop+1, pColumnLayout->GetStyleName());
1261 break;
1263 rColID = pColumnLayout->GetNext();
1264 pColumnLayout = dynamic_cast<LwpColumnLayout *>(rColID.obj().get());
1266 if (!pColumnLayout)
1268 pXFTable->SetColumnStyle(iLoop+1, m_DefaultColumnStyleName);
1273 * @short split conflict merged cells
1275 void LwpTableLayout::SplitConflictCells()
1277 LwpTable * pTable = GetTable();
1278 if (!pTable)
1279 return;
1280 sal_uInt16 nCol = pTable->GetColumn();
1281 sal_uInt16 nRow = pTable->GetRow();
1283 sal_uInt16 nEffectRows;
1284 std::map<sal_uInt16,LwpRowLayout*>::iterator iter1;
1285 std::map<sal_uInt16,LwpRowLayout*>::iterator iter2;
1286 LwpRowLayout* pRowLayout;
1287 LwpRowLayout* pEffectRow;
1289 for (sal_uInt16 i=0; i<nRow; )
1291 iter1 = m_RowsMap.find(i);
1292 if (iter1 == m_RowsMap.end())//default rows
1294 i++;
1295 continue;
1297 pRowLayout= iter1->second;
1298 if (!pRowLayout->GetMergeCellFlag())
1300 i++;
1301 continue;
1303 else
1305 nEffectRows = i + pRowLayout->GetCurMaxSpannedRows(0,(sal_uInt8)nCol);
1307 for (sal_uInt16 j = i+1; j<nEffectRows; j++)
1309 iter2 = m_RowsMap.find(j);
1310 if (iter2 == m_RowsMap.end())
1311 continue;
1312 pEffectRow = iter2->second;
1313 if (!pEffectRow->GetMergeCellFlag())
1314 continue;
1315 else
1316 pEffectRow->SetCellSplit(nEffectRows);
1318 i = nEffectRows;
1320 }//end for
1324 * @short add default row which are missing in the file
1325 * @param pXFTable - pointer to new created table
1326 * @param nStartCol - starting column
1327 * @param nEndCol - end column
1328 * @return pXFTable
1330 void LwpTableLayout::ConvertDefaultRow(XFTable* pXFTable,sal_uInt8 nStartCol,
1331 sal_uInt8 nEndCol,sal_uInt16 nRowID)
1333 // current row doesn't exist in the file
1334 XFRow * pRow = new XFRow();
1335 pRow->SetStyleName(m_DefaultRowStyleName);
1337 for (sal_uInt16 j =0;j < nEndCol-nStartCol; j++)
1339 // if table has default cell layout, use it to ConvertCell
1340 // otherwise use blank cell
1341 XFCell * pCell = NULL;
1342 if (m_pDefaultCellLayout)
1344 pCell = m_pDefaultCellLayout->ConvertCell(
1345 GetTable()->GetObjectID(),nRowID,j+nStartCol);
1347 else
1349 pCell = new XFCell();
1351 pRow->AddCell(pCell);
1354 pXFTable->AddRow(pRow);
1357 * @short set cell map info
1358 * @param pXFCell - pointer to xfcell
1359 * @param nRow - row id
1360 * @param nCol - column id
1362 void LwpTableLayout::SetCellsMap(sal_uInt16 nRow,sal_uInt8 nCol,XFCell* pXFCell)
1364 std::pair<std::pair<sal_uInt16,sal_uInt8>,XFCell*> cell;
1365 std::pair<sal_uInt16,sal_uInt8> pos;
1366 pos.first = nRow;
1367 pos.second = nCol;
1368 cell.first = pos;
1369 cell.second = pXFCell;
1370 m_CellsMap.insert(cell);
1374 * @short get cell map info
1375 * @param nRow - row id
1376 * @param nCol - column id
1377 * @return pXFCell
1379 XFCell* LwpTableLayout::GetCellsMap(sal_uInt16 nRow,sal_uInt8 nCol)
1381 std::pair<sal_uInt16,sal_uInt8> pos;
1382 pos.first = nRow;
1383 pos.second = nCol;
1384 std::map<std::pair<sal_uInt16,sal_uInt8>,XFCell*>::iterator iter;
1385 iter = m_CellsMap.find(pos);
1386 if (iter == m_CellsMap.end())
1387 return NULL;
1388 return iter->second;
1391 * @descr Get row layout by row id
1392 * @param nRow - row id
1394 LwpRowLayout* LwpTableLayout::GetRowLayout(sal_uInt16 nRow)
1396 LwpObjectID& rRowID = GetChildHead();
1397 LwpRowLayout * pRowLayout = dynamic_cast<LwpRowLayout *>(rRowID.obj().get());
1398 while (pRowLayout)
1400 if(pRowLayout->GetRowID() == nRow)
1401 return pRowLayout;
1403 rRowID = pRowLayout->GetNext();
1404 pRowLayout = dynamic_cast<LwpRowLayout *>(rRowID.obj().get());
1406 return NULL;
1409 //add end by
1410 LwpColumnLayout::LwpColumnLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
1411 : LwpVirtualLayout(objHdr, pStrm)
1412 , ccolid(0)
1413 , cwidth(0)
1416 LwpColumnLayout::~LwpColumnLayout()
1418 void LwpColumnLayout::Read()
1420 LwpObjectStream* pStrm = m_pObjStrm;
1422 LwpVirtualLayout::Read();
1424 sal_uInt16 colid;
1426 colid = pStrm->QuickReaduInt16(); // forced to lushort
1427 ccolid = (sal_uInt8)colid; // Phillip
1428 cwidth = pStrm->QuickReadInt32();
1430 pStrm->SkipExtra();
1433 void LwpColumnLayout::RegisterStyle(double dCalculatedWidth)
1435 XFColStyle * pColStyle = new XFColStyle();
1436 pColStyle->SetWidth(static_cast<float>(dCalculatedWidth));
1437 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
1438 m_StyleName = pXFStyleManager->AddStyle(pColStyle).m_pStyle->GetStyleName();
1441 LwpTableHeadingLayout::LwpTableHeadingLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
1442 : LwpTableLayout(objHdr, pStrm)
1443 , cStartRow(0)
1444 , cEndRow(0)
1447 LwpTableHeadingLayout::~LwpTableHeadingLayout()
1450 * @short read table heading layout
1451 * @param
1452 * @return
1454 void LwpTableHeadingLayout::Read()
1456 LwpTableLayout::Read();
1458 cStartRow = m_pObjStrm->QuickReaduInt16();
1459 cEndRow = m_pObjStrm->QuickReaduInt16();
1461 m_pObjStrm->SkipExtra();
1465 * @short get start and end row number of table heading
1466 * @param
1467 * @return *pStartRow - starting row number
1468 * @return *pEndRow - end row number
1470 void LwpTableHeadingLayout::GetStartEndRow(sal_uInt16& nStartRow, sal_uInt16& nEndRow)
1472 nStartRow = cStartRow;
1473 nEndRow = cEndRow;
1476 * @short get first row heading layout of table heading
1477 * @param
1478 * @return LwpRowHeadingLayout * - pointer to first row heading layout of table heading
1480 LwpRowHeadingLayout * LwpTableHeadingLayout::GetFirstRowHeadingLayout()
1482 LwpObjectID& rID = GetChildHead();
1483 if(!rID.IsNull())
1485 LwpRowHeadingLayout * pHeadingRow = dynamic_cast<LwpRowHeadingLayout *>(rID.obj().get());
1486 return pHeadingRow;
1488 return NULL;
1491 LwpSuperParallelColumnLayout::LwpSuperParallelColumnLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm):LwpSuperTableLayout(objHdr, pStrm)
1494 LwpSuperParallelColumnLayout::~LwpSuperParallelColumnLayout()
1497 void LwpSuperParallelColumnLayout::Read()
1499 LwpSuperTableLayout::Read();
1500 m_pObjStrm->SkipExtra();
1504 LwpSuperGlossaryLayout::LwpSuperGlossaryLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm):LwpSuperTableLayout(objHdr, pStrm)
1508 LwpSuperGlossaryLayout::~LwpSuperGlossaryLayout()
1512 void LwpSuperGlossaryLayout::Read()
1514 LwpSuperTableLayout::Read();
1515 m_pObjStrm->SkipExtra();
1518 LwpParallelColumnsLayout::LwpParallelColumnsLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm):LwpTableLayout(objHdr, pStrm)
1522 LwpParallelColumnsLayout::~LwpParallelColumnsLayout()
1526 void LwpParallelColumnsLayout::Read()
1528 LwpTableLayout::Read();
1529 m_pObjStrm->SkipExtra();
1532 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */