]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormBibtex.C
simple ws changes only
[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 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;
40
41 using std::vector;
42 using std::string;
43
44
45 typedef FormController<ControlBibtex, FormView<FD_bibtex> > base_class;
46
47 FormBibtex::FormBibtex(Dialog & parent)
48         : base_class(parent, _("BibTeX Database"))
49 {}
50
51
52 void FormBibtex::build()
53 {
54         dialog_.reset(build_bibtex(this));
55
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);
61
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);
70
71         // trigger an input event for cut&paste with middle mouse button.
72         setPrehandler(dialog_->input_database);
73         setPrehandler(dialog_->input_style);
74
75         fl_set_input_return(dialog_->input_database, FL_RETURN_CHANGED);
76         fl_set_input_return(dialog_->input_style, FL_RETURN_CHANGED);
77
78         // callback for double click in browser
79         fl_set_browser_dblclick_callback(dialog_->browser_styles,
80                                          C_FormDialogView_InputCB, 2);
81
82         fl_addto_choice(dialog_->choice_btprint,
83                         _(" all cited references "
84                           "| all uncited references "
85                           "| all references ").c_str());
86
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);
92
93         str = _("Browse directory for BibTeX stylefiles");
94         tooltips().init(dialog_->button_style_browse, str);
95
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);
99
100         str = _("Select if the bibliography should appear in the Table "
101                 "of Contents");
102         tooltips().init(dialog_->check_bibtotoc, str);
103
104         str = _("Double click to choose a BibTeX style from the list.");
105         tooltips().init(dialog_->browser_styles, str);
106
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);
110 #endif
111
112         str = _("Updates your TeX system for a new bibstyle list. Only "
113                 "the styles which are in directories where TeX finds them "
114                 "are listed!");
115         tooltips().init(dialog_->button_rescan, str);
116
117         str = _("The bibliography section contains...");
118         tooltips().init(dialog_->choice_btprint, str);
119 }
120
121
122 ButtonPolicy::SMInput FormBibtex::input(FL_OBJECT * ob, long ob_value)
123 {
124         if (ob == dialog_->button_database_browse) {
125                 // When browsing, take the first file only
126                 string const in_name = getString(dialog_->input_database);
127                 FileFilterList const
128                         filter(_("*.bib| BibTeX Databases (*.bib)"));
129                 string out_name =
130                         controller().browse("", _("Select Database"),
131                                             filter);
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                 FileFilterList const
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());
148                 }
149
150         } else if (ob == dialog_->browser_styles && ob_value == 2) {
151                 // double clicked in styles browser
152                 string const style = getString(dialog_->browser_styles);
153                 if (style.empty()) {
154                         return ButtonPolicy::SMI_NOOP;
155                 } else {
156                         fl_set_input(dialog_->input_style,
157                                         ChangeExtension(style, "").c_str());
158                 }
159                 // reset the browser so that the following
160                 // single-click callback doesn't do anything
161                 fl_deselect_browser(dialog_->browser_styles);
162
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());
170         }
171
172         // with an empty database nothing makes sense ...
173         if (!compare(fl_get_input(dialog_->input_database), "")) {
174                 return ButtonPolicy::SMI_NOOP;
175         }
176
177         return ButtonPolicy::SMI_VALID;
178 }
179
180
181 void FormBibtex::update()
182 {
183         fl_set_input(dialog_->input_database,
184                      controller().params().getContents().c_str());
185
186         string bibtotoc = "bibtotoc";
187         string bibstyle = controller().params().getOptions();
188
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, ',');
196                 } else {
197                         bibstyle.erase();
198                 }
199         }
200         fl_set_input(dialog_->input_style, bibstyle.c_str());
201
202         string btprint = controller().params().getSecOptions();
203         int btp = 1;
204         if (btprint == "btPrintNotCited")
205                 btp = 2;
206         else if (btprint == "btPrintAll")
207                 btp = 3;
208
209         fl_set_choice(dialog_->choice_btprint, btp);
210         setEnabled(dialog_->choice_btprint, bibtopic);
211
212         vector<string> styles;
213         controller().getBibStyles(styles);
214
215         fl_clear_browser(dialog_->browser_styles);
216         fl_add_browser_line(dialog_->browser_styles,
217                             getStringFromVector(styles, "\n").c_str());
218 }
219
220 namespace {
221
222 string const unique_and_no_extensions(string const & str_in)
223 {
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());
228         }
229         lyx::eliminate_duplicates(dbase);
230         return getStringFromVector(dbase);
231 }
232
233 } // namespace anon
234
235
236 void FormBibtex::apply()
237 {
238         string const db = getString(dialog_->input_database);
239         if (db.empty()) {
240                 // no database -> no bibtex-command and no options!
241                 controller().params().setContents("");
242                 controller().params().setOptions("");
243                 controller().params().setSecOptions("");
244                 return;
245         }
246
247         controller().params().setContents(unique_and_no_extensions(db));
248
249         // empty is valid!
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), "");
254         }
255
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);
261
262         } else {
263                 // At least one of addtotoc and bibstyle is empty.
264                 // No harm to output both!
265                 controller().params().setOptions(bibtotoc + bibstyle);
266         }
267
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);
274                 switch (btp) {
275                 case 1:
276                         controller().params().setSecOptions("btPrintCited");
277                         break;
278                 case 2:
279                         controller().params().setSecOptions("btPrintNotCited");
280                         break;
281                 case 3:
282                         controller().params().setSecOptions("btPrintAll");
283                         break;
284                 }
285         }
286
287         else
288                 controller().params().setSecOptions("");
289 }