summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSampo Savolainen <v2@iki.fi>2008-02-15 06:41:22 +0000
committerSampo Savolainen <v2@iki.fi>2008-02-15 06:41:22 +0000
commite58375fddab92aa423ed104ac7954982c18d580a (patch)
tree4a5980755f80f344e01542bd515b4799b41e56b2
parent9a9595bcfe153a11cd1224bbd7face68de662053 (diff)
Make import GUI report if you are importing a file of a name that
already exists in the session. Legwork to allow updating existing source files via the import dialog. Fix bug which caused the current import logic to select existing file name as target file when importing. This caused the newly imported file to be concatenated after the original data. git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@3059 d708f5d6-7413-0410-9779-e7cbd77b26cf
-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));