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