1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/builderfactory.hxx>
32 #include <vcl/msgbox.hxx>
34 #include "scresid.hxx"
35 #include "dpobject.hxx"
38 #include "globstr.hrc"
43 using namespace ::com::sun::star::sheet
;
45 using ::com::sun::star::uno::Sequence
;
50 /** Appends all strings from the Sequence to the list box.
52 Empty strings are replaced by a localized "(empty)" entry and inserted at
53 the specified position.
55 @return true = The passed string list contains an empty string entry.
57 template< typename ListBoxType
>
58 bool lclFillListBox( ListBoxType
& rLBox
, const Sequence
< OUString
>& rStrings
, sal_Int32 nEmptyPos
= LISTBOX_APPEND
)
61 const OUString
* pStr
= rStrings
.getConstArray();
64 for( const OUString
* pEnd
= pStr
+ rStrings
.getLength(); pStr
!= pEnd
; ++pStr
)
66 if( !pStr
->isEmpty() )
67 rLBox
.InsertEntry( *pStr
);
70 rLBox
.InsertEntry( ScGlobal::GetRscString( STR_EMPTYDATA
), nEmptyPos
);
78 template< typename ListBoxType
>
79 bool lclFillListBox( ListBoxType
& rLBox
, const vector
<ScDPLabelData::Member
>& rMembers
, sal_Int32 nEmptyPos
= LISTBOX_APPEND
)
82 vector
<ScDPLabelData::Member
>::const_iterator itr
= rMembers
.begin(), itrEnd
= rMembers
.end();
83 for (; itr
!= itrEnd
; ++itr
)
85 OUString aName
= itr
->getDisplayName();
87 rLBox
.InsertEntry(aName
);
90 rLBox
.InsertEntry(ScGlobal::GetRscString(STR_EMPTYDATA
), nEmptyPos
);
97 /** This table represents the order of the strings in the resource string array. */
98 static const PivotFunc spnFunctions
[] =
113 const sal_uInt16 SC_BASEITEM_PREV_POS
= 0;
114 const sal_uInt16 SC_BASEITEM_NEXT_POS
= 1;
115 const sal_uInt16 SC_BASEITEM_USER_POS
= 2;
117 const sal_uInt16 SC_SORTNAME_POS
= 0;
118 const sal_uInt16 SC_SORTDATA_POS
= 1;
120 const long SC_SHOW_DEFAULT
= 10;
122 static const ScDPListBoxWrapper::MapEntryType spRefTypeMap
[] =
124 { 0, DataPilotFieldReferenceType::NONE
},
125 { 1, DataPilotFieldReferenceType::ITEM_DIFFERENCE
},
126 { 2, DataPilotFieldReferenceType::ITEM_PERCENTAGE
},
127 { 3, DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE
},
128 { 4, DataPilotFieldReferenceType::RUNNING_TOTAL
},
129 { 5, DataPilotFieldReferenceType::ROW_PERCENTAGE
},
130 { 6, DataPilotFieldReferenceType::COLUMN_PERCENTAGE
},
131 { 7, DataPilotFieldReferenceType::TOTAL_PERCENTAGE
},
132 { 8, DataPilotFieldReferenceType::INDEX
},
133 { WRAPPER_LISTBOX_ENTRY_NOTFOUND
, DataPilotFieldReferenceType::NONE
}
136 static const ScDPListBoxWrapper::MapEntryType spLayoutMap
[] =
138 { 0, DataPilotFieldLayoutMode::TABULAR_LAYOUT
},
139 { 1, DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP
},
140 { 2, DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM
},
141 { WRAPPER_LISTBOX_ENTRY_NOTFOUND
, DataPilotFieldLayoutMode::TABULAR_LAYOUT
}
144 static const ScDPListBoxWrapper::MapEntryType spShowFromMap
[] =
146 { 0, DataPilotFieldShowItemsMode::FROM_TOP
},
147 { 1, DataPilotFieldShowItemsMode::FROM_BOTTOM
},
148 { WRAPPER_LISTBOX_ENTRY_NOTFOUND
, DataPilotFieldShowItemsMode::FROM_TOP
}
153 ScDPFunctionListBox::ScDPFunctionListBox(vcl::Window
* pParent
, WinBits nStyle
)
154 : ListBox(pParent
, nStyle
)
159 VCL_BUILDER_DECL_FACTORY(ScDPFunctionListBox
)
161 WinBits nWinStyle
= WB_LEFT
|WB_VCENTER
|WB_3DLOOK
|WB_SIMPLEMODE
;
162 OString sBorder
= VclBuilder::extractCustomProperty(rMap
);
163 if (!sBorder
.isEmpty())
164 nWinStyle
|= WB_BORDER
;
165 rRet
= VclPtr
<ScDPFunctionListBox
>::Create(pParent
, nWinStyle
);
168 void ScDPFunctionListBox::SetSelection( PivotFunc nFuncMask
)
170 if( (nFuncMask
== PivotFunc::NONE
) || (nFuncMask
== PivotFunc::Auto
) )
173 for( sal_Int32 nEntry
= 0, nCount
= GetEntryCount(); nEntry
< nCount
; ++nEntry
)
174 SelectEntryPos( nEntry
, bool(nFuncMask
& spnFunctions
[ nEntry
]) );
177 PivotFunc
ScDPFunctionListBox::GetSelection() const
179 PivotFunc nFuncMask
= PivotFunc::NONE
;
180 for( sal_Int32 nSel
= 0, nCount
= GetSelectEntryCount(); nSel
< nCount
; ++nSel
)
181 nFuncMask
|= spnFunctions
[ GetSelectEntryPos( nSel
) ];
185 void ScDPFunctionListBox::FillFunctionNames()
187 OSL_ENSURE( !GetEntryCount(), "ScDPMultiFuncListBox::FillFunctionNames - do not add texts to resource" );
189 ResStringArray
aArr( ScResId( SCSTR_DPFUNCLISTBOX
) );
190 for( sal_uInt16 nIndex
= 0, nCount
= sal::static_int_cast
<sal_uInt16
>(aArr
.Count()); nIndex
< nCount
; ++nIndex
)
191 InsertEntry( aArr
.GetString( nIndex
) );
194 ScDPFunctionDlg::ScDPFunctionDlg(
195 vcl::Window
* pParent
, const ScDPLabelDataVector
& rLabelVec
,
196 const ScDPLabelData
& rLabelData
, const ScPivotFuncData
& rFuncData
)
197 : ModalDialog(pParent
, "DataFieldDialog",
198 "modules/scalc/ui/datafielddialog.ui")
199 , mrLabelVec(rLabelVec
)
202 get(mpFtName
, "name");
203 get(mpLbType
, "type");
204 mxLbTypeWrp
.reset(new ScDPListBoxWrapper(*mpLbType
, spRefTypeMap
));
205 get(mpLbFunc
, "functions");
206 mpLbFunc
->set_height_request(mpLbFunc
->GetTextHeight() * 8);
207 get(mpFtBaseField
, "basefieldft");
208 get(mpLbBaseField
, "basefield");
209 get(mpFtBaseItem
, "baseitemft");
210 get(mpLbBaseItem
, "baseitem");
213 Init( rLabelData
, rFuncData
);
216 ScDPFunctionDlg::~ScDPFunctionDlg()
221 void ScDPFunctionDlg::dispose()
226 mpFtBaseField
.clear();
227 mpLbBaseField
.clear();
228 mpFtBaseItem
.clear();
229 mpLbBaseItem
.clear();
231 ModalDialog::dispose();
235 PivotFunc
ScDPFunctionDlg::GetFuncMask() const
237 return mpLbFunc
->GetSelection();
240 DataPilotFieldReference
ScDPFunctionDlg::GetFieldRef() const
242 DataPilotFieldReference aRef
;
244 aRef
.ReferenceType
= mxLbTypeWrp
->GetControlValue();
245 aRef
.ReferenceField
= GetBaseFieldName(mpLbBaseField
->GetSelectEntry());
247 sal_Int32 nBaseItemPos
= mpLbBaseItem
->GetSelectEntryPos();
248 switch( nBaseItemPos
)
250 case SC_BASEITEM_PREV_POS
:
251 aRef
.ReferenceItemType
= DataPilotFieldReferenceItemType::PREVIOUS
;
253 case SC_BASEITEM_NEXT_POS
:
254 aRef
.ReferenceItemType
= DataPilotFieldReferenceItemType::NEXT
;
258 aRef
.ReferenceItemType
= DataPilotFieldReferenceItemType::NAMED
;
259 if( !mbEmptyItem
|| (nBaseItemPos
> SC_BASEITEM_USER_POS
) )
260 aRef
.ReferenceItemName
= GetBaseItemName(mpLbBaseItem
->GetSelectEntry());
267 void ScDPFunctionDlg::Init( const ScDPLabelData
& rLabelData
, const ScPivotFuncData
& rFuncData
)
270 PivotFunc nFuncMask
= (rFuncData
.mnFuncMask
== PivotFunc::NONE
) ? PivotFunc::Sum
: rFuncData
.mnFuncMask
;
271 mpLbFunc
->SetSelection( nFuncMask
);
274 mpFtName
->SetText(rLabelData
.getDisplayName());
277 mpLbFunc
->SetDoubleClickHdl( LINK( this, ScDPFunctionDlg
, DblClickHdl
) );
278 mpLbType
->SetSelectHdl( LINK( this, ScDPFunctionDlg
, SelectHdl
) );
279 mpLbBaseField
->SetSelectHdl( LINK( this, ScDPFunctionDlg
, SelectHdl
) );
281 // base field list box
282 OUString aSelectedEntry
;
283 for( ScDPLabelDataVector::const_iterator aIt
= mrLabelVec
.begin(), aEnd
= mrLabelVec
.end(); aIt
!= aEnd
; ++aIt
)
285 mpLbBaseField
->InsertEntry((*aIt
)->getDisplayName());
286 maBaseFieldNameMap
.insert(
287 NameMapType::value_type((*aIt
)->getDisplayName(), (*aIt
)->maName
));
288 if ((*aIt
)->maName
== rFuncData
.maFieldRef
.ReferenceField
)
289 aSelectedEntry
= (*aIt
)->getDisplayName();
292 // base item list box
293 mpLbBaseItem
->SetSeparatorPos( SC_BASEITEM_USER_POS
- 1 );
295 // select field reference type
296 mxLbTypeWrp
->SetControlValue( rFuncData
.maFieldRef
.ReferenceType
);
297 SelectHdl( *mpLbType
.get() ); // enables base field/item list boxes
300 mpLbBaseField
->SelectEntry(aSelectedEntry
);
301 if( mpLbBaseField
->GetSelectEntryPos() >= mpLbBaseField
->GetEntryCount() )
302 mpLbBaseField
->SelectEntryPos( 0 );
303 SelectHdl( *mpLbBaseField
.get() ); // fills base item list, selects base item
306 switch( rFuncData
.maFieldRef
.ReferenceItemType
)
308 case DataPilotFieldReferenceItemType::PREVIOUS
:
309 mpLbBaseItem
->SelectEntryPos( SC_BASEITEM_PREV_POS
);
311 case DataPilotFieldReferenceItemType::NEXT
:
312 mpLbBaseItem
->SelectEntryPos( SC_BASEITEM_NEXT_POS
);
316 if( mbEmptyItem
&& rFuncData
.maFieldRef
.ReferenceItemName
.isEmpty() )
318 // select special "(empty)" entry added before other items
319 mpLbBaseItem
->SelectEntryPos( SC_BASEITEM_USER_POS
);
323 sal_Int32 nStartPos
= mbEmptyItem
? (SC_BASEITEM_USER_POS
+ 1) : SC_BASEITEM_USER_POS
;
324 sal_Int32 nPos
= FindBaseItemPos( rFuncData
.maFieldRef
.ReferenceItemName
, nStartPos
);
325 if( nPos
>= mpLbBaseItem
->GetEntryCount() )
326 nPos
= (mpLbBaseItem
->GetEntryCount() > SC_BASEITEM_USER_POS
) ? SC_BASEITEM_USER_POS
: SC_BASEITEM_PREV_POS
;
327 mpLbBaseItem
->SelectEntryPos( nPos
);
333 const OUString
& ScDPFunctionDlg::GetBaseFieldName(const OUString
& rLayoutName
) const
335 NameMapType::const_iterator itr
= maBaseFieldNameMap
.find(rLayoutName
);
336 return itr
== maBaseFieldNameMap
.end() ? rLayoutName
: itr
->second
;
339 const OUString
& ScDPFunctionDlg::GetBaseItemName(const OUString
& rLayoutName
) const
341 NameMapType::const_iterator itr
= maBaseItemNameMap
.find(rLayoutName
);
342 return itr
== maBaseItemNameMap
.end() ? rLayoutName
: itr
->second
;
345 sal_Int32
ScDPFunctionDlg::FindBaseItemPos( const OUString
& rEntry
, sal_Int32 nStartPos
) const
347 sal_Int32 nPos
= nStartPos
;
349 while (nPos
< mpLbBaseItem
->GetEntryCount())
351 // translate the displayed field name back to its original field name.
352 const OUString
& rInName
= mpLbBaseItem
->GetEntry(nPos
);
353 const OUString
& rName
= GetBaseItemName(rInName
);
354 if (rName
.equals(rEntry
))
361 return bFound
? nPos
: LISTBOX_ENTRY_NOTFOUND
;
364 IMPL_LINK_TYPED( ScDPFunctionDlg
, SelectHdl
, ListBox
&, rLBox
, void )
366 if( &rLBox
== mpLbType
)
368 bool bEnableField
, bEnableItem
;
369 switch( mxLbTypeWrp
->GetControlValue() )
371 case DataPilotFieldReferenceType::ITEM_DIFFERENCE
:
372 case DataPilotFieldReferenceType::ITEM_PERCENTAGE
:
373 case DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE
:
374 bEnableField
= bEnableItem
= true;
377 case DataPilotFieldReferenceType::RUNNING_TOTAL
:
383 bEnableField
= bEnableItem
= false;
386 bEnableField
&= mpLbBaseField
->GetEntryCount() > 0;
387 mpFtBaseField
->Enable( bEnableField
);
388 mpLbBaseField
->Enable( bEnableField
);
390 bEnableItem
&= bEnableField
;
391 mpFtBaseItem
->Enable( bEnableItem
);
392 mpLbBaseItem
->Enable( bEnableItem
);
394 else if( &rLBox
== mpLbBaseField
)
396 // keep "previous" and "next" entries
397 while( mpLbBaseItem
->GetEntryCount() > SC_BASEITEM_USER_POS
)
398 mpLbBaseItem
->RemoveEntry( SC_BASEITEM_USER_POS
);
400 // update item list for current base field
402 size_t nBasePos
= mpLbBaseField
->GetSelectEntryPos();
403 if( nBasePos
< mrLabelVec
.size() )
405 const vector
<ScDPLabelData::Member
>& rMembers
= mrLabelVec
[nBasePos
]->maMembers
;
406 mbEmptyItem
= lclFillListBox(*mpLbBaseItem
, rMembers
, SC_BASEITEM_USER_POS
);
407 // build cache for base names.
409 vector
<ScDPLabelData::Member
>::const_iterator itr
= rMembers
.begin(), itrEnd
= rMembers
.end();
410 for (; itr
!= itrEnd
; ++itr
)
411 aMap
.insert(NameMapType::value_type(itr
->getDisplayName(), itr
->maName
));
412 maBaseItemNameMap
.swap(aMap
);
416 sal_uInt16 nItemPos
= (mpLbBaseItem
->GetEntryCount() > SC_BASEITEM_USER_POS
) ? SC_BASEITEM_USER_POS
: SC_BASEITEM_PREV_POS
;
417 mpLbBaseItem
->SelectEntryPos( nItemPos
);
421 IMPL_LINK_NOARG_TYPED(ScDPFunctionDlg
, DblClickHdl
, ListBox
&, void)
426 ScDPSubtotalDlg::ScDPSubtotalDlg( vcl::Window
* pParent
, ScDPObject
& rDPObj
,
427 const ScDPLabelData
& rLabelData
, const ScPivotFuncData
& rFuncData
,
428 const ScDPNameVec
& rDataFields
, bool bEnableLayout
)
429 : ModalDialog(pParent
, "PivotFieldDialog",
430 "modules/scalc/ui/pivotfielddialog.ui")
432 , mrDataFields(rDataFields
)
433 , maLabelData(rLabelData
)
434 , mbEnableLayout(bEnableLayout
)
437 get(mpBtnOptions
, "options");
438 get(mpCbShowAll
, "showall");
439 get(mpFtName
, "name");
440 get(mpLbFunc
, "functions");
441 mpLbFunc
->EnableMultiSelection(true);
442 mpLbFunc
->set_height_request(mpLbFunc
->GetTextHeight() * 8);
443 get(mpRbNone
, "none");
444 get(mpRbAuto
, "auto");
445 get(mpRbUser
, "user");
447 Init( rLabelData
, rFuncData
);
450 ScDPSubtotalDlg::~ScDPSubtotalDlg()
455 void ScDPSubtotalDlg::dispose()
464 mpBtnOptions
.clear();
465 ModalDialog::dispose();
468 PivotFunc
ScDPSubtotalDlg::GetFuncMask() const
470 PivotFunc nFuncMask
= PivotFunc::NONE
;
472 if( mpRbAuto
->IsChecked() )
473 nFuncMask
= PivotFunc::Auto
;
474 else if( mpRbUser
->IsChecked() )
475 nFuncMask
= mpLbFunc
->GetSelection();
480 void ScDPSubtotalDlg::FillLabelData( ScDPLabelData
& rLabelData
) const
482 rLabelData
.mnFuncMask
= GetFuncMask();
483 rLabelData
.mnUsedHier
= maLabelData
.mnUsedHier
;
484 rLabelData
.mbShowAll
= mpCbShowAll
->IsChecked();
485 rLabelData
.maMembers
= maLabelData
.maMembers
;
486 rLabelData
.maSortInfo
= maLabelData
.maSortInfo
;
487 rLabelData
.maLayoutInfo
= maLabelData
.maLayoutInfo
;
488 rLabelData
.maShowInfo
= maLabelData
.maShowInfo
;
489 rLabelData
.mbRepeatItemLabels
= maLabelData
.mbRepeatItemLabels
;
492 void ScDPSubtotalDlg::Init( const ScDPLabelData
& rLabelData
, const ScPivotFuncData
& rFuncData
)
495 mpFtName
->SetText(rLabelData
.getDisplayName());
498 mpRbNone
->SetClickHdl( LINK( this, ScDPSubtotalDlg
, RadioClickHdl
) );
499 mpRbAuto
->SetClickHdl( LINK( this, ScDPSubtotalDlg
, RadioClickHdl
) );
500 mpRbUser
->SetClickHdl( LINK( this, ScDPSubtotalDlg
, RadioClickHdl
) );
502 RadioButton
* pRBtn
= nullptr;
503 switch( rFuncData
.mnFuncMask
)
505 case PivotFunc::NONE
: pRBtn
= mpRbNone
; break;
506 case PivotFunc::Auto
: pRBtn
= mpRbAuto
; break;
507 default: pRBtn
= mpRbUser
;
510 RadioClickHdl( pRBtn
);
513 mpLbFunc
->SetSelection( rFuncData
.mnFuncMask
);
514 mpLbFunc
->SetDoubleClickHdl( LINK( this, ScDPSubtotalDlg
, DblClickHdl
) );
517 mpCbShowAll
->Check( rLabelData
.mbShowAll
);
520 mpBtnOptions
->SetClickHdl( LINK( this, ScDPSubtotalDlg
, ClickHdl
) );
523 IMPL_LINK_TYPED( ScDPSubtotalDlg
, RadioClickHdl
, Button
*, pBtn
, void )
525 mpLbFunc
->Enable( pBtn
== mpRbUser
);
528 IMPL_LINK_NOARG_TYPED(ScDPSubtotalDlg
, DblClickHdl
, ListBox
&, void)
533 IMPL_LINK_TYPED( ScDPSubtotalDlg
, ClickHdl
, Button
*, pBtn
, void )
535 if (pBtn
== mpBtnOptions
)
537 VclPtrInstance
< ScDPSubtotalOptDlg
> pDlg( this, mrDPObj
, maLabelData
, mrDataFields
, mbEnableLayout
);
538 if( pDlg
->Execute() == RET_OK
)
539 pDlg
->FillLabelData( maLabelData
);
543 ScDPSubtotalOptDlg::ScDPSubtotalOptDlg( vcl::Window
* pParent
, ScDPObject
& rDPObj
,
544 const ScDPLabelData
& rLabelData
, const ScDPNameVec
& rDataFields
,
546 : ModalDialog(pParent
, "DataFieldOptionsDialog",
547 "modules/scalc/ui/datafieldoptionsdialog.ui")
549 , maLabelData(rLabelData
)
551 get(m_pLbSortBy
, "sortby");
552 m_pLbSortBy
->set_width_request(m_pLbSortBy
->approximate_char_width() * 20);
553 get(m_pRbSortAsc
, "ascending");
554 get(m_pRbSortDesc
, "descending");
555 get(m_pRbSortMan
, "manual");
556 get(m_pLayoutFrame
, "layoutframe");
557 get(m_pLbLayout
, "layout");
558 get(m_pCbLayoutEmpty
, "emptyline");
559 get(m_pCbRepeatItemLabels
, "repeatitemlabels");
560 get(m_pCbShow
, "show");
561 get(m_pNfShow
, "items");
562 get(m_pFtShow
, "showft");
563 get(m_pFtShowFrom
, "showfromft");
564 get(m_pLbShowFrom
, "from");
565 get(m_pFtShowUsing
, "usingft");
566 get(m_pLbShowUsing
, "using");
567 get(m_pHideFrame
, "hideframe");
568 get(m_pLbHide
, "hideitems");
569 m_pLbHide
->set_height_request(GetTextHeight() * 5);
570 get(m_pFtHierarchy
, "hierarchyft");
571 get(m_pLbHierarchy
, "hierarchy");
573 m_xLbLayoutWrp
.reset(new ScDPListBoxWrapper(*m_pLbLayout
, spLayoutMap
));
574 m_xLbShowFromWrp
.reset(new ScDPListBoxWrapper(*m_pLbShowFrom
, spShowFromMap
));
576 Init( rDataFields
, bEnableLayout
);
579 ScDPSubtotalOptDlg::~ScDPSubtotalOptDlg()
584 void ScDPSubtotalOptDlg::dispose()
587 m_pRbSortAsc
.clear();
588 m_pRbSortDesc
.clear();
589 m_pRbSortMan
.clear();
590 m_pLayoutFrame
.clear();
592 m_pCbLayoutEmpty
.clear();
593 m_pCbRepeatItemLabels
.clear();
597 m_pFtShowFrom
.clear();
598 m_pLbShowFrom
.clear();
599 m_pFtShowUsing
.clear();
600 m_pLbShowUsing
.clear();
601 m_pHideFrame
.clear();
603 m_pFtHierarchy
.clear();
604 m_pLbHierarchy
.clear();
605 ModalDialog::dispose();
608 void ScDPSubtotalOptDlg::FillLabelData( ScDPLabelData
& rLabelData
) const
612 if( m_pRbSortMan
->IsChecked() )
613 rLabelData
.maSortInfo
.Mode
= DataPilotFieldSortMode::MANUAL
;
614 else if( m_pLbSortBy
->GetSelectEntryPos() == SC_SORTNAME_POS
)
615 rLabelData
.maSortInfo
.Mode
= DataPilotFieldSortMode::NAME
;
617 rLabelData
.maSortInfo
.Mode
= DataPilotFieldSortMode::DATA
;
619 ScDPName aFieldName
= GetFieldName(m_pLbSortBy
->GetSelectEntry());
620 if (!aFieldName
.maName
.isEmpty())
622 rLabelData
.maSortInfo
.Field
=
623 ScDPUtil::createDuplicateDimensionName(aFieldName
.maName
, aFieldName
.mnDupCount
);
624 rLabelData
.maSortInfo
.IsAscending
= m_pRbSortAsc
->IsChecked();
627 // *** LAYOUT MODE ***
629 rLabelData
.maLayoutInfo
.LayoutMode
= m_xLbLayoutWrp
->GetControlValue();
630 rLabelData
.maLayoutInfo
.AddEmptyLines
= m_pCbLayoutEmpty
->IsChecked();
631 rLabelData
.mbRepeatItemLabels
= m_pCbRepeatItemLabels
->IsChecked();
635 aFieldName
= GetFieldName(m_pLbShowUsing
->GetSelectEntry());
636 if (!aFieldName
.maName
.isEmpty())
638 rLabelData
.maShowInfo
.IsEnabled
= m_pCbShow
->IsChecked();
639 rLabelData
.maShowInfo
.ShowItemsMode
= m_xLbShowFromWrp
->GetControlValue();
640 rLabelData
.maShowInfo
.ItemCount
= sal::static_int_cast
<sal_Int32
>( m_pNfShow
->GetValue() );
641 rLabelData
.maShowInfo
.DataField
=
642 ScDPUtil::createDuplicateDimensionName(aFieldName
.maName
, aFieldName
.mnDupCount
);
645 // *** HIDDEN ITEMS ***
647 rLabelData
.maMembers
= maLabelData
.maMembers
;
648 sal_uLong nVisCount
= m_pLbHide
->GetEntryCount();
649 for( sal_uLong nPos
= 0; nPos
< nVisCount
; ++nPos
)
650 rLabelData
.maMembers
[nPos
].mbVisible
= !m_pLbHide
->IsChecked(nPos
);
654 rLabelData
.mnUsedHier
= m_pLbHierarchy
->GetSelectEntryCount() ? m_pLbHierarchy
->GetSelectEntryPos() : 0;
657 void ScDPSubtotalOptDlg::Init( const ScDPNameVec
& rDataFields
, bool bEnableLayout
)
661 sal_Int32 nSortMode
= maLabelData
.maSortInfo
.Mode
;
663 // sort fields list box
664 m_pLbSortBy
->InsertEntry(maLabelData
.getDisplayName());
666 for( ScDPNameVec::const_iterator aIt
= rDataFields
.begin(), aEnd
= rDataFields
.end(); aIt
!= aEnd
; ++aIt
)
668 // Cache names for later lookup.
669 maDataFieldNameMap
.insert(NameMapType::value_type(aIt
->maLayoutName
, *aIt
));
671 m_pLbSortBy
->InsertEntry( aIt
->maLayoutName
);
672 m_pLbShowUsing
->InsertEntry( aIt
->maLayoutName
); // for AutoShow
675 if( m_pLbSortBy
->GetEntryCount() > SC_SORTDATA_POS
)
676 m_pLbSortBy
->SetSeparatorPos( SC_SORTDATA_POS
- 1 );
678 sal_Int32 nSortPos
= SC_SORTNAME_POS
;
679 if( nSortMode
== DataPilotFieldSortMode::DATA
)
681 nSortPos
= FindListBoxEntry( *m_pLbSortBy
, maLabelData
.maSortInfo
.Field
, SC_SORTDATA_POS
);
682 if( nSortPos
>= m_pLbSortBy
->GetEntryCount() )
684 nSortPos
= SC_SORTNAME_POS
;
685 nSortMode
= DataPilotFieldSortMode::MANUAL
;
688 m_pLbSortBy
->SelectEntryPos( nSortPos
);
691 m_pRbSortAsc
->SetClickHdl( LINK( this, ScDPSubtotalOptDlg
, RadioClickHdl
) );
692 m_pRbSortDesc
->SetClickHdl( LINK( this, ScDPSubtotalOptDlg
, RadioClickHdl
) );
693 m_pRbSortMan
->SetClickHdl( LINK( this, ScDPSubtotalOptDlg
, RadioClickHdl
) );
695 RadioButton
* pRBtn
= nullptr;
698 case DataPilotFieldSortMode::NONE
:
699 case DataPilotFieldSortMode::MANUAL
:
700 pRBtn
= m_pRbSortMan
;
703 pRBtn
= maLabelData
.maSortInfo
.IsAscending
? m_pRbSortAsc
: m_pRbSortDesc
;
706 RadioClickHdl( pRBtn
);
708 // *** LAYOUT MODE ***
710 m_pLayoutFrame
->Enable(bEnableLayout
);
712 m_xLbLayoutWrp
->SetControlValue( maLabelData
.maLayoutInfo
.LayoutMode
);
713 m_pCbLayoutEmpty
->Check( maLabelData
.maLayoutInfo
.AddEmptyLines
);
714 m_pCbRepeatItemLabels
->Check( maLabelData
.mbRepeatItemLabels
);
718 m_pCbShow
->Check( maLabelData
.maShowInfo
.IsEnabled
);
719 m_pCbShow
->SetClickHdl( LINK( this, ScDPSubtotalOptDlg
, CheckHdl
) );
721 m_xLbShowFromWrp
->SetControlValue( maLabelData
.maShowInfo
.ShowItemsMode
);
722 long nCount
= static_cast< long >( maLabelData
.maShowInfo
.ItemCount
);
724 nCount
= SC_SHOW_DEFAULT
;
725 m_pNfShow
->SetValue( nCount
);
727 // m_pLbShowUsing already filled above
728 m_pLbShowUsing
->SelectEntry( maLabelData
.maShowInfo
.DataField
);
729 if( m_pLbShowUsing
->GetSelectEntryPos() >= m_pLbShowUsing
->GetEntryCount() )
730 m_pLbShowUsing
->SelectEntryPos( 0 );
732 CheckHdl(m_pCbShow
); // enable/disable dependent controls
734 // *** HIDDEN ITEMS ***
740 if( maLabelData
.maHiers
.getLength() > 1 )
742 lclFillListBox( *m_pLbHierarchy
, maLabelData
.maHiers
);
743 sal_Int32 nHier
= maLabelData
.mnUsedHier
;
744 if( (nHier
< 0) || (nHier
>= maLabelData
.maHiers
.getLength()) ) nHier
= 0;
745 m_pLbHierarchy
->SelectEntryPos( static_cast< sal_Int32
>( nHier
) );
746 m_pLbHierarchy
->SetSelectHdl( LINK( this, ScDPSubtotalOptDlg
, SelectHdl
) );
750 m_pFtHierarchy
->Disable();
751 m_pLbHierarchy
->Disable();
755 void ScDPSubtotalOptDlg::InitHideListBox()
758 lclFillListBox( *m_pLbHide
, maLabelData
.maMembers
);
759 size_t n
= maLabelData
.maMembers
.size();
760 for (sal_uLong i
= 0; i
< n
; ++i
)
761 m_pLbHide
->CheckEntryPos(i
, !maLabelData
.maMembers
[i
].mbVisible
);
762 bool bEnable
= m_pLbHide
->GetEntryCount() > 0;
763 m_pHideFrame
->Enable(bEnable
);
766 ScDPName
ScDPSubtotalOptDlg::GetFieldName(const OUString
& rLayoutName
) const
768 NameMapType::const_iterator itr
= maDataFieldNameMap
.find(rLayoutName
);
769 return itr
== maDataFieldNameMap
.end() ? ScDPName() : itr
->second
;
772 sal_Int32
ScDPSubtotalOptDlg::FindListBoxEntry(
773 const ListBox
& rLBox
, const OUString
& rEntry
, sal_Int32 nStartPos
) const
775 sal_Int32 nPos
= nStartPos
;
777 while (nPos
< rLBox
.GetEntryCount())
779 // translate the displayed field name back to its original field name.
780 ScDPName aName
= GetFieldName(rLBox
.GetEntry(nPos
));
781 OUString aUnoName
= ScDPUtil::createDuplicateDimensionName(aName
.maName
, aName
.mnDupCount
);
782 if (aUnoName
.equals(rEntry
))
789 return bFound
? nPos
: LISTBOX_ENTRY_NOTFOUND
;
792 IMPL_LINK_TYPED( ScDPSubtotalOptDlg
, RadioClickHdl
, Button
*, pBtn
, void )
794 m_pLbSortBy
->Enable( pBtn
!= m_pRbSortMan
);
797 IMPL_LINK_TYPED( ScDPSubtotalOptDlg
, CheckHdl
, Button
*, pCBox
, void )
799 if (pCBox
== m_pCbShow
)
801 bool bEnable
= m_pCbShow
->IsChecked();
802 m_pNfShow
->Enable( bEnable
);
803 m_pFtShow
->Enable( bEnable
);
804 m_pFtShowFrom
->Enable( bEnable
);
805 m_pLbShowFrom
->Enable( bEnable
);
807 bool bEnableUsing
= bEnable
&& (m_pLbShowUsing
->GetEntryCount() > 0);
808 m_pFtShowUsing
->Enable(bEnableUsing
);
809 m_pLbShowUsing
->Enable(bEnableUsing
);
813 IMPL_LINK_TYPED( ScDPSubtotalOptDlg
, SelectHdl
, ListBox
&, rLBox
, void )
815 if (&rLBox
== m_pLbHierarchy
)
817 mrDPObj
.GetMembers(maLabelData
.mnCol
, m_pLbHierarchy
->GetSelectEntryPos(), maLabelData
.maMembers
);
822 ScDPShowDetailDlg::ScDPShowDetailDlg( vcl::Window
* pParent
, ScDPObject
& rDPObj
, sal_uInt16 nOrient
) :
823 ModalDialog ( pParent
, "ShowDetail", "modules/scalc/ui/showdetaildialog.ui" ),
826 get(mpLbDims
, "dimsTreeview");
829 ScDPSaveData
* pSaveData
= rDPObj
.GetSaveData();
830 long nDimCount
= rDPObj
.GetDimCount();
831 for (long nDim
=0; nDim
<nDimCount
; nDim
++)
834 sal_Int32 nDimFlags
= 0;
835 OUString aName
= rDPObj
.GetDimName( nDim
, bIsDataLayout
, &nDimFlags
);
836 if ( !bIsDataLayout
&& !rDPObj
.IsDuplicated( nDim
) && ScDPObject::IsOrientationAllowed( nOrient
, nDimFlags
) )
838 const ScDPSaveDimension
* pDimension
= pSaveData
? pSaveData
->GetExistingDimensionByName(aName
) : nullptr;
839 if ( !pDimension
|| (pDimension
->GetOrientation() != nOrient
) )
843 const OUString
* pLayoutName
= pDimension
->GetLayoutName();
845 aName
= *pLayoutName
;
847 mpLbDims
->InsertEntry( aName
);
848 maNameIndexMap
.insert(DimNameIndexMap::value_type(aName
, nDim
));
852 if( mpLbDims
->GetEntryCount() )
853 mpLbDims
->SelectEntryPos( 0 );
855 mpLbDims
->SetDoubleClickHdl( LINK( this, ScDPShowDetailDlg
, DblClickHdl
) );
858 ScDPShowDetailDlg::~ScDPShowDetailDlg()
863 void ScDPShowDetailDlg::dispose()
867 ModalDialog::dispose();
870 short ScDPShowDetailDlg::Execute()
872 return mpLbDims
->GetEntryCount() ? ModalDialog::Execute() : static_cast<short>(RET_CANCEL
);
875 OUString
ScDPShowDetailDlg::GetDimensionName() const
877 // Look up the internal dimension name which may be different from the
878 // displayed field name.
879 OUString aSelectedName
= mpLbDims
->GetSelectEntry();
880 DimNameIndexMap::const_iterator itr
= maNameIndexMap
.find(aSelectedName
);
881 if (itr
== maNameIndexMap
.end())
882 // This should never happen!
883 return aSelectedName
;
885 long nDim
= itr
->second
;
886 bool bIsDataLayout
= false;
887 return mrDPObj
.GetDimName(nDim
, bIsDataLayout
);
890 IMPL_LINK_TYPED( ScDPShowDetailDlg
, DblClickHdl
, ListBox
&, rLBox
, void )
892 if( &rLBox
== mpLbDims
)
896 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */