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 <vcl/waitobj.hxx>
24 #include "viewdata.hxx"
25 #include "document.hxx"
26 #include "uiitems.hxx"
28 #include "globalnames.hxx"
30 #include "scresid.hxx"
31 #include "queryentry.hxx"
32 #include "typedstrdata.hxx"
36 #include "globstr.hrc"
38 #include "pfiltdlg.hxx"
39 #include <svl/zforlist.hxx>
40 #include <svl/sharedstringpool.hxx>
42 ScPivotFilterDlg::ScPivotFilterDlg(vcl::Window
* pParent
, const SfxItemSet
& rArgSet
,
44 : ModalDialog(pParent
, "PivotFilterDialog",
45 "modules/scalc/ui/pivotfilterdialog.ui" )
48 aStrNone ( SC_RESSTR(SCSTR_NONE
) ),
49 aStrEmpty ( SC_RESSTR(SCSTR_FILTER_EMPTY
) ),
50 aStrNotEmpty ( SC_RESSTR(SCSTR_FILTER_NOTEMPTY
) ),
51 aStrColumn ( SC_RESSTR(SCSTR_COLUMN
) ),
53 nWhichQuery ( rArgSet
.GetPool()->GetWhich( SID_QUERY
) ),
54 theQueryData ( static_cast<const ScQueryItem
&>(
55 rArgSet
.Get( nWhichQuery
)).GetQueryData() ),
59 nSrcTab ( nSourceTab
), // ist nicht im QueryParam
62 get(m_pLbField1
, "field1");
63 get(m_pLbCond1
, "cond1");
64 get(m_pEdVal1
, "val1");
65 get(m_pLbConnect1
, "connect1");
66 get(m_pLbField2
, "field2");
67 get(m_pLbCond2
, "cond2");
68 get(m_pEdVal2
, "val2");
69 get(m_pLbConnect2
, "connect2");
70 get(m_pLbField3
, "field3");
71 get(m_pLbCond3
, "cond3");
72 get(m_pEdVal3
, "val3");
73 get(m_pBtnCase
, "case");
74 get(m_pBtnRegExp
, "regexp");
75 get(m_pBtnUnique
, "unique");
76 get(m_pFtDbArea
, "dbarea");
78 for (sal_uInt16 i
=0; i
<=MAXCOL
; i
++)
79 pEntryLists
[i
] = NULL
;
84 ScPivotFilterDlg::~ScPivotFilterDlg()
89 void ScPivotFilterDlg::dispose()
91 for (sal_uInt16 i
=0; i
<=MAXCOL
; i
++)
92 delete pEntryLists
[i
];
98 m_pLbConnect1
.clear();
102 m_pLbConnect2
.clear();
107 m_pBtnRegExp
.clear();
108 m_pBtnUnique
.clear();
110 for (auto a
: aValueEdArr
) a
.clear();
111 for (auto a
: aFieldLbArr
) a
.clear();
112 for (auto a
: aCondLbArr
) a
.clear();
113 ModalDialog::dispose();
116 void ScPivotFilterDlg::Init( const SfxItemSet
& rArgSet
)
118 const ScQueryItem
& rQueryItem
= static_cast<const ScQueryItem
&>(
119 rArgSet
.Get( nWhichQuery
));
121 m_pBtnCase
->SetClickHdl ( LINK( this, ScPivotFilterDlg
, CheckBoxHdl
) );
123 m_pLbField1
->SetSelectHdl ( LINK( this, ScPivotFilterDlg
, LbSelectHdl
) );
124 m_pLbField2
->SetSelectHdl ( LINK( this, ScPivotFilterDlg
, LbSelectHdl
) );
125 m_pLbField3
->SetSelectHdl ( LINK( this, ScPivotFilterDlg
, LbSelectHdl
) );
126 m_pLbConnect1
->SetSelectHdl( LINK( this, ScPivotFilterDlg
, LbSelectHdl
) );
127 m_pLbConnect2
->SetSelectHdl( LINK( this, ScPivotFilterDlg
, LbSelectHdl
) );
129 m_pBtnCase
->Check( theQueryData
.bCaseSens
);
130 m_pBtnRegExp
->Check( theQueryData
.bRegExp
);
131 m_pBtnUnique
->Check( !theQueryData
.bDuplicate
);
133 pViewData
= rQueryItem
.GetViewData();
134 pDoc
= pViewData
? pViewData
->GetDocument() : NULL
;
136 // fuer leichteren Zugriff:
137 aFieldLbArr
[0] = m_pLbField1
;
138 aFieldLbArr
[1] = m_pLbField2
;
139 aFieldLbArr
[2] = m_pLbField3
;
140 aValueEdArr
[0] = m_pEdVal1
;
141 aValueEdArr
[1] = m_pEdVal2
;
142 aValueEdArr
[2] = m_pEdVal3
;
143 aCondLbArr
[0] = m_pLbCond1
;
144 aCondLbArr
[1] = m_pLbCond2
;
145 aCondLbArr
[2] = m_pLbCond3
;
147 if ( pViewData
&& pDoc
)
149 ScRange
theCurArea ( ScAddress( theQueryData
.nCol1
,
152 ScAddress( theQueryData
.nCol2
,
155 ScDBCollection
* pDBColl
= pDoc
->GetDBCollection();
156 OUString theDbName
= OUString(STR_DB_LOCAL_NONAME
);
159 * Ueberpruefen, ob es sich bei dem uebergebenen
160 * Bereich um einen Datenbankbereich handelt:
165 ScAddress
& rStart
= theCurArea
.aStart
;
166 ScAddress
& rEnd
= theCurArea
.aEnd
;
167 ScDBData
* pDBData
= pDBColl
->GetDBAtArea( rStart
.Tab(),
168 rStart
.Col(), rStart
.Row(),
169 rEnd
.Col(), rEnd
.Row() );
171 theDbName
= pDBData
->GetName();
175 aBuf
.appendAscii(" (");
176 aBuf
.append(theDbName
);
178 m_pFtDbArea
->SetText(aBuf
.makeStringAndClear());
182 m_pFtDbArea
->SetText( EMPTY_OUSTRING
);
185 // Feldlisten einlesen und Eintraege selektieren:
189 for ( SCSIZE i
=0; i
<3; i
++ )
191 if ( theQueryData
.GetEntry(i
).bDoQuery
)
193 const ScQueryEntry
& rEntry
= theQueryData
.GetEntry(i
);
194 const ScQueryEntry::Item
& rItem
= rEntry
.GetQueryItem();
195 OUString aValStr
= rItem
.maString
.getString();
196 if (rEntry
.IsQueryByEmpty())
198 else if (rEntry
.IsQueryByNonEmpty())
199 aValStr
= aStrNotEmpty
;
200 sal_uInt16 nCondPos
= (sal_uInt16
)rEntry
.eOp
;
201 sal_uInt16 nFieldSelPos
= GetFieldSelPos( static_cast<SCCOL
>(rEntry
.nField
) );
203 aFieldLbArr
[i
]->SelectEntryPos( nFieldSelPos
);
204 aCondLbArr
[i
]->SelectEntryPos( nCondPos
);
205 UpdateValueList( static_cast<sal_uInt16
>(i
+1) );
206 aValueEdArr
[i
]->SetText( aValStr
);
207 if (aValStr
.equals(aStrEmpty
) || aValStr
.equals(aStrNotEmpty
))
208 aCondLbArr
[i
]->Disable();
212 aFieldLbArr
[i
]->SelectEntryPos( 0 ); // "keiner" selektieren
213 aCondLbArr
[i
]->SelectEntryPos( 0 ); // "=" selektieren
214 UpdateValueList( static_cast<sal_uInt16
>(i
) );
215 aValueEdArr
[i
]->SetText( EMPTY_OUSTRING
);
217 aValueEdArr
[i
]->SetModifyHdl( LINK( this, ScPivotFilterDlg
, ValModifyHdl
) );
220 // Disable/Enable Logik:
222 (m_pLbField1
->GetSelectEntryPos() != 0)
223 && (m_pLbField2
->GetSelectEntryPos() != 0)
224 ? m_pLbConnect1
->SelectEntryPos( (sal_uInt16
)theQueryData
.GetEntry(1).eConnect
)
225 : m_pLbConnect1
->SetNoSelection();
227 (m_pLbField2
->GetSelectEntryPos() != 0)
228 && (m_pLbField3
->GetSelectEntryPos() != 0)
229 ? m_pLbConnect2
->SelectEntryPos( (sal_uInt16
)theQueryData
.GetEntry(2).eConnect
)
230 : m_pLbConnect2
->SetNoSelection();
232 if ( m_pLbField1
->GetSelectEntryPos() == 0 )
234 m_pLbConnect1
->Disable();
235 m_pLbField2
->Disable();
236 m_pLbCond2
->Disable();
237 m_pEdVal2
->Disable();
239 else if ( m_pLbConnect1
->GetSelectEntryCount() == 0 )
241 m_pLbField2
->Disable();
242 m_pLbCond2
->Disable();
243 m_pEdVal2
->Disable();
246 if ( m_pLbField2
->GetSelectEntryPos() == 0 )
248 m_pLbConnect2
->Disable();
249 m_pLbField3
->Disable();
250 m_pLbCond3
->Disable();
251 m_pEdVal3
->Disable();
253 else if ( m_pLbConnect2
->GetSelectEntryCount() == 0 )
255 m_pLbField3
->Disable();
256 m_pLbCond3
->Disable();
257 m_pEdVal3
->Disable();
261 void ScPivotFilterDlg::FillFieldLists()
263 m_pLbField1
->Clear();
264 m_pLbField2
->Clear();
265 m_pLbField3
->Clear();
266 m_pLbField1
->InsertEntry( aStrNone
, 0 );
267 m_pLbField2
->InsertEntry( aStrNone
, 0 );
268 m_pLbField3
->InsertEntry( aStrNone
, 0 );
273 SCTAB nTab
= nSrcTab
;
274 SCCOL nFirstCol
= theQueryData
.nCol1
;
275 SCROW nFirstRow
= theQueryData
.nRow1
;
276 SCCOL nMaxCol
= theQueryData
.nCol2
;
280 for ( col
=nFirstCol
; col
<=nMaxCol
; col
++ )
282 aFieldName
= pDoc
->GetString(col
, nFirstRow
, nTab
);
283 if ( aFieldName
.isEmpty() )
285 aFieldName
= ScGlobal::ReplaceOrAppend( aStrColumn
, "%1", ScColToAlpha( col
));
287 m_pLbField1
->InsertEntry( aFieldName
, i
);
288 m_pLbField2
->InsertEntry( aFieldName
, i
);
289 m_pLbField3
->InsertEntry( aFieldName
, i
);
296 void ScPivotFilterDlg::UpdateValueList( sal_uInt16 nList
)
298 if ( pDoc
&& nList
>0 && nList
<=3 )
300 ComboBox
* pValList
= aValueEdArr
[nList
-1];
301 sal_Int32 nFieldSelPos
= aFieldLbArr
[nList
-1]->GetSelectEntryPos();
302 sal_Int32 nListPos
= 0;
303 OUString aCurValue
= pValList
->GetText();
306 pValList
->InsertEntry( aStrNotEmpty
, 0 );
307 pValList
->InsertEntry( aStrEmpty
, 1 );
310 if ( pDoc
&& nFieldSelPos
)
312 SCCOL nColumn
= theQueryData
.nCol1
+ static_cast<SCCOL
>(nFieldSelPos
) - 1;
313 if (!pEntryLists
[nColumn
])
315 WaitObject
aWaiter( this );
317 SCTAB nTab
= nSrcTab
;
318 SCROW nFirstRow
= theQueryData
.nRow1
;
319 SCROW nLastRow
= theQueryData
.nRow2
;
321 bool bHasDates
= false;
322 bool bCaseSens
= m_pBtnCase
->IsChecked();
323 pEntryLists
[nColumn
] = new std::vector
<ScTypedStrData
>;
324 pDoc
->GetFilterEntriesArea(
325 nColumn
, nFirstRow
, nLastRow
, nTab
, bCaseSens
, *pEntryLists
[nColumn
], bHasDates
);
328 std::vector
<ScTypedStrData
>* pColl
= pEntryLists
[nColumn
];
329 std::vector
<ScTypedStrData
>::const_iterator it
= pColl
->begin(), itEnd
= pColl
->end();
330 for (; it
!= itEnd
; ++it
)
332 pValList
->InsertEntry(it
->GetString(), nListPos
);
336 pValList
->SetText( aCurValue
);
340 void ScPivotFilterDlg::ClearValueList( sal_uInt16 nList
)
342 if ( nList
>0 && nList
<=3 )
344 ComboBox
* pValList
= aValueEdArr
[nList
-1];
346 pValList
->InsertEntry( aStrNotEmpty
, 0 );
347 pValList
->InsertEntry( aStrEmpty
, 1 );
348 pValList
->SetText( EMPTY_OUSTRING
);
352 sal_uInt16
ScPivotFilterDlg::GetFieldSelPos( SCCOL nField
)
354 if ( nField
>= theQueryData
.nCol1
&& nField
<= theQueryData
.nCol2
)
355 return static_cast<sal_uInt16
>(nField
- theQueryData
.nCol1
+ 1);
360 const ScQueryItem
& ScPivotFilterDlg::GetOutputItem()
362 ScQueryParam
theParam( theQueryData
);
363 sal_Int32 nConnect1
= m_pLbConnect1
->GetSelectEntryPos();
364 sal_Int32 nConnect2
= m_pLbConnect2
->GetSelectEntryPos();
366 svl::SharedStringPool
& rPool
= pViewData
->GetDocument()->GetSharedStringPool();
368 for ( SCSIZE i
=0; i
<3; i
++ )
370 sal_uInt16 nField
= aFieldLbArr
[i
]->GetSelectEntryPos();
371 ScQueryOp eOp
= (ScQueryOp
)aCondLbArr
[i
]->GetSelectEntryPos();
373 bool bDoThis
= (aFieldLbArr
[i
]->GetSelectEntryPos() != 0);
374 theParam
.GetEntry(i
).bDoQuery
= bDoThis
;
378 ScQueryEntry
& rEntry
= theParam
.GetEntry(i
);
379 ScQueryEntry::Item
& rItem
= rEntry
.GetQueryItem();
381 OUString aStrVal
= aValueEdArr
[i
]->GetText();
384 * Dialog liefert die ausgezeichneten Feldwerte "leer"/"nicht leer"
385 * als Konstanten in nVal in Verbindung mit dem Schalter
386 * bQueryByString auf FALSE.
388 if ( aStrVal
.equals(aStrEmpty
) )
390 OSL_ASSERT(eOp
== SC_EQUAL
);
391 rEntry
.SetQueryByEmpty();
393 else if ( aStrVal
.equals(aStrNotEmpty
) )
395 OSL_ASSERT(eOp
== SC_EQUAL
);
396 rEntry
.SetQueryByNonEmpty();
400 rItem
.maString
= rPool
.intern(aStrVal
);
402 rItem
.meType
= ScQueryEntry::ByString
;
405 rEntry
.nField
= nField
? (theQueryData
.nCol1
+
406 static_cast<SCCOL
>(nField
) - 1) : static_cast<SCCOL
>(0);
411 theParam
.GetEntry(1).eConnect
= (nConnect1
!= LISTBOX_ENTRY_NOTFOUND
)
412 ? (ScQueryConnect
)nConnect1
414 theParam
.GetEntry(2).eConnect
= (nConnect2
!= LISTBOX_ENTRY_NOTFOUND
)
415 ? (ScQueryConnect
)nConnect2
418 theParam
.bInplace
= false;
419 theParam
.nDestTab
= 0; // Woher kommen diese Werte?
420 theParam
.nDestCol
= 0;
421 theParam
.nDestRow
= 0;
423 theParam
.bDuplicate
= !m_pBtnUnique
->IsChecked();
424 theParam
.bCaseSens
= m_pBtnCase
->IsChecked();
425 theParam
.bRegExp
= m_pBtnRegExp
->IsChecked();
427 if ( pOutItem
) DELETEZ( pOutItem
);
428 pOutItem
= new ScQueryItem( nWhichQuery
, &theParam
);
435 IMPL_LINK( ScPivotFilterDlg
, LbSelectHdl
, ListBox
*, pLb
)
438 * Behandlung der Enable/Disable-Logik,
439 * abhaengig davon, welche ListBox angefasst wurde:
442 if (pLb
== m_pLbConnect1
)
444 if ( !m_pLbField2
->IsEnabled() )
446 m_pLbField2
->Enable();
447 m_pLbCond2
->Enable();
451 else if (pLb
== m_pLbConnect2
)
453 if ( !m_pLbField3
->IsEnabled() )
455 m_pLbField3
->Enable();
456 m_pLbCond3
->Enable();
460 else if (pLb
== m_pLbField1
)
462 if ( m_pLbField1
->GetSelectEntryPos() == 0 )
464 m_pLbConnect1
->SetNoSelection();
465 m_pLbConnect2
->SetNoSelection();
466 m_pLbField2
->SelectEntryPos( 0 );
467 m_pLbField3
->SelectEntryPos( 0 );
468 m_pLbCond2
->SelectEntryPos( 0 );
469 m_pLbCond3
->SelectEntryPos( 0 );
474 m_pLbConnect1
->Disable();
475 m_pLbConnect2
->Disable();
476 m_pLbField2
->Disable();
477 m_pLbField3
->Disable();
478 m_pLbCond2
->Disable();
479 m_pLbCond3
->Disable();
480 m_pEdVal2
->Disable();
481 m_pEdVal3
->Disable();
485 UpdateValueList( 1 );
486 if ( !m_pLbConnect1
->IsEnabled() )
488 m_pLbConnect1
->Enable();
492 else if (pLb
== m_pLbField2
)
494 if ( m_pLbField2
->GetSelectEntryPos() == 0 )
496 m_pLbConnect2
->SetNoSelection();
497 m_pLbField3
->SelectEntryPos( 0 );
498 m_pLbCond3
->SelectEntryPos( 0 );
502 m_pLbConnect2
->Disable();
503 m_pLbField3
->Disable();
504 m_pLbCond3
->Disable();
505 m_pEdVal3
->Disable();
509 UpdateValueList( 2 );
510 if ( !m_pLbConnect2
->IsEnabled() )
512 m_pLbConnect2
->Enable();
516 else if (pLb
== m_pLbField3
)
518 ( m_pLbField3
->GetSelectEntryPos() == 0 )
519 ? ClearValueList( 3 )
520 : UpdateValueList( 3 );
526 IMPL_LINK( ScPivotFilterDlg
, CheckBoxHdl
, CheckBox
*, pBox
)
528 // bei Gross-/Kleinschreibung die Werte-Listen aktualisieren
530 if (pBox
== m_pBtnCase
) // Wertlisten
532 for (sal_uInt16 i
=0; i
<=MAXCOL
; i
++)
533 DELETEZ( pEntryLists
[i
] );
535 OUString aCurVal1
= m_pEdVal1
->GetText();
536 OUString aCurVal2
= m_pEdVal2
->GetText();
537 OUString aCurVal3
= m_pEdVal3
->GetText();
538 UpdateValueList( 1 );
539 UpdateValueList( 2 );
540 UpdateValueList( 3 );
541 m_pEdVal1
->SetText( aCurVal1
);
542 m_pEdVal2
->SetText( aCurVal2
);
543 m_pEdVal3
->SetText( aCurVal3
);
549 IMPL_LINK( ScPivotFilterDlg
, ValModifyHdl
, ComboBox
*, pEd
)
553 OUString aStrVal
= pEd
->GetText();
554 ListBox
* pLb
= m_pLbCond1
;
556 if ( pEd
== m_pEdVal2
) pLb
= m_pLbCond2
;
557 else if ( pEd
== m_pEdVal3
) pLb
= m_pLbCond3
;
559 // wenn einer der Sonderwerte leer/nicht-leer
560 // gewaehlt wird, so macht nur der =-Operator Sinn:
562 if ( aStrEmpty
.equals(aStrVal
) || aStrNotEmpty
.equals(aStrVal
) )
564 pLb
->SelectEntry(OUString('='));
574 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */