[gst-debugger/refactor-v1.0] refactor: restore properties module
- From: Marcin Kolny <mkolny src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gst-debugger/refactor-v1.0] refactor: restore properties module
- Date: Fri, 2 Oct 2015 16:23:46 +0000 (UTC)
commit 10f9bc85161bc87ab356bbbb369e74d4c2e3e019
Author: Marcin Kolny <marcin kolny gmail com>
Date: Fri Oct 2 18:23:08 2015 +0200
refactor: restore properties module
src/common/deserializer.c | 26 +++++-
src/common/deserializer.h | 3 +-
src/common/gst-utils.c | 23 ++++++
src/common/gst-utils.h | 7 ++
src/common/gstdebugger.proto | 2 +
src/common/serializer.c | 2 +-
src/debugserver/gstdebugserver.c | 12 +++-
src/debugserver/gstdebugservertypes.c | 1 +
src/gst-debugger/Makefile.am | 15 ++++-
src/gst-debugger/controller/command_factory.cpp | 41 ++++------
src/gst-debugger/controller/command_factory.h | 4 +-
src/gst-debugger/controller/controller.cpp | 65 +++++++--------
src/gst-debugger/controller/controller.h | 2 +
src/gst-debugger/dialogs/klasses_dialog.cpp | 4 +-
src/gst-debugger/dialogs/klasses_dialog.h | 2 +-
src/gst-debugger/gvalue-converter/gvalue_base.cpp | 55 ++++++++++---
src/gst-debugger/gvalue-converter/gvalue_base.h | 22 ++++-
.../gvalue-converter/gvalue_boolean.cpp | 19 +++--
src/gst-debugger/gvalue-converter/gvalue_boolean.h | 5 +-
src/gst-debugger/gvalue-converter/gvalue_caps.cpp | 29 +++++---
src/gst-debugger/gvalue-converter/gvalue_caps.h | 6 +-
.../gvalue-converter/gvalue_numeric.cpp | 28 ++++---
src/gst-debugger/gvalue-converter/gvalue_numeric.h | 8 +-
.../gvalue-converter/gvalue_string.cpp | 19 +++--
src/gst-debugger/gvalue-converter/gvalue_string.h | 5 +-
.../gvalue-converter/gvalue_unknown.cpp | 28 +++++++
src/gst-debugger/gvalue-converter/gvalue_unknown.h | 26 ++++++
src/gst-debugger/models/gst_klass_model.h | 10 +++
src/gst-debugger/models/gst_pipeline_model.cpp | 11 ++-
src/gst-debugger/models/gst_pipeline_model.h | 6 +-
src/gst-debugger/modules/gst_properties_module.cpp | 83 +++++++++-----------
src/gst-debugger/modules/gst_properties_module.h | 4 +-
32 files changed, 387 insertions(+), 186 deletions(-)
---
diff --git a/src/common/deserializer.c b/src/common/deserializer.c
index 14a4477..d6dbe11 100644
--- a/src/common/deserializer.c
+++ b/src/common/deserializer.c
@@ -92,15 +92,19 @@ GstBuffer* gst_buffer_deserialize (const gchar * buffer, gint size)
return gstbuffer;
}
-void g_value_deserialize (GValue * value, GType type, InternalGType internal_type, const gchar * data)
+void g_value_deserialize (GValue * value, GType type, InternalGType internal_type,
+ const gchar * data, gint len)
{
+ // I don't use string for Value::data field, because serializer implementation
+ // might change in the future (I don't break the API then).
+ gchar *t_data = g_strndup (data, len);
switch (internal_type) {
case INTERNAL_GTYPE_ENUM:
case INTERNAL_GTYPE_FLAGS:
{
GValue tmp = G_VALUE_INIT;
g_value_init (&tmp, type);
- gst_value_deserialize (&tmp, data);
+ gst_value_deserialize (&tmp, t_data);
if (internal_type == INTERNAL_GTYPE_ENUM) {
g_value_init(value, gst_utils_get_virtual_enum_type ());
g_value_set_enum (value, g_value_get_int (&tmp));
@@ -113,15 +117,25 @@ void g_value_deserialize (GValue * value, GType type, InternalGType internal_typ
}
case INTERNAL_GTYPE_GST_OBJECT: // and with pointers
case INTERNAL_GTYPE_FUNDAMENTAL:
- case INTERNAL_GTYPE_UNKNOWN:
g_value_init (value, type);
- gst_value_deserialize (value, data);
+ gst_value_deserialize (value, t_data);
break;
+ case INTERNAL_GTYPE_UNKNOWN:
+ {
+ GValue tmp = G_VALUE_INIT;
+ g_value_init (&tmp, G_TYPE_STRING);
+ gst_value_deserialize (&tmp, t_data);
+ g_value_init (value, gst_unknown_type_get_type ());
+ g_value_take_boxed (value, gst_unknown_type_new (g_value_get_string (&tmp)));
+ g_value_unset (&tmp);
+
+ break;
+ }
case INTERNAL_GTYPE_CAPS:
{
GstCaps *caps;
g_value_init (value, G_TYPE_STRING);
- gst_value_deserialize (value, data);
+ gst_value_deserialize (value, t_data);
caps = gst_caps_from_string (g_value_get_string (value));
g_value_unset (value);
g_value_init (value, GST_TYPE_CAPS);
@@ -129,4 +143,6 @@ void g_value_deserialize (GValue * value, GType type, InternalGType internal_typ
break;
}
}
+
+ g_free (t_data);
}
diff --git a/src/common/deserializer.h b/src/common/deserializer.h
index 3070074..7e6a54d 100644
--- a/src/common/deserializer.h
+++ b/src/common/deserializer.h
@@ -22,7 +22,8 @@ GstMessage* gst_message_deserialize (const gchar * buffer, gint size);
GstBuffer* gst_buffer_deserialize (const gchar * buffer, gint size);
-void g_value_deserialize (GValue * value, GType type, InternalGType internal_type, const gchar * data);
+void g_value_deserialize (GValue * value, GType type, InternalGType internal_type,
+ const gchar * data, gint len);
G_END_DECLS
diff --git a/src/common/gst-utils.c b/src/common/gst-utils.c
index ccfeae3..034538b 100644
--- a/src/common/gst-utils.c
+++ b/src/common/gst-utils.c
@@ -167,3 +167,26 @@ GType gst_utils_get_virtual_flags_type (void)
return (GType) id;
}
+
+
+static gpointer gst_unknown_type_copy (gpointer *object)
+{
+ return gst_unknown_type_new (((GstUnknownType*)object)->type_name);
+}
+
+static void gst_unknown_type_free (gpointer *object)
+{
+ g_free (((GstUnknownType*)object)->type_name);
+ g_slice_free1 (sizeof (GstUnknownType), object);
+}
+
+G_DEFINE_BOXED_TYPE (GstUnknownType, gst_unknown_type, (GBoxedCopyFunc)gst_unknown_type_copy,
(GBoxedFreeFunc)gst_unknown_type_free);
+
+GstUnknownType* gst_unknown_type_new (const gchar *type_name)
+{
+ GstUnknownType *self = g_slice_new (GstUnknownType);
+ self->type_name = g_strdup (type_name);
+ return self;
+}
+
+
diff --git a/src/common/gst-utils.h b/src/common/gst-utils.h
index 7d7779c..bd6d71b 100644
--- a/src/common/gst-utils.h
+++ b/src/common/gst-utils.h
@@ -19,6 +19,13 @@ GType gst_utils_get_virtual_enum_type (void);
GType gst_utils_get_virtual_flags_type (void);
+typedef struct {
+ gchar *type_name;
+} GstUnknownType;
+
+GType gst_unknown_type_get_type(void);
+GstUnknownType *gst_unknown_type_new (const gchar *type_name);
+
G_END_DECLS
#endif /* __GST_DEBUGGER_GST_UTILS_H__ */
diff --git a/src/common/gstdebugger.proto b/src/common/gstdebugger.proto
index 52cd357..d4c2aa0 100644
--- a/src/common/gstdebugger.proto
+++ b/src/common/gstdebugger.proto
@@ -11,6 +11,7 @@ message Value {
required uint64 gtype = 1;
optional int32 internal_type = 2;
required bytes data = 3;
+ required string type_name = 4;
}
message PropertyInfo {
@@ -109,6 +110,7 @@ message Command {
string log_threshold = 6;
bool entire_topology = 7;
PropertyRequest property = 8;
+ PropertyValue property_set = 9;
}
}
diff --git a/src/common/serializer.c b/src/common/serializer.c
index cb5c3e4..e41a4a5 100644
--- a/src/common/serializer.c
+++ b/src/common/serializer.c
@@ -154,7 +154,7 @@ gchar * g_value_serialize (GValue * value, GType * type, InternalGType * interna
} else {
g_value_init(&tmp, G_TYPE_STRING);
gchar buffer[128];
- snprintf (buffer, 128, "<unknown type '%s', can not read value>", g_type_name (value->g_type));
+ snprintf (buffer, 128, "%s", g_type_name (value->g_type));
*type = G_TYPE_STRING;
*internal_type = INTERNAL_GTYPE_UNKNOWN;
g_value_set_string (&tmp, g_strdup (buffer));
diff --git a/src/debugserver/gstdebugserver.c b/src/debugserver/gstdebugserver.c
index f64e225..3c2440b 100644
--- a/src/debugserver/gstdebugserver.c
+++ b/src/debugserver/gstdebugserver.c
@@ -218,8 +218,9 @@ gst_debugserver_tracer_send_property (GstDebugserverTcp * tcp_server, TcpClient
value.data.data = serialized_data;
value.data.len = serialized_data == NULL ? 0 : strlen (serialized_data);
value.gtype = out_gtype;
+ value.type_name = (gchar*) g_type_name (spec->value_type);
- if (out_gtype == spec->value_type) {
+ if (out_gtype != spec->value_type) {
value.internal_type = out_internal_type;
value.has_internal_type = TRUE;
} else {
@@ -432,6 +433,15 @@ static void gst_debugserver_command_handler (GstDebugger__Command * command,
case GST_DEBUGGER__COMMAND__COMMAND_TYPE_PROPERTY:
gst_debugserver_process_property_request (self, client, command->property);
break;
+ case GST_DEBUGGER__COMMAND__COMMAND_TYPE_PROPERTY_SET:
+ {
+ GValue val = G_VALUE_INIT;
+ GstElement *element = gst_utils_get_element_from_path (GST_ELEMENT_CAST (self->pipeline),
command->property_set->object);
+ g_value_deserialize (&val, command->property_set->value->gtype,
command->property_set->value->internal_type,
+ command->property_set->value->data.data, command->property_set->value->data.len);
+ g_object_set_property (G_OBJECT (element), command->property_set->name, &val);
+ g_value_unset (&val);
+ }
}
}
diff --git a/src/debugserver/gstdebugservertypes.c b/src/debugserver/gstdebugservertypes.c
index 89fb36c..e20377a 100644
--- a/src/debugserver/gstdebugservertypes.c
+++ b/src/debugserver/gstdebugservertypes.c
@@ -189,6 +189,7 @@ static void gst_debugserver_types_send_klass (GstDebugserverTcp *tcp_server, Tcp
g_param_value_set_default (specs[i], &gvalue);
value = (GstDebugger__Value*) g_malloc (sizeof (GstDebugger__Value));
gst_debugger__value__init (value);
+ value->type_name = (gchar*) g_type_name (specs[i]->value_type);
value->data.data = (uint8_t*) g_value_serialize (&gvalue, &out_gtype, &out_internal_type);
value->data.len = value->data.data == NULL ? 0 : strlen (value->data.data);
value->gtype = out_gtype;
diff --git a/src/gst-debugger/Makefile.am b/src/gst-debugger/Makefile.am
index af2841c..cfad0a9 100644
--- a/src/gst-debugger/Makefile.am
+++ b/src/gst-debugger/Makefile.am
@@ -69,7 +69,20 @@ gst_debugger_ GST_API_VERSION@_SOURCES = \
modules/gst_properties_module.h \
models/gst_klass_model.h \
dialogs/klasses_dialog.h \
- dialogs/klasses_dialog.cpp
+ dialogs/klasses_dialog.cpp \
+ gvalue-converter/gvalue_base.cpp \
+ gvalue-converter/gvalue_base.h \
+ gvalue-converter/gvalue_unknown.cpp \
+ gvalue-converter/gvalue_unknown.h \
+ gvalue-converter/gvalue_numeric.cpp \
+ gvalue-converter/gvalue_numeric.h \
+ gvalue-converter/gvalue_boolean.cpp \
+ gvalue-converter/gvalue_boolean.h \
+ gvalue-converter/gvalue_caps.cpp \
+ gvalue-converter/gvalue_caps.h \
+ gvalue-converter/gvalue_string.cpp \
+ gvalue-converter/gvalue_string.h
+
gst_debugger_ GST_API_VERSION@_LDFLAGS = $(GTKMM_LIBS) $(GSTMM_LIBS) $(GVC_LIBS) $(PROTOBUF_LIBS) -lX11
gst_debugger_ GST_API_VERSION@_LDADD = ../common/libgst-debugger-common-cpp- GST_DEBUGGER_API_VERSION@.la
diff --git a/src/gst-debugger/controller/command_factory.cpp b/src/gst-debugger/controller/command_factory.cpp
index aa49910..4f20e69 100644
--- a/src/gst-debugger/controller/command_factory.cpp
+++ b/src/gst-debugger/controller/command_factory.cpp
@@ -111,34 +111,29 @@ void CommandFactory::send_request_debug_categories_command()
client->send_command(cmd);
}
-
-/*
-void CommandFactory::send_request_topology_command()
+void CommandFactory::send_set_property_command(const std::string &path, const std::string &property_name,
GValue *gvalue)
{
- Command cmd;
- cmd.set_command_type(Command_CommandType_TOPOLOGY);
-
- client->send_command(cmd);
-}
+ GstDebugger::Value *value = new GstDebugger::Value();
+ GType gtype; InternalGType internal_type;
+ char *data = g_value_serialize(gvalue, >ype, &internal_type);
+ value->set_data(data);
+ g_free (data);
+ value->set_gtype(gtype);
+ value->set_internal_type(internal_type);
+ value->set_type_name("xxx"); // todo
+
+ GstDebugger::PropertyValue *prop_val = new GstDebugger::PropertyValue();
+ prop_val->set_object(path);
+ prop_val->set_name(property_name);
+ prop_val->set_allocated_value(value);
-void CommandFactory::send_property_command(const std::string &path, const std::string &property_name, GValue
*gvalue)
-{
- Command cmd;
- cmd.set_command_type(Command_CommandType_PROPERTY);
- Property *property = new Property();
- property->set_element_path(path);
- property->set_property_name(property_name);
- GType type; InternalGType internal_type;
- gchar *serialized = g_value_serialize(gvalue, &type, &internal_type);
- property->set_property_value(serialized);
- g_free(serialized);
- property->set_internal_type(internal_type);
- property->set_type(type);
- cmd.set_allocated_property(property);
+ GstDebugger::Command cmd;
+ cmd.set_allocated_property_set(prop_val);
client->send_command(cmd);
-}
+}
+/*
void CommandFactory::send_request_pad_dynamic_info(const std::string &pad_path)
{
Command cmd;
diff --git a/src/gst-debugger/controller/command_factory.h b/src/gst-debugger/controller/command_factory.h
index 0e94573..00101f4 100644
--- a/src/gst-debugger/controller/command_factory.h
+++ b/src/gst-debugger/controller/command_factory.h
@@ -28,8 +28,8 @@ public:
void send_data_type_request_command(const std::string &type_name,
GstDebugger::TypeDescriptionRequest_Type type);
void send_request_debug_categories_command();
void send_request_entire_topology_command();
- /*void send_property_command(const std::string &path, const std::string &property_name, GValue
*gvalue);
- void send_request_pad_dynamic_info(const std::string &pad_path);*/
+ void send_set_property_command(const std::string &path, const std::string &property_name, GValue
*gvalue);
+ /*void send_request_pad_dynamic_info(const std::string &pad_path);*/
};
#endif /* SRC_GST_DEBUGGER_CONTROLLER_COMMAND_FACTORY_H_ */
diff --git a/src/gst-debugger/controller/controller.cpp b/src/gst-debugger/controller/controller.cpp
index c9c814c..043c26c 100644
--- a/src/gst-debugger/controller/controller.cpp
+++ b/src/gst-debugger/controller/controller.cpp
@@ -7,6 +7,10 @@
#include "controller.h"
#include "ui_utils.h"
+#include "element_path_processor.h"
+
+#include "common/common.h"
+#include "common/deserializer.h"
#include <gtkmm.h>
@@ -30,6 +34,7 @@ Controller::Controller(IMainView *view)
int Controller::run(int &argc, char **&argv)
{
Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv,
"eu.cookandcommit.gst-debugger");
+ app->set_flags(app->get_flags() | Gio::APPLICATION_NON_UNIQUE);
view->set_controller(shared_from_this());
return app->run(*view);
}
@@ -74,31 +79,10 @@ void Controller::process_frame(const GstDebugger::GStreamerData &data)
on_klass_list_changed(data.element_klass().name(), true);
break;
case GstDebugger::GStreamerData::kPropertyValue:
+ add_property(data.property_value());
on_property_value_received(data.property_value());
break;
}
- /*
- case GstreamerInfo_InfoType_PROPERTY:
- {
- std::string name = info.property().type_name();
- if ((info.property().internal_type() == INTERNAL_GTYPE_ENUM ||
info.property().internal_type() == INTERNAL_GTYPE_FLAGS) && !enum_container.has_item(name))
- {
- send_enum_type_request_command(name);
- }
- append_property(info.property());
- on_property_received(info.property());
- break;
- }
- case GstreamerInfo_InfoType_FACTORY:
- update_factory_model(info.factory_info());
- on_factory_list_changed(info.factory_info().name());
- break;
- case GstreamerInfo_InfoType_PAD_DYNAMIC_INFO:
- update_pad_dynamic_info(info.pad_dynamic_info());
- break;
- default:
- break;
- }*/
}
template<typename T>
@@ -257,21 +241,32 @@ void Controller::update_klass_model(const GstDebugger::ElementKlass &klass_info)
*it = model;
}
}
-/*
-void Controller::append_property(const Property& property)
+
+void Controller::add_property(const GstDebugger::PropertyValue &value)
{
- GValue *value = new GValue;
- *value = {0};
- g_value_deserialize(value, property.type(), (InternalGType)property.internal_type(),
property.property_value().c_str());
-
- auto element = ElementModel::get_parent_element_from_path(property.element_path());
- std::shared_ptr<GValueBase> gvalue(GValueBase::build_gvalue(value));
- element->add_property(property.property_name(), gvalue);
- gvalue->widget_value_changed.connect([gvalue, property, this] {
- this->send_property_command(property.element_path(), property.property_name(),
gvalue->get_gvalue());
- });
+ auto element =
std::dynamic_pointer_cast<ElementModel>(ElementPathProcessor(value.object()).get_last_obj());
+
+ if (!element)
+ return;
+
+ GValue *g_val = new GValue;
+ *g_val = {0};
+ g_value_deserialize(g_val, value.value().gtype(), (InternalGType)value.value().internal_type(),
+ value.value().data().c_str(), value.value().data().length());
+
+ bool had_property = element->has_property(value.name());
+
+ auto vb = element->add_property(value.name(), g_val);
+
+ if (!had_property)
+ {
+ auto obj = value.object(); auto name = value.name();
+ vb->widget_value_changed.connect([this, name, obj, vb]{
+ this->send_set_property_command(obj, name, vb->get_gvalue());
+ });
+ }
}
-*/
+
void Controller::log(const std::string &message)
{
// todo date/time?
diff --git a/src/gst-debugger/controller/controller.h b/src/gst-debugger/controller/controller.h
index 8d328d4..a91b176 100644
--- a/src/gst-debugger/controller/controller.h
+++ b/src/gst-debugger/controller/controller.h
@@ -42,6 +42,8 @@ private:
void update_factory_model(const GstDebugger::FactoryType &factory_info);
void update_klass_model(const GstDebugger::ElementKlass &klass_element);
+ void add_property(const GstDebugger::PropertyValue &value);
+
/*
diff --git a/src/gst-debugger/dialogs/klasses_dialog.cpp b/src/gst-debugger/dialogs/klasses_dialog.cpp
index f0af2ef..565d2b2 100644
--- a/src/gst-debugger/dialogs/klasses_dialog.cpp
+++ b/src/gst-debugger/dialogs/klasses_dialog.cpp
@@ -37,7 +37,7 @@ void KlassesDialog::set_controller(const std::shared_ptr<Controller> &controller
c[klasses_columns.m_col_value] = VALUE; \
} while (false)
-std::string KlassesDialog::g_param_flags_to_string(GParamFlags v, std::string flags_name)
+std::string KlassesDialog::g_param_flags_to_string(GParamFlags v)
{
#define xstr(s) str(s)
#define str(s) #s
@@ -95,7 +95,7 @@ void KlassesDialog::reload_list(const Glib::ustring &klass_name, bool add)
APPEND_SUB_ROW(cr, "Nick", property.get_nick());
APPEND_SUB_ROW(cr, "Blurb", property.get_blurb());
- APPEND_SUB_ROW(cr, "Flags", g_param_flags_to_string(property.get_flags(),
"GParamFlags"));
+ APPEND_SUB_ROW(cr, "Flags", g_param_flags_to_string(property.get_flags()));
}
}
}
diff --git a/src/gst-debugger/dialogs/klasses_dialog.h b/src/gst-debugger/dialogs/klasses_dialog.h
index a75ae7b..98e401b 100644
--- a/src/gst-debugger/dialogs/klasses_dialog.h
+++ b/src/gst-debugger/dialogs/klasses_dialog.h
@@ -31,7 +31,7 @@ class KlassesDialog : public RemoteDataDialog
void reload_list(const Glib::ustring &klass_name, bool add);
- std::string g_param_flags_to_string(GParamFlags v, std::string flags_name);
+ std::string g_param_flags_to_string(GParamFlags v);
public:
KlassesDialog(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& builder);
diff --git a/src/gst-debugger/gvalue-converter/gvalue_base.cpp
b/src/gst-debugger/gvalue-converter/gvalue_base.cpp
index 5799a46..2c57ce9 100644
--- a/src/gst-debugger/gvalue-converter/gvalue_base.cpp
+++ b/src/gst-debugger/gvalue-converter/gvalue_base.cpp
@@ -6,11 +6,13 @@
*/
#include "gvalue_base.h"
+#include "gvalue_unknown.h"
+#include "gvalue_numeric.h"
#include "gvalue_boolean.h"
#include "gvalue_caps.h"
-#include "gvalue_enum.h"
-#include "gvalue_numeric.h"
#include "gvalue_string.h"
+/*#include "gvalue_enum.h"
+*/
#include <gst/gst.h>
@@ -21,18 +23,21 @@ GValueBase::GValueBase(GValue *gobj)
GValueBase::~GValueBase()
{
+ clear_gvalue();
+}
+
+void GValueBase::clear_gvalue()
+{
if (g_value != nullptr)
{
g_value_unset(g_value);
delete g_value;
}
- delete widget;
}
GValueBase* GValueBase::build_gvalue(GValue* gobj)
{
GType value_type = G_VALUE_TYPE(gobj);
-
switch (value_type)
{
case G_TYPE_STRING:
@@ -59,23 +64,51 @@ GValueBase* GValueBase::build_gvalue(GValue* gobj)
break;
}
- if (G_TYPE_IS_ENUM(G_VALUE_TYPE(gobj)) || G_TYPE_IS_FLAGS(G_VALUE_TYPE(gobj)))
+ /*if (G_TYPE_IS_ENUM(G_VALUE_TYPE(gobj)) || G_TYPE_IS_FLAGS(G_VALUE_TYPE(gobj)))
{
return new GValueEnum(gobj);
}
+*/
- if (G_VALUE_TYPE(gobj) == gst_caps_get_type())
+ if (G_VALUE_TYPE(gobj) == GST_TYPE_CAPS)
{
return new GValueCaps(gobj);
}
- return nullptr;
+ return new GValueUnknown(gobj);
+}
+
+void GValueBase::destroy_widget(GtkWidget *object, gpointer user_data)
+{
+ GValueBase *val = reinterpret_cast<GValueBase*>(user_data);
+
+ val->widgets.erase(std::remove(val->widgets.begin(),
+ val->widgets.end(), Glib::wrap(object)), val->widgets.end());
}
-void GValueBase::update_gvalue(const std::shared_ptr<GValueBase> &gvalue)
+Gtk::Widget* GValueBase::get_widget()
{
- this->g_value = gvalue->g_value;
- gvalue->g_value = nullptr;
+ Gtk::Widget* widget = Gtk::manage(create_widget());
- update_widget();
+ g_signal_connect((gpointer)widget->gobj(), "destroy",
+ (GCallback)&GValueBase::destroy_widget, (gpointer)this);
+
+ widgets.push_back(widget);
+
+ widget->set_data("is-gvalue-widget", GINT_TO_POINTER(1));
+
+ return widget;
+}
+
+void GValueBase::update_gvalue(GValue* gobj)
+{
+ if (gobj != g_value)
+ {
+ clear_gvalue();
+ g_value = gobj;
+ }
+
+ for (auto widget : widgets)
+ update_widget(widget);
}
+
diff --git a/src/gst-debugger/gvalue-converter/gvalue_base.h b/src/gst-debugger/gvalue-converter/gvalue_base.h
index 91c48ae..c5fa17e 100644
--- a/src/gst-debugger/gvalue-converter/gvalue_base.h
+++ b/src/gst-debugger/gvalue-converter/gvalue_base.h
@@ -13,28 +13,40 @@
#include <gtkmm.h>
#include <string>
+#include <vector>
class GValueBase
{
+ void clear_gvalue();
+
protected:
GValue* g_value;
- mutable Gtk::Widget *widget = nullptr;
+ mutable std::vector<Gtk::Widget*> widgets;
+
+ virtual Gtk::Widget *create_widget() = 0;
+
+ virtual void update_widget(Gtk::Widget* widget) = 0;
+
+ static void destroy_widget(GtkWidget *object, gpointer user_data);
- virtual void update_widget() {}
public:
GValueBase(GValue* gobj);
virtual ~GValueBase();
virtual std::string to_string() const = 0;
- virtual Gtk::Widget* get_widget() const = 0;
-
- void update_gvalue(const std::shared_ptr<GValueBase> &gvalue);
+ /*
+ * caller should manage returned object
+ * by adding it to the container
+ * */
+ Gtk::Widget* get_widget();
static GValueBase* build_gvalue(GValue* g_value);
GValue* get_gvalue() const { return g_value; }
+ void update_gvalue(GValue* gobj);
+
sigc::signal<void> widget_value_changed;
};
diff --git a/src/gst-debugger/gvalue-converter/gvalue_boolean.cpp
b/src/gst-debugger/gvalue-converter/gvalue_boolean.cpp
index 6d531c6..b231d9b 100644
--- a/src/gst-debugger/gvalue-converter/gvalue_boolean.cpp
+++ b/src/gst-debugger/gvalue-converter/gvalue_boolean.cpp
@@ -28,17 +28,18 @@ std::string GValueBoolean::to_string() const
return get_value() ? "true" : "false";
}
-Gtk::Widget* GValueBoolean::get_widget() const
+Gtk::Widget* GValueBoolean::create_widget()
{
- if (widget == nullptr)
- {
- auto cb = new Gtk::CheckButton();
+ auto cb = new Gtk::CheckButton();
- cb->signal_toggled().connect([this, cb]{ g_value_set_boolean(g_value, cb->get_active()); });
- cb->signal_toggled().connect(widget_value_changed);
+ cb->signal_toggled().connect([this, cb]{ g_value_set_boolean(g_value, cb->get_active()); });
+ cb->signal_toggled().connect(widget_value_changed);
+ update_widget(cb);
- widget = cb;
- }
+ return cb;
+}
+
+void GValueBoolean::update_widget(Gtk::Widget* widget)
+{
dynamic_cast<Gtk::CheckButton*>(widget)->set_active(get_value());
- return widget;
}
diff --git a/src/gst-debugger/gvalue-converter/gvalue_boolean.h
b/src/gst-debugger/gvalue-converter/gvalue_boolean.h
index 340565a..3ac979f 100644
--- a/src/gst-debugger/gvalue-converter/gvalue_boolean.h
+++ b/src/gst-debugger/gvalue-converter/gvalue_boolean.h
@@ -12,11 +12,12 @@
class GValueBoolean : public GValueBase
{
+ Gtk::Widget* create_widget() override;
+
+ void update_widget(Gtk::Widget* widget) override;
public:
GValueBoolean(GValue* gobj);
- Gtk::Widget *get_widget() const override;
-
std::string to_string() const override;
bool get_value() const;
diff --git a/src/gst-debugger/gvalue-converter/gvalue_caps.cpp
b/src/gst-debugger/gvalue-converter/gvalue_caps.cpp
index f1e64a4..c1d15f9 100644
--- a/src/gst-debugger/gvalue-converter/gvalue_caps.cpp
+++ b/src/gst-debugger/gvalue-converter/gvalue_caps.cpp
@@ -16,19 +16,28 @@ GValueCaps::GValueCaps(GValue *gobj)
std::string GValueCaps::to_string() const
{
- Glib::Value<Glib::RefPtr<Gst::Caps>> v;
- v.init(g_value);
+ gchar *str = gst_caps_to_string(gst_value_get_caps(g_value));
+ std::string caps_str = str;
+ g_free(str);
+ return caps_str;
+}
+
+Gtk::Widget* GValueCaps::create_widget()
+{
+ auto entry = new Gtk::Entry();
+ entry->signal_activate().connect([this, entry] {
+ GstCaps *caps = gst_caps_from_string(entry->get_text().c_str());
+ gst_value_set_caps(this->g_value, caps);
+ gst_caps_unref(caps);
+ update_gvalue(this->g_value);
+ });
- return v.get()->to_string();
+ entry->signal_activate().connect(widget_value_changed);
+ update_widget(entry);
+ return entry;
}
-Gtk::Widget* GValueCaps::get_widget() const
+void GValueCaps::update_widget(Gtk::Widget* widget)
{
- if (widget == nullptr)
- {
- widget = new Gtk::Entry();
- }
dynamic_cast<Gtk::Entry*>(widget)->set_text(to_string());
- return widget;
}
-
diff --git a/src/gst-debugger/gvalue-converter/gvalue_caps.h b/src/gst-debugger/gvalue-converter/gvalue_caps.h
index f163123..b866e4b 100644
--- a/src/gst-debugger/gvalue-converter/gvalue_caps.h
+++ b/src/gst-debugger/gvalue-converter/gvalue_caps.h
@@ -12,12 +12,14 @@
class GValueCaps : public GValueBase
{
+ Gtk::Widget* create_widget() override;
+
+ void update_widget(Gtk::Widget* widget) override;
+
public:
GValueCaps(GValue* gobj);
std::string to_string() const override;
-
- Gtk::Widget* get_widget() const override;
};
#endif /* SRC_GST_DEBUGGER_GVALUE_CONVERTER_GVALUE_CAPS_H_ */
diff --git a/src/gst-debugger/gvalue-converter/gvalue_numeric.cpp
b/src/gst-debugger/gvalue-converter/gvalue_numeric.cpp
index ccb9071..3d67a4e 100644
--- a/src/gst-debugger/gvalue-converter/gvalue_numeric.cpp
+++ b/src/gst-debugger/gvalue-converter/gvalue_numeric.cpp
@@ -30,22 +30,28 @@ void GValueNumeric<T>::update_value(const T &val)
v.set(val);
g_value_reset(this->g_value);
g_value_copy(v.gobj(), this->g_value);
+
+ update_gvalue(this->g_value);
}
template<typename T>
-Gtk::Widget* GValueNumeric<T>::get_widget() const
+void GValueNumeric<T>::update_widget(Gtk::Widget* widget)
{
- if (widget == nullptr)
- {
- auto entry = new Gtk::Entry();
- entry->signal_activate().connect([this, entry]{
- update_value(std::atol(entry->get_text().c_str()));
- });
- entry->signal_activate().connect(widget_value_changed);
- widget = entry;
- }
dynamic_cast<Gtk::Entry*>(widget)->set_text(to_string());
- return widget;
+}
+
+template<typename T>
+Gtk::Widget* GValueNumeric<T>::create_widget()
+{
+ auto entry = new Gtk::Entry();
+ entry->signal_activate().connect([this, entry]{
+ update_value((T)std::atol(entry->get_text().c_str()));
+ });
+
+ entry->signal_activate().connect(widget_value_changed);
+ update_widget(entry);
+
+ return entry;
}
// Check GCC
diff --git a/src/gst-debugger/gvalue-converter/gvalue_numeric.h
b/src/gst-debugger/gvalue-converter/gvalue_numeric.h
index f2c9935..71192fe 100644
--- a/src/gst-debugger/gvalue-converter/gvalue_numeric.h
+++ b/src/gst-debugger/gvalue-converter/gvalue_numeric.h
@@ -13,14 +13,14 @@
template<typename T>
class GValueNumeric : public GValueBase
{
+ void update_value(const T &val);
+ Gtk::Widget* create_widget() override;
+ void update_widget(Gtk::Widget* widget) override;
+
public:
GValueNumeric(GValue* gobj);
std::string to_string() const override;
-
- Gtk::Widget* get_widget() const override;
-
- void update_value(const T &val);
};
diff --git a/src/gst-debugger/gvalue-converter/gvalue_string.cpp
b/src/gst-debugger/gvalue-converter/gvalue_string.cpp
index 8f144f5..e143a33 100644
--- a/src/gst-debugger/gvalue-converter/gvalue_string.cpp
+++ b/src/gst-debugger/gvalue-converter/gvalue_string.cpp
@@ -21,13 +21,20 @@ std::string GValueString::to_string() const
return v.get();
}
-Gtk::Widget* GValueString::get_widget() const
+Gtk::Widget* GValueString::create_widget()
{
- if (widget == nullptr)
- {
- widget = new Gtk::Entry();
- }
+ auto entry = new Gtk::Entry();
+ entry->signal_activate().connect([this, entry] {
+ g_value_set_string(g_value, entry->get_text().c_str());
+ update_gvalue(this->g_value);
+ });
+ entry->signal_activate().connect(widget_value_changed);
+ update_widget(entry);
+ return entry;
+}
+
+void GValueString::update_widget(Gtk::Widget* widget)
+{
dynamic_cast<Gtk::Entry*>(widget)->set_text(to_string());
- return widget;
}
diff --git a/src/gst-debugger/gvalue-converter/gvalue_string.h
b/src/gst-debugger/gvalue-converter/gvalue_string.h
index 13222e3..dbb5da1 100644
--- a/src/gst-debugger/gvalue-converter/gvalue_string.h
+++ b/src/gst-debugger/gvalue-converter/gvalue_string.h
@@ -12,12 +12,15 @@
class GValueString : public GValueBase
{
+ Gtk::Widget* create_widget() override;
+
+ void update_widget(Gtk::Widget* widget) override;
+
public:
GValueString(GValue* gobj);
std::string to_string() const override;
- Gtk::Widget* get_widget() const override;
};
#endif /* SRC_GST_DEBUGGER_GVALUE_CONVERTER_GVALUE_STRING_H_ */
diff --git a/src/gst-debugger/gvalue-converter/gvalue_unknown.cpp
b/src/gst-debugger/gvalue-converter/gvalue_unknown.cpp
new file mode 100644
index 0000000..2c91897
--- /dev/null
+++ b/src/gst-debugger/gvalue-converter/gvalue_unknown.cpp
@@ -0,0 +1,28 @@
+/*
+ * gvalue_unknown.cpp
+ *
+ * Created on: Oct 1, 2015
+ * Author: loganek
+ */
+
+#include "gvalue_unknown.h"
+#include "common/gst-utils.h"
+GValueUnknown::GValueUnknown(GValue *gobj)
+: GValueBase(gobj)
+{}
+
+std::string GValueUnknown::to_string() const
+{
+ GstUnknownType *unknown_type = (GstUnknownType*)g_value_get_boxed(g_value);
+ return "unsupported type: " + std::string(unknown_type->type_name);
+}
+
+Gtk::Widget* GValueUnknown::create_widget()
+{
+ auto lbl = new Gtk::Label();
+
+ lbl->set_text(to_string());
+
+ return lbl;
+}
+
diff --git a/src/gst-debugger/gvalue-converter/gvalue_unknown.h
b/src/gst-debugger/gvalue-converter/gvalue_unknown.h
new file mode 100644
index 0000000..78808df
--- /dev/null
+++ b/src/gst-debugger/gvalue-converter/gvalue_unknown.h
@@ -0,0 +1,26 @@
+/*
+ * gvalue_unknown.h
+ *
+ * Created on: Oct 1, 2015
+ * Author: loganek
+ */
+
+#ifndef SRC_GST_DEBUGGER_GVALUE_CONVERTER_GVALUE_UNKNOWN_H_
+#define SRC_GST_DEBUGGER_GVALUE_CONVERTER_GVALUE_UNKNOWN_H_
+
+#include "gvalue_base.h"
+
+class GValueUnknown : public GValueBase
+{
+protected:
+ Gtk::Widget* create_widget() override;
+
+ void update_widget(Gtk::Widget* widget) override{}
+
+public:
+ GValueUnknown(GValue* gobj);
+
+ std::string to_string() const override;
+};
+
+#endif /* SRC_GST_DEBUGGER_GVALUE_CONVERTER_GVALUE_UNKNOWN_H_ */
diff --git a/src/gst-debugger/models/gst_klass_model.h b/src/gst-debugger/models/gst_klass_model.h
index b3669e5..301326e 100644
--- a/src/gst-debugger/models/gst_klass_model.h
+++ b/src/gst-debugger/models/gst_klass_model.h
@@ -51,6 +51,16 @@ public:
}
const std::vector<PropertyModel>& get_properties() const { return properties; }
+
+ boost::optional<PropertyModel> get_property(const std::string &property_name) const
+ {
+ auto it = std::find_if(properties.begin(), properties.end(), [property_name](const
PropertyModel& m) { return m.get_name() == property_name; });
+
+ if (it == properties.end())
+ return boost::none;
+
+ return *it;
+ }
};
#endif /* SRC_GST_DEBUGGER_MODELS_GST_KLASS_MODEL_H_ */
diff --git a/src/gst-debugger/models/gst_pipeline_model.cpp b/src/gst-debugger/models/gst_pipeline_model.cpp
index 017b2d2..48de45e 100644
--- a/src/gst-debugger/models/gst_pipeline_model.cpp
+++ b/src/gst-debugger/models/gst_pipeline_model.cpp
@@ -70,18 +70,21 @@ std::shared_ptr<ElementModel> ElementModel::get_child(const std::string &child_n
return (it != children.end()) ? *it : std::shared_ptr<ElementModel>();
}
-/*void ElementModel::add_property(const std::string &name, const std::shared_ptr<GValueBase>& gvalue)
+std::shared_ptr<GValueBase> ElementModel::add_property(const std::string &name, GValue *g_val)
{
if (properties.find(name) == properties.end())
{
- properties[name] = gvalue;
+ auto vb = std::shared_ptr<GValueBase>(GValueBase::build_gvalue(g_val));
+ properties[name] = vb;
+ return vb;
}
else
{
- gvalue->update_gvalue(gvalue);
+ properties[name]->update_gvalue(g_val);
+ return properties[name];
}
}
-*/
+
std::shared_ptr<ElementModel> ElementModel::get_parent_element_from_path(const std::string &path)
{
ElementPathProcessor proc(path);
diff --git a/src/gst-debugger/models/gst_pipeline_model.h b/src/gst-debugger/models/gst_pipeline_model.h
index 3d233dd..89ba6b2 100644
--- a/src/gst-debugger/models/gst_pipeline_model.h
+++ b/src/gst-debugger/models/gst_pipeline_model.h
@@ -111,12 +111,16 @@ public:
const std::vector<std::shared_ptr<PadModel>>& get_pads() const { return pads; }
- //void add_property(const std::string &name, const std::shared_ptr<GValueBase>& gvalue);
+ std::shared_ptr<GValueBase> add_property(const std::string &name, GValue *g_val);
+
+ bool has_property(const std::string &name) const { return properties.find(name) != properties.end(); }
static std::shared_ptr<ElementModel> get_parent_element_from_path(const std::string &path);
std::map<std::string, std::shared_ptr<GValueBase>> get_properties() const { return properties; }
+ std::string get_type_name() const { return type_name; }
+
std::shared_ptr<GValueBase> get_property(const std::string &name) { return properties[name]; }
void clean_model() { children.clear(); pads.clear(); properties.clear(); }
diff --git a/src/gst-debugger/modules/gst_properties_module.cpp
b/src/gst-debugger/modules/gst_properties_module.cpp
index 4940e15..405bbc5 100644
--- a/src/gst-debugger/modules/gst_properties_module.cpp
+++ b/src/gst-debugger/modules/gst_properties_module.cpp
@@ -73,23 +73,23 @@ void GstPropertiesModule::new_property_()
return;
}
- /* todo std::shared_ptr<GValueBase> value_base = element->get_property(property->name());
- std::shared_ptr<GValueEnum> value_enum = std::dynamic_pointer_cast<GValueEnum>(value_base);
+ std::shared_ptr<GValueBase> value_base = element->get_property(property->name());
+ /*std::shared_ptr<GValueEnum> value_enum = std::dynamic_pointer_cast<GValueEnum>(value_base);
- auto& container = const_cast<RemoteDataContainer<GstEnumType>&>(controller->get_enum_container());
- if (value_enum && container.has_item(property->type_name()))
+ if (value_enum && controller->get_enum_type(property->value().type_name()))
{
- value_enum->set_type(container.get_item(property->type_name()));
- }
+ value_enum->set_type(container.get_item(property->value().type_name()));
+ }*/
- if (!update_property(value_base, property))
+ if (!update_property(value_base, property->name()))
{
- append_property(value_base, property);
- }*/
+ append_property(value_base, property->name());
+ }
+
delete property;
}
-/*bool GstPropertiesModule::update_property(const std::shared_ptr<GValueBase>& value_base,
GstDebugger::PropertyInfo *property)
+bool GstPropertiesModule::update_property(const std::shared_ptr<GValueBase>& value_base, const std::string
prop_name)
{
for (auto internal_box : properties_box->get_children())
{
@@ -99,61 +99,52 @@ void GstPropertiesModule::new_property_()
continue;
}
- Gtk::Label *label = nullptr;
- Gtk::Widget *widget = nullptr;
+ if (reinterpret_cast<gchar*>(hb->get_data("property-name")) != prop_name)
+ continue;
- for (auto cd : hb->get_children())
+ for (auto widget : hb->get_children())
{
- if (label == nullptr && (label = dynamic_cast<Gtk::Label*>(cd)) != nullptr)
- {
- if (label->get_text() != property->name())
- {
- label = nullptr;
- break;
- }
- }
- else if (dynamic_cast<Gtk::Button*>(cd) == nullptr ||
dynamic_cast<Gtk::CheckButton*>(cd) != nullptr)
+ if (widget->get_data("is-gvalue-widget") == GINT_TO_POINTER(1))
{
- widget = cd;
+ bool sensitive = widget->get_sensitive();
+ hb->remove(*widget);
+ widget = value_base->get_widget();
+ widget->set_sensitive(sensitive);
+ widget->show();
+ hb->pack_start(*widget, true, 10);
+ hb->reorder_child(*widget, 1);
+ return true;
}
}
-
- if (label == nullptr || widget == nullptr)
- {
- continue;
- }
-
- hb->remove(*widget);
- widget = value_base->get_widget();
- widget->show();
- hb->pack_start(*widget, true, 10);
- hb->reorder_child(*widget, 1);
- return true;
}
return false;
-}*/
-/*
-void GstPropertiesModule::append_property(const std::shared_ptr<GValueBase>& value_base,
GstDebugger::PropertyInfo *property)
+}
+
+void GstPropertiesModule::append_property(const std::shared_ptr<GValueBase>& value_base, const std::string
&prop_name)
{
+ auto e = std::dynamic_pointer_cast<ElementModel>(controller->get_selected_object());
+ if (!e) return;
+ auto klass = controller->get_klass(e->get_type_name());
+ if (!klass) return;
+ auto prop = klass.get().get_property(prop_name);
+ if (!prop) return;
+
Gtk::Box *hbox = new Gtk::Box (Gtk::ORIENTATION_HORIZONTAL, 0);
- hbox->show();
- auto prop_name = property->name();
+ hbox->set_data("property-name", g_strdup (prop_name.c_str()), g_free);
Gtk::Label *lbl = Gtk::manage(new Gtk::Label(prop_name));
- lbl->set_tooltip_text(property->blurb());
- lbl->show();
+ lbl->set_tooltip_text(prop->get_blurb());
Gtk::Button *btn = Gtk::manage(new Gtk::Button("Refresh"));
btn->signal_clicked().connect([this, prop_name] {request_selected_element_property(prop_name);});
- btn->show();
hbox->pack_start(*lbl, false, false);
auto value_widget = value_base->get_widget();
- value_widget->show();
- value_widget->set_sensitive(property->flags() & G_PARAM_WRITABLE);
+ value_widget->set_sensitive(prop.get().get_flags() & G_PARAM_WRITABLE);
hbox->pack_start(*value_widget, true, true);
hbox->pack_start(*btn, false, false);
properties_box->pack_start(*hbox);
+ hbox->show_all();
}
-*/
+
void GstPropertiesModule::clear_widgets()
{
for (auto c : properties_box->get_children())
diff --git a/src/gst-debugger/modules/gst_properties_module.h
b/src/gst-debugger/modules/gst_properties_module.h
index 24dc973..c2342ed 100644
--- a/src/gst-debugger/modules/gst_properties_module.h
+++ b/src/gst-debugger/modules/gst_properties_module.h
@@ -25,8 +25,8 @@ private:
std::string previous_element_path;
-// void append_property(const std::shared_ptr<GValueBase>& value_base, GstDebugger::PropertyInfo
*property);
-// bool update_property(const std::shared_ptr<GValueBase>& value_base, GstDebugger::PropertyInfo
*property);
+ void append_property(const std::shared_ptr<GValueBase>& value_base, const std::string &prop_name);
+ bool update_property(const std::shared_ptr<GValueBase>& value_base, const std::string prop_name);
void request_selected_element_property(const std::string &property_name);
void show_pad_properties();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]