Update called vala api.
[stuffkeeper.git] / src / stuffkeeper-data-entry.gob
blob724b21edf27df6c7d415f2313f691aafc56da8a9
3 %h{
4 #include <gtk/gtk.h>
5 #include "misc.h"
6 #include "stuffkeeper-data-item.h"
7 %}
9 %ph{
10 #include "stuffkeeper-data-backend.h"
14         enum {
15                 PRIVATE_FIELD_DEFAULT = 0
16         };
20 class Stuffkeeper:Data:Entry from Gtk:Entry 
22     private StuffkeeperDataItem *item = {NULL};
23     private gchar *field = {NULL} destroywith g_free;
24     private gulong changed_item_entry = {0};
25     private gulong changed_entry = {0};
27     private guint changed_entry_timeout = {0};
28     private GdkColor writing ;
29     private GdkColor base;
30     private GdkColor text;
32     /* lock signal */
33     private gulong signal_backend_locked = {0};
35     private
36     gboolean  
37     save_changes(self)
38     {
39         /* Add a reference */
40         g_object_ref(self);
41         const gchar *text = gtk_entry_get_text(GTK_ENTRY(self));
42         self->_priv->changed_entry_timeout = 0;
44         gtk_widget_modify_text(GTK_WIDGET(self), GTK_STATE_NORMAL, &(self->_priv->text));
45         gtk_widget_modify_base(GTK_WIDGET(self), GTK_STATE_NORMAL, &(self->_priv->base));
47         if(self->_priv->field)
48         {
49             stuffkeeper_data_item_set_string(self->_priv->item, self->_priv->field, text);
50         }else{
51             stuffkeeper_data_item_set_title(self->_priv->item, text);
52         }
54         g_object_unref(self);
55         return FALSE;
56     }
60     private
61     void
62     changed(self, gpointer data)
63     {
64         printf("entry changed\n");
65         if(self->_priv->changed_entry_timeout)
66         {
67             g_source_remove(self->_priv->changed_entry_timeout);
68         }
69         self->_priv->changed_entry_timeout = g_timeout_add(1000,(GSourceFunc)self_save_changes,self);
71         gtk_widget_modify_text(GTK_WIDGET(self), GTK_STATE_NORMAL, &(GTK_WIDGET(self)->style->black));
72         gtk_widget_modify_base(GTK_WIDGET(self), GTK_STATE_NORMAL, &(self->_priv->writing));
73     }
75     private
76     void
77     item_changed(self,const gchar *field, StuffkeeperDataItem *item)
78     {
79         const gchar *text = gtk_entry_get_text(GTK_ENTRY(self));
80         gchar *value = NULL;
81         if(self->_priv->field)
82         {
83             if(field && strcmp(field, self->_priv->field) == 0)
84             {
85                 value = stuffkeeper_data_item_get_string(item, self->_priv->field);
86             }
87         }else{
88             value = stuffkeeper_data_item_get_title(item); 
89             if(stuffkeeper_data_item_has_generated_title(item))
90                 gtk_editable_set_editable(GTK_EDITABLE(self), FALSE);
91             else
92                 gtk_editable_set_editable(GTK_EDITABLE(self), TRUE);
93         }
94         if(value)
95         {
96             if(strcmp(text,value))
97             {
98                 printf("Changed\n");
99                 g_signal_handler_block(self,self->_priv->changed_entry);
100                 gtk_entry_set_text(GTK_ENTRY(self), value);
101                 g_signal_handler_unblock(self,self->_priv->changed_entry);
102             }
103             g_free(value);
104         }
105     }
106     private 
107     void
108     style_set(self, GtkStyle *prev, GtkWidget *wid)
109     {
110         if(self->_priv->changed_entry_timeout == 0) {
111             if(self->_priv->field == NULL && 
112                     !stuffkeeper_data_item_has_generated_title(self->_priv->item)
113             ) {
114                 /* Special case: Item is an editable title - use default system colors */
115                 self->_priv->base = (GTK_WIDGET(self)->style->base[GTK_STATE_NORMAL]);
116                 self->_priv->text = (GTK_WIDGET(self)->style->text[GTK_STATE_NORMAL]);
117             }
118             else {
119                 /* Normal case: match colors with parent (hereby making enrty "transparent") */
120                 GtkWidget *parent_bin = NULL;
122                 g_debug("Matching colors for StuffkeeperDataEntry with parent\n");
123                 parent_bin = wid->parent; 
124                 while(parent_bin && !GTK_IS_BIN(parent_bin)) {
125                     parent_bin = GTK_WIDGET(parent_bin)->parent;
126                 }
127                 if(parent_bin) {
128                     g_signal_handlers_block_by_func(G_OBJECT(self), self_style_set, wid);
129                     self->_priv->base = (GTK_WIDGET(parent_bin)->style->bg[GTK_STATE_NORMAL]);
130                     self->_priv->text = (GTK_WIDGET(parent_bin)->style->text[GTK_STATE_NORMAL]);
131                     gtk_widget_modify_base(GTK_WIDGET(wid), GTK_STATE_NORMAL, &(self->_priv->base));
132                     gtk_widget_modify_text(GTK_WIDGET(wid), GTK_STATE_NORMAL, &(self->_priv->text));
133                     g_signal_handlers_unblock_by_func(G_OBJECT(self),self_style_set , wid);
134                 }
135                 else {
136                     g_debug("No GtkBin parent found for StuffkeeperDataEntr\n");
137                 }
138             }
139         }
140     }
141     private
142     void
143     backend_locked(self, GParamSpec *arg1, StuffkeeperDataBackend *backend)
144     {
145         gboolean locked = stuffkeeper_data_backend_get_locked(backend);
146         if(self->_priv->field == NULL) /* if it is an title */
147         {
148             if(stuffkeeper_data_item_has_generated_title(self->_priv->item))
149             {
150                 gtk_editable_set_editable(GTK_EDITABLE(self), FALSE);
151                 return;
152             }
153         }
154         gtk_editable_set_editable(GTK_EDITABLE(self), !locked);
155     }
156     public
157     GtkWidget *
158     new(StuffkeeperDataItem *item, const gchar *field)
159     {
160         Self *obj = GET_NEW;
161         gchar *value =NULL;
163         if(!g_key_file_get_boolean(config_file, "interface", "has-border",NULL))
164         gtk_entry_set_has_frame(GTK_ENTRY(obj), FALSE);
166         obj->_priv->base = (GTK_WIDGET(obj)->style->base[GTK_STATE_NORMAL]);
167         obj->_priv->text = (GTK_WIDGET(obj)->style->text[GTK_STATE_NORMAL]);
168         obj->_priv->writing.red = 255*255;
169         obj->_priv->writing.green = 253*255;
170         obj->_priv->writing.blue = 197*255;
171         gdk_colormap_alloc_color(gtk_widget_get_default_colormap(), &(obj->_priv->writing), TRUE,TRUE);
172         g_signal_connect_swapped(G_OBJECT(obj), "style-set", G_CALLBACK(self_style_set),obj);
174         /* store item */
175         obj->_priv->item = item; 
176         /* field */
177         obj->_priv->field = g_strdup(field);
178             
179         obj->_priv->changed_item_entry = g_signal_connect_swapped(G_OBJECT(item), "item-changed", G_CALLBACK(self_item_changed), obj);
181         /* update the entry */
182         if(obj->_priv->field)
183         {
184             value = stuffkeeper_data_item_get_string(item, obj->_priv->field);
185         }else{
186             value = stuffkeeper_data_item_get_title(item); 
187             if(stuffkeeper_data_item_has_generated_title(item)) {
188                 gtk_editable_set_editable(GTK_EDITABLE(obj), FALSE);
189                 GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(obj), GTK_CAN_FOCUS);
190             }
191             else {
192                 gtk_editable_set_editable(GTK_EDITABLE(obj), TRUE);
193                 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(obj), GTK_CAN_FOCUS);
194             }
195         }
196         if(value)
197         {
198             gtk_entry_set_text(GTK_ENTRY(obj), value);
199             g_free(value);
200         }
201         else {
202             gchar *field = stuffkeeper_data_schema_get_custom_field_string(stuffkeeper_data_item_get_schema(item), 
203                 obj->_priv->field,
204                 PRIVATE_FIELD_DEFAULT); 
205             if(field) {
206                 gtk_entry_set_text(GTK_ENTRY(obj), field);
207                 /* make it stick */
208                 self_changed(obj,NULL);
209                 g_free(field);
210             }
211         }
212         obj->_priv->signal_backend_locked = g_signal_connect_swapped(G_OBJECT(stuffkeeper_data_item_get_backend(item)), 
213                                                                      "notify::locked", G_CALLBACK(self_backend_locked), obj);
214         self_backend_locked(obj,NULL, STUFFKEEPER_DATA_BACKEND(stuffkeeper_data_item_get_backend(item)));
216         /* this is destroyed when self is destroyed, so no need to disconnect myself */
217         obj->_priv->changed_entry = g_signal_connect(G_OBJECT(obj), "changed", G_CALLBACK(self_changed), NULL);
218         return GTK_WIDGET(obj);
219     }
221     override (G:Object)
222         void
223         finalize (G:Object *obj)
224         {
225             Self *self = SELF(obj);
226             if(self->_priv->signal_backend_locked) {                                                                     
227                 g_signal_handler_disconnect(G_OBJECT(stuffkeeper_data_item_get_backend(self->_priv->item)), self->_priv->signal_backend_locked);
228                 self->_priv->signal_backend_locked = 0;
229             }
230             if(self->_priv->changed_item_entry)
231             {
232                 g_signal_handler_disconnect(self->_priv->item,self->_priv->changed_item_entry);
233                 self->_priv->changed_item_entry = 0;
234             }
235            if(self->_priv->changed_entry_timeout)
236             {
237                 g_source_remove(self->_priv->changed_entry_timeout);
238                 self->_priv->changed_entry_timeout = 0;
239                 printf("Finalize: %p\n", self);
240                 self_save_changes(self);
241             }
243             PARENT_HANDLER(obj);
244         }