]> git.lyx.org Git - features.git/blob - src/frontends/xforms/FormBibtex.C
xforms clean-up, described in detail in my mail of 31 May. See
[features.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, a.leeming@ic.ac.uk
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
31
32 using std::vector;
33 using std::sort;
34
35
36 typedef FormCB<ControlBibtex, FormDB<FD_bibtex> > base_class;
37
38 FormBibtex::FormBibtex(ControlBibtex & c)
39         : base_class(c, _("BibTeX Database"))
40 {}
41
42
43 void FormBibtex::build()
44 {
45         dialog_.reset(build_bibtex(this));
46
47         fl_set_input_return(dialog_->input_database, FL_RETURN_CHANGED);
48         fl_set_input_return(dialog_->input_style, FL_RETURN_CHANGED);
49
50         setPrehandler(dialog_->input_database);
51         setPrehandler(dialog_->input_style);
52
53         // Manage the ok, apply, restore and cancel/close buttons
54         bc().setOK(dialog_->button_ok);
55         bc().setCancel(dialog_->button_close);
56
57         bc().addReadOnly(dialog_->button_database_browse);
58         bc().addReadOnly(dialog_->input_database);
59         bc().addReadOnly(dialog_->button_style_browse);
60         bc().addReadOnly(dialog_->input_style);
61         bc().addReadOnly(dialog_->check_bibtotoc);
62
63         // set up the tooltips
64         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\".");
65         tooltips().init(dialog_->button_database_browse, str);
66
67         str = _("Browse your directory for BibTeX stylefiles.");
68         tooltips().init(dialog_->button_style_browse, str);
69
70         str = _("The BibTeX style to use (only one allowed). Insert it without the default extension \".bst\" and without path. Most of the bibstyles are stored in $TEXMF/bibtex/bst. $TEXMF is the root dir of the local TeX tree. In \"View->TeX Information\" you can list all installed styles.");
71         tooltips().init(dialog_->input_style, str);
72
73         str = _("Activate this option if you want the bibliography to appear in the Table of Contents (which doesn't happen by default).");
74         tooltips().init(dialog_->check_bibtotoc, str);
75 }
76
77
78 ButtonPolicy::SMInput FormBibtex::input(FL_OBJECT * ob, long)
79 {
80         if (ob == dialog_->button_database_browse) {
81                 // When browsing, take the first file only
82                 string const in_name = fl_get_input(dialog_->input_database);
83                 string out_name =
84                         controller().Browse("",
85                                             _("Select Database"),
86                                             _("*.bib| BibTeX Databases (*.bib)"));
87                 if (!out_name.empty()) {
88                         // add the database to any existing ones
89                         if (!in_name.empty())
90                                 out_name = in_name + ',' + out_name;
91
92                         fl_freeze_form(form());
93                         fl_set_input(dialog_->input_database, out_name.c_str());
94                         fl_unfreeze_form(form());
95                 }
96         }
97
98         if (ob == dialog_->button_style_browse) {
99                 string const in_name = fl_get_input(dialog_->input_style);
100                 string out_name =
101                         controller().Browse(in_name,
102                                             _("Select BibTeX-Style"),
103                                             _("*.bst| BibTeX Styles (*.bst)"));
104                 if (!out_name.empty()) {
105                         fl_freeze_form(form());
106                         fl_set_input(dialog_->input_style, out_name.c_str());
107                         fl_unfreeze_form(form());
108                 }
109         }
110
111         if (!compare(fl_get_input(dialog_->input_database),"")) {
112                 return ButtonPolicy::SMI_NOOP;
113         }
114
115         return ButtonPolicy::SMI_VALID;
116 }
117
118
119 void FormBibtex::update()
120 {
121         fl_set_input(dialog_->input_database,
122                      controller().params().getContents().c_str());
123         string bibtotoc = "bibtotoc";
124         string bibstyle (controller().params().getOptions().c_str());
125         if (prefixIs(bibstyle,bibtotoc)) { // bibtotoc exists?
126                 fl_set_button(dialog_->check_bibtotoc,1);
127                 if (contains(bibstyle,',')) { // bibstyle exists?
128                         bibstyle = split(bibstyle,bibtotoc,',');
129                 } else {
130                         bibstyle = "";
131                 }
132
133                 fl_set_input(dialog_->input_style,bibstyle.c_str());
134
135         } else {
136                 fl_set_button(dialog_->check_bibtotoc,0);
137                 fl_set_input(dialog_->input_style,bibstyle.c_str());
138         }
139 }
140
141 namespace {
142
143 // Remove all duplicate entries in c.
144 // Taken stright out of Stroustrup
145 template<class C>
146 void eliminate_duplicates(C & c)
147 {
148         sort(c.begin(), c.end());
149         typename C::iterator p = std::unique(c.begin(), c.end());
150         c.erase(p, c.end());
151 }
152
153
154 string const unique_and_no_extensions(string const & str_in)
155 {
156         vector<string> dbase = getVectorFromString(str_in);
157         for (vector<string>::iterator it = dbase.begin();
158              it != dbase.end(); ++it) {
159                 *it = ChangeExtension(*it, "");
160         }
161         eliminate_duplicates(dbase);
162         return getStringFromVector(dbase);
163 }
164
165 } // namespace anon
166
167
168 void FormBibtex::apply()
169 {
170         string const db = fl_get_input(dialog_->input_database);
171         if (db.empty()) {
172                 // no database -> no bibtex-command and no options!
173                 controller().params().setContents("");
174                 controller().params().setOptions("");
175                 return;
176         }
177
178         controller().params().setContents(unique_and_no_extensions(db));
179
180         // empty is valid!
181         string bibstyle = fl_get_input(dialog_->input_style);
182         if (!bibstyle.empty()) {
183                 // save the BibTeX style without any ".bst" extension
184                 bibstyle = ChangeExtension(OnlyFilename(bibstyle), "");
185         }
186
187         bool const bibtotoc = fl_get_button(dialog_->check_bibtotoc);
188
189         if (bibtotoc && (!bibstyle.empty())) {
190                 // both bibtotoc and style
191                 controller().params().setOptions("bibtotoc,"+bibstyle);
192
193         } else if (bibtotoc) {
194                 // bibtotoc and no style
195                 controller().params().setOptions("bibtotoc");
196
197         } else  // all other cases
198                 controller().params().setOptions(bibstyle);
199 }