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 > 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 > 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. */ 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 172 ScDPFunctionListBox::ScDPFunctionListBox( Window* pParent, const ResId& rResId ) : 173 MultiListBox( pParent, rResId ) 174 { 175 FillFunctionNames(); 176 } 177 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 187 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 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 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 233 sal_uInt16 ScDPFunctionDlg::GetFuncMask() const 234 { 235 return maLbFunc.GetSelection(); 236 } 237 238 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 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 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 382 IMPL_LINK( ScDPFunctionDlg, DblClickHdl, MultiListBox*, EMPTYARG ) 383 { 384 maBtnOk.Click(); 385 return 0; 386 } 387 388 // ============================================================================ 389 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 415 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 427 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 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 471 IMPL_LINK( ScDPSubtotalDlg, RadioClickHdl, RadioButton*, pBtn ) 472 { 473 maLbFunc.Enable( pBtn == &maRbUser ); 474 return 0; 475 } 476 477 IMPL_LINK( ScDPSubtotalDlg, DblClickHdl, MultiListBox*, EMPTYARG ) 478 { 479 maBtnOk.Click(); 480 return 0; 481 } 482 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 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 534 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 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 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 681 IMPL_LINK( ScDPSubtotalOptDlg, RadioClickHdl, RadioButton*, pBtn ) 682 { 683 maLbSortBy.Enable( pBtn != &maRbSortMan ); 684 return 0; 685 } 686 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 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 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 760 short ScDPShowDetailDlg::Execute() 761 { 762 return maLbDims.GetEntryCount() ? ModalDialog::Execute() : RET_CANCEL; 763 } 764 765 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 780 IMPL_LINK( ScDPShowDetailDlg, DblClickHdl, ListBox*, pLBox ) 781 { 782 if( pLBox == &maLbDims ) 783 maBtnOk.Click(); 784 return 0; 785 } 786 787 // ============================================================================ 788 789