Applets
searchmodel.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "core/searchmodel.h"
00022
00023 #include "config-kickoff-applets.h"
00024
00025
00026
00027 #include <KDebug>
00028 #include <KMimeType>
00029 #include <KServiceTypeTrader>
00030 #ifdef HAVE_STRIGIDBUS
00031 #include <strigi/qtdbus/strigiclient.h>
00032 #endif
00033 #include <solid/networking.h>
00034
00035
00036 #include "core/models.h"
00037
00038 using namespace Kickoff;
00039
00040 class SearchModel::Private
00041 {
00042 public:
00043 Private(SearchModel *parent) : q(parent) {}
00044
00045 void addItemForIface(SearchInterface *iface, QStandardItem *item) {
00046 int index = searchIfaces.indexOf(iface);
00047 Q_ASSERT(index >= 0);
00048 q->item(index)->appendRow(item);
00049 }
00050 void clear() {
00051 for (int i = 0;i < q->rowCount();i++) {
00052 q->item(i)->removeRows(0, q->item(i)->rowCount());
00053 }
00054 }
00055
00056 SearchModel * const q;
00057 QList<SearchInterface*> searchIfaces;
00058 };
00059
00060 SearchModel::SearchModel(QObject *parent)
00061 : KickoffModel(parent)
00062 , d(new Private(this))
00063 {
00064 d->searchIfaces << new ApplicationSearch(this);
00065
00066 d->searchIfaces << new WebSearch(this);
00067
00068 foreach(SearchInterface *iface, d->searchIfaces) {
00069 QStandardItem *ifaceItem = new QStandardItem(iface->name());
00070 appendRow(ifaceItem);
00071 connect(iface, SIGNAL(resultsAvailable(QStringList)),
00072 this, SLOT(resultsAvailable(QStringList)));
00073 connect(iface, SIGNAL(resultsAvailable(ResultList)),
00074 this, SLOT(resultsAvailable(ResultList)));
00075 connect(iface, SIGNAL(resultsAvailable(QStringList)),
00076 this, SIGNAL(resultsAvailable()));
00077 connect(iface, SIGNAL(resultsAvailable(ResultList)),
00078 this, SIGNAL(resultsAvailable()));
00079 }
00080 }
00081 SearchModel::~SearchModel()
00082 {
00083 delete d;
00084 }
00085 void SearchModel::resultsAvailable(const QStringList& results)
00086 {
00087 SearchInterface *iface = qobject_cast<SearchInterface*>(sender());
00088
00089 Q_ASSERT(iface);
00090
00091 foreach(const QString& result, results) {
00092
00093 QStandardItem *resultItem = StandardItemFactory::createItemForUrl(result);
00094 d->addItemForIface(iface, resultItem);
00095 }
00096 }
00097 void SearchModel::resultsAvailable(const ResultList& results)
00098 {
00099 SearchInterface *iface = qobject_cast<SearchInterface*>(sender());
00100
00101 Q_ASSERT(iface);
00102
00103 foreach(const SearchResult& result, results) {
00104 QStandardItem *item = StandardItemFactory::createItemForUrl(result.url);
00105 item->setData(result.title, Qt::DisplayRole);
00106 item->setData(result.subTitle, SubTitleRole);
00107 d->addItemForIface(iface, item);
00108 }
00109 }
00110 void SearchModel::setQuery(const QString& query)
00111 {
00112 d->clear();
00113
00114 if (query.isEmpty()) {
00115 return;
00116 }
00117
00118 foreach(SearchInterface *iface, d->searchIfaces) {
00119 iface->setQuery(query);
00120 }
00121 }
00122
00123 SearchInterface::SearchInterface(QObject *parent)
00124 : QObject(parent)
00125 {
00126 }
00127
00128 ApplicationSearch::ApplicationSearch(QObject *parent)
00129 : SearchInterface(parent)
00130 {
00131 }
00132
00133 QString ApplicationSearch::name() const
00134 {
00135 return i18n("Applications");
00136 }
00137
00138 void ApplicationSearch::setQuery(const QString& query)
00139 {
00140
00141 QString traderQuery = QString("((exist GenericName) and ('%1' ~~ GenericName)) or ('%1' ~~ Name) or ('%1' ~~ Exec) or ((exist Keywords) and ('%1' ~in Keywords))"
00142
00143 )
00144 .arg(query);
00145 KServiceTypeTrader *trader = KServiceTypeTrader::self();
00146 KService::List results = trader->query("Application", traderQuery);
00147
00148
00149
00150 QHash<QString, int> desktopNames;
00151 QSet<QString> execFields;
00152
00153
00154 for (int i = 0;i < results.count();i++) {
00155 KService::Ptr service = results[i];
00156 int existingPos = desktopNames.value(service->name(), -1);
00157 KService::Ptr existing = existingPos < 0 ? KService::Ptr(0) : results[existingPos];
00158
00159
00160 if (!existing.isNull()) {
00161 if (isLaterVersion(existing, service)) {
00162 results[i] = 0;
00163 } else if (isLaterVersion(service, existing)) {
00164 results[existingPos] = 0;
00165 } else {
00166
00167
00168
00169 if (execFields.contains(service->exec()) && service->noDisplay()) {
00170 results[i] = 0;
00171 }
00172 }
00173 } else {
00174 desktopNames.insert(service->name(), i);
00175 execFields.insert(service->exec());
00176 }
00177 }
00178
00179
00180 QStringList pathResults;
00181 foreach(const KService::Ptr &service, results) {
00182 if (!service.isNull() && !service->noDisplay()) {
00183 pathResults << service->entryPath();
00184 }
00185 }
00186 emit resultsAvailable(pathResults);
00187 }
00188
00189 QString ApplicationSearch::mimeNameForQuery(const QString& query) const
00190 {
00191 KMimeType::Ptr type = KMimeType::findByPath('.' + query, 0, true);
00192 if (type) {
00193 kDebug() << "Mime type name" << type->name();
00194 return type->name();
00195 }
00196 return QString();
00197 }
00198 WebSearch::WebSearch(QObject *parent)
00199 : SearchInterface(parent)
00200 {
00201 }
00202 QString WebSearch::name() const
00203 {
00204 return i18n("Web Searches");
00205 }
00206 void WebSearch::setQuery(const QString& query)
00207 {
00208 ResultList results;
00209 SearchResult googleResult;
00210 googleResult.url = QString("http://www.google.com/search?q=%1").arg(query);
00211 googleResult.title = i18n("Search web for '%1'", query);
00212 results << googleResult;
00213 emit resultsAvailable(results);
00214 }
00215 IndexerSearch::IndexerSearch(QObject *parent)
00216 : SearchInterface(parent)
00217 {
00218 }
00219 QString IndexerSearch::name() const
00220 {
00221 return i18n("Documents");
00222 }
00223 void IndexerSearch::setQuery(const QString& query)
00224 {
00225 #ifdef HAVE_STRIGIDBUS
00226 static const StrigiClient searchClient;
00227
00228 QList<QString> urls;
00229 QList<StrigiHit> hits = searchClient.getHits(query, 10, 0);
00230 foreach(const StrigiHit& hit, hits) {
00231 if (!hit.uri.isEmpty()) {
00232 urls << hit.uri;
00233 }
00234 }
00235 emit resultsAvailable(urls);
00236 #endif
00237 }
00238
00239 #include "searchmodel.moc"