Make TildaWindow determine number correctly
[tilda-gobject.git] / tilda-window.c
1 #include "tilda.h"
2 #include "tilda-window.h"
3 #include "tilda-window-dbus-glue.h"
4
5 static gboolean
6 tilda_window_add_term (TildaWindow *tw)
7 {
8         // FIXME: this is totally bad, but it's a good hack for feasability
9         static gint mynumber = 0;
10         TildaTerminal *tt = g_object_new (TILDA_TYPE_TERMINAL,
11                                                                           "number", mynumber++,
12                                                                           "window-number", tw->number,
13                                                                           "parent-window", tw,
14                                                                           NULL);
15         g_ptr_array_add (tw->terms, tt);
16
17         GtkWidget *label = gtk_label_new ("Tilda");
18         gint index = gtk_notebook_prepend_page (GTK_NOTEBOOK(tw->notebook), tt->hbox, label);
19         gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK(tw->notebook), tt->hbox, TRUE, TRUE, GTK_PACK_END);
20         //gtk_notebook_set_current_page (GTK_NOTEBOOK(tw->notebook), index);
21
22         if (gtk_notebook_get_n_pages (GTK_NOTEBOOK(tw->notebook)) > 1)
23                 gtk_notebook_set_show_tabs (GTK_NOTEBOOK(tw->notebook), TRUE);
24
25         return TRUE;
26 }
27
28 static gboolean
29 tilda_window_remove_term (TildaWindow *tw, int number)
30 {
31         int i;
32
33         for (i=0; i<tw->terms->len; ++i)
34         {
35                 TildaTerminal *tt = g_ptr_array_index (tw->terms, i);
36
37                 if (tt->number == number)
38                         g_print ("Need to remove window %d terminal %d\n", tw->number, tt->number);
39         }
40
41         return TRUE;
42 }
43
44 static void
45 tilda_window_dbus_register_object (TildaWindow *tw)
46 {
47         gchar *object_path;
48
49         // Register this object with DBus
50         object_path = g_strdup_printf ("/net/sourceforge/Tilda/Window%d", tw->number);
51         dbus_g_connection_register_g_object (dbus_connection, object_path, G_OBJECT(tw));
52         g_free (object_path);
53 }
54
55 /*******************************************************************************
56  * ALL GOBJECT STUFF BELOW PLEASE
57  ******************************************************************************/
58
59 static GObjectClass *parent_class = NULL;
60
61 enum tilda_window_properties {
62         TILDA_WINDOW_NUMBER = 1,
63 };
64
65 static void
66 tilda_window_instance_init (GTypeInstance *instance,
67                                                         gpointer       g_class)
68 {
69         TildaWindow *self = (TildaWindow *) instance;
70         self->dispose_has_run = FALSE;
71
72         /* Initialize all properties */
73         self->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
74         self->notebook = gtk_notebook_new ();
75         self->terms = g_ptr_array_new ();
76
77         /* Somewhat of a "poison" value, incase we don't set this */
78         self->number = 0xdeadbeef;
79 }
80
81 static void
82 tilda_window_set_property (GObject      *object,
83                                                    guint         property_id,
84                                                    const GValue *value,
85                                                    GParamSpec   *pspec)
86 {
87         TildaWindow *self = (TildaWindow *) object;
88
89         switch (property_id) {
90
91                 case TILDA_WINDOW_NUMBER:
92                         self->number = g_value_get_int (value);
93                         g_print ("window number: %d\n", self->number);
94                         break;
95
96                 default:
97                         /* We don't have this property */
98                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
99                         break;
100         }
101 }
102
103 static void
104 tilda_window_get_property (GObject    *object,
105                                                    guint       property_id,
106                                                    GValue     *value,
107                                                    GParamSpec *pspec)
108 {
109         TildaWindow *self = (TildaWindow *) object;
110
111         switch (property_id) {
112
113                 case TILDA_WINDOW_NUMBER:
114                         g_value_set_int (value, self->number);
115                         break;
116
117                 default:
118                         /* We don't have this property */
119                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
120                         break;
121         }
122 }
123
124 static GObject *
125 tilda_window_constructor (GType                  type,
126                                                   guint                  n_construct_properties,
127                                                   GObjectConstructParam *construct_properties)
128 {
129         GObject *obj;
130         TildaWindow *self;
131
132         /* Invoke parent constructor */
133         TildaWindowClass *klass;
134         klass = TILDA_WINDOW_CLASS (g_type_class_peek (TILDA_TYPE_WINDOW));
135         obj = parent_class->constructor (type,
136                                                                          n_construct_properties,
137                                                                          construct_properties);
138
139         /* Do other stuff here. The object is ready to go now, and all
140          * ctor properties have been set.
141          *
142          * TODO: This is the place to do DBus-init */
143         self = TILDA_WINDOW(obj);
144
145         /* Register this object with DBus */
146         tilda_window_dbus_register_object (self);
147
148         gtk_container_add (GTK_CONTAINER(self->window), self->notebook);
149         gtk_widget_show (self->notebook);
150
151         tilda_window_add_term (self);
152         gtk_widget_show_all (self->window);
153
154         return obj;
155 }
156
157 static void
158 my_unref (gpointer data, gpointer user_data)
159 {
160         g_object_unref (G_OBJECT(data));
161 }
162
163 static void
164 tilda_window_dispose (GObject *obj)
165 {
166         TildaWindow *self = (TildaWindow *) obj;
167
168         /* We don't want to run dispose twice, so just return immediately */
169         if (self->dispose_has_run)
170                 return;
171
172         /*
173          * In dispose, you are supposed to free all types referenced from this
174          * object which might themselves hold a reference to self. Generally,
175          * the most simple solution is to unref all members on which you own a
176          * reference.
177          *
178          * NOTE: See the following for how to deal with GtkObject-derived things:
179          * http://library.gnome.org/devel/gtk/unstable/GtkObject.html
180          */
181         g_ptr_array_foreach (self->terms, my_unref, NULL);
182         gtk_widget_destroy (self->window);
183
184         /* Chain up to the parent class */
185         G_OBJECT_CLASS (parent_class)->dispose (obj);
186 }
187
188 static void
189 tilda_window_finalize (GObject *obj)
190 {
191         TildaWindow *self = (TildaWindow *) obj;
192
193         /*
194          * Here, complete the object's destruction.
195          * You might not need to do much...
196          */
197         // TODO: g_free() any primitives here
198         g_ptr_array_free (self->terms, TRUE);
199
200
201         /* Chain up to the parent class */
202         G_OBJECT_CLASS (parent_class)->finalize (obj);
203 }
204
205 static void
206 tilda_window_class_init (gpointer g_class,
207                                                  gpointer g_class_data)
208 {
209         GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
210         TildaWindowClass *klass = TILDA_WINDOW_CLASS (g_class);
211         GParamSpec *pspec;
212
213         /* Hook our functions to this type */
214         gobject_class->set_property = tilda_window_set_property;
215         gobject_class->get_property = tilda_window_get_property;
216         gobject_class->dispose = tilda_window_dispose;
217         gobject_class->finalize = tilda_window_finalize;
218         gobject_class->constructor = tilda_window_constructor;
219
220         parent_class = g_type_class_peek_parent (klass);
221
222         /* Install all of the properties */
223         pspec = g_param_spec_int ("number",
224                                                           "Window number",
225                                                           "Set window's number",
226                                                           0,            // min value
227                                                           INT_MAX,      // max value
228                                                           0,            // def value
229                                                           G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
230
231         g_object_class_install_property (gobject_class,
232                                                                          TILDA_WINDOW_NUMBER,
233                                                                          pspec);
234
235         /* TODO: more properties */
236
237         /* Hook the TildaWindow type into DBus */
238         dbus_g_object_type_install_info (tilda_window_get_type(), &dbus_glib_tilda_window_object_info);
239 }
240
241 GType
242 tilda_window_get_type (void)
243 {
244         static GType type = 0;
245
246         if (type == 0)
247         {
248                 static const GTypeInfo info = {
249                         sizeof (TildaWindowClass),
250                         NULL,   /* base_init */
251                         NULL,   /* base_finalize */
252                         tilda_window_class_init,        /* class_init */
253                         NULL,   /* class_finalize */
254                         NULL,   /* class_data */
255                         sizeof (TildaWindow),
256                         0,              /* n_preallocs */
257                         tilda_window_instance_init,     /* instance_init */
258                 };
259
260                 type = g_type_register_static (G_TYPE_OBJECT,
261                                                                            "TildaWindowType",
262                                                                            &info,
263                                                                            0);
264         }
265
266         return type;
267 }
268
269 #if 0
270
271 int main (int argc, char *argv[])
272 {
273         GObject *tw;
274         gint test_number = INT_MIN;
275
276         /* Initialize the GObject type system */
277         g_type_init ();
278         gtk_init (&argc, &argv);
279
280         tw = g_object_new (TILDA_TYPE_WINDOW, "number", 10, NULL);
281         g_object_get (G_OBJECT (tw), "number", &test_number, NULL);
282         g_assert (test_number == 10);
283
284         g_object_unref (G_OBJECT (tw));
285
286         tw = g_object_new (TILDA_TYPE_WINDOW, "number", 22, NULL);
287         g_object_get (G_OBJECT (tw), "number", &test_number, NULL);
288         g_assert (test_number == 22);
289
290         gtk_main ();
291
292         g_object_unref (G_OBJECT (tw));
293
294         return 0;
295 }
296
297 #endif
298
299 /* vim: set ts=4 sts=4 sw=4 noet tw=112: */