]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormRef.C
Angus's 23rd November patch
[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         // Manage the ok and cancel/close buttons
97         bc_.setOK(dialog_->button_ok);
98         bc_.setCancel(dialog_->button_cancel);
99         bc_.refresh();
100
101         bc_.addReadOnly(dialog_->type);
102 }
103
104
105 void FormRef::update()
106 {
107         fl_set_input(dialog_->ref,  params.getContents().c_str());
108         fl_set_input(dialog_->name, params.getOptions().c_str());
109
110         Type type = getType();
111         fl_set_choice(dialog_->type, type + 1);
112
113         toggle = GOBACK;
114         fl_set_object_label(dialog_->button_go, _("Goto reference"));
115
116         refs.clear();
117         if (inset_ == 0) {
118                 refs = lv_->buffer()->getLabelList();
119                 updateBrowser(refs);
120                 showBrowser();
121         } else {
122                 hideBrowser();
123         }
124         bc_.readOnly(lv_->buffer()->isReadonly());
125 }
126
127
128 void FormRef::updateBrowser(vector<string> const & akeys) const
129 {
130         vector<string> keys(akeys);
131         if (fl_get_button( dialog_->sort))
132                 sort(keys.begin(), keys.end());
133
134         fl_clear_browser(dialog_->browser);
135         for (vector<string>::const_iterator it = keys.begin();
136              it != keys.end(); ++it)
137                 fl_add_browser_line(dialog_->browser, (*it).c_str());
138
139         if (keys.empty()) {
140                 fl_add_browser_line(dialog_->browser,
141                                     _("*** No labels found in document ***"));
142
143                 fl_deactivate_object(dialog_->browser);
144                 fl_deactivate_object(dialog_->button_update);
145                 fl_deactivate_object(dialog_->sort);
146                 fl_set_object_lcol(dialog_->browser, FL_INACTIVE);
147                 fl_set_object_lcol(dialog_->button_update, FL_INACTIVE);
148                 fl_set_object_lcol(dialog_->sort, FL_INACTIVE);
149         } else {
150                 fl_set_browser_topline(dialog_->browser, 1);
151                 fl_activate_object(dialog_->browser);
152                 fl_set_object_lcol(dialog_->browser, FL_BLACK);
153                 fl_activate_object(dialog_->button_update);
154                 fl_set_object_lcol(dialog_->button_update, FL_BLACK);
155                 fl_activate_object(dialog_->sort);
156                 fl_set_object_lcol(dialog_->sort, FL_BLACK);
157         }
158 }
159
160
161 void FormRef::showBrowser() const
162 {
163         fl_show_object(dialog_->browser);
164         fl_show_object(dialog_->button_update);
165         fl_show_object(dialog_->sort);
166
167         setSize(minw_sb, 0);
168
169         fl_deactivate_object(dialog_->type);
170         fl_set_object_lcol(dialog_->type, FL_INACTIVE);
171         fl_deactivate_object(dialog_->button_go);
172         fl_set_object_lcol(dialog_->button_go, FL_INACTIVE);
173         fl_set_object_lcol(dialog_->ref, FL_INACTIVE);
174         bc_.valid(false);
175 }
176
177
178 void FormRef::hideBrowser() const
179 {
180         fl_hide_object(dialog_->browser);
181         fl_hide_object(dialog_->button_update);
182         fl_hide_object(dialog_->sort);
183
184         setSize(minw_hb, 280);
185
186         fl_activate_object(dialog_->type);
187         fl_set_object_lcol(dialog_->type, FL_BLACK);
188         fl_activate_object(dialog_->button_go);
189         fl_set_object_lcol(dialog_->button_go, FL_BLACK);
190         fl_set_object_lcol(dialog_->ref, FL_BLACK);
191         bc_.invalid();
192 }
193
194
195 void FormRef::setSize(int w, int dx) const
196 {
197         static int x1 = dialog_->name->x;
198         static int y1 = dialog_->name->y;
199         static int x2 = dialog_->ref->x;
200         static int y2 = dialog_->ref->y;
201         static int x3 = dialog_->type->x;
202         static int y3 = dialog_->type->y;
203         static int x4 = dialog_->button_go->x;
204         static int y4 = dialog_->button_go->y;
205         static int x5 = dialog_->button_ok->x;
206         static int y5 = dialog_->button_ok->y;
207         static int x6 = dialog_->button_cancel->x;
208         static int y6 = dialog_->button_cancel->y;
209
210         if (form()->w != w) {
211                 minw_ = w;
212                 fl_set_form_size(form(), minw_, minh_);
213         } else
214                 return;
215         
216         fl_set_object_position(dialog_->name,   x1 - dx, y1);
217         fl_set_object_position(dialog_->ref,    x2 - dx, y2);
218         fl_set_object_position(dialog_->type,   x3 - dx, y3);
219         fl_set_object_position(dialog_->button_go,     x4 - dx, y4);
220         fl_set_object_position(dialog_->button_ok,     x5 - dx, y5);
221         fl_set_object_position(dialog_->button_cancel, x6 - dx, y6);
222
223         // These two must be reset apparently
224         // Name is irrelevant to LaTeX documents
225         if (lv_->buffer()->isLatex()) {
226                 fl_deactivate_object(dialog_->name);
227                 fl_set_object_lcol(dialog_->name, FL_INACTIVE);
228         }
229           
230         // Can change reference only through browser
231         fl_deactivate_object(dialog_->ref);
232 }
233
234
235 void FormRef::apply()
236 {
237         if (!lv_->view()->available())
238                 return;
239
240         Type const type = static_cast<Type>(fl_get_choice(dialog_->type) - 1);
241         params.setCmdName(getName(type));
242
243         params.setOptions(fl_get_input(dialog_->name));
244
245         if (inset_ != 0) {
246                 // Only update if contents have changed
247                 if (params != inset_->params()) {
248                         inset_->setParams(params);
249                         lv_->view()->updateInset(inset_, true);
250                 }
251         } else {
252                 lv_->getLyXFunc()->Dispatch(LFUN_REF_INSERT,
253                                             params.getAsString());
254         }
255 }
256
257
258 #ifdef WITH_WARNINGS
259 #warning check use of buttoncontroller
260 // Seems okay except that goref and goback shouldn't
261 // affect the status of ok.
262 #endif
263 bool FormRef::input(FL_OBJECT *, long data)
264 {
265         bool activate(true);
266         switch (data) {
267         // goto reference / go back
268         case 1:
269         {
270                 toggle = static_cast<Goto>(toggle + 1);
271                 if (toggle == GOFIRST ) toggle = GOREF;
272         
273                 switch (toggle) {
274                 case GOREF:
275                 {
276                         lv_->getLyXFunc()->
277                                 Dispatch(LFUN_REF_GOTO,
278                                          params.getContents());
279                         fl_set_object_label(dialog_->button_go, _("Go back"));
280                 }
281                 break;
282
283                 case GOBACK:
284                 {
285                         lv_->getLyXFunc()->Dispatch(LFUN_REF_BACK);
286                         fl_set_object_label(dialog_->button_go,
287                                             _("Goto reference"));
288                 }
289                 break;
290
291                 default:
292                         break;
293                 }
294         }
295         break;
296
297         // choose browser key
298         case 2:
299         {
300                 unsigned int sel = fl_get_browser(dialog_->browser);
301                 if (sel < 1 || sel > refs.size()) break;
302
303                 string s = fl_get_browser_line(dialog_->browser, sel);
304                 fl_set_input(dialog_->ref, s.c_str());
305                 params.setContents(s);
306
307                 toggle = GOBACK;
308                 lv_->getLyXFunc()->Dispatch(LFUN_REF_BACK);
309                 fl_set_object_label(dialog_->button_go, _("Goto reference"));
310
311                 fl_activate_object(dialog_->type);
312                 fl_set_object_lcol(dialog_->type, FL_BLACK);
313                 fl_activate_object(dialog_->button_go);
314                 fl_set_object_lcol(dialog_->button_go, FL_BLACK);
315                 fl_set_object_lcol(dialog_->ref, FL_BLACK);
316         }
317         break;
318
319         // update or sort
320         case 3:
321         {
322                 fl_freeze_form(form());
323                 updateBrowser(refs);
324                 fl_unfreeze_form(form());
325         }
326         break;
327
328         // changed reference type
329         case 4:
330         {
331                 Type type = static_cast<Type>( 
332                         fl_get_choice(dialog_->type) - 1);
333                 if (params.getCmdName() == getName(type)
334                     && inset_) {
335                         activate = false;
336                 }
337         }
338         break;
339
340         default:
341                 break;
342         }
343         return activate;
344 }
345
346
347 FormRef::Type FormRef::getType() const
348 {
349         Type type;
350
351         if (params.getCmdName() == "ref" )
352                 type = REF;
353
354         else if (params.getCmdName() == "pageref" )
355                 type = PAGEREF;
356
357         else if (params.getCmdName() == "vref" )
358                 type = VREF;
359
360         else if (params.getCmdName() == "vpageref" )
361                 type = VPAGEREF;
362
363         else
364                 type = PRETTYREF;
365         
366         return type;
367 }
368
369
370 string const FormRef::getName(Type type) const
371 {
372         string name;
373
374         switch (type) {
375         case REF:
376                 name = "ref";
377                 break;
378         case PAGEREF:
379                 name = "pageref";
380                 break;
381         case VREF:
382                 name = "vref";
383                 break;
384         case VPAGEREF:
385                 name = "vpageref";
386                 break;
387         case PRETTYREF:
388                 name = "prettyref";
389                 break;
390         }
391         
392         return name;
393 }