]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormRef.C
fix a couple of hard crashes, constify local variables, whitespace changes, some...
[lyx.git] / src / frontends / xforms / FormRef.C
1 // -*- C++ -*-
2 /* This file is part of
3  * ====================================================== 
4  *
5  *           LyX, The Document Processor
6  *
7  *           Copyright 2000 The LyX Team.
8  *
9  * ======================================================
10  */
11
12 #include <config.h>
13
14 #include FORMS_H_LOCATION
15
16 #ifdef __GNUG__
17 #pragma implementation
18 #endif
19
20
21 #include "Dialogs.h"
22 #include "FormRef.h"
23 #include "LyXView.h"
24 #include "buffer.h"
25 #include "form_ref.h"
26 #include "lyxfunc.h"
27
28 #include <algorithm>
29
30 using std::sort;
31 using std::vector;
32
33 static int const minw_hb = 250;
34 static int minw_sb;
35
36 FormRef::FormRef(LyXView * lv, Dialogs * d)
37         : FormCommand(lv, d, _("Reference"), new OkCancelReadOnlyPolicy),
38           toggle(GOBACK), dialog_(0)
39 {
40         // let the dialog be shown
41         // These are permanent connections so we won't bother
42         // storing a copy because we won't be disconnecting.
43         d->showRef.connect(slot(this, &FormRef::showInset));
44         d->createRef.connect(slot(this, &FormRef::createInset));
45 }
46
47
48 FormRef::~FormRef()
49 {
50         delete dialog_;
51 }
52
53
54 FL_FORM * FormRef::form() const
55 {
56         if (dialog_) return dialog_->form;
57         return 0;
58 }
59
60
61 void FormRef::connect()
62 {
63         fl_set_form_maxsize(form(), 2 * minw_, minh_);
64         FormCommand::connect();
65 }
66         
67
68 void FormRef::disconnect()
69 {
70         refs.clear();
71         FormCommand::disconnect();
72 }
73
74
75 void FormRef::build()
76 {
77         dialog_ = build_ref();
78
79         fl_addto_choice(dialog_->type,
80                         _(" Ref | Page | TextRef | TextPage | PrettyRef "));
81
82         // Workaround dumb xforms sizing bug
83         minw_ = form()->w;
84         minh_ = form()->h;
85         minw_sb = minw_;
86
87         // Name is irrelevant to LaTeX documents
88         if (lv_->buffer()->isLatex()) {
89                 fl_deactivate_object(dialog_->name);
90                 fl_set_object_lcol(dialog_->name, FL_INACTIVE);
91         }
92           
93         // Can change reference only through browser
94         fl_deactivate_object(dialog_->ref);
95
96         bc_.setOK(dialog_->button_ok);
97         bc_.setCancel(dialog_->button_cancel);
98         bc_.addReadOnly(dialog_->type);
99         bc_.refresh();
100 }
101
102
103 void FormRef::update()
104 {
105         fl_set_input(dialog_->ref,  params.getContents().c_str());
106         fl_set_input(dialog_->name, params.getOptions().c_str());
107
108         Type type = getType();
109         fl_set_choice(dialog_->type, type + 1);
110
111         toggle = GOBACK;
112         fl_set_object_label(dialog_->button_go, _("Goto reference"));
113
114         refs.clear();
115         if (inset_ == 0) {
116                 refs = lv_->buffer()->getLabelList();
117                 updateBrowser(refs);
118                 showBrowser();
119         } else {
120                 hideBrowser();
121         }
122         bc_.readOnly(lv_->buffer()->isReadonly());
123 }
124
125
126 void FormRef::updateBrowser(vector<string> const & akeys) const
127 {
128         vector<string> keys(akeys);
129         if (fl_get_button( dialog_->sort))
130                 sort(keys.begin(), keys.end());
131
132         fl_clear_browser(dialog_->browser);
133         for (vector<string>::const_iterator it = keys.begin();
134              it != keys.end(); ++it)
135                 fl_add_browser_line(dialog_->browser, (*it).c_str());
136
137         if (keys.empty()) {
138                 fl_add_browser_line(dialog_->browser,
139                                     _("*** No labels found in document ***"));
140
141                 fl_deactivate_object(dialog_->browser);
142                 fl_deactivate_object(dialog_->button_update);
143                 fl_deactivate_object(dialog_->sort);
144                 fl_set_object_lcol(dialog_->browser, FL_INACTIVE);
145                 fl_set_object_lcol(dialog_->button_update, FL_INACTIVE);
146                 fl_set_object_lcol(dialog_->sort, FL_INACTIVE);
147         } else {
148                 fl_set_browser_topline(dialog_->browser, 1);
149                 fl_activate_object(dialog_->browser);
150                 fl_set_object_lcol(dialog_->browser, FL_BLACK);
151                 fl_activate_object(dialog_->button_update);
152                 fl_set_object_lcol(dialog_->button_update, FL_BLACK);
153                 fl_activate_object(dialog_->sort);
154                 fl_set_object_lcol(dialog_->sort, FL_BLACK);
155         }
156 }
157
158
159 void FormRef::showBrowser() const
160 {
161         fl_show_object(dialog_->browser);
162         fl_show_object(dialog_->button_update);
163         fl_show_object(dialog_->sort);
164
165         setSize(minw_sb, 0);
166
167         fl_deactivate_object(dialog_->type);
168         fl_set_object_lcol(dialog_->type, FL_INACTIVE);
169         fl_deactivate_object(dialog_->button_go);
170         fl_set_object_lcol(dialog_->button_go, FL_INACTIVE);
171         fl_set_object_lcol(dialog_->ref, FL_INACTIVE);
172         bc_.valid(false);
173 }
174
175
176 void FormRef::hideBrowser() const
177 {
178         fl_hide_object(dialog_->browser);
179         fl_hide_object(dialog_->button_update);
180         fl_hide_object(dialog_->sort);
181
182         setSize(minw_hb, 280);
183
184         fl_activate_object(dialog_->type);
185         fl_set_object_lcol(dialog_->type, FL_BLACK);
186         fl_activate_object(dialog_->button_go);
187         fl_set_object_lcol(dialog_->button_go, FL_BLACK);
188         fl_set_object_lcol(dialog_->ref, FL_BLACK);
189         bc_.invalid();
190 }
191
192
193 void FormRef::setSize(int w, int dx) const
194 {
195         static int x1 = dialog_->name->x;
196         static int y1 = dialog_->name->y;
197         static int x2 = dialog_->ref->x;
198         static int y2 = dialog_->ref->y;
199         static int x3 = dialog_->type->x;
200         static int y3 = dialog_->type->y;
201         static int x4 = dialog_->button_go->x;
202         static int y4 = dialog_->button_go->y;
203         static int x5 = dialog_->button_ok->x;
204         static int y5 = dialog_->button_ok->y;
205         static int x6 = dialog_->button_cancel->x;
206         static int y6 = dialog_->button_cancel->y;
207
208         if (form()->w != w) {
209                 minw_ = w;
210                 fl_set_form_size(form(), minw_, minh_);
211         } else
212                 return;
213         
214         fl_set_object_position(dialog_->name,   x1 - dx, y1);
215         fl_set_object_position(dialog_->ref,    x2 - dx, y2);
216         fl_set_object_position(dialog_->type,   x3 - dx, y3);
217         fl_set_object_position(dialog_->button_go,     x4 - dx, y4);
218         fl_set_object_position(dialog_->button_ok,     x5 - dx, y5);
219         fl_set_object_position(dialog_->button_cancel, x6 - dx, y6);
220
221         // These two must be reset apparently
222         // Name is irrelevant to LaTeX documents
223         if (lv_->buffer()->isLatex()) {
224                 fl_deactivate_object(dialog_->name);
225                 fl_set_object_lcol(dialog_->name, FL_INACTIVE);
226         }
227           
228         // Can change reference only through browser
229         fl_deactivate_object(dialog_->ref);
230 }
231
232
233 void FormRef::apply()
234 {
235         if (!lv_->view()->available())
236                 return;
237
238         Type const type = static_cast<Type>(fl_get_choice(dialog_->type) - 1);
239         params.setCmdName(getName(type));
240
241         params.setOptions(fl_get_input(dialog_->name));
242
243         if (inset_ != 0) {
244                 // Only update if contents have changed
245                 if (params != inset_->params()) {
246                         inset_->setParams(params);
247                         lv_->view()->updateInset(inset_, true);
248                 }
249         } else {
250                 lv_->getLyXFunc()->Dispatch(LFUN_REF_INSERT,
251                                             params.getAsString());
252         }
253 }
254
255
256 #ifdef WITH_WARNINGS
257 #warning check use of buttoncontroller
258 // Seems okay except that goref and goback shouldn't
259 // affect the status of ok.
260 #endif
261 bool FormRef::input(FL_OBJECT *, long data)
262 {
263         bool activate(true);
264         switch (data) {
265         // goto reference / go back
266         case 1:
267         {
268                 toggle = static_cast<Goto>(toggle + 1);
269                 if (toggle == GOFIRST ) toggle = GOREF;
270         
271                 switch (toggle) {
272                 case GOREF:
273                 {
274                         lv_->getLyXFunc()->
275                                 Dispatch(LFUN_REF_GOTO,
276                                          params.getContents());
277                         fl_set_object_label(dialog_->button_go, _("Go back"));
278                 }
279                 break;
280
281                 case GOBACK:
282                 {
283                         lv_->getLyXFunc()->Dispatch(LFUN_REF_BACK);
284                         fl_set_object_label(dialog_->button_go,
285                                             _("Goto reference"));
286                 }
287                 break;
288
289                 default:
290                         break;
291                 }
292         }
293         break;
294
295         // choose browser key
296         case 2:
297         {
298                 unsigned int sel = fl_get_browser(dialog_->browser);
299                 if (sel < 1 || sel > refs.size()) break;
300
301                 string s = fl_get_browser_line(dialog_->browser, sel);
302                 fl_set_input(dialog_->ref, s.c_str());
303                 params.setContents(s);
304
305                 toggle = GOBACK;
306                 lv_->getLyXFunc()->Dispatch(LFUN_REF_BACK);
307                 fl_set_object_label(dialog_->button_go, _("Goto reference"));
308
309                 fl_activate_object(dialog_->type);
310                 fl_set_object_lcol(dialog_->type, FL_BLACK);
311                 fl_activate_object(dialog_->button_go);
312                 fl_set_object_lcol(dialog_->button_go, FL_BLACK);
313                 fl_set_object_lcol(dialog_->ref, FL_BLACK);
314         }
315         break;
316
317         // update or sort
318         case 3:
319         {
320                 fl_freeze_form(form());
321                 updateBrowser(refs);
322                 fl_unfreeze_form(form());
323         }
324         break;
325
326         // changed reference type
327         case 4:
328         {
329                 Type type = static_cast<Type>( 
330                         fl_get_choice(dialog_->type) - 1);
331                 if (params.getCmdName() == getName(type)
332                     && inset_) {
333                         activate = false;
334                 }
335         }
336         break;
337
338         default:
339                 break;
340         }
341         return activate;
342 }
343
344
345 FormRef::Type FormRef::getType() const
346 {
347         Type type;
348
349         if (params.getCmdName() == "ref" )
350                 type = REF;
351
352         else if (params.getCmdName() == "pageref" )
353                 type = PAGEREF;
354
355         else if (params.getCmdName() == "vref" )
356                 type = VREF;
357
358         else if (params.getCmdName() == "vpageref" )
359                 type = VPAGEREF;
360
361         else
362                 type = PRETTYREF;
363         
364         return type;
365 }
366
367
368 string const FormRef::getName(Type type) const
369 {
370         string name;
371
372         switch (type) {
373         case REF:
374                 name = "ref";
375                 break;
376         case PAGEREF:
377                 name = "pageref";
378                 break;
379         case VREF:
380                 name = "vref";
381                 break;
382         case VPAGEREF:
383                 name = "vpageref";
384                 break;
385         case PRETTYREF:
386                 name = "prettyref";
387                 break;
388         }
389         
390         return name;
391 }