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 <rangelst.hxx>
21 #include <sfx2/dispatch.hxx>
22 #include <vcl/waitobj.hxx>
24 #include "uiitems.hxx"
26 #include "reffact.hxx"
27 #include "viewdata.hxx"
28 #include "document.hxx"
30 #include "scresid.hxx"
31 #include "queryentry.hxx"
33 #include "foptmgr.hxx"
35 #include "globstr.hrc"
38 #include "filtdlg.hxx"
39 #include <vcl/layout.hxx>
40 #include <svl/sharedstringpool.hxx>
44 #define ERRORBOX(rid) ScopedVclPtrInstance<MessageDialog>::Create(this, ScGlobal::GetRscString(rid))->Execute()
46 #define QUERY_ENTRY_COUNT 4
47 #define INVALID_HEADER_POS std::numeric_limits<size_t>::max()
49 ScFilterDlg::EntryList::EntryList() :
50 mnHeaderPos(INVALID_HEADER_POS
) {}
52 ScFilterDlg::ScFilterDlg(SfxBindings
* pB
, SfxChildWindow
* pCW
, vcl::Window
* pParent
,
53 const SfxItemSet
& rArgSet
)
54 : ScAnyRefDlg ( pB
, pCW
, pParent
, "StandardFilterDialog",
55 "modules/scalc/ui/standardfilterdialog.ui" )
56 , aStrUndefined(SC_RESSTR(SCSTR_UNDEFINED
))
57 , aStrNone(SC_RESSTR(SCSTR_NONE
))
58 , aStrEmpty(SC_RESSTR(SCSTR_FILTER_EMPTY
))
59 , aStrNotEmpty(SC_RESSTR(SCSTR_FILTER_NOTEMPTY
))
60 , aStrColumn(SC_RESSTR(SCSTR_COLUMN
))
62 , nWhichQuery(rArgSet
.GetPool()->GetWhich(SID_QUERY
))
63 , theQueryData(static_cast<const ScQueryItem
&>(rArgSet
.Get(nWhichQuery
)).GetQueryData())
68 , bRefInputMode(false)
71 get(pLbConnect1
,"connect1");
72 get(pLbField1
,"field1");
73 get(pLbCond1
,"cond1");
75 get(pLbConnect2
,"connect2");
76 get(pLbField2
,"field2");
77 get(pLbCond2
,"cond2");
79 get(pLbConnect3
,"connect3");
80 get(pLbField3
,"field3");
81 get(pLbCond3
,"cond3");
83 get(pLbConnect4
,"connect4");
84 get(pLbField4
,"field4");
85 get(pLbCond4
,"cond4");
87 get(pScrollBar
,"scrollbar");
88 get(pExpander
,"more");
89 pExpander
->SetExpandedHdl(LINK(this, ScFilterDlg
, MoreExpandedHdl
));
91 get(pBtnCancel
,"cancel");
93 get(pBtnRegExp
,"regexp");
94 get(pBtnHeader
,"header");
95 get(pBtnUnique
,"unique");
96 get(pBtnCopyResult
,"copyresult");
97 get(pLbCopyArea
,"lbcopyarea");
98 get(pEdCopyArea
,"edcopyarea");
99 pEdCopyArea
->SetReferences(this, pBtnCopyResult
);
100 get(pRbCopyArea
,"rbcopyarea");
101 pRbCopyArea
->SetReferences(this, pEdCopyArea
);
102 get(pBtnDestPers
,"destpers");
103 get(pFtDbAreaLabel
,"dbarealabel");
104 get(pFtDbArea
,"dbarea");
108 // Hack: RefInput control
110 pTimer
->SetTimeout( 50 ); // Wait 50ms
111 pTimer
->SetTimeoutHdl( LINK( this, ScFilterDlg
, TimeOutHdl
) );
115 OUString sAccName
= SC_RESSTR(RID_FILTER_OPERATOR
);
116 aBuf
.append(sAccName
);
118 pLbConnect1
->SetAccessibleName(aBuf
.makeStringAndClear());
119 aBuf
.append(sAccName
);
121 pLbConnect2
->SetAccessibleName(aBuf
.makeStringAndClear());
123 sAccName
= SC_RESSTR(RID_FILTER_FIELDNAME
);
124 aBuf
.append(sAccName
);
126 pLbField1
->SetAccessibleName(aBuf
.makeStringAndClear());
127 aBuf
.append(sAccName
);
129 pLbField2
->SetAccessibleName(aBuf
.makeStringAndClear());
130 aBuf
.append(sAccName
);
132 pLbField3
->SetAccessibleName(aBuf
.makeStringAndClear());
134 sAccName
= SC_RESSTR(RID_FILTER_CONDITION
);
135 aBuf
.append(sAccName
);
137 pLbCond1
->SetAccessibleName(aBuf
.makeStringAndClear());
138 aBuf
.append(sAccName
);
140 pLbCond2
->SetAccessibleName(aBuf
.makeStringAndClear());
141 aBuf
.append(sAccName
);
143 pLbCond3
->SetAccessibleName(aBuf
.makeStringAndClear());
145 sAccName
= SC_RESSTR(RID_FILTER_VALUE
);
146 aBuf
.append(sAccName
);
148 pEdVal1
->SetAccessibleName(aBuf
.makeStringAndClear());
149 aBuf
.append(sAccName
);
151 pEdVal2
->SetAccessibleName(aBuf
.makeStringAndClear());
152 aBuf
.append(sAccName
);
154 pEdVal3
->SetAccessibleName(aBuf
.makeStringAndClear());
156 pLbCopyArea
->SetAccessibleName(ScResId(STR_COPY_AREA_TO
));
157 pEdCopyArea
->SetAccessibleName(ScResId(STR_COPY_AREA_TO
));
161 ScFilterDlg::~ScFilterDlg()
166 void ScFilterDlg::dispose()
171 // Hack: RefInput control
199 pBtnCopyResult
.clear();
203 pBtnDestPers
.clear();
204 pFtDbAreaLabel
.clear();
206 ScAnyRefDlg::dispose();
209 void ScFilterDlg::Init( const SfxItemSet
& rArgSet
)
211 const ScQueryItem
& rQueryItem
= static_cast<const ScQueryItem
&>(
212 rArgSet
.Get( nWhichQuery
));
214 pBtnOk
->SetClickHdl ( LINK( this, ScFilterDlg
, EndDlgHdl
) );
215 pBtnCancel
->SetClickHdl ( LINK( this, ScFilterDlg
, EndDlgHdl
) );
216 pBtnHeader
->SetClickHdl ( LINK( this, ScFilterDlg
, CheckBoxHdl
) );
217 pBtnCase
->SetClickHdl ( LINK( this, ScFilterDlg
, CheckBoxHdl
) );
219 pLbField1
->SetSelectHdl ( LINK( this, ScFilterDlg
, LbSelectHdl
) );
220 pLbField2
->SetSelectHdl ( LINK( this, ScFilterDlg
, LbSelectHdl
) );
221 pLbField3
->SetSelectHdl ( LINK( this, ScFilterDlg
, LbSelectHdl
) );
222 pLbField4
->SetSelectHdl ( LINK( this, ScFilterDlg
, LbSelectHdl
) );
223 pLbConnect1
->SetSelectHdl( LINK( this, ScFilterDlg
, LbSelectHdl
) );
224 pLbConnect2
->SetSelectHdl( LINK( this, ScFilterDlg
, LbSelectHdl
) );
225 pLbConnect3
->SetSelectHdl( LINK( this, ScFilterDlg
, LbSelectHdl
) );
226 pLbConnect4
->SetSelectHdl( LINK( this, ScFilterDlg
, LbSelectHdl
) );
228 pLbCond1
->SetSelectHdl( LINK( this, ScFilterDlg
, LbSelectHdl
) );
229 pLbCond2
->SetSelectHdl( LINK( this, ScFilterDlg
, LbSelectHdl
) );
230 pLbCond3
->SetSelectHdl( LINK( this, ScFilterDlg
, LbSelectHdl
) );
231 pLbCond4
->SetSelectHdl( LINK( this, ScFilterDlg
, LbSelectHdl
) );
233 pViewData
= rQueryItem
.GetViewData();
234 pDoc
= pViewData
? pViewData
->GetDocument() : NULL
;
235 nSrcTab
= pViewData
? pViewData
->GetTabNo() : static_cast<SCTAB
>(0);
237 // for easier access:
238 maFieldLbArr
.reserve(QUERY_ENTRY_COUNT
);
239 maFieldLbArr
.push_back(pLbField1
);
240 maFieldLbArr
.push_back(pLbField2
);
241 maFieldLbArr
.push_back(pLbField3
);
242 maFieldLbArr
.push_back(pLbField4
);
243 maValueEdArr
.reserve(QUERY_ENTRY_COUNT
);
244 maValueEdArr
.push_back(pEdVal1
);
245 maValueEdArr
.push_back(pEdVal2
);
246 maValueEdArr
.push_back(pEdVal3
);
247 maValueEdArr
.push_back(pEdVal4
);
248 maCondLbArr
.reserve(QUERY_ENTRY_COUNT
);
249 maCondLbArr
.push_back(pLbCond1
);
250 maCondLbArr
.push_back(pLbCond2
);
251 maCondLbArr
.push_back(pLbCond3
);
252 maCondLbArr
.push_back(pLbCond4
);
253 maConnLbArr
.reserve(QUERY_ENTRY_COUNT
);
254 maConnLbArr
.push_back(pLbConnect1
);
255 maConnLbArr
.push_back(pLbConnect2
);
256 maConnLbArr
.push_back(pLbConnect3
);
257 maConnLbArr
.push_back(pLbConnect4
);
259 // Option initialization:
260 pOptionsMgr
= new ScFilterOptionsMgr(
275 // Read in field lists and select entries
279 for (size_t i
= 0; i
< QUERY_ENTRY_COUNT
; ++i
)
283 size_t nFieldSelPos
= 0;
285 ScQueryEntry
& rEntry
= theQueryData
.GetEntry(i
);
286 if ( rEntry
.bDoQuery
)
288 const ScQueryEntry::Item
& rItem
= rEntry
.GetQueryItem();
289 nCondPos
= static_cast<size_t>(rEntry
.eOp
);
290 nFieldSelPos
= GetFieldSelPos( static_cast<SCCOL
>(rEntry
.nField
) );
291 if (rEntry
.IsQueryByEmpty())
294 maCondLbArr
[i
]->Disable();
296 else if (rEntry
.IsQueryByNonEmpty())
298 aValStr
= aStrNotEmpty
;
299 maCondLbArr
[i
]->Disable();
303 OUString aQueryStr
= rItem
.maString
.getString();
304 if (aQueryStr
.isEmpty())
306 if (rItem
.meType
== ScQueryEntry::ByValue
)
310 pDoc
->GetFormatTable()->GetInputLineString(rItem
.mfVal
, 0, aValStr
);
313 else if (rItem
.meType
== ScQueryEntry::ByDate
)
317 SvNumberFormatter
* pFormatter
= pDoc
->GetFormatTable();
318 pFormatter
->GetInputLineString(rItem
.mfVal
,
319 pFormatter
->GetStandardFormat( css::util::NumberFormat::DATE
), aValStr
);
324 SAL_WARN( "sc", "ScFilterDlg::Init: empty query string, really?");
330 // XXX NOTE: if not ByString we just assume this has been
331 // set to a proper string corresponding to the numeric
339 nFieldSelPos
= pViewData
? GetFieldSelPos(pViewData
->GetCurX()) : 0;
340 rEntry
.nField
= nFieldSelPos
? (theQueryData
.nCol1
+
341 static_cast<SCCOL
>(nFieldSelPos
) - 1) : static_cast<SCCOL
>(0);
342 rEntry
.bDoQuery
=true;
343 if (maRefreshExceptQuery
.size() < i
+ 1)
344 maRefreshExceptQuery
.resize(i
+ 1, false);
345 maRefreshExceptQuery
[i
] = true;
348 maFieldLbArr
[i
]->SelectEntryPos( nFieldSelPos
);
349 maCondLbArr
[i
]->SelectEntryPos( nCondPos
);
350 maValueEdArr
[i
]->SetText( aValStr
);
351 maValueEdArr
[i
]->EnableAutocomplete( false );
352 maValueEdArr
[i
]->SetModifyHdl( LINK( this, ScFilterDlg
, ValModifyHdl
) );
353 UpdateValueList(i
+1);
356 pScrollBar
->SetEndScrollHdl( LINK( this, ScFilterDlg
, ScrollHdl
) );
357 pScrollBar
->SetScrollHdl( LINK( this, ScFilterDlg
, ScrollHdl
) );
359 pScrollBar
->SetRange( Range( 0, 4 ) );
360 pScrollBar
->SetLineSize( 1 );
362 // Disable/Enable Logic:
364 (pLbField1
->GetSelectEntryPos() != 0)
365 && (pLbField2
->GetSelectEntryPos() != 0)
366 ? pLbConnect2
->SelectEntryPos( (sal_uInt16
)theQueryData
.GetEntry(1).eConnect
)
367 : pLbConnect2
->SetNoSelection();
369 (pLbField2
->GetSelectEntryPos() != 0)
370 && (pLbField3
->GetSelectEntryPos() != 0)
371 ? pLbConnect3
->SelectEntryPos( (sal_uInt16
)theQueryData
.GetEntry(2).eConnect
)
372 : pLbConnect3
->SetNoSelection();
374 (pLbField3
->GetSelectEntryPos() != 0)
375 && (pLbField4
->GetSelectEntryPos() != 0)
376 ? pLbConnect4
->SelectEntryPos( (sal_uInt16
)theQueryData
.GetEntry(3).eConnect
)
377 : pLbConnect4
->SetNoSelection();
378 if ( pLbField1
->GetSelectEntryPos() == 0 )
380 pLbConnect2
->Disable();
381 pLbField2
->Disable();
385 else if ( pLbConnect2
->GetSelectEntryCount() == 0 )
387 pLbField2
->Disable();
392 if ( pLbField2
->GetSelectEntryPos() == 0 )
394 pLbConnect3
->Disable();
395 pLbField3
->Disable();
399 else if ( pLbConnect3
->GetSelectEntryCount() == 0 )
401 pLbField3
->Disable();
405 if ( pLbField3
->GetSelectEntryPos() == 0 )
407 pLbConnect4
->Disable();
408 pLbField4
->Disable();
412 else if ( pLbConnect4
->GetSelectEntryCount() == 0 )
414 pLbField4
->Disable();
420 pDoc
->GetChangeTrack()!=NULL
) pBtnCopyResult
->Disable();
421 // Switch on modal mode
422 // SetDispatcherLock( true );
423 //@BugID 54702 Enable/disable only in Basic class
424 // SFX_APPWINDOW->Disable(false); //! general method in ScAnyRefDlg
427 bool ScFilterDlg::Close()
430 pViewData
->GetDocShell()->CancelAutoDBRange();
432 return DoClose( ScFilterDlgWrapper::GetChildWindowId() );
435 // Mouse-selected cell area becomes the new selection and is shown in the
436 // reference text box
438 void ScFilterDlg::SetReference( const ScRange
& rRef
, ScDocument
* pDocP
)
440 if ( bRefInputMode
) // Only possible if in reference edit mode
442 if ( rRef
.aStart
!= rRef
.aEnd
)
443 RefInputStart( pEdCopyArea
);
444 OUString
aRefStr(rRef
.aStart
.Format(SCA_ABS_3D
, pDocP
, pDocP
->GetAddressConvention()));
445 pEdCopyArea
->SetRefString( aRefStr
);
449 void ScFilterDlg::SetActive()
453 pEdCopyArea
->GrabFocus();
454 if ( pEdCopyArea
->GetModifyHdl().IsSet() )
455 ((Link
<>&)pEdCopyArea
->GetModifyHdl()).Call( pEdCopyArea
);
463 void ScFilterDlg::FillFieldLists()
469 pLbField1
->InsertEntry( aStrNone
, 0 );
470 pLbField2
->InsertEntry( aStrNone
, 0 );
471 pLbField3
->InsertEntry( aStrNone
, 0 );
472 pLbField4
->InsertEntry( aStrNone
, 0 );
477 SCTAB nTab
= nSrcTab
;
478 SCCOL nFirstCol
= theQueryData
.nCol1
;
479 SCROW nFirstRow
= theQueryData
.nRow1
;
480 SCCOL nMaxCol
= theQueryData
.nCol2
;
484 for ( col
=nFirstCol
; col
<=nMaxCol
; col
++ )
486 aFieldName
= pDoc
->GetString(col
, nFirstRow
, nTab
);
487 if (!pBtnHeader
->IsChecked() || aFieldName
.isEmpty())
489 aFieldName
= ScGlobal::ReplaceOrAppend( aStrColumn
, "%1", ScColToAlpha( col
));
491 pLbField1
->InsertEntry( aFieldName
, i
);
492 pLbField2
->InsertEntry( aFieldName
, i
);
493 pLbField3
->InsertEntry( aFieldName
, i
);
494 pLbField4
->InsertEntry( aFieldName
, i
);
500 void ScFilterDlg::UpdateValueList( size_t nList
)
502 bool bCaseSens
= pBtnCase
->IsChecked();
504 if (pDoc
&& nList
> 0 && nList
<= QUERY_ENTRY_COUNT
)
506 ComboBox
* pValList
= maValueEdArr
[nList
-1];
507 sal_uInt16 nFieldSelPos
= maFieldLbArr
[nList
-1]->GetSelectEntryPos();
508 sal_uInt16 nListPos
= 0;
509 OUString aCurValue
= pValList
->GetText();
512 pValList
->InsertEntry( aStrNotEmpty
, 0 );
513 pValList
->InsertEntry( aStrEmpty
, 1 );
518 WaitObject
aWaiter( this ); // even if only the list box has content
520 SCCOL nColumn
= theQueryData
.nCol1
+ static_cast<SCCOL
>(nFieldSelPos
) - 1;
521 EntryList
* pList
= NULL
;
522 if (!maEntryLists
.count(nColumn
))
524 size_t nOffset
= GetSliderPos();
525 SCTAB nTab
= nSrcTab
;
526 SCROW nFirstRow
= theQueryData
.nRow1
;
527 SCROW nLastRow
= theQueryData
.nRow2
;
528 if (maHasDates
.size() < nOffset
+nList
)
529 maHasDates
.resize(nOffset
+nList
, false);
530 maHasDates
[nOffset
+nList
-1] = false;
532 // first without the first line
533 std::pair
<EntryListsMap::iterator
, bool> r
=
534 maEntryLists
.insert(nColumn
, new EntryList
);
539 pList
= r
.first
->second
;
540 pDoc
->GetFilterEntriesArea(
541 nColumn
, nFirstRow
+1, nLastRow
,
542 nTab
, bCaseSens
, pList
->maList
, maHasDates
[nOffset
+nList
-1] );
544 // Entry for the first line
545 //! Entry (pHdrEntry) doesn't generate collection?
547 pList
->mnHeaderPos
= INVALID_HEADER_POS
;
548 std::vector
<ScTypedStrData
> aHdrColl
;
550 pDoc
->GetFilterEntriesArea(
551 nColumn
, nFirstRow
, nFirstRow
, nTab
, true, aHdrColl
, bDummy
);
552 if (!aHdrColl
.empty())
554 // See if the header value is already in the list.
555 std::vector
<ScTypedStrData
>::iterator itBeg
= pList
->maList
.begin(), itEnd
= pList
->maList
.end();
556 std::vector
<ScTypedStrData
>::iterator it
= std::find_if(
557 itBeg
, itEnd
, FindTypedStrData(aHdrColl
.front(), bCaseSens
));
560 // Not in the list. Insert it.
561 pList
->maList
.push_back(aHdrColl
.front());
563 std::sort(pList
->maList
.begin(), pList
->maList
.end(), ScTypedStrData::LessCaseSensitive());
565 std::sort(pList
->maList
.begin(), pList
->maList
.end(), ScTypedStrData::LessCaseInsensitive());
567 // Record its position.
568 itBeg
= pList
->maList
.begin();
569 itEnd
= pList
->maList
.end();
570 it
= std::find_if(itBeg
, itEnd
, FindTypedStrData(aHdrColl
.front(), bCaseSens
));
571 pList
->mnHeaderPos
= std::distance(itBeg
, it
);
576 pList
= &maEntryLists
[nColumn
];
580 std::vector
<ScTypedStrData
>::const_iterator it
= pList
->maList
.begin(), itEnd
= pList
->maList
.end();
581 for (; it
!= itEnd
; ++it
)
583 pValList
->InsertEntry(it
->GetString(), nListPos
);
587 pValList
->SetText( aCurValue
);
588 pValList
->EnableDDAutoWidth(false);
591 UpdateHdrInValueList( nList
);
594 void ScFilterDlg::UpdateHdrInValueList( size_t nList
)
596 //! GetText / SetText ??
601 if (nList
== 0 || nList
> QUERY_ENTRY_COUNT
)
604 size_t nFieldSelPos
= maFieldLbArr
[nList
-1]->GetSelectEntryPos();
608 SCCOL nColumn
= theQueryData
.nCol1
+ static_cast<SCCOL
>(nFieldSelPos
) - 1;
609 if (!maEntryLists
.count(nColumn
))
611 OSL_FAIL("Spalte noch nicht initialisiert");
615 size_t nPos
= maEntryLists
[nColumn
].mnHeaderPos
;
616 if (nPos
== INVALID_HEADER_POS
)
619 ComboBox
* pValList
= maValueEdArr
[nList
-1];
620 size_t nListPos
= nPos
+ 2; // for "empty" and "non-empty"
622 const ScTypedStrData
& rHdrEntry
= maEntryLists
[nColumn
].maList
[nPos
];
624 const OUString
& aHdrStr
= rHdrEntry
.GetString();
625 bool bWasThere
= aHdrStr
.equals(pValList
->GetEntry(nListPos
));
626 bool bInclude
= !pBtnHeader
->IsChecked();
628 if (bInclude
) // Include entry
631 pValList
->InsertEntry(aHdrStr
, nListPos
);
636 pValList
->RemoveEntryAt(nListPos
);
640 void ScFilterDlg::ClearValueList( size_t nList
)
642 if (nList
> 0 && nList
<= QUERY_ENTRY_COUNT
)
644 ComboBox
* pValList
= maValueEdArr
[nList
-1];
646 pValList
->InsertEntry( aStrNotEmpty
, 0 );
647 pValList
->InsertEntry( aStrEmpty
, 1 );
648 pValList
->SetText( EMPTY_OUSTRING
);
652 size_t ScFilterDlg::GetFieldSelPos( SCCOL nField
)
654 if ( nField
>= theQueryData
.nCol1
&& nField
<= theQueryData
.nCol2
)
655 return static_cast<size_t>(nField
- theQueryData
.nCol1
+ 1);
660 ScQueryItem
* ScFilterDlg::GetOutputItem()
662 ScAddress theCopyPos
;
663 ScQueryParam
theParam( theQueryData
);
664 bool bCopyPosOk
= false;
666 if ( pBtnCopyResult
->IsChecked() )
668 sal_uInt16 nResult
= theCopyPos
.Parse(
669 pEdCopyArea
->GetText(), pDoc
, pDoc
->GetAddressConvention());
670 bCopyPosOk
= ( SCA_VALID
== (nResult
& SCA_VALID
) );
673 if ( pBtnCopyResult
->IsChecked() && bCopyPosOk
)
675 theParam
.bInplace
= false;
676 theParam
.nDestTab
= theCopyPos
.Tab();
677 theParam
.nDestCol
= theCopyPos
.Col();
678 theParam
.nDestRow
= theCopyPos
.Row();
682 theParam
.bInplace
= true;
683 theParam
.nDestTab
= 0;
684 theParam
.nDestCol
= 0;
685 theParam
.nDestRow
= 0;
688 theParam
.bHasHeader
= pBtnHeader
->IsChecked();
689 theParam
.bByRow
= true;
690 theParam
.bDuplicate
= !pBtnUnique
->IsChecked();
691 theParam
.bCaseSens
= pBtnCase
->IsChecked();
692 theParam
.bRegExp
= pBtnRegExp
->IsChecked();
693 theParam
.bDestPers
= pBtnDestPers
->IsChecked();
695 // only set the three - reset everything else
698 pOutItem
= new ScQueryItem( nWhichQuery
, &theParam
);
703 bool ScFilterDlg::IsRefInputMode() const
705 return bRefInputMode
;
710 IMPL_LINK( ScFilterDlg
, EndDlgHdl
, Button
*, pBtn
)
712 if ( pBtn
== pBtnOk
)
714 bool bAreaInputOk
= true;
716 if ( pBtnCopyResult
->IsChecked() )
718 if ( !pOptionsMgr
->VerifyPosStr( pEdCopyArea
->GetText() ) )
720 if (!pExpander
->get_expanded())
721 pExpander
->set_expanded(true);
723 ERRORBOX( STR_INVALID_TABREF
);
724 pEdCopyArea
->GrabFocus();
725 bAreaInputOk
= false;
731 SetDispatcherLock( false );
733 GetBindings().GetDispatcher()->Execute( FID_FILTER_OK
,
734 SfxCallMode::SLOT
| SfxCallMode::RECORD
,
735 GetOutputItem(), 0L, 0L );
739 else if ( pBtn
== pBtnCancel
)
747 IMPL_LINK_NOARG(ScFilterDlg
, MoreExpandedHdl
)
749 if ( pExpander
->get_expanded() )
754 bRefInputMode
= false;
755 //@BugID 54702 Enable/disable only in Basic class
756 //SFX_APPWINDOW->Disable(FALSE); //! general method in ScAnyRefDlg
761 IMPL_LINK_TYPED( ScFilterDlg
, TimeOutHdl
, Timer
*, _pTimer
, void )
763 // Check if RefInputMode is still true every 50ms
765 if( _pTimer
== pTimer
&& IsActive() )
766 bRefInputMode
= (pEdCopyArea
->HasFocus() || pRbCopyArea
->HasFocus());
768 if ( pExpander
->get_expanded() )
772 IMPL_LINK( ScFilterDlg
, LbSelectHdl
, ListBox
*, pLb
)
775 * Handle enable/disable logic depending on which ListBox was selected
777 sal_uInt16 nOffset
= GetSliderPos();
779 if ( pLb
== pLbConnect1
)
785 sal_uInt16 nConnect1
= pLbConnect1
->GetSelectEntryPos();
786 size_t nQE
= nOffset
;
787 theQueryData
.GetEntry(nQE
).eConnect
=(ScQueryConnect
)nConnect1
;
788 if (maRefreshExceptQuery
.size() < nQE
+ 1)
789 maRefreshExceptQuery
.resize(nQE
+ 1, false);
790 maRefreshExceptQuery
[nQE
] = true;
793 else if ( pLb
== pLbConnect2
)
799 sal_uInt16 nConnect2
= pLbConnect2
->GetSelectEntryPos();
800 size_t nQE
= 1+nOffset
;
801 theQueryData
.GetEntry(nQE
).eConnect
=(ScQueryConnect
)nConnect2
;
802 if (maRefreshExceptQuery
.size() < nQE
+ 1)
803 maRefreshExceptQuery
.resize(nQE
+ 1, false);
804 maRefreshExceptQuery
[nQE
]=true;
806 else if ( pLb
== pLbConnect3
)
812 sal_uInt16 nConnect3
= pLbConnect3
->GetSelectEntryPos();
813 size_t nQE
= 2 + nOffset
;
814 theQueryData
.GetEntry(nQE
).eConnect
= (ScQueryConnect
)nConnect3
;
815 if (maRefreshExceptQuery
.size() < nQE
+ 1)
816 maRefreshExceptQuery
.resize(nQE
+ 1, false);
817 maRefreshExceptQuery
[nQE
] = true;
820 else if ( pLb
== pLbConnect4
)
826 sal_uInt16 nConnect4
= pLbConnect4
->GetSelectEntryPos();
827 size_t nQE
= 3 + nOffset
;
828 theQueryData
.GetEntry(nQE
).eConnect
= (ScQueryConnect
)nConnect4
;
829 if (maRefreshExceptQuery
.size() < nQE
+ 1)
830 maRefreshExceptQuery
.resize(nQE
+ 1, false);
831 maRefreshExceptQuery
[nQE
] = true;
833 else if ( pLb
== pLbField1
)
835 if ( pLbField1
->GetSelectEntryPos() == 0 )
837 pLbConnect2
->SetNoSelection();
838 pLbConnect3
->SetNoSelection();
839 pLbConnect4
->SetNoSelection();
840 pLbField2
->SelectEntryPos( 0 );
841 pLbField3
->SelectEntryPos( 0 );
842 pLbField4
->SelectEntryPos( 0 );
843 pLbCond2
->SelectEntryPos( 0 );
844 pLbCond3
->SelectEntryPos( 0 );
845 pLbCond4
->SelectEntryPos( 0 );
851 pLbConnect2
->Disable();
852 pLbConnect3
->Disable();
853 pLbConnect4
->Disable();
854 pLbField2
->Disable();
855 pLbField3
->Disable();
856 pLbField4
->Disable();
863 SCSIZE nCount
= theQueryData
.GetEntryCount();
864 if (maRefreshExceptQuery
.size() < nCount
+ 1)
865 maRefreshExceptQuery
.resize(nCount
+ 1, false);
866 for (sal_uInt16 i
= nOffset
; i
< nCount
; ++i
)
868 theQueryData
.GetEntry(i
).bDoQuery
= false;
869 maRefreshExceptQuery
[i
] = false;
870 theQueryData
.GetEntry(i
).nField
= static_cast<SCCOL
>(0);
872 maRefreshExceptQuery
[nOffset
] = true;
876 UpdateValueList( 1 );
877 if ( !pLbConnect2
->IsEnabled() )
879 pLbConnect2
->Enable();
881 theQueryData
.GetEntry(nOffset
).bDoQuery
= true;
882 sal_uInt16 nField
= pLb
->GetSelectEntryPos();
883 theQueryData
.GetEntry(nOffset
).nField
= theQueryData
.nCol1
+ static_cast<SCCOL
>(nField
) - 1 ;
886 else if ( pLb
== pLbField2
)
888 if ( pLbField2
->GetSelectEntryPos() == 0 )
890 pLbConnect3
->SetNoSelection();
891 pLbConnect4
->SetNoSelection();
892 pLbField3
->SelectEntryPos( 0 );
893 pLbField4
->SelectEntryPos( 0 );
894 pLbCond3
->SelectEntryPos( 0 );
895 pLbCond4
->SelectEntryPos( 0 );
900 pLbConnect3
->Disable();
901 pLbConnect4
->Disable();
902 pLbField3
->Disable();
903 pLbField4
->Disable();
909 sal_uInt16 nTemp
=nOffset
+1;
910 SCSIZE nCount
= theQueryData
.GetEntryCount();
911 if (maRefreshExceptQuery
.size() < nCount
)
912 maRefreshExceptQuery
.resize(nCount
, false);
913 for (sal_uInt16 i
= nTemp
; i
< nCount
; i
++)
915 theQueryData
.GetEntry(i
).bDoQuery
= false;
916 maRefreshExceptQuery
[i
] = false;
917 theQueryData
.GetEntry(i
).nField
= static_cast<SCCOL
>(0);
919 maRefreshExceptQuery
[nTemp
] = true;
923 UpdateValueList( 2 );
924 if ( !pLbConnect3
->IsEnabled() )
926 pLbConnect3
->Enable();
928 sal_uInt16 nField
= pLb
->GetSelectEntryPos();
929 sal_uInt16 nQ
=1+nOffset
;
930 theQueryData
.GetEntry(nQ
).bDoQuery
= true;
931 theQueryData
.GetEntry(nQ
).nField
= theQueryData
.nCol1
+ static_cast<SCCOL
>(nField
) - 1 ;
934 else if ( pLb
== pLbField3
)
936 if ( pLbField3
->GetSelectEntryPos() == 0 )
938 pLbConnect4
->SetNoSelection();
939 pLbField4
->SelectEntryPos( 0 );
940 pLbCond4
->SelectEntryPos( 0 );
944 pLbConnect4
->Disable();
945 pLbField4
->Disable();
949 sal_uInt16 nTemp
=nOffset
+2;
950 SCSIZE nCount
= theQueryData
.GetEntryCount();
951 if (maRefreshExceptQuery
.size() < nCount
)
952 maRefreshExceptQuery
.resize(nCount
, false);
953 for (sal_uInt16 i
= nTemp
; i
< nCount
; ++i
)
955 theQueryData
.GetEntry(i
).bDoQuery
= false;
956 maRefreshExceptQuery
[i
] = false;
957 theQueryData
.GetEntry(i
).nField
= static_cast<SCCOL
>(0);
959 maRefreshExceptQuery
[nTemp
] = true;
963 UpdateValueList( 3 );
964 if ( !pLbConnect4
->IsEnabled() )
966 pLbConnect4
->Enable();
969 sal_uInt16 nField
= pLb
->GetSelectEntryPos();
970 sal_uInt16 nQ
=2+nOffset
;
971 theQueryData
.GetEntry(nQ
).bDoQuery
= true;
972 theQueryData
.GetEntry(nQ
).nField
= theQueryData
.nCol1
+ static_cast<SCCOL
>(nField
) - 1 ;
976 else if ( pLb
== pLbField4
)
978 if ( pLbField4
->GetSelectEntryPos() == 0 )
981 sal_uInt16 nTemp
=nOffset
+3;
982 SCSIZE nCount
= theQueryData
.GetEntryCount();
983 if (maRefreshExceptQuery
.size() < nCount
)
984 maRefreshExceptQuery
.resize(nCount
, false);
985 for (sal_uInt16 i
= nTemp
; i
< nCount
; ++i
)
987 theQueryData
.GetEntry(i
).bDoQuery
= false;
988 maRefreshExceptQuery
[i
] = false;
989 theQueryData
.GetEntry(i
).nField
= static_cast<SCCOL
>(0);
991 maRefreshExceptQuery
[nTemp
] = true;
995 UpdateValueList( 4 );
996 sal_uInt16 nField
= pLb
->GetSelectEntryPos();
997 sal_uInt16 nQ
=3+nOffset
;
998 theQueryData
.GetEntry(nQ
).bDoQuery
= true;
999 theQueryData
.GetEntry(nQ
).nField
= theQueryData
.nCol1
+ static_cast<SCCOL
>(nField
) - 1 ;
1003 else if ( pLb
== pLbCond1
)
1005 theQueryData
.GetEntry(nOffset
).eOp
=(ScQueryOp
)pLb
->GetSelectEntryPos();
1007 else if ( pLb
== pLbCond2
)
1009 sal_uInt16 nQ
=1+nOffset
;
1010 theQueryData
.GetEntry(nQ
).eOp
=(ScQueryOp
)pLb
->GetSelectEntryPos();
1012 else if ( pLb
== pLbCond3
)
1014 sal_uInt16 nQ
=2+nOffset
;
1015 theQueryData
.GetEntry(nQ
).eOp
=(ScQueryOp
)pLb
->GetSelectEntryPos();
1019 sal_uInt16 nQ
=3+nOffset
;
1020 theQueryData
.GetEntry(nQ
).eOp
=(ScQueryOp
)pLb
->GetSelectEntryPos();
1026 IMPL_LINK( ScFilterDlg
, CheckBoxHdl
, CheckBox
*, pBox
)
1029 // Field list: Columnxx <-> column header string
1030 // Value list: Column header value not applicable.
1031 // Upper/lower case:
1032 // Value list: completely new
1034 if ( pBox
== pBtnHeader
) // Field list and value list
1036 sal_uInt16 nCurSel1
= pLbField1
->GetSelectEntryPos();
1037 sal_uInt16 nCurSel2
= pLbField2
->GetSelectEntryPos();
1038 sal_uInt16 nCurSel3
= pLbField3
->GetSelectEntryPos();
1039 sal_uInt16 nCurSel4
= pLbField4
->GetSelectEntryPos();
1041 pLbField1
->SelectEntryPos( nCurSel1
);
1042 pLbField2
->SelectEntryPos( nCurSel2
);
1043 pLbField3
->SelectEntryPos( nCurSel3
);
1044 pLbField4
->SelectEntryPos( nCurSel4
);
1046 UpdateHdrInValueList( 1 );
1047 UpdateHdrInValueList( 2 );
1048 UpdateHdrInValueList( 3 );
1049 UpdateHdrInValueList( 4 );
1052 if ( pBox
== pBtnCase
) // Complete value list
1054 maEntryLists
.clear();
1055 UpdateValueList( 1 ); // current text is recorded
1056 UpdateValueList( 2 );
1057 UpdateValueList( 3 );
1058 UpdateValueList( 4 );
1064 IMPL_LINK( ScFilterDlg
, ValModifyHdl
, ComboBox
*, pEd
)
1066 size_t nOffset
= GetSliderPos();
1068 size_t nQE
= i
+ nOffset
;
1071 OUString aStrVal
= pEd
->GetText();
1072 ListBox
* pLbCond
= pLbCond1
;
1073 ListBox
* pLbField
= pLbField1
;
1074 if ( pEd
== pEdVal2
)
1077 pLbField
= pLbField2
;
1081 if ( pEd
== pEdVal3
)
1084 pLbField
= pLbField3
;
1088 if ( pEd
== pEdVal4
)
1091 pLbField
= pLbField4
;
1096 if ( aStrEmpty
.equals(aStrVal
) || aStrNotEmpty
.equals(aStrVal
) )
1098 pLbCond
->SelectEntry(OUString('='));
1104 if (maHasDates
.size() < nQE
+ 1)
1105 maHasDates
.resize(nQE
+ 1, false);
1106 if (maRefreshExceptQuery
.size() < nQE
+ 1)
1107 maRefreshExceptQuery
.resize(nQE
+ 1, false);
1109 ScQueryEntry
& rEntry
= theQueryData
.GetEntry( nQE
);
1110 ScQueryEntry::Item
& rItem
= rEntry
.GetQueryItem();
1111 bool bDoThis
= (pLbField
->GetSelectEntryPos() != 0);
1112 rEntry
.bDoQuery
= bDoThis
;
1114 if ( rEntry
.bDoQuery
|| maRefreshExceptQuery
[nQE
] )
1116 bool bByEmptyOrNotByEmpty
= false;
1117 if ( aStrEmpty
.equals(aStrVal
) )
1119 bByEmptyOrNotByEmpty
= true;
1120 rEntry
.SetQueryByEmpty();
1122 else if ( aStrNotEmpty
.equals(aStrVal
) )
1124 bByEmptyOrNotByEmpty
= true;
1125 rEntry
.SetQueryByNonEmpty();
1129 rItem
.maString
= pDoc
->GetSharedStringPool().intern(aStrVal
);
1132 sal_uInt32 nIndex
= 0;
1133 bool bNumber
= pDoc
->GetFormatTable()->IsNumberFormat(
1134 rItem
.maString
.getString(), nIndex
, rItem
.mfVal
);
1135 rItem
.meType
= bNumber
? ScQueryEntry::ByValue
: ScQueryEntry::ByString
;
1138 sal_uInt16 nField
= pLbField
->GetSelectEntryPos();
1139 rEntry
.nField
= nField
? (theQueryData
.nCol1
+
1140 static_cast<SCCOL
>(nField
) - 1) : static_cast<SCCOL
>(0);
1142 ScQueryOp eOp
= (ScQueryOp
)pLbCond
->GetSelectEntryPos();
1144 if (maHasDates
[nQE
] && !bByEmptyOrNotByEmpty
)
1145 rItem
.meType
= ScQueryEntry::ByDate
;
1151 IMPL_LINK_NOARG(ScFilterDlg
, ScrollHdl
)
1157 void ScFilterDlg::SliderMoved()
1159 size_t nOffset
= GetSliderPos();
1160 RefreshEditRow( nOffset
);
1163 size_t ScFilterDlg::GetSliderPos()
1165 return static_cast<size_t>(pScrollBar
->GetThumbPos());
1168 void ScFilterDlg::RefreshEditRow( size_t nOffset
)
1171 maConnLbArr
[0]->Hide();
1173 maConnLbArr
[0]->Show();
1175 for (size_t i
= 0; i
< QUERY_ENTRY_COUNT
; ++i
)
1178 size_t nCondPos
= 0;
1179 size_t nFieldSelPos
= 0;
1180 size_t nQE
= i
+ nOffset
;
1182 if (maRefreshExceptQuery
.size() < nQE
+ 1)
1183 maRefreshExceptQuery
.resize(nQE
+ 1, false);
1185 ScQueryEntry
& rEntry
= theQueryData
.GetEntry( nQE
);
1186 if ( rEntry
.bDoQuery
|| maRefreshExceptQuery
[nQE
] )
1188 nCondPos
= static_cast<size_t>(rEntry
.eOp
);
1190 nFieldSelPos
= GetFieldSelPos( static_cast<SCCOL
>(rEntry
.nField
) );
1192 const ScQueryEntry::Item
& rItem
= rEntry
.GetQueryItem();
1193 OUString aQueryStr
= rItem
.maString
.getString();
1194 if (rEntry
.IsQueryByEmpty())
1196 aValStr
= aStrEmpty
;
1197 maCondLbArr
[i
]->Disable();
1199 else if (rEntry
.IsQueryByNonEmpty())
1201 aValStr
= aStrNotEmpty
;
1202 maCondLbArr
[i
]->Disable();
1206 aValStr
= aQueryStr
;
1207 maCondLbArr
[i
]->Enable();
1209 maFieldLbArr
[i
]->Enable();
1210 maValueEdArr
[i
]->Enable();
1217 maConnLbArr
[i
+1]->Enable();
1219 maConnLbArr
[i
+1]->Disable();
1220 size_t nQENext
= nQE
+ 1;
1221 if (maRefreshExceptQuery
.size() < nQENext
+ 1)
1222 maRefreshExceptQuery
.resize(nQENext
+ 1, false);
1223 if (theQueryData
.GetEntry(nQENext
).bDoQuery
|| maRefreshExceptQuery
[nQENext
])
1224 maConnLbArr
[i
+1]->SelectEntryPos( (sal_uInt16
) theQueryData
.GetEntry(nQENext
).eConnect
);
1226 maConnLbArr
[i
+1]->SetNoSelection();
1231 if(theQueryData
.GetEntry( nQE
-1).bDoQuery
)
1232 maConnLbArr
[i
]->Enable();
1234 maConnLbArr
[i
]->Disable();
1236 if (maRefreshExceptQuery
.size() < nQE
+ 1)
1237 maRefreshExceptQuery
.resize(nQE
+ 1, false);
1238 if(rEntry
.bDoQuery
|| maRefreshExceptQuery
[nQE
])
1239 maConnLbArr
[i
]->SelectEntryPos( (sal_uInt16
) rEntry
.eConnect
);
1241 maConnLbArr
[i
]->SetNoSelection();
1251 maConnLbArr
[i
+1]->SetNoSelection();
1252 maConnLbArr
[i
+1]->Disable();
1257 if(theQueryData
.GetEntry( nQE
-1).bDoQuery
)
1258 maConnLbArr
[i
]->Enable();
1260 maConnLbArr
[i
]->Disable();
1261 maConnLbArr
[i
]->SetNoSelection();
1263 maFieldLbArr
[i
]->Disable();
1264 maCondLbArr
[i
]->Disable();
1265 maValueEdArr
[i
]->Disable();
1267 maFieldLbArr
[i
]->SelectEntryPos( nFieldSelPos
);
1268 maCondLbArr
[i
]->SelectEntryPos( nCondPos
);
1269 maValueEdArr
[i
]->SetText( aValStr
);
1270 UpdateValueList(i
+1);
1274 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */