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,
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 ************************************************************************/
58 * For LWP filter architecture prototype - table layouts
60 /*************************************************************************
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()
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
*pID
= GetChildTail();
119 while(pID
&& !pID
->IsNull())
121 LwpLayout
* pLayout
= dynamic_cast<LwpLayout
*>(pID
->obj());
126 if (pLayout
->GetLayoutType() == LWP_TABLE_LAYOUT
)
128 return dynamic_cast<LwpTableLayout
*>(pLayout
);
130 pID
= pLayout
->GetPrevious();
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
*pID
= GetChildTail();
143 while(pID
&& !pID
->IsNull())
145 LwpLayout
* pLayout
= dynamic_cast<LwpLayout
*>(pID
->obj());
151 if (pLayout
->GetLayoutType() == LWP_TABLE_HEADING_LAYOUT
)
153 return dynamic_cast<LwpTableHeadingLayout
*>(pLayout
);
155 pID
= pLayout
->GetPrevious();
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
178 sal_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();
187 * @short Judge whether table is justifiable, borrowed from Word Pro code
191 sal_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();
224 LwpTable
*pTable
= pTableLayout
->GetTable();
230 double dDefaultWidth
= pTable
->GetWidth();
231 sal_uInt16 nCol
= pTable
->GetColumn();
235 for(sal_uInt16 i
=0; i
< nCol
; i
++)
237 LwpObjectID
*pColumnID
= pTableLayout
->GetColumnLayoutHead();
238 LwpColumnLayout
* pColumnLayout
= dynamic_cast<LwpColumnLayout
*>(pColumnID
->obj());
239 double dColumnWidth
= dDefaultWidth
;
240 while (pColumnLayout
)
242 if(pColumnLayout
->GetColumnID() == i
)
244 dColumnWidth
= pColumnLayout
->GetWidth();
247 pColumnID
= pColumnLayout
->GetNext();
248 pColumnLayout
= dynamic_cast<LwpColumnLayout
*>(pColumnID
->obj());
250 dWidth
+= dColumnWidth
;
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
266 void LwpSuperTableLayout::ApplyShadow(XFTableStyle
*pTableStyle
)
268 // use shadow property of supertable
269 boost::scoped_ptr
<XFShadow
> pXFShadow(GetXFShadow());
272 pTableStyle
->SetShadow(pXFShadow
->GetPosition(), pXFShadow
->GetOffset(), pXFShadow
->GetColor());
276 * @short Apply pattern fill to table style
277 * @param pTableStyle - pointer of XFTableStyle
280 void LwpSuperTableLayout::ApplyPatternFill(XFTableStyle
* pTableStyle
)
282 XFBGImage
* pXFBGImage
= this->GetFillPattern();
285 pTableStyle
->SetBackImage(pXFBGImage
);
290 * @short Apply background to table style
291 * @param pTableStyle - pointer of XFTableStyle
294 void LwpSuperTableLayout::ApplyBackGround(XFTableStyle
* pTableStyle
)
296 if (this->IsPatternFill())
298 ApplyPatternFill(pTableStyle
);
302 ApplyBackColor(pTableStyle
);
306 * @short Apply back color to table
307 * @param pTableStyle - pointer of XFTableStyle
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
324 void LwpSuperTableLayout::ApplyWatermark(XFTableStyle
*pTableStyle
)
326 XFBGImage
* pBGImage
= GetXFBGImage();
329 pTableStyle
->SetBackImage(pBGImage
);
333 * @short Apply alignment to table
334 * @param pTableStyle - pointer of XFTableStyle
337 void LwpSuperTableLayout::ApplyAlignment(XFTableStyle
* pTableStyle
)
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
355 void LwpSuperTableLayout::XFConvert(XFContentContainer
* pCont
)
357 if ( LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE
== GetRelativeType()
358 && !GetContainerLayout()->IsCell())
360 LwpTableLayout
* pTableLayout
= GetTableLayout();
363 pTableLayout
->XFConvert(pCont
);
366 else if(IsRelativeAnchored())
368 //anchor to paragraph except "with paragraph above"
369 XFConvertFrame(pCont
);
373 //anchor to page, frame, cell
374 m_pFrame
->XFConvert(pCont
);
378 * @short convert frame which anchor to page
382 void LwpSuperTableLayout::XFConvertFrame(XFContentContainer
* pCont
, sal_Int32 nStart
, sal_Int32 nEnd
, sal_Bool bAll
)
386 XFFrame
* pXFFrame
= NULL
;
389 pXFFrame
= new XFFrame();
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();
401 pTableLayout
->XFConvert(pXFFrame
);
403 //add frame to the container
404 pCont
->Add(pXFFrame
);
409 * @short register frame style
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
), m_nRows(0), m_nCols(0), m_pXFTable(NULL
)
426 LwpTableLayout::~LwpTableLayout()
432 delete [] m_pColumns
;
437 * @short Get neighbour cell by specifying ROW+COL
440 * @return LwpCellLayout *
442 LwpCellLayout
* LwpTableLayout::GetCellByRowCol(sal_uInt16 nRow
, sal_uInt16 nCol
)
444 if (nRow
>= m_nRows
|| nCol
>= m_nCols
)
447 return m_WordProCellsMap
[nRow
*m_nCols
+ nCol
];
450 * @short traverse all table cells
455 void LwpTableLayout::TraverseTable()
457 sal_uInt32 nCount
= m_nRows
*m_nCols
;
459 // new cell map nRow*nCOl and initialize
460 for (sal_uInt32 iLoop
= 0; iLoop
< nCount
; ++iLoop
)
462 m_WordProCellsMap
.push_back(GetDefaultCellLayout());
466 LwpObjectID
*pRowID
= GetChildHead();
467 LwpRowLayout
* pRowLayout
= dynamic_cast<LwpRowLayout
*>(pRowID
->obj());
470 pRowLayout
->SetRowMap();
472 // for 's analysis job
473 m_RowsMap
[pRowLayout
->GetRowID()] = pRowLayout
;
474 pRowLayout
->CollectMergeInfo();
475 // end for 's analysis
477 pRowID
= pRowLayout
->GetNext();
478 pRowLayout
= dynamic_cast<LwpRowLayout
*>(pRowID
->obj());
483 * @short search the cell map
484 * @param nRow - row id (0 based)
485 * @param nRow - row id (0 based)
486 * @return LwpObjectID * - pointer to cell story object ID
488 LwpObjectID
* LwpTableLayout::SearchCellStoryMap(sal_uInt16 nRow
, sal_uInt16 nCol
)
490 if (nRow
>= m_nRows
|| nCol
>= m_nCols
)
495 LwpCellLayout
* pCell
= GetCellByRowCol(nRow
, nCol
);
498 // maybe connected cell layout
499 // maybe default cell layout
500 if (nRow
!= pCell
->GetRowID() || nCol
!= pCell
->GetColID())
504 return pCell
->GetContent();
511 * @short Get parent super table layout of table layout
512 * @return LwpSuperTableLayout * - pointer of parent super table layout
514 LwpSuperTableLayout
* LwpTableLayout::GetSuperTableLayout()
516 return dynamic_cast<LwpSuperTableLayout
*>(GetParent()->obj());
519 * @short Get table pointer
520 * @return LwpTable * - content table pointer
522 LwpTable
* LwpTableLayout::GetTable()
524 LwpTable
*pTable
= dynamic_cast<LwpTable
*>(m_Content
.obj());
528 * @short Get column style name by column ID
529 * @param sal_uInt16 -- col id(0 based)
530 * @return OUString - name of column style
532 OUString
LwpTableLayout::GetColumnWidth(sal_uInt16 nCol
)
537 return m_DefaultColumnStyleName
;
540 LwpColumnLayout
* pCol
= m_pColumns
[nCol
];
543 return pCol
->GetStyleName();
546 return m_DefaultColumnStyleName
;
549 * @short analyze all columns to get whole table width and width of all columns
550 * @short and register all column styles
553 void LwpTableLayout::RegisterColumns()
555 LwpTable
* pTable
= GetTable();
556 LwpSuperTableLayout
* pSuper
= GetSuperTableLayout();
558 sal_uInt16 nCols
= m_nCols
;
560 m_pColumns
= new LwpColumnLayout
*[nCols
];
561 sal_Bool
* pWidthCalculated
= new sal_Bool
[nCols
];
562 for(sal_uInt16 i
=0;i
<nCols
; i
++)
564 pWidthCalculated
[i
] = sal_False
;
565 m_pColumns
[i
] = NULL
;
568 double dDefaultColumn
= pTable
->GetWidth();
569 sal_uInt16 nJustifiableColumn
= nCols
;
571 double dTableWidth
= pSuper
->GetTableWidth();
573 // Get total width of justifiable columns
574 // NOTICE: all default columns are regarded as justifiable columns
575 LwpObjectID
*pColumnID
= GetColumnLayoutHead();
576 LwpColumnLayout
* pColumnLayout
= dynamic_cast<LwpColumnLayout
*>(pColumnID
->obj());
577 while (pColumnLayout
)
579 m_pColumns
[pColumnLayout
->GetColumnID()] = pColumnLayout
;
580 if (!pColumnLayout
->IsJustifiable())
582 pWidthCalculated
[pColumnLayout
->GetColumnID()] = sal_True
;
583 dTableWidth
-= pColumnLayout
->GetWidth();
584 nJustifiableColumn
--;
587 pColumnID
= pColumnLayout
->GetNext();
588 pColumnLayout
= dynamic_cast<LwpColumnLayout
*>(pColumnID
->obj());
591 // if all columns are not justifiable, the rightmost column will be changed to justifiable
592 if(nJustifiableColumn
== 0)
594 nJustifiableColumn
++;
595 if (m_pColumns
[nCols
- 1])
597 pWidthCalculated
[nCols
-1] = sal_False
;
598 dTableWidth
+= m_pColumns
[nCols
-1]->GetWidth();
603 dTableWidth
= dDefaultColumn
;
608 // justifiable columns will share the remain width averagely
609 dDefaultColumn
= dTableWidth
/nJustifiableColumn
;
611 // register default column style
612 XFColStyle
*pColStyle
= new XFColStyle();
613 pColStyle
->SetWidth(static_cast<float>(dDefaultColumn
));
615 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
616 m_DefaultColumnStyleName
= pXFStyleManager
->AddStyle(pColStyle
)->GetStyleName();
618 // register existed column style
620 for( i
=0;i
<nCols
; i
++)
624 m_pColumns
[i
]->SetFoundry(m_pFoundry
);
625 if(!pWidthCalculated
[i
])
627 // justifiable ----register style with calculated value
628 m_pColumns
[i
]->SetStyleName(m_DefaultColumnStyleName
);
632 // not justifiable ---- register style with original value
633 m_pColumns
[i
]->RegisterStyle(m_pColumns
[i
]->GetWidth());
637 delete [] pWidthCalculated
;
640 * @short register all row styles
643 void LwpTableLayout::RegisterRows()
645 LwpTable
* pTable
= GetTable();
652 // register default row style
653 XFRowStyle
* pRowStyle
= new XFRowStyle();
654 if (m_nDirection
& 0x0030)
656 pRowStyle
->SetMinRowHeight((float)pTable
->GetHeight());
660 pRowStyle
->SetRowHeight((float)pTable
->GetHeight());
662 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
663 m_DefaultRowStyleName
= pXFStyleManager
->AddStyle(pRowStyle
)->GetStyleName();
665 // register style of rows
666 LwpObjectID
* pRowID
= GetChildHead();
667 LwpRowLayout
* pRowLayout
= dynamic_cast<LwpRowLayout
*>(pRowID
->obj());
670 pRowLayout
->SetFoundry(m_pFoundry
);
671 pRowLayout
->RegisterStyle();
673 pRowID
= pRowLayout
->GetNext();
674 pRowLayout
= dynamic_cast<LwpRowLayout
*>(pRowID
->obj());
678 * @short register table style, if needed, including frame style
681 void LwpTableLayout::RegisterStyle()
683 // get super table layout
684 LwpSuperTableLayout
* pSuper
= GetSuperTableLayout();
692 LwpTable
* pTable
= GetTable();
699 // get row/column number of this table
700 m_nRows
= pTable
->GetRow();
701 m_nCols
= pTable
->GetColumn();
703 // get default cell layout of current table
704 LwpObjectID
* pID
= pTable
->GetDefaultCellStyle();
707 m_pDefaultCellLayout
= dynamic_cast<LwpCellLayout
*>(pID
->obj());
710 // register columns styles
713 // register style of whole table
714 XFTableStyle
* pTableStyle
= new XFTableStyle();
716 sal_uInt8 nType
= pSuper
->GetRelativeType();
717 // If the table is not "with paragraph above" placement, create an frame style
718 // by supertable layout
719 if ( LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE
== nType
720 && !pSuper
->GetContainerLayout()->IsCell())
723 // pSuper->ApplyBackColor(pTableStyle);
724 pSuper
->ApplyBackGround(pTableStyle
);
725 pSuper
->ApplyWatermark(pTableStyle
);
726 pSuper
->ApplyShadow(pTableStyle
);
727 pSuper
->ApplyAlignment(pTableStyle
);
728 pTableStyle
->SetWidth(pSuper
->GetTableWidth());
732 pSuper
->RegisterFrameStyle();
733 pTableStyle
->SetAlign(enumXFAlignCenter
);
734 pTableStyle
->SetWidth(pSuper
->GetTableWidth());
736 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
737 m_StyleName
= pXFStyleManager
->AddStyle(pTableStyle
)->GetStyleName();
739 //convert to OO table now and register row stle
743 SplitConflictCells();
745 // Register rows layouts, it must be after SplitConflictCells
752 //Comment:The old code doesn't check if the LwpFoundry pointer is NULL,
753 // So the NULL pointer cause sodc frozee. Add code to check the
756 if( GetFoundry() && GetTable() )
758 PutCellVals( GetFoundry(),*GetTable()->GetObjectID() );
761 * @short read table layout
764 void LwpTableLayout::ParseTable()
766 // get super table layout
767 LwpSuperTableLayout
* pSuper
= GetSuperTableLayout();
774 // set name of object
775 m_pXFTable
= new XFTable
;
776 m_pXFTable
->SetTableName(pSuper
->GetName()->str());
778 m_pXFTable
->SetStyleName(m_StyleName
);
780 sal_uInt16 nRow
= m_nRows
;
781 sal_uInt8 nCol
= (sal_uInt8
)m_nCols
;
783 //process header rows
784 LwpTableHeadingLayout
* pTableHeading
;
785 pTableHeading
= pSuper
->GetTableHeadingLayout();
786 sal_uInt16 nStartHeadRow
;
787 sal_uInt16 nEndHeadRow
;
788 sal_uInt16 nContentRow
;
791 pTableHeading
->GetStartEndRow(nStartHeadRow
,nEndHeadRow
);
792 if (nStartHeadRow
!= 0)
793 ConvertTable(m_pXFTable
,0,nRow
,0,nCol
);
796 nContentRow
= ConvertHeadingRow(m_pXFTable
,nStartHeadRow
,nEndHeadRow
+1);
797 ConvertTable(m_pXFTable
,nContentRow
,nRow
,0,nCol
);
801 ConvertTable(m_pXFTable
,0,nRow
,0,nCol
);
805 * @short read table layout
808 void LwpTableLayout::Read()
812 // before layout hierarchy rework!
813 if(LwpFileHeader::m_nFileRevision
< 0x000b)
817 m_ColumnLayout
.ReadIndexed(m_pObjStrm
);
819 m_pObjStrm
->SkipExtra();
823 * @short Convert table
825 * @return pCont - container which will contain table
827 void LwpTableLayout::XFConvert(XFContentContainer
* pCont
)
830 pCont
->Add(m_pXFTable
);
833 * @short convert heading row
834 * @param pXFTable - pointer of table
835 * @param nStartRow - start heading row ID
836 * @param nEndRow - end heading row ID
838 sal_uInt16
LwpTableLayout::ConvertHeadingRow(
839 XFTable
* pXFTable
,sal_uInt16 nStartHeadRow
,sal_uInt16 nEndHeadRow
)
841 sal_uInt16 nContentRow
;
842 sal_uInt8 nCol
= static_cast<sal_uInt8
>(GetTable()->GetColumn());
843 XFTable
* pTmpTable
= new XFTable
;
846 ConvertTable(pTmpTable
,nStartHeadRow
,nEndHeadRow
,0,nCol
);
848 sal_uInt16 nRowNum
= static_cast<sal_uInt16
>(pTmpTable
->GetRowCount());
849 sal_uInt8
* CellMark
= new sal_uInt8
[nRowNum
];
850 sal_Bool bFindFlag
= sal_False
;
854 pXFRow
= pTmpTable
->GetRow(1);
855 pXFTable
->AddHeaderRow(pXFRow
);
856 pTmpTable
->RemoveRow(1);
857 nContentRow
= nEndHeadRow
;
861 sal_uInt8 nFirstColSpann
= 1;
862 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
);
882 void LwpTableLayout::SplitRowToCells(XFTable
* pTmpTable
,XFTable
* pXFTable
,
883 sal_uInt8 nFirstColSpann
,sal_uInt8
* pCellMark
)
887 sal_uInt16 nRowNum
= static_cast<sal_uInt16
>(pTmpTable
->GetRowCount());
888 sal_uInt8 nCol
= static_cast<sal_uInt8
>(GetTable()->GetColumn());
890 XFRow
* pXFRow
= new XFRow
;
892 //register style for heading row
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
));
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
);
915 pRowStyle
->SetRowHeight((float)fHeight
);
917 pXFRow
->SetStyleName(pXFStyleManager
->AddStyle(pRowStyle
)->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
;
928 for (i
=1;i
<=nRowNum
;i
++)
930 pOldRow
= pTmpTable
->GetRow(i
);
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
);
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
);
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 sal_Bool
LwpTableLayout::FindSplitColMark(XFTable
* pXFTable
,sal_uInt8
* pCellMark
,
982 sal_uInt8
& nMaxColSpan
)
984 sal_uInt16 nRowNum
= static_cast<sal_uInt16
>(pXFTable
->GetRowCount());
985 sal_uInt8 nColNum
= static_cast<sal_uInt8
>(pXFTable
->GetColumnCount());
986 sal_uInt8 nCellMark
=0;
989 sal_Bool bFindFlag
= sal_False
;
992 for(sal_uInt8 i
=1;i
<=nColNum
;i
++)
997 //find current max column span
999 for (nRowLoop
=1;nRowLoop
<=nRowNum
;nRowLoop
++)
1002 for(nCellLoop
=1; nCellLoop
<i
+1; nCellLoop
++)
1004 pTmpRow
= pXFTable
->GetRow(nRowLoop
);
1005 XFCell
* pCell
= pTmpRow
->GetCell(nCellLoop
);
1007 nColSpan
+= static_cast<sal_uInt8
>(pCell
->GetColSpaned());
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 colum
1017 for (nRowLoop
=1;nRowLoop
<=nRowNum
;nRowLoop
++)
1019 pTmpRow
= pXFTable
->GetRow(nRowLoop
);
1022 for (nCellLoop
=1; nCellLoop
<=pTmpRow
->GetCellCount(); nCellLoop
++)
1024 if (nCount
>nMaxColSpan
)
1026 nCount
+= static_cast<sal_uInt8
>(pTmpRow
->GetCell(nCellLoop
)->GetColSpaned());
1027 if (nCount
== nMaxColSpan
)
1029 nCellMark
= nCellLoop
;
1036 pCellMark
[nRowLoop
] = nCellMark
;
1038 for(nRowLoop
=1;nRowLoop
<=nRowNum
;nRowLoop
++)//check if all ==0,break
1040 if (pCellMark
[nRowLoop
] == 0)
1043 if (nRowLoop
== nRowNum
+1)
1045 bFindFlag
= sal_True
;
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
);
1079 LwpRowLayout
* pRow
= iter
->second
;
1080 if (pRow
->GetCurMaxSpannedRows(nStartCol
,nEndCol
) == 1)
1082 pRow
->ConvertCommonRow(pXFTable
,nStartCol
,nEndCol
);
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
1106 if( !pFoundry
) return;
1111 LwpDLVListHeadHolder
* pHolder
= (LwpDLVListHeadHolder
*)pFoundry
->GetNumberManager()->GetTableRangeID().obj();
1113 LwpTableRange
* pTableRange
= (LwpTableRange
*)pHolder
->GetHeadID()->obj();
1116 while (NULL
!=pTableRange
)
1118 LwpObjectID aID
= pTableRange
->GetTableID();
1119 if (aID
== aTableID
)
1123 pTableRange
= pTableRange
->GetNext();
1128 LwpCellRange
* pRange
= (LwpCellRange
*)pTableRange
->GetCellRangeID().obj();
1129 LwpFolder
* pFolder
= (LwpFolder
*)pRange
->GetFolderID().obj();
1130 LwpObjectID aRowListID
= pFolder
->GetChildHeadID();
1131 LwpRowList
* pRowList
= (LwpRowList
*)aRowListID
.obj();
1134 while( NULL
!=pRowList
)
1136 sal_uInt16 nRowID
= pRowList
->GetRowID();
1138 LwpCellList
* pCellList
= (LwpCellList
*)pRowList
->GetChildHeadID().obj();
1140 while( NULL
!=pCellList
)
1143 sal_uInt16 nColID
= pCellList
->GetColumnID();
1145 XFCell
* pCell
= GetCellsMap(nRowID
,static_cast<sal_uInt8
>(nColID
));
1148 pCellList
->Convert(pCell
, this);
1151 PostProcessParagraph(pCell
, nRowID
, nColID
);
1155 //Hidden cell would not be in cellsmap
1159 pCellList
= (LwpCellList
*)pCellList
->GetNextID().obj();
1162 pRowList
=(LwpRowList
*)pRowList
->GetNextID().obj();
1172 * @short 1. set number right alignment to right if number 2. remove tab added before if number
1173 * @param pCell - cell which to be process
1174 * @param nRowID - row number in Word Pro file
1175 * @param nColID - column number in Word Pro file
1177 void LwpTableLayout::PostProcessParagraph(XFCell
*pCell
, sal_uInt16 nRowID
, sal_uInt16 nColID
)
1179 // if number right, set alignment to right
1180 LwpCellLayout
* pCellLayout
= GetCellByRowCol(nRowID
, nColID
);
1183 XFParagraph
* pXFPara
= NULL
;
1184 pXFPara
= static_cast<XFParagraph
*>(pCell
->FindFirstContent(enumXFContentPara
));
1188 XFColor aNullColor
= XFColor();
1192 OUString sNumfmt
= pCellLayout
->GetNumfmtName();
1193 sal_Bool bColorMod
= sal_False
;
1194 XFNumberStyle
* pNumStyle
= NULL
;
1195 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
1196 if (!sNumfmt
.isEmpty())
1198 pNumStyle
= (XFNumberStyle
*)pXFStyleManager
->FindStyle( sNumfmt
);
1199 aColor
= pNumStyle
->GetColor();
1200 if ( pNumStyle
&& aColor
!= aNullColor
)
1201 bColorMod
= sal_True
;//end
1204 XFParaStyle
* pStyle
= pXFStyleManager
->FindParaStyle(pXFPara
->GetStyleName());
1205 if (pStyle
->GetNumberRight() || bColorMod
)
1207 XFParaStyle
* pOverStyle
= new XFParaStyle
;
1208 *pOverStyle
= *pStyle
;
1210 if (pStyle
->GetNumberRight())
1211 pOverStyle
->SetAlignType(enumXFAlignEnd
);
1215 XFFont
* pFont
= pOverStyle
->GetFont();
1216 aColor
= pFont
->GetColor();
1217 if ( aColor
== aNullColor
)
1219 XFFont
* pNewFont
= new XFFont
;
1220 aColor
= pNumStyle
->GetColor();
1221 pNewFont
->SetColor(aColor
);
1222 pOverStyle
->SetFont(pNewFont
);
1226 pOverStyle
->SetStyleName(A2OUSTR(""));
1227 OUString StyleName
= pXFStyleManager
->AddStyle(pOverStyle
)->GetStyleName();
1229 pXFPara
->SetStyleName(StyleName
);
1236 * @short Parse all cols of table
1237 * @param pXFTable - pointer to created XFTable
1239 void LwpTableLayout::ConvertColumn(XFTable
*pXFTable
,sal_uInt8 nStartCol
,sal_uInt8 nEndCol
)
1241 LwpTable
* pTable
= GetTable();
1248 for (sal_uInt32 iLoop
= 0; iLoop
< static_cast<sal_uInt32
>(nEndCol
)-nStartCol
; ++iLoop
)
1251 LwpObjectID
*pColID
= GetColumnLayoutHead();
1252 LwpColumnLayout
* pColumnLayout
= dynamic_cast<LwpColumnLayout
*>(pColID
->obj());
1253 while (pColumnLayout
)
1255 if (pColumnLayout
->GetColumnID() == (iLoop
+nStartCol
))
1257 pXFTable
->SetColumnStyle(iLoop
+1, pColumnLayout
->GetStyleName());
1260 pColID
= pColumnLayout
->GetNext();
1261 pColumnLayout
= dynamic_cast<LwpColumnLayout
*>(pColID
->obj());
1265 pXFTable
->SetColumnStyle(iLoop
+1, m_DefaultColumnStyleName
);
1270 * @short split conflict merged cells
1272 void LwpTableLayout::SplitConflictCells()
1274 LwpTable
* pTable
= GetTable();
1277 sal_uInt16 nCol
= pTable
->GetColumn();
1278 sal_uInt16 nRow
= pTable
->GetRow();
1280 sal_uInt16 nEffectRows
;
1281 std::map
<sal_uInt16
,LwpRowLayout
*>::iterator iter1
;
1282 std::map
<sal_uInt16
,LwpRowLayout
*>::iterator iter2
;
1283 LwpRowLayout
* pRowLayout
;
1284 LwpRowLayout
* pEffectRow
;
1286 for (sal_uInt16 i
=0; i
<nRow
; )
1288 iter1
= m_RowsMap
.find(i
);
1289 if (iter1
== m_RowsMap
.end())//default rows
1294 pRowLayout
= iter1
->second
;
1295 if (pRowLayout
->GetMergeCellFlag() == sal_False
)
1302 nEffectRows
= i
+ pRowLayout
->GetCurMaxSpannedRows(0,(sal_uInt8
)nCol
);
1304 for (sal_uInt16 j
= i
+1; j
<nEffectRows
; j
++)
1306 iter2
= m_RowsMap
.find(j
);
1307 if (iter2
== m_RowsMap
.end())
1309 pEffectRow
= iter2
->second
;
1310 if (pEffectRow
->GetMergeCellFlag() == sal_False
)
1313 pEffectRow
->SetCellSplit(nEffectRows
);
1321 * @short add default row which are missing in the file
1322 * @param pXFTable - pointer to new created table
1323 * @param nStartCol - starting column
1324 * @param nEndCol - end column
1327 void LwpTableLayout::ConvertDefaultRow(XFTable
* pXFTable
,sal_uInt8 nStartCol
,
1328 sal_uInt8 nEndCol
,sal_uInt16 nRowID
)
1330 // current row doesn't exist in the file
1331 XFRow
* pRow
= new XFRow();
1332 pRow
->SetStyleName(m_DefaultRowStyleName
);
1334 for (sal_uInt16 j
=0;j
< nEndCol
-nStartCol
; j
++)
1336 // if table has default cell layout, use it to ConvertCell
1337 // otherwise use blank cell
1338 XFCell
* pCell
= NULL
;
1339 if (m_pDefaultCellLayout
)
1341 pCell
= m_pDefaultCellLayout
->ConvertCell(
1342 *GetTable()->GetObjectID(),nRowID
,j
+nStartCol
);
1346 pCell
= new XFCell();
1348 pRow
->AddCell(pCell
);
1351 pXFTable
->AddRow(pRow
);
1354 * @short set cell map info
1355 * @param pXFCell - pointer to xfcell
1356 * @param nRow - row id
1357 * @param nCol - column id
1359 void LwpTableLayout::SetCellsMap(sal_uInt16 nRow
,sal_uInt8 nCol
,XFCell
* pXFCell
)
1361 std::pair
<std::pair
<sal_uInt16
,sal_uInt8
>,XFCell
*> cell
;
1362 std::pair
<sal_uInt16
,sal_uInt8
> pos
;
1366 cell
.second
= pXFCell
;
1367 m_CellsMap
.insert(cell
);
1371 * @short get cell map info
1372 * @param nRow - row id
1373 * @param nCol - column id
1376 XFCell
* LwpTableLayout::GetCellsMap(sal_uInt16 nRow
,sal_uInt8 nCol
)
1378 std::pair
<sal_uInt16
,sal_uInt8
> pos
;
1381 std::map
<std::pair
<sal_uInt16
,sal_uInt8
>,XFCell
*>::iterator iter
;
1382 iter
= m_CellsMap
.find(pos
);
1383 if (iter
== m_CellsMap
.end())
1385 return iter
->second
;
1388 * @descr Get row layout by row id
1389 * @param nRow - row id
1391 LwpRowLayout
* LwpTableLayout::GetRowLayout(sal_uInt16 nRow
)
1393 LwpObjectID
*pRowID
= GetChildHead();
1394 LwpRowLayout
* pRowLayout
= dynamic_cast<LwpRowLayout
*>(pRowID
->obj());
1397 if(pRowLayout
->GetRowID() == nRow
)
1400 pRowID
= pRowLayout
->GetNext();
1401 pRowLayout
= dynamic_cast<LwpRowLayout
*>(pRowID
->obj());
1408 LwpColumnLayout::LwpColumnLayout(LwpObjectHeader
&objHdr
, LwpSvStream
* pStrm
)
1409 : LwpVirtualLayout(objHdr
, pStrm
)
1412 LwpColumnLayout::~LwpColumnLayout()
1414 void LwpColumnLayout::Read()
1416 LwpObjectStream
* pStrm
= m_pObjStrm
;
1418 LwpVirtualLayout::Read();
1422 colid
= pStrm
->QuickReaduInt16(); // forced to lushort
1423 ccolid
= (sal_uInt8
)colid
; // Phillip
1424 cwidth
= pStrm
->QuickReadInt32();
1429 void LwpColumnLayout::RegisterStyle(double dCalculatedWidth
)
1431 XFColStyle
* pColStyle
= new XFColStyle();
1432 pColStyle
->SetWidth(static_cast<float>(dCalculatedWidth
));
1433 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
1434 m_StyleName
= pXFStyleManager
->AddStyle(pColStyle
)->GetStyleName();
1437 LwpTableHeadingLayout::LwpTableHeadingLayout(LwpObjectHeader
&objHdr
, LwpSvStream
* pStrm
)
1438 : LwpTableLayout(objHdr
, pStrm
)
1441 LwpTableHeadingLayout::~LwpTableHeadingLayout()
1444 * @short read table heading layout
1448 void LwpTableHeadingLayout::Read()
1450 LwpTableLayout::Read();
1452 cStartRow
= m_pObjStrm
->QuickReaduInt16();
1453 cEndRow
= m_pObjStrm
->QuickReaduInt16();
1455 m_pObjStrm
->SkipExtra();
1459 * @short get start and end row number of table heading
1461 * @return *pStartRow - starting row number
1462 * @return *pEndRow - end row number
1464 void LwpTableHeadingLayout::GetStartEndRow(sal_uInt16
& nStartRow
, sal_uInt16
& nEndRow
)
1466 nStartRow
= cStartRow
;
1470 * @short get first row heading layout of table heading
1472 * @return LwpRowHeadingLayout * - pointer to first row heading layout of table heading
1474 LwpRowHeadingLayout
* LwpTableHeadingLayout::GetFirstRowHeadingLayout()
1476 LwpObjectID
*pID
= GetChildHead();
1477 if(pID
&& !pID
->IsNull())
1479 LwpRowHeadingLayout
* pHeadingRow
= dynamic_cast<LwpRowHeadingLayout
*>(pID
->obj());
1485 LwpSuperParallelColumnLayout::LwpSuperParallelColumnLayout(LwpObjectHeader
&objHdr
, LwpSvStream
* pStrm
):LwpSuperTableLayout(objHdr
, pStrm
)
1488 LwpSuperParallelColumnLayout::~LwpSuperParallelColumnLayout()
1491 void LwpSuperParallelColumnLayout::Read()
1493 LwpSuperTableLayout::Read();
1494 m_pObjStrm
->SkipExtra();
1498 LwpSuperGlossaryLayout::LwpSuperGlossaryLayout(LwpObjectHeader
&objHdr
, LwpSvStream
* pStrm
):LwpSuperTableLayout(objHdr
, pStrm
)
1502 LwpSuperGlossaryLayout::~LwpSuperGlossaryLayout()
1506 void LwpSuperGlossaryLayout::Read()
1508 LwpSuperTableLayout::Read();
1509 m_pObjStrm
->SkipExtra();
1513 LwpParallelColumnsLayout::LwpParallelColumnsLayout(LwpObjectHeader
&objHdr
, LwpSvStream
* pStrm
):LwpTableLayout(objHdr
, pStrm
)
1517 LwpParallelColumnsLayout::~LwpParallelColumnsLayout()
1521 void LwpParallelColumnsLayout::Read()
1523 LwpTableLayout::Read();
1524 m_pObjStrm
->SkipExtra();
1527 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */