initial pass at a missing file dialog and "relocatable" source files. lots more to...
[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, false, false);
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
51 SearchPathOption::~SearchPathOption()
52 {
53         
54
55 }
56
57 void
58 SearchPathOption::path_chosen ()
59 {
60         string path = add_chooser.get_filename ();
61         add_path (path);
62 }
63
64 void
65 SearchPathOption::add_to_page (OptionEditorPage* p)
66 {
67         int const n = p->table.property_n_rows();
68         p->table.resize (n + 2, 3);
69
70         Label* label = manage (new Label);
71         label->set_alignment (0.0, 0.5);
72         label->set_markup (string_compose ("<b>%1</b>", _name));
73
74         p->table.attach (*label, 0, 1, n, n + 1, FILL | EXPAND);
75         p->table.attach (vbox, 0, 3, n + 1, n + 2, FILL | EXPAND);
76 }
77
78 void
79 SearchPathOption::clear ()
80 {
81         path_box.remove (session_label);
82         for (list<PathEntry*>::iterator p = paths.begin(); p != paths.end(); ++p) {
83                 path_box.remove ((*p)->box);
84                 delete *p;
85         }
86         paths.clear ();
87 }
88
89 void
90 SearchPathOption::set_state_from_config ()
91 {
92         string str = _get ();
93         vector<string> dirs;
94
95         clear ();
96         path_box.pack_start (session_label);
97
98         split (str, dirs, ':');
99         
100         for (vector<string>::iterator d = dirs.begin(); d != dirs.end(); ++d) {
101                 add_path (*d);
102         }
103 }
104
105 void
106 SearchPathOption::changed ()
107 {
108         string str;
109         
110         for (list<PathEntry*>::iterator p = paths.begin(); p != paths.end(); ++p) {
111
112                 if (p == paths.begin()) {
113                         /* skip first entry, its always "the session"
114                          */
115                         continue;
116                 }
117
118                 if (!str.empty()) {
119                         str += ':';
120                 }
121                 str += (*p)->entry.get_text ();
122         }
123
124         _set (str);
125 }
126
127 void
128 SearchPathOption::add_path (const string& path, bool removable)
129 {
130         PathEntry* pe = new PathEntry (path, removable);
131         paths.push_back (pe);
132         path_box.pack_start (pe->box, false, false);
133 }
134
135 void
136 SearchPathOption::remove_path (const string& path)
137 {
138 }
139
140 SearchPathOption::PathEntry::PathEntry (const std::string& path, bool removable)
141         : remove_button (Stock::REMOVE)
142 {
143         entry.set_text (path);
144         entry.show ();
145
146         box.set_spacing (6);
147         box.set_homogeneous (false);
148         box.pack_start (entry, true, true);
149         
150         if (removable) {
151                 box.pack_start (remove_button, false, false);
152                 remove_button.show ();
153         }
154
155         box.show ();
156 }