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