1 /* AbiWord
2  * Copyright (C) 1998 AbiSource, Inc.
3  * Copyright (c) 2001,2002 Tomas Frydrych
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301 USA.
19  */
20 
21 #define pf_FRAG_OBJECT_LENGTH 1
22 
23 #include "pf_Frag_Object.h"
24 #include "px_ChangeRecord.h"
25 #include "px_CR_Object.h"
26 #include "pt_Types.h"
27 #include "ut_string.h"
28 #include "pt_PieceTable.h"
29 
pf_Frag_Object(pt_PieceTable * pPT,PTObjectType objectType,PT_AttrPropIndex indexAP)30 pf_Frag_Object::pf_Frag_Object(pt_PieceTable * pPT,
31                                PTObjectType objectType,
32                                PT_AttrPropIndex indexAP)
33     : pf_Frag(pPT, pf_Frag::PFT_Object, pf_FRAG_OBJECT_LENGTH)
34 {
35 	m_pObjectSubclass = NULL;
36     m_objectType = objectType;
37     m_indexAP = indexAP;
38     const PP_AttrProp * pAP = NULL;
39 	xxx_UT_DEBUGMSG(("Frag Object created indexAP %x \n",m_indexAP));
40     m_pPieceTable->getAttrProp(m_indexAP,&pAP);
41     UT_return_if_fail (pAP);
42     const gchar* pszType = NULL;
43     const gchar* pszName = NULL;
44 	const gchar* pszParam = NULL;
45 
46     pAP->getAttribute(static_cast<const gchar *>("type"), pszType);
47     pAP->getAttribute(static_cast<const gchar *>("name"), pszName);
48     pAP->getAttribute(static_cast<const gchar *>("param"), pszParam);
49 
50     fd_Field::FieldType fieldType = fd_Field::FD_None;
51 
52     if (objectType==PTO_Field)
53     {
54 		if(pszType == NULL)
55 		{
56 			UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
57 			pszType = "test";
58 		}
59     	switch(*pszType)
60     	{
61     		case 'a':
62 				if (0 == strcmp(pszType, "app_ver"))
63 				{
64 					fieldType = fd_Field::FD_App_Version;
65 				}
66 				else if (0 == strcmp(pszType, "app_id"))
67 				{
68 					fieldType = fd_Field::FD_App_ID;
69 				}
70 				else if (0 == strcmp(pszType, "app_options"))
71 				{
72 					fieldType = fd_Field::FD_App_Options;
73 				}
74 				else if (0 == strcmp(pszType, "app_target"))
75 				{
76 					fieldType = fd_Field::FD_App_Target;
77 				}
78 				else if (0 == strcmp(pszType, "app_compiledate"))
79 				{
80 					fieldType = fd_Field::FD_App_CompileDate;
81 				}
82 				else if (0 == strcmp(pszType, "app_compiletime"))
83 				{
84 					fieldType = fd_Field::FD_App_CompileTime;
85 				}
86 		        else
87         		{
88 		            UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
89         		    //Better than segfaulting I figure
90 		            fieldType = fd_Field::FD_None;
91         		}
92 				break;
93     		case 'c':
94 				if (0 == strcmp(pszType, "char_count"))
95 				{
96 					fieldType = fd_Field::FD_Doc_CharCount;
97 				}
98 		        else
99         		{
100 		            UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
101         		    //Better than segfaulting I figure
102 		            fieldType = fd_Field::FD_None;
103         		}
104     			break;
105     		case 'd':
106 				if (0 == strcmp(pszType, "date"))
107 				{
108 					fieldType = fd_Field::FD_Date;
109 				}
110 				else if (0 == strcmp(pszType, "date_mmddyy"))
111 				{
112 					fieldType = fd_Field::FD_Date_MMDDYY;
113 				}
114 				else if (0 == strcmp(pszType, "date_ddmmyy"))
115 				{
116 					fieldType = fd_Field::FD_Date_DDMMYY;
117 				}
118 				else if (0 == strcmp(pszType, "date_mdy"))
119 				{
120 					fieldType = fd_Field::FD_Date_MDY;
121 				}
122 				else if (0 == strcmp(pszType, "date_mthdy"))
123 				{
124 					fieldType = fd_Field::FD_Date_MthDY;
125 				}
126 				else if (0 == strcmp(pszType, "date_dfl"))
127 				{
128 					fieldType = fd_Field::FD_Date_DFL;
129 				}
130 				else if (0 == strcmp(pszType, "date_ntdfl"))
131 				{
132 					fieldType = fd_Field::FD_Date_NTDFL;
133 				}
134 				else if (0 == strcmp(pszType, "date_wkday"))
135 				{
136 					fieldType = fd_Field::FD_Date_Wkday;
137 				}
138 				else if (0 == strcmp(pszType, "date_doy"))
139 				{
140 					fieldType = fd_Field::FD_Date_DOY;
141 				}
142 				else if (0 == strcmp(pszType, "datetime_custom"))
143 				{
144 					fieldType = fd_Field::FD_DateTime_Custom;
145 				}
146 		        else
147         		{
148 		            UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
149         		    //Better than segfaulting I figure
150 		            fieldType = fd_Field::FD_None;
151         		}
152 				break;
153     		case 'e':
154 				if (0 == strcmp(pszType, "endnote_ref"))
155 				{
156 					fieldType = fd_Field::FD_Endnote_Ref;
157 				}
158 				else if (0 == strcmp(pszType, "endnote_anchor"))
159 				{
160 					fieldType = fd_Field::FD_Endnote_Anchor;
161 				}
162 		        else
163         		{
164 		            UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
165         		    //Better than segfaulting I figure
166 		            fieldType = fd_Field::FD_None;
167         		}
168 				break;
169     		case 'f':
170 				if (0 == strcmp(pszType, "file_name"))
171 				{
172 					fieldType = fd_Field::FD_FileName;
173 				}
174 				else if (0 == strcmp(pszType, "footnote_ref"))
175 				{
176 					fieldType = fd_Field::FD_Footnote_Ref;
177 				}
178 				else if (0 == strcmp(pszType, "footnote_anchor"))
179 				{
180 					fieldType = fd_Field::FD_Footnote_Anchor;
181 				}
182 		        else
183         		{
184 		            UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
185         		    //Better than segfaulting I figure
186 		            fieldType = fd_Field::FD_None;
187         		}
188 				break;
189     		case 'l':
190 				if (0 == strcmp(pszType, "list_label"))
191 		        {
192         		    fieldType = fd_Field::FD_ListLabel;
193 		        }
194 				else if (0 == strcmp(pszType, "line_count"))
195 				{
196 					fieldType = fd_Field::FD_Doc_LineCount;
197 				}
198 		        else
199         		{
200 		            UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
201         		    //Better than segfaulting I figure
202 		            fieldType = fd_Field::FD_None;
203         		}
204     			break;
205     		case 'm':
206 		        if (0 == strcmp(pszType, "mail_merge"))
207 		        {
208         		    fieldType = fd_Field::FD_MailMerge;
209 		        }
210 			else if(0 == strcmp(pszType, "meta_title"))
211 			  {
212 			    fieldType = fd_Field::FD_Meta_Title;
213 			  }
214 			else if(0 == strcmp(pszType, "meta_creator"))
215 			  {
216 			    fieldType = fd_Field::FD_Meta_Creator;
217 			  }
218 			else if(0 == strcmp(pszType, "meta_subject"))
219 			  {
220 			    fieldType = fd_Field::FD_Meta_Subject;
221 			  }
222 			else if(0 == strcmp(pszType, "meta_publisher"))
223 			  {
224 			    fieldType = fd_Field::FD_Meta_Publisher;
225 			  }
226 			else if(0 == strcmp(pszType, "meta_date"))
227 			  {
228 			    fieldType = fd_Field::FD_Meta_Date;
229 			  }
230 
231                         else if(0 == strcmp(pszType, "meta_date_last_changed"))
232 			  {
233 			    fieldType = fd_Field::FD_Meta_Date_Last_Changed;
234 			  }
235 			else if(0 == strcmp(pszType, "meta_type"))
236 			  {
237 			    fieldType = fd_Field::FD_Meta_Type;
238 			  }
239 			else if(0 == strcmp(pszType, "meta_language"))
240 			  {
241 			    fieldType = fd_Field::FD_Meta_Language;
242 			  }
243 			else if(0 == strcmp(pszType, "meta_rights"))
244 			  {
245 			    fieldType = fd_Field::FD_Meta_Rights;
246 			  }
247 			else if(0 == strcmp(pszType, "meta_keywords"))
248 			  {
249 			    fieldType = fd_Field::FD_Meta_Keywords;
250 			  }
251 			else if(0 == strcmp(pszType, "meta_contributor"))
252 			  {
253 			    fieldType = fd_Field::FD_Meta_Contributor;
254 			  }
255 			else if(0 == strcmp(pszType, "meta_coverage"))
256 			  {
257 			    fieldType = fd_Field::FD_Meta_Coverage;
258 			  }
259 			else if(0 == strcmp(pszType, "meta_description"))
260 			  {
261 			    fieldType = fd_Field::FD_Meta_Description;
262 			  }
263 		        else if (0 == strcmp(pszType, "martin_test"))
264 		        {
265         		    fieldType = fd_Field::FD_MartinTest;
266 		        }
267 		        else
268         		{
269 		            UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
270         		    //Better than segfaulting I figure
271 		            fieldType = fd_Field::FD_None;
272         		}
273 		        break;
274     		case 'n':
275 				if (0 == strcmp(pszType, "nbsp_count"))
276 				{
277 					fieldType = fd_Field::FD_Doc_NbspCount;
278 				}
279 		        else
280         		{
281 		            UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
282         		    //Better than segfaulting I figure
283 		            fieldType = fd_Field::FD_None;
284         		}
285 				break;
286     		case 'p':
287 				if (0 == strcmp(pszType, "page_number"))
288 		        {
289         		    fieldType = fd_Field::FD_PageNumber;
290 		        }
291 		        else if (0 == strcmp(pszType, "page_count"))
292         		{
293 		            fieldType = fd_Field::FD_PageCount;
294         		}
295 				else if (0 == strcmp(pszType, "para_count"))
296 				{
297 					fieldType = fd_Field::FD_Doc_ParaCount;
298 				}
299 				else if (0 == strcmp(pszType, "page_ref"))
300 				{
301 					fieldType = fd_Field::FD_PageReference;
302 				}
303 		        else
304         		{
305 		            UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
306         		    //Better than segfaulting I figure
307 		            fieldType = fd_Field::FD_None;
308         		}
309         		break;
310 		    case 's':
311 				if(0 == strcmp(pszType, "sum_rows"))
312 				{
313 					fieldType = fd_Field::FD_Table_sum_rows;
314 				}
315 				if(0 == strcmp(pszType, "sum_cols"))
316 				{
317 					fieldType = fd_Field::FD_Table_sum_cols;
318 				}
319 				break;
320     		case 't':
321 		        if (0 == strcmp(pszType, "test"))
322         		{
323 		            fieldType = fd_Field::FD_Test;
324         		}
325 		        else if (0 == strcmp(pszType, "time"))
326         		{
327 		            fieldType = fd_Field::FD_Time;
328         		}
329 				else if (0 == strcmp(pszType, "time_miltime"))
330 				{
331 					fieldType = fd_Field::FD_Time_MilTime;
332 				}
333 				else if (0 == strcmp(pszType, "time_ampm"))
334 				{
335 					fieldType = fd_Field::FD_Time_AMPM;
336 				}
337 				else if (0 == strcmp(pszType, "time_zone"))
338 				{
339 					fieldType = fd_Field::FD_Time_Zone;
340 				}
341 				else if (0 == strcmp(pszType, "time_epoch"))
342 				{
343 					fieldType = fd_Field::FD_Time_Epoch;
344 				}
345 		        else
346         		{
347 		            UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
348         		    //Better than segfaulting I figure
349 		            fieldType = fd_Field::FD_None;
350         		}
351         		break;
352     		case 'w':
353 				if (0 == strcmp(pszType, "word_count"))
354 				{
355 					fieldType = fd_Field::FD_Doc_WordCount;
356 				}
357 		        else
358         		{
359 		            UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
360         		    //Better than segfaulting I figure
361 		            fieldType = fd_Field::FD_None;
362         		}
363 				break;
364 #if 0
365 // When adding new fields under any of these characters, please move
366 // the label up where it belongs
367     		case 'b':
368     		case 'g':
369     		case 'h':
370     		case 'i':
371     		case 'j':
372     		case 'k':
373     		case 'o':
374     		case 'q':
375     		case 'r':
376     		case 's':
377     		case 'u':
378     		case 'v':
379     		case 'x':
380     		case 'y':
381     		case 'z':
382 #endif
383     		default:
384     			UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
385        		    //Better than segfaulting I figure
386 	            fieldType = fd_Field::FD_None;
387     	}
388         m_pField = new fd_Field(*this, pPT,fieldType, pszParam);
389     }
390     else if (objectType==PTO_Bookmark)
391     {
392     	po_Bookmark::BookmarkType BT;
393 
394 		if(!pszType) {
395 			// see bug 6489...
396 			UT_ASSERT_NOT_REACHED();
397 			BT = po_Bookmark::POBOOKMARK_END;
398 		} else if(0 == strcmp(pszType, "end"))
399 			BT = po_Bookmark::POBOOKMARK_END;
400 		else
401 			BT = po_Bookmark::POBOOKMARK_START;
402 
403 		UT_return_if_fail (pszName && *pszName);
404 		m_pObjectSubclass = static_cast<void *>(new po_Bookmark(*this,pPT,BT, pszName));
405     }
406 
407 }
408 
~pf_Frag_Object()409 pf_Frag_Object::~pf_Frag_Object()
410 {
411 
412     if (m_pObjectSubclass)
413 	{
414 		// make sure that we delete what we should ...
415     	switch(m_objectType)
416     	{
417     		case PTO_Field:
418     		break;
419     		case PTO_Bookmark:
420     		{
421     			po_Bookmark *bm = static_cast<po_Bookmark*>(m_pObjectSubclass);
422     			delete bm;
423     		}
424     		break;
425     		default:
426 	    		UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
427     	}
428 	    m_pObjectSubclass = NULL;
429 	}
430 	delete m_pField;
431 	m_pField = 0;
432 }
433 
_isContentEqual(const pf_Frag & f2) const434 bool pf_Frag_Object::_isContentEqual(const pf_Frag &f2) const
435 {
436 	if(!pf_Frag::_isContentEqual(f2))
437 		return false;
438 
439 	if(getObjectType() != ((const pf_Frag_Object&)(f2)).getObjectType())
440 		return false;
441 
442 	pf_Frag * pf1 = const_cast<pf_Frag_Object*>(this);
443 	pf_Frag * pf2 = const_cast<pf_Frag*>(&f2);
444 
445 	if(m_pField)
446 	{
447 		if(!pf2->getField())
448 			return false;
449 
450 		if(pf1->getField()->getFieldType() != pf2->getField()->getFieldType())
451 			return false;
452 	}
453 
454 	return true;
455 }
456 
457 
getObjectType(void) const458 PTObjectType pf_Frag_Object::getObjectType(void) const
459 {
460     return m_objectType;
461 }
462 
createSpecialChangeRecord(PX_ChangeRecord ** ppcr,PT_DocPosition dpos,PT_BlockOffset blockOffset)463 bool pf_Frag_Object::createSpecialChangeRecord(PX_ChangeRecord ** ppcr,
464                                                   PT_DocPosition dpos,
465                                                   PT_BlockOffset blockOffset)
466 {
467     UT_return_val_if_fail (ppcr,false);
468 
469     PX_ChangeRecord_Object * pcr
470     	 = new PX_ChangeRecord_Object(PX_ChangeRecord::PXT_InsertObject,
471                                      dpos, m_indexAP, getXID(), m_objectType,
472                                      blockOffset, m_pField,
473 				      this);
474 
475     if (!pcr)
476         return false;
477 
478     *ppcr = pcr;
479     return true;
480 }
481 
482 
getBookmark() const483 po_Bookmark * pf_Frag_Object::getBookmark() const
484 {
485 	if(m_objectType == PTO_Bookmark)
486 		return static_cast<po_Bookmark*>(m_pObjectSubclass);
487 	else
488 		return 0;
489 }
490