]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormForks.C
Really dull and boring header shit
[lyx.git] / src / frontends / xforms / FormForks.C
1 /**
2  * \file FormForks.C
3  * Read the file COPYING
4  *
5  * \author Angus Leeming 
6  *
7  * Full author contact details are available in file CREDITS
8  * \date 2001-10-22
9  */
10
11 #include <config.h>
12
13 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #include "xformsBC.h"
18 #include "FormForks.h"
19 #include "ControlForks.h"
20 #include "forms/form_forks.h"
21 #include "Tooltips.h"
22 #include "helper_funcs.h"
23 #include "xforms_helpers.h"
24 #include "gettext.h"
25 #include "support/lstrings.h"
26 #include FORMS_H_LOCATION
27
28 using std::vector;
29 using std::find;
30 using std::find_if;
31
32 typedef FormCB<ControlForks, FormDB<FD_forks> > base_class;
33
34 FormForks::FormForks()
35         : base_class(_("Child processes"))
36 {}
37
38
39 void FormForks::build() {
40         dialog_.reset(build_forks(this));
41
42         // It appears that the browsers aren't initialised properly.
43         // This fudge fixes tings.
44         fl_add_browser_line(dialog_->browser_children, " ");
45         fl_add_browser_line(dialog_->browser_kill, " ");
46         fl_clear_browser(dialog_->browser_children);
47         fl_clear_browser(dialog_->browser_kill);
48
49         // Manage the ok, apply, restore and cancel/close buttons
50         bc().setOK(dialog_->button_ok);
51         bc().setApply(dialog_->button_apply);
52         bc().setCancel(dialog_->button_close);
53         bc().invalid();
54
55         // Set up the tooltip mechanism
56         string str = _("All currently running child processes forked by LyX.");
57         tooltips().init(dialog_->browser_children, str);
58
59         str = _("A list of all child processes to kill.");
60         tooltips().init(dialog_->browser_kill, str);
61
62         str = _("Add all processes to the list of processes to kill.");
63         tooltips().init(dialog_->button_all, str);
64
65         str = _("Add the currently selected child process to the list of processes to kill.");
66         tooltips().init(dialog_->button_add, str);
67
68         str = _("Remove the currently selected item from the list of processes to kill.");
69         tooltips().init(dialog_->button_remove, str);
70 }
71
72
73 void FormForks::update()
74 {
75         if (!form())
76                 return;
77
78         string const current_pid_str =
79                 getString(dialog_->browser_kill);
80         pid_t const current_pid = strToInt(current_pid_str);
81
82         vector<pid_t> pids = controller().getPIDs();
83
84         // No child processes.
85         if (pids.empty()) {
86                 if (fl_get_browser_maxline(dialog_->browser_kill) > 0)
87                         fl_clear_browser(dialog_->browser_kill);
88                 if (fl_get_browser_maxline(dialog_->browser_children) > 0)
89                         fl_clear_browser(dialog_->browser_children);
90
91                 setEnabled(dialog_->browser_children, false);
92                 setEnabled(dialog_->browser_kill,     false);
93                 setEnabled(dialog_->button_all,       false);
94                 setEnabled(dialog_->button_add,       false);
95                 setEnabled(dialog_->button_remove,    false);
96
97                 return;
98         }
99
100         // Remove any processes from the kill browser that aren't in the
101         // vector of existing PIDs.
102         for (int i = 1; i <= fl_get_browser_maxline(dialog_->browser_kill);
103              ++i) {
104                 string const pid_str =
105                         getString(dialog_->browser_kill, i);
106                 pid_t const pid = strToInt(pid_str);
107                 vector<pid_t>::const_iterator it =
108                         find(pids.begin(), pids.end(), pid);
109                 if (it == pids.end())
110                         fl_delete_browser_line(dialog_->browser_kill, i);
111         }
112
113         // Build the children browser from scratch.
114         if (fl_get_browser_maxline(dialog_->browser_children) > 0)
115                 fl_clear_browser(dialog_->browser_children);
116         int i = 1;
117         for (vector<pid_t>::const_iterator it = pids.begin();
118              it != pids.end(); ++it) {
119                 string const pid_str = tostr(*it);
120                 string const command = controller().getCommand(*it);
121                 string const line = pid_str + '\t' + command;
122
123                 fl_add_browser_line(dialog_->browser_children, line.c_str());
124
125                 if (*it == current_pid)
126                         fl_select_browser_line(dialog_->browser_children, i);
127                 ++i;
128         }
129
130         setEnabled(dialog_->browser_children, true);
131         setEnabled(dialog_->button_all,       true);
132         setEnabled(dialog_->button_add,       true);
133 }
134
135
136 void FormForks::apply()
137 {
138         // Get the list of all processes to kill.
139         vector<string> const kill_vec =
140                 getVector(dialog_->browser_kill);
141
142         if (kill_vec.empty())
143                 return;
144
145         // Remove these items from the vector of child processes.
146         for (int i = 1; i <= fl_get_browser_maxline(dialog_->browser_children);
147              ++i) {
148                 string const selection =
149                         getString(dialog_->browser_children, i);
150                 string pid_str;
151                 split(selection, pid_str, '\t');
152
153                 vector<string>::const_iterator it =
154                         find(kill_vec.begin(), kill_vec.end(), pid_str);
155
156                 if (it != kill_vec.end())
157                         fl_delete_browser_line(dialog_->browser_children, i);
158         }
159
160         // Clear the kill browser and deactivate appropriately.
161         fl_clear_browser(dialog_->browser_kill);
162         setEnabled(dialog_->browser_kill,  false);
163         setEnabled(dialog_->button_remove, false);
164
165         // Pass these pids to the controller for destruction.
166         for (vector<string>::const_iterator it = kill_vec.begin();
167              it != kill_vec.end(); ++it) {
168                 pid_t const pid = strToInt(*it);
169                 controller().kill(pid);
170         }
171
172 }
173
174
175 ButtonPolicy::SMInput FormForks::input(FL_OBJECT * ob, long)
176 {
177         ButtonPolicy::SMInput activate = ButtonPolicy::SMI_NOOP;
178
179         if (ob == dialog_->browser_children) {
180                 activate = input_browser_children();
181
182         } else if (ob == dialog_->browser_kill) {
183                 activate = input_browser_kill();
184
185         } else if (ob == dialog_->button_all) {
186                 activate = input_button_all();
187
188         } else if (ob == dialog_->button_add) {
189                 activate = input_button_add();
190
191         } else if (ob == dialog_->button_remove) {
192                 activate = input_button_remove();
193         }
194
195         return activate;
196 }
197
198 ButtonPolicy::SMInput FormForks::input_browser_children()
199 {
200         // Selected an item in the browser containing a list of all child
201         // processes.
202
203         // 1. Highlight this item in the browser of processes to kill
204         //    if it is already there.
205
206         // 2. If it is there, enable the remove button so that it can
207         //    be removed from this list, if so desired.
208
209         // 3. If it isn't there, activate the add button so that it can
210         //    be added to this list if so desired.
211
212         string const selection =
213                 getString(dialog_->browser_children);
214         string pid_str;
215         split(selection, pid_str, '\t');
216
217         vector<string> const kill_vec =
218                 getVector(dialog_->browser_kill);
219
220         vector<string>::const_iterator it =
221                 find(kill_vec.begin(), kill_vec.end(), pid_str);
222
223         fl_deselect_browser(dialog_->browser_kill);
224         if (it != kill_vec.end()) {
225                 int const n = int(it - kill_vec.begin());
226                 fl_select_browser_line(dialog_->browser_kill, n+1);
227                 fl_set_browser_topline(dialog_->browser_kill, n+1);
228         }
229
230         setEnabled(dialog_->button_remove, it != kill_vec.end());
231         setEnabled(dialog_->button_add,    it == kill_vec.end());
232
233         return ButtonPolicy::SMI_NOOP;
234 }
235
236
237 namespace {
238
239 class FindPID {
240 public:
241         FindPID(string const & pid) : pid_(pid) {}
242         bool operator()(string const & line)
243         {
244                 if (line.empty())
245                         return false;
246
247                 string pid_str;
248                 split(line, pid_str, '\t');
249                 return pid_str == pid_;
250         }
251
252 private:
253         string pid_;
254 };
255
256 } // namespace anon
257
258
259 ButtonPolicy::SMInput FormForks::input_browser_kill()
260 {
261         // Selected an item in the browser containing a list of processes
262         // to kill.
263
264         // 1. Highlight this item in the browser of all child processes.
265
266         // 2. Enable the remove button so that it can removed from this list,
267         //    if so desired.
268
269         // 3. Disable the add button.
270
271         string const pid_str =
272                 getString(dialog_->browser_kill);
273
274         // Find this string in the list of all child processes
275         vector<string> const child_vec =
276                 getVector(dialog_->browser_children);
277
278         vector<string>::const_iterator it =
279                 find_if(child_vec.begin(), child_vec.end(), FindPID(pid_str));
280
281         fl_deselect_browser(dialog_->browser_children);
282         if (it != child_vec.end()) {
283                 int const n = int(it - child_vec.begin());
284                 fl_select_browser_line(dialog_->browser_children, n+1);
285                 fl_set_browser_topline(dialog_->browser_children, n+1);
286         }
287
288         setEnabled(dialog_->button_remove, true);
289         setEnabled(dialog_->button_add,    false);
290
291         return ButtonPolicy::SMI_NOOP;
292 }
293
294
295 namespace {
296
297 vector<string> const getPIDvector(FL_OBJECT * ob)
298 {
299         vector<string> vec = getVector(ob);
300         if (vec.empty())
301                 return vec;
302
303         for (vector<string>::iterator it = vec.begin(); it != vec.end(); ++it) {
304                 string pid_str;
305                 split(*it, pid_str, '\t');
306                 *it = pid_str;
307         }
308
309         return vec;
310 }
311
312 } // namespace anon
313
314
315 ButtonPolicy::SMInput FormForks::input_button_all()
316 {
317         // Pressed the "All" button.
318
319         // 1. Check that the browser of processes to kill doesn't already
320         //    contain the entire list.
321
322         // 2. If it doesn't, copy the PIDs of all child processes into the
323         //    browser of processes to kill.
324
325         // 3. Deactivate the "children" browser and the "add" and "all" buttons
326
327         // 4. Activate the "kill" browser and the "remove" button"
328
329         ButtonPolicy::SMInput activate = ButtonPolicy::SMI_NOOP;
330
331         vector<string> const pid_vec = getPIDvector(dialog_->browser_children);
332
333         // to resolve a warning about comparison between signed and unsigned.
334         int const pid_vec_size = int(pid_vec.size());
335
336         if (fl_get_browser_maxline(dialog_->browser_kill) != pid_vec_size) {
337                 activate = ButtonPolicy::SMI_VALID;
338
339                 fl_clear_browser(dialog_->browser_kill);
340                 for (vector<string>::const_iterator it = pid_vec.begin();
341                      it != pid_vec.end(); ++it) {
342                         fl_add_browser_line(dialog_->browser_kill, it->c_str());
343                 }
344
345                 if (fl_get_browser_maxline(dialog_->browser_kill) >= 1)
346                         fl_set_browser_topline(dialog_->browser_kill, 1);
347         }
348
349         setEnabled(dialog_->browser_children, false);
350         setEnabled(dialog_->button_add,       false);
351         setEnabled(dialog_->button_all,       false);
352         setEnabled(dialog_->browser_kill,     true);
353         setEnabled(dialog_->button_remove,    true);
354
355         return activate;
356 }
357
358
359 ButtonPolicy::SMInput FormForks::input_button_add()
360 {
361         // Pressed the "Add" button.
362
363         // 1. Copy the PID of the selected item in the browser of all child
364         //    processes over into the browser of processes to kill.
365
366         // 2. Activate the "kill" browser and the "remove" button.
367
368         // 3. Deactivate the "add" button.
369
370         string const selection = getString(dialog_->browser_children);
371         string pid_str;
372         split(selection, pid_str, '\t');
373
374         vector<string> const kill_vec =
375                 getVector(dialog_->browser_kill);
376
377         vector<string>::const_iterator it =
378                 find(kill_vec.begin(), kill_vec.end(), pid_str);
379
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);
384         }
385
386         setEnabled(dialog_->browser_kill,  true);
387         setEnabled(dialog_->button_remove, true);
388         setEnabled(dialog_->button_add,    false);
389
390         return ButtonPolicy::SMI_VALID;
391 }
392
393
394 ButtonPolicy::SMInput FormForks::input_button_remove()
395 {
396         // Pressed the "Remove" button.
397
398         // 1. Remove the selected item in the browser of processes to kill.
399
400         // 2. Activate the "add" button and "all" buttons.
401
402         // 3. Deactivate the "remove" button.
403
404         int const sel = fl_get_browser(dialog_->browser_kill);
405         fl_delete_browser_line(dialog_->browser_kill, sel);
406
407         setEnabled(dialog_->button_add,    true);
408         setEnabled(dialog_->button_all,    true);
409         setEnabled(dialog_->button_remove, false);
410
411         return ButtonPolicy::SMI_VALID;
412 }