2 Copyright 2007 Robert Knight <robertknight@gmail.com>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
21 #include "core/searchmodel.h"
23 #include "config-kickoff-applets.h"
29 #include <KServiceTypeTrader>
30 #ifdef HAVE_STRIGIDBUS
31 #include <strigi/qtdbus/strigiclient.h>
33 #include <solid/networking.h>
36 #include "core/models.h"
38 using namespace Kickoff
;
40 class SearchModel::Private
43 Private(SearchModel
*parent
) : q(parent
) {}
45 void addItemForIface(SearchInterface
*iface
,QStandardItem
*item
)
47 int index
= searchIfaces
.indexOf(iface
);
49 q
->item(index
)->appendRow(item
);
53 for (int i
=0;i
<q
->rowCount();i
++) {
54 q
->item(i
)->removeRows(0,q
->item(i
)->rowCount());
58 SearchModel
* const q
;
59 QList
<SearchInterface
*> searchIfaces
;
62 SearchModel::SearchModel(QObject
*parent
)
63 : KickoffModel(parent
)
64 , d(new Private(this))
66 d
->searchIfaces
<< new ApplicationSearch(this);
67 //d->searchIfaces << new IndexerSearch(this);
68 d
->searchIfaces
<< new WebSearch(this);
70 foreach(SearchInterface
*iface
,d
->searchIfaces
) {
71 QStandardItem
*ifaceItem
= new QStandardItem(iface
->name());
73 connect(iface
,SIGNAL(resultsAvailable(QStringList
)),
74 this,SLOT(resultsAvailable(QStringList
)));
75 connect(iface
,SIGNAL(resultsAvailable(ResultList
)),
76 this,SLOT(resultsAvailable(ResultList
)));
79 SearchModel::~SearchModel()
83 void SearchModel::resultsAvailable(const QStringList
& results
)
85 SearchInterface
*iface
= qobject_cast
<SearchInterface
*>(sender());
89 foreach(const QString
& result
,results
) {
90 //kDebug() << "Search hit from" << iface->name() << result;
91 QStandardItem
*resultItem
= StandardItemFactory::createItemForUrl(result
);
92 d
->addItemForIface(iface
,resultItem
);
95 void SearchModel::resultsAvailable(const ResultList
& results
)
97 SearchInterface
*iface
= qobject_cast
<SearchInterface
*>(sender());
101 foreach(const SearchResult
& result
,results
) {
102 QStandardItem
*item
= StandardItemFactory::createItemForUrl(result
.url
);
103 item
->setData(result
.title
,Qt::DisplayRole
);
104 item
->setData(result
.subTitle
,SubTitleRole
);
105 d
->addItemForIface(iface
,item
);
108 void SearchModel::setQuery(const QString
& query
)
112 if (query
.isEmpty()) {
116 foreach(SearchInterface
*iface
, d
->searchIfaces
) {
117 iface
->setQuery(query
);
121 SearchInterface::SearchInterface(QObject
*parent
)
126 ApplicationSearch::ApplicationSearch(QObject
*parent
)
127 : SearchInterface(parent
)
131 QString
ApplicationSearch::name() const
133 return i18n("Applications");
136 void ApplicationSearch::setQuery(const QString
& query
)
138 //QString mimeName = mimeNameForQuery(query);
139 QString traderQuery
= QString("((exist GenericName) and ('%1' ~~ GenericName)) or ('%1' ~~ Name) or ((exist Keywords) and ('%1' ~in Keywords))"
140 //" or ('%2' in MimeType)"
142 .arg(query
); //.arg(mimeName);
143 KServiceTypeTrader
*trader
= KServiceTypeTrader::self();
144 KService::List results
= trader
->query("Application",traderQuery
);
146 // If we have KDE 3 and KDE 4 versions of a service, return only the
148 QHash
<QString
,int> desktopNames
;
149 QSet
<QString
> execFields
;
150 for (int i
=0;i
<results
.count();i
++) {
151 KService::Ptr service
= results
[i
];
153 int existingPos
= desktopNames
.value(service
->name(),-1);
154 KService::Ptr existing
= existingPos
< 0 ? KService::Ptr(0) : results
[existingPos
];
156 if (!existing
.isNull()) {
157 if (isLaterVersion(existing
,service
)) {
159 } else if (isLaterVersion(service
,existing
)) {
160 results
[existingPos
] = 0;
162 // do not show more than one entry which does the same thing when run
163 // (ie. ignore entries that have an identical 'Exec' field to an existing
165 if (execFields
.contains(service
->exec())) {
170 desktopNames
.insert(service
->name(),i
);
171 execFields
.insert(service
->exec());
175 QStringList pathResults
;
176 foreach(KService::Ptr service
,results
) {
177 if (!service
.isNull() && !service
->noDisplay()) {
178 pathResults
<< service
->entryPath();
181 emit
resultsAvailable(pathResults
);
184 QString
ApplicationSearch::mimeNameForQuery(const QString
& query
) const
186 KMimeType::Ptr type
= KMimeType::findByPath('.'+query
,0,true);
188 kDebug() << "Mime type name" << type
->name();
193 WebSearch::WebSearch(QObject
*parent
)
194 : SearchInterface(parent
)
197 QString
WebSearch::name() const
199 return i18n("Web Searches");
201 void WebSearch::setQuery(const QString
& query
)
204 SearchResult googleResult
;
205 googleResult
.url
= QString("http://www.google.com/search?q=%1").arg(query
);
206 googleResult
.title
= i18n("Search web for '%1'",query
);
207 results
<< googleResult
;
208 emit
resultsAvailable(results
);
210 IndexerSearch::IndexerSearch(QObject
*parent
)
211 : SearchInterface(parent
)
214 QString
IndexerSearch::name() const
216 return i18n("Documents");
218 void IndexerSearch::setQuery(const QString
& query
)
220 #ifdef HAVE_STRIGIDBUS
221 static const StrigiClient searchClient
;
224 QList
<StrigiHit
> hits
= searchClient
.getHits(query
,10,0);
225 foreach(const StrigiHit
& hit
,hits
) {
226 if (!hit
.uri
.isEmpty()) {
230 emit
resultsAvailable(urls
);
234 #include "searchmodel.moc"