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