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