]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormRef.C
This file is part of LyX, the document processor.
[lyx.git] / src / frontends / xforms / FormRef.C
1 /**
2  * \file xforms/FormRef.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Angus Leeming 
7  *
8  * Full author contact details are available in file CREDITS
9  */
10
11 #include <config.h>
12 #include <algorithm>
13
14 #ifdef __GNUG__
15 #pragma implementation
16 #endif
17
18 #include "xformsBC.h"
19 #include "ControlRef.h"
20 #include "FormRef.h"
21 #include "forms/form_ref.h"
22 #include "xforms_helpers.h"
23 #include "insets/insetref.h"
24 #include "helper_funcs.h" // getStringFromVector
25 #include "support/lstrings.h" // frontStrip, strip
26 #include FORMS_H_LOCATION
27
28 using std::find;
29 using std::max;
30 using std::sort;
31 using std::vector;
32
33 typedef FormCB<ControlRef, FormDB<FD_ref> > base_class;
34
35 FormRef::FormRef()
36         : base_class(_("Reference")),
37           at_ref_(false)
38 {}
39
40
41 void FormRef::build()
42 {
43         dialog_.reset(build_ref(this));
44
45         for (int i = 0; !InsetRef::types[i].latex_name.empty(); ++i)
46                 fl_addto_choice(dialog_->choice_type,
47                                 _(InsetRef::types[i].gui_name.c_str()));
48
49         // Force the user to use the browser to change refs.
50         fl_deactivate_object(dialog_->input_ref);
51
52         fl_set_input_return(dialog_->input_name, FL_RETURN_CHANGED);
53         fl_set_input_return(dialog_->input_ref,  FL_RETURN_CHANGED);
54
55         setPrehandler(dialog_->input_name);
56         setPrehandler(dialog_->input_ref);
57
58         // Manage the ok and cancel/close buttons
59         bc().setOK(dialog_->button_ok);
60         bc().setApply(dialog_->button_apply);
61         bc().setCancel(dialog_->button_close);
62         bc().setRestore(dialog_->button_restore);
63
64         bc().addReadOnly(dialog_->button_update);
65         bc().addReadOnly(dialog_->input_name);
66         bc().addReadOnly(dialog_->input_ref);
67 }
68
69
70 void FormRef::update()
71 {
72         fl_set_input(dialog_->input_ref,
73                      controller().params().getContents().c_str());
74         fl_set_input(dialog_->input_name,
75                      controller().params().getOptions().c_str());
76         fl_set_choice(dialog_->choice_type,
77                       InsetRef::getType(controller().params().getCmdName()) + 1);
78
79         at_ref_ = false;
80         fl_set_object_label(dialog_->button_go, _("Go to reference"));
81
82         // Name is irrelevant to LaTeX/Literate documents
83         if (controller().docType() == ControlRef::LATEX ||
84             controller().docType() == ControlRef::LITERATE) {
85                 setEnabled(dialog_->input_name, false);
86         } else {
87                 setEnabled(dialog_->input_name, true);
88         }
89
90         // type is irrelevant to LinuxDoc/DocBook.
91         if (controller().docType() == ControlRef::LINUXDOC ||
92             controller().docType() == ControlRef::DOCBOOK) {
93                 fl_set_choice(dialog_->choice_type, 1);
94                 setEnabled(dialog_->choice_type, false);
95         } else {
96                 setEnabled(dialog_->choice_type, true);
97         }
98
99         // Get the available buffers
100         vector<string> const buffers = controller().getBufferList();
101         vector<string> const choice_buffers =
102                 getVector(dialog_->choice_buffer);
103
104         // If different from the current contents of the choice, then update it
105         if (buffers != choice_buffers) {
106                 // create a string of entries " entry1 | entry2 | entry3 "
107                 // with which to initialise the xforms choice object.
108                 string const choice =
109                         " " + getStringFromVector(buffers, " | ") + " ";
110
111                 fl_clear_choice(dialog_->choice_buffer);
112                 fl_addto_choice(dialog_->choice_buffer, choice.c_str());
113
114                 fl_set_choice(dialog_->choice_buffer,
115                               controller().getBufferNum() + 1);
116         }
117
118         string const name = controller().
119                 getBufferName(fl_get_choice(dialog_->choice_buffer) - 1);
120         refs_ = controller().getLabelList(name);
121
122         updateBrowser(refs_);
123 }
124
125
126 void FormRef::updateBrowser(vector<string> const & akeys) const
127 {
128         vector<string> keys(akeys);
129         if (fl_get_button(dialog_->check_sort))
130                 sort(keys.begin(), keys.end());
131
132         vector<string> browser_keys = getVector(dialog_->browser_refs);
133
134         if (browser_keys == keys)
135                 return;
136
137         fl_clear_browser(dialog_->browser_refs);
138         for (vector<string>::const_iterator it = keys.begin();
139              it != keys.end(); ++it)
140                 fl_add_browser_line(dialog_->browser_refs, it->c_str());
141
142         if (keys.empty()) {
143                 fl_add_browser_line(dialog_->browser_refs,
144                                     _("*** No labels found in document ***"));
145
146                 setEnabled(dialog_->browser_refs, false);
147                 setEnabled(dialog_->check_sort,   false);
148
149                 fl_set_input(dialog_->input_ref, "");
150         } else {
151                 setEnabled(dialog_->browser_refs, true);
152                 setEnabled(dialog_->check_sort,   true);
153
154                 string ref = fl_get_input(dialog_->input_ref);
155                 vector<string>::const_iterator cit = (ref.empty())
156                         ? keys.begin()
157                         : find(keys.begin(), keys.end(), ref);
158                 if (cit == keys.end()) {
159                         fl_deselect_browser(dialog_->browser_refs);
160                 } else {
161                         if (ref.empty())
162                                 fl_set_input(dialog_->input_ref, cit->c_str());
163
164                         int const i = static_cast<int>(cit - keys.begin());
165                         fl_set_browser_topline(dialog_->browser_refs, max(i-5, 1));
166                         fl_select_browser_line(dialog_->browser_refs, i+1);
167                 }
168         }
169 }
170
171
172 void FormRef::apply()
173 {
174         int const type = fl_get_choice(dialog_->choice_type) - 1;
175         controller().params().setCmdName(InsetRef::getName(type));
176
177         controller().params().setOptions(fl_get_input(dialog_->input_name));
178         controller().params().setContents(fl_get_input(dialog_->input_ref));
179 }
180
181
182 ButtonPolicy::SMInput FormRef::input(FL_OBJECT * ob, long)
183 {
184         ButtonPolicy::SMInput activate(ButtonPolicy::SMI_VALID);
185
186         if (ob == dialog_->button_go) {
187                 // goto reference / go back
188
189                 // No change to data
190                 activate = ButtonPolicy::SMI_NOOP;
191
192                 at_ref_ = !at_ref_;
193                 if (at_ref_) {
194                         controller().gotoRef(fl_get_input(dialog_->input_ref));
195                         fl_set_object_label(dialog_->button_go, _("Go back"));
196                 } else {
197                         controller().gotoBookmark();
198                         fl_set_object_label(dialog_->button_go,
199                                             _("Go to reference"));
200                 }
201
202         } else if (ob == dialog_->browser_refs) {
203
204                 unsigned int sel = fl_get_browser(dialog_->browser_refs);
205                 if (sel < 1 || sel > refs_.size())
206                         return ButtonPolicy::SMI_NOOP;
207
208                 if (!controller().bufferIsReadonly()) {
209                         string s = fl_get_browser_line(dialog_->browser_refs, sel);
210                         fl_set_input(dialog_->input_ref, s.c_str());
211                 }
212
213                 if (at_ref_)
214                         controller().gotoBookmark();
215                 at_ref_ = false;
216                 fl_set_object_label(dialog_->button_go, _("Go to reference"));
217
218                 setEnabled(dialog_->choice_type,      true);
219                 setEnabled(dialog_->button_go, true);
220                 fl_set_object_lcol(dialog_->input_ref, FL_BLACK);
221
222         } else if (ob == dialog_->button_update ||
223                    ob == dialog_->check_sort ||
224                    ob == dialog_->choice_buffer) {
225
226                 if (ob == dialog_->button_update ||
227                     ob == dialog_->choice_buffer) {
228                         string const name =
229                                 controller().getBufferName(fl_get_choice(dialog_->choice_buffer) - 1);
230                         refs_ = controller().getLabelList(name);
231                 }
232
233                 fl_freeze_form(form());
234                 updateBrowser(refs_);
235                 fl_unfreeze_form(form());
236
237         } else if (ob == dialog_->choice_type) {
238
239                 int const type = fl_get_choice(dialog_->choice_type) - 1;
240                 if (controller().params().getCmdName() ==
241                     InsetRef::getName(type)) {
242                         activate = ButtonPolicy::SMI_NOOP;
243                 }
244         }
245
246         return activate;
247 }