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