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