Index: xap_Prefs.cpp
===================================================================
RCS file: /cvsroot/abi/src/af/xap/xp/xap_Prefs.cpp,v
retrieving revision 1.59
diff -u -5 -r1.59 xap_Prefs.cpp
--- xap_Prefs.cpp	23 Nov 2001 07:03:20 -0000	1.59
+++ xap_Prefs.cpp	2 Jul 2002 07:00:42 -0000
@@ -43,20 +43,22 @@
 
 enum
 {
 	TT_ABIPREFERENCES,
 	TT_GEOMETRY,
+	TT_PLUGIN,
 	TT_RECENT,
 	TT_SCHEME,
 	TT_SELECT
 };
 
 // keep these in alphabetical order
 static struct xmlToIdMapping s_Tokens[] =
 {
 	{ "AbiPreferences",		TT_ABIPREFERENCES },
 	{ "Geometry",			TT_GEOMETRY },
+	{ "Plugin",				TT_PLUGIN },
 	{ "Recent",				TT_RECENT },
 	{ "Scheme",				TT_SCHEME },
 	{ "Select",				TT_SELECT }
 };
 
@@ -412,25 +414,36 @@
 }
 
 XAP_Prefs::~XAP_Prefs(void)
 {
 	UT_VECTOR_PURGEALL(XAP_PrefsScheme *, m_vecSchemes);
+	UT_VECTOR_PURGEALL(XAP_PrefsScheme *, m_vecPluginSchemes);
 	UT_VECTOR_FREEALL(char *, m_vecRecent);
 	UT_VECTOR_PURGEALL(tPrefsListenersPair *, m_vecPrefsListeners);
 }
 
 /*****************************************************************/
 
-XAP_PrefsScheme * XAP_Prefs::getNthScheme(UT_uint32 k) const
+XAP_PrefsScheme * XAP_Prefs::_getNthScheme(UT_uint32 k, const UT_Vector &vecSchemes) const
 {
-	UT_uint32 kLimit = m_vecSchemes.getItemCount();
+	UT_uint32 kLimit = vecSchemes.getItemCount();
 	if (k < kLimit)
-		return (XAP_PrefsScheme *)m_vecSchemes.getNthItem(k);
+		return (XAP_PrefsScheme *)vecSchemes.getNthItem(k);
 	else
 		return NULL;
 }
 
+XAP_PrefsScheme * XAP_Prefs::getNthScheme(UT_uint32 k) const
+{
+	return _getNthScheme(k, m_vecSchemes);
+}
+
+XAP_PrefsScheme * XAP_Prefs::getNthPluginScheme(UT_uint32 k) const
+{
+	return _getNthScheme(k, m_vecPluginSchemes);
+}
+
 XAP_PrefsScheme * XAP_Prefs::getScheme(const XML_Char * szSchemeName) const
 {
 	UT_uint32 kLimit = m_vecSchemes.getItemCount();
 	UT_uint32 k;
 
@@ -443,10 +456,26 @@
 	}
 
 	return NULL;
 }
 
+XAP_PrefsScheme * XAP_Prefs::getPluginScheme(const XML_Char * szSchemeName) const
+{
+	UT_uint32 kLimit = m_vecPluginSchemes.getItemCount();
+	UT_uint32 k;
+
+	for (k=0; k<kLimit; k++)
+	{
+		XAP_PrefsScheme * p = getNthPluginScheme(k);
+		UT_ASSERT(p);
+		if (strcmp((const char*)szSchemeName,(const char*)p->getSchemeName()) == 0)
+			return p;
+	}
+
+	return NULL;
+}
+
 bool XAP_Prefs::addScheme(XAP_PrefsScheme * pNewScheme)
 {
 	const XML_Char * szBuiltinSchemeName = getBuiltinSchemeName();
 	const XML_Char * szThisSchemeName = pNewScheme->getSchemeName();
 	
@@ -457,10 +486,15 @@
 	}
 	
 	return (m_vecSchemes.addItem(pNewScheme) == 0);
 }
 
+bool XAP_Prefs::addPluginScheme(XAP_PrefsScheme * pNewScheme)
+{
+	return (m_vecPluginSchemes.addItem(pNewScheme) == 0);
+}
+
 
 XAP_PrefsScheme * XAP_Prefs::getCurrentScheme(bool bCreate)
 {
 	if (bCreate)
 	{
@@ -767,10 +801,55 @@
 		if (!addScheme(pNewScheme))
 			goto MemoryError;
 		pNewScheme = NULL;				// we don't own it anymore
 		break;
 		}
+		case TT_PLUGIN:
+		{
+		// Almost the same as TT_SCHEME, except is denoted by <Plugin ... /> 
+		// instead of <Scheme ... /> and has no builtin to deal with
+
+		bool bIsNamed = false;
+		
+		pNewScheme = new XAP_PrefsScheme(this, NULL);
+		if (!pNewScheme)
+			goto MemoryError;
+		
+		const XML_Char ** a = atts;
+		while (*a)
+		{
+			UT_ASSERT(a[1] && *a[1]);	// require a value for each attribute keyword
+
+			if (strcmp((const char*)a[0], "name") == 0)
+			{
+				bIsNamed = true;
+				
+				if (getPluginScheme(a[1]))
+				{
+					UT_DEBUGMSG(("Duplicate Plugin scheme [%s]; ignoring latter instance.\n",a[1]));
+					goto IgnoreThisScheme;
+				}
+
+				if (!pNewScheme->setSchemeName(a[1]))
+					goto MemoryError;
+
+				UT_DEBUGMSG(("Found Preferences Plugin scheme [%s].\n",a[1]));
+			}
+			else
+			{
+				if (!pNewScheme->setValue(a[0],a[1]))
+					goto MemoryError;
+			}
+
+			a += 2;
+		}
+
+		if (!addPluginScheme(pNewScheme))
+			goto MemoryError;
+		pNewScheme = NULL;				// we don't own it anymore
+		break;
+		}
 		case TT_RECENT:
 		{
 		m_parserState.m_bFoundRecent = true;
 		
 		// we expect something of the form:
@@ -1122,10 +1201,63 @@
 				}
 			}
 				
 			fprintf(fp,"\t\t/>\n");
 		}
