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