675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "session_metadata_dialog.h"
-
#include <sstream>
-
-#include <gtkmm2ext/utils.h>
+#include <gtkmm/filechooserdialog.h>
+#include <gtkmm/messagedialog.h>
+#include <gtkmm/stock.h>
#include "pbd/xml++.h"
+#include "pbd/error.h"
+
+#include "ardour/filename_extensions.h"
#include "ardour/session.h"
-#include "ardour/session_directory.h"
#include "ardour/session_utils.h"
-#include "i18n.h"
+#include "gtkmm2ext/utils.h"
+
+#include "session_metadata_dialog.h"
+
+#include "pbd/i18n.h"
using namespace std;
using namespace Glib;
+using namespace PBD;
#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))
/*** MetadataField ***/
-MetadataField::MetadataField (ustring const & field_name) :
+MetadataField::MetadataField (string const & field_name) :
_name (field_name)
{
}
/* TextMetadataField */
-TextMetadataField::TextMetadataField (Getter getter, Setter setter, ustring const & field_name, guint width ) :
+TextMetadataField::TextMetadataField (Getter getter, Setter setter, string const & field_name, guint width ) :
MetadataField (field_name),
getter (getter),
setter (setter),
Gtk::Widget &
TextMetadataField::name_widget ()
{
- label = Gtk::manage (new Gtk::Label(_name + ':', Gtk::ALIGN_LEFT));
+ label = Gtk::manage (new Gtk::Label(_name + ':'));
+ label->set_alignment (1, 0.5);
return *label;
}
/* NumberMetadataField */
-NumberMetadataField::NumberMetadataField (Getter getter, Setter setter, ustring const & field_name, guint numbers, guint width) :
+NumberMetadataField::NumberMetadataField (Getter getter, Setter setter, string const & field_name, guint numbers, guint width) :
MetadataField (field_name),
getter (getter),
setter (setter),
void
NumberMetadataField::update_value ()
{
- // Accpt only numbers
+ // Accept only numbers that will fit into a uint32_t
uint32_t number = str_to_uint (entry->get_text());
_value = uint_to_str (number);
entry->set_text (_value);
Gtk::Widget &
NumberMetadataField::name_widget ()
{
- label = Gtk::manage (new Gtk::Label(_name + ':', Gtk::ALIGN_LEFT));
+ label = Gtk::manage (new Gtk::Label(_name + ':'));
+ label->set_alignment (1, 0.5);
return *label;
}
return *entry;
}
-ustring
+string
NumberMetadataField::uint_to_str (uint32_t i) const
{
std::ostringstream oss ("");
}
uint32_t
-NumberMetadataField::str_to_uint (ustring const & str) const
+NumberMetadataField::str_to_uint (string const & str) const
{
- ustring tmp (str);
- ustring::size_type i;
- while ((i = tmp.find_first_not_of("1234567890")) != ustring::npos) {
+ string tmp (str);
+ string::size_type i;
+ while ((i = tmp.find_first_not_of("1234567890")) != string::npos) {
tmp.erase (i, 1);
}
}
+
+/* EAN13MetadataField */
+
+EAN13MetadataField::EAN13MetadataField (Getter getter, Setter setter, string const & field_name, guint width) :
+ MetadataField (field_name),
+ getter (getter),
+ setter (setter),
+ width (width)
+{
+ entry = 0;
+ label = 0;
+ value_label = 0;
+ status_label = Gtk::manage (new Gtk::Label (""));
+}
+
+MetadataPtr
+EAN13MetadataField::copy ()
+{
+ return MetadataPtr (new EAN13MetadataField (getter, setter, _name, width));
+}
+
+void
+EAN13MetadataField::save_data (ARDOUR::SessionMetadata & data) const
+{
+ CALL_MEMBER_FN (data, setter) (_value);
+}
+
+void
+EAN13MetadataField::load_data (ARDOUR::SessionMetadata const & data)
+{
+ _value = CALL_MEMBER_FN (data, getter) ();
+ if (entry) {
+ entry->set_text (_value);
+ }
+ update_status ();
+}
+
+void
+EAN13MetadataField::update_value ()
+{
+ // Accept only numeric characters
+ _value = numeric_string (entry->get_text());
+ entry->set_text (_value);
+ update_status ();
+}
+
+void
+EAN13MetadataField::update_status ()
+{
+ int len = _value.length ();
+ if (len == 13) {
+ // calculate EAN-13 modulo 10 check digit
+ int sum = 0;
+ const char *p = _value.c_str();
+ for (int i = 0; i < 12; i++) {
+ char c = p[i] - '0';
+ if (i % 2) {
+ sum += c * 3;
+ } else {
+ sum += c;
+ }
+ }
+ sum %= 10;
+ if (sum)
+ sum = 10 - sum;
+
+ if (sum == p[12] - '0') {
+ status_label->set_markup (string_compose(
+ "<span color=\"green\">%1: %2</span>",
+ _("EAN Check digit OK"), sum));
+ } else {
+ status_label->set_markup (string_compose(
+ "<span color=\"#ffa755\">%1: %2 (%3 %4)</span>",
+ _("EAN Check digit error"), p[12] - '0', _("expected"), sum));
+ }
+ } else if (len > 0) {
+ status_label->set_markup (string_compose(
+ "<span color=\"#ffa755\">%1: %2 (<13)</span>",
+ _("EAN Length error"), len));
+ } else {
+ status_label->set_text("");
+ }
+}
+
+Gtk::Widget &
+EAN13MetadataField::name_widget ()
+{
+ label = Gtk::manage (new Gtk::Label(_name + ':'));
+ label->set_alignment (1, 0.5);
+ return *label;
+}
+
+Gtk::Widget &
+EAN13MetadataField::value_widget ()
+{
+ value_label = Gtk::manage (new Gtk::Label(_value));
+ return *value_label;
+}
+
+Gtk::Widget &
+EAN13MetadataField::edit_widget ()
+{
+ entry = Gtk::manage (new Gtk::Entry());
+
+ entry->set_text (_value);
+ entry->set_width_chars (width);
+ entry->set_max_length (13);
+ entry->signal_changed().connect (sigc::mem_fun(*this, &EAN13MetadataField::update_value));
+
+ return *entry;
+}
+
+string
+EAN13MetadataField::numeric_string (string const & str) const
+{
+ string tmp (str);
+ string::size_type i;
+ while ((i = tmp.find_first_not_of("1234567890")) != string::npos) {
+ tmp.erase (i, 1);
+ }
+ return tmp;
+}
+
/* SessionMetadataSet */
-SessionMetadataSet::SessionMetadataSet (ustring const & name) :
- name (name)
+SessionMetadataSet::SessionMetadataSet (string const & name)
+ : name (name)
{
}
/* SessionMetadataSetEditable */
-SessionMetadataSetEditable::SessionMetadataSetEditable (ustring const & name) :
- SessionMetadataSet (name)
+SessionMetadataSetEditable::SessionMetadataSetEditable (string const & name)
+ : SessionMetadataSet (name)
{
table.set_row_spacings (6);
table.set_col_spacings (12);
+ table.set_homogeneous (false);
vbox.pack_start (table, false, false);
vbox.set_spacing (6);
vbox.set_border_width (6);
return;
}
- ARDOUR::SessionMetadata const & data = _session->metadata();
+ ARDOUR::SessionMetadata const & data = *(ARDOUR::SessionMetadata::Metadata());
table.resize (list.size(), 2);
uint32_t row = 0;
for (DataList::const_iterator it = list.begin(); it != list.end(); ++it) {
field = *it;
field->load_data (data);
- table.attach (field->name_widget(), 0, 1, row, row + 1);
+ table.attach (field->name_widget(), 0, 1, row, row + 1, Gtk::FILL);
table.attach (field->edit_widget(), 1, 2, row, row + 1);
++row;
}
void
SessionMetadataSetEditable::save_data ()
{
- ARDOUR::SessionMetadata & data = _session->metadata();
+ ARDOUR::SessionMetadata & data = *(ARDOUR::SessionMetadata::Metadata());
for (DataList::const_iterator it = list.begin(); it != list.end(); ++it) {
(*it)->save_data(data);
}
/* SessionMetadataSetImportable */
-SessionMetadataSetImportable::SessionMetadataSetImportable (ustring const & name) :
- SessionMetadataSet (name),
- session_list (list)
+SessionMetadataSetImportable::SessionMetadataSetImportable (string const & name)
+ : SessionMetadataSet (name)
+ , session_list (list)
{
tree = Gtk::ListStore::create (tree_cols);
tree_view.set_model (tree);
SessionMetadataSetImportable::load_extra_data (ARDOUR::SessionMetadata const & data)
{
if (!_session) {
- std::cerr << "Programming error: no session set for SessionMetaDataSetImportable (in load_data)!" << std::endl;
+ error << string_compose (_("programming error: %1"), "no session set for SessionMetaDataSetImportable (in load_data)!") << endmsg;
return;
}
- ARDOUR::SessionMetadata & session_data = _session->metadata();
+ ARDOUR::SessionMetadata const & session_data = *(ARDOUR::SessionMetadata::Metadata());
MetadataPtr session_field;
MetadataPtr import_field;
import_field->load_data(data); // hasn't been done yet
// Make string for values TODO get color from somewhere?
- ustring values = "<span weight=\"ultralight\" color=\"#777\">" + session_field->value() + "</span>\n"
- + "<span weight=\"bold\">" + import_field->value() + "</span>";
+ string values = "<span weight=\"ultralight\" color=\"#777\">" + session_field->value() + "</span>\n"
+ + "<span weight=\"bold\">" + import_field->value() + "</span>";
Gtk::TreeModel::iterator row_iter = tree->append();
Gtk::TreeModel::Row row = *row_iter;
SessionMetadataSetImportable::save_data ()
{
if (!_session) {
- std::cerr << "Programming error: no session set for SessionMetaDataSetImportable (in import_data)!" << std::endl;
+ error << string_compose (_("programming error: %1"), "no session set for SessionMetaDataSetImportable (in import_data)!") << endmsg;
return;
}
- ARDOUR::SessionMetadata & session_data = _session->metadata();
+ ARDOUR::SessionMetadata & session_data = *(ARDOUR::SessionMetadata::Metadata());
Gtk::TreeModel::Children fields = tree->children();
Gtk::TreeModel::Children::iterator it;
}
void
-SessionMetadataSetImportable::selection_changed (ustring const & path)
+SessionMetadataSetImportable::selection_changed (string const & path)
{
select_all_check.set_inconsistent (true);
/* SessionMetadataDialog */
template <typename DataSet>
-SessionMetadataDialog<DataSet>::SessionMetadataDialog (ustring const & name) :
+SessionMetadataDialog<DataSet>::SessionMetadataDialog (string const & name) :
ArdourDialog (name, true)
{
cancel_button = add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
cancel_button->signal_clicked().connect (sigc::mem_fun(*this, &SessionMetadataDialog::end_dialog));
- save_button = add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
+ save_button = add_button (Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
save_button->signal_clicked().connect (sigc::mem_fun(*this, &SessionMetadataDialog::save_and_close));
}
template <typename DataSet>
void
-SessionMetadataDialog<DataSet>::init_data ()
+SessionMetadataDialog<DataSet>::init_data ( bool skip_user )
{
if (!_session) {
- std::cerr << "Programming error: no session set for SessionMetaDataDialog (in init_data)!" << std::endl;
+ error << string_compose (_("programming error: %1"), "no session set for SessionMetaDataDialog (in init_data)!") << endmsg;
return;
}
+ if (!skip_user)
+ init_user_data ();
init_track_data ();
init_album_data ();
init_people_data ();
+ init_school_data ();
for (DataSetList::iterator it = data_list.begin(); it != data_list.end(); ++it) {
(*it)->set_session (_session);
SessionMetadataDialog<DataSet>::save_and_close ()
{
save_data ();
+ _session->set_dirty();
end_dialog ();
}
template <typename DataSet>
void
-SessionMetadataDialog<DataSet>::warn_user (ustring const & string)
+SessionMetadataDialog<DataSet>::warn_user (string const & string)
{
Gtk::MessageDialog msg (string, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
msg.run();
get_vbox()->pack_start (widget, true, true, 0);
}
+template <typename DataSet>
+void
+SessionMetadataDialog<DataSet>::init_user_data ()
+{
+ DataSetPtr data_set (new DataSet (_("User")));
+ data_list.push_back (data_set);
+
+ MetadataPtr ptr;
+
+ ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::user_name, &ARDOUR::SessionMetadata::set_user_name, _("Name")));
+ data_set->add_data_field (ptr);
+
+ ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::user_email, &ARDOUR::SessionMetadata::set_user_email, _("Email")));
+ data_set->add_data_field (ptr);
+
+ ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::user_web, &ARDOUR::SessionMetadata::set_user_web, _("Web")));
+ data_set->add_data_field (ptr);
+
+ ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::organization, &ARDOUR::SessionMetadata::set_organization, _("Organization")));
+ data_set->add_data_field (ptr);
+
+ ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::country, &ARDOUR::SessionMetadata::set_country, _("Country")));
+ data_set->add_data_field (ptr);
+
+}
+
template <typename DataSet>
void
SessionMetadataDialog<DataSet>::init_track_data ()
ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::isrc, &ARDOUR::SessionMetadata::set_isrc, _("ISRC")));
data_set->add_data_field (ptr);
+
+ ptr = MetadataPtr (new EAN13MetadataField (&ARDOUR::SessionMetadata::barcode, &ARDOUR::SessionMetadata::set_barcode, _("EAN barcode")));
+ data_set->add_data_field (ptr);
+
+ // EAN13MetadataField is the only kind of MetadataField which has a status label.
+ EAN13MetadataField &emf = (EAN13MetadataField &) *ptr;
+ ((Gtk::VBox &) data_set->get_widget()).pack_end (*emf.status_label);
+ emf.update_status ();
}
template <typename DataSet>
ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::dj_mixer, &ARDOUR::SessionMetadata::set_dj_mixer, _("DJ Mixer")));
data_set->add_data_field (ptr);
- ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::mixer, &ARDOUR::SessionMetadata::set_mixer, _("Mixer")));
+ ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::mixer, &ARDOUR::SessionMetadata::set_mixer, S_("Metadata|Mixer")));
data_set->add_data_field (ptr);
}
+template <typename DataSet>
+void
+SessionMetadataDialog<DataSet>::init_school_data ()
+{
+ DataSetPtr data_set (new DataSet (_("School")));
+ data_list.push_back (data_set);
+
+ MetadataPtr ptr;
+
+ ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::instructor, &ARDOUR::SessionMetadata::set_instructor, _("Instructor")));
+ data_set->add_data_field (ptr);
+
+ ptr = MetadataPtr (new TextMetadataField (&ARDOUR::SessionMetadata::course, &ARDOUR::SessionMetadata::set_course, _("Course")));
+ data_set->add_data_field (ptr);
+
+}
+
/* SessionMetadataEditor */
SessionMetadataEditor::SessionMetadataEditor () :
SessionMetadataImporter::run ()
{
if (!_session) {
- std::cerr << "Programming error: no session set for SessionMetaDataImporter (in run)!" << std::endl;
+ error << string_compose (_("programming error: %1"), "no session set for SessionMetaDataImporter (in run)!") << endmsg;
return;
}
session_selector.set_default_response(Gtk::RESPONSE_ACCEPT);
Gtk::FileFilter session_filter;
- session_filter.add_pattern ("*.ardour");
- session_filter.set_name (_("Ardour sessions"));
+ session_filter.add_pattern (string_compose(X_("*%1"), ARDOUR::statefile_suffix));
+ session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
session_selector.add_filter (session_filter);
session_selector.set_filter (session_filter);
/* We have a session: load the data and run dialog */
- string filename = Glib::build_filename (path, name + ".ardour");
+ string filename = Glib::build_filename (path, name + ARDOUR::statefile_suffix);
XMLTree session_tree;
if (!session_tree.read (filename)) {
- warn_user (_("A proper ardour session file was not selected!"));
+ warn_user (_("This session file could not be read!"));
return;
}
return;
}
+ //create a temporary
ARDOUR::SessionMetadata data;
data.set_state (*node, version);
-
- init_data ();
+ init_data ( true ); //skip user data here
load_extra_data (data);
init_gui();