summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/editor.h4
-rw-r--r--gtk2_ardour/editor_audio_import.cc295
-rw-r--r--libs/ardour/ardour/session.h8
-rw-r--r--libs/ardour/import.cc43
4 files changed, 249 insertions, 101 deletions
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index f6f4188b58..f76804d288 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -1050,6 +1050,8 @@ class Editor : public PublicEditor
void add_external_audio_action (Editing::ImportMode);
void external_audio_dialog ();
+
+ int check_whether_and_how_to_import(string, bool all_or_nothing = true);
bool check_multichannel_status (const std::vector<Glib::ustring>& paths);
SoundFileOmega* sfbrowser;
@@ -1062,7 +1064,7 @@ class Editor : public PublicEditor
bool idle_do_embed (vector<Glib::ustring> paths, Editing::ImportDisposition, Editing::ImportMode mode, nframes64_t&);
int import_sndfiles (vector<Glib::ustring> paths, Editing::ImportMode mode, ARDOUR::SrcQuality, nframes64_t& pos,
- int target_regions, int target_tracks, boost::shared_ptr<ARDOUR::AudioTrack>&);
+ int target_regions, int target_tracks, boost::shared_ptr<ARDOUR::AudioTrack>&, bool);
int embed_sndfiles (vector<Glib::ustring> paths, bool multiple_files, bool& check_sample_rate, Editing::ImportMode mode,
nframes64_t& pos, int target_regions, int target_tracks, boost::shared_ptr<ARDOUR::AudioTrack>&);
diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc
index 971b77acef..fa14e2b88f 100644
--- a/gtk2_ardour/editor_audio_import.cc
+++ b/gtk2_ardour/editor_audio_import.cc
@@ -42,6 +42,7 @@
#include <ardour/audiofilesource.h>
#include <ardour/region_factory.h>
#include <ardour/source_factory.h>
+#include <ardour/session.h>
#include <pbd/memento_command.h>
#include "ardour_ui.h"
@@ -114,60 +115,139 @@ Editor::external_audio_dialog ()
sfbrowser->show_all ();
- again:
- int response = sfbrowser->run ();
- switch (response) {
- case RESPONSE_APPLY:
- // leave the dialog open
- break;
+ bool keepRunning;
- case RESPONSE_OK:
- sfbrowser->hide ();
- break;
+ do {
+ keepRunning = false;
- default:
- // cancel from the browser - we are done
- sfbrowser->hide ();
- return;
- }
+ int response = sfbrowser->run ();
- /* lets do it */
-
- paths = sfbrowser->get_paths ();
+ switch (response) {
+ case RESPONSE_APPLY:
+ // leave the dialog open
+ break;
- ImportPosition pos = sfbrowser->get_position ();
- ImportMode mode = sfbrowser->get_mode ();
- ImportDisposition chns = sfbrowser->get_channel_disposition ();
- nframes64_t where;
+ case RESPONSE_OK:
+ sfbrowser->hide ();
+ break;
- switch (pos) {
- case ImportAtEditPoint:
- where = get_preferred_edit_position ();
- break;
- case ImportAtTimestamp:
- where = -1;
- break;
- case ImportAtPlayhead:
- where = playhead_cursor->current_frame;
- break;
- case ImportAtStart:
- where = session->current_start_frame();
- break;
- }
+ default:
+ // cancel from the browser - we are done
+ sfbrowser->hide ();
+ return;
+ }
- SrcQuality quality = sfbrowser->get_src_quality();
+ /* lets do it */
+
+ paths = sfbrowser->get_paths ();
+
+ ImportPosition pos = sfbrowser->get_position ();
+ ImportMode mode = sfbrowser->get_mode ();
+ ImportDisposition chns = sfbrowser->get_channel_disposition ();
+ nframes64_t where;
+
+ switch (pos) {
+ case ImportAtEditPoint:
+ where = get_preferred_edit_position ();
+ break;
+ case ImportAtTimestamp:
+ where = -1;
+ break;
+ case ImportAtPlayhead:
+ where = playhead_cursor->current_frame;
+ break;
+ case ImportAtStart:
+ where = session->current_start_frame();
+ break;
+ }
- if (sfbrowser->copy_files_btn.get_active()) {
- do_import (paths, chns, mode, quality, where);
- } else {
- do_embed (paths, chns, mode, where);
+ SrcQuality quality = sfbrowser->get_src_quality();
+
+
+ if (sfbrowser->copy_files_btn.get_active()) {
+ do_import (paths, chns, mode, quality, where);
+ } else {
+ do_embed (paths, chns, mode, where);
+ }
+
+ if (response == RESPONSE_APPLY) {
+ sfbrowser->clear_selection ();
+ keepRunning = true;
+ }
+
+ } while (keepRunning);
+}
+
+typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
+
+/**
+ * Updating is still disabled, see note in libs/ardour/import.cc Session::import_audiofiles()
+ *
+ * all_or_nothing:
+ * true = show "Update", "Import" and "Skip"
+ * false = show "Import", and "Cancel"
+ *
+ * Returns:
+ * 0 To update an existing source of the same name
+ * 1 To import/embed the file normally (make sure the new name will be unique)
+ * 2 If the user wants to skip this file
+ **/
+int
+Editor::check_whether_and_how_to_import(string path, bool all_or_nothing)
+{
+ string wave_name (basename(path.c_str()));
+
+ AudioSourceList all_sources = session->get_audio_sources();
+ bool wave_name_exists = false;
+
+ for (AudioSourceList::iterator i = all_sources.begin(); i != all_sources.end(); ++i) {
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(i->second);
+
+ string tmp (basename(afs->path().c_str()));
+
+ if (tmp == wave_name) {
+ wave_name_exists = true;
+ break;
+ }
}
- if (response == RESPONSE_APPLY) {
- sfbrowser->clear_selection ();
- goto again;
+ int function = 1;
+
+
+ if (wave_name_exists) {
+ string message;
+ if (all_or_nothing) {
+ // updating is still disabled
+ //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);
+ 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);
+ } else {
+ message = _("Lorem ipsum. Do you want to skidaddle?");
+
+ }
+ MessageDialog dialog(message, false,Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_NONE, true);
+
+ if (all_or_nothing) {
+ // disabled
+ //dialog.add_button("Update", 0);
+ dialog.add_button("Import", 1);
+ dialog.add_button("Skip", 2);
+ } else {
+ dialog.add_button("Import", 1);
+ dialog.add_button("Cancel", 2);
+ }
+
+
+ //dialog.add_button("Skip all", 4); // All or rest?
+
+ dialog.show();
+
+ function = dialog.run ();
+
+ dialog.hide();
}
+
+ return function;
}
boost::shared_ptr<AudioTrack>
@@ -205,79 +285,107 @@ Editor::do_import (vector<ustring> paths, ImportDisposition chns, ImportMode mod
{
boost::shared_ptr<AudioTrack> track;
vector<ustring> to_import;
- bool ok = false;
+ bool ok = true;
int nth = 0;
if (interthread_progress_window == 0) {
build_interthread_progress_window ();
}
- switch (chns) {
- case Editing::ImportDistinctFiles:
- for (vector<ustring>::iterator a = paths.begin(); a != paths.end(); ++a) {
-
- to_import.clear ();
- to_import.push_back (*a);
- if (mode == Editing::ImportToTrack) {
- track = get_nth_selected_audio_track (nth++);
- }
-
- if (import_sndfiles (to_import, mode, quality, pos, 1, -1, track)) {
- goto out;
+ if (chns == Editing::ImportMergeFiles) {
+ /* create 1 region from all paths, add to 1 track,
+ ignore "track"
+ */
+ bool cancel = false;
+ for (vector<ustring>::iterator a = paths.begin(); a != paths.end() && ok; ++a) {
+ int check = check_whether_and_how_to_import(*a, false);
+ if (check == 2) {
+ cancel = true;
+ break;
}
+ }
+ if (!cancel) {
+ if (import_sndfiles (paths, mode, quality, pos, 1, 1, track, false)) {
+ ok = false;
+ }
}
- break;
- case Editing::ImportDistinctChannels:
- for (vector<ustring>::iterator a = paths.begin(); a != paths.end(); ++a) {
+ } else {
+ bool replace;
- to_import.clear ();
- to_import.push_back (*a);
+ for (vector<ustring>::iterator a = paths.begin(); a != paths.end() && ok; ++a) {
- if (import_sndfiles (to_import, mode, quality, pos, -1, -1, track)) {
- goto out;
+ int check = check_whether_and_how_to_import(*a, true);
+
+ if (check == 2 ) {
+ // skip
+ continue;
}
- }
- break;
+ if (check == 0) {
+ fatal << "Updating existing sources should be disabled!" << endl;
+ replace = true;
+ } else if (check == 1) {
+ replace = false;
+ }
+
- case Editing::ImportMergeFiles:
- /* create 1 region from all paths, add to 1 track,
- ignore "track"
- */
- if (import_sndfiles (paths, mode, quality, pos, 1, 1, track)) {
- goto out;
- }
- break;
+ switch (chns) {
+ case Editing::ImportDistinctFiles:
- case Editing::ImportSerializeFiles:
- for (vector<ustring>::iterator a = paths.begin(); a != paths.end(); ++a) {
+ to_import.clear ();
+ to_import.push_back (*a);
- to_import.clear ();
- to_import.push_back (*a);
-
- /* create 1 region from this path, add to 1 track,
- reuse "track" across paths
- */
+ if (mode == Editing::ImportToTrack) {
+ track = get_nth_selected_audio_track (nth++);
+ }
- if (import_sndfiles (to_import, mode, quality, pos, 1, 1, track)) {
- goto out;
+ if (import_sndfiles (to_import, mode, quality, pos, 1, -1, track, replace)) {
+ ok = false;
+ }
+
+ break;
+
+ case Editing::ImportDistinctChannels:
+
+ to_import.clear ();
+ to_import.push_back (*a);
+
+ if (import_sndfiles (to_import, mode, quality, pos, -1, -1, track, replace)) {
+ ok = false;
+ }
+
+ break;
+
+ case Editing::ImportSerializeFiles:
+
+ to_import.clear ();
+ to_import.push_back (*a);
+
+ /* create 1 region from this path, add to 1 track,
+ reuse "track" across paths
+ */
+
+ if (import_sndfiles (to_import, mode, quality, pos, 1, 1, track, replace)) {
+ ok = false;
+ }
+
+ break;
+
+ case Editing::ImportMergeFiles:
+ // Not entered
+ break;
}
+ }
+ if (ok) {
+ session->save_state ("");
}
- break;
- }
- ok = true;
-
- out:
- if (ok) {
- session->save_state ("");
+ interthread_progress_window->hide_all ();
}
-
- interthread_progress_window->hide_all ();
}
bool
@@ -365,7 +473,7 @@ Editor::_do_embed (vector<ustring> paths, ImportDisposition chns, ImportMode mod
int
Editor::import_sndfiles (vector<ustring> paths, ImportMode mode, SrcQuality quality, nframes64_t& pos,
- int target_regions, int target_tracks, boost::shared_ptr<AudioTrack>& track)
+ int target_regions, int target_tracks, boost::shared_ptr<AudioTrack>& track, bool replace)
{
WindowTitle title = string_compose (_("importing %1"), paths.front());
@@ -382,6 +490,7 @@ Editor::import_sndfiles (vector<ustring> paths, ImportMode mode, SrcQuality qual
import_status.freeze = false;
import_status.done = 0.0;
import_status.quality = quality;
+ import_status.replace_existing_source = replace;
interthread_progress_connection = Glib::signal_timeout().connect
(bind (mem_fun(*this, &Editor::import_progress_timeout), (gpointer) 0), 100);
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 2889e73c38..9866c1cbe0 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -577,10 +577,10 @@ class Session : public PBD::StatefulDestructible
string doing_what;
/* control info */
- bool sample_convert;
SrcQuality quality;
volatile bool freeze;
std::vector<Glib::ustring> paths;
+ bool replace_existing_source;
/* result */
SourceList sources;
@@ -1494,6 +1494,12 @@ class Session : public PBD::StatefulDestructible
AudioSourceList audio_sources;
+ public:
+ AudioSourceList get_audio_sources() { return audio_sources; }
+
+ private:
+
+
int load_sources (const XMLNode& node);
XMLNode& get_sources_as_xml ();
diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc
index 3c3e63be90..edf8f03373 100644
--- a/libs/ardour/import.cc
+++ b/libs/ardour/import.cc
@@ -66,7 +66,7 @@ open_importable_source (const string& path, nframes_t samplerate, ARDOUR::SrcQua
}
static std::string
-get_non_existent_filename (const std::string& basename, uint channel, uint channels)
+get_non_existent_filename (const bool allow_replacing, const std::string destdir, const std::string& basename, uint channel, uint channels)
{
char buf[PATH_MAX+1];
bool goodfile = false;
@@ -85,7 +85,9 @@ get_non_existent_filename (const std::string& basename, uint channel, uint chann
snprintf (buf, sizeof(buf), "%s.wav", base.c_str());
}
- if (Glib::file_test (buf, Glib::FILE_TEST_EXISTS)) {
+
+ string tempname = destdir + "/" + buf;
+ if (!allow_replacing && Glib::file_test (tempname, Glib::FILE_TEST_EXISTS)) {
/* if the file already exists, we must come up with
* a new name for it. for now we just keep appending
@@ -105,7 +107,7 @@ get_non_existent_filename (const std::string& basename, uint channel, uint chann
}
static vector<string>
-get_paths_for_new_sources (const string& import_file_path, const string& session_dir, uint channels)
+get_paths_for_new_sources (const bool allow_replacing, const string& import_file_path, const string& session_dir, uint channels)
{
vector<string> new_paths;
const string basename = basename_nosuffix (import_file_path);
@@ -116,7 +118,7 @@ get_paths_for_new_sources (const string& import_file_path, const string& session
filepath = session_dir;
filepath += '/';
- filepath += get_non_existent_filename (basename, n, channels);
+ filepath += get_non_existent_filename (allow_replacing, session_dir, basename, n, channels);
new_paths.push_back (filepath);
}
@@ -125,6 +127,25 @@ get_paths_for_new_sources (const string& import_file_path, const string& session
}
static bool
+map_existing_mono_sources (const vector<string>& new_paths, Session& sess,
+ uint samplerate, vector<boost::shared_ptr<AudioFileSource> >& newfiles, Session *session)
+{
+ for (vector<string>::const_iterator i = new_paths.begin();
+ i != new_paths.end(); ++i)
+ {
+ boost::shared_ptr<Source> source = session->source_by_path_and_channel(*i, 0);
+
+ if (source == 0) {
+ error << string_compose(_("Could not find a source for %1 even though we are updating this file!"), (*i)) << endl;
+ return false;
+ }
+
+ newfiles.push_back(boost::dynamic_pointer_cast<AudioFileSource>(source));
+ }
+ return true;
+}
+
+static bool
create_mono_sources_for_writing (const vector<string>& new_paths, Session& sess,
uint samplerate, vector<boost::shared_ptr<AudioFileSource> >& newfiles)
{
@@ -228,6 +249,10 @@ remove_file_source (boost::shared_ptr<AudioFileSource> file_source)
::unlink (file_source->path().c_str());
}
+// This function is still unable to cleanly update an existing source, even though
+// it is possible to set the import_status flag accordingly. The functinality
+// is disabled at the GUI until the Source implementations are able to provide
+// the necessary API.
void
Session::import_audiofiles (import_status& status)
{
@@ -254,13 +279,19 @@ Session::import_audiofiles (import_status& status)
return;
}
- vector<string> new_paths = get_paths_for_new_sources (*p,
+ vector<string> new_paths = get_paths_for_new_sources (status.replace_existing_source,
+ *p,
discover_best_sound_dir (),
source->channels());
AudioSources newfiles;
- status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles);
+ if (status.replace_existing_source) {
+ fatal << "THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" << endl;
+ status.cancel = !map_existing_mono_sources (new_paths, *this, frame_rate(), newfiles, this);
+ } else {
+ status.cancel = !create_mono_sources_for_writing (new_paths, *this, frame_rate(), newfiles);
+ }
// copy on cancel/failure so that any files that were created will be removed below
std::copy (newfiles.begin(), newfiles.end(), std::back_inserter(all_new_sources));