/* buildertest.c
* Copyright ( C ) 2006 - 2007 Async Open Source
* Authors : Johan Dahlin
* Henrique Romano
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation ; either
* version 2 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Library General Public License for more details .
*
* You should have received a copy of the GNU Library General Public
* License along with this library . If not , see < http : //www.gnu.org/licenses/>.
*/
#include <string.h>
#include <libintl.h>
#include <locale.h>
#include <math.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
#ifdef G_OS_WIN32
# define _BUILDER_TEST_EXPORT __declspec(dllexport)
#else
# define _BUILDER_TEST_EXPORT __attribute__((visibility("default" )))
#endif
/* exported for GtkBuilder */
_BUILDER_TEST_EXPORT void signal_normal (GtkWindow *window, GParamSpec *spec);
_BUILDER_TEST_EXPORT void signal_after (GtkWindow *window, GParamSpec *spec);
_BUILDER_TEST_EXPORT void signal_object (GtkButton *button, GParamSpec *spec);
_BUILDER_TEST_EXPORT void signal_object_after (GtkButton *button, GParamSpec *spec);
_BUILDER_TEST_EXPORT void signal_first (GtkButton *button, GParamSpec *spec);
_BUILDER_TEST_EXPORT void signal_second (GtkButton *button, GParamSpec *spec);
_BUILDER_TEST_EXPORT void signal_extra (GtkButton *button, GParamSpec *spec);
_BUILDER_TEST_EXPORT void signal_extra2 (GtkButton *button, GParamSpec *spec);
static GtkBuilder *
builder_new_from_string (const char *buffer,
gsize length,
const char *domain)
{
GtkBuilder *builder;
GError *error = NULL;
builder = gtk_builder_new ();
if (domain)
gtk_builder_set_translation_domain (builder, domain);
gtk_builder_add_from_string (builder, buffer, length, &error);
if (error)
{
g_print ("ERROR: %s" , error->message);
g_error_free (error);
}
return builder;
}
static void
test_parser (void )
{
GtkBuilder *builder;
GError *error;
builder = gtk_builder_new ();
error = NULL;
gtk_builder_add_from_string (builder, "<xxx/>" , -1 , &error);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_UNHANDLED_TAG);
g_clear_error (&error);
gtk_builder_add_from_string (builder, "<interface invalid=\" X\"/>" , -1 , &error);
g_assert_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE);
g_clear_error (&error);
gtk_builder_add_from_string (builder, "<interface><child/></interface>" , -1 , &error);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_TAG);
g_clear_error (&error);
gtk_builder_add_from_string (builder, "<interface><object class=\" GtkBox\" id=\" a\"><object class=\" GtkBox\" id=\" b\"/></object></interface>" , -1 , &error);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_TAG);
g_clear_error (&error);
gtk_builder_add_from_string (builder, "<interface><object class=\" Unknown\" id=\" a\"></object></interface>" , -1 , &error);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_VALUE);
g_clear_error (&error);
gtk_builder_add_from_string (builder, "<interface><object class=\" GtkWidget\" id=\" a\" constructor=\" none\"></object></interface>" , -1 , &error);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_VALUE);
g_clear_error (&error);
gtk_builder_add_from_string (builder, "<interface><object class=\" GtkButton\" id=\" a\"><child internal-child=\" foobar\"><object class=\" GtkButton\" id=\" int \"/></child></object></interface>" , -1 , &error);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_VALUE);
g_clear_error (&error);
gtk_builder_add_from_string (builder, "<interface><object class=\" GtkButton\" id=\" a\"></object><object class=\" GtkButton\" id=\" a\"/></object></interface>" , -1 , &error);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_DUPLICATE_ID);
g_clear_error (&error);
gtk_builder_add_from_string (builder, "<interface><object class=\" GtkButton\" id=\" a\"><property name=\" deafbeef\"></property></object></interface>" , -1 , &error);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_PROPERTY);
g_clear_error (&error);
gtk_builder_add_from_string (builder, "<interface><object class=\" GtkButton\" id=\" a\"><signal name=\" deafbeef\" handler=\" gtk_true\"/></object></interface>" , -1 , &error);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_SIGNAL);
g_error_free (error);
g_object_unref (builder);
}
static int normal = 0 ;
static int after = 0 ;
static int object = 0 ;
static int object_after = 0 ;
_BUILDER_TEST_EXPORT
void /* exported for GtkBuilder */
signal_normal (GtkWindow *window, GParamSpec *spec)
{
g_assert_true (GTK_IS_WINDOW (window));
g_assert_true (normal == 0 );
g_assert_true (after == 0 );
normal++;
}
_BUILDER_TEST_EXPORT
void /* exported for GtkBuilder */
signal_after (GtkWindow *window, GParamSpec *spec)
{
g_assert_true (GTK_IS_WINDOW (window));
g_assert_true (normal == 1 );
g_assert_true (after == 0 );
after++;
}
_BUILDER_TEST_EXPORT
void /* exported for GtkBuilder */
signal_object (GtkButton *button, GParamSpec *spec)
{
g_assert_true (GTK_IS_BUTTON (button));
g_assert_true (object == 0 );
g_assert_true (object_after == 0 );
object++;
}
_BUILDER_TEST_EXPORT
void /* exported for GtkBuilder */
signal_object_after (GtkButton *button, GParamSpec *spec)
{
g_assert_true (GTK_IS_BUTTON (button));
g_assert_true (object == 1 );
g_assert_true (object_after == 0 );
object_after++;
}
_BUILDER_TEST_EXPORT
void /* exported for GtkBuilder */
signal_first (GtkButton *button, GParamSpec *spec)
{
g_assert_true (normal == 0 );
normal = 10 ;
}
_BUILDER_TEST_EXPORT
void /* exported for GtkBuilder */
signal_second (GtkButton *button, GParamSpec *spec)
{
g_assert_true (normal == 10 );
normal = 20 ;
}
_BUILDER_TEST_EXPORT
void /* exported for GtkBuilder */
signal_extra (GtkButton *button, GParamSpec *spec)
{
g_assert_true (normal == 20 );
normal = 30 ;
}
_BUILDER_TEST_EXPORT
void /* exported for GtkBuilder */
signal_extra2 (GtkButton *button, GParamSpec *spec)
{
g_assert_true (normal == 30 );
normal = 40 ;
}
static void
test_connect_signals (void )
{
GtkBuilder *builder;
GObject *window;
const char buffer[] =
"<interface>"
" <object class=\" GtkButton\" id=\" button\"/>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <signal name=\" notify::title\" handler=\" signal_normal\"/>"
" <signal name=\" notify::title\" handler=\" signal_after\" after=\" yes\"/>"
" <signal name=\" notify::title\" handler=\" signal_object\""
" object=\" button\"/>"
" <signal name=\" notify::title\" handler=\" signal_object_after\""
" object=\" button\" after=\" yes\"/>"
" </object>"
"</interface>" ;
const char buffer_order[] =
"<interface>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <signal name=\" notify::title\" handler=\" signal_first\"/>"
" <signal name=\" notify::title\" handler=\" signal_second\"/>"
" </object>"
"</interface>" ;
const char buffer_extra[] =
"<interface>"
" <object class=\" GtkWindow\" id=\" window2\">"
" <signal name=\" notify::title\" handler=\" signal_extra\"/>"
" </object>"
"</interface>" ;
const char buffer_extra2[] =
"<interface>"
" <object class=\" GtkWindow\" id=\" window3\">"
" <signal name=\" notify::title\" handler=\" signal_extra2\"/>"
" </object>"
"</interface>" ;
const char buffer_after_child[] =
"<interface>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <child>"
" <object class=\" GtkButton\" id=\" button1\"/>"
" </child>"
" <signal name=\" notify::title\" handler=\" signal_normal\"/>"
" </object>"
"</interface>" ;
builder = builder_new_from_string (buffer, -1 , NULL);
window = gtk_builder_get_object (builder, "window1" );
gtk_window_set_title (GTK_WINDOW (window), "test" );
g_assert_cmpint (normal, ==, 1 );
g_assert_cmpint (after, ==, 1 );
g_assert_cmpint (object, ==, 1 );
g_assert_cmpint (object_after, ==, 1 );
gtk_window_destroy (GTK_WINDOW (window));
g_object_unref (builder);
builder = builder_new_from_string (buffer_order, -1 , NULL);
window = gtk_builder_get_object (builder, "window1" );
normal = 0 ;
gtk_window_set_title (GTK_WINDOW (window), "test" );
g_assert_true (normal == 20 );
gtk_window_destroy (GTK_WINDOW (window));
gtk_builder_add_from_string (builder, buffer_extra,
strlen (buffer_extra), NULL);
gtk_builder_add_from_string (builder, buffer_extra2,
strlen (buffer_extra2), NULL);
window = gtk_builder_get_object (builder, "window2" );
gtk_window_set_title (GTK_WINDOW (window), "test" );
g_assert_true (normal == 30 );
gtk_window_destroy (GTK_WINDOW (window));
window = gtk_builder_get_object (builder, "window3" );
gtk_window_set_title (GTK_WINDOW (window), "test" );
g_assert_true (normal == 40 );
gtk_window_destroy (GTK_WINDOW (window));
g_object_unref (builder);
/* new test, reset globals */
after = 0 ;
normal = 0 ;
builder = builder_new_from_string (buffer_after_child, -1 , NULL);
window = gtk_builder_get_object (builder, "window1" );
gtk_window_set_title (GTK_WINDOW (window), "test" );
g_assert_true (normal == 1 );
gtk_window_destroy (GTK_WINDOW (window));
g_object_unref (builder);
}
static void
test_domain (void )
{
GtkBuilder *builder;
const char buffer1[] = "<interface/>" ;
const char buffer2[] = "<interface domain=\" domain\"/>" ;
const char *domain;
builder = builder_new_from_string (buffer1, -1 , NULL);
domain = gtk_builder_get_translation_domain (builder);
g_assert_true (domain == NULL);
g_object_unref (builder);
builder = builder_new_from_string (buffer1, -1 , "domain-1" );
domain = gtk_builder_get_translation_domain (builder);
g_assert_nonnull (domain);
g_assert_true (strcmp (domain, "domain-1" ) == 0 );
g_object_unref (builder);
builder = builder_new_from_string (buffer2, -1 , NULL);
domain = gtk_builder_get_translation_domain (builder);
g_assert_null (domain);
g_object_unref (builder);
}
#if 0
static void
test_translation (void )
{
GtkBuilder *builder;
const char buffer[] =
"<interface>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <child>"
" <object class=\" GtkLabel\" id=\" label\">"
" <property name=\" label\" translatable=\" yes\">File</property>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
GtkLabel *window, *label;
setlocale (LC_ALL, "sv_SE" );
textdomain ("builder" );
bindtextdomain ("builder" , "tests" );
builder = builder_new_from_string (buffer, -1 , NULL);
label = GTK_LABEL (gtk_builder_get_object (builder, "label" ));
g_assert_true (strcmp (gtk_label_get_text (label), "Arkiv" ) == 0 );
window = gtk_builder_get_object (builder, "window1" );
gtk_window_destroy (GTK_WINDOW (window));
g_object_unref (builder);
}
#endif
static void
test_sizegroup (void )
{
GtkBuilder * builder;
const char buffer1[] =
"<interface domain=\" test\">"
" <object class=\" GtkSizeGroup\" id=\" sizegroup1\">"
" <property name=\" mode\">horizontal</property>"
" <widgets>"
" <widget name=\" radio1\"/>"
" <widget name=\" radio2\"/>"
" </widgets>"
" </object>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <child>"
" <object class=\" GtkBox\" id=\" vbox1\">"
" <property name=\" orientation\">vertical</property>"
" <child>"
" <object class=\" GtkCheckButton\" id=\" radio1\"/>"
" </child>"
" <child>"
" <object class=\" GtkCheckButton\" id=\" radio2\"/>"
" </child>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
const char buffer2[] =
"<interface domain=\" test\">"
" <object class=\" GtkSizeGroup\" id=\" sizegroup1\">"
" <property name=\" mode\">horizontal</property>"
" <widgets>"
" </widgets>"
" </object>"
"</interface>" ;
const char buffer3[] =
"<interface domain=\" test\">"
" <object class=\" GtkSizeGroup\" id=\" sizegroup1\">"
" <property name=\" mode\">horizontal</property>"
" <widgets>"
" <widget name=\" radio1\"/>"
" <widget name=\" radio2\"/>"
" </widgets>"
" </object>"
" <object class=\" GtkSizeGroup\" id=\" sizegroup2\">"
" <property name=\" mode\">horizontal</property>"
" <widgets>"
" <widget name=\" radio1\"/>"
" <widget name=\" radio2\"/>"
" </widgets>"
" </object>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <child>"
" <object class=\" GtkBox\" id=\" vbox1\">"
" <property name=\" orientation\">vertical</property>"
" <child>"
" <object class=\" GtkCheckButton\" id=\" radio1\"/>"
" </child>"
" <child>"
" <object class=\" GtkCheckButton\" id=\" radio2\"/>"
" </child>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
GObject *sizegroup;
GSList *widgets;
builder = builder_new_from_string (buffer1, -1 , NULL);
sizegroup = gtk_builder_get_object (builder, "sizegroup1" );
widgets = gtk_size_group_get_widgets (GTK_SIZE_GROUP (sizegroup));
g_assert_cmpint (g_slist_length (widgets), ==, 2 );
g_slist_free (widgets);
g_object_unref (builder);
builder = builder_new_from_string (buffer2, -1 , NULL);
sizegroup = gtk_builder_get_object (builder, "sizegroup1" );
widgets = gtk_size_group_get_widgets (GTK_SIZE_GROUP (sizegroup));
g_assert_cmpint (g_slist_length (widgets), ==, 0 );
g_slist_free (widgets);
g_object_unref (builder);
builder = builder_new_from_string (buffer3, -1 , NULL);
sizegroup = gtk_builder_get_object (builder, "sizegroup1" );
widgets = gtk_size_group_get_widgets (GTK_SIZE_GROUP (sizegroup));
g_assert_cmpint (g_slist_length (widgets), ==, 2 );
g_slist_free (widgets);
sizegroup = gtk_builder_get_object (builder, "sizegroup2" );
widgets = gtk_size_group_get_widgets (GTK_SIZE_GROUP (sizegroup));
g_assert_cmpint (g_slist_length (widgets), ==, 2 );
g_slist_free (widgets);
#if 0
{
GObject *window;
window = gtk_builder_get_object (builder, "window1" );
gtk_window_destroy (GTK_WINDOW (window));
}
#endif
g_object_unref (builder);
}
static void
test_list_store (void )
{
const char buffer1[] =
"<interface>"
" <object class=\" GtkListStore\" id=\" liststore1\">"
" <columns>"
" <column type=\" gchararray\"/>"
" <column type=\" guint\"/>"
" </columns>"
" </object>"
"</interface>" ;
const char buffer2[] =
"<interface>"
" <object class=\" GtkListStore\" id=\" liststore1\">"
" <columns>"
" <column type=\" gchararray\"/>"
" <column type=\" gchararray\"/>"
" <column type=\" gint\"/>"
" </columns>"
" <data>"
" <row>"
" <col id=\" 0 \" translatable=\" yes\">John</col>"
" <col id=\" 1 \" context=\" foo\">Doe</col>"
" <col id=\" 2 \" comments=\" foobar\">25</col>"
" </row>"
" <row>"
" <col id=\" 0 \">Johan</col>"
" <col id=\" 1 \">Dole</col>"
" <col id=\" 2 \">50</col>"
" </row>"
" </data>"
" </object>"
"</interface>" ;
const char buffer3[] =
"<interface>"
" <object class=\" GtkListStore\" id=\" liststore1\">"
" <columns>"
" <column type=\" gchararray\"/>"
" <column type=\" gchararray\"/>"
" <column type=\" gint\"/>"
" </columns>"
" <data>"
" <row>"
" <col id=\" 1 \" context=\" foo\">Doe</col>"
" <col id=\" 0 \" translatable=\" yes\">John</col>"
" <col id=\" 2 \" comments=\" foobar\">25</col>"
" </row>"
" <row>"
" <col id=\" 2 \">50</col>"
" <col id=\" 1 \">Dole</col>"
" <col id=\" 0 \">Johan</col>"
" </row>"
" <row>"
" <col id=\" 2 \">19</col>"
" </row>"
" </data>"
" </object>"
"</interface>" ;
GtkBuilder *builder;
GObject *store;
GtkTreeIter iter;
char *surname, *lastname;
int age;
builder = builder_new_from_string (buffer1, -1 , NULL);
store = gtk_builder_get_object (builder, "liststore1" );
g_assert_cmpint (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)), ==, 2 );
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0 ), ==, G_TYPE_STRING);
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1 ), ==, G_TYPE_UINT);
g_object_unref (builder);
builder = builder_new_from_string (buffer2, -1 , NULL);
store = gtk_builder_get_object (builder, "liststore1" );
g_assert_cmpint (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)), ==, 3 );
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0 ), ==, G_TYPE_STRING);
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1 ), ==, G_TYPE_STRING);
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 2 ), ==, G_TYPE_INT);
g_assert_cmpint (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter), ==, TRUE );
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
0 , &surname,
1 , &lastname,
2 , &age,
-1 );
g_assert_cmpstr (surname, ==, "John" );
g_free (surname);
g_assert_cmpstr (lastname, ==, "Doe" );
g_free (lastname);
g_assert_cmpint (age, ==, 25 );
g_assert_true (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
0 , &surname,
1 , &lastname,
2 , &age,
-1 );
g_assert_cmpstr (surname, ==, "Johan" );
g_free (surname);
g_assert_cmpstr (lastname, ==, "Dole" );
g_free (lastname);
g_assert_cmpint (age, ==, 50 );
g_assert_false (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
g_object_unref (builder);
builder = builder_new_from_string (buffer3, -1 , NULL);
store = gtk_builder_get_object (builder, "liststore1" );
g_assert_cmpint (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)), ==, 3 );
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0 ), ==, G_TYPE_STRING);
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1 ), ==, G_TYPE_STRING);
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 2 ), ==, G_TYPE_INT);
g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
0 , &surname,
1 , &lastname,
2 , &age,
-1 );
g_assert_cmpstr (surname, ==, "John" );
g_free (surname);
g_assert_cmpstr (lastname, ==, "Doe" );
g_free (lastname);
g_assert_cmpint (age, ==, 25 );
g_assert_true (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
0 , &surname,
1 , &lastname,
2 , &age,
-1 );
g_assert_cmpstr (surname, ==, "Johan" );
g_free (surname);
g_assert_cmpstr (lastname, ==, "Dole" );
g_free (lastname);
g_assert_cmpint (age, ==, 50 );
g_assert_true (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
0 , &surname,
1 , &lastname,
2 , &age,
-1 );
g_assert_null (surname);
g_assert_null (lastname);
g_assert_cmpint (age, ==, 19 );
g_assert_false (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
g_object_unref (builder);
}
static void
test_tree_store (void )
{
const char buffer[] =
"<interface domain=\" test\">"
" <object class=\" GtkTreeStore\" id=\" treestore1\">"
" <columns>"
" <column type=\" gchararray\"/>"
" <column type=\" guint\"/>"
" </columns>"
" </object>"
"</interface>" ;
const char buffer2[] =
"<interface>"
" <object class=\" GtkTreeStore\" id=\" treestore1\">"
" <columns>"
" <column type=\" gchararray\"/>"
" <column type=\" gchararray\"/>"
" <column type=\" gint\"/>"
" </columns>"
" <data>"
" <row>"
" <col id=\" 0 \" translatable=\" yes\">John</col>"
" <col id=\" 1 \" context=\" foo\">Doe</col>"
" <col id=\" 2 \" comments=\" foobar\">25</col>"
" </row>"
" <row>"
" <col id=\" 0 \">Johan</col>"
" <col id=\" 1 \">Dole</col>"
" <col id=\" 2 \">50</col>"
" </row>"
" </data>"
" </object>"
"</interface>" ;
const char buffer3[] =
"<interface>"
" <object class=\" GtkTreeStore\" id=\" treestore1\">"
" <columns>"
" <column type=\" gchararray\"/>"
" <column type=\" gchararray\"/>"
" <column type=\" gint\"/>"
" </columns>"
" <data>"
" <row>"
" <col id=\" 1 \" context=\" foo\">Doe</col>"
" <col id=\" 0 \" translatable=\" yes\">John</col>"
" <col id=\" 2 \" comments=\" foobar\">25</col>"
" </row>"
" <row>"
" <col id=\" 2 \">50</col>"
" <col id=\" 1 \">Dole</col>"
" <col id=\" 0 \">Johan</col>"
" </row>"
" <row>"
" <col id=\" 2 \">19</col>"
" </row>"
" </data>"
" </object>"
"</interface>" ;
const char buffer4[] =
"<interface>"
" <object class=\" GtkTreeStore\" id=\" treestore1\">"
" <columns>"
" <column type=\" gchararray\"/>"
" <column type=\" gchararray\"/>"
" <column type=\" gint\"/>"
" </columns>"
" <data>"
" <row>"
" <col id=\" 1 \" context=\" foo\">Doe</col>"
" <col id=\" 0 \" translatable=\" yes\">John</col>"
" <col id=\" 2 \" comments=\" foobar\">25</col>"
" <row>"
" <col id=\" 2 \">50</col>"
" <col id=\" 1 \">Dole</col>"
" <col id=\" 0 \">Johan</col>"
" </row>"
" </row>"
" <row>"
" <col id=\" 2 \">19</col>"
" </row>"
" </data>"
" </object>"
"</interface>" ;
GtkBuilder *builder;
GObject *store;
GtkTreeIter iter, parent;
char *surname, *lastname;
int age;
builder = builder_new_from_string (buffer, -1 , NULL);
store = gtk_builder_get_object (builder, "treestore1" );
g_assert_true (GTK_IS_TREE_STORE (store));
g_assert_cmpint (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)), ==, 2 );
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0 ), ==, G_TYPE_STRING);
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1 ), ==, G_TYPE_UINT);
g_object_unref (builder);
builder = builder_new_from_string (buffer2, -1 , NULL);
store = gtk_builder_get_object (builder, "treestore1" );
g_assert_true (GTK_IS_TREE_STORE (store));
g_assert_cmpint (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)), ==, 3 );
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0 ), ==, G_TYPE_STRING);
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1 ), ==, G_TYPE_STRING);
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 2 ), ==, G_TYPE_INT);
g_assert_cmpint (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter), ==, TRUE );
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
0 , &surname,
1 , &lastname,
2 , &age,
-1 );
g_assert_cmpstr (surname, ==, "John" );
g_free (surname);
g_assert_cmpstr (lastname, ==, "Doe" );
g_free (lastname);
g_assert_cmpint (age, ==, 25 );
g_assert_true (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
0 , &surname,
1 , &lastname,
2 , &age,
-1 );
g_assert_cmpstr (surname, ==, "Johan" );
g_free (surname);
g_assert_cmpstr (lastname, ==, "Dole" );
g_free (lastname);
g_assert_cmpint (age, ==, 50 );
g_assert_false (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
g_object_unref (builder);
builder = builder_new_from_string (buffer3, -1 , NULL);
store = gtk_builder_get_object (builder, "treestore1" );
g_assert_true (GTK_IS_TREE_STORE (store));
g_assert_cmpint (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)), ==, 3 );
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0 ), ==, G_TYPE_STRING);
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1 ), ==, G_TYPE_STRING);
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 2 ), ==, G_TYPE_INT);
g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
0 , &surname,
1 , &lastname,
2 , &age,
-1 );
g_assert_cmpstr (surname, ==, "John" );
g_free (surname);
g_assert_cmpstr (lastname, ==, "Doe" );
g_free (lastname);
g_assert_cmpint (age, ==, 25 );
g_assert_true (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
0 , &surname,
1 , &lastname,
2 , &age,
-1 );
g_assert_cmpstr (surname, ==, "Johan" );
g_free (surname);
g_assert_cmpstr (lastname, ==, "Dole" );
g_free (lastname);
g_assert_cmpint (age, ==, 50 );
g_assert_true (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
0 , &surname,
1 , &lastname,
2 , &age,
-1 );
g_assert_null (surname);
g_assert_null (lastname);
g_assert_cmpint (age, ==, 19 );
g_assert_false (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
g_object_unref (builder);
builder = builder_new_from_string (buffer4, -1 , NULL);
store = gtk_builder_get_object (builder, "treestore1" );
g_assert_true (GTK_IS_TREE_STORE (store));
g_assert_cmpint (gtk_tree_model_get_n_columns (GTK_TREE_MODEL (store)), ==, 3 );
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 0 ), ==, G_TYPE_STRING);
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 1 ), ==, G_TYPE_STRING);
g_assert_cmpint (gtk_tree_model_get_column_type (GTK_TREE_MODEL (store), 2 ), ==, G_TYPE_INT);
g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
0 , &surname,
1 , &lastname,
2 , &age,
-1 );
g_assert_cmpstr (surname, ==, "John" );
g_free (surname);
g_assert_cmpstr (lastname, ==, "Doe" );
g_free (lastname);
g_assert_cmpint (age, ==, 25 );
parent = iter;
g_assert_true (gtk_tree_model_iter_children (GTK_TREE_MODEL (store), &iter, &parent));
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
0 , &surname,
1 , &lastname,
2 , &age,
-1 );
g_assert_cmpstr (surname, ==, "Johan" );
g_free (surname);
g_assert_cmpstr (lastname, ==, "Dole" );
g_free (lastname);
g_assert_cmpint (age, ==, 50 );
g_assert_false (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
iter = parent;
g_assert_true (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
0 , &surname,
1 , &lastname,
2 , &age,
-1 );
g_assert_null (surname);
g_assert_null (lastname);
g_assert_cmpint (age, ==, 19 );
g_assert_false (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
g_object_unref (builder);
}
static void
test_types (void )
{
const char buffer[] =
"<interface>"
" <object class=\" GtkBox\" id=\" box\"/>"
" <object class=\" GtkButton\" id=\" button\"/>"
" <object class=\" GtkCheckButton\" id=\" checkbutton\"/>"
" <object class=\" GtkDialog\" id=\" dialog\"/>"
" <object class=\" GtkDrawingArea\" id=\" drawingarea\"/>"
" <object class=\" GtkEntry\" id=\" entry\"/>"
" <object class=\" GtkFontButton\" id=\" fontbutton\"/>"
" <object class=\" GtkImage\" id=\" image\"/>"
" <object class=\" GtkLabel\" id=\" label\"/>"
" <object class=\" GtkListStore\" id=\" liststore\"/>"
" <object class=\" GtkNotebook\" id=\" notebook\"/>"
" <object class=\" GtkProgressBar\" id=\" progressbar\"/>"
" <object class=\" GtkSizeGroup\" id=\" sizegroup\"/>"
" <object class=\" GtkScrolledWindow\" id=\" scrolledwindow\"/>"
" <object class=\" GtkSpinButton\" id=\" spinbutton\"/>"
" <object class=\" GtkStatusbar\" id=\" statusbar\"/>"
" <object class=\" GtkTextView\" id=\" textview\"/>"
" <object class=\" GtkToggleButton\" id=\" togglebutton\"/>"
" <object class=\" GtkTreeStore\" id=\" treestore\"/>"
" <object class=\" GtkTreeView\" id=\" treeview\"/>"
" <object class=\" GtkViewport\" id=\" viewport\"/>"
" <object class=\" GtkWindow\" id=\" window\"/>"
"</interface>" ;
const char buffer2[] =
"<interface>"
" <object class=\" GtkWindow\" type-func=\" gtk_window_get_type\" id=\" window\"/>"
"</interface>" ;
const char buffer3[] =
"<interface>"
" <object class=\" XXXInvalidType\" type-func=\" gtk_window_get_type\" id=\" window\"/>"
"</interface>" ;
const char buffer4[] =
"<interface>"
" <object class=\" GtkWindow\" type-func=\" xxx_invalid_get_type_function\" id=\" window\"/>"
"</interface>" ;
const char buffer5[] =
"<interface>"
" <object type-func=\" gtk_window_get_type\" id=\" window\"/>"
"</interface>" ;
GtkBuilder *builder;
GObject *window;
GError *error;
builder = builder_new_from_string (buffer, -1 , NULL);
gtk_window_destroy (GTK_WINDOW (gtk_builder_get_object (builder, "dialog" )));
gtk_window_destroy (GTK_WINDOW (gtk_builder_get_object (builder, "window" )));
g_object_unref (builder);
builder = builder_new_from_string (buffer2, -1 , NULL);
window = gtk_builder_get_object (builder, "window" );
g_assert_true (GTK_IS_WINDOW (window));
gtk_window_destroy (GTK_WINDOW (window));
g_object_unref (builder);
builder = builder_new_from_string (buffer3, -1 , NULL);
window = gtk_builder_get_object (builder, "window" );
g_assert_true (GTK_IS_WINDOW (window));
gtk_window_destroy (GTK_WINDOW (window));
g_object_unref (builder);
error = NULL;
builder = gtk_builder_new ();
gtk_builder_add_from_string (builder, buffer4, -1 , &error);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_TYPE_FUNCTION);
g_error_free (error);
g_object_unref (builder);
error = NULL;
builder = gtk_builder_new ();
gtk_builder_add_from_string (builder, buffer5, -1 , &error);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_MISSING_ATTRIBUTE);
g_error_free (error);
g_object_unref (builder);
}
static void
test_spin_button (void )
{
GtkBuilder *builder;
const char buffer[] =
"<interface>"
"<object class=\" GtkAdjustment\" id=\" adjustment1\">"
"<property name=\" lower\">0</property>"
"<property name=\" upper\">10</property>"
"<property name=\" step-increment\">2</property>"
"<property name=\" page-increment\">3</property>"
"<property name=\" page-size\">0</property>"
"<property name=\" value\">1</property>"
"</object>"
"<object class=\" GtkSpinButton\" id=\" spinbutton1\">"
"<property name=\" visible\">True</property>"
"<property name=\" adjustment\">adjustment1</property>"
"</object>"
"</interface>" ;
GObject *obj;
GtkAdjustment *adjustment;
double value;
builder = builder_new_from_string (buffer, -1 , NULL);
obj = gtk_builder_get_object (builder, "spinbutton1" );
g_assert_true (GTK_IS_SPIN_BUTTON (obj));
adjustment = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (obj));
g_assert_true (GTK_IS_ADJUSTMENT (adjustment));
g_object_get (adjustment, "value" , &value, NULL);
g_assert_cmpint (value, ==, 1 );
g_object_get (adjustment, "lower" , &value, NULL);
g_assert_cmpint (value, ==, 0 );
g_object_get (adjustment, "upper" , &value, NULL);
g_assert_cmpint (value, ==, 10 );
g_object_get (adjustment, "step-increment" , &value, NULL);
g_assert_cmpint (value, ==, 2 );
g_object_get (adjustment, "page-increment" , &value, NULL);
g_assert_cmpint (value, ==, 3 );
g_object_get (adjustment, "page-size" , &value, NULL);
g_assert_cmpint (value, ==, 0 );
g_object_unref (builder);
}
static void
test_notebook (void )
{
GtkBuilder *builder;
const char buffer[] =
"<interface>"
" <object class=\" GtkNotebook\" id=\" notebook1\">"
" <child>"
" <object class=\" GtkNotebookPage\">"
" <property name=\" child\">"
" <object class=\" GtkLabel\" id=\" label1\">"
" <property name=\" label\">label1</property>"
" </object>"
" </property>"
" <property name=\" tab\">"
" <object class=\" GtkLabel\" id=\" tablabel1\">"
" <property name=\" label\">tab_label1</property>"
" </object>"
" </property>"
" </object>"
" </child>"
" <child>"
" <object class=\" GtkNotebookPage\">"
" <property name=\" child\">"
" <object class=\" GtkLabel\" id=\" label2\">"
" <property name=\" label\">label2</property>"
" </object>"
" </property>"
" <property name=\" tab\">"
" <object class=\" GtkLabel\" id=\" tablabel2\">"
" <property name=\" label\">tab_label2</property>"
" </object>"
" </property>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
GObject *notebook;
GtkWidget *label;
builder = builder_new_from_string (buffer, -1 , NULL);
notebook = gtk_builder_get_object (builder, "notebook1" );
g_assert_nonnull (notebook);
g_assert_cmpint (gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)), ==, 2 );
label = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 0 );
g_assert_true (GTK_IS_LABEL (label));
g_assert_cmpstr (gtk_label_get_label (GTK_LABEL (label)), ==, "label1" );
label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (notebook), label);
g_assert_true (GTK_IS_LABEL (label));
g_assert_cmpstr (gtk_label_get_label (GTK_LABEL (label)), ==, "tab_label1" );
label = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 1 );
g_assert_true (GTK_IS_LABEL (label));
g_assert_cmpstr (gtk_label_get_label (GTK_LABEL (label)), ==, "label2" );
label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (notebook), label);
g_assert_true (GTK_IS_LABEL (label));
g_assert_cmpstr (gtk_label_get_label (GTK_LABEL (label)), ==, "tab_label2" );
g_object_unref (builder);
}
static void
test_construct_only_property (void )
{
GtkBuilder *builder;
const char buffer[] =
"<interface>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <property name=\" css-name\">amazing</property>"
" </object>"
"</interface>" ;
const char buffer2[] =
"<interface>"
" <object class=\" GtkTextTagTable\" id=\" tagtable1\"/>"
" <object class=\" GtkTextBuffer\" id=\" textbuffer1\">"
" <property name=\" tag-table\">tagtable1</property>"
" </object>"
"</interface>" ;
GObject *widget, *tagtable, *textbuffer;
builder = builder_new_from_string (buffer, -1 , NULL);
widget = gtk_builder_get_object (builder, "window1" );
g_assert_cmpstr (gtk_widget_get_css_name (GTK_WIDGET (widget)), ==, "amazing" );
gtk_window_destroy (GTK_WINDOW (widget));
g_object_unref (builder);
builder = builder_new_from_string (buffer2, -1 , NULL);
textbuffer = gtk_builder_get_object (builder, "textbuffer1" );
g_assert_nonnull (textbuffer);
g_object_get (textbuffer, "tag-table" , &tagtable, NULL);
g_assert_true (tagtable == gtk_builder_get_object (builder, "tagtable1" ));
g_object_unref (tagtable);
g_object_unref (builder);
}
static void
test_object_properties (void )
{
GtkBuilder *builder;
const char buffer[] =
"<interface>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <child>"
" <object class=\" GtkBox\" id=\" vbox\">"
" <property name=\" orientation\">vertical</property>"
" <child>"
" <object class=\" GtkLabel\" id=\" label1\">"
" <property name=\" mnemonic-widget\">spinbutton1</property>"
" </object>"
" </child>"
" <child>"
" <object class=\" GtkSpinButton\" id=\" spinbutton1\"/>"
" </child>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
const char buffer2[] =
"<interface>"
" <object class=\" GtkWindow\" id=\" window2\"/>"
"</interface>" ;
GObject *label, *spinbutton, *window;
builder = builder_new_from_string (buffer, -1 , NULL);
label = gtk_builder_get_object (builder, "label1" );
g_assert_nonnull (label);
spinbutton = gtk_builder_get_object (builder, "spinbutton1" );
g_assert_nonnull (spinbutton);
g_assert_true (spinbutton == (GObject*)gtk_label_get_mnemonic_widget (GTK_LABEL (label)));
gtk_builder_add_from_string (builder, buffer2, -1 , NULL);
window = gtk_builder_get_object (builder, "window2" );
g_assert_nonnull (window);
gtk_window_destroy (GTK_WINDOW (window));
g_object_unref (builder);
}
static void
test_children (void )
{
GtkBuilder * builder;
GtkWidget *content_area;
const char buffer1[] =
"<interface>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <child>"
" <object class=\" GtkButton\" id=\" button1\">"
" <property name=\" label\">Hello</property>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
const char buffer2[] =
"<interface>"
" <object class=\" GtkDialog\" id=\" dialog1\">"
" <property name=\" use_header_bar\">1</property>"
" <child internal-child=\" content_area\">"
" <object class=\" GtkBox\" id=\" dialog1-vbox\">"
" <property name=\" orientation\">vertical</property>"
" <child internal-child=\" action_area\">"
" <object class=\" GtkBox\" id=\" dialog1-action_area\">"
" <property name=\" orientation\">horizontal</property>"
" </object>"
" </child>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
GObject *window, *button;
GObject *dialog, *vbox, *action_area;
GtkWidget *child;
int count;
builder = builder_new_from_string (buffer1, -1 , NULL);
window = gtk_builder_get_object (builder, "window1" );
g_assert_true (GTK_IS_WINDOW (window));
button = gtk_builder_get_object (builder, "button1" );
g_assert_true (GTK_IS_BUTTON (button));
g_assert_nonnull (gtk_widget_get_parent (GTK_WIDGET(button)));
g_assert_cmpstr (gtk_buildable_get_buildable_id (GTK_BUILDABLE (gtk_widget_get_parent (GTK_WIDGET (button)))), ==, "window1" );
gtk_window_destroy (GTK_WINDOW (window));
g_object_unref (builder);
builder = builder_new_from_string (buffer2, -1 , NULL);
dialog = gtk_builder_get_object (builder, "dialog1" );
g_assert_true (GTK_IS_DIALOG (dialog));
count = 0 ;
for (child = gtk_widget_get_first_child (GTK_WIDGET (dialog));
child != NULL;
child = gtk_widget_get_next_sibling (child))
count++;
g_assert_cmpint (count, ==, 2 );
vbox = gtk_builder_get_object (builder, "dialog1-vbox" );
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
g_assert_true (GTK_IS_BOX (vbox));
g_assert_cmpint (gtk_orientable_get_orientation (GTK_ORIENTABLE (vbox)), ==, GTK_ORIENTATION_VERTICAL);
g_assert_cmpstr (gtk_buildable_get_buildable_id (GTK_BUILDABLE (content_area)), ==, "dialog1-vbox" );
action_area = gtk_builder_get_object (builder, "dialog1-action_area" );
g_assert_true (GTK_IS_BOX (action_area));
g_assert_cmpint (gtk_orientable_get_orientation (GTK_ORIENTABLE (action_area)), ==, GTK_ORIENTATION_HORIZONTAL);
g_assert_nonnull (gtk_widget_get_parent (GTK_WIDGET (action_area)));
g_assert_nonnull (gtk_buildable_get_buildable_id (GTK_BUILDABLE (action_area)));
gtk_window_destroy (GTK_WINDOW (dialog));
g_object_unref (builder);
}
static void
test_layout_properties (void )
{
GtkBuilder * builder;
const char buffer1[] =
"<interface>"
" <object class=\" GtkGrid\" id=\" grid1\">"
" <child>"
" <object class=\" GtkLabel\" id=\" label1\">"
" <layout>"
" <property name=\" column\">1</property>"
" </layout>"
" </object>"
" </child>"
" <child>"
" <object class=\" GtkLabel\" id=\" label2\">"
" <layout>"
" <property name=\" column\">0</property>"
" </layout>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
GObject *label, *vbox;
builder = builder_new_from_string (buffer1, -1 , NULL);
vbox = gtk_builder_get_object (builder, "grid1" );
g_assert_true (GTK_IS_GRID (vbox));
label = gtk_builder_get_object (builder, "label1" );
g_assert_true (GTK_IS_LABEL (label));
label = gtk_builder_get_object (builder, "label2" );
g_assert_true (GTK_IS_LABEL (label));
g_object_unref (builder);
}
static void
test_treeview_column (void )
{
GtkBuilder *builder;
const char buffer[] =
"<interface>"
"<object class=\" GtkListStore\" id=\" liststore1\">"
" <columns>"
" <column type=\" gchararray\"/>"
" <column type=\" guint\"/>"
" </columns>"
" <data>"
" <row>"
" <col id=\" 0 \">John</col>"
" <col id=\" 1 \">25</col>"
" </row>"
" </data>"
"</object>"
"<object class=\" GtkWindow\" id=\" window1\">"
" <child>"
" <object class=\" GtkTreeView\" id=\" treeview1\">"
" <property name=\" visible\">True</property>"
" <property name=\" model\">liststore1</property>"
" <child>"
" <object class=\" GtkTreeViewColumn\" id=\" column1\">"
" <property name=\" title\">Test</property>"
" <child>"
" <object class=\" GtkCellRendererText\" id=\" renderer1\"/>"
" <attributes>"
" <attribute name=\" text\">1</attribute>"
" </attributes>"
" </child>"
" </object>"
" </child>"
" <child>"
" <object class=\" GtkTreeViewColumn\" id=\" column2\">"
" <property name=\" title\">Number</property>"
" <child>"
" <object class=\" GtkCellRendererText\" id=\" renderer2\"/>"
" <attributes>"
" <attribute name=\" text\">0</attribute>"
" </attributes>"
" </child>"
" </object>"
" </child>"
" </object>"
" </child>"
"</object>"
"</interface>" ;
GObject *window, *treeview;
GtkTreeViewColumn *column;
GList *renderers;
GObject *renderer;
builder = builder_new_from_string (buffer, -1 , NULL);
treeview = gtk_builder_get_object (builder, "treeview1" );
g_assert_true (GTK_IS_TREE_VIEW (treeview));
column = gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), 0 );
g_assert_true (GTK_IS_TREE_VIEW_COLUMN (column));
g_assert_cmpstr (gtk_tree_view_column_get_title (column), ==, "Test" );
renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
g_assert_cmpint (g_list_length (renderers), ==, 1 );
renderer = g_list_nth_data (renderers, 0 );
g_assert_true (GTK_IS_CELL_RENDERER_TEXT (renderer));
g_list_free (renderers);
window = gtk_builder_get_object (builder, "window1" );
gtk_window_destroy (GTK_WINDOW (window));
g_object_unref (builder);
}
static void
test_icon_view (void )
{
GtkBuilder *builder;
const char buffer[] =
"<interface>"
" <object class=\" GtkListStore\" id=\" liststore1\">"
" <columns>"
" <column type=\" gchararray\"/>"
" <column type=\" GdkPixbuf\"/>"
" </columns>"
" <data>"
" <row>"
" <col id=\" 0 \">test</col>"
" </row>"
" </data>"
" </object>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <child>"
" <object class=\" GtkIconView\" id=\" iconview1\">"
" <property name=\" model\">liststore1</property>"
" <property name=\" text-column\">0</property>"
" <property name=\" pixbuf-column\">1</property>"
" <property name=\" visible\">True</property>"
" <child>"
" <object class=\" GtkCellRendererText\" id=\" renderer1\"/>"
" <attributes>"
" <attribute name=\" text\">0</attribute>"
" </attributes>"
" </child>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
GObject *window, *iconview;
builder = builder_new_from_string (buffer, -1 , NULL);
iconview = gtk_builder_get_object (builder, "iconview1" );
g_assert_true (GTK_IS_ICON_VIEW (iconview));
window = gtk_builder_get_object (builder, "window1" );
gtk_window_destroy (GTK_WINDOW (window));
g_object_unref (builder);
}
static void
test_combo_box (void )
{
GtkBuilder *builder;
const char buffer[] =
"<interface>"
" <object class=\" GtkListStore\" id=\" liststore1\">"
" <columns>"
" <column type=\" guint\"/>"
" <column type=\" gchararray\"/>"
" </columns>"
" <data>"
" <row>"
" <col id=\" 0 \">1</col>"
" <col id=\" 1 \">Foo</col>"
" </row>"
" <row>"
" <col id=\" 0 \">2</col>"
" <col id=\" 1 \">Bar</col>"
" </row>"
" </data>"
" </object>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <child>"
" <object class=\" GtkComboBox\" id=\" combobox1\">"
" <property name=\" model\">liststore1</property>"
" <property name=\" visible\">True</property>"
" <child>"
" <object class=\" GtkCellRendererText\" id=\" renderer1\"/>"
" <attributes>"
" <attribute name=\" text\">0</attribute>"
" </attributes>"
" </child>"
" <child>"
" <object class=\" GtkCellRendererText\" id=\" renderer2\"/>"
" <attributes>"
" <attribute name=\" text\">1</attribute>"
" </attributes>"
" </child>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
GObject *window, *combobox;
builder = builder_new_from_string (buffer, -1 , NULL);
combobox = gtk_builder_get_object (builder, "combobox1" );
g_assert_nonnull (combobox);
window = gtk_builder_get_object (builder, "window1" );
gtk_window_destroy (GTK_WINDOW (window));
g_object_unref (builder);
}
#if 0
static void
test_combo_box_entry (void )
{
GtkBuilder *builder;
const char buffer[] =
"<interface>"
" <object class=\" GtkListStore\" id=\" liststore1\">"
" <columns>"
" <column type=\" guint\"/>"
" <column type=\" gchararray\"/>"
" </columns>"
" <data>"
" <row>"
" <col id=\" 0 \">1</col>"
" <col id=\" 1 \">Foo</col>"
" </row>"
" <row>"
" <col id=\" 0 \">2</col>"
" <col id=\" 1 \">Bar</col>"
" </row>"
" </data>"
" </object>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <child>"
" <object class=\" GtkComboBox\" id=\" comboboxentry1\">"
" <property name=\" model\">liststore1</property>"
" <property name=\" has-entry\">True</property>"
" <property name=\" visible\">True</property>"
" <child>"
" <object class=\" GtkCellRendererText\" id=\" renderer1\"/>"
" <attributes>"
" <attribute name=\" text\">0</attribute>"
" </attributes>"
" </child>"
" <child>"
" <object class=\" GtkCellRendererText\" id=\" renderer2\"/>"
" <attributes>"
" <attribute name=\" text\">1</attribute>"
" </attributes>"
" </child>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
GObject *window, *combobox, *renderer;
char *text;
builder = builder_new_from_string (buffer, -1 , NULL);
combobox = gtk_builder_get_object (builder, "comboboxentry1" );
g_assert_nonnull (combobox);
renderer = gtk_builder_get_object (builder, "renderer2" );
g_assert_nonnull (renderer);
g_object_get (renderer, "text" , &text, NULL);
g_assert_cmpstr (text, ==, "Bar" );
g_free (text);
renderer = gtk_builder_get_object (builder, "renderer1" );
g_assert_nonnull (renderer);
g_object_get (renderer, "text" , &text, NULL);
g_assert_cmpstr (text, ==, "2" );
g_free (text);
window = gtk_builder_get_object (builder, "window1" );
gtk_window_destroy (GTK_WINDOW (window));
g_object_unref (builder);
}
#endif
static void
test_cell_view (void )
{
GtkBuilder *builder;
const char *buffer =
"<interface>"
" <object class=\" GtkListStore\" id=\" liststore1\">"
" <columns>"
" <column type=\" gchararray\"/>"
" </columns>"
" <data>"
" <row>"
" <col id=\" 0 \">test</col>"
" </row>"
" </data>"
" </object>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <child>"
" <object class=\" GtkCellView\" id=\" cellview1\">"
" <property name=\" visible\">True</property>"
" <property name=\" model\">liststore1</property>"
" <child>"
" <object class=\" GtkCellRendererText\" id=\" renderer1\"/>"
" <attributes>"
" <attribute name=\" text\">0</attribute>"
" </attributes>"
" </child>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
GObject *cellview;
GObject *model, *window;
GtkTreePath *path;
GList *renderers;
builder = builder_new_from_string (buffer, -1 , NULL);
cellview = gtk_builder_get_object (builder, "cellview1" );
g_assert_nonnull (builder);
g_assert_true (GTK_IS_CELL_VIEW (cellview));
g_object_get (cellview, "model" , &model, NULL);
g_assert_true (GTK_IS_TREE_MODEL (model));
g_object_unref (model);
path = gtk_tree_path_new_first ();
gtk_cell_view_set_displayed_row (GTK_CELL_VIEW (cellview), path);
gtk_tree_path_free (path);
renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (cellview));
g_assert_cmpint (g_list_length (renderers), ==, 1 );
g_list_free (renderers);
window = gtk_builder_get_object (builder, "window1" );
g_assert_nonnull (window);
gtk_window_destroy (GTK_WINDOW (window));
g_object_unref (builder);
}
static void
test_dialog (void )
{
GtkBuilder * builder;
const char buffer1[] =
"<interface>"
" <object class=\" GtkDialog\" id=\" dialog1\">"
" <child internal-child=\" content_area\">"
" <object class=\" GtkBox\" id=\" dialog1-vbox\">"
" <property name=\" orientation\">vertical</property>"
" <child internal-child=\" action_area\">"
" <object class=\" GtkBox\" id=\" dialog1-action_area\">"
" <property name=\" orientation\">horizontal</property>"
" <child>"
" <object class=\" GtkButton\" id=\" button_cancel\"/>"
" </child>"
" <child>"
" <object class=\" GtkButton\" id=\" button_ok\"/>"
" </child>"
" </object>"
" </child>"
" </object>"
" </child>"
" <action-widgets>"
" <action-widget response=\" 3 \">button_ok</action-widget>"
" <action-widget response=\" -5 \">button_cancel</action-widget>"
" </action-widgets>"
" </object>"
"</interface>" ;
GObject *dialog1;
GObject *button_ok;
GObject *button_cancel;
builder = builder_new_from_string (buffer1, -1 , NULL);
dialog1 = gtk_builder_get_object (builder, "dialog1" );
button_ok = gtk_builder_get_object (builder, "button_ok" );
g_assert_cmpint (gtk_dialog_get_response_for_widget (GTK_DIALOG (dialog1), GTK_WIDGET (button_ok)), ==, 3 );
button_cancel = gtk_builder_get_object (builder, "button_cancel" );
g_assert_cmpint (gtk_dialog_get_response_for_widget (GTK_DIALOG (dialog1), GTK_WIDGET (button_cancel)), ==, -5 );
gtk_window_destroy (GTK_WINDOW (dialog1));
g_object_unref (builder);
}
static void
test_message_dialog (void )
{
GtkBuilder * builder;
const char buffer1[] =
"<interface>"
" <object class=\" GtkMessageDialog\" id=\" dialog1\">"
" <child internal-child=\" message_area\">"
" <object class=\" GtkBox\" id=\" dialog-message-area\">"
" <property name=\" orientation\">vertical</property>"
" <child>"
" <object class=\" GtkExpander\" id=\" expander\"/>"
" </child>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
GObject *dialog1;
GObject *expander;
builder = builder_new_from_string (buffer1, -1 , NULL);
dialog1 = gtk_builder_get_object (builder, "dialog1" );
expander = gtk_builder_get_object (builder, "expander" );
g_assert_true (GTK_IS_EXPANDER (expander));
g_assert_true (gtk_widget_get_parent (GTK_WIDGET (expander)) == gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (dialog1)));
gtk_window_destroy (GTK_WINDOW (dialog1));
g_object_unref (builder);
}
static void
test_widget (void )
{
const char *buffer =
"<interface>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <property name=\" focus-widget\">button1</property>"
" <child>"
" <object class=\" GtkButton\" id=\" button1\">"
" </object>"
" </child>"
" </object>"
"</interface>" ;
const char *buffer2 =
"<interface>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <child>"
" <object class=\" GtkButton\" id=\" button1\">"
" <property name=\" receives-default \">True</property>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
const char *buffer3 =
"<interface>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <child>"
" <object class=\" GtkBox\" id=\" vbox1\">"
" <property name=\" orientation\">vertical</property>"
" <child>"
" <object class=\" GtkLabel\" id=\" label1\">"
" </object>"
" </child>"
" <child>"
" <object class=\" GtkButton\" id=\" button1\">"
" </object>"
" </child>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
const char *buffer4 =
"<interface>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <child>"
" <object class=\" GtkLabel\" id=\" label1\">"
" <property name=\" label\">Thelabel</property>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
GtkBuilder *builder;
GObject *window1, *button1, *label1;
builder = builder_new_from_string (buffer, -1 , NULL);
button1 = gtk_builder_get_object (builder, "button1" );
g_assert_true (gtk_widget_is_focus (GTK_WIDGET (button1)));
window1 = gtk_builder_get_object (builder, "window1" );
gtk_window_destroy (GTK_WINDOW (window1));
g_object_unref (builder);
builder = builder_new_from_string (buffer2, -1 , NULL);
button1 = gtk_builder_get_object (builder, "button1" );
g_assert_true (gtk_widget_get_receives_default (GTK_WIDGET (button1)));
g_object_unref (builder);
builder = builder_new_from_string (buffer3, -1 , NULL);
window1 = gtk_builder_get_object (builder, "window1" );
label1 = gtk_builder_get_object (builder, "label1" );
g_assert_true (GTK_IS_LABEL (label1));
gtk_window_destroy (GTK_WINDOW (window1));
g_object_unref (builder);
builder = builder_new_from_string (buffer4, -1 , NULL);
label1 = gtk_builder_get_object (builder, "label1" );
g_assert_true (GTK_IS_LABEL (label1));
g_object_unref (builder);
}
static void
test_window (void )
{
const char *buffer1 =
"<interface>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <property name=\" title\"></property>"
" </object>"
"</interface>" ;
const char *buffer2 =
"<interface>"
" <object class=\" GtkWindow\" id=\" window1\">"
" </object>"
"</interface>" ;
GtkBuilder *builder;
GObject *window1;
char *title;
builder = builder_new_from_string (buffer1, -1 , NULL);
window1 = gtk_builder_get_object (builder, "window1" );
g_object_get (window1, "title" , &title, NULL);
g_assert_cmpstr (title, ==, "" );
g_free (title);
gtk_window_destroy (GTK_WINDOW (window1));
g_object_unref (builder);
builder = builder_new_from_string (buffer2, -1 , NULL);
window1 = gtk_builder_get_object (builder, "window1" );
gtk_window_destroy (GTK_WINDOW (window1));
g_object_unref (builder);
}
static void
test_value_from_string (void )
{
GValue value = G_VALUE_INIT;
GError *error = NULL;
GtkBuilder *builder;
builder = gtk_builder_new ();
g_assert_true (gtk_builder_value_from_string_type (builder, G_TYPE_STRING, "test" , &value, &error));
g_assert_true (G_VALUE_HOLDS_STRING (&value));
g_assert_cmpstr (g_value_get_string (&value), ==, "test" );
g_value_unset (&value);
g_assert_true (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "true" , &value, &error));
g_assert_true (G_VALUE_HOLDS_BOOLEAN (&value));
g_assert_true (g_value_get_boolean (&value));
g_value_unset (&value);
g_assert_true (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "false" , &value, &error));
g_assert_true (G_VALUE_HOLDS_BOOLEAN (&value));
g_assert_false (g_value_get_boolean (&value));
g_value_unset (&value);
g_assert_true (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "yes" , &value, &error));
g_assert_true (G_VALUE_HOLDS_BOOLEAN (&value));
g_assert_true (g_value_get_boolean (&value));
g_value_unset (&value);
g_assert_true (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "no" , &value, &error));
g_assert_true (G_VALUE_HOLDS_BOOLEAN (&value));
g_assert_false (g_value_get_boolean (&value));
g_value_unset (&value);
g_assert_true (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "0" , &value, &error));
g_assert_true (G_VALUE_HOLDS_BOOLEAN (&value));
g_assert_false (g_value_get_boolean (&value));
g_value_unset (&value);
g_assert_true (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "1" , &value, &error));
g_assert_true (G_VALUE_HOLDS_BOOLEAN (&value));
g_assert_true (g_value_get_boolean (&value));
g_value_unset (&value);
g_assert_true (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "tRuE" , &value, &error));
g_assert_true (G_VALUE_HOLDS_BOOLEAN (&value));
g_assert_true (g_value_get_boolean (&value));
g_value_unset (&value);
g_assert_true (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "blaurgh" , &value, &error) == FALSE );
g_value_unset (&value);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_VALUE);
g_clear_error (&error);
g_assert_true (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "yess" , &value, &error) == FALSE );
g_value_unset (&value);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_VALUE);
g_clear_error (&error);
g_assert_true (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "trueee" , &value, &error) == FALSE );
g_value_unset (&value);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_VALUE);
g_clear_error (&error);
g_assert_false (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "" , &value, &error));
g_value_unset (&value);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_VALUE);
g_clear_error (&error);
g_assert_true (gtk_builder_value_from_string_type (builder, G_TYPE_INT, "12345" , &value, &error));
g_assert_true (G_VALUE_HOLDS_INT (&value));
g_assert_cmpint (g_value_get_int (&value), ==, 12345 );
g_value_unset (&value);
g_assert_true (gtk_builder_value_from_string_type (builder, G_TYPE_LONG, "9912345" , &value, &error));
g_assert_true (G_VALUE_HOLDS_LONG (&value));
g_assert_cmpint (g_value_get_long (&value), ==, 9912345 );
g_value_unset (&value);
g_assert_true (gtk_builder_value_from_string_type (builder, G_TYPE_UINT, "2345" , &value, &error));
g_assert_true (G_VALUE_HOLDS_UINT (&value));
g_assert_cmpint (g_value_get_uint (&value), ==, 2345 );
g_value_unset (&value);
g_assert_true (gtk_builder_value_from_string_type (builder, G_TYPE_INT64, "-2345" , &value, &error));
g_assert_true (G_VALUE_HOLDS_INT64 (&value));
g_assert_cmpint (g_value_get_int64 (&value), ==, -2345 );
g_value_unset (&value);
g_assert_true (gtk_builder_value_from_string_type (builder, G_TYPE_UINT64, "2345" , &value, &error));
g_assert_true (G_VALUE_HOLDS_UINT64 (&value));
g_assert_cmpint (g_value_get_uint64 (&value), ==, 2345 );
g_value_unset (&value);
g_assert_true (gtk_builder_value_from_string_type (builder, G_TYPE_FLOAT, "1.454" , &value, &error));
g_assert_true (G_VALUE_HOLDS_FLOAT (&value));
g_assert_cmpfloat (fabs (g_value_get_float (&value) - 1 .454 ), <, 0 .00001 );
g_value_unset (&value);
g_assert_false (gtk_builder_value_from_string_type (builder, G_TYPE_FLOAT, "abc" , &value, &error));
g_value_unset (&value);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_VALUE);
g_clear_error (&error);
g_assert_false (gtk_builder_value_from_string_type (builder, G_TYPE_INT, "/-+,abc" , &value, &error));
g_value_unset (&value);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_VALUE);
g_clear_error (&error);
g_assert_true (gtk_builder_value_from_string_type (builder, GTK_TYPE_TEXT_DIRECTION, "rtl" , &value, &error));
g_assert_true (G_VALUE_HOLDS_ENUM (&value));
g_assert_cmpint (g_value_get_enum (&value), ==, GTK_TEXT_DIR_RTL);
g_value_unset (&value);
g_assert_false (gtk_builder_value_from_string_type (builder, GTK_TYPE_TEXT_DIRECTION, "sliff" , &value, &error));
g_value_unset (&value);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_VALUE);
g_clear_error (&error);
g_assert_false (gtk_builder_value_from_string_type (builder, GTK_TYPE_TEXT_DIRECTION, "foobar" , &value, &error));
g_value_unset (&value);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_VALUE);
g_clear_error (&error);
g_object_unref (builder);
}
static gboolean model_freed = FALSE ;
static void
model_weakref (gpointer data,
GObject *model)
{
model_freed = TRUE ;
}
static void
test_reference_counting (void )
{
GtkBuilder *builder;
const char buffer1[] =
"<interface>"
" <object class=\" GtkListStore\" id=\" liststore1\"/>"
" <object class=\" GtkListStore\" id=\" liststore2\"/>"
" <object class=\" GtkWindow\" id=\" window1\">"
" <child>"
" <object class=\" GtkTreeView\" id=\" treeview1\">"
" <property name=\" model\">liststore1</property>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
const char buffer2[] =
"<interface>"
" <object class=\" GtkBox\" id=\" vbox1\">"
" <property name=\" orientation\">vertical</property>"
" <child>"
" <object class=\" GtkLabel\" id=\" label1\"/>"
" </child>"
" </object>"
"</interface>" ;
GObject *window, *treeview, *model;
builder = builder_new_from_string (buffer1, -1 , NULL);
window = gtk_builder_get_object (builder, "window1" );
treeview = gtk_builder_get_object (builder, "treeview1" );
model = gtk_builder_get_object (builder, "liststore1" );
g_object_unref (builder);
g_object_weak_ref (model, (GWeakNotify)model_weakref, NULL);
g_assert_false (model_freed);
gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), NULL);
g_assert_true (model_freed);
gtk_window_destroy (GTK_WINDOW (window));
builder = builder_new_from_string (buffer2, -1 , NULL);
g_object_unref (builder);
}
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
typedef struct {
gboolean weight;
gboolean foreground;
gboolean underline;
gboolean size;
gboolean font_desc;
gboolean language;
} FoundAttrs;
static gboolean
filter_pango_attrs (PangoAttribute *attr,
gpointer data)
{
FoundAttrs *found = (FoundAttrs *)data;
if (attr->klass->type == PANGO_ATTR_WEIGHT)
found->weight = TRUE ;
else if (attr->klass->type == PANGO_ATTR_FOREGROUND)
found->foreground = TRUE ;
else if (attr->klass->type == PANGO_ATTR_UNDERLINE)
found->underline = TRUE ;
/* Make sure optional start/end properties are working */
else if (attr->klass->type == PANGO_ATTR_SIZE &&
attr->start_index == 5 &&
attr->end_index == 10 )
found->size = TRUE ;
else if (attr->klass->type == PANGO_ATTR_FONT_DESC)
found->font_desc = TRUE ;
else if (attr->klass->type == PANGO_ATTR_LANGUAGE)
found->language = TRUE ;
return TRUE ;
}
static void
test_pango_attributes (void )
{
GtkBuilder *builder;
FoundAttrs found = { 0 , };
const char buffer[] =
"<interface>"
" <object class=\" GtkLabel\" id=\" label1\">"
" <attributes>"
" <attribute name=\" weight\" value=\" PANGO_WEIGHT_BOLD\"/>"
" <attribute name=\" foreground\" value=\" DarkSlateGray\"/>"
" <attribute name=\" underline\" value=\" True \"/>"
" <attribute name=\" size\" value=\" 4 \" start=\" 5 \" end=\" 10 \"/>"
" <attribute name=\" font-desc\" value=\" Sans Italic 22 \"/>"
" <attribute name=\" language\" value=\" pt_BR\"/>"
" </attributes>"
" </object>"
"</interface>" ;
const char err_buffer1[] =
"<interface>"
" <object class=\" GtkLabel\" id=\" label1\">"
" <attributes>"
" <attribute name=\" weight\"/>"
" </attributes>"
" </object>"
"</interface>" ;
const char err_buffer2[] =
"<interface>"
" <object class=\" GtkLabel\" id=\" label1\">"
" <attributes>"
" <attribute name=\" weight\" value=\" PANGO_WEIGHT_BOLD\" unrecognized=\" True \"/>"
" </attributes>"
" </object>"
"</interface>" ;
GObject *label;
GError *error = NULL;
PangoAttrList *attrs, *filtered;
/* Test attributes are set */
builder = builder_new_from_string (buffer, -1 , NULL);
label = gtk_builder_get_object (builder, "label1" );
g_assert_nonnull (label);
attrs = gtk_label_get_attributes (GTK_LABEL (label));
g_assert_nonnull (attrs);
filtered = pango_attr_list_filter (attrs, filter_pango_attrs, &found);
g_assert_true (filtered);
pango_attr_list_unref (filtered);
g_assert_true (found.weight);
g_assert_true (found.foreground);
g_assert_true (found.underline);
g_assert_true (found.size);
g_assert_true (found.language);
g_assert_true (found.font_desc);
g_object_unref (builder);
/* Test errors are set */
builder = gtk_builder_new ();
gtk_builder_add_from_string (builder, err_buffer1, -1 , &error);
g_assert_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_MISSING_ATTRIBUTE);
g_object_unref (builder);
g_clear_error (&error);
builder = gtk_builder_new ();
gtk_builder_add_from_string (builder, err_buffer2, -1 , &error);
g_assert_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE);
g_object_unref (builder);
g_error_free (error);
}
static void
test_requires (void )
{
GtkBuilder *builder;
GError *error = NULL;
char *buffer;
const char buffer_fmt[] =
"<interface>"
" <requires lib=\" gtk\" version=\" %d.%d\"/>"
"</interface>" ;
buffer = g_strdup_printf (buffer_fmt, GTK_MAJOR_VERSION, GTK_MINOR_VERSION + 1 );
builder = gtk_builder_new ();
gtk_builder_add_from_string (builder, buffer, -1 , &error);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_VERSION_MISMATCH);
g_object_unref (builder);
g_error_free (error);
g_free (buffer);
}
static void
test_add_objects (void )
{
GtkBuilder *builder;
GError *error;
int ret;
GObject *obj;
const char *objects[2 ] = {"mainbox" , NULL};
const char *objects2[3 ] = {"mainbox" , "window2" , NULL};
const char buffer[] =
"<interface>"
" <object class=\" GtkWindow\" id=\" window\">"
" <child>"
" <object class=\" GtkBox\" id=\" mainbox\">"
" <property name=\" orientation\">vertical</property>"
" <property name=\" visible\">True</property>"
" <child>"
" <object class=\" GtkLabel\" id=\" label1\">"
" <property name=\" visible\">True</property>"
" <property name=\" label\" translatable=\" no\">first label</property>"
" </object>"
" </child>"
" <child>"
" <object class=\" GtkLabel\" id=\" label2\">"
" <property name=\" visible\">True</property>"
" <property name=\" label\" translatable=\" no\">second label</property>"
" </object>"
" </child>"
" </object>"
" </child>"
" </object>"
" <object class=\" GtkWindow\" id=\" window2\">"
" <child>"
" <object class=\" GtkLabel\" id=\" label3\">"
" <property name=\" label\" translatable=\" no\">second label</property>"
" </object>"
" </child>"
" </object>"
"<interface/>" ;
error = NULL;
builder = gtk_builder_new ();
ret = gtk_builder_add_objects_from_string (builder, buffer, -1 , objects, &error);
g_assert_no_error (error);
obj = gtk_builder_get_object (builder, "window" );
g_assert_null (obj);
obj = gtk_builder_get_object (builder, "window2" );
g_assert_null (obj);
obj = gtk_builder_get_object (builder, "mainbox" );
g_assert_true (GTK_IS_WIDGET (obj));
g_object_unref (builder);
error = NULL;
builder = gtk_builder_new ();
ret = gtk_builder_add_objects_from_string (builder, buffer, -1 , objects2, &error);
g_assert_true (ret);
g_assert_null (error);
obj = gtk_builder_get_object (builder, "window" );
g_assert_null (obj);
obj = gtk_builder_get_object (builder, "window2" );
g_assert_true (GTK_IS_WINDOW (obj));
gtk_window_destroy (GTK_WINDOW (obj));
obj = gtk_builder_get_object (builder, "mainbox" );
g_assert_true (GTK_IS_WIDGET (obj));
g_object_unref (builder);
}
static void
test_message_area (void )
{
GtkBuilder *builder;
GObject *obj, *obj1;
const char buffer[] =
"<interface>"
" <object class=\" GtkInfoBar\" id=\" infobar1\">"
" <child>"
" <object class=\" GtkBox\" id=\" contentarea1\">"
" <property name=\" orientation\">horizontal</property>"
" <child>"
" <object class=\" GtkLabel\" id=\" content\">"
" <property name=\" label\" translatable=\" yes\">Message</property>"
" </object>"
" </child>"
" </object>"
" </child>"
" <child type=\" action\">"
" <object class=\" GtkButton\" id=\" button_ok\">"
" <property name=\" label\">gtk-ok</property>"
" </object>"
" </child>"
" <action-widgets>"
" <action-widget response=\" 1 \">button_ok</action-widget>"
" </action-widgets>"
" </object>"
"</interface>" ;
builder = builder_new_from_string (buffer, -1 , NULL);
obj = gtk_builder_get_object (builder, "infobar1" );
g_assert_true (GTK_IS_INFO_BAR (obj));
obj1 = gtk_builder_get_object (builder, "content" );
g_assert_true (GTK_IS_LABEL (obj1));
obj1 = gtk_builder_get_object (builder, "button_ok" );
g_assert_true (GTK_IS_BUTTON (obj1));
g_object_unref (builder);
}
static void
test_gmenu (void )
{
GtkBuilder *builder;
GObject *obj, *obj1;
const char buffer[] =
"<interface>"
" <object class=\" GtkWindow\" id=\" window\">"
" </object>"
" <menu id='edit-menu'>"
" <section>"
" <item>"
" <attribute name='label'>Undo</attribute>"
" <attribute name='action'>undo</attribute>"
" </item>"
" <item>"
" <attribute name='label'>Redo</attribute>"
" <attribute name='action'>redo</attribute>"
" </item>"
" </section>"
" <section></section>"
" <section>"
" <attribute name='label'>Copy & Paste</attribute>"
" <item>"
" <attribute name='label'>Cut</attribute>"
" <attribute name='action'>cut</attribute>"
" </item>"
" <item>"
" <attribute name='label'>Copy</attribute>"
" <attribute name='action'>copy</attribute>"
" </item>"
" <item>"
" <attribute name='label'>Paste</attribute>"
" <attribute name='action'>paste</attribute>"
" </item>"
" </section>"
" <item><link name='section' id='blargh'>"
" <item>"
" <attribute name='label'>Bold</attribute>"
" <attribute name='action'>bold</attribute>"
" </item>"
" <submenu>"
" <attribute name='label'>Language</attribute>"
" <item>"
" <attribute name='label'>Latin</attribute>"
" <attribute name='action'>lang</attribute>"
" <attribute name='target'>'latin'</attribute>"
" </item>"
" <item>"
" <attribute name='label'>Greek</attribute>"
" <attribute name='action'>lang</attribute>"
" <attribute name='target'>'greek'</attribute>"
" </item>"
" <item>"
" <attribute name='label'>Urdu</attribute>"
" <attribute name='action'>lang</attribute>"
" <attribute name='target'>'urdu'</attribute>"
" </item>"
" </submenu>"
" </link></item>"
" </menu>"
"</interface>" ;
builder = builder_new_from_string (buffer, -1 , NULL);
obj = gtk_builder_get_object (builder, "window" );
g_assert_true (GTK_IS_WINDOW (obj));
obj1 = gtk_builder_get_object (builder, "edit-menu" );
g_assert_true (G_IS_MENU_MODEL (obj1));
obj1 = gtk_builder_get_object (builder, "blargh" );
g_assert_true (G_IS_MENU_MODEL (obj1));
g_object_unref (builder);
}
static void
test_level_bar (void )
{
GtkBuilder *builder;
GError *error = NULL;
GObject *obj, *obj1;
const char buffer1[] =
"<interface>"
" <object class=\" GtkWindow\" id=\" window\">"
" <child>"
" <object class=\" GtkLevelBar\" id=\" levelbar\">"
" <property name=\" value\">4.70</property>"
" <property name=\" min-value\">2</property>"
" <property name=\" max-value\">5</property>"
" <offsets>"
" <offset name=\" low\" value=\" 2 .25 \"/>"
" <offset name=\" custom\" value=\" 3 \"/>"
" <offset name=\" high\" value=\" 3 \"/>"
" </offsets>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
const char buffer2[] =
"<interface>"
" <object class=\" GtkLevelBar\" id=\" levelbar\">"
" <offsets>"
" <offset name=\" low\" bogus_attr=\" foo\"/>"
" </offsets>"
" </object>"
"</interface>" ;
const char buffer3[] =
"<interface>"
" <object class=\" GtkLevelBar\" id=\" levelbar\">"
" <offsets>"
" <offset name=\" low\" value=\" 1 \"/>"
" </offsets>"
" <bogus_tag>"
" </bogus_tag>"
" </object>"
"</interface>" ;
builder = gtk_builder_new ();
gtk_builder_add_from_string (builder, buffer1, -1 , &error);
g_assert_true (error == NULL);
obj = gtk_builder_get_object (builder, "window" );
g_assert_true (GTK_IS_WINDOW (obj));
obj1 = gtk_builder_get_object (builder, "levelbar" );
g_assert_true (GTK_IS_LEVEL_BAR (obj1));
g_object_unref (builder);
error = NULL;
builder = gtk_builder_new ();
gtk_builder_add_from_string (builder, buffer2, -1 , &error);
g_assert_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_MISSING_ATTRIBUTE);
g_error_free (error);
g_object_unref (builder);
error = NULL;
builder = gtk_builder_new ();
gtk_builder_add_from_string (builder, buffer3, -1 , &error);
g_assert_error (error, GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_UNHANDLED_TAG);
g_error_free (error);
g_object_unref (builder);
}
static void
test_expose_object (void )
{
GtkBuilder *builder;
GError *error = NULL;
GtkWidget *menu;
GObject *obj;
const char buffer[] =
"<interface>"
" <object class=\" GtkMenuButton\" id=\" button\">"
" <property name=\" popover\">external_menu</property>"
" </object>"
"</interface>" ;
menu = gtk_popover_new ();
builder = gtk_builder_new ();
gtk_builder_expose_object (builder, "external_menu" , G_OBJECT (menu));
gtk_builder_add_from_string (builder, buffer, -1 , &error);
g_assert_no_error (error);
obj = gtk_builder_get_object (builder, "button" );
g_assert_true (GTK_IS_MENU_BUTTON (obj));
g_assert_true (gtk_menu_button_get_popover (GTK_MENU_BUTTON (obj)) == GTK_POPOVER (menu));
g_object_unref (builder);
}
static void
test_no_ids (void )
{
GtkBuilder *builder;
GError *error = NULL;
GObject *obj;
const char buffer[] =
"<interface>"
" <object class=\" GtkInfoBar\">"
" <child>"
" <object class=\" GtkBox\">"
" <property name=\" orientation\">horizontal</property>"
" <child>"
" <object class=\" GtkLabel\">"
" <property name=\" label\" translatable=\" yes\">Message</property>"
" </object>"
" </child>"
" </object>"
" </child>"
" <child type=\" action\">"
" <object class=\" GtkButton\" id=\" button_ok\">"
" <property name=\" label\">gtk-ok</property>"
" </object>"
" </child>"
" <action-widgets>"
" <action-widget response=\" 1 \">button_ok</action-widget>"
" </action-widgets>"
" </object>"
"</interface>" ;
builder = gtk_builder_new ();
gtk_builder_add_from_string (builder, buffer, -1 , &error);
g_assert_no_error (error);
obj = gtk_builder_get_object (builder, "button_ok" );
g_assert_true (GTK_IS_BUTTON (obj));
g_object_unref (builder);
}
static void
test_property_bindings (void )
{
const char *buffer =
"<interface>"
" <object class=\" GtkWindow\" id=\" window\">"
" <child>"
" <object class=\" GtkBox\" id=\" vbox\">"
" <property name=\" visible\">True</property>"
" <property name=\" orientation\">vertical</property>"
" <child>"
" <object class=\" GtkCheckButton\" id=\" checkbutton\">"
" <property name=\" active\">false</property>"
" </object>"
" </child>"
" <child>"
" <object class=\" GtkButton\" id=\" button\">"
" <property name=\" sensitive\" bind-source=\" checkbutton\" bind-property=\" active\" bind-flags=\" sync-create\">false</property>"
" </object>"
" </child>"
" <child>"
" <object class=\" GtkButton\" id=\" button2\">"
" <property name=\" sensitive\" bind-source=\" checkbutton\" bind-property=\" active\" />"
" </object>"
" </child>"
" <child>"
" <object class=\" GtkButton\" id=\" button3\">"
" <property name=\" sensitive\" bind-source=\" button\" bind-flags=\" sync-create\" />"
" </object>"
" </child>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
GtkBuilder *builder;
GObject *checkbutton, *button, *button2, *button3, *window;
builder = builder_new_from_string (buffer, -1 , NULL);
checkbutton = gtk_builder_get_object (builder, "checkbutton" );
g_assert_true (GTK_IS_CHECK_BUTTON (checkbutton));
g_assert_true (!gtk_check_button_get_active (GTK_CHECK_BUTTON (checkbutton)));
button = gtk_builder_get_object (builder, "button" );
g_assert_true (GTK_IS_BUTTON (button));
g_assert_false (gtk_widget_get_sensitive (GTK_WIDGET (button)));
button2 = gtk_builder_get_object (builder, "button2" );
g_assert_true (GTK_IS_BUTTON (button2));
g_assert_true (gtk_widget_get_sensitive (GTK_WIDGET (button2)));
button3 = gtk_builder_get_object (builder, "button3" );
g_assert_true (GTK_IS_BUTTON (button3));
g_assert_false (gtk_widget_get_sensitive (GTK_WIDGET (button3)));
gtk_check_button_set_active (GTK_CHECK_BUTTON (checkbutton), TRUE );
g_assert_true (gtk_widget_get_sensitive (GTK_WIDGET (button)));
g_assert_true (gtk_widget_get_sensitive (GTK_WIDGET (button2)));
g_assert_true (gtk_widget_get_sensitive (GTK_WIDGET (button3)));
window = gtk_builder_get_object (builder, "window" );
gtk_window_destroy (GTK_WINDOW (window));
g_object_unref (builder);
}
#define MY_GTK_GRID_TEMPLATE "\
<interface>\n\
<template class =\"MyGtkGrid\" parent=\"GtkGrid\" >\n\
<property name=\"visible\" >True </property>\n\
<child>\n\
<object class =\"GtkLabel\" id=\"label\" >\n\
<property name=\"visible\" >True </property>\n\
</object>\n\
</child>\n\
</template >\n\
</interface>\n"
#define MY_TYPE_GTK_GRID (my_gtk_grid_get_type ())
#define MY_IS_GTK_GRID(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MY_TYPE_GTK_GRID))
typedef struct
{
GtkGridClass parent_class;
} MyGtkGridClass;
typedef struct
{
GtkLabel *label;
} MyGtkGridPrivate;
typedef struct
{
GtkGrid parent_instance;
GtkLabel *label;
MyGtkGridPrivate *priv;
} MyGtkGrid;
G_DEFINE_TYPE_WITH_PRIVATE (MyGtkGrid, my_gtk_grid, GTK_TYPE_GRID);
static void
my_gtk_grid_init (MyGtkGrid *grid)
{
grid->priv = my_gtk_grid_get_instance_private (grid);
gtk_widget_init_template (GTK_WIDGET (grid));
}
static void
my_gtk_grid_class_init (MyGtkGridClass *klass)
{
GBytes *template = g_bytes_new_static (MY_GTK_GRID_TEMPLATE, strlen (MY_GTK_GRID_TEMPLATE));
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
gtk_widget_class_set_template (widget_class, template );
gtk_widget_class_bind_template_child (widget_class, MyGtkGrid, label);
gtk_widget_class_bind_template_child_private (widget_class, MyGtkGrid, label);
g_bytes_unref (template );
}
static void
test_template (void )
{
MyGtkGrid *my_gtk_grid;
/* make sure the type we are trying to register does not exist */
g_assert_false (g_type_from_name ("MyGtkGrid" ));
/* create the template object */
my_gtk_grid = g_object_new (MY_TYPE_GTK_GRID, NULL);
/* Check everything is fine */
g_assert_true (g_type_from_name ("MyGtkGrid" ));
g_assert_true (MY_IS_GTK_GRID (my_gtk_grid));
g_assert_true (my_gtk_grid->label == my_gtk_grid->priv->label);
g_assert_true (GTK_IS_LABEL (my_gtk_grid->label));
g_assert_true (GTK_IS_LABEL (my_gtk_grid->priv->label));
g_object_ref_sink (my_gtk_grid);
g_object_unref (my_gtk_grid);
}
_BUILDER_TEST_EXPORT void
on_cellrenderertoggle1_toggled (GtkCellRendererToggle *cell)
{
}
static void
test_anaconda_signal (void )
{
GtkBuilder *builder;
const char buffer[] =
"<?xml version='1.0' encoding='UTF-8'?>"
"<interface>"
" <requires lib='gtk' version='4.0'/>"
" <object class='GtkListStore' id='liststore1'>"
" <columns>"
" <!-- column-name use -->"
" <column type='gboolean'/>"
" </columns>"
" </object>"
" <object class='GtkWindow' id='window1'>"
" <child>"
" <object class='GtkTreeView' id='treeview1'>"
" <property name='visible'>True</property>"
" <property name='model'>liststore1</property>"
" <child internal-child='selection'>"
" <object class='GtkTreeSelection' id='treeview-selection1'/>"
" </child>"
" <child>"
" <object class='GtkTreeViewColumn' id='treeviewcolumn1'>"
" <property name='title' translatable='yes'>column</property>"
" <child>"
" <object class='GtkCellRendererToggle' id='cellrenderertoggle1'>"
" <signal name='toggled' handler='on_cellrenderertoggle1_toggled' swapped='no'/>"
" </object>"
" <attributes>"
" <attribute name='active'>0</attribute>"
" </attributes>"
" </child>"
" </object>"
" </child>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
builder = builder_new_from_string (buffer, -1 , NULL);
g_object_unref (builder);
}
static void
test_file_filter (void )
{
GtkBuilder *builder;
GObject *obj;
GtkFileFilter *filter;
const char buffer[] =
"<interface>"
" <object class='GtkFileFilter' id='filter1'>"
" <property name='name'>Text and Images</property>"
" <mime-types>"
" <mime-type>text/plain</mime-type>"
" <mime-type>image/*</mime-type>"
" </mime-types>"
" <patterns>"
" <pattern>*.txt</pattern>"
" <pattern>*.png</pattern>"
" </patterns>"
" </object>"
"</interface>" ;
builder = builder_new_from_string (buffer, -1 , NULL);
obj = gtk_builder_get_object (builder, "filter1" );
g_assert_true (GTK_IS_FILE_FILTER (obj));
filter = GTK_FILE_FILTER (obj);
g_assert_cmpstr (gtk_file_filter_get_name (filter), ==, "Text and Images" );
g_assert_true (g_strv_contains (gtk_file_filter_get_attributes (filter), G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE));
g_assert_true (g_strv_contains (gtk_file_filter_get_attributes (filter), G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME));
g_object_unref (builder);
}
static void
test_shortcuts (void )
{
GtkBuilder *builder;
GObject *obj;
const char buffer[] =
"<interface>"
" <object class='GtkBox' id='box'>"
" <child>"
" <object class='GtkShortcutController' id='controller'>"
" <property name='scope'>managed</property>"
" <child>"
" <object class='GtkShortcut'>"
" <property name='trigger'><Control>k</property>"
" <property name='action'>activate</property>"
" </object>"
" </child>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
builder = builder_new_from_string (buffer, -1 , NULL);
obj = gtk_builder_get_object (builder, "controller" );
g_assert_true (GTK_IS_SHORTCUT_CONTROLLER (obj));
g_object_unref (builder);
}
static void
test_transforms (void )
{
GtkBuilder * builder;
const char buffer1[] =
"<interface>"
" <object class=\" GtkFixed\" id=\" fixed1\">"
" <child>"
" <object class=\" GtkLabel\" id=\" label1\">"
" <layout>"
" <property name=\" transform\">rotateX(45.0)</property>"
" </layout>"
" </object>"
" </child>"
" <child>"
" <object class=\" GtkLabel\" id=\" label2\">"
" <layout>"
" <property name=\" transform\">scale3d(1,2,3)translate3d(2,3,0)</property>"
" </layout>"
" </object>"
" </child>"
" </object>"
"</interface>" ;
GObject *label, *vbox;
builder = builder_new_from_string (buffer1, -1 , NULL);
vbox = gtk_builder_get_object (builder, "fixed1" );
g_assert_true (GTK_IS_FIXED (vbox));
label = gtk_builder_get_object (builder, "label1" );
g_assert_true (GTK_IS_LABEL (label));
label = gtk_builder_get_object (builder, "label2" );
g_assert_true (GTK_IS_LABEL (label));
g_object_unref (builder);
}
G_MODULE_EXPORT char *
builder_get_search (gpointer item)
{
return g_strdup (gtk_string_filter_get_search (item));
}
G_MODULE_EXPORT char *
builder_copy_arg (gpointer item, const char *arg)
{
return g_strdup (arg);
}
G_MODULE_EXPORT char *
builder_get_search_if_null (gpointer item, const char *arg)
{
return (arg == NULL) ? g_strdup (gtk_string_filter_get_search (item)) : g_strdup (arg);
}
static void
test_expressions (void )
{
const char *tests[] = {
"<interface>"
" <object class='GtkStringFilter' id='filter'>"
" <property name='search'>Hello World</property>"
" <property name='expression'><constant type='gchararray'>Hello World</constant></property>"
" </object>"
"</interface>" ,
"<interface>"
" <object class='GtkStringFilter' id='filter'>"
" <property name='search'>Hello World</property>"
" <property name='expression'><closure type='gchararray' function='builder_get_search'></closure></property>"
" </object>"
"</interface>" ,
"<interface>"
" <object class='GtkStringFilter' id='filter'>"
" <property name='search'>Hello World</property>"
" <property name='expression'><lookup type='GtkStringFilter' name='search'></lookup></property>"
" </object>"
"</interface>" ,
"<interface>"
" <object class='GtkStringFilter' id='filter'>"
" <property name='search'>Hello World</property>"
" <property name='expression'><closure type='gchararray' function='builder_copy_arg'>"
" <constant type='gchararray'>Hello World</constant>"
" </closure></property>"
" </object>"
"</interface>" ,
"<interface>"
" <object class='GtkLabel' id='label'></object>"
" <object class='GtkStringFilter' id='filter'>"
" <property name='search'>Hello World</property>"
" <property name='expression'>"
" <try>"
" <lookup name='title' type='GtkWindow'>"
" <lookup name='root' type='GtkLabel'>label</lookup>"
" </lookup>"
" <constant type='gchararray'>Hello World</constant>"
" </try>"
" </property>"
" </object>"
"</interface>" ,
"<interface>"
" <object class='GtkStringFilter' id='filter'>"
" <property name='search'>Hello World</property>"
" <property name='expression'>"
" <closure type='gchararray' function='builder_get_search_if_null'>"
" <constant type='gchararray' initial='true' />"
" </closure>"
" </property>"
" </object>"
"</interface>" ,
};
GtkBuilder *builder;
GObject *obj;
guint i;
for (i = 0 ; i < G_N_ELEMENTS (tests); i++)
{
builder = builder_new_from_string (tests[i], -1 , NULL);
obj = gtk_builder_get_object (builder, "filter" );
g_assert_true (GTK_IS_FILTER (obj));
g_assert_true (gtk_filter_match (GTK_FILTER (obj), obj));
g_object_unref (builder);
}
}
#define MY_GTK_BOX_TEMPLATE "\
<interface>\n\
<template class =\"MyGtkBox\" parent=\"GtkWidget\" >\n\
<child>\n\
<object class =\"GtkLabel\" id=\"label\" >\n\
<property name=\"label\" >First</property>\n\
</object>\n\
</child>\n\
<child>\n\
<object class =\"GtkLabel\" id=\"label2\" >\n\
<property name=\"label\" >Second</property>\n\
</object>\n\
</child>\n\
</template >\n\
</interface>\n"
#define MY_TYPE_GTK_BOX (my_gtk_box_get_type ())
G_DECLARE_FINAL_TYPE (MyGtkBox, my_gtk_box, MY, GTK_BOX, GtkWidget)
struct _MyGtkBox
{
GtkWidget parent_instance;
GtkLabel *label;
GtkLabel *label2;
};
G_DEFINE_TYPE (MyGtkBox, my_gtk_box, GTK_TYPE_WIDGET);
static void
my_gtk_box_init (MyGtkBox *grid)
{
gtk_widget_init_template (GTK_WIDGET (grid));
}
static void
my_gtk_box_dispose (GObject *obj)
{
MyGtkBox *my_gtk_box = MY_GTK_BOX (obj);
GtkWidget *child;
while ((child = gtk_widget_get_first_child (GTK_WIDGET (my_gtk_box))))
gtk_widget_unparent (child);
G_OBJECT_CLASS (my_gtk_box_parent_class)->dispose (obj);
}
static void
my_gtk_box_class_init (MyGtkBoxClass *klass)
{
GBytes *template = g_bytes_new_static (MY_GTK_BOX_TEMPLATE, strlen (MY_GTK_BOX_TEMPLATE));
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
gtk_widget_class_set_template (widget_class, template );
gtk_widget_class_bind_template_child (widget_class, MyGtkBox, label);
gtk_widget_class_bind_template_child (widget_class, MyGtkBox, label2);
G_OBJECT_CLASS (klass)->dispose = my_gtk_box_dispose;
g_bytes_unref (template );
}
typedef struct
{
MyGtkBox *my_gtk_box;
guint destroy_count;
} BoxDestroyData;
static void
my_label_destroy (GtkLabel *label, BoxDestroyData *data)
{
g_assert_true (MY_IS_GTK_BOX (data->my_gtk_box));
/* Make sure the other label is null if it was disposed first */
g_assert_true (!data->my_gtk_box->label2 || GTK_IS_LABEL (data->my_gtk_box->label2));
data->destroy_count++;
}
static void
my_label2_destroy (GtkLabel *label2, BoxDestroyData *data)
{
g_assert_true (MY_IS_GTK_BOX (data->my_gtk_box));
/* Make sure the other label is null if it was disposed first */
g_assert_true (!data->my_gtk_box->label || GTK_IS_LABEL (data->my_gtk_box->label));
data->destroy_count++;
}
static void
test_child_dispose_order (void )
{
BoxDestroyData data = { 0 , };
/* make sure the type we are trying to register does not exist */
g_assert_false (g_type_from_name ("MyGtkBox" ));
/* create the template object */
data.my_gtk_box = g_object_ref_sink (g_object_new (MY_TYPE_GTK_BOX, NULL));
/* Check everything is fine */
g_assert_true (g_type_from_name ("MyGtkBox" ));
g_assert_true (MY_IS_GTK_BOX (data.my_gtk_box));
g_assert_true (GTK_IS_LABEL (data.my_gtk_box->label));
g_assert_true (GTK_IS_LABEL (data.my_gtk_box->label2));
/* Check if both labels are destroyed */
g_signal_connect (data.my_gtk_box->label, "destroy" , G_CALLBACK (my_label_destroy), &data);
g_signal_connect (data.my_gtk_box->label2, "destroy" , G_CALLBACK (my_label2_destroy), &data);
g_object_unref (data.my_gtk_box);
g_assert_cmpuint (data.destroy_count, ==, 2 );
}
#define MY_GTK_BUILDABLE_TEMPLATE "\
<interface>\n\
<template class =\"MyGtkBuildable\" parent=\"GtkWidget\" >\n\
<custom/>\n\
<custom>\n\
<custom/>\n\
</custom>\n\
</template >\n\
</interface>\n"
#define MY_TYPE_GTK_BUILDABLE (my_gtk_buildable_get_type ())
G_DECLARE_FINAL_TYPE (MyGtkBuildable, my_gtk_buildable, MY, GTK_BUILDABLE, GtkWidget)
struct _MyGtkBuildable
{
GtkWidget parent_instance;
};
static void my_gtk_buildable_buildable_init (GtkBuildableIface *iface);
static GtkBuildableIface *parent_buildable_iface;
G_DEFINE_TYPE_WITH_CODE (MyGtkBuildable, my_gtk_buildable, GTK_TYPE_WIDGET,
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
my_gtk_buildable_buildable_init));
static void
my_gtk_buildable_init (MyGtkBuildable *buildable)
{
gtk_widget_init_template (GTK_WIDGET (buildable));
}
static void
my_gtk_buildable_class_init (MyGtkBuildableClass *klass)
{
GBytes *template = g_bytes_new_static (MY_GTK_BUILDABLE_TEMPLATE, strlen (MY_GTK_BUILDABLE_TEMPLATE));
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
gtk_widget_class_set_template (widget_class, template );
g_bytes_unref (template );
}
static const GtkBuildableParser custom_parser = {
NULL,
NULL,
NULL,
NULL
};
static gboolean
my_gtk_buildable_custom_tag_start (GtkBuildable *buildable,
GtkBuilder *builder,
GObject *child,
const char *tagname,
GtkBuildableParser *parser,
gpointer *parser_data)
{
if (strcmp (tagname, "custom" ) == 0 ) {
*parser = custom_parser;
*parser_data = NULL;
return TRUE ;
}
return FALSE ;
}
static void
my_gtk_buildable_custom_finished (GtkBuildable *buildable,
GtkBuilder *builder,
GObject *child,
const char *tagname,
gpointer user_data)
{
if (strcmp (tagname, "custom" ) == 0 )
return ;
parent_buildable_iface->custom_finished (buildable, builder, child,
tagname, user_data);
}
static void
my_gtk_buildable_buildable_init (GtkBuildableIface *iface)
{
parent_buildable_iface = g_type_interface_peek_parent (iface);
iface->custom_tag_start = my_gtk_buildable_custom_tag_start;
iface->custom_finished = my_gtk_buildable_custom_finished;
}
static void
test_buildable (void )
{
MyGtkBuildable *my_gtk_buildable;
/* make sure the type we are trying to register does not exist */
g_assert_false (g_type_from_name ("MyGtkBuildable" ));
/* create the template object */
my_gtk_buildable = g_object_new (MY_TYPE_GTK_BUILDABLE, NULL);
/* Check everything is fine */
g_assert_true (g_type_from_name ("MyGtkBuildable" ));
g_assert_true (MY_IS_GTK_BUILDABLE (my_gtk_buildable));
g_object_ref_sink (my_gtk_buildable);
g_object_unref (my_gtk_buildable);
}
static GFile *
builder_object_get_file_property (GtkBuilder *builder, const gchar *object_id)
{
GObject *obj = gtk_builder_get_object (builder, object_id);
GFile *value = NULL;
g_assert_nonnull (obj);
g_object_get (obj, "file" , &value, NULL);
g_assert_nonnull (value);
g_assert_true (g_type_is_a (G_OBJECT_TYPE (value), G_TYPE_FILE));
return value;
}
static void
test_picture (void )
{
GtkBuilder *builder;
GError *error = NULL;
GFile *file_path, *file_uri;
gchar *contents = NULL;
gchar *path, *uri;
/* Load from file so builder knows where to read the files from */
path = g_test_build_filename (G_TEST_DIST, "ui" , "picture.ui" , NULL);
builder = gtk_builder_new ();
gtk_builder_add_from_file (builder, path, &error);
if (error)
{
g_print ("ERROR: %s" , error->message);
g_error_free (error);
}
g_assert_null (error);
file_path = builder_object_get_file_property (builder, "relative_path" );
path = g_file_get_path (file_path);
g_assert_nonnull (path);
/* Check path is absolute */
g_assert_true (g_path_is_absolute (path));
/* Check contents can be loaded */
g_assert_true (g_file_load_contents (file_path, NULL, &contents, NULL, NULL, NULL));
g_free (contents);
file_uri = builder_object_get_file_property (builder, "relative_uri" );
uri = g_file_get_uri (file_uri);
g_assert_nonnull (uri);
/* Check uri is absolute */
g_assert_true (g_str_has_prefix (uri, "file://"));
g_assert_true (g_path_is_absolute (uri + strlen("file://")));
g_assert_true (g_file_load_contents (file_uri, NULL, &contents, NULL, NULL, NULL));
g_free (contents);
g_object_unref (builder);
g_free (path);
g_free (uri);
}
int
main (int argc, char **argv)
{
/* initialize test program */
gtk_test_init (&argc, &argv);
g_test_add_func ("/Builder/Parser" , test_parser);
g_test_add_func ("/Builder/Types" , test_types);
g_test_add_func ("/Builder/Construct-Only Properties" , test_construct_only_property);
g_test_add_func ("/Builder/Children" , test_children);
g_test_add_func ("/Builder/Layout Properties" , test_layout_properties);
g_test_add_func ("/Builder/Object Properties" , test_object_properties);
g_test_add_func ("/Builder/Notebook" , test_notebook);
g_test_add_func ("/Builder/Domain" , test_domain);
g_test_add_func ("/Builder/Signal Autoconnect" , test_connect_signals);
g_test_add_func ("/Builder/Spin Button" , test_spin_button);
g_test_add_func ("/Builder/SizeGroup" , test_sizegroup);
g_test_add_func ("/Builder/ListStore" , test_list_store);
g_test_add_func ("/Builder/TreeStore" , test_tree_store);
g_test_add_func ("/Builder/TreeView Column" , test_treeview_column);
g_test_add_func ("/Builder/IconView" , test_icon_view);
g_test_add_func ("/Builder/ComboBox" , test_combo_box);
#if 0
g_test_add_func ("/Builder/ComboBox Entry" , test_combo_box_entry);
#endif
g_test_add_func ("/Builder/CellView" , test_cell_view);
g_test_add_func ("/Builder/Dialog" , test_dialog);
g_test_add_func ("/Builder/Widget" , test_widget);
g_test_add_func ("/Builder/Value From String" , test_value_from_string);
g_test_add_func ("/Builder/Reference Counting" , test_reference_counting);
g_test_add_func ("/Builder/Window" , test_window);
g_test_add_func ("/Builder/PangoAttributes" , test_pango_attributes);
g_test_add_func ("/Builder/Requires" , test_requires);
g_test_add_func ("/Builder/AddObjects" , test_add_objects);
g_test_add_func ("/Builder/MessageArea" , test_message_area);
g_test_add_func ("/Builder/MessageDialog" , test_message_dialog);
g_test_add_func ("/Builder/GMenu" , test_gmenu);
g_test_add_func ("/Builder/LevelBar" , test_level_bar);
g_test_add_func ("/Builder/Expose Object" , test_expose_object);
g_test_add_func ("/Builder/Template" , test_template);
g_test_add_func ("/Builder/No IDs" , test_no_ids);
g_test_add_func ("/Builder/Property Bindings" , test_property_bindings);
g_test_add_func ("/Builder/anaconda-signal" , test_anaconda_signal);
g_test_add_func ("/Builder/FileFilter" , test_file_filter);
g_test_add_func ("/Builder/Shortcuts" , test_shortcuts);
g_test_add_func ("/Builder/Transforms" , test_transforms);
g_test_add_func ("/Builder/Expressions" , test_expressions);
g_test_add_func ("/Builder/Child Dispose Order" , test_child_dispose_order);
g_test_add_func ("/Builder/Buildable" , test_buildable);
g_test_add_func ("/Builder/Picture" , test_picture);
return g_test_run();
}
Messung V0.5 in Prozent C=99 H=90 G=94
¤ Dauer der Verarbeitung: 0.42 Sekunden
(vorverarbeitet am 2026-07-03)
¤
*© Formatika GbR, Deutschland