1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */
2 
3 /* AbiWord
4  * Copyright (C) 1998 AbiSource, Inc.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301 USA.
20  */
21 
22 #include "ut_locale.h"
23 #include "ut_types.h"
24 #include "ut_misc.h"
25 #include "ut_string.h"
26 #include "ut_assert.h"
27 #include "ut_debugmsg.h"
28 #include "pt_PieceTable.h"
29 #include "pd_Style.h"
30 #include "fl_AutoLists.h"
31 #include "ut_hash.h"
32 #include "xap_Strings.h"
33 #include "xap_App.h"
34 #include "xap_EncodingManager.h"
35 
36 ///////////////////////////////////////////////////////////////////
37 // Styles represent named collections of formatting properties.
38 
39 #define _s(name, displayed, type, base, follow, props)	\
40 	do { const gchar * a[] = {						\
41 			PT_NAME_ATTRIBUTE_NAME, name,				\
42 			PT_TYPE_ATTRIBUTE_NAME, type,				\
43 			PT_BASEDON_ATTRIBUTE_NAME, base,			\
44 			PT_FOLLOWEDBY_ATTRIBUTE_NAME, follow,		\
45 			PT_PROPS_ATTRIBUTE_NAME, props,				\
46 			0};											\
47 		if (!_createBuiltinStyle(name, displayed, a))	\
48 			goto Failed;								\
49 	} while(0)
50 
51 typedef struct
52 {
53 	const char*	pStyle;
54 	int		nID;
55 
56 } ST_LOCALISED_STYLES;
57 
58 //
59 //	A list of the styles and they correspondant localised name
60 //
61 //  IMPORTANT: when adding styles here, please check also
62 //  s_translateStyleId() in ie_imp_MSWord_97.cpp and if there is a
63 //  corresponding Word style make sure that it gets translated into
64 //  this unlocalised name. Tomas, May 10, 2003
65 ST_LOCALISED_STYLES stLocalised[] =
66 {
67 
68 	{"Numbered List",			XAP_STRING_ID_STYLE_NUMBER_LIST},
69 	{"Plain Text",      		XAP_STRING_ID_STYLE_PLAIN_TEXT},
70 	{"Heading 1",           	XAP_STRING_ID_STYLE_HEADING1},
71 	{"Heading 2",           	XAP_STRING_ID_STYLE_HEADING2},
72 	{"Heading 3",           	XAP_STRING_ID_STYLE_HEADING3},
73 	{"Heading 4",           	XAP_STRING_ID_STYLE_HEADING4},
74 	{"Contents Header",         XAP_STRING_ID_STYLE_TOCHEADING},
75 	{"Contents 1",              XAP_STRING_ID_STYLE_TOCHEADING1},
76 	{"Contents 2",              XAP_STRING_ID_STYLE_TOCHEADING2},
77 	{"Contents 3",              XAP_STRING_ID_STYLE_TOCHEADING3},
78 	{"Contents 4",              XAP_STRING_ID_STYLE_TOCHEADING4},
79 	{"Normal",         	        XAP_STRING_ID_STYLE_NORMAL},
80 	{"Block Text",              XAP_STRING_ID_STYLE_BLOCKTEXT},
81 	{"Lower Case List",         XAP_STRING_ID_STYLE_LOWERCASELIST},
82 	{"Upper Case List",         XAP_STRING_ID_STYLE_UPPERCASTELIST},
83 	{"Lower Roman List",        XAP_STRING_ID_STYLE_LOWERROMANLIST},
84 	{"Upper Roman List",        XAP_STRING_ID_STYLE_UPPERROMANLIST},
85 	{"Bullet List",             XAP_STRING_ID_STYLE_BULLETLIST},
86 	{"Dashed List",             XAP_STRING_ID_STYLE_DASHEDLIST},
87 	{"Square List",             XAP_STRING_ID_STYLE_SQUARELIST},
88 	{"Triangle List",           XAP_STRING_ID_STYLE_TRIANGLELIST},
89 	{"Diamond List",	        XAP_STRING_ID_STYLE_DIAMONLIST},
90 	{"Star List",               XAP_STRING_ID_STYLE_STARLIST},
91 	{"Tick List",               XAP_STRING_ID_STYLE_TICKLIST},
92 	{"Box List",                XAP_STRING_ID_STYLE_BOXLIST},
93 	{"Hand List",               XAP_STRING_ID_STYLE_HANDLIST},
94 	{"Heart List",              XAP_STRING_ID_STYLE_HEARTLIST},
95 	{"Arrowhead List",          XAP_STRING_ID_STYLE_ARROWHEADLIST},
96 	{"Chapter Heading",         XAP_STRING_ID_STYLE_CHAPHEADING},
97 	{"Section Heading",         XAP_STRING_ID_STYLE_SECTHEADING},
98 	{"Endnote Reference",       XAP_STRING_ID_STYLE_ENDREFERENCE},
99 	{"Endnote Text",            XAP_STRING_ID_STYLE_ENDTEXT},
100 	{"Endnote",                 XAP_STRING_ID_STYLE_ENDNOTE},
101 	{"Footnote Reference",      XAP_STRING_ID_STYLE_FOOTREFERENCE},
102 	{"Footnote Text",           XAP_STRING_ID_STYLE_FOOTTEXT},
103 	{"Footnote",                XAP_STRING_ID_STYLE_FOOTNOTE},
104 	{"Numbered Heading 1",      XAP_STRING_ID_STYLE_NUMHEAD1},
105 	{"Numbered Heading 2",      XAP_STRING_ID_STYLE_NUMHEAD2},
106 	{"Numbered Heading 3",      XAP_STRING_ID_STYLE_NUMHEAD3},
107 	{"Implies List",	       	XAP_STRING_ID_STYLE_IMPLIES_LIST},
108 	{"None",                    XAP_STRING_ID_STYLE_NONE},
109 	{NULL,	0}
110 };
111 
112 
113 /*
114 	Gets a style name and returns its localised name
115 */
s_getLocalisedStyleName(const char * szStyle,std::string & utf8)116 void pt_PieceTable::s_getLocalisedStyleName(const char *szStyle, std::string &utf8)
117 {
118   static XAP_App * pApp = XAP_App::getApp();
119 
120 	const XAP_StringSet * pSS = pApp->getStringSet();
121 	utf8 = szStyle;
122 	int n;
123 
124 	for (n=0; stLocalised[n].pStyle; n++)
125 	{
126 		if (strcmp(szStyle, stLocalised[n].pStyle)==0)
127 		{
128 			pSS->getValueUTF8(stLocalised[n].nID, utf8);
129 			break;
130 		}
131 	}
132 
133 }
134 
135 /*
136 	Gets the style name from its localised name
137 */
s_getUnlocalisedStyleName(const char * szLocStyle)138 const char *pt_PieceTable::s_getUnlocalisedStyleName (const char *szLocStyle)
139 {
140 	static XAP_App *pApp = XAP_App::getApp();
141 	const XAP_StringSet *pSS = pApp->getStringSet();
142 
143 	for (int n = 0; stLocalised[n].pStyle; n++)
144 		if (strcmp(szLocStyle, pSS->getValue(stLocalised[n].nID)) == 0)
145 			return stLocalised[n].pStyle;
146 
147 	return szLocStyle;
148 }
149 
_loadBuiltinStyles(void)150 bool pt_PieceTable::_loadBuiltinStyles(void)
151 {
152 	static XAP_App *pApp = XAP_App::getApp();
153 	const XAP_StringSet *pSS = pApp->getStringSet();
154 	/*
155 		!!! if adding or removing properties to the list_fmt, you have to make also changes to
156 		pt_VarSet.cpp mergeAP()
157 	*/
158 	UT_LocaleTransactor t(LC_NUMERIC, "C");
159 
160 	const char* list_fmt = " list-style:%s; start-value:%s; margin-left:%fin; text-indent:-%fin; "
161 		"field-color:%s;list-delim:%s; field-font:%s; list-decimal:%s";
162 	UT_String list_fmt_tmp;
163 	UT_String stTmp;
164 	const char* szFmt;
165 
166 	// findNearestFont will do a fuzzy match, and return the nearest font in the
167 	// system -- use the locale language
168 	UT_UTF8String s = XAP_EncodingManager::get_instance()->getLanguageISOName();
169 
170 	const char * pCountry
171 		= XAP_EncodingManager::get_instance()->getLanguageISOTerritory();
172 
173 	if(pCountry)
174 	{
175 		s += "-";
176 		s += pCountry;
177 	}
178 
179 	const char* pszFamily = XAP_App::findNearestFont("Times New Roman",
180 													 "normal", "",
181 													 "normal", "", "12pt",
182 													 s.utf8_str());
183 
184 	UT_String_sprintf(stTmp, "font-family:%s; font-size:12pt; font-weight:normal; "
185 					  "font-style:normal; font-stretch:normal; font-variant:normal; "
186 					  "margin-top:0pt; margin-bottom:0pt; "
187 					  "margin-left:0pt; margin-right:0pt; text-decoration:none; "
188 					  "text-indent:0in; text-position:normal; line-height:1.0; "
189 					  "color:000000; bgcolor:transparent; widows:2", pszFamily);
190 
191 	pszFamily = XAP_App::findNearestFont("Arial", "normal", "",
192 										 "normal", "", "12pt", s.utf8_str());
193 
194 	// used to set the dom-dir of the style here, but we do not want to do that. The
195 	// dom-dir property should be inherited from the section or document (the user can, of
196 	// course, modify the style, but that is up to them).
197 #	ifdef BIDI_RTL_DOMINANT
198 	stTmp += "; text-align:right";
199 #	else
200 	stTmp += "; text-align:left";
201 #	endif
202 
203 	_s("Normal", true,	"P", "",       "Current Settings", stTmp.c_str());
204 
205 	szFmt = "font-family:%s; font-size:%dpt; font-weight:bold; margin-top:22pt; margin-bottom:3pt; keep-with-next:1";
206 	UT_String_sprintf(stTmp, szFmt, pszFamily, 17);
207 	_s("Heading 1", true,	"P", "Normal", "Normal", stTmp.c_str());
208 	UT_String_sprintf(stTmp, szFmt, pszFamily, 14);
209 	_s("Heading 2", true,	"P", "Normal", "Normal", stTmp.c_str());
210 	UT_String_sprintf(stTmp, szFmt, pszFamily, 12);
211 	_s("Heading 3", true,	"P", "Normal", "Normal", stTmp.c_str());
212 	_s("Heading 4", true,	"P", "Normal", "Normal", stTmp.c_str());
213 	_s("Plain Text", true,"P", "Normal", "Current Settings", "font-family:Courier New");
214 	_s("Block Text", true,"P", "Normal", "Current Settings", "margin-left:1in; margin-right:1in; margin-bottom:6pt");
215 
216 	UT_String_sprintf(stTmp, list_fmt, "Numbered List", "1",LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L.", "NULL", ".");
217 	_s("Numbered List",true,"P", "", "Current Settings", stTmp.c_str());
218 
219 	UT_String_sprintf(stTmp, list_fmt, "Lower Case List","1", LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L)", "NULL", ".");
220 	_s("Lower Case List",true,"P", "Numbered List", "Current Settings", stTmp.c_str());
221 	UT_String_sprintf(stTmp, list_fmt, "Upper Case List","1", LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L)", "NULL", ".");
222 	_s("Upper Case List",false,"P", "Numbered List", "Current Settings", stTmp.c_str());
223 
224 	UT_String_sprintf(stTmp, list_fmt, "Lower Roman List","1", LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L", "NULL", ".");
225 	_s("Lower Roman List",false,"P", "Normal", "Current Settings", stTmp.c_str());
226 
227 	UT_String_sprintf(stTmp, list_fmt,"Upper Roman List","1", LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L", "NULL", ".");
228 	_s("Upper Roman List",false,"P", "Numbered List", "Current Settings", stTmp.c_str());
229 
230 	UT_String_sprintf(stTmp, list_fmt, "Bullet List","0", LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L", pszFamily,"NULL");
231 
232 	_s("Bullet List",true, "P", "", "Current Settings", stTmp.c_str());
233 	UT_String_sprintf(stTmp, list_fmt, "Implies List","0", LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L", pszFamily, "NULL");
234 	_s("Implies List",false, "P", "", "Current Settings", stTmp.c_str());
235 
236 	UT_String_sprintf(stTmp, list_fmt, "Dashed List","0", LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L", "NULL", "NULL");
237 	_s("Dashed List",true, "P", "", "Current Settings", stTmp.c_str());
238 
239 	UT_String_sprintf(stTmp, list_fmt, "Square List","0", LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L", pszFamily, "NULL");
240 	_s("Square List",false, "P", "", "Current Settings", stTmp.c_str());
241 
242 	UT_String_sprintf(stTmp, list_fmt, "Triangle List","0", LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L", pszFamily, "NULL");
243 	_s("Triangle List",false, "P", "", "Current Settings", stTmp.c_str());
244 
245 	UT_String_sprintf(stTmp, list_fmt, "Diamond List","0", LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L", pszFamily, "NULL");
246 	_s("Diamond List",false, "P", "", "Current Settings", stTmp.c_str());
247 
248 	UT_String_sprintf(stTmp, list_fmt, "Star List","0", LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L", pszFamily, "NULL");
249 	_s("Star List",false, "P", "", "Current Settings", stTmp.c_str());
250 
251 	UT_String_sprintf(stTmp, list_fmt, "Tick List","0", LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L", pszFamily, "NULL");
252 	_s("Tick List",false, "P", "", "Current Settings", stTmp.c_str());
253 
254 	UT_String_sprintf(stTmp, list_fmt, "Box List","0", LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L", pszFamily, "NULL");
255 	_s("Box List",false, "P", "", "Current Settings", stTmp.c_str());
256 
257 	UT_String_sprintf(stTmp, list_fmt, "Hand List","0", LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L", pszFamily, "NULL");
258 	_s("Hand List",false, "P", "", "Current Settings", stTmp.c_str());
259 
260 	UT_String_sprintf(stTmp, list_fmt, "Heart List","0", LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L", pszFamily, "NULL");
261 	_s("Heart List",false, "P", "", "Current Settings", stTmp.c_str());
262 
263 	UT_String_sprintf(stTmp, list_fmt, "Arrowhead List","0", LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L", pszFamily, "NULL");
264 	_s("Arrowhead List",false, "P", "", "Current Settings", stTmp.c_str());
265 
266 	// pszFamily is the nearest font to Arial found in the system
267 	UT_String_sprintf(stTmp, "tabstops:0.3in/L0; list-style:Numbered List; "
268 					  "start-value:1; margin-left:0.0in; text-indent:0.0in; "
269 					  "field-color:transparent; list-delim:%%L.; field-font:%s; "
270 					  "list-decimal:", pszFamily);
271 
272 
273     _s("Numbered Heading 1",true,"P","Heading 1","Normal", stTmp.c_str());
274     _s("Numbered Heading 2",true,"P","Heading 2","Normal", stTmp.c_str());
275     _s("Numbered Heading 3",true,"P","Heading 3","Normal", stTmp.c_str());
276 
277 	// pszFamily is the nearest font to Arial found in the system
278 
279 	UT_String_sprintf(stTmp, list_fmt, "Numbered List", "1",LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L.", "NULL", ".");
280 
281     _s("Contents 1",false,"P","Normal","Normal", stTmp.c_str());
282 
283 	UT_String_sprintf(stTmp, list_fmt, "Numbered List", "1",2*LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L.", "NULL", ".");
284     _s("Contents 2",false,"P","Normal","Normal", stTmp.c_str());
285 	UT_String_sprintf(stTmp, list_fmt, "Numbered List", "1",3*LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L.", "NULL", ".");
286     _s("Contents 3",false,"P","Normal","Normal", stTmp.c_str());
287 	UT_String_sprintf(stTmp, list_fmt, "Numbered List", "1",4*LIST_DEFAULT_INDENT, LIST_DEFAULT_INDENT_LABEL, "transparent", "%L.", "NULL", ".");
288     _s("Contents 4",false,"P","Normal","Normal", stTmp.c_str());
289 
290 
291 	szFmt = "font-family:%s; font-size:%dpt; font-weight:bold; margin-top:12pt; margin-bottom:6pt; text-align:center; keep-with-next:1";
292 	UT_String_sprintf(stTmp, szFmt, pszFamily, 16);
293     _s("Contents Header",false,"P","Normal","Normal", stTmp.c_str());
294 
295 
296 	szFmt = "tabstops:1.1in/L0; list-style:Numbered List; "
297 		"start-value:1; margin-left:0.0in; text-indent:0.0in; "
298 		"field-color:transparent; list-delim:%s %%L.; "
299 		"field-font:%s; list-decimal:";
300 	UT_String_sprintf(stTmp, szFmt, pSS->getValue(XAP_STRING_ID_STYLE_DELIM_CHAPTER), pszFamily);
301 
302     _s("Chapter Heading",true,"P","Numbered Heading 1","Normal", stTmp.c_str());
303 
304 	UT_String_sprintf(stTmp, szFmt, pSS->getValue(XAP_STRING_ID_STYLE_DELIM_SECTION), pszFamily);
305     _s("Section Heading",true,"P","Numbered Heading 1","Normal", stTmp.c_str());
306 
307 	_s("Endnote Reference",false,"C", "None", "Current Settings", "text-position:superscript; font-size:10pt");
308 	_s("Endnote Text",false,"P", "Normal", "Current Settings", "text-position:normal");
309 	_s("Endnote",false,"P", "Normal", "Current Settings", "text-position:normal;text-indent:-0.2in;margin-left:0.2in");
310 
311 	_s("Footnote Reference",false,"C", "None", "Current Settings", "text-position:superscript; font-size:10pt");
312 	_s("Footnote Text",false,"P", "Normal", "Current Settings", "text-position:normal; font-size:10pt");
313 	_s("Footnote",false,"P", "Normal", "Current Settings", "text-position:normal; font-size:10pt;text-indent:-0.2in;margin-left:0.2in");
314 
315 	return true;
316 
317 Failed:
318 	return false;
319 }
320 
_createBuiltinStyle(const char * szName,bool bDisplayed,const gchar ** attributes)321 bool pt_PieceTable::_createBuiltinStyle(const char * szName, bool bDisplayed, const gchar ** attributes)
322 {
323 	// this function can only be called before loading the document.
324 	UT_return_val_if_fail (m_pts==PTS_Create, false);
325 
326 	PT_AttrPropIndex indexAP;
327 	if (!m_varset.storeAP(attributes,&indexAP))
328 		return false;
329 
330 	// verify unique name
331 	PD_Style * pStyle = NULL;
332 	if (getStyle(szName,&pStyle) == true)
333 		return false;		// duplicate name
334 
335 	pStyle = new PD_BuiltinStyle(this, indexAP, szName, bDisplayed);
336 	if (pStyle)
337 		m_hashStyles.insert(std::make_pair(szName, pStyle));
338 
339 	return true;
340 }
341 
342 
appendStyle(const gchar ** attributes)343 bool pt_PieceTable::appendStyle(const gchar ** attributes)
344 {
345 	// this function can only be called while loading the document.
346   //UT_ASSERT(m_pts==PTS_Loading);
347 
348 	// first, store the attributes and properties and get an index to them.
349 
350 	PT_AttrPropIndex indexAP;
351 	if (!m_varset.storeAP(attributes,&indexAP))
352 		return false;
353 
354 	// verify unique name
355 
356 	UT_ASSERT_HARMLESS(sizeof(char) == sizeof(gchar));
357 	const char * szName = UT_getAttribute(PT_NAME_ATTRIBUTE_NAME, attributes);
358 	if (!szName || !*szName)
359 	{
360 		UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
361 		return true;		// silently ignore unnamed styles
362 	}
363 	PD_Style * pStyle = NULL;
364 	if (getStyle(szName,&pStyle) == true)
365 	{
366 		// duplicate name
367 		UT_return_val_if_fail (pStyle, false);
368 		if (pStyle->isUserDefined())
369 		{
370 			// already loaded, ignore redefinition
371 			UT_DEBUGMSG(("appendStyle[%s]: duplicate definition ignored\n", szName));
372 			return true;
373 		}
374 
375 		// override builtin definition
376 		return pStyle->setIndexAP(indexAP);
377 	}
378 	else
379 	{
380 		// this is a new name
381 		pStyle = new PD_Style(this, indexAP, szName);
382 
383 //
384 // TODO: Learn how to use Dom's AbiObject instead of this hack.
385 // Rob asks, as AbiObject is no more, is this still a hack?
386 //
387 
388 		if (pStyle)
389 			m_hashStyles.insert(std::make_pair(szName,pStyle));
390 
391 		return true;
392 	}
393 }
394 
removeStyle(const gchar * szName)395 bool pt_PieceTable::removeStyle (const gchar * szName)
396 {
397 	UT_return_val_if_fail (szName, false);
398 	UT_ASSERT_HARMLESS(sizeof(char) == sizeof(gchar));
399 
400 	UT_DEBUGMSG(("DOM: remove the style, maybe recode the hash-table\n"));
401 
402 	PD_Style * pStyle;
403 
404 	if (getStyle(szName,&pStyle))
405 	{
406 		if (!pStyle->isUserDefined())
407 			return false; // can't destroy a builtin style
408 
409 		delete pStyle;
410 
411 		m_hashStyles.erase(szName);
412 		return true;
413 	}
414 
415 	return false;
416 }
417 
getStyle(const char * szName,PD_Style ** ppStyle) const418 bool pt_PieceTable::getStyle(const char * szName, PD_Style ** ppStyle) const
419 {
420 	//UT_ASSERT(szName && *szName);
421 
422 	StyleMap::const_iterator iter = m_hashStyles.find(szName);
423 	if(iter == m_hashStyles.end()) {
424 		return false;
425 	}
426 
427 	if (ppStyle)
428 	{
429 		*ppStyle = iter->second;
430 	}
431 
432 	return true;
433 }
434 
getStyleCount(void) const435 size_t pt_PieceTable::getStyleCount (void) const
436 {
437   return (size_t) m_hashStyles.size();
438 }
439 
440 #if 0 // currentl unused. suppress warning
441 ///////////////////////////////////////////////////////////////////////
442 /*!
443  * compareStyleNames this function is used to compare the char * strings names
444  * of the styles with the qsort method on UT_Vector.
445 \param const void * vS1  - pointer to a PD_Style pointer
446 \param const void * vS2  - pointer to a PD_Style pointer
447 \returns -ve if sz1 < sz2, 0 if sz1 == sz2, +ve if sz1 > sz2
448 */
449 static UT_sint32 compareStyleNames(const void * vS1, const void * vS2)
450 {
451 	const PD_Style ** pS1 = (const PD_Style **) vS1;
452 	const PD_Style ** pS2 = (const PD_Style **) vS2;
453 	const char * sz1 = (*pS1)->getName();
454 	const char * sz2 = (*pS2)->getName();
455 	return g_ascii_strcasecmp(sz1, sz2);
456 }
457 #endif
458 
459 /*!
460     Do not use this function inside loops, used the other enumStyles() instead !!!
461  */
enumStyles(UT_uint32 k,const char ** pszName,const PD_Style ** ppStyle) const462 bool pt_PieceTable::enumStyles(UT_uint32 k,
463 							   const char ** pszName,
464 							   const PD_Style ** ppStyle) const
465 {
466 	// return the kth style.
467 
468 	UT_uint32 kLimit = m_hashStyles.size();
469 	if (k >= kLimit)
470 		return false;
471 
472 	UT_GenericVector<PD_Style*> * vStyle = NULL;
473 	enumStyles(vStyle);
474 	//vStyle->qsort(compareStyleNames);
475 
476 	PD_Style * pStyle = vStyle->getNthItem(k);
477 	UT_return_val_if_fail (pStyle,false);
478 
479 	if (ppStyle)
480 	{
481 		*ppStyle = pStyle;
482 	}
483 
484 	if (pszName)
485 	{
486 	  *pszName = pStyle->getName();
487 	}
488 	UT_ASSERT_HARMLESS(*pszName);
489 
490 	delete vStyle;
491 
492 	return true;
493 }
494 
495 /*!
496     generate vector of styles
497     the caller has to delete pStyle when done ...
498 */
enumStyles(UT_GenericVector<PD_Style * > * & pStyles) const499 bool pt_PieceTable::enumStyles(UT_GenericVector<PD_Style*> *& pStyles) const
500 {
501 	pStyles = new UT_GenericVector<PD_Style*>;
502 
503 	for(StyleMap::const_iterator iter = m_hashStyles.begin();
504 		iter != m_hashStyles.end(); ++iter) {
505 		pStyles->addItem(iter->second);
506 	}
507 
508 	return true;
509 }
510