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