1 /* 2 * Copyright (C) 2008-2013 Paul Davis <paul@linuxaudiosystems.com> 3 * Copyright (C) 2009 Carl Hetherington <carl@carlh.net> 4 * Copyright (C) 2009 David Robillard <d@drobilla.net> 5 * Copyright (C) 2015 Colin Fletcher <colin.m.fletcher@googlemail.com> 6 * Copyright (C) 2017 Robin Gareus <robin@gareus.org> 7 * 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. 12 * 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. 17 * 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. 21 */ 22 23 #ifndef __session_metadata_dialog_h__ 24 #define __session_metadata_dialog_h__ 25 26 #include "ardour_dialog.h" 27 28 #ifdef interface 29 #undef interface 30 #endif 31 32 #include <gtkmm/box.h> 33 #include <gtkmm/button.h> 34 #include <gtkmm/checkbutton.h> 35 #include <gtkmm/entry.h> 36 #include <gtkmm/label.h> 37 #include <gtkmm/liststore.h> 38 #include <gtkmm/notebook.h> 39 #include <gtkmm/table.h> 40 #include <gtkmm/textview.h> 41 #include <gtkmm/treemodel.h> 42 #include <gtkmm/treeview.h> 43 44 #include <boost/shared_ptr.hpp> 45 46 #include <string> 47 #include <list> 48 49 #include "ardour/session_metadata.h" 50 51 class MetadataField; 52 typedef boost::shared_ptr<MetadataField> MetadataPtr; 53 54 /// Wraps a metadata field to be used in a GUI 55 class MetadataField 56 { 57 public: 58 MetadataField (std::string const & field_name); 59 virtual ~MetadataField(); 60 virtual MetadataPtr copy () = 0; 61 62 virtual void save_data (ARDOUR::SessionMetadata & data) const = 0; 63 virtual void load_data (ARDOUR::SessionMetadata const & data) = 0; 64 name()65 virtual std::string name() { return _name; } value()66 virtual std::string value() { return _value; } 67 68 /// Get widget containing name of field 69 virtual Gtk::Widget & name_widget () = 0; 70 /// Get label containing value of field 71 virtual Gtk::Widget & value_widget () = 0; 72 /// Get widget for editing value 73 virtual Gtk::Widget & edit_widget () = 0; 74 protected: 75 std::string _name; 76 std::string _value; 77 }; 78 79 /// MetadataField that contains text 80 class TextMetadataField : public MetadataField 81 { 82 protected: 83 typedef std::string (ARDOUR::SessionMetadata::*Getter) () const; 84 typedef void (ARDOUR::SessionMetadata::*Setter) (std::string const &); 85 public: 86 TextMetadataField (Getter getter, Setter setter, std::string const & field_name, guint width = 50); 87 MetadataPtr copy (); 88 89 void save_data (ARDOUR::SessionMetadata & data) const; 90 void load_data (ARDOUR::SessionMetadata const & data); 91 92 Gtk::Widget & name_widget (); 93 Gtk::Widget & value_widget (); 94 Gtk::Widget & edit_widget (); 95 protected: 96 void update_value (); 97 98 Getter getter; 99 Setter setter; 100 101 Gtk::Label* label; 102 Gtk::Label* value_label; 103 Gtk::Entry* entry; 104 105 guint width; 106 }; 107 108 /// MetadataField that contains longform text 109 class LongTextMetadataField : public TextMetadataField 110 { 111 public: 112 LongTextMetadataField (Getter getter, Setter setter, std::string const & field_name, guint width = 50); 113 MetadataPtr copy (); 114 115 Gtk::Widget & edit_widget (); 116 private: 117 void update_value (); 118 119 Gtk::TextView* tview; 120 }; 121 122 /// MetadataField that accepts only numbers 123 class NumberMetadataField : public MetadataField 124 { 125 private: 126 typedef uint32_t (ARDOUR::SessionMetadata::*Getter) () const; 127 typedef void (ARDOUR::SessionMetadata::*Setter) (uint32_t); 128 public: 129 NumberMetadataField (Getter getter, Setter setter, std::string const & field_name, guint numbers, guint width = 50); 130 MetadataPtr copy (); 131 132 void save_data (ARDOUR::SessionMetadata & data) const; 133 void load_data (ARDOUR::SessionMetadata const & data); 134 135 Gtk::Widget & name_widget (); 136 Gtk::Widget & value_widget (); 137 Gtk::Widget & edit_widget (); 138 private: 139 void update_value (); 140 std::string uint_to_str (uint32_t i) const; 141 uint32_t str_to_uint (std::string const & str) const; 142 143 Getter getter; 144 Setter setter; 145 146 Gtk::Label* label; 147 Gtk::Label* value_label; 148 Gtk::Entry* entry; 149 150 guint numbers; 151 guint width; 152 }; 153 154 /// MetadataField that accepts EAN-13 data only 155 class EAN13MetadataField : public MetadataField 156 { 157 private: 158 typedef std::string (ARDOUR::SessionMetadata::*Getter) () const; 159 typedef void (ARDOUR::SessionMetadata::*Setter) (std::string const &); 160 public: 161 EAN13MetadataField (Getter getter, Setter setter, std::string const & field_name, guint width = 13); 162 MetadataPtr copy (); 163 164 void save_data (ARDOUR::SessionMetadata & data) const; 165 void load_data (ARDOUR::SessionMetadata const & data); 166 167 Gtk::Widget & name_widget (); 168 Gtk::Widget & value_widget (); 169 Gtk::Widget & edit_widget (); 170 171 Gtk::Label* status_label; 172 void update_status (); 173 private: 174 void update_value (); 175 std::string numeric_string (std::string const & str) const; 176 177 Getter getter; 178 Setter setter; 179 180 Gtk::Label* label; 181 Gtk::Label* value_label; 182 Gtk::Entry* entry; 183 184 guint width; 185 }; 186 187 /// Interface for MetadataFields 188 class SessionMetadataSet : public ARDOUR::SessionHandlePtr 189 { 190 public: 191 SessionMetadataSet (std::string const & name); ~SessionMetadataSet()192 virtual ~SessionMetadataSet () {}; 193 194 void add_data_field (MetadataPtr field); 195 196 /// allows loading extra data into data sets (for importing etc.) load_extra_data(ARDOUR::SessionMetadata const &)197 virtual void load_extra_data (ARDOUR::SessionMetadata const & /*data*/) { } 198 /// Saves data to session 199 virtual void save_data () = 0; 200 201 virtual Gtk::Widget & get_widget () = 0; 202 virtual Gtk::Widget & get_tab_widget () = 0; 203 204 protected: 205 typedef std::list<MetadataPtr> DataList; 206 DataList list; 207 std::string name; 208 }; 209 210 /// Contains MetadataFields for editing 211 class SessionMetadataSetEditable : public SessionMetadataSet 212 { 213 public: 214 SessionMetadataSetEditable (std::string const & name); 215 get_widget()216 Gtk::Widget & get_widget () { return vbox; } 217 Gtk::Widget & get_tab_widget (); 218 219 /// Sets session and loads data 220 void set_session (ARDOUR::Session * s); 221 /// Saves from MetadataFields into data 222 void save_data (); 223 224 private: 225 Gtk::VBox vbox; 226 Gtk::Table table; 227 Gtk::Label tab_widget; 228 }; 229 230 /// Contains MetadataFields for importing 231 class SessionMetadataSetImportable : public SessionMetadataSet 232 { 233 public: 234 SessionMetadataSetImportable (std::string const & name); 235 get_widget()236 Gtk::Widget & get_widget () { return tree_view; } 237 Gtk::Widget & get_tab_widget (); 238 Gtk::Widget & get_select_all_widget (); 239 240 /// Loads importable data from data 241 void load_extra_data (ARDOUR::SessionMetadata const & data); 242 /// Saves from importable data (see load_data) to session_data 243 void save_data (); 244 245 private: 246 DataList & session_list; // References MetadataSet::list 247 DataList import_list; 248 249 struct Columns : public Gtk::TreeModel::ColumnRecord 250 { 251 public: 252 Gtk::TreeModelColumn<std::string> field; 253 Gtk::TreeModelColumn<std::string> values; 254 Gtk::TreeModelColumn<bool> import; 255 Gtk::TreeModelColumn<MetadataPtr> data; 256 ColumnsColumns257 Columns() { add (field); add (values); add (import); add (data); } 258 }; 259 260 Glib::RefPtr<Gtk::ListStore> tree; 261 Columns tree_cols; 262 Gtk::TreeView tree_view; 263 264 Gtk::Label tab_widget; 265 Gtk::CheckButton select_all_check; 266 267 void select_all (); 268 void selection_changed (std::string const & path); 269 }; 270 271 /// Metadata dialog interface 272 /** 273 * The DataSets are initalized in this class so that all 274 * Dialogs have the same sets of data in the same order. 275 */ 276 template <typename DataSet> 277 class SessionMetadataDialog : public ArdourDialog 278 { 279 public: 280 SessionMetadataDialog (std::string const & name); 281 282 protected: 283 void init_data ( bool skip_user = false ); 284 void load_extra_data (ARDOUR::SessionMetadata const & data); 285 void save_data (); 286 287 virtual void init_gui () = 0; 288 virtual void save_and_close (); 289 virtual void end_dialog (); 290 291 void warn_user (std::string const & string); 292 293 typedef std::list<Gtk::Widget *> WidgetList; 294 typedef boost::shared_ptr<WidgetList> WidgetListPtr; 295 typedef Gtk::Widget & (DataSet::*WidgetFunc) (); 296 297 /// Returns list of widgets gathered by calling f for each data set 298 WidgetListPtr get_custom_widgets (WidgetFunc f); 299 300 /// Adds a widget to the table (vertical stacking) with automatic spacing 301 void add_widget (Gtk::Widget & widget); 302 303 Gtk::Notebook notebook; 304 305 private: 306 void init_user_data (); 307 void init_description_data (); 308 void init_track_data (); 309 void init_album_data (); 310 void init_people_data (); 311 void init_school_data (); 312 313 typedef boost::shared_ptr<SessionMetadataSet> DataSetPtr; 314 typedef std::list<DataSetPtr> DataSetList; 315 DataSetList data_list; 316 317 Gtk::Button * save_button; 318 Gtk::Button * cancel_button; 319 }; 320 321 class SessionMetadataEditor : public SessionMetadataDialog<SessionMetadataSetEditable> 322 { 323 public: 324 SessionMetadataEditor (); 325 ~SessionMetadataEditor (); 326 void run (); 327 private: 328 void init_gui (); 329 }; 330 331 class SessionMetadataImporter : public SessionMetadataDialog<SessionMetadataSetImportable> { 332 public: 333 SessionMetadataImporter (); 334 ~SessionMetadataImporter (); 335 void run (); 336 337 private: 338 void init_gui (); 339 340 // Select all from -widget 341 Gtk::HBox selection_hbox; 342 Gtk::Label selection_label; 343 344 }; 345 346 #endif 347