e1d02337b43e1c17262b1c440d5ee3f8a685716d
[ardour.git] / gtk2_ardour / session_metadata_dialog.h
1 /*
2     Copyright (C) 2008 Paul Davis
3     Author: Sakari Bergen
4
5     This program is free software; you can redistribute it and/or modify it
6     under the terms of the GNU General Public License as published by the Free
7     Software Foundation; either version 2 of the License, or (at your option)
8     any later version.
9
10     This program is distributed in the hope that it will be useful, but WITHOUT
11     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13     for more details.
14
15     You should have received a copy of the GNU General Public License along
16     with this program; if not, write to the Free Software Foundation, Inc.,
17     675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #ifndef __session_metadata_dialog_h__
21 #define __session_metadata_dialog_h__
22
23 #include "ardour_dialog.h"
24
25 #ifdef interface
26 #undef interface
27 #endif
28
29 #include <gtkmm.h>
30 #include <boost/shared_ptr.hpp>
31
32 #include <string>
33 #include <list>
34
35 #include "ardour/session_metadata.h"
36
37 class MetadataField;
38 typedef boost::shared_ptr<MetadataField> MetadataPtr;
39
40 /// Wraps a metadata field to be used in a GUI
41 class MetadataField
42 {
43 public:
44         MetadataField (std::string const & field_name);
45         virtual ~MetadataField();
46         virtual MetadataPtr copy () = 0;
47
48         virtual void save_data (ARDOUR::SessionMetadata & data) const = 0;
49         virtual void load_data (ARDOUR::SessionMetadata const & data) = 0;
50
51         virtual std::string name() { return _name; }
52         virtual std::string value() { return _value; }
53
54         /// Get widget containing name of field
55         virtual Gtk::Widget & name_widget () = 0;
56         /// Get label containing value of field
57         virtual Gtk::Widget & value_widget () = 0;
58         /// Get widget for editing value
59         virtual Gtk::Widget & edit_widget () = 0;
60 protected:
61         std::string _name;
62         std::string _value;
63 };
64
65 /// MetadataField that contains text
66 class TextMetadataField : public MetadataField
67 {
68 private:
69         typedef std::string (ARDOUR::SessionMetadata::*Getter) () const;
70         typedef void (ARDOUR::SessionMetadata::*Setter) (std::string const &);
71 public:
72         TextMetadataField (Getter getter, Setter setter, std::string const & field_name, guint width = 50);
73         MetadataPtr copy ();
74
75         void save_data (ARDOUR::SessionMetadata & data) const;
76         void load_data (ARDOUR::SessionMetadata const & data);
77
78         Gtk::Widget & name_widget ();
79         Gtk::Widget & value_widget ();
80         Gtk::Widget & edit_widget ();
81 private:
82         void update_value ();
83
84         Getter getter;
85         Setter setter;
86
87         Gtk::Label* label;
88         Gtk::Label* value_label;
89         Gtk::Entry* entry;
90
91         guint width;
92 };
93
94 /// MetadataField that accepts only numbers
95 class NumberMetadataField : public MetadataField
96 {
97 private:
98         typedef uint32_t (ARDOUR::SessionMetadata::*Getter) () const;
99         typedef void (ARDOUR::SessionMetadata::*Setter) (uint32_t);
100 public:
101         NumberMetadataField (Getter getter, Setter setter, std::string const & field_name, guint numbers, guint width = 50);
102         MetadataPtr copy ();
103
104         void save_data (ARDOUR::SessionMetadata & data) const;
105         void load_data (ARDOUR::SessionMetadata const & data);
106
107         Gtk::Widget & name_widget ();
108         Gtk::Widget & value_widget ();
109         Gtk::Widget & edit_widget ();
110 private:
111         void update_value ();
112         std::string uint_to_str (uint32_t i) const;
113         uint32_t str_to_uint (std::string const & str) const;
114
115         Getter getter;
116         Setter setter;
117
118         Gtk::Label* label;
119         Gtk::Label* value_label;
120         Gtk::Entry* entry;
121
122         guint numbers;
123         guint width;
124 };
125
126 /// MetadataField that accepts EAN-13 data only
127 class EAN13MetadataField : public MetadataField
128 {
129 private:
130         typedef std::string (ARDOUR::SessionMetadata::*Getter) () const;
131         typedef void (ARDOUR::SessionMetadata::*Setter) (std::string const &);
132 public:
133         EAN13MetadataField (Getter getter, Setter setter, std::string const & field_name, guint width = 13);
134         MetadataPtr copy ();
135
136         void save_data (ARDOUR::SessionMetadata & data) const;
137         void load_data (ARDOUR::SessionMetadata const & data);
138
139         Gtk::Widget & name_widget ();
140         Gtk::Widget & value_widget ();
141         Gtk::Widget & edit_widget ();
142
143         Gtk::Label* status_label;
144         void update_status ();
145 private:
146         void update_value ();
147         std::string numeric_string (std::string const & str) const;
148
149         Getter getter;
150         Setter setter;
151
152         Gtk::Label* label;
153         Gtk::Label* value_label;
154         Gtk::Entry* entry;
155
156         guint width;
157 };
158
159 /// Interface for MetadataFields
160 class SessionMetadataSet : public ARDOUR::SessionHandlePtr
161 {
162 public:
163         SessionMetadataSet (std::string const & name);
164         virtual ~SessionMetadataSet () {};
165
166         void add_data_field (MetadataPtr field);
167
168         /// allows loading extra data into data sets (for importing etc.)
169         virtual void load_extra_data (ARDOUR::SessionMetadata const & /*data*/) { }
170         /// Saves data to session
171         virtual void save_data () = 0;
172
173         virtual Gtk::Widget & get_widget () = 0;
174         virtual Gtk::Widget & get_tab_widget () = 0;
175
176 protected:
177         typedef std::list<MetadataPtr> DataList;
178         DataList list;
179         std::string name;
180 };
181
182 /// Contains MetadataFields for editing
183 class SessionMetadataSetEditable : public SessionMetadataSet
184 {
185 public:
186         SessionMetadataSetEditable (std::string const & name);
187
188         Gtk::Widget & get_widget () { return vbox; }
189         Gtk::Widget & get_tab_widget ();
190
191         /// Sets session and loads data
192         void set_session (ARDOUR::Session * s);
193         /// Saves from MetadataFields into data
194         void save_data ();
195
196 private:
197         Gtk::VBox vbox;
198         Gtk::Table table;
199         Gtk::Label tab_widget;
200 };
201
202 /// Contains MetadataFields for importing
203 class SessionMetadataSetImportable : public SessionMetadataSet
204 {
205 public:
206         SessionMetadataSetImportable (std::string const & name);
207
208         Gtk::Widget & get_widget () { return tree_view; }
209         Gtk::Widget & get_tab_widget ();
210         Gtk::Widget & get_select_all_widget ();
211
212         /// Loads importable data from data
213         void load_extra_data (ARDOUR::SessionMetadata const & data);
214         /// Saves from importable data (see load_data) to session_data
215         void save_data ();
216
217 private:
218         DataList & session_list; // References MetadataSet::list
219         DataList import_list;
220
221         struct Columns : public Gtk::TreeModel::ColumnRecord
222         {
223         public:
224                 Gtk::TreeModelColumn<std::string>     field;
225                 Gtk::TreeModelColumn<std::string>     values;
226                 Gtk::TreeModelColumn<bool>        import;
227                 Gtk::TreeModelColumn<MetadataPtr> data;
228
229                 Columns() { add (field); add (values); add (import); add (data); }
230         };
231
232         Glib::RefPtr<Gtk::ListStore>  tree;
233         Columns                       tree_cols;
234         Gtk::TreeView                 tree_view;
235
236         Gtk::Label                    tab_widget;
237         Gtk::CheckButton              select_all_check;
238
239         void select_all ();
240         void selection_changed (std::string const & path);
241 };
242
243 /// Metadata dialog interface
244 /**
245  * The DataSets are initalized in this class so that all
246  * Dialogs have the same sets of data in the same order.
247  */
248 template <typename DataSet>
249 class SessionMetadataDialog : public ArdourDialog
250 {
251 public:
252         SessionMetadataDialog (std::string const & name);
253
254 protected:
255         void init_data ( bool skip_user = false );
256         void load_extra_data (ARDOUR::SessionMetadata const & data);
257         void save_data ();
258
259         virtual void init_gui () = 0;
260         virtual void save_and_close ();
261         virtual void end_dialog ();
262
263         void warn_user (std::string const & string);
264
265         typedef std::list<Gtk::Widget *> WidgetList;
266         typedef boost::shared_ptr<WidgetList> WidgetListPtr;
267         typedef Gtk::Widget & (DataSet::*WidgetFunc) ();
268
269         /// Returns list of widgets gathered by calling f for each data set
270         WidgetListPtr get_custom_widgets (WidgetFunc f);
271
272         /// Adds a widget to the table (vertical stacking) with automatic spacing
273         void add_widget (Gtk::Widget & widget);
274
275         Gtk::Notebook     notebook;
276
277 private:
278         void init_user_data ();
279         void init_track_data ();
280         void init_album_data ();
281         void init_people_data ();
282         void init_school_data ();
283
284         typedef boost::shared_ptr<SessionMetadataSet> DataSetPtr;
285         typedef std::list<DataSetPtr> DataSetList;
286         DataSetList data_list;
287
288         Gtk::Button *     save_button;
289         Gtk::Button *     cancel_button;
290 };
291
292 class SessionMetadataEditor : public SessionMetadataDialog<SessionMetadataSetEditable>
293 {
294 public:
295         SessionMetadataEditor ();
296         ~SessionMetadataEditor ();
297         void run ();
298 private:
299         void init_gui ();
300 };
301
302 class SessionMetadataImporter : public SessionMetadataDialog<SessionMetadataSetImportable> {
303   public:
304         SessionMetadataImporter ();
305         ~SessionMetadataImporter ();
306         void run ();
307
308   private:
309         void init_gui ();
310
311         // Select all from -widget
312         Gtk::HBox    selection_hbox;
313         Gtk::Label   selection_label;
314
315 };
316
317 #endif