1 /***************************************************************************
2  *
3  *
4  *  Copyright  2008  Philippe Rouquier <brasero-app@wanadoo.fr>
5  *  Copyright  2008  Luis Medinas <lmedinas@gmail.com>
6  *
7  *
8  *  Brasero is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  Brasero is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU Library General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to:
20  * 	The Free Software Foundation, Inc.,
21  * 	51 Franklin Street, Fifth Floor
22  * 	Boston, MA  02110-1301, USA.
23  *
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #  include <config.h>
28 #endif
29 
30 #include <string.h>
31 
32 #include <glib.h>
33 #include <glib/gi18n.h>
34 
35 #include <gtk/gtk.h>
36 
37 #include "brasero-eject-dialog.h"
38 #include "brasero-drive-selection.h"
39 #include "brasero-medium.h"
40 #include "brasero-drive.h"
41 #include "brasero-volume.h"
42 #include "brasero-utils.h"
43 #include "brasero-burn.h"
44 #include "brasero-misc.h"
45 #include "brasero-app.h"
46 
47 typedef struct _BraseroEjectDialogPrivate BraseroEjectDialogPrivate;
48 struct _BraseroEjectDialogPrivate {
49 	GtkWidget *selector;
50 	GtkWidget *eject_button;
51 	gboolean cancelled;
52 };
53 
54 #define BRASERO_EJECT_DIALOG_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_EJECT_DIALOG, BraseroEjectDialogPrivate))
55 
56 G_DEFINE_TYPE (BraseroEjectDialog, brasero_eject_dialog, GTK_TYPE_DIALOG);
57 
58 static void
brasero_eject_dialog_activate(GtkDialog * dialog,GtkResponseType answer)59 brasero_eject_dialog_activate (GtkDialog *dialog,
60 			       GtkResponseType answer)
61 {
62 	BraseroDrive *drive;
63 	GError *error = NULL;
64 	BraseroEjectDialogPrivate *priv;
65 
66 	if (answer != GTK_RESPONSE_OK)
67 		return;
68 
69 	priv = BRASERO_EJECT_DIALOG_PRIVATE (dialog);
70 
71 	gtk_widget_set_sensitive (GTK_WIDGET (priv->selector), FALSE);
72 	gtk_widget_set_sensitive (priv->eject_button, FALSE);
73 
74 	/* In here we could also remove the lock held by any app (including
75 	 * brasero) through brasero_drive_unlock. We'd need a warning
76 	 * dialog though which would identify why the lock is held and even
77 	 * better which application is holding the lock so the user does know
78 	 * if he can take the risk to remove the lock. */
79 
80 	/* NOTE 2: we'd need also the ability to reset the drive through a SCSI
81 	 * command. The problem is brasero may need to be privileged then as
82 	 * cdrecord/cdrdao seem to be. */
83 	drive = brasero_drive_selection_get_active (BRASERO_DRIVE_SELECTION (priv->selector));
84 	brasero_drive_unlock (drive);
85 
86 	/*if (brasero_volume_is_mounted (BRASERO_VOLUME (medium))
87 	&& !brasero_volume_umount (BRASERO_VOLUME (medium), TRUE, &error)) {
88 		BRASERO_BURN_LOG ("Error unlocking medium: %s", error?error->message:"Unknown error");
89 		return TRUE;
90 	}*/
91 	if (!brasero_drive_eject (drive, TRUE, &error)) {
92 		gchar *string;
93 		gchar *display_name;
94 
95 		if (!priv->cancelled || error) {
96 			display_name = brasero_drive_get_display_name (drive);
97 			string = g_strdup_printf (_("The disc in \"%s\" cannot be ejected"), display_name);
98 			g_free (display_name);
99 
100 			brasero_app_alert (brasero_app_get_default (),
101 			                   string,
102 			                   error?error->message:_("An unknown error occurred"),
103 			                   GTK_MESSAGE_ERROR);
104 
105 			g_free (string);
106 		}
107 
108 		g_clear_error (&error);
109 	}
110 
111 	g_object_unref (drive);
112 }
113 
114 gboolean
brasero_eject_dialog_cancel(BraseroEjectDialog * dialog)115 brasero_eject_dialog_cancel (BraseroEjectDialog *dialog)
116 {
117 	BraseroEjectDialogPrivate *priv;
118 	BraseroDrive *drive;
119 
120 	priv = BRASERO_EJECT_DIALOG_PRIVATE (dialog);
121 	drive = brasero_drive_selection_get_active (BRASERO_DRIVE_SELECTION (priv->selector));
122 
123 	if (drive) {
124 		priv->cancelled = TRUE;
125 		brasero_drive_cancel_current_operation (drive);
126 		g_object_unref (drive);
127 	}
128 
129 	return TRUE;
130 }
131 
132 static void
brasero_eject_dialog_cancel_cb(GtkWidget * button_cancel,BraseroEjectDialog * dialog)133 brasero_eject_dialog_cancel_cb (GtkWidget *button_cancel,
134                                 BraseroEjectDialog *dialog)
135 {
136 	brasero_eject_dialog_cancel (dialog);
137 }
138 
139 static void
brasero_eject_dialog_class_init(BraseroEjectDialogClass * klass)140 brasero_eject_dialog_class_init (BraseroEjectDialogClass *klass)
141 {
142 	GtkDialogClass *dialog_class = GTK_DIALOG_CLASS (klass);
143 
144 	g_type_class_add_private (klass, sizeof (BraseroEjectDialogPrivate));
145 
146 	dialog_class->response = brasero_eject_dialog_activate;
147 }
148 
149 static void
brasero_eject_dialog_init(BraseroEjectDialog * obj)150 brasero_eject_dialog_init (BraseroEjectDialog *obj)
151 {
152 	gchar *title_str;
153 	GtkWidget *box;
154 	GtkWidget *hbox;
155 	GtkWidget *label;
156 	GtkWidget *button;
157 	BraseroEjectDialogPrivate *priv;
158 
159 	priv = BRASERO_EJECT_DIALOG_PRIVATE (obj);
160 	priv->cancelled = FALSE;
161 
162 	box = gtk_dialog_get_content_area (GTK_DIALOG (obj));
163 
164 	priv->selector = brasero_drive_selection_new ();
165 	gtk_widget_show (GTK_WIDGET (priv->selector));
166 
167 	title_str = g_strdup (_("Select a disc"));
168 
169 	label = gtk_label_new (title_str);
170 	gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
171 	gtk_widget_show (label);
172 
173 	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
174 	gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
175 	gtk_widget_show (hbox);
176 	gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, TRUE, 0);
177 
178 	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
179 	gtk_box_pack_start (GTK_BOX (hbox), priv->selector, FALSE, TRUE, 0);
180 	g_free (title_str);
181 
182 	brasero_drive_selection_show_type (BRASERO_DRIVE_SELECTION (priv->selector),
183 	                                   BRASERO_DRIVE_TYPE_ALL_BUT_FILE);
184 
185 	button = gtk_dialog_add_button (GTK_DIALOG (obj),
186 	                                GTK_STOCK_CANCEL,
187 	                                GTK_RESPONSE_CANCEL);
188 	g_signal_connect (button,
189 	                  "clicked",
190 	                  G_CALLBACK (brasero_eject_dialog_cancel_cb),
191 	                  obj);
192 
193 	button = brasero_utils_make_button (_("_Eject"),
194 					    NULL,
195 					    "media-eject",
196 					    GTK_ICON_SIZE_BUTTON);
197 	gtk_dialog_add_action_widget (GTK_DIALOG (obj),
198 	                              button,
199 	                              GTK_RESPONSE_OK);
200 	gtk_widget_show (button);
201 	priv->eject_button = button;
202 }
203 
204 GtkWidget *
brasero_eject_dialog_new()205 brasero_eject_dialog_new ()
206 {
207 	return g_object_new (BRASERO_TYPE_EJECT_DIALOG,
208 			     "title", (_("Eject Disc")),
209 			     NULL);
210 }
211 
212