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 #undef SC_DLLIMPLEMENTATION
22 #include <viewdata.hxx>
23 #include <document.hxx>
24 #include <uiitems.hxx>
26 #include <globalnames.hxx>
28 #include <scresid.hxx>
29 #include <queryentry.hxx>
30 #include <filterentries.hxx>
33 #include <strings.hrc>
35 #include <pfiltdlg.hxx>
36 #include <svl/sharedstringpool.hxx>
37 #include <osl/diagnose.h>
39 ScPivotFilterDlg::ScPivotFilterDlg(weld::Window
* pParent
, const SfxItemSet
& rArgSet
,
41 : GenericDialogController(pParent
, u
"modules/scalc/ui/pivotfilterdialog.ui"_ustr
, u
"PivotFilterDialog"_ustr
)
42 , aStrNone(ScResId(SCSTR_NONE
))
43 , aStrEmpty(ScResId(SCSTR_FILTER_EMPTY
))
44 , aStrNotEmpty(ScResId(SCSTR_FILTER_NOTEMPTY
))
45 , aStrColumn(ScResId(SCSTR_COLUMN_LETTER
))
46 , nWhichQuery(rArgSet
.GetPool()->GetWhichIDFromSlotID(SID_QUERY
))
47 , theQueryData(static_cast<const ScQueryItem
&>(rArgSet
.Get(nWhichQuery
)).GetQueryData())
50 , nSrcTab(nSourceTab
) // is not in QueryParam
51 , m_xLbField1(m_xBuilder
->weld_combo_box(u
"field1"_ustr
))
52 , m_xLbCond1(m_xBuilder
->weld_combo_box(u
"cond1"_ustr
))
53 , m_xEdVal1(m_xBuilder
->weld_combo_box(u
"val1"_ustr
))
54 , m_xLbConnect1(m_xBuilder
->weld_combo_box(u
"connect1"_ustr
))
55 , m_xLbField2(m_xBuilder
->weld_combo_box(u
"field2"_ustr
))
56 , m_xLbCond2(m_xBuilder
->weld_combo_box(u
"cond2"_ustr
))
57 , m_xEdVal2(m_xBuilder
->weld_combo_box(u
"val2"_ustr
))
58 , m_xLbConnect2(m_xBuilder
->weld_combo_box(u
"connect2"_ustr
))
59 , m_xLbField3(m_xBuilder
->weld_combo_box(u
"field3"_ustr
))
60 , m_xLbCond3(m_xBuilder
->weld_combo_box(u
"cond3"_ustr
))
61 , m_xEdVal3(m_xBuilder
->weld_combo_box(u
"val3"_ustr
))
62 , m_xBtnCase(m_xBuilder
->weld_check_button(u
"case"_ustr
))
63 , m_xBtnRegExp(m_xBuilder
->weld_check_button(u
"regexp"_ustr
))
64 , m_xBtnUnique(m_xBuilder
->weld_check_button(u
"unique"_ustr
))
65 , m_xFtDbArea(m_xBuilder
->weld_label(u
"dbarea"_ustr
))
70 ScPivotFilterDlg::~ScPivotFilterDlg()
74 void ScPivotFilterDlg::Init( const SfxItemSet
& rArgSet
)
76 const ScQueryItem
& rQueryItem
= static_cast<const ScQueryItem
&>(
77 rArgSet
.Get( nWhichQuery
));
79 m_xBtnCase
->connect_toggled( LINK( this, ScPivotFilterDlg
, CheckBoxHdl
) );
81 m_xLbField1
->connect_changed ( LINK( this, ScPivotFilterDlg
, LbSelectHdl
) );
82 m_xLbField2
->connect_changed ( LINK( this, ScPivotFilterDlg
, LbSelectHdl
) );
83 m_xLbField3
->connect_changed ( LINK( this, ScPivotFilterDlg
, LbSelectHdl
) );
84 m_xLbConnect1
->connect_changed( LINK( this, ScPivotFilterDlg
, LbSelectHdl
) );
85 m_xLbConnect2
->connect_changed( LINK( this, ScPivotFilterDlg
, LbSelectHdl
) );
87 m_xBtnCase
->set_active( theQueryData
.bCaseSens
);
88 m_xBtnRegExp
->set_active( theQueryData
.eSearchType
== utl::SearchParam::SearchType::Regexp
);
89 m_xBtnUnique
->set_active( !theQueryData
.bDuplicate
);
91 pViewData
= rQueryItem
.GetViewData();
92 pDoc
= pViewData
? &pViewData
->GetDocument() : nullptr;
95 aFieldLbArr
[0] = m_xLbField1
.get();
96 aFieldLbArr
[1] = m_xLbField2
.get();
97 aFieldLbArr
[2] = m_xLbField3
.get();
98 aValueEdArr
[0] = m_xEdVal1
.get();
99 aValueEdArr
[1] = m_xEdVal2
.get();
100 aValueEdArr
[2] = m_xEdVal3
.get();
101 aCondLbArr
[0] = m_xLbCond1
.get();
102 aCondLbArr
[1] = m_xLbCond2
.get();
103 aCondLbArr
[2] = m_xLbCond3
.get();
105 if ( pViewData
&& pDoc
)
107 ScRange
theCurArea ( ScAddress( theQueryData
.nCol1
,
110 ScAddress( theQueryData
.nCol2
,
113 ScDBCollection
* pDBColl
= pDoc
->GetDBCollection();
114 OUString theDbName
= STR_DB_LOCAL_NONAME
;
116 // Check if the passed range is a database range
120 ScAddress
& rStart
= theCurArea
.aStart
;
121 ScAddress
& rEnd
= theCurArea
.aEnd
;
122 ScDBData
* pDBData
= pDBColl
->GetDBAtArea( rStart
.Tab(),
123 rStart
.Col(), rStart
.Row(),
124 rEnd
.Col(), rEnd
.Row() );
126 theDbName
= pDBData
->GetName();
129 OUString sLabel
= " (" + theDbName
+ ")";
130 m_xFtDbArea
->set_label(sLabel
);
134 m_xFtDbArea
->set_label(OUString());
137 // Read the field lists and select the entries:
141 for ( SCSIZE i
=0; i
<3; i
++ )
143 if ( theQueryData
.GetEntry(i
).bDoQuery
)
145 const ScQueryEntry
& rEntry
= theQueryData
.GetEntry(i
);
146 const ScQueryEntry::Item
& rItem
= rEntry
.GetQueryItem();
147 OUString aValStr
= rItem
.maString
.getString();
148 if (rEntry
.IsQueryByEmpty())
150 else if (rEntry
.IsQueryByNonEmpty())
151 aValStr
= aStrNotEmpty
;
152 sal_uInt16 nCondPos
= static_cast<sal_uInt16
>(rEntry
.eOp
);
153 sal_uInt16 nFieldSelPos
= GetFieldSelPos( static_cast<SCCOL
>(rEntry
.nField
) );
155 aFieldLbArr
[i
]->set_active( nFieldSelPos
);
156 aCondLbArr
[i
]->set_active( nCondPos
);
157 UpdateValueList( static_cast<sal_uInt16
>(i
+1) );
158 aValueEdArr
[i
]->set_entry_text(aValStr
);
159 if (aValStr
== aStrEmpty
|| aValStr
== aStrNotEmpty
)
160 aCondLbArr
[i
]->set_sensitive(false);
164 aFieldLbArr
[i
]->set_active( 0 ); // "none" selected
165 aCondLbArr
[i
]->set_active( 0 ); // "=" selected
166 UpdateValueList( static_cast<sal_uInt16
>(i
) );
167 aValueEdArr
[i
]->set_entry_text(OUString());
169 aValueEdArr
[i
]->connect_changed( LINK( this, ScPivotFilterDlg
, ValModifyHdl
) );
172 // disable/enable logic:
174 if (m_xLbField1
->get_active() != 0 && m_xLbField2
->get_active() != 0)
175 m_xLbConnect1
->set_active( static_cast<sal_uInt16
>(theQueryData
.GetEntry(1).eConnect
) );
177 m_xLbConnect1
->set_active(-1);
179 if (m_xLbField2
->get_active() != 0 && m_xLbField3
->get_active() != 0)
180 m_xLbConnect2
->set_active( static_cast<sal_uInt16
>(theQueryData
.GetEntry(2).eConnect
) );
182 m_xLbConnect2
->set_active(-1);
184 if (m_xLbField1
->get_active() == 0)
186 m_xLbConnect1
->set_sensitive(false);
187 m_xLbField2
->set_sensitive(false);
188 m_xLbCond2
->set_sensitive(false);
189 m_xEdVal2
->set_sensitive(false);
191 else if (m_xLbConnect1
->get_active() == -1)
193 m_xLbField2
->set_sensitive(false);
194 m_xLbCond2
->set_sensitive(false);
195 m_xEdVal2
->set_sensitive(false);
198 if (m_xLbField2
->get_active() == 0)
200 m_xLbConnect2
->set_sensitive(false);
201 m_xLbField3
->set_sensitive(false);
202 m_xLbCond3
->set_sensitive(false);
203 m_xEdVal3
->set_sensitive(false);
205 else if (m_xLbConnect2
->get_active() == -1)
207 m_xLbField3
->set_sensitive(false);
208 m_xLbCond3
->set_sensitive(false);
209 m_xEdVal3
->set_sensitive(false);
213 void ScPivotFilterDlg::FillFieldLists()
215 m_xLbField1
->clear();
216 m_xLbField2
->clear();
217 m_xLbField3
->clear();
218 m_xLbField1
->append_text(aStrNone
);
219 m_xLbField2
->append_text(aStrNone
);
220 m_xLbField3
->append_text(aStrNone
);
226 SCTAB nTab
= nSrcTab
;
227 SCCOL nFirstCol
= theQueryData
.nCol1
;
228 SCROW nFirstRow
= theQueryData
.nRow1
;
229 SCCOL nMaxCol
= theQueryData
.nCol2
;
232 for ( col
=nFirstCol
; col
<=nMaxCol
; col
++ )
234 aFieldName
= pDoc
->GetString(col
, nFirstRow
, nTab
);
235 if ( aFieldName
.isEmpty() )
237 aFieldName
= ScGlobal::ReplaceOrAppend( aStrColumn
, u
"%1", ScColToAlpha( col
));
239 m_xLbField1
->append_text(aFieldName
);
240 m_xLbField2
->append_text(aFieldName
);
241 m_xLbField3
->append_text(aFieldName
);
245 void ScPivotFilterDlg::UpdateValueList( sal_uInt16 nList
)
247 if ( !(pDoc
&& nList
>0 && nList
<=3) )
250 weld::ComboBox
* pValList
= aValueEdArr
[nList
-1];
251 sal_Int32 nFieldSelPos
= aFieldLbArr
[nList
-1]->get_active();
252 OUString aCurValue
= pValList
->get_active_text();
255 pValList
->append_text(aStrNotEmpty
);
256 pValList
->append_text(aStrEmpty
);
258 if ( pDoc
&& nFieldSelPos
)
260 SCCOL nColumn
= theQueryData
.nCol1
+ static_cast<SCCOL
>(nFieldSelPos
) - 1;
261 if (!m_pEntryLists
[nColumn
])
263 weld::WaitObject
aWaiter(m_xDialog
.get());
265 SCTAB nTab
= nSrcTab
;
266 SCROW nFirstRow
= theQueryData
.nRow1
;
267 SCROW nLastRow
= theQueryData
.nRow2
;
269 bool bCaseSens
= m_xBtnCase
->get_active();
270 m_pEntryLists
[nColumn
].reset( new ScFilterEntries
);
271 pDoc
->GetFilterEntriesArea(
272 nColumn
, nFirstRow
, nLastRow
, nTab
, bCaseSens
, *m_pEntryLists
[nColumn
]);
275 const ScFilterEntries
* pColl
= m_pEntryLists
[nColumn
].get();
276 for (const auto& rEntry
: *pColl
)
278 pValList
->append_text(rEntry
.GetString());
281 pValList
->set_entry_text(aCurValue
);
284 void ScPivotFilterDlg::ClearValueList( sal_uInt16 nList
)
286 if ( nList
>0 && nList
<=3 )
288 weld::ComboBox
* pValList
= aValueEdArr
[nList
-1];
290 pValList
->append_text(aStrNotEmpty
);
291 pValList
->append_text(aStrEmpty
);
292 pValList
->set_entry_text(OUString());
296 sal_uInt16
ScPivotFilterDlg::GetFieldSelPos( SCCOL nField
)
298 if ( nField
>= theQueryData
.nCol1
&& nField
<= theQueryData
.nCol2
)
299 return static_cast<sal_uInt16
>(nField
- theQueryData
.nCol1
+ 1);
304 const ScQueryItem
& ScPivotFilterDlg::GetOutputItem()
306 ScQueryParam
theParam( theQueryData
);
307 sal_Int32 nConnect1
= m_xLbConnect1
->get_active();
308 sal_Int32 nConnect2
= m_xLbConnect2
->get_active();
310 svl::SharedStringPool
& rPool
= pViewData
->GetDocument().GetSharedStringPool();
312 for ( SCSIZE i
=0; i
<3; i
++ )
314 const sal_Int32 nField
= aFieldLbArr
[i
]->get_active();
315 ScQueryOp eOp
= static_cast<ScQueryOp
>(aCondLbArr
[i
]->get_active());
317 bool bDoThis
= (aFieldLbArr
[i
]->get_active() != 0);
318 theParam
.GetEntry(i
).bDoQuery
= bDoThis
;
322 ScQueryEntry
& rEntry
= theParam
.GetEntry(i
);
323 ScQueryEntry::Item
& rItem
= rEntry
.GetQueryItem();
325 OUString aStrVal
= aValueEdArr
[i
]->get_active_text();
328 * The dialog returns the specific field values "empty"/"non empty"
329 * as constant in nVal in connection with the bQueryByString switch
332 if ( aStrVal
== aStrEmpty
)
334 OSL_ASSERT(eOp
== SC_EQUAL
);
335 rEntry
.SetQueryByEmpty();
337 else if ( aStrVal
== aStrNotEmpty
)
339 OSL_ASSERT(eOp
== SC_EQUAL
);
340 rEntry
.SetQueryByNonEmpty();
344 rItem
.maString
= rPool
.intern(aStrVal
);
346 rItem
.meType
= ScQueryEntry::ByString
;
349 rEntry
.nField
= nField
? (theQueryData
.nCol1
+
350 static_cast<SCCOL
>(nField
) - 1) : static_cast<SCCOL
>(0);
355 theParam
.GetEntry(1).eConnect
= (nConnect1
!= -1)
356 ? static_cast<ScQueryConnect
>(nConnect1
)
358 theParam
.GetEntry(2).eConnect
= (nConnect2
!= -1)
359 ? static_cast<ScQueryConnect
>(nConnect2
)
362 theParam
.bInplace
= false;
363 theParam
.nDestTab
= 0; // Where do those values come from?
364 theParam
.nDestCol
= 0;
365 theParam
.nDestRow
= 0;
367 theParam
.bDuplicate
= !m_xBtnUnique
->get_active();
368 theParam
.bCaseSens
= m_xBtnCase
->get_active();
369 theParam
.eSearchType
= m_xBtnRegExp
->get_active() ? utl::SearchParam::SearchType::Regexp
: utl::SearchParam::SearchType::Normal
;
371 pOutItem
.reset( new ScQueryItem( nWhichQuery
, &theParam
) );
378 IMPL_LINK( ScPivotFilterDlg
, LbSelectHdl
, weld::ComboBox
&, rLb
, void )
381 * Handling the enable/disable logic based on which ListBox was touched:
383 if (&rLb
== m_xLbConnect1
.get())
385 if ( !m_xLbField2
->get_sensitive() )
387 m_xLbField2
->set_sensitive(true);
388 m_xLbCond2
->set_sensitive(true);
389 m_xEdVal2
->set_sensitive(true);
392 else if (&rLb
== m_xLbConnect2
.get())
394 if ( !m_xLbField3
->get_sensitive() )
396 m_xLbField3
->set_sensitive(true);
397 m_xLbCond3
->set_sensitive(true);
398 m_xEdVal3
->set_sensitive(true);
401 else if (&rLb
== m_xLbField1
.get())
403 if ( m_xLbField1
->get_active() == 0 )
405 m_xLbConnect1
->set_active(-1);
406 m_xLbConnect2
->set_active(-1);
407 m_xLbField2
->set_active( 0 );
408 m_xLbField3
->set_active( 0 );
409 m_xLbCond2
->set_active( 0 );
410 m_xLbCond3
->set_active( 0 );
415 m_xLbConnect1
->set_sensitive(false);
416 m_xLbConnect2
->set_sensitive(false);
417 m_xLbField2
->set_sensitive(false);
418 m_xLbField3
->set_sensitive(false);
419 m_xLbCond2
->set_sensitive(false);
420 m_xLbCond3
->set_sensitive(false);
421 m_xEdVal2
->set_sensitive(false);
422 m_xEdVal3
->set_sensitive(false);
426 UpdateValueList( 1 );
427 if ( !m_xLbConnect1
->get_sensitive() )
429 m_xLbConnect1
->set_sensitive(true);
433 else if (&rLb
== m_xLbField2
.get())
435 if ( m_xLbField2
->get_active() == 0 )
437 m_xLbConnect2
->set_active(-1);
438 m_xLbField3
->set_active( 0 );
439 m_xLbCond3
->set_active( 0 );
443 m_xLbConnect2
->set_sensitive(false);
444 m_xLbField3
->set_sensitive(false);
445 m_xLbCond3
->set_sensitive(false);
446 m_xEdVal3
->set_sensitive(false);
450 UpdateValueList( 2 );
451 if (!m_xLbConnect2
->get_sensitive())
453 m_xLbConnect2
->set_sensitive(true);
457 else if (&rLb
== m_xLbField3
.get())
459 if (m_xLbField3
->get_active() == 0)
466 IMPL_LINK(ScPivotFilterDlg
, CheckBoxHdl
, weld::Toggleable
&, rBox
, void)
468 // update the value lists when dealing with uppercase/lowercase
470 if (&rBox
!= m_xBtnCase
.get()) // value lists
473 for (auto& a
: m_pEntryLists
)
476 OUString aCurVal1
= m_xEdVal1
->get_active_text();
477 OUString aCurVal2
= m_xEdVal2
->get_active_text();
478 OUString aCurVal3
= m_xEdVal3
->get_active_text();
479 UpdateValueList( 1 );
480 UpdateValueList( 2 );
481 UpdateValueList( 3 );
482 m_xEdVal1
->set_entry_text(aCurVal1
);
483 m_xEdVal2
->set_entry_text(aCurVal2
);
484 m_xEdVal3
->set_entry_text(aCurVal3
);
487 IMPL_LINK( ScPivotFilterDlg
, ValModifyHdl
, weld::ComboBox
&, rEd
, void )
489 OUString aStrVal
= rEd
.get_active_text();
490 weld::ComboBox
* pLb
= m_xLbCond1
.get();
492 if ( &rEd
== m_xEdVal2
.get() ) pLb
= m_xLbCond2
.get();
493 else if ( &rEd
== m_xEdVal3
.get() ) pLb
= m_xLbCond3
.get();
495 // if cond of the special values "empty"/"non-empty" was chosen only the
496 // =-operand makes sense:
498 if ( aStrEmpty
== aStrVal
|| aStrNotEmpty
== aStrVal
)
500 pLb
->set_active_text(OUString('='));
501 pLb
->set_sensitive(false);
504 pLb
->set_sensitive(true);
507 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */