Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <config_folders.h>
21 :
22 : #include <swtypes.hxx>
23 : #include <labelcfg.hxx>
24 : #include <labimp.hxx>
25 : #include <comphelper/string.hxx>
26 : #include <rtl/bootstrap.hxx>
27 : #include <unotools/configpaths.hxx>
28 : #include <xmlreader/xmlreader.hxx>
29 :
30 : #include <unomid.h>
31 :
32 : using namespace utl;
33 : using namespace ::com::sun::star::uno;
34 : using namespace ::com::sun::star::beans;
35 :
36 0 : static inline void lcl_assertEndingItem(xmlreader::XmlReader& reader)
37 : {
38 : int nsId;
39 0 : xmlreader::Span name;
40 : xmlreader::XmlReader::Result res;
41 0 : res = reader.nextItem(xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
42 : assert(res == xmlreader::XmlReader::RESULT_END);
43 : (void) res;
44 0 : }
45 :
46 0 : static inline OUString lcl_getValue(xmlreader::XmlReader& reader,
47 : const xmlreader::Span& span)
48 : {
49 : int nsId;
50 0 : xmlreader::Span name;
51 : xmlreader::XmlReader::Result res;
52 0 : res = reader.nextItem(xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
53 : assert(res == xmlreader::XmlReader::RESULT_BEGIN && name.equals(span));
54 0 : res = reader.nextItem(xmlreader::XmlReader::TEXT_RAW, &name, &nsId);
55 : assert(res == xmlreader::XmlReader::RESULT_TEXT);
56 : (void) res; (void) span;
57 0 : OUString sTmp = name.convertFromUtf8();
58 0 : lcl_assertEndingItem(reader);
59 0 : return sTmp;
60 : }
61 :
62 0 : static Sequence<OUString> lcl_CreatePropertyNames(const OUString& rPrefix)
63 : {
64 0 : Sequence<OUString> aProperties(2);
65 0 : OUString* pProperties = aProperties.getArray();
66 0 : for(sal_Int32 nProp = 0; nProp < 2; nProp++)
67 0 : pProperties[nProp] = rPrefix;
68 :
69 0 : pProperties[ 0] += "Name";
70 0 : pProperties[ 1] += "Measure";
71 0 : return aProperties;
72 : }
73 :
74 0 : SwLabelConfig::SwLabelConfig() :
75 0 : ConfigItem("Office.Labels/Manufacturer")
76 : {
77 0 : OUString uri("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/labels/labels.xml");
78 0 : rtl::Bootstrap::expandMacros(uri);
79 0 : xmlreader::XmlReader reader(uri);
80 : int nsId;
81 0 : xmlreader::Span name;
82 : xmlreader::XmlReader::Result res;
83 0 : OUString sManufacturer;
84 0 : OUString sName;
85 0 : OUString sMeasure;
86 :
87 : // fill m_aLabels and m_aManufacturers with the predefined labels
88 : res = reader.nextItem(
89 0 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
90 : assert(
91 : res == xmlreader::XmlReader::RESULT_BEGIN
92 : && name.equals("manufacturers"));
93 : res = reader.nextItem(
94 0 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
95 0 : while (res != xmlreader::XmlReader::RESULT_END)
96 : {
97 : // Opening manufacturer
98 : assert(
99 : res == xmlreader::XmlReader::RESULT_BEGIN
100 : && name.equals("manufacturer"));
101 : // Get the name
102 0 : reader.nextAttribute(&nsId, &name);
103 : assert(
104 : nsId == xmlreader::XmlReader::NAMESPACE_NONE
105 : && name.equals("name"));
106 0 : sManufacturer = reader.getAttributeValue(false).convertFromUtf8();
107 :
108 : for(;;) {
109 : // Opening label or ending manufacturer
110 : res = reader.nextItem(
111 0 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
112 0 : if (res == xmlreader::XmlReader::RESULT_END)
113 0 : break;
114 : assert(
115 : res == xmlreader::XmlReader::RESULT_BEGIN
116 : && name.equals("label"));
117 : // Get name value
118 0 : sName = lcl_getValue(reader, xmlreader::Span("name"));
119 : // Get measure value
120 0 : sMeasure = lcl_getValue(reader, xmlreader::Span("measure"));
121 : // Ending label mark
122 0 : lcl_assertEndingItem(reader);
123 0 : if ( m_aLabels.find( sManufacturer ) == m_aLabels.end() )
124 0 : m_aManufacturers.push_back( sManufacturer );
125 0 : m_aLabels[sManufacturer][sName].m_aMeasure = sMeasure;
126 0 : m_aLabels[sManufacturer][sName].m_bPredefined = true;
127 : }
128 : // Get next manufacturer or end
129 : res = reader.nextItem(
130 0 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
131 : };
132 : res = reader.nextItem(
133 0 : xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
134 : assert(res == xmlreader::XmlReader::RESULT_DONE);
135 :
136 : // add to m_aLabels and m_aManufacturers the custom labels
137 0 : const Sequence<OUString>& rMan = GetNodeNames( OUString() );
138 0 : const OUString* pMan = rMan.getConstArray();
139 0 : for ( sal_Int32 nMan = 0; nMan < rMan.getLength(); nMan++ )
140 : {
141 0 : sManufacturer = pMan[nMan];
142 0 : const Sequence<OUString> aLabels = GetNodeNames( sManufacturer );
143 0 : const OUString* pLabels = aLabels.getConstArray();
144 0 : for( sal_Int32 nLabel = 0; nLabel < aLabels.getLength(); nLabel++ )
145 : {
146 0 : OUString sPrefix( sManufacturer );
147 0 : sPrefix += "/";
148 0 : sPrefix += pLabels[nLabel];
149 0 : sPrefix += "/";
150 0 : Sequence<OUString> aPropNames = lcl_CreatePropertyNames( sPrefix );
151 0 : Sequence<Any> aValues = GetProperties( aPropNames );
152 0 : const Any* pValues = aValues.getConstArray();
153 0 : if (aValues.getLength() >= 1)
154 0 : if(pValues[0].hasValue())
155 0 : pValues[0] >>= sName;
156 0 : if (aValues.getLength() >= 2)
157 0 : if(pValues[1].hasValue())
158 0 : pValues[1] >>= sMeasure;
159 0 : if ( m_aLabels.find( sManufacturer ) == m_aLabels.end() )
160 0 : m_aManufacturers.push_back( sManufacturer );
161 0 : m_aLabels[sManufacturer][sName].m_aMeasure = sMeasure;
162 0 : m_aLabels[sManufacturer][sName].m_bPredefined = false;
163 0 : }
164 0 : }
165 0 : }
166 :
167 0 : SwLabelConfig::~SwLabelConfig()
168 : {
169 0 : }
170 :
171 : // the config item is not writable ?:
172 0 : void SwLabelConfig::Commit() {}
173 :
174 0 : void SwLabelConfig::Notify( const ::com::sun::star::uno::Sequence< OUString >& ) {}
175 :
176 0 : static SwLabRec* lcl_CreateSwLabRec(const OUString& rType, const OUString& rMeasure, const OUString& rManufacturer)
177 : {
178 0 : SwLabRec* pNewRec = new SwLabRec;
179 0 : pNewRec->aMake = rManufacturer;
180 0 : pNewRec->lPWidth = 0;
181 0 : pNewRec->lPHeight = 0;
182 0 : pNewRec->aType = rType;
183 : //all values are contained as colon-separated 1/100 mm values
184 : //except for the continuous flag ('C'/'S') and nCols, nRows (sal_Int32)
185 0 : OUString sMeasure(rMeasure);
186 0 : sal_uInt16 nTokenCount = comphelper::string::getTokenCount(sMeasure, ';');
187 0 : for(sal_uInt16 i = 0; i < nTokenCount; i++)
188 : {
189 0 : OUString sToken(sMeasure.getToken(i, ';' ));
190 0 : int nVal = sToken.toInt32();
191 0 : switch(i)
192 : {
193 0 : case 0 : pNewRec->bCont = sToken[0] == 'C'; break;
194 0 : case 1 : pNewRec->lHDist = convertMm100ToTwip(nVal); break;
195 0 : case 2 : pNewRec->lVDist = convertMm100ToTwip(nVal); break;
196 0 : case 3 : pNewRec->lWidth = convertMm100ToTwip(nVal); break;
197 0 : case 4 : pNewRec->lHeight = convertMm100ToTwip(nVal); break;
198 0 : case 5 : pNewRec->lLeft = convertMm100ToTwip(nVal); break;
199 0 : case 6 : pNewRec->lUpper = convertMm100ToTwip(nVal); break;
200 0 : case 7 : pNewRec->nCols = nVal; break;
201 0 : case 8 : pNewRec->nRows = nVal; break;
202 0 : case 9 : pNewRec->lPWidth = convertMm100ToTwip(nVal); break;
203 0 : case 10 : pNewRec->lPHeight = convertMm100ToTwip(nVal); break;
204 : }
205 0 : }
206 : // lines added for compatibility with custom label definitions saved before patch fdo#44516
207 0 : if (pNewRec->lPWidth == 0 || pNewRec->lPHeight == 0)
208 : {
209 : // old style definition (no paper dimensions), calculate probable values
210 0 : pNewRec->lPWidth = 2 * pNewRec->lLeft + (pNewRec->nCols - 1) * pNewRec->lHDist + pNewRec->lWidth;
211 0 : pNewRec->lPHeight = ( pNewRec->bCont ? pNewRec->nRows * pNewRec->lVDist : 2 * pNewRec->lUpper + (pNewRec->nRows - 1) * pNewRec->lVDist + pNewRec->lHeight );
212 : }
213 0 : return pNewRec;
214 : }
215 :
216 0 : static Sequence<PropertyValue> lcl_CreateProperties(
217 : Sequence<OUString>& rPropNames, OUString& rMeasure, const SwLabRec& rRec)
218 : {
219 0 : const OUString* pNames = rPropNames.getConstArray();
220 0 : Sequence<PropertyValue> aRet(rPropNames.getLength());
221 0 : PropertyValue* pValues = aRet.getArray();
222 0 : OUString sColon(";");
223 :
224 0 : for(sal_Int32 nProp = 0; nProp < rPropNames.getLength(); nProp++)
225 : {
226 0 : pValues[nProp].Name = pNames[nProp];
227 0 : switch(nProp)
228 : {
229 0 : case 0: pValues[nProp].Value <<= OUString(rRec.aType); break;
230 : case 1:
231 : {
232 0 : rMeasure = "";
233 0 : rMeasure += rRec.bCont ? OUString( "C" ) : OUString( "S" ); rMeasure += sColon;
234 0 : rMeasure += OUString::number( convertTwipToMm100( rRec.lHDist ) ); rMeasure += sColon;
235 0 : rMeasure += OUString::number( convertTwipToMm100( rRec.lVDist ) ); rMeasure += sColon;
236 0 : rMeasure += OUString::number( convertTwipToMm100( rRec.lWidth ) ); rMeasure += sColon;
237 0 : rMeasure += OUString::number( convertTwipToMm100( rRec.lHeight ) ); rMeasure += sColon;
238 0 : rMeasure += OUString::number( convertTwipToMm100( rRec.lLeft ) ); rMeasure += sColon;
239 0 : rMeasure += OUString::number( convertTwipToMm100( rRec.lUpper ) ); rMeasure += sColon;
240 0 : rMeasure += OUString::number( rRec.nCols ); rMeasure += sColon;
241 0 : rMeasure += OUString::number( rRec.nRows ); rMeasure += sColon;
242 0 : rMeasure += OUString::number( convertTwipToMm100( rRec.lPWidth ) ); rMeasure += sColon;
243 0 : rMeasure += OUString::number( convertTwipToMm100( rRec.lPHeight ) );
244 0 : pValues[nProp].Value <<= rMeasure;
245 : }
246 0 : break;
247 : }
248 : }
249 0 : return aRet;
250 : }
251 :
252 : // function fills SwLabDlg with label definitions for manufacturer rManufacturer
253 0 : void SwLabelConfig::FillLabels(const OUString& rManufacturer, SwLabRecs& rLabArr)
254 : {
255 0 : if (m_aLabels.find(rManufacturer) == m_aLabels.end())
256 0 : return;
257 0 : for (std::map<OUString, SwLabelMeasure>::iterator it = m_aLabels[rManufacturer].begin();
258 0 : it != m_aLabels[rManufacturer].end(); ++it)
259 0 : rLabArr.push_back( lcl_CreateSwLabRec(it->first, it->second.m_aMeasure, rManufacturer) );
260 : }
261 :
262 0 : sal_Bool SwLabelConfig::HasLabel(const OUString& rManufacturer, const OUString& rType)
263 : {
264 0 : return ( ( m_aLabels.find(rManufacturer) != m_aLabels.end() ) &&
265 0 : ( m_aLabels[rManufacturer].find(rType) != m_aLabels[rManufacturer].end() ) );
266 : }
267 :
268 0 : static bool lcl_Exists(const OUString& rNode, const Sequence<OUString>& rLabels)
269 : {
270 0 : const OUString* pLabels = rLabels.getConstArray();
271 0 : for(sal_Int32 i = 0; i < rLabels.getLength(); i++)
272 0 : if(pLabels[i] == rNode)
273 0 : return true;
274 0 : return false;
275 : }
276 :
277 : // label is always saved as a custom label
278 : // predefined labels can NOT be overwritten by custom labels with same manufacturer/name
279 0 : void SwLabelConfig::SaveLabel( const OUString& rManufacturer,
280 : const OUString& rType, const SwLabRec& rRec )
281 : {
282 0 : OUString sFoundNode;
283 : bool bManufacturerNodeFound;
284 0 : if ( m_aLabels.find( rManufacturer ) == m_aLabels.end() ||
285 0 : GetNodeNames( rManufacturer ).getLength() == 0 )
286 : {
287 0 : bManufacturerNodeFound = false;
288 : // manufacturer node does not exist, add (and also to m_aManufacturers)
289 0 : if ( !AddNode( OUString(), rManufacturer ) )
290 : {
291 : OSL_FAIL("New configuration node could not be created");
292 0 : return ;
293 : }
294 0 : m_aManufacturers.push_back( rManufacturer );
295 : }
296 : else
297 0 : bManufacturerNodeFound = true;
298 :
299 0 : if ( !bManufacturerNodeFound ||
300 0 : m_aLabels[rManufacturer].find( rType ) == m_aLabels[rManufacturer].end() )
301 : {
302 : // type does not yet exist, add to config
303 0 : const Sequence<OUString> aLabels = GetNodeNames( rManufacturer );
304 0 : sal_Int32 nIndex = aLabels.getLength();
305 0 : OUString sPrefix( "Label" );
306 0 : sFoundNode = sPrefix;
307 0 : sFoundNode += OUString::number( nIndex );
308 0 : while ( lcl_Exists( sFoundNode, aLabels ) )
309 : {
310 0 : sFoundNode = sPrefix;
311 0 : sFoundNode += OUString::number(nIndex++);
312 0 : }
313 : }
314 : else
315 : {
316 : // get the appropiate node
317 0 : OUString sManufacturer( wrapConfigurationElementName( rManufacturer ) );
318 0 : const Sequence<OUString> aLabels = GetNodeNames( sManufacturer );
319 0 : const OUString* pLabels = aLabels.getConstArray();
320 0 : for (sal_Int32 nLabel = 0; nLabel < aLabels.getLength(); nLabel++)
321 : {
322 0 : OUString sPrefix( sManufacturer );
323 0 : sPrefix += "/";
324 0 : sPrefix += pLabels[nLabel];
325 0 : sPrefix += "/";
326 0 : Sequence<OUString> aProperties(1);
327 0 : aProperties.getArray()[0] = sPrefix;
328 0 : aProperties.getArray()[0] += "Name";
329 0 : Sequence<Any> aValues = GetProperties( aProperties );
330 0 : const Any* pValues = aValues.getConstArray();
331 0 : if ( pValues[0].hasValue() )
332 : {
333 0 : OUString sTmp;
334 0 : pValues[0] >>= sTmp;
335 0 : if ( rType == sTmp )
336 : {
337 0 : sFoundNode = pLabels[nLabel];
338 0 : break;
339 0 : }
340 : }
341 0 : }
342 : }
343 :
344 0 : OUString sPrefix( wrapConfigurationElementName( rManufacturer ) );
345 0 : sPrefix += "/";
346 0 : sPrefix += sFoundNode;
347 0 : sPrefix += "/";
348 0 : Sequence<OUString> aPropNames = lcl_CreatePropertyNames( sPrefix );
349 0 : OUString sMeasure;
350 0 : Sequence<PropertyValue> aPropValues = lcl_CreateProperties( aPropNames, sMeasure, rRec );
351 0 : SetSetProperties( wrapConfigurationElementName( rManufacturer ), aPropValues );
352 :
353 : //update m_aLabels
354 0 : m_aLabels[rManufacturer][rType].m_aMeasure = sMeasure;
355 0 : m_aLabels[rManufacturer][rType].m_bPredefined = false;
356 0 : }
357 :
358 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|