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