diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2010-11-09 06:03:51 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2010-11-09 06:03:51 +0000 |
commit | 5c6ba165f684fbd45be33c83d41083567d4dd88f (patch) | |
tree | b3108d53b3a82fb1ea522038fe4500e0c38349bb /gtk2_ardour | |
parent | d29f14bf33bc807be7b95015e4f011f4ad741cc6 (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.cc | 28 | ||||
-rw-r--r-- | gtk2_ardour/ardour_ui.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/missing_file_dialog.cc | 166 | ||||
-rw-r--r-- | gtk2_ardour/missing_file_dialog.h | 39 | ||||
-rw-r--r-- | gtk2_ardour/option_editor.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/search_path_option.cc | 156 | ||||
-rw-r--r-- | gtk2_ardour/search_path_option.h | 50 | ||||
-rw-r--r-- | gtk2_ardour/session_option_editor.cc | 30 | ||||
-rw-r--r-- | gtk2_ardour/wscript | 2 |
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', |