]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormRef.C
update patch from Angus
[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         bc_.addReadOnly(dialog_->type);
89         bc_.addReadOnly(dialog_->name);
90 }
91
92
93 void FormRef::update()
94 {
95         fl_set_input(dialog_->ref,  params.getContents().c_str());
96         fl_set_input(dialog_->name, params.getOptions().c_str());
97
98         Type type = getType();
99         fl_set_choice(dialog_->type, type+1);
100
101         toggle = GOBACK;
102         fl_set_object_label(dialog_->button_go, _("Goto reference"));
103
104         // Name is irrelevant to LaTeX documents
105         if (lv_->buffer()->isLatex()) {
106                 fl_deactivate_object(dialog_->name);
107                 fl_set_object_lcol(dialog_->name, FL_INACTIVE);
108         }
109           
110         refs = lv_->buffer()->getLabelList();
111         updateBrowser(refs);
112
113         if (inset_ == 0) {
114         } else {
115         }
116
117         bc_.readOnly(lv_->buffer()->isReadonly());
118 }
119
120
121 void FormRef::updateBrowser(vector<string> const & akeys) const
122 {
123         vector<string> keys(akeys);
124         if (fl_get_button( dialog_->sort))
125                 sort(keys.begin(), keys.end());
126
127         fl_clear_browser(dialog_->browser);
128         for (vector<string>::const_iterator it = keys.begin();
129              it != keys.end(); ++it)
130                 fl_add_browser_line(dialog_->browser, (*it).c_str());
131
132         if (keys.empty()) {
133                 fl_add_browser_line(dialog_->browser,
134                                     _("*** No labels found in document ***"));
135
136                 fl_deactivate_object(dialog_->browser);
137                 fl_deactivate_object(dialog_->button_update);
138                 fl_deactivate_object(dialog_->sort);
139                 fl_set_object_lcol(dialog_->browser, FL_INACTIVE);
140                 fl_set_object_lcol(dialog_->button_update, FL_INACTIVE);
141                 fl_set_object_lcol(dialog_->sort, FL_INACTIVE);
142         } else {
143                 fl_set_browser_topline(dialog_->browser, 1);
144                 fl_activate_object(dialog_->browser);
145                 fl_set_object_lcol(dialog_->browser, FL_BLACK);
146                 fl_activate_object(dialog_->button_update);
147                 fl_set_object_lcol(dialog_->button_update, FL_BLACK);
148                 fl_activate_object(dialog_->sort);
149                 fl_set_object_lcol(dialog_->sort, FL_BLACK);
150
151                 string ref = fl_get_input(dialog_->ref);
152                 vector<string>::const_iterator cit =
153                         find(refs.begin(), refs.end(), ref);
154
155                 if (cit != refs.end()) {
156                         int const i = static_cast<int>(cit - refs.begin());
157                         fl_set_browser_topline(dialog_->browser, max(i-5, 1));
158                         fl_select_browser_line(dialog_->browser, i+1);
159                 }
160         }
161 }
162
163
164 void FormRef::apply()
165 {
166         if (!lv_->view()->available())
167                 return;
168
169         Type const type = static_cast<Type>(fl_get_choice(dialog_->type) - 1);
170         params.setCmdName(getName(type));
171
172         params.setOptions(fl_get_input(dialog_->name));
173         params.setContents(fl_get_input(dialog_->ref));
174
175         if (inset_ != 0) {
176                 // Only update if contents have changed
177                 if (params != inset_->params()) {
178                         inset_->setParams(params);
179                         lv_->view()->updateInset(inset_, true);
180                 }
181         } else {
182                 lv_->getLyXFunc()->Dispatch(LFUN_REF_INSERT,
183                                             params.getAsString());
184         }
185 }
186
187
188 bool FormRef::input(FL_OBJECT *, long data)
189 {
190         bool activate(true);
191         switch (data) {
192         // goto reference / go back
193         case 1:
194         {
195                 // No change to data
196                 activate = false;
197                 
198                 toggle = static_cast<Goto>(toggle + 1);
199                 if (toggle == GOFIRST ) toggle = GOREF;
200         
201                 switch (toggle) {
202                 case GOREF:
203                 {
204                         lv_->getLyXFunc()->
205                                 Dispatch(LFUN_REF_GOTO,
206                                          params.getContents());
207                         fl_set_object_label(dialog_->button_go, _("Go back"));
208                 }
209                 break;
210
211                 case GOBACK:
212                 {
213                         lv_->getLyXFunc()->Dispatch(LFUN_REF_BACK);
214                         fl_set_object_label(dialog_->button_go,
215                                             _("Goto reference"));
216                 }
217                 break;
218
219                 default:
220                         break;
221                 }
222         }
223         break;
224
225         // choose browser key
226         case 2:
227         {
228                 unsigned int sel = fl_get_browser(dialog_->browser);
229                 if (sel < 1 || sel > refs.size()) break;
230
231                 if (!lv_->buffer()->isReadonly()) {
232                         string s = fl_get_browser_line(dialog_->browser, sel);
233                         fl_set_input(dialog_->ref, s.c_str());
234                 }
235
236                 toggle = GOBACK;
237                 lv_->getLyXFunc()->Dispatch(LFUN_REF_BACK);
238                 fl_set_object_label(dialog_->button_go, _("Goto reference"));
239
240                 fl_activate_object(dialog_->type);
241                 fl_set_object_lcol(dialog_->type, FL_BLACK);
242                 fl_activate_object(dialog_->button_go);
243                 fl_set_object_lcol(dialog_->button_go, FL_BLACK);
244                 fl_set_object_lcol(dialog_->ref, FL_BLACK);
245         }
246         break;
247
248         // update or sort
249         case 3:
250         {
251                 fl_freeze_form(form());
252                 updateBrowser(refs);
253                 fl_unfreeze_form(form());
254         }
255         break;
256
257         // changed reference type
258         case 4:
259         {
260                 Type type = static_cast<Type>( 
261                         fl_get_choice(dialog_->type) - 1);
262                 if (params.getCmdName() == getName(type)
263                     && inset_) {
264                         activate = false;
265                 }
266         }
267         break;
268
269         default:
270                 break;
271         }
272
273         return activate;
274 }
275
276
277 FormRef::Type FormRef::getType() const
278 {
279         Type type;
280
281         if (params.getCmdName() == "ref" )
282                 type = REF;
283
284         else if (params.getCmdName() == "pageref" )
285                 type = PAGEREF;
286
287         else if (params.getCmdName() == "vref" )
288                 type = VREF;
289
290         else if (params.getCmdName() == "vpageref" )
291                 type = VPAGEREF;
292
293         else
294                 type = PRETTYREF;
295         
296         return type;
297 }
298
299
300 string const FormRef::getName(Type type) const
301 {
302         string name;
303
304         switch (type) {
305         case REF:
306                 name = "ref";
307                 break;
308         case PAGEREF:
309                 name = "pageref";
310                 break;
311         case VREF:
312                 name = "vref";
313                 break;
314         case VPAGEREF:
315                 name = "vpageref";
316                 break;
317         case PRETTYREF:
318                 name = "prettyref";
319                 break;
320         }
321         
322         return name;
323 }