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