3 * Copyright 2001 the LyX Team
4 * Read the file COPYING
6 * \author Angus Leeming, a.leeming@ic.ac.uk
13 #pragma implementation
17 #include "FormForks.h"
18 #include "ControlForks.h"
19 #include "forms/form_forks.h"
21 #include "helper_funcs.h"
22 #include "xforms_helpers.h"
24 #include "support/lstrings.h"
25 #include FORMS_H_LOCATION
31 typedef FormCB<ControlForks, FormDB<FD_forks> > base_class;
33 FormForks::FormForks(ControlForks & c, Dialogs & d)
34 : base_class(c, d, _("Child processes"))
38 void FormForks::build() {
39 dialog_.reset(build_forks(this));
41 // It appears that the browsers aren't initialised properly.
42 // This fudge fixes tings.
43 fl_add_browser_line(dialog_->browser_children, " ");
44 fl_add_browser_line(dialog_->browser_kill, " ");
45 fl_clear_browser(dialog_->browser_children);
46 fl_clear_browser(dialog_->browser_kill);
48 // Manage the ok, apply, restore and cancel/close buttons
49 bc().setOK(dialog_->button_ok);
50 bc().setApply(dialog_->button_apply);
51 bc().setCancel(dialog_->button_close);
54 // Set up the tooltip mechanism
55 string str = _("All currently running child processes forked by LyX.");
56 tooltips().init(dialog_->browser_children, str);
58 str = _("A list of all child processes to kill.");
59 tooltips().init(dialog_->browser_kill, str);
61 str = _("Add all processes to the list of processes to kill.");
62 tooltips().init(dialog_->button_all, str);
64 str = _("Add the currently selected child process to the list of processes to kill.");
65 tooltips().init(dialog_->button_add, str);
67 str = _("Remove the currently selected item from the list of processes to kill.");
68 tooltips().init(dialog_->button_remove, str);
72 void FormForks::update()
77 string const current_pid_str =
78 getSelectedStringFromBrowser(dialog_->browser_kill);
79 pid_t const current_pid = strToInt(current_pid_str);
81 vector<pid_t> pids = controller().getPIDs();
83 // No child processes.
85 if (fl_get_browser_maxline(dialog_->browser_kill) > 0)
86 fl_clear_browser(dialog_->browser_kill);
87 if (fl_get_browser_maxline(dialog_->browser_children) > 0)
88 fl_clear_browser(dialog_->browser_children);
90 setEnabled(dialog_->browser_children, false);
91 setEnabled(dialog_->browser_kill, false);
92 setEnabled(dialog_->button_all, false);
93 setEnabled(dialog_->button_add, false);
94 setEnabled(dialog_->button_remove, false);
99 // Remove any processes from the kill browser that aren't in the
100 // vector of existing PIDs.
101 for (int i = 1; i <= fl_get_browser_maxline(dialog_->browser_kill);
103 string const pid_str =
104 getStringFromBrowser(dialog_->browser_kill, i);
105 pid_t const pid = strToInt(pid_str);
106 vector<pid_t>::const_iterator it =
107 find(pids.begin(), pids.end(), pid);
108 if (it == pids.end())
109 fl_delete_browser_line(dialog_->browser_kill, i);
112 // Build the children browser from scratch.
113 if (fl_get_browser_maxline(dialog_->browser_children) > 0)
114 fl_clear_browser(dialog_->browser_children);
116 for (vector<pid_t>::const_iterator it = pids.begin();
117 it != pids.end(); ++it) {
118 string const pid_str = tostr(*it);
119 string const command = controller().getCommand(*it);
120 string const line = pid_str + '\t' + command;
122 fl_add_browser_line(dialog_->browser_children, line.c_str());
124 if (*it == current_pid)
125 fl_select_browser_line(dialog_->browser_children, i);
129 setEnabled(dialog_->browser_children, true);
130 setEnabled(dialog_->button_all, true);
131 setEnabled(dialog_->button_add, true);
135 void FormForks::apply()
137 // Get the list of all processes to kill.
138 vector<string> const kill_vec =
139 getVectorFromBrowser(dialog_->browser_kill);
141 if (kill_vec.empty())
144 // Remove these items from the vector of child processes.
145 for (int i = 1; i <= fl_get_browser_maxline(dialog_->browser_children);
147 string const selection =
148 getStringFromBrowser(dialog_->browser_children, i);
150 split(selection, pid_str, '\t');
152 vector<string>::const_iterator it =
153 find(kill_vec.begin(), kill_vec.end(), pid_str);
155 if (it != kill_vec.end())
156 fl_delete_browser_line(dialog_->browser_children, i);
159 // Clear the kill browser and deactivate appropriately.
160 fl_clear_browser(dialog_->browser_kill);
161 setEnabled(dialog_->browser_kill, false);
162 setEnabled(dialog_->button_remove, false);
164 // Pass these pids to the controller for destruction.
165 for (vector<string>::const_iterator it = kill_vec.begin();
166 it != kill_vec.end(); ++it) {
167 pid_t const pid = strToInt(*it);
168 controller().kill(pid);
174 ButtonPolicy::SMInput FormForks::input(FL_OBJECT * ob, long)
176 ButtonPolicy::SMInput activate = ButtonPolicy::SMI_NOOP;
178 if (ob == dialog_->browser_children) {
179 activate = input_browser_children();
181 } else if (ob == dialog_->browser_kill) {
182 activate = input_browser_kill();
184 } else if (ob == dialog_->button_all) {
185 activate = input_button_all();
187 } else if (ob == dialog_->button_add) {
188 activate = input_button_add();
190 } else if (ob == dialog_->button_remove) {
191 activate = input_button_remove();
197 ButtonPolicy::SMInput FormForks::input_browser_children()
199 // Selected an item in the browser containing a list of all child
202 // 1. Highlight this item in the browser of processes to kill
203 // if it is already there.
205 // 2. If it is there, enable the remove button so that it can
206 // be removed from this list, if so desired.
208 // 3. If it isn't there, activate the add button so that it can
209 // be added to this list if so desired.
211 string const selection =
212 getSelectedStringFromBrowser(dialog_->browser_children);
214 split(selection, pid_str, '\t');
216 vector<string> const kill_vec =
217 getVectorFromBrowser(dialog_->browser_kill);
219 vector<string>::const_iterator it =
220 find(kill_vec.begin(), kill_vec.end(), pid_str);
222 fl_deselect_browser(dialog_->browser_kill);
223 if (it != kill_vec.end()) {
224 int const n = int(it - kill_vec.begin());
225 fl_select_browser_line(dialog_->browser_kill, n+1);
226 fl_set_browser_topline(dialog_->browser_kill, n+1);
229 setEnabled(dialog_->button_remove, it != kill_vec.end());
230 setEnabled(dialog_->button_add, it == kill_vec.end());
232 return ButtonPolicy::SMI_NOOP;
240 FindPID(string const & pid) : pid_(pid) {}
241 bool operator()(string const & line)
247 split(line, pid_str, '\t');
248 return pid_str == pid_;
258 ButtonPolicy::SMInput FormForks::input_browser_kill()
260 // Selected an item in the browser containing a list of processes
263 // 1. Highlight this item in the browser of all child processes.
265 // 2. Enable the remove button so that it can removed from this list,
268 // 3. Disable the add button.
270 string const pid_str =
271 getSelectedStringFromBrowser(dialog_->browser_kill);
273 // Find this string in the list of all child processes
274 vector<string> const child_vec =
275 getVectorFromBrowser(dialog_->browser_children);
277 vector<string>::const_iterator it =
278 find_if(child_vec.begin(), child_vec.end(), FindPID(pid_str));
280 fl_deselect_browser(dialog_->browser_children);
281 if (it != child_vec.end()) {
282 int const n = int(it - child_vec.begin());
283 fl_select_browser_line(dialog_->browser_children, n+1);
284 fl_set_browser_topline(dialog_->browser_children, n+1);
287 setEnabled(dialog_->button_remove, true);
288 setEnabled(dialog_->button_add, false);
290 return ButtonPolicy::SMI_NOOP;
296 vector<string> const getPIDvector(FL_OBJECT * ob)
298 vector<string> vec = getVectorFromBrowser(ob);
302 for (vector<string>::iterator it = vec.begin(); it != vec.end(); ++it) {
304 split(*it, pid_str, '\t');
314 ButtonPolicy::SMInput FormForks::input_button_all()
316 // Pressed the "All" button.
318 // 1. Check that the browser of processes to kill doesn't already
319 // contain the entire list.
321 // 2. If it doesn't, copy the PIDs of all child processes into the
322 // browser of processes to kill.
324 // 3. Deactivate the "children" browser and the "add" and "all" buttons
326 // 4. Activate the "kill" browser and the "remove" button"
328 ButtonPolicy::SMInput activate = ButtonPolicy::SMI_NOOP;
330 vector<string> const pid_vec = getPIDvector(dialog_->browser_children);
332 // to resolve a warning about comparison between signed and unsigned.
333 int const pid_vec_size = int(pid_vec.size());
335 if (fl_get_browser_maxline(dialog_->browser_kill) != pid_vec_size) {
336 activate = ButtonPolicy::SMI_VALID;
338 fl_clear_browser(dialog_->browser_kill);
339 for (vector<string>::const_iterator it = pid_vec.begin();
340 it != pid_vec.end(); ++it) {
341 fl_add_browser_line(dialog_->browser_kill, it->c_str());
344 if (fl_get_browser_maxline(dialog_->browser_kill) >= 1)
345 fl_set_browser_topline(dialog_->browser_kill, 1);
348 setEnabled(dialog_->browser_children, false);
349 setEnabled(dialog_->button_add, false);
350 setEnabled(dialog_->button_all, false);
351 setEnabled(dialog_->browser_kill, true);
352 setEnabled(dialog_->button_remove, true);
358 ButtonPolicy::SMInput FormForks::input_button_add()
360 // Pressed the "Add" button.
362 // 1. Copy the PID of the selected item in the browser of all child
363 // processes over into the browser of processes to kill.
365 // 2. Activate the "kill" browser and the "remove" button.
367 // 3. Deactivate the "add" button.
369 string const selection =
370 getSelectedStringFromBrowser(dialog_->browser_children);
372 split(selection, pid_str, '\t');
374 vector<string> const kill_vec =
375 getVectorFromBrowser(dialog_->browser_kill);
377 vector<string>::const_iterator it =
378 find(kill_vec.begin(), kill_vec.end(), pid_str);
380 if (it == kill_vec.end()) {
381 fl_add_browser_line(dialog_->browser_kill, pid_str.c_str());
382 int const n = fl_get_browser_maxline(dialog_->browser_kill);
383 fl_select_browser_line(dialog_->browser_kill, n);
386 setEnabled(dialog_->browser_kill, true);
387 setEnabled(dialog_->button_remove, true);
388 setEnabled(dialog_->button_add, false);
390 return ButtonPolicy::SMI_VALID;
394 ButtonPolicy::SMInput FormForks::input_button_remove()
396 // Pressed the "Remove" button.
398 // 1. Remove the selected item in the browser of processes to kill.
400 // 2. Activate the "add" button and "all" buttons.
402 // 3. Deactivate the "remove" button.
404 int const sel = fl_get_browser(dialog_->browser_kill);
405 fl_delete_browser_line(dialog_->browser_kill, sel);
407 setEnabled(dialog_->button_add, true);
408 setEnabled(dialog_->button_all, true);
409 setEnabled(dialog_->button_remove, false);
411 return ButtonPolicy::SMI_VALID;