1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #include "precompiled_reportdesign.hxx"
24 #include "xmlGroup.hxx"
25 #include "xmlSection.hxx"
26 #include "xmlFunction.hxx"
27 #include "xmlfilter.hxx"
28 #include <xmloff/xmltoken.hxx>
29 #include <xmloff/xmlnmspe.hxx>
30 #include <xmloff/nmspmap.hxx>
31 #include <xmloff/xmluconv.hxx>
32 #include "xmlHelper.hxx"
33 #include "xmlEnums.hxx"
34 #include <ucbhelper/content.hxx>
35 #include <comphelper/namecontainer.hxx>
36 #include <com/sun/star/report/GroupOn.hpp>
37 #include <com/sun/star/report/KeepTogether.hpp>
38 #include <tools/debug.hxx>
39 
40 namespace rptxml
41 {
42 	using namespace ::com::sun::star;
43 	using namespace ::com::sun::star::uno;
44 	using namespace ::com::sun::star::report;
45 	using namespace ::com::sun::star::xml::sax;
46 
lcl_getKeepTogetherOption(const::rtl::OUString & _sValue)47 	sal_uInt16 lcl_getKeepTogetherOption(const ::rtl::OUString& _sValue)
48 	{
49 		sal_uInt16 nRet = report::KeepTogether::NO;
50 		const SvXMLEnumMapEntry* aXML_EnumMap = OXMLHelper::GetKeepTogetherOptions();
51 		SvXMLUnitConverter::convertEnum( nRet, _sValue, aXML_EnumMap );
52 		return nRet;
53 	}
DBG_NAME(rpt_OXMLGroup)54 DBG_NAME( rpt_OXMLGroup )
55 
56 OXMLGroup::OXMLGroup( ORptFilter& _rImport
57 				,sal_uInt16 nPrfx
58 				,const ::rtl::OUString& _sLocalName
59 				,const Reference< XAttributeList > & _xAttrList
60 				) :
61 	SvXMLImportContext( _rImport, nPrfx, _sLocalName )
62 {
63     DBG_CTOR( rpt_OXMLGroup,NULL);
64 
65 	m_xGroups = _rImport.getReportDefinition()->getGroups();
66 	OSL_ENSURE(m_xGroups.is(),"Groups is NULL!");
67 	m_xGroup = m_xGroups->createGroup();
68 
69 	OSL_ENSURE(_xAttrList.is(),"Attribute list is NULL!");
70 
71 	const SvXMLNamespaceMap& rMap = _rImport.GetNamespaceMap();
72 	const SvXMLTokenMap& rTokenMap = _rImport.GetGroupElemTokenMap();
73     m_xGroup->setSortAscending(sal_False);// the default value has to be set
74 	const sal_Int16 nLength = (_xAttrList.is()) ? _xAttrList->getLength() : 0;
75 	static const ::rtl::OUString s_sTRUE = ::xmloff::token::GetXMLToken(XML_TRUE);
76 	for(sal_Int16 i = 0; i < nLength; ++i)
77 	{
78         ::rtl::OUString sLocalName;
79 		const ::rtl::OUString sAttrName = _xAttrList->getNameByIndex( i );
80 		const sal_uInt16 nPrefix = rMap.GetKeyByAttrName( sAttrName,&sLocalName );
81 		::rtl::OUString sValue = _xAttrList->getValueByIndex( i );
82 
83 		try
84 		{
85 			switch( rTokenMap.Get( nPrefix, sLocalName ) )
86 			{
87 				case XML_TOK_START_NEW_COLUMN:
88 					m_xGroup->setStartNewColumn(sValue == s_sTRUE);
89 					break;
90 				case XML_TOK_RESET_PAGE_NUMBER:
91 					m_xGroup->setResetPageNumber(sValue == s_sTRUE);
92 					break;
93 				case XML_TOK_SORT_ASCENDING:
94 					m_xGroup->setSortAscending(sValue == s_sTRUE);
95 					break;
96 				case XML_TOK_GROUP_EXPRESSION:
97                     {
98                         sal_Int32 nLen = sValue.getLength();
99                         if ( nLen )
100                         {
101 
102                             const static ::rtl::OUString s_sChanged(RTL_CONSTASCII_USTRINGPARAM("rpt:HASCHANGED(\""));
103                             sal_Int32 nPos = sValue.indexOf(s_sChanged);
104                             if ( nPos == -1 )
105                                 nPos = 5;
106                             else
107                             {
108                                 nPos = s_sChanged.getLength();
109                                 static ::rtl::OUString s_sQuote(RTL_CONSTASCII_USTRINGPARAM("\"\""));
110                                 static ::rtl::OUString s_sSingleQuote(RTL_CONSTASCII_USTRINGPARAM("\""));
111                                 sal_Int32 nIndex = sValue.indexOf(s_sQuote,nPos);
112                                 while ( nIndex > -1 )
113                                 {
114                                     sValue = sValue.replaceAt(nIndex,2,s_sSingleQuote);
115                                     nIndex = sValue.indexOf(s_sQuote,nIndex+2);
116                                 }
117                                 nLen = sValue.getLength() - 1;
118                             }
119                             sValue = sValue.copy(nPos,nLen-nPos-1);
120                             const ORptFilter::TGroupFunctionMap& aFunctions = _rImport.getFunctions();
121                             ORptFilter::TGroupFunctionMap::const_iterator aFind = aFunctions.find(sValue);
122                             if ( aFind != aFunctions.end() )
123                             {
124                                 sal_Int32 nIndex = 0;
125                                 const ::rtl::OUString sCompleteFormula = aFind->second->getFormula();
126                                 ::rtl::OUString sExpression = sCompleteFormula.getToken(1,'[',nIndex);
127                                 nIndex = 0;
128                                 sExpression = sExpression.getToken(0,']',nIndex);
129                                 nIndex = 0;
130                                 const ::rtl::OUString sFormula = sCompleteFormula.getToken(0,'(',nIndex);
131                                 ::sal_Int16 nGroupOn = report::GroupOn::DEFAULT;
132 
133                                 if ( sFormula ==::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("rpt:LEFT")))
134                                 {
135                                     nGroupOn = report::GroupOn::PREFIX_CHARACTERS;
136                                     ::rtl::OUString sInterval = sCompleteFormula.getToken(1,';',nIndex);
137                                     nIndex = 0;
138                                     sInterval = sInterval.getToken(0,')',nIndex);
139                                     m_xGroup->setGroupInterval(sInterval.toInt32());
140                                 }
141                                 else if ( sFormula == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("rpt:YEAR")))
142                                     nGroupOn = report::GroupOn::YEAR;
143 	                            else if ( sFormula == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("rpt:MONTH")))
144                                 {
145 	                                nGroupOn = report::GroupOn::MONTH;
146                                 }
147                                 else if ( sCompleteFormula.matchIgnoreAsciiCase(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("rpt:INT((MONTH")),0)
148                                        && sCompleteFormula.endsWithIgnoreAsciiCaseAsciiL("-1)/3)+1",8) )
149                                 {
150                                     nGroupOn = report::GroupOn::QUARTAL;
151                                 }
152 	                            else if ( sFormula ==::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("rpt:WEEK")))
153 	                                nGroupOn = report::GroupOn::WEEK;
154 	                            else if ( sFormula ==::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("rpt:DAY")))
155 	                                nGroupOn = report::GroupOn::DAY;
156 	                            else if ( sFormula ==::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("rpt:HOUR")))
157 	                                nGroupOn = report::GroupOn::HOUR;
158 	                            else if ( sFormula ==::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("rpt:MINUTE")))
159 	                                nGroupOn = report::GroupOn::MINUTE;
160                                 else if ( sFormula ==::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("rpt:INT")))
161                                 {
162                                     nGroupOn = report::GroupOn::INTERVAL;
163                                     _rImport.removeFunction(sExpression);
164                                     sExpression = sExpression.copy(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("INT_count_")).getLength());
165 
166                                     nIndex = 0;
167                                     ::rtl::OUString sInterval = sCompleteFormula.getToken(1,'/',nIndex);
168                                     nIndex = 0;
169                                     sInterval = sInterval.getToken(0,')',nIndex);
170                                     m_xGroup->setGroupInterval(sInterval.toInt32());
171                                 }
172 
173                                 m_xGroup->setGroupOn(nGroupOn);
174 
175                                 _rImport.removeFunction(sValue);
176                                 sValue = sExpression;
177                             }
178                             m_xGroup->setExpression(sValue);
179                         }
180                     }
181 					break;
182 				case XML_TOK_GROUP_KEEP_TOGETHER:
183 					m_xGroup->setKeepTogether(lcl_getKeepTogetherOption(sValue));
184 					break;
185                 default:
186                     break;
187 			}
188 		}
189 		catch(const Exception&)
190 		{
191 			OSL_ENSURE(0,"Exception catched while putting group props!");
192 		}
193 	}
194 }
195 // -----------------------------------------------------------------------------
196 
~OXMLGroup()197 OXMLGroup::~OXMLGroup()
198 {
199 
200     DBG_DTOR( rpt_OXMLGroup,NULL);
201 }
202 // -----------------------------------------------------------------------------
CreateChildContext(sal_uInt16 nPrefix,const::rtl::OUString & rLocalName,const Reference<XAttributeList> & xAttrList)203 SvXMLImportContext* OXMLGroup::CreateChildContext(
204 		sal_uInt16 nPrefix,
205         const ::rtl::OUString& rLocalName,
206 		const Reference< XAttributeList > & xAttrList )
207 {
208 	SvXMLImportContext *pContext = 0;
209     ORptFilter& rImport = GetOwnImport();
210 	const SvXMLTokenMap&	rTokenMap	= rImport.GetGroupElemTokenMap();
211 
212 	switch( rTokenMap.Get( nPrefix, rLocalName ) )
213 	{
214         case XML_TOK_GROUP_FUNCTION:
215 			{
216 				rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP );
217 				pContext = new OXMLFunction( rImport, nPrefix, rLocalName,xAttrList,m_xGroup.get());
218 			}
219 			break;
220 		case XML_TOK_GROUP_HEADER:
221 			{
222 				rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP );
223 				m_xGroup->setHeaderOn(sal_True);
224 				pContext = new OXMLSection( rImport, nPrefix, rLocalName,xAttrList,m_xGroup->getHeader());
225 			}
226 			break;
227         case XML_TOK_GROUP_GROUP:
228 			rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP );
229 			pContext = new OXMLGroup( rImport, nPrefix, rLocalName,xAttrList);
230 			break;
231 		case XML_TOK_GROUP_DETAIL:
232 			{
233 				rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP );
234 				Reference<XReportDefinition> m_xComponent = rImport.getReportDefinition();
235 				pContext = new OXMLSection( rImport, nPrefix, rLocalName,xAttrList ,m_xComponent->getDetail());
236 			}
237 			break;
238 
239 		case XML_TOK_GROUP_FOOTER:
240 			{
241 				rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP );
242 				m_xGroup->setFooterOn(sal_True);
243 				pContext = new OXMLSection( rImport, nPrefix, rLocalName,xAttrList,m_xGroup->getFooter());
244 			}
245 			break;
246         default:
247             break;
248 	}
249 
250 	if( !pContext )
251 		pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
252 
253 	return pContext;
254 }
255 // -----------------------------------------------------------------------------
GetOwnImport()256 ORptFilter& OXMLGroup::GetOwnImport()
257 {
258 	return static_cast<ORptFilter&>(GetImport());
259 }
260 // -----------------------------------------------------------------------------
EndElement()261 void OXMLGroup::EndElement()
262 {
263 	try
264 	{
265         // the group elements end in the reverse order
266 		m_xGroups->insertByIndex(0,uno::makeAny(m_xGroup));
267 	}catch(uno::Exception&)
268 	{
269 		OSL_ENSURE(0,"Exception catched!");
270 	}
271 }
272 // -----------------------------------------------------------------------------
273 //----------------------------------------------------------------------------
274 } // namespace rptxml
275 // -----------------------------------------------------------------------------
276