hythmbox-2.98/widgets/rb-uri-dialog.c

No issues found

  1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  2  *
  3  *  Copyright (C) 2005 Renato Araujo Oliveira Filho - INdT <renato.filho@indt.org.br>
  4  *
  5  *  This program is free software; you can redistribute it and/or modify
  6  *  it under the terms of the GNU General Public License as published by
  7  *  the Free Software Foundation; either version 2 of the License, or
  8  *  (at your option) any later version.
  9  *
 10  *  The Rhythmbox authors hereby grant permission for non-GPL compatible
 11  *  GStreamer plugins to be used and distributed together with GStreamer
 12  *  and Rhythmbox. This permission is above and beyond the permissions granted
 13  *  by the GPL license by which Rhythmbox is covered. If you modify this code
 14  *  you may extend this exception to your version of the code, but you are not
 15  *  obligated to do so. If you do not wish to do so, delete this exception
 16  *  statement from your version.
 17  *
 18  *  This program is distributed in the hope that it will be useful,
 19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 21  *  GNU General Public License for more details.
 22  *
 23  *  You should have received a copy of the GNU General Public License
 24  *  along with this program; if not, write to the Free Software
 25  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 26  *
 27  */
 28 
 29 #include "config.h"
 30 
 31 #include <string.h>
 32 #include <time.h>
 33 
 34 #include <glib/gi18n.h>
 35 #include <gtk/gtk.h>
 36 #include <libsoup/soup.h>
 37 
 38 #include "rb-uri-dialog.h"
 39 #include "rb-builder-helpers.h"
 40 #include "rb-dialog.h"
 41 #include "rb-debug.h"
 42 
 43 /**
 44  * SECTION:rb-uri-dialog
 45  * @short_description: simple URI entry dialog
 46  * @include: rb-uri-dialog.h
 47  *
 48  * A simple dialog used to request a single URI from the user.
 49  */
 50 
 51 static void rb_uri_dialog_class_init (RBURIDialogClass *klass);
 52 static void rb_uri_dialog_init (RBURIDialog *dialog);
 53 static void rb_uri_dialog_response_cb (GtkDialog *gtkdialog,
 54 				       int response_id,
 55 				       RBURIDialog *dialog);
 56 static void rb_uri_dialog_text_changed (GtkEditable *buffer,
 57 					RBURIDialog *dialog);
 58 static void rb_uri_dialog_set_property (GObject *object,
 59 					guint prop_id,
 60 					const GValue *value,
 61 					GParamSpec *pspec);
 62 static void rb_uri_dialog_get_property (GObject *object,
 63 					guint prop_id,
 64 					GValue *value,
 65 					GParamSpec *pspec);
 66 static void rb_uri_dialog_clipboard_yank_url (GtkClipboard *clipboard,
 67 					      const char *text,
 68 					      gpointer data);
 69 
 70 struct RBURIDialogPrivate
 71 {
 72 	GtkWidget   *label;
 73 	GtkWidget   *url;
 74 	GtkWidget   *okbutton;
 75 	GtkWidget   *cancelbutton;
 76 };
 77 
 78 #define RB_URI_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_URI_DIALOG, RBURIDialogPrivate))
 79 
 80 enum
 81 {
 82 	LOCATION_ADDED,
 83 	LAST_SIGNAL
 84 };
 85 
 86 enum
 87 {
 88 	PROP_0,
 89 	PROP_LABEL
 90 };
 91 
 92 static guint rb_uri_dialog_signals [LAST_SIGNAL] = { 0 };
 93 
 94 G_DEFINE_TYPE (RBURIDialog, rb_uri_dialog, GTK_TYPE_DIALOG)
 95 
 96 static void
 97 rb_uri_dialog_class_init (RBURIDialogClass *klass)
 98 {
 99 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
100 	
101 	object_class->set_property = rb_uri_dialog_set_property;
102 	object_class->get_property = rb_uri_dialog_get_property;
103 
104 	/**
105 	 * RBURIDialog:label:
106 	 *
107 	 * The label displayed in the dialog.
108 	 */
109 	g_object_class_install_property (object_class,
110 					 PROP_LABEL,
111 					 g_param_spec_string ("label",
112 					                      "label",
113 					                      "label",
114 							      "",
115 					                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
116 
117 	/**
118 	 * RBURIDialog::location-added:
119 	 * @dialog: the #RBURIDialog
120 	 * @uri: URI entered
121 	 *
122 	 * Emitted when the user has entered a URI into the dialog.
123 	 */
124 	rb_uri_dialog_signals [LOCATION_ADDED] =
125 		g_signal_new ("location-added",
126 			      G_OBJECT_CLASS_TYPE (object_class),
127 			      G_SIGNAL_RUN_LAST,
128 			      G_STRUCT_OFFSET (RBURIDialogClass, location_added),
129 			      NULL, NULL,
130 			      g_cclosure_marshal_VOID__STRING,
131 			      G_TYPE_NONE,
132 			      1,
133 			      G_TYPE_STRING);
134 
135 	g_type_class_add_private (klass, sizeof (RBURIDialogPrivate));
136 }
137 
138 static void
139 rb_uri_dialog_init (RBURIDialog *dialog)
140 {
141 	GtkWidget  *content_area;
142 	GtkBuilder *builder;
143 
144 	/* create the dialog and some buttons forward - close */
145 	dialog->priv = RB_URI_DIALOG_GET_PRIVATE (dialog);
146 
147 	g_signal_connect_object (G_OBJECT (dialog),
148 				 "response",
149 				 G_CALLBACK (rb_uri_dialog_response_cb),
150 				 dialog, 0);
151 
152 	content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
153 
154 	gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
155 	gtk_box_set_spacing (GTK_BOX (content_area), 2);
156 
157 	dialog->priv->cancelbutton = gtk_dialog_add_button (GTK_DIALOG (dialog),
158 							    GTK_STOCK_CANCEL,
159 							    GTK_RESPONSE_CANCEL);
160 	dialog->priv->okbutton = gtk_dialog_add_button (GTK_DIALOG (dialog),
161 							GTK_STOCK_ADD,
162 							GTK_RESPONSE_OK);
163 	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
164 
165 	builder = rb_builder_load ("uri-new.ui", dialog);
166 
167 	gtk_container_add (GTK_CONTAINER (content_area),
168 			   GTK_WIDGET (gtk_builder_get_object (builder, "newuri")));
169 
170 	/* get the widgets from the GtkBuilder */
171 	dialog->priv->label = GTK_WIDGET (gtk_builder_get_object (builder, "label"));
172 	dialog->priv->url = GTK_WIDGET (gtk_builder_get_object (builder, "txt_url"));
173 	gtk_entry_set_activates_default (GTK_ENTRY (dialog->priv->url), TRUE);
174 
175 	g_signal_connect_object (G_OBJECT (dialog->priv->url),
176 				 "changed",
177 				 G_CALLBACK (rb_uri_dialog_text_changed),
178 				 dialog, 0);
179 
180 	/* if we can get a url from the clipboard, populate the entry with that,
181 	 * since there's a good chance that's what the user wants to do anyway.
182 	 */
183 	gtk_clipboard_request_text (gtk_clipboard_get(GDK_SELECTION_CLIPBOARD),
184 				    rb_uri_dialog_clipboard_yank_url,
185 				    dialog);
186 	gtk_clipboard_request_text (gtk_clipboard_get(GDK_SELECTION_PRIMARY),
187 				    rb_uri_dialog_clipboard_yank_url,
188 				    dialog);
189 
190 	/* default focus */
191 	gtk_widget_grab_focus (dialog->priv->url);
192 
193 	/* FIXME */
194 	gtk_widget_set_sensitive (dialog->priv->okbutton, FALSE);
195 
196 	g_object_unref (builder);
197 }
198 
199 static void
200 rb_uri_dialog_set_property (GObject *object,
201 			    guint prop_id,
202 			    const GValue *value,
203 			    GParamSpec *pspec)
204 {
205 	RBURIDialog *dialog = RB_URI_DIALOG (object);
206 
207 	switch (prop_id) {
208 	case PROP_LABEL:
209 		gtk_label_set_text (GTK_LABEL (dialog->priv->label), g_value_get_string (value));
210 		break;
211 	default:
212 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
213 		break;
214 	}
215 }
216 
217 static void
218 rb_uri_dialog_get_property (GObject *object,
219 			    guint prop_id,
220 			    GValue *value,
221 			    GParamSpec *pspec)
222 {
223 	RBURIDialog *dialog = RB_URI_DIALOG (object);
224 
225 	switch (prop_id) {
226 	case PROP_LABEL:
227 		g_value_set_string (value, gtk_label_get_text (GTK_LABEL (dialog->priv->label)));
228 		break;
229 	default:
230 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
231 		break;
232 	}
233 }
234 
235 /**
236  * rb_uri_dialog_new:
237  * @title: Window title for the dialog
238  * @label: Label to display in the dialog
239  *
240  * Creates a URI entry dialog.
241  *
242  * Returns: URI dialog instance.
243  */
244 GtkWidget *
245 rb_uri_dialog_new (const char *title, const char *label)
246 {
247 	RBURIDialog *dialog;
248 
249 	dialog = g_object_new (RB_TYPE_URI_DIALOG,
250 			       "title", title,
251 			       "label", label,
252 			       NULL);
253 	return GTK_WIDGET (dialog);
254 }
255 
256 static void
257 rb_uri_dialog_response_cb (GtkDialog *gtkdialog,
258 				   int response_id,
259 				   RBURIDialog *dialog)
260 {
261 	char *valid_url;
262 	char *str;
263 
264 	if (response_id != GTK_RESPONSE_OK)
265 		return;
266 
267 	str = gtk_editable_get_chars (GTK_EDITABLE (dialog->priv->url), 0, -1);
268 	valid_url = g_strstrip (str);
269 
270 	g_signal_emit (dialog, rb_uri_dialog_signals [LOCATION_ADDED], 0, valid_url);
271 
272 	g_free (str);
273 
274 	gtk_widget_hide (GTK_WIDGET (gtkdialog));
275 }
276 
277 static void
278 rb_uri_dialog_text_changed (GtkEditable *buffer,
279 				    RBURIDialog *dialog)
280 {
281 	char *text = gtk_editable_get_chars (buffer, 0, -1);
282 	gboolean has_text = ((text != NULL) && (*text != 0));
283 
284 	g_free (text);
285 
286 	gtk_widget_set_sensitive (dialog->priv->okbutton, has_text);
287 }
288 
289 static void
290 rb_uri_dialog_clipboard_yank_url (GtkClipboard *clipboard, const char *text, gpointer data)
291 {
292 	RBURIDialog *dialog = RB_URI_DIALOG (data);
293 	SoupURI *uri;
294 
295 	if (text == NULL) {
296 		return;
297 	}
298 
299 	uri = soup_uri_new (text);
300 	if (SOUP_URI_VALID_FOR_HTTP (uri)) {
301 		gtk_entry_set_text (GTK_ENTRY (dialog->priv->url),
302 				    soup_uri_to_string (uri, FALSE));
303 		gtk_editable_select_region (GTK_EDITABLE (dialog->priv->url), 0, -1);
304 	}
305 
306 	if (uri != NULL) {
307 		soup_uri_free (uri);
308 	}
309 }