mask tweaks, focus follows centroid, gradient/colorpicker rework, no hard edges in...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / shbtnprefs.C
1 #include "bcwindowbase.h"
2 #include "bcdisplayinfo.h"
3 #include "bcdialog.h"
4 #include "awindow.h"
5 #include "awindowgui.h"
6 #include "cstrdup.h"
7 #include "indexable.h"
8 #include "language.h"
9 #include "mainerror.h"
10 #include "mainsession.h"
11 #include "mwindow.h"
12 #include "shbtnprefs.h"
13 #include "preferences.h"
14 #include "preferencesthread.h"
15 #include "theme.h"
16
17 #include <sys/wait.h>
18
19 ShBtnRun::ShBtnRun(const char *nm, const char *cmds, int warn)
20  : Thread(0, 0, 1)
21 {
22         argv.set_array_delete();
23         strncpy(name, nm, sizeof(name)-1);
24         name[sizeof(name)-1] = 0;
25         strncpy(commands, cmds, sizeof(commands)-1);
26         commands[sizeof(commands)-1] = 0;
27         this->warn = warn;
28 }
29 ShBtnRun::~ShBtnRun()
30 {
31         argv.remove_all_objects();
32 }
33
34 void ShBtnRun::add_arg(const char *v)
35 {
36         argv.append(cstrdup(v));
37 }
38
39 void ShBtnRun::run()
40 {
41         pid_t pid = vfork();
42         if( pid < 0 ) {
43                 perror("fork");
44                 return;
45         }
46         char msg[BCTEXTLEN];
47         if( !pid ) {
48                 argv.append(0);
49                 execvp(argv[0], &argv[0]);
50                 return;
51         }
52         // warn <0:always, =0:never, >0:on err
53         if( !warn ) return;
54         int stat;  waitpid(pid, &stat, 0);
55         if( !stat ) {
56                 if( warn > 0 ) return;
57                 sprintf(msg, "%s: completed", name);
58         }
59         else
60                 sprintf(msg, "%s: error exit status %d", name, stat);
61         MainError::show_error(msg);
62 }
63
64 ShBtnPref::ShBtnPref(const char *nm, const char *cmds, int warn, int run_script)
65 {
66         strncpy(name, nm, sizeof(name));
67         strncpy(commands, cmds, sizeof(commands));
68         this->warn = warn;
69         this->run_script = run_script;
70 }
71
72 ShBtnPref::~ShBtnPref()
73 {
74 }
75
76 void ShBtnPref::execute(ArrayList<Indexable*> &args)
77 {
78 // thread async+autodelete, no explicit delete
79         ShBtnRun *job = new ShBtnRun(name, commands, warn);
80         job->add_arg("/bin/bash");
81         job->add_arg(commands);
82         int n = args.size();
83         for( int i=0; i<n; ++i ) {
84                 Indexable *idxbl = args[i];
85                 if( !idxbl->is_asset ) continue;
86                 job->add_arg(idxbl->path);
87         }
88         job->start();
89 }
90
91 void ShBtnPref::execute()
92 {
93         ShBtnRun *job = new ShBtnRun(name, commands, warn);
94         job->add_arg("/bin/bash");
95         job->add_arg("-c");
96         job->add_arg(commands);
97         job->start();
98 }
99
100 ShBtnEditDialog::ShBtnEditDialog(PreferencesWindow *pwindow)
101  : BC_DialogThread()
102 {
103         this->pwindow = pwindow;
104 }
105
106 ShBtnEditDialog::~ShBtnEditDialog()
107 {
108         close_window();
109 }
110
111 BC_Window* ShBtnEditDialog::new_gui()
112 {
113         BC_DisplayInfo display_info;
114         int x = display_info.get_abs_cursor_x();
115         int y = display_info.get_abs_cursor_y();
116
117         sb_window = new ShBtnEditWindow(this, x, y);
118         sb_window->create_objects();
119         return sb_window;
120 }
121
122 void ShBtnEditDialog::handle_close_event(int result)
123 {
124         sb_window = 0;
125 }
126
127
128 ShBtnEditWindow::ShBtnEditWindow(ShBtnEditDialog *shbtn_edit, int x, int y)
129  : BC_Window(_(PROGRAM_NAME ": Shell"), x, y, 300, 200, 300, 200, 0, 0, 1)
130 {
131         this->shbtn_edit = shbtn_edit;
132         sb_dialog = 0;
133 }
134
135 ShBtnEditWindow::~ShBtnEditWindow()
136 {
137         delete sb_dialog;
138 }
139
140 int ShBtnEditWindow::list_update()
141 {
142         shbtn_items.remove_all_objects();
143         Preferences *preferences = shbtn_edit->pwindow->thread->preferences;
144         for( int i=0; i<preferences->shbtn_prefs.size(); ++i ) {
145                 shbtn_items.append(new ShBtnPrefItem(preferences->shbtn_prefs[i]));
146         }
147         return op_list->update(&shbtn_items, 0, 0, 1);
148 }
149
150 ShBtnAddButton::ShBtnAddButton(ShBtnEditWindow *sb_window, int x, int y)
151  : BC_GenericButton(x, y, _("Add"))
152 {
153         this->sb_window = sb_window;
154 }
155
156 ShBtnAddButton::~ShBtnAddButton()
157 {
158 }
159
160 int ShBtnAddButton::handle_event()
161 {
162
163         Preferences *preferences = sb_window->shbtn_edit->pwindow->thread->preferences;
164         ShBtnPref *pref = new ShBtnPref(_("new"), "", 0, 0);
165         preferences->shbtn_prefs.append(pref);
166         sb_window->list_update();
167         return sb_window->start_edit(pref);
168 }
169
170 ShBtnDelButton::ShBtnDelButton(ShBtnEditWindow *sb_window, int x, int y)
171  : BC_GenericButton(x, y, _("Del"))
172 {
173         this->sb_window = sb_window;
174 }
175
176 ShBtnDelButton::~ShBtnDelButton()
177 {
178 }
179
180 int ShBtnDelButton::handle_event()
181 {
182         ShBtnPrefItem *sp = (ShBtnPrefItem *)sb_window->op_list->get_selection(0,0);
183         if( !sp ) return 0;
184         Preferences *preferences = sb_window->shbtn_edit->pwindow->thread->preferences;
185         preferences->shbtn_prefs.remove(sp->pref);
186         sb_window->list_update();
187         return 1;
188 }
189
190 ShBtnEditButton::ShBtnEditButton(ShBtnEditWindow *sb_window, int x, int y)
191  : BC_GenericButton(x, y, _("Edit"))
192 {
193         this->sb_window = sb_window;
194 }
195
196 ShBtnEditButton::~ShBtnEditButton()
197 {
198 }
199
200 int ShBtnEditButton::handle_event()
201 {
202         ShBtnPrefItem *sp = (ShBtnPrefItem *)sb_window->op_list->get_selection(0,0);
203         if( !sp ) return 0;
204         return sb_window->start_edit(sp->pref);
205 }
206
207 ShBtnTextDialog::ShBtnTextDialog(ShBtnEditWindow *sb_window)
208  : BC_DialogThread()
209 {
210         this->sb_window = sb_window;
211         this->pref = 0;
212 }
213
214 ShBtnTextDialog::~ShBtnTextDialog()
215 {
216         close_window();
217 }
218
219 ShBtnTextWindow::ShBtnTextWindow(ShBtnEditWindow *sb_window, int x, int y)
220  : BC_Window(_(PROGRAM_NAME ": Commands"), x, y, 640, 160, 640, 150, 0, 0, 1)
221 {
222         this->sb_window = sb_window;
223         warn = sb_window->sb_dialog->pref->warn;
224         run_script = sb_window->sb_dialog->pref->run_script;
225 }
226
227 ShBtnTextWindow::~ShBtnTextWindow()
228 {
229 }
230
231
232 ShBtnErrWarnItem::ShBtnErrWarnItem(ShBtnErrWarn *popup,
233                 const char *text, int warn)
234  : BC_MenuItem(text)
235 {
236         this->popup = popup;
237         this->warn = warn;
238 }
239
240 int ShBtnErrWarnItem::handle_event()
241 {
242         popup->set_text(get_text());
243         popup->st_window->warn = warn;
244         return 1;
245 }
246
247 ShBtnErrWarn::ShBtnErrWarn(ShBtnTextWindow *st_window, int x, int y)
248  : BC_PopupMenu(x, y, 120, st_window->warn < 0 ? _("Always"):
249         !st_window->warn ? _("Never") : _("On Error"))
250 {
251         this->st_window = st_window;
252 }
253 ShBtnErrWarn::~ShBtnErrWarn()
254 {
255 }
256 int ShBtnErrWarn::handle_event()
257 {
258         return 0;
259 }
260
261 void ShBtnErrWarn::create_objects()
262 {
263         add_item(new ShBtnErrWarnItem(this,_("Always"), -1));
264         add_item(new ShBtnErrWarnItem(this,_("Never"), 0));
265         add_item(new ShBtnErrWarnItem(this,_("On Error"), 1));
266 }
267
268
269 ShBtnRunScript::ShBtnRunScript(ShBtnTextWindow *st_window, int x, int y)
270  : BC_CheckBox(x, y, &st_window->run_script, _("run /path/script.sh + argvs"))
271 {
272         this->st_window = st_window;
273 }
274
275 ShBtnRunScript::~ShBtnRunScript()
276 {
277 }
278
279 void ShBtnTextWindow::create_objects()
280 {
281         lock_window("ShBtnTextWindow::create_objects");
282         int x = 10, y = 10;
283         int x1 = 160;
284         BC_Title *title = new BC_Title(x, y, _("Label:"));
285         add_subwindow(title);
286         title = new BC_Title(x1, y, _("Commands:"));
287         add_subwindow(title);
288         y += title->get_h() + 8;
289         ShBtnPref *pref = sb_window->sb_dialog->pref;
290         cmd_name = new BC_TextBox(x, y, 140, 1, pref->name);
291         add_subwindow(cmd_name);
292         cmd_text = new BC_ScrollTextBox(this, x1, y, get_w()-x1-20, 4, pref->commands);
293         cmd_text->create_objects();
294         y += cmd_text->get_h() + 16;
295         add_subwindow(title = new BC_Title(x1,y, _("OnExit Notify:")));
296         x1 += title->get_w() + 10;
297         add_subwindow(st_err_warn = new ShBtnErrWarn(this, x1, y));
298         st_err_warn->create_objects();
299         x1 += st_err_warn->get_w() + 20;
300         add_subwindow(st_run_script = new ShBtnRunScript(this, x1, y));
301         y = get_h() - ShBtnTextOK::calculate_h() - 10;
302         add_subwindow(new ShBtnTextOK(this, x, y));
303         show_window();
304         unlock_window();
305 }
306
307 ShBtnTextOK::ShBtnTextOK(ShBtnTextWindow *st_window, int x, int y)
308  : BC_OKButton(x, y)
309 {
310         this->st_window = st_window;
311 }
312
313 ShBtnTextOK::~ShBtnTextOK()
314 {
315 }
316
317 int ShBtnTextOK::handle_event()
318 {
319         ShBtnPref *pref = st_window->sb_window->sb_dialog->pref;
320         strcpy(pref->name, st_window->cmd_name->get_text());
321         strcpy(pref->commands, st_window->cmd_text->get_text());
322         pref->warn = st_window->warn;
323         pref->run_script = st_window->run_script;
324         return BC_OKButton::handle_event();
325 }
326
327
328 BC_Window *ShBtnTextDialog::new_gui()
329 {
330         BC_DisplayInfo display_info;
331         int x = display_info.get_abs_cursor_x();
332         int y = display_info.get_abs_cursor_y();
333
334         st_window = new ShBtnTextWindow(sb_window, x, y);
335         st_window->create_objects();
336         return st_window;
337 }
338
339 void ShBtnTextDialog::handle_close_event(int result)
340 {
341         if( !result ) {
342                 sb_window->lock_window("ShBtnTextDialog::handle_close_event");
343                 sb_window->list_update();
344                 sb_window->unlock_window();
345         }
346         st_window = 0;
347 }
348
349 int ShBtnTextDialog::start_edit(ShBtnPref *pref)
350 {
351         this->pref = pref;
352         start();
353         return 1;
354 }
355
356 void ShBtnEditWindow::create_objects()
357 {
358         lock_window("ShBtnEditWindow::create_objects");
359         Preferences *preferences = shbtn_edit->pwindow->thread->preferences;
360         for( int i=0; i<preferences->shbtn_prefs.size(); ++i ) {
361                 shbtn_items.append(new ShBtnPrefItem(preferences->shbtn_prefs[i]));
362         }
363         int x = 10, y = 10;
364         add_subwindow(op_list = new ShBtnPrefList(this, x, y));
365         x = 190;
366         add_subwindow(add_button = new ShBtnAddButton(this, x, y));
367         y += add_button->get_h() + 8;
368         add_subwindow(del_button = new ShBtnDelButton(this, x, y));
369         y += del_button->get_h() + 8;
370         add_subwindow(edit_button = new ShBtnEditButton(this, x, y));
371         add_subwindow(new BC_OKButton(this));
372         show_window();
373         unlock_window();
374 }
375
376 int ShBtnEditWindow::start_edit(ShBtnPref *pref)
377 {
378         if( !sb_dialog )
379                 sb_dialog = new ShBtnTextDialog(this);
380         return sb_dialog->start_edit(pref);
381 }
382
383
384 ShBtnPrefItem::ShBtnPrefItem(ShBtnPref *pref)
385  : BC_ListBoxItem(pref->name)
386 {
387         this->pref = pref;
388 }
389
390 ShBtnPrefItem::~ShBtnPrefItem()
391 {
392 }
393
394 ShBtnPrefList::ShBtnPrefList(ShBtnEditWindow *sb_window, int x, int y)
395  : BC_ListBox(x, y, 140, 100, LISTBOX_TEXT, &sb_window->shbtn_items, 0, 0)
396 {
397         this->sb_window = sb_window;
398 }
399
400 ShBtnPrefList::~ShBtnPrefList()
401 {
402 }
403
404 int ShBtnPrefList::handle_event()
405 {
406         return 1;
407 }
408
409 MainShBtnItem::MainShBtnItem(MainShBtns *shbtns, ShBtnPref *pref)
410  : BC_MenuItem(pref->name)
411 {
412         this->shbtns = shbtns;
413         this->pref = pref;
414 }
415
416 int MainShBtnItem::handle_event()
417 {
418         MWindow *mwindow = shbtns->mwindow;
419         if( pref->run_script ) {
420                 AWindowGUI *agui = mwindow->awindow->gui;
421                 agui->lock_window("MainShBtnItem::handle_event");
422                 mwindow->awindow->gui->collect_assets();
423                 pref->execute(*mwindow->session->drag_assets);
424                 agui->unlock_window();
425         }
426         else
427                 pref->execute();
428         return 1;
429 }
430
431 MainShBtns::MainShBtns(MWindow *mwindow, int x, int y)
432  : BC_PopupMenu(x, y, 0, "", -1, mwindow->theme->shbtn_data)
433 {
434         this->mwindow = mwindow;
435         set_tooltip(_("shell cmds"));
436 }
437
438 int MainShBtns::load(Preferences *preferences)
439 {
440         while( total_items() ) del_item(0);
441         for( int i=0; i<preferences->shbtn_prefs.size(); ++i )
442                 add_item(new MainShBtnItem(this, preferences->shbtn_prefs[i]));
443         return 0;
444 }
445
446 int MainShBtns::handle_event()
447 {
448         return 1;
449 }
450