on 6161205 help sign in
unity8/plugins/Unity/scope.cpp
286 lines 9.5 kB history raw
1/*
2 * Copyright (C) 2011 Canonical, Ltd.
3 *
4 * Authors:
5 * Florian Boucault <florian.boucault@canonical.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
20// Self
21#include "scope.h"
23// local
24#include "categories.h"
25#include "variantutils.h"
27// Qt
28#include <QUrl>
29#include <QDebug>
30#include <QtGui/QDesktopServices>
32#include <libintl.h>
34Scope::Scope(QObject *parent) :
35 QObject(parent)
37 m_results = new DeeListModel(this);
38 m_categories = new Categories(this);
40 m_categories->setResultModel(m_results);
43QString Scope::id() const
45 return QString::fromStdString(m_unityScope->id());
48QString Scope::name() const
50 return QString::fromStdString(m_unityScope->name());
53QString Scope::iconHint() const
55 return QString::fromStdString(m_unityScope->icon_hint());
58QString Scope::description() const
60 return QString::fromStdString(m_unityScope->description());
63QString Scope::searchHint() const
65 return QString::fromStdString(m_unityScope->search_hint());
68bool Scope::visible() const
70 return m_unityScope->visible();
73QString Scope::shortcut() const
75 return QString::fromStdString(m_unityScope->shortcut());
78bool Scope::connected() const
80 return m_unityScope->connected();
83DeeListModel* Scope::results() const
85 return m_results;
88Categories* Scope::categories() const
90 return m_categories;
93QString Scope::searchQuery() const
95 return m_searchQuery;
98QString Scope::noResultsHint() const
100 return m_noResultsHint;
103void Scope::setSearchQuery(const QString& search_query)
105 /* Checking for m_searchQuery.isNull() which returns true only when the string
106 has never been set is necessary because when search_query is the empty
107 string ("") and m_searchQuery is the null string,
108 search_query != m_searchQuery is still true.
109 */
110 if (m_searchQuery.isNull() || search_query != m_searchQuery) {
111 m_searchQuery = search_query;
112 m_unityScope->Search(search_query.toStdString(), sigc::mem_fun(this, &Scope::searchFinished));
113 Q_EMIT searchQueryChanged();
114 }
117void Scope::setNoResultsHint(const QString& hint) {
118 if (hint != m_noResultsHint) {
119 m_noResultsHint = hint;
120 Q_EMIT noResultsHintChanged();
121 }
124void Scope::activate(const QVariant &uri, const QVariant &icon_hint, const QVariant &category,
125 const QVariant &result_type, const QVariant &mimetype, const QVariant &title,
126 const QVariant &comment, const QVariant &dnd_uri, const QVariant &metadata)
128 unity::dash::LocalResult res;
129 res.uri = uri.toString().toStdString();
130 res.icon_hint = icon_hint.toString().toStdString();
131 res.category_index = category.toUInt();
132 res.result_type = result_type.toUInt();
133 res.mimetype = mimetype.toString().toStdString();
134 res.name = title.toString().toStdString();
135 res.comment = comment.toString().toStdString();
136 res.dnd_uri = dnd_uri.toString().toStdString();
137 res.hints = hintsMapFromQVariant(metadata);
139 m_unityScope->Activate(res);
142void Scope::onActivated(unity::dash::LocalResult const& result, unity::dash::ScopeHandledType type, unity::glib::HintsMap const&)
144 if (type == unity::dash::NOT_HANDLED) {
145 fallbackActivate(QString::fromStdString(result.uri));
146 }
149void Scope::fallbackActivate(const QString& uri)
151 /* FIXME: stripping all content before the first column because for some
152 reason the scopes give uri with junk content at their beginning.
153 */
154 QString tweakedUri = uri;
155 int firstColumnAt = tweakedUri.indexOf(":");
156 tweakedUri.remove(0, firstColumnAt+1);
158 /* Tries various methods to trigger a sensible action for the given 'uri'.
159 If it has no understanding of the given scheme it falls back on asking
160 Qt to open the uri.
161 */
162 QUrl url(tweakedUri);
163 if (url.scheme() == "file") {
164 /* Override the files place's default URI handler: we want the file
165 manager to handle opening folders, not the dash.
167 Ref: https://bugs.launchpad.net/upicek/+bug/689667
168 */
169 QDesktopServices::openUrl(url);
170 return;
171 }
172 if (url.scheme() == "application") {
173 // TODO: implement application handling
174 return;
175 }
177 qWarning() << "FIXME: Possibly no handler for scheme: " << url.scheme();
178 qWarning() << "Trying to open" << tweakedUri;
179 /* Try our luck */
180 QDesktopServices::openUrl(uri); //url?
183void Scope::setUnityScope(const unity::dash::Scope::Ptr& scope)
185 m_unityScope = scope;
187 if (QString::fromStdString(m_unityScope->results()->swarm_name) == QString(":local")) {
188 m_results->setModel(m_unityScope->results()->model());
189 } else {
190 m_results->setName(QString::fromStdString(m_unityScope->results()->swarm_name));
191 }
193 if (QString::fromStdString(m_unityScope->categories()->swarm_name) == QString(":local")) {
194 m_categories->setModel(m_unityScope->categories()->model());
195 } else {
196 m_categories->setName(QString::fromStdString(m_unityScope->categories()->swarm_name));
197 }
199 /* Property change signals */
200 m_unityScope->id.changed.connect(sigc::mem_fun(this, &Scope::idChanged));
201 m_unityScope->name.changed.connect(sigc::mem_fun(this, &Scope::nameChanged));
202 m_unityScope->icon_hint.changed.connect(sigc::mem_fun(this, &Scope::iconHintChanged));
203 m_unityScope->description.changed.connect(sigc::mem_fun(this, &Scope::descriptionChanged));
204 m_unityScope->search_hint.changed.connect(sigc::mem_fun(this, &Scope::searchHintChanged));
205 m_unityScope->visible.changed.connect(sigc::mem_fun(this, &Scope::visibleChanged));
206 m_unityScope->shortcut.changed.connect(sigc::mem_fun(this, &Scope::shortcutChanged));
207 m_unityScope->connected.changed.connect(sigc::mem_fun(this, &Scope::connectedChanged));
208 m_unityScope->results.changed.connect(sigc::mem_fun(this, &Scope::onResultsChanged));
209 m_unityScope->results()->swarm_name.changed.connect(sigc::mem_fun(this, &Scope::onResultsSwarmNameChanged));
210 m_unityScope->results()->model.changed.connect(sigc::mem_fun(this, &Scope::onResultsModelChanged));
211 m_unityScope->categories()->model.changed.connect(sigc::mem_fun(this, &Scope::onCategoriesModelChanged));
212 m_unityScope->categories.changed.connect(sigc::mem_fun(this, &Scope::onCategoriesChanged));
213 m_unityScope->categories()->swarm_name.changed.connect(sigc::mem_fun(this, &Scope::onCategoriesSwarmNameChanged));
214 /* Signals forwarding */
215 connect(this, SIGNAL(searchFinished(const std::string &, unity::glib::HintsMap const &, unity::glib::Error const &)), SLOT(onSearchFinished(const std::string &, unity::glib::HintsMap const &)));
217 /* FIXME: signal should be forwarded instead of calling the handler directly */
218 m_unityScope->activated.connect(sigc::mem_fun(this, &Scope::onActivated));
220 /* Synchronize local states with m_unityScope right now and whenever
221 m_unityScope becomes connected */
222 /* FIXME: should emit change notification signals for all properties */
223 connect(this, SIGNAL(connectedChanged(bool)), SLOT(synchronizeStates()));
224 synchronizeStates();
227unity::dash::Scope::Ptr Scope::unityScope() const
229 return m_unityScope;
232void Scope::synchronizeStates()
234 if (connected()) {
235 /* Forward local states to m_unityScope */
236 if (!m_searchQuery.isNull()) {
237 m_unityScope->Search(m_searchQuery.toStdString());
238 }
239 }
242void Scope::onResultsSwarmNameChanged(const std::string& /* swarm_name */)
244 m_results->setName(QString::fromStdString(m_unityScope->results()->swarm_name));
247void Scope::onResultsChanged(const unity::dash::Results::Ptr& /* results */)
249 m_results->setName(QString::fromStdString(m_unityScope->results()->swarm_name));
252void Scope::onResultsModelChanged(unity::glib::Object<DeeModel> /* model */)
254 m_results->setModel(m_unityScope->results()->model());
257void Scope::onCategoriesSwarmNameChanged(const std::string& /* swarm_name */)
259 m_categories->setName(QString::fromStdString(m_unityScope->categories()->swarm_name));
262void Scope::onCategoriesChanged(const unity::dash::Categories::Ptr& /* categories */)
264 m_categories->setName(QString::fromStdString(m_unityScope->categories()->swarm_name));
267void Scope::onCategoriesModelChanged(unity::glib::Object<DeeModel> model)
269 m_categories->setModel(model);
272void Scope::onSearchFinished(const std::string& /* query */, unity::glib::HintsMap const &hints)
274 QString hint;
276 if (!m_unityScope->results()->count()) {
277 unity::glib::HintsMap::const_iterator it = hints.find("no-results-hint");
278 if (it != hints.end()) {
279 hint = QString::fromStdString(it->second.GetString());
280 } else {
281 hint = QString::fromUtf8(dgettext("unity", "Sorry, there is nothing that matches your search."));
282 }
283 }
285 setNoResultsHint(hint);