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 30 31 #ifndef PCH 32 #include <vcl/waitobj.hxx> 33 #endif 34 35 // INCLUDE --------------------------------------------------------------- 36 37 #include "viewdata.hxx" 38 #include "document.hxx" 39 #include "uiitems.hxx" 40 #include "global.hxx" 41 #include "dbcolect.hxx" 42 #include "scresid.hxx" 43 44 #include "sc.hrc" 45 #include "filter.hrc" 46 #include "globstr.hrc" 47 48 #define _PFILTDLG_CXX 49 #include "pfiltdlg.hxx" 50 #undef _PFILTDLG_CXX 51 #include <svl/zforlist.hxx> 52 53 //================================================================== 54 55 ScPivotFilterDlg::ScPivotFilterDlg( Window* pParent, 56 const SfxItemSet& rArgSet, 57 SCTAB nSourceTab ) 58 59 : ModalDialog ( pParent, ScResId( RID_SCDLG_PIVOTFILTER ) ), 60 // 61 aFlCriteria ( this, ScResId( FL_CRITERIA ) ), 62 aLbField1 ( this, ScResId( LB_FIELD1 ) ), 63 aLbCond1 ( this, ScResId( LB_COND1 ) ), 64 aEdVal1 ( this, ScResId( ED_VAL1 ) ), 65 aLbConnect1 ( this, ScResId( LB_OP1 ) ), 66 aLbField2 ( this, ScResId( LB_FIELD2 ) ), 67 aLbCond2 ( this, ScResId( LB_COND2 ) ), 68 aEdVal2 ( this, ScResId( ED_VAL2 ) ), 69 aLbConnect2 ( this, ScResId( LB_OP2 ) ), 70 aLbField3 ( this, ScResId( LB_FIELD3 ) ), 71 aLbCond3 ( this, ScResId( LB_COND3 ) ), 72 aEdVal3 ( this, ScResId( ED_VAL3 ) ), 73 aFtConnect ( this, ScResId( FT_OP ) ), 74 aFtField ( this, ScResId( FT_FIELD ) ), 75 aFtCond ( this, ScResId( FT_COND ) ), 76 aFtVal ( this, ScResId( FT_VAL ) ), 77 aFlOptions ( this, ScResId( FL_OPTIONS ) ), 78 aBtnCase ( this, ScResId( BTN_CASE ) ), 79 aBtnRegExp ( this, ScResId( BTN_REGEXP ) ), 80 aBtnUnique ( this, ScResId( BTN_UNIQUE ) ), 81 aFtDbAreaLabel ( this, ScResId( FT_DBAREA_LABEL ) ), 82 aFtDbArea ( this, ScResId( FT_DBAREA ) ), 83 aBtnOk ( this, ScResId( BTN_OK ) ), 84 aBtnCancel ( this, ScResId( BTN_CANCEL ) ), 85 aBtnHelp ( this, ScResId( BTN_HELP ) ), 86 aBtnMore ( this, ScResId( BTN_MORE ) ), 87 aStrUndefined ( ScResId( SCSTR_UNDEFINED ) ), 88 aStrNoName ( ScGlobal::GetRscString(STR_DB_NONAME) ), 89 aStrNone ( ScResId( SCSTR_NONE ) ), 90 aStrEmpty ( ScResId( SCSTR_EMPTY ) ), 91 aStrNotEmpty ( ScResId( SCSTR_NOTEMPTY ) ), 92 aStrRow ( ScResId( SCSTR_ROW ) ), 93 aStrColumn ( ScResId( SCSTR_COLUMN ) ), 94 // 95 nWhichQuery ( rArgSet.GetPool()->GetWhich( SID_QUERY ) ), 96 theQueryData ( ((const ScQueryItem&) 97 rArgSet.Get( nWhichQuery )).GetQueryData() ), 98 pOutItem ( NULL ), 99 pViewData ( NULL ), 100 pDoc ( NULL ), 101 nSrcTab ( nSourceTab ), // ist nicht im QueryParam 102 nFieldCount ( 0 ) 103 { 104 for (sal_uInt16 i=0; i<=MAXCOL; i++) 105 pEntryLists[i] = NULL; 106 107 Init( rArgSet ); 108 FreeResource(); 109 } 110 111 //------------------------------------------------------------------------ 112 113 __EXPORT ScPivotFilterDlg::~ScPivotFilterDlg() 114 { 115 for (sal_uInt16 i=0; i<=MAXCOL; i++) 116 delete pEntryLists[i]; 117 118 if ( pOutItem ) 119 delete pOutItem; 120 } 121 122 //------------------------------------------------------------------------ 123 124 void __EXPORT ScPivotFilterDlg::Init( const SfxItemSet& rArgSet ) 125 { 126 const ScQueryItem& rQueryItem = (const ScQueryItem&) 127 rArgSet.Get( nWhichQuery ); 128 129 aBtnCase.SetClickHdl ( LINK( this, ScPivotFilterDlg, CheckBoxHdl ) ); 130 131 aLbField1.SetSelectHdl ( LINK( this, ScPivotFilterDlg, LbSelectHdl ) ); 132 aLbField2.SetSelectHdl ( LINK( this, ScPivotFilterDlg, LbSelectHdl ) ); 133 aLbField3.SetSelectHdl ( LINK( this, ScPivotFilterDlg, LbSelectHdl ) ); 134 aLbConnect1.SetSelectHdl( LINK( this, ScPivotFilterDlg, LbSelectHdl ) ); 135 aLbConnect2.SetSelectHdl( LINK( this, ScPivotFilterDlg, LbSelectHdl ) ); 136 137 aBtnMore.AddWindow( &aBtnCase ); 138 aBtnMore.AddWindow( &aBtnRegExp ); 139 aBtnMore.AddWindow( &aBtnUnique ); 140 aBtnMore.AddWindow( &aFtDbAreaLabel ); 141 aBtnMore.AddWindow( &aFtDbArea ); 142 aBtnMore.AddWindow( &aFlOptions ); 143 144 aBtnCase .Check( theQueryData.bCaseSens ); 145 aBtnRegExp .Check( theQueryData.bRegExp ); 146 aBtnUnique .Check( !theQueryData.bDuplicate ); 147 148 pViewData = rQueryItem.GetViewData(); 149 pDoc = pViewData ? pViewData->GetDocument() : NULL; 150 151 // fuer leichteren Zugriff: 152 aFieldLbArr [0] = &aLbField1; 153 aFieldLbArr [1] = &aLbField2; 154 aFieldLbArr [2] = &aLbField3; 155 aValueEdArr [0] = &aEdVal1; 156 aValueEdArr [1] = &aEdVal2; 157 aValueEdArr [2] = &aEdVal3; 158 aCondLbArr [0] = &aLbCond1; 159 aCondLbArr [1] = &aLbCond2; 160 aCondLbArr [2] = &aLbCond3; 161 162 if ( pViewData && pDoc ) 163 { 164 String theAreaStr; 165 ScRange theCurArea ( ScAddress( theQueryData.nCol1, 166 theQueryData.nRow1, 167 nSrcTab ), 168 ScAddress( theQueryData.nCol2, 169 theQueryData.nRow2, 170 nSrcTab ) ); 171 ScDBCollection* pDBColl = pDoc->GetDBCollection(); 172 String theDbArea; 173 String theDbName = aStrNoName; 174 175 /* 176 * Ueberpruefen, ob es sich bei dem uebergebenen 177 * Bereich um einen Datenbankbereich handelt: 178 */ 179 180 theCurArea.Format( theAreaStr, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() ); 181 182 if ( pDBColl ) 183 { 184 ScAddress& rStart = theCurArea.aStart; 185 ScAddress& rEnd = theCurArea.aEnd; 186 ScDBData* pDBData = pDBColl->GetDBAtArea( rStart.Tab(), 187 rStart.Col(), rStart.Row(), 188 rEnd.Col(), rEnd.Row() ); 189 if ( pDBData ) 190 pDBData->GetName( theDbName ); 191 } 192 193 theDbArea.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" (")); 194 theDbArea += theDbName; 195 theDbArea += ')'; 196 aFtDbArea.SetText( theDbArea ); 197 } 198 else 199 { 200 aFtDbArea.SetText( EMPTY_STRING ); 201 } 202 203 // Feldlisten einlesen und Eintraege selektieren: 204 205 FillFieldLists(); 206 207 for ( SCSIZE i=0; i<3; i++ ) 208 { 209 if ( theQueryData.GetEntry(i).bDoQuery ) 210 { 211 ScQueryEntry& rEntry = theQueryData.GetEntry(i); 212 213 String aValStr = *rEntry.pStr; 214 if (!rEntry.bQueryByString && aValStr == EMPTY_STRING) 215 { 216 if (rEntry.nVal == SC_EMPTYFIELDS) 217 aValStr = aStrEmpty; 218 else if (rEntry.nVal == SC_NONEMPTYFIELDS) 219 aValStr = aStrNotEmpty; 220 } 221 sal_uInt16 nCondPos = (sal_uInt16)rEntry.eOp; 222 sal_uInt16 nFieldSelPos = GetFieldSelPos( static_cast<SCCOL>(rEntry.nField) ); 223 224 aFieldLbArr[i]->SelectEntryPos( nFieldSelPos ); 225 aCondLbArr [i]->SelectEntryPos( nCondPos ); 226 UpdateValueList( static_cast<sal_uInt16>(i+1) ); 227 aValueEdArr[i]->SetText( aValStr ); 228 if (aValStr == aStrEmpty || aValStr == aStrNotEmpty) 229 aCondLbArr[i]->Disable(); 230 } 231 else 232 { 233 aFieldLbArr[i]->SelectEntryPos( 0 ); // "keiner" selektieren 234 aCondLbArr [i]->SelectEntryPos( 0 ); // "=" selektieren 235 UpdateValueList( static_cast<sal_uInt16>(i) ); 236 aValueEdArr[i]->SetText( EMPTY_STRING ); 237 } 238 aValueEdArr[i]->SetModifyHdl( LINK( this, ScPivotFilterDlg, ValModifyHdl ) ); 239 } 240 241 // Disable/Enable Logik: 242 243 (aLbField1.GetSelectEntryPos() != 0) 244 && (aLbField2.GetSelectEntryPos() != 0) 245 ? aLbConnect1.SelectEntryPos( (sal_uInt16)theQueryData.GetEntry(1).eConnect ) 246 : aLbConnect1.SetNoSelection(); 247 248 (aLbField2.GetSelectEntryPos() != 0) 249 && (aLbField3.GetSelectEntryPos() != 0) 250 ? aLbConnect2.SelectEntryPos( (sal_uInt16)theQueryData.GetEntry(2).eConnect ) 251 : aLbConnect2.SetNoSelection(); 252 253 if ( aLbField1.GetSelectEntryPos() == 0 ) 254 { 255 aLbConnect1.Disable(); 256 aLbField2.Disable(); 257 aLbCond2.Disable(); 258 aEdVal2.Disable(); 259 } 260 else if ( aLbConnect1.GetSelectEntryCount() == 0 ) 261 { 262 aLbField2.Disable(); 263 aLbCond2.Disable(); 264 aEdVal2.Disable(); 265 } 266 267 if ( aLbField2.GetSelectEntryPos() == 0 ) 268 { 269 aLbConnect2.Disable(); 270 aLbField3.Disable(); 271 aLbCond3.Disable(); 272 aEdVal3.Disable(); 273 } 274 else if ( aLbConnect2.GetSelectEntryCount() == 0 ) 275 { 276 aLbField3.Disable(); 277 aLbCond3.Disable(); 278 aEdVal3.Disable(); 279 } 280 } 281 282 //------------------------------------------------------------------------ 283 284 void ScPivotFilterDlg::FillFieldLists() 285 { 286 aLbField1.Clear(); 287 aLbField2.Clear(); 288 aLbField3.Clear(); 289 aLbField1.InsertEntry( aStrNone, 0 ); 290 aLbField2.InsertEntry( aStrNone, 0 ); 291 aLbField3.InsertEntry( aStrNone, 0 ); 292 293 if ( pDoc ) 294 { 295 String aFieldName; 296 SCTAB nTab = nSrcTab; 297 SCCOL nFirstCol = theQueryData.nCol1; 298 SCROW nFirstRow = theQueryData.nRow1; 299 SCCOL nMaxCol = theQueryData.nCol2; 300 SCCOL col = 0; 301 sal_uInt16 i=1; 302 303 for ( col=nFirstCol; col<=nMaxCol; col++ ) 304 { 305 pDoc->GetString( col, nFirstRow, nTab, aFieldName ); 306 if ( aFieldName.Len() == 0 ) 307 { 308 aFieldName = aStrColumn; 309 aFieldName += ' '; 310 aFieldName += ScColToAlpha( col ); 311 } 312 aLbField1.InsertEntry( aFieldName, i ); 313 aLbField2.InsertEntry( aFieldName, i ); 314 aLbField3.InsertEntry( aFieldName, i ); 315 i++; 316 } 317 nFieldCount = i; 318 } 319 } 320 321 //------------------------------------------------------------------------ 322 323 void ScPivotFilterDlg::UpdateValueList( sal_uInt16 nList ) 324 { 325 if ( pDoc && nList>0 && nList<=3 ) 326 { 327 ComboBox* pValList = aValueEdArr[nList-1]; 328 sal_uInt16 nFieldSelPos = aFieldLbArr[nList-1]->GetSelectEntryPos(); 329 sal_uInt16 nListPos = 0; 330 String aCurValue = pValList->GetText(); 331 332 pValList->Clear(); 333 pValList->InsertEntry( aStrNotEmpty, 0 ); 334 pValList->InsertEntry( aStrEmpty, 1 ); 335 nListPos = 2; 336 337 if ( pDoc && nFieldSelPos ) 338 { 339 SCCOL nColumn = theQueryData.nCol1 + static_cast<SCCOL>(nFieldSelPos) - 1; 340 if (!pEntryLists[nColumn]) 341 { 342 WaitObject aWaiter( this ); 343 344 SCTAB nTab = nSrcTab; 345 SCROW nFirstRow = theQueryData.nRow1; 346 SCROW nLastRow = theQueryData.nRow2; 347 nFirstRow++; 348 bool bHasDates = false; 349 350 pEntryLists[nColumn] = new TypedScStrCollection( 128, 128 ); 351 pEntryLists[nColumn]->SetCaseSensitive( aBtnCase.IsChecked() ); 352 pDoc->GetFilterEntriesArea( nColumn, nFirstRow, nLastRow, 353 nTab, *pEntryLists[nColumn], bHasDates ); 354 } 355 356 TypedScStrCollection* pColl = pEntryLists[nColumn]; 357 sal_uInt16 nValueCount = pColl->GetCount(); 358 if ( nValueCount > 0 ) 359 { 360 for ( sal_uInt16 i=0; i<nValueCount; i++ ) 361 { 362 pValList->InsertEntry( (*pColl)[i]->GetString(), nListPos ); 363 nListPos++; 364 } 365 } 366 } 367 pValList->SetText( aCurValue ); 368 } 369 } 370 371 //------------------------------------------------------------------------ 372 373 void ScPivotFilterDlg::ClearValueList( sal_uInt16 nList ) 374 { 375 if ( nList>0 && nList<=3 ) 376 { 377 ComboBox* pValList = aValueEdArr[nList-1]; 378 pValList->Clear(); 379 pValList->InsertEntry( aStrNotEmpty, 0 ); 380 pValList->InsertEntry( aStrEmpty, 1 ); 381 pValList->SetText( EMPTY_STRING ); 382 } 383 } 384 385 //------------------------------------------------------------------------ 386 387 sal_uInt16 ScPivotFilterDlg::GetFieldSelPos( SCCOL nField ) 388 { 389 if ( nField >= theQueryData.nCol1 && nField <= theQueryData.nCol2 ) 390 return static_cast<sal_uInt16>(nField - theQueryData.nCol1 + 1); 391 else 392 return 0; 393 } 394 395 //------------------------------------------------------------------------ 396 397 const ScQueryItem& ScPivotFilterDlg::GetOutputItem() 398 { 399 ScQueryParam theParam( theQueryData ); 400 sal_uInt16 nConnect1 = aLbConnect1.GetSelectEntryPos(); 401 sal_uInt16 nConnect2 = aLbConnect2.GetSelectEntryPos(); 402 403 for ( SCSIZE i=0; i<3; i++ ) 404 { 405 sal_uInt16 nField = aFieldLbArr[i]->GetSelectEntryPos(); 406 ScQueryOp eOp = (ScQueryOp)aCondLbArr[i]->GetSelectEntryPos(); 407 408 sal_Bool bDoThis = (aFieldLbArr[i]->GetSelectEntryPos() != 0); 409 theParam.GetEntry(i).bDoQuery = bDoThis; 410 411 if ( bDoThis ) 412 { 413 ScQueryEntry& rEntry = theParam.GetEntry(i); 414 415 String aStrVal( aValueEdArr[i]->GetText() ); 416 417 /* 418 * Dialog liefert die ausgezeichneten Feldwerte "leer"/"nicht leer" 419 * als Konstanten in nVal in Verbindung mit dem Schalter 420 * bQueryByString auf FALSE. 421 */ 422 if ( aStrVal == aStrEmpty ) 423 { 424 *rEntry.pStr = EMPTY_STRING; 425 rEntry.nVal = SC_EMPTYFIELDS; 426 rEntry.bQueryByString = sal_False; 427 } 428 else if ( aStrVal == aStrNotEmpty ) 429 { 430 *rEntry.pStr = EMPTY_STRING; 431 rEntry.nVal = SC_NONEMPTYFIELDS; 432 rEntry.bQueryByString = sal_False; 433 } 434 else 435 { 436 *rEntry.pStr = aStrVal; 437 rEntry.nVal = 0; 438 rEntry.bQueryByString = sal_True; 439 } 440 441 rEntry.nField = nField ? (theQueryData.nCol1 + 442 static_cast<SCCOL>(nField) - 1) : static_cast<SCCOL>(0); 443 rEntry.eOp = eOp; 444 } 445 } 446 447 theParam.GetEntry(1).eConnect = (nConnect1 != LISTBOX_ENTRY_NOTFOUND) 448 ? (ScQueryConnect)nConnect1 449 : SC_AND; 450 theParam.GetEntry(2).eConnect = (nConnect2 != LISTBOX_ENTRY_NOTFOUND) 451 ? (ScQueryConnect)nConnect2 452 : SC_AND; 453 454 theParam.bInplace = sal_False; 455 theParam.nDestTab = 0; // Woher kommen diese Werte? 456 theParam.nDestCol = 0; 457 theParam.nDestRow = 0; 458 459 theParam.bDuplicate = !aBtnUnique.IsChecked(); 460 theParam.bCaseSens = aBtnCase.IsChecked(); 461 theParam.bRegExp = aBtnRegExp.IsChecked(); 462 463 if ( pOutItem ) DELETEZ( pOutItem ); 464 pOutItem = new ScQueryItem( nWhichQuery, &theParam ); 465 466 return *pOutItem; 467 } 468 469 //------------------------------------------------------------------------ 470 // Handler: 471 //------------------------------------------------------------------------ 472 473 IMPL_LINK( ScPivotFilterDlg, LbSelectHdl, ListBox*, pLb ) 474 { 475 /* 476 * Behandlung der Enable/Disable-Logik, 477 * abhaengig davon, welche ListBox angefasst wurde: 478 */ 479 480 if ( pLb == &aLbConnect1 ) 481 { 482 if ( !aLbField2.IsEnabled() ) 483 { 484 aLbField2.Enable(); 485 aLbCond2.Enable(); 486 aEdVal2.Enable(); 487 } 488 } 489 else if ( pLb == &aLbConnect2 ) 490 { 491 if ( !aLbField3.IsEnabled() ) 492 { 493 aLbField3.Enable(); 494 aLbCond3.Enable(); 495 aEdVal3.Enable(); 496 } 497 } 498 else if ( pLb == &aLbField1 ) 499 { 500 if ( aLbField1.GetSelectEntryPos() == 0 ) 501 { 502 aLbConnect1.SetNoSelection(); 503 aLbConnect2.SetNoSelection(); 504 aLbField2.SelectEntryPos( 0 ); 505 aLbField3.SelectEntryPos( 0 ); 506 aLbCond2.SelectEntryPos( 0 ); 507 aLbCond3.SelectEntryPos( 0 ); 508 ClearValueList( 1 ); 509 ClearValueList( 2 ); 510 ClearValueList( 3 ); 511 512 aLbConnect1.Disable(); 513 aLbConnect2.Disable(); 514 aLbField2.Disable(); 515 aLbField3.Disable(); 516 aLbCond2.Disable(); 517 aLbCond3.Disable(); 518 aEdVal2.Disable(); 519 aEdVal3.Disable(); 520 } 521 else 522 { 523 UpdateValueList( 1 ); 524 if ( !aLbConnect1.IsEnabled() ) 525 { 526 aLbConnect1.Enable(); 527 } 528 } 529 } 530 else if ( pLb == &aLbField2 ) 531 { 532 if ( aLbField2.GetSelectEntryPos() == 0 ) 533 { 534 aLbConnect2.SetNoSelection(); 535 aLbField3.SelectEntryPos( 0 ); 536 aLbCond3.SelectEntryPos( 0 ); 537 ClearValueList( 2 ); 538 ClearValueList( 3 ); 539 540 aLbConnect2.Disable(); 541 aLbField3.Disable(); 542 aLbCond3.Disable(); 543 aEdVal3.Disable(); 544 } 545 else 546 { 547 UpdateValueList( 2 ); 548 if ( !aLbConnect2.IsEnabled() ) 549 { 550 aLbConnect2.Enable(); 551 } 552 } 553 } 554 else if ( pLb == &aLbField3 ) 555 { 556 ( aLbField3.GetSelectEntryPos() == 0 ) 557 ? ClearValueList( 3 ) 558 : UpdateValueList( 3 ); 559 } 560 561 return 0; 562 } 563 564 //---------------------------------------------------------------------------- 565 566 IMPL_LINK( ScPivotFilterDlg, CheckBoxHdl, CheckBox*, pBox ) 567 { 568 // bei Gross-/Kleinschreibung die Werte-Listen aktualisieren 569 570 if ( pBox == &aBtnCase ) // Wertlisten 571 { 572 for (sal_uInt16 i=0; i<=MAXCOL; i++) 573 DELETEZ( pEntryLists[i] ); 574 575 String aCurVal1 = aEdVal1.GetText(); 576 String aCurVal2 = aEdVal2.GetText(); 577 String aCurVal3 = aEdVal3.GetText(); 578 UpdateValueList( 1 ); 579 UpdateValueList( 2 ); 580 UpdateValueList( 3 ); 581 aEdVal1.SetText( aCurVal1 ); 582 aEdVal2.SetText( aCurVal2 ); 583 aEdVal3.SetText( aCurVal3 ); 584 } 585 586 return 0; 587 } 588 589 //------------------------------------------------------------------------ 590 591 IMPL_LINK( ScPivotFilterDlg, ValModifyHdl, ComboBox*, pEd ) 592 { 593 if ( pEd ) 594 { 595 String aStrVal = pEd->GetText(); 596 ListBox* pLb = &aLbCond1; 597 598 if ( pEd == &aEdVal2 ) pLb = &aLbCond2; 599 else if ( pEd == &aEdVal3 ) pLb = &aLbCond3; 600 601 // wenn einer der Sonderwerte leer/nicht-leer 602 // gewaehlt wird, so macht nur der =-Operator Sinn: 603 604 if ( aStrEmpty == aStrVal || aStrNotEmpty == aStrVal ) 605 { 606 pLb->SelectEntry( '=' ); 607 pLb->Disable(); 608 } 609 else 610 pLb->Enable(); 611 } 612 613 return 0; 614 } 615 616 617