~canonical-dx-team/unity/unity.fix-ql-losing-focus

798.5.1 by Mikkel Kamstrup Erlandsen
Add initial stubs to support the com.canonical.Unity.LauncherEntry DBus API in Unity
1
// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2
/*
3
 * Copyright (C) 2011 Canonical Ltd
4
 *
5
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License version 3 as
7
 * published by the Free Software Foundation.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
 *
17
 * Authored by: Mikkel Kamstrup Erlandsen <mikkel.kamstrup@canonical.com>
18
 */
19
20
#include "LauncherEntryRemote.h"
21
798.5.7 by Mikkel Kamstrup Erlandsen
Fix LauncherEntryRemote to apply the right magic Nux Object macros
22
NUX_IMPLEMENT_OBJECT_TYPE (LauncherEntryRemote);
23
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
24
/**
25
 * Create a new LauncherEntryRemote parsed from the raw DBus wire format
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
26
 * of the com.canonical.Unity.LauncherEntry.Update signal '(sa{sv})'. The
27
 * dbus_name argument should be the unique bus name of the process owning
28
 * the launcher entry.
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
29
 *
30
 * You don't normally need to use this constructor yourself. The
31
 * LauncherEntryRemoteModel will do that for you when needed.
32
 */
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
33
LauncherEntryRemote::LauncherEntryRemote(const gchar *dbus_name, GVariant *val)
798.5.1 by Mikkel Kamstrup Erlandsen
Add initial stubs to support the com.canonical.Unity.LauncherEntry DBus API in Unity
34
{
829.2.1 by Neil Jagdish Patel
started to copy things into final implementation
35
  gchar        *app_uri;
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
36
  GVariantIter *prop_iter;
37
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
38
  g_return_if_fail (dbus_name != NULL);
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
39
  g_return_if_fail (val != NULL);
40
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
41
  _dbus_name = g_strdup (dbus_name);
42
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
43
  _emblem = NULL;
44
  _count = G_GINT64_CONSTANT (0);
45
  _progress = 0.0;
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
46
  _quicklist = NULL;
798.5.1 by Mikkel Kamstrup Erlandsen
Add initial stubs to support the com.canonical.Unity.LauncherEntry DBus API in Unity
47
  
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
48
  _emblem_visible = FALSE;
49
  _count_visible = FALSE;
50
  _progress_visible = FALSE;
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
51
52
  g_variant_ref_sink (val);
53
  g_variant_get (val, "(sa{sv})", &app_uri, &prop_iter);
54
55
  _app_uri = app_uri; // steal ref
56
811.2.1 by Mikkel Kamstrup Erlandsen
Slight change in how Update() DBus signals are treated in the Launcher API. By definition they only contain the "delta" - ie. the changed properties. Before this fix we always replaced all entry properties wholesale.
57
  Update (prop_iter);
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
58
59
  g_variant_iter_free (prop_iter);
60
  g_variant_unref (val);
798.5.1 by Mikkel Kamstrup Erlandsen
Add initial stubs to support the com.canonical.Unity.LauncherEntry DBus API in Unity
61
}
62
63
LauncherEntryRemote::~LauncherEntryRemote()
64
{
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
65
  if (_dbus_name)
66
    {
67
      g_free (_dbus_name);
68
      _dbus_name = NULL;
69
    }
70
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
71
  if (_app_uri)
72
    {
73
      g_free (_app_uri);
74
      _app_uri = NULL;
75
    }
798.5.1 by Mikkel Kamstrup Erlandsen
Add initial stubs to support the com.canonical.Unity.LauncherEntry DBus API in Unity
76
  
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
77
  if (_emblem)
78
    {
79
      g_free (_emblem);
80
      _emblem = NULL;
81
    }
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
82
83
  if (_quicklist)
84
    {
85
      g_object_unref (_quicklist);
86
      _quicklist = NULL;
87
    }
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
88
}
89
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
90
/**
91
 * The appuri property is on the form application://$desktop_file_id and is
92
 * used within the LauncherEntryRemoteModel to uniquely identify the various
93
 * applications.
94
 *
95
 * Note that a desktop file id is defined to be the base name of the desktop
96
 * file including the extension. Eg. gedit.desktop. Thus a full appuri could be
97
 * application://gedit.desktop.
98
 */
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
99
const gchar*
100
LauncherEntryRemote::AppUri()
101
{
102
  return _app_uri;
103
}
104
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
105
/**
106
 * Return the unique DBus name for the remote party owning this launcher entry.
107
 */
