1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */
2 
3 /* AbiSource
4  *
5  * Copyright (C) 2007 Philippe Milot <PhilMilot@gmail.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 // Class definition include
24 #include <OXMLi_ListenerState_Common.h>
25 
26 // Internal includes
27 #include <OXMLi_Types.h>
28 #include <OXMLi_PackageManager.h>
29 #include <OXML_Document.h>
30 #include <OXML_Element.h>
31 #include <OXML_Element_Run.h>
32 #include <OXML_Element_Text.h>
33 #include <OXML_Element_Field.h>
34 #include <OXML_Types.h>
35 #include <OXML_Theme.h>
36 #include <OXML_Style.h>
37 #include <OXML_Section.h>
38 #include <OXML_FontManager.h>
39 
40 // AbiWord includes
41 #include <ut_units.h>
42 #include <ut_misc.h>
43 #include <ut_debugmsg.h>
44 #include <ut_assert.h>
45 
46 // External includes
47 #include <cstring>
48 
OXMLi_ListenerState_Common()49 OXMLi_ListenerState_Common::OXMLi_ListenerState_Common() :
50 	OXMLi_ListenerState(),
51 	m_pendingSectBreak(false),
52 	m_pendingSectBreakType(NEXTPAGE_BREAK),
53 	m_eqField(false),
54 	m_pageNumberField(false),
55 	m_fldChar(false)
56 {
57 
58 }
59 
~OXMLi_ListenerState_Common()60 OXMLi_ListenerState_Common::~OXMLi_ListenerState_Common()
61 {
62 }
63 
startElement(OXMLi_StartElementRequest * rqst)64 void OXMLi_ListenerState_Common::startElement (OXMLi_StartElementRequest * rqst)
65 {
66 	UT_return_if_fail( this->_error_if_fail(rqst != NULL) );
67 
68 	if(nameMatches(rqst->pName, NS_W_KEY, "instrText"))
69 	{
70 		rqst->handled = true;
71 	} else if(nameMatches(rqst->pName, NS_W_KEY, "fldChar")) {
72 		const gchar* fldCharType = attrMatches(NS_W_KEY, "fldCharType", rqst->ppAtts);
73 		if(!fldCharType)
74 		{
75 			UT_DEBUGMSG(("SERHAT: fldChar tag without fldCharType attribute\n"));
76 			return;
77 		}
78 		if(!strcmp(fldCharType, "begin"))
79 		{
80 			m_eqField = false;
81 			m_pageNumberField = false;
82 			m_fldChar = true;
83 		}
84 		else if(!strcmp(fldCharType, "end"))
85 		{
86 			m_eqField = false;
87 			m_pageNumberField = false;
88 			m_fldChar = false;
89 		}
90 	} else if(nameMatches(rqst->pName, NS_W_KEY, "p")) {
91 		//New paragraph...
92 		OXML_SharedElement elem(new OXML_Element_Paragraph(""));
93 		rqst->stck->push(elem);
94 
95 		rqst->handled = true;
96 	} else if (nameMatches(rqst->pName, NS_W_KEY, "r")) {
97 		//New text run...
98 		OXML_SharedElement elem(new OXML_Element_Run(""));
99 		rqst->stck->push(elem);
100 
101 		rqst->handled = true;
102 
103 	} else if (nameMatches(rqst->pName, NS_W_KEY, "t")) {
104 		if(m_fldChar && m_pageNumberField) // page number is already set with field element correctly.
105 		{
106 			rqst->handled = true;
107 			return;
108 		}
109 		//New text...
110 		OXML_SharedElement elem(new OXML_Element_Text("", 0));
111 		rqst->stck->push(elem);
112 		rqst->handled = true;
113 
114 	} else if (nameMatches(rqst->pName, NS_W_KEY, "sectPr")) {
115 		//Verify the context...
116 		std::string contextTag = rqst->context->back();
117 		if (contextMatches(contextTag, NS_W_KEY, "pPr") ||
118 			contextMatches(contextTag, NS_W_KEY, "body")) {
119 			OXML_SharedElement dummy(new OXML_Element_Paragraph(""));
120 			rqst->stck->push(dummy);
121 
122 			m_pendingSectBreak = true;
123 			rqst->handled = true;
124 		}
125 
126 /********************************
127  ****  PARAGRAPH FORMATTING  ****
128  ********************************/
129 	} else if(nameMatches(rqst->pName, NS_W_KEY, "shd")) {
130 		std::string contextTag = rqst->context->back();
131 
132 		if(!contextMatches(contextTag, NS_W_KEY, "pPr") &&
133 			!contextMatches(contextTag, NS_W_KEY, "rPr"))
134 			return;
135 
136 		const gchar* fill = attrMatches(NS_W_KEY, "fill", rqst->ppAtts);
137 
138 		OXML_SharedElement elem = rqst->stck->top();
139 
140 		if(fill && strcmp(fill, "auto"))
141 		{
142 			UT_Error err = UT_OK;
143 			err = elem->setProperty("bgcolor", fill);
144 			if(err != UT_OK) {
145 				UT_DEBUGMSG(("FRT:OpenXML importer can't set background-color:%s\n", fill));
146 			}
147 		}
148 		rqst->handled = true;
149 
150 	} else if ( nameMatches(rqst->pName, NS_W_KEY, "pageBreakBefore")){
151 		OXML_ElementTag tag = PG_BREAK;
152 		OXML_SharedElement br ( new OXML_Element("", tag, SPAN) );
153 		rqst->stck->push(br);
154 		rqst->handled = true;
155 
156 	} else if ( nameMatches(rqst->pName, NS_W_KEY, "tab")){
157 		//verify the context
158 		std::string contextTag = rqst->context->back();
159 
160 		if (contextMatches(contextTag, NS_W_KEY, "r")) {
161 			//This is an actual tab to be inserted
162 			OXML_SharedElement tab ( new OXML_Element_Text("\t", 2) );
163 			rqst->stck->push(tab);
164 			rqst->handled = true;
165 		}
166 		else if(contextMatches(contextTag, NS_W_KEY, "tabs")){
167 			OXML_SharedElement para = rqst->stck->top();
168 			const gchar* val = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
169 			const gchar* pos = attrMatches(NS_W_KEY, "pos", rqst->ppAtts);
170 			const gchar* leadCh = attrMatches(NS_W_KEY, "leader", rqst->ppAtts);
171 			if(!val || !*val || !pos || !*pos)
172 				return;
173 
174 			std::string value(val);
175 			std::string position(_TwipsToInches(pos));
176 			position += "in";
177 			std::string leader("0"); //no leader by default
178 
179 			std::string tabstops("");
180 			const gchar* tabProp = NULL;
181 			para->getProperty("tabstops", tabProp);
182 			if(tabProp)
183 			{
184 				tabstops = tabProp;
185 				tabstops += ",";
186 			}
187 
188 			tabstops += position;
189 			tabstops += "/";
190 
191 			if(!value.compare("left"))
192 				tabstops += "L";
193 			else if(!value.compare("right"))
194 				tabstops += "R";
195 			else if(!value.compare("center"))
196 				tabstops += "C";
197 			else if(!value.compare("bar"))
198 				tabstops += "B";
199 			else if(!value.compare("decimal"))
200 				tabstops += "D";
201 
202 			if(leadCh)
203 			{
204 				std::string leaderChar(leadCh);
205 				if(!leaderChar.compare("dot"))
206 					leader = "1";
207 				else if(!leaderChar.compare("heavy"))
208 					leader = "3";
209 				else if(!leaderChar.compare("hyphen"))
210 					leader = "2";
211 				else if(!leaderChar.compare("middleDot"))
212 					leader = "1";
213 				else if(!leaderChar.compare("underscore"))
214 					leader = "3";
215 			}
216 			tabstops += leader;
217 
218 			para->setProperty("tabstops", tabstops);
219 		}
220 		rqst->handled = true;
221 	} else if ( nameMatches(rqst->pName, NS_W_KEY, "ilvl")){
222 		//verify the context
223 		std::string contextTag = rqst->context->back();
224 		if(contextMatches(contextTag, NS_W_KEY, "numPr")){
225 			OXML_SharedElement para = rqst->stck->top();
226 			const gchar* val = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
227 			if(!val || !*val)
228 				return;
229 			std::string level(val);
230 			para->setAttribute("level", level.c_str());
231 		}
232 		rqst->handled = true;
233 	} else if ( nameMatches(rqst->pName, NS_W_KEY, "numId")){
234 		//verify the context
235 		std::string contextTag = rqst->context->back();
236 		if(contextMatches(contextTag, NS_W_KEY, "numPr")){
237 			OXML_SharedElement para = rqst->stck->top();
238 			const gchar* val = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
239 			if(!val || !*val)
240 				return;
241 			std::string numId(val);
242 
243 			OXML_Document* doc = OXML_Document::getInstance();
244 			std::string absNumId = doc->getMappedNumberingId(numId);
245 			if(!absNumId.empty())
246 				para->setAttribute("listid", absNumId.c_str());
247 		}
248 		rqst->handled = true;
249 	} else if ( nameMatches(rqst->pName, NS_W_KEY, "jc") ||
250 				nameMatches(rqst->pName, NS_W_KEY, "ind") ||
251 				nameMatches(rqst->pName, NS_W_KEY, "spacing") ||
252 				nameMatches(rqst->pName, NS_W_KEY, "pStyle")) {
253 	//Verify the context...
254 	std::string contextTag = rqst->context->at(rqst->context->size() - 2);
255 	if (contextMatches(contextTag, NS_W_KEY, "p") ||
256 		contextMatches(contextTag, NS_W_KEY, "pPrDefault") ||
257 		contextMatches(contextTag, NS_W_KEY, "lvl") ||
258 		contextMatches(contextTag, NS_W_KEY, "style")) {
259 
260 		OXML_SharedElement para = rqst->stck->top();
261 
262 		if (nameMatches(rqst->pName, NS_W_KEY, "jc")) {
263 			const gchar * val = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
264 
265 			if (!val || !*val)
266 				return;
267 
268 			if (!strcmp(val, "left")) {
269 				UT_return_if_fail( _error_if_fail( UT_OK == para->setProperty("text-align", "left") ));
270 			} else if (!strcmp(val, "center")) {
271 				UT_return_if_fail( _error_if_fail( UT_OK == para->setProperty("text-align", "center") ));
272 			} else if (!strcmp(val, "right")) {
273 				UT_return_if_fail( _error_if_fail( UT_OK == para->setProperty("text-align", "right") ));
274 			} else if (!strcmp(val, "numTab")) {
275 				//Deprecated; align left
276 				UT_return_if_fail( _error_if_fail( UT_OK == para->setProperty("text-align", "left") ));
277 			} else {
278 				//We justify for the values of "both", "distribute", "thaiDistribute", and the kashida variants
279 				UT_return_if_fail( _error_if_fail( UT_OK == para->setProperty("text-align", "justify") ));
280 			}
281 
282 		} else if (nameMatches(rqst->pName, NS_W_KEY, "ind")) {
283 			const gchar * left = attrMatches(NS_W_KEY, "left", rqst->ppAtts);
284 			const gchar * right = attrMatches(NS_W_KEY, "right", rqst->ppAtts);
285 			const gchar * fLine = attrMatches(NS_W_KEY, "firstLine", rqst->ppAtts);
286 			const gchar * hanging = attrMatches(NS_W_KEY, "hanging", rqst->ppAtts);
287 
288 			std::string final = "";
289 			if (left != NULL) {
290 				final = _TwipsToPoints(left); //convert to points
291 				final += "pt";
292 				UT_return_if_fail( _error_if_fail( UT_OK == para->setProperty("margin-left", final.c_str()) ));
293 			}
294 			if (right != NULL) {
295 				final = _TwipsToPoints(right); //convert to points
296 				final += "pt";
297 				UT_return_if_fail( _error_if_fail( UT_OK == para->setProperty("margin-right", final.c_str()) ));
298 			}
299 			if (fLine != NULL) {
300 				final = _TwipsToPoints(fLine); //convert to points
301 				final += "pt";
302 				UT_return_if_fail( _error_if_fail( UT_OK == para->setProperty("text-indent", final.c_str()) ));
303 			} else if (hanging != NULL) {
304 				final = _TwipsToPoints(hanging); //convert to points
305 				//This is hanging, invert the sign
306 				if (final[0] == '-')
307 					final.erase(0,1);
308 				else
309 					final.insert(0,1,'-');
310 				final += "pt";
311 				UT_return_if_fail( _error_if_fail( UT_OK == para->setProperty("text-indent", final.c_str()) ));
312 			}
313 
314 		} else if (nameMatches(rqst->pName, NS_W_KEY, "spacing")) {
315 			const gchar * before = attrMatches(NS_W_KEY, "before", rqst->ppAtts);
316 			const gchar * after = attrMatches(NS_W_KEY, "after", rqst->ppAtts);
317 			const gchar * lineRule = attrMatches(NS_W_KEY, "lineRule", rqst->ppAtts);
318 
319 			std::string final = "";
320 			if (before != NULL) {
321 				final = _TwipsToPoints(before); //convert to points
322 				final += "pt";
323 				UT_return_if_fail( _error_if_fail( UT_OK == para->setProperty("margin-top", final.c_str()) ));
324 			}
325 			if (after != NULL) {
326 				final = _TwipsToPoints(after); //convert to points
327 				final += "pt";
328 				UT_return_if_fail( _error_if_fail( UT_OK == para->setProperty("margin-bottom", final.c_str()) ));
329 			}
330 			if (lineRule != NULL && !strcmp(lineRule, "auto")) {
331 				//For now, we only handle "auto".
332 				const gchar * line = attrMatches(NS_W_KEY, "line", rqst->ppAtts);
333 				UT_return_if_fail( _error_if_fail(line != NULL) );
334 				double ln_spc = UT_convertDimensionless(line) / 240;
335 				final = UT_convertToDimensionlessString(ln_spc);
336 				UT_return_if_fail( _error_if_fail( UT_OK == para->setProperty("line-height", final.c_str()) ));
337 			}
338 		} else if (nameMatches(rqst->pName, NS_W_KEY, "pStyle")) {
339 			const gchar * val = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
340 			UT_return_if_fail( _error_if_fail(val != NULL) );
341 			if (!strcmp(val, "Normal")) val = "_Normal"; //Cannot interfere with document defaults
342 			OXML_Document * doc = OXML_Document::getInstance();
343 			UT_return_if_fail( _error_if_fail(doc != NULL) );
344 			OXML_SharedStyle ref = doc->getStyleById(val);
345 			if (ref.get() != NULL && ref->getName().compare("")) {
346 				UT_return_if_fail( _error_if_fail( UT_OK == para->setAttribute(PT_STYLE_ATTRIBUTE_NAME, ref->getName().c_str()) ));
347 			}
348 
349 		}
350 
351 		rqst->handled = true;
352 	}
353 
354 /******* END OF PARAGRAPH FORMATTING ********/
355 
356 /**************************
357  ****  RUN FORMATTING  ****
358  **************************/
359 	} else if (	nameMatches(rqst->pName, NS_W_KEY, "b") ||
360 				nameMatches(rqst->pName, NS_W_KEY, "i") ||
361 				nameMatches(rqst->pName, NS_W_KEY, "u") ||
362 				nameMatches(rqst->pName, NS_W_KEY, "color") ||
363 				nameMatches(rqst->pName, NS_W_KEY, "vertAlign") || // for subscript and superscript
364 				nameMatches(rqst->pName, NS_W_KEY, "highlight") ||
365 				nameMatches(rqst->pName, NS_W_KEY, "strike") ||
366 				nameMatches(rqst->pName, NS_W_KEY, "dstrike") ||
367 				nameMatches(rqst->pName, NS_W_KEY, "rFonts") ||
368 				nameMatches(rqst->pName, NS_W_KEY, "lang") ||
369 				nameMatches(rqst->pName, NS_W_KEY, "noProof") ||
370 				nameMatches(rqst->pName, NS_W_KEY, "vanish") ||
371 				nameMatches(rqst->pName, NS_W_KEY, "sz") ) {
372 		//Verify the context...
373 		std::string contextTag = rqst->context->at(rqst->context->size() - 2);
374 		if (contextMatches(contextTag, NS_W_KEY, "r") ||
375 			contextMatches(contextTag, NS_W_KEY, "rPrDefault") ||
376 			contextMatches(contextTag, NS_W_KEY, "style")) {
377 			OXML_SharedElement run = rqst->stck->top();
378 
379 			if (nameMatches(rqst->pName, NS_W_KEY, "b")) {
380 				const gchar * isOn = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
381 				if (isOn == NULL || !strcmp(isOn, "on") || !strcmp(isOn, "1") || !strcmp(isOn, "true") ) {
382 					UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("font-weight", "bold") ));
383 				} else {
384 					UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("font-weight", "normal") ));
385 				}
386 
387 			} else if (nameMatches(rqst->pName, NS_W_KEY, "i")) {
388 				const gchar * isOn = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
389 				if (isOn == NULL || !strcmp(isOn, "on") || !strcmp(isOn, "1") || !strcmp(isOn, "true") ) {
390 					UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("font-style", "italic") ));
391 				} else {
392 					UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("font-style", "normal") ));
393 				}
394 
395 			} else if (nameMatches(rqst->pName, NS_W_KEY, "vertAlign")) {
396 				const gchar * val = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
397 				if (val == NULL || !*val || !strcmp(val, "baseline")) {
398 					UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("text-position", "normal") ));
399 				} else if (!strcmp(val, "superscript")) {
400 					UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("text-position", "superscript") ));
401 				} else if (!strcmp(val, "subscript")) {
402 					UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("text-position", "subscript") ));
403 				}
404 
405 			} else if (nameMatches(rqst->pName, NS_W_KEY, "u")) {
406 				const gchar * newVal = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
407 				if(!newVal)
408 				{
409 					newVal = "single";
410 				}
411 				std::string final_val = "";
412 				const gchar * previousVal = NULL;
413 				if (UT_OK == run->getProperty("text-decoration", previousVal)) {
414 					final_val = previousVal;
415 				}
416 				if ( !strcmp(newVal, "none") ) {
417 					final_val += " ";
418 					final_val += "none";
419 				} else { //if NOT "none", we add underline (no matter the underline style, we only support single line)
420 					final_val += " ";
421 					final_val += "underline";
422 				}
423 				UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("text-decoration", final_val.c_str()) ));
424 
425 			} else if (nameMatches(rqst->pName, NS_W_KEY, "color")) {
426 				const gchar * val = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
427 				if (val != NULL) {
428 					if (!strcmp(val, "auto")) val = "#000000";
429 					UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("color", val)));
430 				} else {
431 					val = attrMatches(NS_W_KEY, "themeColor", rqst->ppAtts);
432 					UT_return_if_fail( this->_error_if_fail(val != NULL) );
433 					std::string color = "#000000"; //default color in case of illegal themeColor value.
434 					OXML_Document * doc = OXML_Document::getInstance();
435 					UT_return_if_fail( this->_error_if_fail(doc != NULL) );
436 					OXML_SharedTheme theme = doc->getTheme();
437 					if (!strcmp(val,"accent1")) {
438 						color = theme->getColor(ACCENT1);
439 					} else if (!strcmp(val,"accent2")) {
440 						color = theme->getColor(ACCENT2);
441 					} else if (!strcmp(val,"accent3")) {
442 						color = theme->getColor(ACCENT3);
443 					} else if (!strcmp(val,"accent4")) {
444 						color = theme->getColor(ACCENT4);
445 					} else if (!strcmp(val,"accent5")) {
446 						color = theme->getColor(ACCENT5);
447 					} else if (!strcmp(val,"accent6")) {
448 						color = theme->getColor(ACCENT6);
449 					} else if (!strcmp(val,"dark1")) {
450 						color = theme->getColor(DARK1);
451 					} else if (!strcmp(val,"dark2")) {
452 						color = theme->getColor(DARK2);
453 					} else if (!strcmp(val,"light1")) {
454 						color = theme->getColor(LIGHT1);
455 					} else if (!strcmp(val,"light2")) {
456 						color = theme->getColor(LIGHT2);
457 					} else if (!strcmp(val,"hlink")) {
458 						color = theme->getColor(HYPERLINK);
459 					} else if (!strcmp(val,"folHlink")) {
460 						color = theme->getColor(FOLLOWED_HYPERLINK);
461 					} else if (!strcmp(val,"none")) {
462 						color = "#000000";
463 					}
464 					UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("color", color.c_str())));
465 				}
466 
467 			} else if (nameMatches(rqst->pName, NS_W_KEY, "highlight")) {
468 				const gchar * val = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
469 				UT_return_if_fail( this->_error_if_fail(val != NULL) );
470 				if (!strcmp(val, "darkYellow")) val = "olive"; //the only value not supported by CSS (equivalent to Olive)
471 				else if (!strcmp(val, "none")) val = "black"; //bypass inherited color value when "none"
472 				std::string hex = "";
473 				for (UT_uint32 i = 0; i <= strlen(val); i++) {
474 					hex += tolower(val[i]);
475 				}
476 				UT_HashColor conv;
477 				val = conv.setColor(hex.c_str());
478 				UT_return_if_fail( this->_error_if_fail( NULL != val ) );
479 				UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("bgcolor", val)));
480 
481 			} else if (nameMatches(rqst->pName, NS_W_KEY, "strike") ||
482 					   nameMatches(rqst->pName, NS_W_KEY, "dstrike")) {
483 				const gchar * isOn = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
484 				std::string final_val = "";
485 				const gchar * previousVal = NULL;
486 				if (UT_OK == run->getProperty("text-decoration", previousVal)) {
487 					final_val = previousVal;
488 				}
489 				if ( isOn == NULL || !strcmp(isOn, "on") || !strcmp(isOn, "1") || !strcmp(isOn, "true")  ) {
490 					final_val += " ";
491 					final_val += "line-through";
492 				} else {
493 					final_val += " ";
494 					final_val += "none";
495 				}
496 				UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("text-decoration", final_val.c_str()) ));
497 
498 			} else if (nameMatches(rqst->pName, NS_W_KEY, "rFonts")) {
499 				OXML_Document * doc = OXML_Document::getInstance();
500 				UT_return_if_fail( this->_error_if_fail(doc != NULL) );
501 				OXML_SharedFontManager fmgr = doc->getFontManager();
502 				UT_return_if_fail( this->_error_if_fail(fmgr.get() != NULL) );
503 
504 				std::string fontName;
505 				OXML_FontLevel level = UNKNOWN_LEVEL;
506 				OXML_CharRange range = UNKNOWN_RANGE;
507 
508 				const gchar * ascii = NULL;
509 				const gchar * eastAsia = NULL;
510 				const gchar * bidi = NULL;
511 				const gchar * hAnsi = NULL;
512 				if (NULL != (ascii = attrMatches(NS_W_KEY, "asciiTheme", rqst->ppAtts))) {
513 					this->getFontLevelRange(ascii, level, range);
514 					fontName = fmgr->getValidFont(level, range); //Retrieve valid font name from Theme
515 				} else if (NULL != (ascii = attrMatches(NS_W_KEY, "ascii", rqst->ppAtts))) {
516 					fontName = fmgr->getValidFont(ascii); //Make sure the name is valid
517 				} else if (NULL != (eastAsia = attrMatches(NS_W_KEY, "eastAsiaTheme", rqst->ppAtts))) {
518 					this->getFontLevelRange(eastAsia, level, range);
519 					fontName = fmgr->getValidFont(level, range); //Retrieve valid font name from Theme
520 				} else if (NULL != (eastAsia = attrMatches(NS_W_KEY, "eastAsia", rqst->ppAtts))) {
521 					fontName = fmgr->getValidFont(eastAsia); //Make sure the name is valid
522 				} else if (NULL != (bidi = attrMatches(NS_W_KEY, "csTheme", rqst->ppAtts))) {
523 					this->getFontLevelRange(bidi, level, range);
524 					fontName = fmgr->getValidFont(level, range); //Retrieve valid font name from Theme
525 				} else if (NULL != (bidi = attrMatches(NS_W_KEY, "cs", rqst->ppAtts))) {
526 					fontName = fmgr->getValidFont(bidi); //Make sure the name is valid
527 				} else if (NULL != (hAnsi = attrMatches(NS_W_KEY, "hAnsiTheme", rqst->ppAtts))) {
528 					this->getFontLevelRange(hAnsi, level, range);
529 					fontName = fmgr->getValidFont(level, range); //Retrieve valid font name from Theme
530 				} else if (NULL != (hAnsi = attrMatches(NS_W_KEY, "hAnsi", rqst->ppAtts))) {
531 					fontName = fmgr->getValidFont(hAnsi); //Make sure the name is valid
532 				} else {
533 					fontName = fmgr->getDefaultFont();
534 				}
535 				UT_return_if_fail( _error_if_fail( UT_OK == run->setProperty("font-family", fontName.c_str()) ));
536 
537 			} else if (nameMatches(rqst->pName, NS_W_KEY, "lang")) {
538 				const gchar * val = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
539 				const gchar * eastAsia = attrMatches(NS_W_KEY, "eastAsia", rqst->ppAtts);
540 				const gchar * bidi = attrMatches(NS_W_KEY, "bidi", rqst->ppAtts);
541 				const gchar * previousVal = NULL;
542 				if (UT_OK == run->getProperty("lang", previousVal)) {
543 					if ( 0 != strcmp(previousVal, "-none-"))
544 						val = previousVal;
545 				}
546 				if ( val != NULL)
547 					UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("lang", val) ));
548 				if ( eastAsia != NULL)
549 					UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("lang", eastAsia) ));
550 				if ( bidi != NULL)
551 					UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("lang", bidi) ));
552 
553 			} else if (nameMatches(rqst->pName, NS_W_KEY, "noProof")) {
554 				//noProof has priority over lang, so no need to check for previous values
555 				const gchar * isOn = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
556 				if (isOn == NULL || !strcmp(isOn, "on") || !strcmp(isOn, "1") || !strcmp(isOn, "true") )
557 					UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("lang", "-none-") ));
558 
559 			} else if (nameMatches(rqst->pName, NS_W_KEY, "vanish")) {
560 				const gchar * isOn = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
561 				if (isOn == NULL || !strcmp(isOn, "on") || !strcmp(isOn, "1") || !strcmp(isOn, "true") ) {
562 					UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("display", "none") ));
563 				} else {
564 					UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("display", "inline") ));
565 				}
566 
567 			} else if (nameMatches(rqst->pName, NS_W_KEY, "sz")) {
568 				const gchar * szStr = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
569 				UT_return_if_fail( this->_error_if_fail(szStr != NULL) );
570 				double sz = UT_convertDimensionless(szStr) / 2;
571 				UT_return_if_fail( this->_error_if_fail(sz > 0) );
572 				std::string pt_value = UT_convertToDimensionlessString(sz);
573 				pt_value += "pt";
574 				UT_return_if_fail( this->_error_if_fail( UT_OK == run->setProperty("font-size", pt_value.c_str()) ));
575 			}
576 			rqst->handled = true;
577 		}
578 
579 /******* END OF RUN FORMATTING ********/
580 
581 /******************************
582  ****  SECTION FORMATTING  ****
583  ******************************/
584 
585 	} else if (	nameMatches(rqst->pName, NS_W_KEY, "type") ||
586 				nameMatches(rqst->pName, NS_W_KEY, "footerReference") ||
587 				nameMatches(rqst->pName, NS_W_KEY, "headerReference") ||
588 				nameMatches(rqst->pName, NS_W_KEY, "cols")) {
589 		//Verify the context...
590 		std::string contextTag = rqst->context->back();
591 		if (contextMatches(contextTag, NS_W_KEY, "sectPr")) {
592 			if (nameMatches(rqst->pName, NS_W_KEY, "type")) {
593 				const gchar * val = attrMatches(NS_W_KEY, "val", rqst->ppAtts);
594 				UT_return_if_fail( this->_error_if_fail(val != NULL) );
595 
596 				UT_ASSERT(m_pendingSectBreak == true);
597 				if (!strcmp(val, "continuous")) {
598 					m_pendingSectBreakType = CONTINUOUS_BREAK;
599 				} else if (!strcmp(val, "evenPage")) {
600 					m_pendingSectBreakType = EVENPAGE_BREAK;
601 				} else if (!strcmp(val, "oddPage")) {
602 					m_pendingSectBreakType = ODDPAGE_BREAK;
603 				} else { //nextPage and nextColumn
604 					m_pendingSectBreakType = NEXTPAGE_BREAK;
605 				}
606 				rqst->handled = true;
607 
608 			} else if (nameMatches(rqst->pName, NS_W_KEY, "footerReference")) {
609 				const gchar * id = attrMatches(NS_R_KEY, "id", rqst->ppAtts);
610 				UT_return_if_fail( this->_error_if_fail(id != NULL) );
611 				OXML_SharedSection last = rqst->sect_stck->top();
612 
613 				OXMLi_PackageManager * mgr = OXMLi_PackageManager::getInstance();
614 				UT_return_if_fail( _error_if_fail( UT_OK == mgr->parseDocumentHdrFtr(id) ) );
615 
616 				OXML_Document * doc = OXML_Document::getInstance();
617 				UT_return_if_fail(_error_if_fail(doc != NULL));
618 				const gchar * type = attrMatches(NS_W_KEY, "type", rqst->ppAtts);
619 				UT_return_if_fail( this->_error_if_fail(type != NULL) );
620 
621 				if (!strcmp(type, "default")) {
622 					last->setFooterId(id, DEFAULT_HDRFTR);
623 					type = "footer";
624 				} else if (!strcmp(type, "even")) {
625 					last->setFooterId(id, EVENPAGE_HDRFTR);
626 					type = "footer-even";
627 				} else {
628 					last->setFooterId(id, FIRSTPAGE_HDRFTR);
629 					type = "footer-first";
630 				}
631 
632 				OXML_SharedSection ftr = doc->getFooter(id);
633 				UT_return_if_fail(_error_if_fail( UT_OK == ftr->setAttribute("type", type) ));
634 
635 			} else if (nameMatches(rqst->pName, NS_W_KEY, "headerReference")) {
636 				const gchar * id = attrMatches(NS_R_KEY, "id", rqst->ppAtts);
637 				UT_return_if_fail( this->_error_if_fail(id != NULL) );
638 				OXML_SharedSection last = rqst->sect_stck->top();
639 
640 				OXMLi_PackageManager * mgr = OXMLi_PackageManager::getInstance();
641 				UT_return_if_fail( _error_if_fail( UT_OK == mgr->parseDocumentHdrFtr(id) ) );
642 
643 				OXML_Document * doc = OXML_Document::getInstance();
644 				UT_return_if_fail(_error_if_fail(doc != NULL));
645 				const gchar * type = attrMatches(NS_W_KEY, "type", rqst->ppAtts);
646 				UT_return_if_fail( this->_error_if_fail(type != NULL) );
647 
648 				if (!strcmp(type, "default")) {
649 					last->setHeaderId(id, DEFAULT_HDRFTR);
650 					type = "header";
651 				} else if (!strcmp(type, "even")) {
652 					last->setHeaderId(id, EVENPAGE_HDRFTR);
653 					type = "header-even";
654 				} else {
655 					last->setHeaderId(id, FIRSTPAGE_HDRFTR);
656 					type = "header-first";
657 				}
658 
659 				OXML_SharedSection hdr = doc->getHeader(id);
660 				UT_return_if_fail(_error_if_fail( UT_OK == hdr->setAttribute("type", type) ));
661 			}
662 			else if (nameMatches(rqst->pName, NS_W_KEY, "cols")) {
663 				const gchar * num = attrMatches(NS_W_KEY, "num", rqst->ppAtts);
664 				const gchar * sep = attrMatches(NS_W_KEY, "sep", rqst->ppAtts);
665 
666 				if(!num || atoi(num)<1)
667 					num = "1";
668 
669 				if(!sep)
670 					sep = "off";
671 
672 				OXML_SharedSection last = rqst->sect_stck->top();
673 				last->setProperty("columns", num);
674 				last->setProperty("column-line", sep);
675 			}
676 		}
677 
678 	} else if (nameMatches(rqst->pName, NS_W_KEY, "footnoteReference")) {
679 		const gchar * id = attrMatches(NS_W_KEY, "id", rqst->ppAtts);
680 		if(id)
681 		{
682 			OXML_SharedElement footnote(new OXML_Element_Field(id, fd_Field::FD_Footnote_Ref, ""));
683 			rqst->stck->push(footnote);
684 		}
685 		rqst->handled = true;
686 
687 	} else if (nameMatches(rqst->pName, NS_W_KEY, "endnoteReference")) {
688 		const gchar * id = attrMatches(NS_W_KEY, "id", rqst->ppAtts);
689 		if(id)
690 		{
691 			OXML_SharedElement endnote(new OXML_Element_Field(id, fd_Field::FD_Endnote_Ref, ""));
692 			rqst->stck->push(endnote);
693 		}
694 		rqst->handled = true;
695 
696 	} else if (nameMatches(rqst->pName, NS_W_KEY, "hyperlink")) {
697 		const gchar * id = attrMatches(NS_R_KEY, "id", rqst->ppAtts);
698 		const gchar * anchor = attrMatches(NS_W_KEY, "anchor", rqst->ppAtts);
699 		if(id)
700 		{
701 			OXMLi_PackageManager * mgr = OXMLi_PackageManager::getInstance();
702 			std::string target = mgr->getPartName(id);
703 			OXML_Element_Hyperlink* hyperlink = new OXML_Element_Hyperlink("");
704 			hyperlink->setHyperlinkTarget(target);
705 			OXML_SharedElement elem(hyperlink);
706 			rqst->stck->push(elem);
707 		}
708 		else if(anchor)
709 		{
710 			std::string bookmarkAnchor("#");
711 			bookmarkAnchor += anchor;
712 			OXML_Element_Hyperlink* hyperlink = new OXML_Element_Hyperlink("");
713 			hyperlink->setHyperlinkTarget(bookmarkAnchor);
714 			OXML_SharedElement elem(hyperlink);
715 			rqst->stck->push(elem);
716 		}
717 		rqst->handled = true;
718 
719 	} else if (nameMatches(rqst->pName, NS_W_KEY, "bookmarkStart")) {
720 		const gchar * id = attrMatches(NS_W_KEY, "id", rqst->ppAtts);
721 		const gchar * name = attrMatches(NS_W_KEY, "name", rqst->ppAtts);
722 		if(id && name)
723 		{
724 			std::string bookmarkId(id);
725 			std::string bookmarkName(name);
726 			OXML_Element_Bookmark* bookmark = new OXML_Element_Bookmark(bookmarkId);
727 			bookmark->setType("start");
728 			bookmark->setName(bookmarkName);
729 			OXML_SharedElement elem(bookmark);
730 			rqst->stck->push(elem);
731 			OXML_Document* pDoc = OXML_Document::getInstance();
732 			if(!pDoc->setBookmarkName(bookmarkId, bookmarkName))
733 				return;
734 		}
735 		rqst->handled = true;
736 
737 	} else if (nameMatches(rqst->pName, NS_W_KEY, "bookmarkEnd")) {
738 		const gchar * id = attrMatches(NS_W_KEY, "id", rqst->ppAtts);
739 		if(id)
740 		{
741 			std::string bookmarkId(id);
742 			OXML_Element_Bookmark* bookmark = new OXML_Element_Bookmark(bookmarkId);
743 			bookmark->setType("end");
744 			OXML_Document* pDoc = OXML_Document::getInstance();
745 			bookmark->setName(pDoc->getBookmarkName(bookmarkId));
746 			OXML_SharedElement elem(bookmark);
747 			rqst->stck->push(elem);
748 		}
749 		rqst->handled = true;
750 
751 /******* END OF SECTION FORMATTING ********/
752 
753 	} else if (nameMatches(rqst->pName, NS_W_KEY, "br")) {
754 		const gchar * type = attrMatches(NS_W_KEY, "type", rqst->ppAtts);
755 // The optional attribute can be missing. In that case a default
756 // value is implied.
757 //		UT_return_if_fail( this->_error_if_fail(type != NULL) );
758 
759 		OXML_ElementTag tag;
760 		if (type && !strcmp(type, "column")) {
761 			tag = CL_BREAK;
762 		} else if (type && !strcmp(type, "page")) {
763 			tag = PG_BREAK;
764 		} else { //textWrapping
765 			tag = LN_BREAK;
766 		}
767 		OXML_SharedElement br ( new OXML_Element("", tag, SPAN) );
768 		rqst->stck->push(br);
769 
770 		rqst->handled = true;
771 	}
772 }
773 
endElement(OXMLi_EndElementRequest * rqst)774 void OXMLi_ListenerState_Common::endElement (OXMLi_EndElementRequest * rqst)
775 {
776 	UT_return_if_fail( this->_error_if_fail(rqst != NULL) );
777 
778 	if (nameMatches(rqst->pName, NS_W_KEY, "p")) {
779 		//Paragraph is done, appending it.
780 		if (rqst->stck->size() == 1) { //Only the paragraph is on the stack, append to section
781 			OXML_SharedElement elem = rqst->stck->top();
782 			UT_return_if_fail( this->_error_if_fail(elem.get() != NULL) );
783 			OXML_SharedSection sect = rqst->sect_stck->top();
784 			UT_return_if_fail( this->_error_if_fail(sect.get() != NULL) );
785 			UT_return_if_fail( this->_error_if_fail(UT_OK == sect->appendElement(elem) ) );
786 			rqst->stck->pop();
787 		} else { //Append to next element on the stack
788 			UT_return_if_fail( this->_error_if_fail( UT_OK == _flushTopLevel(rqst->stck, rqst->sect_stck) ) );
789 		}
790 
791 		//Perform the section break if any
792 		if (m_pendingSectBreak) {
793 			OXML_Document * doc = OXML_Document::getInstance();
794 			UT_return_if_fail(_error_if_fail(doc != NULL));
795 			OXML_SharedSection sect(new OXML_Section());
796 			sect->setBreakType(m_pendingSectBreakType);
797 			m_pendingSectBreakType = NEXTPAGE_BREAK;
798 			rqst->sect_stck->push(sect);
799 			m_pendingSectBreak = false;
800 		}
801 
802 		rqst->handled = true;
803 	} else if (nameMatches(rqst->pName, NS_W_KEY, "r")) {
804 		//Run is done, appending it.
805 		UT_return_if_fail( this->_error_if_fail( UT_OK == _flushTopLevel(rqst->stck, rqst->sect_stck) ) );
806 
807 		rqst->handled = true;
808 	} else if (nameMatches(rqst->pName, NS_W_KEY, "t")) {
809 		if(m_fldChar && m_pageNumberField) // page number is already set with field element correctly.
810 		{
811 			rqst->handled = true;
812 			return;
813 		}
814 		//Text is done, appending it.
815 		UT_return_if_fail( this->_error_if_fail( UT_OK == _flushTopLevel(rqst->stck, rqst->sect_stck) ) );
816 		rqst->handled = true;
817 	} else if(nameMatches(rqst->pName, NS_W_KEY, "instrText")) {
818 		if(m_eqField || m_pageNumberField)
819 		{
820 			//instrText including equation or page number field is done, appending it.
821 			UT_return_if_fail( this->_error_if_fail( UT_OK == _flushTopLevel(rqst->stck, rqst->sect_stck) ) );
822 		}
823 		rqst->handled = true;
824 	} else if (nameMatches(rqst->pName, NS_W_KEY, "sectPr")) {
825 		std::string contextTag = rqst->context->back();
826 		if (contextMatches(contextTag, NS_W_KEY, "pPr") ||
827 			contextMatches(contextTag, NS_W_KEY, "body")) {
828 			OXML_SharedSection sect = rqst->sect_stck->top();
829 			UT_return_if_fail(_error_if_fail(sect.get() != NULL));
830 			OXML_SharedElement dummy = rqst->stck->top();
831 			const gchar ** atts = dummy->getAttributes();
832 			if (atts != NULL) {
833 				UT_return_if_fail(_error_if_fail(UT_OK == sect->appendAttributes(atts)));
834 			}
835 			atts = dummy->getProperties();
836 			if (atts != NULL) {
837 				UT_return_if_fail(_error_if_fail(UT_OK == sect->appendProperties(atts)));
838 			}
839 			rqst->stck->pop();
840 
841 			rqst->handled = true;
842 		}
843 	} else if (	nameMatches(rqst->pName, NS_W_KEY, "jc") ||
844 				nameMatches(rqst->pName, NS_W_KEY, "ind") ||
845 				nameMatches(rqst->pName, NS_W_KEY, "spacing") ) {
846 		rqst->handled = true;
847 	} else if (	nameMatches(rqst->pName, NS_W_KEY, "b") ||
848 				nameMatches(rqst->pName, NS_W_KEY, "i") ||
849 				nameMatches(rqst->pName, NS_W_KEY, "u") ||
850 				nameMatches(rqst->pName, NS_W_KEY, "color") ||
851 				nameMatches(rqst->pName, NS_W_KEY, "vertAlign") ||
852 				nameMatches(rqst->pName, NS_W_KEY, "highlight") ||
853 				nameMatches(rqst->pName, NS_W_KEY, "strike") ||
854 				nameMatches(rqst->pName, NS_W_KEY, "dstrike") ||
855 				nameMatches(rqst->pName, NS_W_KEY, "rFonts") ||
856 				nameMatches(rqst->pName, NS_W_KEY, "lang") ||
857 				nameMatches(rqst->pName, NS_W_KEY, "noProof") ||
858 				nameMatches(rqst->pName, NS_W_KEY, "vanish") ||
859 				nameMatches(rqst->pName, NS_W_KEY, "fldChar") ||
860 				nameMatches(rqst->pName, NS_W_KEY, "sz") ) {
861 		rqst->handled = true;
862 	} else if (	nameMatches(rqst->pName, NS_W_KEY, "type") ||
863 				nameMatches(rqst->pName, NS_W_KEY, "footerReference") ||
864 				nameMatches(rqst->pName, NS_W_KEY, "headerReference") ||
865 				nameMatches(rqst->pName, NS_W_KEY, "cols")) {
866 		std::string contextTag = rqst->context->back();
867 		if (contextMatches(contextTag, NS_W_KEY, "sectPr")) {
868 			rqst->handled = true;
869 		}
870 	} else if (nameMatches(rqst->pName, NS_W_KEY, "tab")) {
871 		std::string contextTag = rqst->context->back();
872 		if (contextMatches(contextTag, NS_W_KEY, "r")) {
873 			UT_return_if_fail( this->_error_if_fail( UT_OK == _flushTopLevel(rqst->stck, rqst->sect_stck) ) );
874 			rqst->handled = true;
875 		}
876 		else if(contextMatches(contextTag, NS_W_KEY, "tabs"))
877 			rqst->handled = true;
878 	} else if (nameMatches(rqst->pName, NS_W_KEY, "br")) {
879 		UT_return_if_fail( this->_error_if_fail( UT_OK == _flushTopLevel(rqst->stck, rqst->sect_stck) ) );
880 		rqst->handled = true;
881 	} else if (nameMatches(rqst->pName, NS_W_KEY, "footnoteReference") ||
882 			   nameMatches(rqst->pName, NS_W_KEY, "endnoteReference")) {
883 		UT_return_if_fail( this->_error_if_fail( UT_OK == _flushTopLevel(rqst->stck, rqst->sect_stck) ) );
884 		rqst->handled = true;
885 	} else if (nameMatches(rqst->pName, NS_W_KEY, "hyperlink")) {
886 		UT_return_if_fail( this->_error_if_fail( UT_OK == _flushTopLevel(rqst->stck, rqst->sect_stck) ) );
887 		rqst->handled = true;
888 	} else if (nameMatches(rqst->pName, NS_W_KEY, "bookmarkStart") ||
889 				nameMatches(rqst->pName, NS_W_KEY, "bookmarkEnd")) {
890 		UT_return_if_fail( this->_error_if_fail( UT_OK == _flushTopLevel(rqst->stck, rqst->sect_stck) ) );
891 		rqst->handled = true;
892 	} else if (nameMatches(rqst->pName, NS_W_KEY, "pageBreakBefore")) {
893 		UT_return_if_fail( this->_error_if_fail( UT_OK == _flushTopLevel(rqst->stck, rqst->sect_stck) ) );
894 		rqst->handled = true;
895 	} else if (nameMatches(rqst->pName, NS_W_KEY, "shd")) {
896 		std::string contextTag = rqst->context->back();
897 		rqst->handled = contextMatches(contextTag, NS_W_KEY, "pPr") || contextMatches(contextTag, NS_W_KEY, "rPr");
898 	}
899 }
900 
charData(OXMLi_CharDataRequest * rqst)901 void OXMLi_ListenerState_Common::charData (OXMLi_CharDataRequest * rqst)
902 {
903 	if(!rqst)
904 	{
905 		UT_DEBUGMSG(("FRT: OpenXML importer invalid NULL request in OXMLi_ListenerState_Common.charData\n"));
906 		return;
907 	}
908 
909 	if(rqst->stck->empty())
910 		return;
911 
912 	std::string contextTag = "";
913 	if(!rqst->context->empty())
914 	{
915 		contextTag = rqst->context->back();
916 	}
917 	int instrText = contextMatches(contextTag, NS_W_KEY, "instrText");
918 	if(instrText)
919 	{
920 		UT_ASSERT(rqst->buffer != NULL);
921 		OXML_SharedElement run = rqst->stck->top();
922 		OXML_SharedElement sharedElem(new OXML_Element_Text("", 0));
923 		std::string overline = "\\to";
924 		std::string underline = "\\bo";
925 		std::string eq = "EQ";
926 		std::string pageNumber = "PAGE   \\* MERGEFORMAT";
927 		std::string v(rqst->buffer);
928 		std::string value = "";
929 		size_t isOverline = v.find(overline);
930 		size_t isUnderline = v.find(underline);
931 		size_t isEQ = v.find(eq);
932 		size_t isPageNumber = v.find(pageNumber);
933 		size_t openingParenthesis;
934 		size_t closingParenthesis;
935 		UT_Error err;
936 		if(isEQ != std::string::npos) // handle EQ fields
937 		{
938 			if(isOverline != std::string::npos && isUnderline == std::string::npos)
939 			{
940 				// if starts with "EQ \x \to", then overline property is used
941 				err = run->setProperty("text-decoration", "overline");
942 				if(err != UT_OK)
943 				{
944 					UT_DEBUGMSG(("SERHAT: Could not set overline property!\n"));
945 					return;
946 				}
947 			}
948 			else if(isUnderline != std::string::npos && isOverline == std::string::npos)
949 			{
950 				// if starts with "EQ \x \bo", then underline property is used
951 				err = run->setProperty("text-decoration", "underline");
952 				if(err != UT_OK)
953 				{
954 					UT_DEBUGMSG(("SERHAT: Could not set underline property!\n"));
955 					return;
956 				}
957 			}
958 			rqst->stck->push(sharedElem);
959 			m_eqField = true;
960 			m_pageNumberField = false;
961 			openingParenthesis = v.find("(");
962 			closingParenthesis = v.find(")");
963 			value = v.substr(int(openingParenthesis)+1, int(closingParenthesis)-int(openingParenthesis)-1); // the string between parentheses is extracted
964 			OXML_Element* elem = sharedElem.get();
965 			OXML_Element_Text* textElement = static_cast<OXML_Element_Text*>(elem);
966 			textElement->setText(value.c_str(), value.size());
967 		}
968 		else if(isPageNumber != std::string::npos) // handle page number fields
969 		{
970 			m_pageNumberField = true;
971 			m_eqField = false;
972 			OXML_SharedElement fieldElem(new OXML_Element_Field("", v, ""));
973 			rqst->stck->push(fieldElem);
974 		}
975 		else
976 		{
977 			m_eqField = false;
978 			m_pageNumberField = false;
979 		}
980 	}
981 	else
982 	{
983 		OXML_SharedElement sharedElem = rqst->stck->top();
984 		OXML_Element* elem = sharedElem.get();
985 
986 		if(!elem || (elem->getTag() != T_TAG))
987 			return;
988 
989 		OXML_Element_Text* textElement = static_cast<OXML_Element_Text*>(elem);
990 		textElement->setText(rqst->buffer, rqst->length);
991 	}
992 }
993