add mask color radio btn sel, fix del all mask btn, fix mask dflt kfrm draw name...
[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         if( pid > 0 ) {
47                 int stat;  waitpid(pid, &stat, 0);
48                 if( warn && stat ) {
49                         char msg[BCTEXTLEN];
50                         sprintf(msg, "%s: error exit status %d", name, stat);
51                         MainError::show_error(msg);
52                 }
53                 return;
54         }
55         argv.append(0);
56         execvp(argv[0], &argv[0]);
57 }
58
59 ShBtnPref::ShBtnPref(const char *nm, const char *cmds, int warn, int run_script)
60 {
61         strncpy(name, nm, sizeof(name));
62         strncpy(commands, cmds, sizeof(commands));
63         this->warn = warn;
64         this->run_script = run_script;
65 }
66
67 ShBtnPref::~ShBtnPref()
68 {
69 }
70
71 void ShBtnPref::execute(ArrayList<Indexable*> &args)
72 {
73 // thread async+autodelete, no explicit delete
74         ShBtnRun *job = new ShBtnRun(name, commands, warn);
75         job->add_arg("/bin/bash");
76         job->add_arg(commands);
77         int n = args.size();
78         for( int i=0; i<n; ++i ) {
79                 Indexable *idxbl = args[i];
80                 if( !idxbl->is_asset ) continue;
81                 job->add_arg(idxbl->path);
82         }
83         job->start();
84 }
85
86 void ShBtnPref::execute()
87 {
88         ShBtnRun *job = new ShBtnRun(name, commands, warn);
89         job->add_arg("/bin/bash");
90         job->add_arg("-c");
91         job->add_arg(commands);
92         job->start();
93 }
94
95 ShBtnEditDialog::ShBtnEditDialog(PreferencesWindow *pwindow)
96  : BC_DialogThread()
97 {
98         this->pwindow = pwindow;
99 }
100
101 ShBtnEditDialog::~ShBtnEditDialog()
102 {
103         close_window();
104 }
105
106 BC_Window* ShBtnEditDialog::new_gui()
107 {
108         BC_DisplayInfo display_info;
109         int x = display_info.get_abs_cursor_x();
110         int y = display_info.get_abs_cursor_y();
111
112         sb_window = new ShBtnEditWindow(this, x, y);
113         sb_window->create_objects();
114         return sb_window;
115 }
116
117 void ShBtnEditDialog::handle_close_event(int result)
118 {
119         sb_window = 0;
120 }
121
122
123 ShBtnEditWindow::ShBtnEditWindow(ShBtnEditDialog *shbtn_edit, int x, int y)
124  : BC_Window(_(PROGRAM_NAME ": Shell"), x, y, 300, 200, 300, 200, 0, 0, 1)
125 {
126         this->shbtn_edit = shbtn_edit;
127         sb_dialog = 0;
128 }
129
130 ShBtnEditWindow::~ShBtnEditWindow()
131 {
132         delete sb_dialog;
133 }
134
135 int ShBtnEditWindow::list_update()
136 {
137         shbtn_items.remove_all_objects();
138         Preferences *preferences = shbtn_edit->pwindow->thread->preferences;
139         for( int i=0; i<preferences->shbtn_prefs.size(); ++i ) {
140                 shbtn_items.append(new ShBtnPrefItem(preferences->shbtn_prefs[i]));
141         }
142         return op_list->update(&shbtn_items, 0, 0, 1);
143 }
144
145 ShBtnAddButton::ShBtnAddButton(ShBtnEditWindow *sb_window, int x, int y)
146  : BC_GenericButton(x, y, _("Add"))
147 {
148         this->sb_window = sb_window;
149 }
150
151 ShBtnAddButton::~ShBtnAddButton()
152 {
153 }
154
155 int ShBtnAddButton::handle_event()
156 {
157
158         Preferences *preferences = sb_window->shbtn_edit->pwindow->thread->preferences;
159         ShBtnPref *pref = new ShBtnPref(_("new"), "", 0, 0);
160         preferences->shbtn_prefs.append(pref);
161         sb_window->list_update();
162         return sb_window->start_edit(pref);
163 }
164
165 ShBtnDelButton::ShBtnDelButton(ShBtnEditWindow *sb_window, int x, int y)
166  : BC_GenericButton(x, y, _("Del"))
167 {
168         this->sb_window = sb_window;
169 }
170
171 ShBtnDelButton::~ShBtnDelButton()
172 {
173 }
174
175 int ShBtnDelButton::handle_event()
176 {
177         ShBtnPrefItem *sp = (ShBtnPrefItem *)sb_window->op_list->get_selection(0,0);
178         if( !sp ) return 0;
179         Preferences *preferences = sb_window->shbtn_edit->pwindow->thread->preferences;
180         preferences->shbtn_prefs.remove(sp->pref);
181         sb_window->list_update();
182         return 1;
183 }
184
185 ShBtnEditButton::ShBtnEditButton(ShBtnEditWindow *sb_window, int x, int y)
186  : BC_GenericButton(x, y, _("Edit"))
187 {
188         this->sb_window = sb_window;
189 }
190
191 ShBtnEditButton::~ShBtnEditButton()
192 {
193 }
194
195 int ShBtnEditButton::handle_event()
196 {
197         ShBtnPrefItem *sp = (ShBtnPrefItem *)sb_window->op_list->get_selection(0,0);
198         if( !sp ) return 0;
199         return sb_window->start_edit(sp->pref);
200 }
201
202 ShBtnTextDialog::ShBtnTextDialog(ShBtnEditWindow *sb_window)
203  : BC_DialogThread()
204 {
205         this->sb_window = sb_window;
206         this->pref = 0;
207 }
208
209 ShBtnTextDialog::~ShBtnTextDialog()
210 {
211         close_window();
212 }
213
214 ShBtnTextWindow::ShBtnTextWindow(ShBtnEditWindow *sb_window, int x, int y)
215  : BC_Window(_(PROGRAM_NAME ": Commands"), x, y, 640, 160, 640, 150, 0, 0, 1)
216 {
217         this->sb_window = sb_window;
218         warn = sb_window->sb_dialog->pref->warn;
219         run_script = sb_window->sb_dialog->pref->run_script;
220 }
221
222 ShBtnTextWindow::~ShBtnTextWindow()
223 {
224 }
225
226 ShBtnErrWarn::ShBtnErrWarn(ShBtnTextWindow *st_window, int x, int y)
227  : BC_CheckBox(x, y, &st_window->warn, _("Warn on err exit"))
228 {
229         this->st_window = st_window;
230 }
231
232 ShBtnErrWarn::~ShBtnErrWarn()
233 {
234 }
235
236 ShBtnRunScript::ShBtnRunScript(ShBtnTextWindow *st_window, int x, int y)
237  : BC_CheckBox(x, y, &st_window->run_script, _("run /path/script.sh + argvs"))
238 {
239         this->st_window = st_window;
240 }
241
242 ShBtnRunScript::~ShBtnRunScript()
243 {
244 }
245
246 void ShBtnTextWindow::create_objects()
247 {
248         lock_window("ShBtnTextWindow::create_objects");
249         int x = 10, y = 10;
250         int x1 = 160;
251         BC_Title *title = new BC_Title(x, y, _("Label:"));
252         add_subwindow(title);
253         title = new BC_Title(x1, y, _("Commands:"));
254         add_subwindow(title);
255         y += title->get_h() + 8;
256         ShBtnPref *pref = sb_window->sb_dialog->pref;
257         cmd_name = new BC_TextBox(x, y, 140, 1, pref->name);
258         add_subwindow(cmd_name);
259         cmd_text = new BC_ScrollTextBox(this, x1, y, get_w()-x1-20, 4, pref->commands);
260         cmd_text->create_objects();
261         y += cmd_text->get_h() + 16;
262         add_subwindow(st_err_warn = new ShBtnErrWarn(this, x1, y));
263         x1 += st_err_warn->get_w() + 20;
264         add_subwindow(st_run_script = new ShBtnRunScript(this, x1, y));
265         y = get_h() - ShBtnTextOK::calculate_h() - 10;
266         add_subwindow(new ShBtnTextOK(this, x, y));
267         show_window();
268         unlock_window();
269 }
270
271 ShBtnTextOK::ShBtnTextOK(ShBtnTextWindow *st_window, int x, int y)
272  : BC_OKButton(x, y)
273 {
274         this->st_window = st_window;
275 }
276
277 ShBtnTextOK::~ShBtnTextOK()
278 {
279 }
280
281 int ShBtnTextOK::handle_event()
282 {
283         ShBtnPref *pref = st_window->sb_window->sb_dialog->pref;
284         strcpy(pref->name, st_window->cmd_name->get_text());
285         strcpy(pref->commands, st_window->cmd_text->get_text());
286         pref->warn = st_window->warn;
287         pref->run_script = st_window->run_script;
288         return BC_OKButton::handle_event();
289 }
290
291
292 BC_Window *ShBtnTextDialog::new_gui()
293 {
294         BC_DisplayInfo display_info;
295         int x = display_info.get_abs_cursor_x();
296         int y = display_info.get_abs_cursor_y();
297
298         st_window = new ShBtnTextWindow(sb_window, x, y);
299         st_window->create_objects();
300         return st_window;
301 }
302
303 void ShBtnTextDialog::handle_close_event(int result)
304 {
305         if( !result ) {
306                 sb_window->lock_window("ShBtnTextDialog::handle_close_event");
307                 sb_window->list_update();
308                 sb_window->unlock_window();
309         }
310         st_window = 0;
311 }
312
313 int ShBtnTextDialog::start_edit(ShBtnPref *pref)
314 {
315         this->pref = pref;
316         start();
317         return 1;
318 }
319
320 void ShBtnEditWindow::create_objects()
321 {
322         lock_window("ShBtnEditWindow::create_objects");
323         Preferences *preferences = shbtn_edit->pwindow->thread->preferences;
324         for( int i=0; i<preferences->shbtn_prefs.size(); ++i ) {
325                 shbtn_items.append(new ShBtnPrefItem(preferences->shbtn_prefs[i]));
326         }
327         int x = 10, y = 10;
328         add_subwindow(op_list = new ShBtnPrefList(this, x, y));
329         x = 190;
330         add_subwindow(add_button = new ShBtnAddButton(this, x, y));
331         y += add_button->get_h() + 8;
332         add_subwindow(del_button = new ShBtnDelButton(this, x, y));
333         y += del_button->get_h() + 8;
334         add_subwindow(edit_button = new ShBtnEditButton(this, x, y));
335         add_subwindow(new BC_OKButton(this));
336         show_window();
337         unlock_window();
338 }
339
340 int ShBtnEditWindow::start_edit(ShBtnPref *pref)
341 {
342         if( !sb_dialog )
343                 sb_dialog = new ShBtnTextDialog(this);
344         return sb_dialog->start_edit(pref);
345 }
346
347
348 ShBtnPrefItem::ShBtnPrefItem(ShBtnPref *pref)
349  : BC_ListBoxItem(pref->name)
350 {
351         this->pref = pref;
352 }
353
354 ShBtnPrefItem::~ShBtnPrefItem()
355 {
356 }
357
358 ShBtnPrefList::ShBtnPrefList(ShBtnEditWindow *sb_window, int x, int y)
359  : BC_ListBox(x, y, 140, 100, LISTBOX_TEXT, &sb_window->shbtn_items, 0, 0)
360 {
361         this->sb_window = sb_window;
362 }
363
364 ShBtnPrefList::~ShBtnPrefList()
365 {
366 }
367
368 int ShBtnPrefList::handle_event()
369 {
370         return 1;
371 }
372
373 MainShBtnItem::MainShBtnItem(MainShBtns *shbtns, ShBtnPref *pref)
374  : BC_MenuItem(pref->name)
375 {
376         this->shbtns = shbtns;
377         this->pref = pref;
378 }
379
380 int MainShBtnItem::handle_event()
381 {
382         MWindow *mwindow = shbtns->mwindow;
383         if( pref->run_script ) {
384                 AWindowGUI *agui = mwindow->awindow->gui;
385                 agui->lock_window("MainShBtnItem::handle_event");
386                 mwindow->awindow->gui->collect_assets();
387                 pref->execute(*mwindow->session->drag_assets);
388                 agui->unlock_window();
389         }
390         else
391                 pref->execute();
392         return 1;
393 }
394
395 MainShBtns::MainShBtns(MWindow *mwindow, int x, int y)
396  : BC_PopupMenu(x, y, 0, "", -1, mwindow->theme->shbtn_data)
397 {
398         this->mwindow = mwindow;
399         set_tooltip(_("shell cmds"));
400 }
401
402 int MainShBtns::load(Preferences *preferences)
403 {
404         while( total_items() ) del_item(0);
405         for( int i=0; i<preferences->shbtn_prefs.size(); ++i )
406                 add_item(new MainShBtnItem(this, preferences->shbtn_prefs[i]));
407         return 0;
408 }
409
410 int MainShBtns::handle_event()
411 {
412         return 1;
413 }
414