1 /*
2  * ===========================
3  * VDK Visual Development Kit
4  * Version 0.4
5  * October 1998
6  * ===========================
7  *
8  * Copyright (C) 1998, Mario Motta
9  * Developed by Mario Motta <mmotta@guest.net>
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Library General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Library General Public License for more details.
20  *
21  * You should have received a copy of the GNU Library General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24  * 02111-1307, USA.
25  *
26 */
27 
28 
29 #include "vdk/entry.h"
30 #include "vdk/forms.h"
31 #include "vdk/colors.h"
32 //#include <string>
33 
34 static void
EntryChanged(GtkWidget * wid,gpointer gp)35 EntryChanged(GtkWidget* wid, gpointer gp)
36 {
37   g_return_if_fail(wid != NULL);
38   GtkEntry* entry = GTK_ENTRY(wid);
39   VDKEntry* vdkentry = reinterpret_cast<VDKEntry*>(gp);
40   char* p = gtk_editable_get_chars (GTK_EDITABLE(entry), 0,-1);
41   if(p)
42     {
43 #ifdef USE_SIGCPLUSPLUS
44       vdkentry->Text.OnValueChanged.emit(vdkentry,vdkentry->GetText());
45 #endif
46       vdkentry->SignalEmit(changed_signal);
47       g_free(p);
48     }
49 }
50 
51 int
FocusOutEvent(GtkWidget *,GdkEventFocus *,gpointer wid)52 VDKEntry::FocusOutEvent(GtkWidget *,
53 			    GdkEventFocus*,
54 			    gpointer wid)
55 {
56   g_return_val_if_fail(wid != NULL,FALSE);
57   VDKEntry* obj = reinterpret_cast<VDKEntry*>(wid);
58   obj->SignalEmit(focus_out_signal);
59   return FALSE;//TRUE;
60 }
61 /*
62  */
63 int
FocusInEvent(GtkWidget *,GdkEventFocus *,gpointer wid)64 VDKEntry::FocusInEvent(GtkWidget *,
65 			    GdkEventFocus *,
66 			    gpointer wid)
67 {
68   g_return_val_if_fail(wid != NULL,FALSE);
69   VDKEntry* obj = reinterpret_cast<VDKEntry*>(wid);
70   obj->SignalEmit(focus_in_signal);
71   return FALSE;//TRUE;
72 }
73 /*
74  */
VDKEntry(VDKForm * owner,int maxLen,char * def)75 VDKEntry::VDKEntry(VDKForm* owner, int maxLen, char* def):
76   VDKObject(owner),
77   Text("Text", this, NULL, &VDKEntry::SetText, &VDKEntry::GetText),
78   Editable("Editable", this, true, &VDKEntry::SetEditable),
79   Hidden("Hidden", this, false, &VDKEntry::SetHidden)
80 {
81 	if (maxLen) widget = sigwid = gtk_entry_new_with_max_length(maxLen);
82 	else widget = sigwid = gtk_entry_new();
83 	if(def) SetText(def);
84 	s_activated.obj = this;
85 	s_activated.signal = activate_signal;
86 	s_changed.obj = this;
87 	s_changed.signal = changed_signal;
88 	gtk_signal_connect(GTK_OBJECT(widget),"activate",
89 		GTK_SIGNAL_FUNC(VDKObject::VDKSignalPipe),
90 	(gpointer) &s_activated);
91 	/*
92 	changeConnect = gtk_signal_connect(GTK_OBJECT(widget),"changed",
93 		GTK_SIGNAL_FUNC(VDKObject::VDKSignalPipe),
94 		(gpointer) &s_changed);
95 	*/
96 	changeConnect = gtk_signal_connect(GTK_OBJECT(widget),"changed",
97 		GTK_SIGNAL_FUNC(::EntryChanged),
98 		(gpointer) this);
99 	gtk_signal_connect(GTK_OBJECT(widget),
100 		"focus_out_event",
101 		GTK_SIGNAL_FUNC(VDKEntry::FocusOutEvent),
102 		(gpointer) this);
103 	gtk_signal_connect(GTK_OBJECT(widget),
104 		"focus_in_event",
105 		GTK_SIGNAL_FUNC(VDKEntry::FocusInEvent),
106 		(gpointer) this);
107 	ConnectDefaultSignals();
108 }
109 /*
110  */
~VDKEntry()111 VDKEntry::~VDKEntry()
112 {
113 }
114 
115 /*
116  */
SetText(char * s)117 void VDKEntry::SetText(char* s)
118 {
119   int len = strlen(s);
120   if(len)
121     {
122       char* local = new char[len+1];
123       strcpy(local,s);
124       if(!g_utf8_validate(local,-1,NULL))
125 	g_locale_to_utf8(local,-1,NULL,NULL,NULL);
126       gtk_entry_set_text(GTK_ENTRY(widget),local);
127       delete[] local;
128     }
129   else
130     gtk_entry_set_text(GTK_ENTRY(widget),"");
131 }
132 /*
133  */
GetText()134 char* VDKEntry::GetText()
135 {
136 	char* p = gtk_editable_get_chars (GTK_EDITABLE(WrappedWidget()), 0,-1);
137 	if (p) {
138 		buffer = p;
139 		g_free(p);
140 	}
141 	return (char*) buffer;
142 }
143 
144 /*
145  */
SetBackground(VDKRgb rgb,GtkStateType state)146 void VDKEntry::SetBackground(VDKRgb rgb,
147 			     GtkStateType state)
148 {
149   VDKColor *color = new VDKColor(Owner(),rgb.red,rgb.green,rgb.blue);
150   gtk_widget_modify_base (widget, state, color->Color());
151   /*
152   GtkStyle* style = gtk_style_copy(gtk_widget_get_style(widget));
153   g_return_if_fail(style != NULL);
154   gtk_style_ref(style);
155   style->base[state] = *(color->Color());
156   gtk_widget_set_style(widget,style);
157   */
158 }
159 /*
160  */
SetForeground(VDKRgb rgb,GtkStateType state)161 void VDKEntry::SetForeground(VDKRgb rgb,
162 			     GtkStateType state)
163 {
164   VDKColor *color = new VDKColor(Owner(),rgb.red,rgb.green,rgb.blue);
165   gtk_widget_modify_text (widget, state, color->Color());
166   /*
167   GtkStyle* style = gtk_style_copy(gtk_widget_get_style(widget));
168   g_return_if_fail(style != NULL);
169   gtk_style_ref(style);
170   style->base[state] = *(color->Color());
171   gtk_widget_set_style(widget,style);
172   */
173 }
174 
175 /*
176  */
177 void
SetFont(VDKFont * font)178 VDKEntry::SetFont(VDKFont* font)
179 {
180 if(!GTK_WIDGET_REALIZED(WrappedWidget()))
181   VDKObject::SetFont(font);
182 else
183   {
184     GtkRcStyle *rc_style;
185     rc_style = gtk_rc_style_new ();
186     rc_style->font_desc =
187       pango_font_description_copy (font->AsPangoFontDescription());
188     gtk_widget_modify_style (WrappedWidget(), rc_style);
189     gtk_rc_style_unref (rc_style);
190     gtk_widget_size_request (WrappedWidget(), NULL);
191   }
192 }
193 
194 // COMPLETION SUPPORT
195 static GtkTreeModel *
196 create_string_completion_model (char* completion_list[]);
197 
198 static gboolean
199 match_func (GtkEntryCompletion *completion,
200 	    const gchar        *key,
201 	    GtkTreeIter        *iter,
202 	    gpointer            user_data);
203 /*
204   completion_list must be a NULL terminating string array;
205  */
206 
207 void
SetCompletion(char ** completion_list)208 VDKEntry::SetCompletion(char** completion_list)
209 {
210   // uses any previous model if any
211   GtkEntryCompletion * completion = gtk_entry_get_completion (GTK_ENTRY (widget));
212   GtkTreeModel *completion_model = NULL;
213   if(!completion)
214     {
215       /* Create the completion object */
216       completion = gtk_entry_completion_new ();
217       /* Assign the completion to the entry */
218       gtk_entry_set_completion (GTK_ENTRY (widget), completion);
219       g_object_unref (completion);
220     }
221   /* Create a tree model and use it as the completion model */
222   completion_model = create_string_completion_model (completion_list);
223   gtk_entry_completion_set_model (completion, completion_model);
224   g_object_unref (completion_model);
225   /* Use model column 0 as the text column */
226   gtk_entry_completion_set_text_column (completion, 0);
227   gtk_entry_completion_set_minimum_key_length (completion, 1);
228   gtk_entry_completion_set_match_func (completion, match_func, NULL, NULL);
229   return;
230 }
231 //
232 void
AddCompletionItem(char * completion_item)233 VDKEntry::AddCompletionItem(char* completion_item)
234 {
235   GtkEntryCompletion * completion = gtk_entry_get_completion (GTK_ENTRY (widget));
236   GtkListStore *store = NULL;
237   if(completion)
238     {
239       GtkTreeIter iter;
240       store = GTK_LIST_STORE (gtk_entry_completion_get_model (completion));
241       if(store)
242 	{
243 	  gtk_list_store_append (store, &iter);
244 	  gtk_list_store_set (store, &iter, 0, completion_item, -1);
245 	}
246     }
247 }
248 //
249 void
RemoveCompletionItem(char * completion_item)250 VDKEntry::RemoveCompletionItem(char* completion_item)
251 {
252   GtkEntryCompletion * completion = gtk_entry_get_completion (GTK_ENTRY (widget));
253   GtkTreeModel *store = NULL;
254   if(completion)
255     {
256       GtkTreeIter iter;
257       store = gtk_entry_completion_get_model (completion);
258       if(store)
259 	{
260 	  gchar *item = NULL;
261 	  for(bool flag = gtk_tree_model_get_iter_first(store,&iter);
262 	      flag; flag = gtk_tree_model_iter_next(store,&iter))
263 	    {
264 	        gtk_tree_model_get (store, &iter, 0, &item, -1);
265 		if(!strcmp(item,completion_item))
266 		  {
267 		    gtk_list_store_remove (GTK_LIST_STORE(store),&iter);
268 		    break;
269 		  }
270 	    }
271 	}
272     }
273 }
274 /*
275 ---------- SUPPORT ---------
276 */
277 static gboolean
match_func(GtkEntryCompletion * completion,const gchar * key,GtkTreeIter * iter,gpointer user_data)278 match_func (GtkEntryCompletion *completion,
279 	    const gchar        *key,
280 	    GtkTreeIter        *iter,
281 	    gpointer            user_data)
282 {
283   gchar *item = NULL;
284   GtkTreeModel *model;
285 
286   gboolean ret = FALSE;
287 
288   model = gtk_entry_completion_get_model (completion);
289 
290   gtk_tree_model_get (model, iter, 0, &item, -1);
291 
292   if (item != NULL)
293     {
294       if (strncmp (key, item, strlen (key)) == 0)
295 	ret = TRUE;
296       g_free (item);
297     }
298 
299   return ret;
300 }
301 
302 GtkTreeModel *
create_string_completion_model(char * completion_list[])303 create_string_completion_model (char* completion_list[])
304 {
305   GtkListStore *store;
306   GtkTreeIter iter;
307   store = gtk_list_store_new (1, G_TYPE_STRING);
308   for(int t = 0; completion_list[t]; t++)
309     {
310       gtk_list_store_append (store, &iter);
311       gtk_list_store_set (store, &iter, 0, completion_list[t], -1);
312     }
313   return GTK_TREE_MODEL (store);
314 }
315 
316