]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormBaseDeprecated.C
xforms clean-up, described in detail in my mail of 31 May. See
[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 "Tooltips.h"
20 #include FORMS_H_LOCATION
21
22 #include "lyxrc.h"
23
24 #include "frontends/LyXView.h"
25
26 #include "support/LAssert.h"
27
28 #include <boost/bind.hpp>
29
30 extern "C" {
31
32 // Callback function invoked by xforms when the dialog is closed by the
33 // window manager
34 static int C_WMHideCB(FL_FORM *, void *);
35
36 // Callback function invoked by the xforms pre- and post-handler routines
37 static int C_PrehandlerCB(FL_OBJECT *, int, FL_Coord, FL_Coord, int, void *);
38
39 } // extern "C"
40
41
42 FormBaseDeprecated::FormBaseDeprecated(LyXView * lv, Dialogs * d,
43                                        string const & t, bool allowResize)
44         : lv_(lv), d_(d), title_(t),
45           minw_(0), minh_(0), allow_resize_(allowResize),
46           tooltips_(new Tooltips)
47 {
48         lyx::Assert(lv && d);
49 }
50
51
52 FormBaseDeprecated::~FormBaseDeprecated()
53 {
54         delete tooltips_;
55 }
56
57
58 Tooltips & FormBaseDeprecated::tooltips()
59 {
60         return *tooltips_;
61 }
62
63
64 void FormBaseDeprecated::redraw()
65 {
66         if (form() && form()->visible)
67                 fl_redraw_form(form());
68 }
69
70
71 void FormBaseDeprecated::connect()
72 {
73         fl_set_form_minsize(form(), minw_, minh_);
74         r_ = Dialogs::redrawGUI.connect(boost::bind(&FormBaseDeprecated::redraw, this));
75 }
76
77
78 void FormBaseDeprecated::disconnect()
79 {
80         h_.disconnect();
81         r_.disconnect();
82 }
83
84
85 void FormBaseDeprecated::show()
86 {
87         if (!form()) {
88                 build();
89
90                 double const scale = scale_to_fit_tabs(form());
91                 if (scale > 1.001)
92                         scale_form(form(), scale);
93
94                 bc().refresh();
95
96                 // work around dumb xforms sizing bug
97                 minw_ = form()->w;
98                 minh_ = form()->h;
99
100                 fl_set_form_atclose(form(), C_WMHideCB, 0);
101         }
102
103         fl_freeze_form(form());
104         update();
105         fl_unfreeze_form(form());
106
107         if (form()->visible) {
108                 fl_raise_form(form());
109                 /* This XMapWindow() will hopefully ensure that
110                  * iconified dialogs are de-iconified. Mad props
111                  * out to those crazy Xlib guys for forgetting a
112                  * XDeiconifyWindow(). At least WindowMaker, when
113                  * being notified of the redirected MapRequest will
114                  * specifically de-iconify. From source, fvwm2 seems
115                  * to do the same.
116                  */
117                 XMapWindow(fl_get_display(), form()->window);
118         } else {
119                 connect();
120
121                 // calls to fl_set_form_minsize/maxsize apply only to the next
122                 // fl_show_form(), so this comes first.
123                 fl_set_form_minsize(form(), minw_, minh_);
124                 if (!allow_resize_)
125                         fl_set_form_maxsize(form(), minw_, minh_);
126
127                 fl_show_form(form(),
128                              FL_PLACE_MOUSE | FL_FREE_SIZE,
129                              (lyxrc.dialogs_iconify_with_main ? FL_TRANSIENT : 0),
130                              title_.c_str());
131         }
132
133         tooltips().set();
134 }
135
136
137 void FormBaseDeprecated::hide()
138 {
139         // xforms sometimes tries to process a hint-type MotionNotify, and
140         // use XQueryPointer, without verifying if the window still exists.
141         // So we try to clear out motion events in the queue before the
142         // DestroyNotify
143         XSync(fl_get_display(), false);
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"