Tidy up a couple of bits in the session option editor.
[ardour.git] / gtk2_ardour / search_path_option.cc
1 /*
2     Copyright (C) 2010 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include "pbd/strsplit.h"
20 #include "search_path_option.h"
21
22 using namespace std;
23 using namespace Gtk;
24
25 SearchPathOption::SearchPathOption (const string& pathname, const string& label,
26                                     sigc::slot<std::string> get, sigc::slot<bool, std::string> set)
27         : Option (pathname, label)
28         , _get (get)
29         , _set (set)
30         , add_chooser (_("Select folder to search for media"), FILE_CHOOSER_ACTION_SELECT_FOLDER)
31 {
32         add_chooser.signal_file_set().connect (sigc::mem_fun (*this, &SearchPathOption::path_chosen));
33
34         HBox* hbox = manage (new HBox);
35
36         hbox->set_border_width (12);
37         hbox->set_spacing (6);
38         hbox->pack_end (add_chooser, true, true);
39         hbox->pack_end (*manage (new Label ("Click to add a new location")), false, false);
40         hbox->show_all ();
41         
42         vbox.pack_start (path_box);
43         vbox.pack_end (*hbox);
44
45         session_label.set_use_markup (true);
46         session_label.set_markup (string_compose ("<i>%1</i>", _("the session folder")));
47         session_label.set_alignment (0.0, 0.5);
48         session_label.show ();
49
50         path_box.pack_start (session_label);
51 }
52
53 SearchPathOption::~SearchPathOption()
54 {
55         
56
57 }
58
59 void
60 SearchPathOption::path_chosen ()
61 {
62         string path = add_chooser.get_filename ();
63         add_path (path);
64         changed ();
65 }
66
67 void
68 SearchPathOption::add_to_page (OptionEditorPage* p)
69 {
70         int const n = p->table.property_n_rows();
71         p->table.resize (n + 1, 3);
72
73         Label* label = manage (new Label);
74         label->set_alignment (0.0, 0.0);
75         label->set_markup (string_compose ("%1", _name));
76
77         p->table.attach (*label, 1, 2, n, n + 1, FILL | EXPAND);
78         p->table.attach (vbox, 2, 3, n, n + 1, FILL | EXPAND);
79 }
80
81 void
82 SearchPathOption::clear ()
83 {
84         path_box.remove (session_label);
85         for (list<PathEntry*>::iterator p = paths.begin(); p != paths.end(); ++p) {
86                 path_box.remove ((*p)->box);
87                 delete *p;
88         }
89         paths.clear ();
90 }
91
92 void
93 SearchPathOption::set_state_from_config ()
94 {
95         string str = _get ();
96         vector<string> dirs;
97
98         clear ();
99         path_box.pack_start (session_label);
100
101         split (str, dirs, ':');
102         
103         for (vector<string>::iterator d = dirs.begin(); d != dirs.end(); ++d) {
104                 add_path (*d);
105         }
106 }
107
108 void
109 SearchPathOption::changed ()
110 {
111         string str;
112         
113         for (list<PathEntry*>::iterator p = paths.begin(); p != paths.end(); ++p) {
114
115                 if (!str.empty()) {
116                         str += ':';
117                 }
118                 str += (*p)->entry.get_text ();
119         }
120
121         _set (str);
122 }
123
124 void
125 SearchPathOption::add_path (const string& path, bool removable)
126 {
127         PathEntry* pe = new PathEntry (path, removable);
128         paths.push_back (pe);
129         path_box.pack_start (pe->box, false, false);
130         pe->remove_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (*this, &SearchPathOption::remove_path), pe));
131 }
132
133 void
134 SearchPathOption::remove_path (PathEntry* pe)
135 {
136         path_box.remove (pe->box);
137         paths.remove (pe);
138         delete pe;
139         changed ();
140 }
141
142 SearchPathOption::PathEntry::PathEntry (const std::string& path, bool removable)
143         : remove_button (Stock::REMOVE)
144 {
145         entry.set_text (path);
146         entry.show ();
147
148         box.set_spacing (6);
149         box.set_homogeneous (false);
150         box.pack_start (entry, true, true);
151         
152         if (removable) {
153                 box.pack_start (remove_button, false, false);
154                 remove_button.show ();
155         }
156
157         box.show ();
158 }