summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2010-11-09 06:03:51 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2010-11-09 06:03:51 +0000
commit5c6ba165f684fbd45be33c83d41083567d4dd88f (patch)
treeb3108d53b3a82fb1ea522038fe4500e0c38349bb /gtk2_ardour
parentd29f14bf33bc807be7b95015e4f011f4ad741cc6 (diff)
initial pass at a missing file dialog and "relocatable" source files. lots more to do here
git-svn-id: svn://localhost/ardour2/branches/3.0@7983 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/ardour_ui.cc28
-rw-r--r--gtk2_ardour/ardour_ui.h2
-rw-r--r--gtk2_ardour/missing_file_dialog.cc166
-rw-r--r--gtk2_ardour/missing_file_dialog.h39
-rw-r--r--gtk2_ardour/option_editor.h2
-rw-r--r--gtk2_ardour/search_path_option.cc156
-rw-r--r--gtk2_ardour/search_path_option.h50
-rw-r--r--gtk2_ardour/session_option_editor.cc30
-rw-r--r--gtk2_ardour/wscript2
9 files changed, 467 insertions, 8 deletions
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index 3c0e5b91fa..a14018e014 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -102,6 +102,7 @@ typedef uint64_t microseconds_t;
#include "window_proxy.h"
#include "global_port_matrix.h"
#include "location_ui.h"
+#include "missing_file_dialog.h"
#include "i18n.h"
@@ -264,6 +265,10 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
ARDOUR::Session::Quit.connect (forever_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::finish, this), gui_context ());
+ /* handle requests to deal with missing files */
+
+ ARDOUR::Session::MissingFile.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::missing_file, this, _1, _2, _3));
+
/* lets get this party started */
try {
@@ -3689,3 +3694,26 @@ ARDOUR_UI::remove_window_proxy (WindowProxyBase* p)
{
_window_proxies.remove (p);
}
+
+int
+ARDOUR_UI::missing_file (Session*s, std::string str, DataType type)
+{
+ MissingFileDialog dialog (s, str, type);
+
+ dialog.show ();
+ dialog.present ();
+
+ int result = dialog.run ();
+ dialog.hide ();
+
+ switch (result) {
+ case RESPONSE_OK:
+ break;
+ default:
+ return 1; // quit entire session load
+ }
+
+ result = dialog.get_action ();
+
+ return result;
+}
diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h
index 3f947b2af8..3f4ed3eca5 100644
--- a/gtk2_ardour/ardour_ui.h
+++ b/gtk2_ardour/ardour_ui.h
@@ -716,6 +716,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
void queue_finish ();
std::list<WindowProxyBase*> _window_proxies;
+
+ int missing_file (ARDOUR::Session*s, std::string str, ARDOUR::DataType type);
};
#endif /* __ardour_gui_h__ */
diff --git a/gtk2_ardour/missing_file_dialog.cc b/gtk2_ardour/missing_file_dialog.cc
new file mode 100644
index 0000000000..3054adf25c
--- /dev/null
+++ b/gtk2_ardour/missing_file_dialog.cc
@@ -0,0 +1,166 @@
+/*
+ Copyright (C) 2010 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.
+*/
+
+#include "pbd/compose.h"
+#include "pbd/replace_all.h"
+#include "pbd/strsplit.h"
+
+#include "ardour/session.h"
+
+#include "missing_file_dialog.h"
+
+using namespace Gtk;
+using namespace std;
+using namespace ARDOUR;
+using namespace PBD;
+
+MissingFileDialog::MissingFileDialog (Session* s, const std::string& path, DataType type)
+ : ArdourDialog (_("Missing File!"), true, false)
+ , filetype (type)
+ , chooser (FILE_CHOOSER_ACTION_SELECT_FOLDER)
+ , use_chosen (_("Add chosen folder to search path, and try again"))
+ , choice_group (use_chosen.get_group())
+ , use_chosen_and_no_more_questions (choice_group, _("Add chosen folder to search path, try again but don't ask me again"), false)
+ , stop_loading_button (choice_group, _("Stop loading this session"), false)
+ , all_missing_ok (choice_group, _("This and all other missing files are OK"), false)
+ , this_missing_ok (choice_group, _("This missing file is OK"), false)
+{
+ set_session (s);
+
+ add_button (_("Done"), RESPONSE_OK);
+
+ string typestr;
+
+ switch (type) {
+ case DataType::AUDIO:
+ typestr = _("An audio");
+ break;
+ case DataType::MIDI:
+ typestr = _("A MIDI");
+ break;
+ }
+
+ string dirstr;
+
+ dirstr = s->source_search_path (type);
+ replace_all (dirstr, ":", "\n");
+
+ msg.set_markup (string_compose (_("%1 file (\"%2\") cannot be found.\n\n\
+Currently, Ardour has searched in the following folders for this file:\n\n\
+<tt>%3</tt>\n\n\
+The following options are available:"), typestr, path, dirstr));
+
+ VBox* button_packer_box = manage (new VBox);
+
+ button_packer_box->set_spacing (6);
+ button_packer_box->set_border_width (12);
+
+ button_packer_box->pack_start (use_chosen, false, false);
+ button_packer_box->pack_start (use_chosen_and_no_more_questions, false, false);
+ button_packer_box->pack_start (this_missing_ok, false, false);
+ button_packer_box->pack_start (all_missing_ok, false, false);
+ button_packer_box->pack_start (stop_loading_button, false, false);
+
+ button_packer_box->show_all ();
+
+ get_vbox()->set_spacing (6);
+ get_vbox()->set_border_width (12);
+ get_vbox()->set_homogeneous (false);
+
+ get_vbox()->pack_start (msg, false, false);
+
+ HBox* hbox = manage (new HBox);
+ hbox->pack_start (*button_packer_box, false, true);
+ hbox->show ();
+
+ get_vbox()->pack_start (*hbox, false, false);
+ get_vbox()->pack_start (chooser, true, true);
+
+ msg.show ();
+ chooser.set_size_request (-1, 300);
+ chooser.show ();
+ chooser.set_current_folder (Glib::get_home_dir());
+ chooser.set_create_folders (false);
+}
+
+void
+MissingFileDialog::add_chosen ()
+{
+ string str;
+ string newdir;
+ vector<string> dirs;
+
+ switch (filetype) {
+ case DataType::AUDIO:
+ str = _session->config.get_audio_search_path();
+ break;
+ case DataType::MIDI:
+ str = _session->config.get_midi_search_path();
+ break;
+ }
+
+ split (str, dirs, ':');
+
+ newdir = chooser.get_filename ();
+
+ for (vector<string>::iterator d = dirs.begin(); d != dirs.end(); d++) {
+ if (*d == newdir) {
+ return;
+ }
+ }
+
+ if (!str.empty()) {
+ str += ':';
+ }
+
+ str += newdir;
+
+ switch (filetype) {
+ case DataType::AUDIO:
+ _session->config.set_audio_search_path (str);
+ break;
+ case DataType::MIDI:
+ _session->config.set_midi_search_path (str);
+ break;
+ }
+}
+
+int
+MissingFileDialog::get_action ()
+{
+
+ if (use_chosen.get_active ()) {
+ add_chosen ();
+ return 0;
+ }
+
+ if (use_chosen_and_no_more_questions.get_active()) {
+ add_chosen ();
+ return 2;
+ }
+
+ if (this_missing_ok.get_active()) {
+ return -1;
+ }
+
+ if (all_missing_ok.get_active ()) {
+ return 3;
+ }
+
+ return 1;
+}
diff --git a/gtk2_ardour/missing_file_dialog.h b/gtk2_ardour/missing_file_dialog.h
new file mode 100644
index 0000000000..dce720fcdb
--- /dev/null
+++ b/gtk2_ardour/missing_file_dialog.h
@@ -0,0 +1,39 @@
+#ifndef __gtk_ardour_missing_file_dialog_h__
+#define __gtk_ardour_missing_file_dialog_h__
+
+#include <string>
+#include <gtkmm/label.h>
+#include <gtkmm/filechooserwidget.h>
+#include <gtkmm/radiobutton.h>
+
+#include "ardour/types.h"
+
+#include "ardour_dialog.h"
+
+namespace ARDOUR {
+ class Session;
+}
+
+class MissingFileDialog : public ArdourDialog
+{
+ public:
+ MissingFileDialog (ARDOUR::Session*, const std::string& path, ARDOUR::DataType type);
+
+ int get_action();
+
+ private:
+ ARDOUR::DataType filetype;
+
+ Gtk::FileChooserWidget chooser;
+ Gtk::RadioButton use_chosen;
+ Gtk::RadioButton::Group choice_group;
+ Gtk::RadioButton use_chosen_and_no_more_questions;
+ Gtk::RadioButton stop_loading_button;
+ Gtk::RadioButton all_missing_ok;
+ Gtk::RadioButton this_missing_ok;
+ Gtk::Label msg;
+
+ void add_chosen ();
+};
+
+#endif /* __gtk_ardour_missing_file_dialog_h__ */
diff --git a/gtk2_ardour/option_editor.h b/gtk2_ardour/option_editor.h
index f76ba2df93..0258f955aa 100644
--- a/gtk2_ardour/option_editor.h
+++ b/gtk2_ardour/option_editor.h
@@ -136,7 +136,7 @@ public:
return _id;
}
-private:
+protected:
std::string _id;
std::string _name;
diff --git a/gtk2_ardour/search_path_option.cc b/gtk2_ardour/search_path_option.cc
new file mode 100644
index 0000000000..be01b9b1aa
--- /dev/null
+++ b/gtk2_ardour/search_path_option.cc
@@ -0,0 +1,156 @@
+/*
+ Copyright (C) 2010 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.
+*/
+
+#include "pbd/strsplit.h"
+#include "search_path_option.h"
+
+using namespace std;
+using namespace Gtk;
+
+SearchPathOption::SearchPathOption (const string& pathname, const string& label,
+ sigc::slot<std::string> get, sigc::slot<bool, std::string> set)
+ : Option (pathname, label)
+ , _get (get)
+ , _set (set)
+ , add_chooser (_("Select folder to search for media"), FILE_CHOOSER_ACTION_SELECT_FOLDER)
+{
+ add_chooser.signal_file_set().connect (sigc::mem_fun (*this, &SearchPathOption::path_chosen));
+
+ HBox* hbox = manage (new HBox);
+
+ hbox->set_border_width (12);
+ hbox->set_spacing (6);
+ hbox->pack_end (add_chooser, false, false);
+ hbox->pack_end (*manage (new Label ("Click to add a new location")), false, false);
+ hbox->show_all ();
+
+ vbox.pack_start (path_box);
+ vbox.pack_end (*hbox);
+
+ session_label.set_use_markup (true);
+ session_label.set_markup (string_compose ("<i>%1</i>", _("the session folder")));
+ session_label.set_alignment (0.0, 0.5);
+ session_label.show ();
+}
+
+SearchPathOption::~SearchPathOption()
+{
+
+
+}
+
+void
+SearchPathOption::path_chosen ()
+{
+ string path = add_chooser.get_filename ();
+ add_path (path);
+}
+
+void
+SearchPathOption::add_to_page (OptionEditorPage* p)
+{
+ int const n = p->table.property_n_rows();
+ p->table.resize (n + 2, 3);
+
+ Label* label = manage (new Label);
+ label->set_alignment (0.0, 0.5);
+ label->set_markup (string_compose ("<b>%1</b>", _name));
+
+ p->table.attach (*label, 0, 1, n, n + 1, FILL | EXPAND);
+ p->table.attach (vbox, 0, 3, n + 1, n + 2, FILL | EXPAND);
+}
+
+void
+SearchPathOption::clear ()
+{
+ path_box.remove (session_label);
+ for (list<PathEntry*>::iterator p = paths.begin(); p != paths.end(); ++p) {
+ path_box.remove ((*p)->box);
+ delete *p;
+ }
+ paths.clear ();
+}
+
+void
+SearchPathOption::set_state_from_config ()
+{
+ string str = _get ();
+ vector<string> dirs;
+
+ clear ();
+ path_box.pack_start (session_label);
+
+ split (str, dirs, ':');
+
+ for (vector<string>::iterator d = dirs.begin(); d != dirs.end(); ++d) {
+ add_path (*d);
+ }
+}
+
+void
+SearchPathOption::changed ()
+{
+ string str;
+
+ for (list<PathEntry*>::iterator p = paths.begin(); p != paths.end(); ++p) {
+
+ if (p == paths.begin()) {
+ /* skip first entry, its always "the session"
+ */
+ continue;
+ }
+
+ if (!str.empty()) {
+ str += ':';
+ }
+ str += (*p)->entry.get_text ();
+ }
+
+ _set (str);
+}
+
+void
+SearchPathOption::add_path (const string& path, bool removable)
+{
+ PathEntry* pe = new PathEntry (path, removable);
+ paths.push_back (pe);
+ path_box.pack_start (pe->box, false, false);
+}
+
+void
+SearchPathOption::remove_path (const string& path)
+{
+}
+
+SearchPathOption::PathEntry::PathEntry (const std::string& path, bool removable)
+ : remove_button (Stock::REMOVE)
+{
+ entry.set_text (path);
+ entry.show ();
+
+ box.set_spacing (6);
+ box.set_homogeneous (false);
+ box.pack_start (entry, true, true);
+
+ if (removable) {
+ box.pack_start (remove_button, false, false);
+ remove_button.show ();
+ }
+
+ box.show ();
+}
diff --git a/gtk2_ardour/search_path_option.h b/gtk2_ardour/search_path_option.h
new file mode 100644
index 0000000000..7163924b8c
--- /dev/null
+++ b/gtk2_ardour/search_path_option.h
@@ -0,0 +1,50 @@
+#ifndef __gtk_ardour_search_path_option_h__
+#define __gtk_ardour_search_path_option_h__
+
+#include <string>
+
+#include <gtkmm/filechooserbutton.h>
+#include <gtkmm/entry.h>
+#include <gtkmm/button.h>
+#include <gtkmm/box.h>
+
+#include "option_editor.h"
+
+class SearchPathOption : public Option
+{
+ public:
+ SearchPathOption (const std::string& pathname, const std::string& label,
+ sigc::slot<std::string>, sigc::slot<bool, std::string>);
+ ~SearchPathOption ();
+
+ void set_state_from_config ();
+ void add_to_page (OptionEditorPage*);
+ void clear ();
+
+ protected:
+ sigc::slot<std::string> _get; ///< slot to get the configuration variable's value
+ sigc::slot<bool, std::string> _set; ///< slot to set the configuration variable's value
+
+ struct PathEntry {
+ PathEntry (const std::string& path, bool removable=true);
+
+ Gtk::Entry entry;
+ Gtk::Button remove_button;
+ Gtk::HBox box;
+
+ std::string path;
+ };
+
+ std::list<PathEntry*> paths;
+ Gtk::FileChooserButton add_chooser;
+ Gtk::VBox vbox;
+ Gtk::VBox path_box;
+ Gtk::Label session_label;
+
+ void add_path (const std::string& path, bool removable=true);
+ void remove_path (const std::string& path);
+ void changed ();
+ void path_chosen ();
+};
+
+#endif /* __gtk_ardour_search_path_option_h__ */
diff --git a/gtk2_ardour/session_option_editor.cc b/gtk2_ardour/session_option_editor.cc
index 0715c105fe..ec7ee86c8d 100644
--- a/gtk2_ardour/session_option_editor.cc
+++ b/gtk2_ardour/session_option_editor.cc
@@ -25,6 +25,7 @@
#include "gui_thread.h"
#include "session_option_editor.h"
+#include "search_path_option.h"
#include "i18n.h"
using namespace std;
@@ -177,9 +178,9 @@ SessionOptionEditor::SessionOptionEditor (Session* s)
sigc::mem_fun (*_session_config, &SessionConfiguration::set_show_region_fades)
));
- /* MISC */
+ /* Media */
- add_option (_("Misc"), new OptionEditorHeading (_("Audio file format")));
+ add_option (_("Media"), new OptionEditorHeading (_("Audio file format")));
ComboOption<SampleFormat>* sf = new ComboOption<SampleFormat> (
"native-file-data-format",
@@ -192,7 +193,7 @@ SessionOptionEditor::SessionOptionEditor (Session* s)
sf->add (FormatInt24, _("24-bit integer"));
sf->add (FormatInt16, _("16-bit integer"));
- add_option (_("Misc"), sf);
+ add_option (_("Media"), sf);
ComboOption<HeaderFormat>* hf = new ComboOption<HeaderFormat> (
"native-file-header-format",
@@ -206,13 +207,28 @@ SessionOptionEditor::SessionOptionEditor (Session* s)
hf->add (WAVE64, _("WAVE-64"));
hf->add (CAF, _("CAF"));
- add_option (_("Misc"), hf);
+ add_option (_("Media"), hf);
+
+ add_option (_("Media"), new OptionEditorHeading (_("Media Locations")));
- add_option (_("Misc"), new OptionEditorHeading (_("Layering")));
+ SearchPathOption* spo = new SearchPathOption ("audio-search-path", _("Search for audio files in:"),
+ sigc::mem_fun (*_session_config, &SessionConfiguration::get_audio_search_path),
+ sigc::mem_fun (*_session_config, &SessionConfiguration::set_audio_search_path));
+ add_option (_("Media"), spo);
+
+ spo = new SearchPathOption ("midi-search-path", _("Search for MIDI files in:"),
+ sigc::mem_fun (*_session_config, &SessionConfiguration::get_midi_search_path),
+ sigc::mem_fun (*_session_config, &SessionConfiguration::set_midi_search_path));
+
+ add_option (_("Media"), spo);
+
+ /* Misc */
+
+ add_option (_("Misc"), new OptionEditorHeading (_("Layering (in overlaid mode)")));
ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
"layer-model",
- _("Layering model in overlaid mode"),
+ _("Layering model"),
sigc::mem_fun (*_session_config, &SessionConfiguration::get_layer_model),
sigc::mem_fun (*_session_config, &SessionConfiguration::set_layer_model)
);
@@ -227,7 +243,7 @@ SessionOptionEditor::SessionOptionEditor (Session* s)
ComboOption<InsertMergePolicy>* li = new ComboOption<InsertMergePolicy> (
"insert-merge-policy",
- _("Policy for handling same note and channel overlaps"),
+ _("Policy for handling same note\nand channel overlaps"),
sigc::mem_fun (*_session_config, &SessionConfiguration::get_insert_merge_policy),
sigc::mem_fun (*_session_config, &SessionConfiguration::set_insert_merge_policy)
);
diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript
index e72d022829..7d3f74f024 100644
--- a/gtk2_ardour/wscript
+++ b/gtk2_ardour/wscript
@@ -141,6 +141,7 @@ gtk2_ardour_sources = [
'midi_streamview.cc',
'midi_time_axis.cc',
'midi_tracer.cc',
+ 'missing_file_dialog.cc',
'mixer_group_tabs.cc',
'mixer_strip.cc',
'mixer_ui.cc',
@@ -186,6 +187,7 @@ gtk2_ardour_sources = [
'route_processor_selection.cc',
'route_time_axis.cc',
'route_ui.cc',
+ 'search_path_option.cc',
'selection.cc',
'send_ui.cc',
'session_import_dialog.cc',