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.menus1
-rw-r--r--gtk2_ardour/editor.h1
-rw-r--r--gtk2_ardour/editor_actions.cc2
-rw-r--r--gtk2_ardour/editor_audio_import.cc9
-rw-r--r--gtk2_ardour/playlist_selector.cc29
-rw-r--r--gtk2_ardour/session_import_dialog.cc321
-rw-r--r--gtk2_ardour/session_import_dialog.h101
8 files changed, 465 insertions, 0 deletions
diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript
index a3cec81c3d..0388910ebd 100644
--- a/gtk2_ardour/SConscript
+++ b/gtk2_ardour/SConscript
@@ -223,6 +223,7 @@ route_time_axis.cc
route_ui.cc
selection.cc
send_ui.cc
+session_import_dialog.cc
session_metadata_dialog.cc
sfdb_ui.cc
simpleline.cc
diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus
index a37645dca8..ed4ea0c2a6 100644
--- a/gtk2_ardour/ardour.menus
+++ b/gtk2_ardour/ardour.menus
@@ -18,6 +18,7 @@
<menuitem action='AddTrackBus'/>
<separator/>
<menuitem action='addExistingAudioFiles'/>
+ <menuitem action='importFromSession'/>
<separator/>
<menu name='Export' action='Export'>
<menuitem action='ExportAudio'/>
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index a0918241bd..6374b29d06 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -1213,6 +1213,7 @@ class Editor : public PublicEditor
void add_external_audio_action (Editing::ImportMode);
void external_audio_dialog ();
+ void session_import_dialog ();
int check_whether_and_how_to_import(string, bool all_or_nothing = true);
bool check_multichannel_status (const std::vector<Glib::ustring>& paths);
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index 80b76369d0..fdad190c47 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -754,6 +754,8 @@ Editor::register_actions ()
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, X_("addExternalAudioToRegionList"), _("Import to Region List"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportAsRegion));
ActionManager::session_sensitive_actions.push_back (act);
+
++ ActionManager::register_action (editor_actions, X_("importFromSession"), _("Import From Session"), mem_fun(*this, &Editor::session_import_dialog));
act = ActionManager::register_toggle_action (editor_actions, X_("toggle-waveform-visible"), _("Show Waveforms"), mem_fun (*this, &Editor::toggle_waveform_visibility));
ActionManager::track_selection_sensitive_actions.push_back (act);
diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc
index 90202aa3d9..a12eb0857f 100644
--- a/gtk2_ardour/editor_audio_import.cc
+++ b/gtk2_ardour/editor_audio_import.cc
@@ -55,6 +55,7 @@
#include "editing.h"
#include "audio_time_axis.h"
#include "midi_time_axis.h"
+#include "session_import_dialog.h"
#include "utils.h"
#include "i18n.h"
@@ -184,6 +185,14 @@ Editor::external_audio_dialog ()
} while (keepRunning);
}
+void
+Editor::session_import_dialog ()
+{
+ SessionImportDialog dialog (*session);
+ ensure_float (dialog);
+ dialog.run ();
+}
+
typedef std::map<PBD::ID,boost::shared_ptr<ARDOUR::Source> > SourceMap;
/**
diff --git a/gtk2_ardour/playlist_selector.cc b/gtk2_ardour/playlist_selector.cc
index 39abfe3dc1..0ca9432fcb 100644
--- a/gtk2_ardour/playlist_selector.cc
+++ b/gtk2_ardour/playlist_selector.cc
@@ -183,6 +183,35 @@ PlaylistSelector::show_for (RouteUI* ruix)
}
}
+ // Add unassigned (imported) playlists to the list
+ list<boost::shared_ptr<Playlist> > unassigned;
+ session->unassigned_playlists (unassigned);
+
+ TreeModel::Row row;
+ TreeModel::Row* selected_row = 0;
+ TreePath this_path;
+
+ row = *(model->append (others.children()));
+ row[columns.text] = _("Imported");
+ proxy = row[columns.playlist];
+ proxy.reset ();
+
+ for (list<boost::shared_ptr<Playlist> >::iterator p = unassigned.begin(); p != unassigned.end(); ++p) {
+ TreeModel::Row child_row;
+
+ child_row = *(model->append (row.children()));
+ child_row[columns.text] = (*p)->name();
+ child_row[columns.playlist] = *p;
+
+ if (*p == this_ds->playlist()) {
+ selected_row = &child_row;
+ }
+
+ if (selected_row != 0) {
+ tree.get_selection()->select (*selected_row);
+ }
+ }
+
show_all ();
select_connection = tree.get_selection()->signal_changed().connect (mem_fun(*this, &PlaylistSelector::selection_changed));
}
diff --git a/gtk2_ardour/session_import_dialog.cc b/gtk2_ardour/session_import_dialog.cc
new file mode 100644
index 0000000000..42eb7c56cb
--- /dev/null
+++ b/gtk2_ardour/session_import_dialog.cc
@@ -0,0 +1,321 @@
+/*
+ Copyright (C) 2008 Paul Davis
+ Author: Sakari Bergen
+
+ 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.
+
+*/
+
+#include "session_import_dialog.h"
+
+#include <pbd/failed_constructor.h>
+
+#include <ardour/audio_region_importer.h>
+#include <ardour/audio_playlist_importer.h>
+#include <ardour/location_importer.h>
+#include <ardour/tempo_map_importer.h>
+
+#include <gtkmm2ext/utils.h>
+#include <gtkmm2ext/window_title.h>
+
+#include "prompter.h"
+#include "i18n.h"
+
+using namespace ARDOUR;
+
+SessionImportDialog::SessionImportDialog (ARDOUR::Session & target) :
+ ArdourDialog (_("Import from session")),
+ target (target),
+ file_browse_button (_("Browse"))
+{
+ // File entry
+ file_entry.set_name ("ImportFileNameEntry");
+ file_entry.set_text ("/");
+ Gtkmm2ext::set_size_request_to_display_given_text (file_entry, X_("Kg/quite/a/reasonable/size/for/files/i/think"), 5, 8);
+
+ file_browse_button.set_name ("EditorGTKButton");
+ file_browse_button.signal_clicked().connect (mem_fun(*this, &SessionImportDialog::browse));
+
+ file_hbox.set_spacing (5);
+ file_hbox.set_border_width (5);
+ file_hbox.pack_start (file_entry, true, true);
+ file_hbox.pack_start (file_browse_button, false, false);
+
+ file_frame.add (file_hbox);
+ file_frame.set_border_width (5);
+ file_frame.set_name ("ImportFrom");
+ file_frame.set_label (_("Import from Session"));
+
+ get_vbox()->pack_start (file_frame, false, false);
+
+ // Session browser
+ session_tree = Gtk::TreeStore::create (sb_cols);
+ session_browser.set_model (session_tree);
+
+ session_browser.set_name ("SessionBrowser");
+ session_browser.append_column (_("Elements"), sb_cols.name);
+ session_browser.append_column_editable (_("Import"), sb_cols.queued);
+ session_browser.get_column(0)->set_min_width (180);
+ session_browser.get_column(1)->set_min_width (40);
+ session_browser.get_column(1)->set_sizing (Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
+
+ session_scroll.set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ session_scroll.add (session_browser);
+ session_scroll.set_size_request (220, 400);
+
+ // Connect signals
+ Gtk::CellRendererToggle *toggle = dynamic_cast<Gtk::CellRendererToggle *> (session_browser.get_column_cell_renderer (1));
+ toggle->signal_toggled().connect(mem_fun (*this, &SessionImportDialog::update));
+ session_browser.signal_row_activated().connect(mem_fun (*this, &SessionImportDialog::show_info));
+
+ get_vbox()->pack_start (session_scroll, false, false);
+
+ // Tooltips
+ session_browser.set_has_tooltip();
+ session_browser.signal_query_tooltip().connect(mem_fun(*this, &SessionImportDialog::query_tooltip));
+
+ // Buttons
+ cancel_button = add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+ cancel_button->signal_clicked().connect (mem_fun (*this, &SessionImportDialog::end_dialog));
+ ok_button = add_button (_("Import"), Gtk::RESPONSE_ACCEPT);
+ ok_button->signal_clicked().connect (mem_fun (*this, &SessionImportDialog::do_merge));
+
+ // prompt signals
+ ElementImporter::Rename.connect (mem_fun (*this, &SessionImportDialog::open_rename_dialog));
+ ElementImporter::Prompt.connect (mem_fun (*this, &SessionImportDialog::open_prompt_dialog));
+
+ // Finalize
+ show_all();
+}
+
+void
+SessionImportDialog::load_session (const string& filename)
+{
+ tree.read (filename);
+ AudioRegionImportHandler *region_handler;
+
+ region_handler = new AudioRegionImportHandler (tree, target);
+ handlers.push_back (HandlerPtr(region_handler));
+ handlers.push_back (HandlerPtr(new AudioPlaylistImportHandler (tree, target, *region_handler)));
+ handlers.push_back (HandlerPtr(new UnusedAudioPlaylistImportHandler (tree, target, *region_handler)));
+ handlers.push_back (HandlerPtr(new LocationImportHandler (tree, target)));
+ handlers.push_back (HandlerPtr(new TempoMapImportHandler (tree, target)));
+
+ fill_list();
+
+ if (ElementImportHandler::dirty()) {
+ // Warn user
+ string txt = _("Some elements had errors in them. Please see the log for details");
+ Gtk::MessageDialog msg (txt, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
+ msg.run();
+ }
+}
+
+void
+SessionImportDialog::fill_list ()
+{
+ session_tree->clear();
+
+ // Loop through element types
+ for (HandlerList::iterator handler = handlers.begin(); handler != handlers.end(); ++handler) {
+ Gtk::TreeModel::iterator iter = session_tree->append();
+ Gtk::TreeModel::Row row = *iter;
+ row[sb_cols.name] = (*handler)->get_info();
+ row[sb_cols.queued] = false;
+ row[sb_cols.element] = ElementPtr(); // "Null" pointer
+
+ // Loop through elements
+ ElementList &elements = (*handler)->elements;
+ for (ElementList::iterator element = elements.begin(); element != elements.end(); ++element) {
+ iter = session_tree->append(row.children());
+ Gtk::TreeModel::Row child = *iter;
+ child[sb_cols.name] = (*element)->get_name();
+ child[sb_cols.queued] = false;
+ child[sb_cols.element] = *element;
+ }
+ }
+}
+
+void
+SessionImportDialog::browse ()
+{
+ Gtk::FileChooserDialog dialog(_("Import from session"), browse_action());
+ dialog.set_transient_for(*this);
+ dialog.set_filename (file_entry.get_text());
+
+ dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+ dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
+
+ int result = dialog.run();
+
+ if (result == Gtk::RESPONSE_OK) {
+ string filename = dialog.get_filename();
+
+ if (filename.length()) {
+ file_entry.set_text (filename);
+ load_session (filename);
+ }
+ }
+}
+
+void
+SessionImportDialog::do_merge ()
+{
+
+ // element types
+ Gtk::TreeModel::Children types = session_browser.get_model()->children();
+ Gtk::TreeModel::Children::iterator ti;
+ for (ti = types.begin(); ti != types.end(); ++ti) {
+ // elements
+ Gtk::TreeModel::Children elements = ti->children();
+ Gtk::TreeModel::Children::iterator ei;
+ for (ei = elements.begin(); ei != elements.end(); ++ei) {
+ if ((*ei)[sb_cols.queued]) {
+ ElementPtr element = (*ei)[sb_cols.element];
+ element->move();
+ }
+ }
+ }
+
+ end_dialog();
+
+ if (ElementImportHandler::errors()) {
+ // Warn user
+ string txt = _("Some elements had errors in them. Please see the log for details");
+ Gtk::MessageDialog msg (txt, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
+ msg.run();
+ }
+}
+
+
+void
+SessionImportDialog::update (string path)
+{
+ Gtk::TreeModel::iterator cell = session_browser.get_model()->get_iter (path);
+
+ // Select all elements if element type is selected
+ if (path.size() == 1) {
+ {
+ // Prompt user for verification
+ string txt = _("This will select all elements of this type!");
+ Gtk::MessageDialog msg (txt, false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_OK_CANCEL, true);
+ if (msg.run() == Gtk::RESPONSE_CANCEL) {
+ (*cell)[sb_cols.queued] = false;
+ return;
+ }
+ }
+
+ Gtk::TreeModel::Children elements = cell->children();
+ Gtk::TreeModel::Children::iterator ei;
+ for (ei = elements.begin(); ei != elements.end(); ++ei) {
+ ElementPtr element = (*ei)[sb_cols.element];
+ if (element->prepare_move()) {
+ (*ei)[sb_cols.queued] = true;
+ } else {
+ (*cell)[sb_cols.queued] = false; // Not all are selected
+ }
+ }
+ return;
+ }
+
+ ElementPtr element = (*cell)[sb_cols.element];
+ if ((*cell)[sb_cols.queued]) {
+ if (!element->prepare_move()) {
+ (*cell)[sb_cols.queued] = false;
+ }
+ } else {
+ element->cancel_move();
+ }
+}
+
+void
+SessionImportDialog::show_info(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column)
+{
+ if (path.size() == 1) {
+ return;
+ }
+
+ Gtk::TreeModel::iterator cell = session_browser.get_model()->get_iter (path);
+ ElementPtr element = (*cell)[sb_cols.element];
+ string info = element->get_info();
+
+ Gtk::MessageDialog msg (info, false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_OK, true);
+ msg.run();
+}
+
+bool
+SessionImportDialog::query_tooltip(int x, int y, bool keyboard_tooltip, const Glib::RefPtr<Gtk::Tooltip>& tooltip)
+{
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn* column;
+ int cell_x, cell_y;
+
+ // Get element
+ session_browser.get_path_at_pos (x, y, path, column, cell_x, cell_y);
+ if (path.gobj() == 0) {
+ return false;
+ }
+ Gtk::TreeModel::iterator row = session_browser.get_model()->get_iter (path);
+ //--row; // FIXME Strange offset in rows, if someone figures this out, please fix
+ ElementPtr element = (*row)[sb_cols.element];
+ if (element.get() == 0) {
+ return false;
+ }
+
+ // Prepare tooltip
+ tooltip->set_text(element->get_info());
+
+ return true;
+}
+
+void
+SessionImportDialog::end_dialog ()
+{
+ hide_all();
+
+ set_modal (false);
+ ok_button->set_sensitive(true);
+}
+
+std::pair<bool, string>
+SessionImportDialog::open_rename_dialog (string text, string name)
+{
+ ArdourPrompter prompter(true);
+ string new_name;
+
+ prompter.set_name ("Prompter");
+ prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
+ prompter.set_prompt (text);
+ prompter.set_initial_text (name);
+
+ if (prompter.run() == Gtk::RESPONSE_ACCEPT) {
+ prompter.get_result (new_name);
+ if (new_name.length()) {
+ name = new_name;
+ }
+ return std::make_pair (true, new_name);
+ }
+ return std::make_pair (false, new_name);
+}
+
+bool
+SessionImportDialog::open_prompt_dialog (string text)
+{
+ Gtk::MessageDialog msg (text, false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_OK_CANCEL, true);
+ if (msg.run() == Gtk::RESPONSE_OK) {
+ return true;
+ }
+ return false;
+}
diff --git a/gtk2_ardour/session_import_dialog.h b/gtk2_ardour/session_import_dialog.h
new file mode 100644
index 0000000000..22cccd1262
--- /dev/null
+++ b/gtk2_ardour/session_import_dialog.h
@@ -0,0 +1,101 @@
+/*
+ Copyright (C) 2008 Paul Davis
+ Author: Sakari Bergen
+
+ 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.
+
+*/
+
+#ifndef __session_import_dialog_h__
+#define __session_import_dialog_h__
+
+#include <string>
+#include <list>
+#include <utility>
+
+#include <boost/shared_ptr.hpp>
+#include <gtkmm.h>
+
+#include <pbd/xml++.h>
+#include <ardour/element_importer.h>
+#include <ardour/element_import_handler.h>
+
+#include "ardour_dialog.h"
+
+using std::string;
+
+namespace ARDOUR {
+ class Session;
+}
+
+class SessionImportDialog : public ArdourDialog
+{
+ private:
+ typedef boost::shared_ptr<ARDOUR::ElementImportHandler> HandlerPtr;
+ typedef std::list<HandlerPtr> HandlerList;
+
+ typedef boost::shared_ptr<ARDOUR::ElementImporter> ElementPtr;
+ typedef std::list<ElementPtr> ElementList;
+
+ public:
+ SessionImportDialog (ARDOUR::Session & target);
+
+ virtual Gtk::FileChooserAction browse_action() const { return Gtk::FILE_CHOOSER_ACTION_OPEN; }
+
+ private:
+
+ void load_session (const string& filename);
+ void fill_list ();
+ void browse ();
+ void do_merge ();
+ void end_dialog ();
+ void update (string path);
+ void show_info(const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column);
+ bool query_tooltip(int x, int y, bool keyboard_tooltip, const Glib::RefPtr<Gtk::Tooltip>& tooltip);
+
+ std::pair<bool, string> open_rename_dialog (string text, string name);
+ bool open_prompt_dialog (string text);
+
+ // Data
+ HandlerList handlers;
+ XMLTree tree;
+ ARDOUR::Session &target;
+
+ // GUI
+ Gtk::Frame file_frame;
+ Gtk::HBox file_hbox;
+ Gtk::Entry file_entry;
+ Gtk::Button file_browse_button;
+
+ struct SessionBrowserColumns : public Gtk::TreeModel::ColumnRecord
+ {
+ public:
+ Gtk::TreeModelColumn<std::string> name;
+ Gtk::TreeModelColumn<bool> queued;
+ Gtk::TreeModelColumn<ElementPtr> element;
+
+ SessionBrowserColumns() { add (name); add (queued); add (element); }
+ };
+
+ SessionBrowserColumns sb_cols;
+ Glib::RefPtr<Gtk::TreeStore> session_tree;
+ Gtk::TreeView session_browser;
+ Gtk::ScrolledWindow session_scroll;
+
+ Gtk::Button* ok_button;
+ Gtk::Button* cancel_button;
+};
+
+#endif