1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
13 File: YQPkgSearchFilterView.cc
15 Author: Stefan Hundhammer <sh@suse.de>
17 Textdomain "packages-qt"
25 #include <QPushButton>
26 #include <QRadioButton>
28 #include <QProgressDialog>
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 )
53 QVBoxLayout *layout = new QVBoxLayout;
56 layout->setMargin( MARGIN );
57 layout->setSpacing( SPACING );
62 QLabel * label = new QLabel( _( "Searc&h:" ), this );
64 layout->addWidget(label);
65 label->setFont( YQUI::yqApp()->headingFont() );
67 // Input field ( combo box ) for search text
68 _searchText = new QComboBox( this );
69 Q_CHECK_PTR( _searchText );
70 layout->addWidget(_searchText);
71 _searchText->setEditable( true );
72 label->setBuddy( _searchText );
75 // Box for search button
76 QHBoxLayout * hbox = new QHBoxLayout();
78 layout->addLayout(hbox);
82 _searchButton = new QPushButton( _( "&Search" ), this );
83 Q_CHECK_PTR( _searchButton );
84 hbox->addWidget(_searchButton);
86 connect( _searchButton, SIGNAL( clicked() ),
87 this, SLOT ( filter() ) );
95 QGroupBox * gbox = new QGroupBox( _( "Search in" ), this );
97 layout->addWidget(gbox);
98 QVBoxLayout *vlayout = new QVBoxLayout;
99 gbox->setLayout(vlayout);
101 _searchInName = new QCheckBox( _( "&Name" ), gbox ); Q_CHECK_PTR( _searchInName );
102 vlayout->addWidget(_searchInName);
103 _searchInSummary = new QCheckBox( _( "Su&mmary" ), gbox ); Q_CHECK_PTR( _searchInSummary );
104 vlayout->addWidget(_searchInSummary);
105 _searchInDescription = new QCheckBox( _( "Descr&iption" ), gbox ); Q_CHECK_PTR( _searchInDescription );
106 vlayout->addWidget(_searchInDescription);
108 vlayout->addStretch();
110 // Intentionally NOT marking RPM tags for translation
111 _searchInProvides = new QCheckBox( "RPM \"&Provides\"" , gbox ); Q_CHECK_PTR( _searchInProvides );
112 vlayout->addWidget(_searchInProvides);
113 _searchInRequires = new QCheckBox( "RPM \"Re&quires\"" , gbox ); Q_CHECK_PTR( _searchInRequires );
114 vlayout->addWidget(_searchInRequires);
116 _searchInName->setChecked( true );
117 _searchInSummary->setChecked( true );
119 layout->addStretch();
126 label = new QLabel( _( "Search &Mode:" ), this );
127 Q_CHECK_PTR( label );
128 layout->addWidget(label);
130 _searchMode = new QComboBox( this );
131 Q_CHECK_PTR( _searchMode );
132 layout->addWidget(_searchMode);
134 _searchMode->setEditable( false );
136 label->setBuddy( _searchMode );
138 // Caution: combo box items must be inserted in the same order as enum SearchMode!
139 _searchMode->addItem( _( "Contains" ) );
140 _searchMode->addItem( _( "Begins with" ) );
141 _searchMode->addItem( _( "Exact Match" ) );
142 _searchMode->addItem( _( "Use Wild Cards" ) );
143 _searchMode->addItem( _( "Use Regular Expression" ) );
145 _searchMode->setCurrentIndex( Contains );
148 layout->addStretch();
150 _caseSensitive = new QCheckBox( _( "Case Sensiti&ve" ), this );
151 Q_CHECK_PTR( _caseSensitive );
152 layout->addWidget(_caseSensitive);
154 for ( int i=0; i < 6; i++ )
155 layout->addStretch();
159 YQPkgSearchFilterView::~YQPkgSearchFilterView()
166 YQPkgSearchFilterView::keyPressEvent( QKeyEvent * event )
170 if ( event->modifiers() == Qt::NoModifier ) // No Ctrl / Alt / Shift etc. pressed
172 if ( event->key() == Qt::Key_Return ||
173 event->key() == Qt::Key_Enter )
175 _searchButton->animateClick();
182 QWidget::keyPressEvent( event );
187 YQPkgSearchFilterView::setFocus()
189 _searchText->setFocus();
194 YQPkgSearchFilterView::minimumSizeHint() const
196 return QSize( 0, 0 );
201 YQPkgSearchFilterView::filterIfVisible()
209 YQPkgSearchFilterView::filter()
214 if ( ! _searchText->currentText().isEmpty() )
216 // Create a progress dialog that is only displayed if the search takes
217 // longer than a couple of seconds ( default: 4 ).
219 QProgressDialog progress( _( "Searching..." ), // text
220 _( "&Cancel" ), // cancelButtonLabel
225 progress.setWindowTitle( "" );
226 progress.setMinimumDuration( 2000 ); // millisec
229 QRegExp regexp( _searchText->currentText() );
230 regexp.setCaseSensitivity( _caseSensitive->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive );
231 regexp.setPatternSyntax( (_searchMode->currentIndex() == UseWildcards) ? QRegExp::Wildcard : QRegExp::RegExp);
238 for ( ZyppPoolIterator it = zyppPkgBegin();
239 it != zyppPkgEnd() && ! progress.wasCanceled();
242 ZyppSel selectable = *it;
245 check( selectable, selectable->candidateObj(), regexp ) ||
246 check( selectable, selectable->installedObj(), regexp );
248 // If there is neither an installed nor a candidate package, check
249 // any other instance.
252 ! selectable->candidateObj() &&
253 ! selectable->installedObj() )
254 check( selectable, selectable->theObj(), regexp );
257 progress.setValue( count++ );
259 if ( timer.elapsed() > 300 ) // milisec
261 // Process events only every 300 milliseconds - this is very
262 // expensive since both the progress dialog and the package
263 // list change all the time, thus display updates are necessary
266 qApp->processEvents();
271 if ( _matchCount == 0 )
272 emit message( _( "No Results." ) );
275 emit filterFinished();
280 YQPkgSearchFilterView::check( ZyppSel selectable,
283 QRegExp regexp( _searchText->currentText() );
284 regexp.setCaseSensitivity( _caseSensitive->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive );
285 regexp.setPatternSyntax( (_searchMode->currentIndex() == UseWildcards) ? QRegExp::Wildcard : QRegExp::RegExp);
286 return check( selectable, zyppObj, regexp );
291 YQPkgSearchFilterView::check( ZyppSel selectable,
293 const QRegExp & regexp )
299 ( _searchInName->isChecked() && check( zyppObj->name(), regexp ) ) ||
300 ( _searchInSummary->isChecked() && check( zyppObj->summary(), regexp ) ) ||
301 ( _searchInDescription->isChecked() && check( zyppObj->description(), regexp ) ) ||
302 ( _searchInProvides->isChecked() && check( zyppObj->dep( zypp::Dep::PROVIDES ), regexp ) ) ||
303 ( _searchInRequires->isChecked() && check( zyppObj->dep( zypp::Dep::REQUIRES ), regexp ) );
307 ZyppPkg zyppPkg = tryCastToZyppPkg( zyppObj );
312 emit filterMatch( selectable, zyppPkg );
321 YQPkgSearchFilterView::check( const string & attribute,
322 const QRegExp & regexp )
324 QString att = fromUTF8( attribute );
325 QString searchText = _searchText->currentText();
328 switch ( _searchMode->currentIndex() )
331 match = att.contains( searchText, _caseSensitive->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive);
335 match = att.startsWith( searchText ); // only case sensitive
339 match = ( att == searchText );
344 // Both cases differ in how the regexp is set up during initialization
345 match = att.contains( regexp );
348 // Intentionally omitting "default" branch - let gcc watch for unhandled enums
356 YQPkgSearchFilterView::check( const zypp::CapSet & capSet, const QRegExp & regexp )
358 for ( zypp::CapSet::const_iterator it = capSet.begin();
362 if ( check( ( *it).index(), regexp ) )
364 // y2debug( "Match for %s", (*it).asString().c_str() );
374 #include "YQPkgSearchFilterView.moc"