1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svtools.hxx"
30 
31 #include <svtools/fontsubstconfig.hxx>
32 #include <svl/svarray.hxx>
33 #include <com/sun/star/beans/PropertyValue.hpp>
34 #include <com/sun/star/uno/Any.hxx>
35 #include <com/sun/star/uno/Sequence.hxx>
36 #include <tools/debug.hxx>
37 
38 #include <vcl/outdev.hxx>
39 #include <rtl/logfile.hxx>
40 
41 using namespace utl;
42 using namespace rtl;
43 using namespace com::sun::star;
44 using namespace com::sun::star::uno;
45 using namespace com::sun::star::beans;
46 
47 #define C2U(cChar) OUString::createFromAscii(cChar)
48 
49 const sal_Char cReplacement[] = "Replacement";
50 const sal_Char cFontPairs[] = "FontPairs";
51 
52 const sal_Char cReplaceFont[] 	= "ReplaceFont";
53 const sal_Char cSubstituteFont[]= "SubstituteFont";
54 const sal_Char cOnScreenOnly[] 	= "OnScreenOnly";
55 const sal_Char cAlways[] 		= "Always";
56 
57 //-----------------------------------------------------------------------------
58 typedef SubstitutionStruct* SubstitutionStructPtr;
59 SV_DECL_PTRARR_DEL(SubstitutionStructArr, SubstitutionStructPtr, 2, 2)
60 SV_IMPL_PTRARR(SubstitutionStructArr, SubstitutionStructPtr);
61 //-----------------------------------------------------------------------------
62 struct SvtFontSubstConfig_Impl
63 {
64 	SubstitutionStructArr	aSubstArr;
65 };
66 /* -----------------------------18.01.01 12:04--------------------------------
67 
68  ---------------------------------------------------------------------------*/
69 SvtFontSubstConfig::SvtFontSubstConfig() :
70 	ConfigItem(C2U("Office.Common/Font/Substitution")),
71 	bIsEnabled(sal_False),
72 	pImpl(new SvtFontSubstConfig_Impl)
73 {
74 	RTL_LOGFILE_CONTEXT(aLog, "svtools SvtFontSubstConfig::SvtFontSubstConfig()");
75 
76 	Sequence<OUString> aNames(1);
77 	aNames.getArray()[0] = C2U(cReplacement);
78 	Sequence<Any> aValues = GetProperties(aNames);
79 	DBG_ASSERT(aValues.getConstArray()[0].hasValue(), "no value available");
80 	if(aValues.getConstArray()[0].hasValue())
81 		bIsEnabled = *(sal_Bool*)aValues.getConstArray()[0].getValue();
82 
83 	OUString sPropPrefix(C2U(cFontPairs));
84     Sequence<OUString> aNodeNames = GetNodeNames(sPropPrefix, CONFIG_NAME_LOCAL_PATH);
85 	const OUString* pNodeNames = aNodeNames.getConstArray();
86 	Sequence<OUString> aPropNames(aNodeNames.getLength() * 4);
87 	OUString* pNames = aPropNames.getArray();
88 	sal_Int32 nName = 0;
89 	sPropPrefix += C2U("/");
90 	sal_Int32 nNode;
91 	for(nNode = 0; nNode < aNodeNames.getLength(); nNode++)
92 	{
93 		OUString sStart(sPropPrefix);
94 		sStart += pNodeNames[nNode];
95 		sStart += C2U("/");
96 		pNames[nName] = sStart; 	pNames[nName++] += C2U(cReplaceFont);
97 		pNames[nName] = sStart; 	pNames[nName++] += C2U(cSubstituteFont);
98 		pNames[nName] = sStart; 	pNames[nName++] += C2U(cAlways);
99 		pNames[nName] = sStart; 	pNames[nName++] += C2U(cOnScreenOnly);
100 	}
101 	Sequence<Any> aNodeValues = GetProperties(aPropNames);
102 	const Any* pNodeValues = aNodeValues.getConstArray();
103 	nName = 0;
104 	for(nNode = 0; nNode < aNodeNames.getLength(); nNode++)
105 	{
106 		SubstitutionStructPtr pInsert = new SubstitutionStruct;
107 		pNodeValues[nName++] >>= pInsert->sFont;
108 		pNodeValues[nName++] >>= pInsert->sReplaceBy;
109 		pInsert->bReplaceAlways = *(sal_Bool*)pNodeValues[nName++].getValue();
110 		pInsert->bReplaceOnScreenOnly = *(sal_Bool*)pNodeValues[nName++].getValue();
111 		pImpl->aSubstArr.Insert(pInsert, pImpl->aSubstArr.Count());
112 	}
113 }
114 /* -----------------------------18.01.01 12:06--------------------------------
115 
116  ---------------------------------------------------------------------------*/
117 SvtFontSubstConfig::~SvtFontSubstConfig()
118 {
119 	delete pImpl;
120 }
121 /*-- 18.01.01 12:08:00---------------------------------------------------
122 
123   -----------------------------------------------------------------------*/
124 void SvtFontSubstConfig::Notify( const com::sun::star::uno::Sequence< rtl::OUString >& )
125 {
126 }
127 
128 void SvtFontSubstConfig::Commit()
129 {
130 	Sequence<OUString> aNames(1);
131 	aNames.getArray()[0] = C2U(cReplacement);
132 	Sequence<Any> aValues(1);
133 	aValues.getArray()[0].setValue(&bIsEnabled, ::getBooleanCppuType());
134 	PutProperties(aNames, aValues);
135 
136 	OUString sNode(C2U(cFontPairs));
137 	if(!pImpl->aSubstArr.Count())
138 		ClearNodeSet(sNode);
139 	else
140 	{
141 		Sequence<PropertyValue> aSetValues(4 * pImpl->aSubstArr.Count());
142 		PropertyValue* pSetValues = aSetValues.getArray();
143 		sal_Int32 nSetValue = 0;
144 
145 		const OUString sReplaceFont(C2U(cReplaceFont));
146 		const OUString sSubstituteFont(C2U(cSubstituteFont));
147 		const OUString sAlways(C2U(cAlways));
148 		const OUString sOnScreenOnly(C2U(cOnScreenOnly));
149 
150 		const uno::Type& rBoolType = ::getBooleanCppuType();
151 		for(sal_uInt16 i = 0; i < pImpl->aSubstArr.Count(); i++)
152 		{
153 			OUString sPrefix(sNode);
154 			sPrefix += C2U("/_");
155 			sPrefix += OUString::valueOf((sal_Int32)i);
156 			sPrefix += C2U("/");
157 
158 			SubstitutionStructPtr pSubst = pImpl->aSubstArr[i];
159 			pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sReplaceFont;
160 			pSetValues[nSetValue++].Value <<= pSubst->sFont;
161 			pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sSubstituteFont;
162 			pSetValues[nSetValue++].Value <<= pSubst->sReplaceBy;
163 			pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sAlways;
164 			pSetValues[nSetValue++].Value.setValue(&pSubst->bReplaceAlways, rBoolType);
165 			pSetValues[nSetValue].Name = sPrefix; pSetValues[nSetValue].Name += sOnScreenOnly;
166 			pSetValues[nSetValue++].Value.setValue(&pSubst->bReplaceOnScreenOnly, rBoolType);
167 		}
168 		ReplaceSetProperties(sNode, aSetValues);
169 	}
170 }
171 /*-- 18.01.01 12:08:00---------------------------------------------------
172 
173   -----------------------------------------------------------------------*/
174 sal_Int32 SvtFontSubstConfig::SubstitutionCount() const
175 {
176 	return pImpl->aSubstArr.Count();
177 }
178 /*-- 18.01.01 12:08:00---------------------------------------------------
179 
180   -----------------------------------------------------------------------*/
181 void SvtFontSubstConfig::ClearSubstitutions()
182 {
183 	pImpl->aSubstArr.DeleteAndDestroy(0, pImpl->aSubstArr.Count());
184 }
185 /*-- 18.01.01 12:08:00---------------------------------------------------
186 
187   -----------------------------------------------------------------------*/
188 const SubstitutionStruct* SvtFontSubstConfig::GetSubstitution(sal_Int32 nPos)
189 {
190 	DBG_ASSERT(nPos >= 0 && nPos < pImpl->aSubstArr.Count(), "illegal array index");
191 	if(nPos >= 0 && nPos < pImpl->aSubstArr.Count())
192 		return pImpl->aSubstArr[(sal_uInt16)nPos];
193 	return 0;
194 }
195 /*-- 18.01.01 12:08:01---------------------------------------------------
196 
197   -----------------------------------------------------------------------*/
198 void SvtFontSubstConfig::AddSubstitution(const SubstitutionStruct& rToAdd)
199 {
200 	SubstitutionStructPtr pInsert = new SubstitutionStruct(rToAdd);
201 	pImpl->aSubstArr.Insert(pInsert, pImpl->aSubstArr.Count());
202 }
203 
204 void SvtFontSubstConfig::Apply()
205 {
206 	OutputDevice::BeginFontSubstitution();
207 
208 	// Alte Substitution entfernen
209 	sal_uInt16 nOldCount = OutputDevice::GetFontSubstituteCount();
210 
211 	while (nOldCount)
212 		OutputDevice::RemoveFontSubstitute(--nOldCount);
213 
214 	// Neue Substitution einlesen
215     sal_Int32 nCount = IsEnabled() ? SubstitutionCount() : 0;
216 
217 	for (sal_Int32  i = 0; i < nCount; i++)
218 	{
219 	    sal_uInt16 nFlags = 0;
220 		const SubstitutionStruct* pSubs = GetSubstitution(i);
221 		if(pSubs->bReplaceAlways)
222 			nFlags |= FONT_SUBSTITUTE_ALWAYS;
223 		if(pSubs->bReplaceOnScreenOnly)
224 			nFlags |= FONT_SUBSTITUTE_SCREENONLY;
225 		OutputDevice::AddFontSubstitute( String(pSubs->sFont), String(pSubs->sReplaceBy), nFlags );
226     }
227 
228 	OutputDevice::EndFontSubstitution();
229 }
230