3 * Copyright (C) 2016-2020 William Morrow
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published
7 * by the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 #include "bcwindowbase.h"
22 #include "bcdisplayinfo.h"
25 #include "awindowgui.h"
27 #include "indexable.h"
29 #include "mainerror.h"
30 #include "mainsession.h"
32 #include "shbtnprefs.h"
33 #include "preferences.h"
34 #include "preferencesthread.h"
39 ShBtnRun::ShBtnRun(const char *nm, const char *cmds, int warn)
42 argv.set_array_delete();
43 strncpy(name, nm, sizeof(name)-1);
44 name[sizeof(name)-1] = 0;
45 strncpy(commands, cmds, sizeof(commands)-1);
46 commands[sizeof(commands)-1] = 0;
51 argv.remove_all_objects();
54 void ShBtnRun::add_arg(const char *v)
56 argv.append(cstrdup(v));
69 execvp(argv[0], &argv[0]);
72 // warn <0:always, =0:never, >0:on err
74 int stat; waitpid(pid, &stat, 0);
76 if( warn > 0 ) return;
77 sprintf(msg, "%s: completed", name);
80 sprintf(msg, "%s: error exit status %d", name, stat);
81 MainError::show_error(msg);
84 ShBtnPref::ShBtnPref(const char *nm, const char *cmds, int warn, int run_script)
86 strncpy(name, nm, sizeof(name));
87 strncpy(commands, cmds, sizeof(commands));
89 this->run_script = run_script;
92 ShBtnPref::~ShBtnPref()
96 void ShBtnPref::execute(ArrayList<Indexable*> &args)
98 // thread async+autodelete, no explicit delete
99 ShBtnRun *job = new ShBtnRun(name, commands, warn);
100 job->add_arg("/bin/bash");
101 job->add_arg(commands);
103 for( int i=0; i<n; ++i ) {
104 Indexable *idxbl = args[i];
105 if( !idxbl->is_asset ) continue;
106 job->add_arg(idxbl->path);
111 void ShBtnPref::execute()
113 ShBtnRun *job = new ShBtnRun(name, commands, warn);
114 job->add_arg("/bin/bash");
116 job->add_arg(commands);
120 ShBtnEditDialog::ShBtnEditDialog(PreferencesWindow *pwindow)
123 this->pwindow = pwindow;
126 ShBtnEditDialog::~ShBtnEditDialog()
131 BC_Window* ShBtnEditDialog::new_gui()
133 BC_DisplayInfo display_info;
134 int x = display_info.get_abs_cursor_x();
135 int y = display_info.get_abs_cursor_y();
137 sb_window = new ShBtnEditWindow(this, x, y);
138 sb_window->create_objects();
142 void ShBtnEditDialog::handle_close_event(int result)
148 ShBtnEditWindow::ShBtnEditWindow(ShBtnEditDialog *shbtn_edit, int x, int y)
149 : BC_Window(_(PROGRAM_NAME ": Shell"), x, y,
150 xS(300), yS(200), xS(300), yS(200), 0, 0, 1)
152 this->shbtn_edit = shbtn_edit;
154 // *** CONTEXT_HELP ***
155 context_help_set_keyword("Menu Bar Shell Commands");
158 ShBtnEditWindow::~ShBtnEditWindow()
163 int ShBtnEditWindow::list_update()
165 shbtn_items.remove_all_objects();
166 Preferences *preferences = shbtn_edit->pwindow->thread->preferences;
167 for( int i=0; i<preferences->shbtn_prefs.size(); ++i ) {
168 shbtn_items.append(new ShBtnPrefItem(preferences->shbtn_prefs[i]));
170 return op_list->update(&shbtn_items, 0, 0, 1);
173 ShBtnAddButton::ShBtnAddButton(ShBtnEditWindow *sb_window, int x, int y)
174 : BC_GenericButton(x, y, _("Add"))
176 this->sb_window = sb_window;
179 ShBtnAddButton::~ShBtnAddButton()
183 int ShBtnAddButton::handle_event()
186 Preferences *preferences = sb_window->shbtn_edit->pwindow->thread->preferences;
187 ShBtnPref *pref = new ShBtnPref(_("new"), "", 0, 0);
188 preferences->shbtn_prefs.append(pref);
189 sb_window->list_update();
190 return sb_window->start_edit(pref);
193 ShBtnDelButton::ShBtnDelButton(ShBtnEditWindow *sb_window, int x, int y)
194 : BC_GenericButton(x, y, _("Del"))
196 this->sb_window = sb_window;
199 ShBtnDelButton::~ShBtnDelButton()
203 int ShBtnDelButton::handle_event()
205 ShBtnPrefItem *sp = (ShBtnPrefItem *)sb_window->op_list->get_selection(0,0);
207 Preferences *preferences = sb_window->shbtn_edit->pwindow->thread->preferences;
208 preferences->shbtn_prefs.remove(sp->pref);
209 sb_window->list_update();
213 ShBtnEditButton::ShBtnEditButton(ShBtnEditWindow *sb_window, int x, int y)
214 : BC_GenericButton(x, y, _("Edit"))
216 this->sb_window = sb_window;
219 ShBtnEditButton::~ShBtnEditButton()
223 int ShBtnEditButton::handle_event()
225 ShBtnPrefItem *sp = (ShBtnPrefItem *)sb_window->op_list->get_selection(0,0);
227 return sb_window->start_edit(sp->pref);
230 ShBtnTextDialog::ShBtnTextDialog(ShBtnEditWindow *sb_window)
233 this->sb_window = sb_window;
237 ShBtnTextDialog::~ShBtnTextDialog()
242 ShBtnTextWindow::ShBtnTextWindow(ShBtnEditWindow *sb_window, int x, int y)
243 : BC_Window(_(PROGRAM_NAME ": Commands"), x, y,
244 xS(640), yS(160), xS(640), yS(150), 0, 0, 1)
246 this->sb_window = sb_window;
247 warn = sb_window->sb_dialog->pref->warn;
248 run_script = sb_window->sb_dialog->pref->run_script;
249 // *** CONTEXT_HELP ***
250 context_help_set_keyword("Menu Bar Shell Commands");
253 ShBtnTextWindow::~ShBtnTextWindow()
258 ShBtnErrWarnItem::ShBtnErrWarnItem(ShBtnErrWarn *popup,
259 const char *text, int warn)
266 int ShBtnErrWarnItem::handle_event()
268 popup->set_text(get_text());
269 popup->st_window->warn = warn;
273 ShBtnErrWarn::ShBtnErrWarn(ShBtnTextWindow *st_window, int x, int y)
274 : BC_PopupMenu(x, y, xS(120), st_window->warn < 0 ? _("Always"):
275 !st_window->warn ? _("Never") : _("On Error"))
277 this->st_window = st_window;
279 ShBtnErrWarn::~ShBtnErrWarn()
282 int ShBtnErrWarn::handle_event()
287 void ShBtnErrWarn::create_objects()
289 add_item(new ShBtnErrWarnItem(this,_("Always"), -1));
290 add_item(new ShBtnErrWarnItem(this,_("Never"), 0));
291 add_item(new ShBtnErrWarnItem(this,_("On Error"), 1));
295 ShBtnRunScript::ShBtnRunScript(ShBtnTextWindow *st_window, int x, int y)
296 : BC_CheckBox(x, y, &st_window->run_script, _("run /path/script.sh + argvs"))
298 this->st_window = st_window;
301 ShBtnRunScript::~ShBtnRunScript()
305 void ShBtnTextWindow::create_objects()
307 lock_window("ShBtnTextWindow::create_objects");
308 int x = xS(10), y = yS(10);
310 BC_Title *title = new BC_Title(x, y, _("Label:"));
311 add_subwindow(title);
312 title = new BC_Title(x1, y, _("Commands:"));
313 add_subwindow(title);
314 y += title->get_h() + yS(8);
315 ShBtnPref *pref = sb_window->sb_dialog->pref;
316 cmd_name = new BC_TextBox(x, y, xS(140), 1, pref->name);
317 add_subwindow(cmd_name);
318 cmd_text = new BC_ScrollTextBox(this, x1, y, get_w()-x1-xS(20), 4, pref->commands);
319 cmd_text->create_objects();
320 y += cmd_text->get_h() + yS(16);
321 add_subwindow(title = new BC_Title(x1,y, _("OnExit Notify:")));
322 x1 += title->get_w() + xS(10);
323 add_subwindow(st_err_warn = new ShBtnErrWarn(this, x1, y));
324 st_err_warn->create_objects();
325 x1 += st_err_warn->get_w() + xS(20);
326 add_subwindow(st_run_script = new ShBtnRunScript(this, x1, y));
327 y = get_h() - ShBtnTextOK::calculate_h() - yS(10);
328 add_subwindow(new ShBtnTextOK(this, x, y));
333 ShBtnTextOK::ShBtnTextOK(ShBtnTextWindow *st_window, int x, int y)
336 this->st_window = st_window;
339 ShBtnTextOK::~ShBtnTextOK()
343 int ShBtnTextOK::handle_event()
345 ShBtnPref *pref = st_window->sb_window->sb_dialog->pref;
346 strcpy(pref->name, st_window->cmd_name->get_text());
347 strcpy(pref->commands, st_window->cmd_text->get_text());
348 pref->warn = st_window->warn;
349 pref->run_script = st_window->run_script;
350 return BC_OKButton::handle_event();
354 BC_Window *ShBtnTextDialog::new_gui()
356 BC_DisplayInfo display_info;
357 int x = display_info.get_abs_cursor_x();
358 int y = display_info.get_abs_cursor_y();
360 st_window = new ShBtnTextWindow(sb_window, x, y);
361 st_window->create_objects();
365 void ShBtnTextDialog::handle_close_event(int result)
368 sb_window->lock_window("ShBtnTextDialog::handle_close_event");
369 sb_window->list_update();
370 sb_window->unlock_window();
375 int ShBtnTextDialog::start_edit(ShBtnPref *pref)
382 void ShBtnEditWindow::create_objects()
384 lock_window("ShBtnEditWindow::create_objects");
385 Preferences *preferences = shbtn_edit->pwindow->thread->preferences;
386 for( int i=0; i<preferences->shbtn_prefs.size(); ++i ) {
387 shbtn_items.append(new ShBtnPrefItem(preferences->shbtn_prefs[i]));
389 int x = xS(10), y = yS(10);
390 add_subwindow(op_list = new ShBtnPrefList(this, x, y));
392 add_subwindow(add_button = new ShBtnAddButton(this, x, y));
393 y += add_button->get_h() + yS(8);
394 add_subwindow(del_button = new ShBtnDelButton(this, x, y));
395 y += del_button->get_h() + yS(8);
396 add_subwindow(edit_button = new ShBtnEditButton(this, x, y));
397 add_subwindow(new BC_OKButton(this));
402 int ShBtnEditWindow::start_edit(ShBtnPref *pref)
405 sb_dialog = new ShBtnTextDialog(this);
406 return sb_dialog->start_edit(pref);
410 ShBtnPrefItem::ShBtnPrefItem(ShBtnPref *pref)
411 : BC_ListBoxItem(pref->name)
416 ShBtnPrefItem::~ShBtnPrefItem()
420 ShBtnPrefList::ShBtnPrefList(ShBtnEditWindow *sb_window, int x, int y)
421 : BC_ListBox(x, y, xS(140), yS(100), LISTBOX_TEXT, &sb_window->shbtn_items, 0, 0)
423 this->sb_window = sb_window;
426 ShBtnPrefList::~ShBtnPrefList()
430 int ShBtnPrefList::handle_event()
435 MainShBtnItem::MainShBtnItem(MainShBtns *shbtns, ShBtnPref *pref)
436 : BC_MenuItem(pref->name)
438 this->shbtns = shbtns;
442 int MainShBtnItem::handle_event()
444 MWindow *mwindow = shbtns->mwindow;
445 if( pref->run_script ) {
446 AWindowGUI *agui = mwindow->awindow->gui;
447 agui->lock_window("MainShBtnItem::handle_event");
448 mwindow->awindow->gui->collect_assets();
449 pref->execute(*mwindow->session->drag_assets);
450 agui->unlock_window();
457 MainShBtns::MainShBtns(MWindow *mwindow, int x, int y)
458 : BC_PopupMenu(x, y, 0, "", -1, mwindow->theme->shbtn_data)
460 this->mwindow = mwindow;
461 set_tooltip(_("shell cmds"));
462 // *** CONTEXT_HELP ***
463 context_help_set_keyword("Menu Bar Shell Commands");
466 int MainShBtns::load(Preferences *preferences)
468 while( total_items() ) del_item(0);
469 for( int i=0; i<preferences->shbtn_prefs.size(); ++i )
470 add_item(new MainShBtnItem(this, preferences->shbtn_prefs[i]));
474 int MainShBtns::handle_event()