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/lstrings.h"
26 #include "support/lyxalgo.h"
28 #include "lyx_forms.h"
30 using lyx::support::ChangeExtension;
31 using lyx::support::compare;
32 using lyx::support::contains;
33 using lyx::support::getStringFromVector;
34 using lyx::support::getVectorFromString;
35 using lyx::support::OnlyFilename;
36 using lyx::support::prefixIs;
37 using lyx::support::split;
42 typedef FormController<ControlBibtex, FormView<FD_bibtex> > base_class;
44 FormBibtex::FormBibtex(Dialog & parent)
45 : base_class(parent, _("BibTeX Database"))
49 void FormBibtex::build()
51 dialog_.reset(build_bibtex(this));
53 // Manage the ok, apply, restore and cancel/close buttons
54 bcview().setOK(dialog_->button_ok);
55 bcview().setApply(dialog_->button_apply);
56 bcview().setCancel(dialog_->button_close);
57 bcview().setRestore(dialog_->button_restore);
59 // disable for read-only documents
60 bcview().addReadOnly(dialog_->input_database);
61 bcview().addReadOnly(dialog_->button_database_browse);
62 bcview().addReadOnly(dialog_->button_style_browse);
63 bcview().addReadOnly(dialog_->button_rescan);
64 bcview().addReadOnly(dialog_->input_style);
65 bcview().addReadOnly(dialog_->check_bibtotoc);
67 // trigger an input event for cut&paste with middle mouse button.
68 setPrehandler(dialog_->input_database);
69 setPrehandler(dialog_->input_style);
71 fl_set_input_return(dialog_->input_database, FL_RETURN_CHANGED);
72 fl_set_input_return(dialog_->input_style, FL_RETURN_CHANGED);
74 // callback for double click in browser
75 fl_set_browser_dblclick_callback(dialog_->browser_styles,
76 C_FormDialogView_InputCB, 2);
78 // set up the tooltips
79 string str = _("The database you want to cite from. Insert it "
80 "without the default extension \".bib\". Use comma "
81 "to separate databases.");
82 tooltips().init(dialog_->button_database_browse, str);
84 str = _("Browse directory for BibTeX stylefiles");
85 tooltips().init(dialog_->button_style_browse, str);
87 str = _("The BibTeX style to use (only one allowed). Insert it without "
88 "the default extension \".bst\" and without path.");
89 tooltips().init(dialog_->input_style, str);
91 str = _("Select if the bibliography should appear in the Table "
93 tooltips().init(dialog_->check_bibtotoc, str);
95 str = _("Double click to choose a BibTeX style from the list.");
96 tooltips().init(dialog_->browser_styles, str);
98 #if FL_VERSION == 0 || (FL_REVISION == 0 && FL_FIXLEVEL == 0)
99 // Work-around xforms' bug; enable tooltips for browser widgets.
100 setPrehandler(dialog_->browser_styles);
103 str = _("Updates your TeX system for a new bibstyle list. Only "
104 "the styles which are in directories where TeX finds them "
106 tooltips().init(dialog_->button_rescan, str);
110 ButtonPolicy::SMInput FormBibtex::input(FL_OBJECT * ob, long ob_value)
112 if (ob == dialog_->button_database_browse) {
113 // When browsing, take the first file only
114 string const in_name = getString(dialog_->input_database);
116 controller().Browse("",
117 _("Select Database"),
118 _("*.bib| BibTeX Databases (*.bib)"));
119 if (!out_name.empty()) {
120 // add the database to any existing ones
121 if (!in_name.empty())
122 out_name = in_name + ',' + out_name;
124 fl_set_input(dialog_->input_database, out_name.c_str());
127 } else if (ob == dialog_->button_style_browse) {
128 string const in_name = getString(dialog_->input_style);
129 string const style = controller().Browse(in_name,
130 _("Select BibTeX-Style"),
131 _("*.bst| BibTeX Styles (*.bst)"));
132 if (!style.empty()) {
133 fl_set_input(dialog_->input_style, style.c_str());
136 } else if (ob == dialog_->browser_styles && ob_value == 2) {
137 // double clicked in styles browser
138 string const style = getString(dialog_->browser_styles);
140 return ButtonPolicy::SMI_NOOP;
142 fl_set_input(dialog_->input_style,
143 ChangeExtension(style, "").c_str());
145 // reset the browser so that the following
146 // single-click callback doesn't do anything
147 fl_deselect_browser(dialog_->browser_styles);
149 } else if (ob == dialog_->button_rescan) {
150 fl_clear_browser(dialog_->browser_styles);
151 controller().rescanBibStyles();
152 vector<string> styles;
153 controller().getBibStyles(styles);
154 fl_add_browser_line(dialog_->browser_styles,
155 getStringFromVector(styles, "\n").c_str());
158 // with an empty database nothing makes sense ...
159 if (!compare(fl_get_input(dialog_->input_database), "")) {
160 return ButtonPolicy::SMI_NOOP;
163 return ButtonPolicy::SMI_VALID;
167 void FormBibtex::update()
169 fl_set_input(dialog_->input_database,
170 controller().params().getContents().c_str());
172 string bibtotoc = "bibtotoc";
173 string bibstyle = controller().params().getOptions();
175 bool const bibtotoc_exists = prefixIs(bibstyle, bibtotoc);
176 fl_set_button(dialog_->check_bibtotoc, bibtotoc_exists);
177 if (bibtotoc_exists) {
178 if (contains(bibstyle, ',')) { // bibstyle exists?
179 bibstyle = split(bibstyle, bibtotoc, ',');
184 fl_set_input(dialog_->input_style, bibstyle.c_str());
186 vector<string> styles;
187 controller().getBibStyles(styles);
189 fl_clear_browser(dialog_->browser_styles);
190 fl_add_browser_line(dialog_->browser_styles,
191 getStringFromVector(styles, "\n").c_str());
196 string const unique_and_no_extensions(string const & str_in)
198 vector<string> dbase = getVectorFromString(str_in);
199 for (vector<string>::iterator it = dbase.begin();
200 it != dbase.end(); ++it) {
201 *it = ChangeExtension(*it, string());
203 lyx::eliminate_duplicates(dbase);
204 return getStringFromVector(dbase);
210 void FormBibtex::apply()
212 string const db = getString(dialog_->input_database);
214 // no database -> no bibtex-command and no options!
215 controller().params().setContents("");
216 controller().params().setOptions("");
220 controller().params().setContents(unique_and_no_extensions(db));
223 string bibstyle = getString(dialog_->input_style);
224 if (!bibstyle.empty()) {
225 // save the BibTeX style without any ".bst" extension
226 bibstyle = ChangeExtension(OnlyFilename(bibstyle), "");
229 bool const addtotoc = fl_get_button(dialog_->check_bibtotoc);
230 string const bibtotoc = addtotoc ? "bibtotoc" : "";
231 if (addtotoc && !bibstyle.empty()) {
232 // Both bibtotoc and style.
233 controller().params().setOptions(bibtotoc + ',' + bibstyle);
236 // At least one of addtotoc and bibstyle is empty. No harm to output both!
237 controller().params().setOptions(bibtotoc + bibstyle);