1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */
2 
3 /* AbiWord
4  * Copyright (C) 2002 Martin Sevior <msevior@physics.unimelb.edu.au>
5  * Copyright (C) 2003 Francis James Franklin <fjf@alinameridon.com>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301 USA.
21  */
22 
23 #ifndef IE_TABLES
24 #define IE_TABLES
25 
26 #include <stack>
27 #include "pd_Document.h"
28 #include "pt_Types.h"
29 #include "ut_wctomb.h"
30 
31 class PD_Document;
32 class PX_ChangeRecord_Object;
33 class PP_AttrProp;
34 class ie_imp_table;
35 
36 
37 class ABI_EXPORT ie_PartTable
38 {
39  public:
40 	ie_PartTable(PD_Document * pDoc);
41 	virtual ~ie_PartTable(void);
42 	void             setDoc(PD_Document * pDoc);
43 	void             setTableApi(pf_Frag_Strux* sdh,PT_AttrPropIndex iApi);
44 	void             setCellApi(PT_AttrPropIndex iApi);
45 	UT_sint32        getLeft(void);
46 	UT_sint32        getRight(void);
getPrevRight(void)47 	UT_sint32        getPrevRight(void) {return m_iPrevRight;}
48 	UT_sint32        getTop(void);
49 	UT_sint32        getBot(void);
50 	const char *     getTableProp(const char * pPropName);
51 	const char *     getCellProp(const char * pPropName);
getTableAPI(void)52 	PT_AttrPropIndex getTableAPI(void) const {return m_apiTable;}
getCellAPI(void)53 	PT_AttrPropIndex getCellAPI(void) const { return m_apiCell;}
54 	UT_sint32        getNumRows(void);
55 	UT_sint32        getNumCols(void);
getCurRow(void)56 	UT_sint32        getCurRow(void) const { return m_iCurRow;}
incCurRow(void)57 	void             incCurRow(void) { m_iCurRow++;}
getTableSDH(void)58 	pf_Frag_Strux* getTableSDH(void)
59 		{ return m_TableSDH;}
60 	void             setCellJustOpenned(bool b);
61 	bool             isCellJustOpenned(void);
62  private:
63 	void                  _setRowsCols(void);
64 	void                  _clearAll(void);
65 	void                  _clearAllCell(void);
66 	PD_Document *         m_pDoc;
67 	PT_AttrPropIndex      m_apiTable;
68 	PT_AttrPropIndex      m_apiCell;
69 	const PP_AttrProp *   m_TableAttProp;
70 	const PP_AttrProp *   m_CellAttProp;
71 	UT_sint32             m_iNumRows;
72 	UT_sint32             m_iNumCols;
73 	UT_sint32             m_iLeft;
74 	UT_sint32             m_iRight;
75 	UT_sint32             m_iTop;
76 	UT_sint32             m_iBot;
77 	UT_sint32             m_iPrevLeft;
78 	UT_sint32             m_iPrevRight;
79 	UT_sint32             m_iPrevTop;
80 	UT_sint32             m_iPrevBot;
81 	pf_Frag_Strux*     m_TableSDH;
82 	bool                  m_bIsCellJustOpenned;
83 	UT_sint32             m_iCurRow;
84 };
85 
86 
87 class ABI_EXPORT ie_Table
88 {
89  public:
90 	ie_Table(PD_Document * pDoc);
91 	ie_Table(void);
92 	virtual ~ie_Table(void);
93 	void             setDoc(PD_Document * pDoc);
94 	void             OpenTable(pf_Frag_Strux* tableSDH, PT_AttrPropIndex iApi);
95 	void             OpenCell(PT_AttrPropIndex iApi);
96 	void             CloseTable(void);
97 	void             CloseCell(void);
98     bool             isNewRow(void);
99 	UT_sint32        getLeft(void);
100 	UT_sint32        getRight(void);
101 	UT_sint32        getTop(void);
102 	UT_sint32        getBot(void);
103 	UT_sint32        getNumRows(void);
104 	UT_sint32        getNumCols(void);
105 	const char *     getTableProp(const char * pPropName);
106 	const char *     getCellProp(const char * pPropName);
107 	UT_sint32        getNestDepth(void);
108 	void             setCellRowCol(UT_sint32 row, UT_sint32 col);
109 	pf_Frag_Strux* getTableSDH(void);
110 	void             setCellJustOpenned(bool b);
111 	bool             isCellJustOpenned(void);
112 	PT_AttrPropIndex getTableAPI(void);
113 	PT_AttrPropIndex getCellAPI(void);
114 	UT_sint32        getPrevNumRightMostVMerged(void);
115 	UT_sint32        getCurRow(void);
116 	void             incCurRow(void);
117  private:
118 	PD_Document *     m_pDoc;
119 	std::stack<ie_PartTable*> m_sLastTable;
120 	bool              m_bNewRow;
121 	pf_Frag_Strux*  m_sdhLastCell;
122 };
123 
124 
125 class ABI_EXPORT ie_imp_cell
126 {
127  public:
128 	ie_imp_cell(ie_imp_table * pImpTable, PD_Document * pDoc,
129 				ie_imp_cell * pImpCell, UT_sint32 iRow);
130 	virtual          ~ie_imp_cell(void);
131 	void             setCellX(UT_sint32 cellx);
132 	UT_sint32        getCellX(void);
133 	void             setCellLeft(ie_imp_cell * pImpCell);
134 	void             setLeft(UT_sint32 iLeft);
135 	UT_sint32        getLeft(void);
136 	void             setRight(UT_sint32 iRight);
137 	UT_sint32        getRight(void);
138 	void             setTop(UT_sint32 iTop);
139 	UT_sint32        getTop(void);
140 	void             setBot(UT_sint32 iBot);
141 	UT_sint32        getBot(void);
142 	pf_Frag_Strux* getCellSDH(void);
143 	void             setCellSDH(pf_Frag_Strux* cellSDH);
144 	bool             writeCellPropsInDoc(void);
145 	ie_imp_cell *    getCellAbove(void);
146 	ie_imp_cell *    getCellBelow(void);
147 	ie_imp_cell *    getCellLeft(void);
148 	ie_imp_cell *    getCellRight(void);
149 	void             addPropString(const UT_String & sPropString);
150 	void             setProp(const UT_String & psProp, const UT_String & psVal);
151 	UT_String        getPropVal(const UT_String & psProp);
152 	void             setProp(const char * szProp, const char * szVal);
153 	UT_String        getPropVal(const char * szProp);
getRow(void)154 	UT_sint32        getRow(void) { return m_iRow;}
setMergeAbove(bool bAbove)155 	void             setMergeAbove(bool bAbove) { m_bMergeAbove = bAbove;}
setMergeRight(bool bRight)156 	void             setMergeRight(bool bRight) {m_bMergeRight = bRight;}
setMergeLeft(bool bLeft)157 	void             setMergeLeft(bool bLeft) {m_bMergeLeft = bLeft;}
setFirstHorizontalMerge(bool bHori)158 	void             setFirstHorizontalMerge(bool bHori) {m_bFirstHori = bHori;}
setFirstVerticalMerge(bool bVert)159 	void             setFirstVerticalMerge( bool bVert) {m_bFirstVertical = bVert;}
isMergedAbove(void)160 	bool             isMergedAbove(void )const {return m_bMergeAbove;}
isMergedRight(void)161 	bool             isMergedRight(void) const {return m_bMergeRight;}
isMergedLeft(void)162 	bool             isMergedLeft(void) const {return m_bMergeLeft;}
isFirstVerticalMerged(void)163 	bool             isFirstVerticalMerged(void) const {return m_bFirstVertical;}
isFirstHorizontalMerged(void)164 	bool             isFirstHorizontalMerged(void) const {return m_bFirstHori;}
165 	void             copyCell(ie_imp_cell * pCell);
setImpTable(ie_imp_table * pTable)166 	void             setImpTable(ie_imp_table * pTable) { m_pImpTable = pTable;}
setRow(UT_sint32 row)167 	void             setRow(UT_sint32 row) { m_iRow = row;}
168  private:
169 	PD_Document *         m_pDoc;
170 	UT_sint32             m_iCellX;
171 	UT_sint32             m_iLeft;
172 	UT_sint32             m_iRight;
173 	UT_sint32             m_iTop;
174 	UT_sint32             m_iBot;
175 	pf_Frag_Strux*     m_cellSDH;
176 	ie_imp_table   *      m_pImpTable;
177     ie_imp_cell *         m_pCellLeft;
178 	UT_sint32             m_iRow;
179 	bool                  m_bMergeAbove;
180 	bool                  m_bMergeRight;
181 	bool                  m_bMergeLeft;
182 	bool                  m_bFirstVertical;
183 	bool                  m_bFirstHori;
184 	UT_String             m_sCellProps;
185 };
186 
187 
188 class ABI_EXPORT ie_imp_table
189 {
190  public:
191 	ie_imp_table(PD_Document * pDoc);
192 	virtual ~ie_imp_table(void);
193 	UT_sint32           OpenCell(void);
194 	UT_sint32           NewRow(void);
195 	void                setCellRowNthCell(UT_sint32 row, UT_sint32 col);
196 	ie_imp_cell *       getNthCellOnRow(UT_sint32 iCell);
197 	void                setCellX(UT_sint32 cellx);
198 	pf_Frag_Strux*   getTableSDH(void);
199 	void                setTableSDH(pf_Frag_Strux* cellSDH);
200 	void                writeTablePropsInDoc(void);
201 	void                writeAllCellPropsInDoc(void);
202 	void                setProp(const UT_String & psProp, const UT_String & psVal);
203 	void                setProp(const char *szProp, const char *  szVal);
204 	UT_String           getPropVal(const UT_String & psProp);
205 	UT_String           getPropVal(const char * szProp);
206 	UT_String           getCellPropVal(const UT_String & psProp);
207 	void                setCellProp(const UT_String & psProp, const UT_String & psVal);
208 	ie_imp_cell *       getCurCell(void);
209 	void                setNthCellOnThisRow(UT_sint32 iCell);
210 	void                buildTableStructure(void);
setAutoFit(bool bVal)211 	void                setAutoFit(bool bVal) {m_bAutoFit = bVal;}
isAutoFit(void)212 	bool                isAutoFit(void) { return m_bAutoFit;}
isNewRow(void)213 	bool                isNewRow(void) { return m_bNewRow;}
214 	UT_sint32           getColNumber(ie_imp_cell * pImpCell);
215 	ie_imp_cell *       getCellAtRowColX(UT_sint32 newRow,UT_sint32 cellX);
216 	void                CloseCell(void);
wasTableUsed(void)217 	bool                wasTableUsed(void) { return m_bTableUsed;}
setCell(ie_imp_cell * pCell)218 	void                setCell( ie_imp_cell * pCell) { m_pCurImpCell = pCell;}
getRow(void)219 	UT_sint32           getRow(void) { return m_iRowCounter;}
220 	void                removeExtraneousCells(void);
221 	void                removeOnThisCellRow(ie_imp_cell * pCell);
222 	void                removeCurrentRow(void);
223 	void                deleteRow(UT_sint32 row);
224 	UT_sint32           getNumRows(void);
setPosOnRow(UT_sint32 posOnRow)225 	void                setPosOnRow(UT_sint32 posOnRow) { m_iPosOnRow = posOnRow;}
getPosOnRow(void)226 	UT_sint32           getPosOnRow(void) { return m_iPosOnRow;}
setCellXOnRow(UT_sint32 cellxOnRow)227 	void                setCellXOnRow(UT_sint32 cellxOnRow) { m_iCellXOnRow = cellxOnRow;}
getCellXOnRow(void)228 	UT_sint32           getCellXOnRow(void) { return m_iCellXOnRow;}
incPosOnRow(void)229 	void                incPosOnRow(void) { m_iPosOnRow++;}
incCellXOnRow(void)230 	void                incCellXOnRow(void) { m_iCellXOnRow++;}
231 	bool                getVecOfCellsOnRow(UT_sint32 row, UT_GenericVector<ie_imp_cell*> * pVec);
232 	bool                removeRow(UT_sint32 row);
233 	void                appendRow(UT_GenericVector<ie_imp_cell*>* pVecRowOfCells);
234 	bool                doCellXMatch(UT_sint32 iCellX1, UT_sint32 iCellX2,bool bIsLast = false);
235  private:
236 	void                _buildCellXVector(void);
237 	void                _removeAllStruxes(void);
238 	PD_Document *       m_pDoc;
239 	pf_Frag_Strux*   m_tableSDH;
240 	ie_imp_cell *       m_pCurImpCell;
241 	UT_sint32           m_iRowCounter;
242 	UT_String           m_sTableProps;
243 	bool                m_bAutoFit;
244 	bool                m_bNewRow;
245 	bool                m_bTableUsed;
246 	UT_sint32           m_iPosOnRow;
247 	UT_sint32           m_iCellXOnRow;
248 	UT_GenericVector<ie_imp_cell*> m_vecCells;
249 	UT_NumberVector           m_vecCellX;
250 	UT_NumberVector           m_vecSavedX;
251 };
252 
253 class ABI_EXPORT ie_imp_table_control
254 {
255 public:
256 	ie_imp_table_control(PD_Document * pDoc);
257 	virtual ~ie_imp_table_control(void);
258 	UT_sint32           getNestDepth(void);
259 	void                OpenTable(void);
260 	UT_sint32           OpenCell(void);
261 	void                CloseTable(void);
262 	void                CloseCell(void);
263 	ie_imp_table *      getTable(void);
264 	bool                NewRow(void);
265 	void                SaveRowInfo(void);
266 	void                RemoveRowInfo(void);
267 private:
268 	std::stack<ie_imp_table*> m_sLastTable;
269 	PD_Document *       m_pDoc;
270 };
271 
272 // EXPERIMENTAL CODE
273 #define USE_IE_IMP_TABLEHELPER 1
274 
275 #ifdef USE_IE_IMP_TABLEHELPER
276 enum TableZone
277 	{
278 		/* tz_caption, */
279 		tz_head,
280 		tz_foot,
281 		tz_body
282 	};
283 class ABI_EXPORT CellHelper
284 {
285 public:
286 	CellHelper ();
287 	void setProp(const char * szProp, const UT_String sVal);
288 	UT_UTF8String		m_style;
289 
290 		/* cell frag/strux
291 		 */
292 	pf_Frag_Strux *		m_pfsCell;
293 
294 		/* cell-attach points
295 		 */
296 	UT_sint32			m_bottom;
297 	UT_sint32			m_left;
298 	UT_sint32			m_right;
299 	UT_sint32			m_top;
300 
301 	UT_sint32			m_rowspan;
302 	UT_sint32			m_colspan;
303 
304 	CellHelper *		m_next;
305 	TableZone           m_tzone;
306 	UT_String           m_sCellProps;
isVirtual()307 	bool	isVirtual () const { return (m_next != 0); }
308 };
309 
310 class ABI_EXPORT IE_Imp_TableHelper
311 {
312 public:
313 	IE_Imp_TableHelper (PD_Document * pDocument, pf_Frag_Strux * pfsInsertionPoint, const char * style);
314 
315 	~IE_Imp_TableHelper ();
316 	bool	           tableStart ();
317 
318 	bool	           tableEnd ();
319 	bool	           theadStart (const char * style);
320 	bool	           tfootStart (const char * style);
321 	bool	           tbodyStart (const char * style = 0);
322 
323 	bool	           trStart (const char * style);
324 	bool	           tdStart (UT_sint32 rowspan, UT_sint32 colspan, const char * style, pf_Frag_Strux * pfsThis);
325 	/* append/insert methods
326 	 */
327 	bool	           Block (PTStruxType pts, const gchar ** attributes);
328 	bool	           BlockFormat (const gchar ** attributes);
329 
330 	bool	           Inline (const UT_UCSChar * ucs4_str, UT_sint32 length);
331 	bool	           InlineFormat (const gchar ** attributes);
332 
333 	bool	           Object (PTObjectType pto, const gchar ** attributes);
334     void               padAllRowsWithCells(UT_GenericVector<CellHelper *> & vecCells,UT_sint32 extra);
335 	void               padRowWithCells(UT_GenericVector<CellHelper *> & vecCells,UT_sint32 row, UT_sint32 extra);
336 	CellHelper *       getCellAtRowCol(UT_GenericVector<CellHelper *> & vecCells, UT_sint32 row, UT_sint32 col);
337     bool               setCaptionOn(void);
338 	bool               setCaptionOff(void);
339 	bool               tdEnd(void);
340 
getInsertionPoint()341 	pf_Frag_Strux *	    getInsertionPoint () const { return m_pfsInsertionPoint; }
342 
343 private:
344 
345 	/* 1. Need a section on column definitions, allowing for <col> and <colgroup><col>
346 	 * 2. <thead> & <tfoot> should come before <tbody>; any repeats or trailing entries
347 	 *    shall be treated as additional <tbody> sections for the moment
348 	 */
349 	bool	trEnd ();
350 	void	trClean ();
351 	bool	tdPending ();
352 
353 	PD_Document *		m_pDocument;
354 
355 	UT_UTF8String		m_style_table;
356 	UT_UTF8String		m_style_tzone; // thead,tfoot,tbody
357 	UT_UTF8String		m_style; // tr
358 
359 	/* cell frag/strux
360 	 */
361 	pf_Frag_Strux *		m_pfsInsertionPoint;
362 	pf_Frag_Strux *		m_pfsTableStart;
363 	pf_Frag_Strux *		m_pfsTableEnd;
364 	pf_Frag_Strux *     m_pfsCellPoint;
365 	UT_sint32			m_rows;
366 	UT_sint32			m_rows_head;
367 	UT_sint32			m_rows_head_max;
368 	UT_sint32			m_rows_foot;
369 	UT_sint32			m_rows_foot_max;
370 	UT_sint32			m_rows_body;
371 	UT_sint32			m_rows_body_max;
372 
373 	UT_sint32			m_cols;
374 	UT_sint32			m_cols_max;
375 
376 	UT_sint32			m_col_next;
377 	UT_sint32			m_row_next;
378 
379 	UT_GenericVector<CellHelper *>	m_thead;
380 	UT_GenericVector<CellHelper *>	m_tfoot;
381 	UT_GenericVector<CellHelper *>	m_tbody;
382 
383 	CellHelper *		m_current;
384 	TableZone			m_tzone;
385 	bool                m_bBlockInsertedForCell;
getDoc()386 	PD_Document *	    getDoc () const { return m_pDocument; }
387 	bool                m_bCaptionOn;
388 };
389 
390 class ABI_EXPORT IE_Imp_TableHelperStack
391 {
392 public:
393 	IE_Imp_TableHelperStack (void);
394 
395 	~IE_Imp_TableHelperStack ();
396 
397 	void					clear ();
398 	IE_Imp_TableHelper *	top () const;
399 
400 	bool					tableStart (PD_Document * pDocument, const char * style);
401 	bool					tableEnd ();
402 
403 	bool					theadStart (const char * style);
404 	bool					tfootStart (const char * style);
405 	bool					tbodyStart (const char * style = 0);
406 	bool					trStart (const char * style);
407 	bool					tdStart (UT_sint32 rowspan, UT_sint32 colspan, const char * style);
408 
409 	/* append/insert methods
410 	 */
411 	bool					Block (PTStruxType pts, const gchar ** attributes);
412 	bool					BlockFormat (const gchar ** attributes);
413 
414 	bool					Inline (const UT_UCSChar * ucs4_str, UT_sint32 length);
415 	bool					InlineFormat (const gchar ** attributes);
416 
417 	bool					Object (PTObjectType pto, const gchar ** attributes);
418 	bool                    setCaptionOn(void);
419 	bool                    setCaptionOff(void);
420 	bool                    tdEnd(void);
421 private:
422 	PD_Document *			m_pDocument;
423 
424 	UT_sint32				m_count;
425 	UT_sint32				m_max;
426 
427 	IE_Imp_TableHelper **	m_stack;
428 	bool					push (const char * style);
429 	bool					pop ();
430 };
431 
432 #endif /* USE_IE_IMP_TABLEHELPER */
433 
434 #endif /* IE_TABLE */
435