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