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