+
+		// add Plugin Scheme (plugin specific preferences) if they exist
+		kLimit = m_vecPluginSchemes.getItemCount();
+		for (k=0; k<kLimit; k++)
+		{
+			XAP_PrefsScheme * p = getNthPluginScheme(k);
+			UT_ASSERT(p);
+
+			const XML_Char * szThisSchemeName = p->getSchemeName();
+			fprintf(fp,"\n\t<Plugin\n\t\tname=\"%s\"\n",szThisSchemeName);
+
+			const XML_Char * szKey;
+			const XML_Char * szValue;
+			UT_uint32 j;
+
+			for (j=0;(p->getNthValue(j, &szKey, &szValue)) ; j++)
+			{
+					// szValue is UTF8.  Convert to Unicode and then
+					// do XML-encoding of XML-special characters and
+					// non-ASCII characters.  The printed value
+					// strings will get XML parsing and conversion to
+					// UTF8 the next time the application reads the
+					// prefs file.
+					UT_GrowBuf gb;
+					UT_decodeUTF8string(szValue, UT_XML_strlen(szValue), &gb);
+					UT_uint32 length = gb.getLength();
+					fprintf(fp,"\t\t%s=\"",szKey);
+					for (UT_uint32 udex=0; udex<length; ++udex)
+					{
+						UT_UCSChar ch = *(gb.getPointer(udex));
+						switch (ch)
+						{
+						case '&':   fputs("&amp;", fp);  break;
+						case '<':   fputs("&lt;", fp);  break;
+						case '>':   fputs("&gt;", fp);  break;
+						case '"':   fputs("&quot;", fp);  break;
+						default:
+							if (ch < ' ' || ch >= 128)
+							{
+								fprintf(fp, "&#x%x;", ch);
+							}
+							else
+							{
+								putc(ch, fp);
+							}
+						}
+					}
+					fputs("\"\n", fp);
+			}
+				
+			fprintf(fp,"\t\t/>\n");
+		}
+		// end Plugin preferences
 
 		fprintf(fp,"\n\t<Recent\n\t\tmax=\"%d\"\n",
 				(UT_uint32)m_iMaxRecent);
 
 		kLimit = m_vecRecent.getItemCount();
Index: xap_Prefs.h
===================================================================
RCS file: /cvsroot/abi/src/af/xap/xp/xap_Prefs.h,v
retrieving revision 1.31
diff -u -5 -r1.31 xap_Prefs.h
--- xap_Prefs.h	10 Apr 2002 07:58:42 -0000	1.31
+++ xap_Prefs.h	2 Jul 2002 07:00:43 -0000
@@ -98,12 +98,15 @@
 	bool					loadPrefsFile(void);
 	bool					loadSystemDefaultPrefsFile(const char * szSystemDefaultPrefsPathname);
 	bool					savePrefsFile(void);
 	
 	XAP_PrefsScheme *		getNthScheme(UT_uint32 k) const;
-    XAP_PrefsScheme *		getScheme(const XML_Char * szSchemeName) const;
+	XAP_PrefsScheme *		getNthPluginScheme(UT_uint32 k) const;
+	XAP_PrefsScheme *		getScheme(const XML_Char * szSchemeName) const;
+	XAP_PrefsScheme *		getPluginScheme(const XML_Char * szSchemeName) const;
 	bool					addScheme(XAP_PrefsScheme * pNewScheme);
+	bool					addPluginScheme(XAP_PrefsScheme * pNewScheme);
 	XAP_PrefsScheme *		getCurrentScheme(bool bCreate = false);
 	bool					setCurrentScheme(const XML_Char * szSchemeName);
 
 	bool					getPrefsValue(const XML_Char * szKey, const XML_Char ** pszValue) const;
 	bool					getPrefsValue(const UT_String &stKey, UT_String &stValue) const;
@@ -137,16 +140,18 @@
 
 	// a only-to-be-used-by XAP_PrefsScheme::setValue
 	void					_markPrefChange	( const XML_Char *szKey );
 protected:
 	void					_pruneRecent(void);
+	XAP_PrefsScheme * 		_getNthScheme(UT_uint32 k, const UT_Vector &vecSchemes) const;
 
 	XAP_App *				m_pApp;
 	bool					m_bAutoSavePrefs; /* save on any changes or only when user asks */
 	bool					m_bUseEnvLocale; /* use POSIX env vars to set locale */
 
 	UT_Vector				m_vecSchemes;		/* vector of XAP_PrefsScheme */
+	UT_Vector				m_vecPluginSchemes;	/* vector of XAP_PrefsScheme */
 	XAP_PrefsScheme *		m_currentScheme;
 	XAP_PrefsScheme *		m_builtinScheme;
 
 	UT_uint32				m_iMaxRecent;
 	UT_Vector				m_vecRecent;		/* vector of (char *) */
