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 : #include "filtdlg.hxx"
37 : #include <vcl/msgbox.hxx>
38 :
39 : // DEFINE --------------------------------------------------------------------
40 :
41 : #define ERRORBOX(rid) ErrorBox( this, WinBits( WB_OK|WB_DEF_OK),\
42 : ScGlobal::GetRscString(rid) ).Execute()
43 :
44 : // class ScSpecialFilterDialog
45 :
46 0 : ScSpecialFilterDlg::ScSpecialFilterDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
47 : const SfxItemSet& rArgSet )
48 :
49 : : ScAnyRefDlg ( pB, pCW, pParent, "AdvancedFilterDialog", "modules/scalc/ui/advancedfilterdialog.ui" ),
50 :
51 :
52 : aStrUndefined ( SC_RESSTR(SCSTR_UNDEFINED) ),
53 : pOptionsMgr ( NULL ),
54 0 : nWhichQuery ( rArgSet.GetPool()->GetWhich( SID_QUERY ) ),
55 : theQueryData ( ((const ScQueryItem&)
56 0 : rArgSet.Get( nWhichQuery )).GetQueryData() ),
57 : pOutItem ( NULL ),
58 : pViewData ( NULL ),
59 : pDoc ( NULL ),
60 : pRefInputEdit ( NULL ),
61 : bRefInputMode ( false ),
62 0 : pTimer ( NULL )
63 : {
64 0 : get(pLbFilterArea,"lbfilterarea");
65 0 : get(pEdFilterArea,"edfilterarea");
66 0 : pEdFilterArea->SetReferences(this, get<VclFrame>("filterframe")->get_label_widget());
67 0 : get(pRbFilterArea,"rbfilterarea");
68 0 : pRbFilterArea->SetReferences(this, pEdFilterArea);
69 0 : get(pBtnCase,"case");
70 0 : get(pBtnRegExp,"regexp");
71 0 : get(pBtnHeader,"header");
72 0 : get(pBtnUnique,"unique");
73 0 : get(pBtnCopyResult,"copyresult");
74 0 : get(pLbCopyArea,"lbcopyarea");
75 0 : get(pEdCopyArea,"edcopyarea");
76 0 : pEdCopyArea->SetReferences(this, pBtnCopyResult);
77 0 : get(pRbCopyArea,"rbcopyarea");
78 0 : pRbCopyArea->SetReferences(this, pEdCopyArea);
79 0 : get(pBtnDestPers,"destpers");
80 0 : get(pFtDbAreaLabel,"dbarealabel");
81 0 : get(pFtDbArea,"dbarea");
82 0 : get(pBtnOk,"ok");
83 0 : get(pBtnCancel,"cancel");
84 0 : get(pExpander,"more");
85 :
86 0 : Init( rArgSet );
87 0 : pEdFilterArea->GrabFocus();
88 :
89 : // Hack: RefInput-Kontrolle
90 0 : pTimer = new Timer;
91 0 : pTimer->SetTimeout( 50 ); // 50ms warten
92 0 : pTimer->SetTimeoutHdl( LINK( this, ScSpecialFilterDlg, TimeOutHdl ) );
93 0 : pTimer->Start();
94 :
95 0 : pLbCopyArea->SetAccessibleName(pBtnCopyResult->GetText());
96 0 : pEdCopyArea->SetAccessibleName(pBtnCopyResult->GetText());
97 0 : }
98 :
99 :
100 0 : ScSpecialFilterDlg::~ScSpecialFilterDlg()
101 : {
102 0 : sal_uInt16 nEntries = pLbFilterArea->GetEntryCount();
103 : sal_uInt16 i;
104 :
105 0 : for ( i=1; i<nEntries; i++ )
106 0 : delete (OUString*)pLbFilterArea->GetEntryData( i );
107 :
108 0 : delete pOptionsMgr;
109 :
110 0 : if ( pOutItem )
111 0 : delete pOutItem;
112 :
113 : // Hack: RefInput-Kontrolle
114 0 : pTimer->Stop();
115 0 : delete pTimer;
116 0 : }
117 :
118 :
119 0 : void ScSpecialFilterDlg::Init( const SfxItemSet& rArgSet )
120 : {
121 : const ScQueryItem& rQueryItem = (const ScQueryItem&)
122 0 : rArgSet.Get( nWhichQuery );
123 :
124 0 : pBtnOk->SetClickHdl ( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) );
125 0 : pBtnCancel->SetClickHdl ( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) );
126 0 : pLbFilterArea->SetSelectHdl ( LINK( this, ScSpecialFilterDlg, FilterAreaSelHdl ) );
127 0 : pEdFilterArea->SetModifyHdl ( LINK( this, ScSpecialFilterDlg, FilterAreaModHdl ) );
128 :
129 0 : pViewData = rQueryItem.GetViewData();
130 0 : pDoc = pViewData ? pViewData->GetDocument() : NULL;
131 :
132 0 : pEdFilterArea->SetText( EMPTY_OUSTRING ); // may be overwritten below
133 :
134 0 : if ( pViewData && pDoc )
135 : {
136 0 : if(pDoc->GetChangeTrack()!=NULL) pBtnCopyResult->Disable();
137 :
138 0 : ScRangeName* pRangeNames = pDoc->GetRangeName();
139 0 : pLbFilterArea->Clear();
140 0 : pLbFilterArea->InsertEntry( aStrUndefined, 0 );
141 :
142 0 : if (!pRangeNames->empty())
143 : {
144 0 : ScRangeName::const_iterator itr = pRangeNames->begin(), itrEnd = pRangeNames->end();
145 0 : sal_uInt16 nInsert = 0;
146 0 : for (; itr != itrEnd; ++itr)
147 : {
148 0 : if (!itr->second->HasType(RT_CRITERIA))
149 0 : continue;
150 :
151 0 : nInsert = pLbFilterArea->InsertEntry(itr->second->GetName());
152 0 : OUString aSymbol;
153 0 : itr->second->GetSymbol(aSymbol);
154 0 : pLbFilterArea->SetEntryData(nInsert, new OUString(aSymbol));
155 0 : }
156 : }
157 :
158 : // is there a stored source range?
159 :
160 0 : ScRange aAdvSource;
161 0 : if (rQueryItem.GetAdvancedQuerySource(aAdvSource))
162 : {
163 0 : OUString aRefStr(aAdvSource.Format(SCR_ABS_3D, pDoc, pDoc->GetAddressConvention()));
164 0 : pEdFilterArea->SetRefString( aRefStr );
165 : }
166 : }
167 :
168 0 : pLbFilterArea->SelectEntryPos( 0 );
169 :
170 : // Optionen initialisieren lassen:
171 :
172 : pOptionsMgr = new ScFilterOptionsMgr(
173 : pViewData,
174 : theQueryData,
175 : pBtnCase,
176 : pBtnRegExp,
177 : pBtnHeader,
178 : pBtnUnique,
179 : pBtnCopyResult,
180 : pBtnDestPers,
181 : pLbCopyArea,
182 : pEdCopyArea,
183 : pRbCopyArea,
184 : pFtDbAreaLabel,
185 : pFtDbArea,
186 0 : aStrUndefined );
187 :
188 : // Spezialfilter braucht immer Spaltenkoepfe
189 0 : pBtnHeader->Check(true);
190 0 : pBtnHeader->Disable();
191 :
192 : // Modal-Modus einschalten
193 : // SetDispatcherLock( true );
194 : //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
195 : //SFX_APPWINDOW->Disable(false); //! allgemeine Methode im ScAnyRefDlg
196 0 : }
197 :
198 :
199 0 : bool ScSpecialFilterDlg::Close()
200 : {
201 0 : if (pViewData)
202 0 : pViewData->GetDocShell()->CancelAutoDBRange();
203 :
204 0 : return DoClose( ScSpecialFilterDlgWrapper::GetChildWindowId() );
205 : }
206 :
207 : // Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
208 : // neue Selektion im Referenz-Edit angezeigt wird.
209 :
210 0 : void ScSpecialFilterDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
211 : {
212 0 : if ( bRefInputMode && pRefInputEdit ) // Nur moeglich, wenn im Referenz-Editmodus
213 : {
214 0 : if ( rRef.aStart != rRef.aEnd )
215 0 : RefInputStart( pRefInputEdit );
216 :
217 0 : OUString aRefStr;
218 0 : const formula::FormulaGrammar::AddressConvention eConv = pDocP->GetAddressConvention();
219 :
220 0 : if ( pRefInputEdit == pEdCopyArea)
221 0 : aRefStr = rRef.aStart.Format(SCA_ABS_3D, pDocP, eConv);
222 0 : else if ( pRefInputEdit == pEdFilterArea)
223 0 : aRefStr = rRef.Format(SCR_ABS_3D, pDocP, eConv);
224 :
225 0 : pRefInputEdit->SetRefString( aRefStr );
226 : }
227 0 : }
228 :
229 :
230 0 : void ScSpecialFilterDlg::SetActive()
231 : {
232 0 : if ( bRefInputMode )
233 : {
234 0 : if ( pRefInputEdit == pEdCopyArea )
235 : {
236 0 : pEdCopyArea->GrabFocus();
237 0 : if ( pEdCopyArea->GetModifyHdl().IsSet() )
238 0 : ((Link&)pEdCopyArea->GetModifyHdl()).Call( pEdCopyArea );
239 : }
240 0 : else if ( pRefInputEdit == pEdFilterArea )
241 : {
242 0 : pEdFilterArea->GrabFocus();
243 0 : FilterAreaModHdl( pEdFilterArea );
244 : }
245 : }
246 : else
247 0 : GrabFocus();
248 :
249 0 : RefInputDone();
250 0 : }
251 :
252 :
253 0 : ScQueryItem* ScSpecialFilterDlg::GetOutputItem( const ScQueryParam& rParam,
254 : const ScRange& rSource )
255 : {
256 0 : if ( pOutItem ) DELETEZ( pOutItem );
257 0 : pOutItem = new ScQueryItem( nWhichQuery, &rParam );
258 0 : pOutItem->SetAdvancedQuerySource( &rSource );
259 :
260 0 : return pOutItem;
261 : }
262 :
263 :
264 0 : bool ScSpecialFilterDlg::IsRefInputMode() const
265 : {
266 0 : return bRefInputMode;
267 : }
268 :
269 : // Handler:
270 :
271 :
272 0 : IMPL_LINK( ScSpecialFilterDlg, EndDlgHdl, Button*, pBtn )
273 : {
274 : OSL_ENSURE( pDoc && pViewData, "Document or ViewData not found. :-/" );
275 :
276 0 : if ( (pBtn == pBtnOk) && pDoc && pViewData )
277 : {
278 0 : OUString theCopyStr( pEdCopyArea->GetText() );
279 0 : OUString theAreaStr( pEdFilterArea->GetText() );
280 0 : ScQueryParam theOutParam( theQueryData );
281 0 : ScAddress theAdrCopy;
282 0 : sal_Bool bEditInputOk = true;
283 0 : sal_Bool bQueryOk = false;
284 0 : ScRange theFilterArea;
285 0 : const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
286 :
287 0 : if ( pBtnCopyResult->IsChecked() )
288 : {
289 0 : sal_Int32 nColonPos = theCopyStr.indexOf( ':' );
290 :
291 0 : if ( -1 != nColonPos )
292 0 : theCopyStr = theCopyStr.copy( 0, nColonPos );
293 :
294 0 : sal_uInt16 nResult = theAdrCopy.Parse( theCopyStr, pDoc, eConv );
295 :
296 0 : if ( SCA_VALID != (nResult & SCA_VALID) )
297 : {
298 0 : if (!pExpander->get_expanded())
299 0 : pExpander->set_expanded(true);
300 :
301 0 : ERRORBOX( STR_INVALID_TABREF );
302 0 : pEdCopyArea->GrabFocus();
303 0 : bEditInputOk = false;
304 : }
305 : }
306 :
307 0 : if ( bEditInputOk )
308 : {
309 0 : sal_uInt16 nResult = ScRange().Parse( theAreaStr, pDoc, eConv );
310 :
311 0 : if ( SCA_VALID != (nResult & SCA_VALID) )
312 : {
313 0 : ERRORBOX( STR_INVALID_TABREF );
314 0 : pEdFilterArea->GrabFocus();
315 0 : bEditInputOk = false;
316 : }
317 : }
318 :
319 0 : if ( bEditInputOk )
320 : {
321 : /*
322 : * Alle Edit-Felder enthalten gueltige Bereiche.
323 : * Nun wird versucht aus dem Filterbereich
324 : * ein ScQueryParam zu erzeugen:
325 : */
326 :
327 0 : sal_uInt16 nResult = theFilterArea.Parse( theAreaStr, pDoc, eConv );
328 :
329 0 : if ( SCA_VALID == (nResult & SCA_VALID) )
330 : {
331 0 : ScAddress& rStart = theFilterArea.aStart;
332 0 : ScAddress& rEnd = theFilterArea.aEnd;
333 :
334 0 : if ( pBtnCopyResult->IsChecked() )
335 : {
336 0 : theOutParam.bInplace = false;
337 0 : theOutParam.nDestTab = theAdrCopy.Tab();
338 0 : theOutParam.nDestCol = theAdrCopy.Col();
339 0 : theOutParam.nDestRow = theAdrCopy.Row();
340 : }
341 : else
342 : {
343 0 : theOutParam.bInplace = true;
344 0 : theOutParam.nDestTab = 0;
345 0 : theOutParam.nDestCol = 0;
346 0 : theOutParam.nDestRow = 0;
347 : }
348 :
349 0 : theOutParam.bHasHeader = pBtnHeader->IsChecked();
350 0 : theOutParam.bByRow = true;
351 0 : theOutParam.bCaseSens = pBtnCase->IsChecked();
352 0 : theOutParam.bRegExp = pBtnRegExp->IsChecked();
353 0 : theOutParam.bDuplicate = !pBtnUnique->IsChecked();
354 0 : theOutParam.bDestPers = pBtnDestPers->IsChecked();
355 :
356 : bQueryOk =
357 0 : pDoc->CreateQueryParam( rStart.Col(),
358 : rStart.Row(),
359 0 : rEnd.Col(),
360 : rEnd.Row(),
361 0 : rStart.Tab(),
362 0 : theOutParam );
363 : }
364 : }
365 :
366 0 : if ( bQueryOk )
367 : {
368 0 : SetDispatcherLock( false );
369 0 : SwitchToDocument();
370 0 : GetBindings().GetDispatcher()->Execute( FID_FILTER_OK,
371 : SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
372 0 : GetOutputItem( theOutParam, theFilterArea ), 0L, 0L );
373 0 : Close();
374 : }
375 : else
376 : {
377 0 : ERRORBOX( STR_INVALID_QUERYAREA );
378 0 : pEdFilterArea->GrabFocus();
379 0 : }
380 : }
381 0 : else if ( pBtn == pBtnCancel )
382 : {
383 0 : Close();
384 : }
385 0 : return 0;
386 : }
387 :
388 :
389 0 : IMPL_LINK( ScSpecialFilterDlg, TimeOutHdl, Timer*, _pTimer )
390 : {
391 : // alle 50ms nachschauen, ob RefInputMode noch stimmt
392 :
393 0 : if( (_pTimer == pTimer) && IsActive() )
394 : {
395 0 : if( pEdCopyArea->HasFocus() || pRbCopyArea->HasFocus() )
396 : {
397 0 : pRefInputEdit = pEdCopyArea;
398 0 : bRefInputMode = true;
399 : }
400 0 : else if( pEdFilterArea->HasFocus() || pRbFilterArea->HasFocus() )
401 : {
402 0 : pRefInputEdit = pEdFilterArea;
403 0 : bRefInputMode = true;
404 : }
405 0 : else if( bRefInputMode )
406 : {
407 0 : pRefInputEdit = NULL;
408 0 : bRefInputMode = false;
409 : }
410 : }
411 :
412 0 : pTimer->Start();
413 :
414 0 : return 0;
415 : }
416 :
417 :
418 0 : IMPL_LINK( ScSpecialFilterDlg, FilterAreaSelHdl, ListBox*, pLb )
419 : {
420 0 : if ( pLb == pLbFilterArea )
421 : {
422 0 : OUString aString;
423 0 : sal_uInt16 nSelPos = pLbFilterArea->GetSelectEntryPos();
424 :
425 0 : if ( nSelPos > 0 )
426 0 : aString = *(OUString*)pLbFilterArea->GetEntryData( nSelPos );
427 :
428 0 : pEdFilterArea->SetText( aString );
429 : }
430 :
431 0 : return 0;
432 : }
433 :
434 :
435 0 : IMPL_LINK( ScSpecialFilterDlg, FilterAreaModHdl, formula::RefEdit*, pEd )
436 : {
437 0 : if ( pEd == pEdFilterArea )
438 : {
439 0 : if ( pDoc && pViewData )
440 : {
441 0 : OUString theCurAreaStr = pEd->GetText();
442 0 : sal_uInt16 nResult = ScRange().Parse( theCurAreaStr, pDoc );
443 :
444 0 : if ( SCA_VALID == (nResult & SCA_VALID) )
445 : {
446 0 : OUString* pStr = NULL;
447 0 : sal_Bool bFound = false;
448 0 : sal_uInt16 i = 0;
449 0 : sal_uInt16 nCount = pLbFilterArea->GetEntryCount();
450 :
451 0 : for ( i=1; i<nCount && !bFound; i++ )
452 : {
453 0 : pStr = (OUString*)pLbFilterArea->GetEntryData( i );
454 0 : bFound = (theCurAreaStr == *pStr);
455 : }
456 :
457 0 : if ( bFound )
458 0 : pLbFilterArea->SelectEntryPos( --i );
459 : else
460 0 : pLbFilterArea->SelectEntryPos( 0 );
461 0 : }
462 : }
463 : else
464 0 : pLbFilterArea->SelectEntryPos( 0 );
465 : }
466 :
467 0 : return 0;
468 0 : }
469 :
470 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|