]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/FormBibtex.C
Replace 'using namespace abc;' with 'using abc::xyz;'
[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/lstrings.h"
26 #include "support/lyxalgo.h"
27
28 #include "lyx_forms.h"
29
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;
38
39 using std::vector;
40
41
42 typedef FormController<ControlBibtex, FormView<FD_bibtex> > base_class;
43
44 FormBibtex::FormBibtex(Dialog & parent)
45         : base_class(parent, _("BibTeX Database"))
46 {}
47
48
49 void FormBibtex::build()
50 {
51         dialog_.reset(build_bibtex(this));
52
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);
58
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);
66
67         // trigger an input event for cut&paste with middle mouse button.
68         setPrehandler(dialog_->input_database);
69         setPrehandler(dialog_->input_style);
70
71         fl_set_input_return(dialog_->input_database, FL_RETURN_CHANGED);
72         fl_set_input_return(dialog_->input_style, FL_RETURN_CHANGED);
73
74         // callback for double click in browser
75         fl_set_browser_dblclick_callback(dialog_->browser_styles,
76                                          C_FormDialogView_InputCB, 2);
77
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);
83
84         str = _("Browse directory for BibTeX stylefiles");
85         tooltips().init(dialog_->button_style_browse, str);
86
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);
90
91         str = _("Select if the bibliography should appear in the Table "
92                 "of Contents");
93         tooltips().init(dialog_->check_bibtotoc, str);
94
95         str = _("Double click to choose a BibTeX style from the list.");
96         tooltips().init(dialog_->browser_styles, str);
97
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);
101 #endif
102
103         str = _("Updates your TeX system for a new bibstyle list. Only "
104                 "the styles which are in directories where TeX finds them "
105                 "are listed!");
106         tooltips().init(dialog_->button_rescan, str);
107 }
108
109
110 ButtonPolicy::SMInput FormBibtex::input(FL_OBJECT * ob, long ob_value)
111 {
112         if (ob == dialog_->button_database_browse) {
113                 // When browsing, take the first file only
114                 string const in_name = getString(dialog_->input_database);
115                 string out_name =
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;
123
124                         fl_set_input(dialog_->input_database, out_name.c_str());
125                 }
126
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());
134                 }
135
136         } else if (ob == dialog_->browser_styles && ob_value == 2) {
137                 // double clicked in styles browser
138                 string const style = getString(dialog_->browser_styles);
139                 if (style.empty()) {
140                         return ButtonPolicy::SMI_NOOP;
141                 } else {
142                         fl_set_input(dialog_->input_style,
143                                         ChangeExtension(style, "").c_str());
144                 }
145                 // reset the browser so that the following
146                 // single-click callback doesn't do anything
147                 fl_deselect_browser(dialog_->browser_styles);
148
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());
156         }
157
158         // with an empty database nothing makes sense ...
159         if (!compare(fl_get_input(dialog_->input_database), "")) {
160                 return ButtonPolicy::SMI_NOOP;
161         }
162
163         return ButtonPolicy::SMI_VALID;
164 }
165
166
167 void FormBibtex::update()
168 {
169         fl_set_input(dialog_->input_database,
170                      controller().params().getContents().c_str());
171
172         string bibtotoc = "bibtotoc";
173         string bibstyle = controller().params().getOptions();
174
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, ',');
180                 } else {
181                         bibstyle.erase();
182                 }
183         }
184         fl_set_input(dialog_->input_style, bibstyle.c_str());
185
186         vector<string> styles;
187         controller().getBibStyles(styles);
188
189         fl_clear_browser(dialog_->browser_styles);
190         fl_add_browser_line(dialog_->browser_styles,
191                             getStringFromVector(styles, "\n").c_str());
192 }
193
194 namespace {
195
196 string const unique_and_no_extensions(string const & str_in)
197 {
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());
202         }
203         lyx::eliminate_duplicates(dbase);
204         return getStringFromVector(dbase);
205 }
206
207 } // namespace anon
208
209
210 void FormBibtex::apply()
211 {
212         string const db = getString(dialog_->input_database);
213         if (db.empty()) {
214                 // no database -> no bibtex-command and no options!
215                 controller().params().setContents("");
216                 controller().params().setOptions("");
217                 return;
218         }
219
220         controller().params().setContents(unique_and_no_extensions(db));
221
222         // empty is valid!
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), "");
227         }
228
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);
234
235         } else {
236                 // At least one of addtotoc and bibstyle is empty. No harm to output both!
237                 controller().params().setOptions(bibtotoc + bibstyle);
238         }
239 }