1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */
2 
3 /* AbiSource
4  *
5  * Copyright (C) 2008 Firat Kiyak <firatkiyak@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 //External includes
24 #include <boost/lexical_cast.hpp>
25 
26 // Class definition include
27 #include <OXML_List.h>
28 
29 // Internal includes
30 #include <OXML_Types.h>
31 #include <OXML_Document.h>
32 
33 // AbiWord includes
34 #include <ut_types.h>
35 #include <ut_misc.h>
36 #include <pd_Document.h>
37 
OXML_List()38 OXML_List::OXML_List() :
39 	OXML_ObjectWithAttrProp(),
40 	id(0),
41 	parentId(0),
42 	level(0),
43 	startValue(0),
44 	delim(""),
45 	decimal(""),
46 	type(NUMBERED_LIST)
47 {
48 
49 }
50 
~OXML_List()51 OXML_List::~OXML_List()
52 {
53 }
54 
setId(UT_uint32 listId)55 void OXML_List::setId(UT_uint32 listId)
56 {
57 	id = listId;
58 }
59 
setParentId(UT_uint32 parentListId)60 void OXML_List::setParentId(UT_uint32 parentListId)
61 {
62 	parentId = parentListId;
63 }
64 
setLevel(UT_uint32 lvl)65 void OXML_List::setLevel(UT_uint32 lvl)
66 {
67 	level = lvl;
68 }
69 
setStartValue(UT_uint32 val)70 void OXML_List::setStartValue(UT_uint32 val)
71 {
72 	startValue = val;
73 }
74 
setDelim(const std::string & dlm)75 void OXML_List::setDelim(const std::string & dlm)
76 {
77 	UT_Error err = UT_OK;
78 
79 	delim = dlm;
80 
81 	if(type == BULLETED_LIST)
82 	{
83 	    UT_UCS4String ucs4Str = delim;
84 
85 		if (!ucs4Str.empty())
86 		{
87 			switch (ucs4Str[0])
88 			{
89 				case 8226: // U+2022 BULLET
90 					type = BULLETED_LIST;
91 					err = setProperty("field-font", "NULL");
92 					break;
93 
94 				case 8211: // U+2013 EN DASH
95 					type = DASHED_LIST;
96 					err = setProperty("field-font", "NULL");
97 					break;
98 
99 				case 9632:  // U+25A0 BLACK SQUARE
100 				case 61607: // MS WORD 2007 BLACK SQUARE
101 					type = SQUARE_LIST;
102 					err = setProperty("field-font", "NULL");
103 					break;
104 
105 				case 9650: // U+25B2 BLACK UP-POINTING TRIANGLE
106 				case 9654: // TRIANGLE
107 				case 61656: // MS WORD 2007 TRIANGLE ARROW
108 					type = TRIANGLE_LIST;
109 					err = setProperty("field-font", "NULL");
110 					break;
111 
112 				case 9670: //U+25C6 DIAMOND
113 				case 9830: // U+2666 BLACK DIAMOND SUIT
114 				case 61558: // MS WORD 2007 DIAMOND SUIT
115 					type = DIAMOND_LIST;
116 					err = setProperty("field-font", "NULL");
117 					break;
118 
119 				case 10035: // U+2733 EIGHT SPOKED ASTERISK
120 				case 42: // MS WORD 2007 EIGHT SPOKED ASTERISK
121 					type = STAR_LIST;
122 					err = setProperty("field-font", "NULL");
123 					break;
124 
125 				case 10003: // U+2713 CHECK MARK
126 				case 61692: // MS WORD 2007 CHECK MARK
127 					type = TICK_LIST;
128 					err = setProperty("field-font", "NULL");
129 					break;
130 
131 				case 9633: //BOX
132 				case 10066: // U+2752 UPPER RIGHT SHADOWED WHITE SQUARE
133 					type = BOX_LIST;
134 					err = setProperty("field-font", "NULL");
135 					break;
136 
137 				case 9758: // U+261E WHITE RIGHT POINTING INDEX
138 					type = HAND_LIST;
139 					err = setProperty("field-font", "NULL");
140 					break;
141 
142 				case 9829: // U+2665 BLACK HEART SUIT
143 				case 61609: //MS WORD 2007 HEART SUIT
144 					type = HEART_LIST;
145 					err = setProperty("field-font", "NULL");
146 					break;
147 
148 				case 8658: // U+21D2 RIGHTWARDS DOUBLE ARROW
149 					type = IMPLIES_LIST;
150 					err = setProperty("field-font", "NULL");
151 					break;
152 
153 				default:
154 					type = BULLETED_LIST;
155 					err = setProperty("field-font", "NULL");
156 					break;
157 			};
158 		}
159 	}
160 
161 	if(err != UT_OK)
162 	{
163 		UT_DEBUGMSG(("FRT:OpenXML importer setting field-font property failed\n"));
164 		type = BULLETED_LIST;
165 	}
166 }
167 
setDecimal(const std::string & dcml)168 void OXML_List::setDecimal(const std::string & dcml)
169 {
170 	decimal = dcml;
171 }
172 
setType(FL_ListType typ)173 void OXML_List::setType(FL_ListType typ)
174 {
175 	type = typ;
176 }
177 
getId()178 UT_uint32 OXML_List::getId()
179 {
180 	return id;
181 }
182 
getParentId()183 UT_uint32 OXML_List::getParentId()
184 {
185 	return parentId;
186 }
187 
getLevel()188 UT_uint32 OXML_List::getLevel()
189 {
190 	return level;
191 }
192 
getStartValue()193 UT_uint32 OXML_List::getStartValue()
194 {
195 	return startValue;
196 }
197 
getDelim()198 const gchar* OXML_List::getDelim()
199 {
200 	return delim.c_str();
201 }
202 
getDecimal()203 const gchar* OXML_List::getDecimal()
204 {
205 	return decimal.c_str();
206 }
207 
getType()208 FL_ListType OXML_List::getType()
209 {
210 	return type;
211 }
212 
213 /**
214  * Serializes the abstract numbering definitions. Numbering definitions are serialized
215  * in serializeNumbering function.
216  */
serialize(IE_Exp_OpenXML * exporter)217 UT_Error OXML_List::serialize(IE_Exp_OpenXML* exporter)
218 {
219 	UT_Error err = UT_OK;
220 
221 	err = exporter->startAbstractNumbering(TARGET_NUMBERING, id);
222 	if(err != UT_OK)
223 	{
224 		UT_DEBUGMSG(("FRT: Can't start Abstract Numbering\n"));
225 		return err;
226 	}
227 
228 	err = exporter->setMultilevelType(TARGET_NUMBERING, "hybridMultilevel");
229 	if(err != UT_OK)
230 	{
231 		UT_DEBUGMSG(("FRT: Can't set Multilevel Type\n"));
232 		return err;
233 	}
234 
235 	int i;
236 	for(i=0; i<=8; i++)
237 	{
238 		err = exporter->startNumberingLevel(TARGET_NUMBERING, i); //level
239 		if(err != UT_OK)
240 		{
241 			UT_DEBUGMSG(("FRT: Can't start Numbering Level\n"));
242 			return err;
243 		}
244 
245 		err = exporter->setListStartValue(TARGET_NUMBERING, startValue);
246 		if(err != UT_OK)
247 		{
248 			UT_DEBUGMSG(("FRT: Can't start List Start Value\n"));
249 			return err;
250 		}
251 
252 		std::string txt(delim);
253 		const char* search = "%L";
254 		size_t index = txt.find(search, 0, 2);
255 
256 		if(index != std::string::npos)
257 		{
258 			txt = txt.replace(index+1, 1, 1, '1'+i);
259 		}
260 
261 		std::string fontFamily("Times New Roman");
262 		const gchar* listType = "bullet";
263 		switch(type)
264 		{
265 			case NUMBERED_LIST:
266 				if((i % 3) == 1){
267 					listType = "lowerRoman";
268 				}
269 				else if((i % 3) == 2){
270 					listType = "lowerLetter";
271 				}
272 				else{
273 					listType = "decimal";
274 				}
275 				break;
276 
277 			case UPPERCASE_LIST:
278 				listType = "upperLetter";
279 				break;
280 
281 			case LOWERCASE_LIST:
282 				listType = "lowerLetter";
283 				break;
284 
285 			case UPPERROMAN_LIST:
286 				listType = "upperRoman";
287 				break;
288 
289 			case LOWERROMAN_LIST:
290 				listType = "lowerRoman";
291 				break;
292 
293 			case ARABICNUMBERED_LIST:
294 				listType = "arabicAbjad";
295 				break;
296 
297 			case HEBREW_LIST:
298 				listType = "hebrew1";
299 				break;
300 
301 			//the rest is bullet
302 			case DASHED_LIST:
303 				txt = DASH;
304 				break;
305 			case SQUARE_LIST:
306 				txt = SQUARE;
307 				break;
308 			case TRIANGLE_LIST:
309 				txt = TRIANGLE;
310 				fontFamily = "Wingdings";
311 				break;
312 			case DIAMOND_LIST:
313 				txt = DIAMOND;
314 				fontFamily = "Wingdings";
315 				break;
316 			case STAR_LIST:
317 				txt = STAR;
318 				break;
319 			case IMPLIES_LIST:
320 				txt = IMPLIES;
321 				break;
322 			case BOX_LIST:
323 				txt = BOX;
324 				break;
325 			case HAND_LIST:
326 				txt = HAND;
327 				break;
328 			case HEART_LIST:
329 				txt = HEART;
330 				break;
331 			case TICK_LIST:
332 				txt = TICK;
333 				fontFamily = "Wingdings";
334 				break;
335 			case BULLETED_LIST:
336 				txt = BULLET;
337 				break;
338 			default:
339 				txt = BULLET;
340 				break;
341 		}
342 
343 		err = exporter->setListType(TARGET_NUMBERING, listType);
344 		if(err != UT_OK)
345 		{
346 			UT_DEBUGMSG(("FRT: Can't set List Type\n"));
347 			return err;
348 		}
349 
350 		err = exporter->setListLevelText(TARGET_NUMBERING, txt.c_str());
351 		if(err != UT_OK)
352 		{
353 			UT_DEBUGMSG(("FRT: Can't set List Level Text\n"));
354 			return err;
355 		}
356 
357 		err = exporter->startRunProperties(TARGET_NUMBERING);
358 		if(err != UT_OK)
359 		{
360 			UT_DEBUGMSG(("FRT: Can't start List Level Run Properties\n"));
361 			return err;
362 		}
363 
364 		err = exporter->setFontFamily(TARGET_NUMBERING, fontFamily.c_str());
365 		if(err != UT_OK)
366 		{
367 			UT_DEBUGMSG(("FRT: Can't set font family\n"));
368 			return err;
369 		}
370 
371 		err = exporter->finishRunProperties(TARGET_NUMBERING);
372 		if(err != UT_OK)
373 		{
374 			UT_DEBUGMSG(("FRT: Can't finish List Level Run Properties\n"));
375 			return err;
376 		}
377 
378 		err = exporter->finishNumberingLevel(TARGET_NUMBERING);
379 		if(err != UT_OK)
380 		{
381 			UT_DEBUGMSG(("FRT: Can't finish Numbering Level\n"));
382 			return err;
383 		}
384 	}
385 
386 	err = exporter->finishAbstractNumbering(TARGET_NUMBERING);
387 	if(err != UT_OK)
388 	{
389 		UT_DEBUGMSG(("FRT: Can't finish Abstract Numbering\n"));
390 		return err;
391 	}
392 
393 	return UT_OK;
394 }
395 
396 /**
397  * Serializes the numbering definitions. Numbering definitions have to
398  * come after all the abstract numbering definitions.
399  */
serializeNumbering(IE_Exp_OpenXML * exporter)400 UT_Error OXML_List::serializeNumbering(IE_Exp_OpenXML* exporter)
401 {
402 	UT_Error err = UT_OK;
403 
404 	err = exporter->startNumbering(TARGET_NUMBERING, id);
405 	if(err != UT_OK)
406 	{
407 		UT_DEBUGMSG(("FRT: Can't start Numbering\n"));
408 		return err;
409 	}
410 
411 	err = exporter->setAbstractNumberingId(TARGET_NUMBERING, id);
412 	if(err != UT_OK)
413 	{
414 		UT_DEBUGMSG(("FRT: Can't set Abstract Numbering Id\n"));
415 		return err;
416 	}
417 
418 	return exporter->finishNumbering(TARGET_NUMBERING);
419 }
420 
addToPT(PD_Document * pDocument)421 UT_Error OXML_List::addToPT(PD_Document * pDocument)
422 {
423 	UT_Error err = UT_ERROR;
424 
425 	const gchar* ppAttr[13];
426 
427 	std::string listId = boost::lexical_cast<std::string>(id);
428 	std::string parentListId = boost::lexical_cast<std::string>(parentId);
429 	std::string listType = boost::lexical_cast<std::string>(type);
430 	std::string listStartVal = boost::lexical_cast<std::string>(startValue);
431 	std::string listDelim("%L.");
432 	std::string listDecimal(".");
433 	if(decimal.compare(""))
434 		listDecimal = decimal;
435 
436 	ppAttr[0] = "id";
437 	ppAttr[1] = listId.c_str();
438 	ppAttr[2] = "parentid";
439 	ppAttr[3] = parentListId.c_str();
440 	ppAttr[4] = "type";
441 	ppAttr[5] = listType.c_str();
442 	ppAttr[6] = "start-value";
443 	ppAttr[7] = listStartVal.c_str();
444 	ppAttr[8] = "list-delim";
445 	ppAttr[9] = listDelim.c_str();
446 	ppAttr[10] = "list-decimal";
447 	ppAttr[11] = listDecimal.c_str();
448 	ppAttr[12] = 0;
449 
450 	if (pDocument->appendList(ppAttr))
451 		err = UT_OK;
452 
453 	return err;
454 }
455 
456