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