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