17 #include "hudclient.h"
19 #include "hudtoolbarmodel.h"
21 #include <deelistmodel.h>
31 void loadingCB(GObject* , gpointer dst)
33 static_cast<HudClient*
>(dst)->voiceQueryLoading();
36 void listeningCB(GObject* , gpointer dst)
38 static_cast<HudClient*
>(dst)->voiceQueryListening();
41 void heardSomethingCB(GObject* , gpointer dst)
43 static_cast<HudClient*
>(dst)->voiceQueryHeardSomething();
46 void failedCB(GObject* ,
const gchar * , gpointer dst)
48 static_cast<HudClient*
>(dst)->voiceQueryFailed();
51 void finishedCB(GObject* ,
const gchar* query, gpointer dst)
53 static_cast<HudClient*
>(dst)->voiceQueryFinished(QString::fromUtf8(query));
56 void modelReadyCB(GObject* , gpointer dst)
58 static_cast<HudClient*
>(dst)->modelReady(
true);
61 void modelReallyReadyCB(GObject* , gint , gint , gint , gpointer dst)
63 static_cast<HudClient*
>(dst)->modelReallyReady(
true);
66 static void modelsChangedCB(GObject* , gpointer dst)
68 static_cast<HudClient*
>(dst)->queryModelsChanged();
71 static void toolBarUpdatedCB(GObject* , gpointer dst)
73 static_cast<HudToolBarModel*
>(dst)->updatedByBackend();
80 HudClient::HudClient()
82 m_results =
new DeeListModel();
83 m_clientQuery = hud_client_query_new(
"");
84 m_toolBarModel =
new HudToolBarModel(m_clientQuery);
85 m_currentActionParam =
nullptr;
86 m_results->setModel(hud_client_query_get_results_model(m_clientQuery));
88 g_signal_connect(G_OBJECT(m_clientQuery),
"voice-query-loading", G_CALLBACK(loadingCB),
this);
89 g_signal_connect(G_OBJECT(m_clientQuery),
"voice-query-listening", G_CALLBACK(listeningCB),
this);
90 g_signal_connect(G_OBJECT(m_clientQuery),
"voice-query-heard-something", G_CALLBACK(heardSomethingCB),
this);
91 g_signal_connect(G_OBJECT(m_clientQuery),
"voice-query-finished", G_CALLBACK(finishedCB),
this);
92 g_signal_connect(G_OBJECT(m_clientQuery),
"voice-query-failed", G_CALLBACK(failedCB),
this);
93 g_signal_connect(G_OBJECT(m_clientQuery), HUD_CLIENT_QUERY_SIGNAL_MODELS_CHANGED, G_CALLBACK(modelsChangedCB),
this);
94 g_signal_connect(G_OBJECT(m_clientQuery), HUD_CLIENT_QUERY_SIGNAL_TOOLBAR_UPDATED, G_CALLBACK(toolBarUpdatedCB), m_toolBarModel);
105 ToGPointer(
void (*cb)())
123 #define TO_GPOINTER(cb) (ToGPointer(reinterpret_cast<void(*)()>((cb))))
125 HudClient::~HudClient()
127 g_signal_handlers_disconnect_by_func(G_OBJECT(m_clientQuery), TO_GPOINTER(loadingCB),
this);
128 g_signal_handlers_disconnect_by_func(G_OBJECT(m_clientQuery), TO_GPOINTER(listeningCB),
this);
129 g_signal_handlers_disconnect_by_func(G_OBJECT(m_clientQuery), TO_GPOINTER(heardSomethingCB),
this);
130 g_signal_handlers_disconnect_by_func(G_OBJECT(m_clientQuery), TO_GPOINTER(finishedCB),
this);
131 g_signal_handlers_disconnect_by_func(G_OBJECT(m_clientQuery), TO_GPOINTER(toolBarUpdatedCB), m_toolBarModel);
134 delete m_toolBarModel;
136 g_object_unref(m_clientQuery);
139 void HudClient::setQuery(
const QString &new_query)
141 hud_client_query_set_query(m_clientQuery, new_query.toUtf8().constData());
144 void HudClient::startVoiceQuery()
146 hud_client_query_voice_query(m_clientQuery);
149 void HudClient::executeParametrizedAction(
const QVariant &values)
151 updateParametrizedAction(values);
152 hud_client_param_send_commit(m_currentActionParam);
153 g_object_unref(m_currentActionParam);
154 m_currentActionParam =
nullptr;
155 Q_EMIT commandExecuted();
158 void HudClient::updateParametrizedAction(
const QVariant &values)
160 if (m_currentActionParam !=
nullptr) {
161 const QVariantMap map = values.value<QVariantMap>();
162 GActionGroup *ag = hud_client_param_get_actions(m_currentActionParam);
164 auto it = map.begin();
165 for ( ; it != map.end(); ++it) {
166 const QString action = it.key();
167 const QVariant value = it.value();
168 const GVariantType *actionType = g_action_group_get_action_parameter_type(ag, action.toUtf8().constData());
169 if (g_variant_type_equal(actionType, G_VARIANT_TYPE_DOUBLE) && value.canConvert(QVariant::Double)) {
170 g_action_group_activate_action(ag, action.toUtf8().constData(), g_variant_new_double(value.toDouble()));
172 qWarning() <<
"Unsuported action type in HudClient::executeParametrizedAction";
176 qWarning() <<
"Got to HudClient::updateParametrizedAction with no m_currentActionParam";
180 void HudClient::cancelParametrizedAction()
182 if (m_currentActionParam !=
nullptr) {
183 hud_client_param_send_cancel(m_currentActionParam);
184 g_object_unref(m_currentActionParam);
185 m_currentActionParam =
nullptr;
189 void HudClient::executeToolBarAction(HudClientQueryToolbarItems action)
191 hud_client_query_execute_toolbar_item(m_clientQuery, action, 0);
192 Q_EMIT commandExecuted();
195 DeeListModel *HudClient::results()
const
200 QAbstractItemModel *HudClient::toolBarModel()
const
202 return m_toolBarModel;
205 void HudClient::executeCommand(
int index)
207 m_currentActionIndex = index;
208 DeeModel *model = hud_client_query_get_results_model(m_clientQuery);
209 DeeModelIter *iter = dee_model_get_iter_at_row(model, index);
211 GVariant *command_key = dee_model_get_value(model, iter, 0);
212 GVariant *is_parametrized = dee_model_get_value(model, iter, 7);
213 if (g_variant_get_boolean(is_parametrized)) {
214 m_currentActionParam = hud_client_query_execute_param_command(m_clientQuery, command_key, 0);
215 if (m_currentActionParam !=
nullptr) {
216 GMenuModel *menuModel = hud_client_param_get_model (m_currentActionParam);
217 if (menuModel ==
nullptr) {
218 g_signal_connect(m_currentActionParam, HUD_CLIENT_PARAM_SIGNAL_MODEL_READY, G_CALLBACK(modelReadyCB),
this);
223 qWarning() <<
"HudClient::executeCommand::Could not get the HudClientParam for parametrized action with index" << index;
226 hud_client_query_execute_command(m_clientQuery, command_key, 0);
227 Q_EMIT commandExecuted();
229 g_variant_unref(command_key);
230 g_variant_unref(is_parametrized);
233 void HudClient::modelReady(
bool needDisconnect)
235 if (needDisconnect) {
236 g_signal_handlers_disconnect_by_func(m_currentActionParam, TO_GPOINTER(modelReadyCB),
this);
238 GMenuModel *menuModel = hud_client_param_get_model (m_currentActionParam);
239 if (g_menu_model_get_n_items(menuModel) == 0) {
240 g_signal_connect(menuModel,
"items-changed", G_CALLBACK(modelReallyReadyCB),
this);
242 modelReallyReady(
false);
246 static void addAttribute(QVariantMap &properties, GMenuModel *menuModel,
int item,
const char *attribute) {
247 GVariant *v = g_menu_model_get_item_attribute_value(menuModel, item, attribute,
nullptr);
252 properties.insert(attribute, DeeListModel::VariantForData(v));
256 void HudClient::modelReallyReady(
bool needDisconnect)
258 GMenuModel *menuModel = hud_client_param_get_model (m_currentActionParam);
259 if (needDisconnect) {
260 g_signal_handlers_disconnect_by_func(menuModel, TO_GPOINTER(modelReallyReadyCB),
this);
264 for (
int i = 0; i < g_menu_model_get_n_items(menuModel); i++) {
265 GVariant *v = g_menu_model_get_item_attribute_value(menuModel, i,
"parameter-type", G_VARIANT_TYPE_STRING);
270 const QString type = QString::fromUtf8(g_variant_get_string(v,
nullptr));
271 if (type ==
"slider") {
272 const char *sliderAttributes[] = {
"label",
"min",
"max",
"step",
"value",
"live",
"action" };
273 QVariantMap properties;
274 properties.insert(
"parameter-type",
"slider");
275 for (uint j = 0; j <
sizeof(sliderAttributes)/
sizeof(sliderAttributes[0]); ++j) {
276 addAttribute(properties, menuModel, i, sliderAttributes[j]);
283 DeeModel *model = hud_client_query_get_results_model(m_clientQuery);
284 DeeModelIter *iter = dee_model_get_iter_at_row(model, m_currentActionIndex);
285 GVariant *actionTextVariant = dee_model_get_value(model, iter, 1);
286 const QString actionText = QString::fromUtf8(g_variant_get_string(actionTextVariant,
nullptr));
287 g_variant_unref(actionTextVariant);
288 Q_EMIT showParametrizedAction(actionText, QVariant::fromValue(items));
291 void HudClient::queryModelsChanged()
293 m_results->setModel(hud_client_query_get_results_model(m_clientQuery));