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