undo fixes, viewer change_source rework, cleanup
[goodguy/history.git] / cinelerra-5.1 / cinelerra / clippopup.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 "assetedit.h"
23 #include "clippopup.h"
24 #include "assetremove.h"
25 #include "awindow.h"
26 #include "awindowgui.h"
27 #include "bcsignals.h"
28 #include "clipedit.h"
29 #include "cwindow.h"
30 #include "cwindowgui.h"
31 #include "edl.h"
32 #include "filexml.h"
33 #include "language.h"
34 #include "localsession.h"
35 #include "mainerror.h"
36 #include "mainsession.h"
37 #include "mwindow.h"
38 #include "mwindowgui.h"
39 #include "tracks.h"
40 #include "vwindow.h"
41 #include "vwindowgui.h"
42
43
44
45 ClipPopup::ClipPopup(MWindow *mwindow, AWindowGUI *gui)
46  : BC_PopupMenu(0, 0, 0, "", 0)
47 {
48         this->mwindow = mwindow;
49         this->gui = gui;
50 }
51
52 ClipPopup::~ClipPopup()
53 {
54 }
55
56 void ClipPopup::create_objects()
57 {
58         BC_MenuItem *menu_item;
59         BC_SubMenu *submenu;
60         add_item(info = new ClipPopupInfo(mwindow, this));
61         add_item(format = new AWindowListFormat(mwindow, gui));
62         add_item(new ClipPopupSort(mwindow, this));
63         add_item(view = new ClipPopupView(mwindow, this));
64         add_item(view_window = new ClipPopupViewWindow(mwindow, this));
65         add_item(new ClipPopupCopy(mwindow, this));
66         add_item(new ClipPopupPaste(mwindow, this));
67         add_item(menu_item = new BC_MenuItem(_("Match...")));
68         menu_item->add_submenu(submenu = new BC_SubMenu());
69         submenu->add_submenuitem(new ClipMatchSize(mwindow, this));
70         submenu->add_submenuitem(new ClipMatchRate(mwindow, this));
71         submenu->add_submenuitem(new ClipMatchAll(mwindow, this));
72         add_item(new ClipPopupDelete(mwindow, this));
73 }
74
75 void ClipPopup::paste_assets()
76 {
77 // Collect items into the drag vectors for temporary storage
78         gui->lock_window("ClipPopup::paste_assets");
79         mwindow->gui->lock_window("ClipPopup::paste_assets");
80         mwindow->cwindow->gui->lock_window("ClipPopup::paste_assets");
81
82         gui->collect_assets();
83         mwindow->paste_assets(mwindow->edl->local_session->get_selectionstart(1),
84                 mwindow->edl->tracks->first,
85                 0);   // do not overwrite
86
87         gui->unlock_window();
88         mwindow->gui->unlock_window();
89         mwindow->cwindow->gui->unlock_window();
90 }
91
92 void ClipPopup::match_size()
93 {
94 // Collect items into the drag vectors for temporary storage
95         gui->collect_assets();
96         mwindow->gui->lock_window("ClipPopup::match_size");
97         mwindow->asset_to_size();
98         mwindow->gui->unlock_window();
99 }
100
101 void ClipPopup::match_rate()
102 {
103 // Collect items into the drag vectors for temporary storage
104         gui->collect_assets();
105         mwindow->gui->lock_window("ClipPopup::match_rate");
106         mwindow->asset_to_rate();
107         mwindow->gui->unlock_window();
108 }
109
110 void ClipPopup::match_all()
111 {
112 // Collect items into the drag vectors for temporary storage
113         gui->collect_assets();
114         mwindow->gui->lock_window("ClipPopup::match_rate");
115         mwindow->asset_to_all();
116         mwindow->gui->unlock_window();
117 }
118
119 int ClipPopup::update()
120 {
121         format->update();
122         gui->collect_assets();
123         return 0;
124 }
125
126
127 ClipPopupInfo::ClipPopupInfo(MWindow *mwindow, ClipPopup *popup)
128  : BC_MenuItem(_("Info..."))
129 {
130         this->mwindow = mwindow;
131         this->popup = popup;
132 }
133
134 ClipPopupInfo::~ClipPopupInfo()
135 {
136 }
137
138 int ClipPopupInfo::handle_event()
139 {
140         int cur_x, cur_y;
141         popup->gui->get_abs_cursor(cur_x, cur_y, 0);
142
143         if( mwindow->session->drag_assets->total ) {
144                 AssetEdit *asset_edit = mwindow->awindow->get_asset_editor();
145                 asset_edit->edit_asset(
146                         mwindow->session->drag_assets->values[0], cur_x, cur_y);
147         }
148         else
149         if( mwindow->session->drag_clips->total ) {
150                 popup->gui->awindow->clip_edit->edit_clip(
151                         mwindow->session->drag_clips->values[0], cur_x, cur_y);
152         }
153         return 1;
154 }
155
156
157 ClipPopupSort::ClipPopupSort(MWindow *mwindow, ClipPopup *popup)
158  : BC_MenuItem(_("Sort items"))
159 {
160         this->mwindow = mwindow;
161         this->popup = popup;
162 }
163
164 ClipPopupSort::~ClipPopupSort()
165 {
166 }
167
168 int ClipPopupSort::handle_event()
169 {
170         mwindow->awindow->gui->sort_assets(0);
171         return 1;
172 }
173
174
175 ClipPopupView::ClipPopupView(MWindow *mwindow, ClipPopup *popup)
176  : BC_MenuItem(_("View"))
177 {
178         this->mwindow = mwindow;
179         this->popup = popup;
180 }
181
182 ClipPopupView::~ClipPopupView()
183 {
184 }
185
186 int ClipPopupView::handle_event()
187 {
188         VWindow *vwindow = mwindow->get_viewer(1, DEFAULT_VWINDOW);
189
190         if( mwindow->session->drag_assets->total )
191                 vwindow->change_source(
192                         mwindow->session->drag_assets->values[0]);
193         else
194         if( mwindow->session->drag_clips->total )
195                 vwindow->change_source(
196                         mwindow->session->drag_clips->values[0]);
197
198         return 1;
199 }
200
201
202 ClipPopupViewWindow::ClipPopupViewWindow(MWindow *mwindow, ClipPopup *popup)
203  : BC_MenuItem(_("View in new window"))
204 {
205         this->mwindow = mwindow;
206         this->popup = popup;
207 }
208
209 ClipPopupViewWindow::~ClipPopupViewWindow()
210 {
211 }
212
213 int ClipPopupViewWindow::handle_event()
214 {
215 // Find window with nothing
216         VWindow *vwindow = mwindow->get_viewer(1);
217
218 // TODO: create new vwindow or change current vwindow
219         vwindow->gui->lock_window("ClipPopupView::handle_event");
220
221         if( mwindow->session->drag_assets->total )
222                 vwindow->change_source(
223                         mwindow->session->drag_assets->values[0]);
224         else
225         if( mwindow->session->drag_clips->total )
226                 vwindow->change_source(
227                         mwindow->session->drag_clips->values[0]);
228
229         vwindow->gui->unlock_window();
230         return 1;
231 }
232
233
234 ClipPopupCopy::ClipPopupCopy(MWindow *mwindow, ClipPopup *popup)
235  : BC_MenuItem(_("Copy"))
236 {
237         this->mwindow = mwindow;
238         this->popup = popup;
239 }
240 ClipPopupCopy::~ClipPopupCopy()
241 {
242 }
243
244 int ClipPopupCopy::handle_event()
245 {
246         MWindowGUI *gui = mwindow->gui;
247         gui->lock_window("ClipPopupCopy::handle_event");
248         if( mwindow->session->drag_clips->total > 0 ) {
249                 FileXML file;
250                 EDL *edl = mwindow->session->drag_clips->values[0];
251                 double start = 0, end = edl->tracks->total_length();
252                 edl->copy(start, end, 1, 0, 0, &file, "", 1);
253                 const char *file_string = file.string();
254                 long file_length = strlen(file_string);
255                 gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION);
256                 gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION);
257         }
258         gui->unlock_window(); 
259         return 1;
260 }
261
262
263 ClipPopupPaste::ClipPopupPaste(MWindow *mwindow, ClipPopup *popup)
264  : BC_MenuItem(_("Paste"))
265 {
266         this->mwindow = mwindow;
267         this->popup = popup;
268 }
269
270 ClipPopupPaste::~ClipPopupPaste()
271 {
272 }
273
274 int ClipPopupPaste::handle_event()
275 {
276         popup->paste_assets();
277         return 1;
278 }
279
280
281 ClipMatchSize::ClipMatchSize(MWindow *mwindow, ClipPopup *popup)
282  : BC_MenuItem(_("Match project size"))
283 {
284         this->mwindow = mwindow;
285         this->popup = popup;
286 }
287
288 int ClipMatchSize::handle_event()
289 {
290         popup->match_size();
291         return 1;
292 }
293
294
295 ClipMatchRate::ClipMatchRate(MWindow *mwindow, ClipPopup *popup)
296  : BC_MenuItem(_("Match frame rate"))
297 {
298         this->mwindow = mwindow;
299         this->popup = popup;
300 }
301
302 int ClipMatchRate::handle_event()
303 {
304         popup->match_rate();
305         return 1;
306 }
307
308
309 ClipMatchAll::ClipMatchAll(MWindow *mwindow, ClipPopup *popup)
310  : BC_MenuItem(_("Match all"))
311 {
312         this->mwindow = mwindow;
313         this->popup = popup;
314 }
315
316 int ClipMatchAll::handle_event()
317 {
318         popup->match_all();
319         return 1;
320 }
321
322
323 ClipPopupDelete::ClipPopupDelete(MWindow *mwindow, ClipPopup *popup)
324  : BC_MenuItem(_("Delete"))
325 {
326         this->mwindow = mwindow;
327         this->popup = popup;
328 }
329
330
331 ClipPopupDelete::~ClipPopupDelete()
332 {
333 }
334
335 int ClipPopupDelete::handle_event()
336 {
337         mwindow->remove_assets_from_project(1, 1,
338                 mwindow->session->drag_assets,
339                 mwindow->session->drag_clips);
340         return 1;
341 }
342
343
344 ClipPasteToFolder::ClipPasteToFolder(MWindow *mwindow)
345  : BC_MenuItem(_("Paste Clip"))
346 {
347         this->mwindow = mwindow;
348 }
349
350 int ClipPasteToFolder::handle_event()
351 {
352         MWindowGUI *gui = mwindow->gui;
353         gui->lock_window("ClipPasteToFolder::handle_event 1");
354         int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION);
355         if( len ) {
356                 char *string = new char[len];
357                 gui->from_clipboard(string, len, BC_PRIMARY_SELECTION);
358                 const char *clip_header = "<EDL VERSION=";
359                 if( !strncmp(clip_header, string, strlen(clip_header)) ) {
360                         FileXML file;
361                         file.read_from_string(string);
362                         EDL *edl = mwindow->edl;
363                         EDL *new_edl = new EDL(mwindow->edl);
364                         new_edl->create_objects();
365                         new_edl->load_xml(&file, LOAD_ALL);
366                         edl->update_assets(new_edl);
367                         mwindow->save_clip(new_edl, _("paste clip: "));
368                 }
369                 else {
370                         char *cp = strchr(string, '\n');
371                         if( cp-string < 32 ) *cp = 0;
372                         else if( len > 32 ) string[32] = 0;
373                         eprintf("paste buffer is not EDL:\n%s", string);
374                 }
375                 delete [] string;
376         }
377         else {
378                 eprintf("paste buffer empty");
379         }
380         gui->unlock_window();
381         return 1;
382 }
383
384
385 ClipListMenu::ClipListMenu(MWindow *mwindow, AWindowGUI *gui)
386  : BC_PopupMenu(0, 0, 0, "", 0)
387 {
388         this->mwindow = mwindow;
389         this->gui = gui;
390 }
391
392 ClipListMenu::~ClipListMenu()
393 {
394 }
395
396 void ClipListMenu::create_objects()
397 {
398         add_item(format = new AWindowListFormat(mwindow, gui));
399         add_item(new AWindowListSort(mwindow, gui));
400         add_item(new ClipPasteToFolder(mwindow));
401         update();
402 }
403
404 void ClipListMenu::update()
405 {
406         format->update();
407 }
408