1 /*************************************************************************
3 * The Contents of this file are made available subject to the terms of
4 * either of the following licenses
6 * - GNU Lesser General Public License Version 2.1
7 * - Sun Industry Standards Source License Version 1.1
9 * Sun Microsystems Inc., October, 2000
11 * GNU Lesser General Public License Version 2.1
12 * =============================================
13 * Copyright 2000 by Sun Microsystems, Inc.
14 * 901 San Antonio Road, Palo Alto, CA 94303, USA
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License version 2.1, as published by the Free Software Foundation.
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
31 * Sun Industry Standards Source License Version 1.1
32 * =================================================
33 * The contents of this file are subject to the Sun Industry Standards
34 * Source License Version 1.1 (the "License"); You may not use this file
35 * except in compliance with the License. You may obtain a copy of the
36 * License at http://www.openoffice.org/license.html.
38 * Software provided under this License is provided on an "AS IS" basis,
39 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
40 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
41 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
42 * See the License for the specific provisions governing your rights and
43 * obligations concerning the Software.
45 * The Initial Developer of the Original Code is: IBM Corporation
47 * Copyright: 2008 by IBM Corporation
49 * All Rights Reserved.
51 * Contributor(s): _______________________________________
54 ************************************************************************/
57 * For LWP filter architecture prototype - table layouts
59 /*************************************************************************
62 ************************************************************************/
63 #include "lwpglobalmgr.hxx"
64 #include "lwptablelayout.hxx"
65 #include "lwpfoundry.hxx"
66 #include "lwpobjfactory.hxx"
67 #include "lwpholder.hxx"
68 #include "lwptable.hxx"
69 #include "lwptblcell.hxx"
70 #include "lwpnumericfmt.hxx"
71 #include "lwpdlvlist.hxx"
72 #include "lwppara.hxx"
74 #include "xfilter/xfstylemanager.hxx"
75 #include "xfilter/xftablestyle.hxx"
76 #include "xfilter/xftable.hxx"
77 #include "xfilter/xfrow.hxx"
78 #include "xfilter/xfrowstyle.hxx"
79 #include "xfilter/xfcell.hxx"
80 #include "xfilter/xfcellstyle.hxx"
81 #include "xfilter/xfcolstyle.hxx"
82 #include "xfilter/xfframestyle.hxx"
83 #include "xfilter/xfframe.hxx"
84 #include "xfilter/xffloatframe.hxx"
85 #include "lwpframelayout.hxx"
86 #include "xfilter/xfparastyle.hxx"
88 LwpSuperTableLayout::LwpSuperTableLayout(LwpObjectHeader
&objHdr
, LwpSvStream
* pStrm
)
89 : LwpPlacableLayout(objHdr
, pStrm
)
91 m_pFrame
= new LwpFrame(this);
94 LwpSuperTableLayout::~LwpSuperTableLayout()
102 * @short Read super table layout record
104 void LwpSuperTableLayout::Read()
106 LwpPlacableLayout::Read();
107 m_pObjStrm
->SkipExtra();
111 * @short Get child table layout
112 * @return pointer to table layout
114 LwpTableLayout
* LwpSuperTableLayout::GetTableLayout()
116 LwpObjectID
*pID
= GetChildTail();
118 while(pID
&& !pID
->IsNull())
120 LwpVirtualLayout
* pLayout
= static_cast<LwpVirtualLayout
*>(pID
->obj());
125 if (pLayout
->GetLayoutType() == LWP_TABLE_LAYOUT
)
127 return static_cast<LwpTableLayout
*>(pLayout
);
129 pID
= pLayout
->GetPrevious();
135 * @short Get effective heading table layout, the one just before table layout is the only one which is effective
136 * @return LwpTableHeadingLayout* - pointer to table heading layout
138 LwpTableHeadingLayout
* LwpSuperTableLayout::GetTableHeadingLayout()
140 LwpObjectID
*pID
= GetChildTail();
142 while(pID
&& !pID
->IsNull())
144 LwpVirtualLayout
* pLayout
= static_cast<LwpVirtualLayout
*>(pID
->obj());
150 if (pLayout
->GetLayoutType() == LWP_TABLE_HEADING_LAYOUT
)
152 return static_cast<LwpTableHeadingLayout
*>(pLayout
);
154 pID
= pLayout
->GetPrevious();
160 * @short Register super table layout style
162 void LwpSuperTableLayout::RegisterStyle()
164 // if this layout is style of real table entry
165 LwpTableLayout
* pTableLayout
= GetTableLayout();
166 if (pTableLayout
!= NULL
)
168 pTableLayout
->SetFoundry(m_pFoundry
);
169 pTableLayout
->RegisterStyle();
173 * @short Judge whether table size is according to content, borrowed from Word Pro code
177 sal_Bool
LwpSuperTableLayout::IsSizeRightToContent()
179 /* Only "with paragraph above" tables can size right to content. */
180 if (GetRelativeType() == LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE
)
181 return LwpPlacableLayout::IsSizeRightToContent();
186 * @short Judge whether table is justifiable, borrowed from Word Pro code
190 sal_Bool
LwpSuperTableLayout::IsJustifiable()
192 return (GetRelativeType() != LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE
|| IsSizeRightToContent());
195 * @short Get width of frame outside table
196 * @param pTableStyle - pointer of XFTableStyle
197 * @return double - table width
199 double LwpSuperTableLayout::GetWidth()
201 double dWidth
= GetTableWidth();
202 double dLeft
= GetMarginsValue(MARGIN_LEFT
);
203 double dRight
= GetMarginsValue(MARGIN_RIGHT
);
205 return (dWidth
+ dLeft
+ dRight
);
208 * @short Get width of table
209 * @param pTableStyle - pointer of XFTableStyle
210 * @return double - table width
212 double LwpSuperTableLayout::GetTableWidth()
214 sal_Int32 nWidth
= 0;
215 if(!IsJustifiable() || ((nWidth
= LwpMiddleLayout::GetMinimumWidth()) <= 0))
217 LwpTableLayout
* pTableLayout
= GetTableLayout();
223 LwpTable
*pTable
= pTableLayout
->GetTable();
229 double dDefaultWidth
= pTable
->GetWidth();
230 sal_uInt16 nCol
= pTable
->GetColumn();
234 for(sal_uInt16 i
=0; i
< nCol
; i
++)
236 LwpObjectID
*pColumnID
= pTableLayout
->GetColumnLayoutHead();
237 LwpColumnLayout
* pColumnLayout
= static_cast<LwpColumnLayout
*>(pColumnID
->obj());
238 double dColumnWidth
= dDefaultWidth
;
239 while (pColumnLayout
)
241 if(pColumnLayout
->GetColumnID() == i
)
243 dColumnWidth
= pColumnLayout
->GetWidth();
246 pColumnID
= pColumnLayout
->GetNext();
247 pColumnLayout
= static_cast<LwpColumnLayout
*>(pColumnID
->obj());
249 dWidth
+= dColumnWidth
;
255 double dLeft
= GetMarginsValue(MARGIN_LEFT
);
256 double dRight
= GetMarginsValue(MARGIN_RIGHT
);
257 return LwpTools::ConvertFromUnitsToMetric(nWidth
)-dLeft
-dRight
;
261 * @short Apply shadow to table
262 * @param pTableStyle - pointer of XFTableStyle
265 void LwpSuperTableLayout::ApplyShadow(XFTableStyle
*pTableStyle
)
267 // use shadow property of supertable
268 XFShadow
* pXFShadow
= GetXFShadow();
271 pTableStyle
->SetShadow(pXFShadow
->GetPosition(), pXFShadow
->GetOffset(), pXFShadow
->GetColor());
275 * @short Apply pattern fill to table style
276 * @param pTableStyle - pointer of XFTableStyle
279 void LwpSuperTableLayout::ApplyPatternFill(XFTableStyle
* pTableStyle
)
281 XFBGImage
* pXFBGImage
= this->GetFillPattern();
284 pTableStyle
->SetBackImage(pXFBGImage
);
289 * @short Apply background to table style
290 * @param pTableStyle - pointer of XFTableStyle
293 void LwpSuperTableLayout::ApplyBackGround(XFTableStyle
* pTableStyle
)
295 if (this->IsPatternFill())
297 ApplyPatternFill(pTableStyle
);
301 ApplyBackColor(pTableStyle
);
305 * @short Apply back color to table
306 * @param pTableStyle - pointer of XFTableStyle
309 void LwpSuperTableLayout::ApplyBackColor(XFTableStyle
*pTableStyle
)
311 LwpColor
* pColor
= GetBackColor();
312 if(pColor
&& pColor
->IsValidColor())
314 XFColor
aColor(pColor
->To24Color());
315 pTableStyle
->SetBackColor(aColor
);
319 * @short Apply watermark to table
320 * @param pTableStyle - pointer of XFTableStyle
323 void LwpSuperTableLayout::ApplyWatermark(XFTableStyle
*pTableStyle
)
325 XFBGImage
* pBGImage
= GetXFBGImage();
328 pTableStyle
->SetBackImage(pBGImage
);
332 * @short Apply alignment to table
333 * @param pTableStyle - pointer of XFTableStyle
336 void LwpSuperTableLayout::ApplyAlignment(XFTableStyle
* pTableStyle
)
340 aPoint
= GetGeometry()->GetOrigin();
341 //LwpPoint aPoint = GetOrigin();
342 double dXOffset
= LwpTools::ConvertFromUnitsToMetric(aPoint
.GetX());
344 // add left padding to alignment distance
345 double dLeft
= GetMarginsValue(MARGIN_LEFT
);
347 pTableStyle
->SetAlign(enumXFAlignStart
, dXOffset
+ dLeft
);
350 * @short Add table to container
351 * @param pCont - pointer of container
354 void LwpSuperTableLayout::XFConvert(XFContentContainer
* pCont
)
356 if ( LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE
== GetRelativeType()
357 && !GetContainerLayout()->IsCell())
359 LwpTableLayout
* pTableLayout
= GetTableLayout();
362 pTableLayout
->XFConvert(pCont
);
365 else if(IsRelativeAnchored())
367 //anchor to paragraph except "with paragraph above"
368 XFConvertFrame(pCont
);
372 //anchor to page, frame, cell
373 m_pFrame
->XFConvert(pCont
);
377 * @short convert frame which anchor to page
381 void LwpSuperTableLayout::XFConvertFrame(XFContentContainer
* pCont
, sal_Int32 nStart
, sal_Int32 nEnd
, sal_Bool bAll
)
385 XFFrame
* pXFFrame
= NULL
;
388 pXFFrame
= new XFFrame();
392 pXFFrame
= new XFFloatFrame(nStart
, nEnd
, bAll
);
395 m_pFrame
->Parse(pXFFrame
, static_cast<sal_uInt16
>(nStart
));
396 //parse table, and add table to frame
397 LwpTableLayout
* pTableLayout
= GetTableLayout();
400 pTableLayout
->XFConvert(pXFFrame
);
402 //add frame to the container
403 pCont
->Add(pXFFrame
);
412 void LwpSuperTableLayout::ParseFrame(XFFrame
* pXFFrame
)
416 m_pFrame
->Parse(pXFFrame
);
420 * @short register frame style
424 void LwpSuperTableLayout::RegisterFrameStyle()
426 XFFrameStyle
* pFrameStyle
= new XFFrameStyle();
427 m_pFrame
->RegisterStyle(pFrameStyle
);
430 LwpTableLayout::LwpTableLayout(LwpObjectHeader
&objHdr
, LwpSvStream
* pStrm
)
431 : LwpLayout(objHdr
, pStrm
),m_pXFTable(NULL
), m_nRows(0), m_nCols(0)
437 LwpTableLayout::~LwpTableLayout()
443 delete [] m_pColumns
;
448 * @short Get neighbour cell by specifying ROW+COL
451 * @return LwpCellLayout *
453 LwpCellLayout
* LwpTableLayout::GetCellByRowCol(sal_uInt16 nRow
, sal_uInt16 nCol
)
455 if (nRow
>= m_nRows
|| nCol
>= m_nCols
)
458 return m_WordProCellsMap
[nRow
*m_nCols
+ nCol
];
461 * @short traverse all table cells
466 void LwpTableLayout::TraverseTable()
468 sal_uInt32 iLoop
, jLoop
;
469 sal_uInt32 nCount
= m_nRows
*m_nCols
;
471 // new cell map nRow*nCOl and initialize
472 for(iLoop
= 0;iLoop
<nCount
; iLoop
++)
474 m_WordProCellsMap
.push_back(GetDefaultCellLayout());
478 LwpObjectID
*pRowID
= GetChildHead();
479 LwpRowLayout
* pRowLayout
= static_cast<LwpRowLayout
*>(pRowID
->obj());
482 pRowLayout
->SetRowMap();
484 // for 's analysis job
485 m_RowsMap
[pRowLayout
->GetRowID()] = pRowLayout
;
486 pRowLayout
->CollectMergeInfo();
487 // end for 's analysis
489 pRowID
= pRowLayout
->GetNext();
490 pRowLayout
= static_cast<LwpRowLayout
*>(pRowID
->obj());
495 * @short search the cell map
496 * @param nRow - row id (0 based)
497 * @param nRow - row id (0 based)
498 * @return LwpObjectID * - pointer to cell story object ID
500 LwpObjectID
* LwpTableLayout::SearchCellStoryMap(sal_uInt16 nRow
, sal_uInt16 nCol
)
502 if (nRow
>= m_nRows
|| nCol
>= m_nCols
)
507 LwpCellLayout
* pCell
= GetCellByRowCol(nRow
, nCol
);
510 // maybe connected cell layout
511 // maybe default cell layout
512 if (nRow
!= pCell
->GetRowID() || nCol
!= pCell
->GetColID())
516 return pCell
->GetContent();
523 * @short Get parent super table layout of table layout
524 * @return LwpSuperTableLayout * - pointer of parent super table layout
526 LwpSuperTableLayout
* LwpTableLayout::GetSuperTableLayout()
528 return static_cast<LwpSuperTableLayout
*>(GetParent()->obj());
531 * @short Get table pointer
532 * @return LwpTable * - content table pointer
534 LwpTable
* LwpTableLayout::GetTable()
536 LwpTable
*pTable
= static_cast<LwpTable
*>(m_Content
.obj());
540 * @short Get column style name by column ID
541 * @param sal_uInt16 -- col id(0 based)
542 * @return OUString - name of column style
544 OUString
LwpTableLayout::GetColumnWidth(sal_uInt16 nCol
)
549 return m_DefaultColumnStyleName
;
552 LwpColumnLayout
* pCol
= m_pColumns
[nCol
];
555 return pCol
->GetStyleName();
558 return m_DefaultColumnStyleName
;
561 * @short analyze all columns to get whole table width and width of all columns
562 * @short and register all column styles
565 void LwpTableLayout::RegisterColumns()
567 LwpTable
* pTable
= GetTable();
568 LwpSuperTableLayout
* pSuper
= GetSuperTableLayout();
570 sal_uInt16 nCols
= m_nCols
;
572 m_pColumns
= new LwpColumnLayout
*[nCols
];
573 sal_Bool
* pWidthCalculated
= new sal_Bool
[nCols
];
574 for(sal_uInt16 i
=0;i
<nCols
; i
++)
576 pWidthCalculated
[i
] = sal_False
;
577 m_pColumns
[i
] = NULL
;
580 double dDefaultColumn
= pTable
->GetWidth();
581 sal_uInt16 nJustifiableColumn
= nCols
;
583 double dTableWidth
= pSuper
->GetTableWidth();
585 // Get total width of justifiable columns
586 // NOTICE: all default columns are regarded as justifiable columns
587 LwpObjectID
*pColumnID
= GetColumnLayoutHead();
588 LwpColumnLayout
* pColumnLayout
= static_cast<LwpColumnLayout
*>(pColumnID
->obj());
589 while (pColumnLayout
)
591 m_pColumns
[pColumnLayout
->GetColumnID()] = pColumnLayout
;
592 if (!pColumnLayout
->IsJustifiable())
594 pWidthCalculated
[pColumnLayout
->GetColumnID()] = sal_True
;
595 dTableWidth
-= pColumnLayout
->GetWidth();
596 nJustifiableColumn
--;
599 pColumnID
= pColumnLayout
->GetNext();
600 pColumnLayout
= static_cast<LwpColumnLayout
*>(pColumnID
->obj());
603 // if all columns are not justifiable, the rightmost column will be changed to justifiable
604 if(nJustifiableColumn
== 0)
606 nJustifiableColumn
++;
607 if (m_pColumns
[nCols
- 1])
609 pWidthCalculated
[nCols
-1] = sal_False
;
610 dTableWidth
+= m_pColumns
[nCols
-1]->GetWidth();
615 dTableWidth
= dDefaultColumn
;
620 // justifiable columns will share the remain width averagely
621 dDefaultColumn
= dTableWidth
/nJustifiableColumn
;
623 // register defualt column style
624 XFColStyle
*pColStyle
= new XFColStyle();
625 pColStyle
->SetWidth(static_cast<float>(dDefaultColumn
));
627 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
628 m_DefaultColumnStyleName
= pXFStyleManager
->AddStyle(pColStyle
)->GetStyleName();
630 // register existed column style
632 for( i
=0;i
<nCols
; i
++)
636 m_pColumns
[i
]->SetFoundry(m_pFoundry
);
637 if(!pWidthCalculated
[i
])
639 // justifiable ----register style with calculated value
640 m_pColumns
[i
]->SetStyleName(m_DefaultColumnStyleName
);
644 // not justifiable ---- register style with original value
645 m_pColumns
[i
]->RegisterStyle(m_pColumns
[i
]->GetWidth());
649 delete [] pWidthCalculated
;
652 * @short register all row styles
655 void LwpTableLayout::RegisterRows()
657 LwpTable
* pTable
= GetTable();
664 // register default row style
665 XFRowStyle
* pRowStyle
= new XFRowStyle();
666 if (m_nDirection
& 0x0030)
668 pRowStyle
->SetMinRowHeight((float)pTable
->GetHeight());
672 pRowStyle
->SetRowHeight((float)pTable
->GetHeight());
674 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
675 m_DefaultRowStyleName
= pXFStyleManager
->AddStyle(pRowStyle
)->GetStyleName();
677 // register style of rows
678 LwpObjectID
* pRowID
= GetChildHead();
679 LwpRowLayout
* pRowLayout
= static_cast<LwpRowLayout
*>(pRowID
->obj());
682 pRowLayout
->SetFoundry(m_pFoundry
);
683 pRowLayout
->RegisterStyle();
685 pRowID
= pRowLayout
->GetNext();
686 pRowLayout
= static_cast<LwpRowLayout
*>(pRowID
->obj());
690 * @short register table style, if needed, including frame style
693 void LwpTableLayout::RegisterStyle()
695 // get super table layout
696 LwpSuperTableLayout
* pSuper
= GetSuperTableLayout();
704 LwpTable
* pTable
= GetTable();
711 // get row/column number of this table
712 m_nRows
= pTable
->GetRow();
713 m_nCols
= pTable
->GetColumn();
715 // get default cell layout of current table
716 LwpObjectID
* pID
= pTable
->GetDefaultCellStyle();
719 m_pDefaultCellLayout
= static_cast<LwpCellLayout
*>(pID
->obj());
722 // register columns styles
725 // register style of whole table
726 XFTableStyle
* pTableStyle
= new XFTableStyle();
728 sal_uInt8 nType
= pSuper
->GetRelativeType();
729 // If the table is not "with paragraph above" placement, create an frame style
730 // by supertable layout
731 if ( LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE
== nType
732 && !pSuper
->GetContainerLayout()->IsCell())
735 // pSuper->ApplyBackColor(pTableStyle);
736 pSuper
->ApplyBackGround(pTableStyle
);
737 pSuper
->ApplyWatermark(pTableStyle
);
738 pSuper
->ApplyShadow(pTableStyle
);
739 pSuper
->ApplyAlignment(pTableStyle
);
740 pTableStyle
->SetWidth(pSuper
->GetTableWidth());
744 pSuper
->RegisterFrameStyle();
745 pTableStyle
->SetAlign(enumXFAlignCenter
);
746 pTableStyle
->SetWidth(pSuper
->GetTableWidth());
748 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
749 m_StyleName
= pXFStyleManager
->AddStyle(pTableStyle
)->GetStyleName();
751 //convert to OO table now and register row stle
755 SplitConflictCells();
757 // Register rows layouts, it must be after SplitConflictCells
764 //Comment:The old code doesn't check if the LwpFoundry pointer is NULL,
765 // So the NULL pointer cause sodc frozee. Add code to check the
768 if( GetFoundry() && GetTable() )
770 PutCellVals( GetFoundry(),*GetTable()->GetObjectID() );
773 * @short read table layout
776 void LwpTableLayout::Parse()
778 // get super table layout
779 LwpSuperTableLayout
* pSuper
= GetSuperTableLayout();
786 // set name of object
787 m_pXFTable
= new XFTable
;
788 m_pXFTable
->SetTableName(pSuper
->GetName()->str());
790 m_pXFTable
->SetStyleName(m_StyleName
);
792 sal_uInt16 nRow
= m_nRows
;
793 sal_uInt8 nCol
= (sal_uInt8
)m_nCols
;
795 //process header rows
796 LwpTableHeadingLayout
* pTableHeading
;
797 pTableHeading
= pSuper
->GetTableHeadingLayout();
798 sal_uInt16 nStartHeadRow
;
799 sal_uInt16 nEndHeadRow
;
800 sal_uInt16 nContentRow
;
803 pTableHeading
->GetStartEndRow(nStartHeadRow
,nEndHeadRow
);
804 if (nStartHeadRow
!= 0)
805 ConvertTable(m_pXFTable
,0,nRow
,0,nCol
);
808 nContentRow
= ConvertHeadingRow(m_pXFTable
,nStartHeadRow
,nEndHeadRow
+1);
809 ConvertTable(m_pXFTable
,nContentRow
,nRow
,0,nCol
);
813 ConvertTable(m_pXFTable
,0,nRow
,0,nCol
);
817 * @short read table layout
820 void LwpTableLayout::Read()
824 // before layout hierarchy rework!
825 if(LwpFileHeader::m_nFileRevision
< 0x000b)
829 m_ColumnLayout
.ReadIndexed(m_pObjStrm
);
831 m_pObjStrm
->SkipExtra();
835 * @short Convert table
837 * @return pCont - container which will contain table
839 void LwpTableLayout::XFConvert(XFContentContainer
* pCont
)
842 pCont
->Add(m_pXFTable
);
845 * @short convert heading row
846 * @param pXFTable - pointer of table
847 * @param nStartRow - start heading row ID
848 * @param nEndRow - end heading row ID
850 sal_uInt16
LwpTableLayout::ConvertHeadingRow(
851 XFTable
* pXFTable
,sal_uInt16 nStartHeadRow
,sal_uInt16 nEndHeadRow
)
853 sal_uInt16 nContentRow
;
854 sal_uInt8 nCol
= static_cast<sal_uInt8
>(GetTable()->GetColumn());
855 sal_uInt8 nFirstColSpann
= 1;
856 XFTable
* pTmpTable
= new XFTable
;
859 ConvertTable(pTmpTable
,nStartHeadRow
,nEndHeadRow
,0,nCol
);
861 sal_uInt16 nRowNum
= static_cast<sal_uInt16
>(pTmpTable
->GetRowCount());
862 sal_uInt8
* CellMark
= new sal_uInt8
[nRowNum
];
863 sal_Bool bFindFlag
= sal_False
;
867 pXFRow
= pTmpTable
->GetRow(1);
868 pXFTable
->AddHeaderRow(pXFRow
);
869 pTmpTable
->RemoveRow(1);
870 nContentRow
= nEndHeadRow
;
874 bFindFlag
= FindSplitColMark(pTmpTable
,CellMark
,nFirstColSpann
);
876 if (bFindFlag
)//split to 2 cells
878 SplitRowToCells(pTmpTable
,pXFTable
,nFirstColSpann
,CellMark
);
879 nContentRow
= nEndHeadRow
;
881 else//can not split,the first row will be the heading row,the rest will be content row
883 pXFRow
= pTmpTable
->GetRow(1);
884 pXFTable
->AddHeaderRow(pXFRow
);
885 pTmpTable
->RemoveRow(1);
886 nContentRow
= m_RowsMap
[0]->GetCurMaxSpannedRows(0,nCol
);
894 void LwpTableLayout::SplitRowToCells(XFTable
* pTmpTable
,XFTable
* pXFTable
,
895 sal_uInt8 nFirstColSpann
,sal_uInt8
* pCellMark
)
899 sal_uInt16 nRowNum
= static_cast<sal_uInt16
>(pTmpTable
->GetRowCount());
900 sal_uInt8 nCol
= static_cast<sal_uInt8
>(GetTable()->GetColumn());
902 XFRow
* pXFRow
= new XFRow
;
904 //register style for heading row
907 XFRowStyle
* pRowStyle
= new XFRowStyle
;
908 styleName
= pTmpTable
->GetRow(1)->GetStyleName();
910 // get settings of the row and assign them to new row style
911 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
912 XFRowStyle
*pTempRowStyle
= static_cast<XFRowStyle
*>(pXFStyleManager
->FindStyle(styleName
));
914 *pRowStyle
= *pTempRowStyle
;
916 for (i
=1;i
<=nRowNum
;i
++)
918 styleName
= pTmpTable
->GetRow(i
)->GetStyleName();
919 fHeight
+=static_cast<XFRowStyle
*>(pXFStyleManager
->FindStyle(styleName
))->GetRowHeight();
921 if (m_nDirection
& 0x0030)
923 pRowStyle
->SetMinRowHeight((float)fHeight
);
927 pRowStyle
->SetRowHeight((float)fHeight
);
929 pXFRow
->SetStyleName(pXFStyleManager
->AddStyle(pRowStyle
)->GetStyleName());
931 //construct headong row
932 XFCell
* pXFCell1
= new XFCell
;
933 XFCell
* pXFCell2
= new XFCell
;
934 XFTable
* pSubTable1
= new XFTable
;
935 XFTable
* pSubTable2
= new XFTable
;
940 for (i
=1;i
<=nRowNum
;i
++)
942 pOldRow
= pTmpTable
->GetRow(i
);
944 pNewRow
->SetStyleName(pOldRow
->GetStyleName());
945 for (j
=1;j
<=pCellMark
[i
];j
++)
947 pNewCell
= pOldRow
->GetCell(j
);
948 pNewRow
->AddCell(pNewCell
);
950 pSubTable1
->AddRow(pNewRow
);
952 ConvertColumn(pSubTable1
,0,nFirstColSpann
);//add column info
954 pXFCell1
->Add(pSubTable1
);
955 pXFCell1
->SetColumnSpaned(nFirstColSpann
);
956 pXFRow
->AddCell(pXFCell1
);
958 for (i
=1;i
<=nRowNum
;i
++)
960 pOldRow
= pTmpTable
->GetRow(i
);
962 pNewRow
->SetStyleName(pOldRow
->GetStyleName());
963 for(j
=pCellMark
[i
]+1;j
<=pOldRow
->GetCellCount();j
++)
965 pNewCell
= pOldRow
->GetCell(j
);
966 pNewRow
->AddCell(pNewCell
);
968 pSubTable2
->AddRow(pNewRow
);
971 ConvertColumn(pSubTable2
,nFirstColSpann
,nCol
);//add column info
972 pXFCell2
->Add(pSubTable2
);
973 pXFCell2
->SetColumnSpaned(nCol
-nFirstColSpann
);
974 pXFRow
->AddCell(pXFCell2
);
976 pXFTable
->AddHeaderRow(pXFRow
);
979 for (i
=1;i
<=nRowNum
;i
++)
981 pOldRow
= pTmpTable
->GetRow(i
);
982 for(j
=1;j
<=pOldRow
->GetCellCount();j
++)
983 pOldRow
->RemoveCell(j
);
984 pTmpTable
->RemoveRow(i
);
989 * @short find if the heading rows can be split to 2 cells
990 * @param pXFTable - pointer of tmp XFtable
991 * @param CellMark - pointer of cell mark array
993 sal_Bool
LwpTableLayout::FindSplitColMark(XFTable
* pXFTable
,sal_uInt8
* pCellMark
,
994 sal_uInt8
& nMaxColSpan
)
996 sal_uInt16 nRowNum
= static_cast<sal_uInt16
>(pXFTable
->GetRowCount());
997 sal_uInt8 nColNum
= static_cast<sal_uInt8
>(pXFTable
->GetColumnCount());
998 sal_uInt8 nCellMark
=0;
1001 sal_Bool bFindFlag
= sal_False
;
1004 for(sal_uInt8 i
=1;i
<=nColNum
;i
++)
1006 sal_uInt16 nRowLoop
;
1007 sal_uInt8 nCellLoop
;
1009 //find current max column span
1011 for (nRowLoop
=1;nRowLoop
<=nRowNum
;nRowLoop
++)
1014 for(nCellLoop
=1; nCellLoop
<i
+1; nCellLoop
++)
1016 pTmpRow
= pXFTable
->GetRow(nRowLoop
);
1017 XFCell
* pCell
= pTmpRow
->GetCell(nCellLoop
);
1019 nColSpan
+= static_cast<sal_uInt8
>(pCell
->GetColSpaned());
1023 if (nColSpan
> nMaxColSpan
)
1024 nMaxColSpan
= nColSpan
;
1025 pCellMark
[nRowLoop
] = 0;//reset all cell mark to zero
1028 //find if other row has the same colum
1029 for (nRowLoop
=1;nRowLoop
<=nRowNum
;nRowLoop
++)
1031 pTmpRow
= pXFTable
->GetRow(nRowLoop
);
1034 for (nCellLoop
=1; nCellLoop
<=pTmpRow
->GetCellCount(); nCellLoop
++)
1036 if (nCount
>nMaxColSpan
)
1038 nCount
+= static_cast<sal_uInt8
>(pTmpRow
->GetCell(nCellLoop
)->GetColSpaned());
1039 if (nCount
== nMaxColSpan
)
1041 nCellMark
= nCellLoop
;
1048 pCellMark
[nRowLoop
] = nCellMark
;
1050 for(nRowLoop
=1;nRowLoop
<=nRowNum
;nRowLoop
++)//check if all ==0,break
1052 if (pCellMark
[nRowLoop
] == 0)
1055 if (nRowLoop
== nRowNum
+1)
1057 bFindFlag
= sal_True
;
1066 * @short convert word pro table to SODC table
1067 * @param pXFTable - pointer of table
1068 * @param nStartRow - start row ID
1069 * @param nEndRow - end row ID
1070 * @param nStartCol - start column ID
1071 * @param nEndCol - end column ID
1073 void LwpTableLayout::ConvertTable(XFTable
* pXFTable
,sal_uInt16 nStartRow
,
1074 sal_uInt16 nEndRow
,sal_uInt8 nStartCol
,sal_uInt8 nEndCol
)
1076 //out put column info TO BE CHANGED,note by ,2005/4/4
1077 ConvertColumn(pXFTable
,nStartCol
,nEndCol
);
1080 std::map
<sal_uInt16
,LwpRowLayout
*>::iterator iter
;
1082 for (sal_uInt16 i
=nStartRow
; i
<nEndRow
;)
1084 iter
= m_RowsMap
.find(i
);
1085 if (iter
== m_RowsMap
.end())
1087 ConvertDefaultRow(pXFTable
,nStartCol
,nEndCol
,i
);
1092 LwpRowLayout
* pRow
= iter
->second
;
1093 if (pRow
->GetCurMaxSpannedRows(nStartCol
,nEndCol
) == 1)
1095 pRow
->ConvertCommonRow(pXFTable
,nStartCol
,nEndCol
);
1100 pRow
->ConvertRow(pXFTable
,nStartCol
,nEndCol
);
1101 i
+= pRow
->GetCurMaxSpannedRows(nStartCol
,nEndCol
);
1108 * @short apply numeric value and formula to cell
1109 * @param pFoundry - pointer of foundry
1110 * @param aTableID - table ID
1112 void LwpTableLayout::PutCellVals(LwpFoundry
* pFoundry
, LwpObjectID aTableID
)
1115 //Comment:The old code doesn't check if the LwpFoundry pointer is NULL,
1116 // So the NULL pointer cause sodc frozee. Add code to check the
1119 if( !pFoundry
) return;
1124 LwpDLVListHeadHolder
* pHolder
= (LwpDLVListHeadHolder
*)pFoundry
->GetNumberManager()->GetTableRangeID().obj();
1126 LwpTableRange
* pTableRange
= (LwpTableRange
*)pHolder
->GetHeadID()->obj();
1129 while (NULL
!=pTableRange
)
1131 LwpObjectID aID
= pTableRange
->GetTableID();
1132 if (aID
== aTableID
)
1136 pTableRange
= pTableRange
->GetNext();
1141 LwpCellRange
* pRange
= (LwpCellRange
*)pTableRange
->GetCellRangeID().obj();
1142 LwpFolder
* pFolder
= (LwpFolder
*)pRange
->GetFolderID().obj();
1143 LwpObjectID aRowListID
= pFolder
->GetChildHeadID();
1144 LwpRowList
* pRowList
= (LwpRowList
*)aRowListID
.obj();
1147 while( NULL
!=pRowList
)
1149 sal_uInt16 nRowID
= pRowList
->GetRowID();
1151 LwpCellList
* pCellList
= (LwpCellList
*)pRowList
->GetChildHeadID().obj();
1153 while( NULL
!=pCellList
)
1156 sal_uInt16 nColID
= pCellList
->GetColumnID();
1158 XFCell
* pCell
= GetCellsMap(nRowID
,static_cast<sal_uInt8
>(nColID
));
1161 pCellList
->Convert(pCell
, this);
1164 PostProcessParagraph(pCell
, nRowID
, nColID
);
1168 //Hidden cell would not be in cellsmap
1172 pCellList
= (LwpCellList
*)pCellList
->GetNextID().obj();
1175 pRowList
=(LwpRowList
*)pRowList
->GetNextID().obj();
1185 * @short 1. set number right alignment to right if number 2. remove tab added before if number
1186 * @param pCell - cell which to be process
1187 * @param nRowID - row number in Word Pro file
1188 * @param nColID - column number in Word Pro file
1190 void LwpTableLayout::PostProcessParagraph(XFCell
*pCell
, sal_uInt16 nRowID
, sal_uInt16 nColID
)
1192 // if number right, set alignment to right
1193 LwpCellLayout
* pCellLayout
= GetCellByRowCol(nRowID
, nColID
);
1196 XFParagraph
* pXFPara
= NULL
;
1197 //mod by ,fix bug 2759,2006/3/22
1198 pXFPara
= static_cast<XFParagraph
*>(pCell
->FindFirstContent(enumXFContentPara
));
1203 XFColor aNullColor
= XFColor();
1207 OUString sNumfmt
= pCellLayout
->GetNumfmtName();
1208 sal_Bool bColorMod
= sal_False
;
1209 XFNumberStyle
* pNumStyle
= NULL
;
1210 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
1211 if (sNumfmt
.getLength())
1213 pNumStyle
= (XFNumberStyle
*)pXFStyleManager
->FindStyle( sNumfmt
);
1214 aColor
= pNumStyle
->GetColor();
1215 if ( pNumStyle
&& aColor
!= aNullColor
)
1216 bColorMod
= sal_True
;//end
1219 XFParaStyle
* pStyle
= pXFStyleManager
->FindParaStyle(pXFPara
->GetStyleName());
1220 if (pStyle
->GetNumberRight() || bColorMod
)
1222 XFParaStyle
* pOverStyle
= new XFParaStyle
;
1223 *pOverStyle
= *pStyle
;
1225 if (pStyle
->GetNumberRight())
1226 pOverStyle
->SetAlignType(enumXFAlignEnd
);
1230 XFFont
* pFont
= pOverStyle
->GetFont();
1231 aColor
= pFont
->GetColor();
1232 if ( aColor
== aNullColor
)
1234 XFFont
* pNewFont
= new XFFont
;
1235 aColor
= pNumStyle
->GetColor();
1236 pNewFont
->SetColor(aColor
);
1237 pOverStyle
->SetFont(pNewFont
);
1241 pOverStyle
->SetStyleName(A2OUSTR(""));
1242 OUString StyleName
= pXFStyleManager
->AddStyle(pOverStyle
)->GetStyleName();
1244 pXFPara
->SetStyleName(StyleName
);
1251 * @short Parse all cols of table
1252 * @param pXFTable - pointer to created XFTable
1254 void LwpTableLayout::ConvertColumn(XFTable
*pXFTable
,sal_uInt8 nStartCol
,sal_uInt8 nEndCol
)
1256 LwpTable
* pTable
= GetTable();
1263 for (sal_uInt16 iLoop
= 0; iLoop
< nEndCol
-nStartCol
; iLoop
++)
1266 LwpObjectID
*pColID
= GetColumnLayoutHead();
1267 LwpColumnLayout
* pColumnLayout
= static_cast<LwpColumnLayout
*>(pColID
->obj());
1268 while (pColumnLayout
)
1270 if (pColumnLayout
->GetColumnID() == (iLoop
+nStartCol
))
1272 pXFTable
->SetColumnStyle(iLoop
+1, pColumnLayout
->GetStyleName());
1275 pColID
= pColumnLayout
->GetNext();
1276 pColumnLayout
= static_cast<LwpColumnLayout
*>(pColID
->obj());
1280 pXFTable
->SetColumnStyle(iLoop
+1, m_DefaultColumnStyleName
);
1285 * @short split conflict merged cells
1287 void LwpTableLayout::SplitConflictCells()
1289 LwpTable
* pTable
= GetTable();
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
1309 pRowLayout
= iter1
->second
;
1310 if (pRowLayout
->GetMergeCellFlag() == sal_False
)
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())
1324 pEffectRow
= iter2
->second
;
1325 if (pEffectRow
->GetMergeCellFlag() == sal_False
)
1328 pEffectRow
->SetCellSplit(nEffectRows
);
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
1342 void LwpTableLayout::ConvertDefaultRow(XFTable
* 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
);
1348 sal_Bool bIsTop
= sal_False
;
1349 sal_Bool bIsRight
= sal_False
;
1351 for (sal_uInt16 j
=0;j
< nEndCol
-nStartCol
; j
++)
1353 // if table has default cell layout, use it to ConvertCell
1354 // otherwise use blank cell
1355 XFCell
* pCell
= NULL
;
1356 if (m_pDefaultCellLayout
)
1358 pCell
= m_pDefaultCellLayout
->ConvertCell(
1359 *GetTable()->GetObjectID(),nRowID
,j
+nStartCol
);
1363 pCell
= new XFCell();
1365 pRow
->AddCell(pCell
);
1368 pXFTable
->AddRow(pRow
);
1371 * @short set cell map info
1372 * @param pXFCell - pointer to xfcell
1373 * @param nRow - row id
1374 * @param nCol - column id
1376 void LwpTableLayout::SetCellsMap(sal_uInt16 nRow
,sal_uInt8 nCol
,XFCell
* pXFCell
)
1378 std::pair
<std::pair
<sal_uInt16
,sal_uInt8
>,XFCell
*> cell
;
1379 std::pair
<sal_uInt16
,sal_uInt8
> pos
;
1383 cell
.second
= pXFCell
;
1384 m_CellsMap
.insert(cell
);
1388 * @short get cell map info
1389 * @param nRow - row id
1390 * @param nCol - column id
1393 XFCell
* LwpTableLayout::GetCellsMap(sal_uInt16 nRow
,sal_uInt8 nCol
)
1395 std::pair
<sal_uInt16
,sal_uInt8
> pos
;
1398 std::map
<std::pair
<sal_uInt16
,sal_uInt8
>,XFCell
*>::iterator iter
;
1399 iter
= m_CellsMap
.find(pos
);
1400 if (iter
== m_CellsMap
.end())
1402 return iter
->second
;
1405 * @descr Get row layout by row id
1406 * @param nRow - row id
1408 LwpRowLayout
* LwpTableLayout::GetRowLayout(sal_uInt16 nRow
)
1410 LwpObjectID
*pRowID
= GetChildHead();
1411 LwpRowLayout
* pRowLayout
= static_cast<LwpRowLayout
*>(pRowID
->obj());
1414 if(pRowLayout
->GetRowID() == nRow
)
1417 pRowID
= pRowLayout
->GetNext();
1418 pRowLayout
= static_cast<LwpRowLayout
*>(pRowID
->obj());
1425 LwpColumnLayout::LwpColumnLayout(LwpObjectHeader
&objHdr
, LwpSvStream
* pStrm
)
1426 : LwpVirtualLayout(objHdr
, pStrm
)
1429 LwpColumnLayout::~LwpColumnLayout()
1431 void LwpColumnLayout::Read()
1433 LwpObjectStream
* pStrm
= m_pObjStrm
;
1435 LwpVirtualLayout::Read();
1439 colid
= pStrm
->QuickReaduInt16(); // forced to lushort
1440 ccolid
= (sal_uInt8
)colid
; // Phillip
1441 cwidth
= pStrm
->QuickReadInt32();
1446 void LwpColumnLayout::RegisterStyle(double dCalculatedWidth
)
1448 XFColStyle
* pColStyle
= new XFColStyle();
1449 pColStyle
->SetWidth(static_cast<float>(dCalculatedWidth
));
1450 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
1451 m_StyleName
= pXFStyleManager
->AddStyle(pColStyle
)->GetStyleName();
1454 LwpTableHeadingLayout::LwpTableHeadingLayout(LwpObjectHeader
&objHdr
, LwpSvStream
* pStrm
)
1455 : LwpTableLayout(objHdr
, pStrm
)
1458 LwpTableHeadingLayout::~LwpTableHeadingLayout()
1461 * @short read table heading layout
1465 void LwpTableHeadingLayout::Read()
1467 LwpTableLayout::Read();
1469 cStartRow
= m_pObjStrm
->QuickReaduInt16();
1470 cEndRow
= m_pObjStrm
->QuickReaduInt16();
1472 m_pObjStrm
->SkipExtra();
1476 * @short get start and end row number of table heading
1478 * @return *pStartRow - starting row number
1479 * @return *pEndRow - end row number
1481 void LwpTableHeadingLayout::GetStartEndRow(sal_uInt16
& nStartRow
, sal_uInt16
& nEndRow
)
1483 nStartRow
= cStartRow
;
1487 * @short get first row heading layout of table heading
1489 * @return LwpRowHeadingLayout * - pointer to first row heading layout of table heading
1491 LwpRowHeadingLayout
* LwpTableHeadingLayout::GetFirstRowHeadingLayout()
1493 LwpObjectID
*pID
= GetChildHead();
1494 if(pID
&& !pID
->IsNull())
1496 LwpRowHeadingLayout
* pHeadingRow
= static_cast<LwpRowHeadingLayout
*>(pID
->obj());
1502 LwpSuperParallelColumnLayout::LwpSuperParallelColumnLayout(LwpObjectHeader
&objHdr
, LwpSvStream
* pStrm
):LwpSuperTableLayout(objHdr
, pStrm
)
1505 LwpSuperParallelColumnLayout::~LwpSuperParallelColumnLayout()
1508 void LwpSuperParallelColumnLayout::Read()
1510 LwpSuperTableLayout::Read();
1511 m_pObjStrm
->SkipExtra();
1515 LwpSuperGlossaryLayout::LwpSuperGlossaryLayout(LwpObjectHeader
&objHdr
, LwpSvStream
* pStrm
):LwpSuperTableLayout(objHdr
, pStrm
)
1519 LwpSuperGlossaryLayout::~LwpSuperGlossaryLayout()
1523 void LwpSuperGlossaryLayout::Read()
1525 LwpSuperTableLayout::Read();
1526 m_pObjStrm
->SkipExtra();
1530 LwpParallelColumnsLayout::LwpParallelColumnsLayout(LwpObjectHeader
&objHdr
, LwpSvStream
* pStrm
):LwpTableLayout(objHdr
, pStrm
)
1534 LwpParallelColumnsLayout::~LwpParallelColumnsLayout()
1538 void LwpParallelColumnsLayout::Read()
1540 LwpTableLayout::Read();
1541 m_pObjStrm
->SkipExtra();