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