]> git.lyx.org Git - features.git/blob - src/frontends/xforms/FormBibtex.C
a80c97818d937dd5c59cfa18b5267f25b4ad4cea
[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
7  * \author John Levon
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 "form_bibtex.h"
20 #include "gettext.h"
21 #include "debug.h"
22 #include "xforms_helpers.h"
23 #include "helper_funcs.h"
24 #include "support/LAssert.h"
25 #include "support/lstrings.h"
26 #include "support/filetools.h"
27
28
29 typedef FormCB<ControlBibtex, FormDB<FD_form_bibtex> > base_class;
30
31 FormBibtex::FormBibtex(ControlBibtex & c)
32         : base_class(c, _("BibTeX Database"))
33 {}
34
35
36 void FormBibtex::build()
37 {
38         dialog_.reset(build_bibtex());
39
40         fl_set_input_return(dialog_->database, FL_RETURN_CHANGED);
41         fl_set_input_return(dialog_->style, FL_RETURN_CHANGED);
42
43         // Manage the ok, apply, restore and cancel/close buttons
44         bc().setOK(dialog_->button_ok);
45         bc().setCancel(dialog_->button_cancel);
46
47         bc().addReadOnly(dialog_->database_browse);
48         bc().addReadOnly(dialog_->database);
49         bc().addReadOnly(dialog_->style_browse);
50         bc().addReadOnly(dialog_->style);
51         bc().addReadOnly(dialog_->radio_bibtotoc);
52
53         // set up the feedback mechanism
54         setPrehandler(dialog_->database_browse);
55         setPrehandler(dialog_->database);
56         setPrehandler(dialog_->style_browse);
57         setPrehandler(dialog_->style);
58         setPrehandler(dialog_->radio_bibtotoc);
59 }
60
61
62 ButtonPolicy::SMInput FormBibtex::input(FL_OBJECT * ob, long)
63 {
64         if (ob == dialog_->database_browse) {
65                 // When browsing, take the first file only 
66                 string const in_name = fl_get_input(dialog_->database);
67                 string out_name = 
68                         controller().Browse("",
69                                             "Select Database",
70                                             "*.bib| BibTeX Databases (*.bib)");
71                 if (!out_name.empty()) {
72                         // add the database to any existing ones
73                         if (!in_name.empty())
74                                 out_name = in_name + ", " + out_name;
75
76                         fl_freeze_form(form()); 
77                         fl_set_input(dialog_->database, out_name.c_str());
78                         fl_unfreeze_form(form()); 
79                 }
80         }
81
82         if (ob == dialog_->style_browse) {
83                 string const in_name = fl_get_input(dialog_->style);
84                 string out_name = 
85                         controller().Browse(in_name,
86                                             "Select BibTeX-Style",
87                                             "*.bst| BibTeX Styles (*.bst)");
88                 if (!out_name.empty()) {
89                         fl_freeze_form(form()); 
90                         fl_set_input(dialog_->style, out_name.c_str());
91                         fl_unfreeze_form(form()); 
92                 }
93         }
94   
95         if (!compare(fl_get_input(dialog_->database),"")) {
96                 return ButtonPolicy::SMI_NOOP;
97         }
98
99         return ButtonPolicy::SMI_VALID;
100 }
101
102
103 void FormBibtex::update()
104 {
105         fl_set_input(dialog_->database,
106                      controller().params().getContents().c_str());
107         string bibtotoc = "bibtotoc";
108         string bibstyle (controller().params().getOptions().c_str());
109         if (prefixIs(bibstyle,bibtotoc)) { // bibtotoc exists?
110                 fl_set_button(dialog_->radio_bibtotoc,1);
111                 if (contains(bibstyle,',')) { // bibstyle exists?
112                         bibstyle = split(bibstyle,bibtotoc,',');
113                 } else {
114                         bibstyle = "";
115                 }
116
117                 fl_set_input(dialog_->style,bibstyle.c_str());
118
119         } else {
120                 fl_set_button(dialog_->radio_bibtotoc,0);
121                 fl_set_input(dialog_->style,bibstyle.c_str());
122         }
123 }
124
125 namespace {
126
127 // Remove all duplicate entries in c.
128 // Taken stright out of Stroustrup
129 template<class C> void eliminate_duplicates(C & c)
130 {
131         std::sort(c.begin(), c.end()); // sort
132         typename C::iterator p = std::unique(c.begin(), c.end()); // compact
133         c.erase(p, c.end()); // shrink
134 }
135
136 string const unique_and_no_extensions(string const & str_in)
137 {
138         std::vector<string> dbase = getVectorFromString(str_in);
139         for (std::vector<string>::iterator it = dbase.begin();
140              it != dbase.end(); ++it) {
141                 *it = ChangeExtension(*it, "");
142         }
143         eliminate_duplicates(dbase);
144         return subst(getStringFromVector(dbase),",",", ");
145 }
146  
147 } // namespace anon
148
149
150 void FormBibtex::apply()
151 {
152         string const db = fl_get_input(dialog_->database);
153         if (db.empty()) {
154                 // no database -> no bibtex-command and no options!
155                 controller().params().setContents("");
156                 controller().params().setOptions("");
157                 return;
158         }
159         
160         controller().params().setContents(unique_and_no_extensions(db));
161
162         // empty is valid!
163         string bibstyle = fl_get_input(dialog_->style);
164         if (!bibstyle.empty()) {
165                 // save the BibTeX style without any ".bst" extension
166                 bibstyle = ChangeExtension(OnlyFilename(bibstyle), "");
167         }
168
169         bool const bibtotoc = fl_get_button(dialog_->radio_bibtotoc);
170         
171         if (bibtotoc && (!bibstyle.empty())) {
172                 // both bibtotoc and style
173                 controller().params().setOptions("bibtotoc,"+bibstyle);
174
175         } else if (bibtotoc) {
176                 // bibtotoc and no style
177                 controller().params().setOptions("bibtotoc");
178
179         } else if (!bibstyle.empty()){
180                 // only style
181                 controller().params().setOptions(bibstyle);
182         }
183 }
184
185 void FormBibtex::clear_feedback()
186 {
187         fl_set_object_label(dialog_->text_info, "");
188         fl_redraw_object(dialog_->text_info);
189 }
190
191 void FormBibtex::feedback(FL_OBJECT * ob)
192 {
193         lyx::Assert(ob);
194
195         string str;
196
197         if (ob == dialog_->database) {
198                 str = N_("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\".");
199
200         } else if (ob == dialog_->database_browse) {
201                 str = _("Browse your directory for BibTeX databases.");
202
203         } else if (ob == dialog_->style) {
204                 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 \"Help->TeX Info\" you can list all installed styles.");
205
206         } else if (ob == dialog_->style_browse) {
207                 str = _("Browse your directory for BibTeX stylefiles.");
208
209         } else if (ob == dialog_->radio_bibtotoc) {
210                 str = _("Activate this option if you want the bibliography to appear in the Table of Contents (which doesn't happen by default).");
211         }
212
213         str = formatted(_(str), dialog_->text_info->w-10, FL_SMALL_SIZE);
214
215         fl_set_object_label(dialog_->text_info, str.c_str());
216         fl_set_object_lsize(dialog_->text_info, FL_SMALL_SIZE);
217         fl_redraw_object(dialog_->text_info);
218 }