bump product version to 4.1.6.2
[LibreOffice.git] / sc / source / ui / dbgui / pvfundlg.cxx
blobaf369f47a287594a887b3d34471ccedeb8817098
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 #undef SC_DLLIMPLEMENTATION
22 #include "pvfundlg.hxx"
24 #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
25 #include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
26 #include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
27 #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
28 #include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
30 #include <tools/resary.hxx>
31 #include <vcl/msgbox.hxx>
33 #include "scresid.hxx"
34 #include "dpobject.hxx"
35 #include "dpsave.hxx"
36 #include "pvfundlg.hrc"
37 #include "globstr.hrc"
38 #include "dputil.hxx"
40 #include <vector>
42 // ============================================================================
44 using namespace ::com::sun::star::sheet;
46 using ::com::sun::star::uno::Sequence;
47 using ::std::vector;
49 // ============================================================================
51 namespace {
53 /** Appends all strings from the Sequence to the list box.
55 Empty strings are replaced by a localized "(empty)" entry and inserted at
56 the specified position.
58 @return true = The passed string list contains an empty string entry.
60 template< typename ListBoxType >
61 bool lclFillListBox( ListBoxType& rLBox, const Sequence< OUString >& rStrings, sal_uInt16 nEmptyPos = LISTBOX_APPEND )
63 bool bEmpty = false;
64 const OUString* pStr = rStrings.getConstArray();
65 if( pStr )
67 for( const OUString* pEnd = pStr + rStrings.getLength(); pStr != pEnd; ++pStr )
69 if( !pStr->isEmpty() )
70 rLBox.InsertEntry( *pStr );
71 else
73 rLBox.InsertEntry( ScGlobal::GetRscString( STR_EMPTYDATA ), nEmptyPos );
74 bEmpty = true;
78 return bEmpty;
81 template< typename ListBoxType >
82 bool lclFillListBox( ListBoxType& rLBox, const vector<ScDPLabelData::Member>& rMembers, sal_uInt16 nEmptyPos = LISTBOX_APPEND )
84 bool bEmpty = false;
85 vector<ScDPLabelData::Member>::const_iterator itr = rMembers.begin(), itrEnd = rMembers.end();
86 for (; itr != itrEnd; ++itr)
88 OUString aName = itr->getDisplayName();
89 if (!aName.isEmpty())
90 rLBox.InsertEntry(aName);
91 else
93 rLBox.InsertEntry(ScGlobal::GetRscString(STR_EMPTYDATA), nEmptyPos);
94 bEmpty = true;
97 return bEmpty;
100 /** This table represents the order of the strings in the resource string array. */
101 static const sal_uInt16 spnFunctions[] =
103 PIVOT_FUNC_SUM,
104 PIVOT_FUNC_COUNT,
105 PIVOT_FUNC_AVERAGE,
106 PIVOT_FUNC_MAX,
107 PIVOT_FUNC_MIN,
108 PIVOT_FUNC_PRODUCT,
109 PIVOT_FUNC_COUNT_NUM,
110 PIVOT_FUNC_STD_DEV,
111 PIVOT_FUNC_STD_DEVP,
112 PIVOT_FUNC_STD_VAR,
113 PIVOT_FUNC_STD_VARP
116 const sal_uInt16 SC_BASEITEM_PREV_POS = 0;
117 const sal_uInt16 SC_BASEITEM_NEXT_POS = 1;
118 const sal_uInt16 SC_BASEITEM_USER_POS = 2;
120 const sal_uInt16 SC_SORTNAME_POS = 0;
121 const sal_uInt16 SC_SORTDATA_POS = 1;
123 const long SC_SHOW_DEFAULT = 10;
125 static const ScDPListBoxWrapper::MapEntryType spRefTypeMap[] =
127 { 0, DataPilotFieldReferenceType::NONE },
128 { 1, DataPilotFieldReferenceType::ITEM_DIFFERENCE },
129 { 2, DataPilotFieldReferenceType::ITEM_PERCENTAGE },
130 { 3, DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE },
131 { 4, DataPilotFieldReferenceType::RUNNING_TOTAL },
132 { 5, DataPilotFieldReferenceType::ROW_PERCENTAGE },
133 { 6, DataPilotFieldReferenceType::COLUMN_PERCENTAGE },
134 { 7, DataPilotFieldReferenceType::TOTAL_PERCENTAGE },
135 { 8, DataPilotFieldReferenceType::INDEX },
136 { LISTBOX_ENTRY_NOTFOUND, DataPilotFieldReferenceType::NONE }
139 static const ScDPListBoxWrapper::MapEntryType spLayoutMap[] =
141 { 0, DataPilotFieldLayoutMode::TABULAR_LAYOUT },
142 { 1, DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP },
143 { 2, DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM },
144 { LISTBOX_ENTRY_NOTFOUND, DataPilotFieldLayoutMode::TABULAR_LAYOUT }
147 static const ScDPListBoxWrapper::MapEntryType spShowFromMap[] =
149 { 0, DataPilotFieldShowItemsMode::FROM_TOP },
150 { 1, DataPilotFieldShowItemsMode::FROM_BOTTOM },
151 { LISTBOX_ENTRY_NOTFOUND, DataPilotFieldShowItemsMode::FROM_TOP }
154 } // namespace
156 // ============================================================================
158 ScDPFunctionListBox::ScDPFunctionListBox( Window* pParent, const ResId& rResId ) :
159 MultiListBox( pParent, rResId )
161 FillFunctionNames();
164 void ScDPFunctionListBox::SetSelection( sal_uInt16 nFuncMask )
166 if( (nFuncMask == PIVOT_FUNC_NONE) || (nFuncMask == PIVOT_FUNC_AUTO) )
167 SetNoSelection();
168 else
169 for( sal_uInt16 nEntry = 0, nCount = GetEntryCount(); nEntry < nCount; ++nEntry )
170 SelectEntryPos( nEntry, (nFuncMask & spnFunctions[ nEntry ]) != 0 );
173 sal_uInt16 ScDPFunctionListBox::GetSelection() const
175 sal_uInt16 nFuncMask = PIVOT_FUNC_NONE;
176 for( sal_uInt16 nSel = 0, nCount = GetSelectEntryCount(); nSel < nCount; ++nSel )
177 nFuncMask |= spnFunctions[ GetSelectEntryPos( nSel ) ];
178 return nFuncMask;
181 void ScDPFunctionListBox::FillFunctionNames()
183 OSL_ENSURE( !GetEntryCount(), "ScDPMultiFuncListBox::FillFunctionNames - do not add texts to resource" );
184 Clear();
185 ResStringArray aArr( ScResId( SCSTR_DPFUNCLISTBOX ) );
186 for( sal_uInt16 nIndex = 0, nCount = sal::static_int_cast<sal_uInt16>(aArr.Count()); nIndex < nCount; ++nIndex )
187 InsertEntry( aArr.GetString( nIndex ) );
190 // ============================================================================
192 ScDPFunctionDlg::ScDPFunctionDlg(
193 Window* pParent, const ScDPLabelDataVector& rLabelVec,
194 const ScDPLabelData& rLabelData, const ScPivotFuncData& rFuncData ) :
195 ModalDialog ( pParent, ScResId( RID_SCDLG_DPDATAFIELD ) ),
196 maFlFunc ( this, ScResId( FL_FUNC ) ),
197 maLbFunc ( this, ScResId( LB_FUNC ) ),
198 maFtNameLabel ( this, ScResId( FT_NAMELABEL ) ),
199 maFtName ( this, ScResId( FT_NAME ) ),
200 maFlDisplay ( this, ScResId( FL_DISPLAY ) ),
201 maFtType ( this, ScResId( FT_TYPE ) ),
202 maLbType ( this, ScResId( LB_TYPE ) ),
203 maFtBaseField ( this, ScResId( FT_BASEFIELD ) ),
204 maLbBaseField ( this, ScResId( LB_BASEFIELD ) ),
205 maFtBaseItem ( this, ScResId( FT_BASEITEM ) ),
206 maLbBaseItem ( this, ScResId( LB_BASEITEM ) ),
207 maBtnOk ( this, ScResId( BTN_OK ) ),
208 maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
209 maBtnHelp ( this, ScResId( BTN_HELP ) ),
210 maBtnMore ( this, ScResId( BTN_MORE ) ),
211 maLbTypeWrp ( maLbType, spRefTypeMap ),
212 mrLabelVec ( rLabelVec ),
213 mbEmptyItem ( false )
215 FreeResource();
216 Init( rLabelData, rFuncData );
217 maLbFunc.EnableMultiSelection(false);
220 sal_uInt16 ScDPFunctionDlg::GetFuncMask() const
222 return maLbFunc.GetSelection();
225 DataPilotFieldReference ScDPFunctionDlg::GetFieldRef() const
227 DataPilotFieldReference aRef;
229 aRef.ReferenceType = maLbTypeWrp.GetControlValue();
230 aRef.ReferenceField = GetBaseFieldName(maLbBaseField.GetSelectEntry());
232 sal_uInt16 nBaseItemPos = maLbBaseItem.GetSelectEntryPos();
233 switch( nBaseItemPos )
235 case SC_BASEITEM_PREV_POS:
236 aRef.ReferenceItemType = DataPilotFieldReferenceItemType::PREVIOUS;
237 break;
238 case SC_BASEITEM_NEXT_POS:
239 aRef.ReferenceItemType = DataPilotFieldReferenceItemType::NEXT;
240 break;
241 default:
243 aRef.ReferenceItemType = DataPilotFieldReferenceItemType::NAMED;
244 if( !mbEmptyItem || (nBaseItemPos > SC_BASEITEM_USER_POS) )
245 aRef.ReferenceItemName = GetBaseItemName(maLbBaseItem.GetSelectEntry());
249 return aRef;
252 void ScDPFunctionDlg::Init( const ScDPLabelData& rLabelData, const ScPivotFuncData& rFuncData )
254 // list box
255 sal_uInt16 nFuncMask = (rFuncData.mnFuncMask == PIVOT_FUNC_NONE) ? PIVOT_FUNC_SUM : rFuncData.mnFuncMask;
256 maLbFunc.SetSelection( nFuncMask );
258 // field name
259 maFtName.SetText(rLabelData.getDisplayName());
261 // "More button" controls
262 maBtnMore.AddWindow( &maFlDisplay );
263 maBtnMore.AddWindow( &maFtType );
264 maBtnMore.AddWindow( &maLbType );
265 maBtnMore.AddWindow( &maFtBaseField );
266 maBtnMore.AddWindow( &maLbBaseField );
267 maBtnMore.AddWindow( &maFtBaseItem );
268 maBtnMore.AddWindow( &maLbBaseItem );
270 // handlers
271 maLbFunc.SetDoubleClickHdl( LINK( this, ScDPFunctionDlg, DblClickHdl ) );
272 maLbType.SetSelectHdl( LINK( this, ScDPFunctionDlg, SelectHdl ) );
273 maLbBaseField.SetSelectHdl( LINK( this, ScDPFunctionDlg, SelectHdl ) );
275 // base field list box
276 OUString aSelectedEntry;
277 for( ScDPLabelDataVector::const_iterator aIt = mrLabelVec.begin(), aEnd = mrLabelVec.end(); aIt != aEnd; ++aIt )
279 maLbBaseField.InsertEntry(aIt->getDisplayName());
280 maBaseFieldNameMap.insert(
281 NameMapType::value_type(aIt->getDisplayName(), aIt->maName));
282 if (aIt->maName == rFuncData.maFieldRef.ReferenceField)
283 aSelectedEntry = aIt->getDisplayName();
286 // base item list box
287 maLbBaseItem.SetSeparatorPos( SC_BASEITEM_USER_POS - 1 );
289 // select field reference type
290 maLbTypeWrp.SetControlValue( rFuncData.maFieldRef.ReferenceType );
291 SelectHdl( &maLbType ); // enables base field/item list boxes
293 // select base field
294 maLbBaseField.SelectEntry(aSelectedEntry);
295 if( maLbBaseField.GetSelectEntryPos() >= maLbBaseField.GetEntryCount() )
296 maLbBaseField.SelectEntryPos( 0 );
297 SelectHdl( &maLbBaseField ); // fills base item list, selects base item
299 // select base item
300 switch( rFuncData.maFieldRef.ReferenceItemType )
302 case DataPilotFieldReferenceItemType::PREVIOUS:
303 maLbBaseItem.SelectEntryPos( SC_BASEITEM_PREV_POS );
304 break;
305 case DataPilotFieldReferenceItemType::NEXT:
306 maLbBaseItem.SelectEntryPos( SC_BASEITEM_NEXT_POS );
307 break;
308 default:
310 if( mbEmptyItem && rFuncData.maFieldRef.ReferenceItemName.isEmpty() )
312 // select special "(empty)" entry added before other items
313 maLbBaseItem.SelectEntryPos( SC_BASEITEM_USER_POS );
315 else
317 sal_uInt16 nStartPos = mbEmptyItem ? (SC_BASEITEM_USER_POS + 1) : SC_BASEITEM_USER_POS;
318 sal_uInt16 nPos = FindBaseItemPos( rFuncData.maFieldRef.ReferenceItemName, nStartPos );
319 if( nPos >= maLbBaseItem.GetEntryCount() )
320 nPos = (maLbBaseItem.GetEntryCount() > SC_BASEITEM_USER_POS) ? SC_BASEITEM_USER_POS : SC_BASEITEM_PREV_POS;
321 maLbBaseItem.SelectEntryPos( nPos );
327 const OUString& ScDPFunctionDlg::GetBaseFieldName(const OUString& rLayoutName) const
329 NameMapType::const_iterator itr = maBaseFieldNameMap.find(rLayoutName);
330 return itr == maBaseFieldNameMap.end() ? rLayoutName : itr->second;
333 const OUString& ScDPFunctionDlg::GetBaseItemName(const OUString& rLayoutName) const
335 NameMapType::const_iterator itr = maBaseItemNameMap.find(rLayoutName);
336 return itr == maBaseItemNameMap.end() ? rLayoutName : itr->second;
339 sal_uInt16 ScDPFunctionDlg::FindBaseItemPos( const String& rEntry, sal_uInt16 nStartPos ) const
341 sal_uInt16 nPos = nStartPos;
342 bool bFound = false;
343 while (nPos < maLbBaseItem.GetEntryCount())
345 // translate the displayed field name back to its original field name.
346 const OUString& rName = GetBaseItemName(maLbBaseItem.GetEntry(nPos));
347 if (rName.equals(rEntry))
349 bFound = true;
350 break;
352 ++nPos;
354 return bFound ? nPos : LISTBOX_ENTRY_NOTFOUND;
357 IMPL_LINK( ScDPFunctionDlg, SelectHdl, ListBox*, pLBox )
359 if( pLBox == &maLbType )
361 bool bEnableField, bEnableItem;
362 switch( maLbTypeWrp.GetControlValue() )
364 case DataPilotFieldReferenceType::ITEM_DIFFERENCE:
365 case DataPilotFieldReferenceType::ITEM_PERCENTAGE:
366 case DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE:
367 bEnableField = bEnableItem = true;
368 break;
370 case DataPilotFieldReferenceType::RUNNING_TOTAL:
371 bEnableField = true;
372 bEnableItem = false;
373 break;
375 default:
376 bEnableField = bEnableItem = false;
379 bEnableField &= maLbBaseField.GetEntryCount() > 0;
380 maFtBaseField.Enable( bEnableField );
381 maLbBaseField.Enable( bEnableField );
383 bEnableItem &= bEnableField;
384 maFtBaseItem.Enable( bEnableItem );
385 maLbBaseItem.Enable( bEnableItem );
387 else if( pLBox == &maLbBaseField )
389 // keep "previous" and "next" entries
390 while( maLbBaseItem.GetEntryCount() > SC_BASEITEM_USER_POS )
391 maLbBaseItem.RemoveEntry( SC_BASEITEM_USER_POS );
393 // update item list for current base field
394 mbEmptyItem = false;
395 size_t nBasePos = maLbBaseField.GetSelectEntryPos();
396 if( nBasePos < mrLabelVec.size() )
398 const vector<ScDPLabelData::Member>& rMembers = mrLabelVec[nBasePos].maMembers;
399 mbEmptyItem = lclFillListBox( maLbBaseItem, rMembers, SC_BASEITEM_USER_POS );
400 // build cache for base names.
401 NameMapType aMap;
402 vector<ScDPLabelData::Member>::const_iterator itr = rMembers.begin(), itrEnd = rMembers.end();
403 for (; itr != itrEnd; ++itr)
404 aMap.insert(NameMapType::value_type(itr->getDisplayName(), itr->maName));
405 maBaseItemNameMap.swap(aMap);
408 // select base item
409 sal_uInt16 nItemPos = (maLbBaseItem.GetEntryCount() > SC_BASEITEM_USER_POS) ? SC_BASEITEM_USER_POS : SC_BASEITEM_PREV_POS;
410 maLbBaseItem.SelectEntryPos( nItemPos );
412 return 0;
415 IMPL_LINK_NOARG(ScDPFunctionDlg, DblClickHdl)
417 maBtnOk.Click();
418 return 0;
421 // ============================================================================
423 ScDPSubtotalDlg::ScDPSubtotalDlg( Window* pParent, ScDPObject& rDPObj,
424 const ScDPLabelData& rLabelData, const ScPivotFuncData& rFuncData,
425 const ScDPNameVec& rDataFields, bool bEnableLayout ) :
426 ModalDialog ( pParent, ScResId( RID_SCDLG_PIVOTSUBT ) ),
427 maFlSubt ( this, ScResId( FL_FUNC ) ),
428 maRbNone ( this, ScResId( RB_NONE ) ),
429 maRbAuto ( this, ScResId( RB_AUTO ) ),
430 maRbUser ( this, ScResId( RB_USER ) ),
431 maLbFunc ( this, ScResId( LB_FUNC ) ),
432 maFtNameLabel ( this, ScResId( FT_NAMELABEL ) ),
433 maFtName ( this, ScResId( FT_NAME ) ),
434 maCbShowAll ( this, ScResId( CB_SHOWALL ) ),
435 maBtnOk ( this, ScResId( BTN_OK ) ),
436 maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
437 maBtnHelp ( this, ScResId( BTN_HELP ) ),
438 maBtnOptions ( this, ScResId( BTN_OPTIONS ) ),
439 mrDPObj ( rDPObj ),
440 mrDataFields ( rDataFields ),
441 maLabelData ( rLabelData ),
442 mbEnableLayout ( bEnableLayout )
444 FreeResource();
445 Init( rLabelData, rFuncData );
448 sal_uInt16 ScDPSubtotalDlg::GetFuncMask() const
450 sal_uInt16 nFuncMask = PIVOT_FUNC_NONE;
452 if( maRbAuto.IsChecked() )
453 nFuncMask = PIVOT_FUNC_AUTO;
454 else if( maRbUser.IsChecked() )
455 nFuncMask = maLbFunc.GetSelection();
457 return nFuncMask;
460 void ScDPSubtotalDlg::FillLabelData( ScDPLabelData& rLabelData ) const
462 rLabelData.mnFuncMask = GetFuncMask();
463 rLabelData.mnUsedHier = maLabelData.mnUsedHier;
464 rLabelData.mbShowAll = maCbShowAll.IsChecked();
465 rLabelData.maMembers = maLabelData.maMembers;
466 rLabelData.maSortInfo = maLabelData.maSortInfo;
467 rLabelData.maLayoutInfo = maLabelData.maLayoutInfo;
468 rLabelData.maShowInfo = maLabelData.maShowInfo;
471 void ScDPSubtotalDlg::Init( const ScDPLabelData& rLabelData, const ScPivotFuncData& rFuncData )
473 // field name
474 maFtName.SetText(rLabelData.getDisplayName());
476 // radio buttons
477 maRbNone.SetClickHdl( LINK( this, ScDPSubtotalDlg, RadioClickHdl ) );
478 maRbAuto.SetClickHdl( LINK( this, ScDPSubtotalDlg, RadioClickHdl ) );
479 maRbUser.SetClickHdl( LINK( this, ScDPSubtotalDlg, RadioClickHdl ) );
481 RadioButton* pRBtn = 0;
482 switch( rFuncData.mnFuncMask )
484 case PIVOT_FUNC_NONE: pRBtn = &maRbNone; break;
485 case PIVOT_FUNC_AUTO: pRBtn = &maRbAuto; break;
486 default: pRBtn = &maRbUser;
488 pRBtn->Check();
489 RadioClickHdl( pRBtn );
491 // list box
492 maLbFunc.SetSelection( rFuncData.mnFuncMask );
493 maLbFunc.SetDoubleClickHdl( LINK( this, ScDPSubtotalDlg, DblClickHdl ) );
495 // show all
496 maCbShowAll.Check( rLabelData.mbShowAll );
498 // options
499 maBtnOptions.SetClickHdl( LINK( this, ScDPSubtotalDlg, ClickHdl ) );
502 // ----------------------------------------------------------------------------
504 IMPL_LINK( ScDPSubtotalDlg, RadioClickHdl, RadioButton*, pBtn )
506 maLbFunc.Enable( pBtn == &maRbUser );
507 return 0;
510 IMPL_LINK_NOARG(ScDPSubtotalDlg, DblClickHdl)
512 maBtnOk.Click();
513 return 0;
516 IMPL_LINK( ScDPSubtotalDlg, ClickHdl, PushButton*, pBtn )
518 if( pBtn == &maBtnOptions )
520 ScDPSubtotalOptDlg* pDlg = new ScDPSubtotalOptDlg( this, mrDPObj, maLabelData, mrDataFields, mbEnableLayout );
521 if( pDlg->Execute() == RET_OK )
522 pDlg->FillLabelData( maLabelData );
523 delete pDlg;
525 return 0;
528 // ============================================================================
530 ScDPSubtotalOptDlg::ScDPSubtotalOptDlg( Window* pParent, ScDPObject& rDPObj,
531 const ScDPLabelData& rLabelData, const ScDPNameVec& rDataFields,
532 bool bEnableLayout ) :
533 ModalDialog ( pParent, ScResId( RID_SCDLG_DPSUBTOTAL_OPT ) ),
534 maFlSortBy ( this, ScResId( FL_SORT_BY ) ),
535 maLbSortBy ( this, ScResId( LB_SORT_BY ) ),
536 maRbSortAsc ( this, ScResId( RB_SORT_ASC ) ),
537 maRbSortDesc ( this, ScResId( RB_SORT_DESC ) ),
538 maRbSortMan ( this, ScResId( RB_SORT_MAN ) ),
539 maFlLayout ( this, ScResId( FL_LAYOUT ) ),
540 maFtLayout ( this, ScResId( FT_LAYOUT ) ),
541 maLbLayout ( this, ScResId( LB_LAYOUT ) ),
542 maCbLayoutEmpty ( this, ScResId( CB_LAYOUT_EMPTY ) ),
543 maFlAutoShow ( this, ScResId( FL_AUTOSHOW ) ),
544 maCbShow ( this, ScResId( CB_SHOW ) ),
545 maNfShow ( this, ScResId( NF_SHOW ) ),
546 maFtShow ( this, ScResId( FT_SHOW ) ),
547 maFtShowFrom ( this, ScResId( FT_SHOW_FROM ) ),
548 maLbShowFrom ( this, ScResId( LB_SHOW_FROM ) ),
549 maFtShowUsing ( this, ScResId( FT_SHOW_USING ) ),
550 maLbShowUsing ( this, ScResId( LB_SHOW_USING ) ),
551 maFlHide ( this, ScResId( FL_HIDE ) ),
552 maLbHide ( this, ScResId( CT_HIDE ) ),
553 maFtHierarchy ( this, ScResId( FT_HIERARCHY ) ),
554 maLbHierarchy ( this, ScResId( LB_HIERARCHY ) ),
555 maBtnOk ( this, ScResId( BTN_OK ) ),
556 maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
557 maBtnHelp ( this, ScResId( BTN_HELP ) ),
558 maLbLayoutWrp ( maLbLayout, spLayoutMap ),
559 maLbShowFromWrp ( maLbShowFrom, spShowFromMap ),
560 mrDPObj ( rDPObj ),
561 maLabelData ( rLabelData )
563 FreeResource();
564 Init( rDataFields, bEnableLayout );
567 void ScDPSubtotalOptDlg::FillLabelData( ScDPLabelData& rLabelData ) const
569 // *** SORTING ***
571 if( maRbSortMan.IsChecked() )
572 rLabelData.maSortInfo.Mode = DataPilotFieldSortMode::MANUAL;
573 else if( maLbSortBy.GetSelectEntryPos() == SC_SORTNAME_POS )
574 rLabelData.maSortInfo.Mode = DataPilotFieldSortMode::NAME;
575 else
576 rLabelData.maSortInfo.Mode = DataPilotFieldSortMode::DATA;
578 ScDPName aFieldName = GetFieldName(maLbSortBy.GetSelectEntry());
579 if (!aFieldName.maName.isEmpty())
581 rLabelData.maSortInfo.Field =
582 ScDPUtil::createDuplicateDimensionName(aFieldName.maName, aFieldName.mnDupCount);
583 rLabelData.maSortInfo.IsAscending = maRbSortAsc.IsChecked();
586 // *** LAYOUT MODE ***
588 rLabelData.maLayoutInfo.LayoutMode = maLbLayoutWrp.GetControlValue();
589 rLabelData.maLayoutInfo.AddEmptyLines = maCbLayoutEmpty.IsChecked();
591 // *** AUTO SHOW ***
593 aFieldName = GetFieldName(maLbShowUsing.GetSelectEntry());
594 if (!aFieldName.maName.isEmpty())
596 rLabelData.maShowInfo.IsEnabled = maCbShow.IsChecked();
597 rLabelData.maShowInfo.ShowItemsMode = maLbShowFromWrp.GetControlValue();
598 rLabelData.maShowInfo.ItemCount = sal::static_int_cast<sal_Int32>( maNfShow.GetValue() );
599 rLabelData.maShowInfo.DataField =
600 ScDPUtil::createDuplicateDimensionName(aFieldName.maName, aFieldName.mnDupCount);
603 // *** HIDDEN ITEMS ***
605 rLabelData.maMembers = maLabelData.maMembers;
606 sal_uLong nVisCount = maLbHide.GetEntryCount();
607 for( sal_uInt16 nPos = 0; nPos < nVisCount; ++nPos )
608 rLabelData.maMembers[nPos].mbVisible = !maLbHide.IsChecked(nPos);
610 // *** HIERARCHY ***
612 rLabelData.mnUsedHier = maLbHierarchy.GetSelectEntryCount() ? maLbHierarchy.GetSelectEntryPos() : 0;
615 void ScDPSubtotalOptDlg::Init( const ScDPNameVec& rDataFields, bool bEnableLayout )
617 // *** SORTING ***
619 sal_Int32 nSortMode = maLabelData.maSortInfo.Mode;
621 // sort fields list box
622 maLbSortBy.InsertEntry(maLabelData.getDisplayName());
624 for( ScDPNameVec::const_iterator aIt = rDataFields.begin(), aEnd = rDataFields.end(); aIt != aEnd; ++aIt )
626 // Cache names for later lookup.
627 maDataFieldNameMap.insert(NameMapType::value_type(aIt->maLayoutName, *aIt));
629 maLbSortBy.InsertEntry( aIt->maLayoutName );
630 maLbShowUsing.InsertEntry( aIt->maLayoutName ); // for AutoShow
633 if( maLbSortBy.GetEntryCount() > SC_SORTDATA_POS )
634 maLbSortBy.SetSeparatorPos( SC_SORTDATA_POS - 1 );
636 sal_uInt16 nSortPos = SC_SORTNAME_POS;
637 if( nSortMode == DataPilotFieldSortMode::DATA )
639 nSortPos = FindListBoxEntry( maLbSortBy, maLabelData.maSortInfo.Field, SC_SORTDATA_POS );
640 if( nSortPos >= maLbSortBy.GetEntryCount() )
642 nSortPos = SC_SORTNAME_POS;
643 nSortMode = DataPilotFieldSortMode::MANUAL;
646 maLbSortBy.SelectEntryPos( nSortPos );
648 // sorting mode
649 maRbSortAsc.SetClickHdl( LINK( this, ScDPSubtotalOptDlg, RadioClickHdl ) );
650 maRbSortDesc.SetClickHdl( LINK( this, ScDPSubtotalOptDlg, RadioClickHdl ) );
651 maRbSortMan.SetClickHdl( LINK( this, ScDPSubtotalOptDlg, RadioClickHdl ) );
653 RadioButton* pRBtn = 0;
654 switch( nSortMode )
656 case DataPilotFieldSortMode::NONE:
657 case DataPilotFieldSortMode::MANUAL:
658 pRBtn = &maRbSortMan;
659 break;
660 default:
661 pRBtn = maLabelData.maSortInfo.IsAscending ? &maRbSortAsc : &maRbSortDesc;
663 pRBtn->Check();
664 RadioClickHdl( pRBtn );
666 // *** LAYOUT MODE ***
668 maFlLayout.Enable( bEnableLayout );
669 maFtLayout.Enable( bEnableLayout );
670 maLbLayout.Enable( bEnableLayout );
671 maCbLayoutEmpty.Enable( bEnableLayout );
673 maLbLayoutWrp.SetControlValue( maLabelData.maLayoutInfo.LayoutMode );
674 maCbLayoutEmpty.Check( maLabelData.maLayoutInfo.AddEmptyLines );
676 // *** AUTO SHOW ***
678 maCbShow.Check( maLabelData.maShowInfo.IsEnabled );
679 maCbShow.SetClickHdl( LINK( this, ScDPSubtotalOptDlg, CheckHdl ) );
681 maLbShowFromWrp.SetControlValue( maLabelData.maShowInfo.ShowItemsMode );
682 long nCount = static_cast< long >( maLabelData.maShowInfo.ItemCount );
683 if( nCount < 1 )
684 nCount = SC_SHOW_DEFAULT;
685 maNfShow.SetValue( nCount );
687 // maLbShowUsing already filled above
688 maLbShowUsing.SelectEntry( maLabelData.maShowInfo.DataField );
689 if( maLbShowUsing.GetSelectEntryPos() >= maLbShowUsing.GetEntryCount() )
690 maLbShowUsing.SelectEntryPos( 0 );
692 CheckHdl( &maCbShow ); // enable/disable dependent controls
694 // *** HIDDEN ITEMS ***
696 maLbHide.SetHelpId( HID_SC_DPSUBT_HIDE );
697 InitHideListBox();
699 // *** HIERARCHY ***
701 if( maLabelData.maHiers.getLength() > 1 )
703 lclFillListBox( maLbHierarchy, maLabelData.maHiers );
704 sal_Int32 nHier = maLabelData.mnUsedHier;
705 if( (nHier < 0) || (nHier >= maLabelData.maHiers.getLength()) ) nHier = 0;
706 maLbHierarchy.SelectEntryPos( static_cast< sal_uInt16 >( nHier ) );
707 maLbHierarchy.SetSelectHdl( LINK( this, ScDPSubtotalOptDlg, SelectHdl ) );
709 else
711 maFtHierarchy.Disable();
712 maLbHierarchy.Disable();
716 void ScDPSubtotalOptDlg::InitHideListBox()
718 maLbHide.Clear();
719 lclFillListBox( maLbHide, maLabelData.maMembers );
720 size_t n = maLabelData.maMembers.size();
721 for (size_t i = 0; i < n; ++i)
722 maLbHide.CheckEntryPos(static_cast<sal_uInt16>(i), !maLabelData.maMembers[i].mbVisible);
723 bool bEnable = maLbHide.GetEntryCount() > 0;
724 maFlHide.Enable( bEnable );
725 maLbHide.Enable( bEnable );
728 ScDPName ScDPSubtotalOptDlg::GetFieldName(const OUString& rLayoutName) const
730 NameMapType::const_iterator itr = maDataFieldNameMap.find(rLayoutName);
731 return itr == maDataFieldNameMap.end() ? ScDPName() : itr->second;
734 sal_uInt16 ScDPSubtotalOptDlg::FindListBoxEntry(
735 const ListBox& rLBox, const String& rEntry, sal_uInt16 nStartPos ) const
737 sal_uInt16 nPos = nStartPos;
738 bool bFound = false;
739 while (nPos < rLBox.GetEntryCount())
741 // translate the displayed field name back to its original field name.
742 ScDPName aName = GetFieldName(rLBox.GetEntry(nPos));
743 OUString aUnoName = ScDPUtil::createDuplicateDimensionName(aName.maName, aName.mnDupCount);
744 if (aUnoName.equals(rEntry))
746 bFound = true;
747 break;
749 ++nPos;
751 return bFound ? nPos : LISTBOX_ENTRY_NOTFOUND;
754 IMPL_LINK( ScDPSubtotalOptDlg, RadioClickHdl, RadioButton*, pBtn )
756 maLbSortBy.Enable( pBtn != &maRbSortMan );
757 return 0;
760 IMPL_LINK( ScDPSubtotalOptDlg, CheckHdl, CheckBox*, pCBox )
762 if( pCBox == &maCbShow )
764 bool bEnable = maCbShow.IsChecked();
765 maNfShow.Enable( bEnable );
766 maFtShow.Enable( bEnable );
767 maFtShowFrom.Enable( bEnable );
768 maLbShowFrom.Enable( bEnable );
770 bool bEnableUsing = bEnable && (maLbShowUsing.GetEntryCount() > 0);
771 maFtShowUsing.Enable( bEnableUsing );
772 maLbShowUsing.Enable( bEnableUsing );
774 return 0;
777 IMPL_LINK( ScDPSubtotalOptDlg, SelectHdl, ListBox*, pLBox )
779 if( pLBox == &maLbHierarchy )
781 mrDPObj.GetMembers(maLabelData.mnCol, maLbHierarchy.GetSelectEntryPos(), maLabelData.maMembers);
782 InitHideListBox();
784 return 0;
787 // ============================================================================
789 ScDPShowDetailDlg::ScDPShowDetailDlg( Window* pParent, ScDPObject& rDPObj, sal_uInt16 nOrient ) :
790 ModalDialog ( pParent, ScResId( RID_SCDLG_DPSHOWDETAIL ) ),
791 maFtDims ( this, ScResId( FT_DIMS ) ),
792 maLbDims ( this, ScResId( LB_DIMS ) ),
793 maBtnOk ( this, ScResId( BTN_OK ) ),
794 maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
795 maBtnHelp ( this, ScResId( BTN_HELP ) ),
797 mrDPObj(rDPObj)
799 FreeResource();
801 ScDPSaveData* pSaveData = rDPObj.GetSaveData();
802 long nDimCount = rDPObj.GetDimCount();
803 for (long nDim=0; nDim<nDimCount; nDim++)
805 bool bIsDataLayout;
806 sal_Int32 nDimFlags = 0;
807 OUString aName = rDPObj.GetDimName( nDim, bIsDataLayout, &nDimFlags );
808 if ( !bIsDataLayout && !rDPObj.IsDuplicated( nDim ) && ScDPObject::IsOrientationAllowed( nOrient, nDimFlags ) )
810 const ScDPSaveDimension* pDimension = pSaveData ? pSaveData->GetExistingDimensionByName(aName) : 0;
811 if ( !pDimension || (pDimension->GetOrientation() != nOrient) )
813 if (pDimension)
815 const OUString* pLayoutName = pDimension->GetLayoutName();
816 if (pLayoutName)
817 aName = *pLayoutName;
819 maLbDims.InsertEntry( aName );
820 maNameIndexMap.insert(DimNameIndexMap::value_type(aName, nDim));
824 if( maLbDims.GetEntryCount() )
825 maLbDims.SelectEntryPos( 0 );
827 maLbDims.SetDoubleClickHdl( LINK( this, ScDPShowDetailDlg, DblClickHdl ) );
830 short ScDPShowDetailDlg::Execute()
832 return maLbDims.GetEntryCount() ? ModalDialog::Execute() : static_cast<short>(RET_CANCEL);
835 OUString ScDPShowDetailDlg::GetDimensionName() const
837 // Look up the internal dimension name which may be different from the
838 // displayed field name.
839 String aSelectedName = maLbDims.GetSelectEntry();
840 DimNameIndexMap::const_iterator itr = maNameIndexMap.find(aSelectedName);
841 if (itr == maNameIndexMap.end())
842 // This should never happen!
843 return aSelectedName;
845 long nDim = itr->second;
846 bool bIsDataLayout = false;
847 return mrDPObj.GetDimName(nDim, bIsDataLayout);
850 IMPL_LINK( ScDPShowDetailDlg, DblClickHdl, ListBox*, pLBox )
852 if( pLBox == &maLbDims )
853 maBtnOk.Click();
854 return 0;
857 // ============================================================================
859 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */