1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
26 #include "reffact.hxx"
27 #include "viewdata.hxx"
28 #include "document.hxx"
30 #include "scresid.hxx"
32 #include "foptmgr.hxx"
34 #include "globstr.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() ),
57 pViewData ( nullptr ),
59 pRefInputEdit ( nullptr ),
60 bRefInputMode ( false ),
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
);
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");
82 get(pBtnCancel
,"cancel");
83 get(pExpander
,"more");
86 pEdFilterArea
->GrabFocus();
88 // Hack: RefInput-Kontrolle
90 // FIXME: this is an abomination
91 pIdle
->SetPriority( SchedulerPriority::LOWEST
);
92 pIdle
->SetIdleHdl( LINK( this, ScSpecialFilterDlg
, TimeOutHdl
) );
95 pLbCopyArea
->SetAccessibleName(pBtnCopyResult
->GetText());
96 pEdCopyArea
->SetAccessibleName(pBtnCopyResult
->GetText());
99 ScSpecialFilterDlg::~ScSpecialFilterDlg()
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
));
115 // Hack: RefInput-Kontrolle
119 pLbFilterArea
.clear();
120 pEdFilterArea
.clear();
121 pRbFilterArea
.clear();
127 pBtnCopyResult
.clear();
131 pBtnDestPers
.clear();
132 pFtDbAreaLabel
.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
))
171 const sal_Int32 nInsert
= pLbFilterArea
->InsertEntry(itr
->second
->GetName());
173 itr
->second
->GetSymbol(aSymbol
);
174 pLbFilterArea
->SetEntryData(nInsert
, new OUString(aSymbol
));
178 // is there a stored source range?
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(
208 // Spezialfilter braucht immer Spaltenkoepfe
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()
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
);
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()
252 if ( pRefInputEdit
== pEdCopyArea
)
254 pEdCopyArea
->GrabFocus();
255 pEdCopyArea
->GetModifyHdl().Call( *pEdCopyArea
);
257 else if ( pRefInputEdit
== pEdFilterArea
)
259 pEdFilterArea
->GrabFocus();
260 FilterAreaModHdl( *pEdFilterArea
);
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
);
279 bool ScSpecialFilterDlg::IsRefInputMode() const
281 return bRefInputMode
;
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;
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;
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();
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();
372 pDoc
->CreateQueryParam( rStart
.Col(),
383 SetDispatcherLock( false );
385 GetBindings().GetDispatcher()->ExecuteList(FID_FILTER_OK
,
386 SfxCallMode::SLOT
| SfxCallMode::RECORD
,
387 { GetOutputItem(theOutParam
, theFilterArea
) });
392 ERRORBOX( STR_INVALID_QUERYAREA
);
393 pEdFilterArea
->GrabFocus();
396 else if ( pBtn
== pBtnCancel
)
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;
428 IMPL_LINK_TYPED( ScSpecialFilterDlg
, FilterAreaSelHdl
, ListBox
&, rLb
, void )
430 if ( &rLb
== pLbFilterArea
)
433 const sal_Int32 nSelPos
= pLbFilterArea
->GetSelectEntryPos();
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
);
464 pLbFilterArea
->SelectEntryPos( 0 );
468 pLbFilterArea
->SelectEntryPos( 0 );
472 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */