1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
13 File: YQPkgSearchFilterView.cc
15 Author: Stefan Hundhammer <sh@suse.de>
17 Textdomain "packages-qt"
21 #include <qcheckbox.h>
22 #include <qcombobox.h>
25 #include <qpushbutton.h>
26 #include <qradiobutton.h>
27 #include <qvbuttongroup.h>
28 #include <qvgroupbox.h>
29 #include <qprogressdialog.h>
30 #include <qdatetime.h>
32 #define y2log_component "qt-pkg"
33 #include <ycp/y2log.h>
35 #include "YQPkgSearchFilterView.h"
36 #include "QY2LayoutUtils.h"
39 #include "YQApplication.h"
46 #define SPACING 6 // between subwidgets
47 #define MARGIN 4 // around the widget
50 YQPkgSearchFilterView::YQPkgSearchFilterView( QWidget * parent )
55 setSpacing( SPACING );
60 QLabel * label = new QLabel( _( "Searc&h:" ), this );
62 label->setFont( YQUI::yqApp()->headingFont() );
64 // Input field ( combo box ) for search text
65 _searchText = new QComboBox( this );
66 CHECK_PTR( _searchText );
67 _searchText->setEditable( true );
68 label->setBuddy( _searchText );
71 // Box for search button
72 QHBox * hbox = new QHBox( this );
78 _searchButton = new QPushButton( _( "&Search" ), hbox );
79 CHECK_PTR( _searchButton );
81 connect( _searchButton, SIGNAL( clicked() ),
82 this, SLOT ( filter() ) );
90 QVGroupBox * gbox = new QVGroupBox( _( "Search in" ), this );
94 _searchInName = new QCheckBox( _( "&Name" ), gbox ); CHECK_PTR( _searchInName );
95 _searchInSummary = new QCheckBox( _( "Su&mmary" ), gbox ); CHECK_PTR( _searchInSummary );
96 _searchInDescription = new QCheckBox( _( "Descr&iption" ), gbox ); CHECK_PTR( _searchInDescription );
100 // Intentionally NOT marking RPM tags for translation
101 _searchInProvides = new QCheckBox( "RPM \"&Provides\"" , gbox ); CHECK_PTR( _searchInProvides );
102 _searchInRequires = new QCheckBox( "RPM \"Re&quires\"" , gbox ); CHECK_PTR( _searchInRequires );
104 _searchInName->setChecked( true );
105 _searchInSummary->setChecked( true );
114 label = new QLabel( _( "Search &Mode:" ), this );
117 _searchMode = new QComboBox( this );
118 CHECK_PTR( _searchMode );
119 _searchMode->setEditable( false );
121 label->setBuddy( _searchMode );
123 // Caution: combo box items must be inserted in the same order as enum SearchMode!
124 _searchMode->insertItem( _( "Contains" ) );
125 _searchMode->insertItem( _( "Begins with" ) );
126 _searchMode->insertItem( _( "Exact Match" ) );
127 _searchMode->insertItem( _( "Use Wild Cards" ) );
128 _searchMode->insertItem( _( "Use Regular Expression" ) );
130 _searchMode->setCurrentItem( Contains );
135 _caseSensitive = new QCheckBox( _( "Case Sensiti&ve" ), this );
136 CHECK_PTR( _caseSensitive );
138 for ( int i=0; i < 6; i++ )
143 YQPkgSearchFilterView::~YQPkgSearchFilterView()
150 YQPkgSearchFilterView::keyPressEvent( QKeyEvent * event )
154 if ( event->state() == 0 ) // No Ctrl / Alt / Shift etc. pressed
156 if ( event->key() == Qt::Key_Return ||
157 event->key() == Qt::Key_Enter )
159 _searchButton->animateClick();
166 QVBox::keyPressEvent( event );
171 YQPkgSearchFilterView::setFocus()
173 _searchText->setFocus();
178 YQPkgSearchFilterView::minimumSizeHint() const
180 return QSize( 0, 0 );
185 YQPkgSearchFilterView::filterIfVisible()
193 YQPkgSearchFilterView::filter()
198 if ( ! _searchText->currentText().isEmpty() )
200 // Create a progress dialog that is only displayed if the search takes
201 // longer than a couple of seconds ( default: 4 ).
203 QProgressDialog progress( _( "Searching..." ), // text
204 _( "&Cancel" ), // cancelButtonLabel
206 Y2PM::packageManager().size(), // totalSteps
210 this, 0, // parent, name
212 progress.setCaption( "" );
213 progress.setMinimumDuration( 2000 ); // millisec
216 QRegExp regexp = _searchText->currentText();
217 regexp.setCaseSensitive( _caseSensitive->isChecked() );
218 regexp.setWildcard( _searchMode->currentItem() == UseWildcards );
225 for ( ZyppPoolIterator it = zyppPkgBegin();
226 it != zyppPkgEnd() && ! progress.wasCancelled();
229 ZyppSel selectable = *it;
232 check( selectable, selectable->candidateObj(), regexp ) ||
233 check( selectable, selectable->installedObj(), regexp );
235 // If there is neither an installed nor a candidate package, check
236 // any other instance.
239 ! selectable->candidateObj() &&
240 ! selectable->installedObj() )
241 check( selectable, selectable->theObj(), regexp );
244 progress.setProgress( count++ );
246 if ( timer.elapsed() > 300 ) // milisec
248 // Process events only every 300 milliseconds - this is very
249 // expensive since both the progress dialog and the package
250 // list change all the time, thus display updates are necessary
253 qApp->processEvents();
258 if ( _matchCount == 0 )
259 emit message( _( "No Results." ) );
262 emit filterFinished();
267 YQPkgSearchFilterView::check( ZyppSel selectable,
270 QRegExp regexp = _searchText->currentText();
271 regexp.setCaseSensitive( _caseSensitive->isChecked() );
272 regexp.setWildcard( _searchMode->currentItem() == UseWildcards );
274 return check( selectable, zyppObj, regexp );
279 YQPkgSearchFilterView::check( ZyppSel selectable,
281 const QRegExp & regexp )
287 ( _searchInName->isChecked() && check( zyppObj->name(), regexp ) ) ||
288 ( _searchInSummary->isChecked() && check( zyppObj->summary(), regexp ) ) ||
289 ( _searchInDescription->isChecked() && check( zyppObj->description(), regexp ) ) ||
290 ( _searchInProvides->isChecked() && check( zyppObj->dep( zypp::Dep::PROVIDES ), regexp ) ) ||
291 ( _searchInRequires->isChecked() && check( zyppObj->dep( zypp::Dep::REQUIRES ), regexp ) );
295 ZyppPkg zyppPkg = tryCastToZyppPkg( zyppObj );
300 emit filterMatch( selectable, zyppPkg );
309 YQPkgSearchFilterView::check( const string & attribute,
310 const QRegExp & regexp )
312 QString att = fromUTF8( attribute );
313 QString searchText = _searchText->currentText();
316 switch ( _searchMode->currentItem() )
319 match = att.contains( searchText, _caseSensitive->isChecked() );
323 match = att.startsWith( searchText ); // only case sensitive
327 match = ( att == searchText );
332 // Both cases differ in how the regexp is set up during initialization
333 match = att.contains( regexp );
336 // Intentionally omitting "default" branch - let gcc watch for unhandled enums
344 YQPkgSearchFilterView::check( const zypp::CapSet & capSet, const QRegExp & regexp )
346 for ( zypp::CapSet::const_iterator it = capSet.begin();
350 if ( check( ( *it).index(), regexp ) )
352 // y2debug( "Match for %s", (*it).asString().c_str() );
362 #include "YQPkgSearchFilterView.moc"