3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Angus Leeming
11 * Full author contact details are available in file CREDITS.
16 #include "FormBibtex.h"
17 #include "ControlBibtex.h"
18 #include "forms/form_bibtex.h"
21 #include "xforms_helpers.h"
24 #include "support/filetools.h"
25 #include "support/globbing.h"
26 #include "support/lstrings.h"
27 #include "support/lyxalgo.h"
29 #include "lyx_forms.h"
31 using lyx::support::ChangeExtension;
32 using lyx::support::compare;
33 using lyx::support::contains;
34 using lyx::support::FileFilterList;
35 using lyx::support::getStringFromVector;
36 using lyx::support::getVectorFromString;
37 using lyx::support::OnlyFilename;
38 using lyx::support::prefixIs;
39 using lyx::support::split;
45 typedef FormController<ControlBibtex, FormView<FD_bibtex> > base_class;
47 FormBibtex::FormBibtex(Dialog & parent)
48 : base_class(parent, _("BibTeX Database"))
52 void FormBibtex::build()
54 dialog_.reset(build_bibtex(this));
56 // Manage the ok, apply, restore and cancel/close buttons
57 bcview().setOK(dialog_->button_ok);
58 bcview().setApply(dialog_->button_apply);
59 bcview().setCancel(dialog_->button_close);
60 bcview().setRestore(dialog_->button_restore);
62 // disable for read-only documents
63 bcview().addReadOnly(dialog_->input_database);
64 bcview().addReadOnly(dialog_->button_database_browse);
65 bcview().addReadOnly(dialog_->button_style_browse);
66 bcview().addReadOnly(dialog_->button_rescan);
67 bcview().addReadOnly(dialog_->input_style);
68 bcview().addReadOnly(dialog_->check_bibtotoc);
69 bcview().addReadOnly(dialog_->choice_btprint);
71 // trigger an input event for cut&paste with middle mouse button.
72 setPrehandler(dialog_->input_database);
73 setPrehandler(dialog_->input_style);
75 fl_set_input_return(dialog_->input_database, FL_RETURN_CHANGED);
76 fl_set_input_return(dialog_->input_style, FL_RETURN_CHANGED);
78 // callback for double click in browser
79 fl_set_browser_dblclick_callback(dialog_->browser_styles,
80 C_FormDialogView_InputCB, 2);
82 fl_addto_choice(dialog_->choice_btprint,
83 _(" all cited references "
84 "| all uncited references "
85 "| all references ").c_str());
87 // set up the tooltips
88 string str = _("The database you want to cite from. Insert it "
89 "without the default extension \".bib\". Use comma "
90 "to separate databases.");
91 tooltips().init(dialog_->button_database_browse, str);
93 str = _("Browse directory for BibTeX stylefiles");
94 tooltips().init(dialog_->button_style_browse, str);
96 str = _("The BibTeX style to use (only one allowed). Insert it without "
97 "the default extension \".bst\" and without path.");
98 tooltips().init(dialog_->input_style, str);
100 str = _("Select if the bibliography should appear in the Table "
102 tooltips().init(dialog_->check_bibtotoc, str);
104 str = _("Double click to choose a BibTeX style from the list.");
105 tooltips().init(dialog_->browser_styles, str);
107 #if FL_VERSION == 0 || (FL_REVISION == 0 && FL_FIXLEVEL == 0)
108 // Work-around xforms' bug; enable tooltips for browser widgets.
109 setPrehandler(dialog_->browser_styles);
112 str = _("Updates your TeX system for a new bibstyle list. Only "
113 "the styles which are in directories where TeX finds them "
115 tooltips().init(dialog_->button_rescan, str);
117 str = _("The bibliography section contains...");
118 tooltips().init(dialog_->choice_btprint, str);
122 ButtonPolicy::SMInput FormBibtex::input(FL_OBJECT * ob, long ob_value)
124 if (ob == dialog_->button_database_browse) {
125 // When browsing, take the first file only
126 string const in_name = getString(dialog_->input_database);
128 filter(_("*.bib| BibTeX Databases (*.bib)"));
130 controller().browse("", _("Select Database"),
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;
137 fl_set_input(dialog_->input_database, out_name.c_str());
140 } else if (ob == dialog_->button_style_browse) {
141 string const in_name = getString(dialog_->input_style);
143 filter(_("*.bst| BibTeX Styles (*.bst)"));
144 string const style = controller()
145 .browse(in_name, _("Select BibTeX-Style"), filter);
146 if (!style.empty()) {
147 fl_set_input(dialog_->input_style, style.c_str());
150 } else if (ob == dialog_->browser_styles && ob_value == 2) {
151 // double clicked in styles browser
152 string const style = getString(dialog_->browser_styles);
154 return ButtonPolicy::SMI_NOOP;
156 fl_set_input(dialog_->input_style,
157 ChangeExtension(style, "").c_str());
159 // reset the browser so that the following
160 // single-click callback doesn't do anything
161 fl_deselect_browser(dialog_->browser_styles);
163 } else if (ob == dialog_->button_rescan) {
164 fl_clear_browser(dialog_->browser_styles);
165 controller().rescanBibStyles();
166 vector<string> styles;
167 controller().getBibStyles(styles);
168 fl_add_browser_line(dialog_->browser_styles,
169 getStringFromVector(styles, "\n").c_str());
172 // with an empty database nothing makes sense ...
173 if (!compare(fl_get_input(dialog_->input_database), "")) {
174 return ButtonPolicy::SMI_NOOP;
177 return ButtonPolicy::SMI_VALID;
181 void FormBibtex::update()
183 fl_set_input(dialog_->input_database,
184 controller().params().getContents().c_str());
186 string bibtotoc = "bibtotoc";
187 string bibstyle = controller().params().getOptions();
189 bool const bibtopic = controller().usingBibtopic();
190 bool const bibtotoc_exists = prefixIs(bibstyle, bibtotoc);
191 fl_set_button(dialog_->check_bibtotoc, bibtotoc_exists && !bibtopic);
192 setEnabled(dialog_->check_bibtotoc, !bibtopic);
193 if (bibtotoc_exists) {
194 if (contains(bibstyle, ',')) { // bibstyle exists?
195 bibstyle = split(bibstyle, bibtotoc, ',');
200 fl_set_input(dialog_->input_style, bibstyle.c_str());
202 string btprint = controller().params().getSecOptions();
204 if (btprint == "btPrintNotCited")
206 else if (btprint == "btPrintAll")
209 fl_set_choice(dialog_->choice_btprint, btp);
210 setEnabled(dialog_->choice_btprint, bibtopic);
212 vector<string> styles;
213 controller().getBibStyles(styles);
215 fl_clear_browser(dialog_->browser_styles);
216 fl_add_browser_line(dialog_->browser_styles,
217 getStringFromVector(styles, "\n").c_str());
222 string const unique_and_no_extensions(string const & str_in)
224 vector<string> dbase = getVectorFromString(str_in);
225 for (vector<string>::iterator it = dbase.begin();
226 it != dbase.end(); ++it) {
227 *it = ChangeExtension(*it, string());
229 lyx::eliminate_duplicates(dbase);
230 return getStringFromVector(dbase);
236 void FormBibtex::apply()
238 string const db = getString(dialog_->input_database);
240 // no database -> no bibtex-command and no options!
241 controller().params().setContents("");
242 controller().params().setOptions("");
243 controller().params().setSecOptions("");
247 controller().params().setContents(unique_and_no_extensions(db));
250 string bibstyle = getString(dialog_->input_style);
251 if (!bibstyle.empty()) {
252 // save the BibTeX style without any ".bst" extension
253 bibstyle = ChangeExtension(OnlyFilename(bibstyle), "");
256 bool const addtotoc = fl_get_button(dialog_->check_bibtotoc);
257 string const bibtotoc = addtotoc ? "bibtotoc" : "";
258 if (addtotoc && !bibstyle.empty()) {
259 // Both bibtotoc and style.
260 controller().params().setOptions(bibtotoc + ',' + bibstyle);
263 // At least one of addtotoc and bibstyle is empty.
264 // No harm to output both!
265 controller().params().setOptions(bibtotoc + bibstyle);
268 // bibtopic allows three kinds of sections:
269 // 1. sections that include all cited references of the database(s)
270 // 2. sec. that include all uncited references of the database(s)
271 // 3. sec. that include all references of the database(s), cited or not
272 if (controller().usingBibtopic()){
273 int btp = fl_get_choice(dialog_->choice_btprint);
276 controller().params().setSecOptions("btPrintCited");
279 controller().params().setSecOptions("btPrintNotCited");
282 controller().params().setSecOptions("btPrintAll");
288 controller().params().setSecOptions("");