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