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