fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / ui / dbgui / filtdlg.cxx
blob5ffac4434adfe12c7913fa6ffcad2f5b8c67f0a0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <rangelst.hxx>
21 #include <sfx2/dispatch.hxx>
22 #include <vcl/waitobj.hxx>
24 #include "uiitems.hxx"
25 #include "dbdata.hxx"
26 #include "reffact.hxx"
27 #include "viewdata.hxx"
28 #include "document.hxx"
29 #include "docsh.hxx"
30 #include "scresid.hxx"
31 #include "queryentry.hxx"
33 #include "foptmgr.hxx"
35 #include "globstr.hrc"
36 #include "filter.hrc"
38 #include "filtdlg.hxx"
39 #include <vcl/layout.hxx>
40 #include <svl/sharedstringpool.hxx>
42 #include <limits>
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))
61 , pOptionsMgr(NULL)
62 , nWhichQuery(rArgSet.GetPool()->GetWhich(SID_QUERY))
63 , theQueryData(static_cast<const ScQueryItem&>(rArgSet.Get(nWhichQuery)).GetQueryData())
64 , pOutItem(NULL)
65 , pViewData(NULL)
66 , pDoc(NULL)
67 , nSrcTab(0)
68 , bRefInputMode(false)
69 , pTimer(NULL)
71 get(pLbConnect1,"connect1");
72 get(pLbField1,"field1");
73 get(pLbCond1,"cond1");
74 get(pEdVal1,"val1");
75 get(pLbConnect2,"connect2");
76 get(pLbField2,"field2");
77 get(pLbCond2,"cond2");
78 get(pEdVal2,"val2");
79 get(pLbConnect3,"connect3");
80 get(pLbField3,"field3");
81 get(pLbCond3,"cond3");
82 get(pEdVal3,"val3");
83 get(pLbConnect4,"connect4");
84 get(pLbField4,"field4");
85 get(pLbCond4,"cond4");
86 get(pEdVal4,"val4");
87 get(pScrollBar,"scrollbar");
88 get(pExpander,"more");
89 pExpander->SetExpandedHdl(LINK(this, ScFilterDlg, MoreExpandedHdl));
90 get(pBtnOk,"ok");
91 get(pBtnCancel,"cancel");
92 get(pBtnCase,"case");
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");
106 Init( rArgSet );
108 // Hack: RefInput control
109 pTimer = new Timer;
110 pTimer->SetTimeout( 50 ); // Wait 50ms
111 pTimer->SetTimeoutHdl( LINK( this, ScFilterDlg, TimeOutHdl ) );
113 OUStringBuffer aBuf;
115 OUString sAccName = SC_RESSTR(RID_FILTER_OPERATOR);
116 aBuf.append(sAccName);
117 aBuf.append(" 1");
118 pLbConnect1->SetAccessibleName(aBuf.makeStringAndClear());
119 aBuf.append(sAccName);
120 aBuf.append(" 2");
121 pLbConnect2->SetAccessibleName(aBuf.makeStringAndClear());
123 sAccName = SC_RESSTR(RID_FILTER_FIELDNAME);
124 aBuf.append(sAccName);
125 aBuf.append(" 1");
126 pLbField1->SetAccessibleName(aBuf.makeStringAndClear());
127 aBuf.append(sAccName);
128 aBuf.append(" 2");
129 pLbField2->SetAccessibleName(aBuf.makeStringAndClear());
130 aBuf.append(sAccName);
131 aBuf.append(" 3");
132 pLbField3->SetAccessibleName(aBuf.makeStringAndClear());
134 sAccName = SC_RESSTR(RID_FILTER_CONDITION);
135 aBuf.append(sAccName);
136 aBuf.append(" 1");
137 pLbCond1->SetAccessibleName(aBuf.makeStringAndClear());
138 aBuf.append(sAccName);
139 aBuf.append(" 2");
140 pLbCond2->SetAccessibleName(aBuf.makeStringAndClear());
141 aBuf.append(sAccName);
142 aBuf.append(" 3");
143 pLbCond3->SetAccessibleName(aBuf.makeStringAndClear());
145 sAccName = SC_RESSTR(RID_FILTER_VALUE);
146 aBuf.append(sAccName);
147 aBuf.append(" 1");
148 pEdVal1->SetAccessibleName(aBuf.makeStringAndClear());
149 aBuf.append(sAccName);
150 aBuf.append(" 2");
151 pEdVal2->SetAccessibleName(aBuf.makeStringAndClear());
152 aBuf.append(sAccName);
153 aBuf.append(" 3");
154 pEdVal3->SetAccessibleName(aBuf.makeStringAndClear());
156 pLbCopyArea->SetAccessibleName(ScResId(STR_COPY_AREA_TO));
157 pEdCopyArea->SetAccessibleName(ScResId(STR_COPY_AREA_TO));
161 ScFilterDlg::~ScFilterDlg()
163 disposeOnce();
166 void ScFilterDlg::dispose()
168 delete pOptionsMgr;
169 delete pOutItem;
171 // Hack: RefInput control
172 pTimer->Stop();
173 delete pTimer;
175 pLbConnect1.clear();
176 pLbField1.clear();
177 pLbCond1.clear();
178 pEdVal1.clear();
179 pLbConnect2.clear();
180 pLbField2.clear();
181 pLbCond2.clear();
182 pEdVal2.clear();
183 pLbConnect3.clear();
184 pLbField3.clear();
185 pLbCond3.clear();
186 pEdVal3.clear();
187 pLbConnect4.clear();
188 pLbField4.clear();
189 pLbCond4.clear();
190 pEdVal4.clear();
191 pScrollBar.clear();
192 pExpander.clear();
193 pBtnOk.clear();
194 pBtnCancel.clear();
195 pBtnCase.clear();
196 pBtnRegExp.clear();
197 pBtnHeader.clear();
198 pBtnUnique.clear();
199 pBtnCopyResult.clear();
200 pLbCopyArea.clear();
201 pEdCopyArea.clear();
202 pRbCopyArea.clear();
203 pBtnDestPers.clear();
204 pFtDbAreaLabel.clear();
205 pFtDbArea.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(
261 pViewData,
262 theQueryData,
263 pBtnCase,
264 pBtnRegExp,
265 pBtnHeader,
266 pBtnUnique,
267 pBtnCopyResult,
268 pBtnDestPers,
269 pLbCopyArea,
270 pEdCopyArea,
271 pRbCopyArea,
272 pFtDbAreaLabel,
273 pFtDbArea,
274 aStrUndefined );
275 // Read in field lists and select entries
277 FillFieldLists();
279 for (size_t i = 0; i < QUERY_ENTRY_COUNT; ++i)
281 OUString aValStr;
282 size_t nCondPos = 0;
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())
293 aValStr = aStrEmpty;
294 maCondLbArr[i]->Disable();
296 else if (rEntry.IsQueryByNonEmpty())
298 aValStr = aStrNotEmpty;
299 maCondLbArr[i]->Disable();
301 else
303 OUString aQueryStr = rItem.maString.getString();
304 if (aQueryStr.isEmpty())
306 if (rItem.meType == ScQueryEntry::ByValue)
308 if (pDoc)
310 pDoc->GetFormatTable()->GetInputLineString(rItem.mfVal, 0, aValStr);
313 else if (rItem.meType == ScQueryEntry::ByDate)
315 if (pDoc)
317 SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
318 pFormatter->GetInputLineString(rItem.mfVal,
319 pFormatter->GetStandardFormat( css::util::NumberFormat::DATE), aValStr);
322 else
324 SAL_WARN( "sc", "ScFilterDlg::Init: empty query string, really?");
325 aValStr = aQueryStr;
328 else
330 // XXX NOTE: if not ByString we just assume this has been
331 // set to a proper string corresponding to the numeric
332 // value earlier!
333 aValStr = aQueryStr;
337 else if ( i == 0 )
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 );
361 pLbConnect1->Hide();
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();
382 pLbCond2->Disable();
383 pEdVal2->Disable();
385 else if ( pLbConnect2->GetSelectEntryCount() == 0 )
387 pLbField2->Disable();
388 pLbCond2->Disable();
389 pEdVal2->Disable();
392 if ( pLbField2->GetSelectEntryPos() == 0 )
394 pLbConnect3->Disable();
395 pLbField3->Disable();
396 pLbCond3->Disable();
397 pEdVal3->Disable();
399 else if ( pLbConnect3->GetSelectEntryCount() == 0 )
401 pLbField3->Disable();
402 pLbCond3->Disable();
403 pEdVal3->Disable();
405 if ( pLbField3->GetSelectEntryPos() == 0 )
407 pLbConnect4->Disable();
408 pLbField4->Disable();
409 pLbCond4->Disable();
410 pEdVal4->Disable();
412 else if ( pLbConnect4->GetSelectEntryCount() == 0 )
414 pLbField4->Disable();
415 pLbCond4->Disable();
416 pEdVal4->Disable();
419 if(pDoc!=NULL &&
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()
429 if (pViewData)
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()
451 if ( bRefInputMode )
453 pEdCopyArea->GrabFocus();
454 if ( pEdCopyArea->GetModifyHdl().IsSet() )
455 ((Link<>&)pEdCopyArea->GetModifyHdl()).Call( pEdCopyArea );
457 else
458 GrabFocus();
460 RefInputDone();
463 void ScFilterDlg::FillFieldLists()
465 pLbField1->Clear();
466 pLbField2->Clear();
467 pLbField3->Clear();
468 pLbField4->Clear();
469 pLbField1->InsertEntry( aStrNone, 0 );
470 pLbField2->InsertEntry( aStrNone, 0 );
471 pLbField3->InsertEntry( aStrNone, 0 );
472 pLbField4->InsertEntry( aStrNone, 0 );
474 if ( pDoc )
476 OUString aFieldName;
477 SCTAB nTab = nSrcTab;
478 SCCOL nFirstCol = theQueryData.nCol1;
479 SCROW nFirstRow = theQueryData.nRow1;
480 SCCOL nMaxCol = theQueryData.nCol2;
481 SCCOL col = 0;
482 sal_uInt16 i=1;
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 );
495 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();
511 pValList->Clear();
512 pValList->InsertEntry( aStrNotEmpty, 0 );
513 pValList->InsertEntry( aStrEmpty, 1 );
514 nListPos = 2;
516 if ( nFieldSelPos )
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);
535 if (!r.second)
536 // insertion failed.
537 return;
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;
549 bool bDummy = false;
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));
558 if (it == itEnd)
560 // Not in the list. Insert it.
561 pList->maList.push_back(aHdrColl.front());
562 if (bCaseSens)
563 std::sort(pList->maList.begin(), pList->maList.end(), ScTypedStrData::LessCaseSensitive());
564 else
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);
575 else
576 pList = &maEntryLists[nColumn];
578 OSL_ASSERT(pList);
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);
584 nListPos++;
587 pValList->SetText( aCurValue );
588 pValList->EnableDDAutoWidth(false);
591 UpdateHdrInValueList( nList );
594 void ScFilterDlg::UpdateHdrInValueList( size_t nList )
596 //! GetText / SetText ??
598 if (!pDoc)
599 return;
601 if (nList == 0 || nList > QUERY_ENTRY_COUNT)
602 return;
604 size_t nFieldSelPos = maFieldLbArr[nList-1]->GetSelectEntryPos();
605 if (!nFieldSelPos)
606 return;
608 SCCOL nColumn = theQueryData.nCol1 + static_cast<SCCOL>(nFieldSelPos) - 1;
609 if (!maEntryLists.count(nColumn))
611 OSL_FAIL("Spalte noch nicht initialisiert");
612 return;
615 size_t nPos = maEntryLists[nColumn].mnHeaderPos;
616 if (nPos == INVALID_HEADER_POS)
617 return;
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
630 if (!bWasThere)
631 pValList->InsertEntry(aHdrStr, nListPos);
633 else // Omit entry
635 if (bWasThere)
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];
645 pValList->Clear();
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);
656 else
657 return 0;
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();
680 else
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
697 DELETEZ( pOutItem );
698 pOutItem = new ScQueryItem( nWhichQuery, &theParam );
700 return pOutItem;
703 bool ScFilterDlg::IsRefInputMode() const
705 return bRefInputMode;
708 // Handler:
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;
729 if ( bAreaInputOk )
731 SetDispatcherLock( false );
732 SwitchToDocument();
733 GetBindings().GetDispatcher()->Execute( FID_FILTER_OK,
734 SfxCallMode::SLOT | SfxCallMode::RECORD,
735 GetOutputItem(), 0L, 0L );
736 Close();
739 else if ( pBtn == pBtnCancel )
741 Close();
744 return 0;
747 IMPL_LINK_NOARG(ScFilterDlg, MoreExpandedHdl)
749 if ( pExpander->get_expanded() )
750 pTimer->Start();
751 else
753 pTimer->Stop();
754 bRefInputMode = false;
755 //@BugID 54702 Enable/disable only in Basic class
756 //SFX_APPWINDOW->Disable(FALSE); //! general method in ScAnyRefDlg
758 return 0;
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() )
769 pTimer->Start();
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 )
781 pLbField1->Enable();
782 pLbCond1->Enable();
783 pEdVal1->Enable();
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 )
795 pLbField2->Enable();
796 pLbCond2->Enable();
797 pEdVal2->Enable();
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 )
808 pLbField3->Enable();
809 pLbCond3->Enable();
810 pEdVal3->Enable();
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 )
822 pLbField4->Enable();
823 pLbCond4->Enable();
824 pEdVal4->Enable();
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 );
846 ClearValueList( 1 );
847 ClearValueList( 2 );
848 ClearValueList( 3 );
849 ClearValueList( 4 );
851 pLbConnect2->Disable();
852 pLbConnect3->Disable();
853 pLbConnect4->Disable();
854 pLbField2->Disable();
855 pLbField3->Disable();
856 pLbField4->Disable();
857 pLbCond2->Disable();
858 pLbCond3->Disable();
859 pLbCond4->Disable();
860 pEdVal2->Disable();
861 pEdVal3->Disable();
862 pEdVal4->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;
874 else
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 );
896 ClearValueList( 2 );
897 ClearValueList( 3 );
898 ClearValueList( 4 );
900 pLbConnect3->Disable();
901 pLbConnect4->Disable();
902 pLbField3->Disable();
903 pLbField4->Disable();
904 pLbCond3->Disable();
905 pLbCond4->Disable();
906 pEdVal3->Disable();
907 pEdVal4->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;
921 else
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 );
941 ClearValueList( 3 );
942 ClearValueList( 4 );
944 pLbConnect4->Disable();
945 pLbField4->Disable();
946 pLbCond4->Disable();
947 pEdVal4->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;
961 else
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 )
980 ClearValueList( 4 );
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;
993 else
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();
1017 else
1019 sal_uInt16 nQ=3+nOffset;
1020 theQueryData.GetEntry(nQ).eOp=(ScQueryOp)pLb->GetSelectEntryPos();
1023 return 0;
1026 IMPL_LINK( ScFilterDlg, CheckBoxHdl, CheckBox*, pBox )
1028 // Column headers:
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();
1040 FillFieldLists();
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 );
1061 return 0;
1064 IMPL_LINK( ScFilterDlg, ValModifyHdl, ComboBox*, pEd )
1066 size_t nOffset = GetSliderPos();
1067 size_t i = 0;
1068 size_t nQE = i + nOffset;
1069 if ( pEd )
1071 OUString aStrVal = pEd->GetText();
1072 ListBox* pLbCond = pLbCond1;
1073 ListBox* pLbField = pLbField1;
1074 if ( pEd == pEdVal2 )
1076 pLbCond = pLbCond2;
1077 pLbField = pLbField2;
1078 i=1;
1079 nQE=i+nOffset;
1081 if ( pEd == pEdVal3 )
1083 pLbCond = pLbCond3;
1084 pLbField = pLbField3;
1085 i=2;
1086 nQE=i+nOffset;
1088 if ( pEd == pEdVal4 )
1090 pLbCond = pLbCond4;
1091 pLbField = pLbField4;
1092 i=3;
1093 nQE=i+nOffset;
1096 if ( aStrEmpty.equals(aStrVal) || aStrNotEmpty.equals(aStrVal) )
1098 pLbCond->SelectEntry(OUString('='));
1099 pLbCond->Disable();
1101 else
1102 pLbCond->Enable();
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();
1127 else
1129 rItem.maString = pDoc->GetSharedStringPool().intern(aStrVal);
1130 rItem.mfVal = 0.0;
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();
1143 rEntry.eOp = eOp;
1144 if (maHasDates[nQE] && !bByEmptyOrNotByEmpty)
1145 rItem.meType = ScQueryEntry::ByDate;
1148 return 0;
1151 IMPL_LINK_NOARG(ScFilterDlg, ScrollHdl)
1153 SliderMoved();
1154 return 0;
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 )
1170 if (nOffset==0)
1171 maConnLbArr[0]->Hide();
1172 else
1173 maConnLbArr[0]->Show();
1175 for (size_t i = 0; i < QUERY_ENTRY_COUNT; ++i)
1177 OUString aValStr;
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);
1189 if(rEntry.bDoQuery)
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();
1204 else
1206 aValStr = aQueryStr;
1207 maCondLbArr[i]->Enable();
1209 maFieldLbArr[i]->Enable();
1210 maValueEdArr[i]->Enable();
1212 if (nOffset==0)
1214 if (i<3)
1216 if(rEntry.bDoQuery)
1217 maConnLbArr[i+1]->Enable();
1218 else
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 );
1225 else
1226 maConnLbArr[i+1]->SetNoSelection();
1229 else
1231 if(theQueryData.GetEntry( nQE-1).bDoQuery)
1232 maConnLbArr[i]->Enable();
1233 else
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 );
1240 else
1241 maConnLbArr[i]->SetNoSelection();
1245 else
1247 if (nOffset==0)
1249 if(i<3)
1251 maConnLbArr[i+1]->SetNoSelection();
1252 maConnLbArr[i+1]->Disable();
1255 else
1257 if(theQueryData.GetEntry( nQE-1).bDoQuery)
1258 maConnLbArr[i]->Enable();
1259 else
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: */