Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <sfx2/dispatch.hxx>
21 :
22 : #include "uiitems.hxx"
23 : #include "rangenam.hxx"
24 : #include "dbdata.hxx"
25 : #include "reffact.hxx"
26 : #include "viewdata.hxx"
27 : #include "document.hxx"
28 : #include "docsh.hxx"
29 : #include "scresid.hxx"
30 :
31 : #include "foptmgr.hxx"
32 :
33 : #include "globstr.hrc"
34 : #include "filter.hrc"
35 :
36 : #define _SFILTDLG_CXX
37 : #include "filtdlg.hxx"
38 : #undef _SFILTDLG_CXX
39 : #include <vcl/msgbox.hxx>
40 :
41 : // DEFINE --------------------------------------------------------------------
42 :
43 : #define ERRORBOX(rid) ErrorBox( this, WinBits( WB_OK|WB_DEF_OK),\
44 : ScGlobal::GetRscString(rid) ).Execute()
45 :
46 :
47 : //============================================================================
48 : // class ScSpecialFilterDialog
49 :
50 : //----------------------------------------------------------------------------
51 :
52 0 : ScSpecialFilterDlg::ScSpecialFilterDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
53 : const SfxItemSet& rArgSet )
54 :
55 : : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_SPEC_FILTER ),
56 : //
57 : aFtFilterArea ( this, ScResId( FT_CRITERIA_AREA ) ),
58 : aLbFilterArea ( this, ScResId( LB_CRITERIA_AREA ) ),
59 : aEdFilterArea ( this, this, ScResId( ED_CRITERIA_AREA ) ),
60 : aRbFilterArea ( this, ScResId( RB_CRITERIA_AREA ), &aEdFilterArea, this ),
61 : //
62 : aFlOptions ( this, ScResId( FL_OPTIONS ) ),
63 : aBtnCase ( this, ScResId( BTN_CASE ) ),
64 : aBtnRegExp ( this, ScResId( BTN_REGEXP ) ),
65 : aBtnHeader ( this, ScResId( BTN_HEADER ) ),
66 : aBtnUnique ( this, ScResId( BTN_UNIQUE ) ),
67 : aBtnCopyResult ( this, ScResId( BTN_COPY_RESULT ) ),
68 : aLbCopyArea ( this, ScResId( LB_COPY_AREA ) ),
69 : aEdCopyArea ( this, this, ScResId( ED_COPY_AREA ) ),
70 : aRbCopyArea ( this, ScResId( RB_COPY_AREA ), &aEdCopyArea, this ),
71 : aBtnDestPers ( this, ScResId( BTN_DEST_PERS ) ),
72 : aFtDbAreaLabel ( this, ScResId( FT_DBAREA_LABEL ) ),
73 : aFtDbArea ( this, ScResId( FT_DBAREA ) ),
74 : aStrUndefined ( SC_RESSTR(SCSTR_UNDEFINED) ),
75 : aBtnOk ( this, ScResId( BTN_OK ) ),
76 : aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
77 : aBtnHelp ( this, ScResId( BTN_HELP ) ),
78 : aBtnMore ( this, ScResId( BTN_MORE ) ),
79 : //
80 : pOptionsMgr ( NULL ),
81 0 : nWhichQuery ( rArgSet.GetPool()->GetWhich( SID_QUERY ) ),
82 : theQueryData ( ((const ScQueryItem&)
83 0 : rArgSet.Get( nWhichQuery )).GetQueryData() ),
84 : pOutItem ( NULL ),
85 : pViewData ( NULL ),
86 : pDoc ( NULL ),
87 : pRefInputEdit ( NULL ),
88 : bRefInputMode ( false ),
89 0 : pTimer ( NULL )
90 : {
91 0 : Init( rArgSet );
92 0 : aEdFilterArea.GrabFocus();
93 :
94 0 : FreeResource();
95 :
96 : // Hack: RefInput-Kontrolle
97 0 : pTimer = new Timer;
98 0 : pTimer->SetTimeout( 50 ); // 50ms warten
99 0 : pTimer->SetTimeoutHdl( LINK( this, ScSpecialFilterDlg, TimeOutHdl ) );
100 0 : pTimer->Start();
101 :
102 0 : aLbCopyArea.SetAccessibleName(aBtnCopyResult.GetText());
103 0 : aEdCopyArea.SetAccessibleName(aBtnCopyResult.GetText());
104 0 : aLbCopyArea.SetAccessibleRelationLabeledBy(&aBtnCopyResult);
105 0 : aEdCopyArea.SetAccessibleRelationLabeledBy(&aBtnCopyResult);
106 0 : }
107 :
108 :
109 : //----------------------------------------------------------------------------
110 :
111 0 : ScSpecialFilterDlg::~ScSpecialFilterDlg()
112 : {
113 0 : sal_uInt16 nEntries = aLbFilterArea.GetEntryCount();
114 : sal_uInt16 i;
115 :
116 0 : for ( i=1; i<nEntries; i++ )
117 0 : delete (String*)aLbFilterArea.GetEntryData( i );
118 :
119 0 : delete pOptionsMgr;
120 :
121 0 : if ( pOutItem )
122 0 : delete pOutItem;
123 :
124 : // Hack: RefInput-Kontrolle
125 0 : pTimer->Stop();
126 0 : delete pTimer;
127 0 : }
128 :
129 :
130 : //----------------------------------------------------------------------------
131 :
132 0 : void ScSpecialFilterDlg::Init( const SfxItemSet& rArgSet )
133 : {
134 : const ScQueryItem& rQueryItem = (const ScQueryItem&)
135 0 : rArgSet.Get( nWhichQuery );
136 :
137 0 : aBtnOk.SetClickHdl ( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) );
138 0 : aBtnCancel.SetClickHdl ( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) );
139 0 : aLbFilterArea.SetSelectHdl ( LINK( this, ScSpecialFilterDlg, FilterAreaSelHdl ) );
140 0 : aEdFilterArea.SetModifyHdl ( LINK( this, ScSpecialFilterDlg, FilterAreaModHdl ) );
141 :
142 0 : pViewData = rQueryItem.GetViewData();
143 0 : pDoc = pViewData ? pViewData->GetDocument() : NULL;
144 :
145 0 : aEdFilterArea.SetText( EMPTY_STRING ); // may be overwritten below
146 :
147 0 : if ( pViewData && pDoc )
148 : {
149 0 : if(pDoc->GetChangeTrack()!=NULL) aBtnCopyResult.Disable();
150 :
151 0 : ScRangeName* pRangeNames = pDoc->GetRangeName();
152 0 : aLbFilterArea.Clear();
153 0 : aLbFilterArea.InsertEntry( aStrUndefined, 0 );
154 :
155 0 : if (!pRangeNames->empty())
156 : {
157 0 : ScRangeName::const_iterator itr = pRangeNames->begin(), itrEnd = pRangeNames->end();
158 0 : sal_uInt16 nInsert = 0;
159 0 : for (; itr != itrEnd; ++itr)
160 : {
161 0 : if (!itr->second->HasType(RT_CRITERIA))
162 0 : continue;
163 :
164 0 : nInsert = aLbFilterArea.InsertEntry(itr->second->GetName());
165 0 : rtl::OUString aSymbol;
166 0 : itr->second->GetSymbol(aSymbol);
167 0 : aLbFilterArea.SetEntryData(nInsert, new String(aSymbol));
168 0 : }
169 : }
170 :
171 : // is there a stored source range?
172 :
173 0 : ScRange aAdvSource;
174 0 : if (rQueryItem.GetAdvancedQuerySource(aAdvSource))
175 : {
176 0 : String aRefStr;
177 0 : aAdvSource.Format( aRefStr, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
178 0 : aEdFilterArea.SetRefString( aRefStr );
179 : }
180 : }
181 :
182 0 : aLbFilterArea.SelectEntryPos( 0 );
183 :
184 : // Optionen initialisieren lassen:
185 :
186 : pOptionsMgr = new ScFilterOptionsMgr(
187 : pViewData,
188 : theQueryData,
189 : aBtnMore,
190 : aBtnCase,
191 : aBtnRegExp,
192 : aBtnHeader,
193 : aBtnUnique,
194 : aBtnCopyResult,
195 : aBtnDestPers,
196 : aLbCopyArea,
197 : aEdCopyArea,
198 : aRbCopyArea,
199 : aFtDbAreaLabel,
200 : aFtDbArea,
201 : aFlOptions,
202 0 : aStrUndefined );
203 :
204 : // Spezialfilter braucht immer Spaltenkoepfe
205 0 : aBtnHeader.Check(true);
206 0 : aBtnHeader.Disable();
207 :
208 : // Modal-Modus einschalten
209 : // SetDispatcherLock( true );
210 : //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
211 : //SFX_APPWINDOW->Disable(false); //! allgemeine Methode im ScAnyRefDlg
212 0 : }
213 :
214 :
215 : //----------------------------------------------------------------------------
216 :
217 0 : sal_Bool ScSpecialFilterDlg::Close()
218 : {
219 0 : if (pViewData)
220 0 : pViewData->GetDocShell()->CancelAutoDBRange();
221 :
222 0 : return DoClose( ScSpecialFilterDlgWrapper::GetChildWindowId() );
223 : }
224 :
225 :
226 : //----------------------------------------------------------------------------
227 : // Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
228 : // neue Selektion im Referenz-Edit angezeigt wird.
229 :
230 0 : void ScSpecialFilterDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
231 : {
232 0 : if ( bRefInputMode && pRefInputEdit ) // Nur moeglich, wenn im Referenz-Editmodus
233 : {
234 0 : if ( rRef.aStart != rRef.aEnd )
235 0 : RefInputStart( pRefInputEdit );
236 :
237 0 : String aRefStr;
238 0 : const formula::FormulaGrammar::AddressConvention eConv = pDocP->GetAddressConvention();
239 :
240 0 : if ( pRefInputEdit == &aEdCopyArea)
241 0 : rRef.aStart.Format( aRefStr, SCA_ABS_3D, pDocP, eConv );
242 0 : else if ( pRefInputEdit == &aEdFilterArea)
243 0 : rRef.Format( aRefStr, SCR_ABS_3D, pDocP, eConv );
244 :
245 0 : pRefInputEdit->SetRefString( aRefStr );
246 : }
247 0 : }
248 :
249 :
250 : //----------------------------------------------------------------------------
251 :
252 0 : void ScSpecialFilterDlg::SetActive()
253 : {
254 0 : if ( bRefInputMode )
255 : {
256 0 : if ( pRefInputEdit == &aEdCopyArea )
257 : {
258 0 : aEdCopyArea.GrabFocus();
259 0 : if ( aEdCopyArea.GetModifyHdl().IsSet() )
260 0 : ((Link&)aEdCopyArea.GetModifyHdl()).Call( &aEdCopyArea );
261 : }
262 0 : else if ( pRefInputEdit == &aEdFilterArea )
263 : {
264 0 : aEdFilterArea.GrabFocus();
265 0 : FilterAreaModHdl( &aEdFilterArea );
266 : }
267 : }
268 : else
269 0 : GrabFocus();
270 :
271 0 : RefInputDone();
272 0 : }
273 :
274 :
275 : //----------------------------------------------------------------------------
276 :
277 0 : ScQueryItem* ScSpecialFilterDlg::GetOutputItem( const ScQueryParam& rParam,
278 : const ScRange& rSource )
279 : {
280 0 : if ( pOutItem ) DELETEZ( pOutItem );
281 0 : pOutItem = new ScQueryItem( nWhichQuery, &rParam );
282 0 : pOutItem->SetAdvancedQuerySource( &rSource );
283 :
284 0 : return pOutItem;
285 : }
286 :
287 :
288 : //----------------------------------------------------------------------------
289 :
290 0 : sal_Bool ScSpecialFilterDlg::IsRefInputMode() const
291 : {
292 0 : return bRefInputMode;
293 : }
294 :
295 :
296 : //----------------------------------------------------------------------------
297 : // Handler:
298 : // ========
299 :
300 0 : IMPL_LINK( ScSpecialFilterDlg, EndDlgHdl, Button*, pBtn )
301 : {
302 : OSL_ENSURE( pDoc && pViewData, "Document or ViewData not found. :-/" );
303 :
304 0 : if ( (pBtn == &aBtnOk) && pDoc && pViewData )
305 : {
306 0 : String theCopyStr( aEdCopyArea.GetText() );
307 0 : String theAreaStr( aEdFilterArea.GetText() );
308 0 : ScQueryParam theOutParam( theQueryData );
309 0 : ScAddress theAdrCopy;
310 0 : sal_Bool bEditInputOk = true;
311 0 : sal_Bool bQueryOk = false;
312 0 : ScRange theFilterArea;
313 0 : const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
314 :
315 0 : if ( aBtnCopyResult.IsChecked() )
316 : {
317 0 : xub_StrLen nColonPos = theCopyStr.Search( ':' );
318 :
319 0 : if ( STRING_NOTFOUND != nColonPos )
320 0 : theCopyStr.Erase( nColonPos );
321 :
322 0 : sal_uInt16 nResult = theAdrCopy.Parse( theCopyStr, pDoc, eConv );
323 :
324 0 : if ( SCA_VALID != (nResult & SCA_VALID) )
325 : {
326 0 : if ( !aBtnMore.GetState() )
327 0 : aBtnMore.SetState( true );
328 :
329 0 : ERRORBOX( STR_INVALID_TABREF );
330 0 : aEdCopyArea.GrabFocus();
331 0 : bEditInputOk = false;
332 : }
333 : }
334 :
335 0 : if ( bEditInputOk )
336 : {
337 0 : sal_uInt16 nResult = ScRange().Parse( theAreaStr, pDoc, eConv );
338 :
339 0 : if ( SCA_VALID != (nResult & SCA_VALID) )
340 : {
341 0 : ERRORBOX( STR_INVALID_TABREF );
342 0 : aEdFilterArea.GrabFocus();
343 0 : bEditInputOk = false;
344 : }
345 : }
346 :
347 0 : if ( bEditInputOk )
348 : {
349 : /*
350 : * Alle Edit-Felder enthalten gueltige Bereiche.
351 : * Nun wird versucht aus dem Filterbereich
352 : * ein ScQueryParam zu erzeugen:
353 : */
354 :
355 0 : sal_uInt16 nResult = theFilterArea.Parse( theAreaStr, pDoc, eConv );
356 :
357 0 : if ( SCA_VALID == (nResult & SCA_VALID) )
358 : {
359 0 : ScAddress& rStart = theFilterArea.aStart;
360 0 : ScAddress& rEnd = theFilterArea.aEnd;
361 :
362 0 : if ( aBtnCopyResult.IsChecked() )
363 : {
364 0 : theOutParam.bInplace = false;
365 0 : theOutParam.nDestTab = theAdrCopy.Tab();
366 0 : theOutParam.nDestCol = theAdrCopy.Col();
367 0 : theOutParam.nDestRow = theAdrCopy.Row();
368 : }
369 : else
370 : {
371 0 : theOutParam.bInplace = true;
372 0 : theOutParam.nDestTab = 0;
373 0 : theOutParam.nDestCol = 0;
374 0 : theOutParam.nDestRow = 0;
375 : }
376 :
377 0 : theOutParam.bHasHeader = aBtnHeader.IsChecked();
378 0 : theOutParam.bByRow = true;
379 0 : theOutParam.bCaseSens = aBtnCase.IsChecked();
380 0 : theOutParam.bRegExp = aBtnRegExp.IsChecked();
381 0 : theOutParam.bDuplicate = !aBtnUnique.IsChecked();
382 0 : theOutParam.bDestPers = aBtnDestPers.IsChecked();
383 :
384 : bQueryOk =
385 0 : pDoc->CreateQueryParam( rStart.Col(),
386 : rStart.Row(),
387 0 : rEnd.Col(),
388 : rEnd.Row(),
389 0 : rStart.Tab(),
390 0 : theOutParam );
391 : }
392 : }
393 :
394 0 : if ( bQueryOk )
395 : {
396 0 : SetDispatcherLock( false );
397 0 : SwitchToDocument();
398 0 : GetBindings().GetDispatcher()->Execute( FID_FILTER_OK,
399 : SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
400 0 : GetOutputItem( theOutParam, theFilterArea ), 0L, 0L );
401 0 : Close();
402 : }
403 : else
404 : {
405 0 : ERRORBOX( STR_INVALID_QUERYAREA );
406 0 : aEdFilterArea.GrabFocus();
407 0 : }
408 : }
409 0 : else if ( pBtn == &aBtnCancel )
410 : {
411 0 : Close();
412 : }
413 0 : return 0;
414 : }
415 :
416 :
417 : //----------------------------------------------------------------------------
418 :
419 0 : IMPL_LINK( ScSpecialFilterDlg, TimeOutHdl, Timer*, _pTimer )
420 : {
421 : // alle 50ms nachschauen, ob RefInputMode noch stimmt
422 :
423 0 : if( (_pTimer == pTimer) && IsActive() )
424 : {
425 0 : if( aEdCopyArea.HasFocus() || aRbCopyArea.HasFocus() )
426 : {
427 0 : pRefInputEdit = &aEdCopyArea;
428 0 : bRefInputMode = true;
429 : }
430 0 : else if( aEdFilterArea.HasFocus() || aRbFilterArea.HasFocus() )
431 : {
432 0 : pRefInputEdit = &aEdFilterArea;
433 0 : bRefInputMode = true;
434 : }
435 0 : else if( bRefInputMode )
436 : {
437 0 : pRefInputEdit = NULL;
438 0 : bRefInputMode = false;
439 : }
440 : }
441 :
442 0 : pTimer->Start();
443 :
444 0 : return 0;
445 : }
446 :
447 :
448 : //----------------------------------------------------------------------------
449 :
450 0 : IMPL_LINK( ScSpecialFilterDlg, FilterAreaSelHdl, ListBox*, pLb )
451 : {
452 0 : if ( pLb == &aLbFilterArea )
453 : {
454 0 : String aString;
455 0 : sal_uInt16 nSelPos = aLbFilterArea.GetSelectEntryPos();
456 :
457 0 : if ( nSelPos > 0 )
458 0 : aString = *(String*)aLbFilterArea.GetEntryData( nSelPos );
459 :
460 0 : aEdFilterArea.SetText( aString );
461 : }
462 :
463 0 : return 0;
464 : }
465 :
466 :
467 : //----------------------------------------------------------------------------
468 :
469 0 : IMPL_LINK( ScSpecialFilterDlg, FilterAreaModHdl, formula::RefEdit*, pEd )
470 : {
471 0 : if ( pEd == &aEdFilterArea )
472 : {
473 0 : if ( pDoc && pViewData )
474 : {
475 0 : String theCurAreaStr = pEd->GetText();
476 0 : sal_uInt16 nResult = ScRange().Parse( theCurAreaStr, pDoc );
477 :
478 0 : if ( SCA_VALID == (nResult & SCA_VALID) )
479 : {
480 0 : String* pStr = NULL;
481 0 : sal_Bool bFound = false;
482 0 : sal_uInt16 i = 0;
483 0 : sal_uInt16 nCount = aLbFilterArea.GetEntryCount();
484 :
485 0 : for ( i=1; i<nCount && !bFound; i++ )
486 : {
487 0 : pStr = (String*)aLbFilterArea.GetEntryData( i );
488 0 : bFound = (theCurAreaStr == *pStr);
489 : }
490 :
491 0 : if ( bFound )
492 0 : aLbFilterArea.SelectEntryPos( --i );
493 : else
494 0 : aLbFilterArea.SelectEntryPos( 0 );
495 0 : }
496 : }
497 : else
498 0 : aLbFilterArea.SelectEntryPos( 0 );
499 : }
500 :
501 0 : return 0;
502 15 : }
503 :
504 :
505 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|