]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormRef.C
365e844c61b052681f51d85598ea5d3eca45b756
[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::find;
31 using std::max;
32 using std::sort;
33 using std::vector;
34
35 FormRef::FormRef(LyXView * lv, Dialogs * d)
36         : FormCommand(lv, d, _("Reference"), new NoRepeatedApplyPolicy),
37           toggle(GOBACK), dialog_(0)
38 {
39         // let the dialog be shown
40         // These are permanent connections so we won't bother
41         // storing a copy because we won't be disconnecting.
42         d->showRef.connect(slot(this, &FormRef::showInset));
43         d->createRef.connect(slot(this, &FormRef::createInset));
44 }
45
46
47 FormRef::~FormRef()
48 {
49         delete dialog_;
50 }
51
52
53 FL_FORM * FormRef::form() const
54 {
55         if (dialog_) return dialog_->form;
56         return 0;
57 }
58
59
60 void FormRef::disconnect()
61 {
62         refs.clear();
63         FormCommand::disconnect();
64 }
65
66
67 void FormRef::build()
68 {
69         dialog_ = build_ref();
70
71         fl_addto_choice(dialog_->type,
72                         _(" Ref | Page | TextRef | TextPage | PrettyRef "));
73
74         // Workaround dumb xforms sizing bug
75         minw_ = form()->w;
76         minh_ = form()->h;
77
78         // Force the user to use the browser to change refs.
79         fl_deactivate_object(dialog_->ref);
80
81         // Manage the ok and cancel/close buttons
82         bc_.setOK(dialog_->button_ok);
83         bc_.setApply(dialog_->button_apply);
84         bc_.setCancel(dialog_->button_cancel);
85         bc_.setUndoAll(dialog_->button_restore);
86         bc_.refresh();
87
88 #warning I had to uncomment this so the buttons could be disabled in update() (dekel)
89         //bc_.addReadOnly(dialog_->type);
90         //bc_.addReadOnly(dialog_->name);
91 }
92
93
94 void FormRef::update()
95 {
96         if (inset_) {
97                 fl_set_input(dialog_->ref,  params.getContents().c_str());
98                 fl_set_input(dialog_->name, params.getOptions().c_str());
99                 fl_set_choice(dialog_->type, getType()+1);
100         }
101
102         toggle = GOBACK;
103         fl_set_object_label(dialog_->button_go, _("Goto reference"));
104
105         // Name is irrelevant to LaTeX/Literate documents, while
106         // type is irrelevant to LinuxDoc/DocBook.
107         if (lv_->buffer()->isLatex() || lv_->buffer()->isLatex()) {
108                 fl_deactivate_object(dialog_->name);
109                 fl_set_object_lcol(dialog_->name, FL_INACTIVE);
110                 fl_activate_object(dialog_->type);
111                 fl_set_object_lcol(dialog_->type, FL_BLACK);
112         } else {
113                 fl_set_choice(dialog_->type, REF+1);
114
115                 fl_activate_object(dialog_->name);
116                 fl_set_object_lcol(dialog_->name, FL_BLACK);
117                 fl_deactivate_object(dialog_->type);
118                 fl_set_object_lcol(dialog_->type, FL_INACTIVE);
119         }
120
121         refs = lv_->buffer()->getLabelList();
122         updateBrowser(refs);
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_->sort);
145                 fl_set_object_lcol(dialog_->browser, FL_INACTIVE);
146                 fl_set_object_lcol(dialog_->sort, FL_INACTIVE);
147         } else {
148                 fl_activate_object(dialog_->browser);
149                 fl_set_object_lcol(dialog_->browser, FL_BLACK);
150                 fl_activate_object(dialog_->sort);
151                 fl_set_object_lcol(dialog_->sort, FL_BLACK);
152
153                 string ref = fl_get_input(dialog_->ref);
154                 vector<string>::const_iterator cit =
155                         find(keys.begin(), keys.end(), ref);
156                 if (cit == keys.end())
157                         cit = keys.begin();
158
159                 int const i = static_cast<int>(cit - keys.begin());
160                 fl_set_browser_topline(dialog_->browser, max(i-5, 1));
161                 fl_select_browser_line(dialog_->browser, i+1);
162         }
163 }
164
165
166 void FormRef::apply()
167 {
168         if (!lv_->view()->available())
169                 return;
170
171         Type const type = static_cast<Type>(fl_get_choice(dialog_->type) - 1);
172         params.setCmdName(getName(type));
173
174         params.setOptions(fl_get_input(dialog_->name));
175         params.setContents(fl_get_input(dialog_->ref));
176
177         if (inset_ != 0) {
178                 // Only update if contents have changed
179                 if (params != inset_->params()) {
180                         inset_->setParams(params);
181                         lv_->view()->updateInset(inset_, true);
182                 }
183         } else {
184                 lv_->getLyXFunc()->Dispatch(LFUN_REF_INSERT,
185                                             params.getAsString());
186         }
187 }
188
189
190 bool FormRef::input(FL_OBJECT *, long data)
191 {
192         bool activate(true);
193         switch (data) {
194         // goto reference / go back
195         case 1:
196         {
197                 // No change to data
198                 activate = false;
199                 
200                 toggle = static_cast<Goto>(toggle + 1);
201                 if (toggle == GOFIRST ) toggle = GOREF;
202         
203                 switch (toggle) {
204                 case GOREF:
205                 {
206                         lv_->getLyXFunc()->
207                                 Dispatch(LFUN_REF_GOTO,
208                                          fl_get_input(dialog_->ref));
209                         fl_set_object_label(dialog_->button_go, _("Go back"));
210                 }
211                 break;
212
213                 case GOBACK:
214                 {
215                         lv_->getLyXFunc()->Dispatch(LFUN_REF_BACK);
216                         fl_set_object_label(dialog_->button_go,
217                                             _("Goto reference"));
218                 }
219                 break;
220
221                 default:
222                         break;
223                 }
224         }
225         break;
226
227         // choose browser key
228         case 2:
229         {
230                 unsigned int sel = fl_get_browser(dialog_->browser);
231                 if (sel < 1 || sel > refs.size()) break;
232
233                 if (!lv_->buffer()->isReadonly()) {
234                         string s = fl_get_browser_line(dialog_->browser, sel);
235                         fl_set_input(dialog_->ref, s.c_str());
236                 }
237
238                 toggle = GOBACK;
239                 lv_->getLyXFunc()->Dispatch(LFUN_REF_BACK);
240                 fl_set_object_label(dialog_->button_go, _("Goto reference"));
241
242                 fl_activate_object(dialog_->type);
243                 fl_set_object_lcol(dialog_->type, FL_BLACK);
244                 fl_activate_object(dialog_->button_go);
245                 fl_set_object_lcol(dialog_->button_go, FL_BLACK);
246                 fl_set_object_lcol(dialog_->ref, FL_BLACK);
247         }
248         break;
249
250         // update or sort
251         case 3:
252                 refs = lv_->buffer()->getLabelList();
253
254                 // fall through to...
255         case 4:
256                 fl_freeze_form(form());
257                 updateBrowser(refs);
258                 fl_unfreeze_form(form());
259                 break;
260
261         // changed reference type
262         case 5:
263         {
264                 Type type = static_cast<Type>( 
265                         fl_get_choice(dialog_->type) - 1);
266                 if (params.getCmdName() == getName(type)
267                     && inset_) {
268                         activate = false;
269                 }
270         }
271         break;
272
273         default:
274                 break;
275         }
276
277         return activate;
278 }
279
280
281 FormRef::Type FormRef::getType() const
282 {
283         Type type;
284
285         if (params.getCmdName() == "ref" )
286                 type = REF;
287
288         else if (params.getCmdName() == "pageref" )
289                 type = PAGEREF;
290
291         else if (params.getCmdName() == "vref" )
292                 type = VREF;
293
294         else if (params.getCmdName() == "vpageref" )
295                 type = VPAGEREF;
296
297         else
298                 type = PRETTYREF;
299         
300         return type;
301 }
302
303
304 string const FormRef::getName(Type type) const
305 {
306         string name;
307
308         switch (type) {
309         case REF:
310                 name = "ref";
311                 break;
312         case PAGEREF:
313                 name = "pageref";
314                 break;
315         case VREF:
316                 name = "vref";
317                 break;
318         case VPAGEREF:
319                 name = "vpageref";
320                 break;
321         case PRETTYREF:
322                 name = "prettyref";
323                 break;
324         }
325         
326         return name;
327 }