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 "form_forks.h"
21 #include "helper_funcs.h"
22 #include "xforms_helpers.h"
24 #include "support/lstrings.h"
30 typedef FormCB<ControlForks, FormDB<FD_form_forks> > base_class;
32 FormForks::FormForks(ControlForks & c)
33 : base_class(c, _("Child processes"))
37 void FormForks::build() {
38 dialog_.reset(build_forks());
40 // It appears that the browsers aren't initialised properly.
41 // This fudge fixes tings.
42 fl_add_browser_line(dialog_->browser_children, " ");
43 fl_add_browser_line(dialog_->browser_kill, " ");
44 fl_clear_browser(dialog_->browser_children);
45 fl_clear_browser(dialog_->browser_kill);
47 // Manage the ok, apply, restore and cancel/close buttons
48 bc().setOK(dialog_->button_ok);
49 bc().setApply(dialog_->button_apply);
50 bc().setCancel(dialog_->button_close);
53 // Set up the tooltip mechanism
54 string str = _("All currently running child processes forked by LyX.");
55 tooltips().init(dialog_->browser_children, str);
57 str = _("A list of all child processes to kill.");
58 tooltips().init(dialog_->browser_kill, str);
60 str = _("Add all processes to the list of processes to kill.");
61 tooltips().init(dialog_->button_all, str);
63 str = _("Add the currently selected child process to the list of processes to kill.");
64 tooltips().init(dialog_->button_add, str);
66 str = _("Remove the currently selected item from the list of processes to kill.");
67 tooltips().init(dialog_->button_remove, str);
71 void FormForks::update()
76 string const current_pid_str =
77 getSelectedStringFromBrowser(dialog_->browser_kill);
78 pid_t const current_pid = strToInt(current_pid_str);
80 vector<pid_t> pids = controller().getPIDs();
82 // No child processes.
84 if (fl_get_browser_maxline(dialog_->browser_kill) > 0)
85 fl_clear_browser(dialog_->browser_kill);
86 if (fl_get_browser_maxline(dialog_->browser_children) > 0)
87 fl_clear_browser(dialog_->browser_children);
89 setEnabled(dialog_->browser_children, false);
90 setEnabled(dialog_->browser_kill, false);
91 setEnabled(dialog_->button_all, false);
92 setEnabled(dialog_->button_add, false);
93 setEnabled(dialog_->button_remove, false);
98 // Remove any processes from the kill browser that aren't in the
99 // vector of existing PIDs.
100 for (int i = 1; i <= fl_get_browser_maxline(dialog_->browser_kill);
102 string const pid_str =
103 getStringFromBrowser(dialog_->browser_kill, i);
104 pid_t const pid = strToInt(pid_str);
105 vector<pid_t>::const_iterator it =
106 find(pids.begin(), pids.end(), pid);
107 if (it == pids.end())
108 fl_delete_browser_line(dialog_->browser_kill, i);
111 // Build the children browser from scratch.
112 if (fl_get_browser_maxline(dialog_->browser_children) > 0)
113 fl_clear_browser(dialog_->browser_children);
115 for (vector<pid_t>::const_iterator it = pids.begin();
116 it != pids.end(); ++it) {
117 string const pid_str = tostr(*it);
118 string const command = controller().getCommand(*it);
119 string const line = pid_str + '\t' + command;
121 fl_add_browser_line(dialog_->browser_children, line.c_str());
123 if (*it == current_pid)
124 fl_select_browser_line(dialog_->browser_children, i);
128 setEnabled(dialog_->browser_children, true);
129 setEnabled(dialog_->button_all, true);
130 setEnabled(dialog_->button_add, true);
134 void FormForks::apply()
136 // Get the list of all processes to kill.
137 vector<string> const kill_vec =
138 getVectorFromBrowser(dialog_->browser_kill);
140 if (kill_vec.empty())
143 // Remove these items from the vector of child processes.
144 for (int i = 1; i <= fl_get_browser_maxline(dialog_->browser_children);
146 string const selection =
147 getStringFromBrowser(dialog_->browser_children, i);
149 split(selection, pid_str, '\t');
151 vector<string>::const_iterator it =
152 find(kill_vec.begin(), kill_vec.end(), pid_str);
154 if (it != kill_vec.end())
155 fl_delete_browser_line(dialog_->browser_children, i);
158 // Clear the kill browser and deactivate appropriately.
159 fl_clear_browser(dialog_->browser_kill);
160 setEnabled(dialog_->browser_kill, false);
161 setEnabled(dialog_->button_remove, false);
163 // Pass these pids to the controller for destruction.
164 for (vector<string>::const_iterator it = kill_vec.begin();
165 it != kill_vec.end(); ++it) {
166 pid_t const pid = strToInt(*it);
167 controller().kill(pid);
173 ButtonPolicy::SMInput FormForks::input(FL_OBJECT * ob, long)
175 ButtonPolicy::SMInput activate = ButtonPolicy::SMI_NOOP;
177 if (ob == dialog_->browser_children) {
178 activate = input_browser_children();
180 } else if (ob == dialog_->browser_kill) {
181 activate = input_browser_kill();
183 } else if (ob == dialog_->button_all) {
184 activate = input_button_all();
186 } else if (ob == dialog_->button_add) {
187 activate = input_button_add();
189 } else if (ob == dialog_->button_remove) {
190 activate = input_button_remove();
196 ButtonPolicy::SMInput FormForks::input_browser_children()
198 // Selected an item in the browser containing a list of all child
201 // 1. Highlight this item in the browser of processes to kill
202 // if it is already there.
204 // 2. If it is there, enable the remove button so that it can
205 // be removed from this list, if so desired.
207 // 3. If it isn't there, activate the add button so that it can
208 // be added to this list if so desired.
210 string const selection =
211 getSelectedStringFromBrowser(dialog_->browser_children);
213 split(selection, pid_str, '\t');
215 vector<string> const kill_vec =
216 getVectorFromBrowser(dialog_->browser_kill);
218 vector<string>::const_iterator it =
219 find(kill_vec.begin(), kill_vec.end(), pid_str);
221 fl_deselect_browser(dialog_->browser_kill);
222 if (it != kill_vec.end()) {
223 int const n = int(it - kill_vec.begin());
224 fl_select_browser_line(dialog_->browser_kill, n+1);
225 fl_set_browser_topline(dialog_->browser_kill, n+1);
228 setEnabled(dialog_->button_remove, it != kill_vec.end());
229 setEnabled(dialog_->button_add, it == kill_vec.end());
231 return ButtonPolicy::SMI_NOOP;
239 FindPID(string const & pid) : pid_(pid) {}
240 bool operator()(string const & line)
246 split(line, pid_str, '\t');
247 return pid_str == pid_;
257 ButtonPolicy::SMInput FormForks::input_browser_kill()
259 // Selected an item in the browser containing a list of processes
262 // 1. Highlight this item in the browser of all child processes.
264 // 2. Enable the remove button so that it can removed from this list,
267 // 3. Disable the add button.
269 string const pid_str =
270 getSelectedStringFromBrowser(dialog_->browser_kill);
272 // Find this string in the list of all child processes
273 vector<string> const child_vec =
274 getVectorFromBrowser(dialog_->browser_children);
276 vector<string>::const_iterator it =
277 find_if(child_vec.begin(), child_vec.end(), FindPID(pid_str));
279 fl_deselect_browser(dialog_->browser_children);
280 if (it != child_vec.end()) {
281 int const n = int(it - child_vec.begin());
282 fl_select_browser_line(dialog_->browser_children, n+1);
283 fl_set_browser_topline(dialog_->browser_children, n+1);
286 setEnabled(dialog_->button_remove, true);
287 setEnabled(dialog_->button_add, false);
289 return ButtonPolicy::SMI_NOOP;
295 vector<string> const getPIDvector(FL_OBJECT * ob)
297 vector<string> vec = getVectorFromBrowser(ob);
301 for (vector<string>::iterator it = vec.begin(); it != vec.end(); ++it) {
303 split(*it, pid_str, '\t');
313 ButtonPolicy::SMInput FormForks::input_button_all()
315 // Pressed the "All" button.
317 // 1. Check that the browser of processes to kill doesn't already
318 // contain the entire list.
320 // 2. If it doesn't, copy the PIDs of all child processes into the
321 // browser of processes to kill.
323 // 3. Deactivate the "children" browser and the "add" and "all" buttons
325 // 4. Activate the "kill" browser and the "remove" button"
327 ButtonPolicy::SMInput activate = ButtonPolicy::SMI_NOOP;
329 vector<string> const pid_vec = getPIDvector(dialog_->browser_children);
331 // to resolve a warning about comparison between signed and unsigned.
332 int const pid_vec_size = int(pid_vec.size());
334 if (fl_get_browser_maxline(dialog_->browser_kill) != pid_vec_size) {
335 activate = ButtonPolicy::SMI_VALID;
337 fl_clear_browser(dialog_->browser_kill);
338 for (vector<string>::const_iterator it = pid_vec.begin();
339 it != pid_vec.end(); ++it) {
340 fl_add_browser_line(dialog_->browser_kill, it->c_str());
343 if (fl_get_browser_maxline(dialog_->browser_kill) >= 1)
344 fl_set_browser_topline(dialog_->browser_kill, 1);
347 setEnabled(dialog_->browser_children, false);
348 setEnabled(dialog_->button_add, false);
349 setEnabled(dialog_->button_all, false);
350 setEnabled(dialog_->browser_kill, true);
351 setEnabled(dialog_->button_remove, true);
357 ButtonPolicy::SMInput FormForks::input_button_add()
359 // Pressed the "Add" button.
361 // 1. Copy the PID of the selected item in the browser of all child
362 // processes over into the browser of processes to kill.
364 // 2. Activate the "kill" browser and the "remove" button.
366 // 3. Deactivate the "add" button.
368 string const selection =
369 getSelectedStringFromBrowser(dialog_->browser_children);
371 split(selection, pid_str, '\t');
373 vector<string> const kill_vec =
374 getVectorFromBrowser(dialog_->browser_kill);
376 vector<string>::const_iterator it =
377 find(kill_vec.begin(), kill_vec.end(), pid_str);
379 if (it == kill_vec.end()) {
380 fl_add_browser_line(dialog_->browser_kill, pid_str.c_str());
381 int const n = fl_get_browser_maxline(dialog_->browser_kill);
382 fl_select_browser_line(dialog_->browser_kill, n);
385 setEnabled(dialog_->browser_kill, true);
386 setEnabled(dialog_->button_remove, true);
387 setEnabled(dialog_->button_add, false);
389 return ButtonPolicy::SMI_VALID;
393 ButtonPolicy::SMInput FormForks::input_button_remove()
395 // Pressed the "Remove" button.
397 // 1. Remove the selected item in the browser of processes to kill.
399 // 2. Activate the "add" button and "all" buttons.
401 // 3. Deactivate the "remove" button.
403 int const sel = fl_get_browser(dialog_->browser_kill);
404 fl_delete_browser_line(dialog_->browser_kill, sel);
406 setEnabled(dialog_->button_add, true);
407 setEnabled(dialog_->button_all, true);
408 setEnabled(dialog_->button_remove, false);
410 return ButtonPolicy::SMI_VALID;