57459ef9d154087f0e4099b64e2a11493a79be96
[goodguy/history.git] / cinelerra-5.0 / cinelerra / vwindow.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2012 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 "asset.h"
23 #include "assets.h"
24 #include "clip.h"
25 #include "clipedit.h"
26 #include "bchash.h"
27 #include "edl.h"
28 #include "edlsession.h"
29 #include "filesystem.h"
30 #include "filexml.h"
31 #include "indexable.h"
32 #include "language.h"
33 #include "localsession.h"
34 #include "mainclock.h"
35 #include "mainmenu.h"
36 #include "mainsession.h"
37 #include "mwindow.h"
38 #include "mwindowgui.h"
39 #include "playbackengine.h"
40 #include "tracks.h"
41 #include "transportque.h"
42 #include "vplayback.h"
43 #include "vtimebar.h"
44 #include "vtracking.h"
45 #include "vwindow.h"
46 #include "vwindowgui.h"
47
48
49 VWindow::VWindow(MWindow *mwindow)
50  : BC_DialogThread()
51 {
52         this->mwindow = mwindow;
53         gui = 0;
54         playback_engine = 0;
55         playback_cursor = 0;
56         clip_edit = 0;
57         indexable = 0;
58         edl = 0;
59 }
60
61
62 VWindow::~VWindow()
63 {
64         close_window();
65 //printf("VWindow::~VWindow 1\n");
66         delete playback_engine;
67 //printf("VWindow::~VWindow 1\n");
68         delete playback_cursor;
69         delete_source(1, 0);
70         delete clip_edit;
71 //printf("VWindow::~VWindow 2\n");
72 }
73
74 void VWindow::delete_source(int do_main_edl, int update_gui)
75 {
76         if(do_main_edl) mwindow->edl->remove_vwindow_edl(get_edl());
77
78
79         if(edl)
80         {
81 //printf("VWindow::delete_source %d %p\n", __LINE__, edl);
82                 edl->Garbage::remove_user();
83 //printf("VWindow::delete_source %d\n", __LINE__);
84                 edl = 0;
85         }
86
87 //      if(mwindow->edl->vwindow_edl && !mwindow->edl->vwindow_edl_shared)
88 //      {
89 //              mwindow->edl->vwindow_edl->Garbage::remove_user();
90 //              mwindow->edl->vwindow_edl = 0;
91 //              mwindow->edl->vwindow_edl_shared = 0;
92 //      }
93
94 //printf("VWindow::delete_source %d\n", __LINE__);
95         if(indexable) indexable->Garbage::remove_user();
96 //printf("VWindow::delete_source %d\n", __LINE__);
97         indexable = 0;
98
99         if(update_gui) gui->change_source(0, _("Viewer"));
100 }
101
102
103 void VWindow::load_defaults()
104 {
105 }
106
107 void VWindow::create_objects()
108 {
109 }
110
111
112 void VWindow::handle_close_event(int result)
113 {
114         delete_source(1, 0);
115         delete playback_engine;
116         delete playback_cursor;
117         delete clip_edit;
118         playback_engine = 0;
119         playback_cursor = 0;
120         clip_edit = 0;
121         if( mwindow->in_destructor ) return;
122
123         int total = 0;
124         for(int i = 0; i < mwindow->vwindows.size(); i++)
125         {
126
127 //printf("VWindow::handle_close_event %d %d\n", __LINE__, mwindow->vwindows.get(i)->is_running());
128                 if(mwindow->vwindows.get(i)->is_running()) total++;
129         }
130 // subtract ourselves
131         total--;
132
133 // Update the menu if no viewers visible
134         if(!total)
135         {
136                 mwindow->gui->lock_window("VWindowGUI::close_event");
137                 mwindow->gui->mainmenu->show_vwindow->set_checked(0);
138                 mwindow->gui->unlock_window();
139                 
140                 mwindow->session->show_vwindow = 0;
141                 mwindow->save_defaults();
142         }
143 }
144
145
146
147 BC_Window* VWindow::new_gui()
148 {
149 //printf("VWindow::create_objects 1\n");
150         gui = new VWindowGUI(mwindow, this);
151 //printf("VWindow::create_objects 1\n");
152         gui->create_objects();
153 //printf("VWindow::create_objects 1\n");
154
155         playback_engine = new VPlayback(mwindow, this, gui->canvas);
156 //printf("VWindow::create_objects 1\n");
157
158 // Start command loop
159         playback_engine->create_objects();
160 //printf("VWindow::create_objects 1\n");
161         gui->transport->set_engine(playback_engine);
162 //printf("VWindow::create_objects 1\n");
163         playback_cursor = new VTracking(mwindow, this);
164 //printf("VWindow::create_objects 1\n");
165         playback_cursor->create_objects();
166 //printf("VWindow::create_objects 2\n");
167
168         clip_edit = new ClipEdit(mwindow, 0, this);
169         return gui;
170 }
171
172
173 EDL* VWindow::get_edl()
174 {
175 //      return mwindow->edl->vwindow_edl;
176         return edl;
177 }
178
179 Indexable* VWindow::get_source()
180 {
181         return this->indexable;
182 }
183
184 void VWindow::change_source(int edl_number)
185 {
186         if(!is_running()) return;
187
188 //printf("VWindow::change_source %d %p\n", __LINE__, mwindow->edl->get_vwindow_edl(edl_number));
189         if( edl_number >= 0 && edl_number < mwindow->edl->total_vwindow_edls() &&
190                  mwindow->edl->get_vwindow_edl(edl_number) )
191         {
192                 this->edl = mwindow->edl->get_vwindow_edl(edl_number);
193                 this->edl->Garbage::add_user();
194                 gui->change_source(get_edl(), get_edl()->local_session->clip_title);
195                 update_position(CHANGE_ALL, 1, 1, 1);
196         }
197         else
198         {
199                 delete_source(1, 1);
200 //              if(indexable) indexable->Garbage::remove_user();
201 //              indexable = 0;
202 //              mwindow->edl->vwindow_edl_shared = 0;
203         }
204 }
205
206 void VWindow::change_source(Indexable *indexable)
207 {
208         if(!running()) return;
209 //printf("VWindow::change_source %d\n", __LINE__);
210 //      if(asset && this->asset &&
211 //              asset->id == this->asset->id &&
212 //              asset == this->asset) return;
213
214 //printf("VWindow::change_source %d\n", __LINE__);
215
216         char title[BCTEXTLEN];
217         FileSystem fs;
218         fs.extract_name(title, indexable->path);
219 //printf("VWindow::change_source 1\n");
220
221         delete_source(1, 0);
222 //printf("VWindow::change_source 1\n");
223
224 // Generate EDL off of main EDL for cutting
225         Asset *asset = 0;
226         EDL *nested_edl = 0;
227         if(indexable->is_asset)
228         {
229                 this->indexable = asset = new Asset;
230                 asset->copy_from((Asset*)indexable, 0);
231         }
232         else
233         {
234                 this->indexable = nested_edl = new EDL;
235                 nested_edl->create_objects();
236                 nested_edl->copy_all((EDL*)indexable);
237         }
238
239 // Create EDL
240         this->edl = new EDL(mwindow->edl);
241         this->edl->create_objects();
242         mwindow->edl->append_vwindow_edl(this->edl, 1);
243
244 //      mwindow->edl->vwindow_edl = new EDL(mwindow->edl);
245 //      mwindow->edl->vwindow_edl_shared = 0;
246 //      mwindow->edl->vwindow_edl->create_objects();
247
248 //printf("VWindow::change_source 1 %d %p %p\n", __LINE__, asset, nested_edl);
249         if(asset)
250                 mwindow->asset_to_edl(this->edl, asset);
251         else
252                 mwindow->edl_to_nested(this->edl, nested_edl);
253
254 // Update GUI
255         gui->change_source(this->edl, title);
256         update_position(CHANGE_ALL, 1, 1, 1);
257
258
259
260 //printf("VWindow::change_source 2\n");
261 }
262
263 void VWindow::change_source(EDL *edl)
264 {
265         if(!running()) return;
266 //printf("VWindow::change_source %d %p\n", __LINE__, edl);
267 // EDLs are identical
268 //      if(edl && mwindow->edl->vwindow_edl && 
269 //              edl->id == mwindow->edl->vwindow_edl->id) return;
270         if(edl && get_edl() && edl->id == get_edl()->id) return;
271
272         delete_source(1, 0);
273
274         if(edl)
275         {
276                 mwindow->edl->append_vwindow_edl(edl, 1);
277                 this->edl = edl;
278                 this->edl->Garbage::add_user();
279
280 //              mwindow->edl->vwindow_edl = edl;
281 // in order not to later delete edl if it is shared
282 //              edl->Garbage::add_user();
283 //              mwindow->edl->vwindow_edl_shared = 1;
284
285 // Update GUI
286                 gui->change_source(edl, edl->local_session->clip_title);
287                 update_position(CHANGE_ALL, 1, 1, 1);
288         }
289         else
290                 gui->change_source(edl, _("Viewer"));
291 }
292
293 void VWindow::change_source(char *folder, int item)
294 {
295 //printf("VWindow::change_source %d\n", __LINE__);
296         int result = 0;
297         if(!running()) return;
298 // Search EDLs
299         if(!strcasecmp(folder, CLIP_FOLDER))
300         {
301                 if(item < mwindow->edl->clips.total)
302                 {
303                         change_source(mwindow->edl->clips.values[item]);
304                         result = 1;
305                 }
306         }
307         else
308 // Search media
309         if(!strcasecmp(folder, MEDIA_FOLDER))
310         {
311                 if(item < mwindow->edl->assets->total())
312                 {
313                         change_source(mwindow->edl->assets->get_item_number(item));
314                         result = 1;
315                 }
316         }
317         else
318 // Search extra clip folders
319         {
320         }
321         
322         if(!result)
323         {
324                 delete_source(1, 1);
325         }
326 }
327
328
329
330
331 void VWindow::goto_start()
332 {
333         if(get_edl())
334         {
335                 get_edl()->local_session->set_selectionstart(0);
336                 get_edl()->local_session->set_selectionend(0);
337                 update_position(CHANGE_NONE, 
338                         0, 
339                         1, 
340                         0);
341         }
342 }
343
344 void VWindow::goto_end()
345 {
346         if(get_edl())
347         {
348                 double position = get_edl()->tracks->total_length();
349                 get_edl()->local_session->set_selectionstart(position);
350                 get_edl()->local_session->set_selectionend(position);
351                 update_position(CHANGE_NONE, 
352                         0, 
353                         1,
354                         0);
355         }
356 }
357
358 void VWindow::update(int do_timebar)
359 {
360         if(do_timebar)
361                 gui->timebar->update(1);
362 }
363
364 void VWindow::update_position(int change_type, 
365         int use_slider, 
366         int update_slider,
367         int lock_window)
368 {
369         EDL *edl = get_edl();
370         if(edl)
371         {
372 //printf("VWindow::update_position %d\n", __LINE__);
373 //edl->dump();
374                 playback_engine->que->send_command(CURRENT_FRAME, 
375                         change_type,
376                         edl,
377                         1);
378
379                 if(lock_window) gui->lock_window("VWindow::update_position");
380                 gui->clock->update(edl->local_session->get_selectionstart(1));
381                 if(lock_window) gui->unlock_window();
382         }
383 }
384
385
386
387
388
389 int VWindow::update_position(double position)
390 {
391         EDL *edl = get_edl();
392         if(edl)
393         {
394                 gui->unlock_window();
395
396                 playback_engine->interrupt_playback(1);
397
398                 position = mwindow->edl->align_to_frame(position, 0);
399                 position = MAX(0, position);
400
401                 edl->local_session->set_selectionstart(position);
402                 edl->local_session->set_selectionend(position);
403
404                 gui->lock_window("VWindow::update_position 1");
405                 update_position(CHANGE_NONE, 0, 1, 0);
406         }
407
408         return 1;
409 }
410
411
412 void VWindow::set_inpoint()
413 {
414         EDL *edl = get_edl();
415         if(edl)
416         {
417                 edl->set_inpoint(edl->local_session->get_selectionstart(1));
418                 gui->timebar->update(1);
419         }
420 }
421
422 void VWindow::set_outpoint()
423 {
424         EDL *edl = get_edl();
425         if(edl)
426         {
427                 edl->set_outpoint(edl->local_session->get_selectionstart(1));
428                 gui->timebar->update(1);
429         }
430 }
431
432 void VWindow::clear_inpoint()
433 {
434         EDL *edl = get_edl();
435         if(edl)
436         {
437                 edl->local_session->unset_inpoint();
438                 gui->timebar->update(1);
439         }
440 }
441
442 void VWindow::clear_outpoint()
443 {
444         EDL *edl = get_edl();
445         if(edl)
446         {
447                 edl->local_session->unset_outpoint();
448                 gui->timebar->update(1);
449         }
450 }
451
452 void VWindow::copy()
453 {
454         EDL *edl = get_edl();
455         if(edl)
456         {
457                 double start = edl->local_session->get_selectionstart();
458                 double end = edl->local_session->get_selectionend();
459                 FileXML file;
460                 edl->copy(start,
461                         end,
462                         0,
463                         0,
464                         0,
465                         &file,
466                         "",
467                         1);
468                 const char *file_string = file.string();
469                 long file_length = strlen(file_string);
470                 mwindow->gui->lock_window();
471                 mwindow->gui->get_clipboard()->to_clipboard(file_string, file_length,
472                         SECONDARY_SELECTION);
473                 mwindow->gui->get_clipboard()->to_clipboard(file_string, file_length,
474                         BC_PRIMARY_SELECTION);
475                 mwindow->gui->unlock_window();
476         }
477 }
478
479 void VWindow::splice_selection()
480 {
481 }
482
483 void VWindow::overwrite_selection()
484 {
485 }
486