552f2d353e9cf3b43745c1e9c1970c1715b92542
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / savefile.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 "confirmsave.h"
23 #include "bchash.h"
24 #include "bcrecentlist.h"
25 #include "edl.h"
26 #include "file.h"
27 #include "filexml.h"
28 #include "fileformat.h"
29 #include "indexfile.h"
30 #include "language.h"
31 #include "mainerror.h"
32 #include "mainmenu.h"
33 #include "mwindow.h"
34 #include "mwindowgui.h"
35 #include "playback3d.h"
36 #include "savefile.h"
37 #include "mainsession.h"
38
39 #include <string.h>
40
41
42 SaveBackup::SaveBackup(MWindow *mwindow)
43  : BC_MenuItem(_("Save backup"), "b", 'b')
44 {
45         this->mwindow = mwindow;
46 }
47 int SaveBackup::handle_event()
48 {
49         mwindow->save_backup();
50         mwindow->gui->show_message(_("Saved backup."));
51         return 1;
52 }
53
54
55 Save::Save(MWindow *mwindow) : BC_MenuItem(_("Save"), "s", 's')
56 {
57         this->mwindow = mwindow;
58         quit_now = 0;
59 }
60
61 void Save::create_objects(SaveAs *saveas)
62 {
63         this->saveas = saveas;
64 }
65
66 int Save::handle_event()
67 {
68         if(mwindow->session->filename[0] == 0)
69         {
70                 saveas->start();
71         }
72         else
73         {
74 // save it
75 // TODO: Move this into mwindow.
76                 FileXML file;
77                 mwindow->edl->save_xml(&file, mwindow->session->filename);
78                 file.terminate_string();
79
80                 if(file.write_to_file(mwindow->session->filename))
81                 {
82                         char string2[256];
83                         sprintf(string2, _("Couldn't open %s"), mwindow->session->filename);
84                         ErrorBox error(_(PROGRAM_NAME ": Error"),
85                                 mwindow->gui->get_abs_cursor_x(1),
86                                 mwindow->gui->get_abs_cursor_y(1));
87                         error.create_objects(string2);
88                         error.raise_window();
89                         error.run_window();
90                         return 1;
91                 }
92                 else
93                 {
94                         char string[BCTEXTLEN];
95                         sprintf(string, _("\"%s\" %dC written"),
96                                  mwindow->session->filename, (int)strlen(file.string()));
97                         mwindow->gui->show_message(string);
98                 }
99                 mwindow->session->changes_made = 0;
100 // Last command in program
101                 if( saveas->quit_now )
102                         mwindow->quit();
103         }
104         return 1;
105 }
106
107 int Save::save_before_quit()
108 {
109         mwindow->gui->lock_window("Save::save_before_quit");
110         saveas->quit_now = 1;
111         handle_event();
112         mwindow->gui->unlock_window();
113         return 0;
114 }
115
116 SaveAs::SaveAs(MWindow *mwindow)
117  : BC_MenuItem(_("Save as..."), "Shift-S", 'S'), Thread()
118 {
119         set_shift(1);
120         this->mwindow = mwindow;
121         quit_now = 0;
122 }
123
124 int SaveAs::set_mainmenu(MainMenu *mmenu)
125 {
126         this->mmenu = mmenu;
127         return 0;
128 }
129
130 int SaveAs::handle_event()
131 {
132         quit_now = 0;
133         start();
134         return 1;
135 }
136
137 void SaveAs::run()
138 {
139 // ======================================= get path from user
140         int result;
141 //printf("SaveAs::run 1\n");
142         char directory[1024], filename[1024];
143         sprintf(directory, "~");
144         mwindow->defaults->get("DIRECTORY", directory);
145
146 // Loop if file exists
147         do{
148                 SaveFileWindow *window;
149
150                 window = new SaveFileWindow(mwindow, directory);
151                 window->lock_window("SaveAs::run");
152                 window->create_objects();
153                 window->unlock_window();
154                 result = window->run_window();
155                 mwindow->defaults->update("DIRECTORY", window->get_submitted_path());
156                 strcpy(filename, window->get_submitted_path());
157                 delete window;
158
159 // Extend the filename with .xml
160                 if(strlen(filename) < 4 ||
161                         strcasecmp(&filename[strlen(filename) - 4], ".xml"))
162                 {
163                         strcat(filename, ".xml");
164                 }
165
166 // ======================================= try to save it
167                 if(filename[0] == 0) return;              // no filename given
168                 if(result == 1) return;          // user cancelled
169                 result = ConfirmSave::test_file(mwindow, filename);
170         }while(result);        // file exists so repeat
171
172 //printf("SaveAs::run 6 %s\n", filename);
173
174
175
176
177 // save it
178         FileXML file;
179         mwindow->gui->lock_window("SaveAs::run 1");
180 // update the project name
181         mwindow->set_filename(filename);
182         mwindow->edl->save_xml(&file, filename);
183         mwindow->gui->unlock_window();
184         file.terminate_string();
185
186         if(file.write_to_file(filename))
187         {
188                 char string2[256];
189                 mwindow->set_filename("");      // update the project name
190                 sprintf(string2, _("Couldn't open %s."), filename);
191                 ErrorBox error(_(PROGRAM_NAME ": Error"),
192                         mwindow->gui->get_abs_cursor_x(1),
193                         mwindow->gui->get_abs_cursor_y(1));
194                 error.create_objects(string2);
195                 error.raise_window();
196                 error.run_window();
197                 return;
198         }
199         else
200         {
201                 char string[BCTEXTLEN];
202                 sprintf(string, _("\"%s\" %dC written"), filename, (int)strlen(file.string()));
203                 mwindow->gui->lock_window("SaveAs::run 2");
204                 mwindow->gui->show_message(string);
205                 mwindow->gui->unlock_window();
206         }
207
208
209         mwindow->session->changes_made = 0;
210         mmenu->add_load(filename);
211 // Last command in program
212         if( quit_now )
213                 mwindow->quit();
214         return;
215 }
216
217
218 SaveFileWindow::SaveFileWindow(MWindow *mwindow, char *init_directory)
219  : BC_FileBox(mwindow->gui->get_abs_cursor_x(1),
220         mwindow->gui->get_abs_cursor_y(1) - BC_WindowBase::get_resources()->filebox_h / 2,
221         init_directory,
222         _(PROGRAM_NAME ": Save"),
223         _("Enter a filename to save as"))
224 {
225         this->mwindow = mwindow;
226 }
227
228 SaveFileWindow::~SaveFileWindow() {}
229
230
231
232 int SaveProjectModeItem::handle_event()
233 {
234         ((SaveProjectMode *)get_popup_menu())->update(id);
235         return 1;
236 }
237
238 SaveProjectMode::SaveProjectMode(SaveProjectWindow *gui, int x, int y)
239  : BC_PopupMenu(x, y, xS(100), "")
240 {
241         this->gui = gui;
242         save_modes[SAVE_PROJECT_COPY]     = _("Copy");
243         save_modes[SAVE_PROJECT_SYMLINK]  = _("SymLink");
244         save_modes[SAVE_PROJECT_RELLINK]  = _("RelLink");
245 }
246
247 SaveProjectMode::~SaveProjectMode()
248 {
249 }
250
251 void SaveProjectMode::create_objects()
252 {
253         add_item(new SaveProjectModeItem(save_modes[SAVE_PROJECT_COPY],    SAVE_PROJECT_COPY));
254         add_item(new SaveProjectModeItem(save_modes[SAVE_PROJECT_SYMLINK], SAVE_PROJECT_SYMLINK));
255         add_item(new SaveProjectModeItem(save_modes[SAVE_PROJECT_RELLINK], SAVE_PROJECT_RELLINK));
256         set_text(save_modes[gui->save_mode]);
257 }
258
259 void SaveProjectMode::update(int mode)
260 {
261         if( gui->save_mode == mode ) return;
262         set_text(save_modes[gui->save_mode = mode]);
263 }
264
265 SaveProjectTextBox::SaveProjectTextBox(SaveProjectWindow *gui, int x, int y, int w)
266  : BC_TextBox(x, y, w, 1, gui->dir_path)
267 {
268         this->gui = gui;
269 }
270 SaveProjectTextBox::~SaveProjectTextBox()
271 {
272 }
273
274 int SaveProjectTextBox::handle_event()
275 {
276         return 1;
277 }
278
279 SaveProjectWindow::SaveProjectWindow(MWindow *mwindow, const char *dir_path,
280                         int save_mode, int overwrite, int reload)
281  : BC_Window(_(PROGRAM_NAME ": Export Project"),
282                 mwindow->gui->get_abs_cursor_x(1),
283                 mwindow->gui->get_abs_cursor_y(1) -
284                         BC_WindowBase::get_resources()->filebox_h / 2,
285                 xS(540), yS(220), xS(540), yS(220), 0)
286 {
287         this->mwindow = mwindow;
288         strcpy(this->dir_path, dir_path);
289         this->overwrite = overwrite;
290         this->save_mode = save_mode;
291         this->reload = reload;
292 }
293 SaveProjectWindow::~SaveProjectWindow()
294 {
295 }
296
297 void SaveProjectWindow::create_objects()
298 {
299         int xs10 = xS(10), xs20 = xS(20);
300         int ys10 = yS(10), ys20 = yS(20);
301         int x = xs20, y = ys20, x1 = get_w()-xS(80);
302         BC_Title *title;
303         add_subwindow(title = new BC_Title(x, y, _("Project Directory:")));
304         y += title->get_h() + ys10;
305         add_subwindow(textbox = new SaveProjectTextBox(this, x, y, x1-x));
306         x1 += xs10;
307         add_subwindow(recent_project = new BC_RecentList("RECENT_PROJECT",
308                 mwindow->defaults, textbox, 10, x1, y, xS(300), yS(100)));
309         recent_project->load_items("RECENT_PROJECT");
310         x1 += recent_project->get_w() + xs10;
311         add_subwindow(browse_button = new BrowseButton(mwindow->theme, this,
312                 textbox, x1, y-yS(5), "", "", "", 1));
313         y += textbox->get_h() + ys20;
314         add_subwindow(mode_popup = new SaveProjectMode(this, x, y));
315         mode_popup->create_objects();
316         y += mode_popup->get_h() + ys10;
317         x1 = x;
318         BC_CheckBox *overwrite_files, *reload_project;
319         add_subwindow(overwrite_files = new BC_CheckBox(x1, y, &overwrite, _("Overwrite files")));
320         x1 += overwrite_files->get_w() + xs20;
321         add_subwindow(reload_project = new BC_CheckBox(x1, y, &reload, _("Reload project")));
322         add_subwindow(new BC_OKButton(this));
323         add_subwindow(new BC_CancelButton(this));
324         show_window(1);
325 }
326
327 SaveProject::SaveProject(MWindow *mwindow)
328  : BC_MenuItem(_("Export Project..."), "Alt-s", 's'), Thread()
329 {
330         set_alt(1);
331         this->mwindow = mwindow;
332 }
333
334 int SaveProject::handle_event()
335 {
336         start();
337         return 1;
338 }
339
340 void SaveProject::run()
341 {
342         char dir_path[1024];  sprintf(dir_path, "~");
343         mwindow->defaults->get("PROJECT_DIRECTORY", dir_path);
344         int reload = mwindow->defaults->get("PROJECT_RELOAD", 0);
345         int overwrite = mwindow->defaults->get("PROJECT_OVERWRITE", 0);
346         int save_mode = mwindow->defaults->get("PROJECT_SAVE_MODE", 0);
347
348         SaveProjectWindow window(mwindow, dir_path, save_mode, overwrite, reload);
349         window.lock_window("SaveProject::run");
350         window.create_objects();
351         window.unlock_window();
352         int result = window.run_window();
353         if( result ) return;
354
355         strcpy(dir_path, window.textbox->get_text());
356         window.recent_project->add_item("RECENT_PROJECT", dir_path);
357         reload = window.get_reload();
358         overwrite = window.get_overwrite();
359         save_mode = window.get_save_mode();
360         mwindow->defaults->update("PROJECT_DIRECTORY", dir_path);
361         mwindow->defaults->update("PROJECT_RELOAD", reload);
362         mwindow->defaults->update("PROJECT_OVERWRITE", overwrite);
363         mwindow->defaults->update("PROJECT_SAVE_MODE", save_mode);
364         mwindow->save_project(dir_path, save_mode, overwrite, reload);
365 }
366