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