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 #undef SC_DLLIMPLEMENTATION
28
29 #include "pvfundlg.hxx"
30
31 #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
32 #include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
33 #include <com/sun/star/sheet/DataPilotFieldLayoutMode.hpp>
34 #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
35 #include <com/sun/star/sheet/DataPilotFieldShowItemsMode.hpp>
36
37 #include <tools/resary.hxx>
38 #include <vcl/msgbox.hxx>
39
40 #include "scresid.hxx"
41 #include "dpobject.hxx"
42 #include "dpsave.hxx"
43 #include "pvfundlg.hrc"
44 #include "globstr.hrc"
45
46 #include <vector>
47
48 // ============================================================================
49
50 using namespace ::com::sun::star::sheet;
51
52 using ::rtl::OUString;
53 using ::com::sun::star::uno::Sequence;
54 using ::std::vector;
55
56 // ============================================================================
57
58 namespace {
59
60 /** Appends all strings from the Sequence to the list box.
61
62 Empty strings are replaced by a localized "(empty)" entry and inserted at
63 the specified position.
64
65 @return true = The passed string list contains an empty string entry.
66 */
67 template< typename ListBoxType >
lclFillListBox(ListBoxType & rLBox,const Sequence<OUString> & rStrings,sal_uInt16 nEmptyPos=LISTBOX_APPEND)68 bool lclFillListBox( ListBoxType& rLBox, const Sequence< OUString >& rStrings, sal_uInt16 nEmptyPos = LISTBOX_APPEND )
69 {
70 bool bEmpty = false;
71 if( const OUString* pStr = rStrings.getConstArray() )
72 {
73 for( const OUString* pEnd = pStr + rStrings.getLength(); pStr != pEnd; ++pStr )
74 {
75 if( pStr->getLength() )
76 rLBox.InsertEntry( *pStr );
77 else
78 {
79 rLBox.InsertEntry( ScGlobal::GetRscString( STR_EMPTYDATA ), nEmptyPos );
80 bEmpty = true;
81 }
82 }
83 }
84 return bEmpty;
85 }
86
87 template< typename ListBoxType >
lclFillListBox(ListBoxType & rLBox,const vector<ScDPLabelData::Member> & rMembers,sal_uInt16 nEmptyPos=LISTBOX_APPEND)88 bool lclFillListBox( ListBoxType& rLBox, const vector<ScDPLabelData::Member>& rMembers, sal_uInt16 nEmptyPos = LISTBOX_APPEND )
89 {
90 bool bEmpty = false;
91 vector<ScDPLabelData::Member>::const_iterator itr = rMembers.begin(), itrEnd = rMembers.end();
92 for (; itr != itrEnd; ++itr)
93 {
94 OUString aName = itr->getDisplayName();
95 if (aName.getLength())
96 rLBox.InsertEntry(aName);
97 else
98 {
99 rLBox.InsertEntry(ScGlobal::GetRscString(STR_EMPTYDATA), nEmptyPos);
100 bEmpty = true;
101 }
102 }
103 return bEmpty;
104 }
105
106 /** Searches for a listbox entry, starts search at specified position. */
lclFindListBoxEntry(const ListBox & rLBox,const String & rEntry,sal_uInt16 nStartPos)107 sal_uInt16 lclFindListBoxEntry( const ListBox& rLBox, const String& rEntry, sal_uInt16 nStartPos )
108 {
109 sal_uInt16 nPos = nStartPos;
110 while( (nPos < rLBox.GetEntryCount()) && (rLBox.GetEntry( nPos ) != rEntry) )
111 ++nPos;
112 return (nPos < rLBox.GetEntryCount()) ? nPos : LISTBOX_ENTRY_NOTFOUND;
113 }
114
115 /** This table represents the order of the strings in the resource string array. */
116 static const sal_uInt16 spnFunctions[] =
117 {
118 PIVOT_FUNC_SUM,
119 PIVOT_FUNC_COUNT,
120 PIVOT_FUNC_AVERAGE,
121 PIVOT_FUNC_MAX,
122 PIVOT_FUNC_MIN,
123 PIVOT_FUNC_PRODUCT,
124 PIVOT_FUNC_COUNT_NUM,
125 PIVOT_FUNC_STD_DEV,
126 PIVOT_FUNC_STD_DEVP,
127 PIVOT_FUNC_STD_VAR,
128 PIVOT_FUNC_STD_VARP
129 };
130
131 const sal_uInt16 SC_BASEITEM_PREV_POS = 0;
132 const sal_uInt16 SC_BASEITEM_NEXT_POS = 1;
133 const sal_uInt16 SC_BASEITEM_USER_POS = 2;
134
135 const sal_uInt16 SC_SORTNAME_POS = 0;
136 const sal_uInt16 SC_SORTDATA_POS = 1;
137
138 const long SC_SHOW_DEFAULT = 10;
139
140 static const ScDPListBoxWrapper::MapEntryType spRefTypeMap[] =
141 {
142 { 0, DataPilotFieldReferenceType::NONE },
143 { 1, DataPilotFieldReferenceType::ITEM_DIFFERENCE },
144 { 2, DataPilotFieldReferenceType::ITEM_PERCENTAGE },
145 { 3, DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE },
146 { 4, DataPilotFieldReferenceType::RUNNING_TOTAL },
147 { 5, DataPilotFieldReferenceType::ROW_PERCENTAGE },
148 { 6, DataPilotFieldReferenceType::COLUMN_PERCENTAGE },
149 { 7, DataPilotFieldReferenceType::TOTAL_PERCENTAGE },
150 { 8, DataPilotFieldReferenceType::INDEX },
151 { LISTBOX_ENTRY_NOTFOUND, DataPilotFieldReferenceType::NONE }
152 };
153
154 static const ScDPListBoxWrapper::MapEntryType spLayoutMap[] =
155 {
156 { 0, DataPilotFieldLayoutMode::TABULAR_LAYOUT },
157 { 1, DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_TOP },
158 { 2, DataPilotFieldLayoutMode::OUTLINE_SUBTOTALS_BOTTOM },
159 { LISTBOX_ENTRY_NOTFOUND, DataPilotFieldLayoutMode::TABULAR_LAYOUT }
160 };
161
162 static const ScDPListBoxWrapper::MapEntryType spShowFromMap[] =
163 {
164 { 0, DataPilotFieldShowItemsMode::FROM_TOP },
165 { 1, DataPilotFieldShowItemsMode::FROM_BOTTOM },
166 { LISTBOX_ENTRY_NOTFOUND, DataPilotFieldShowItemsMode::FROM_TOP }
167 };
168
169 } // namespace
170
171 // ============================================================================
172
ScDPFunctionListBox(Window * pParent,const ResId & rResId)173 ScDPFunctionListBox::ScDPFunctionListBox( Window* pParent, const ResId& rResId ) :
174 MultiListBox( pParent, rResId )
175 {
176 FillFunctionNames();
177 }
178
SetSelection(sal_uInt16 nFuncMask)179 void ScDPFunctionListBox::SetSelection( sal_uInt16 nFuncMask )
180 {
181 if( (nFuncMask == PIVOT_FUNC_NONE) || (nFuncMask == PIVOT_FUNC_AUTO) )
182 SetNoSelection();
183 else
184 for( sal_uInt16 nEntry = 0, nCount = GetEntryCount(); nEntry < nCount; ++nEntry )
185 SelectEntryPos( nEntry, (nFuncMask & spnFunctions[ nEntry ]) != 0 );
186 }
187
GetSelection() const188 sal_uInt16 ScDPFunctionListBox::GetSelection() const
189 {
190 sal_uInt16 nFuncMask = PIVOT_FUNC_NONE;
191 for( sal_uInt16 nSel = 0, nCount = GetSelectEntryCount(); nSel < nCount; ++nSel )
192 nFuncMask |= spnFunctions[ GetSelectEntryPos( nSel ) ];
193 return nFuncMask;
194 }
195
FillFunctionNames()196 void ScDPFunctionListBox::FillFunctionNames()
197 {
198 DBG_ASSERT( !GetEntryCount(), "ScDPFunctionListBox::FillFunctionNames - do not add texts to resource" );
199 Clear();
200 ResStringArray aArr( ScResId( SCSTR_DPFUNCLISTBOX ) );
201 for( sal_uInt16 nIndex = 0, nCount = sal::static_int_cast<sal_uInt16>(aArr.Count()); nIndex < nCount; ++nIndex )
202 InsertEntry( aArr.GetString( nIndex ) );
203 }
204
205 // ============================================================================
206
ScDPFunctionDlg(Window * pParent,const ScDPLabelDataVector & rLabelVec,const ScDPLabelData & rLabelData,const ScPivotFuncData & rFuncData)207 ScDPFunctionDlg::ScDPFunctionDlg(
208 Window* pParent, const ScDPLabelDataVector& rLabelVec,
209 const ScDPLabelData& rLabelData, const ScPivotFuncData& rFuncData ) :
210 ModalDialog ( pParent, ScResId( RID_SCDLG_DPDATAFIELD ) ),
211 maFlFunc ( this, ScResId( FL_FUNC ) ),
212 maLbFunc ( this, ScResId( LB_FUNC ) ),
213 maFtNameLabel ( this, ScResId( FT_NAMELABEL ) ),
214 maFtName ( this, ScResId( FT_NAME ) ),
215 maFlDisplay ( this, ScResId( FL_DISPLAY ) ),
216 maFtType ( this, ScResId( FT_TYPE ) ),
217 maLbType ( this, ScResId( LB_TYPE ) ),
218 maFtBaseField ( this, ScResId( FT_BASEFIELD ) ),
219 maLbBaseField ( this, ScResId( LB_BASEFIELD ) ),
220 maFtBaseItem ( this, ScResId( FT_BASEITEM ) ),
221 maLbBaseItem ( this, ScResId( LB_BASEITEM ) ),
222 maBtnOk ( this, ScResId( BTN_OK ) ),
223 maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
224 maBtnHelp ( this, ScResId( BTN_HELP ) ),
225 maBtnMore ( this, ScResId( BTN_MORE ) ),
226 maLbTypeWrp ( maLbType, spRefTypeMap ),
227 mrLabelVec ( rLabelVec ),
228 mbEmptyItem ( false )
229 {
230 FreeResource();
231 Init( rLabelData, rFuncData );
232 }
233
GetFuncMask() const234 sal_uInt16 ScDPFunctionDlg::GetFuncMask() const
235 {
236 return maLbFunc.GetSelection();
237 }
238
GetFieldRef() const239 DataPilotFieldReference ScDPFunctionDlg::GetFieldRef() const
240 {
241 DataPilotFieldReference aRef;
242
243 aRef.ReferenceType = maLbTypeWrp.GetControlValue();
244 aRef.ReferenceField = maLbBaseField.GetSelectEntry();
245
246 sal_uInt16 nBaseItemPos = maLbBaseItem.GetSelectEntryPos();
247 switch( nBaseItemPos )
248 {
249 case SC_BASEITEM_PREV_POS:
250 aRef.ReferenceItemType = DataPilotFieldReferenceItemType::PREVIOUS;
251 break;
252 case SC_BASEITEM_NEXT_POS:
253 aRef.ReferenceItemType = DataPilotFieldReferenceItemType::NEXT;
254 break;
255 default:
256 {
257 aRef.ReferenceItemType = DataPilotFieldReferenceItemType::NAMED;
258 if( !mbEmptyItem || (nBaseItemPos > SC_BASEITEM_USER_POS) )
259 aRef.ReferenceItemName = maLbBaseItem.GetSelectEntry();
260 }
261 }
262
263 return aRef;
264 }
265
Init(const ScDPLabelData & rLabelData,const ScPivotFuncData & rFuncData)266 void ScDPFunctionDlg::Init( const ScDPLabelData& rLabelData, const ScPivotFuncData& rFuncData )
267 {
268 // list box
269 sal_uInt16 nFuncMask = (rFuncData.mnFuncMask == PIVOT_FUNC_NONE) ? PIVOT_FUNC_SUM : rFuncData.mnFuncMask;
270 maLbFunc.SetSelection( nFuncMask );
271
272 // field name
273 maFtName.SetText(rLabelData.getDisplayName());
274
275 // "More button" controls
276 maBtnMore.AddWindow( &maFlDisplay );
277 maBtnMore.AddWindow( &maFtType );
278 maBtnMore.AddWindow( &maLbType );
279 maBtnMore.AddWindow( &maFtBaseField );
280 maBtnMore.AddWindow( &maLbBaseField );
281 maBtnMore.AddWindow( &maFtBaseItem );
282 maBtnMore.AddWindow( &maLbBaseItem );
283
284 // handlers
285 maLbFunc.SetDoubleClickHdl( LINK( this, ScDPFunctionDlg, DblClickHdl ) );
286 maLbType.SetSelectHdl( LINK( this, ScDPFunctionDlg, SelectHdl ) );
287 maLbBaseField.SetSelectHdl( LINK( this, ScDPFunctionDlg, SelectHdl ) );
288
289 // base field list box
290 for( ScDPLabelDataVector::const_iterator aIt = mrLabelVec.begin(), aEnd = mrLabelVec.end(); aIt != aEnd; ++aIt )
291 maLbBaseField.InsertEntry(aIt->getDisplayName());
292
293 // base item list box
294 maLbBaseItem.SetSeparatorPos( SC_BASEITEM_USER_POS - 1 );
295
296 // select field reference type
297 maLbTypeWrp.SetControlValue( rFuncData.maFieldRef.ReferenceType );
298 SelectHdl( &maLbType ); // enables base field/item list boxes
299
300 // select base field
301 maLbBaseField.SelectEntry( rFuncData.maFieldRef.ReferenceField );
302 if( maLbBaseField.GetSelectEntryPos() >= maLbBaseField.GetEntryCount() )
303 maLbBaseField.SelectEntryPos( 0 );
304 SelectHdl( &maLbBaseField ); // fills base item list, selects base item
305
306 // select base item
307 switch( rFuncData.maFieldRef.ReferenceItemType )
308 {
309 case DataPilotFieldReferenceItemType::PREVIOUS:
310 maLbBaseItem.SelectEntryPos( SC_BASEITEM_PREV_POS );
311 break;
312 case DataPilotFieldReferenceItemType::NEXT:
313 maLbBaseItem.SelectEntryPos( SC_BASEITEM_NEXT_POS );
314 break;
315 default:
316 {
317 if( mbEmptyItem && !rFuncData.maFieldRef.ReferenceItemName.getLength() )
318 {
319 // select special "(empty)" entry added before other items
320 maLbBaseItem.SelectEntryPos( SC_BASEITEM_USER_POS );
321 }
322 else
323 {
324 sal_uInt16 nStartPos = mbEmptyItem ? (SC_BASEITEM_USER_POS + 1) : SC_BASEITEM_USER_POS;
325 sal_uInt16 nPos = lclFindListBoxEntry( maLbBaseItem, rFuncData.maFieldRef.ReferenceItemName, nStartPos );
326 if( nPos >= maLbBaseItem.GetEntryCount() )
327 nPos = (maLbBaseItem.GetEntryCount() > SC_BASEITEM_USER_POS) ? SC_BASEITEM_USER_POS : SC_BASEITEM_PREV_POS;
328 maLbBaseItem.SelectEntryPos( nPos );
329 }
330 }
331 }
332 }
333
IMPL_LINK(ScDPFunctionDlg,SelectHdl,ListBox *,pLBox)334 IMPL_LINK( ScDPFunctionDlg, SelectHdl, ListBox*, pLBox )
335 {
336 if( pLBox == &maLbType )
337 {
338 bool bEnableField, bEnableItem;
339 switch( maLbTypeWrp.GetControlValue() )
340 {
341 case DataPilotFieldReferenceType::ITEM_DIFFERENCE:
342 case DataPilotFieldReferenceType::ITEM_PERCENTAGE:
343 case DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE:
344 bEnableField = bEnableItem = true;
345 break;
346
347 case DataPilotFieldReferenceType::RUNNING_TOTAL:
348 bEnableField = true;
349 bEnableItem = false;
350 break;
351
352 default:
353 bEnableField = bEnableItem = false;
354 }
355
356 bEnableField &= maLbBaseField.GetEntryCount() > 0;
357 maFtBaseField.Enable( bEnableField );
358 maLbBaseField.Enable( bEnableField );
359
360 bEnableItem &= bEnableField;
361 maFtBaseItem.Enable( bEnableItem );
362 maLbBaseItem.Enable( bEnableItem );
363 }
364 else if( pLBox == &maLbBaseField )
365 {
366 // keep "previous" and "next" entries
367 while( maLbBaseItem.GetEntryCount() > SC_BASEITEM_USER_POS )
368 maLbBaseItem.RemoveEntry( SC_BASEITEM_USER_POS );
369
370 // update item list for current base field
371 mbEmptyItem = false;
372 size_t nBasePos = maLbBaseField.GetSelectEntryPos();
373 if( nBasePos < mrLabelVec.size() )
374 mbEmptyItem = lclFillListBox( maLbBaseItem, mrLabelVec[ nBasePos ].maMembers, SC_BASEITEM_USER_POS );
375
376 // select base item
377 sal_uInt16 nItemPos = (maLbBaseItem.GetEntryCount() > SC_BASEITEM_USER_POS) ? SC_BASEITEM_USER_POS : SC_BASEITEM_PREV_POS;
378 maLbBaseItem.SelectEntryPos( nItemPos );
379 }
380 return 0;
381 }
382
IMPL_LINK(ScDPFunctionDlg,DblClickHdl,MultiListBox *,EMPTYARG)383 IMPL_LINK( ScDPFunctionDlg, DblClickHdl, MultiListBox*, EMPTYARG )
384 {
385 maBtnOk.Click();
386 return 0;
387 }
388
389 // ============================================================================
390
ScDPSubtotalDlg(Window * pParent,ScDPObject & rDPObj,const ScDPLabelData & rLabelData,const ScPivotFuncData & rFuncData,const ScDPNameVec & rDataFields,bool bEnableLayout)391 ScDPSubtotalDlg::ScDPSubtotalDlg( Window* pParent, ScDPObject& rDPObj,
392 const ScDPLabelData& rLabelData, const ScPivotFuncData& rFuncData,
393 const ScDPNameVec& rDataFields, bool bEnableLayout ) :
394 ModalDialog ( pParent, ScResId( RID_SCDLG_PIVOTSUBT ) ),
395 maFlSubt ( this, ScResId( FL_FUNC ) ),
396 maRbNone ( this, ScResId( RB_NONE ) ),
397 maRbAuto ( this, ScResId( RB_AUTO ) ),
398 maRbUser ( this, ScResId( RB_USER ) ),
399 maLbFunc ( this, ScResId( LB_FUNC ) ),
400 maFtNameLabel ( this, ScResId( FT_NAMELABEL ) ),
401 maFtName ( this, ScResId( FT_NAME ) ),
402 maCbShowAll ( this, ScResId( CB_SHOWALL ) ),
403 maBtnOk ( this, ScResId( BTN_OK ) ),
404 maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
405 maBtnHelp ( this, ScResId( BTN_HELP ) ),
406 maBtnOptions ( this, ScResId( BTN_OPTIONS ) ),
407 mrDPObj ( rDPObj ),
408 mrDataFields ( rDataFields ),
409 maLabelData ( rLabelData ),
410 mbEnableLayout ( bEnableLayout )
411 {
412 FreeResource();
413 Init( rLabelData, rFuncData );
414 }
415
GetFuncMask() const416 sal_uInt16 ScDPSubtotalDlg::GetFuncMask() const
417 {
418 sal_uInt16 nFuncMask = PIVOT_FUNC_NONE;
419
420 if( maRbAuto.IsChecked() )
421 nFuncMask = PIVOT_FUNC_AUTO;
422 else if( maRbUser.IsChecked() )
423 nFuncMask = maLbFunc.GetSelection();
424
425 return nFuncMask;
426 }
427
FillLabelData(ScDPLabelData & rLabelData) const428 void ScDPSubtotalDlg::FillLabelData( ScDPLabelData& rLabelData ) const
429 {
430 rLabelData.mnFuncMask = GetFuncMask();
431 rLabelData.mnUsedHier = maLabelData.mnUsedHier;
432 rLabelData.mbShowAll = maCbShowAll.IsChecked();
433 rLabelData.maMembers = maLabelData.maMembers;
434 rLabelData.maSortInfo = maLabelData.maSortInfo;
435 rLabelData.maLayoutInfo = maLabelData.maLayoutInfo;
436 rLabelData.maShowInfo = maLabelData.maShowInfo;
437 }
438
Init(const ScDPLabelData & rLabelData,const ScPivotFuncData & rFuncData)439 void ScDPSubtotalDlg::Init( const ScDPLabelData& rLabelData, const ScPivotFuncData& rFuncData )
440 {
441 // field name
442 maFtName.SetText(rLabelData.getDisplayName());
443
444 // radio buttons
445 maRbNone.SetClickHdl( LINK( this, ScDPSubtotalDlg, RadioClickHdl ) );
446 maRbAuto.SetClickHdl( LINK( this, ScDPSubtotalDlg, RadioClickHdl ) );
447 maRbUser.SetClickHdl( LINK( this, ScDPSubtotalDlg, RadioClickHdl ) );
448
449 RadioButton* pRBtn = 0;
450 switch( rFuncData.mnFuncMask )
451 {
452 case PIVOT_FUNC_NONE: pRBtn = &maRbNone; break;
453 case PIVOT_FUNC_AUTO: pRBtn = &maRbAuto; break;
454 default: pRBtn = &maRbUser;
455 }
456 pRBtn->Check();
457 RadioClickHdl( pRBtn );
458
459 // list box
460 maLbFunc.SetSelection( rFuncData.mnFuncMask );
461 maLbFunc.SetDoubleClickHdl( LINK( this, ScDPSubtotalDlg, DblClickHdl ) );
462
463 // show all
464 maCbShowAll.Check( rLabelData.mbShowAll );
465
466 // options
467 maBtnOptions.SetClickHdl( LINK( this, ScDPSubtotalDlg, ClickHdl ) );
468 }
469
470 // ----------------------------------------------------------------------------
471
IMPL_LINK(ScDPSubtotalDlg,RadioClickHdl,RadioButton *,pBtn)472 IMPL_LINK( ScDPSubtotalDlg, RadioClickHdl, RadioButton*, pBtn )
473 {
474 maLbFunc.Enable( pBtn == &maRbUser );
475 return 0;
476 }
477
IMPL_LINK(ScDPSubtotalDlg,DblClickHdl,MultiListBox *,EMPTYARG)478 IMPL_LINK( ScDPSubtotalDlg, DblClickHdl, MultiListBox*, EMPTYARG )
479 {
480 maBtnOk.Click();
481 return 0;
482 }
483
IMPL_LINK(ScDPSubtotalDlg,ClickHdl,PushButton *,pBtn)484 IMPL_LINK( ScDPSubtotalDlg, ClickHdl, PushButton*, pBtn )
485 {
486 if( pBtn == &maBtnOptions )
487 {
488 ScDPSubtotalOptDlg* pDlg = new ScDPSubtotalOptDlg( this, mrDPObj, maLabelData, mrDataFields, mbEnableLayout );
489 if( pDlg->Execute() == RET_OK )
490 pDlg->FillLabelData( maLabelData );
491 delete pDlg;
492 }
493 return 0;
494 }
495
496 // ============================================================================
497
ScDPSubtotalOptDlg(Window * pParent,ScDPObject & rDPObj,const ScDPLabelData & rLabelData,const ScDPNameVec & rDataFields,bool bEnableLayout)498 ScDPSubtotalOptDlg::ScDPSubtotalOptDlg( Window* pParent, ScDPObject& rDPObj,
499 const ScDPLabelData& rLabelData, const ScDPNameVec& rDataFields,
500 bool bEnableLayout ) :
501 ModalDialog ( pParent, ScResId( RID_SCDLG_DPSUBTOTAL_OPT ) ),
502 maFlSortBy ( this, ScResId( FL_SORT_BY ) ),
503 maLbSortBy ( this, ScResId( LB_SORT_BY ) ),
504 maRbSortAsc ( this, ScResId( RB_SORT_ASC ) ),
505 maRbSortDesc ( this, ScResId( RB_SORT_DESC ) ),
506 maRbSortMan ( this, ScResId( RB_SORT_MAN ) ),
507 maFlLayout ( this, ScResId( FL_LAYOUT ) ),
508 maFtLayout ( this, ScResId( FT_LAYOUT ) ),
509 maLbLayout ( this, ScResId( LB_LAYOUT ) ),
510 maCbLayoutEmpty ( this, ScResId( CB_LAYOUT_EMPTY ) ),
511 maFlAutoShow ( this, ScResId( FL_AUTOSHOW ) ),
512 maCbShow ( this, ScResId( CB_SHOW ) ),
513 maNfShow ( this, ScResId( NF_SHOW ) ),
514 maFtShow ( this, ScResId( FT_SHOW ) ),
515 maFtShowFrom ( this, ScResId( FT_SHOW_FROM ) ),
516 maLbShowFrom ( this, ScResId( LB_SHOW_FROM ) ),
517 maFtShowUsing ( this, ScResId( FT_SHOW_USING ) ),
518 maLbShowUsing ( this, ScResId( LB_SHOW_USING ) ),
519 maFlHide ( this, ScResId( FL_HIDE ) ),
520 maLbHide ( this, ScResId( CT_HIDE ) ),
521 maFtHierarchy ( this, ScResId( FT_HIERARCHY ) ),
522 maLbHierarchy ( this, ScResId( LB_HIERARCHY ) ),
523 maBtnOk ( this, ScResId( BTN_OK ) ),
524 maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
525 maBtnHelp ( this, ScResId( BTN_HELP ) ),
526 maLbLayoutWrp ( maLbLayout, spLayoutMap ),
527 maLbShowFromWrp ( maLbShowFrom, spShowFromMap ),
528 mrDPObj ( rDPObj ),
529 maLabelData ( rLabelData )
530 {
531 FreeResource();
532 Init( rDataFields, bEnableLayout );
533 }
534
FillLabelData(ScDPLabelData & rLabelData) const535 void ScDPSubtotalOptDlg::FillLabelData( ScDPLabelData& rLabelData ) const
536 {
537 // *** SORTING ***
538
539 if( maRbSortMan.IsChecked() )
540 rLabelData.maSortInfo.Mode = DataPilotFieldSortMode::MANUAL;
541 else if( maLbSortBy.GetSelectEntryPos() == SC_SORTNAME_POS )
542 rLabelData.maSortInfo.Mode = DataPilotFieldSortMode::NAME;
543 else
544 rLabelData.maSortInfo.Mode = DataPilotFieldSortMode::DATA;
545
546 rLabelData.maSortInfo.Field = maLbSortBy.GetSelectEntry();
547 rLabelData.maSortInfo.IsAscending = maRbSortAsc.IsChecked();
548
549 // *** LAYOUT MODE ***
550
551 rLabelData.maLayoutInfo.LayoutMode = maLbLayoutWrp.GetControlValue();
552 rLabelData.maLayoutInfo.AddEmptyLines = maCbLayoutEmpty.IsChecked();
553
554 // *** AUTO SHOW ***
555
556 rLabelData.maShowInfo.IsEnabled = maCbShow.IsChecked();
557 rLabelData.maShowInfo.ShowItemsMode = maLbShowFromWrp.GetControlValue();
558 rLabelData.maShowInfo.ItemCount = sal::static_int_cast<sal_Int32>( maNfShow.GetValue() );
559 rLabelData.maShowInfo.DataField = maLbShowUsing.GetSelectEntry();
560
561 // *** HIDDEN ITEMS ***
562
563 rLabelData.maMembers = maLabelData.maMembers;
564 sal_uLong nVisCount = maLbHide.GetEntryCount();
565 for( sal_uInt16 nPos = 0; nPos < nVisCount; ++nPos )
566 rLabelData.maMembers[nPos].mbVisible = !maLbHide.IsChecked(nPos);
567
568 // *** HIERARCHY ***
569
570 rLabelData.mnUsedHier = maLbHierarchy.GetSelectEntryCount() ? maLbHierarchy.GetSelectEntryPos() : 0;
571 }
572
Init(const ScDPNameVec & rDataFields,bool bEnableLayout)573 void ScDPSubtotalOptDlg::Init( const ScDPNameVec& rDataFields, bool bEnableLayout )
574 {
575 // *** SORTING ***
576
577 sal_Int32 nSortMode = maLabelData.maSortInfo.Mode;
578
579 // sort fields list box
580 maLbSortBy.InsertEntry(maLabelData.getDisplayName());
581
582 for( ScDPNameVec::const_iterator aIt = rDataFields.begin(), aEnd = rDataFields.end(); aIt != aEnd; ++aIt )
583 {
584 maLbSortBy.InsertEntry( *aIt );
585 maLbShowUsing.InsertEntry( *aIt ); // for AutoShow
586 }
587 if( maLbSortBy.GetEntryCount() > SC_SORTDATA_POS )
588 maLbSortBy.SetSeparatorPos( SC_SORTDATA_POS - 1 );
589
590 sal_uInt16 nSortPos = SC_SORTNAME_POS;
591 if( nSortMode == DataPilotFieldSortMode::DATA )
592 {
593 nSortPos = lclFindListBoxEntry( maLbSortBy, maLabelData.maSortInfo.Field, SC_SORTDATA_POS );
594 if( nSortPos >= maLbSortBy.GetEntryCount() )
595 {
596 nSortPos = SC_SORTNAME_POS;
597 nSortMode = DataPilotFieldSortMode::MANUAL;
598 }
599 }
600 maLbSortBy.SelectEntryPos( nSortPos );
601
602 // sorting mode
603 maRbSortAsc.SetClickHdl( LINK( this, ScDPSubtotalOptDlg, RadioClickHdl ) );
604 maRbSortDesc.SetClickHdl( LINK( this, ScDPSubtotalOptDlg, RadioClickHdl ) );
605 maRbSortMan.SetClickHdl( LINK( this, ScDPSubtotalOptDlg, RadioClickHdl ) );
606
607 RadioButton* pRBtn = 0;
608 switch( nSortMode )
609 {
610 case DataPilotFieldSortMode::NONE:
611 case DataPilotFieldSortMode::MANUAL:
612 pRBtn = &maRbSortMan;
613 break;
614 default:
615 pRBtn = maLabelData.maSortInfo.IsAscending ? &maRbSortAsc : &maRbSortDesc;
616 }
617 pRBtn->Check();
618 RadioClickHdl( pRBtn );
619
620 // *** LAYOUT MODE ***
621
622 maFlLayout.Enable( bEnableLayout );
623 maFtLayout.Enable( bEnableLayout );
624 maLbLayout.Enable( bEnableLayout );
625 maCbLayoutEmpty.Enable( bEnableLayout );
626
627 maLbLayoutWrp.SetControlValue( maLabelData.maLayoutInfo.LayoutMode );
628 maCbLayoutEmpty.Check( maLabelData.maLayoutInfo.AddEmptyLines );
629
630 // *** AUTO SHOW ***
631
632 maCbShow.Check( maLabelData.maShowInfo.IsEnabled );
633 maCbShow.SetClickHdl( LINK( this, ScDPSubtotalOptDlg, CheckHdl ) );
634
635 maLbShowFromWrp.SetControlValue( maLabelData.maShowInfo.ShowItemsMode );
636 long nCount = static_cast< long >( maLabelData.maShowInfo.ItemCount );
637 if( nCount < 1 )
638 nCount = SC_SHOW_DEFAULT;
639 maNfShow.SetValue( nCount );
640
641 // maLbShowUsing already filled above
642 maLbShowUsing.SelectEntry( maLabelData.maShowInfo.DataField );
643 if( maLbShowUsing.GetSelectEntryPos() >= maLbShowUsing.GetEntryCount() )
644 maLbShowUsing.SelectEntryPos( 0 );
645
646 CheckHdl( &maCbShow ); // enable/disable dependent controls
647
648 // *** HIDDEN ITEMS ***
649
650 maLbHide.SetHelpId( HID_SC_DPSUBT_HIDE );
651 InitHideListBox();
652
653 // *** HIERARCHY ***
654
655 if( maLabelData.maHiers.getLength() > 1 )
656 {
657 lclFillListBox( maLbHierarchy, maLabelData.maHiers );
658 sal_Int32 nHier = maLabelData.mnUsedHier;
659 if( (nHier < 0) || (nHier >= maLabelData.maHiers.getLength()) ) nHier = 0;
660 maLbHierarchy.SelectEntryPos( static_cast< sal_uInt16 >( nHier ) );
661 maLbHierarchy.SetSelectHdl( LINK( this, ScDPSubtotalOptDlg, SelectHdl ) );
662 }
663 else
664 {
665 maFtHierarchy.Disable();
666 maLbHierarchy.Disable();
667 }
668 }
669
InitHideListBox()670 void ScDPSubtotalOptDlg::InitHideListBox()
671 {
672 maLbHide.Clear();
673 lclFillListBox( maLbHide, maLabelData.maMembers );
674 size_t n = maLabelData.maMembers.size();
675 for (size_t i = 0; i < n; ++i)
676 maLbHide.CheckEntryPos(static_cast<sal_uInt16>(i), !maLabelData.maMembers[i].mbVisible);
677 bool bEnable = maLbHide.GetEntryCount() > 0;
678 maFlHide.Enable( bEnable );
679 maLbHide.Enable( bEnable );
680 }
681
IMPL_LINK(ScDPSubtotalOptDlg,RadioClickHdl,RadioButton *,pBtn)682 IMPL_LINK( ScDPSubtotalOptDlg, RadioClickHdl, RadioButton*, pBtn )
683 {
684 maLbSortBy.Enable( pBtn != &maRbSortMan );
685 return 0;
686 }
687
IMPL_LINK(ScDPSubtotalOptDlg,CheckHdl,CheckBox *,pCBox)688 IMPL_LINK( ScDPSubtotalOptDlg, CheckHdl, CheckBox*, pCBox )
689 {
690 if( pCBox == &maCbShow )
691 {
692 bool bEnable = maCbShow.IsChecked();
693 maNfShow.Enable( bEnable );
694 maFtShow.Enable( bEnable );
695 maFtShowFrom.Enable( bEnable );
696 maLbShowFrom.Enable( bEnable );
697
698 bool bEnableUsing = bEnable && (maLbShowUsing.GetEntryCount() > 0);
699 maFtShowUsing.Enable( bEnableUsing );
700 maLbShowUsing.Enable( bEnableUsing );
701 }
702 return 0;
703 }
704
IMPL_LINK(ScDPSubtotalOptDlg,SelectHdl,ListBox *,pLBox)705 IMPL_LINK( ScDPSubtotalOptDlg, SelectHdl, ListBox*, pLBox )
706 {
707 if( pLBox == &maLbHierarchy )
708 {
709 mrDPObj.GetMembers(maLabelData.mnCol, maLbHierarchy.GetSelectEntryPos(), maLabelData.maMembers);
710 InitHideListBox();
711 }
712 return 0;
713 }
714
715 // ============================================================================
716
ScDPShowDetailDlg(Window * pParent,ScDPObject & rDPObj,sal_uInt16 nOrient)717 ScDPShowDetailDlg::ScDPShowDetailDlg( Window* pParent, ScDPObject& rDPObj, sal_uInt16 nOrient ) :
718 ModalDialog ( pParent, ScResId( RID_SCDLG_DPSHOWDETAIL ) ),
719 maFtDims ( this, ScResId( FT_DIMS ) ),
720 maLbDims ( this, ScResId( LB_DIMS ) ),
721 maBtnOk ( this, ScResId( BTN_OK ) ),
722 maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
723 maBtnHelp ( this, ScResId( BTN_HELP ) ),
724
725 mrDPObj(rDPObj)
726 {
727 FreeResource();
728
729 ScDPSaveData* pSaveData = rDPObj.GetSaveData();
730 long nDimCount = rDPObj.GetDimCount();
731 for (long nDim=0; nDim<nDimCount; nDim++)
732 {
733 sal_Bool bIsDataLayout;
734 sal_Int32 nDimFlags = 0;
735 String aName = rDPObj.GetDimName( nDim, bIsDataLayout, &nDimFlags );
736 if ( !bIsDataLayout && !rDPObj.IsDuplicated( nDim ) && ScDPObject::IsOrientationAllowed( nOrient, nDimFlags ) )
737 {
738 const ScDPSaveDimension* pDimension = pSaveData ? pSaveData->GetExistingDimensionByName(aName) : 0;
739 if ( !pDimension || (pDimension->GetOrientation() != nOrient) )
740 {
741 if (pDimension)
742 {
743 const OUString* pLayoutName = pDimension->GetLayoutName();
744 if (pLayoutName)
745 aName = *pLayoutName;
746 }
747 if ( aName.Len() )
748 {
749 maLbDims.InsertEntry( aName );
750 maNameIndexMap.insert(DimNameIndexMap::value_type(aName, nDim));
751 }
752 }
753 }
754 }
755 if( maLbDims.GetEntryCount() )
756 maLbDims.SelectEntryPos( 0 );
757
758 maLbDims.SetDoubleClickHdl( LINK( this, ScDPShowDetailDlg, DblClickHdl ) );
759 }
760
Execute()761 short ScDPShowDetailDlg::Execute()
762 {
763 return maLbDims.GetEntryCount() ? ModalDialog::Execute() : RET_CANCEL;
764 }
765
GetDimensionName() const766 String ScDPShowDetailDlg::GetDimensionName() const
767 {
768 // Look up the internal dimension name which may be different from the
769 // displayed field name.
770 String aSelectedName = maLbDims.GetSelectEntry();
771 DimNameIndexMap::const_iterator itr = maNameIndexMap.find(aSelectedName);
772 if (itr == maNameIndexMap.end())
773 // This should never happen!
774 return aSelectedName;
775
776 long nDim = itr->second;
777 sal_Bool bIsDataLayout = false;
778 return mrDPObj.GetDimName(nDim, bIsDataLayout);
779 }
780
IMPL_LINK(ScDPShowDetailDlg,DblClickHdl,ListBox *,pLBox)781 IMPL_LINK( ScDPShowDetailDlg, DblClickHdl, ListBox*, pLBox )
782 {
783 if( pLBox == &maLbDims )
784 maBtnOk.Click();
785 return 0;
786 }
787
788 // ============================================================================
789
790