not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / plasma / applets / kickoff / core / searchmodel.cpp
blob5029490a6b95213e4ce1394b29196bad3824459a
1 /*
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.
20 // Own
21 #include "core/searchmodel.h"
23 #include "config-kickoff-applets.h"
24 // Qt
26 // KDE
27 #include <KDebug>
28 #include <KMimeType>
29 #include <KServiceTypeTrader>
30 #ifdef HAVE_STRIGIDBUS
31 #include <strigi/qtdbus/strigiclient.h>
32 #endif
33 #include <solid/networking.h>
35 // Local
36 #include "core/models.h"
38 using namespace Kickoff;
40 class SearchModel::Private
42 public:
43 Private(SearchModel *parent) : q(parent) {}
45 void addItemForIface(SearchInterface *iface, QStandardItem *item) {
46 int index = searchIfaces.indexOf(iface);
47 Q_ASSERT(index >= 0);
48 q->item(index)->appendRow(item);
50 void clear() {
51 for (int i = 0;i < q->rowCount();i++) {
52 q->item(i)->removeRows(0, q->item(i)->rowCount());
56 SearchModel * const q;
57 QList<SearchInterface*> searchIfaces;
60 SearchModel::SearchModel(QObject *parent)
61 : KickoffModel(parent)
62 , d(new Private(this))
64 d->searchIfaces << new ApplicationSearch(this);
65 //d->searchIfaces << new IndexerSearch(this);
66 d->searchIfaces << new WebSearch(this);
68 foreach(SearchInterface *iface, d->searchIfaces) {
69 QStandardItem *ifaceItem = new QStandardItem(iface->name());
70 appendRow(ifaceItem);
71 connect(iface, SIGNAL(resultsAvailable(QStringList)),
72 this, SLOT(resultsAvailable(QStringList)));
73 connect(iface, SIGNAL(resultsAvailable(ResultList)),
74 this, SLOT(resultsAvailable(ResultList)));
75 connect(iface, SIGNAL(resultsAvailable(QStringList)),
76 this, SIGNAL(resultsAvailable()));
77 connect(iface, SIGNAL(resultsAvailable(ResultList)),
78 this, SIGNAL(resultsAvailable()));
81 SearchModel::~SearchModel()
83 delete d;
85 void SearchModel::resultsAvailable(const QStringList& results)
87 SearchInterface *iface = qobject_cast<SearchInterface*>(sender());
89 Q_ASSERT(iface);
91 foreach(const QString& result, results) {
92 //kDebug() << "Search hit from" << iface->name() << result;
93 QStandardItem *resultItem = StandardItemFactory::createItemForUrl(result);
94 d->addItemForIface(iface, resultItem);
97 void SearchModel::resultsAvailable(const ResultList& results)
99 SearchInterface *iface = qobject_cast<SearchInterface*>(sender());
101 Q_ASSERT(iface);
103 foreach(const SearchResult& result, results) {
104 QStandardItem *item = StandardItemFactory::createItemForUrl(result.url);
105 item->setData(result.title, Qt::DisplayRole);
106 item->setData(result.subTitle, SubTitleRole);
107 d->addItemForIface(iface, item);
110 void SearchModel::setQuery(const QString& query)
112 d->clear();
114 if (query.isEmpty()) {
115 return;
118 foreach(SearchInterface *iface, d->searchIfaces) {
119 iface->setQuery(query);
123 SearchInterface::SearchInterface(QObject *parent)
124 : QObject(parent)
128 ApplicationSearch::ApplicationSearch(QObject *parent)
129 : SearchInterface(parent)
133 QString ApplicationSearch::name() const
135 return i18n("Applications");
138 void ApplicationSearch::setQuery(const QString& query)
140 //QString mimeName = mimeNameForQuery(query);
141 QString traderQuery = QString("((exist GenericName) and ('%1' ~~ GenericName)) or ('%1' ~~ Name) or ('%1' ~~ Exec) or ((exist Keywords) and ('%1' ~in Keywords))"
142 //" or ('%2' in MimeType)"
144 .arg(query); //.arg(mimeName);
145 KServiceTypeTrader *trader = KServiceTypeTrader::self();
146 KService::List results = trader->query("Application", traderQuery);
148 // If we have KDE 3 and KDE 4 versions of a service, return only the
149 // KDE 4 version
150 QHash<QString, int> desktopNames;
151 QSet<QString> execFields;
154 for (int i = 0;i < results.count();i++) {
155 KService::Ptr service = results[i];
156 int existingPos = desktopNames.value(service->name(), -1);
157 KService::Ptr existing = existingPos < 0 ? KService::Ptr(0) : results[existingPos];
160 if (!existing.isNull()) {
161 if (isLaterVersion(existing, service)) {
162 results[i] = 0;
163 } else if (isLaterVersion(service, existing)) {
164 results[existingPos] = 0;
165 } else {
166 // do not show more than one entry which does the same thing when run
167 // (ie. ignore entries that have an identical 'Exec' field to an existing
168 // entry)
169 if (execFields.contains(service->exec()) && service->noDisplay()) {
170 results[i] = 0;
173 } else {
174 desktopNames.insert(service->name(), i);
175 execFields.insert(service->exec());
180 QStringList pathResults;
181 foreach(const KService::Ptr &service, results) {
182 if (!service.isNull() && !service->noDisplay()) {
183 pathResults << service->entryPath();
186 emit resultsAvailable(pathResults);
189 QString ApplicationSearch::mimeNameForQuery(const QString& query) const
191 KMimeType::Ptr type = KMimeType::findByPath('.' + query, 0, true);
192 if (type) {
193 kDebug() << "Mime type name" << type->name();
194 return type->name();
196 return QString();
198 WebSearch::WebSearch(QObject *parent)
199 : SearchInterface(parent)
202 QString WebSearch::name() const
204 return i18n("Web Searches");
206 void WebSearch::setQuery(const QString& query)
208 ResultList results;
209 SearchResult googleResult;
210 googleResult.url = QString("http://www.google.com/search?q=%1").arg(query);
211 googleResult.title = i18n("Search web for '%1'", query);
212 results << googleResult;
213 emit resultsAvailable(results);
215 IndexerSearch::IndexerSearch(QObject *parent)
216 : SearchInterface(parent)
219 QString IndexerSearch::name() const
221 return i18n("Documents");
223 void IndexerSearch::setQuery(const QString& query)
225 #ifdef HAVE_STRIGIDBUS
226 static const StrigiClient searchClient;
228 QList<QString> urls;
229 QList<StrigiHit> hits = searchClient.getHits(query, 10, 0);
230 foreach(const StrigiHit& hit, hits) {
231 if (!hit.uri.isEmpty()) {
232 urls << hit.uri;
235 emit resultsAvailable(urls);
236 #endif
239 #include "searchmodel.moc"