xref: /core/dbaccess/source/ui/dlg/queryfilter.cxx (revision d52a4dba)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <queryfilter.hxx>
21 #include <com/sun/star/sdbc/DataType.hpp>
22 #include <com/sun/star/util/Date.hpp>
23 #include <com/sun/star/sdbc/ColumnSearch.hpp>
24 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
25 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
26 #include <com/sun/star/sdbc/XConnection.hpp>
27 #include <comphelper/string.hxx>
28 #include <comphelper/diagnose_ex.hxx>
29 #include <osl/diagnose.h>
30 #include <connectivity/dbtools.hxx>
31 #include <strings.hxx>
32 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
33 
34 using namespace dbaui;
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::container;
37 using namespace ::com::sun::star::sdb;
38 using namespace ::com::sun::star::sdbc;
39 using namespace ::com::sun::star::sdbcx;
40 using namespace ::com::sun::star::beans;
41 
Replace_OS_PlaceHolder(OUString & aString)42 static void Replace_OS_PlaceHolder(OUString& aString)
43 {
44     aString = aString.replaceAll( "*", "%" );
45     aString = aString.replaceAll( "?", "_" );
46 }
47 
Replace_SQL_PlaceHolder(OUString & aString)48 static void Replace_SQL_PlaceHolder(OUString& aString)
49 {
50     aString = aString.replaceAll( "%", "*" );
51     aString = aString.replaceAll( "_", "?" );
52 }
53 
DlgFilterCrit(weld::Window * pParent,const Reference<XComponentContext> & rxContext,const Reference<XConnection> & _rxConnection,const Reference<XSingleSelectQueryComposer> & _rxComposer,const Reference<XNameAccess> & _rxCols)54 DlgFilterCrit::DlgFilterCrit(weld::Window * pParent,
55                              const Reference< XComponentContext >& rxContext,
56                              const Reference< XConnection>& _rxConnection,
57                              const Reference< XSingleSelectQueryComposer >& _rxComposer,
58                              const Reference< XNameAccess>& _rxCols)
59     : GenericDialogController(pParent, u"dbaccess/ui/queryfilterdialog.ui"_ustr, u"QueryFilterDialog"_ustr)
60     , m_xQueryComposer(_rxComposer)
61     , m_xColumns( _rxCols )
62     , m_xConnection( _rxConnection )
63     , m_xMetaData( _rxConnection->getMetaData() )
64     , m_aPredicateInput( rxContext, _rxConnection, getParseContext() )
65     , m_xLB_WHEREFIELD1(m_xBuilder->weld_combo_box(u"field1"_ustr))
66     , m_xLB_WHERECOMP1(m_xBuilder->weld_combo_box(u"cond1"_ustr))
67     , m_xET_WHEREVALUE1(m_xBuilder->weld_entry(u"value1"_ustr))
68     , m_xLB_WHERECOND2(m_xBuilder->weld_combo_box(u"op2"_ustr))
69     , m_xLB_WHEREFIELD2(m_xBuilder->weld_combo_box(u"field2"_ustr))
70     , m_xLB_WHERECOMP2(m_xBuilder->weld_combo_box(u"cond2"_ustr))
71     , m_xET_WHEREVALUE2(m_xBuilder->weld_entry(u"value2"_ustr))
72     , m_xLB_WHERECOND3(m_xBuilder->weld_combo_box(u"op3"_ustr))
73     , m_xLB_WHEREFIELD3(m_xBuilder->weld_combo_box(u"field3"_ustr))
74     , m_xLB_WHERECOMP3(m_xBuilder->weld_combo_box(u"cond3"_ustr))
75     , m_xET_WHEREVALUE3(m_xBuilder->weld_entry(u"value3"_ustr))
76 {
77     //set all condition preferred width to max width
78     //if all entries exist
79     Size aSize(m_xLB_WHERECOMP1->get_preferred_size());
80     m_xLB_WHERECOMP1->set_size_request(aSize.Width(), -1);
81     m_xLB_WHERECOMP2->set_size_request(aSize.Width(), -1);
82     m_xLB_WHERECOMP3->set_size_request(aSize.Width(), -1);
83     const sal_Int32 nEntryCount =  m_xLB_WHERECOMP1->get_count();
84     m_aSTR_COMPARE_OPERATORS.resize(nEntryCount);
85     for (sal_Int32 i = 0; i < nEntryCount; ++i)
86     {
87         m_aSTR_COMPARE_OPERATORS[i] = m_xLB_WHERECOMP1->get_text(i);
88     }
89     m_xLB_WHERECOMP1->clear();
90 
91     // ... also write it into the remaining fields
92     Reference<XPropertySet> xColumn;
93     for (auto& colName : m_xColumns->getElementNames())
94     {
95         try
96         {
97             xColumn.set(m_xColumns->getByName(colName), UNO_QUERY_THROW);
98 
99             sal_Int32 nDataType( 0 );
100             OSL_VERIFY( xColumn->getPropertyValue( PROPERTY_TYPE ) >>= nDataType );
101             sal_Int32 eColumnSearch = ::dbtools::getSearchColumnFlag( m_xConnection, nDataType );
102             if ( eColumnSearch == ColumnSearch::NONE )
103                 continue;
104 
105             bool bIsSearchable( true );
106             OSL_VERIFY( xColumn->getPropertyValue( PROPERTY_ISSEARCHABLE ) >>= bIsSearchable );
107             if ( !bIsSearchable )
108                 continue;
109         }
110         catch( const Exception& )
111         {
112             DBG_UNHANDLED_EXCEPTION("dbaccess");
113         }
114         m_xLB_WHEREFIELD1->append_text(colName);
115         m_xLB_WHEREFIELD2->append_text(colName);
116         m_xLB_WHEREFIELD3->append_text(colName);
117     }
118 
119     Reference<XNameAccess> xSelectColumns = Reference<XColumnsSupplier>(m_xQueryComposer,UNO_QUERY_THROW)->getColumns();
120     for (auto& colName : xSelectColumns->getElementNames())
121     {
122         // don't insert a column name twice
123         if (!m_xColumns->hasByName(colName))
124         {
125             xColumn.set(xSelectColumns->getByName(colName), UNO_QUERY);
126             OSL_ENSURE(xColumn.is(),"DlgFilterCrit::DlgFilterCrit: Column is null!");
127             sal_Int32 nDataType(0);
128             xColumn->getPropertyValue(PROPERTY_TYPE) >>= nDataType;
129             sal_Int32 eColumnSearch = dbtools::getSearchColumnFlag(m_xConnection,nDataType);
130             // TODO
131             // !pColumn->IsFunction()
132             if(eColumnSearch != ColumnSearch::NONE)
133             {
134                 m_xLB_WHEREFIELD1->append_text(colName);
135                 m_xLB_WHEREFIELD2->append_text(colName);
136                 m_xLB_WHEREFIELD3->append_text(colName);
137             }
138         }
139     }
140     // initialize the listboxes with noEntry
141     m_xLB_WHEREFIELD1->set_active(0);
142     m_xLB_WHEREFIELD2->set_active(0);
143     m_xLB_WHEREFIELD3->set_active(0);
144 
145     // insert the criteria into the dialog
146     Sequence<Sequence<PropertyValue > > aValues = m_xQueryComposer->getStructuredFilter();
147     int i(0);
148     fillLines(i, aValues);
149     aValues = m_xQueryComposer->getStructuredHavingClause();
150     fillLines(i, aValues);
151 
152     EnableLines();
153 
154     m_xLB_WHEREFIELD1->connect_changed(LINK(this,DlgFilterCrit,ListSelectHdl));
155     m_xLB_WHEREFIELD2->connect_changed(LINK(this,DlgFilterCrit,ListSelectHdl));
156     m_xLB_WHEREFIELD3->connect_changed(LINK(this,DlgFilterCrit,ListSelectHdl));
157 
158     m_xLB_WHERECOMP1->connect_changed(LINK(this,DlgFilterCrit,ListSelectCompHdl));
159     m_xLB_WHERECOMP2->connect_changed(LINK(this,DlgFilterCrit,ListSelectCompHdl));
160     m_xLB_WHERECOMP3->connect_changed(LINK(this,DlgFilterCrit,ListSelectCompHdl));
161 
162     m_xET_WHEREVALUE1->connect_focus_out( LINK( this, DlgFilterCrit, PredicateLoseFocus ) );
163     m_xET_WHEREVALUE2->connect_focus_out( LINK( this, DlgFilterCrit, PredicateLoseFocus ) );
164     m_xET_WHEREVALUE3->connect_focus_out( LINK( this, DlgFilterCrit, PredicateLoseFocus ) );
165 
166     if (m_xET_WHEREVALUE1->get_sensitive())
167         m_xET_WHEREVALUE1->grab_focus();
168 }
169 
~DlgFilterCrit()170 DlgFilterCrit::~DlgFilterCrit()
171 {
172 }
173 
GetOSQLPredicateType(std::u16string_view _rSelectedPredicate) const174 sal_Int32 DlgFilterCrit::GetOSQLPredicateType( std::u16string_view _rSelectedPredicate ) const
175 {
176     sal_Int32 nPredicateIndex = -1;
177     for ( size_t i=0; i < m_aSTR_COMPARE_OPERATORS.size(); ++i)
178         if ( m_aSTR_COMPARE_OPERATORS[i] == _rSelectedPredicate )
179         {
180             nPredicateIndex = i;
181             break;
182         }
183 
184     sal_Int32 nPredicateType = SQLFilterOperator::NOT_SQLNULL;
185     switch ( nPredicateIndex )
186     {
187     case 0:
188         nPredicateType = SQLFilterOperator::EQUAL;
189         break;
190     case 1:
191         nPredicateType = SQLFilterOperator::NOT_EQUAL;
192         break;
193     case 2:
194         nPredicateType = SQLFilterOperator::LESS;
195         break;
196     case 3:
197         nPredicateType = SQLFilterOperator::LESS_EQUAL;
198         break;
199     case 4:
200         nPredicateType = SQLFilterOperator::GREATER;
201         break;
202     case 5:
203         nPredicateType = SQLFilterOperator::GREATER_EQUAL;
204         break;
205     case 6:
206         nPredicateType = SQLFilterOperator::LIKE;
207         break;
208     case 7:
209         nPredicateType = SQLFilterOperator::NOT_LIKE;
210         break;
211     case 8:
212         nPredicateType = SQLFilterOperator::SQLNULL;
213         break;
214     case 9:
215         nPredicateType = SQLFilterOperator::NOT_SQLNULL;
216         break;
217     default:
218         OSL_FAIL( "DlgFilterCrit::GetOSQLPredicateType: unknown predicate string!" );
219         break;
220     }
221 
222     return nPredicateType;
223 }
224 
GetSelectionPos(sal_Int32 eType,const weld::ComboBox & rListBox)225 sal_Int32 DlgFilterCrit::GetSelectionPos(sal_Int32 eType, const weld::ComboBox& rListBox)
226 {
227     sal_Int32 nPos;
228     switch(eType)
229     {
230         case SQLFilterOperator::EQUAL:
231             nPos = 0;
232             break;
233         case SQLFilterOperator::NOT_EQUAL:
234             nPos = 1;
235             break;
236         case SQLFilterOperator::LESS:
237             nPos = 2;
238             break;
239         case SQLFilterOperator::LESS_EQUAL:
240             nPos = 3;
241             break;
242         case SQLFilterOperator::GREATER:
243             nPos = 4;
244             break;
245         case SQLFilterOperator::GREATER_EQUAL:
246             nPos = 5;
247             break;
248         case SQLFilterOperator::NOT_LIKE:
249             nPos = rListBox.get_count() > 2 ? rListBox.get_count()-3 : 0;
250             break;
251         case SQLFilterOperator::LIKE:
252             nPos = rListBox.get_count() > 2 ? rListBox.get_count()-4 : 1;
253             break;
254         case SQLFilterOperator::SQLNULL:
255             nPos = rListBox.get_count()-2;
256             break;
257         case SQLFilterOperator::NOT_SQLNULL:
258             nPos = rListBox.get_count()-1;
259             break;
260         default:
261             //  TODO  What value should this be?
262             nPos = 0;
263             break;
264     }
265     return nPos;
266 }
267 
getCondition(const weld::ComboBox & _rField,const weld::ComboBox & _rComp,const weld::Entry & _rValue,PropertyValue & _rFilter) const268 bool DlgFilterCrit::getCondition(const weld::ComboBox& _rField,const weld::ComboBox& _rComp,const weld::Entry& _rValue,PropertyValue& _rFilter) const
269 {
270     bool bHaving = false;
271     try
272     {
273         _rFilter.Name = _rField.get_active_text();
274         Reference< XPropertySet > xColumn = getQueryColumn(_rFilter.Name);
275         if ( xColumn.is() )
276         {
277             bool bFunction = false;
278             OUString sTableName;
279             Reference< XPropertySetInfo > xInfo = xColumn->getPropertySetInfo();
280             if ( xInfo->hasPropertyByName(PROPERTY_REALNAME) )
281             {
282                 if ( xInfo->hasPropertyByName(PROPERTY_TABLENAME) )
283                 {
284                     xColumn->getPropertyValue(PROPERTY_TABLENAME)   >>= sTableName;
285                     if ( !sTableName.isEmpty() )
286                     {
287                         // properly quote all parts of the table name, so
288                         // e.g. <schema>.<table> becomes "<schema>"."<table>"
289                         OUString aCatalog,aSchema,aTable;
290                         ::dbtools::qualifiedNameComponents( m_xMetaData, sTableName, aCatalog, aSchema, aTable, ::dbtools::EComposeRule::InDataManipulation );
291                         sTableName = ::dbtools::composeTableName( m_xMetaData, aCatalog, aSchema, aTable, true, ::dbtools::EComposeRule::InDataManipulation );
292                     }
293                 }
294                 xColumn->getPropertyValue(PROPERTY_REALNAME)    >>= _rFilter.Name;
295                 static constexpr OUString sAgg = u"AggregateFunction"_ustr;
296                 if ( xInfo->hasPropertyByName(sAgg) )
297                     xColumn->getPropertyValue(sAgg) >>= bHaving;
298                 static constexpr OUString sFunction = u"Function"_ustr;
299                 if ( xInfo->hasPropertyByName(sFunction) )
300                     xColumn->getPropertyValue(sFunction) >>= bFunction;
301             }
302             if ( !bFunction )
303             {
304                 const OUString aQuote    = m_xMetaData.is() ? m_xMetaData->getIdentifierQuoteString() : OUString();
305                 _rFilter.Name = ::dbtools::quoteName(aQuote,_rFilter.Name);
306                 if ( !sTableName.isEmpty() )
307                 {
308                     sTableName += "." + _rFilter.Name;
309                     _rFilter.Name = sTableName;
310                 }
311             }
312         }
313     }
314     catch(const Exception&)
315     {
316     }
317 
318     _rFilter.Handle = GetOSQLPredicateType( _rComp.get_active_text() );
319     if ( SQLFilterOperator::SQLNULL != _rFilter.Handle && _rFilter.Handle != SQLFilterOperator::NOT_SQLNULL )
320     {
321         OUString sPredicateValue;
322         m_aPredicateInput.getPredicateValue( _rValue.get_text(), getMatchingColumn( _rValue ) ) >>= sPredicateValue;
323         if ( _rFilter.Handle == SQLFilterOperator::LIKE ||
324              _rFilter.Handle == SQLFilterOperator::NOT_LIKE )
325             ::Replace_OS_PlaceHolder( sPredicateValue );
326         _rFilter.Value <<= sPredicateValue;
327     }
328     return bHaving;
329 }
330 
getColumn(const OUString & _rFieldName) const331 Reference< XPropertySet > DlgFilterCrit::getColumn( const OUString& _rFieldName ) const
332 {
333     Reference< XPropertySet > xColumn;
334     try
335     {
336         if ( m_xColumns.is() && m_xColumns->hasByName( _rFieldName ) )
337             m_xColumns->getByName( _rFieldName ) >>= xColumn;
338 
339         Reference< XNameAccess> xColumns = Reference< XColumnsSupplier >(m_xQueryComposer,UNO_QUERY_THROW)->getColumns();
340         if ( xColumns.is() && !xColumn.is() )
341         {
342             for (auto& colName : xColumns->getElementNames())
343             {
344                 Reference<XPropertySet> xProp(xColumns->getByName(colName), UNO_QUERY);
345                 if ( xProp.is() && xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_REALNAME) )
346                 {
347                     OUString sRealName;
348                     xProp->getPropertyValue(PROPERTY_REALNAME)  >>= sRealName;
349                     if ( sRealName == _rFieldName )
350                     {
351                         if (m_xColumns.is() && m_xColumns->hasByName(colName))
352                             m_xColumns->getByName(colName) >>= xColumn;
353                         break;
354                     }
355                 }
356             }
357         }
358     }
359     catch( const Exception& )
360     {
361         DBG_UNHANDLED_EXCEPTION("dbaccess");
362     }
363 
364     return xColumn;
365 }
366 
getQueryColumn(const OUString & _rFieldName) const367 Reference< XPropertySet > DlgFilterCrit::getQueryColumn( const OUString& _rFieldName ) const
368 {
369     Reference< XPropertySet > xColumn;
370     try
371     {
372         Reference< XNameAccess> xColumns = Reference< XColumnsSupplier >(m_xQueryComposer,UNO_QUERY_THROW)->getColumns();
373         if ( xColumns.is() && xColumns->hasByName( _rFieldName ) )
374             xColumns->getByName( _rFieldName ) >>= xColumn;
375     }
376     catch( const Exception& )
377     {
378         DBG_UNHANDLED_EXCEPTION("dbaccess");
379     }
380 
381     return xColumn;
382 }
383 
getMatchingColumn(const weld::Entry & _rValueInput) const384 Reference< XPropertySet > DlgFilterCrit::getMatchingColumn( const weld::Entry& _rValueInput ) const
385 {
386     // the name
387     OUString sField;
388     if ( &_rValueInput == m_xET_WHEREVALUE1.get() )
389     {
390         sField = m_xLB_WHEREFIELD1->get_active_text();
391     }
392     else if ( &_rValueInput == m_xET_WHEREVALUE2.get() )
393     {
394         sField = m_xLB_WHEREFIELD2->get_active_text();
395     }
396     else if ( &_rValueInput == m_xET_WHEREVALUE3.get() )
397     {
398         sField = m_xLB_WHEREFIELD3->get_active_text();
399     }
400     else {
401         OSL_FAIL( "DlgFilterCrit::getMatchingColumn: invalid event source!" );
402     }
403 
404     // the field itself
405     return getColumn( sField );
406 }
407 
IMPL_LINK(DlgFilterCrit,PredicateLoseFocus,weld::Widget &,rControl,void)408 IMPL_LINK( DlgFilterCrit, PredicateLoseFocus, weld::Widget&, rControl, void )
409 {
410     weld::Entry& rField = dynamic_cast<weld::Entry&>(rControl);
411     // retrieve the field affected
412     Reference< XPropertySet> xColumn(getMatchingColumn(rField));
413     // and normalize its content
414     if ( xColumn.is() )
415     {
416         OUString sText(rField.get_text());
417         m_aPredicateInput.normalizePredicateString(sText, xColumn);
418         rField.set_text(sText);
419     }
420 }
421 
SetLine(int nIdx,const PropertyValue & _rItem,bool _bOr)422 void DlgFilterCrit::SetLine( int nIdx, const PropertyValue& _rItem, bool _bOr )
423 {
424     OUString aStr;
425     _rItem.Value >>= aStr;
426     if ( _rItem.Handle == SQLFilterOperator::LIKE ||
427          _rItem.Handle == SQLFilterOperator::NOT_LIKE )
428         ::Replace_SQL_PlaceHolder(aStr);
429     aStr = comphelper::string::stripEnd(aStr, ' ');
430 
431     Reference< XPropertySet > xColumn = getColumn( _rItem.Name );
432 
433     // to make sure that we only set first three
434     weld::ComboBox* pColumnListControl =  nullptr;
435     weld::ComboBox* pPredicateListControl = nullptr;
436     weld::Entry* pPredicateValueControl = nullptr;
437     switch( nIdx )
438     {
439         case 0:
440             pColumnListControl = m_xLB_WHEREFIELD1.get();
441             pPredicateListControl = m_xLB_WHERECOMP1.get();
442             pPredicateValueControl = m_xET_WHEREVALUE1.get();
443             break;
444         case 1:
445             m_xLB_WHERECOND2->set_active( _bOr ? 1 : 0 );
446 
447             pColumnListControl = m_xLB_WHEREFIELD2.get();
448             pPredicateListControl = m_xLB_WHERECOMP2.get();
449             pPredicateValueControl = m_xET_WHEREVALUE2.get();
450             break;
451         case 2:
452             m_xLB_WHERECOND3->set_active( _bOr ? 1 : 0 );
453 
454             pColumnListControl = m_xLB_WHEREFIELD3.get();
455             pPredicateListControl = m_xLB_WHERECOMP3.get();
456             pPredicateValueControl = m_xET_WHEREVALUE3.get();
457             break;
458     }
459 
460     if ( !(pColumnListControl && pPredicateListControl && pPredicateValueControl) )
461         return;
462 
463     OUString sName;
464     if ( xColumn.is() )
465         xColumn->getPropertyValue(PROPERTY_NAME) >>= sName;
466     else
467         sName = _rItem.Name;
468     // select the appropriate field name
469     SelectField( *pColumnListControl, sName );
470     ListSelectHdl( *pColumnListControl );
471 
472     // select the appropriate condition
473     pPredicateListControl->set_active( GetSelectionPos( _rItem.Handle, *pPredicateListControl ) );
474 
475     // initially normalize this value
476     OUString aString( aStr );
477     m_aPredicateInput.normalizePredicateString( aString, xColumn );
478     pPredicateValueControl->set_text( aString );
479 }
480 
SelectField(weld::ComboBox & rBox,std::u16string_view rField)481 void DlgFilterCrit::SelectField(weld::ComboBox& rBox, std::u16string_view rField)
482 {
483     const sal_Int32 nCnt = rBox.get_count();
484 
485     for( sal_Int32 i=0 ; i<nCnt ; i++ )
486     {
487         if (rBox.get_text(i) == rField)
488         {
489             rBox.set_active(i);
490             return;
491         }
492     }
493 
494     rBox.set_active(0);
495 }
496 
EnableLines()497 void DlgFilterCrit::EnableLines()
498 {
499     // enabling/disabling of whole lines
500     if( m_xLB_WHEREFIELD1->get_active() == 0 )
501     {
502         m_xLB_WHEREFIELD2->set_sensitive(false);
503         m_xLB_WHERECOND2->set_sensitive(false);
504         m_xLB_WHERECOMP2->set_sensitive(false);
505         m_xET_WHEREVALUE2->set_sensitive(false);
506 
507         m_xLB_WHEREFIELD3->set_sensitive(false);
508         m_xLB_WHERECOND3->set_sensitive(false);
509         m_xLB_WHERECOMP3->set_sensitive(false);
510         m_xET_WHEREVALUE3->set_sensitive(false);
511     }
512     else
513     {
514         m_xLB_WHEREFIELD2->set_sensitive(true);
515         m_xLB_WHERECOND2->set_sensitive(true);
516         m_xLB_WHERECOMP2->set_sensitive(true);
517         m_xET_WHEREVALUE2->set_sensitive(true);
518 
519         m_xLB_WHEREFIELD3->set_sensitive(true);
520         m_xLB_WHERECOND3->set_sensitive(true);
521         m_xLB_WHERECOMP3->set_sensitive(true);
522         m_xET_WHEREVALUE3->set_sensitive(true);
523     }
524 
525     if( m_xLB_WHEREFIELD2->get_active() == 0 )
526     {
527         m_xLB_WHEREFIELD3->set_sensitive(false);
528         m_xLB_WHERECOND3->set_sensitive(false);
529         m_xLB_WHERECOMP3->set_sensitive(false);
530         m_xET_WHEREVALUE3->set_sensitive(false);
531     }
532     else
533     {
534         m_xLB_WHEREFIELD3->set_sensitive(true);
535         m_xLB_WHERECOND3->set_sensitive(true);
536         m_xLB_WHERECOMP3->set_sensitive(true);
537         m_xET_WHEREVALUE3->set_sensitive(true);
538     }
539 
540     // comparison field equal to NOENTRY
541     if( m_xLB_WHEREFIELD1->get_active() == 0 )
542     {
543         m_xLB_WHERECOMP1->set_sensitive(false);
544         m_xET_WHEREVALUE1->set_sensitive(false);
545     }
546     else
547     {
548         m_xLB_WHEREFIELD1->set_sensitive(true);
549         m_xLB_WHERECOMP1->set_sensitive(true);
550         m_xET_WHEREVALUE1->set_sensitive(true);
551     }
552 
553     if( m_xLB_WHEREFIELD2->get_active() == 0 )
554     {
555         m_xLB_WHERECOND2->set_sensitive(false);
556         m_xLB_WHERECOMP2->set_sensitive(false);
557         m_xET_WHEREVALUE2->set_sensitive(false);
558     }
559     else
560     {
561         m_xLB_WHERECOND2->set_sensitive(true);
562         m_xLB_WHEREFIELD2->set_sensitive(true);
563         m_xLB_WHERECOMP2->set_sensitive(true);
564         m_xET_WHEREVALUE2->set_sensitive(true);
565     }
566 
567     if( m_xLB_WHEREFIELD3->get_active() == 0 )
568     {
569         m_xLB_WHERECOND3->set_sensitive(false);
570         m_xLB_WHERECOMP3->set_sensitive(false);
571         m_xET_WHEREVALUE3->set_sensitive(false);
572     }
573     else
574     {
575         m_xLB_WHERECOND3->set_sensitive(true);
576         m_xLB_WHERECOND3->set_sensitive(true);
577         m_xLB_WHEREFIELD3->set_sensitive(true);
578         m_xLB_WHERECOMP3->set_sensitive(true);
579         m_xET_WHEREVALUE3->set_sensitive(true);
580     }
581 
582     // comparison operator equal to ISNULL or ISNOTNULL
583     if(m_xLB_WHERECOMP1->get_count() > 2 &&
584         ((m_xLB_WHERECOMP1->get_active() == m_xLB_WHERECOMP1->get_count()-1) ||
585          (m_xLB_WHERECOMP1->get_active() == m_xLB_WHERECOMP1->get_count()-2)) )
586         m_xET_WHEREVALUE1->set_sensitive(false);
587 
588     if(m_xLB_WHERECOMP2->get_count() > 2 &&
589         ((m_xLB_WHERECOMP2->get_active() == m_xLB_WHERECOMP2->get_count()-1) ||
590          (m_xLB_WHERECOMP2->get_active() == m_xLB_WHERECOMP2->get_count()-2)) )
591         m_xET_WHEREVALUE2->set_sensitive(false);
592 
593     if(m_xLB_WHERECOMP3->get_count() > 2 &&
594         ((m_xLB_WHERECOMP3->get_active() == m_xLB_WHERECOMP3->get_count()-1) ||
595          (m_xLB_WHERECOMP3->get_active() == m_xLB_WHERECOMP3->get_count()-2)) )
596         m_xET_WHEREVALUE3->set_sensitive(false);
597 }
598 
IMPL_LINK(DlgFilterCrit,ListSelectHdl,weld::ComboBox &,rListBox,void)599 IMPL_LINK( DlgFilterCrit, ListSelectHdl, weld::ComboBox&, rListBox, void )
600 {
601     OUString aName;
602     weld::ComboBox* pComp;
603     if(&rListBox == m_xLB_WHEREFIELD1.get())
604     {
605         aName = m_xLB_WHEREFIELD1->get_active_text();
606         pComp = m_xLB_WHERECOMP1.get();
607     }
608     else if(&rListBox == m_xLB_WHEREFIELD2.get())
609     {
610         aName = m_xLB_WHEREFIELD2->get_active_text();
611         pComp = m_xLB_WHERECOMP2.get();
612     }
613     else
614     {
615         aName = m_xLB_WHEREFIELD3->get_active_text();
616         pComp = m_xLB_WHERECOMP3.get();
617     }
618 
619     pComp->clear();
620 
621     Reference<XPropertySet> xColumn = getColumn(aName);
622     if ( xColumn.is() )
623     {
624         sal_Int32 nDataType = 0;
625         xColumn->getPropertyValue(PROPERTY_TYPE) >>= nDataType;
626         sal_Int32 eColumnSearch = dbtools::getSearchColumnFlag(m_xConnection,nDataType);
627 
628         if(eColumnSearch  == ColumnSearch::FULL)
629         {
630             for(size_t i=0;i < m_aSTR_COMPARE_OPERATORS.size(); i++)
631                 pComp->append_text(m_aSTR_COMPARE_OPERATORS[i]);
632         }
633         else if(eColumnSearch == ColumnSearch::CHAR)
634         {
635             for(sal_Int32 i=6; i<10; i++)
636                 pComp->append_text(m_aSTR_COMPARE_OPERATORS[i]);
637         }
638         else if(eColumnSearch == ColumnSearch::BASIC)
639         {
640             size_t i;
641             for( i = 0; i < 6; i++ )
642                 pComp->append_text(m_aSTR_COMPARE_OPERATORS[i]);
643             for(i=8; i < m_aSTR_COMPARE_OPERATORS.size(); ++i)
644                 pComp->append_text(m_aSTR_COMPARE_OPERATORS[i]);
645         }
646         else
647         {
648             OSL_FAIL("DlgFilterCrit::ListSelectHdl: This column should not exist at all.");
649         }
650     }
651     pComp->set_active(0);
652 
653     EnableLines();
654 }
655 
IMPL_LINK_NOARG(DlgFilterCrit,ListSelectCompHdl,weld::ComboBox &,void)656 IMPL_LINK_NOARG(DlgFilterCrit, ListSelectCompHdl, weld::ComboBox&, void)
657 {
658     EnableLines();
659 }
660 
BuildWherePart()661 void DlgFilterCrit::BuildWherePart()
662 {
663     Sequence<Sequence<PropertyValue> > aFilter(1),aHaving(1);
664 
665     if( m_xLB_WHEREFIELD1->get_active() != 0 )
666     {
667         PropertyValue aValue;
668         if ( getCondition(*m_xLB_WHEREFIELD1,*m_xLB_WHERECOMP1,*m_xET_WHEREVALUE1,aValue) )
669         {
670             aHaving = { { aValue } };
671         }
672         else
673         {
674             aFilter = { { aValue} };
675         }
676     }
677 
678     if( m_xLB_WHEREFIELD2->get_active() != 0 )
679     {
680         PropertyValue aValue;
681         Sequence<Sequence<PropertyValue> >& _rValues = aFilter;
682         if ( getCondition(*m_xLB_WHEREFIELD2,*m_xLB_WHERECOMP2,*m_xET_WHEREVALUE2,aValue) )
683             _rValues = aHaving;
684         if ( m_xLB_WHERECOND2->get_active() )
685             _rValues.realloc( _rValues.getLength() + 1);
686         sal_Int32 nPos = _rValues.getLength() - 1;
687         sal_Int32 nAndPos = _rValues[nPos].getLength();
688         auto pValues = _rValues.getArray();
689         pValues[nPos].realloc( _rValues[nPos].getLength() + 1);
690         pValues[nPos].getArray()[nAndPos] = aValue;
691     }
692 
693     if( m_xLB_WHEREFIELD3->get_active() != 0 )
694     {
695         PropertyValue aValue;
696         Sequence<Sequence<PropertyValue> >& _rValues = aFilter;
697         if ( getCondition(*m_xLB_WHEREFIELD3,*m_xLB_WHERECOMP3,*m_xET_WHEREVALUE3,aValue) )
698             _rValues = aHaving;
699         if (m_xLB_WHERECOND3->get_active())
700             _rValues.realloc( _rValues.getLength() + 1);
701         sal_Int32 nPos = _rValues.getLength() - 1;
702         sal_Int32 nAndPos = _rValues[nPos].getLength();
703         auto pValues = _rValues.getArray();
704         pValues[nPos].realloc( _rValues[nPos].getLength() + 1);
705         pValues[nPos].getArray()[nAndPos] = aValue;
706     }
707     try
708     {
709         m_xQueryComposer->setStructuredFilter(aFilter);
710         m_xQueryComposer->setStructuredHavingClause(aHaving);
711     }
712     catch(const Exception&)
713     {
714         DBG_UNHANDLED_EXCEPTION("dbaccess");
715     }
716 }
717 
fillLines(int & i,const Sequence<Sequence<PropertyValue>> & _aValues)718 void DlgFilterCrit::fillLines(int &i, const Sequence< Sequence< PropertyValue > >& _aValues)
719 {
720     bool bOr(i != 0); // WHERE clause and HAVING clause are always ANDed, nor ORed
721     for (auto& rOr : _aValues)
722     {
723         for (auto& rAnd : rOr)
724         {
725             SetLine(i++, rAnd, bOr);
726             bOr = false;
727         }
728         bOr=true;
729     }
730 }
731 
732 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
733