Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / ui / dbgui / sfiltdlg.cxx
blobcc8950e1124ecbb81566ff5650bf4a38fbb010d8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sfx2/dispatch.hxx>
21 #include <vcl/idle.hxx>
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"
32 #include "foptmgr.hxx"
34 #include "globstr.hrc"
35 #include "filter.hrc"
37 #include "filtdlg.hxx"
38 #include <vcl/msgbox.hxx>
40 // DEFINE --------------------------------------------------------------------
42 #define ERRORBOX(rid) ScopedVclPtrInstance<MessageDialog>(this, ScGlobal::GetRscString(rid))->Execute()
44 // class ScSpecialFilterDialog
46 ScSpecialFilterDlg::ScSpecialFilterDlg( SfxBindings* pB, SfxChildWindow* pCW, vcl::Window* pParent,
47 const SfxItemSet& rArgSet )
49 : ScAnyRefDlg ( pB, pCW, pParent, "AdvancedFilterDialog", "modules/scalc/ui/advancedfilterdialog.ui" ),
51 aStrUndefined ( SC_RESSTR(SCSTR_UNDEFINED) ),
52 pOptionsMgr ( nullptr ),
53 nWhichQuery ( rArgSet.GetPool()->GetWhich( SID_QUERY ) ),
54 theQueryData ( static_cast<const ScQueryItem&>(
55 rArgSet.Get( nWhichQuery )).GetQueryData() ),
56 pOutItem ( nullptr ),
57 pViewData ( nullptr ),
58 pDoc ( nullptr ),
59 pRefInputEdit ( nullptr ),
60 bRefInputMode ( false ),
61 pIdle ( nullptr )
63 get(pLbFilterArea,"lbfilterarea");
64 get(pEdFilterArea,"edfilterarea");
65 pEdFilterArea->SetReferences(this, get<VclFrame>("filterframe")->get_label_widget());
66 get(pRbFilterArea,"rbfilterarea");
67 pRbFilterArea->SetReferences(this, pEdFilterArea);
68 get(pBtnCase,"case");
69 get(pBtnRegExp,"regexp");
70 get(pBtnHeader,"header");
71 get(pBtnUnique,"unique");
72 get(pBtnCopyResult,"copyresult");
73 get(pLbCopyArea,"lbcopyarea");
74 get(pEdCopyArea,"edcopyarea");
75 pEdCopyArea->SetReferences(this, pBtnCopyResult);
76 get(pRbCopyArea,"rbcopyarea");
77 pRbCopyArea->SetReferences(this, pEdCopyArea);
78 get(pBtnDestPers,"destpers");
79 get(pFtDbAreaLabel,"dbarealabel");
80 get(pFtDbArea,"dbarea");
81 get(pBtnOk,"ok");
82 get(pBtnCancel,"cancel");
83 get(pExpander,"more");
85 Init( rArgSet );
86 pEdFilterArea->GrabFocus();
88 // Hack: RefInput-Kontrolle
89 pIdle = new Idle;
90 // FIXME: this is an abomination
91 pIdle->SetPriority( SchedulerPriority::LOWEST );
92 pIdle->SetIdleHdl( LINK( this, ScSpecialFilterDlg, TimeOutHdl ) );
93 pIdle->Start();
95 pLbCopyArea->SetAccessibleName(pBtnCopyResult->GetText());
96 pEdCopyArea->SetAccessibleName(pBtnCopyResult->GetText());
99 ScSpecialFilterDlg::~ScSpecialFilterDlg()
101 disposeOnce();
104 void ScSpecialFilterDlg::dispose()
106 const sal_Int32 nEntries = pLbFilterArea->GetEntryCount();
108 for ( sal_Int32 i=1; i<nEntries; ++i )
109 delete static_cast<OUString*>(pLbFilterArea->GetEntryData( i ));
111 delete pOptionsMgr;
113 delete pOutItem;
115 // Hack: RefInput-Kontrolle
116 pIdle->Stop();
117 delete pIdle;
119 pLbFilterArea.clear();
120 pEdFilterArea.clear();
121 pRbFilterArea.clear();
122 pExpander.clear();
123 pBtnCase.clear();
124 pBtnRegExp.clear();
125 pBtnHeader.clear();
126 pBtnUnique.clear();
127 pBtnCopyResult.clear();
128 pLbCopyArea.clear();
129 pEdCopyArea.clear();
130 pRbCopyArea.clear();
131 pBtnDestPers.clear();
132 pFtDbAreaLabel.clear();
133 pFtDbArea.clear();
134 pBtnOk.clear();
135 pBtnCancel.clear();
136 pRefInputEdit.clear();
137 ScAnyRefDlg::dispose();
140 void ScSpecialFilterDlg::Init( const SfxItemSet& rArgSet )
142 const ScQueryItem& rQueryItem = static_cast<const ScQueryItem&>(
143 rArgSet.Get( nWhichQuery ));
145 pBtnOk->SetClickHdl ( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) );
146 pBtnCancel->SetClickHdl ( LINK( this, ScSpecialFilterDlg, EndDlgHdl ) );
147 pLbFilterArea->SetSelectHdl ( LINK( this, ScSpecialFilterDlg, FilterAreaSelHdl ) );
148 pEdFilterArea->SetModifyHdl ( LINK( this, ScSpecialFilterDlg, FilterAreaModHdl ) );
150 pViewData = rQueryItem.GetViewData();
151 pDoc = pViewData ? pViewData->GetDocument() : nullptr;
153 pEdFilterArea->SetText( EMPTY_OUSTRING ); // may be overwritten below
155 if ( pViewData && pDoc )
157 if(pDoc->GetChangeTrack()!=nullptr) pBtnCopyResult->Disable();
159 ScRangeName* pRangeNames = pDoc->GetRangeName();
160 pLbFilterArea->Clear();
161 pLbFilterArea->InsertEntry( aStrUndefined, 0 );
163 if (!pRangeNames->empty())
165 ScRangeName::const_iterator itr = pRangeNames->begin(), itrEnd = pRangeNames->end();
166 for (; itr != itrEnd; ++itr)
168 if (!itr->second->HasType(ScRangeData::Type::Criteria))
169 continue;
171 const sal_Int32 nInsert = pLbFilterArea->InsertEntry(itr->second->GetName());
172 OUString aSymbol;
173 itr->second->GetSymbol(aSymbol);
174 pLbFilterArea->SetEntryData(nInsert, new OUString(aSymbol));
178 // is there a stored source range?
180 ScRange aAdvSource;
181 if (rQueryItem.GetAdvancedQuerySource(aAdvSource))
183 OUString aRefStr(aAdvSource.Format(ScRefFlags::RANGE_ABS_3D, pDoc, pDoc->GetAddressConvention()));
184 pEdFilterArea->SetRefString( aRefStr );
188 pLbFilterArea->SelectEntryPos( 0 );
190 // Optionen initialisieren lassen:
192 pOptionsMgr = new ScFilterOptionsMgr(
193 pViewData,
194 theQueryData,
195 pBtnCase,
196 pBtnRegExp,
197 pBtnHeader,
198 pBtnUnique,
199 pBtnCopyResult,
200 pBtnDestPers,
201 pLbCopyArea,
202 pEdCopyArea,
203 pRbCopyArea,
204 pFtDbAreaLabel,
205 pFtDbArea,
206 aStrUndefined );
208 // Spezialfilter braucht immer Spaltenkoepfe
209 pBtnHeader->Check();
210 pBtnHeader->Disable();
212 // Modal-Modus einschalten
213 // SetDispatcherLock( true );
214 //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
215 //SFX_APPWINDOW->Disable(false); //! allgemeine Methode im ScAnyRefDlg
218 bool ScSpecialFilterDlg::Close()
220 if (pViewData)
221 pViewData->GetDocShell()->CancelAutoDBRange();
223 return DoClose( ScSpecialFilterDlgWrapper::GetChildWindowId() );
226 // Uebergabe eines mit der Maus selektierten Tabellenbereiches, der dann als
227 // neue Selektion im Referenz-Edit angezeigt wird.
229 void ScSpecialFilterDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
231 if ( bRefInputMode && pRefInputEdit ) // Nur moeglich, wenn im Referenz-Editmodus
233 if ( rRef.aStart != rRef.aEnd )
234 RefInputStart( pRefInputEdit );
236 OUString aRefStr;
237 const formula::FormulaGrammar::AddressConvention eConv = pDocP->GetAddressConvention();
239 if ( pRefInputEdit == pEdCopyArea)
240 aRefStr = rRef.aStart.Format(ScRefFlags::ADDR_ABS_3D, pDocP, eConv);
241 else if ( pRefInputEdit == pEdFilterArea)
242 aRefStr = rRef.Format(ScRefFlags::RANGE_ABS_3D, pDocP, eConv);
244 pRefInputEdit->SetRefString( aRefStr );
248 void ScSpecialFilterDlg::SetActive()
250 if ( bRefInputMode )
252 if ( pRefInputEdit == pEdCopyArea )
254 pEdCopyArea->GrabFocus();
255 pEdCopyArea->GetModifyHdl().Call( *pEdCopyArea );
257 else if ( pRefInputEdit == pEdFilterArea )
259 pEdFilterArea->GrabFocus();
260 FilterAreaModHdl( *pEdFilterArea );
263 else
264 GrabFocus();
266 RefInputDone();
269 ScQueryItem* ScSpecialFilterDlg::GetOutputItem( const ScQueryParam& rParam,
270 const ScRange& rSource )
272 if ( pOutItem ) DELETEZ( pOutItem );
273 pOutItem = new ScQueryItem( nWhichQuery, &rParam );
274 pOutItem->SetAdvancedQuerySource( &rSource );
276 return pOutItem;
279 bool ScSpecialFilterDlg::IsRefInputMode() const
281 return bRefInputMode;
284 // Handler:
286 IMPL_LINK_TYPED( ScSpecialFilterDlg, EndDlgHdl, Button*, pBtn, void )
288 OSL_ENSURE( pDoc && pViewData, "Document or ViewData not found. :-/" );
290 if ( (pBtn == pBtnOk) && pDoc && pViewData )
292 OUString theCopyStr( pEdCopyArea->GetText() );
293 OUString theAreaStr( pEdFilterArea->GetText() );
294 ScQueryParam theOutParam( theQueryData );
295 ScAddress theAdrCopy;
296 bool bEditInputOk = true;
297 bool bQueryOk = false;
298 ScRange theFilterArea;
299 const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
301 if ( pBtnCopyResult->IsChecked() )
303 sal_Int32 nColonPos = theCopyStr.indexOf( ':' );
305 if ( -1 != nColonPos )
306 theCopyStr = theCopyStr.copy( 0, nColonPos );
308 ScRefFlags nResult = theAdrCopy.Parse( theCopyStr, pDoc, eConv );
310 if ( (nResult & ScRefFlags::VALID) == ScRefFlags::ZERO )
312 if (!pExpander->get_expanded())
313 pExpander->set_expanded(true);
315 ERRORBOX( STR_INVALID_TABREF );
316 pEdCopyArea->GrabFocus();
317 bEditInputOk = false;
321 if ( bEditInputOk )
323 ScRefFlags nResult = ScRange().Parse( theAreaStr, pDoc, eConv );
325 if ( (nResult & ScRefFlags::VALID) == ScRefFlags::ZERO )
327 ERRORBOX( STR_INVALID_TABREF );
328 pEdFilterArea->GrabFocus();
329 bEditInputOk = false;
333 if ( bEditInputOk )
336 * Alle Edit-Felder enthalten gueltige Bereiche.
337 * Nun wird versucht aus dem Filterbereich
338 * ein ScQueryParam zu erzeugen:
341 ScRefFlags nResult = theFilterArea.Parse( theAreaStr, pDoc, eConv );
343 if ( (nResult & ScRefFlags::VALID) == ScRefFlags::VALID )
345 ScAddress& rStart = theFilterArea.aStart;
346 ScAddress& rEnd = theFilterArea.aEnd;
348 if ( pBtnCopyResult->IsChecked() )
350 theOutParam.bInplace = false;
351 theOutParam.nDestTab = theAdrCopy.Tab();
352 theOutParam.nDestCol = theAdrCopy.Col();
353 theOutParam.nDestRow = theAdrCopy.Row();
355 else
357 theOutParam.bInplace = true;
358 theOutParam.nDestTab = 0;
359 theOutParam.nDestCol = 0;
360 theOutParam.nDestRow = 0;
363 theOutParam.bHasHeader = pBtnHeader->IsChecked();
364 theOutParam.bByRow = true;
365 theOutParam.bCaseSens = pBtnCase->IsChecked();
366 theOutParam.eSearchType = pBtnRegExp->IsChecked() ? utl::SearchParam::SRCH_REGEXP :
367 utl::SearchParam::SRCH_NORMAL;
368 theOutParam.bDuplicate = !pBtnUnique->IsChecked();
369 theOutParam.bDestPers = pBtnDestPers->IsChecked();
371 bQueryOk =
372 pDoc->CreateQueryParam( rStart.Col(),
373 rStart.Row(),
374 rEnd.Col(),
375 rEnd.Row(),
376 rStart.Tab(),
377 theOutParam );
381 if ( bQueryOk )
383 SetDispatcherLock( false );
384 SwitchToDocument();
385 GetBindings().GetDispatcher()->ExecuteList(FID_FILTER_OK,
386 SfxCallMode::SLOT | SfxCallMode::RECORD,
387 { GetOutputItem(theOutParam, theFilterArea) });
388 Close();
390 else
392 ERRORBOX( STR_INVALID_QUERYAREA );
393 pEdFilterArea->GrabFocus();
396 else if ( pBtn == pBtnCancel )
398 Close();
402 IMPL_LINK_TYPED( ScSpecialFilterDlg, TimeOutHdl, Idle*, _pIdle, void )
404 // every 50ms check whether RefInputMode is still true
406 if( (_pIdle == pIdle) && IsActive() )
408 if( pEdCopyArea->HasFocus() || pRbCopyArea->HasFocus() )
410 pRefInputEdit = pEdCopyArea;
411 bRefInputMode = true;
413 else if( pEdFilterArea->HasFocus() || pRbFilterArea->HasFocus() )
415 pRefInputEdit = pEdFilterArea;
416 bRefInputMode = true;
418 else if( bRefInputMode )
420 pRefInputEdit = nullptr;
421 bRefInputMode = false;
425 pIdle->Start();
428 IMPL_LINK_TYPED( ScSpecialFilterDlg, FilterAreaSelHdl, ListBox&, rLb, void )
430 if ( &rLb == pLbFilterArea )
432 OUString aString;
433 const sal_Int32 nSelPos = pLbFilterArea->GetSelectEntryPos();
435 if ( nSelPos > 0 )
436 aString = *static_cast<OUString*>(pLbFilterArea->GetEntryData( nSelPos ));
438 pEdFilterArea->SetText( aString );
442 IMPL_LINK_TYPED( ScSpecialFilterDlg, FilterAreaModHdl, Edit&, rEd, void )
444 if ( &rEd == pEdFilterArea )
446 if ( pDoc && pViewData )
448 OUString theCurAreaStr = rEd.GetText();
449 ScRefFlags nResult = ScRange().Parse( theCurAreaStr, pDoc );
451 if ( (nResult & ScRefFlags::VALID) == ScRefFlags::VALID )
453 const sal_Int32 nCount = pLbFilterArea->GetEntryCount();
455 for ( sal_Int32 i=1; i<nCount; ++i )
457 OUString* pStr = static_cast<OUString*>(pLbFilterArea->GetEntryData( i ));
458 if (theCurAreaStr == *pStr)
460 pLbFilterArea->SelectEntryPos( i );
461 return;
464 pLbFilterArea->SelectEntryPos( 0 );
467 else
468 pLbFilterArea->SelectEntryPos( 0 );
472 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */