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