1 /** \file uitapecreate.c
2 * \brief Gtk3 dialog to create and attach a new tape image
3 *
4 * \author Bas Wassink <b.wassink@ziggo.nl>
5 */
6
7 /*
8 * This file is part of VICE, the Versatile Commodore Emulator.
9 * See README for copyright notice.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program 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
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 * 02111-1307 USA.
25 */
26
27 #include "vice.h"
28 #include <gtk/gtk.h>
29 #include <string.h>
30
31 #include "basewidgets.h"
32 #include "basedialogs.h"
33 #include "debug_gtk3.h"
34 #include "widgethelpers.h"
35 #include "filechooserhelpers.h"
36 #include "util.h"
37 #include "lib.h"
38 #include "attach.h"
39 #include "diskimage.h" /* for DISK_IMAGE_TYPE_TAP*/
40 #include "cbmimage.h"
41 #include "resources.h"
42 #include "tape.h"
43 #include "ui.h"
44
45 #include "uitapecreate.h"
46
47
48 /* forward declarations of functions */
49 static gboolean create_tape_image(const char *filename);
50
51
52 /** \brief Reference to the 'auto-attach' check button
53 */
54 static GtkWidget *auto_attach = NULL;
55
56
57 /** \brief Handler for 'response' event of the dialog
58 *
59 * This handler is called when the user clicks a button in the dialog.
60 *
61 * \param[in] widget the dialog
62 * \param[in] response_id response ID
63 * \param[in] data extra data (unused)
64 */
on_response(GtkWidget * widget,gint response_id,gpointer data)65 static void on_response(GtkWidget *widget, gint response_id, gpointer data)
66 {
67 gchar *filename;
68 int status = TRUE;
69
70 switch (response_id) {
71
72 case GTK_RESPONSE_ACCEPT:
73 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget));
74 if (filename != NULL) {
75 /* create tape */
76 status = create_tape_image(filename);
77 }
78 g_free(filename);
79 if (status) {
80 /* image creation and attaching was succesful, exit dialog */
81 gtk_widget_destroy(widget);
82 }
83 break;
84
85 case GTK_RESPONSE_REJECT:
86 gtk_widget_destroy(widget);
87 break;
88 default:
89 debug_gtk3("warning: unhandled response ID %d\n", response_id);
90 break;
91 }
92 }
93
94
95 /** \brief Actually create the tape image and attach it
96 *
97 * \param[in] filename filename of the new image
98 *
99 * \return bool
100 */
create_tape_image(const char * filename)101 static gboolean create_tape_image(const char *filename)
102 {
103 gboolean status = TRUE;
104 char *fname_copy;
105
106 /* fix extension */
107 fname_copy = util_add_extension_const(filename, "tap");
108
109 /* try to create the image */
110 if (cbmimage_create_image(fname_copy, DISK_IMAGE_TYPE_TAP) < 0) {
111 vice_gtk3_message_error("VICE error",
112 "Failed to create tape image '%s'", fname_copy);
113 status = FALSE;
114 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_attach))) {
115 /* try to attach the image */
116 if (tape_image_attach(1, fname_copy) < 0) {
117 vice_gtk3_message_error("VICE error",
118 "Failed to attach tape image '%s'", fname_copy);
119 status = FALSE;
120 }
121 }
122
123 lib_free(fname_copy);
124 return status;
125 }
126
127
128 /** \brief Create the 'extra' widget for the dialog
129 *
130 * \return GtkGrid
131 */
create_extra_widget(void)132 static GtkWidget *create_extra_widget(void)
133 {
134 GtkWidget *grid;
135
136 /* create a grid with some spacing and margins */
137 grid = vice_gtk3_grid_new_spaced(VICE_GTK3_DEFAULT, VICE_GTK3_DEFAULT);
138 g_object_set(grid, "margin-left", 16, "margin-right", 16, NULL);
139
140 auto_attach = gtk_check_button_new_with_label("Auto-attach tape image");
141 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(auto_attach), TRUE);
142 gtk_grid_attach(GTK_GRID(grid), auto_attach, 0, 0, 1, 1);
143
144 gtk_widget_show_all(grid);
145 return grid;
146 }
147
148
149 /** \brief Create and show 'attach new tape image' dialog
150 *
151 * \param[in] parent parent widget (ignored)
152 * \param[in] data extra data (ignored)
153 *
154 */
uitapecreate_dialog_show(GtkWidget * parent,gpointer data)155 void uitapecreate_dialog_show(GtkWidget *parent, gpointer data)
156 {
157 GtkWidget *dialog;
158 GtkFileFilter *filter;
159
160 dialog = gtk_file_chooser_dialog_new(
161 "Create and attach a new tape image",
162 ui_get_active_window(),
163 GTK_FILE_CHOOSER_ACTION_SAVE,
164 /* buttons */
165 "Save", GTK_RESPONSE_ACCEPT,
166 "Close", GTK_RESPONSE_REJECT,
167 NULL, NULL);
168
169 gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog),
170 TRUE);
171
172 gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dialog),
173 create_extra_widget());
174
175 filter = gtk_file_filter_new();
176 gtk_file_filter_set_name(filter, "Tape images (*.tap)");
177 gtk_file_filter_add_pattern(filter, "*.tap");
178 gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
179
180 g_signal_connect(dialog, "response", G_CALLBACK(on_response), NULL);
181
182 gtk_widget_show(dialog);
183 }
184