mp3splt-gtk
drag_and_drop.c
1 /**********************************************************
2  *
3  * mp3splt-gtk -- utility based on mp3splt,
4  * for mp3/ogg splitting without decoding
5  *
6  * Copyright: (C) 2005-2012 Alexandru Munteanu
7  * Contact: m@ioalex.net
8  *
9  * http://mp3splt.sourceforge.net/
10  *
11  *********************************************************/
12 /**********************************************************
13  *
14  * This program is free software; you can redistribute it and/or
15 
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
28  * USA.
29  *
30  *********************************************************/
31 
32 #include "drag_and_drop.h"
33 
34 static void dnd_data_received(GtkWidget *window, GdkDragContext *drag_context,
35  gint x, gint y, GtkSelectionData *data, guint info, guint time,
36  gboolean discard_data_files, gboolean discard_audio_files,
37  gboolean single_file_mode, ui_state *ui);
38 
39 static void dnd_data_received_data_files(GtkWidget *window,
40  GdkDragContext *drag_context, gint x, gint y, GtkSelectionData *data, guint info,
41  guint time, ui_state *ui)
42 {
43  dnd_data_received(window, drag_context, x, y, data, info, time, FALSE, TRUE, TRUE, ui);
44 }
45 
46 static void dnd_data_received_batch_mode_audio_files(GtkWidget *window,
47  GdkDragContext *drag_context, gint x, gint y, GtkSelectionData *data, guint info,
48  guint time, ui_state *ui)
49 {
50  dnd_data_received(window, drag_context, x, y, data, info, time, TRUE, FALSE, FALSE, ui);
51 }
52 
53 static void dnd_data_received_single_mode_audio_files(GtkWidget *window,
54  GdkDragContext *drag_context, gint x, gint y, GtkSelectionData *data, guint info,
55  guint time, ui_state *ui)
56 {
57  dnd_data_received(window, drag_context, x, y, data, info, time, TRUE, FALSE, TRUE, ui);
58 }
59 
60 static void dnd_data_received_single_mode_audio_and_data_files(GtkWidget *window,
61  GdkDragContext *drag_context, gint x, gint y, GtkSelectionData *data, guint info,
62  guint time, ui_state *ui)
63 {
64  dnd_data_received(window, drag_context, x, y, data, info, time, FALSE, FALSE, TRUE, ui);
65 }
66 
67 void dnd_add_drag_data_received_to_widget(GtkWidget *widget, drop_type type, ui_state *ui)
68 {
69  gtk_drag_dest_set(widget, GTK_DEST_DEFAULT_ALL, drop_types, 3,
70  GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
71 
72  switch (type)
73  {
74  case DND_SINGLE_MODE_AUDIO_FILE:
75  g_signal_connect(G_OBJECT(widget), "drag-data-received",
76  G_CALLBACK(dnd_data_received_single_mode_audio_files), ui);
77  break;
78  case DND_BATCH_MODE_AUDIO_FILES:
79  g_signal_connect(G_OBJECT(widget), "drag-data-received",
80  G_CALLBACK(dnd_data_received_batch_mode_audio_files), ui);
81  break;
82  case DND_DATA_FILES:
83  g_signal_connect(G_OBJECT(widget), "drag-data-received",
84  G_CALLBACK(dnd_data_received_data_files), ui);
85  break;
86  case DND_SINGLE_MODE_AUDIO_FILE_AND_DATA_FILES:
87  g_signal_connect(G_OBJECT(widget), "drag-data-received",
88  G_CALLBACK(dnd_data_received_single_mode_audio_and_data_files), ui);
89  break;
90  default:
91  break;
92  }
93 }
94 
95 static void dnd_data_received(GtkWidget *window, GdkDragContext *drag_context,
96  gint x, gint y, GtkSelectionData *data, guint info, guint time,
97  gboolean discard_data_files, gboolean discard_audio_files,
98  gboolean single_file_mode, ui_state *ui)
99 {
100  gchar **drop_filenames = gtk_selection_data_get_uris(data);
101  if (drop_filenames == NULL)
102  {
103  const gchar *received_data = (gchar *)gtk_selection_data_get_text(data);
104  if (received_data == NULL)
105  {
106  return;
107  }
108 
109  drop_filenames = g_strsplit(received_data, "\n", 0);
110  }
111 
112  GSList *filenames = NULL;
113 
114  gint current_index = 0;
115  gchar *current_filename = drop_filenames[current_index];
116  while (current_filename != NULL)
117  {
118  gchar *filename = NULL;
119  if (strstr(current_filename, "file:") == current_filename)
120  {
121  filename = g_filename_from_uri(current_filename, NULL, NULL);
122  }
123  else
124  {
125  filename = g_strdup(current_filename);
126  }
127 
129 
130  if (file_exists(filename))
131  {
132  gchar *ext = strrchr(filename, '.');
133  GString *ext_str = g_string_new(ext);
134  g_string_ascii_up(ext_str);
135  if ((strstr(ext_str->str, ".MP3") != NULL) ||
136  (strstr(ext_str->str, ".OGG") != NULL))
137  {
138  filenames = g_slist_append(filenames, filename);
139  }
140  else if (!discard_data_files)
141  {
142  import_file(filename, ui);
143  }
144  g_string_free(ext_str, FALSE);
145  }
146  else if (directory_exists(filename) && !single_file_mode)
147  {
148  filenames = g_slist_append(filenames, filename);
149  }
150  else
151  {
152  g_free(filename);
153  }
154 
155  current_index++;
156  current_filename = drop_filenames[current_index];
157  }
158  g_strfreev(drop_filenames);
159 
160  if (filenames == NULL)
161  {
162  return;
163  }
164 
165  if (g_slist_length(filenames) == 0)
166  {
167  g_slist_free(filenames);
168  return;
169  }
170 
171  if (discard_audio_files)
172  {
173  g_slist_foreach(filenames, (GFunc)g_free, NULL);
174  g_slist_free(filenames);
175 
176  return;
177  }
178 
179  if (single_file_mode)
180  {
181  GSList *last_filename = g_slist_last(filenames);
182  import_file(last_filename->data, ui);
183 
184  g_slist_foreach(filenames, (GFunc)g_free, NULL);
185  g_slist_free(filenames);
186  }
187  else
188  {
189  import_files_to_batch_and_free(filenames, ui);
190  }
191 }
192