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 <sal/log.hxx>
23 #include <uiitems.hxx>
24 #include <reffact.hxx>
25 #include <viewdata.hxx>
26 #include <document.hxx>
28 #include <scresid.hxx>
29 #include <queryentry.hxx>
31 #include <foptmgr.hxx>
33 #include <globstr.hrc>
34 #include <strings.hrc>
36 #include <filtdlg.hxx>
37 #include <svx/colorwindow.hxx>
38 #include <vcl/svapp.hxx>
39 #include <vcl/settings.hxx>
40 #include <vcl/virdev.hxx>
41 #include <vcl/weld.hxx>
42 #include <svl/numformat.hxx>
43 #include <svl/sharedstringpool.hxx>
47 #define QUERY_ENTRY_COUNT 4
48 #define INVALID_HEADER_POS std::numeric_limits<size_t>::max()
50 ScFilterDlg::EntryList::EntryList() :
51 mnHeaderPos(INVALID_HEADER_POS
) {}
53 ScFilterDlg::ScFilterDlg(SfxBindings
* pB
, SfxChildWindow
* pCW
, weld::Window
* pParent
,
54 const SfxItemSet
& rArgSet
)
55 : ScAnyRefDlgController(pB
, pCW
, pParent
,
56 u
"modules/scalc/ui/standardfilterdialog.ui"_ustr
, u
"StandardFilterDialog"_ustr
)
57 , aStrUndefined(ScResId(SCSTR_UNDEFINED
))
58 , aStrNone(ScResId(SCSTR_NONE
))
59 , aStrEmpty(ScResId(SCSTR_FILTER_EMPTY
))
60 , aStrNotEmpty(ScResId(SCSTR_FILTER_NOTEMPTY
))
61 , aStrColumn(ScResId(SCSTR_COLUMN_LETTER
))
62 , aStrFontColor(ScResId(SCSTR_FILTER_FONT_COLOR_COND
))
63 , aStrBackgroundColor(ScResId(SCSTR_FILTER_BACKGROUND_COLOR_COND
))
64 , nWhichQuery(rArgSet
.GetPool()->GetWhichIDFromSlotID(SID_QUERY
))
65 , theQueryData(static_cast<const ScQueryItem
&>(rArgSet
.Get(nWhichQuery
)).GetQueryData())
69 , bRefInputMode(false)
70 , m_xLbConnect1(m_xBuilder
->weld_combo_box(u
"connect1"_ustr
))
71 , m_xLbField1(m_xBuilder
->weld_combo_box(u
"field1"_ustr
))
72 , m_xLbCond1(m_xBuilder
->weld_combo_box(u
"cond1"_ustr
))
73 , m_xEdVal1(m_xBuilder
->weld_combo_box(u
"val1"_ustr
))
74 , m_xLbColor1(m_xBuilder
->weld_combo_box(u
"color1"_ustr
))
75 , m_xBtnRemove1(m_xBuilder
->weld_button(u
"remove1"_ustr
))
76 , m_xLbConnect2(m_xBuilder
->weld_combo_box(u
"connect2"_ustr
))
77 , m_xLbField2(m_xBuilder
->weld_combo_box(u
"field2"_ustr
))
78 , m_xLbCond2(m_xBuilder
->weld_combo_box(u
"cond2"_ustr
))
79 , m_xEdVal2(m_xBuilder
->weld_combo_box(u
"val2"_ustr
))
80 , m_xLbColor2(m_xBuilder
->weld_combo_box(u
"color2"_ustr
))
81 , m_xBtnRemove2(m_xBuilder
->weld_button(u
"remove2"_ustr
))
82 , m_xLbConnect3(m_xBuilder
->weld_combo_box(u
"connect3"_ustr
))
83 , m_xLbField3(m_xBuilder
->weld_combo_box(u
"field3"_ustr
))
84 , m_xLbCond3(m_xBuilder
->weld_combo_box(u
"cond3"_ustr
))
85 , m_xEdVal3(m_xBuilder
->weld_combo_box(u
"val3"_ustr
))
86 , m_xLbColor3(m_xBuilder
->weld_combo_box(u
"color3"_ustr
))
87 , m_xBtnRemove3(m_xBuilder
->weld_button(u
"remove3"_ustr
))
88 , m_xLbConnect4(m_xBuilder
->weld_combo_box(u
"connect4"_ustr
))
89 , m_xLbField4(m_xBuilder
->weld_combo_box(u
"field4"_ustr
))
90 , m_xLbCond4(m_xBuilder
->weld_combo_box(u
"cond4"_ustr
))
91 , m_xEdVal4(m_xBuilder
->weld_combo_box(u
"val4"_ustr
))
92 , m_xLbColor4(m_xBuilder
->weld_combo_box(u
"color4"_ustr
))
93 , m_xBtnRemove4(m_xBuilder
->weld_button(u
"remove4"_ustr
))
94 , m_xContents(m_xBuilder
->weld_widget(u
"grid"_ustr
))
95 , m_xScrollBar(m_xBuilder
->weld_scrolled_window(u
"scrollbar"_ustr
, true))
96 , m_xExpander(m_xBuilder
->weld_expander(u
"more"_ustr
))
97 , m_xBtnClear(m_xBuilder
->weld_button(u
"clear"_ustr
))
98 , m_xBtnOk(m_xBuilder
->weld_button(u
"ok"_ustr
))
99 , m_xBtnCancel(m_xBuilder
->weld_button(u
"cancel"_ustr
))
100 , m_xBtnCase(m_xBuilder
->weld_check_button(u
"case"_ustr
))
101 , m_xBtnRegExp(m_xBuilder
->weld_check_button(u
"regexp"_ustr
))
102 , m_xBtnHeader(m_xBuilder
->weld_check_button(u
"header"_ustr
))
103 , m_xBtnUnique(m_xBuilder
->weld_check_button(u
"unique"_ustr
))
104 , m_xBtnCopyResult(m_xBuilder
->weld_check_button(u
"copyresult"_ustr
))
105 , m_xLbCopyArea(m_xBuilder
->weld_combo_box(u
"lbcopyarea"_ustr
))
106 , m_xEdCopyArea(new formula::RefEdit(m_xBuilder
->weld_entry(u
"edcopyarea"_ustr
)))
107 , m_xRbCopyArea(new formula::RefButton(m_xBuilder
->weld_button(u
"rbcopyarea"_ustr
)))
108 , m_xBtnDestPers(m_xBuilder
->weld_check_button(u
"destpers"_ustr
))
109 , m_xFtDbAreaLabel(m_xBuilder
->weld_label(u
"dbarealabel"_ustr
))
110 , m_xFtDbArea(m_xBuilder
->weld_label(u
"dbarea"_ustr
))
112 m_xExpander
->connect_expanded(LINK(this, ScFilterDlg
, MoreExpandedHdl
));
113 m_xEdCopyArea
->SetReferences(this, m_xFtDbAreaLabel
.get());
114 m_xRbCopyArea
->SetReferences(this, m_xEdCopyArea
.get());
116 assert(m_xLbCond1
->find_text(aStrFontColor
) != -1);
117 assert(m_xLbCond1
->find_text(aStrBackgroundColor
) != -1);
121 // Hack: RefInput control
122 pTimer
.reset( new Timer("ScFilterTimer") );
123 pTimer
->SetTimeout( 50 ); // Wait 50ms
124 pTimer
->SetInvokeHandler( LINK( this, ScFilterDlg
, TimeOutHdl
) );
127 ScFilterDlg::~ScFilterDlg()
132 // Hack: RefInput control
138 VirtualDevice
* lcl_getColorImage(const Color
&rColor
)
140 const StyleSettings
& rStyleSettings
= Application::GetSettings().GetStyleSettings();
141 Size
aImageSize(rStyleSettings
.GetListBoxPreviewDefaultPixelSize());
143 VclPtrInstance
<VirtualDevice
> xDevice
;
144 xDevice
->SetOutputSize(aImageSize
);
145 const tools::Rectangle
aRect(Point(0, 0), aImageSize
);
146 if (rColor
== COL_NONE_COLOR
)
148 const Color
aW(COL_WHITE
);
149 const Color
aG(0xef, 0xef, 0xef);
150 xDevice
->DrawCheckered(aRect
.TopLeft(), aRect
.GetSize(), 8, aW
, aG
);
151 xDevice
->SetFillColor();
155 xDevice
->SetFillColor(rColor
);
158 xDevice
->DrawRect(aRect
);
160 return xDevice
.get();
164 void ScFilterDlg::Init( const SfxItemSet
& rArgSet
)
166 const ScQueryItem
& rQueryItem
= static_cast<const ScQueryItem
&>(
167 rArgSet
.Get( nWhichQuery
));
169 m_xBtnClear
->connect_clicked ( LINK( this, ScFilterDlg
, BtnClearHdl
) );
170 m_xBtnOk
->connect_clicked ( LINK( this, ScFilterDlg
, EndDlgHdl
) );
171 m_xBtnCancel
->connect_clicked ( LINK( this, ScFilterDlg
, EndDlgHdl
) );
172 m_xBtnHeader
->connect_toggled ( LINK( this, ScFilterDlg
, CheckBoxHdl
) );
173 m_xBtnCase
->connect_toggled ( LINK( this, ScFilterDlg
, CheckBoxHdl
) );
175 m_xLbField1
->connect_changed ( LINK( this, ScFilterDlg
, LbSelectHdl
) );
176 m_xLbField2
->connect_changed ( LINK( this, ScFilterDlg
, LbSelectHdl
) );
177 m_xLbField3
->connect_changed ( LINK( this, ScFilterDlg
, LbSelectHdl
) );
178 m_xLbField4
->connect_changed ( LINK( this, ScFilterDlg
, LbSelectHdl
) );
179 m_xLbConnect1
->connect_changed( LINK( this, ScFilterDlg
, LbSelectHdl
) );
180 m_xLbConnect2
->connect_changed( LINK( this, ScFilterDlg
, LbSelectHdl
) );
181 m_xLbConnect3
->connect_changed( LINK( this, ScFilterDlg
, LbSelectHdl
) );
182 m_xLbConnect4
->connect_changed( LINK( this, ScFilterDlg
, LbSelectHdl
) );
184 m_xLbField1
->append_text(u
"0000000000"_ustr
);
185 m_xLbField1
->set_active(0);
186 auto nPrefWidth
= m_xLbField1
->get_preferred_size().Width();
187 m_xLbField1
->clear();
189 m_xLbField1
->set_size_request(nPrefWidth
, -1);
190 m_xLbField2
->set_size_request(nPrefWidth
, -1);
191 m_xLbField3
->set_size_request(nPrefWidth
, -1);
192 m_xLbField4
->set_size_request(nPrefWidth
, -1);
194 m_xLbCond1
->connect_changed( LINK( this, ScFilterDlg
, LbSelectHdl
) );
195 m_xLbCond2
->connect_changed( LINK( this, ScFilterDlg
, LbSelectHdl
) );
196 m_xLbCond3
->connect_changed( LINK( this, ScFilterDlg
, LbSelectHdl
) );
197 m_xLbCond4
->connect_changed( LINK( this, ScFilterDlg
, LbSelectHdl
) );
199 m_xLbColor1
->connect_changed( LINK( this, ScFilterDlg
, LbSelectHdl
) );
200 m_xLbColor2
->connect_changed( LINK( this, ScFilterDlg
, LbSelectHdl
) );
201 m_xLbColor3
->connect_changed( LINK( this, ScFilterDlg
, LbSelectHdl
) );
202 m_xLbColor4
->connect_changed( LINK( this, ScFilterDlg
, LbSelectHdl
) );
204 m_xBtnRemove1
->connect_clicked( LINK( this, ScFilterDlg
, BtnRemoveHdl
) );
205 m_xBtnRemove2
->connect_clicked( LINK( this, ScFilterDlg
, BtnRemoveHdl
) );
206 m_xBtnRemove3
->connect_clicked( LINK( this, ScFilterDlg
, BtnRemoveHdl
) );
207 m_xBtnRemove4
->connect_clicked( LINK( this, ScFilterDlg
, BtnRemoveHdl
) );
209 pViewData
= rQueryItem
.GetViewData();
210 pDoc
= pViewData
? &pViewData
->GetDocument() : nullptr;
211 nSrcTab
= pViewData
? pViewData
->GetTabNo() : static_cast<SCTAB
>(0);
213 // for easier access:
214 maFieldLbArr
.reserve(QUERY_ENTRY_COUNT
);
215 maFieldLbArr
.push_back(m_xLbField1
.get());
216 maFieldLbArr
.push_back(m_xLbField2
.get());
217 maFieldLbArr
.push_back(m_xLbField3
.get());
218 maFieldLbArr
.push_back(m_xLbField4
.get());
219 maValueEdArr
.reserve(QUERY_ENTRY_COUNT
);
220 maValueEdArr
.push_back(m_xEdVal1
.get());
221 maValueEdArr
.push_back(m_xEdVal2
.get());
222 maValueEdArr
.push_back(m_xEdVal3
.get());
223 maValueEdArr
.push_back(m_xEdVal4
.get());
224 maCondLbArr
.reserve(QUERY_ENTRY_COUNT
);
225 maCondLbArr
.push_back(m_xLbCond1
.get());
226 maCondLbArr
.push_back(m_xLbCond2
.get());
227 maCondLbArr
.push_back(m_xLbCond3
.get());
228 maCondLbArr
.push_back(m_xLbCond4
.get());
229 maConnLbArr
.reserve(QUERY_ENTRY_COUNT
);
230 maConnLbArr
.push_back(m_xLbConnect1
.get());
231 maConnLbArr
.push_back(m_xLbConnect2
.get());
232 maConnLbArr
.push_back(m_xLbConnect3
.get());
233 maConnLbArr
.push_back(m_xLbConnect4
.get());
234 maColorLbArr
.reserve(QUERY_ENTRY_COUNT
);
235 maColorLbArr
.push_back(m_xLbColor1
.get());
236 maColorLbArr
.push_back(m_xLbColor2
.get());
237 maColorLbArr
.push_back(m_xLbColor3
.get());
238 maColorLbArr
.push_back(m_xLbColor4
.get());
239 maRemoveBtnArr
.reserve(QUERY_ENTRY_COUNT
);
240 maRemoveBtnArr
.push_back(m_xBtnRemove1
.get());
241 maRemoveBtnArr
.push_back(m_xBtnRemove2
.get());
242 maRemoveBtnArr
.push_back(m_xBtnRemove3
.get());
243 maRemoveBtnArr
.push_back(m_xBtnRemove4
.get());
245 // Option initialization:
246 pOptionsMgr
.reset( new ScFilterOptionsMgr(
253 m_xBtnCopyResult
.get(),
254 m_xBtnDestPers
.get(),
258 m_xFtDbAreaLabel
.get(),
261 // Read in field lists and select entries
265 for (size_t i
= 0; i
< QUERY_ENTRY_COUNT
; ++i
)
269 size_t nFieldSelPos
= 0;
271 maColorLbArr
[i
]->set_visible(false);
273 ScQueryEntry
& rEntry
= theQueryData
.GetEntry(i
);
274 if ( rEntry
.bDoQuery
)
276 nCondPos
= static_cast<size_t>(rEntry
.eOp
);
277 nFieldSelPos
= GetFieldSelPos( static_cast<SCCOL
>(rEntry
.nField
) );
278 if (rEntry
.IsQueryByEmpty())
281 maCondLbArr
[i
]->set_sensitive(false);
283 else if (rEntry
.IsQueryByNonEmpty())
285 aValStr
= aStrNotEmpty
;
286 maCondLbArr
[i
]->set_sensitive(false);
288 else if (rEntry
.IsQueryByTextColor() || rEntry
.IsQueryByBackgroundColor())
290 nCondPos
= maCondLbArr
[i
]->find_text(
291 rEntry
.IsQueryByTextColor() ? aStrFontColor
: aStrBackgroundColor
);
292 maValueEdArr
[i
]->set_visible(false);
293 maColorLbArr
[i
]->set_visible(true);
294 maColorLbArr
[i
]->set_sensitive(true);
298 const ScQueryEntry::Item
& rItem
= rEntry
.GetQueryItem();
299 OUString aQueryStr
= rItem
.maString
.getString();
300 SetValString(aQueryStr
, rItem
, aValStr
);
305 nFieldSelPos
= pViewData
? GetFieldSelPos(pViewData
->GetCurX()) : 0;
306 rEntry
.nField
= nFieldSelPos
? (theQueryData
.nCol1
+
307 static_cast<SCCOL
>(nFieldSelPos
) - 1) : static_cast<SCCOL
>(0);
308 rEntry
.bDoQuery
=true;
309 if (maRefreshExceptQuery
.size() < i
+ 1)
310 maRefreshExceptQuery
.resize(i
+ 1, false);
311 maRefreshExceptQuery
[i
] = true;
314 maFieldLbArr
[i
]->set_active( nFieldSelPos
);
315 maCondLbArr
[i
]->set_active( nCondPos
);
316 maValueEdArr
[i
]->set_entry_text( aValStr
);
317 maValueEdArr
[i
]->set_entry_completion(false);
318 maValueEdArr
[i
]->connect_changed( LINK( this, ScFilterDlg
, ValModifyHdl
) );
319 UpdateValueList(i
+1);
320 UpdateColorList(i
+1);
323 m_xScrollBar
->connect_vadjustment_changed( LINK( this, ScFilterDlg
, ScrollHdl
) );
324 m_xScrollBar
->vadjustment_configure(0, 0, 8, 1, 3, 4);
325 Size
aSize(m_xContents
->get_preferred_size());
326 m_xContents
->set_size_request(aSize
.Width(), aSize
.Height());
328 m_xLbConnect1
->hide();
329 // Disable/Enable Logic:
331 (m_xLbField1
->get_active() != 0)
332 && (m_xLbField2
->get_active() != 0)
333 ? m_xLbConnect2
->set_active( static_cast<sal_uInt16
>(theQueryData
.GetEntry(1).eConnect
) )
334 : m_xLbConnect2
->set_active(-1);
336 (m_xLbField2
->get_active() != 0)
337 && (m_xLbField3
->get_active() != 0)
338 ? m_xLbConnect3
->set_active( static_cast<sal_uInt16
>(theQueryData
.GetEntry(2).eConnect
) )
339 : m_xLbConnect3
->set_active(-1);
341 (m_xLbField3
->get_active() != 0)
342 && (m_xLbField4
->get_active() != 0)
343 ? m_xLbConnect4
->set_active( static_cast<sal_uInt16
>(theQueryData
.GetEntry(3).eConnect
) )
344 : m_xLbConnect4
->set_active(-1);
345 if ( m_xLbField1
->get_active() == 0 )
347 m_xLbConnect2
->set_sensitive(false);
348 m_xLbField2
->set_sensitive(false);
349 m_xLbCond2
->set_sensitive(false);
350 m_xEdVal2
->set_sensitive(false);
351 m_xLbColor2
->set_sensitive(false);
352 m_xBtnRemove2
->set_sensitive(false);
354 else if ( m_xLbConnect2
->get_active() == -1 )
356 m_xLbField2
->set_sensitive(false);
357 m_xLbCond2
->set_sensitive(false);
358 m_xEdVal2
->set_sensitive(false);
359 m_xLbColor2
->set_sensitive(false);
360 m_xBtnRemove2
->set_sensitive(false);
363 if ( m_xLbField2
->get_active() == 0 )
365 m_xLbConnect3
->set_sensitive(false);
366 m_xLbField3
->set_sensitive(false);
367 m_xLbCond3
->set_sensitive(false);
368 m_xEdVal3
->set_sensitive(false);
369 m_xLbColor3
->set_sensitive(false);
370 m_xBtnRemove3
->set_sensitive(false);
372 else if ( m_xLbConnect3
->get_active() == -1 )
374 m_xLbField3
->set_sensitive(false);
375 m_xLbCond3
->set_sensitive(false);
376 m_xEdVal3
->set_sensitive(false);
377 m_xLbColor3
->set_sensitive(false);
378 m_xBtnRemove3
->set_sensitive(false);
380 if ( m_xLbField3
->get_active() == 0 )
382 m_xLbConnect4
->set_sensitive(false);
383 m_xLbField4
->set_sensitive(false);
384 m_xLbCond4
->set_sensitive(false);
385 m_xEdVal4
->set_sensitive(false);
386 m_xLbColor4
->set_sensitive(false);
387 m_xBtnRemove4
->set_sensitive(false);
389 else if ( m_xLbConnect4
->get_active() == -1 )
391 m_xLbField4
->set_sensitive(false);
392 m_xLbCond4
->set_sensitive(false);
393 m_xEdVal4
->set_sensitive(false);
394 m_xLbColor4
->set_sensitive(false);
395 m_xBtnRemove4
->set_sensitive(false);
398 m_xEdVal1
->set_entry_width_chars(10);
399 m_xEdVal2
->set_entry_width_chars(10);
400 m_xEdVal3
->set_entry_width_chars(10);
401 m_xEdVal4
->set_entry_width_chars(10);
403 if (pDoc
!= nullptr && pDoc
->GetChangeTrack() != nullptr)
404 m_xBtnCopyResult
->set_sensitive(false);
407 void ScFilterDlg::Close()
410 pViewData
->GetDocShell()->CancelAutoDBRange();
412 DoClose( ScFilterDlgWrapper::GetChildWindowId() );
415 // Mouse-selected cell area becomes the new selection and is shown in the
416 // reference text box
418 void ScFilterDlg::SetReference( const ScRange
& rRef
, ScDocument
& rDocP
)
420 if ( bRefInputMode
) // Only possible if in reference edit mode
422 if ( rRef
.aStart
!= rRef
.aEnd
)
423 RefInputStart( m_xEdCopyArea
.get() );
424 OUString
aRefStr(rRef
.aStart
.Format(ScRefFlags::ADDR_ABS_3D
, &rDocP
, rDocP
.GetAddressConvention()));
425 m_xEdCopyArea
->SetRefString( aRefStr
);
429 void ScFilterDlg::SetActive()
433 m_xEdCopyArea
->GrabFocus();
434 m_xEdCopyArea
->GetModifyHdl().Call( *m_xEdCopyArea
);
437 m_xDialog
->grab_focus();
442 void ScFilterDlg::FillFieldLists()
444 m_xLbField1
->freeze();
445 m_xLbField2
->freeze();
446 m_xLbField3
->freeze();
447 m_xLbField4
->freeze();
449 m_xLbField1
->clear();
450 m_xLbField2
->clear();
451 m_xLbField3
->clear();
452 m_xLbField4
->clear();
453 m_xLbField1
->append_text( aStrNone
);
454 m_xLbField2
->append_text( aStrNone
);
455 m_xLbField3
->append_text( aStrNone
);
456 m_xLbField4
->append_text( aStrNone
);
461 SCTAB nTab
= nSrcTab
;
462 SCCOL nFirstCol
= theQueryData
.nCol1
;
463 SCROW nFirstRow
= theQueryData
.nRow1
;
464 SCCOL nMaxCol
= theQueryData
.nCol2
;
467 for ( col
=nFirstCol
; col
<=nMaxCol
; col
++ )
469 aFieldName
= pDoc
->GetString(col
, nFirstRow
, nTab
);
470 if (!m_xBtnHeader
->get_active() || aFieldName
.isEmpty())
472 aFieldName
= ScGlobal::ReplaceOrAppend( aStrColumn
, u
"%1", ScColToAlpha( col
));
474 m_xLbField1
->append_text( aFieldName
);
475 m_xLbField2
->append_text( aFieldName
);
476 m_xLbField3
->append_text( aFieldName
);
477 m_xLbField4
->append_text( aFieldName
);
487 void ScFilterDlg::UpdateValueList( size_t nList
)
489 bool bCaseSens
= m_xBtnCase
->get_active();
491 if (pDoc
&& nList
> 0 && nList
<= QUERY_ENTRY_COUNT
)
493 weld::ComboBox
* pValList
= maValueEdArr
[nList
-1];
494 const sal_Int32 nFieldSelPos
= maFieldLbArr
[nList
-1]->get_active();
495 OUString aCurValue
= pValList
->get_active_text();
497 std::unique_ptr
<weld::WaitObject
> xWaiter
;
498 std::vector
<weld::ComboBoxEntry
> aEntries
;
499 aEntries
.emplace_back(aStrNotEmpty
);
500 aEntries
.emplace_back(aStrEmpty
);
504 xWaiter
.reset(new weld::WaitObject(m_xDialog
.get())); // even if only the list box has content
505 SCCOL nColumn
= theQueryData
.nCol1
+ static_cast<SCCOL
>(nFieldSelPos
) - 1;
506 EntryList
* pList
= nullptr;
507 if (!m_EntryLists
.count(nColumn
))
509 size_t nOffset
= GetSliderPos();
510 SCTAB nTab
= nSrcTab
;
511 SCROW nFirstRow
= theQueryData
.nRow1
;
512 SCROW nLastRow
= theQueryData
.nRow2
;
513 if (maHasDates
.size() < nOffset
+nList
)
514 maHasDates
.resize(nOffset
+nList
, false);
515 maHasDates
[nOffset
+nList
-1] = false;
517 // first without the first line
518 std::pair
<EntryListsMap::iterator
, bool> r
=
519 m_EntryLists
.insert(std::make_pair(nColumn
, std::make_unique
<EntryList
>()));
524 pList
= r
.first
->second
.get();
525 pDoc
->GetFilterEntriesArea(
526 nColumn
, nFirstRow
+1, nLastRow
,
527 nTab
, bCaseSens
, pList
->maFilterEntries
);
528 maHasDates
[nOffset
+nList
-1] = pList
->maFilterEntries
.mbHasDates
;
530 // Entry for the first line
531 //! Entry (pHdrEntry) doesn't generate collection?
533 pList
->mnHeaderPos
= INVALID_HEADER_POS
;
534 ScFilterEntries aHdrColl
;
535 pDoc
->GetFilterEntriesArea(
536 nColumn
, nFirstRow
, nFirstRow
, nTab
, true, aHdrColl
);
537 if (!aHdrColl
.empty())
539 // See if the header value is already in the list.
540 std::vector
<ScTypedStrData
>::iterator itBeg
= pList
->maFilterEntries
.begin(), itEnd
= pList
->maFilterEntries
.end();
541 if (std::none_of(itBeg
, itEnd
, FindTypedStrData(aHdrColl
.front(), bCaseSens
)))
543 // Not in the list. Insert it.
544 pList
->maFilterEntries
.push_back(aHdrColl
.front());
546 std::sort(pList
->maFilterEntries
.begin(), pList
->maFilterEntries
.end(), ScTypedStrData::LessCaseSensitive());
548 std::sort(pList
->maFilterEntries
.begin(), pList
->maFilterEntries
.end(), ScTypedStrData::LessCaseInsensitive());
550 // Record its position.
551 itBeg
= pList
->maFilterEntries
.begin();
552 itEnd
= pList
->maFilterEntries
.end();
553 auto it
= std::find_if(itBeg
, itEnd
, FindTypedStrData(aHdrColl
.front(), bCaseSens
));
554 pList
->mnHeaderPos
= std::distance(itBeg
, it
);
559 pList
= m_EntryLists
[nColumn
].get();
563 for (const auto& rEntry
: pList
->maFilterEntries
)
564 aEntries
.emplace_back(rEntry
.GetString());
566 pValList
->insert_vector(aEntries
, false);
567 pValList
->set_entry_text(aCurValue
);
570 UpdateHdrInValueList( nList
);
573 void ScFilterDlg::UpdateHdrInValueList( size_t nList
)
575 //! GetText / SetText ??
580 if (nList
== 0 || nList
> QUERY_ENTRY_COUNT
)
583 size_t nFieldSelPos
= maFieldLbArr
[nList
-1]->get_active();
587 SCCOL nColumn
= theQueryData
.nCol1
+ static_cast<SCCOL
>(nFieldSelPos
) - 1;
588 if (!m_EntryLists
.count(nColumn
))
590 OSL_FAIL("column not yet initialized");
594 size_t const nPos
= m_EntryLists
[nColumn
]->mnHeaderPos
;
595 if (nPos
== INVALID_HEADER_POS
)
598 weld::ComboBox
* pValList
= maValueEdArr
[nList
-1];
599 int nListPos
= nPos
+ 2; // for "empty" and "non-empty"
601 const ScTypedStrData
& rHdrEntry
= m_EntryLists
[nColumn
]->maFilterEntries
.maStrData
[nPos
];
603 const OUString
& aHdrStr
= rHdrEntry
.GetString();
604 bool bWasThere
= nListPos
< pValList
->get_count() && aHdrStr
== pValList
->get_text(nListPos
);
605 bool bInclude
= !m_xBtnHeader
->get_active();
607 if (bInclude
) // Include entry
610 pValList
->insert_text(nListPos
, aHdrStr
);
615 pValList
->remove(nListPos
);
619 void ScFilterDlg::ClearValueList( size_t nList
)
621 if (nList
> 0 && nList
<= QUERY_ENTRY_COUNT
)
623 weld::ComboBox
* pValList
= maValueEdArr
[nList
-1];
625 pValList
->append_text( aStrNotEmpty
);
626 pValList
->append_text( aStrEmpty
);
627 pValList
->set_entry_text( OUString() );
631 void ScFilterDlg::UpdateColorList(size_t nList
)
633 if (!pDoc
|| nList
<= 0 || nList
> QUERY_ENTRY_COUNT
)
636 size_t nPos
= nList
- 1;
637 ScQueryEntry
& rEntry
= theQueryData
.GetEntry(nPos
);
638 const sal_Int32 nFieldSelPos
= maFieldLbArr
[nPos
]->get_active();
642 SCCOL nColumn
= theQueryData
.nCol1
+ static_cast<SCCOL
>(nFieldSelPos
) - 1;
643 EntryList
* pList
= m_EntryLists
[nColumn
].get();
647 std::set
<Color
> aColors
;
648 OUString sSelectedCondition
= maCondLbArr
[nPos
]->get_active_text();
649 if (sSelectedCondition
== aStrFontColor
)
650 aColors
= pList
->maFilterEntries
.getTextColors();
651 else if (sSelectedCondition
== aStrBackgroundColor
)
652 aColors
= pList
->maFilterEntries
.getBackgroundColors();
656 maColorLbArr
[nPos
]->clear();
657 for (const auto& rColor
: aColors
)
659 OUString sId
= rColor
.AsRGBHexString();
660 if (rColor
== COL_AUTO
)
662 OUString sText
= sSelectedCondition
== aStrFontColor
663 ? ScResId(SCSTR_FILTER_AUTOMATIC_COLOR
)
664 : ScResId(SCSTR_FILTER_NO_FILL
);
665 maColorLbArr
[nPos
]->append(sId
, sText
);
669 VirtualDevice
* pDev
= lcl_getColorImage(rColor
);
670 maColorLbArr
[nPos
]->append(sId
, OUString(), *pDev
);
673 const auto& rItem
= rEntry
.GetQueryItem();
674 if (rItem
.maColor
== rColor
675 && ((sSelectedCondition
== aStrFontColor
&& rItem
.meType
== ScQueryEntry::ByTextColor
)
676 || (sSelectedCondition
== aStrBackgroundColor
677 && rItem
.meType
== ScQueryEntry::ByBackgroundColor
)))
679 maColorLbArr
[nPos
]->set_active_id(sId
);
684 size_t ScFilterDlg::GetFieldSelPos( SCCOL nField
)
686 if ( nField
>= theQueryData
.nCol1
&& nField
<= theQueryData
.nCol2
)
687 return static_cast<size_t>(nField
- theQueryData
.nCol1
+ 1);
692 ScQueryItem
* ScFilterDlg::GetOutputItem()
694 ScAddress theCopyPos
;
695 ScQueryParam
theParam( theQueryData
);
696 bool bCopyPosOk
= false;
698 if ( m_xBtnCopyResult
->get_active() )
700 ScRefFlags nResult
= theCopyPos
.Parse(
701 m_xEdCopyArea
->GetText(), *pDoc
, pDoc
->GetAddressConvention());
702 bCopyPosOk
= (nResult
& ScRefFlags::VALID
) == ScRefFlags::VALID
;
705 if ( m_xBtnCopyResult
->get_active() && bCopyPosOk
)
707 theParam
.bInplace
= false;
708 theParam
.nDestTab
= theCopyPos
.Tab();
709 theParam
.nDestCol
= theCopyPos
.Col();
710 theParam
.nDestRow
= theCopyPos
.Row();
714 theParam
.bInplace
= true;
715 theParam
.nDestTab
= 0;
716 theParam
.nDestCol
= 0;
717 theParam
.nDestRow
= 0;
720 theParam
.bHasHeader
= m_xBtnHeader
->get_active();
721 theParam
.bByRow
= true;
722 theParam
.bDuplicate
= !m_xBtnUnique
->get_active();
723 theParam
.bCaseSens
= m_xBtnCase
->get_active();
724 theParam
.eSearchType
= m_xBtnRegExp
->get_active() ? utl::SearchParam::SearchType::Regexp
: utl::SearchParam::SearchType::Normal
;
725 theParam
.bDestPers
= m_xBtnDestPers
->get_active();
727 // only set the three - reset everything else
729 pOutItem
.reset( new ScQueryItem( nWhichQuery
, &theParam
) );
731 return pOutItem
.get();
734 bool ScFilterDlg::IsRefInputMode() const
736 return bRefInputMode
;
741 IMPL_LINK( ScFilterDlg
, BtnClearHdl
, weld::Button
&, rBtn
, void )
743 if ( &rBtn
!= m_xBtnClear
.get() )
747 m_xScrollBar
->vadjustment_set_value(0);
749 RefreshEditRow( nOffset
);
751 // clear all conditions
752 m_xLbConnect1
->set_active(-1);
753 m_xLbConnect2
->set_active(-1);
754 m_xLbConnect3
->set_active(-1);
755 m_xLbConnect4
->set_active(-1);
756 m_xLbField1
->set_active(0);
757 m_xLbField2
->set_active(0);
758 m_xLbField3
->set_active(0);
759 m_xLbField4
->set_active(0);
760 m_xLbCond1
->set_active(0);
761 m_xLbCond2
->set_active(0);
762 m_xLbCond3
->set_active(0);
763 m_xLbCond4
->set_active(0);
769 // disable fields for second row onward
770 m_xLbConnect2
->set_sensitive(false);
771 m_xLbConnect3
->set_sensitive(false);
772 m_xLbConnect4
->set_sensitive(false);
773 m_xLbField2
->set_sensitive(false);
774 m_xLbField3
->set_sensitive(false);
775 m_xLbField4
->set_sensitive(false);
776 m_xLbCond2
->set_sensitive(false);
777 m_xLbCond3
->set_sensitive(false);
778 m_xLbCond4
->set_sensitive(false);
779 m_xEdVal2
->set_sensitive(false);
780 m_xEdVal3
->set_sensitive(false);
781 m_xEdVal4
->set_sensitive(false);
782 m_xLbColor2
->set_sensitive(false);
783 m_xLbColor3
->set_sensitive(false);
784 m_xLbColor4
->set_sensitive(false);
785 m_xBtnRemove2
->set_sensitive(false);
786 m_xBtnRemove3
->set_sensitive(false);
787 m_xBtnRemove4
->set_sensitive(false);
789 // clear query data objects
790 SCSIZE nCount
= theQueryData
.GetEntryCount();
791 if (maRefreshExceptQuery
.size() < nCount
+ 1)
792 maRefreshExceptQuery
.resize(nCount
+ 1, false);
793 for (SCSIZE i
= 0; i
< nCount
; ++i
)
795 theQueryData
.GetEntry(i
).bDoQuery
= false;
796 maRefreshExceptQuery
[i
] = false;
797 theQueryData
.GetEntry(i
).nField
= static_cast<SCCOL
>(0);
799 maRefreshExceptQuery
[0] = true;
802 IMPL_LINK( ScFilterDlg
, EndDlgHdl
, weld::Button
&, rBtn
, void )
804 if ( &rBtn
== m_xBtnOk
.get() )
806 bool bAreaInputOk
= true;
808 if ( m_xBtnCopyResult
->get_active() )
810 if ( !pOptionsMgr
->VerifyPosStr( m_xEdCopyArea
->GetText() ) )
812 if (!m_xExpander
->get_expanded())
813 m_xExpander
->set_expanded(true);
815 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(m_xDialog
.get(),
816 VclMessageType::Warning
, VclButtonsType::Ok
,
817 ScResId(STR_INVALID_TABREF
)));
819 m_xEdCopyArea
->GrabFocus();
820 bAreaInputOk
= false;
826 SetDispatcherLock( false );
828 GetBindings().GetDispatcher()->ExecuteList(FID_FILTER_OK
,
829 SfxCallMode::SLOT
| SfxCallMode::RECORD
,
830 { GetOutputItem() });
834 else if ( &rBtn
== m_xBtnCancel
.get() )
836 response(RET_CANCEL
);
840 IMPL_LINK_NOARG(ScFilterDlg
, MoreExpandedHdl
, weld::Expander
&, void)
842 if ( m_xExpander
->get_expanded() )
847 bRefInputMode
= false;
848 //@BugID 54702 Enable/disable only in Basic class
849 //SFX_APPWINDOW->Disable(FALSE); //! general method in ScAnyRefDlg
853 IMPL_LINK( ScFilterDlg
, TimeOutHdl
, Timer
*, _pTimer
, void )
855 // Check if RefInputMode is still true every 50ms
856 if (_pTimer
== pTimer
.get() && m_xDialog
->has_toplevel_focus())
857 bRefInputMode
= (m_xEdCopyArea
->GetWidget()->has_focus() || m_xRbCopyArea
->GetWidget()->has_focus());
859 if ( m_xExpander
->get_expanded() )
863 IMPL_LINK(ScFilterDlg
, LbSelectHdl
, weld::ComboBox
&, rLb
, void)
866 * Handle enable/disable logic depending on which ListBox was selected
868 sal_uInt16 nOffset
= GetSliderPos();
870 if ( &rLb
== m_xLbConnect1
.get() )
872 m_xLbField1
->set_sensitive(true);
873 m_xLbCond1
->set_sensitive(true);
874 m_xEdVal1
->set_sensitive(true);
875 m_xBtnRemove1
->set_sensitive(true);
877 const sal_Int32 nConnect1
= m_xLbConnect1
->get_active();
878 size_t nQE
= nOffset
;
879 theQueryData
.GetEntry(nQE
).eConnect
=static_cast<ScQueryConnect
>(nConnect1
);
880 if (maRefreshExceptQuery
.size() < nQE
+ 1)
881 maRefreshExceptQuery
.resize(nQE
+ 1, false);
882 maRefreshExceptQuery
[nQE
] = true;
884 else if ( &rLb
== m_xLbConnect2
.get() )
886 m_xLbField2
->set_sensitive(true);
887 m_xLbCond2
->set_sensitive(true);
888 m_xEdVal2
->set_sensitive(true);
889 m_xBtnRemove2
->set_sensitive(true);
891 const sal_Int32 nConnect2
= m_xLbConnect2
->get_active();
892 size_t nQE
= 1+nOffset
;
893 theQueryData
.GetEntry(nQE
).eConnect
=static_cast<ScQueryConnect
>(nConnect2
);
894 if (maRefreshExceptQuery
.size() < nQE
+ 1)
895 maRefreshExceptQuery
.resize(nQE
+ 1, false);
896 maRefreshExceptQuery
[nQE
]=true;
898 else if ( &rLb
== m_xLbConnect3
.get() )
900 m_xLbField3
->set_sensitive(true);
901 m_xLbCond3
->set_sensitive(true);
902 m_xEdVal3
->set_sensitive(true);
903 m_xBtnRemove3
->set_sensitive(true);
905 const sal_Int32 nConnect3
= m_xLbConnect3
->get_active();
906 size_t nQE
= 2 + nOffset
;
907 theQueryData
.GetEntry(nQE
).eConnect
= static_cast<ScQueryConnect
>(nConnect3
);
908 if (maRefreshExceptQuery
.size() < nQE
+ 1)
909 maRefreshExceptQuery
.resize(nQE
+ 1, false);
910 maRefreshExceptQuery
[nQE
] = true;
913 else if ( &rLb
== m_xLbConnect4
.get() )
915 m_xLbField4
->set_sensitive(true);
916 m_xLbCond4
->set_sensitive(true);
917 m_xEdVal4
->set_sensitive(true);
918 m_xLbColor4
->set_sensitive(true);
919 m_xBtnRemove4
->set_sensitive(true);
921 const sal_Int32 nConnect4
= m_xLbConnect4
->get_active();
922 size_t nQE
= 3 + nOffset
;
923 theQueryData
.GetEntry(nQE
).eConnect
= static_cast<ScQueryConnect
>(nConnect4
);
924 if (maRefreshExceptQuery
.size() < nQE
+ 1)
925 maRefreshExceptQuery
.resize(nQE
+ 1, false);
926 maRefreshExceptQuery
[nQE
] = true;
928 else if ( &rLb
== m_xLbField1
.get() )
930 if ( m_xLbField1
->get_active() == 0 )
932 m_xLbConnect2
->set_active(-1);
933 m_xLbConnect3
->set_active(-1);
934 m_xLbConnect4
->set_active(-1);
935 m_xLbField2
->set_active( 0 );
936 m_xLbField3
->set_active( 0 );
937 m_xLbField4
->set_active( 0 );
938 m_xLbCond2
->set_active( 0 );
939 m_xLbCond3
->set_active( 0 );
940 m_xLbCond4
->set_active( 0 );
946 m_xLbConnect2
->set_sensitive(false);
947 m_xLbConnect3
->set_sensitive(false);
948 m_xLbConnect4
->set_sensitive(false);
949 m_xLbField2
->set_sensitive(false);
950 m_xLbField3
->set_sensitive(false);
951 m_xLbField4
->set_sensitive(false);
952 m_xLbCond2
->set_sensitive(false);
953 m_xLbCond3
->set_sensitive(false);
954 m_xLbCond4
->set_sensitive(false);
955 m_xEdVal2
->set_sensitive(false);
956 m_xEdVal3
->set_sensitive(false);
957 m_xEdVal4
->set_sensitive(false);
958 m_xLbColor2
->set_sensitive(false);
959 m_xLbColor3
->set_sensitive(false);
960 m_xLbColor4
->set_sensitive(false);
961 m_xBtnRemove2
->set_sensitive(false);
962 m_xBtnRemove3
->set_sensitive(false);
963 m_xBtnRemove4
->set_sensitive(false);
964 SCSIZE nCount
= theQueryData
.GetEntryCount();
965 if (maRefreshExceptQuery
.size() < nCount
+ 1)
966 maRefreshExceptQuery
.resize(nCount
+ 1, false);
967 for (SCSIZE i
= nOffset
; i
< nCount
; ++i
)
969 theQueryData
.GetEntry(i
).bDoQuery
= false;
970 maRefreshExceptQuery
[i
] = false;
971 theQueryData
.GetEntry(i
).nField
= static_cast<SCCOL
>(0);
973 maRefreshExceptQuery
[nOffset
] = true;
977 UpdateValueList( 1 );
978 UpdateColorList( 1 );
979 if ( !m_xLbConnect2
->get_sensitive() )
981 m_xLbConnect2
->set_sensitive(true);
983 theQueryData
.GetEntry(nOffset
).bDoQuery
= true;
984 const sal_Int32 nField
= rLb
.get_active();
985 theQueryData
.GetEntry(nOffset
).nField
= theQueryData
.nCol1
+ static_cast<SCCOL
>(nField
) - 1 ;
988 else if ( &rLb
== m_xLbField2
.get() )
990 if ( m_xLbField2
->get_active() == 0 )
992 m_xLbConnect3
->set_active(-1);
993 m_xLbConnect4
->set_active(-1);
994 m_xLbField3
->set_active( 0 );
995 m_xLbField4
->set_active( 0 );
996 m_xLbCond3
->set_active( 0 );
997 m_xLbCond4
->set_active( 0 );
1000 ClearValueList( 4 );
1002 m_xLbConnect3
->set_sensitive(false);
1003 m_xLbConnect4
->set_sensitive(false);
1004 m_xLbField3
->set_sensitive(false);
1005 m_xLbField4
->set_sensitive(false);
1006 m_xLbCond3
->set_sensitive(false);
1007 m_xLbCond4
->set_sensitive(false);
1008 m_xEdVal3
->set_sensitive(false);
1009 m_xEdVal4
->set_sensitive(false);
1010 m_xLbColor3
->set_sensitive(false);
1011 m_xLbColor4
->set_sensitive(false);
1012 m_xBtnRemove3
->set_sensitive(false);
1013 m_xBtnRemove4
->set_sensitive(false);
1015 sal_uInt16 nTemp
=nOffset
+1;
1016 SCSIZE nCount
= theQueryData
.GetEntryCount();
1017 if (maRefreshExceptQuery
.size() < nCount
)
1018 maRefreshExceptQuery
.resize(nCount
, false);
1019 for (SCSIZE i
= nTemp
; i
< nCount
; i
++)
1021 theQueryData
.GetEntry(i
).bDoQuery
= false;
1022 maRefreshExceptQuery
[i
] = false;
1023 theQueryData
.GetEntry(i
).nField
= static_cast<SCCOL
>(0);
1025 maRefreshExceptQuery
[nTemp
] = true;
1029 UpdateValueList( 2 );
1030 UpdateColorList( 2 );
1031 if ( !m_xLbConnect3
->get_sensitive() )
1033 m_xLbConnect3
->set_sensitive(true);
1035 const sal_Int32 nField
= rLb
.get_active();
1036 sal_uInt16 nQ
=1+nOffset
;
1037 theQueryData
.GetEntry(nQ
).bDoQuery
= true;
1038 theQueryData
.GetEntry(nQ
).nField
= theQueryData
.nCol1
+ static_cast<SCCOL
>(nField
) - 1 ;
1041 else if ( &rLb
== m_xLbField3
.get() )
1043 if ( m_xLbField3
->get_active() == 0 )
1045 m_xLbConnect4
->set_active(-1);
1046 m_xLbField4
->set_active( 0 );
1047 m_xLbCond4
->set_active( 0 );
1048 ClearValueList( 3 );
1049 ClearValueList( 4 );
1051 m_xLbConnect4
->set_sensitive(false);
1052 m_xLbField4
->set_sensitive(false);
1053 m_xLbCond4
->set_sensitive(false);
1054 m_xEdVal4
->set_sensitive(false);
1055 m_xLbColor4
->set_sensitive(false);
1056 m_xBtnRemove4
->set_sensitive(false);
1058 sal_uInt16 nTemp
=nOffset
+2;
1059 SCSIZE nCount
= theQueryData
.GetEntryCount();
1060 if (maRefreshExceptQuery
.size() < nCount
)
1061 maRefreshExceptQuery
.resize(nCount
, false);
1062 for (SCSIZE i
= nTemp
; i
< nCount
; ++i
)
1064 theQueryData
.GetEntry(i
).bDoQuery
= false;
1065 maRefreshExceptQuery
[i
] = false;
1066 theQueryData
.GetEntry(i
).nField
= static_cast<SCCOL
>(0);
1068 maRefreshExceptQuery
[nTemp
] = true;
1072 UpdateValueList( 3 );
1073 UpdateColorList( 3 );
1074 if ( !m_xLbConnect4
->get_sensitive() )
1076 m_xLbConnect4
->set_sensitive(true);
1079 const sal_Int32 nField
= rLb
.get_active();
1080 sal_uInt16 nQ
=2+nOffset
;
1081 theQueryData
.GetEntry(nQ
).bDoQuery
= true;
1082 theQueryData
.GetEntry(nQ
).nField
= theQueryData
.nCol1
+ static_cast<SCCOL
>(nField
) - 1 ;
1086 else if ( &rLb
== m_xLbField4
.get() )
1088 if ( m_xLbField4
->get_active() == 0 )
1090 ClearValueList( 4 );
1091 sal_uInt16 nTemp
=nOffset
+3;
1092 SCSIZE nCount
= theQueryData
.GetEntryCount();
1093 if (maRefreshExceptQuery
.size() < nCount
)
1094 maRefreshExceptQuery
.resize(nCount
, false);
1095 for (SCSIZE i
= nTemp
; i
< nCount
; ++i
)
1097 theQueryData
.GetEntry(i
).bDoQuery
= false;
1098 maRefreshExceptQuery
[i
] = false;
1099 theQueryData
.GetEntry(i
).nField
= static_cast<SCCOL
>(0);
1101 maRefreshExceptQuery
[nTemp
] = true;
1105 UpdateValueList( 4 );
1106 UpdateColorList( 4 );
1107 const sal_Int32 nField
= rLb
.get_active();
1108 sal_uInt16 nQ
=3+nOffset
;
1109 theQueryData
.GetEntry(nQ
).bDoQuery
= true;
1110 theQueryData
.GetEntry(nQ
).nField
= theQueryData
.nCol1
+ static_cast<SCCOL
>(nField
) - 1 ;
1114 else if (&rLb
== m_xLbCond1
.get() || &rLb
== m_xLbCond2
.get() || &rLb
== m_xLbCond3
.get()
1115 || &rLb
== m_xLbCond4
.get())
1119 bool bEnableColorLb
= false;
1120 if (rLb
.get_active_text() == aStrFontColor
|| rLb
.get_active_text() == aStrBackgroundColor
)
1122 bEnableColorLb
= true;
1127 op
= static_cast<ScQueryOp
>(rLb
.get_active());
1130 if (&rLb
== m_xLbCond1
.get())
1133 m_xLbColor1
->set_visible(bEnableColorLb
);
1134 m_xLbColor1
->set_sensitive(bEnableColorLb
);
1135 m_xEdVal1
->set_visible(!bEnableColorLb
);
1138 else if (&rLb
== m_xLbCond2
.get())
1141 m_xLbColor2
->set_visible(bEnableColorLb
);
1142 m_xLbColor2
->set_sensitive(bEnableColorLb
);
1143 m_xEdVal2
->set_visible(!bEnableColorLb
);
1146 else if (&rLb
== m_xLbCond3
.get())
1149 m_xLbColor3
->set_visible(bEnableColorLb
);
1150 m_xLbColor3
->set_sensitive(bEnableColorLb
);
1151 m_xEdVal3
->set_visible(!bEnableColorLb
);
1154 else if (&rLb
== m_xLbCond4
.get())
1157 m_xLbColor4
->set_visible(bEnableColorLb
);
1158 m_xLbColor4
->set_sensitive(bEnableColorLb
);
1159 m_xEdVal4
->set_visible(!bEnableColorLb
);
1163 auto aEntry
= theQueryData
.GetEntry(nQ
);
1166 else if (&rLb
== m_xLbColor1
.get() || &rLb
== m_xLbColor2
.get() || &rLb
== m_xLbColor3
.get()
1167 || &rLb
== m_xLbColor4
.get())
1170 if (&rLb
== m_xLbColor1
.get())
1174 else if (&rLb
== m_xLbColor2
.get())
1178 else if (&rLb
== m_xLbColor3
.get())
1182 else if (&rLb
== m_xLbColor4
.get())
1187 ScQueryEntry
& aEntry
= theQueryData
.GetEntry(nQ
);
1188 Color aColor
= Color::STRtoRGB(maColorLbArr
[nQ
]->get_active_id());
1189 if (maCondLbArr
[nQ
]->get_active_text() == aStrFontColor
)
1191 aEntry
.SetQueryByTextColor(aColor
);
1193 else if (maCondLbArr
[nQ
]->get_active_text() == aStrBackgroundColor
)
1195 aEntry
.SetQueryByBackgroundColor(aColor
);
1200 IMPL_LINK( ScFilterDlg
, CheckBoxHdl
, weld::Toggleable
&, rBox
, void )
1203 // Field list: Columnxx <-> column header string
1204 // Value list: Column header value not applicable.
1205 // Upper/lower case:
1206 // Value list: completely new
1208 if ( &rBox
== m_xBtnHeader
.get() ) // Field list and value list
1210 const sal_Int32 nCurSel1
= m_xLbField1
->get_active();
1211 const sal_Int32 nCurSel2
= m_xLbField2
->get_active();
1212 const sal_Int32 nCurSel3
= m_xLbField3
->get_active();
1213 const sal_Int32 nCurSel4
= m_xLbField4
->get_active();
1215 m_xLbField1
->set_active( nCurSel1
);
1216 m_xLbField2
->set_active( nCurSel2
);
1217 m_xLbField3
->set_active( nCurSel3
);
1218 m_xLbField4
->set_active( nCurSel4
);
1220 UpdateHdrInValueList( 1 );
1221 UpdateHdrInValueList( 2 );
1222 UpdateHdrInValueList( 3 );
1223 UpdateHdrInValueList( 4 );
1226 if ( &rBox
!= m_xBtnCase
.get() ) // Complete value list
1229 m_EntryLists
.clear();
1230 UpdateValueList( 1 ); // current text is recorded
1231 UpdateValueList( 2 );
1232 UpdateValueList( 3 );
1233 UpdateValueList( 4 );
1235 UpdateColorList( 1 );
1236 UpdateColorList( 2 );
1237 UpdateColorList( 3 );
1238 UpdateColorList( 4 );
1241 IMPL_LINK( ScFilterDlg
, ValModifyHdl
, weld::ComboBox
&, rEd
, void )
1243 size_t nOffset
= GetSliderPos();
1245 size_t nQE
= i
+ nOffset
;
1246 OUString aStrVal
= rEd
.get_active_text();
1247 weld::ComboBox
* pLbCond
= m_xLbCond1
.get();
1248 weld::ComboBox
* pLbField
= m_xLbField1
.get();
1249 if ( &rEd
== m_xEdVal2
.get() )
1251 pLbCond
= m_xLbCond2
.get();
1252 pLbField
= m_xLbField2
.get();
1256 if ( &rEd
== m_xEdVal3
.get() )
1258 pLbCond
= m_xLbCond3
.get();
1259 pLbField
= m_xLbField3
.get();
1263 if ( &rEd
== m_xEdVal4
.get() )
1265 pLbCond
= m_xLbCond4
.get();
1266 pLbField
= m_xLbField4
.get();
1271 if ( aStrEmpty
== aStrVal
|| aStrNotEmpty
== aStrVal
)
1273 pLbCond
->set_active_text(OUString('='));
1274 pLbCond
->set_sensitive(false);
1277 pLbCond
->set_sensitive(true);
1279 if (maHasDates
.size() < nQE
+ 1)
1280 maHasDates
.resize(nQE
+ 1, false);
1281 if (maRefreshExceptQuery
.size() < nQE
+ 1)
1282 maRefreshExceptQuery
.resize(nQE
+ 1, false);
1284 ScQueryEntry
& rEntry
= theQueryData
.GetEntry( nQE
);
1285 ScQueryEntry::Item
& rItem
= rEntry
.GetQueryItem();
1286 bool bDoThis
= (pLbField
->get_active() != 0);
1287 rEntry
.bDoQuery
= bDoThis
;
1289 if ( !(rEntry
.bDoQuery
|| maRefreshExceptQuery
[nQE
]) )
1292 bool bByEmptyOrNotByEmpty
= false;
1293 if ( aStrEmpty
== aStrVal
)
1295 bByEmptyOrNotByEmpty
= true;
1296 rEntry
.SetQueryByEmpty();
1298 else if ( aStrNotEmpty
== aStrVal
)
1300 bByEmptyOrNotByEmpty
= true;
1301 rEntry
.SetQueryByNonEmpty();
1305 rItem
.maString
= pDoc
->GetSharedStringPool().intern(aStrVal
);
1307 rItem
.meType
= ScQueryEntry::ByString
;
1310 const sal_Int32 nField
= pLbField
->get_active();
1311 rEntry
.nField
= nField
? (theQueryData
.nCol1
+
1312 static_cast<SCCOL
>(nField
) - 1) : static_cast<SCCOL
>(0);
1314 ScQueryOp eOp
= static_cast<ScQueryOp
>(pLbCond
->get_active());
1316 if (maHasDates
[nQE
] && !bByEmptyOrNotByEmpty
)
1317 rItem
.meType
= ScQueryEntry::ByDate
;
1320 IMPL_LINK( ScFilterDlg
, BtnRemoveHdl
, weld::Button
&, rBtn
, void )
1322 // Calculate the row to delete
1323 sal_uInt16 nOffset
= GetSliderPos();
1324 int nButtonIndex
= 0;
1325 if ( &rBtn
== m_xBtnRemove2
.get() )
1327 if ( &rBtn
== m_xBtnRemove3
.get() )
1329 if ( &rBtn
== m_xBtnRemove4
.get() )
1331 SCSIZE nRowToDelete
= nOffset
+ nButtonIndex
;
1333 // Check that the index is sensible
1334 SCSIZE nCount
= theQueryData
.GetEntryCount();
1335 if (nRowToDelete
>= nCount
)
1337 SAL_WARN( "sc", "ScFilterDlg::BtnRemoveHdl: could not delete row - invalid index.");
1341 // Resize maRefreshExceptQuery
1342 if (maRefreshExceptQuery
.size() < nCount
+ 1)
1343 maRefreshExceptQuery
.resize(nCount
+ 1, false);
1345 // Move all the subsequent rows back one position;
1346 // also find the last row, which we will delete
1347 SCSIZE nRowToClear
= nCount
-1;
1348 for (SCSIZE i
= nRowToDelete
; i
< nCount
-1; ++i
)
1350 if (theQueryData
.GetEntry(i
+1).bDoQuery
)
1352 theQueryData
.GetEntry(i
) = theQueryData
.GetEntry(i
+1);
1361 // If the next row is being edited, but not confirmed, move it back
1363 if (nRowToClear
< nCount
-1 && maRefreshExceptQuery
[nRowToClear
+1])
1365 theQueryData
.GetEntry(nRowToClear
) = theQueryData
.GetEntry(nRowToClear
+1);
1366 maRefreshExceptQuery
[nRowToClear
] = true;
1367 maRefreshExceptQuery
[nRowToClear
+1] = false;
1371 // Remove the very last one, since everything has moved back
1372 theQueryData
.GetEntry(nRowToClear
).bDoQuery
= false;
1373 theQueryData
.GetEntry(nRowToClear
).nField
= static_cast<SCCOL
>(0);
1374 maRefreshExceptQuery
[nRowToClear
] = false;
1377 // Always enable the very first row
1378 if (!theQueryData
.GetEntry(0).bDoQuery
)
1380 maRefreshExceptQuery
[0] = true;
1384 RefreshEditRow( nOffset
);
1386 // Special handling if the very first row was cleared
1387 if (!theQueryData
.GetEntry(0).bDoQuery
)
1389 m_xLbConnect1
->set_active(-1);
1390 m_xLbField1
->set_active(0);
1391 m_xLbField1
->set_sensitive(true);
1392 m_xLbCond1
->set_active(0);
1393 m_xLbCond1
->set_sensitive(true);
1398 IMPL_LINK_NOARG(ScFilterDlg
, ScrollHdl
, weld::ScrolledWindow
&, void)
1403 void ScFilterDlg::SliderMoved()
1405 size_t nOffset
= GetSliderPos();
1406 RefreshEditRow( nOffset
);
1409 size_t ScFilterDlg::GetSliderPos() const
1411 return static_cast<size_t>(m_xScrollBar
->vadjustment_get_value());
1414 void ScFilterDlg::RefreshEditRow( size_t nOffset
)
1417 maConnLbArr
[0]->hide();
1419 maConnLbArr
[0]->show();
1421 for (size_t i
= 0; i
< QUERY_ENTRY_COUNT
; ++i
)
1424 size_t nCondPos
= 0;
1425 size_t nFieldSelPos
= 0;
1426 size_t nQE
= i
+ nOffset
;
1428 maColorLbArr
[i
]->set_visible(false);
1430 if (maRefreshExceptQuery
.size() < nQE
+ 1)
1431 maRefreshExceptQuery
.resize(nQE
+ 1, false);
1433 ScQueryEntry
& rEntry
= theQueryData
.GetEntry( nQE
);
1434 if ( rEntry
.bDoQuery
|| maRefreshExceptQuery
[nQE
] )
1436 nCondPos
= static_cast<size_t>(rEntry
.eOp
);
1438 nFieldSelPos
= GetFieldSelPos( static_cast<SCCOL
>(rEntry
.nField
) );
1440 const ScQueryEntry::Item
& rItem
= rEntry
.GetQueryItem();
1441 OUString aQueryStr
= rItem
.maString
.getString();
1442 if (rEntry
.IsQueryByEmpty())
1444 aValStr
= aStrEmpty
;
1445 maCondLbArr
[i
]->set_sensitive(false);
1447 else if (rEntry
.IsQueryByNonEmpty())
1449 aValStr
= aStrNotEmpty
;
1450 maCondLbArr
[i
]->set_sensitive(false);
1452 else if (rEntry
.IsQueryByTextColor() || rEntry
.IsQueryByBackgroundColor())
1454 nCondPos
= maCondLbArr
[i
]->find_text(
1455 rEntry
.IsQueryByTextColor() ? aStrFontColor
: aStrBackgroundColor
);
1457 maValueEdArr
[i
]->set_visible(false);
1458 maColorLbArr
[i
]->set_visible(true);
1459 maColorLbArr
[i
]->set_sensitive(true);
1463 SetValString(aQueryStr
, rItem
, aValStr
);
1464 maCondLbArr
[i
]->set_sensitive(true);
1466 maFieldLbArr
[i
]->set_sensitive(true);
1467 maValueEdArr
[i
]->set_sensitive(true);
1468 maRemoveBtnArr
[i
]->set_sensitive(true);
1475 maConnLbArr
[i
+1]->set_sensitive(true);
1477 maConnLbArr
[i
+1]->set_sensitive(false);
1478 size_t nQENext
= nQE
+ 1;
1479 if (maRefreshExceptQuery
.size() < nQENext
+ 1)
1480 maRefreshExceptQuery
.resize(nQENext
+ 1, false);
1481 if (theQueryData
.GetEntry(nQENext
).bDoQuery
|| maRefreshExceptQuery
[nQENext
])
1482 maConnLbArr
[i
+1]->set_active( static_cast<sal_uInt16
>(theQueryData
.GetEntry(nQENext
).eConnect
) );
1484 maConnLbArr
[i
+1]->set_active(-1);
1489 if(theQueryData
.GetEntry( nQE
-1).bDoQuery
)
1490 maConnLbArr
[i
]->set_sensitive(true);
1492 maConnLbArr
[i
]->set_sensitive(false);
1494 if (maRefreshExceptQuery
.size() < nQE
+ 1)
1495 maRefreshExceptQuery
.resize(nQE
+ 1, false);
1496 if(rEntry
.bDoQuery
|| maRefreshExceptQuery
[nQE
])
1497 maConnLbArr
[i
]->set_active( static_cast<sal_uInt16
>(rEntry
.eConnect
) );
1499 maConnLbArr
[i
]->set_active(-1);
1509 maConnLbArr
[i
+1]->set_active(-1);
1510 maConnLbArr
[i
+1]->set_sensitive(false);
1515 if(theQueryData
.GetEntry( nQE
-1).bDoQuery
)
1516 maConnLbArr
[i
]->set_sensitive(true);
1518 maConnLbArr
[i
]->set_sensitive(false);
1519 maConnLbArr
[i
]->set_active(-1);
1521 maFieldLbArr
[i
]->set_sensitive(false);
1522 maCondLbArr
[i
]->set_sensitive(false);
1523 maValueEdArr
[i
]->set_sensitive(false);
1524 maRemoveBtnArr
[i
]->set_sensitive(false);
1526 maFieldLbArr
[i
]->set_active( nFieldSelPos
);
1527 maCondLbArr
[i
]->set_active( nCondPos
);
1528 maValueEdArr
[i
]->set_entry_text( aValStr
);
1529 UpdateValueList(i
+1);
1530 UpdateColorList(i
+1);
1534 void ScFilterDlg::SetValString( const OUString
& rQueryStr
, const ScQueryEntry::Item
& rItem
,
1537 if (rQueryStr
.isEmpty())
1539 pDoc
= pViewData
? &pViewData
->GetDocument() : nullptr;
1540 if (rItem
.meType
== ScQueryEntry::ByValue
)
1543 rValStr
= pDoc
->GetFormatTable()->GetInputLineString(rItem
.mfVal
, 0);
1545 else if (rItem
.meType
== ScQueryEntry::ByDate
)
1549 SvNumberFormatter
* pFormatter
= pDoc
->GetFormatTable();
1550 rValStr
= pFormatter
->GetInputLineString(rItem
.mfVal
,
1551 pFormatter
->GetStandardFormat( SvNumFormatType::DATE
));
1556 SAL_WARN( "sc", "ScFilterDlg::SetValString: empty query string, really?");
1557 rValStr
= rQueryStr
;
1562 // XXX NOTE: if not ByString we just assume this has been
1563 // set to a proper string corresponding to the numeric
1565 rValStr
= rQueryStr
;
1569 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */