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 // System - Includes --------------------------------------------------------- 32 33 34 35 // INCLUDE ------------------------------------------------------------------- 36 #include <sfx2/dispatch.hxx> 37 38 #include "uiitems.hxx" 39 #include "rangenam.hxx" 40 #include "dbcolect.hxx" 41 #include "reffact.hxx" 42 #include "viewdata.hxx" 43 #include "document.hxx" 44 #include "docsh.hxx" 45 #include "scresid.hxx" 46 47 #include "foptmgr.hxx" 48 49 #include "globstr.hrc" 50 #include "filter.hrc" 51 52 #define _SFILTDLG_CXX 53 #include "filtdlg.hxx" 54 #undef _SFILTDLG_CXX 55 #include <vcl/msgbox.hxx> 56 57 // DEFINE -------------------------------------------------------------------- 58 59 #define ERRORBOX(rid) ErrorBox( this, WinBits( WB_OK|WB_DEF_OK),\ 60 ScGlobal::GetRscString(rid) ).Execute() 61 62 63 //============================================================================ 64 // class ScSpecialFilterDialog 65 66 //---------------------------------------------------------------------------- 67 68 ScSpecialFilterDlg::ScSpecialFilterDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent, 69 const SfxItemSet& rArgSet ) 70 71 : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_SPEC_FILTER ), 72 // 73 aFtFilterArea ( this, ScResId( FT_CRITERIA_AREA ) ), 74 aLbFilterArea ( this, ScResId( LB_CRITERIA_AREA ) ), 75 aEdFilterArea ( this, this, ScResId( ED_CRITERIA_AREA ) ), 76 aRbFilterArea ( this, ScResId( RB_CRITERIA_AREA ), &aEdFilterArea, this ), 77 // 78 aFlOptions ( this, ScResId( FL_OPTIONS ) ), 79 _INIT_COMMON_FILTER_RSCOBJS 80 aBtnOk ( this, ScResId( BTN_OK ) ), 81 aBtnCancel ( this, ScResId( BTN_CANCEL ) ), 82 aBtnHelp ( this, ScResId( BTN_HELP ) ), 83 aBtnMore ( this, ScResId( BTN_MORE ) ), 84 // 85 pOptionsMgr ( NULL ), 86 nWhichQuery ( rArgSet.GetPool()->GetWhich( SID_QUERY ) ), 87 theQueryData ( ((const ScQueryItem&) 88 rArgSet.Get( nWhichQuery )).GetQueryData() ), 89 pOutItem ( NULL ), 90 pViewData ( NULL ), 91 pDoc ( NULL ), 92 pRefInputEdit ( NULL ), 93 bRefInputMode ( sal_False ), 94 pTimer ( NULL ) 95 { 96 Init( rArgSet ); 97 aEdFilterArea.GrabFocus(); 98 99 FreeResource(); 100 101 // Hack: RefInput-Kontrolle 102 pTimer = new Timer; 103 pTimer->SetTimeout( 50 ); // 50ms warten 104 pTimer->SetTimeoutHdl( LINK( this, ScSpecialFilterDlg, TimeOutHdl ) ); 105 pTimer->Start(); 106 107 aLbCopyArea.SetAccessibleName(aBtnCopyResult.GetText()); 108 aEdCopyArea.SetAccessibleName(aBtnCopyResult.GetText()); 109 aLbCopyArea.SetAccessibleRelationLabeledBy(&aBtnCopyResult); 110 aEdCopyArea.SetAccessibleRelationLabeledBy(&aBtnCopyResult); 111 } 112 113 114 //---------------------------------------------------------------------------- 115 116 __EXPORT ScSpecialFilterDlg::~ScSpecialFilterDlg() 117 { 118 sal_uInt16 nEntries = aLbFilterArea.GetEntryCount(); 119 sal_uInt16 i; 120 121 for ( i=1; i<nEntries; i++ ) 122 delete (String*)aLbFilterArea.GetEntryData( i ); 123 124 delete pOptionsMgr; 125 126 if ( pOutItem ) 127 delete pOutItem; 128 129 // Hack: RefInput-Kontrolle 130 pTimer->Stop(); 131 delete pTimer; 132 } 133 134 135 //---------------------------------------------------------------------------- 136 137 void __EXPORT ScSpecialFilterDlg::Init( const SfxItemSet& rArgSet ) 138 { 139 const ScQueryItem& rQueryItem = (const ScQueryItem&) 140 rArgSet.Get( nWhichQuery ); 141 142 aBtnOk.SetClickHdl ( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) ); 143 aBtnCancel.SetClickHdl ( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) ); 144 aLbFilterArea.SetSelectHdl ( LINK( this, ScSpecialFilterDlg, FilterAreaSelHdl ) ); 145 aEdFilterArea.SetModifyHdl ( LINK( this, ScSpecialFilterDlg, FilterAreaModHdl ) ); 146 147 pViewData = rQueryItem.GetViewData(); 148 pDoc = pViewData ? pViewData->GetDocument() : NULL; 149 150 aEdFilterArea.SetText( EMPTY_STRING ); // may be overwritten below 151 152 if ( pViewData && pDoc ) 153 { 154 if(pDoc->GetChangeTrack()!=NULL) aBtnCopyResult.Disable(); 155 156 ScRangeName* pRangeNames = pDoc->GetRangeName(); 157 const sal_uInt16 nCount = pRangeNames ? pRangeNames->GetCount() : 0; 158 159 /* 160 * Aus den RangeNames des Dokumentes werden nun die 161 * gemerkt, bei denen es sich um Filter-Bereiche handelt 162 */ 163 164 aLbFilterArea.Clear(); 165 aLbFilterArea.InsertEntry( aStrUndefined, 0 ); 166 167 if ( nCount > 0 ) 168 { 169 String aString; 170 ScRangeData* pData = NULL; 171 sal_uInt16 nInsert = 0; 172 173 for ( sal_uInt16 i=0; i<nCount; i++ ) 174 { 175 pData = (ScRangeData*)(pRangeNames->At( i )); 176 if ( pData ) 177 { 178 if ( pData->HasType( RT_CRITERIA ) ) 179 { 180 pData->GetName( aString ); 181 nInsert = aLbFilterArea.InsertEntry( aString ); 182 pData->GetSymbol( aString ); 183 aLbFilterArea.SetEntryData( nInsert, 184 new String( aString ) ); 185 } 186 } 187 } 188 } 189 190 // is there a stored source range? 191 192 ScRange aAdvSource; 193 if (rQueryItem.GetAdvancedQuerySource(aAdvSource)) 194 { 195 String aRefStr; 196 aAdvSource.Format( aRefStr, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() ); 197 aEdFilterArea.SetRefString( aRefStr ); 198 } 199 } 200 201 aLbFilterArea.SelectEntryPos( 0 ); 202 203 // Optionen initialisieren lassen: 204 205 pOptionsMgr = new ScFilterOptionsMgr( 206 this, 207 pViewData, 208 theQueryData, 209 aBtnMore, 210 aBtnCase, 211 aBtnRegExp, 212 aBtnHeader, 213 aBtnUnique, 214 aBtnCopyResult, 215 aBtnDestPers, 216 aLbCopyArea, 217 aEdCopyArea, 218 aRbCopyArea, 219 aFtDbAreaLabel, 220 aFtDbArea, 221 aFlOptions, 222 aStrNoName, 223 aStrUndefined ); 224 225 // #35206# Spezialfilter braucht immer Spaltenkoepfe 226 aBtnHeader.Check(sal_True); 227 aBtnHeader.Disable(); 228 229 // Modal-Modus einschalten 230 // SetDispatcherLock( sal_True ); 231 //@BugID 54702 Enablen/Disablen nur noch in Basisklasse 232 //SFX_APPWINDOW->Disable(sal_False); //! allgemeine Methode im ScAnyRefDlg 233 } 234 235 236 //---------------------------------------------------------------------------- 237 238 sal_Bool __EXPORT ScSpecialFilterDlg::Close() 239 { 240 if (pViewData) 241 pViewData->GetDocShell()->CancelAutoDBRange(); 242 243 return DoClose( ScSpecialFilterDlgWrapper::GetChildWindowId() ); 244 } 245 246 247 //---------------------------------------------------------------------------- 248 // Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als 249 // neue Selektion im Referenz-Edit angezeigt wird. 250 251 void ScSpecialFilterDlg::SetReference( const ScRange& rRef, ScDocument* pDocP ) 252 { 253 if ( bRefInputMode && pRefInputEdit ) // Nur moeglich, wenn im Referenz-Editmodus 254 { 255 if ( rRef.aStart != rRef.aEnd ) 256 RefInputStart( pRefInputEdit ); 257 258 String aRefStr; 259 const formula::FormulaGrammar::AddressConvention eConv = pDocP->GetAddressConvention(); 260 261 if ( pRefInputEdit == &aEdCopyArea) 262 rRef.aStart.Format( aRefStr, SCA_ABS_3D, pDocP, eConv ); 263 else if ( pRefInputEdit == &aEdFilterArea) 264 rRef.Format( aRefStr, SCR_ABS_3D, pDocP, eConv ); 265 266 pRefInputEdit->SetRefString( aRefStr ); 267 } 268 } 269 270 271 //---------------------------------------------------------------------------- 272 273 void ScSpecialFilterDlg::SetActive() 274 { 275 if ( bRefInputMode ) 276 { 277 if ( pRefInputEdit == &aEdCopyArea ) 278 { 279 aEdCopyArea.GrabFocus(); 280 if ( aEdCopyArea.GetModifyHdl().IsSet() ) 281 ((Link&)aEdCopyArea.GetModifyHdl()).Call( &aEdCopyArea ); 282 } 283 else if ( pRefInputEdit == &aEdFilterArea ) 284 { 285 aEdFilterArea.GrabFocus(); 286 FilterAreaModHdl( &aEdFilterArea ); 287 } 288 } 289 else 290 GrabFocus(); 291 292 RefInputDone(); 293 } 294 295 296 //---------------------------------------------------------------------------- 297 298 ScQueryItem* ScSpecialFilterDlg::GetOutputItem( const ScQueryParam& rParam, 299 const ScRange& rSource ) 300 { 301 if ( pOutItem ) DELETEZ( pOutItem ); 302 pOutItem = new ScQueryItem( nWhichQuery, &rParam ); 303 pOutItem->SetAdvancedQuerySource( &rSource ); 304 305 return pOutItem; 306 } 307 308 309 //---------------------------------------------------------------------------- 310 311 sal_Bool ScSpecialFilterDlg::IsRefInputMode() const 312 { 313 return bRefInputMode; 314 } 315 316 317 //---------------------------------------------------------------------------- 318 // Handler: 319 // ======== 320 321 IMPL_LINK( ScSpecialFilterDlg, EndDlgHdl, Button*, pBtn ) 322 { 323 DBG_ASSERT( pDoc && pViewData, "Document or ViewData not found. :-/" ); 324 325 if ( (pBtn == &aBtnOk) && pDoc && pViewData ) 326 { 327 String theCopyStr( aEdCopyArea.GetText() ); 328 String theAreaStr( aEdFilterArea.GetText() ); 329 ScQueryParam theOutParam( theQueryData ); 330 ScAddress theAdrCopy; 331 sal_Bool bEditInputOk = sal_True; 332 sal_Bool bQueryOk = sal_False; 333 ScRange theFilterArea; 334 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention(); 335 336 if ( aBtnCopyResult.IsChecked() ) 337 { 338 xub_StrLen nColonPos = theCopyStr.Search( ':' ); 339 340 if ( STRING_NOTFOUND != nColonPos ) 341 theCopyStr.Erase( nColonPos ); 342 343 sal_uInt16 nResult = theAdrCopy.Parse( theCopyStr, pDoc, eConv ); 344 345 if ( SCA_VALID != (nResult & SCA_VALID) ) 346 { 347 if ( !aBtnMore.GetState() ) 348 aBtnMore.SetState( sal_True ); 349 350 ERRORBOX( STR_INVALID_TABREF ); 351 aEdCopyArea.GrabFocus(); 352 bEditInputOk = sal_False; 353 } 354 } 355 356 if ( bEditInputOk ) 357 { 358 sal_uInt16 nResult = ScRange().Parse( theAreaStr, pDoc, eConv ); 359 360 if ( SCA_VALID != (nResult & SCA_VALID) ) 361 { 362 ERRORBOX( STR_INVALID_TABREF ); 363 aEdFilterArea.GrabFocus(); 364 bEditInputOk = sal_False; 365 } 366 } 367 368 if ( bEditInputOk ) 369 { 370 /* 371 * Alle Edit-Felder enthalten gueltige Bereiche. 372 * Nun wird versucht aus dem Filterbereich 373 * ein ScQueryParam zu erzeugen: 374 */ 375 376 sal_uInt16 nResult = theFilterArea.Parse( theAreaStr, pDoc, eConv ); 377 378 if ( SCA_VALID == (nResult & SCA_VALID) ) 379 { 380 ScAddress& rStart = theFilterArea.aStart; 381 ScAddress& rEnd = theFilterArea.aEnd; 382 383 if ( aBtnCopyResult.IsChecked() ) 384 { 385 theOutParam.bInplace = sal_False; 386 theOutParam.nDestTab = theAdrCopy.Tab(); 387 theOutParam.nDestCol = theAdrCopy.Col(); 388 theOutParam.nDestRow = theAdrCopy.Row(); 389 } 390 else 391 { 392 theOutParam.bInplace = sal_True; 393 theOutParam.nDestTab = 0; 394 theOutParam.nDestCol = 0; 395 theOutParam.nDestRow = 0; 396 } 397 398 theOutParam.bHasHeader = aBtnHeader.IsChecked(); 399 theOutParam.bByRow = sal_True; 400 theOutParam.bCaseSens = aBtnCase.IsChecked(); 401 theOutParam.bRegExp = aBtnRegExp.IsChecked(); 402 theOutParam.bDuplicate = !aBtnUnique.IsChecked(); 403 theOutParam.bDestPers = aBtnDestPers.IsChecked(); 404 405 bQueryOk = 406 pDoc->CreateQueryParam( rStart.Col(), 407 rStart.Row(), 408 rEnd.Col(), 409 rEnd.Row(), 410 rStart.Tab(), 411 theOutParam ); 412 413 // an der DB-Collection koennen nur MAXQUERY Filter-Eintraege 414 // gespeichert werden 415 416 if ( bQueryOk && theOutParam.GetEntryCount() > MAXQUERY && 417 theOutParam.GetEntry(MAXQUERY).bDoQuery ) 418 { 419 bQueryOk = sal_False; // zu viele 420 //! andere Fehlermeldung ?? 421 } 422 } 423 } 424 425 if ( bQueryOk ) 426 { 427 SetDispatcherLock( sal_False ); 428 SwitchToDocument(); 429 GetBindings().GetDispatcher()->Execute( FID_FILTER_OK, 430 SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, 431 GetOutputItem( theOutParam, theFilterArea ), 0L, 0L ); 432 Close(); 433 } 434 else 435 { 436 ERRORBOX( STR_INVALID_QUERYAREA ); 437 aEdFilterArea.GrabFocus(); 438 } 439 } 440 else if ( pBtn == &aBtnCancel ) 441 { 442 Close(); 443 } 444 return 0; 445 } 446 447 448 //---------------------------------------------------------------------------- 449 450 IMPL_LINK( ScSpecialFilterDlg, TimeOutHdl, Timer*, _pTimer ) 451 { 452 // alle 50ms nachschauen, ob RefInputMode noch stimmt 453 454 if( (_pTimer == pTimer) && IsActive() ) 455 { 456 if( aEdCopyArea.HasFocus() || aRbCopyArea.HasFocus() ) 457 { 458 pRefInputEdit = &aEdCopyArea; 459 bRefInputMode = sal_True; 460 } 461 else if( aEdFilterArea.HasFocus() || aRbFilterArea.HasFocus() ) 462 { 463 pRefInputEdit = &aEdFilterArea; 464 bRefInputMode = sal_True; 465 } 466 else if( bRefInputMode ) 467 { 468 pRefInputEdit = NULL; 469 bRefInputMode = sal_False; 470 } 471 } 472 473 pTimer->Start(); 474 475 return 0; 476 } 477 478 479 //---------------------------------------------------------------------------- 480 481 IMPL_LINK( ScSpecialFilterDlg, FilterAreaSelHdl, ListBox*, pLb ) 482 { 483 if ( pLb == &aLbFilterArea ) 484 { 485 String aString; 486 sal_uInt16 nSelPos = aLbFilterArea.GetSelectEntryPos(); 487 488 if ( nSelPos > 0 ) 489 aString = *(String*)aLbFilterArea.GetEntryData( nSelPos ); 490 491 aEdFilterArea.SetText( aString ); 492 } 493 494 return 0; 495 } 496 497 498 //---------------------------------------------------------------------------- 499 500 IMPL_LINK( ScSpecialFilterDlg, FilterAreaModHdl, formula::RefEdit*, pEd ) 501 { 502 if ( pEd == &aEdFilterArea ) 503 { 504 if ( pDoc && pViewData ) 505 { 506 String theCurAreaStr = pEd->GetText(); 507 sal_uInt16 nResult = ScRange().Parse( theCurAreaStr, pDoc ); 508 509 if ( SCA_VALID == (nResult & SCA_VALID) ) 510 { 511 String* pStr = NULL; 512 sal_Bool bFound = sal_False; 513 sal_uInt16 i = 0; 514 sal_uInt16 nCount = aLbFilterArea.GetEntryCount(); 515 516 for ( i=1; i<nCount && !bFound; i++ ) 517 { 518 pStr = (String*)aLbFilterArea.GetEntryData( i ); 519 bFound = (theCurAreaStr == *pStr); 520 } 521 522 if ( bFound ) 523 aLbFilterArea.SelectEntryPos( --i ); 524 else 525 aLbFilterArea.SelectEntryPos( 0 ); 526 } 527 } 528 else 529 aLbFilterArea.SelectEntryPos( 0 ); 530 } 531 532 return 0; 533 } 534 535 536