bump product version to 4.1.6.2
[LibreOffice.git] / sw / source / ui / envelp / labelcfg.cxx
blob81f49f3922b886f3c9b39e326f2e9164c0c98743
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <swtypes.hxx>
21 #include <labelcfg.hxx>
22 #include <labimp.hxx>
23 #include <comphelper/string.hxx>
24 #include <rtl/bootstrap.hxx>
25 #include <unotools/configpaths.hxx>
26 #include <xmlreader/xmlreader.hxx>
28 #include <unomid.h>
30 using namespace utl;
31 using namespace ::com::sun::star::uno;
32 using namespace ::com::sun::star::beans;
34 static inline void lcl_assertEndingItem(xmlreader::XmlReader& reader)
36 int nsId;
37 xmlreader::Span name;
38 xmlreader::XmlReader::Result res;
39 res = reader.nextItem(xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
40 assert(res == xmlreader::XmlReader::RESULT_END);
41 (void) res;
44 static inline OUString lcl_getValue(xmlreader::XmlReader& reader,
45 const xmlreader::Span& span)
47 int nsId;
48 xmlreader::Span name;
49 xmlreader::XmlReader::Result res;
50 res = reader.nextItem(xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
51 assert(res == xmlreader::XmlReader::RESULT_BEGIN && name.equals(span));
52 res = reader.nextItem(xmlreader::XmlReader::TEXT_RAW, &name, &nsId);
53 assert(res == xmlreader::XmlReader::RESULT_TEXT);
54 (void) res; (void) span;
55 OUString sTmp = name.convertFromUtf8();
56 lcl_assertEndingItem(reader);
57 return sTmp;
60 static Sequence<OUString> lcl_CreatePropertyNames(const OUString& rPrefix)
62 Sequence<OUString> aProperties(2);
63 OUString* pProperties = aProperties.getArray();
64 for(sal_Int32 nProp = 0; nProp < 2; nProp++)
65 pProperties[nProp] = rPrefix;
67 pProperties[ 0] += "Name";
68 pProperties[ 1] += "Measure";
69 return aProperties;
72 SwLabelConfig::SwLabelConfig() :
73 ConfigItem("Office.Labels/Manufacturer")
75 OUString uri("$BRAND_BASE_DIR/share/labels/labels.xml");
76 rtl::Bootstrap::expandMacros(uri);
77 xmlreader::XmlReader reader(uri);
78 int nsId;
79 xmlreader::Span name;
80 xmlreader::XmlReader::Result res;
81 OUString sManufacturer;
82 OUString sName;
83 OUString sMeasure;
85 // fill m_aLabels and m_aManufacturers with the predefined labels
86 res = reader.nextItem(
87 xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
88 assert(
89 res == xmlreader::XmlReader::RESULT_BEGIN
90 && name.equals("manufacturers"));
91 res = reader.nextItem(
92 xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
93 while (res != xmlreader::XmlReader::RESULT_END)
95 // Opening manufacturer
96 assert(
97 res == xmlreader::XmlReader::RESULT_BEGIN
98 && name.equals("manufacturer"));
99 // Get the name
100 reader.nextAttribute(&nsId, &name);
101 assert(
102 nsId == xmlreader::XmlReader::NAMESPACE_NONE
103 && name.equals("name"));
104 sManufacturer = reader.getAttributeValue(false).convertFromUtf8();
106 for(;;) {
107 // Opening label or ending manufacturer
108 res = reader.nextItem(
109 xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
110 if (res == xmlreader::XmlReader::RESULT_END)
111 break;
112 assert(
113 res == xmlreader::XmlReader::RESULT_BEGIN
114 && name.equals("label"));
115 // Get name value
116 sName = lcl_getValue(reader, xmlreader::Span("name"));
117 // Get measure value
118 sMeasure = lcl_getValue(reader, xmlreader::Span("measure"));
119 // Ending label mark
120 lcl_assertEndingItem(reader);
121 if ( m_aLabels.find( sManufacturer ) == m_aLabels.end() )
122 m_aManufacturers.push_back( sManufacturer );
123 m_aLabels[sManufacturer][sName].m_aMeasure = sMeasure;
124 m_aLabels[sManufacturer][sName].m_bPredefined = true;
126 // Get next manufacturer or end
127 res = reader.nextItem(
128 xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
130 res = reader.nextItem(
131 xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
132 assert(res == xmlreader::XmlReader::RESULT_DONE);
134 // add to m_aLabels and m_aManufacturers the custom labels
135 const Sequence<OUString>& rMan = GetNodeNames( OUString() );
136 const OUString* pMan = rMan.getConstArray();
137 for ( sal_Int32 nMan = 0; nMan < rMan.getLength(); nMan++ )
139 sManufacturer = pMan[nMan];
140 const Sequence<OUString> aLabels = GetNodeNames( sManufacturer );
141 const OUString* pLabels = aLabels.getConstArray();
142 for( sal_Int32 nLabel = 0; nLabel < aLabels.getLength(); nLabel++ )
144 OUString sPrefix( sManufacturer );
145 sPrefix += "/";
146 sPrefix += pLabels[nLabel];
147 sPrefix += "/";
148 Sequence<OUString> aPropNames = lcl_CreatePropertyNames( sPrefix );
149 Sequence<Any> aValues = GetProperties( aPropNames );
150 const Any* pValues = aValues.getConstArray();
151 if (aValues.getLength() >= 1)
152 if(pValues[0].hasValue())
153 pValues[0] >>= sName;
154 if (aValues.getLength() >= 2)
155 if(pValues[1].hasValue())
156 pValues[1] >>= sMeasure;
157 if ( m_aLabels.find( sManufacturer ) == m_aLabels.end() )
158 m_aManufacturers.push_back( sManufacturer );
159 m_aLabels[sManufacturer][sName].m_aMeasure = sMeasure;
160 m_aLabels[sManufacturer][sName].m_bPredefined = false;
165 SwLabelConfig::~SwLabelConfig()
169 // the config item is not writable ?:
170 void SwLabelConfig::Commit() {}
172 void SwLabelConfig::Notify( const ::com::sun::star::uno::Sequence< OUString >& ) {}
174 static SwLabRec* lcl_CreateSwLabRec(const OUString& rType, const OUString& rMeasure, const OUString& rManufacturer)
176 SwLabRec* pNewRec = new SwLabRec;
177 pNewRec->aMake = rManufacturer;
178 pNewRec->lPWidth = 0;
179 pNewRec->lPHeight = 0;
180 pNewRec->aType = rType;
181 //all values are contained as colon-separated 1/100 mm values
182 //except for the continuous flag ('C'/'S') and nCols, nRows (sal_Int32)
183 String sMeasure(rMeasure);
184 sal_uInt16 nTokenCount = comphelper::string::getTokenCount(sMeasure, ';');
185 for(sal_uInt16 i = 0; i < nTokenCount; i++)
187 String sToken(sMeasure.GetToken(i, ';' ));
188 int nVal = sToken.ToInt32();
189 switch(i)
191 case 0 : pNewRec->bCont = sToken.GetChar(0) == 'C'; break;
192 case 1 : pNewRec->lHDist = MM100_TO_TWIP(nVal); break;
193 case 2 : pNewRec->lVDist = MM100_TO_TWIP(nVal); break;
194 case 3 : pNewRec->lWidth = MM100_TO_TWIP(nVal); break;
195 case 4 : pNewRec->lHeight = MM100_TO_TWIP(nVal); break;
196 case 5 : pNewRec->lLeft = MM100_TO_TWIP(nVal); break;
197 case 6 : pNewRec->lUpper = MM100_TO_TWIP(nVal); break;
198 case 7 : pNewRec->nCols = nVal; break;
199 case 8 : pNewRec->nRows = nVal; break;
200 case 9 : pNewRec->lPWidth = MM100_TO_TWIP(nVal); break;
201 case 10 : pNewRec->lPHeight = MM100_TO_TWIP(nVal); break;
204 // lines added for compatibility with custom label definitions saved before patch fdo#44516
205 if (pNewRec->lPWidth == 0 || pNewRec->lPHeight == 0)
207 // old style definition (no paper dimensions), calculate probable values
208 pNewRec->lPWidth = 2 * pNewRec->lLeft + (pNewRec->nCols - 1) * pNewRec->lHDist + pNewRec->lWidth;
209 pNewRec->lPHeight = ( pNewRec->bCont ? pNewRec->nRows * pNewRec->lVDist : 2 * pNewRec->lUpper + (pNewRec->nRows - 1) * pNewRec->lVDist + pNewRec->lHeight );
211 return pNewRec;
214 static Sequence<PropertyValue> lcl_CreateProperties(
215 Sequence<OUString>& rPropNames, OUString& rMeasure, const SwLabRec& rRec)
217 const OUString* pNames = rPropNames.getConstArray();
218 Sequence<PropertyValue> aRet(rPropNames.getLength());
219 PropertyValue* pValues = aRet.getArray();
220 OUString sColon(";");
222 for(sal_Int32 nProp = 0; nProp < rPropNames.getLength(); nProp++)
224 pValues[nProp].Name = pNames[nProp];
225 switch(nProp)
227 case 0: pValues[nProp].Value <<= OUString(rRec.aType); break;
228 case 1:
230 rMeasure = "";
231 rMeasure += rRec.bCont ? OUString( "C" ) : OUString( "S" ); rMeasure += sColon;
232 rMeasure += OUString::valueOf( TWIP_TO_MM100( rRec.lHDist ) ); rMeasure += sColon;
233 rMeasure += OUString::valueOf( TWIP_TO_MM100( rRec.lVDist ) ); rMeasure += sColon;
234 rMeasure += OUString::valueOf( TWIP_TO_MM100( rRec.lWidth ) ); rMeasure += sColon;
235 rMeasure += OUString::valueOf( TWIP_TO_MM100( rRec.lHeight ) ); rMeasure += sColon;
236 rMeasure += OUString::valueOf( TWIP_TO_MM100( rRec.lLeft ) ); rMeasure += sColon;
237 rMeasure += OUString::valueOf( TWIP_TO_MM100( rRec.lUpper ) ); rMeasure += sColon;
238 rMeasure += OUString::valueOf( rRec.nCols ); rMeasure += sColon;
239 rMeasure += OUString::valueOf( rRec.nRows ); rMeasure += sColon;
240 rMeasure += OUString::valueOf( TWIP_TO_MM100( rRec.lPWidth ) ); rMeasure += sColon;
241 rMeasure += OUString::valueOf( TWIP_TO_MM100( rRec.lPHeight ) );
242 pValues[nProp].Value <<= rMeasure;
244 break;
247 return aRet;
250 // function fills SwLabDlg with label definitions for manufacturer rManufacturer
251 void SwLabelConfig::FillLabels(const OUString& rManufacturer, SwLabRecs& rLabArr)
253 if (m_aLabels.find(rManufacturer) == m_aLabels.end())
254 return;
255 for (std::map<OUString, SwLabelMeasure>::iterator it = m_aLabels[rManufacturer].begin();
256 it != m_aLabels[rManufacturer].end(); ++it)
257 rLabArr.push_back( lcl_CreateSwLabRec(it->first, it->second.m_aMeasure, rManufacturer) );
260 sal_Bool SwLabelConfig::HasLabel(const OUString& rManufacturer, const OUString& rType)
262 return ( ( m_aLabels.find(rManufacturer) != m_aLabels.end() ) &&
263 ( m_aLabels[rManufacturer].find(rType) != m_aLabels[rManufacturer].end() ) );
266 static bool lcl_Exists(const OUString& rNode, const Sequence<OUString>& rLabels)
268 const OUString* pLabels = rLabels.getConstArray();
269 for(sal_Int32 i = 0; i < rLabels.getLength(); i++)
270 if(pLabels[i] == rNode)
271 return true;
272 return false;
275 // label is always saved as a custom label
276 // predefined labels can NOT be overwritten by custom labels with same manufacturer/name
277 void SwLabelConfig::SaveLabel( const OUString& rManufacturer,
278 const OUString& rType, const SwLabRec& rRec )
280 OUString sFoundNode;
281 bool bManufacturerNodeFound;
282 if ( m_aLabels.find( rManufacturer ) == m_aLabels.end() ||
283 GetNodeNames( rManufacturer ).getLength() == 0 )
285 bManufacturerNodeFound = false;
286 // manufacturer node does not exist, add (and also to m_aManufacturers)
287 if ( !AddNode( OUString(), rManufacturer ) )
289 OSL_FAIL("New configuration node could not be created");
290 return ;
292 m_aManufacturers.push_back( rManufacturer );
294 else
295 bManufacturerNodeFound = true;
297 if ( !bManufacturerNodeFound ||
298 m_aLabels[rManufacturer].find( rType ) == m_aLabels[rManufacturer].end() )
300 // type does not yet exist, add to config
301 const Sequence<OUString> aLabels = GetNodeNames( rManufacturer );
302 sal_Int32 nIndex = aLabels.getLength();
303 OUString sPrefix( "Label" );
304 sFoundNode = sPrefix;
305 sFoundNode += OUString::valueOf( nIndex );
306 while ( lcl_Exists( sFoundNode, aLabels ) )
308 sFoundNode = sPrefix;
309 sFoundNode += OUString::valueOf(nIndex++);
312 else
314 // get the appropiate node
315 OUString sManufacturer( wrapConfigurationElementName( rManufacturer ) );
316 const Sequence<OUString> aLabels = GetNodeNames( sManufacturer );
317 const OUString* pLabels = aLabels.getConstArray();
318 for (sal_Int32 nLabel = 0; nLabel < aLabels.getLength(); nLabel++)
320 OUString sPrefix( sManufacturer );
321 sPrefix += "/";
322 sPrefix += pLabels[nLabel];
323 sPrefix += "/";
324 Sequence<OUString> aProperties(1);
325 aProperties.getArray()[0] = sPrefix;
326 aProperties.getArray()[0] += "Name";
327 Sequence<Any> aValues = GetProperties( aProperties );
328 const Any* pValues = aValues.getConstArray();
329 if ( pValues[0].hasValue() )
331 OUString sTmp;
332 pValues[0] >>= sTmp;
333 if ( rType == sTmp )
335 sFoundNode = pLabels[nLabel];
336 break;
342 OUString sPrefix( wrapConfigurationElementName( rManufacturer ) );
343 sPrefix += "/";
344 sPrefix += sFoundNode;
345 sPrefix += "/";
346 Sequence<OUString> aPropNames = lcl_CreatePropertyNames( sPrefix );
347 OUString sMeasure;
348 Sequence<PropertyValue> aPropValues = lcl_CreateProperties( aPropNames, sMeasure, rRec );
349 SetSetProperties( wrapConfigurationElementName( rManufacturer ), aPropValues );
351 //update m_aLabels
352 m_aLabels[rManufacturer][rType].m_aMeasure = sMeasure;
353 m_aLabels[rManufacturer][rType].m_bPredefined = false;
357 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */