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