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