108
const gchar*
109
LauncherEntryRemote::DBusName()
110
{
111
  return _dbus_name;
112
}
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
113
114
const gchar*
115
LauncherEntryRemote::Emblem()
116
{
117
  return _emblem;
118
}
119
120
gint64
121
LauncherEntryRemote::Count()
122
{
123
  return _count;
124
}
125
126
gdouble
127
LauncherEntryRemote::Progress()
128
{
129
  return _progress;
130
}
131
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
132
/**
133
 * Return a pointer to the current quicklist of the launcher entry; NULL if
134
 * it's unset.
135
 *
136
 * The returned object should not be freed.
137
 */
138
DbusmenuClient*
139
LauncherEntryRemote::Quicklist()
140
{
141
  return _quicklist;
142
}
143
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
144
gboolean
145
LauncherEntryRemote::EmblemVisible()
146
{
147
  return _emblem_visible;
148
}
149
150
gboolean
151
LauncherEntryRemote::CountVisible()
152
{
153
  return _count_visible;
154
}
155
156
gboolean
157
LauncherEntryRemote::ProgressVisible()
158
{
159
  return _progress_visible;
160
}
161
798.5.9 by Mikkel Kamstrup Erlandsen
Add support for dynamically updating the unique DBus name owning a LauncherEntryRemote
162
/**
163
 * Set the unique DBus name for the process owning the launcher entry.
164
 *
165
 * If the entry has any exported quicklist it will be removed.
166
 */
167
void
168
LauncherEntryRemote::SetDBusName(const gchar* dbus_name)
169
{
170
  gchar *old_name;
171
172
  if (g_strcmp0 (_dbus_name, dbus_name) == 0)
173
    return;
174
175
  old_name = _dbus_name;
176
  _dbus_name = g_strdup (dbus_name);
177
178
  /* Remove the quicklist since we can't know if it it'll be valid on the
179
   * new name, and we certainly don't want the quicklist to operate on a
180
   * different name than the rest of the launcher API */
181
  SetQuicklist (NULL);
182
811.1.6 by Jason Smith
hook up libunity to launcher
183
  dbus_name_changed.emit (this, old_name);
798.5.9 by Mikkel Kamstrup Erlandsen
Add support for dynamically updating the unique DBus name owning a LauncherEntryRemote
184
  g_free (old_name);
185
}
186
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
187
void
188
LauncherEntryRemote::SetEmblem(const gchar* emblem)
189
{
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
190
  if (g_strcmp0 (_emblem, emblem) == 0)
191
    return;
192
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
193
  if (_emblem)
194
    g_free (_emblem);
195
196
  _emblem = g_strdup (emblem);
811.1.6 by Jason Smith
hook up libunity to launcher
197
  emblem_changed.emit (this);
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
198
}
199
200
void
201
LauncherEntryRemote::SetCount(gint64 count)
202
{
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
203
  if (_count == count)
204
    return;
205
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
206
  _count = count;
811.1.6 by Jason Smith
hook up libunity to launcher
207
  count_changed.emit (this);
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
208
}
209
210
void
211
LauncherEntryRemote::SetProgress(gdouble progress)
212
{
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
213
  if (_progress == progress)
214
    return;
215
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
216
  _progress = progress;
811.1.6 by Jason Smith
hook up libunity to launcher
217
  progress_changed.emit (this);
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
218
}
219
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
220
/**
221
 * Set the quicklist of this entry to be the Dbusmenu on the given path.
222
 * If entry already has a quicklist with the same path this call is a no-op.
223
 *
811.2.1 by Mikkel Kamstrup Erlandsen
Slight change in how Update() DBus signals are treated in the Launcher API. By definition they only contain the "delta" - ie. the changed properties. Before this fix we always replaced all entry properties wholesale.
224
 * To unset the quicklist pass in a NULL path or empty string.
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
225
 */
