]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormRef.C
Fixed the behaviour of Goto-Ref (?)
[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 #include "insets/insetref.h"
28
29 #include <algorithm>
30
31 using std::find;
32 using std::max;
33 using std::sort;
34 using std::vector;
35
36 bool saved_position;
37
38 FormRef::FormRef(LyXView * lv, Dialogs * d)
39         : FormCommand(lv, d, _("Reference"), new NoRepeatedApplyPolicy),
40           at_ref(false), dialog_(0)
41 {
42         // let the dialog be shown
43         // These are permanent connections so we won't bother
44         // storing a copy because we won't be disconnecting.
45         d->showRef.connect(slot(this, &FormRef::showInset));
46         d->createRef.connect(slot(this, &FormRef::createInset));
47 }
48
49
50 FormRef::~FormRef()
51 {
52         delete dialog_;
53 }
54
55
56 FL_FORM * FormRef::form() const
57 {
58         if (dialog_) return dialog_->form;
59         return 0;
60 }
61
62
63 void FormRef::disconnect()
64 {
65         refs.clear();
66         FormCommand::disconnect();
67 }
68
69
70 void FormRef::build()
71 {
72         dialog_ = build_ref();
73
74         for (int i = 0; !InsetRef::types[i].latex_name.empty(); ++i)
75                 fl_addto_choice(dialog_->type,
76                                 _(InsetRef::types[i].gui_name.c_str()));
77
78         // Workaround dumb xforms sizing bug
79         minw_ = form()->w;
80         minh_ = form()->h;
81
82         // Force the user to use the browser to change refs.
83         fl_deactivate_object(dialog_->ref);
84
85         // Manage the ok and cancel/close buttons
86         bc_.setOK(dialog_->button_ok);
87         bc_.setApply(dialog_->button_apply);
88         bc_.setCancel(dialog_->button_cancel);
89         bc_.setUndoAll(dialog_->button_restore);
90         bc_.refresh();
91
92 #warning I had to uncomment this so the buttons could be disabled in update() (dekel)
93         //bc_.addReadOnly(dialog_->type);
94         //bc_.addReadOnly(dialog_->name);
95 }
96
97
98 void FormRef::update()
99 {
100         if (inset_) {
101                 fl_set_input(dialog_->ref,  params.getContents().c_str());
102                 fl_set_input(dialog_->name, params.getOptions().c_str());
103                 fl_set_choice(dialog_->type, 
104                               InsetRef::getType(params.getCmdName()) + 1);
105         }
106
107         at_ref = false;
108         fl_set_object_label(dialog_->button_go, _("Goto reference"));
109
110         // Name is irrelevant to LaTeX/Literate documents, while
111         // type is irrelevant to LinuxDoc/DocBook.
112         if (lv_->buffer()->isLatex() || lv_->buffer()->isLatex()) {
113                 fl_deactivate_object(dialog_->name);
114                 fl_set_object_lcol(dialog_->name, FL_INACTIVE);
115                 fl_activate_object(dialog_->type);
116                 fl_set_object_lcol(dialog_->type, FL_BLACK);
117         } else {
118                 fl_set_choice(dialog_->type, 1);
119
120                 fl_activate_object(dialog_->name);
121                 fl_set_object_lcol(dialog_->name, FL_BLACK);
122                 fl_deactivate_object(dialog_->type);
123                 fl_set_object_lcol(dialog_->type, FL_INACTIVE);
124         }
125
126         refs = lv_->buffer()->getLabelList();
127         updateBrowser(refs);
128
129         bc_.readOnly(lv_->buffer()->isReadonly());
130 }
131
132
133 void FormRef::updateBrowser(vector<string> const & akeys) const
134 {
135         vector<string> keys(akeys);
136         if (fl_get_button(dialog_->sort))
137                 sort(keys.begin(), keys.end());
138
139         fl_clear_browser(dialog_->browser);
140         for (vector<string>::const_iterator it = keys.begin();
141              it != keys.end(); ++it)
142                 fl_add_browser_line(dialog_->browser, (*it).c_str());
143
144         if (keys.empty()) {
145                 fl_add_browser_line(dialog_->browser,
146                                     _("*** No labels found in document ***"));
147
148                 fl_deactivate_object(dialog_->browser);
149                 fl_deactivate_object(dialog_->sort);
150                 fl_set_object_lcol(dialog_->browser, FL_INACTIVE);
151                 fl_set_object_lcol(dialog_->sort, FL_INACTIVE);
152                 fl_set_input(dialog_->ref, "");
153         } else {
154                 fl_activate_object(dialog_->browser);
155                 fl_set_object_lcol(dialog_->browser, FL_BLACK);
156                 fl_activate_object(dialog_->sort);
157                 fl_set_object_lcol(dialog_->sort, FL_BLACK);
158
159                 string ref = fl_get_input(dialog_->ref);
160                 vector<string>::const_iterator cit =
161                         find(keys.begin(), keys.end(), ref);
162                 if (cit == keys.end()) {
163                         cit = keys.begin();
164                         fl_set_input(dialog_->ref, (*cit).c_str());
165                 } else if (ref.empty())
166                         fl_set_input(dialog_->ref, (*cit).c_str());
167
168                 int const i = static_cast<int>(cit - keys.begin());
169                 fl_set_browser_topline(dialog_->browser, max(i-5, 1));
170                 fl_select_browser_line(dialog_->browser, i+1);
171         }
172 }
173
174
175 void FormRef::apply()
176 {
177         if (!lv_->view()->available())
178                 return;
179
180         int const type = fl_get_choice(dialog_->type) - 1;
181         params.setCmdName(InsetRef::getName(type));
182
183         params.setOptions(fl_get_input(dialog_->name));
184         params.setContents(fl_get_input(dialog_->ref));
185
186         if (inset_ != 0) {
187                 // Only update if contents have changed
188                 if (params != inset_->params()) {
189                         inset_->setParams(params);
190                         lv_->view()->updateInset(inset_, true);
191                 }
192         } else {
193                 lv_->getLyXFunc()->Dispatch(LFUN_REF_INSERT,
194                                             params.getAsString());
195         }
196 }
197
198
199 bool FormRef::input(FL_OBJECT *, long data)
200 {
201         bool activate(true);
202         switch (data) {
203         // goto reference / go back
204         case 1:
205         {
206                 // No change to data
207                 activate = false;
208                 
209                 at_ref = !at_ref;
210                 if (at_ref) {
211                         lv_->getLyXFunc()->Dispatch(LFUN_BOOKMARK_SAVE, "0");
212                         lv_->getLyXFunc()->
213                                 Dispatch(LFUN_REF_GOTO,
214                                          fl_get_input(dialog_->ref));
215                         fl_set_object_label(dialog_->button_go, _("Go back"));
216                 } else {
217                         lv_->getLyXFunc()->Dispatch(LFUN_BOOKMARK_GOTO, "0");
218                         fl_set_object_label(dialog_->button_go,
219                                             _("Goto reference"));
220                 }
221         }
222         break;
223
224         // choose browser key
225         case 2:
226         {
227                 unsigned int sel = fl_get_browser(dialog_->browser);
228                 if (sel < 1 || sel > refs.size()) break;
229
230                 if (!lv_->buffer()->isReadonly()) {
231                         string s = fl_get_browser_line(dialog_->browser, sel);
232                         fl_set_input(dialog_->ref, s.c_str());
233                 }
234
235                 if (at_ref)
236                         lv_->getLyXFunc()->Dispatch(LFUN_BOOKMARK_GOTO, "0");
237                 at_ref = false;
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                 refs = lv_->buffer()->getLabelList();
251
252                 // fall through to...
253         case 4:
254                 fl_freeze_form(form());
255                 updateBrowser(refs);
256                 fl_unfreeze_form(form());
257                 break;
258
259         // changed reference type
260         case 5:
261         {
262                 int const type = fl_get_choice(dialog_->type) - 1;
263                 if (params.getCmdName() == InsetRef::getName(type) && inset_) {
264                         activate = false;
265                 }
266         }
267         break;
268
269         default:
270                 break;
271         }
272
273         return activate;
274 }
275
276