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