226
void
227
LauncherEntryRemote::SetQuicklistPath(const gchar *dbus_path)
228
{
811.2.1 by Mikkel Kamstrup Erlandsen
Slight change in how Update() DBus signals are treated in the Launcher API. By definition they only contain the "delta" - ie. the changed properties. Before this fix we always replaced all entry properties wholesale.
229
  /* Replace "" with NULL to simplify the logic below */
230
  if (g_strcmp0 ("", dbus_path) == 0)
231
    {
232
      dbus_path = NULL;
233
    }
234
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
235
  /* Check if existing quicklist have exact same path
236
   * and ignore the change in that case */
237
  if (_quicklist)
238
    {
239
      gchar *ql_path;
240
      g_object_get (_quicklist, DBUSMENU_CLIENT_PROP_DBUS_OBJECT, &ql_path, NULL);
241
      if (g_strcmp0 (dbus_path, ql_path) == 0)
242
        {
243
          g_free (ql_path);
244
          return;
245
        }
246
247
      /* Prepare for a new quicklist */
248
      g_free (ql_path);
249
      g_object_unref (_quicklist);
250
    }
251
  else if (_quicklist == NULL && dbus_path == NULL)
252
    return;
253
254
  if (dbus_path != NULL)
255
    _quicklist = dbusmenu_client_new (_dbus_name, dbus_path);
256
  else
257
    _quicklist = NULL;
258
811.1.6 by Jason Smith
hook up libunity to launcher
259
  quicklist_changed.emit (this);
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
260
}
261
262
/**
263
 * Set the quicklist of this entry to a given DbusmenuClient.
264
 * If entry already has a quicklist with the same path this call is a no-op.
265
 *
266
 * To unset the quicklist for this entry pass in NULL as the quicklist to set.
267
 */
268
void
269
LauncherEntryRemote::SetQuicklist(DbusmenuClient *quicklist)
270
{
271
  /* Check if existing quicklist have exact same path as the new one
798.5.9 by Mikkel Kamstrup Erlandsen
Add support for dynamically updating the unique DBus name owning a LauncherEntryRemote
272
   * and ignore the change in that case. We also assert that the quicklist
273
   * uses the same name as the connection owning this launcher entry */
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
274
  if (_quicklist)
275
    {
798.5.9 by Mikkel Kamstrup Erlandsen
Add support for dynamically updating the unique DBus name owning a LauncherEntryRemote
276
      gchar *ql_path, *new_ql_path, *new_ql_name;
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
277
      g_object_get (_quicklist, DBUSMENU_CLIENT_PROP_DBUS_OBJECT, &ql_path, NULL);
278
279
      if (quicklist == NULL)
798.5.9 by Mikkel Kamstrup Erlandsen
Add support for dynamically updating the unique DBus name owning a LauncherEntryRemote
280
        {
281
          new_ql_path = NULL;
282
          new_ql_name = NULL;
283
        }
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
284
      else
798.5.9 by Mikkel Kamstrup Erlandsen
Add support for dynamically updating the unique DBus name owning a LauncherEntryRemote
285
        {
286
          g_object_get (quicklist, DBUSMENU_CLIENT_PROP_DBUS_OBJECT, &new_ql_path, NULL);
287
          g_object_get (quicklist, DBUSMENU_CLIENT_PROP_DBUS_NAME, &new_ql_name, NULL);
288
        }
289
798.5.11 by Mikkel Kamstrup Erlandsen
Lax overly strict DBus name checking in LauncherEntryRemote::SetQuicklist()
290
      if (quicklist != NULL && g_strcmp0 (new_ql_name, _dbus_name) != 0)
798.5.9 by Mikkel Kamstrup Erlandsen
Add support for dynamically updating the unique DBus name owning a LauncherEntryRemote
291
        {
292
          g_critical ("Mismatch between quicklist- and launcher entry owner:"
293
                      "%s and %s respectively", new_ql_name, _dbus_name);
294
          g_free (ql_path);
295
          g_free (new_ql_path);
296
          g_free (new_ql_name);
297
          return;
298
        }
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
299
300
      if (g_strcmp0 (new_ql_path, ql_path) == 0)
301
        {
302
          g_free (ql_path);
303
          g_free (new_ql_path);
798.5.9 by Mikkel Kamstrup Erlandsen
Add support for dynamically updating the unique DBus name owning a LauncherEntryRemote
304
          g_free (new_ql_name);
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
305
          return;
306
        }
307
308
      /* Prepare for a new quicklist */
309
      g_free (ql_path);
310
      g_free (new_ql_path);
798.5.9 by Mikkel Kamstrup Erlandsen
Add support for dynamically updating the unique DBus name owning a LauncherEntryRemote
311
      g_free (new_ql_name);
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
312
      g_object_unref (_quicklist);
313
    }
314
  else if (_quicklist == NULL && quicklist == NULL)
315
    return;
316
317
  if (quicklist == NULL)
318
    _quicklist = NULL;
319
  else
320
    _quicklist = (DbusmenuClient *) g_object_ref (quicklist);
321
811.1.6 by Jason Smith
hook up libunity to launcher
322
  quicklist_changed.emit (this);
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
323
}
324
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
325
void
326
LauncherEntryRemote::SetEmblemVisible(gboolean visible)
327
{
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
328
  if (_emblem_visible == visible)
329
    return;
330
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
331
  _emblem_visible = visible;
811.1.6 by Jason Smith
hook up libunity to launcher
332
  emblem_visible_changed.emit (this);
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
333
}
334
335
void
336
LauncherEntryRemote::SetCountVisible(gboolean visible)
337
{
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
338
  if (_count_visible == visible)
339
      return;
340
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
341
  _count_visible = visible;
811.1.6 by Jason Smith
hook up libunity to launcher
342
  count_visible_changed.emit (this);
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
343
}
344
345
void
346
LauncherEntryRemote::SetProgressVisible(gboolean visible)
347
{
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
348
  if (_progress_visible == visible)
349
      return;
350
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
351
  _progress_visible = visible;
811.1.6 by Jason Smith
hook up libunity to launcher
352
  progress_visible_changed.emit (this);
798.5.2 by Mikkel Kamstrup Erlandsen
More stubbing out of the Launcher DBus API, still not functional, but compiles without warnings
353
}
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
354
355
/**
356
 * Set all properties from 'other' on 'this'.
357
 */
