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
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26
27 #include "dpdimsave.hxx"
28 #include "dpgroup.hxx"
29 #include "dpobject.hxx"
30 #include "document.hxx"
31
32 #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
33
34 #include <svl/zforlist.hxx>
35 #include <tools/debug.hxx>
36 #include <rtl/math.hxx>
37 #include <algorithm>
38
39 #include "global.hxx"
40 #include "scresid.hxx"
41 #include "globstr.hrc"
42
43 // ============================================================================
44
ScDPSaveGroupItem(const String & rName)45 ScDPSaveGroupItem::ScDPSaveGroupItem( const String& rName ) :
46 aGroupName( rName )
47 {
48 }
49
~ScDPSaveGroupItem()50 ScDPSaveGroupItem::~ScDPSaveGroupItem()
51 {
52 }
53
AddElement(const String & rName)54 void ScDPSaveGroupItem::AddElement( const String& rName )
55 {
56 aElements.push_back( rName );
57 }
58
AddElementsFromGroup(const ScDPSaveGroupItem & rGroup)59 void ScDPSaveGroupItem::AddElementsFromGroup( const ScDPSaveGroupItem& rGroup )
60 {
61 // add all elements of the other group (used for nested grouping)
62
63 for ( std::vector<String>::const_iterator aIter(rGroup.aElements.begin());
64 aIter != rGroup.aElements.end(); aIter++ )
65 aElements.push_back( *aIter );
66 }
67
RemoveElement(const String & rName)68 bool ScDPSaveGroupItem::RemoveElement( const String& rName )
69 {
70 for ( std::vector<String>::iterator aIter(aElements.begin()); aIter != aElements.end(); aIter++ )
71 if ( *aIter == rName ) //! ignore case
72 {
73 aElements.erase( aIter ); // found -> remove
74 return true; // don't have to look further
75 }
76
77 return false; // not found
78 }
79
IsEmpty() const80 bool ScDPSaveGroupItem::IsEmpty() const
81 {
82 return aElements.empty();
83 }
84
GetElementCount() const85 size_t ScDPSaveGroupItem::GetElementCount() const
86 {
87 return aElements.size();
88 }
89
GetElementByIndex(size_t nIndex) const90 const String* ScDPSaveGroupItem::GetElementByIndex( size_t nIndex ) const
91 {
92 return (nIndex < aElements.size()) ? &aElements[ nIndex ] : 0;
93 }
94
Rename(const String & rNewName)95 void ScDPSaveGroupItem::Rename( const String& rNewName )
96 {
97 aGroupName = rNewName;
98 }
99
RemoveElementsFromGroups(ScDPSaveGroupDimension & rDimension) const100 void ScDPSaveGroupItem::RemoveElementsFromGroups( ScDPSaveGroupDimension& rDimension ) const
101 {
102 // remove this group's elements from their groups in rDimension
103 // (rDimension must be a different dimension from the one which contains this)
104
105 for ( std::vector<String>::const_iterator aIter(aElements.begin()); aIter != aElements.end(); aIter++ )
106 rDimension.RemoveFromGroups( *aIter );
107 }
108
AddToData(ScDPGroupDimension & rDataDim,SvNumberFormatter * pFormatter) const109 void ScDPSaveGroupItem::AddToData( ScDPGroupDimension& rDataDim, SvNumberFormatter* pFormatter ) const
110 {
111 ScDPGroupItem aGroup( aGroupName );
112 ScDPItemData aData;
113
114 for ( std::vector<String>::const_iterator aIter(aElements.begin()); aIter != aElements.end(); aIter++ )
115 {
116 sal_uInt32 nFormat = 0; //! ...
117 double fValue;
118 if ( pFormatter->IsNumberFormat( *aIter, nFormat, fValue ) )
119 aData = ScDPItemData( *aIter, fValue, sal_True );
120 else
121 aData.SetString( *aIter );
122
123 aGroup.AddElement( aData );
124 //! for numeric data, look at source members?
125 }
126
127 rDataDim.AddItem( aGroup );
128 }
129
130 // ============================================================================
131
ScDPSaveGroupDimension(const String & rSource,const String & rName)132 ScDPSaveGroupDimension::ScDPSaveGroupDimension( const String& rSource, const String& rName ) :
133 aSourceDim( rSource ),
134 aGroupDimName( rName ),
135 nDatePart( 0 )
136 {
137 }
138
ScDPSaveGroupDimension(const String & rSource,const String & rName,const ScDPNumGroupInfo & rDateInfo,sal_Int32 nPart)139 ScDPSaveGroupDimension::ScDPSaveGroupDimension( const String& rSource, const String& rName, const ScDPNumGroupInfo& rDateInfo, sal_Int32 nPart ) :
140 aSourceDim( rSource ),
141 aGroupDimName( rName ),
142 aDateInfo( rDateInfo ),
143 nDatePart( nPart )
144 {
145 }
146
~ScDPSaveGroupDimension()147 ScDPSaveGroupDimension::~ScDPSaveGroupDimension()
148 {
149 }
150
SetDateInfo(const ScDPNumGroupInfo & rInfo,sal_Int32 nPart)151 void ScDPSaveGroupDimension::SetDateInfo( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart )
152 {
153 aDateInfo = rInfo;
154 nDatePart = nPart;
155 }
156
AddGroupItem(const ScDPSaveGroupItem & rItem)157 void ScDPSaveGroupDimension::AddGroupItem( const ScDPSaveGroupItem& rItem )
158 {
159 aGroups.push_back( rItem );
160 }
161
CreateGroupName(const String & rPrefix)162 String ScDPSaveGroupDimension::CreateGroupName( const String& rPrefix )
163 {
164 // create a name for a new group, using "Group1", "Group2" etc. (translated prefix in rPrefix)
165
166 //! look in all dimensions, to avoid clashes with automatic groups (=name of base element)?
167 //! (only dimensions for the same base)
168
169 sal_Int32 nAdd = 1; // first try is "Group1"
170 const sal_Int32 nMaxAdd = nAdd + aGroups.size(); // limit the loop
171 while ( nAdd <= nMaxAdd )
172 {
173 String aGroupName( rPrefix );
174 aGroupName.Append( String::CreateFromInt32( nAdd ) );
175 bool bExists = false;
176
177 // look for existing groups
178 for ( ScDPSaveGroupItemVec::const_iterator aIter(aGroups.begin());
179 aIter != aGroups.end() && !bExists; aIter++ )
180 if ( aIter->GetGroupName() == aGroupName ) //! ignore case
181 bExists = true;
182
183 if ( !bExists )
184 return aGroupName; // found a new name
185
186 ++nAdd; // continue with higher number
187 }
188
189 DBG_ERROR("CreateGroupName: no valid name found");
190 return EMPTY_STRING;
191 }
192
GetNamedGroup(const String & rGroupName) const193 const ScDPSaveGroupItem* ScDPSaveGroupDimension::GetNamedGroup( const String& rGroupName ) const
194 {
195 return const_cast< ScDPSaveGroupDimension* >( this )->GetNamedGroupAcc( rGroupName );
196 }
197
GetNamedGroupAcc(const String & rGroupName)198 ScDPSaveGroupItem* ScDPSaveGroupDimension::GetNamedGroupAcc( const String& rGroupName )
199 {
200 for ( ScDPSaveGroupItemVec::iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
201 if ( aIter->GetGroupName() == rGroupName ) //! ignore case
202 return &*aIter;
203
204 return NULL; // none found
205 }
206
GetGroupCount() const207 long ScDPSaveGroupDimension::GetGroupCount() const
208 {
209 return aGroups.size();
210 }
211
GetGroupByIndex(long nIndex) const212 const ScDPSaveGroupItem* ScDPSaveGroupDimension::GetGroupByIndex( long nIndex ) const
213 {
214 return const_cast< ScDPSaveGroupDimension* >( this )->GetGroupAccByIndex( nIndex );
215 }
216
GetGroupAccByIndex(long nIndex)217 ScDPSaveGroupItem* ScDPSaveGroupDimension::GetGroupAccByIndex( long nIndex )
218 {
219 return &aGroups[nIndex];
220 }
221
RemoveFromGroups(const String & rItemName)222 void ScDPSaveGroupDimension::RemoveFromGroups( const String& rItemName )
223 {
224 // if the item is in any group, remove it from the group,
225 // also remove the group if it is empty afterwards
226
227 for ( ScDPSaveGroupItemVec::iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
228 if ( aIter->RemoveElement( rItemName ) )
229 {
230 if ( aIter->IsEmpty() ) // removed last item from the group?
231 aGroups.erase( aIter ); // then remove the group
232
233 return; // don't have to look further
234 }
235 }
236
RemoveGroup(const String & rGroupName)237 void ScDPSaveGroupDimension::RemoveGroup( const String& rGroupName )
238 {
239 for ( ScDPSaveGroupItemVec::iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
240 if ( aIter->GetGroupName() == rGroupName ) //! ignore case
241 {
242 aGroups.erase( aIter );
243 return; // don't have to look further
244 }
245 }
246
IsEmpty() const247 bool ScDPSaveGroupDimension::IsEmpty() const
248 {
249 return aGroups.empty();
250 }
251
HasOnlyHidden(const ScStrCollection & rVisible)252 bool ScDPSaveGroupDimension::HasOnlyHidden( const ScStrCollection& rVisible )
253 {
254 // check if there are only groups that don't appear in the list of visible names
255
256 bool bAllHidden = true;
257 for ( ScDPSaveGroupItemVec::const_iterator aIter(aGroups.begin()); aIter != aGroups.end() && bAllHidden; aIter++ )
258 {
259 StrData aSearch( aIter->GetGroupName() );
260 sal_uInt16 nCollIndex;
261 if ( rVisible.Search( &aSearch, nCollIndex ) )
262 bAllHidden = false; // found one that is visible
263 }
264 return bAllHidden;
265 }
266
Rename(const String & rNewName)267 void ScDPSaveGroupDimension::Rename( const String& rNewName )
268 {
269 aGroupDimName = rNewName;
270 }
271
AddToData(ScDPGroupTableData & rData) const272 void ScDPSaveGroupDimension::AddToData( ScDPGroupTableData& rData ) const
273 {
274 long nSourceIndex = rData.GetDimensionIndex( aSourceDim );
275 if ( nSourceIndex >= 0 )
276 {
277 ScDPGroupDimension aDim( nSourceIndex, aGroupDimName );
278 if ( nDatePart )
279 {
280 // date grouping
281
282 aDim.MakeDateHelper( aDateInfo, nDatePart );
283 }
284 else
285 {
286 // normal (manual) grouping
287
288 SvNumberFormatter* pFormatter = rData.GetDocument()->GetFormatTable();
289
290 for ( ScDPSaveGroupItemVec::const_iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
291 aIter->AddToData( aDim, pFormatter );
292 }
293
294 rData.AddGroupDimension( aDim );
295 }
296 }
297
298 // ============================================================================
299
ScDPSaveNumGroupDimension(const String & rName,const ScDPNumGroupInfo & rInfo)300 ScDPSaveNumGroupDimension::ScDPSaveNumGroupDimension( const String& rName, const ScDPNumGroupInfo& rInfo ) :
301 aDimensionName( rName ),
302 aGroupInfo( rInfo ),
303 nDatePart( 0 )
304 {
305 }
306
ScDPSaveNumGroupDimension(const String & rName,const ScDPNumGroupInfo & rDateInfo,sal_Int32 nPart)307 ScDPSaveNumGroupDimension::ScDPSaveNumGroupDimension( const String& rName, const ScDPNumGroupInfo& rDateInfo, sal_Int32 nPart ) :
308 aDimensionName( rName ),
309 aDateInfo( rDateInfo ),
310 nDatePart( nPart )
311 {
312 }
313
~ScDPSaveNumGroupDimension()314 ScDPSaveNumGroupDimension::~ScDPSaveNumGroupDimension()
315 {
316 }
317
AddToData(ScDPGroupTableData & rData) const318 void ScDPSaveNumGroupDimension::AddToData( ScDPGroupTableData& rData ) const
319 {
320 long nSource = rData.GetDimensionIndex( aDimensionName );
321 if ( nSource >= 0 )
322 {
323 ScDPNumGroupDimension aDim( aGroupInfo ); // aGroupInfo: value grouping
324 if ( nDatePart )
325 aDim.MakeDateHelper( aDateInfo, nDatePart ); // date grouping
326
327 rData.SetNumGroupDimension( nSource, aDim );
328 }
329 }
330
SetGroupInfo(const ScDPNumGroupInfo & rNew)331 void ScDPSaveNumGroupDimension::SetGroupInfo( const ScDPNumGroupInfo& rNew )
332 {
333 aGroupInfo = rNew;
334 }
335
SetDateInfo(const ScDPNumGroupInfo & rInfo,sal_Int32 nPart)336 void ScDPSaveNumGroupDimension::SetDateInfo( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart )
337 {
338 aDateInfo = rInfo;
339 nDatePart = nPart;
340 }
341
342 // ============================================================================
343
344 namespace {
345
346 struct ScDPSaveGroupDimNameFunc
347 {
348 String maDimName;
ScDPSaveGroupDimNameFunc__anonfb0798da0111::ScDPSaveGroupDimNameFunc349 inline explicit ScDPSaveGroupDimNameFunc( const String& rDimName ) : maDimName( rDimName ) {}
operator ()__anonfb0798da0111::ScDPSaveGroupDimNameFunc350 inline bool operator()( const ScDPSaveGroupDimension& rGroupDim ) const { return rGroupDim.GetGroupDimName() == maDimName; }
351 };
352
353 struct ScDPSaveGroupSourceNameFunc
354 {
355 String maSrcDimName;
ScDPSaveGroupSourceNameFunc__anonfb0798da0111::ScDPSaveGroupSourceNameFunc356 inline explicit ScDPSaveGroupSourceNameFunc( const String& rSrcDimName ) : maSrcDimName( rSrcDimName ) {}
operator ()__anonfb0798da0111::ScDPSaveGroupSourceNameFunc357 inline bool operator()( const ScDPSaveGroupDimension& rGroupDim ) const { return rGroupDim.GetSourceDimName() == maSrcDimName; }
358 };
359
360 } // namespace
361
362 // ----------------------------------------------------------------------------
363
ScDPDimensionSaveData()364 ScDPDimensionSaveData::ScDPDimensionSaveData()
365 {
366 }
367
~ScDPDimensionSaveData()368 ScDPDimensionSaveData::~ScDPDimensionSaveData()
369 {
370 }
371
operator ==(const ScDPDimensionSaveData &) const372 bool ScDPDimensionSaveData::operator==( const ScDPDimensionSaveData& ) const
373 {
374 return false;
375 }
376
AddGroupDimension(const ScDPSaveGroupDimension & rGroupDim)377 void ScDPDimensionSaveData::AddGroupDimension( const ScDPSaveGroupDimension& rGroupDim )
378 {
379 DBG_ASSERT( ::std::find_if( maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupDimNameFunc( rGroupDim.GetGroupDimName() ) ) == maGroupDims.end(),
380 "ScDPDimensionSaveData::AddGroupDimension - group dimension exists already" );
381 // ReplaceGroupDimension() adds new or replaces existing
382 ReplaceGroupDimension( rGroupDim );
383 }
384
ReplaceGroupDimension(const ScDPSaveGroupDimension & rGroupDim)385 void ScDPDimensionSaveData::ReplaceGroupDimension( const ScDPSaveGroupDimension& rGroupDim )
386 {
387 ScDPSaveGroupDimVec::iterator aIt = ::std::find_if(
388 maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupDimNameFunc( rGroupDim.GetGroupDimName() ) );
389 if( aIt == maGroupDims.end() )
390 maGroupDims.push_back( rGroupDim );
391 else
392 *aIt = rGroupDim;
393 }
394
RemoveGroupDimension(const String & rGroupDimName)395 void ScDPDimensionSaveData::RemoveGroupDimension( const String& rGroupDimName )
396 {
397 ScDPSaveGroupDimVec::iterator aIt = ::std::find_if(
398 maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupDimNameFunc( rGroupDimName ) );
399 if( aIt != maGroupDims.end() )
400 maGroupDims.erase( aIt );
401 }
402
AddNumGroupDimension(const ScDPSaveNumGroupDimension & rGroupDim)403 void ScDPDimensionSaveData::AddNumGroupDimension( const ScDPSaveNumGroupDimension& rGroupDim )
404 {
405 DBG_ASSERT( maNumGroupDims.count( rGroupDim.GetDimensionName() ) == 0,
406 "ScDPDimensionSaveData::AddNumGroupDimension - numeric group dimension exists already" );
407 // ReplaceNumGroupDimension() adds new or replaces existing
408 ReplaceNumGroupDimension( rGroupDim );
409 }
410
ReplaceNumGroupDimension(const ScDPSaveNumGroupDimension & rGroupDim)411 void ScDPDimensionSaveData::ReplaceNumGroupDimension( const ScDPSaveNumGroupDimension& rGroupDim )
412 {
413 ScDPSaveNumGroupDimMap::iterator aIt = maNumGroupDims.find( rGroupDim.GetDimensionName() );
414 if( aIt == maNumGroupDims.end() )
415 maNumGroupDims.insert( ScDPSaveNumGroupDimMap::value_type( rGroupDim.GetDimensionName(), rGroupDim ) );
416 else
417 aIt->second = rGroupDim;
418 }
419
RemoveNumGroupDimension(const String & rGroupDimName)420 void ScDPDimensionSaveData::RemoveNumGroupDimension( const String& rGroupDimName )
421 {
422 maNumGroupDims.erase( rGroupDimName );
423 }
424
WriteToData(ScDPGroupTableData & rData) const425 void ScDPDimensionSaveData::WriteToData( ScDPGroupTableData& rData ) const
426 {
427 // rData is assumed to be empty
428 // AddToData also handles date grouping
429
430 for( ScDPSaveGroupDimVec::const_iterator aIt = maGroupDims.begin(), aEnd = maGroupDims.end(); aIt != aEnd; ++aIt )
431 aIt->AddToData( rData );
432
433 for( ScDPSaveNumGroupDimMap::const_iterator aIt = maNumGroupDims.begin(), aEnd = maNumGroupDims.end(); aIt != aEnd; ++aIt )
434 aIt->second.AddToData( rData );
435 }
436
GetGroupDimForBase(const String & rBaseDimName) const437 const ScDPSaveGroupDimension* ScDPDimensionSaveData::GetGroupDimForBase( const String& rBaseDimName ) const
438 {
439 return const_cast< ScDPDimensionSaveData* >( this )->GetGroupDimAccForBase( rBaseDimName );
440 }
441
GetNamedGroupDim(const String & rGroupDimName) const442 const ScDPSaveGroupDimension* ScDPDimensionSaveData::GetNamedGroupDim( const String& rGroupDimName ) const
443 {
444 return const_cast< ScDPDimensionSaveData* >( this )->GetNamedGroupDimAcc( rGroupDimName );
445 }
446
GetFirstNamedGroupDim(const String & rBaseDimName) const447 const ScDPSaveGroupDimension* ScDPDimensionSaveData::GetFirstNamedGroupDim( const String& rBaseDimName ) const
448 {
449 return const_cast< ScDPDimensionSaveData* >( this )->GetFirstNamedGroupDimAcc( rBaseDimName );
450 }
451
GetNextNamedGroupDim(const String & rGroupDimName) const452 const ScDPSaveGroupDimension* ScDPDimensionSaveData::GetNextNamedGroupDim( const String& rGroupDimName ) const
453 {
454 return const_cast< ScDPDimensionSaveData* >( this )->GetNextNamedGroupDimAcc( rGroupDimName );
455 }
456
GetNumGroupDim(const String & rGroupDimName) const457 const ScDPSaveNumGroupDimension* ScDPDimensionSaveData::GetNumGroupDim( const String& rGroupDimName ) const
458 {
459 return const_cast< ScDPDimensionSaveData* >( this )->GetNumGroupDimAcc( rGroupDimName );
460 }
461
GetGroupDimAccForBase(const String & rBaseDimName)462 ScDPSaveGroupDimension* ScDPDimensionSaveData::GetGroupDimAccForBase( const String& rBaseDimName )
463 {
464 ScDPSaveGroupDimension* pGroupDim = GetFirstNamedGroupDimAcc( rBaseDimName );
465 return pGroupDim ? pGroupDim : GetNextNamedGroupDimAcc( rBaseDimName );
466 }
467
GetNamedGroupDimAcc(const String & rGroupDimName)468 ScDPSaveGroupDimension* ScDPDimensionSaveData::GetNamedGroupDimAcc( const String& rGroupDimName )
469 {
470 ScDPSaveGroupDimVec::iterator aIt = ::std::find_if(
471 maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupDimNameFunc( rGroupDimName ) );
472 return (aIt == maGroupDims.end()) ? 0 : &*aIt;
473 }
474
GetFirstNamedGroupDimAcc(const String & rBaseDimName)475 ScDPSaveGroupDimension* ScDPDimensionSaveData::GetFirstNamedGroupDimAcc( const String& rBaseDimName )
476 {
477 ScDPSaveGroupDimVec::iterator aIt = ::std::find_if(
478 maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupSourceNameFunc( rBaseDimName ) );
479 return (aIt == maGroupDims.end()) ? 0 : &*aIt;
480 }
481
GetNextNamedGroupDimAcc(const String & rGroupDimName)482 ScDPSaveGroupDimension* ScDPDimensionSaveData::GetNextNamedGroupDimAcc( const String& rGroupDimName )
483 {
484 // find the group dimension with the passed name
485 ScDPSaveGroupDimVec::iterator aIt = ::std::find_if(
486 maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupDimNameFunc( rGroupDimName ) );
487 // find next group dimension based on the same source dimension name
488 if( aIt != maGroupDims.end() )
489 aIt = ::std::find_if( aIt + 1, maGroupDims.end(), ScDPSaveGroupSourceNameFunc( aIt->GetSourceDimName() ) );
490 return (aIt == maGroupDims.end()) ? 0 : &*aIt;
491 }
492
GetNumGroupDimAcc(const String & rGroupDimName)493 ScDPSaveNumGroupDimension* ScDPDimensionSaveData::GetNumGroupDimAcc( const String& rGroupDimName )
494 {
495 ScDPSaveNumGroupDimMap::iterator aIt = maNumGroupDims.find( rGroupDimName );
496 return (aIt == maNumGroupDims.end()) ? 0 : &aIt->second;
497 }
498
HasGroupDimensions() const499 bool ScDPDimensionSaveData::HasGroupDimensions() const
500 {
501 return !maGroupDims.empty() || !maNumGroupDims.empty();
502 }
503
CollectDateParts(const String & rBaseDimName) const504 sal_Int32 ScDPDimensionSaveData::CollectDateParts( const String& rBaseDimName ) const
505 {
506 sal_Int32 nParts = 0;
507 // start with part of numeric group
508 if( const ScDPSaveNumGroupDimension* pNumDim = GetNumGroupDim( rBaseDimName ) )
509 nParts |= pNumDim->GetDatePart();
510 // collect parts from all matching group dimensions
511 for( const ScDPSaveGroupDimension* pGroupDim = GetFirstNamedGroupDim( rBaseDimName ); pGroupDim; pGroupDim = GetNextNamedGroupDim( pGroupDim->GetGroupDimName() ) )
512 nParts |= pGroupDim->GetDatePart();
513
514 return nParts;
515 }
516
CreateGroupDimName(const String & rSourceName,const ScDPObject & rObject,bool bAllowSource,const std::vector<String> * pDeletedNames)517 String ScDPDimensionSaveData::CreateGroupDimName( const String& rSourceName,
518 const ScDPObject& rObject, bool bAllowSource,
519 const std::vector<String>* pDeletedNames )
520 {
521 // create a name for the new dimension by appending a number to the original
522 // dimension's name
523
524 bool bUseSource = bAllowSource; // if set, try the unchanged original name first
525
526 sal_Int32 nAdd = 2; // first try is "Name2"
527 const sal_Int32 nMaxAdd = 1000; // limit the loop
528 while ( nAdd <= nMaxAdd )
529 {
530 String aDimName( rSourceName );
531 if ( !bUseSource )
532 aDimName.Append( String::CreateFromInt32( nAdd ) );
533 bool bExists = false;
534
535 // look for existing group dimensions
536 for( ScDPSaveGroupDimVec::const_iterator aIt = maGroupDims.begin(), aEnd = maGroupDims.end(); (aIt != aEnd) && !bExists; ++aIt )
537 if( aIt->GetGroupDimName() == aDimName ) //! ignore case
538 bExists = true;
539
540 // look for base dimensions that happen to have that name
541 if ( !bExists && rObject.IsDimNameInUse( aDimName ) )
542 {
543 if ( pDeletedNames &&
544 std::find( pDeletedNames->begin(), pDeletedNames->end(), aDimName ) != pDeletedNames->end() )
545 {
546 // allow the name anyway if the name is in pDeletedNames
547 }
548 else
549 bExists = true;
550 }
551
552 if ( !bExists )
553 return aDimName; // found a new name
554
555 if ( bUseSource )
556 bUseSource = false;
557 else
558 ++nAdd; // continue with higher number
559 }
560 DBG_ERROR("CreateGroupDimName: no valid name found");
561 return EMPTY_STRING;
562 }
563
564 namespace {
565
566 static const sal_uInt16 nDatePartIds[] =
567 {
568 STR_DPFIELD_GROUP_BY_SECONDS,
569 STR_DPFIELD_GROUP_BY_MINUTES,
570 STR_DPFIELD_GROUP_BY_HOURS,
571 STR_DPFIELD_GROUP_BY_DAYS,
572 STR_DPFIELD_GROUP_BY_MONTHS,
573 STR_DPFIELD_GROUP_BY_QUARTERS,
574 STR_DPFIELD_GROUP_BY_YEARS
575 };
576
577 }
CreateDateGroupDimName(sal_Int32 nDatePart,const ScDPObject & rObject,bool bAllowSource,const::std::vector<String> * pDeletedNames)578 String ScDPDimensionSaveData::CreateDateGroupDimName( sal_Int32 nDatePart, const ScDPObject& rObject, bool bAllowSource, const ::std::vector< String >* pDeletedNames )
579 {
580 using namespace ::com::sun::star::sheet::DataPilotFieldGroupBy;
581 String aPartName;
582 switch( nDatePart )
583 {
584 case SECONDS: aPartName = ScGlobal::GetRscString( nDatePartIds[0] ); break;
585 case MINUTES: aPartName = ScGlobal::GetRscString( nDatePartIds[1] ); break;
586 case HOURS: aPartName = ScGlobal::GetRscString( nDatePartIds[2] ); break;
587 case DAYS: aPartName = ScGlobal::GetRscString( nDatePartIds[3] ); break;
588 case MONTHS: aPartName = ScGlobal::GetRscString( nDatePartIds[4] ); break;
589 case QUARTERS: aPartName = ScGlobal::GetRscString( nDatePartIds[5] ); break;
590 case YEARS: aPartName = ScGlobal::GetRscString( nDatePartIds[6] ); break;
591 }
592 DBG_ASSERT( aPartName.Len() > 0, "ScDPDimensionSaveData::CreateDateGroupDimName - invalid date part" );
593 return CreateGroupDimName( aPartName, rObject, bAllowSource, pDeletedNames );
594 }
595
596 // ============================================================================
597
598