diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2007-08-26 01:54:34 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2007-08-26 01:54:34 +0000 |
commit | 45199451e0af09e33a02479aa7383f98186f4dcd (patch) | |
tree | 78ec97a1a09716dbd1f9595b6f0a9b5bce9e7ac9 | |
parent | 3dc5ac4b96ff4183a91007999b10d2c3553518b5 (diff) |
round one of import design changes (still not fully functional, but basic stuff works
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2346 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | gtk2_ardour/ardour.bindings.in | 7 | ||||
-rw-r--r-- | gtk2_ardour/ardour.menus | 8 | ||||
-rw-r--r-- | gtk2_ardour/ardour_dialog.cc | 9 | ||||
-rw-r--r-- | gtk2_ardour/ardour_dialog.h | 1 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/editor.cc | 5 | ||||
-rw-r--r-- | gtk2_ardour/editor.h | 15 | ||||
-rw-r--r-- | gtk2_ardour/editor_actions.cc | 4 | ||||
-rw-r--r-- | gtk2_ardour/editor_audio_import.cc | 99 | ||||
-rw-r--r-- | gtk2_ardour/editor_canvas.cc | 4 | ||||
-rw-r--r-- | gtk2_ardour/editor_region_list.cc | 2 | ||||
-rw-r--r-- | gtk2_ardour/editor_selection.cc | 4 | ||||
-rw-r--r-- | gtk2_ardour/sfdb_ui.cc | 411 | ||||
-rw-r--r-- | gtk2_ardour/sfdb_ui.h | 97 |
14 files changed, 387 insertions, 281 deletions
diff --git a/gtk2_ardour/ardour.bindings.in b/gtk2_ardour/ardour.bindings.in index d8316a0147..8877d75501 100644 --- a/gtk2_ardour/ardour.bindings.in +++ b/gtk2_ardour/ardour.bindings.in @@ -20,6 +20,7 @@ ; (gtk_accel_path "<Actions>/redirectmenu/deactivate_all" "") ; (gtk_accel_path "<Actions>/RegionList/SortByRegionPosition" "") ; (gtk_accel_path "<Actions>/Editor/ZoomFocus" "") +(gtk_accel_path "<Actions>/Editor/addExistingAudioFiles" "<Alt>i") ; (gtk_accel_path "<Actions>/options/MeterFalloffSlow" "") ; (gtk_accel_path "<Actions>/RegionList/rlHide" "") ; (gtk_accel_path "<Actions>/Main/Metering" "") @@ -53,7 +54,6 @@ ; (gtk_accel_path "<Actions>/Snap/snap-to-region-end" "") (gtk_accel_path "<Actions>/Editor/edit-cursor-to-next-region-sync" "semicolon") ; (gtk_accel_path "<Actions>/options/StopRecordingOnXrun" "") -; (gtk_accel_path "<Actions>/Editor/addExternalAudioToRegionList" "") ; (gtk_accel_path "<Actions>/RegionList/SortDescending" "") ; (gtk_accel_path "<Actions>/options/DoNotRunPluginsWhileRecording" "") ; (gtk_accel_path "<Actions>/Editor/PullupNone" "") @@ -96,7 +96,6 @@ (gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-start" "comma") ; (gtk_accel_path "<Actions>/Editor/EditCursorMovementOptions" "") ; (gtk_accel_path "<Actions>/redirectmenu/activate_all" "") -; (gtk_accel_path "<Actions>/Editor/addExternalAudioAsTapeTrack" "") ; (gtk_accel_path "<Actions>/redirectmenu/paste" "") ; (gtk_accel_path "<Actions>/Editor/Smpte25" "") ; (gtk_accel_path "<Actions>/options/RegionEquivalentsOverlap" "") @@ -194,7 +193,6 @@ ; (gtk_accel_path "<Actions>/Editor/Smpte2997" "") ; (gtk_accel_path "<Actions>/Editor/ToggleWaveformVisibility" "") (gtk_accel_path "<Actions>/Editor/redo" "<Control>r") -; (gtk_accel_path "<Actions>/Editor/addExternalAudioAsRegion" "") ; (gtk_accel_path "<Actions>/Main/ExportSession" "") ; (gtk_accel_path "<Actions>/options/InputAutoConnectPhysical" "") ; (gtk_accel_path "<Actions>/Snap/snap-to-edit-cursor" "") @@ -204,7 +202,6 @@ ; (gtk_accel_path "<Actions>/redirectmenu/rename" "") ; (gtk_accel_path "<Actions>/RegionList/rlShowAuto" "") (gtk_accel_path "<Actions>/Editor/select-all-before-playhead" "<Control>p") -; (gtk_accel_path "<Actions>/Editor/addExistingAudioFiles" "") ; (gtk_accel_path "<Actions>/Main/Session" "") (gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-start" "F1") ; (gtk_accel_path "<Actions>/Main/AudioFileFormat" "") @@ -228,13 +225,11 @@ (gtk_accel_path "<Actions>/Common/ToggleOptionsEditor" "<Control>o") ; (gtk_accel_path "<Actions>/Editor/PullupMinus4" "") (gtk_accel_path "<Actions>/Common/goto-mixer" "<Alt>m") -; (gtk_accel_path "<Actions>/Editor/addExternalAudioToTrack" "") ; (gtk_accel_path "<Actions>/RegionList/SortBySourceFileCreationDate" "") ; (gtk_accel_path "<Actions>/redirectmenu/activate" "") (gtk_accel_path "<Actions>/Editor/extend-range-to-start-of-region" "leftanglebracket") ; (gtk_accel_path "<Actions>/Editor/PullupMinus1" "") ; (gtk_accel_path "<Actions>/Editor/snap-normal" "") -; (gtk_accel_path "<Actions>/Editor/addExternalAudioAsTrack" "") (gtk_accel_path "<Actions>/Common/ToggleBigClock" "<Alt>b") ; (gtk_accel_path "<Actions>/Snap/snap-to-asixteenthbeat" "") (gtk_accel_path "<Actions>/Editor/select-all-in-punch-range" "<Control>d") diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus index 71a15a7bd3..953254b07c 100644 --- a/gtk2_ardour/ardour.menus +++ b/gtk2_ardour/ardour.menus @@ -13,13 +13,7 @@ <separator/> <menuitem action='AddTrackBus'/> <separator/> - <menu action='addExistingAudioFiles'> - <menuitem action='addExternalAudioAsRegion'/> - <menuitem action='addExternalAudioToTrack'/> - <separator/> - <menuitem action='addExternalAudioAsTrack'/> - <menuitem action='addExternalAudioAsTapeTrack'/> - </menu> + <menuitem action='addExistingAudioFiles'/> <separator/> <menu name='Export' action='Export'> <menuitem action='ExportSession'/> diff --git a/gtk2_ardour/ardour_dialog.cc b/gtk2_ardour/ardour_dialog.cc index c5162919d4..795b924075 100644 --- a/gtk2_ardour/ardour_dialog.cc +++ b/gtk2_ardour/ardour_dialog.cc @@ -34,6 +34,15 @@ ArdourDialog::ArdourDialog (string title, bool modal, bool use_seperator) set_type_hint(Gdk::WINDOW_TYPE_HINT_DIALOG); } +ArdourDialog::ArdourDialog (Gtk::Window& parent, string title, bool modal, bool use_seperator) + : Dialog (title, parent, modal, use_seperator) +{ + session = 0; + + set_type_hint(Gdk::WINDOW_TYPE_HINT_DIALOG); + set_position (Gtk::WIN_POS_CENTER_ON_PARENT); +} + ArdourDialog::~ArdourDialog () { } diff --git a/gtk2_ardour/ardour_dialog.h b/gtk2_ardour/ardour_dialog.h index 069768c143..e0cdb97cdc 100644 --- a/gtk2_ardour/ardour_dialog.h +++ b/gtk2_ardour/ardour_dialog.h @@ -37,6 +37,7 @@ class ArdourDialog : public Gtk::Dialog { public: ArdourDialog (std::string title, bool modal = false, bool use_separator = false); + ArdourDialog (Gtk::Window& parent, std::string title, bool modal = false, bool use_separator = false); ~ArdourDialog(); bool on_enter_notify_event (GdkEventCrossing*); diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 806872f0b2..5e27900f6b 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -400,7 +400,7 @@ ARDOUR_UI::configure_handler (GdkEventConfigure* conf) Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100); have_configure_timeout = true; } - + return FALSE; } diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index d3d7234f9b..0fa6ee0f34 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -2861,7 +2861,7 @@ void Editor::begin_reversible_command (string name) { if (session) { - before = &get_state(); + // before = &get_state(); session->begin_reversible_command (name); } } @@ -2870,7 +2870,8 @@ void Editor::commit_reversible_command () { if (session) { - session->commit_reversible_command (new MementoCommand<Editor>(*this, before, &get_state())); + // session->commit_reversible_command (new MementoCommand<Editor>(*this, before, &get_state())); + session->commit_reversible_command (); } } diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 28b6a0f245..42790fb42a 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -25,6 +25,7 @@ #include <set> #include <string> #include <sys/time.h> +#include <glibmm/ustring.h> #include <boost/optional.hpp> @@ -961,17 +962,19 @@ class Editor : public PublicEditor void insert_region_list_selection (float times); void add_external_audio_action (Editing::ImportMode); + void external_audio_dialog (); + bool check_multichannel_status (const std::vector<Glib::ustring>& paths); - void bring_in_external_audio (Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes_t& pos, bool prompt); - void do_import (vector<Glib::ustring> paths, bool split, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes_t&, bool); + void bring_in_external_audio (Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes_t& pos); + void do_import (vector<Glib::ustring> paths, bool split, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes_t&); - void _do_embed (vector<Glib::ustring> paths, bool split, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes_t&, bool); - void do_embed (vector<Glib::ustring> paths, bool split, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes_t&, bool); - bool idle_do_embed (vector<Glib::ustring> paths, bool split, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes_t&, bool); + void _do_embed (vector<Glib::ustring> paths, bool split, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes_t&); + void do_embed (vector<Glib::ustring> paths, bool split, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes_t&); + bool idle_do_embed (vector<Glib::ustring> paths, bool split, Editing::ImportMode mode, ARDOUR::AudioTrack*, nframes_t&); int import_sndfile (vector<Glib::ustring> paths, Editing::ImportMode mode, ARDOUR::AudioTrack* track, nframes_t& pos); int embed_sndfile (vector<Glib::ustring> paths, bool split, bool multiple_files, bool& check_sample_rate, Editing::ImportMode mode, - ARDOUR::AudioTrack* track, nframes_t& pos, bool prompt); + ARDOUR::AudioTrack* track, nframes_t& pos); int finish_bringing_in_audio (boost::shared_ptr<ARDOUR::AudioRegion> region, uint32_t, uint32_t, ARDOUR::AudioTrack* track, nframes_t& pos, Editing::ImportMode mode); /* generic interthread progress window */ diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index 3036d55d10..1b1edb7931 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -62,7 +62,6 @@ Editor::register_actions () ActionManager::register_action (editor_actions, X_("Timecode"), _("Timecode fps")); ActionManager::register_action (editor_actions, X_("Pullup"), _("Pullup / Pulldown")); ActionManager::register_action (editor_actions, X_("Subframes"), _("Subframes")); - ActionManager::register_action (editor_actions, X_("addExistingAudioFiles"), _("Add Existing Audio")); /* add named actions for the editor */ @@ -378,6 +377,9 @@ Editor::register_actions () /* the next two are duplicate items with different names for use in two different contexts */ + ActionManager::register_action (editor_actions, X_("addExistingAudioFiles"), _("Add Existing Audio"), mem_fun (*this, &Editor::external_audio_dialog)); + + 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)); diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc index 2a81f85d7f..d0b5f6dfa1 100644 --- a/gtk2_ardour/editor_audio_import.cc +++ b/gtk2_ardour/editor_audio_import.cc @@ -22,6 +22,8 @@ #include <errno.h> #include <unistd.h> +#include <sndfile.h> + #include <pbd/pthread_utils.h> #include <pbd/basename.h> #include <pbd/shortpath.h> @@ -74,37 +76,86 @@ Editor::add_external_audio_action (ImportMode mode) } } - bring_in_external_audio (mode, track, pos, false); + bring_in_external_audio (mode, track, pos); } + void -Editor::bring_in_external_audio (ImportMode mode, AudioTrack* track, nframes_t& pos, bool prompt) +Editor::external_audio_dialog () { + vector<Glib::ustring> paths; + 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"), session); - sfdb.set_mode (mode); + SoundFileBrowser browser (_("Add existing audio"), session); + SoundFileOptionsDialog* options = 0; - switch (sfdb.run()) { - case SoundFileOmega::ResponseImport: - do_import (sfdb.get_paths(), sfdb.get_split(), sfdb.get_mode(), track, pos, prompt); - break; + browser.show_all (); + + while (!options) { + + int response = browser.run (); - case SoundFileOmega::ResponseEmbed: - do_embed (sfdb.get_paths(), sfdb.get_split(), sfdb.get_mode(), track, pos, prompt); - break; + switch (response) { + case RESPONSE_OK: + break; + default: + // cancel from the browser - we are done + return; + } + + paths = browser.get_paths (); - default: - break; + options = new SoundFileOptionsDialog (browser, paths, selection->tracks.size()); + options->show_all (); + + response = options->run (); + switch (response) { + case RESPONSE_OK: + // leave options non-null so that we break out of the loop + break; + default: + // back to the browser another try + delete options; + options = 0; + break; + } } + + browser.hide (); + options->hide (); + + /* lets do it */ + + AudioTrack* track = 0; + + if (!selection->tracks.empty()) { + AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(selection->tracks.front()); + if (atv) { + track = atv->audio_track(); + } + } + + if (options->import.get_active()) { + do_import (paths, options->split_files.get_active(), options->mode, track, edit_cursor->current_frame); + } else { + do_embed (paths, options->split_files.get_active(), options->mode, track, edit_cursor->current_frame); + } + + delete options; +} + +void +Editor::bring_in_external_audio (ImportMode mode, AudioTrack* track, nframes_t& pos) +{ } void -Editor::do_import (vector<ustring> paths, bool split, ImportMode mode, AudioTrack* track, nframes_t& pos, bool prompt) +Editor::do_import (vector<ustring> paths, bool split, ImportMode mode, AudioTrack* track, nframes_t& pos) { /* SFDB sets "multichan" to true to indicate "split channels" so reverse the setting to match the way libardour @@ -131,24 +182,24 @@ Editor::do_import (vector<ustring> paths, bool split, ImportMode mode, AudioTrac } bool -Editor::idle_do_embed (vector<ustring> paths, bool split, ImportMode mode, AudioTrack* track, nframes_t& pos, bool prompt) +Editor::idle_do_embed (vector<ustring> paths, bool split, ImportMode mode, AudioTrack* track, nframes_t& pos) { - _do_embed (paths, split, mode, track, pos, prompt); + _do_embed (paths, split, mode, track, pos); return false; } void -Editor::do_embed (vector<ustring> paths, bool split, ImportMode mode, AudioTrack* track, nframes_t& pos, bool prompt) +Editor::do_embed (vector<ustring> paths, bool split, ImportMode mode, AudioTrack* track, nframes_t& pos) { #ifdef GTKOSX - Glib::signal_idle().connect (bind (mem_fun (*this, &Editor::idle_do_embed), paths, split, mode, track, pos, prompt)); + Glib::signal_idle().connect (bind (mem_fun (*this, &Editor::idle_do_embed), paths, split, mode, track, pos)); #else - _do_embed (paths, split, mode, track, pos, prompt); + _do_embed (paths, split, mode, track, pos); #endif } void -Editor::_do_embed (vector<ustring> paths, bool split, ImportMode mode, AudioTrack* track, nframes_t& pos, bool prompt) +Editor::_do_embed (vector<ustring> paths, bool split, ImportMode mode, AudioTrack* track, nframes_t& pos) { bool multiple_files = paths.size() > 1; bool check_sample_rate = true; @@ -201,7 +252,7 @@ Editor::_do_embed (vector<ustring> paths, bool split, ImportMode mode, AudioTrac /* keep them paired */ - if (embed_sndfile (to_embed, split, multiple_files, check_sample_rate, mode, track, pos, prompt) < -1) { + if (embed_sndfile (to_embed, split, multiple_files, check_sample_rate, mode, track, pos) < -1) { break; } @@ -216,7 +267,7 @@ Editor::_do_embed (vector<ustring> paths, bool split, ImportMode mode, AudioTrac foo.clear (); foo.push_back (*x); - if (embed_sndfile (foo, split, multiple_files, check_sample_rate, mode, track, pos, prompt) < -1) { + if (embed_sndfile (foo, split, multiple_files, check_sample_rate, mode, track, pos) < -1) { break; } } @@ -224,7 +275,7 @@ Editor::_do_embed (vector<ustring> paths, bool split, ImportMode mode, AudioTrac } else { - if (embed_sndfile (to_embed, split, multiple_files, check_sample_rate, mode, track, pos, prompt) < -1) { + if (embed_sndfile (to_embed, split, multiple_files, check_sample_rate, mode, track, pos) < -1) { break; } } @@ -288,7 +339,7 @@ Editor::import_sndfile (vector<ustring> paths, ImportMode mode, AudioTrack* trac int Editor::embed_sndfile (vector<Glib::ustring> paths, bool split, bool multiple_files, bool& check_sample_rate, ImportMode mode, - AudioTrack* track, nframes_t& pos, bool prompt) + AudioTrack* track, nframes_t& pos) { boost::shared_ptr<AudioFileSource> source; SourceList sources; diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index 45081a1bbb..2cbd6f2c55 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -464,14 +464,14 @@ Editor::drop_paths (const RefPtr<Gdk::DragContext>& context, /* drop onto canvas background: create new tracks */ nframes_t pos = 0; - do_embed (paths, false, ImportAsTrack, 0, pos, false); + do_embed (paths, false, ImportAsTrack, 0, pos); } else if ((tv = dynamic_cast<AudioTimeAxisView*>(tvp)) != 0) { /* check that its an audio track, not a bus */ if (tv->get_diskstream()) { - do_embed (paths, false, ImportToTrack, tv->audio_track(), frame, true); + do_embed (paths, false, ImportToTrack, tv->audio_track(), frame); } } diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc index f24930f10a..11ffb544fc 100644 --- a/gtk2_ardour/editor_region_list.cc +++ b/gtk2_ardour/editor_region_list.cc @@ -621,7 +621,7 @@ Editor::region_list_display_drag_data_received (const RefPtr<Gdk::DragContext>& if (convert_drop_to_paths (paths, context, x, y, data, info, time) == 0) { nframes_t pos = 0; - do_embed (paths, false, ImportAsRegion, 0, pos, true); + do_embed (paths, false, ImportAsRegion, 0, pos); context->drag_finish (true, false, time); } } diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc index 3758e40d38..c736773dc7 100644 --- a/gtk2_ardour/editor_selection.cc +++ b/gtk2_ardour/editor_selection.cc @@ -561,8 +561,6 @@ Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> regi } } - begin_reversible_command (_("set selected regions")); - switch (op) { case Selection::Toggle: /* XXX this is not correct */ @@ -578,8 +576,6 @@ Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> regi selection->add (all_equivalent_regions); break; } - - commit_reversible_command () ; } bool diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc index 58781873e5..5633edf306 100644 --- a/gtk2_ardour/sfdb_ui.cc +++ b/gtk2_ardour/sfdb_ui.cc @@ -25,6 +25,7 @@ #include <gtkmm/box.h> #include <gtkmm/stock.h> +#include <glibmm/fileutils.h> #include <pbd/convert.h> #include <pbd/tokenizer.h> @@ -42,6 +43,7 @@ #include "gui_thread.h" #include "prompter.h" #include "sfdb_ui.h" +#include "editing.h" #include "utils.h" #include "i18n.h" @@ -49,6 +51,8 @@ using namespace ARDOUR; using namespace PBD; using namespace std; +using namespace Gtk; +using namespace Editing; Glib::ustring SoundFileBrowser::persistent_folder; @@ -58,39 +62,51 @@ SoundFileBox::SoundFileBox () current_pid(0), main_box (false, 3), bottom_box (true, 4), - play_btn(_("Play")), - stop_btn(_("Stop")), - apply_btn(_("Apply")) + play_btn (Stock::MEDIA_PLAY), + stop_btn (Stock::MEDIA_STOP), + apply_btn () { set_name (X_("SoundFileBox")); - set_size_request (250, 500); + set_size_request (250, 250); - border_frame.set_label (_("Soundfile Info")); + Label* label = manage (new Label); + label->set_use_markup (true); + label->set_text (_("<b>Soundfile Info</b>")); + + border_frame.set_label_widget (*label); border_frame.add (main_box); - Gtk::Label* tag_label = manage(new Gtk::Label(_("comma seperated tags"))); + Label* tag_label = manage(new Label(_("comma seperated tags"))); - pack_start (border_frame); + pack_start (border_frame, FALSE, FALSE); set_border_width (4); main_box.set_border_width (4); + Gtk::Image* w = manage (new Image (Stock::APPLY, ICON_SIZE_BUTTON)); + apply_btn.set_image (*w); + apply_btn.set_label (_("Set tags")); + main_box.pack_start(length, false, false); main_box.pack_start(format, false, false); main_box.pack_start(channels, false, false); main_box.pack_start(samplerate, false, false); main_box.pack_start(timecode, false, false); main_box.pack_start(*tag_label, false, false); - main_box.pack_start(tags_entry, false, false); - main_box.pack_start(apply_btn, false, false); + + HBox* hbox = manage (new HBox); + hbox->pack_start (apply_btn, false, false); + hbox->pack_start (tags_entry, true, true); + + main_box.pack_start(*hbox, false, false); main_box.pack_start(bottom_box, false, false); bottom_box.set_homogeneous(true); bottom_box.pack_start(play_btn); bottom_box.pack_start(stop_btn); - play_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::play_btn_clicked)); + play_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::audition)); stop_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::stop_btn_clicked)); apply_btn.signal_clicked().connect (mem_fun (*this, &SoundFileBox::apply_btn_clicked)); tags_entry.signal_activate().connect (mem_fun (*this, &SoundFileBox::apply_btn_clicked)); @@ -103,8 +119,6 @@ SoundFileBox::SoundFileBox () stop_btn.set_no_show_all (true); stop_btn.hide(); - - show_all(); } void @@ -120,7 +134,7 @@ SoundFileBox::set_session(Session* s) } bool -SoundFileBox::setup_labels (string filename) +SoundFileBox::setup_labels (const Glib::ustring& filename) { path = filename; @@ -130,7 +144,7 @@ SoundFileBox::setup_labels (string filename) length.set_text (_("Length: n/a")); format.set_text (_("Format: n/a")); channels.set_text (_("Channels: n/a")); - samplerate.set_text (_("Samplerate: n/a")); + samplerate.set_text (_("Sample rate: n/a")); timecode.set_text (_("Timecode: n/a")); tags_entry.set_text (""); @@ -147,7 +161,9 @@ SoundFileBox::setup_labels (string filename) samplerate.set_text (string_compose(_("Samplerate: %1"), sf_info.samplerate)); timecode.set_text (string_compose (_("Timecode: %1"), length2string(sf_info.timecode, sf_info.samplerate))); - vector<string> tags = Library->get_tags (filename); + // this is a hack that is fixed in trunk, i think (august 26th, 2007) + + vector<string> tags = Library->get_tags (string ("//") + filename); stringstream tag_string; for (vector<string>::iterator i = tags.begin(); i != tags.end(); ++i) { @@ -171,12 +187,11 @@ bool SoundFileBox::tags_entry_left (GdkEventFocus* event) { apply_btn_clicked (); - return true; } void -SoundFileBox::play_btn_clicked () +SoundFileBox::audition () { if (!_session) { return; @@ -184,16 +199,17 @@ SoundFileBox::play_btn_clicked () _session->cancel_audition(); - if (access(path.c_str(), R_OK)) { + if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS)) { warning << string_compose(_("Could not read file: %1 (%2)."), path, strerror(errno)) << endmsg; return; } - typedef std::map<string, boost::shared_ptr<AudioRegion> > RegionCache; + typedef std::map<Glib::ustring, boost::shared_ptr<AudioRegion> > RegionCache; static RegionCache region_cache; RegionCache::iterator the_region; if ((the_region = region_cache.find (path)) == region_cache.end()) { + SourceList srclist; boost::shared_ptr<AudioFileSource> afs; @@ -249,14 +265,18 @@ SoundFileBox::apply_btn_clicked () { string tag_string = tags_entry.get_text (); + if (tag_string.empty()) { + return; + } + vector<string> tags; - if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) { + if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) { warning << _("SoundFileBox: Could not tokenize string: ") << tag_string << endmsg; return; } - Library->set_tags (path, tags); + Library->set_tags (string ("//") + path, tags); Library->save_changes (); } @@ -270,43 +290,46 @@ SoundFileBox::audition_status_changed (bool active) } } -// this needs to be kept in sync with the ImportMode enum defined in editing.h and editing_syms.h. -static const char *import_mode_strings[] = { - N_("Add to Region list"), - N_("Add to selected Track(s)"), - N_("Add as new Track(s)"), - N_("Add as new Tape Track(s)"), - 0 -}; - SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s) : ArdourDialog (title, false), - chooser (Gtk::FILE_CHOOSER_ACTION_OPEN), - found_list (Gtk::ListStore::create(found_list_columns)), + found_list (ListStore::create(found_list_columns)), + chooser (FILE_CHOOSER_ACTION_OPEN), found_list_view (found_list), found_search_btn (_("Search")) { - set_default_size (700, 500); - Gtk::HBox* hbox = manage(new Gtk::HBox); - hbox->pack_start(notebook); - hbox->pack_start(preview, Gtk::PACK_SHRINK); - get_vbox()->pack_start(*hbox); - hbox = manage(new Gtk::HBox); + VBox* vbox; + HBox* hbox; + + vbox = manage (new VBox); + vbox->pack_start (preview, false, false); + + + hbox = manage (new HBox); + hbox->set_spacing (6); + hbox->pack_start (notebook, true, true); + hbox->pack_start (*vbox, false, false); + + get_vbox()->pack_start (*hbox, true, true); + + hbox = manage(new HBox); hbox->pack_start (found_entry); hbox->pack_start (found_search_btn); - Gtk::VBox* vbox = manage(new Gtk::VBox); - vbox->pack_start (*hbox, Gtk::PACK_SHRINK); + vbox = manage(new VBox); + vbox->pack_start (*hbox, PACK_SHRINK); vbox->pack_start (found_list_view); found_list_view.append_column(_("Paths"), found_list_columns.pathname); - notebook.append_page (chooser, _("Files")); - notebook.append_page (*vbox, _("Tags")); + chooser.set_border_width (12); + + notebook.append_page (chooser, _("Search Files")); + notebook.append_page (*vbox, _("Search Tags")); - found_list_view.get_selection()->set_mode (Gtk::SELECTION_MULTIPLE); + found_list_view.get_selection()->set_mode (SELECTION_MULTIPLE); + found_list_view.signal_row_activated().connect (mem_fun (*this, &SoundFileBrowser::found_list_view_activated)); - custom_filter.add_custom (Gtk::FILE_FILTER_FILENAME, mem_fun(*this, &SoundFileBrowser::on_custom)); + custom_filter.add_custom (FILE_FILTER_FILENAME, mem_fun(*this, &SoundFileBrowser::on_custom)); custom_filter.set_name (_("Probable audio files")); matchall_filter.add_pattern ("*.*"); @@ -316,6 +339,7 @@ SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s) chooser.add_filter (matchall_filter); chooser.set_select_multiple (true); chooser.signal_update_preview().connect(mem_fun(*this, &SoundFileBrowser::update_preview)); + chooser.signal_file_activated().connect (mem_fun (*this, &SoundFileBrowser::chooser_file_activated)); if (!persistent_folder.empty()) { chooser.set_current_folder (persistent_folder); @@ -325,8 +349,11 @@ SoundFileBrowser::SoundFileBrowser (string title, ARDOUR::Session* s) found_search_btn.signal_clicked().connect(mem_fun(*this, &SoundFileBrowser::found_search_clicked)); found_entry.signal_activate().connect(mem_fun(*this, &SoundFileBrowser::found_search_clicked)); - - show_all (); + + add_button (Stock::OK, RESPONSE_OK); + add_button (Stock::CANCEL, RESPONSE_CANCEL); + + set_response_sensitive (RESPONSE_OK, false); set_session (s); } @@ -337,13 +364,25 @@ SoundFileBrowser::~SoundFileBrowser () } void +SoundFileBrowser::chooser_file_activated () +{ + preview.audition (); +} + +void +SoundFileBrowser::found_list_view_activated (const TreeModel::Path& path, TreeViewColumn* col) +{ + preview.audition (); +} + +void SoundFileBrowser::set_session (Session* s) { preview.set_session(s); } bool -SoundFileBrowser::on_custom (const Gtk::FileFilter::Info& filter_info) +SoundFileBrowser::on_custom (const FileFilter::Info& filter_info) { return AudioFileSource::safe_file_extension(filter_info.filename); } @@ -351,22 +390,24 @@ SoundFileBrowser::on_custom (const Gtk::FileFilter::Info& filter_info) void SoundFileBrowser::update_preview () { - preview.setup_labels(chooser.get_filename()); + preview.setup_labels (chooser.get_filename()); + set_response_sensitive (RESPONSE_OK, true); } void SoundFileBrowser::found_list_view_selected () { - string file; + Glib::ustring file; - Gtk::TreeView::Selection::ListHandle_Path rows = found_list_view.get_selection()->get_selected_rows (); + TreeView::Selection::ListHandle_Path rows = found_list_view.get_selection()->get_selected_rows (); if (!rows.empty()) { - Gtk::TreeIter iter = found_list->get_iter(*rows.begin()); + TreeIter iter = found_list->get_iter(*rows.begin()); file = (*iter)[found_list_columns.pathname]; chooser.set_filename (file); } preview.setup_labels (file); + set_response_sensitive (RESPONSE_OK, true); } void @@ -376,103 +417,25 @@ SoundFileBrowser::found_search_clicked () vector<string> tags; - if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) { + if (!PBD::tokenize (tag_string, string(","), std::back_inserter (tags), true)) { warning << _("SoundFileBrowser: Could not tokenize string: ") << tag_string << endmsg; return; } - + vector<string> results; Library->search_members_and (results, tags); found_list->clear(); for (vector<string>::iterator i = results.begin(); i != results.end(); ++i) { - Gtk::TreeModel::iterator new_row = found_list->append(); - Gtk::TreeModel::Row row = *new_row; - row[found_list_columns.pathname] = *i; - } -} - -SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s) - : - SoundFileBrowser(title, s) -{ - add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_OK); - add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - - chooser.set_select_multiple (false); - found_list_view.get_selection()->set_mode (Gtk::SELECTION_SINGLE); - show_all (); -} - -string -SoundFileChooser::get_filename () -{ - Gtk::TreeModel::iterator iter; - Gtk::TreeModel::Row row; - - string filename; - switch (notebook.get_current_page()) { - case 0: - filename = chooser.get_filename(); - case 1: - iter = found_list_view.get_selection()->get_selected(); - row = *iter; - filename = row[found_list_columns.pathname]; - default: - /* NOT REACHED */ - return ""; + TreeModel::iterator new_row = found_list->append(); + TreeModel::Row row = *new_row; + string path = Glib::filename_from_uri (string ("file:") + *i); + row[found_list_columns.pathname] = path; } - - struct stat buf; - if (stat (filename.c_str(), &buf) || !S_ISREG(buf.st_mode)) { - return ""; - } - - return filename; -} - -vector<string> SoundFileOmega::mode_strings; - -SoundFileOmega::SoundFileOmega (string title, ARDOUR::Session* s) - : SoundFileBrowser (title, s), - split_check (_("Split Channels")) -{ - ARDOUR_UI::instance()->tooltips().set_tip(split_check, - _("Create a region for each channel")); - - Gtk::Button* btn = add_button (_("Embed"), ResponseEmbed); - ARDOUR_UI::instance()->tooltips().set_tip(*btn, - _("Link to an external file")); - - btn = add_button (_("Import"), ResponseImport); - ARDOUR_UI::instance()->tooltips().set_tip(*btn, - _("Copy a file to the session folder")); - - add_button (Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE); - - if (mode_strings.empty()) { - mode_strings = I18N (import_mode_strings); - } - Gtkmm2ext::set_popdown_strings (mode_combo, mode_strings); - - set_mode (Editing::ImportAsRegion); - - get_action_area()->pack_start (split_check); - get_action_area()->pack_start (mode_combo); - - mode_combo.signal_changed().connect (mem_fun (*this, &SoundFileOmega::mode_changed)); - - show_all (); -} - -bool -SoundFileOmega::get_split () -{ - return split_check.get_active(); } vector<Glib::ustring> -SoundFileOmega::get_paths () +SoundFileBrowser::get_paths () { vector<Glib::ustring> results; @@ -491,12 +454,12 @@ SoundFileOmega::get_paths () } else { - typedef Gtk::TreeView::Selection::ListHandle_Path ListPath; + typedef TreeView::Selection::ListHandle_Path ListPath; ListPath rows = found_list_view.get_selection()->get_selected_rows (); for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) { - Gtk::TreeIter iter = found_list->get_iter(*i); - string str = (*iter)[found_list_columns.pathname]; + TreeIter iter = found_list->get_iter(*i); + Glib::ustring str = (*iter)[found_list_columns.pathname]; results.push_back (str); } @@ -504,66 +467,140 @@ SoundFileOmega::get_paths () } } -void -SoundFileOmega::set_mode (Editing::ImportMode mode) +SoundFileChooser::SoundFileChooser (string title, ARDOUR::Session* s) + : ArdourDialog (title, false), + browser (title, s) { - 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; - case Editing::ImportAsTapeTrack: - split_check.set_sensitive (true); - break; - } + set_default_size (700, 300); + + get_vbox()->pack_start (browser, false, false); + + add_button (Stock::OPEN, RESPONSE_OK); + add_button (Stock::CANCEL, RESPONSE_CANCEL); + + browser.chooser.set_select_multiple (false); + browser.found_list_view.get_selection()->set_mode (SELECTION_SINGLE); + + show_all (); } -Editing::ImportMode -SoundFileOmega::get_mode () +Glib::ustring +SoundFileChooser::get_filename () { - vector<string>::iterator i; - uint32_t n; - string str = mode_combo.get_active_text (); + vector<Glib::ustring> paths; - for (n = 0, i = mode_strings.begin (); i != mode_strings.end(); ++i, ++n) { - if (str == (*i)) { - break; - } - } + paths = browser.get_paths (); - if (i == mode_strings.end()) { - fatal << string_compose (_("programming error: %1"), X_("unknown import mode string")) << endmsg; - /*NOTREACHED*/ + if (paths.empty()) { + return Glib::ustring (); + } + + if (!Glib::file_test (paths.front(), Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) { + return Glib::ustring(); } + + return paths.front(); +} + + +SoundFileOptionsDialog::SoundFileOptionsDialog (Window& parent, const vector<Glib::ustring>& p, int selected_tracks) + : ArdourDialog (parent, _("External Audio Options"), false), + mode (ImportAsTrack), + paths (p), + split_files (_("Split non-mono files")), + merge_stereo (_("Use files as single stereo track")), + as_tracks (rgroup1, _("Use files as new tracks")), + to_tracks (rgroup1, _("Add files to selected tracks")), + as_regions (rgroup1, _("Add files to region list")), + as_tape_tracks (rgroup1, _("Add files as new tape tracks")), + import (rgroup2, _("Copy to Ardour-native files")), + embed (rgroup2, _("Use file without copying")), + selected_track_cnt (selected_tracks) +{ + selection_includes_multichannel = check_multichannel_status (paths); - return (Editing::ImportMode) (n); + block_two.set_border_width (12); + block_three.set_border_width (12); + block_four.set_border_width (12); + + block_two.pack_start (as_tracks, false, false); + block_two.pack_start (to_tracks, false, false); + block_two.pack_start (as_regions, false, false); + block_two.pack_start (as_tape_tracks, false, false); + + as_tracks.signal_toggled().connect (mem_fun (*this, &SoundFileOptionsDialog::mode_changed)); + to_tracks.signal_toggled().connect (mem_fun (*this, &SoundFileOptionsDialog::mode_changed)); + as_regions.signal_toggled().connect (mem_fun (*this, &SoundFileOptionsDialog::mode_changed)); + as_tape_tracks.signal_toggled().connect (mem_fun (*this, &SoundFileOptionsDialog::mode_changed)); + + block_three.pack_start (merge_stereo, false, false); + block_three.pack_start (split_files, false, false); + + block_four.pack_start (import, false, false); + block_four.pack_start (embed, false, false); + + get_vbox()->set_spacing (12); + get_vbox()->pack_start (block_two, false, false); + get_vbox()->pack_start (block_three, false, false); + get_vbox()->pack_start (block_four, false, false); + + if (selected_track_cnt == 0) { + to_tracks.set_sensitive (false); + } else { + to_tracks.set_sensitive (true); + } + + mode_changed (); + + add_button (Stock::OK, RESPONSE_OK); + add_button (Stock::CANCEL, RESPONSE_CANCEL); } void -SoundFileOmega::mode_changed () +SoundFileOptionsDialog::mode_changed () +{ + if (as_tracks.get_active()) { + mode = ImportAsTrack; + } else if (to_tracks.get_active()) { + mode = ImportToTrack; + } else if (as_regions.get_active()) { + mode = ImportAsRegion; + } else { + mode = ImportAsTapeTrack; + } + + if ((mode == ImportAsTrack || mode == ImportAsTapeTrack) && paths.size() == 2) { + merge_stereo.set_sensitive (true); + } else { + merge_stereo.set_sensitive (false); + } + + if (selection_includes_multichannel) { + split_files.set_sensitive (true); + } else { + split_files.set_sensitive (false); + } +} + + +bool +SoundFileOptionsDialog::check_multichannel_status (const vector<Glib::ustring>& paths) { - 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; - case Editing::ImportAsTapeTrack: - split_check.set_sensitive (true); - break; + SNDFILE* sf; + SF_INFO info; + + for (vector<Glib::ustring>::const_iterator i = paths.begin(); i != paths.end(); ++i) { + + info.format = 0; // libsndfile says to clear this before sf_open(). + + if ((sf = sf_open ((char*) (*i).c_str(), SFM_READ, &info)) != 0) { + sf_close (sf); + if (info.channels > 1) { + return true; + } + } } + + return false; } diff --git a/gtk2_ardour/sfdb_ui.h b/gtk2_ardour/sfdb_ui.h index 34c3f558bb..02d9caa2e3 100644 --- a/gtk2_ardour/sfdb_ui.h +++ b/gtk2_ardour/sfdb_ui.h @@ -22,6 +22,7 @@ #include <string> #include <vector> +#include <glibmm/ustring.h> #include <sigc++/signal.h> @@ -48,11 +49,13 @@ class SoundFileBox : public Gtk::VBox virtual ~SoundFileBox () {}; void set_session (ARDOUR::Session* s); - bool setup_labels (std::string filename); + bool setup_labels (const Glib::ustring& filename); + + void audition(); protected: ARDOUR::Session* _session; - std::string path; + Glib::ustring path; ARDOUR::SoundFileInfo sf_info; @@ -77,7 +80,6 @@ class SoundFileBox : public Gtk::VBox Gtk::Button apply_btn; bool tags_entry_left (GdkEventFocus* event); - void play_btn_clicked (); void stop_btn_clicked (); void apply_btn_clicked (); @@ -86,79 +88,94 @@ class SoundFileBox : public Gtk::VBox class SoundFileBrowser : public ArdourDialog { + private: + class FoundTagColumns : public Gtk::TreeModel::ColumnRecord + { + public: + Gtk::TreeModelColumn<Glib::ustring> pathname; + + FoundTagColumns() { add(pathname); } + }; + + FoundTagColumns found_list_columns; + Glib::RefPtr<Gtk::ListStore> found_list; + public: SoundFileBrowser (std::string title, ARDOUR::Session* _s = 0); virtual ~SoundFileBrowser (); virtual void set_session (ARDOUR::Session*); + std::vector<Glib::ustring> get_paths (); + + Gtk::FileChooserWidget chooser; + Gtk::TreeView found_list_view; protected: - Gtk::FileChooserWidget chooser; Gtk::FileFilter custom_filter; Gtk::FileFilter matchall_filter; SoundFileBox preview; static Glib::ustring persistent_folder; - class FoundTagColumns : public Gtk::TreeModel::ColumnRecord - { - public: - Gtk::TreeModelColumn<string> pathname; - - FoundTagColumns() { add(pathname); } - }; - - FoundTagColumns found_list_columns; - Glib::RefPtr<Gtk::ListStore> found_list; - Gtk::TreeView found_list_view; Gtk::Entry found_entry; Gtk::Button found_search_btn; - Gtk::Notebook notebook; - + void update_preview (); void found_list_view_selected (); + void found_list_view_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn*); void found_search_clicked (); + + void chooser_file_activated (); bool on_custom (const Gtk::FileFilter::Info& filter_info); }; -class SoundFileChooser : public SoundFileBrowser +class SoundFileChooser : public ArdourDialog { public: SoundFileChooser (std::string title, ARDOUR::Session* _s = 0); virtual ~SoundFileChooser () {}; - std::string get_filename (); + Glib::ustring get_filename (); + + private: + SoundFileBrowser browser; }; -class SoundFileOmega : public SoundFileBrowser +class SoundFileOptionsDialog : public ArdourDialog { + private: + Gtk::RadioButtonGroup rgroup1; + Gtk::RadioButtonGroup rgroup2; + public: - SoundFileOmega (std::string title, ARDOUR::Session* _s); - virtual ~SoundFileOmega () {}; - - /* 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; + SoundFileOptionsDialog (Gtk::Window& parent, const vector<Glib::ustring>& p, int selected_tracks); + + Editing::ImportMode mode; + + const std::vector<Glib::ustring>& paths; + + Gtk::CheckButton split_files; + Gtk::CheckButton merge_stereo; - std::vector<Glib::ustring> get_paths (); - bool get_split (); + Gtk::RadioButton as_tracks; + Gtk::RadioButton to_tracks; + Gtk::RadioButton as_regions; + Gtk::RadioButton as_tape_tracks; - void set_mode (Editing::ImportMode); - Editing::ImportMode get_mode (); + Gtk::RadioButton import; + Gtk::RadioButton embed; - protected: - Gtk::CheckButton split_check; - Gtk::ComboBoxText mode_combo; - + private: + int selected_track_cnt; + bool selection_includes_multichannel; + Gtk::VBox block_two; + Gtk::VBox block_three; + Gtk::VBox block_four; + + static bool check_multichannel_status (const std::vector<Glib::ustring>& paths); void mode_changed (); - - static std::vector<std::string> mode_strings; }; #endif // __ardour_sfdb_ui_h__ |