summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/SConscript1
-rw-r--r--gtk2_ardour/ardour.menus10
-rw-r--r--gtk2_ardour/crossfade_edit.cc2
-rw-r--r--gtk2_ardour/editing.h19
-rw-r--r--gtk2_ardour/editing_syms.h4
-rw-r--r--gtk2_ardour/editor.cc26
-rw-r--r--gtk2_ardour/editor.h24
-rw-r--r--gtk2_ardour/editor_actions.cc14
-rw-r--r--gtk2_ardour/editor_audio_import.cc395
-rw-r--r--gtk2_ardour/editor_canvas.cc16
-rw-r--r--gtk2_ardour/editor_mouse.cc1
-rw-r--r--gtk2_ardour/editor_ops.cc491
-rw-r--r--gtk2_ardour/editor_region_list.cc5
-rw-r--r--gtk2_ardour/redirect_box.cc6
-rw-r--r--gtk2_ardour/route_ui.cc8
-rw-r--r--gtk2_ardour/sfdb_ui.cc138
-rw-r--r--gtk2_ardour/sfdb_ui.h30
-rw-r--r--gtk2_ardour/utils.cc18
-rw-r--r--gtk2_ardour/utils.h1
-rw-r--r--gtk2_ardour/visual_time_axis.cc14
20 files changed, 619 insertions, 604 deletions
diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript
index 09e5b7f7eb..eedc04c3c5 100644
--- a/gtk2_ardour/SConscript
+++ b/gtk2_ardour/SConscript
@@ -93,6 +93,7 @@ default_keys.cc
editing.cc
editor.cc
editor_actions.cc
+editor_audio_import.cc
editor_audiotrack.cc
editor_canvas.cc
editor_canvas_events.cc
diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus
index 6176032d12..70a8b1d32d 100644
--- a/gtk2_ardour/ardour.menus
+++ b/gtk2_ardour/ardour.menus
@@ -11,7 +11,13 @@
<menuitem action='Snapshot'/>
<menuitem action='SaveTemplate'/>
<separator/>
- <menuitem action='AddTrackBus'/>
+ <menuitem action='AddTrackBus'/>
+ <separator/>
+ <menu action='addExistingAudioFiles'>
+ <menuitem action='addExternalAudioAsRegion'/>
+ <menuitem action='addExternalAudioAsTrack'/>
+ <menuitem action='addExternalAudioToTrack'/>
+ </menu>
<separator/>
<menu name='Export' action='Export'>
<menuitem action='ExportSession'/>
@@ -308,6 +314,6 @@
<menuitem action='SortBySourceFilesystem'/>
</menu>
<separator/>
- <menuitem action='addExternalRegion'/>
+ <menuitem action='addExternalAudioToRegionList'/>
</popup>
</ui>
diff --git a/gtk2_ardour/crossfade_edit.cc b/gtk2_ardour/crossfade_edit.cc
index 451b9781f5..1b4110be50 100644
--- a/gtk2_ardour/crossfade_edit.cc
+++ b/gtk2_ardour/crossfade_edit.cc
@@ -212,8 +212,6 @@ CrossfadeEditor::CrossfadeEditor (Session& s, Crossfade& xf, double my, double m
for (list<Preset*>::iterator i = fade_out_presets->begin(); i != fade_out_presets->end(); ++i) {
- cerr << "looking for xpm " << (*i)->xpm << endl;
-
pxmap = manage (new Image (get_xpm((*i)->xpm)));
pbutton = manage (new Button);
pbutton->add (*pxmap);
diff --git a/gtk2_ardour/editing.h b/gtk2_ardour/editing.h
index 31da83d984..b25b935ee0 100644
--- a/gtk2_ardour/editing.h
+++ b/gtk2_ardour/editing.h
@@ -13,6 +13,7 @@
#define MOUSEMODE(a) /*empty*/
#define ZOOMFOCUS(a) /*empty*/
#define DISPLAYCONTROL(a) /*empty*/
+#define IMPORTMODE(a) /*empty*/
namespace Editing {
@@ -124,6 +125,24 @@ DisplayControl str2displaycontrol (const std::string &);
#undef DISPLAYCONTROL
#define DISPLAYCONTROL(a) /*empty*/
+// IMPORTMODE
+#undef IMPORTMODE
+#define IMPORTMODE(a) a,
+enum ImportMode {
+ #include "editing_syms.h"
+};
+
+#undef IMPORTMODE
+#define IMPORTMODE(s) #s,
+static const char *importmodestrs[] = {
+ #include "editing_syms.h"
+};
+inline const char* enum2str(ImportMode m) {return importmodestrs[m];}
+ImportMode str2importmode (const std::string &);
+
+#undef IMPORTMODE
+#define IMPORTMODE(a) /*empty*/
+
/////////////////////
// These don't need their state saved. yet...
enum CutCopyOp {
diff --git a/gtk2_ardour/editing_syms.h b/gtk2_ardour/editing_syms.h
index b74698c5c4..cf36550fb4 100644
--- a/gtk2_ardour/editing_syms.h
+++ b/gtk2_ardour/editing_syms.h
@@ -53,3 +53,7 @@ DISPLAYCONTROL(FollowPlayhead)
DISPLAYCONTROL(ShowMeasures)
DISPLAYCONTROL(ShowWaveforms)
DISPLAYCONTROL(ShowWaveformsRecording)
+
+IMPORTMODE(ImportAsRegion)
+IMPORTMODE(ImportAsTrack)
+IMPORTMODE(ImportToTrack)
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 9fe0d2767c..bdb8e841cb 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -1982,14 +1982,9 @@ Editor::add_dstream_context_items (Menu_Helpers::MenuList& edit_items)
/* Adding new material */
- Menu *import_menu = manage (new Menu());
- MenuList& import_items = import_menu->items();
- import_menu->set_name ("ArdourContextMenu");
-
- import_items.push_back (MenuElem (_("Insert Region"), bind (mem_fun(*this, &Editor::insert_region_list_selection), 1.0f)));
- import_items.push_back (MenuElem (_("Insert external sndfile"), bind (mem_fun(*this, &Editor::insert_sndfile), false)));
-
- edit_items.push_back (MenuElem (_("Import"), *import_menu));
+ edit_items.push_back (SeparatorElem());
+ edit_items.push_back (MenuElem (_("Insert Selected Region"), bind (mem_fun(*this, &Editor::insert_region_list_selection), 1.0f)));
+ edit_items.push_back (MenuElem (_("Insert Existing Audio"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportToTrack)));
/* Nudge track */
@@ -2905,7 +2900,7 @@ Editor::stop_canvas_autoscroll ()
}
int
-Editor::convert_drop_to_paths (vector<string>& paths,
+Editor::convert_drop_to_paths (vector<ustring>& paths,
const RefPtr<Gdk::DragContext>& context,
gint x,
gint y,
@@ -3445,21 +3440,14 @@ Editor::edit_menu_map_handler (GdkEventAny* ev)
import_menu->set_name ("ArdourContextMenu");
MenuList& import_items = import_menu->items();
- import_items.push_back (MenuElem (_("... as new track"), bind (mem_fun(*this, &Editor::import_audio), true)));
- import_items.push_back (MenuElem (_("... as new region"), bind (mem_fun(*this, &Editor::import_audio), false)));
-
- Menu* embed_menu = manage (new Menu());
- embed_menu->set_name ("ArdourContextMenu");
- MenuList& embed_items = embed_menu->items();
-
- embed_items.push_back (MenuElem (_("... as new track"), bind (mem_fun(*this, &Editor::insert_sndfile), true)));
- embed_items.push_back (MenuElem (_("... as new region"), mem_fun(*this, &Editor::embed_audio)));
+ import_items.push_back (MenuElem (_("... as new track"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportAsTrack)));
+ import_items.push_back (MenuElem (_("... as new region"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportAsRegion)));
edit_items.push_back (MenuElem (_("Import audio (copy)"), *import_menu));
- edit_items.push_back (MenuElem (_("Embed audio (link)"), *embed_menu));
edit_items.push_back (SeparatorElem());
edit_items.push_back (MenuElem (_("Remove last capture"), mem_fun(*this, &Editor::remove_last_capture)));
+
if (!session->have_captured()) {
edit_items.back().set_sensitive (false);
}
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index f0fb67694a..dbc76993d9 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -967,18 +967,16 @@ class Editor : public PublicEditor
void insert_region_list_drag (ARDOUR::AudioRegion&, int x, int y);
void insert_region_list_selection (float times);
- void insert_sndfile (bool as_tracks);
- void embed_audio (); // inserts into region list
- int reject_because_rate_differs (const string & path, ARDOUR::SoundFileInfo& finfo, const string & action, bool multiple_pending);
+ void add_external_audio_action (Editing::ImportMode);
- void do_embed_sndfiles (vector<string> paths, bool split);
- void embed_sndfile (string path, bool split, bool multiple_files, bool& check_sr);
-
- void do_insert_sndfile (vector<string> path, bool multi, jack_nframes_t frame);
- void insert_paths_as_new_tracks (std::vector<std::string> paths, bool multi); // inserts files as new tracks
- void insert_sndfile_into (const string & path, bool multi, AudioTimeAxisView* tv, jack_nframes_t& frame, bool prompt=true);
- static void* _insert_sndfile_thread (void*);
- void* insert_sndfile_thread (void*);
+ void bring_in_external_audio (Editing::ImportMode mode, ARDOUR::AudioTrack*, jack_nframes_t& pos, bool prompt);
+ void do_import (vector<Glib::ustring> paths, bool split, Editing::ImportMode mode, ARDOUR::AudioTrack*, jack_nframes_t&, bool);
+ void do_embed (vector<Glib::ustring> paths, bool split, Editing::ImportMode mode, ARDOUR::AudioTrack*, jack_nframes_t&, bool);
+ void import_sndfile (Glib::ustring path, Editing::ImportMode mode, ARDOUR::AudioTrack* track, jack_nframes_t& pos);
+ void embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool& check_sample_rate, Editing::ImportMode mode,
+ ARDOUR::AudioTrack* track, jack_nframes_t& pos, bool prompt);
+ int finish_bringing_in_audio (ARDOUR::AudioRegion& region, uint32_t, uint32_t, ARDOUR::AudioTrack* track, jack_nframes_t& pos, Editing::ImportMode mode);
+ int reject_because_rate_differs (Glib::ustring path, ARDOUR::SoundFileInfo& finfo, const string & action, bool multiple_pending);
/* generic interthread progress window */
@@ -1003,8 +1001,6 @@ class Editor : public PublicEditor
gint import_progress_timeout (void *);
static void *_import_thread (void *);
void* import_thread ();
- void catch_new_audio_region (ARDOUR::AudioRegion*);
- ARDOUR::AudioRegion* last_audio_region;
/* to support this ... */
@@ -1586,7 +1582,7 @@ class Editor : public PublicEditor
/* Drag-n-Drop */
- int convert_drop_to_paths (std::vector<std::string>& paths,
+ int convert_drop_to_paths (std::vector<Glib::ustring>& paths,
const Glib::RefPtr<Gdk::DragContext>& context,
gint x,
gint y,
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index d0a5c90144..583c272fe0 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -37,6 +37,7 @@ Editor::register_actions ()
ActionManager::register_action (editor_actions, X_("Monitoring"), _("Monitoring"));
ActionManager::register_action (editor_actions, X_("Autoconnect"), _("Autoconnect"));
ActionManager::register_action (editor_actions, X_("Layering"), _("Layering"));
+ ActionManager::register_action (editor_actions, X_("addExistingAudioFiles"), _("Add Existing Audio"));
/* add named actions for the editor */
@@ -339,8 +340,17 @@ Editor::register_actions ()
bind (mem_fun(*this, &Editor::reset_region_list_sort_type), BySourceFileCreationDate));
ActionManager::register_radio_action (rl_actions, sort_type_group, X_("SortBySourceFilesystem"), _("By Source Filesystem"),
bind (mem_fun(*this, &Editor::reset_region_list_sort_type), BySourceFileFS));
-
- act = ActionManager::register_action (rl_actions, X_("addExternalAudio"), _("Embed audio (link)"), mem_fun(*this, &Editor::embed_audio));
+
+
+ /* the next two are duplicate items with different names for use in two different contexts */
+
+ act = ActionManager::register_action (editor_actions, X_("addExternalAudioToRegionList"), _("Add External Audio"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportAsRegion));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, X_("addExternalAudioAsRegion"), _("as Region(s)"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportAsRegion));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, X_("addExternalAudioAsTrack"), _("as Tracks"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportAsTrack));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, X_("addExternalAudioToTrack"), _("to Tracks"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportToTrack));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::register_toggle_action (editor_actions, X_("ToggleWaveformVisibility"), _("Show Waveforms"), mem_fun (*this, &Editor::toggle_waveform_visibility));
diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc
new file mode 100644
index 0000000000..658bb6fe74
--- /dev/null
+++ b/gtk2_ardour/editor_audio_import.cc
@@ -0,0 +1,395 @@
+/*
+ Copyright (C) 2000-2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#include <pbd/pthread_utils.h>
+#include <pbd/basename.h>
+
+#include <gtkmm2ext/choice.h>
+
+#include <ardour/session.h>
+#include <ardour/audioplaylist.h>
+#include <ardour/audioregion.h>
+#include <ardour/diskstream.h>
+#include <ardour/filesource.h>
+#include <ardour/externalsource.h>
+#include <ardour/utils.h>
+#include <ardour/audio_track.h>
+#include <ardour/audioplaylist.h>
+
+#include "ardour_ui.h"
+#include "editor.h"
+#include "sfdb_ui.h"
+#include "editing.h"
+#include "audio_time_axis.h"
+
+#include "i18n.h"
+
+using namespace std;
+using namespace ARDOUR;
+using namespace sigc;
+using namespace Gtk;
+using namespace Editing;
+
+/* Functions supporting the incorporation of external (non-captured) audio material into ardour */
+
+void
+Editor::add_external_audio_action (ImportMode mode)
+{
+ jack_nframes_t& pos = edit_cursor->current_frame;
+ AudioTrack* track = 0;
+
+ if (!selection->tracks.empty()) {
+ AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(selection->tracks.front());
+ if (atv) {
+ track = atv->audio_track();
+ }
+ }
+
+ bring_in_external_audio (mode, track, pos, false);
+}
+
+void
+Editor::bring_in_external_audio (ImportMode mode, AudioTrack* track, jack_nframes_t& pos, bool prompt)
+{
+ if (session == 0) {
+ MessageDialog msg (0, _("You can't import or embed an audiofile until you have a session loaded."));
+ msg.run ();
+ return;
+ }
+
+ SoundFileOmega sfdb (_("Add existing audio to session"));
+ sfdb.set_mode (mode);
+
+ switch (sfdb.run()) {
+ case SoundFileOmega::ResponseImport:
+ do_import (sfdb.get_paths(), sfdb.get_split(), mode, track, pos, prompt);
+ break;
+
+ case SoundFileOmega::ResponseEmbed:
+ do_embed (sfdb.get_paths(), sfdb.get_split(), mode, track, pos, prompt);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void
+Editor::do_import (vector<Glib::ustring> paths, bool split, ImportMode mode, AudioTrack* track, jack_nframes_t& pos, bool prompt)
+{
+ /* SFDB sets "multichan" to true to indicate "split channels"
+ so reverse the setting to match the way libardour
+ interprets it.
+ */
+
+ import_status.multichan = !split;
+
+ if (interthread_progress_window == 0) {
+ build_interthread_progress_window ();
+ }
+
+ /* for each path that was selected, import it and then potentially create a new track
+ containing the new region as the sole contents.
+ */
+
+ for (vector<Glib::ustring>::iterator i = paths.begin(); i != paths.end(); ++i ) {
+ import_sndfile (*i, mode, track, pos);
+ }
+
+ interthread_progress_window->hide_all ();
+}
+
+void
+Editor::do_embed (vector<Glib::ustring> paths, bool split, ImportMode mode, AudioTrack* track, jack_nframes_t& pos, bool prompt)
+{
+ bool multiple_files = paths.size() > 1;
+ bool check_sample_rate = true;
+
+ for (vector<Glib::ustring>::iterator i = paths.begin(); i != paths.end(); ++i) {
+ embed_sndfile (*i, split, multiple_files, check_sample_rate, mode, track, pos, prompt);
+ }
+
+ session->save_state ("");
+}
+
+void
+Editor::import_sndfile (Glib::ustring path, ImportMode mode, AudioTrack* track, jack_nframes_t& pos)
+{
+ interthread_progress_window->set_title (string_compose (_("ardour: importing %1"), path));
+ interthread_progress_window->set_position (Gtk::WIN_POS_MOUSE);
+ interthread_progress_window->show_all ();
+ interthread_progress_bar.set_fraction (0.0f);
+ interthread_cancel_label.set_text (_("Cancel Import"));
+ current_interthread_info = &import_status;
+
+ import_status.pathname = path;
+ import_status.done = false;
+ import_status.cancel = false;
+ import_status.freeze = false;
+ import_status.done = 0.0;
+
+ interthread_progress_connection = Glib::signal_timeout().connect
+ (bind (mem_fun(*this, &Editor::import_progress_timeout), (gpointer) 0), 100);
+
+ track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
+ ARDOUR_UI::instance()->flush_pending ();
+
+ /* start import thread for this path. this will ultimately call Session::import_audiofile()
+ and if successful will add the file as a region to the session region list.
+ */
+
+ pthread_create_and_store ("import", &import_status.thread, 0, _import_thread, this);
+ pthread_detach (import_status.thread);
+
+ while (!(import_status.done || import_status.cancel)) {
+ gtk_main_iteration ();
+ }
+
+ import_status.done = true;
+ interthread_progress_connection.disconnect ();
+
+ /* import thread finished - see if we should build a new track */
+
+ if (!import_status.new_regions.empty()) {
+ AudioRegion& region (*import_status.new_regions.front());
+ finish_bringing_in_audio (region, region.n_channels(), region.n_channels(), track, pos, mode);
+ }
+
+ track_canvas.get_window()->set_cursor (*current_canvas_cursor);
+}
+
+void
+Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool& check_sample_rate, ImportMode mode,
+ AudioTrack* track, jack_nframes_t& pos, bool prompt)
+{
+ ExternalSource *source = 0; /* keep g++ quiet */
+ AudioRegion::SourceList sources;
+ string idspec;
+ string linked_path;
+ SoundFileInfo finfo;
+ string region_name;
+
+ track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
+ ARDOUR_UI::instance()->flush_pending ();
+
+ /* lets see if we can link it into the session */
+
+ linked_path = session->sound_dir();
+ linked_path += PBD::basename (path);
+
+ if (link (path.c_str(), linked_path.c_str()) == 0) {
+
+ /* there are many reasons why link(2) might have failed.
+ but if it succeeds, we now have a link in the
+ session sound dir that will protect against
+ unlinking of the original path. nice.
+ */
+
+ path = linked_path;
+ }
+
+ /* note that we temporarily truncated _id at the colon */
+
+ string error_msg;
+
+ if (!ExternalSource::get_soundfile_info (path, finfo, error_msg)) {
+ error << string_compose(_("Editor: cannot open file \"%1\", (%2)"), selection, error_msg ) << endmsg;
+ return;
+ }
+
+ if (check_sample_rate) {
+ switch (reject_because_rate_differs (path, finfo, "Embed", multiple_files)) {
+ case 0:
+ break;
+ case 1:
+ return;
+ case -1:
+ check_sample_rate = false;
+ break;
+
+ case -2:
+ default:
+ return;
+ }
+ }
+
+ track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
+ ARDOUR_UI::instance()->flush_pending ();
+
+ /* make the proper number of channels in the region */
+
+ for (int n = 0; n < finfo.channels; ++n)
+ {
+ idspec = path;
+ idspec += string_compose(":%1", n);
+
+ try {
+ source = ExternalSource::create (idspec.c_str());
+ sources.push_back(source);
+ }
+
+ catch (failed_constructor& err) {
+ error << string_compose(_("could not open %1"), path) << endmsg;
+ goto out;
+ }
+
+ ARDOUR_UI::instance()->flush_pending ();
+ }
+
+ if (sources.empty()) {
+ goto out;
+ }
+
+ region_name = PBD::basename_nosuffix (path);
+ region_name += "-0";
+
+ AudioRegion* region = new AudioRegion (sources, 0, sources[0]->length(), region_name, 0,
+ Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External));
+
+ uint32_t input_chan = finfo.channels;
+ uint32_t output_chan;
+
+ if (session->get_output_auto_connect() & Session::AutoConnectMaster) {
+ output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
+ } else {
+ output_chan = input_chan;
+ }
+
+ finish_bringing_in_audio (*region, input_chan, output_chan, track, pos, mode);
+
+ out:
+ track_canvas.get_window()->set_cursor (*current_canvas_cursor);
+}
+
+int
+Editor::finish_bringing_in_audio (AudioRegion& region, uint32_t in_chans, uint32_t out_chans, AudioTrack* track, jack_nframes_t& pos, ImportMode mode)
+{
+ switch (mode) {
+ case ImportAsRegion:
+ /* relax, its been done */
+ break;
+
+ case ImportToTrack:
+ if (track) {
+ Playlist* playlist = track->disk_stream().playlist();
+
+ AudioRegion* copy = new AudioRegion (region);
+ begin_reversible_command (_("insert sndfile"));
+ session->add_undo (playlist->get_memento());
+ playlist->add_region (*copy, pos);
+ session->add_redo_no_execute (playlist->get_memento());
+ commit_reversible_command ();
+
+ pos += region.length();
+ }
+ break;
+
+ case ImportAsTrack:
+ AudioTrack* at = session->new_audio_track (in_chans, out_chans);
+ AudioRegion* copy = new AudioRegion (region);
+ at->disk_stream().playlist()->add_region (*copy, pos);
+ break;
+ }
+
+ return 0;
+}
+
+int
+Editor::reject_because_rate_differs (Glib::ustring path, SoundFileInfo& finfo, const string & action, bool multiple_pending)
+{
+ if (!session) {
+ return 1;
+ }
+
+ if (finfo.samplerate != (int) session->frame_rate()) {
+ vector<string> choices;
+
+ choices.push_back (string_compose (_("%1 it anyway"), action));
+
+ if (multiple_pending) {
+ /* XXX assumptions about sentence structure
+ here for translators. Sorry.
+ */
+ choices.push_back (string_compose (_("Don't %1 it"), action));
+ choices.push_back (string_compose (_("%1 all without questions"), action));
+ choices.push_back (_("Cancel entire import"));
+ } else {
+ choices.push_back (_("Cancel"));
+ }
+
+ Gtkmm2ext::Choice rate_choice (
+ string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), path),
+ choices, false);
+
+ switch (rate_choice.run()) {
+ case 0: /* do it anyway */
+ return 0;
+ case 1: /* don't import this one */
+ return 1;
+ case 2: /* do the rest without asking */
+ return -1;
+ case 3: /* stop a multi-file import */
+ default:
+ return -2;
+ }
+ }
+
+ return 0;
+}
+
+void *
+Editor::_import_thread (void *arg)
+{
+ PBD::ThreadCreated (pthread_self(), X_("Import"));
+
+ Editor *ed = (Editor *) arg;
+ return ed->import_thread ();
+}
+
+void *
+Editor::import_thread ()
+{
+ session->import_audiofile (import_status);
+ pthread_exit_pbd (0);
+ /*NOTREACHED*/
+ return 0;
+}
+
+gint
+Editor::import_progress_timeout (void *arg)
+{
+ interthread_progress_label.set_text (import_status.doing_what);
+
+ if (import_status.freeze) {
+ interthread_cancel_button.set_sensitive(false);
+ } else {
+ interthread_cancel_button.set_sensitive(true);
+ }
+
+ if (import_status.doing_what == "building peak files") {
+ interthread_progress_bar.pulse ();
+ return FALSE;
+ } else {
+ interthread_progress_bar.set_fraction (import_status.progress);
+ }
+
+ return !(import_status.done || import_status.cancel);
+}
+
diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc
index c18bf867cd..92844124bd 100644
--- a/gtk2_ardour/editor_canvas.cc
+++ b/gtk2_ardour/editor_canvas.cc
@@ -455,7 +455,7 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context,
TimeAxisView* tvp;
AudioTimeAxisView* tv;
double cy;
- vector<string> paths;
+ vector<ustring> paths;
string spath;
GdkEvent ev;
jack_nframes_t frame;
@@ -484,22 +484,18 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context,
if ((tvp = trackview_by_y_position (cy)) == 0) {
- /* drop onto canvas background: create a new track */
-
- insert_paths_as_new_tracks (paths, false);
+ /* drop onto canvas background: create new tracks */
+ jack_nframes_t pos = 0;
+ do_embed (paths, false, ImportAsTrack, 0, pos, false);
} else if ((tv = dynamic_cast<AudioTimeAxisView*>(tvp)) != 0) {
/* check that its an audio track, not a bus */
-
+
if (tv->get_diskstream()) {
-
- for (vector<string>::iterator p = paths.begin(); p != paths.end(); ++p) {
- insert_sndfile_into (*p, true, tv, frame);
- }
+ do_embed (paths, false, ImportToTrack, tv->audio_track(), frame, true);
}
-
}
out:
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 6b38b904e1..4569b39182 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -333,6 +333,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
break;
case StreamItem:
+ set_selected_track_from_click (Keyboard::selection_type (event->button.state), true, true);
break;
case AutomationTrackItem:
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index f5baecb373..ba40d63fe7 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -198,12 +198,8 @@ Do you really want to destroy %1 ?"),
choices.push_back (_("No, do nothing."));
Gtkmm2ext::Choice prompter (prompt, choices);
-
- if (prompter.run () != RESPONSE_ACCEPT) {
- return;
- }
-
- if (prompter.get_choice() != 0) {
+
+ if (prompter.run() != 0) { /* first choice */
return;
}
@@ -1972,483 +1968,6 @@ Editor::interthread_cancel_clicked ()
}
}
-void *
-Editor::_import_thread (void *arg)
-{
- PBD::ThreadCreated (pthread_self(), X_("Import"));
-
- Editor *ed = (Editor *) arg;
- return ed->import_thread ();
-}
-
-void *
-Editor::import_thread ()
-{
- session->import_audiofile (import_status);
- return 0;
-}
-
-gint
-Editor::import_progress_timeout (void *arg)
-{
- interthread_progress_label.set_text (import_status.doing_what);
-
- if (import_status.freeze) {
- interthread_cancel_button.set_sensitive(false);
- } else {
- interthread_cancel_button.set_sensitive(true);
- }
-
- if (import_status.doing_what == "building peak files") {
- interthread_progress_bar.pulse ();
- return FALSE;
- } else {
- interthread_progress_bar.set_fraction (import_status.progress/100);
- }
-
- return !(import_status.done || import_status.cancel);
-}
-
-void
-Editor::import_audio (bool as_tracks)
-{
- if (session == 0) {
- warning << _("You can't import an audiofile until you have a session loaded.") << endmsg;
- return;
- }
-
- string str;
-
- if (as_tracks) {
- str =_("Import selected as tracks");
- } else {
- str = _("Import selected to region list");
- }
-
- SoundFileOmega sfdb (str);
- sfdb.Imported.connect (bind (mem_fun (*this, &Editor::do_import), as_tracks));
-
- sfdb.run();
-}
-
-void
-Editor::catch_new_audio_region (AudioRegion* ar)
-{
- last_audio_region = ar;
-}
-
-void
-Editor::do_import (vector<string> paths, bool split, bool as_tracks)
-{
- sigc::connection c;
-
- /* SFDB sets "multichan" to true to indicate "split channels"
- so reverse the setting to match the way libardour
- interprets it.
- */
-
- import_status.multichan = !split;
-
- if (interthread_progress_window == 0) {
- build_interthread_progress_window ();
- }
-
- interthread_progress_window->set_title (_("ardour: audio import in progress"));
- interthread_progress_window->set_position (Gtk::WIN_POS_MOUSE);
- interthread_progress_window->show_all ();
- interthread_progress_bar.set_fraction (0.0f);
- interthread_cancel_label.set_text (_("Cancel Import"));
- current_interthread_info = &import_status;
-
- c = session->AudioRegionAdded.connect (mem_fun(*this, &Editor::catch_new_audio_region));
-
- for (vector<string>::iterator i = paths.begin(); i != paths.end(); ++i ) {
-
- interthread_progress_window->set_title (string_compose (_("ardour: importing %1"), (*i)));
-
- import_status.pathname = (*i);
- import_status.done = false;
- import_status.cancel = false;
- import_status.freeze = false;
- import_status.done = 0.0;
-
- interthread_progress_connection =
- Glib::signal_timeout().connect (bind (mem_fun(*this, &Editor::import_progress_timeout), (gpointer) 0), 100);
-
- last_audio_region = 0;
-
- pthread_create_and_store ("import", &import_status.thread, 0, _import_thread, this);
- pthread_detach (import_status.thread);
-
- while (!(import_status.done || import_status.cancel)) {
- gtk_main_iteration ();
- }
-
- import_status.done = true;
- interthread_progress_connection.disconnect ();
-
- if (as_tracks && last_audio_region != 0) {
- uint32_t channels = last_audio_region->n_channels();
-
- AudioTrack* at = session->new_audio_track (channels, channels);
- AudioRegion* copy = new AudioRegion (*last_audio_region);
- at->disk_stream().playlist()->add_region (*copy, 0);
- }
- }
-
- c.disconnect ();
- interthread_progress_window->hide_all ();
-}
-
-int
-Editor::reject_because_rate_differs (const string & path, SoundFileInfo& finfo, const string & action, bool multiple_pending)
-{
- if (!session) {
- return 1;
- }
-
- if (finfo.samplerate != (int) session->frame_rate()) {
- vector<string> choices;
-
- choices.push_back (string_compose (_("%1 it anyway"), action));
-
- if (multiple_pending) {
- /* XXX assumptions about sentence structure
- here for translators. Sorry.
- */
- choices.push_back (string_compose (_("Don't %1 it"), action));
- choices.push_back (string_compose (_("%1 all without questions"), action));
- choices.push_back (_("Cancel entire import"));
- } else {
- choices.push_back (_("Cancel"));
- }
-
- Gtkmm2ext::Choice rate_choice (
- string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), path),
- choices);
-
- int response = rate_choice.run();
-
- switch (response) {
- case RESPONSE_ACCEPT:
- break;
- default:
- /* stop all that might come after this */
- return -2;
- break;
- }
-
- switch (rate_choice.get_choice()) {
- case 0: /* do it anyway */
- return 0;
- case 1: /* don't import this one */
- return 1;
- case 2: /* do the rest without asking */
- return -1;
- case 3: /* stop a multi-file import */
- default:
- return -2;
- }
- }
-
- return 0;
-}
-
-void
-Editor::embed_audio ()
-{
- if (session == 0) {
- warning << _("You can't embed an audiofile until you have a session loaded.") << endmsg;
- return;
- }
-
- SoundFileOmega sfdb (_("Add to External Region list"));
- sfdb.Embedded.connect (mem_fun (*this, &Editor::do_embed_sndfiles));
-
- sfdb.run ();
-}
-
-void
-Editor::do_embed_sndfiles (vector<string> paths, bool split)
-{
- bool multiple_files = paths.size() > 1;
- bool check_sample_rate = true;
-
- for (vector<string>::iterator i = paths.begin(); i != paths.end(); ++i) {
- embed_sndfile (*i, split, multiple_files, check_sample_rate);
- }
-
- session->save_state ("");
-}
-
-void
-Editor::embed_sndfile (string path, bool split, bool multiple_files, bool& check_sample_rate)
-{
- ExternalSource *source = 0; /* keep g++ quiet */
- AudioRegion::SourceList sources;
- string idspec;
- string linked_path;
- SoundFileInfo finfo;
-
- /* lets see if we can link it into the session */
-
- linked_path = session->sound_dir();
- linked_path += PBD::basename (path);
-
- if (link (path.c_str(), linked_path.c_str()) == 0) {
-
- /* there are many reasons why link(2) might have failed.
- but if it succeeds, we now have a link in the
- session sound dir that will protect against
- unlinking of the original path. nice.
- */
-
- path = linked_path;
- }
-
- /* note that we temporarily truncated _id at the colon */
- string error_msg;
- if (!ExternalSource::get_soundfile_info (path, finfo, error_msg)) {
- error << string_compose(_("Editor: cannot open file \"%1\", (%2)"), selection, error_msg ) << endmsg;
- return;
- }
-
- if (check_sample_rate) {
- switch (reject_because_rate_differs (path, finfo, "Embed", multiple_files)) {
- case 0:
- break;
- case 1:
- return;
- case -1:
- check_sample_rate = false;
- break;
-
- case -2:
- default:
- return;
- }
- }
-
- track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
- ARDOUR_UI::instance()->flush_pending ();
-
- /* make the proper number of channels in the region */
-
- for (int n=0; n < finfo.channels; ++n)
- {
- idspec = path;
- idspec += string_compose(":%1", n);
-
- try {
- source = ExternalSource::create (idspec.c_str());
- sources.push_back(source);
- }
-
- catch (failed_constructor& err) {
- error << string_compose(_("could not open %1"), path) << endmsg;
- goto out;
- }
-
- ARDOUR_UI::instance()->flush_pending ();
- }
-
- if (sources.size() > 0) {
-
- string region_name = PBD::basename_nosuffix (path);
- region_name += "-0";
-
- /* The created region isn't dropped. It emits a signal
- that is picked up by the session.
- */
-
- new AudioRegion (sources, 0, sources[0]->length(), region_name, 0,
- Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External));
-
- /* make sure we can see it in the list */
-
- /* its the second node, always */
-
- // GTK2FIX ?? is it still always the 2nd node
-
- TreeModel::Path path ("2");
- region_list_display.expand_row (path, true);
-
- ARDOUR_UI::instance()->flush_pending ();
- }
-
- out:
- track_canvas.get_window()->set_cursor (*current_canvas_cursor);
-}
-
-void
-Editor::insert_sndfile (bool as_tracks)
-{
-// SoundFileSelector& sfdb (ARDOUR_UI::instance()->get_sfdb_window());
- sigc::connection c;
- string str;
-
- if (as_tracks) {
-
-// c = sfdb.Action.connect (mem_fun(*this, &Editor::insert_paths_as_new_tracks));
- str = _("Insert selected as new tracks");
-
- } else {
-
- jack_nframes_t pos;
-
- if (clicked_audio_trackview == 0) {
- return;
- }
-
- if (ensure_cursor (&pos)) {
- return;
- }
-
-// c = sfdb.Action.connect (bind (mem_fun(*this, &Editor::do_insert_sndfile), pos));
- str = _("Insert selected");
- }
-
-// sfdb.run (str, false);
-// c.disconnect ();
-}
-
-void
-Editor::insert_paths_as_new_tracks (vector<string> paths, bool split)
-{
- SoundFileInfo finfo;
- bool multiple_files;
- bool check_sample_rate = true;
- string error_msg;
-
- multiple_files = paths.size() > 1;
-
- for (vector<string>::iterator p = paths.begin(); p != paths.end(); ++p) {
-
- if (!ExternalSource::get_soundfile_info((*p), finfo, error_msg)) {
- error << string_compose(_("Editor: cannot open file \"%1\" (%2)"), (*p), error_msg) << endmsg;
- continue;
- }
-
- /* add a new track */
-
- if (check_sample_rate) {
- switch (reject_because_rate_differs (*p, finfo, "Insert", multiple_files)) {
- case 0:
- break;
- case 1:
- continue;
- case -1:
- check_sample_rate = false;
- break;
-
- case -2:
- return;
- }
- }
-
- uint32_t input_chan = finfo.channels;
- uint32_t output_chan;
-
- if (session->get_output_auto_connect() & Session::AutoConnectMaster) {
- output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
- } else {
- output_chan = input_chan;
- }
-
- (void) session->new_audio_track (input_chan, output_chan);
-
-
- /* get the last (most recently added) track view */
-
- AudioTimeAxisView* tv;
-
- if ((tv = dynamic_cast<AudioTimeAxisView*>(track_views.back())) == 0) {
- fatal << _("programming error: ")
- << X_("last trackview after new_audio_track is not an audio track!")
- << endmsg;
- /*NOTREACHED*/
- }
-
- jack_nframes_t pos = 0;
- insert_sndfile_into (*p, true, tv, pos, false);
- }
-}
-
-void
-Editor::do_insert_sndfile (vector<string> paths, bool split, jack_nframes_t pos)
-{
- for (vector<string>::iterator x = paths.begin(); x != paths.end(); ++x) {
- insert_sndfile_into (*x, !split, clicked_audio_trackview, pos);
- }
-}
-
-void
-Editor::insert_sndfile_into (const string & path, bool multi, AudioTimeAxisView* tv, jack_nframes_t& pos, bool prompt)
-{
- ExternalSource *source = 0; /* keep g++ quiet */
- AudioRegion::SourceList sources;
- string idspec;
- SoundFileInfo finfo;
- string error_msg;
-
- /* note that we temporarily truncated _id at the colon */
-
- if (!ExternalSource::get_soundfile_info (path, finfo, error_msg)) {
- error << string_compose(_("Editor: cannot open file \"%1\" (%2)"), path, error_msg) << endmsg;
- return;
- }
-
- if (prompt && (reject_because_rate_differs (path, finfo, "Insert", false) != 0)) {
- return;
- }
-
- track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
- ARDOUR_UI::instance()->flush_pending ();
-
- /* make the proper number of channels in the region */
-
- for (int n=0; n < finfo.channels; ++n)
- {
- idspec = path;
- idspec += string_compose(":%1", n);
-
- try {
- source = ExternalSource::create (idspec.c_str());
- sources.push_back(source);
- }
-
- catch (failed_constructor& err) {
- error << string_compose(_("could not open %1"), path) << endmsg;
- goto out;
- }
-
- ARDOUR_UI::instance()->flush_pending ();
- }
-
- if (sources.size() > 0) {
-
- string region_name = region_name_from_path (PBD::basename (path));
-
- AudioRegion *region = new AudioRegion (sources, 0, sources[0]->length(), region_name,
- 0, /* irrelevant these days */
- Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External));
-
- begin_reversible_command (_("insert sndfile"));
- session->add_undo (tv->playlist()->get_memento());
- tv->playlist()->add_region (*region, pos);
- session->add_redo_no_execute (tv->playlist()->get_memento());
- commit_reversible_command ();
-
- pos += sources[0]->length();
-
- ARDOUR_UI::instance()->flush_pending ();
- }
-
- out:
- track_canvas.get_window()->set_cursor (*current_canvas_cursor);
- return;
-}
-
void
Editor::region_from_selection ()
{
@@ -3552,10 +3071,8 @@ Editor::remove_last_capture ()
Gtkmm2ext::Choice prompter (prompt, choices);
- if (prompter.run () == RESPONSE_ACCEPT) {
- if (prompter.get_choice() == 0) {
- session->remove_last_capture ();
- }
+ if (prompter.run () == 0) {
+ session->remove_last_capture ();
}
} else {
diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc
index 464a707512..4506b69b5e 100644
--- a/gtk2_ardour/editor_region_list.cc
+++ b/gtk2_ardour/editor_region_list.cc
@@ -574,10 +574,11 @@ Editor::region_list_display_drag_data_received (const RefPtr<Gdk::DragContext>&
const SelectionData& data,
guint info, guint time)
{
- vector<string> paths;
+ vector<ustring> paths;
if (convert_drop_to_paths (paths, context, x, y, data, info, time) == 0) {
- do_embed_sndfiles (paths, false);
+ jack_nframes_t pos = 0;
+ do_embed (paths, false, ImportAsRegion, 0, pos, true);
context->drag_finish (true, false, time);
}
}
diff --git a/gtk2_ardour/redirect_box.cc b/gtk2_ardour/redirect_box.cc
index e95596fbf9..a9cb78d5c4 100644
--- a/gtk2_ardour/redirect_box.cc
+++ b/gtk2_ardour/redirect_box.cc
@@ -900,10 +900,8 @@ RedirectBox::clear_redirects()
Gtkmm2ext::Choice prompter (prompt, choices);
- if (prompter.run () == RESPONSE_ACCEPT) {
- if (prompter.get_choice() == 0) {
- _route.clear_redirects (this);
- }
+ if (prompter.run () == 0) {
+ _route.clear_redirects (this);
}
}
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc
index bf286e36f0..a96ca82009 100644
--- a/gtk2_ardour/route_ui.cc
+++ b/gtk2_ardour/route_ui.cc
@@ -703,12 +703,8 @@ RouteUI::remove_this_route ()
Choice prompter (prompt, choices);
- prompter.show_all ();
-
- if (prompter.run () == RESPONSE_ACCEPT) {
- if (prompter.get_choice() == 0) {
- Glib::signal_idle().connect (bind (sigc::ptr_fun (&RouteUI::idle_remove_this_route), this));
- }
+ if (prompter.run () == 0) {
+ Glib::signal_idle().connect (bind (sigc::ptr_fun (&RouteUI::idle_remove_this_route), this));
}
}
diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc
index 3c8f258f4a..69c8200dd5 100644
--- a/gtk2_ardour/sfdb_ui.cc
+++ b/gtk2_ardour/sfdb_ui.cc
@@ -22,11 +22,13 @@
#include <map>
#include <cerrno>
-#include <pbd/basename.h>
-
#include <gtkmm/box.h>
#include <gtkmm/stock.h>
+#include <pbd/basename.h>
+
+#include <gtkmm2ext/utils.h>
+
#include <ardour/audio_library.h>
#include <ardour/audioregion.h>
#include <ardour/externalsource.h>
@@ -34,12 +36,14 @@
#include "gui_thread.h"
#include "prompter.h"
#include "sfdb_ui.h"
+#include "utils.h"
#include "i18n.h"
using namespace ARDOUR;
+using namespace std;
-std::string length2string (const int32_t frames, const float sample_rate);
+string length2string (const int32_t frames, const float sample_rate);
SoundFileBox::SoundFileBox ()
:
@@ -264,8 +268,8 @@ SoundFileBox::delete_row (const Gtk::TreeModel::iterator& iter)
void
SoundFileBox::audition_status_changed (bool active)
{
- ENSURE_GUI_THREAD(bind (mem_fun (*this, &SoundFileBox::audition_status_changed), active));
-
+ ENSURE_GUI_THREAD(bind (mem_fun (*this, &SoundFileBox::audition_status_changed), active));
+
if (!active) {
stop_btn_clicked ();
}
@@ -281,13 +285,13 @@ SoundFileBox::field_selected ()
}
}
-SoundFileBrowser::SoundFileBrowser (std::string title)
- :
- ArdourDialog(title),
- chooser(Gtk::FILE_CHOOSER_ACTION_OPEN)
+SoundFileBrowser::SoundFileBrowser (string title)
+ : ArdourDialog (title, false),
+ chooser (Gtk::FILE_CHOOSER_ACTION_OPEN)
{
get_vbox()->pack_start(chooser);
chooser.set_preview_widget(preview);
+ chooser.set_select_multiple (true);
chooser.signal_update_preview().connect(mem_fun(*this, &SoundFileBrowser::update_preview));
}
@@ -304,63 +308,117 @@ SoundFileBrowser::update_preview ()
chooser.set_preview_widget_active(preview.setup_labels(chooser.get_filename()));
}
-SoundFileChooser::SoundFileChooser (std::string title)
+SoundFileChooser::SoundFileChooser (string title)
:
SoundFileBrowser(title)
{
add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
-
show_all ();
}
-SoundFileOmega::SoundFileOmega (std::string title)
- :
- SoundFileBrowser(title),
- embed_btn (_("Embed")),
- import_btn (_("Import")),
- split_check (_("Split Channels"))
+static const char *import_mode_strings[] = {
+ X_("Add to Region list"),
+ X_("Add as new Track(s)"),
+ X_("Add to selected Track(s)"),
+ 0
+};
+
+vector<string> SoundFileOmega::mode_strings;
+
+SoundFileOmega::SoundFileOmega (string title)
+ : SoundFileBrowser (title),
+ split_check (_("Split Channels"))
{
- get_action_area()->pack_start(embed_btn);
- get_action_area()->pack_start(import_btn);
+ if (mode_strings.empty()) {
+ mode_strings = internationalize (import_mode_strings);
+ }
+
+ add_button (_("Embed"), ResponseEmbed);
+ add_button (_("Import"), ResponseImport);
add_button (Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE);
- chooser.set_extra_widget(split_check);
+ Gtk::HBox *box = manage (new Gtk::HBox());
+
+ Gtkmm2ext::set_popdown_strings (mode_combo, mode_strings);
+
+ set_mode (Editing::ImportAsRegion);
- embed_btn.signal_clicked().connect (mem_fun (*this, &SoundFileOmega::embed_clicked));
- import_btn.signal_clicked().connect (mem_fun (*this, &SoundFileOmega::import_clicked));
+ box->pack_start (split_check);
+ box->pack_start (mode_combo);
+ mode_combo.signal_changed().connect (mem_fun (*this, &SoundFileOmega::mode_changed));
+
+ chooser.set_extra_widget (*box);
+
show_all ();
}
-void
-SoundFileOmega::embed_clicked ()
+bool
+SoundFileOmega::get_split ()
+{
+ return split_check.get_active();
+}
+
+vector<Glib::ustring>
+SoundFileOmega::get_paths ()
{
- Embedded (chooser.get_filenames(), split_check.get_active());
+ return chooser.get_filenames();
}
void
-SoundFileOmega::import_clicked ()
+SoundFileOmega::set_mode (Editing::ImportMode mode)
{
- Imported (chooser.get_filenames(), split_check.get_active());
+ mode_combo.set_active_text (mode_strings[(int)mode]);
+
+ switch (mode) {
+ case Editing::ImportAsRegion:
+ split_check.set_sensitive (true);
+ break;
+ case Editing::ImportAsTrack:
+ split_check.set_sensitive (true);
+ break;
+ case Editing::ImportToTrack:
+ split_check.set_sensitive (false);
+ break;
+ }
}
-std::string
-length2string (const int32_t frames, const float sample_rate)
+Editing::ImportMode
+SoundFileOmega::get_mode ()
{
- int secs = (int) (frames / sample_rate);
- int hrs = secs / 3600;
- secs -= (hrs * 3600);
- int mins = secs / 60;
- secs -= (mins * 60);
+ vector<string>::iterator i;
+ uint32_t n;
+ string str = mode_combo.get_active_text ();
- int total_secs = (hrs * 3600) + (mins * 60) + secs;
- int frames_remaining = frames - (total_secs * sample_rate);
- float fractional_secs = (float) frames_remaining / sample_rate;
+ for (n = 0, i = mode_strings.begin (); i != mode_strings.end(); ++i, ++n) {
+ if (str == (*i)) {
+ break;
+ }
+ }
- char duration_str[32];
- sprintf (duration_str, "%02d:%02d:%05.2f", hrs, mins, (float) secs + fractional_secs);
+ if (i == mode_strings.end()) {
+ fatal << string_compose (_("programming error: %1"), X_("unknown import mode string")) << endmsg;
+ /*NOTREACHED*/
+ }
- return duration_str;
+ return (Editing::ImportMode) (n);
}
+void
+SoundFileOmega::mode_changed ()
+{
+ Editing::ImportMode mode = get_mode();
+
+ switch (mode) {
+ case Editing::ImportAsRegion:
+ split_check.set_sensitive (true);
+ break;
+ case Editing::ImportAsTrack:
+ split_check.set_sensitive (true);
+ break;
+ case Editing::ImportToTrack:
+ split_check.set_sensitive (false);
+ break;
+ }
+}
diff --git a/gtk2_ardour/sfdb_ui.h b/gtk2_ardour/sfdb_ui.h
index 10a5e9e0fc..9d730bc3cd 100644
--- a/gtk2_ardour/sfdb_ui.h
+++ b/gtk2_ardour/sfdb_ui.h
@@ -33,6 +33,7 @@
#include <gtkmm/dialog.h>
#include <gtkmm/entry.h>
#include <gtkmm/filechooserwidget.h>
+#include <gtkmm/comboboxtext.h>
#include <gtkmm/frame.h>
#include <gtkmm/label.h>
#include <gtkmm/liststore.h>
@@ -42,6 +43,7 @@
#include <ardour/externalsource.h>
#include "ardour_dialog.h"
+#include "editing.h"
class SoundFileBox : public Gtk::VBox
{
@@ -110,7 +112,8 @@ class SoundFileBrowser : public ArdourDialog
SoundFileBrowser (std::string title);
virtual ~SoundFileBrowser () {};
- virtual void set_session (ARDOUR::Session*);
+ virtual void set_session (ARDOUR::Session*);
+
protected:
Gtk::FileChooserWidget chooser;
SoundFileBox preview;
@@ -133,16 +136,27 @@ class SoundFileOmega : public SoundFileBrowser
SoundFileOmega (std::string title);
virtual ~SoundFileOmega () {};
- sigc::signal<void, std::vector<std::string>, bool> Embedded;
- sigc::signal<void, std::vector<std::string>, bool> Imported;
+ /* these are returned by the Dialog::run() method. note
+ that builtin GTK responses are all negative, leaving
+ positive values for application-defined responses.
+ */
+
+ const static int ResponseImport = 1;
+ const static int ResponseEmbed = 2;
+
+ std::vector<Glib::ustring> get_paths ();
+ bool get_split ();
+
+ void set_mode (Editing::ImportMode);
+ Editing::ImportMode get_mode ();
protected:
- Gtk::Button embed_btn;
- Gtk::Button import_btn;
- Gtk::CheckButton split_check;
+ Gtk::CheckButton split_check;
+ Gtk::ComboBoxText mode_combo;
+
+ void mode_changed ();
- void embed_clicked ();
- void import_clicked ();
+ static std::vector<std::string> mode_strings;
};
#endif // __ardour_sfdb_ui_h__
diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc
index c0f1a9eaa8..c96f9a3da1 100644
--- a/gtk2_ardour/utils.cc
+++ b/gtk2_ardour/utils.cc
@@ -592,3 +592,21 @@ get_xpm (std::string name)
return (xpm_map[name]);
}
+string
+length2string (const int32_t frames, const float sample_rate)
+{
+ int secs = (int) (frames / sample_rate);
+ int hrs = secs / 3600;
+ secs -= (hrs * 3600);
+ int mins = secs / 60;
+ secs -= (mins * 60);
+
+ int total_secs = (hrs * 3600) + (mins * 60) + secs;
+ int frames_remaining = frames - (total_secs * sample_rate);
+ float fractional_secs = (float) frames_remaining / sample_rate;
+
+ char duration_str[32];
+ sprintf (duration_str, "%02d:%02d:%05.2f", hrs, mins, (float) secs + fractional_secs);
+
+ return duration_str;
+}
diff --git a/gtk2_ardour/utils.h b/gtk2_ardour/utils.h
index 983753a0dd..608ba10529 100644
--- a/gtk2_ardour/utils.h
+++ b/gtk2_ardour/utils.h
@@ -80,5 +80,6 @@ bool key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev);
Glib::RefPtr<Gdk::Pixbuf> get_xpm(std::string);
static std::map<std::string, Glib::RefPtr<Gdk::Pixbuf> > xpm_map;
const char* const *get_xpm_data (std::string path);
+std::string length2string (const int32_t frames, const float sample_rate);
#endif /* __ardour_gtk_utils_h__ */
diff --git a/gtk2_ardour/visual_time_axis.cc b/gtk2_ardour/visual_time_axis.cc
index 23af21aaca..582c18c86f 100644
--- a/gtk2_ardour/visual_time_axis.cc
+++ b/gtk2_ardour/visual_time_axis.cc
@@ -279,14 +279,12 @@ VisualTimeAxis::remove_this_time_axis(void* src)
Gtkmm2ext::Choice prompter (prompt, choices);
- if (prompter.run () == RESPONSE_ACCEPT) {
- if (prompter.get_choice() == 0) {
- /*
- defer to idle loop, otherwise we'll delete this object
- while we're still inside this function ...
- */
- Glib::signal_idle().connect(bind(sigc::ptr_fun(&VisualTimeAxis::idle_remove_this_time_axis), this, src));
- }
+ if (prompter.run () == 0) {
+ /*
+ defer to idle loop, otherwise we'll delete this object
+ while we're still inside this function ...
+ */
+ Glib::signal_idle().connect(bind(sigc::ptr_fun(&VisualTimeAxis::idle_remove_this_time_axis), this, src));
}
}