Fix sndfile pkg-config name and SYSLIBS.
[ardour.git] / gtk2_ardour / editor_audio_import.cc
1 /*
2     Copyright (C) 2000-2006 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <sys/time.h>
23 #include <errno.h>
24 #include <unistd.h>
25 #include <algorithm>
26
27 #include <sndfile.h>
28
29 #include <pbd/pthread_utils.h>
30 #include <pbd/basename.h>
31 #include <pbd/shortpath.h>
32
33 #include <gtkmm2ext/choice.h>
34 #include <gtkmm2ext/window_title.h>
35
36 #include <ardour/session.h>
37 #include <ardour/session_directory.h>
38 #include <ardour/audioplaylist.h>
39 #include <ardour/audioregion.h>
40 #include <ardour/audio_diskstream.h>
41 #include <ardour/midi_track.h>
42 #include <ardour/midi_region.h>
43 #include <ardour/utils.h>
44 #include <ardour/audio_track.h>
45 #include <ardour/audioplaylist.h>
46 #include <ardour/audiofilesource.h>
47 #include <ardour/region_factory.h>
48 #include <ardour/source_factory.h>
49 #include <ardour/session.h>
50 #include <pbd/memento_command.h>
51
52 #include "ardour_ui.h"
53 #include "editor.h"
54 #include "sfdb_ui.h"
55 #include "editing.h"
56 #include "audio_time_axis.h"
57 #include "midi_time_axis.h"
58 #include "utils.h"
59
60 #include "i18n.h"
61
62 using namespace std;
63 using namespace ARDOUR;
64 using namespace PBD;
65 using namespace sigc;
66 using namespace Gtk;
67 using namespace Gtkmm2ext;
68 using namespace Editing;
69 using Glib::ustring;
70
71 /* Functions supporting the incorporation of external (non-captured) audio material into ardour */
72
73 void
74 Editor::add_external_audio_action (ImportMode mode_hint)
75 {
76         if (session == 0) {
77                 MessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded."));
78                 msg.run ();
79                 return;
80         }
81         
82         if (sfbrowser == 0) {
83                 sfbrowser = new SoundFileOmega (*this, _("Add existing media"), session, 0, true, mode_hint);
84         } else {
85                 sfbrowser->set_mode (mode_hint);
86         }
87
88         external_audio_dialog ();
89 }
90
91 void
92 Editor::external_audio_dialog ()
93 {
94         vector<Glib::ustring> paths;
95         uint32_t track_cnt;
96
97         if (session == 0) {
98                 MessageDialog msg (_("You can't import or embed an audiofile until you have a session loaded."));
99                 msg.run ();
100                 return;
101         }
102         
103         track_cnt = 0;
104
105         for (TrackSelection::iterator x = selection->tracks.begin(); x != selection->tracks.end(); ++x) {
106                 AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(*x);
107                 
108                 if (!atv) {
109                         continue;
110                 } else if (atv->is_audio_track()) {
111                         track_cnt++;
112                 }
113         }
114
115         if (sfbrowser == 0) {
116                 sfbrowser = new SoundFileOmega (*this, _("Add existing media"), session, track_cnt, true);
117         } else {
118                 sfbrowser->reset (track_cnt);
119         }
120
121         sfbrowser->show_all ();
122
123
124         bool keepRunning;
125
126         do {
127                 keepRunning = false;
128
129                 int response = sfbrowser->run ();
130
131                 switch (response) {
132                         case RESPONSE_APPLY:
133                                 // leave the dialog open
134                                 break;
135
136                         case RESPONSE_OK:
137                                 sfbrowser->hide ();
138                                 break;
139
140                         default:
141                                 // cancel from the browser - we are done
142                                 sfbrowser->hide ();
143                                 return;
144                 }
145
146                 /* lets do it */
147
148                 paths = sfbrowser->get_paths ();
149
150                 ImportPosition pos = sfbrowser->get_position ();
151                 ImportMode mode = sfbrowser->get_mode ();
152                 ImportDisposition chns = sfbrowser->get_channel_disposition ();
153                 nframes64_t where;
154
155                 switch (pos) {
156                         case ImportAtEditPoint:
157                                 where = get_preferred_edit_position ();
158                                 break;
159                         case ImportAtTimestamp:
160                                 where = -1;
161                                 break;
162                         case ImportAtPlayhead:
163                                 where = playhead_cursor->current_frame;
164                                 break;
165                         case ImportAtStart:
166                                 where = session->current_start_frame();
167                                 break;
168                 }
169
170                 SrcQuality quality = sfbrowser->get_src_quality();
171
172
173                 if (sfbrowser->copy_files_btn.get_active()) {
174                         do_import (paths, chns, mode, quality, where);
175                 } else {
176                         do_embed (paths, chns, mode, where);
177                 }
178
179                 if (response == RESPONSE_APPLY) {
180                         sfbrowser->clear_selection ();
181                         keepRunning = true;
182                 }
183
184         } while (keepRunning);
185 }
186
187 typedef std::map<PBD::ID,boost::shared_ptr<ARDOUR::Source> > SourceMap;
188
189 /**
190  * Updating is still disabled, see note in libs/ardour/import.cc Session::import_audiofiles()
191  *
192  * all_or_nothing:
193  *   true  = show "Update", "Import" and "Skip"
194  *   false = show "Import", and "Cancel"
195  *
196  * Returns:
197  *     0  To update an existing source of the same name
198  *     1  To import/embed the file normally (make sure the new name will be unique)
199  *     2  If the user wants to skip this file
200  **/
201 int
202 Editor::check_whether_and_how_to_import(string path, bool all_or_nothing)
203 {
204         string wave_name (Glib::path_get_basename(path));
205
206         SourceMap all_sources = session->get_sources();
207         bool wave_name_exists = false;
208
209         for (SourceMap::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
210                 string tmp (Glib::path_get_basename (i->second->path()));
211
212                 if (tmp == wave_name) {
213                         wave_name_exists = true;
214                         break;
215                 }
216         }
217
218         int function = 1;
219
220
221         if (wave_name_exists) {
222                 string message;
223                 if (all_or_nothing) {
224                         // updating is still disabled
225                         //message = string_compose(_("The session already contains a source file named %1. Do you want to update that file (and thus all regions using the file) or import this file as a new file?"),wave_name);
226                         message = string_compose(_("The session already contains a source file named %1. This file will be imported as a new file, please confirm."),wave_name);
227                 } else {
228                         message = string_compose(_("A source file %1 already exists. This operation will not update that source but import the file %2 as a new source, please confirm."), wave_name, wave_name);
229
230                 }
231                 MessageDialog dialog(message, false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_NONE, true);
232
233                 if (all_or_nothing) {
234                         // disabled
235                         //dialog.add_button("Update", 0);
236                         dialog.add_button("Import", 1);
237                         dialog.add_button("Skip",   2);
238                 } else {
239                         dialog.add_button("Import", 1);
240                         dialog.add_button("Cancel", 2);
241                 }
242                 
243                 
244                 //dialog.add_button("Skip all", 4); // All or rest?
245
246                 dialog.show();
247
248                 function = dialog.run ();
249
250                 dialog.hide();
251         }
252
253         return function;
254 }
255
256 boost::shared_ptr<AudioTrack>
257 Editor::get_nth_selected_audio_track (int nth) const
258 {
259         AudioTimeAxisView* atv;
260         TrackSelection::iterator x;
261         
262         for (x = selection->tracks.begin(); nth > 0 && x != selection->tracks.end(); ++x) {
263
264                 atv = dynamic_cast<AudioTimeAxisView*>(*x);
265                 
266                 if (!atv) {
267                         continue;
268                 } else if (atv->is_audio_track()) {
269                         --nth;
270                 }
271         }
272         
273         if (x == selection->tracks.end()) {
274                 atv = dynamic_cast<AudioTimeAxisView*>(selection->tracks.back());
275         } else {
276                 atv = dynamic_cast<AudioTimeAxisView*>(*x);
277         }
278         
279         if (!atv || !atv->is_audio_track()) {
280                 return boost::shared_ptr<AudioTrack>();
281         }
282         
283         return atv->audio_track();
284 }       
285
286 boost::shared_ptr<MidiTrack>
287 Editor::get_nth_selected_midi_track (int nth) const
288 {
289         MidiTimeAxisView* mtv;
290         TrackSelection::iterator x;
291         
292         for (x = selection->tracks.begin(); nth > 0 && x != selection->tracks.end(); ++x) {
293
294                 mtv = dynamic_cast<MidiTimeAxisView*>(*x);
295                 
296                 if (!mtv) {
297                         continue;
298                 } else if (mtv->is_midi_track()) {
299                         --nth;
300                 }
301         }
302         
303         if (x == selection->tracks.end()) {
304                 mtv = dynamic_cast<MidiTimeAxisView*>(selection->tracks.back());
305         } else {
306                 mtv = dynamic_cast<MidiTimeAxisView*>(*x);
307         }
308         
309         if (!mtv || !mtv->is_midi_track()) {
310                 return boost::shared_ptr<MidiTrack>();
311         }
312         
313         return mtv->midi_track();
314 }       
315
316 bool
317 Editor::idle_do_import (vector<ustring> paths, ImportDisposition chns, ImportMode mode, SrcQuality quality, nframes64_t& pos)
318 {
319         _do_import (paths, chns, mode, quality, pos);
320         return false;
321 }
322
323 void
324 Editor::do_import (vector<ustring> paths, ImportDisposition chns, ImportMode mode, SrcQuality quality, nframes64_t& pos)
325 {
326 #ifdef GTKOSX
327         Glib::signal_idle().connect (bind (mem_fun (*this, &Editor::idle_do_import), paths, chns, mode, quality, pos));
328 #else
329         _do_import (paths, chns, mode, quality, pos);
330 #endif
331 }
332
333 void
334 Editor::_do_import (vector<ustring> paths, ImportDisposition chns, ImportMode mode, SrcQuality quality, nframes64_t& pos)
335 {
336         boost::shared_ptr<Track> track;
337         vector<ustring> to_import;
338         bool ok = true;
339         int nth = 0;
340
341         if (interthread_progress_window == 0) {
342                 build_interthread_progress_window ();
343         }
344
345         if (chns == Editing::ImportMergeFiles) {
346                 /* create 1 region from all paths, add to 1 track,
347                    ignore "track"
348                 */
349                 bool cancel = false;
350                 for (vector<ustring>::iterator a = paths.begin(); a != paths.end() && ok; ++a) {
351                         int check = check_whether_and_how_to_import(*a, false);
352                         if (check == 2) {
353                                 cancel = true;
354                                 break;
355                         }
356                 }
357
358                 if (!cancel) {
359                         if (import_sndfiles (paths, mode, quality, pos, 1, 1, track, false)) {
360                                 ok = false;
361                         }
362                 }
363
364         } else {
365                 bool replace = false;
366
367                 for (vector<ustring>::iterator a = paths.begin(); a != paths.end() && ok; ++a) {
368
369                         int check = check_whether_and_how_to_import(*a, true);
370
371                         if (check == 2 ) { 
372                                 // skip
373                                 continue;
374                         }
375
376                         if (check == 0) {
377                                 fatal << "Updating existing sources should be disabled!" << endl;
378                                 replace = true;
379                         } else if (check == 1) {
380                                 replace = false;
381                         }
382                         
383
384                         switch (chns) {
385                                 case Editing::ImportDistinctFiles:
386
387                                         to_import.clear ();
388                                         to_import.push_back (*a);
389
390                                         if (mode == Editing::ImportToTrack) {
391                                                 track = get_nth_selected_audio_track (nth++);
392                                         }
393
394                                         if (import_sndfiles (to_import, mode, quality, pos, 1, -1, track, replace)) {
395                                                 ok = false;
396                                         }
397
398                                         break;
399
400                                 case Editing::ImportDistinctChannels:
401
402                                         to_import.clear ();
403                                         to_import.push_back (*a);
404
405                                         if (import_sndfiles (to_import, mode, quality, pos, -1, -1, track, replace)) {
406                                                 ok = false;
407                                         }
408
409                                         break;
410
411                                 case Editing::ImportSerializeFiles:
412
413                                         to_import.clear ();
414                                         to_import.push_back (*a);
415
416                                         /* create 1 region from this path, add to 1 track,
417                                            reuse "track" across paths
418                                            */
419
420                                         if (import_sndfiles (to_import, mode, quality, pos, 1, 1, track, replace)) {
421                                                 ok = false;
422                                         }
423
424                                         break;
425
426                                 case Editing::ImportMergeFiles:
427                                         // Not entered
428                                         break;
429                         }
430                 }
431
432                 if (ok) {
433                         session->save_state ("");
434                 }
435
436                 interthread_progress_window->hide_all ();
437         }
438 }
439
440 bool
441 Editor::idle_do_embed (vector<ustring> paths, ImportDisposition chns, ImportMode mode, nframes64_t& pos)
442 {
443         _do_embed (paths, chns, mode, pos);
444         return false;
445 }
446
447 void
448 Editor::do_embed (vector<ustring> paths, ImportDisposition chns, ImportMode mode, nframes64_t& pos)
449 {
450 #ifdef GTKOSX
451         Glib::signal_idle().connect (bind (mem_fun (*this, &Editor::idle_do_embed), paths, chns, mode, pos));
452 #else
453         _do_embed (paths, chns, mode, pos);
454 #endif
455 }
456
457 void
458 Editor::_do_embed (vector<ustring> paths, ImportDisposition chns, ImportMode mode, nframes64_t& pos)
459 {
460         boost::shared_ptr<Track> track;
461         bool check_sample_rate = true;
462         bool ok = false;
463         vector<ustring> to_embed;
464         bool multi = paths.size() > 1;
465         int nth = 0;
466
467         switch (chns) {
468         case Editing::ImportDistinctFiles:
469                 for (vector<ustring>::iterator a = paths.begin(); a != paths.end(); ++a) {
470
471                         to_embed.clear ();
472                         to_embed.push_back (*a);
473
474                         if (mode == Editing::ImportToTrack) {
475                                 track = get_nth_selected_audio_track (nth++);
476                         }
477
478                         if (embed_sndfiles (to_embed, multi, check_sample_rate, mode, pos, 1, -1, track) < -1) {
479                                 goto out;
480                         }
481                 }
482                 break;
483                 
484         case Editing::ImportDistinctChannels:
485                 for (vector<ustring>::iterator a = paths.begin(); a != paths.end(); ++a) {
486
487                         to_embed.clear ();
488                         to_embed.push_back (*a);
489
490                         if (embed_sndfiles (to_embed, multi, check_sample_rate, mode, pos, -1, -1, track) < -1) {
491                                 goto out;
492                         }
493                 }
494                 break;
495
496         case Editing::ImportMergeFiles:
497                 if (embed_sndfiles (paths, multi, check_sample_rate, mode, pos, 1, 1, track) < -1) {
498                         goto out;
499                 }
500         break;
501
502         case Editing::ImportSerializeFiles:
503                 for (vector<ustring>::iterator a = paths.begin(); a != paths.end(); ++a) {
504
505                         to_embed.clear ();
506                         to_embed.push_back (*a);
507
508                         if (embed_sndfiles (to_embed, multi, check_sample_rate, mode, pos, 1, 1, track) < -1) {
509                                 goto out;
510                         }
511                 }
512                 break;
513         }
514
515         ok = true;
516         
517   out:  
518         if (ok) {
519                 session->save_state ("");
520         }
521 }
522
523 int
524 Editor::import_sndfiles (vector<ustring> paths, ImportMode mode, SrcQuality quality, nframes64_t& pos, 
525                          int target_regions, int target_tracks, boost::shared_ptr<Track>& track, bool replace)
526 {
527         WindowTitle title = string_compose (_("importing %1"), paths.front());
528
529         interthread_progress_window->set_title (title.get_string());
530         interthread_progress_window->set_position (Gtk::WIN_POS_MOUSE);
531         interthread_progress_bar.set_fraction (0.0f);
532         interthread_cancel_label.set_text (_("Cancel Import"));
533         current_interthread_info = &import_status;
534
535         import_status.paths = paths;
536         import_status.done = false;
537         import_status.cancel = false;
538         import_status.freeze = false;
539         import_status.done = 0.0;
540         import_status.quality = quality;
541         import_status.replace_existing_source = replace;
542
543         interthread_progress_connection = Glib::signal_timeout().connect 
544                 (bind (mem_fun(*this, &Editor::import_progress_timeout), (gpointer) 0), 500);
545         
546         track_canvas->get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
547         ARDOUR_UI::instance()->flush_pending ();
548
549         /* start import thread for this spec. this will ultimately call Session::import_audiofiles()
550            and if successful will add the file(s) as a region to the session region list.
551         */
552         
553         pthread_create_and_store ("import", &import_status.thread, 0, _import_thread, this);
554         pthread_detach (import_status.thread);
555         
556         while (!(import_status.done || import_status.cancel)) {
557                 gtk_main_iteration ();
558         }
559
560         interthread_progress_window->hide ();
561         
562         import_status.done = true;
563         interthread_progress_connection.disconnect ();
564         
565         /* import thread finished - see if we should build a new track */
566
567         boost::shared_ptr<AudioRegion> r;
568         
569         if (import_status.cancel || import_status.sources.empty()) {
570                 goto out;
571         }
572
573         if (add_sources (paths, import_status.sources, pos, mode, target_regions, target_tracks, track, false) == 0) {
574                 session->save_state ("");
575         }
576
577   out:
578         track_canvas->get_window()->set_cursor (*current_canvas_cursor);
579         return 0;
580 }
581
582 int
583 Editor::embed_sndfiles (vector<Glib::ustring> paths, bool multifile,
584                         bool& check_sample_rate, ImportMode mode, nframes64_t& pos, int target_regions, int target_tracks,
585                         boost::shared_ptr<Track>& track)
586 {
587         boost::shared_ptr<AudioFileSource> source;
588         SourceList sources;
589         string linked_path;
590         SoundFileInfo finfo;
591         int ret = 0;
592
593         track_canvas->get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
594         ARDOUR_UI::instance()->flush_pending ();
595
596         for (vector<Glib::ustring>::iterator p = paths.begin(); p != paths.end(); ++p) {
597
598                 ustring path = *p;
599
600                 /* lets see if we can link it into the session */
601                 
602                 sys::path tmp = session->session_directory().sound_path() / Glib::path_get_basename(path);
603                 linked_path = tmp.to_string();
604                 
605                 if (link (path.c_str(), linked_path.c_str()) == 0) {
606
607                         /* there are many reasons why link(2) might have failed.
608                            but if it succeeds, we now have a link in the
609                            session sound dir that will protect against
610                            unlinking of the original path. nice.
611                         */
612                         
613                         path = linked_path;
614
615                 } else {
616
617                         /* one possible reason is that its already linked */
618
619                         if (errno == EEXIST) {
620                                 struct stat sb;
621
622                                 if (stat (linked_path.c_str(), &sb) == 0) {
623                                         if (sb.st_nlink > 1) { // its a hard link, assume its the one we want
624                                                 path = linked_path;
625                                         }
626                                 }
627                         }
628                 }
629                 
630                 /* note that we temporarily truncated _id at the colon */
631                 
632                 string error_msg;
633
634                 if (!AudioFileSource::get_soundfile_info (path, finfo, error_msg)) {
635                         error << string_compose(_("Editor: cannot open file \"%1\", (%2)"), path, error_msg ) << endmsg;
636                         goto out;
637                 }
638                 
639                 if (check_sample_rate  && (finfo.samplerate != (int) session->frame_rate())) {
640                         vector<string> choices;
641                         
642                         if (multifile) {
643                                 choices.push_back (_("Cancel entire import"));
644                                 choices.push_back (_("Don't embed it"));
645                                 choices.push_back (_("Embed all without questions"));
646                         
647                                 Gtkmm2ext::Choice rate_choice (
648                                         string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), 
649                                                         short_path (path, 40)),
650                                         choices, false);
651                                 
652                                 int resx = rate_choice.run ();
653                                 
654                                 switch (resx) {
655                                 case 0: /* stop a multi-file import */
656                                         ret = -2;
657                                         goto out;
658                                 case 1: /* don't embed this one */
659                                         ret = -1;
660                                         goto out;
661                                 case 2: /* do it, and the rest without asking */
662                                         check_sample_rate = false;
663                                         break;
664                                 case 3: /* do it */
665                                         break;
666                                 default:
667                                         ret = -2;
668                                         goto out;
669                                 }
670                         } else {
671                                 choices.push_back (_("Cancel"));
672                                 choices.push_back (_("Embed it anyway"));
673                         
674                                 Gtkmm2ext::Choice rate_choice (
675                                         string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), path),
676                                         choices, false);
677                                 
678                                 int resx = rate_choice.run ();
679                                 
680                                 switch (resx) {
681                                 case 0: /* don't import */
682                                         ret = -1;
683                                         goto out;
684                                 case 1: /* do it */
685                                         break;
686                                 default:
687                                         ret = -2;
688                                         goto out;
689                                 }
690                         }
691                 }
692                 
693                 track_canvas->get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
694
695                 for (int n = 0; n < finfo.channels; ++n) {
696                         try {
697
698                                 /* check if we have this thing embedded already */
699
700                                 boost::shared_ptr<Source> s;
701
702                                 if ((s = session->source_by_path_and_channel (path, n)) == 0) {
703
704                                         cerr << "add embed/import source with defer_peaks = true\n";
705
706                                         source = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable 
707                                                                                                (DataType::AUDIO, *session, path,  n,
708                                                                                                 (mode == ImportAsTapeTrack ? 
709                                                                                                  AudioFileSource::Destructive : 
710                                                                                                  AudioFileSource::Flag (0)),
711                                                                                                 true, true));
712                                 } else {
713                                         source = boost::dynamic_pointer_cast<AudioFileSource> (s);
714                                 }
715
716                                 sources.push_back(source);
717                         } 
718                         
719                         catch (failed_constructor& err) {
720                                 error << string_compose(_("could not open %1"), path) << endmsg;
721                                 goto out;
722                         }
723                         
724                         ARDOUR_UI::instance()->flush_pending ();
725                 }
726         }
727
728         if (sources.empty()) {
729                 goto out;
730         }
731
732         ret = add_sources (paths, sources, pos, mode, target_regions, target_tracks, track, true);
733
734   out:
735         track_canvas->get_window()->set_cursor (*current_canvas_cursor);
736         return ret;
737 }
738
739 int
740 Editor::add_sources (vector<Glib::ustring> paths, SourceList& sources, nframes64_t& pos, ImportMode mode, 
741                      int target_regions, int target_tracks, boost::shared_ptr<Track>& track, bool add_channel_suffix)
742 {
743         vector<boost::shared_ptr<Region> > regions;
744         ustring region_name;
745         uint32_t input_chan = 0;
746         uint32_t output_chan = 0;
747
748         if (pos == -1) { // "use timestamp"
749                 if (sources[0]->natural_position() != 0) {
750                         pos = sources[0]->natural_position();
751                 } else {
752                         pos = get_preferred_edit_position ();
753                 }
754         }
755
756         // kludge (for MIDI we're abusing "channel" for "track" here)
757         if (paths.front().rfind(".mid") != Glib::ustring::npos)
758                 target_regions = -1;
759
760         if (target_regions == 1) {
761
762                 /* take all the sources we have and package them up as a region */
763
764                 region_name = region_name_from_path (paths.front(), (sources.size() > 1), false);
765                 
766                 regions.push_back (RegionFactory::create (sources, 0, sources[0]->length(), region_name, 0,
767                                                            Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
768                 
769         } else if (target_regions == -1) {
770
771                 /* take each source and create a region for each one */
772
773                 SourceList just_one;
774                 SourceList::iterator x;
775                 uint32_t n;
776
777                 for (n = 0, x = sources.begin(); x != sources.end(); ++x, ++n) {
778
779                         just_one.clear ();
780                         just_one.push_back (*x);
781                         
782                         region_name = region_name_from_path ((*x)->path(), false, false, sources.size(), n);
783
784                         regions.push_back (RegionFactory::create (just_one, 0, (*x)->length(), region_name, 0,
785                                                                    Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
786
787                 }
788         }
789
790         if (target_regions == 1) {
791                 input_chan = regions.front()->n_channels();
792         } else {
793                 if (target_tracks == 1) {
794                         input_chan = regions.size();
795                 } else {
796                         input_chan = 1;
797                 }
798         }
799
800         if (Config->get_output_auto_connect() & AutoConnectMaster) {
801                 output_chan = (session->master_out() ? session->master_out()->n_inputs().n_audio() : input_chan);
802         } else {
803                 output_chan = input_chan;
804         }
805
806         int n = 0;
807
808         for (vector<boost::shared_ptr<Region> >::iterator r = regions.begin(); r != regions.end(); ++r, ++n) {
809
810                 finish_bringing_in_material (*r, input_chan, output_chan, pos, mode, track);
811
812                 if (target_tracks != 1) {
813                         track.reset ();
814                 } else {
815                         pos += (*r)->length();
816                 } 
817         }
818
819         /* setup peak file building in another thread */
820
821         for (SourceList::iterator x = sources.begin(); x != sources.end(); ++x) {
822                 SourceFactory::setup_peakfile (*x, true);
823         }
824
825         return 0;
826 }
827         
828 int
829 Editor::finish_bringing_in_material (boost::shared_ptr<Region> region, uint32_t in_chans, uint32_t out_chans, nframes64_t& pos, 
830                                   ImportMode mode, boost::shared_ptr<Track>& existing_track)
831 {
832         boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(region);
833         boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(region);
834
835         switch (mode) {
836         case ImportAsRegion:
837                 /* relax, its been done */
838                 break;
839                 
840         case ImportToTrack:
841         {
842                 if (!existing_track) {
843
844                         if (ar) {
845                                 existing_track = get_nth_selected_audio_track (0);
846                         } else if (mr) {
847                                 existing_track = get_nth_selected_midi_track (0);
848                         }
849
850                         if (!existing_track) {
851                                 return -1;
852                         }
853                 }
854
855                 boost::shared_ptr<Playlist> playlist = existing_track->diskstream()->playlist();
856                 boost::shared_ptr<Region> copy (RegionFactory::create (region));
857                 begin_reversible_command (_("insert file"));
858                 XMLNode &before = playlist->get_state();
859                 playlist->add_region (copy, pos);
860                 session->add_command (new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
861                 commit_reversible_command ();
862                 break;
863         }
864
865         case ImportAsTrack:
866         { 
867                 if (!existing_track) {
868                         if (ar) {
869                                 list<boost::shared_ptr<AudioTrack> > at (session->new_audio_track (in_chans, out_chans, Normal, 1));
870
871                                 if (at.empty()) {
872                                         return -1;
873                                 }
874
875                                 existing_track = at.front();
876                         } else if (mr) {
877                                 list<boost::shared_ptr<MidiTrack> > mt (session->new_midi_track (Normal, 1));
878
879                                 if (mt.empty()) {
880                                         return -1;
881                                 }
882
883                                 existing_track = mt.front();
884                         }
885
886                         existing_track->set_name (region->name());
887                 }
888
889                 boost::shared_ptr<Region> copy (RegionFactory::create (region));
890                 existing_track->diskstream()->playlist()->add_region (copy, pos);
891                 break;
892         }
893
894
895         case ImportAsTapeTrack:
896         {
897                 if (!ar)
898                         return -1;
899
900                 list<boost::shared_ptr<AudioTrack> > at (session->new_audio_track (in_chans, out_chans, Destructive));
901                 if (!at.empty()) {
902                         boost::shared_ptr<Region> copy (RegionFactory::create (region));
903                         at.front()->set_name (basename_nosuffix (copy->name()));
904                         at.front()->diskstream()->playlist()->add_region (copy, pos);
905                 }
906                 break;
907         }
908         }
909
910         return 0;
911 }
912
913 void *
914 Editor::_import_thread (void *arg)
915 {
916         PBD::ThreadCreated (pthread_self(), X_("Import"));
917
918         Editor *ed = (Editor *) arg;
919         return ed->import_thread ();
920 }
921
922 void *
923 Editor::import_thread ()
924 {
925         session->import_audiofiles (import_status);
926         pthread_exit_pbd (0);
927         /*NOTREACHED*/
928         return 0;
929 }
930
931 gint
932 Editor::import_progress_timeout (void *arg)
933 {
934         bool reset = false;
935
936         if (!interthread_progress_window->is_visible()) {
937                 interthread_progress_window->show_all ();
938                 reset = true;
939         }
940
941         interthread_progress_label.set_text (import_status.doing_what);
942
943         if (import_status.freeze) {
944                 interthread_cancel_button.set_sensitive(false);
945         } else {
946                 interthread_cancel_button.set_sensitive(true);
947         }
948
949         if (import_status.doing_what == "building peak files") {
950                 interthread_progress_bar.pulse ();
951                 return FALSE;
952         } else {
953                 float val = import_status.progress;
954                 interthread_progress_bar.set_fraction (min (max (0.0f, val), 1.0f));
955         }
956
957         if (reset) {
958
959                 /* the window is now visible, speed up the updates */
960                 
961                 interthread_progress_connection.disconnect ();
962                 interthread_progress_connection = Glib::signal_timeout().connect 
963                         (bind (mem_fun(*this, &Editor::import_progress_timeout), (gpointer) 0), 100);
964                 return false;
965         } else {
966                 return !(import_status.done || import_status.cancel);
967         }
968 }
969