Replaced broken code in recent_sessions.cc
[ardour.git] / libs / ardour / recent_sessions.cc
1 /*
2     Copyright (C) 2004 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
20 #include <cstring>
21 #include <cerrno>
22 #include <fstream>
23 #include <iostream>
24 #include <sstream>
25 #include <algorithm>
26
27 #include <glib/gstdio.h>
28 #include <glibmm/miscutils.h>
29
30 #include "pbd/error.h"
31
32 #include "ardour/rc_configuration.h"
33 #include "ardour/filesystem_paths.h"
34 #include "ardour/recent_sessions.h"
35
36 #include "i18n.h"
37
38 using namespace std;
39 using namespace ARDOUR;
40 using namespace PBD;
41
42 namespace {
43
44         const char * const recent_file_name = "recent";
45         const char * const recent_templates_file_name = "recent_templates";
46
47 } // anonymous
48
49 int
50 ARDOUR::read_recent_sessions (RecentSessions& rs)
51 {
52         std::string path = Glib::build_filename (user_config_directory(), recent_file_name);
53         FILE* fin = g_fopen (path.c_str(), "rb");
54
55         if (!fin) {
56                 if (errno != ENOENT) {
57                         error << string_compose (_("cannot open recent session file %1 (%2)"), path, strerror (errno)) << endmsg;
58                         return -1;
59                 } else {
60                         return 1;
61                 }
62         }
63
64
65
66         // Read the file into a std::string;
67         std::stringstream recent;
68         char temporaryBuffer[1024];
69         while (!feof(fin))
70         {
71                 size_t charsRead = fread(&temporaryBuffer[0], sizeof(char), 1024, fin);
72                 if (charsRead != 1024 && ferror(fin))
73                 {
74                         error << string_compose (_("Error reading recent session file %1 (%2)"), path, strerror (errno)) << endmsg;
75                         fclose(fin);
76                         return -1;
77                 }
78                 recent << &temporaryBuffer[0];
79         }
80
81
82
83         //ifstream recent (fin);
84
85         while (true) {
86
87                 pair<string,string> newpair;
88
89                 getline(recent, newpair.first);
90
91                 if (!recent.good()) {
92                         break;
93                 }
94
95                 getline(recent, newpair.second);
96
97                 if (!recent.good()) {
98                         break;
99                 }
100
101                 rs.push_back (newpair);
102         }
103
104         /* display sorting should be done in the GUI, otherwise the
105          * natural order will be broken
106          */
107
108         fclose (fin);
109         return 0;
110 }
111
112 int
113 ARDOUR::read_recent_templates (std::deque<std::string>& rt)
114 {
115         std::string path = Glib::build_filename (user_config_directory(), recent_templates_file_name);
116
117         ifstream recent (path.c_str());
118
119         if (!recent) {
120                 if (errno != ENOENT) {
121                         error << string_compose (_("cannot open recent template file %1 (%2)"), path, strerror (errno)) << endmsg;
122                         return -1;
123                 } else {
124                         return 1;
125                 }
126         }
127
128         while (true) {
129
130                 std::string session_template_full_name;
131
132                 getline(recent, session_template_full_name);
133
134                 if (!recent.good()) {
135                         break;
136                 }
137
138                 rt.push_back (session_template_full_name);
139         }
140
141         return 0;
142 }
143
144 int
145 ARDOUR::write_recent_sessions (RecentSessions& rs)
146 {
147         FILE* fout = g_fopen (Glib::build_filename (user_config_directory(), recent_file_name).c_str(), "wb");
148
149         if (!fout) {
150                 return -1;
151         }
152
153         {
154                 stringstream recent;
155                 //ofstream recent (fout);
156
157                 // if (!recent) {
158                 //      fclose (fout);
159                 //      return -1;
160                 // }
161
162                 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
163                         recent << (*i).first << '\n' << (*i).second << endl;
164                 }
165
166                 string recentString = recent.str();
167                 size_t writeSize = recentString.length();
168
169                 fwrite(recentString.c_str(), sizeof(char), writeSize, fout);
170
171                 if (ferror(fout))
172                 {
173                         error << string_compose (_("Error writing recent sessions file %1 (%2)"), recent_file_name, strerror (errno)) << endmsg;
174                         fclose(fout);
175                         return -1;
176                 }
177         }
178
179
180
181         fclose (fout);
182
183         return 0;
184 }
185
186 int
187 ARDOUR::write_recent_templates (std::deque<std::string>& rt)
188 {
189         std::string path = Glib::build_filename (user_config_directory(), recent_templates_file_name);
190
191         std::ofstream recent (path.c_str());
192
193         if (!recent) {
194                 return -1;
195         }
196
197         for (std::deque<std::string>::const_iterator i = rt.begin(); i != rt.end(); ++i) {
198                 recent << (*i) << std::endl;
199         }
200
201         return 0;
202 }
203
204 int
205 ARDOUR::store_recent_sessions (string name, string path)
206 {
207         RecentSessions rs;
208
209         if (ARDOUR::read_recent_sessions (rs) < 0) {
210                 return -1;
211         }
212
213         pair<string,string> newpair;
214
215         newpair.first = name;
216         newpair.second = path;
217
218         rs.erase(remove(rs.begin(), rs.end(), newpair), rs.end());
219
220         rs.push_front (newpair);
221
222         uint32_t max_recent_sessions = Config->get_max_recent_sessions();
223
224         if (rs.size() > max_recent_sessions) {
225                 rs.erase(rs.begin()+max_recent_sessions, rs.end());
226         }
227
228         return ARDOUR::write_recent_sessions (rs);
229 }
230
231 int
232 ARDOUR::store_recent_templates (const std::string& session_template_full_name)
233 {
234         std::deque<std::string> rt;
235
236         if (ARDOUR::read_recent_templates (rt) < 0) {
237                 return -1;
238         }
239
240         rt.erase(remove (rt.begin(), rt.end(), session_template_full_name), rt.end());
241
242         rt.push_front (session_template_full_name);
243
244         uint32_t max_recent_templates = Config->get_max_recent_templates ();
245
246         if (rt.size() > max_recent_templates) {
247                 rt.erase( rt.begin() + max_recent_templates, rt.end ());
248         }
249
250         return ARDOUR::write_recent_templates (rt);
251 }
252
253 int
254 ARDOUR::remove_recent_sessions (const string& path)
255 {
256         RecentSessions rs;
257         bool write = false;
258
259         if (ARDOUR::read_recent_sessions (rs) < 0) {
260                 return -1;
261         }
262
263         for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
264                 if (i->second == path) {
265                         rs.erase (i);
266                         write = true;
267                         break;
268                 }
269         }
270
271         if (write) {
272                 return ARDOUR::write_recent_sessions (rs);
273         } else {
274                 return 1;
275         }
276 }