2 * Copyright (C) 2008-2016 Paul Davis <paul@linuxaudiosystems.com>
3 * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net>
4 * Copyright (C) 2009-2012 David Robillard <d@drobilla.net>
5 * Copyright (C) 2015-2016 Colin Fletcher <colin.m.fletcher@googlemail.com>
6 * Copyright (C) 2015-2019 Robin Gareus <robin@gareus.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <gtkmm/filechooserdialog.h>
25 #include <gtkmm/messagedialog.h>
26 #include <gtkmm/stock.h>
28 #include "pbd/xml++.h"
29 #include "pbd/error.h"
31 #include "ardour/filename_extensions.h"
32 #include "ardour/session.h"
33 #include "ardour/session_utils.h"
35 #include "gtkmm2ext/utils.h"
37 #include "session_metadata_dialog.h"
45 #define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))
47 /*** MetadataField ***/
49 MetadataField::MetadataField (string const & field_name) :
54 MetadataField::~MetadataField() { }
56 /* TextMetadataField */
58 TextMetadataField::TextMetadataField (Getter getter, Setter setter, string const & field_name, guint width ) :
59 MetadataField (field_name),
70 TextMetadataField::copy ()
72 return MetadataPtr (new TextMetadataField (getter, setter, _name, width));
76 TextMetadataField::save_data (ARDOUR::SessionMetadata & data) const
78 CALL_MEMBER_FN (data, setter) (_value);
82 TextMetadataField::load_data (ARDOUR::SessionMetadata const & data)
84 _value = CALL_MEMBER_FN (data, getter) ();
86 entry->set_text (_value);
91 TextMetadataField::name_widget ()
93 label = Gtk::manage (new Gtk::Label(_name + ':'));
94 label->set_alignment (1, 0);
99 TextMetadataField::value_widget ()
101 value_label = Gtk::manage (new Gtk::Label(_value));
106 TextMetadataField::edit_widget ()
108 entry = Gtk::manage (new Gtk::Entry());
110 entry->set_text (_value);
111 entry->set_width_chars (width);
112 entry->signal_changed().connect (sigc::mem_fun(*this, &TextMetadataField::update_value));
118 TextMetadataField::update_value ()
120 _value = entry->get_text ();
123 /* LongTextMetadataField */
125 LongTextMetadataField::LongTextMetadataField (Getter getter, Setter setter, string const & field_name, guint width ) :
126 TextMetadataField (getter, setter, field_name, width)
134 LongTextMetadataField::copy ()
136 return MetadataPtr (new TextMetadataField (getter, setter, _name, width));
140 LongTextMetadataField::edit_widget ()
142 tview = Gtk::manage (new Gtk::TextView());
144 tview->get_buffer()->set_text (_value);
145 tview->set_wrap_mode (Gtk::WRAP_WORD);
146 tview->set_size_request (-1, 400);
147 tview->set_editable (true);
149 Glib::RefPtr<Gtk::TextBuffer> tb (tview->get_buffer());
150 tb->signal_changed().connect (sigc::mem_fun(*this, &LongTextMetadataField::update_value));
156 LongTextMetadataField::update_value ()
158 _value = tview->get_buffer()->get_text ();
161 /* NumberMetadataField */
163 NumberMetadataField::NumberMetadataField (Getter getter, Setter setter, string const & field_name, guint numbers, guint width) :
164 MetadataField (field_name),
176 NumberMetadataField::copy ()
178 return MetadataPtr (new NumberMetadataField (getter, setter, _name, numbers, width));
182 NumberMetadataField::save_data (ARDOUR::SessionMetadata & data) const
184 uint32_t number = str_to_uint (_value);
185 CALL_MEMBER_FN (data, setter) (number);
189 NumberMetadataField::load_data (ARDOUR::SessionMetadata const & data)
191 uint32_t number = CALL_MEMBER_FN (data, getter) ();
192 _value = uint_to_str (number);
194 entry->set_text (_value);
199 NumberMetadataField::update_value ()
201 // Accept only numbers that will fit into a uint32_t
202 uint32_t number = str_to_uint (entry->get_text());
203 _value = uint_to_str (number);
204 entry->set_text (_value);
208 NumberMetadataField::name_widget ()
210 label = Gtk::manage (new Gtk::Label(_name + ':'));
211 label->set_alignment (1, 0);
216 NumberMetadataField::value_widget ()
218 value_label = Gtk::manage (new Gtk::Label(_value));
223 NumberMetadataField::edit_widget ()
225 entry = Gtk::manage (new Gtk::Entry());
227 entry->set_text (_value);
228 entry->set_width_chars (width);
229 entry->set_max_length (numbers);
230 entry->signal_changed().connect (sigc::mem_fun(*this, &NumberMetadataField::update_value));
236 NumberMetadataField::uint_to_str (uint32_t i) const
238 std::ostringstream oss ("");
240 if (oss.str().compare("0")) {
248 NumberMetadataField::str_to_uint (string const & str) const
252 while ((i = tmp.find_first_not_of("1234567890")) != string::npos) {
256 std::istringstream iss(tmp);
264 /* EAN13MetadataField */
266 EAN13MetadataField::EAN13MetadataField (Getter getter, Setter setter, string const & field_name, guint width) :
267 MetadataField (field_name),
275 status_label = Gtk::manage (new Gtk::Label (""));
279 EAN13MetadataField::copy ()
281 return MetadataPtr (new EAN13MetadataField (getter, setter, _name, width));
285 EAN13MetadataField::save_data (ARDOUR::SessionMetadata & data) const
287 CALL_MEMBER_FN (data, setter) (_value);
291 EAN13MetadataField::load_data (ARDOUR::SessionMetadata const & data)
293 _value = CALL_MEMBER_FN (data, getter) ();
295 entry->set_text (_value);
301 EAN13MetadataField::update_value ()
303 // Accept only numeric characters
304 _value = numeric_string (entry->get_text());
305 entry->set_text (_value);
310 EAN13MetadataField::update_status ()
312 int len = _value.length ();
314 // calculate EAN-13 modulo 10 check digit
316 const char *p = _value.c_str();
317 for (int i = 0; i < 12; i++) {
329 if (sum == p[12] - '0') {
330 status_label->set_markup (string_compose(
331 "<span color=\"green\">%1: %2</span>",
332 _("EAN Check digit OK"), sum));
334 status_label->set_markup (string_compose(
335 "<span color=\"#ffa755\">%1: %2 (%3 %4)</span>",
336 _("EAN Check digit error"), p[12] - '0', _("expected"), sum));
338 } else if (len > 0) {
339 status_label->set_markup (string_compose(
340 "<span color=\"#ffa755\">%1: %2 (<13)</span>",
341 _("EAN Length error"), len));
343 status_label->set_text("");
348 EAN13MetadataField::name_widget ()
350 label = Gtk::manage (new Gtk::Label(_name + ':'));
351 label->set_alignment (1, 0);
356 EAN13MetadataField::value_widget ()
358 value_label = Gtk::manage (new Gtk::Label(_value));
363 EAN13MetadataField::edit_widget ()
365 entry = Gtk::manage (new Gtk::Entry());
367 entry->set_text (_value);
368 entry->set_width_chars (width);
369 entry->set_max_length (13);
370 entry->signal_changed().connect (sigc::mem_fun(*this, &EAN13MetadataField::update_value));
376 EAN13MetadataField::numeric_string (string const & str) const
380 while ((i = tmp.find_first_not_of("1234567890")) != string::npos) {
386 /* SessionMetadataSet */
388 SessionMetadataSet::SessionMetadataSet (string const & name)
394 SessionMetadataSet::add_data_field (MetadataPtr field)
396 list.push_back (field);
399 /* SessionMetadataSetEditable */
401 SessionMetadataSetEditable::SessionMetadataSetEditable (string const & name)
402 : SessionMetadataSet (name)
404 table.set_row_spacings (6);
405 table.set_col_spacings (12);
406 table.set_homogeneous (false);
407 vbox.pack_start (table, false, false);
408 vbox.set_spacing (6);
409 vbox.set_border_width (6);
413 SessionMetadataSetEditable::get_tab_widget ()
415 tab_widget.set_text (name);
420 SessionMetadataSetEditable::set_session (ARDOUR::Session * s)
422 SessionHandlePtr::set_session (s);
428 ARDOUR::SessionMetadata const & data = *(ARDOUR::SessionMetadata::Metadata());
430 table.resize (list.size(), 2);
433 for (DataList::const_iterator it = list.begin(); it != list.end(); ++it) {
435 field->load_data (data);
436 table.attach (field->name_widget(), 0, 1, row, row + 1, Gtk::FILL);
437 table.attach (field->edit_widget(), 1, 2, row, row + 1);
443 SessionMetadataSetEditable::save_data ()
445 ARDOUR::SessionMetadata & data = *(ARDOUR::SessionMetadata::Metadata());
446 for (DataList::const_iterator it = list.begin(); it != list.end(); ++it) {
447 (*it)->save_data(data);
451 /* SessionMetadataSetImportable */
453 SessionMetadataSetImportable::SessionMetadataSetImportable (string const & name)
454 : SessionMetadataSet (name)
455 , session_list (list)
457 tree = Gtk::ListStore::create (tree_cols);
458 tree_view.set_model (tree);
460 Gtk::TreeView::Column * viewcol;
463 Gtk::CellRendererToggle * import_render = Gtk::manage(new Gtk::CellRendererToggle());
464 import_render->signal_toggled().connect (sigc::mem_fun(*this, &SessionMetadataSetImportable::selection_changed));
465 viewcol = Gtk::manage(new Gtk::TreeView::Column (_("Import"), *import_render));
466 viewcol->add_attribute (import_render->property_active(), tree_cols.import);
467 tree_view.append_column (*viewcol);
469 // Add field name column
470 tree_view.append_column(_("Field"), tree_cols.field);
472 // Add values column with pango markup
473 Gtk::CellRendererText * values_render = Gtk::manage(new Gtk::CellRendererText());
474 viewcol = Gtk::manage(new Gtk::TreeView::Column (_("Values (current value on top)"), *values_render));
475 viewcol->add_attribute (values_render->property_markup(), tree_cols.values);
476 tree_view.append_column (*viewcol);
478 select_all_check.signal_toggled().connect (sigc::mem_fun(*this, &SessionMetadataSetImportable::select_all));
482 SessionMetadataSetImportable::get_tab_widget ()
484 tab_widget.set_text (name);
489 SessionMetadataSetImportable::get_select_all_widget ()
491 select_all_check.set_label (name);
492 return select_all_check;
496 SessionMetadataSetImportable::load_extra_data (ARDOUR::SessionMetadata const & data)
499 error << string_compose (_("programming error: %1"), "no session set for SessionMetaDataSetImportable (in load_data)!") << endmsg;
503 ARDOUR::SessionMetadata const & session_data = *(ARDOUR::SessionMetadata::Metadata());
505 MetadataPtr session_field;
506 MetadataPtr import_field;
507 DataList::iterator session_it;
508 DataList::iterator import_it;
510 // Copy list and load data to import
511 for (session_it = session_list.begin(); session_it != session_list.end(); ++session_it) {
512 session_field = *session_it;
513 session_field->load_data(session_data);
514 import_list.push_back (session_field->copy());
518 session_it = session_list.begin();
519 import_it = import_list.begin();
520 while (session_it != session_list.end() && import_it != import_list.end()) { // _should_ be the same...
521 session_field = *session_it;
522 import_field = *import_it;
524 import_field->load_data(data); // hasn't been done yet
526 // Make string for values TODO get color from somewhere?
527 string values = "<span weight=\"ultralight\" color=\"#777\">" + session_field->value() + "</span>\n"
528 + "<span weight=\"bold\">" + import_field->value() + "</span>";
530 Gtk::TreeModel::iterator row_iter = tree->append();
531 Gtk::TreeModel::Row row = *row_iter;
533 row[tree_cols.field] = import_field->name();
534 row[tree_cols.values] = values;
535 row[tree_cols.import] = false;
536 row[tree_cols.data] = import_field;
544 SessionMetadataSetImportable::save_data ()
547 error << string_compose (_("programming error: %1"), "no session set for SessionMetaDataSetImportable (in import_data)!") << endmsg;
551 ARDOUR::SessionMetadata & session_data = *(ARDOUR::SessionMetadata::Metadata());
553 Gtk::TreeModel::Children fields = tree->children();
554 Gtk::TreeModel::Children::iterator it;
555 for (it = fields.begin(); it != fields.end(); ++it) {
556 if ((*it)[tree_cols.import]) {
557 MetadataPtr field = (*it)[tree_cols.data];
558 field->save_data (session_data);
564 SessionMetadataSetImportable::select_all ()
566 select_all_check.set_inconsistent (false);
567 bool state = select_all_check.get_active();
569 Gtk::TreeModel::Children fields = tree->children();
570 Gtk::TreeModel::Children::iterator it;
571 for (it = fields.begin(); it != fields.end(); ++it) {
572 (*it)[tree_cols.import] = state;
577 SessionMetadataSetImportable::selection_changed (string const & path)
579 select_all_check.set_inconsistent (true);
581 Gtk::TreeModel::iterator iter = tree->get_iter (path);
582 bool value((*iter)[tree_cols.import]);
583 (*iter)[tree_cols.import] = !value;
586 /* SessionMetadataDialog */
588 template <typename DataSet>
589 SessionMetadataDialog<DataSet>::SessionMetadataDialog (string const & name) :
590 ArdourDialog (name, true)
592 cancel_button = add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
593 cancel_button->signal_clicked().connect (sigc::mem_fun(*this, &SessionMetadataDialog::end_dialog));
594 save_button = add_button (Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
595 save_button->signal_clicked().connect (sigc::mem_fun(*this, &SessionMetadataDialog::save_and_close));
598 template <typename DataSet>
600 SessionMetadataDialog<DataSet>::init_data ( bool skip_user )
603 error << string_compose (_("programming error: %1"), "no session set for SessionMetaDataDialog (in init_data)!") << endmsg;
613 init_description_data ();
615 for (DataSetList::iterator it = data_list.begin(); it != data_list.end(); ++it) {
616 (*it)->set_session (_session);
618 notebook.append_page ((*it)->get_widget(), (*it)->get_tab_widget());
622 template <typename DataSet>
624 SessionMetadataDialog<DataSet>::load_extra_data (ARDOUR::SessionMetadata const & data)
626 for (DataSetList::iterator it = data_list.begin(); it != data_list.end(); ++it) {
627 (*it)->load_extra_data (data);
631 template <typename DataSet>
633 SessionMetadataDialog<DataSet>::save_data ()
635 for (DataSetList::iterator it = data_list.begin(); it != data_list.end(); ++it) {
640 template <typename DataSet>
642 SessionMetadataDialog<DataSet>::save_and_close ()
645 _session->set_dirty();
649 template <typename DataSet>
651 SessionMetadataDialog<DataSet>::end_dialog ()
656 template <typename DataSet>
658 SessionMetadataDialog<DataSet>::warn_user (string const & string)
660 Gtk::MessageDialog msg (string, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
664 template <typename DataSet>
665 boost::shared_ptr<std::list<Gtk::Widget *> >
666 SessionMetadataDialog<DataSet>::get_custom_widgets (WidgetFunc f)
668 WidgetListPtr list (new WidgetList);
669 for (DataSetList::iterator it = data_list.begin(); it != data_list.end(); ++it)
671 DataSet * set = dynamic_cast<DataSet *> (it->get());
672 list->push_back (& CALL_MEMBER_FN (*set, f) ());
678 template <typename DataSet>
680 SessionMetadataDialog<DataSet>::add_widget (Gtk::Widget & widget)
682 get_vbox()->pack_start (widget, true, true, 0);
685 template <typename DataSet>
687 SessionMetadataDialog<DataSet>::init_user_data ()
689 DataSetPtr data_set (new DataSet (_("User")));
690 data_list.push_back (data_set);
694 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::user_name, &ARDOUR::SessionMetadata::set_user_name, _("Name")));
695 data_set->add_data_field (ptr);
697 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::user_email, &ARDOUR::SessionMetadata::set_user_email, _("Email")));
698 data_set->add_data_field (ptr);
700 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::user_web, &ARDOUR::SessionMetadata::set_user_web, _("Web")));
701 data_set->add_data_field (ptr);
703 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::organization, &ARDOUR::SessionMetadata::set_organization, _("Organization")));
704 data_set->add_data_field (ptr);
706 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::country, &ARDOUR::SessionMetadata::set_country, _("Country")));
707 data_set->add_data_field (ptr);
711 template <typename DataSet>
713 SessionMetadataDialog<DataSet>::init_description_data ()
715 DataSetPtr data_set (new DataSet (_("Description")));
716 data_list.push_back (data_set);
720 ptr = MetadataPtr (new LongTextMetadataField (&ARDOUR::SessionMetadata::description, &ARDOUR::SessionMetadata::set_description, _("Description")));
721 data_set->add_data_field (ptr);
725 template <typename DataSet>
727 SessionMetadataDialog<DataSet>::init_track_data ()
729 DataSetPtr data_set (new DataSet (_("Track")));
730 data_list.push_back (data_set);
734 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::title, &ARDOUR::SessionMetadata::set_title, _("Title")));
735 data_set->add_data_field (ptr);
737 ptr = MetadataPtr (new NumberMetadataField (&ARDOUR::SessionMetadata::track_number, &ARDOUR::SessionMetadata::set_track_number, _("Track Number"), 3));
738 data_set->add_data_field (ptr);
740 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::subtitle, &ARDOUR::SessionMetadata::set_subtitle, _("Subtitle")));
741 data_set->add_data_field (ptr);
743 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::grouping, &ARDOUR::SessionMetadata::set_grouping, _("Grouping")));
744 data_set->add_data_field (ptr);
746 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::artist, &ARDOUR::SessionMetadata::set_artist, _("Artist")));
747 data_set->add_data_field (ptr);
749 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::genre, &ARDOUR::SessionMetadata::set_genre, _("Genre")));
750 data_set->add_data_field (ptr);
752 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::comment, &ARDOUR::SessionMetadata::set_comment, _("Comment")));
753 data_set->add_data_field (ptr);
755 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::copyright, &ARDOUR::SessionMetadata::set_copyright, _("Copyright")));
756 data_set->add_data_field (ptr);
759 template <typename DataSet>
761 SessionMetadataDialog<DataSet>::init_album_data ()
763 DataSetPtr data_set (new DataSet (_("Album")));
764 data_list.push_back (data_set);
768 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::album, &ARDOUR::SessionMetadata::set_album, _("Album")));
769 data_set->add_data_field (ptr);
771 ptr = MetadataPtr (new NumberMetadataField (&ARDOUR::SessionMetadata::year, &ARDOUR::SessionMetadata::set_year, _("Year"), 4));
772 data_set->add_data_field (ptr);
774 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::album_artist, &ARDOUR::SessionMetadata::set_album_artist, _("Album Artist")));
775 data_set->add_data_field (ptr);
777 ptr = MetadataPtr (new NumberMetadataField (&ARDOUR::SessionMetadata::total_tracks, &ARDOUR::SessionMetadata::set_total_tracks, _("Total Tracks"), 3));
778 data_set->add_data_field (ptr);
780 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::disc_subtitle, &ARDOUR::SessionMetadata::set_disc_subtitle, _("Disc Subtitle")));
781 data_set->add_data_field (ptr);
783 ptr = MetadataPtr (new NumberMetadataField (&ARDOUR::SessionMetadata::disc_number, &ARDOUR::SessionMetadata::set_disc_number, _("Disc Number"), 2));
784 data_set->add_data_field (ptr);
786 ptr = MetadataPtr (new NumberMetadataField (&ARDOUR::SessionMetadata::total_discs, &ARDOUR::SessionMetadata::set_total_discs, _("Total Discs"), 2));
787 data_set->add_data_field (ptr);
789 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::compilation, &ARDOUR::SessionMetadata::set_compilation, _("Compilation")));
790 data_set->add_data_field (ptr);
792 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::isrc, &ARDOUR::SessionMetadata::set_isrc, _("ISRC")));
793 data_set->add_data_field (ptr);
795 ptr = MetadataPtr (new EAN13MetadataField (&ARDOUR::SessionMetadata::barcode, &ARDOUR::SessionMetadata::set_barcode, _("EAN barcode")));
796 data_set->add_data_field (ptr);
798 // EAN13MetadataField is the only kind of MetadataField which has a status label.
799 EAN13MetadataField &emf = (EAN13MetadataField &) *ptr;
800 ((Gtk::VBox &) data_set->get_widget()).pack_end (*emf.status_label);
801 emf.update_status ();
804 template <typename DataSet>
806 SessionMetadataDialog<DataSet>::init_people_data ()
808 DataSetPtr data_set (new DataSet (_("People")));
809 data_list.push_back (data_set);
813 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::lyricist, &ARDOUR::SessionMetadata::set_lyricist, _("Lyricist")));
814 data_set->add_data_field (ptr);
816 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::composer, &ARDOUR::SessionMetadata::set_composer, _("Composer")));
817 data_set->add_data_field (ptr);
819 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::conductor, &ARDOUR::SessionMetadata::set_conductor, _("Conductor")));
820 data_set->add_data_field (ptr);
822 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::remixer, &ARDOUR::SessionMetadata::set_remixer, _("Remixer")));
823 data_set->add_data_field (ptr);
825 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::arranger, &ARDOUR::SessionMetadata::set_arranger, _("Arranger")));
826 data_set->add_data_field (ptr);
828 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::engineer, &ARDOUR::SessionMetadata::set_engineer, _("Engineer")));
829 data_set->add_data_field (ptr);
831 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::producer, &ARDOUR::SessionMetadata::set_producer, _("Producer")));
832 data_set->add_data_field (ptr);
834 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::dj_mixer, &ARDOUR::SessionMetadata::set_dj_mixer, _("DJ Mixer")));
835 data_set->add_data_field (ptr);
837 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::mixer, &ARDOUR::SessionMetadata::set_mixer, S_("Metadata|Mixer")));
838 data_set->add_data_field (ptr);
841 template <typename DataSet>
843 SessionMetadataDialog<DataSet>::init_school_data ()
845 DataSetPtr data_set (new DataSet (_("School")));
846 data_list.push_back (data_set);
850 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::instructor, &ARDOUR::SessionMetadata::set_instructor, _("Instructor")));
851 data_set->add_data_field (ptr);
853 ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::course, &ARDOUR::SessionMetadata::set_course, _("Course")));
854 data_set->add_data_field (ptr);
858 /* SessionMetadataEditor */
860 SessionMetadataEditor::SessionMetadataEditor () :
861 SessionMetadataDialog<SessionMetadataSetEditable> (_("Edit Session Metadata"))
866 SessionMetadataEditor::~SessionMetadataEditor ()
868 // Remove pages from notebook to get rid of gsignal runtime warnings
869 notebook.pages().clear();
873 SessionMetadataEditor::run ()
882 SessionMetadataEditor::init_gui ()
884 add_widget (notebook);
889 /* SessionMetadataImporter */
891 SessionMetadataImporter::SessionMetadataImporter () :
892 SessionMetadataDialog<SessionMetadataSetImportable> (_("Import session metadata"))
897 SessionMetadataImporter::~SessionMetadataImporter ()
899 // Remove pages from notebook to get rid of gsignal runtime warnings
900 notebook.pages().clear();
904 SessionMetadataImporter::run ()
907 error << string_compose (_("programming error: %1"), "no session set for SessionMetaDataImporter (in run)!") << endmsg;
911 /* Open session file selector */
913 Gtk::FileChooserDialog session_selector(_("Choose session to import metadata from"), Gtk::FILE_CHOOSER_ACTION_OPEN);
914 Gtkmm2ext::add_volume_shortcuts (session_selector);
915 session_selector.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
916 session_selector.add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
917 session_selector.set_default_response(Gtk::RESPONSE_ACCEPT);
919 Gtk::FileFilter session_filter;
920 session_filter.add_pattern (string_compose(X_("*%1"), ARDOUR::statefile_suffix));
921 session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
922 session_selector.add_filter (session_filter);
923 session_selector.set_filter (session_filter);
925 int response = session_selector.run();
926 session_selector.hide ();
929 case Gtk::RESPONSE_ACCEPT:
935 string session_path = session_selector.get_filename();
939 if (session_path.length() > 0) {
940 if (ARDOUR::find_session (session_path, path, name, isnew) != 0) {
947 /* We have a session: load the data and run dialog */
949 string filename = Glib::build_filename (path, name + ARDOUR::statefile_suffix);
950 XMLTree session_tree;
951 if (!session_tree.read (filename)) {
952 warn_user (_("This session file could not be read!"));
956 /* XXX GET VERSION FROM TREE */
959 XMLNode * node = session_tree.root()->child ("Metadata");
962 warn_user (_("The session file didn't contain metadata!\nMaybe this is an old session format?"));
967 ARDOUR::SessionMetadata data;
968 data.set_state (*node, version);
969 init_data ( true ); //skip user data here
970 load_extra_data (data);
977 SessionMetadataImporter::init_gui ()
979 // Select all from -widget
980 add_widget (selection_hbox);
981 selection_label.set_text (_("Import all from:"));
982 selection_hbox.pack_start (selection_label, false, false);
984 WidgetListPtr list = get_custom_widgets (&SessionMetadataSetImportable::get_select_all_widget);
985 for (WidgetList::iterator it = list->begin(); it != list->end(); ++it) {
986 selection_hbox.pack_start (**it, false, false, 6);
989 add_widget (notebook);