]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormBaseDeprecated.C
Switch from SigC signals to boost::signals
[lyx.git] / src / frontends / xforms / FormBaseDeprecated.C
1 /**
2  * \file FormBaseDeprecated.C
3  * Copyright 2000-2001 The LyX Team.
4  * See the file COPYING.
5  *
6  * \author Angus Leeming, a.leeming@ic.ac.uk
7  */
8
9 #include <config.h>
10
11 #ifdef __GNUG__
12 #pragma implementation
13 #endif
14
15 #include "Dialogs.h"
16 #include "FormBaseDeprecated.h"
17 #include "xformsBC.h"
18 #include "xforms_resize.h"
19 #include "GUIRunTime.h"
20 #include "Tooltips.h"
21 #include "lyxrc.h"
22
23 #include "frontends/LyXView.h"
24
25 #include "support/LAssert.h"
26
27 #include <boost/bind.hpp>
28
29 extern "C" {
30
31 // Callback function invoked by xforms when the dialog is closed by the
32 // window manager
33 static int C_WMHideCB(FL_FORM *, void *);
34
35 // Callback function invoked by the xforms pre- and post-handler routines
36 static int C_PrehandlerCB(FL_OBJECT *, int, FL_Coord, FL_Coord, int, void *);
37
38 } // extern "C"
39
40
41 FormBaseDeprecated::FormBaseDeprecated(LyXView * lv, Dialogs * d,
42                                        string const & t, bool allowResize)
43         : lv_(lv), d_(d), title_(t),
44           minw_(0), minh_(0), allow_resize_(allowResize),
45           tooltips_(new Tooltips)
46 {
47         lyx::Assert(lv && d);
48 }
49
50
51 FormBaseDeprecated::~FormBaseDeprecated()
52 {
53         delete tooltips_;
54 }
55
56
57 Tooltips & FormBaseDeprecated::tooltips()
58 {
59         return *tooltips_;
60 }
61
62
63 void FormBaseDeprecated::redraw()
64 {
65         if (form() && form()->visible)
66                 fl_redraw_form(form());
67 }
68
69
70 void FormBaseDeprecated::connect()
71 {
72         fl_set_form_minsize(form(), minw_, minh_);
73         r_ = Dialogs::redrawGUI.connect(boost::bind(&FormBaseDeprecated::redraw, this));
74 }
75
76
77 void FormBaseDeprecated::disconnect()
78 {
79         h_.disconnect();
80         r_.disconnect();
81 }
82
83
84 void FormBaseDeprecated::show()
85 {
86         if (!form()) {
87                 build();
88
89                 double const scale = scale_to_fit_tabs(form());
90                 if (scale > 1.001)
91                         scale_form(form(), scale);
92
93                 bc().refresh();
94
95                 // work around dumb xforms sizing bug
96                 minw_ = form()->w;
97                 minh_ = form()->h;
98
99                 fl_set_form_atclose(form(), C_WMHideCB, 0);
100         }
101
102         fl_freeze_form(form());
103         update();
104         fl_unfreeze_form(form());
105
106         if (form()->visible) {
107                 fl_raise_form(form());
108                 /* This XMapWindow() will hopefully ensure that
109                  * iconified dialogs are de-iconified. Mad props
110                  * out to those crazy Xlib guys for forgetting a
111                  * XDeiconifyWindow(). At least WindowMaker, when
112                  * being notified of the redirected MapRequest will
113                  * specifically de-iconify. From source, fvwm2 seems
114                  * to do the same.
115                  */
116                 XMapWindow(fl_get_display(), form()->window);
117         } else {
118                 connect();
119
120                 // calls to fl_set_form_minsize/maxsize apply only to the next
121                 // fl_show_form(), so this comes first.
122                 fl_set_form_minsize(form(), minw_, minh_);
123                 if (!allow_resize_)
124                         fl_set_form_maxsize(form(), minw_, minh_);
125
126                 fl_show_form(form(),
127                              FL_PLACE_MOUSE | FL_FREE_SIZE,
128                              (lyxrc.dialogs_iconify_with_main ? FL_TRANSIENT : 0),
129                              title_.c_str());
130         }
131
132         tooltips().set();
133 }
134
135
136 void FormBaseDeprecated::hide()
137 {
138         // xforms sometimes tries to process a hint-type MotionNotify, and
139         // use XQueryPointer, without verifying if the window still exists.
140         // So we try to clear out motion events in the queue before the
141         // DestroyNotify
142         XSync(fl_get_display(), false);
143         GUIRunTime::processEvents();
144
145         if (form() && form()->visible) {
146                 // some dialogs might do things to the form first
147                 // such as the nested tabfolder problem in Preferences
148                 disconnect();
149                 fl_hide_form(form());
150         }
151 }
152
153
154 void FormBaseDeprecated::setPrehandler(FL_OBJECT * ob)
155 {
156         lyx::Assert(ob);
157         fl_set_object_prehandler(ob, C_PrehandlerCB);
158 }
159
160
161 void FormBaseDeprecated::WMHideCB()
162 {
163         hide();
164         bc().hide();
165 }
166
167
168 void FormBaseDeprecated::ApplyCB()
169 {
170         apply();
171         bc().apply();
172 }
173
174
175 void FormBaseDeprecated::OKCB()
176 {
177         ok();
178         bc().ok();
179 }
180
181
182 void FormBaseDeprecated::CancelCB()
183 {
184         cancel();
185         bc().cancel();
186 }
187
188
189 void FormBaseDeprecated::InputCB(FL_OBJECT * ob, long data)
190 {
191         // It is possible to set the choice to 0 when using the
192         // keyboard shortcuts. This work-around deals with the problem.
193         if (ob && ob->objclass == FL_CHOICE && fl_get_choice(ob) < 1) {
194                 fl_set_choice(ob, 1);
195         }
196
197         bc().valid(input(ob, data));
198 }
199
200
201 void FormBaseDeprecated::RestoreCB()
202 {
203         bc().restore();
204         restore();
205 }
206
207
208 FormBaseBI::FormBaseBI(LyXView * lv, Dialogs * d, string const & t,
209                        bool allowResize)
210         : FormBaseDeprecated(lv, d, t, allowResize)
211 {}
212
213
214 void FormBaseBI::connect()
215 {
216         h_ = d_->hideAll.connect(boost::bind(&FormBaseBI::hide, this));
217         FormBaseDeprecated::connect();
218 }
219
220
221 FormBaseBD::FormBaseBD(LyXView * lv, Dialogs * d, string const & t,
222                        bool allowResize)
223         : FormBaseDeprecated(lv, d, t, allowResize)
224 {}
225
226
227 void FormBaseBD::connect()
228 {
229         u_ = d_->updateBufferDependent.
230                 connect(boost::bind(&FormBaseBD::updateSlot, this, _1));
231         h_ = d_->hideBufferDependent.
232                 connect(boost::bind(&FormBaseBD::hide, this));
233         FormBaseDeprecated::connect();
234 }
235
236
237 void FormBaseBD::disconnect()
238 {
239         u_.disconnect();
240         FormBaseDeprecated::disconnect();
241 }
242
243
244 namespace {
245
246 FormBaseDeprecated * GetForm(FL_OBJECT * ob)
247 {
248         lyx::Assert(ob && ob->form && ob->form->u_vdata);
249         FormBaseDeprecated * ptr =
250                 static_cast<FormBaseDeprecated *>(ob->form->u_vdata);
251         return ptr;
252 }
253
254 } // namespace anon
255
256
257 extern "C" {
258
259 void C_FormBaseDeprecatedApplyCB(FL_OBJECT * ob, long)
260 {
261         GetForm(ob)->ApplyCB();
262 }
263
264
265 void C_FormBaseDeprecatedOKCB(FL_OBJECT * ob, long)
266 {
267         GetForm(ob)->OKCB();
268 }
269
270
271 void C_FormBaseDeprecatedCancelCB(FL_OBJECT * ob, long)
272 {
273         GetForm(ob)->CancelCB();
274 }
275
276
277 void C_FormBaseDeprecatedInputCB(FL_OBJECT * ob, long d)
278 {
279         GetForm(ob)->InputCB(ob, d);
280 }
281
282
283 void C_FormBaseDeprecatedRestoreCB(FL_OBJECT * ob, long)
284 {
285         GetForm(ob)->RestoreCB();
286 }
287
288 static int C_WMHideCB(FL_FORM * form, void *)
289 {
290         // Close the dialog cleanly, even if the WM is used to do so.
291         lyx::Assert(form && form->u_vdata);
292         FormBaseDeprecated * ptr =
293                 static_cast<FormBaseDeprecated *>(form->u_vdata);
294         ptr->WMHideCB();
295         return FL_CANCEL;
296 }
297
298 static int C_PrehandlerCB(FL_OBJECT * ob, int event,
299                           FL_Coord, FL_Coord, int key, void *)
300 {
301         // Note that the return value is important in the pre-emptive handler.
302         // Don't return anything other than 0.
303         lyx::Assert(ob);
304
305         // Don't Assert this one, as it can happen quite naturally when things
306         // are being deleted in the d-tor.
307         //Assert(ob->form);
308         if (!ob->form) return 0;
309
310         FormBaseDeprecated * ptr =
311                 static_cast<FormBaseDeprecated *>(ob->form->u_vdata);
312
313         if (ptr)
314                 ptr->PrehandlerCB(ob, event, key);
315
316         return 0;
317 }
318
319 } // extern "C"