1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
// This program does not only test the implementation of an interface
// in a custom class. It also tests virtual functions that have leaked memory
// or printed unjustified critical messages in glibmm before version 2.44.
// See https://bugzilla.gnome.org/show_bug.cgi?id=705124.
#include <glibmm.h>
#include <giomm.h> //There are no Interfaces in glibmm, but there are in giomm.
#include <iostream>
#include <cstring>
class CustomAction :
public Gio::Action,
public Glib::Object
{
public:
CustomAction();
// A custom property.
Glib::Property<Glib::ustring> property;
protected:
//Implement vfuncs:
Glib::ustring get_name_vfunc() const override;
Glib::VariantType get_state_type_vfunc() const override;
Glib::VariantBase get_state_hint_vfunc() const override;
};
CustomAction::CustomAction()
: Glib::ObjectBase( typeid(CustomAction) ),
Glib::Object(),
property(*this, "custom_property", "Initial value.")
{
}
static bool get_name_called = false;
Glib::ustring CustomAction::get_name_vfunc() const
{
get_name_called = true;
return "custom-name";
}
Glib::VariantType CustomAction::get_state_type_vfunc() const
{
return Glib::VariantType(G_VARIANT_TYPE_INT16);
}
Glib::VariantBase CustomAction::get_state_hint_vfunc() const
{
return Glib::Variant<gint16>::create(42);
}
int main(int, char**)
{
Glib::init();
CustomAction action;
bool success = true;
Glib::ustring name = action.get_name();
std::cout << "The name is '" << name << "'." << std::endl;
success &= name == "custom-name";
std::cout << "The name property of the implemented interface is '"
<< action.property_name().get_value() << "'." << std::endl;
success &= action.property_name().get_value() == "";
std::cout << "The custom string property is '"
<< action.property.get_value() << "'." << std::endl;
success &= action.property.get_value() == "Initial value.";
action.property = "A new value.";
std::cout << "The custom string property (after changing it) is '"
<< action.property.get_value() << "'." << std::endl;
success &= action.property.get_value() == "A new value.";
gchar* prop_value = nullptr;
g_object_set(action.gobj(), "custom_property", "Another value", NULL);
g_object_get(action.gobj(), "custom_property", &prop_value, NULL);
std::cout << "The custom property after g_object_set/get() is '"
<< prop_value << "'." << std::endl;
success &= std::strcmp(prop_value, "Another value") == 0;
g_free(prop_value);
prop_value = nullptr;
std::cout << "The custom property through the Glib::Property<> is '"
<< action.property.get_value() << "'." << std::endl;
success &= action.property.get_value() == "Another value";
std::cout << "The name property of the implemented interface is '"
<< action.property_name().get_value() << "'." << std::endl;
success &= action.property_name().get_value() == "";
success &= get_name_called;
// Check if other vfuncs leak memory. Use valgrind!
action.get_parameter_type();
action.get_state_type();
action.get_state_type();
action.get_state_hint_variant();
action.get_state_variant();
action.get_enabled();
return success ? EXIT_SUCCESS : EXIT_FAILURE;
}
|