Unity 8
rootstateparser.cpp
1 /*
2  * Copyright 2013 Canonical Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation; version 3.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 #include "rootstateparser.h"
18 
19 extern "C" {
20 #include <glib.h>
21 #include <gio/gio.h>
22 }
23 
24 RootStateParser::RootStateParser(QObject* parent)
25  : ActionStateParser(parent)
26 {
27 }
28 
29 static QString iconUri(GIcon *icon)
30 {
31  QString uri;
32 
33  if (G_IS_THEMED_ICON (icon)) {
34  const gchar* const* iconNames = g_themed_icon_get_names (G_THEMED_ICON (icon));
35 
36  QStringList iconNameList;
37  for (uint index = 0; iconNames[index] != nullptr; index++) {
38  iconNameList << iconNames[index];
39  }
40 
41  if (!iconNameList.empty()) {
42  uri = QStringLiteral("image://theme/%1").arg(iconNameList.join(QStringLiteral(",")));
43  }
44  }
45  else if (G_IS_FILE_ICON (icon)) {
46  GFile *file;
47 
48  file = g_file_icon_get_file (G_FILE_ICON (icon));
49  if (g_file_is_native (file)) {
50  gchar *fileuri;
51 
52  fileuri = g_file_get_path (file);
53  uri = QString(fileuri);
54 
55  g_free (fileuri);
56  }
57  }
58  else if (G_IS_BYTES_ICON (icon)) {
59  gsize size;
60  gconstpointer data;
61  gchar *base64;
62 
63  data = g_bytes_get_data (g_bytes_icon_get_bytes (G_BYTES_ICON (icon)), &size);
64  base64 = g_base64_encode ((const guchar *) data, size);
65 
66  uri = QStringLiteral("data://");
67  uri.append (base64);
68 
69  g_free (base64);
70  }
71 
72  return uri;
73 }
74 
75 QVariant RootStateParser::toQVariant(GVariant* state) const
76 {
77  if (!state) {
78  return QVariant();
79  }
80 
81  if (g_variant_is_of_type(state, G_VARIANT_TYPE_VARDICT)) {
82  GVariantIter iter;
83  GVariant *vvalue;
84  gchar *key;
85  QVariantMap qmap;
86 
87  g_variant_iter_init (&iter, state);
88  while (g_variant_iter_loop (&iter, "{sv}", &key, &vvalue))
89  {
90  QString str = QString::fromUtf8(key);
91  if (str == QLatin1String("icon") && !qmap.contains(QStringLiteral("icons"))) {
92  QStringList icons;
93 
94  // FIXME - should be sending a url.
95  GIcon *gicon = g_icon_deserialize (vvalue);
96  if (gicon) {
97  icons << iconUri(gicon);
98  g_object_unref (gicon);
99  }
100  qmap.insert(QStringLiteral("icons"), icons);
101 
102  } else if (str == QLatin1String("icons")) {
103 
104  QStringList icons;
105 
106  if (g_variant_is_of_type(vvalue, G_VARIANT_TYPE("av"))) {
107  GVariantIter iter;
108  GVariant *val = 0;
109  g_variant_iter_init (&iter, vvalue);
110  while (g_variant_iter_loop (&iter, "v", &val))
111  {
112  // FIXME - should be sending a url.
113  GIcon *gicon = g_icon_deserialize (val);
114  if (gicon) {
115  icons << iconUri(gicon);
116  g_object_unref (gicon);
117  }
118  }
119  }
120  // will overwrite icon.
121  qmap.insert(QStringLiteral("icons"), icons);
122 
123  } else {
124  qmap.insert(str, ActionStateParser::toQVariant(vvalue));
125  }
126  }
127 
128  return QVariant::fromValue(qmap);
129 
130  } else if (g_variant_is_of_type (state, G_VARIANT_TYPE ("(sssb)"))) {
131  QVariantMap qmap;
132 
133  char* label;
134  char* icon;
135  char* accessible_name;
136  gboolean visible;
137  GIcon *gicon;
138 
139  g_variant_get(state, "(sssb)", &label,
140  &icon,
141  &accessible_name,
142  &visible);
143 
144  qmap[QStringLiteral("label")] = label ? QString::fromUtf8(label) : QLatin1String("");
145  qmap[QStringLiteral("accessible-desc")] = accessible_name ? QString::fromUtf8(accessible_name) : QLatin1String("");
146  qmap[QStringLiteral("visible")] = visible;
147 
148  gicon = g_icon_new_for_string (icon, nullptr);
149  if (gicon) {
150  qmap[QStringLiteral("icons")] = QStringList() << iconUri(gicon);
151  g_object_unref (gicon);
152  }
153 
154  if (label) g_free(label);
155  if (icon) g_free(icon);
156  if (accessible_name) g_free(accessible_name);
157 
158  return QVariant::fromValue(qmap);
159  }
160  return ActionStateParser::toQVariant(state);
161 }
162 
163 
164 RootStateObject::RootStateObject(QObject* parent)
165  : QObject(parent)
166 {
167 }
168 
169 QString RootStateObject::title() const
170 {
171  if (!valid()) return QString();
172 
173  return m_currentState.value(QStringLiteral("title"), QVariant::fromValue(QString())).toString();
174 }
175 
176 QString RootStateObject::leftLabel() const
177 {
178  if (!valid()) return QString();
179 
180  return m_currentState.value(QStringLiteral("pre-label"), QVariant::fromValue(QString())).toString();
181 }
182 
183 QString RootStateObject::rightLabel() const
184 {
185  if (!valid()) return QString();
186 
187  return m_currentState.value(QStringLiteral("label"), QVariant::fromValue(QString())).toString();
188 }
189 
190 QStringList RootStateObject::icons() const
191 {
192  if (!valid()) return QStringList();
193 
194  return m_currentState.value(QStringLiteral("icons"), QVariant::fromValue(QStringList())).toStringList();
195 }
196 
197 QString RootStateObject::accessibleName() const
198 {
199  if (!valid()) return QString();
200 
201  return m_currentState.value(QStringLiteral("accessible-desc"), QVariant::fromValue(QString())).toString();
202 }
203 
204 bool RootStateObject::indicatorVisible() const
205 {
206  if (!valid()) return false;
207 
208  return m_currentState.value(QStringLiteral("visible"), QVariant::fromValue(true)).toBool();
209 }
210 
211 void RootStateObject::setCurrentState(const QVariantMap& newState)
212 {
213  QString oldTitle = title();
214  QString oldLeftLabel = leftLabel();
215  QString oldRightLabel = rightLabel();
216  QStringList oldIcons = icons();
217  QString oldAccessibleName = accessibleName();
218  bool oldIndicatorVisible = indicatorVisible();
219 
220  if (m_currentState != newState) {
221  m_currentState = newState;
222  Q_EMIT updated();
223 
224  if (oldTitle != title()) Q_EMIT titleChanged();
225  if (oldLeftLabel != leftLabel()) Q_EMIT leftLabelChanged();
226  if (oldRightLabel != rightLabel()) Q_EMIT rightLabelChanged();
227  if (oldIcons != icons()) Q_EMIT iconsChanged();
228  if (oldAccessibleName != accessibleName()) Q_EMIT accessibleNameChanged();
229  if (oldIndicatorVisible != indicatorVisible()) Q_EMIT indicatorVisibleChanged();
230  }
231 }