]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormBibtex.C
This file is part of LyX, the document processor.
[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 Voss
9  *
10  * Full author contact details are available in file CREDITS
11  */
12
13 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #include <config.h>
18 #include "xformsBC.h"
19 #include "ControlBibtex.h"
20 #include "FormBibtex.h"
21 #include "forms/form_bibtex.h"
22 #include "Tooltips.h"
23 #include "xforms_helpers.h"
24 #include FORMS_H_LOCATION
25
26 #include "helper_funcs.h"
27 #include "gettext.h"
28 #include "debug.h"
29 #include "support/LAssert.h"
30 #include "support/lstrings.h"
31 #include "support/filetools.h"
32 #include "support/lyxalgo.h"
33
34
35 using std::vector;
36 using std::sort;
37
38
39 typedef FormCB<ControlBibtex, FormDB<FD_bibtex> > base_class;
40
41 FormBibtex::FormBibtex()
42         : base_class(_("BibTeX Database"))
43 {}
44
45
46 void FormBibtex::build()
47 {
48         dialog_.reset(build_bibtex(this));
49
50         fl_set_input_return(dialog_->input_database, FL_RETURN_CHANGED);
51         fl_set_input_return(dialog_->input_style, FL_RETURN_CHANGED);
52
53         setPrehandler(dialog_->input_database);
54         setPrehandler(dialog_->input_style);
55
56         // Manage the ok, apply, restore and cancel/close buttons
57         bc().setOK(dialog_->button_ok);
58         bc().setCancel(dialog_->button_close);
59
60         bc().addReadOnly(dialog_->button_database_browse);
61         bc().addReadOnly(dialog_->input_database);
62         bc().addReadOnly(dialog_->button_style_browse);
63         bc().addReadOnly(dialog_->button_style_choose);
64         bc().addReadOnly(dialog_->button_rescan);
65         bc().addReadOnly(dialog_->input_style);
66         bc().addReadOnly(dialog_->check_bibtotoc);
67
68         // set up the tooltips
69         string str = _("The database you want to cite from. Insert it without the default extension \".bib\". If you insert it with the browser, LyX strips the extension. Several databases must be separated by a comma: \"natbib, books\".");
70         tooltips().init(dialog_->button_database_browse, str);
71
72         str = _("Browse your directory for BibTeX stylefiles");
73         tooltips().init(dialog_->button_style_browse, str);
74
75         str = _("The BibTeX style to use (only one allowed). Insert it without the default extension \".bst\" and without path or choose one from the browsers list. Most of the bibstyles are stored in $TEXMF/bibtex/bst. $TEXMF is the root dir of the local TeX tree.");
76         tooltips().init(dialog_->input_style, str);
77
78         str = _("Activate this option if you want the bibliography to appear in the Table of Contents (which doesn't happen by default)");
79         tooltips().init(dialog_->check_bibtotoc, str);
80
81         str = _("Choose a BibTeX style from the browsers list");
82         tooltips().init(dialog_->button_style_choose, str);
83
84         str = _("Updates your TeX system for a new bibstyle list. Only the styles which are in directories where TeX finds them are listed!");
85         tooltips().init(dialog_->button_rescan, str);
86
87 }
88
89
90 ButtonPolicy::SMInput FormBibtex::input(FL_OBJECT * ob, long)
91 {
92         if (ob == dialog_->button_database_browse) {
93                 // When browsing, take the first file only
94                 string const in_name = fl_get_input(dialog_->input_database);
95                 string out_name =
96                         controller().Browse("",
97                                 _("Select Database"),
98                                 _("*.bib| BibTeX Databases (*.bib)"));
99                 if (!out_name.empty()) {
100                         // add the database to any existing ones
101                         if (!in_name.empty())
102                                 out_name = in_name + ',' + out_name;
103
104                         fl_freeze_form(form());
105                         fl_set_input(dialog_->input_database, out_name.c_str());
106                         fl_unfreeze_form(form());
107                 }
108         } else if (ob == dialog_->button_style_browse) {
109                 string const in_name = fl_get_input(dialog_->input_style);
110                 string out_name =
111                         controller().Browse(in_name,
112                                 _("Select BibTeX-Style"),
113                                 _("*.bst| BibTeX Styles (*.bst)"));
114                 if (!out_name.empty()) {
115                         fl_freeze_form(form());
116                         fl_set_input(dialog_->input_style, out_name.c_str());
117                         fl_unfreeze_form(form());
118                 }
119         } else if (ob == dialog_->button_style_choose) {
120                 unsigned int selection = fl_get_browser(dialog_->browser_styles);
121                 if (!selection)
122                         return ButtonPolicy::SMI_NOOP;
123                 
124                 string const out_name = fl_get_browser_line(dialog_->browser_styles,
125                                                                 selection);
126                 fl_set_input(dialog_->input_style,
127                                 ChangeExtension(out_name, string()).c_str());
128         } else if (ob == dialog_->button_rescan) {
129                 fl_clear_browser(dialog_->browser_styles);
130                 controller().rescanBibStyles();
131                 string const str =
132                         controller().getBibStyles();
133                 fl_add_browser_line(dialog_->browser_styles, str.c_str());
134         }
135
136         // with an empty database nothing makes sense ...
137         if (!compare(fl_get_input(dialog_->input_database), "")) {
138                 return ButtonPolicy::SMI_NOOP;
139         }
140
141         return ButtonPolicy::SMI_VALID;
142 }
143
144
145 void FormBibtex::update()
146 {
147         fl_set_input(dialog_->input_database,
148                      controller().params().getContents().c_str());
149         string bibtotoc = "bibtotoc";
150         string bibstyle (controller().params().getOptions().c_str());
151         if (prefixIs(bibstyle, bibtotoc)) { // bibtotoc exists?
152                 fl_set_button(dialog_->check_bibtotoc,1);
153                 if (contains(bibstyle, ',')) { // bibstyle exists?
154                         bibstyle = split(bibstyle, bibtotoc, ',');
155                 } else {
156                         bibstyle = string();
157                 }
158
159                 fl_set_input(dialog_->input_style, bibstyle.c_str());
160
161         } else {
162                 fl_set_button(dialog_->check_bibtotoc,0);
163                 fl_set_input(dialog_->input_style, bibstyle.c_str());
164         }
165         fl_clear_browser(dialog_->browser_styles);
166         string const str =
167                 controller().getBibStyles();
168         fl_add_browser_line(dialog_->browser_styles, str.c_str());
169 }
170
171 namespace {
172
173 string const unique_and_no_extensions(string const & str_in)
174 {
175         vector<string> dbase = getVectorFromString(str_in);
176         for (vector<string>::iterator it = dbase.begin();
177              it != dbase.end(); ++it) {
178                 *it = ChangeExtension(*it, string());
179         }
180         lyx::eliminate_duplicates(dbase);
181         return getStringFromVector(dbase);
182 }
183
184 } // namespace anon
185
186
187 void FormBibtex::apply()
188 {
189         string const db = fl_get_input(dialog_->input_database);
190         if (db.empty()) {
191                 // no database -> no bibtex-command and no options!
192                 controller().params().setContents("");
193                 controller().params().setOptions("");
194                 return;
195         }
196
197         controller().params().setContents(unique_and_no_extensions(db));
198
199         // empty is valid!
200         string bibstyle = fl_get_input(dialog_->input_style);
201         if (!bibstyle.empty()) {
202                 // save the BibTeX style without any ".bst" extension
203                 bibstyle = ChangeExtension(OnlyFilename(bibstyle), "");
204         }
205
206         bool const bibtotoc = fl_get_button(dialog_->check_bibtotoc);
207
208         if (bibtotoc && (!bibstyle.empty())) {
209                 // both bibtotoc and style
210                 controller().params().setOptions("bibtotoc," + bibstyle);
211
212         } else if (bibtotoc) {
213                 // bibtotoc and no style
214                 controller().params().setOptions("bibtotoc");
215
216         } else  // all other cases
217                 controller().params().setOptions(bibstyle);
218 }