rework set default transtion, nested proxy edl fixes, doubleclick proxy media fix...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / presets.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  * 
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * 
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  * 
20  */
21
22 #include "bcsignals.h"
23 #include "bcwindowbase.inc"
24 #include "file.h"
25 #include "filesystem.h"
26 #include "filexml.h"
27 #include "keyframe.h"
28 #include "messages.inc"
29 #include "mwindow.h"
30 #include "pluginserver.h"
31 #include "preferences.inc"
32 #include "presets.h"
33
34 #include <errno.h>
35 #include <string.h>
36
37 PresetsDB::PresetsDB()
38 {
39 }
40
41 void PresetsDB::clear()
42 {
43         plugins.remove_all_objects();
44 }
45
46 void PresetsDB::load_from_file(char *path, int is_factory, int clear_it)
47 {
48         if( clear_it ) clear();
49         FileXML file;
50
51         file.read_from_file(path);
52         load_common(&file, is_factory);
53 }
54
55 void PresetsDB::load_from_string(char *string, int is_factory, int clear_it)
56 {
57         if( clear_it ) clear();
58         
59         FileXML file;
60         file.read_from_string(string);
61         load_common(&file, is_factory);
62 }
63
64
65
66 void PresetsDB::load_common(FileXML *file, int is_factory)
67 {
68         int result = 0;
69         char string[BCTEXTLEN];
70
71         do {
72                 result = file->read_tag();
73                 if( ! result  ) {
74                         if( file->tag.title_is("PLUGIN") ) {
75                                 PresetsDBPlugin *plugin = 0;
76                                 sprintf(string, "Unknown");
77                                 const char *title = file->tag.get_property("TITLE", string);
78
79 // Search for existing plugin
80                                 for( int i=0; i<plugins.size(); ++i ) {
81                                         if( !strcasecmp(plugins[i]->title, title) ) {
82                                                 plugin = plugins[i];
83                                                 break;
84                                         }
85                                 }
86
87 // Create new plugin
88                                 if( !plugin ) {
89                                         plugin = new PresetsDBPlugin(title);
90                                         plugins.append(plugin);
91                                 }
92
93                                 plugin->load(file, is_factory);
94                         }
95                 }
96         } while(!result);
97 }
98
99
100 void PresetsDB::save()
101 {
102         FileXML file;
103         for( int i=0; i<plugins.size(); ++i ) {
104                 PresetsDBPlugin *plugin = plugins[i];
105                 if( plugin->get_total_presets(1) > 0 ) {
106                         plugin->save(&file);
107                 }
108         }
109         file.terminate_string();
110
111         char path[BCTEXTLEN];
112         sprintf(path, "%s/%s", File::get_config_path(), PRESETS_FILE);
113         FileSystem fs;
114         fs.complete_path(path);
115         file.write_to_file(path);
116 }
117
118
119 int PresetsDB::get_total_presets(char *plugin_title, int user_only)
120 {
121         for( int i=0; i<plugins.size(); ++i ) {
122                 PresetsDBPlugin *plugin = plugins[i];
123                 if( !strcasecmp(plugin->title, plugin_title) ) {
124                         return plugin->get_total_presets(user_only);
125                 }
126         }
127
128         return 0;
129 }
130
131
132 // move factory presets to the start, followed by sorted preset titles
133 void PresetsDB::sort(char *plugin_title)
134 {
135         PresetsDBPlugin *plugin = 0;
136         for( int i=0; !plugin && i<plugins.size(); ++i ) {
137                 if( !strcasecmp(plugins[i]->title, plugin_title) )
138                         plugin = plugins[i];
139         }
140
141         if( plugin ) {
142                 int done = 0;
143                 int total_presets = plugin->get_total_presets(0);
144                 while( !done ) {
145                         done = 1;
146                         for( int i=0; i<total_presets-1; ++i ) {
147                                 PresetsDBKeyframe *keyframe1 = plugin->keyframes[i];
148                                 PresetsDBKeyframe *keyframe2 = plugin->keyframes[i+1];
149
150                                 if( (keyframe2->is_factory && !keyframe1->is_factory) ||
151                                     (keyframe2->is_factory == keyframe1->is_factory &&
152                                      strcmp(keyframe2->title, keyframe1->title) < 0) ) {
153                                         plugin->keyframes.set(i, keyframe2);
154                                         plugin->keyframes.set(i + 1, keyframe1);
155                                         done = 0;
156                                 }
157                         }
158                 }
159         }
160 }
161
162
163 char* PresetsDB::get_preset_title(char *plugin_title, int number)
164 {
165         for( int i=0; i<plugins.size(); ++i ) {
166                 PresetsDBPlugin *plugin = plugins[i];
167                 if( !strcasecmp(plugin->title, plugin_title) ) {
168                         if( number < plugin->keyframes.size() )
169                                 return plugin->keyframes[number]->title;
170                         printf("PresetsDB::get_preset_title %d buffer overrun\n", __LINE__);
171                         break;
172                 }
173         }
174         return 0;
175 }
176
177
178 int PresetsDB::get_is_factory(char *plugin_title, int number)
179 {
180         for( int i=0; i<plugins.size(); ++i ) {
181                 PresetsDBPlugin *plugin = plugins[i];
182                 if( !strcasecmp(plugin->title, plugin_title) ) {
183                         if( number < plugin->keyframes.size() )
184                                 return plugin->keyframes[number]->is_factory;
185                         printf("PresetsDB::get_preset_title %d buffer overrun\n", __LINE__);
186                         break;
187                 }
188         }
189         return 0;
190 }
191
192
193 char* PresetsDB::get_preset_data(char *plugin_title, int number)
194 {
195         for( int i=0; i<plugins.size(); ++i ) {
196                 PresetsDBPlugin *plugin = plugins[i];
197                 if( !strcasecmp(plugin->title, plugin_title) ) {
198                         if( number < plugin->keyframes.size() )
199                                 return plugin->keyframes[number]->data;
200                         printf("PresetsDB::get_preset_data %d buffer overrun\n", __LINE__);
201                         break;
202                 }
203         }
204         return 0;
205 }
206
207 PresetsDBPlugin* PresetsDB::get_plugin(const char *plugin_title)
208 {
209         for( int i=0; i<plugins.size(); ++i ) {
210                 PresetsDBPlugin *plugin = plugins[i];
211                 if( !strcasecmp(plugin->title, plugin_title) )
212                         return plugin;
213         }
214         return 0;
215 }
216
217 PresetsDBPlugin* PresetsDB::new_plugin(const char *plugin_title)
218 {
219         PresetsDBPlugin *result = new PresetsDBPlugin(plugin_title);
220         plugins.append(result);
221         return result;
222 }
223
224
225 void PresetsDB::save_preset(const char *plugin_title, 
226         const char *preset_title, 
227         char *data)
228 {
229         PresetsDBPlugin *plugin = get_plugin(plugin_title);
230         if( !plugin ) plugin = new_plugin(plugin_title);
231         PresetsDBKeyframe *keyframe = plugin->get_keyframe(preset_title, 0);
232         if( !keyframe ) keyframe = plugin->new_keyframe(preset_title);
233         keyframe->set_data(data);
234         save();
235
236 }
237
238
239 void PresetsDB::delete_preset(const char *plugin_title, 
240         const char *preset_title,
241         int is_factory)
242 {
243         PresetsDBPlugin *plugin = get_plugin(plugin_title);
244         if( plugin ) {
245                 plugin->delete_keyframe(preset_title);
246         }
247         save();
248 }
249
250 void PresetsDB::load_preset(const char *plugin_title,
251         const char *preset_title, 
252         KeyFrame *keyframe,
253         int is_factory)
254 {
255         PresetsDBPlugin *plugin = get_plugin(plugin_title);
256         if( plugin ) {
257                 plugin->load_preset(preset_title, keyframe, is_factory);
258         }
259 }
260
261 int PresetsDB::preset_exists(const char *plugin_title, 
262         const char *preset_title,
263         int is_factory)
264 {
265         PresetsDBPlugin *plugin = get_plugin(plugin_title);
266         if( plugin ) {
267                 return plugin->preset_exists(preset_title, is_factory);
268         }
269         return 0;
270 }
271
272
273
274
275 PresetsDBKeyframe::PresetsDBKeyframe(const char *title, int is_factory)
276 {
277         this->title = strdup(title);
278         data = 0;
279         this->is_factory = is_factory;
280 }
281
282 PresetsDBKeyframe::~PresetsDBKeyframe()
283 {
284         delete [] title;
285         delete [] data;
286 }
287
288 void PresetsDBKeyframe::set_data(char *data)
289 {
290         delete [] this->data;
291         this->data = new char[strlen(data) + 1];
292         strcpy(this->data, data);
293 }
294
295
296 PresetsDBPlugin::PresetsDBPlugin(const char *title)
297 {
298         this->title = strdup(title);
299 }
300
301 PresetsDBPlugin::~PresetsDBPlugin()
302 {
303         keyframes.remove_all_objects();
304         delete [] title;
305 }
306
307 int PresetsDBPlugin::get_total_presets(int user_only)
308 {
309         if( !user_only )
310                 return keyframes.size();
311         int result = 0;
312         for( int j=0; j<keyframes.size(); ++j )
313                 if( !keyframes[j]->is_factory ) ++result;
314         return result;
315 }
316
317 void PresetsDBPlugin::load(FileXML *file, int is_factory)
318 {
319         int result = 0;
320         char string[BCTEXTLEN];
321
322         do {
323                 result = file->read_tag();
324                 if( !result ) {
325                         if( file->tag.title_is("/PLUGIN") ) break;
326                         else
327                         if( file->tag.title_is("KEYFRAME") ) {
328                                 sprintf(string, "Unknown");
329                                 const char *keyframe_title = file->tag.get_property("TITLE", string);
330                                 PresetsDBKeyframe *keyframe = new PresetsDBKeyframe(keyframe_title, is_factory);
331
332                                 char data[MESSAGESIZE];
333                                 file->read_text_until("/KEYFRAME", data, MESSAGESIZE);
334                                 keyframe->set_data(data);
335                                 keyframes.append(keyframe);
336                 
337                         }
338                 }
339         } while(!result);
340 }
341
342 void PresetsDBPlugin::save(FileXML *file)
343 {
344         file->tag.set_title("PLUGIN");
345         file->tag.set_property("TITLE", title);
346         file->append_tag();
347         file->append_newline();
348
349         for( int j=0; j<keyframes.size(); ++j ) {
350                 PresetsDBKeyframe *keyframe = keyframes[j];
351                 
352                 if( !keyframe->is_factory ) {
353                         file->tag.set_title("KEYFRAME");
354                         file->tag.set_property("TITLE", keyframe->title);
355                         file->append_tag();
356                         file->append_text(keyframe->data);
357                         file->tag.set_title("/KEYFRAME");
358                         file->append_tag();
359                         file->append_newline();
360                 }
361         }
362
363         file->tag.set_title("/PLUGIN");
364         file->append_tag();
365         file->append_newline();
366 }
367
368 PresetsDBKeyframe* PresetsDBPlugin::get_keyframe(const char *title, 
369         int is_factory)
370 {
371         for( int i=0; i<keyframes.size(); ++i ) {
372                 PresetsDBKeyframe *keyframe = keyframes[i];
373                 if( !strcasecmp(keyframe->title, title) && 
374                     keyframe->is_factory == is_factory )
375                         return keyframe;
376         }
377         return 0;
378 }
379
380 void PresetsDBPlugin::delete_keyframe(const char *title)
381 {
382         for( int i=0; i<keyframes.size(); ++i ) {
383                 PresetsDBKeyframe *keyframe = keyframes[i];
384                 if( !strcasecmp(keyframe->title, title) && !keyframe->is_factory ) {
385                         keyframes.remove_object_number(i);
386                         return;
387                 }
388         }
389 }
390
391
392 PresetsDBKeyframe* PresetsDBPlugin::new_keyframe(const char *title)
393 {
394         PresetsDBKeyframe *keyframe = new PresetsDBKeyframe(title, 0);
395         keyframes.append(keyframe);
396         return keyframe;
397 }
398
399 void PresetsDBPlugin::load_preset(const char *preset_title, 
400         KeyFrame *keyframe,
401         int is_factory)
402 {
403         PresetsDBKeyframe *src = get_keyframe(preset_title, is_factory);
404         if( src ) {
405                 keyframe->set_data(src->data);
406 // Save as the plugin's default, Need the path
407 //printf("PresetsDBPlugin::load_preset %d %s\n", __LINE__, title);
408                 PluginServer *server = MWindow::scan_plugindb(title, -1);
409                 if( server ) {
410                         char path[BCTEXTLEN];
411                         server->get_defaults_path(path);
412                         FileSystem fs;
413                         fs.complete_path(path);
414
415                         FILE *fd = fopen(path, "w");
416                         if( fd ) {
417                                 if( !fwrite(src->data, strlen(src->data), 1, fd) ) {
418                                         fprintf(stderr, "PresetsDBPlugin::load_preset %d \"%s\": %s\n",
419                                                 __LINE__,
420                                                 path,
421                                                 strerror(errno));
422                                 }
423
424                                 fclose(fd);
425                         }
426                         else {
427                                 fprintf(stderr, "PresetsDBPlugin::load_preset %d \"%s\": %s\n",
428                                         __LINE__, path, strerror(errno));
429                         }
430                 }
431         }
432 }
433
434 int PresetsDBPlugin::preset_exists(const char *preset_title, int is_factory)
435 {
436         PresetsDBKeyframe *src = get_keyframe(preset_title, is_factory);
437         return src ? 1 : 0;
438 }
439