xref: /AOO41X/main/sc/source/ui/dbgui/sfiltdlg.cxx (revision b3f79822e811ac3493b185030a72c3c5a51f32d8)
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