libanjuta: Fix some warnings and made AnjutaPluginDescription a boxed type
[anjuta.git] / libanjuta / anjuta-entry.c
blob81f7b5aaaebcdbaba9c407f4bd8336aee35b38c5
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * anjuta
4 * Copyright (C) James Liggett 2010 <jrliggett@cox.net>
5 *
6 * anjuta is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * anjuta is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "anjuta-entry.h"
22 /**
23 * SECTION:anjuta-entry
24 * @short_description: #GtkEntry subclass that displays help text with a button
25 * to clear the entry's contents.
26 * @include: libanjuta/anjuta-entry.h
28 * AnjutaEntry is a version of a #GtkEntry that displays some text, in
29 * a lighter color, that describes what is to be entered into it. There is also
30 * a button on the left to clear the entry's content quickly. AnjutaEntry is
31 * similar to the serach boxes used in Evolution and Glade, but is more generic
32 * can can be used in almost any situation.
35 enum
37 PROP_0,
39 PROP_HELP_TEXT
42 typedef enum
44 ANJUTA_ENTRY_NORMAL,
45 ANJUTA_ENTRY_HELP
46 } AnjutaEntryMode;
48 struct _AnjutaEntryPriv
50 gboolean showing_help_text;
51 gchar *help_text;
54 G_DEFINE_TYPE (AnjutaEntry, anjuta_entry, GTK_TYPE_ENTRY);
56 static void
57 anjuta_entry_set_mode (AnjutaEntry *self, AnjutaEntryMode mode)
59 GtkStyle *style;
61 style = gtk_widget_get_style (GTK_WIDGET (self));
63 switch (mode)
65 case ANJUTA_ENTRY_NORMAL:
66 /* Remove the help text from the widget */
67 if (self->priv->showing_help_text)
68 gtk_entry_set_text (GTK_ENTRY (self), "");
70 gtk_widget_modify_text (GTK_WIDGET (self), GTK_STATE_NORMAL, NULL);
72 self->priv->showing_help_text = FALSE;
74 break;
75 case ANJUTA_ENTRY_HELP:
76 if (self->priv->help_text)
77 gtk_entry_set_text (GTK_ENTRY (self), self->priv->help_text);
78 else
79 gtk_entry_set_text (GTK_ENTRY (self), "");
81 gtk_widget_modify_text (GTK_WIDGET (self),
82 GTK_STATE_NORMAL,
83 &(style->text[GTK_STATE_INSENSITIVE]));
85 self->priv->showing_help_text = TRUE;
87 break;
88 default:
89 break;
93 /* It's probably terrible practice for a subclass to be listening to the
94 * parent' class's signals, but for some reason the icon release signal
95 * doesn't have a virtual method pointer in the GtkEntry class structure */
96 static void
97 anjuta_entry_icon_release (GtkEntry *entry, GtkEntryIconPosition icon_pos,
98 GdkEvent *event, gpointer user_data)
100 AnjutaEntry *self;
102 self = ANJUTA_ENTRY (entry);
104 if (icon_pos == GTK_ENTRY_ICON_SECONDARY)
105 gtk_entry_set_text (entry, "");
108 static void
109 anjuta_entry_init (AnjutaEntry *self)
111 self->priv = g_new0 (AnjutaEntryPriv, 1);
113 gtk_entry_set_icon_from_stock (GTK_ENTRY (self), GTK_ENTRY_ICON_SECONDARY,
114 GTK_STOCK_CLEAR);
115 gtk_entry_set_icon_activatable (GTK_ENTRY (self), GTK_ENTRY_ICON_SECONDARY,
116 TRUE);
118 g_signal_connect (G_OBJECT (self), "icon-release",
119 G_CALLBACK (anjuta_entry_icon_release),
120 NULL);
122 anjuta_entry_set_mode (self, ANJUTA_ENTRY_HELP);
125 static void
126 anjuta_entry_finalize (GObject *object)
128 AnjutaEntry *self;
130 self = ANJUTA_ENTRY (object);
132 g_free (self->priv->help_text);
133 g_free (self->priv);
135 G_OBJECT_CLASS (anjuta_entry_parent_class)->finalize (object);
138 static void
139 anjuta_entry_set_property (GObject *object, guint prop_id, const GValue *value,
140 GParamSpec *pspec)
142 AnjutaEntry *self;
144 g_return_if_fail (ANJUTA_IS_ENTRY (object));
146 self = ANJUTA_ENTRY (object);
148 switch (prop_id)
150 case PROP_HELP_TEXT:
151 g_free (self->priv->help_text);
153 self->priv->help_text = g_value_dup_string (value);
155 /* Update the display */
156 if (self->priv->showing_help_text)
158 if (self->priv->help_text)
160 gtk_entry_set_text (GTK_ENTRY (self),
161 self->priv->help_text);
164 break;
165 default:
166 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
167 break;
171 static void
172 anjuta_entry_get_property (GObject *object, guint prop_id, GValue *value,
173 GParamSpec *pspec)
175 AnjutaEntry *self;
177 g_return_if_fail (ANJUTA_IS_ENTRY (object));
179 self = ANJUTA_ENTRY (object);
181 switch (prop_id)
183 case PROP_HELP_TEXT:
184 g_value_set_string (value, self->priv->help_text);
185 break;
186 default:
187 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
188 break;
192 static gboolean
193 anjuta_entry_focus_in_event (GtkWidget *widget, GdkEventFocus *event)
195 AnjutaEntry *self;
197 self = ANJUTA_ENTRY (widget);
199 if (self->priv->showing_help_text)
200 anjuta_entry_set_mode (self, ANJUTA_ENTRY_NORMAL);
202 return GTK_WIDGET_CLASS (anjuta_entry_parent_class)->focus_in_event (widget, event);
205 static gboolean
206 anjuta_entry_focus_out_event (GtkWidget *widget, GdkEventFocus *event)
208 AnjutaEntry *self;
209 const gchar *text;
211 self = ANJUTA_ENTRY (widget);
212 text = gtk_entry_get_text (GTK_ENTRY (widget));
214 if (text == NULL || text[0] == '\0')
215 anjuta_entry_set_mode (self, ANJUTA_ENTRY_HELP);
217 return GTK_WIDGET_CLASS (anjuta_entry_parent_class)->focus_out_event (widget, event);
220 static void
221 anjuta_entry_class_init (AnjutaEntryClass *klass)
223 GObjectClass* object_class = G_OBJECT_CLASS (klass);
224 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
226 object_class->finalize = anjuta_entry_finalize;
227 object_class->set_property = anjuta_entry_set_property;
228 object_class->get_property = anjuta_entry_get_property;
229 widget_class->focus_in_event = anjuta_entry_focus_in_event;
230 widget_class->focus_out_event = anjuta_entry_focus_out_event;
233 * AnjutaEntry::help-text:
235 * Text that should be displayed when the entry is empty. This text should
236 * briefly describe what the user should enter.
238 g_object_class_install_property (object_class,
239 PROP_HELP_TEXT,
240 g_param_spec_string ("help-text",
241 _("Help text"),
242 _("Text to show the user what to enter into the entry"),
244 G_PARAM_READABLE | G_PARAM_WRITABLE));
248 * anjuta_entry_new:
250 * Creates a new AnjutaEntry.
252 GtkWidget *
253 anjuta_entry_new (void)
255 return g_object_new (ANJUTA_TYPE_ENTRY, NULL);
259 * anjuta_entry_get_text:
260 * @self: An AnjutaEntry
262 * Returns the contents of the entry. If the entry is empty, the help text will
263 * be displayed and an empty string will be returned.
265 const gchar *
266 anjuta_entry_get_text (AnjutaEntry *self)
268 return (self->priv->showing_help_text) ?
269 "" : gtk_entry_get_text (GTK_ENTRY (self)) ;
273 * anjuta_entry_dup_text:
274 * @self: An AnjutaEntry
276 * Returns a copy of the contents of the entry. If the entry is empty, the
277 * returned string will be empty. The returned string must be freed when no
278 * longer needed.
280 gchar *
281 anjuta_entry_dup_text (AnjutaEntry *self)
283 return g_strdup (anjuta_entry_get_text (self));
287 * anjuta_entry_set_text:
288 * @self: An AnjutaEntry
289 * @text: The new text
291 * Sets the text on the entry, showing the help text if the text is empty.
293 void
294 anjuta_entry_set_text (AnjutaEntry *self, const gchar *text)
296 if (text != NULL && text[0] != '\0')
297 anjuta_entry_set_mode (self, ANJUTA_ENTRY_NORMAL);
298 else
299 anjuta_entry_set_mode (self, ANJUTA_ENTRY_HELP);
301 gtk_entry_set_text (GTK_ENTRY (self), text);
305 * anjuta_entry_is_showing_help_text:
306 * @self: An AnjutaEntry
308 * Returns whether the entry is showing its help text. In practice, if this
309 * method returns %TRUE, it means that the user has not entered anything.
311 gboolean
312 anjuta_entry_is_showing_help_text (AnjutaEntry *self)
314 return self->priv->showing_help_text;