]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormBibtex.C
Change glob() API to accept a dir parameter.
[lyx.git] / src / frontends / xforms / FormBibtex.C
1 /**
2  * \file FormBibtex.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  * \author John Levon
8  * \author Herbert Voß
9  * \author Rob Lahaye
10  *
11  * Full author contact details are available in file CREDITS.
12  */
13
14 #include <config.h>
15
16 #include "FormBibtex.h"
17 #include "ControlBibtex.h"
18 #include "forms/form_bibtex.h"
19
20 #include "Tooltips.h"
21 #include "xforms_helpers.h"
22 #include "xformsBC.h"
23
24 #include "support/filetools.h"
25 #include "support/lstrings.h"
26 #include "support/lyxalgo.h"
27
28 #include "lyx_forms.h"
29
30 using std::vector;
31 using std::string;
32
33 namespace lyx {
34
35 using support::ChangeExtension;
36 using support::compare;
37 using support::contains;
38 using support::FileFilterList;
39 using support::getStringFromVector;
40 using support::getVectorFromString;
41 using support::OnlyFilename;
42 using support::prefixIs;
43 using support::split;
44
45 namespace frontend {
46
47
48 typedef FormController<ControlBibtex, FormView<FD_bibtex> > base_class;
49
50 FormBibtex::FormBibtex(Dialog & parent)
51         : base_class(parent, _("BibTeX Database"))
52 {}
53
54
55 void FormBibtex::build()
56 {
57         dialog_.reset(build_bibtex(this));
58
59         // Manage the ok, apply, restore and cancel/close buttons
60         bcview().setOK(dialog_->button_ok);
61         bcview().setApply(dialog_->button_apply);
62         bcview().setCancel(dialog_->button_close);
63         bcview().setRestore(dialog_->button_restore);
64
65         // disable for read-only documents
66         bcview().addReadOnly(dialog_->input_database);
67         bcview().addReadOnly(dialog_->button_database_browse);
68         bcview().addReadOnly(dialog_->button_style_browse);
69         bcview().addReadOnly(dialog_->button_rescan);
70         bcview().addReadOnly(dialog_->input_style);
71         bcview().addReadOnly(dialog_->check_bibtotoc);
72         bcview().addReadOnly(dialog_->choice_btprint);
73
74         // trigger an input event for cut&paste with middle mouse button.
75         setPrehandler(dialog_->input_database);
76         setPrehandler(dialog_->input_style);
77
78         fl_set_input_return(dialog_->input_database, FL_RETURN_CHANGED);
79         fl_set_input_return(dialog_->input_style, FL_RETURN_CHANGED);
80
81         // callback for double click in browser
82         fl_set_browser_dblclick_callback(dialog_->browser_styles,
83                                          C_FormDialogView_InputCB, 2);
84
85         fl_addto_choice(dialog_->choice_btprint,
86                         _(" all cited references "
87                           "| all uncited references "
88                           "| all references ").c_str());
89
90         // set up the tooltips
91         string str = _("The database you want to cite from. Insert it "
92                        "without the default extension \".bib\". Use comma "
93                        "to separate databases.");
94         tooltips().init(dialog_->button_database_browse, str);
95
96         str = _("Browse directory for BibTeX stylefiles");
97         tooltips().init(dialog_->button_style_browse, str);
98
99         str = _("The BibTeX style to use (only one allowed). Insert it without "
100                 "the default extension \".bst\" and without path.");
101         tooltips().init(dialog_->input_style, str);
102
103         str = _("Select if the bibliography should appear in the Table "
104                 "of Contents");
105         tooltips().init(dialog_->check_bibtotoc, str);
106
107         str = _("Double click to choose a BibTeX style from the list.");
108         tooltips().init(dialog_->browser_styles, str);
109
110 #if FL_VERSION == 0 || (FL_REVISION == 0 && FL_FIXLEVEL == 0)
111         // Work-around xforms' bug; enable tooltips for browser widgets.
112         setPrehandler(dialog_->browser_styles);
113 #endif
114
115         str = _("Updates your TeX system for a new bibstyle list. Only "
116                 "the styles which are in directories where TeX finds them "
117                 "are listed!");
118         tooltips().init(dialog_->button_rescan, str);
119
120         str = _("The bibliography section contains...");
121         tooltips().init(dialog_->choice_btprint, str);
122 }
123
124
125 ButtonPolicy::SMInput FormBibtex::input(FL_OBJECT * ob, long ob_value)
126 {
127         if (ob == dialog_->button_database_browse) {
128                 // When browsing, take the first file only
129                 string const in_name = getString(dialog_->input_database);
130                 string out_name = controller().browseBib("");
131                 if (!out_name.empty()) {
132                         // add the database to any existing ones
133                         if (!in_name.empty())
134                                 out_name = in_name + ',' + out_name;
135
136                         fl_set_input(dialog_->input_database, out_name.c_str());
137                 }
138
139         } else if (ob == dialog_->button_style_browse) {
140                 string const in_name = getString(dialog_->input_style);
141                 string const style = controller().browseBst(in_name);
142                 if (!style.empty()) {
143                         fl_set_input(dialog_->input_style, style.c_str());
144                 }
145
146         } else if (ob == dialog_->browser_styles && ob_value == 2) {
147                 // double clicked in styles browser
148                 string const style = getString(dialog_->browser_styles);
149                 if (style.empty()) {
150                         return ButtonPolicy::SMI_NOOP;
151                 } else {
152                         fl_set_input(dialog_->input_style,
153                                         ChangeExtension(style, "").c_str());
154                 }
155                 // reset the browser so that the following
156                 // single-click callback doesn't do anything
157                 fl_deselect_browser(dialog_->browser_styles);
158
159         } else if (ob == dialog_->button_rescan) {
160                 fl_clear_browser(dialog_->browser_styles);
161                 controller().rescanBibStyles();
162                 vector<string> styles;
163                 controller().getBibStyles(styles);
164                 fl_add_browser_line(dialog_->browser_styles,
165                                     getStringFromVector(styles, "\n").c_str());
166         }
167
168         // with an empty database nothing makes sense ...
169         if (!compare(fl_get_input(dialog_->input_database), "")) {
170                 return ButtonPolicy::SMI_NOOP;
171         }
172
173         return ButtonPolicy::SMI_VALID;
174 }
175
176
177 void FormBibtex::update()
178 {
179         fl_set_input(dialog_->input_database,
180                      controller().params().getContents().c_str());
181
182         string bibtotoc = "bibtotoc";
183         string bibstyle = controller().params().getOptions();
184
185         bool const bibtopic = controller().usingBibtopic();
186         bool const bibtotoc_exists = prefixIs(bibstyle, bibtotoc);
187         fl_set_button(dialog_->check_bibtotoc, bibtotoc_exists && !bibtopic);
188         setEnabled(dialog_->check_bibtotoc, !bibtopic);
189         if (bibtotoc_exists) {
190                 if (contains(bibstyle, ',')) { // bibstyle exists?
191                         bibstyle = split(bibstyle, bibtotoc, ',');
192                 } else {
193                         bibstyle.erase();
194                 }
195         }
196         fl_set_input(dialog_->input_style, bibstyle.c_str());
197
198         string btprint = controller().params().getSecOptions();
199         int btp = 1;
200         if (btprint == "btPrintNotCited")
201                 btp = 2;
202         else if (btprint == "btPrintAll")
203                 btp = 3;
204
205         fl_set_choice(dialog_->choice_btprint, btp);
206         setEnabled(dialog_->choice_btprint, bibtopic);
207
208         vector<string> styles;
209         controller().getBibStyles(styles);
210
211         fl_clear_browser(dialog_->browser_styles);
212         fl_add_browser_line(dialog_->browser_styles,
213                             getStringFromVector(styles, "\n").c_str());
214 }
215
216 namespace {
217
218 string const unique_and_no_extensions(string const & str_in)
219 {
220         vector<string> dbase = getVectorFromString(str_in);
221         for (vector<string>::iterator it = dbase.begin();
222              it != dbase.end(); ++it) {
223                 *it = ChangeExtension(*it, string());
224         }
225         eliminate_duplicates(dbase);
226         return getStringFromVector(dbase);
227 }
228
229 } // namespace anon
230
231
232 void FormBibtex::apply()
233 {
234         string const db = getString(dialog_->input_database);
235         if (db.empty()) {
236                 // no database -> no bibtex-command and no options!
237                 controller().params().setContents("");
238                 controller().params().setOptions("");
239                 controller().params().setSecOptions("");
240                 return;
241         }
242
243         controller().params().setContents(unique_and_no_extensions(db));
244
245         // empty is valid!
246         string bibstyle = getString(dialog_->input_style);
247         if (!bibstyle.empty()) {
248                 // save the BibTeX style without any ".bst" extension
249                 bibstyle = ChangeExtension(OnlyFilename(bibstyle), "");
250         }
251
252         bool const addtotoc = fl_get_button(dialog_->check_bibtotoc);
253         string const bibtotoc = addtotoc ? "bibtotoc" : "";
254         if (addtotoc && !bibstyle.empty()) {
255                 // Both bibtotoc and style.
256                 controller().params().setOptions(bibtotoc + ',' + bibstyle);
257
258         } else {
259                 // At least one of addtotoc and bibstyle is empty.
260                 // No harm to output both!
261                 controller().params().setOptions(bibtotoc + bibstyle);
262         }
263
264         // bibtopic allows three kinds of sections:
265         // 1. sections that include all cited references of the database(s)
266         // 2. sec. that include all uncited references of the database(s)
267         // 3. sec. that include all references of the database(s), cited or not
268         if (controller().usingBibtopic()){
269                 int btp = fl_get_choice(dialog_->choice_btprint);
270                 switch (btp) {
271                 case 1:
272                         controller().params().setSecOptions("btPrintCited");
273                         break;
274                 case 2:
275                         controller().params().setSecOptions("btPrintNotCited");
276                         break;
277                 case 3:
278                         controller().params().setSecOptions("btPrintAll");
279                         break;
280                 }
281         }
282
283         else
284                 controller().params().setSecOptions("");
285
286 }
287
288 } // namespace frontend
289 } // namespace lyx