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