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