Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*************************************************************************
3 : *
4 : * The Contents of this file are made available subject to the terms of
5 : * either of the following licenses
6 : *
7 : * - GNU Lesser General Public License Version 2.1
8 : * - Sun Industry Standards Source License Version 1.1
9 : *
10 : * Sun Microsystems Inc., October, 2000
11 : *
12 : * GNU Lesser General Public License Version 2.1
13 : * =============================================
14 : * Copyright 2000 by Sun Microsystems, Inc.
15 : * 901 San Antonio Road, Palo Alto, CA 94303, USA
16 : *
17 : * This library is free software; you can redistribute it and/or
18 : * modify it under the terms of the GNU Lesser General Public
19 : * License version 2.1, as published by the Free Software Foundation.
20 : *
21 : * This library is distributed in the hope that it will be useful,
22 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 : * Lesser General Public License for more details.
25 : *
26 : * You should have received a copy of the GNU Lesser General Public
27 : * License along with this library; if not, write to the Free Software
28 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 : * MA 02111-1307 USA
30 : *
31 : *
32 : * Sun Industry Standards Source License Version 1.1
33 : * =================================================
34 : * The contents of this file are subject to the Sun Industry Standards
35 : * Source License Version 1.1 (the "License"); You may not use this file
36 : * except in compliance with the License. You may obtain a copy of the
37 : * License at http://www.openoffice.org/license.html.
38 : *
39 : * Software provided under this License is provided on an "AS IS" basis,
40 : * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
41 : * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
42 : * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
43 : * See the License for the specific provisions governing your rights and
44 : * obligations concerning the Software.
45 : *
46 : * The Initial Developer of the Original Code is: IBM Corporation
47 : *
48 : * Copyright: 2008 by IBM Corporation
49 : *
50 : * All Rights Reserved.
51 : *
52 : * Contributor(s): _______________________________________
53 : *
54 : *
55 : ************************************************************************/
56 : /**
57 : * @file
58 : * For LWP filter architecture prototype - row layouts
59 : */
60 : /*************************************************************************
61 : * Change History
62 : April 2005 Created
63 : ************************************************************************/
64 : #include "lwprowlayout.hxx"
65 : #include "lwptable.hxx"
66 : #include "lwpglobalmgr.hxx"
67 : #include "xfilter/xfstylemanager.hxx"
68 : #include "xfilter/xfrow.hxx"
69 : #include "xfilter/xfrowstyle.hxx"
70 : #include "xfilter/xftablestyle.hxx"
71 : #include "xfilter/xftable.hxx"
72 : #include "xfilter/xfcell.hxx"
73 : #include "xfilter/xfcellstyle.hxx"
74 :
75 6 : LwpRowLayout::LwpRowLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
76 6 : : LwpVirtualLayout(objHdr, pStrm)
77 : {
78 6 : m_ConnCellList.clear();
79 6 : }
80 :
81 11 : LwpRowLayout::~LwpRowLayout()
82 11 : {}
83 :
84 : /**
85 : * @short register row style
86 : * @param
87 : * @param
88 : * @param
89 : * @return
90 : */
91 5 : void LwpRowLayout::SetRowMap(void)
92 : {
93 5 : LwpObjectID *pCellID= GetChildHead();
94 5 : LwpCellLayout * pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj());
95 :
96 13 : while(pCellLayout)
97 : {
98 3 : pCellLayout->SetCellMap();
99 :
100 3 : pCellID = pCellLayout->GetNext();
101 3 : pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj());
102 : }
103 5 : }
104 : /**
105 : * @short register row style
106 : * @param
107 : * @param
108 : * @param
109 : * @return
110 : */
111 5 : void LwpRowLayout::RegisterStyle()
112 : {
113 : // register row style
114 5 : XFRowStyle *pRowStyle = new XFRowStyle();
115 :
116 5 : if (m_nDirection & 0x0030)
117 : {
118 5 : pRowStyle->SetMinRowHeight((float)LwpTools::ConvertFromUnitsToMetric(cheight));
119 : }
120 : else
121 : {
122 0 : pRowStyle->SetRowHeight((float)LwpTools::ConvertFromUnitsToMetric(cheight));
123 : }
124 5 : XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
125 5 : m_StyleName = pXFStyleManager->AddStyle(pRowStyle)->GetStyleName();
126 :
127 5 : LwpTableLayout* pTableLayout = GetParentTableLayout();
128 5 : if (pTableLayout)
129 : {
130 5 : pTableLayout->GetTable();
131 : }
132 : // register cells' style
133 5 : LwpObjectID *pCellID= GetChildHead();
134 5 : LwpCellLayout * pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj());
135 :
136 13 : while(pCellLayout)
137 : {
138 3 : pCellLayout->SetFoundry(m_pFoundry);
139 3 : pCellLayout->RegisterStyle();
140 3 : pCellID = pCellLayout->GetNext();
141 3 : pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj());
142 : }
143 :
144 5 : }
145 : /**
146 : * @short register row style
147 : * @param
148 : * @param
149 : * @param
150 : * @return
151 : */
152 6 : void LwpRowLayout::Read()
153 : {
154 : #define MAXUNIT (0x7fffffffL) // Highest positive UNIT value
155 6 : LwpObjectStream* pStrm = m_pObjStrm;
156 :
157 6 : LwpVirtualLayout::Read();
158 :
159 : //skip CLiteLayout data;
160 6 : LwpAtomHolder ContentClass;
161 6 : ContentClass.Read(pStrm);
162 6 : pStrm->SkipExtra();
163 :
164 : // Row layout content
165 6 : crowid = pStrm->QuickReaduInt16();
166 6 : cheight = pStrm->QuickReadInt32();
167 6 : cLeaderDotCount = (sal_uInt8)pStrm->QuickReaduInt16(); // was written as lushort.
168 6 : cLeaderDotY = MAXUNIT; // Sentinel meaning "not calculated yet"
169 6 : cRowFlags = (sal_uInt8)pStrm->QuickReaduInt16(); // was written as lushort.
170 :
171 6 : pStrm->SkipExtra();
172 6 : }
173 :
174 : /**
175 : * @short Parse rows with connect cell
176 : * @param pXFTable - pointer to created XFTable
177 : */
178 0 : void LwpRowLayout::ConvertRow(XFTable* pXFTable,sal_uInt8 nStartCol,sal_uInt8 nEndCol)
179 : {
180 0 : LwpTableLayout* pTableLayout = GetParentTableLayout();
181 0 : LwpTable* pTable = pTableLayout->GetTable();
182 :
183 : //calculate the connected cell position
184 0 : sal_Int32 nMarkConnCell = FindMarkConnCell(nStartCol,nEndCol);
185 :
186 : //if there is no connected cell
187 0 : if (nMarkConnCell == -1)
188 : {
189 0 : ConvertCommonRow(pXFTable,nStartCol,nEndCol);
190 0 : return;
191 : }
192 :
193 : //register connect row style
194 0 : sal_uInt16 nRowMark = crowid + GetCurMaxSpannedRows(nStartCol,nEndCol);
195 0 : XFRow* pXFRow = new XFRow;
196 0 : RegisterCurRowStyle(pXFRow,nRowMark);
197 :
198 : //if there is connected cell
199 0 : for (sal_uInt8 i=nStartCol; i<nEndCol; )
200 : {
201 : XFCell* pXFCell;
202 : sal_uInt8 nColMark;
203 :
204 0 : if (nMarkConnCell == -1)
205 0 : nColMark = nEndCol;
206 : else
207 0 : nColMark = m_ConnCellList[nMarkConnCell]->GetColID();
208 :
209 0 : if (nColMark > i)//create subtable
210 : {
211 0 : pXFCell = new XFCell;
212 0 : pXFCell->SetColumnSpaned(nColMark-i);
213 0 : XFTable* pSubTable = new XFTable;
214 0 : pTableLayout->ConvertTable(pSubTable,crowid,nRowMark,i,nColMark);
215 0 : pXFCell->Add(pSubTable);
216 0 : i = nColMark;
217 : }
218 : else
219 : {
220 0 : sal_uInt8 nColID = m_ConnCellList[nMarkConnCell]->GetColID()
221 0 : +m_ConnCellList[nMarkConnCell]->GetNumcols()-1;
222 0 : pXFCell = m_ConnCellList[nMarkConnCell]->ConvertCell(
223 0 : *pTable->GetObjectID(),
224 0 : crowid+m_ConnCellList[nMarkConnCell]->GetNumrows()-1,
225 0 : m_ConnCellList[nMarkConnCell]->GetColID());
226 :
227 : //set all cell in this merge cell to cellsmap
228 0 : for (sal_uInt16 nRowLoop = crowid;nRowLoop<nRowMark ;nRowLoop++)
229 0 : for (sal_uInt8 nColLoop = i;nColLoop<nColID+1;nColLoop++)
230 0 : pTableLayout->SetCellsMap(nRowLoop,nColLoop,pXFCell);
231 :
232 0 : i += m_ConnCellList[nMarkConnCell]->GetNumcols();
233 0 : nMarkConnCell = FindNextMarkConnCell(static_cast<sal_uInt16>(nMarkConnCell),nEndCol);
234 : }
235 :
236 0 : if (pXFCell)
237 0 : pXFRow->AddCell(pXFCell);
238 : }
239 0 : pXFTable->AddRow(pXFRow);
240 : }
241 :
242 : /**
243 : * @short register row style in SODC table
244 : * @param pXFRow - pointer of row
245 : * @param nRowMark - spanned row number
246 : */
247 0 : void LwpRowLayout::RegisterCurRowStyle(XFRow* pXFRow,sal_uInt16 nRowMark)
248 : {
249 0 : XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
250 0 : XFRowStyle* pRowStyle = static_cast<XFRowStyle*>(pXFStyleManager->FindStyle(m_StyleName));
251 0 : if (!pRowStyle)
252 0 : return;
253 0 : double fHeight = pRowStyle->GetRowHeight();
254 :
255 0 : XFRowStyle* pNewStyle = new XFRowStyle;
256 0 : *pNewStyle = *pRowStyle;
257 0 : LwpTableLayout* pTableLayout = GetParentTableLayout();
258 0 : if (!pTableLayout)
259 : {
260 0 : delete pNewStyle;
261 0 : return;
262 : }
263 0 : std::map<sal_uInt16,LwpRowLayout*> RowsMap = pTableLayout->GetRowsMap();
264 :
265 0 : for (sal_uInt16 i=crowid+1; i<nRowMark;i++)
266 : {
267 0 : std::map<sal_uInt16,LwpRowLayout*>::iterator iter = RowsMap.find(i);
268 0 : if (iter == RowsMap.end())
269 : {
270 : pRowStyle = static_cast<XFRowStyle*>(
271 0 : pXFStyleManager->FindStyle(pTableLayout->GetDefaultRowStyleName()));
272 0 : fHeight += pRowStyle->GetRowHeight();
273 : }
274 : else
275 : {
276 : pRowStyle = static_cast<XFRowStyle*>(
277 0 : pXFStyleManager->FindStyle(iter->second->GetStyleName()));
278 0 : fHeight+=pRowStyle->GetRowHeight();
279 : }
280 : }
281 :
282 0 : if (m_nDirection & 0x0030)
283 : {
284 0 : pNewStyle->SetMinRowHeight((float)fHeight);
285 : }
286 : else
287 : {
288 0 : pNewStyle->SetRowHeight((float)fHeight);
289 : }
290 :
291 0 : pXFRow->SetStyleName(pXFStyleManager->AddStyle(pNewStyle)->GetStyleName());
292 : }
293 :
294 : /**
295 : * @short find max merge cell in a given column range
296 : * @param nStartCol - start column ID
297 : * @param nEndCol - end column ID
298 : */
299 5 : sal_Int32 LwpRowLayout::FindMarkConnCell(sal_uInt8 nStartCol,sal_uInt8 nEndCol)
300 : {
301 5 : if (m_ConnCellList.empty())
302 5 : return -1;
303 :
304 0 : sal_uInt16 nSpannRows = 1;
305 0 : sal_Int32 nMarkConnCell = -1;
306 :
307 0 : for (sal_uInt16 i=0;i<m_ConnCellList.size();i++)
308 : {
309 0 : if (m_ConnCellList[i]->GetColID()>=nEndCol)
310 0 : break;
311 0 : if (m_ConnCellList[i]->GetColID()>=nStartCol)
312 : {
313 0 : if (m_ConnCellList[i]->GetNumrows()>nSpannRows)
314 : {
315 0 : nSpannRows = m_ConnCellList[i]->GetNumrows();
316 0 : nMarkConnCell = i;
317 : }
318 : }
319 : }
320 0 : return nMarkConnCell;
321 : }
322 :
323 : /**
324 : * @short find next merge cell with the same spanned row number with current merge cell
325 : * @param nStartCol - start column ID
326 : * @param nEndCol - end column ID
327 : */
328 0 : sal_Int32 LwpRowLayout::FindNextMarkConnCell(sal_uInt16 nMarkConnCell,sal_uInt8 nEndCol)
329 : {
330 0 : sal_uInt16 nMaxRows = m_ConnCellList[nMarkConnCell]->GetNumrows();
331 :
332 0 : for (sal_uInt16 i=nMarkConnCell+1;i<m_ConnCellList.size();i++)
333 : {
334 0 : if (m_ConnCellList[i]->GetColID()>=nEndCol)
335 0 : break;
336 0 : if (m_ConnCellList[i]->GetNumrows() == nMaxRows)
337 : {
338 0 : return i;
339 : }
340 : }
341 0 : return -1;
342 : }
343 : /**
344 : * @short get max spanned row numbers in a given column range
345 : * @param nStartCol - start column ID
346 : * @param nEndCol - end column ID
347 : */
348 5 : sal_uInt16 LwpRowLayout::GetCurMaxSpannedRows(sal_uInt8 nStartCol,sal_uInt8 nEndCol)
349 : {
350 5 : sal_Int32 nMarkConnCell = FindMarkConnCell(nStartCol,nEndCol);
351 5 : if (nMarkConnCell == -1)
352 5 : return 1;
353 : else
354 0 : return m_ConnCellList[nMarkConnCell]->GetNumrows();
355 : }
356 : /**
357 : * @short convert row with rowlayout,but no merge cells
358 : * @param pXFTable - pointer of table
359 : * @param nStartCol - start column ID
360 : * @param nEndCol - end column ID
361 : */
362 5 : void LwpRowLayout::ConvertCommonRow(XFTable* pXFTable,sal_uInt8 nStartCol,sal_uInt8 nEndCol)
363 : {
364 5 : XFRow* pRow = new XFRow;
365 5 : pRow->SetStyleName(m_StyleName);
366 :
367 5 : XFCell * pCell = NULL;
368 5 : LwpTableLayout* pTableLayout = GetParentTableLayout();
369 5 : LwpTable* pTable = pTableLayout->GetTable();
370 : sal_uInt8 nCellStartCol,nCellEndCol;
371 :
372 25 : for (sal_uInt8 i = nStartCol; i < nEndCol ; i++)
373 : {
374 : // add row to table
375 20 : LwpObjectID *pCellID= GetChildHead();
376 20 : LwpCellLayout * pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj());
377 20 : nCellStartCol = i;//mark the begin position of cell
378 20 : nCellEndCol = i;//mark the end position of cell
379 48 : while(pCellLayout)
380 : {
381 11 : if (pCellLayout->GetColID() == i)
382 : {
383 3 : if (pCellLayout->GetLayoutType() == LWP_CONNECTED_CELL_LAYOUT)
384 : {
385 0 : LwpConnectedCellLayout* pConnCell = static_cast<LwpConnectedCellLayout*>(pCellLayout);
386 0 : nCellEndCol = i+pConnCell->GetNumcols()-1;
387 0 : i = nCellEndCol;
388 : }
389 3 : pCell = pCellLayout->ConvertCell(*pTable->GetObjectID(),crowid,i);
390 3 : break;
391 : }
392 8 : pCellID = pCellLayout->GetNext();
393 8 : pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj());
394 : }
395 20 : if (!pCellLayout)
396 : {
397 : // if table has default cell layout, use it to ConvertCell
398 : // otherwise use blank cell
399 17 : LwpCellLayout * pDefaultCell = pTableLayout->GetDefaultCellLayout();
400 17 : if (pDefaultCell)
401 : {
402 : pCell = pDefaultCell->ConvertCell(
403 17 : *pTable->GetObjectID(),crowid, i);
404 : }
405 : else
406 : {
407 0 : pCell = new XFCell;
408 : }
409 : }
410 20 : pRow->AddCell(pCell);
411 :
412 40 : for (sal_uInt8 j=nCellStartCol;j<=nCellEndCol;j++)
413 20 : pTableLayout->SetCellsMap(crowid,j,pCell);//set to cellsmap
414 : }
415 :
416 5 : pXFTable->AddRow(pRow);
417 5 : }
418 : /**
419 : * @short collect merge cell info when register row styles
420 : */
421 5 : void LwpRowLayout::CollectMergeInfo()
422 : {
423 5 : LwpObjectID *pCellID= GetChildHead();
424 5 : LwpCellLayout * pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj());
425 :
426 13 : while(pCellLayout)
427 : {
428 3 : if (pCellLayout->GetLayoutType() == LWP_CONNECTED_CELL_LAYOUT)
429 : {
430 0 : LwpConnectedCellLayout* pConnCell = static_cast<LwpConnectedCellLayout*>(pCellLayout);
431 0 : m_ConnCellList.push_back(pConnCell);
432 : }
433 3 : pCellID = pCellLayout->GetNext();
434 3 : pCellLayout = dynamic_cast<LwpCellLayout *>(pCellID->obj());
435 : }
436 5 : }
437 : /**
438 : * @short split merge cells in this row
439 : * @param nEffectRows - max spanned number of prevoius row
440 : */
441 0 : void LwpRowLayout::SetCellSplit(sal_uInt16 nEffectRows)
442 : {
443 : LwpConnectedCellLayout* pConnCell;
444 0 : for (sal_uInt32 i=0; i<m_ConnCellList.size(); i++)
445 : {
446 0 : pConnCell = m_ConnCellList[i];
447 0 : sal_uInt16 nRowSpan = pConnCell->GetRowID()+pConnCell->GetNumrows();
448 0 : if ( nRowSpan > nEffectRows )
449 : {
450 0 : pConnCell->SetNumrows(nEffectRows - pConnCell->GetRowID());
451 : }
452 : }
453 0 : }
454 : /**
455 : * @short check if the row has merge cell
456 : */
457 5 : sal_Bool LwpRowLayout::GetMergeCellFlag()
458 : {
459 5 : if (m_ConnCellList.empty())
460 5 : return sal_False;
461 : else
462 0 : return sal_True;
463 : }
464 :
465 :
466 0 : LwpRowHeadingLayout::LwpRowHeadingLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
467 0 : : LwpRowLayout(objHdr, pStrm)
468 0 : {}
469 :
470 0 : LwpRowHeadingLayout::~LwpRowHeadingLayout()
471 0 : {}
472 0 : void LwpRowHeadingLayout::Read()
473 : {
474 0 : LwpRowLayout::Read();
475 :
476 0 : cRowLayout.ReadIndexed(m_pObjStrm);
477 0 : m_pObjStrm->SkipExtra();
478 0 : }
479 :
480 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|