merge the formfield patch from ooo-build
[ooovba.git] / sc / source / ui / dbgui / sfiltdlg.cxx
blob86de32ed2dffee0795b4f5e414e1ce41d9b8c177
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sfiltdlg.cxx,v $
10 * $Revision: 1.14 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 // System - Includes ---------------------------------------------------------
38 // INCLUDE -------------------------------------------------------------------
39 #include <sfx2/dispatch.hxx>
41 #include "uiitems.hxx"
42 #include "rangenam.hxx"
43 #include "dbcolect.hxx"
44 #include "reffact.hxx"
45 #include "viewdata.hxx"
46 #include "document.hxx"
47 #include "docsh.hxx"
48 #include "scresid.hxx"
50 #include "foptmgr.hxx"
52 #include "globstr.hrc"
53 #include "filter.hrc"
55 #define _SFILTDLG_CXX
56 #include "filtdlg.hxx"
57 #undef _SFILTDLG_CXX
58 #include <vcl/msgbox.hxx>
60 // DEFINE --------------------------------------------------------------------
62 #define ERRORBOX(rid) ErrorBox( this, WinBits( WB_OK|WB_DEF_OK),\
63 ScGlobal::GetRscString(rid) ).Execute()
66 //============================================================================
67 // class ScSpecialFilterDialog
69 //----------------------------------------------------------------------------
71 ScSpecialFilterDlg::ScSpecialFilterDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
72 const SfxItemSet& rArgSet )
74 : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_SPEC_FILTER ),
76 aLbFilterArea ( this, ScResId( LB_CRITERIA_AREA ) ),
77 aFtFilterArea ( this, ScResId( FT_CRITERIA_AREA ) ),
78 aEdFilterArea ( this, this, ScResId( ED_CRITERIA_AREA ) ),
79 aRbFilterArea ( this, ScResId( RB_CRITERIA_AREA ), &aEdFilterArea, this ),
81 aFlOptions ( this, ScResId( FL_OPTIONS ) ),
82 _INIT_COMMON_FILTER_RSCOBJS
83 aBtnOk ( this, ScResId( BTN_OK ) ),
84 aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
85 aBtnHelp ( this, ScResId( BTN_HELP ) ),
86 aBtnMore ( this, ScResId( BTN_MORE ) ),
88 pOptionsMgr ( NULL ),
89 nWhichQuery ( rArgSet.GetPool()->GetWhich( SID_QUERY ) ),
90 theQueryData ( ((const ScQueryItem&)
91 rArgSet.Get( nWhichQuery )).GetQueryData() ),
92 pOutItem ( NULL ),
93 pViewData ( NULL ),
94 pDoc ( NULL ),
95 pRefInputEdit ( NULL ),
96 bRefInputMode ( FALSE ),
97 pTimer ( NULL )
99 Init( rArgSet );
100 aEdFilterArea.GrabFocus();
102 FreeResource();
104 // Hack: RefInput-Kontrolle
105 pTimer = new Timer;
106 pTimer->SetTimeout( 50 ); // 50ms warten
107 pTimer->SetTimeoutHdl( LINK( this, ScSpecialFilterDlg, TimeOutHdl ) );
108 pTimer->Start();
112 //----------------------------------------------------------------------------
114 __EXPORT ScSpecialFilterDlg::~ScSpecialFilterDlg()
116 USHORT nEntries = aLbFilterArea.GetEntryCount();
117 USHORT i;
119 for ( i=1; i<nEntries; i++ )
120 delete (String*)aLbFilterArea.GetEntryData( i );
122 delete pOptionsMgr;
124 if ( pOutItem )
125 delete pOutItem;
127 // Hack: RefInput-Kontrolle
128 pTimer->Stop();
129 delete pTimer;
133 //----------------------------------------------------------------------------
135 void __EXPORT ScSpecialFilterDlg::Init( const SfxItemSet& rArgSet )
137 const ScQueryItem& rQueryItem = (const ScQueryItem&)
138 rArgSet.Get( nWhichQuery );
140 aBtnOk.SetClickHdl ( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) );
141 aBtnCancel.SetClickHdl ( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) );
142 aLbFilterArea.SetSelectHdl ( LINK( this, ScSpecialFilterDlg, FilterAreaSelHdl ) );
143 aEdFilterArea.SetModifyHdl ( LINK( this, ScSpecialFilterDlg, FilterAreaModHdl ) );
145 pViewData = rQueryItem.GetViewData();
146 pDoc = pViewData ? pViewData->GetDocument() : NULL;
148 aEdFilterArea.SetText( EMPTY_STRING ); // may be overwritten below
150 if ( pViewData && pDoc )
152 if(pDoc->GetChangeTrack()!=NULL) aBtnCopyResult.Disable();
154 ScRangeName* pRangeNames = pDoc->GetRangeName();
155 const USHORT nCount = pRangeNames ? pRangeNames->GetCount() : 0;
158 * Aus den RangeNames des Dokumentes werden nun die
159 * gemerkt, bei denen es sich um Filter-Bereiche handelt
162 aLbFilterArea.Clear();
163 aLbFilterArea.InsertEntry( aStrUndefined, 0 );
165 if ( nCount > 0 )
167 String aString;
168 ScRangeData* pData = NULL;
169 USHORT nInsert = 0;
171 for ( USHORT i=0; i<nCount; i++ )
173 pData = (ScRangeData*)(pRangeNames->At( i ));
174 if ( pData )
176 if ( pData->HasType( RT_CRITERIA ) )
178 pData->GetName( aString );
179 nInsert = aLbFilterArea.InsertEntry( aString );
180 pData->GetSymbol( aString );
181 aLbFilterArea.SetEntryData( nInsert,
182 new String( aString ) );
188 // is there a stored source range?
190 ScRange aAdvSource;
191 if (rQueryItem.GetAdvancedQuerySource(aAdvSource))
193 String aRefStr;
194 aAdvSource.Format( aRefStr, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
195 aEdFilterArea.SetRefString( aRefStr );
199 aLbFilterArea.SelectEntryPos( 0 );
201 // Optionen initialisieren lassen:
203 pOptionsMgr = new ScFilterOptionsMgr(
204 this,
205 pViewData,
206 theQueryData,
207 aBtnMore,
208 aBtnCase,
209 aBtnRegExp,
210 aBtnHeader,
211 aBtnUnique,
212 aBtnCopyResult,
213 aBtnDestPers,
214 aLbCopyArea,
215 aEdCopyArea,
216 aRbCopyArea,
217 aFtDbAreaLabel,
218 aFtDbArea,
219 aFlOptions,
220 aStrNoName,
221 aStrUndefined );
223 // #35206# Spezialfilter braucht immer Spaltenkoepfe
224 aBtnHeader.Check(TRUE);
225 aBtnHeader.Disable();
227 // Modal-Modus einschalten
228 // SetDispatcherLock( TRUE );
229 //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
230 //SFX_APPWINDOW->Disable(FALSE); //! allgemeine Methode im ScAnyRefDlg
234 //----------------------------------------------------------------------------
236 BOOL __EXPORT ScSpecialFilterDlg::Close()
238 if (pViewData)
239 pViewData->GetDocShell()->CancelAutoDBRange();
241 return DoClose( ScSpecialFilterDlgWrapper::GetChildWindowId() );
245 //----------------------------------------------------------------------------
246 // Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
247 // neue Selektion im Referenz-Edit angezeigt wird.
249 void ScSpecialFilterDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
251 if ( bRefInputMode && pRefInputEdit ) // Nur moeglich, wenn im Referenz-Editmodus
253 if ( rRef.aStart != rRef.aEnd )
254 RefInputStart( pRefInputEdit );
256 String aRefStr;
257 const formula::FormulaGrammar::AddressConvention eConv = pDocP->GetAddressConvention();
259 if ( pRefInputEdit == &aEdCopyArea)
260 rRef.aStart.Format( aRefStr, SCA_ABS_3D, pDocP, eConv );
261 else if ( pRefInputEdit == &aEdFilterArea)
262 rRef.Format( aRefStr, SCR_ABS_3D, pDocP, eConv );
264 pRefInputEdit->SetRefString( aRefStr );
269 //----------------------------------------------------------------------------
271 void ScSpecialFilterDlg::SetActive()
273 if ( bRefInputMode )
275 if ( pRefInputEdit == &aEdCopyArea )
277 aEdCopyArea.GrabFocus();
278 if ( aEdCopyArea.GetModifyHdl().IsSet() )
279 ((Link&)aEdCopyArea.GetModifyHdl()).Call( &aEdCopyArea );
281 else if ( pRefInputEdit == &aEdFilterArea )
283 aEdFilterArea.GrabFocus();
284 FilterAreaModHdl( &aEdFilterArea );
287 else
288 GrabFocus();
290 RefInputDone();
294 //----------------------------------------------------------------------------
296 ScQueryItem* ScSpecialFilterDlg::GetOutputItem( const ScQueryParam& rParam,
297 const ScRange& rSource )
299 if ( pOutItem ) DELETEZ( pOutItem );
300 pOutItem = new ScQueryItem( nWhichQuery, &rParam );
301 pOutItem->SetAdvancedQuerySource( &rSource );
303 return pOutItem;
307 //----------------------------------------------------------------------------
309 BOOL ScSpecialFilterDlg::IsRefInputMode() const
311 return bRefInputMode;
315 //----------------------------------------------------------------------------
316 // Handler:
317 // ========
319 IMPL_LINK( ScSpecialFilterDlg, EndDlgHdl, Button*, pBtn )
321 DBG_ASSERT( pDoc && pViewData, "Document or ViewData not found. :-/" );
323 if ( (pBtn == &aBtnOk) && pDoc && pViewData )
325 String theCopyStr( aEdCopyArea.GetText() );
326 String theAreaStr( aEdFilterArea.GetText() );
327 ScQueryParam theOutParam( theQueryData );
328 ScAddress theAdrCopy;
329 BOOL bEditInputOk = TRUE;
330 BOOL bQueryOk = FALSE;
331 ScRange theFilterArea;
332 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
334 if ( aBtnCopyResult.IsChecked() )
336 xub_StrLen nColonPos = theCopyStr.Search( ':' );
338 if ( STRING_NOTFOUND != nColonPos )
339 theCopyStr.Erase( nColonPos );
341 USHORT nResult = theAdrCopy.Parse( theCopyStr, pDoc, eConv );
343 if ( SCA_VALID != (nResult & SCA_VALID) )
345 if ( !aBtnMore.GetState() )
346 aBtnMore.SetState( TRUE );
348 ERRORBOX( STR_INVALID_TABREF );
349 aEdCopyArea.GrabFocus();
350 bEditInputOk = FALSE;
354 if ( bEditInputOk )
356 USHORT nResult = ScRange().Parse( theAreaStr, pDoc, eConv );
358 if ( SCA_VALID != (nResult & SCA_VALID) )
360 ERRORBOX( STR_INVALID_TABREF );
361 aEdFilterArea.GrabFocus();
362 bEditInputOk = FALSE;
366 if ( bEditInputOk )
369 * Alle Edit-Felder enthalten gueltige Bereiche.
370 * Nun wird versucht aus dem Filterbereich
371 * ein ScQueryParam zu erzeugen:
374 USHORT nResult = theFilterArea.Parse( theAreaStr, pDoc, eConv );
376 if ( SCA_VALID == (nResult & SCA_VALID) )
378 ScAddress& rStart = theFilterArea.aStart;
379 ScAddress& rEnd = theFilterArea.aEnd;
381 if ( aBtnCopyResult.IsChecked() )
383 theOutParam.bInplace = FALSE;
384 theOutParam.nDestTab = theAdrCopy.Tab();
385 theOutParam.nDestCol = theAdrCopy.Col();
386 theOutParam.nDestRow = theAdrCopy.Row();
388 else
390 theOutParam.bInplace = TRUE;
391 theOutParam.nDestTab = 0;
392 theOutParam.nDestCol = 0;
393 theOutParam.nDestRow = 0;
396 theOutParam.bHasHeader = aBtnHeader.IsChecked();
397 theOutParam.bByRow = TRUE;
398 theOutParam.bCaseSens = aBtnCase.IsChecked();
399 theOutParam.bRegExp = aBtnRegExp.IsChecked();
400 theOutParam.bDuplicate = !aBtnUnique.IsChecked();
401 theOutParam.bDestPers = aBtnDestPers.IsChecked();
403 bQueryOk =
404 pDoc->CreateQueryParam( rStart.Col(),
405 rStart.Row(),
406 rEnd.Col(),
407 rEnd.Row(),
408 rStart.Tab(),
409 theOutParam );
411 // an der DB-Collection koennen nur MAXQUERY Filter-Eintraege
412 // gespeichert werden
414 if ( bQueryOk && theOutParam.GetEntryCount() > MAXQUERY &&
415 theOutParam.GetEntry(MAXQUERY).bDoQuery )
417 bQueryOk = FALSE; // zu viele
418 //! andere Fehlermeldung ??
423 if ( bQueryOk )
425 SetDispatcherLock( FALSE );
426 SwitchToDocument();
427 GetBindings().GetDispatcher()->Execute( FID_FILTER_OK,
428 SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
429 GetOutputItem( theOutParam, theFilterArea ), 0L, 0L );
430 Close();
432 else
434 ERRORBOX( STR_INVALID_QUERYAREA );
435 aEdFilterArea.GrabFocus();
438 else if ( pBtn == &aBtnCancel )
440 Close();
442 return 0;
446 //----------------------------------------------------------------------------
448 IMPL_LINK( ScSpecialFilterDlg, TimeOutHdl, Timer*, _pTimer )
450 // alle 50ms nachschauen, ob RefInputMode noch stimmt
452 if( (_pTimer == pTimer) && IsActive() )
454 if( aEdCopyArea.HasFocus() || aRbCopyArea.HasFocus() )
456 pRefInputEdit = &aEdCopyArea;
457 bRefInputMode = TRUE;
459 else if( aEdFilterArea.HasFocus() || aRbFilterArea.HasFocus() )
461 pRefInputEdit = &aEdFilterArea;
462 bRefInputMode = TRUE;
464 else if( bRefInputMode )
466 pRefInputEdit = NULL;
467 bRefInputMode = FALSE;
471 pTimer->Start();
473 return 0;
477 //----------------------------------------------------------------------------
479 IMPL_LINK( ScSpecialFilterDlg, FilterAreaSelHdl, ListBox*, pLb )
481 if ( pLb == &aLbFilterArea )
483 String aString;
484 USHORT nSelPos = aLbFilterArea.GetSelectEntryPos();
486 if ( nSelPos > 0 )
487 aString = *(String*)aLbFilterArea.GetEntryData( nSelPos );
489 aEdFilterArea.SetText( aString );
492 return 0;
496 //----------------------------------------------------------------------------
498 IMPL_LINK( ScSpecialFilterDlg, FilterAreaModHdl, formula::RefEdit*, pEd )
500 if ( pEd == &aEdFilterArea )
502 if ( pDoc && pViewData )
504 String theCurAreaStr = pEd->GetText();
505 USHORT nResult = ScRange().Parse( theCurAreaStr, pDoc );
507 if ( SCA_VALID == (nResult & SCA_VALID) )
509 String* pStr = NULL;
510 BOOL bFound = FALSE;
511 USHORT i = 0;
512 USHORT nCount = aLbFilterArea.GetEntryCount();
514 for ( i=1; i<nCount && !bFound; i++ )
516 pStr = (String*)aLbFilterArea.GetEntryData( i );
517 bFound = (theCurAreaStr == *pStr);
520 if ( bFound )
521 aLbFilterArea.SelectEntryPos( --i );
522 else
523 aLbFilterArea.SelectEntryPos( 0 );
526 else
527 aLbFilterArea.SelectEntryPos( 0 );
530 return 0;