358
void
359
LauncherEntryRemote::Update(LauncherEntryRemote *other)
360
{
798.5.9 by Mikkel Kamstrup Erlandsen
Add support for dynamically updating the unique DBus name owning a LauncherEntryRemote
361
  /* It's important that we update the DBus name first since it might
362
   * unset the quicklist if it changes */
363
  SetDBusName (other->DBusName ());
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
364
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
365
  SetEmblem (other->Emblem ());
366
  SetCount (other->Count ());
367
  SetProgress (other->Progress ());
798.5.6 by Mikkel Kamstrup Erlandsen
Implement support for quicklists in the Launcher DBus API
368
  SetQuicklist (other->Quicklist());
798.5.4 by Mikkel Kamstrup Erlandsen
Launcher API fully implemented, but is so far untested in the real world :-) It's still not wired up to the UI yet.
369
370
  SetEmblemVisible (other->EmblemVisible ());
371
  SetCountVisible(other->CountVisible ());
372
  SetProgressVisible(other->ProgressVisible());
373
}
811.2.1 by Mikkel Kamstrup Erlandsen
Slight change in how Update() DBus signals are treated in the Launcher API. By definition they only contain the "delta" - ie. the changed properties. Before this fix we always replaced all entry properties wholesale.
374
375
/**
376
 * Iterate over a GVariantIter containing elements of type '{sv}' and apply
377
 * any properties to 'this'.
378
 */
379
void
380
LauncherEntryRemote::Update(GVariantIter *prop_iter)
381
{
382
  gchar       *prop_key;
383
  const gchar *prop_value_s;
384
  GVariant    *prop_value;
385
386
  g_return_if_fail (prop_iter != NULL);
387
388
  while (g_variant_iter_loop (prop_iter, "{sv}", &prop_key, &prop_value))
389
    {
390
      if (g_str_equal ("emblem", prop_key))
391
        {
392
          prop_value_s = g_variant_get_string (prop_value, NULL);
393
          SetEmblem (prop_value_s);
394
        }
395
      else if (g_str_equal ("count", prop_key))
396
        SetCount (g_variant_get_int64 (prop_value));
397
      else if (g_str_equal ("progress", prop_key))
398
        SetProgress (g_variant_get_double (prop_value));
399
      else if (g_str_equal ("emblem-visible", prop_key))
400
        SetEmblemVisible (g_variant_get_boolean (prop_value));
401
      else if (g_str_equal ("count-visible", prop_key))
402
        SetCountVisible (g_variant_get_boolean (prop_value));
403
      else if (g_str_equal ("progress-visible", prop_key))
404
        SetProgressVisible (g_variant_get_boolean (prop_value));
405
      else if (g_str_equal ("quicklist", prop_key))
406
        {
407
          /* The value is the object path of the dbusmenu */
408
          prop_value_s = g_variant_get_string (prop_value,  NULL);
409
          SetQuicklistPath (prop_value_s);
410
        }
411
    }
412
}