]> git.lyx.org Git - features.git/blob - src/frontends/qt4/GuiBibtex.cpp
06210eefbd9f50810f1fcfb6547ea1d745d4345a
[features.git] / src / frontends / qt4 / GuiBibtex.cpp
1 /**
2  * \file GuiBibtex.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author John Levon
7  * \author Herbert Voß
8  * \author Jürgen Spitzmüller
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "GuiBibtex.h"
16
17 #include "ui_BibtexAddUi.h"
18 #include "Qt2BC.h"
19 #include "qt_helpers.h"
20 #include "Validator.h"
21 #include "LyXRC.h"
22
23 #include "controllers/ControlBibtex.h"
24 #include "controllers/ButtonPolicy.h"
25
26 #include "support/filetools.h" // changeExtension
27 #include "support/lstrings.h"
28
29 #include <QPushButton>
30 #include <QListWidget>
31 #include <QCheckBox>
32 #include <QCloseEvent>
33 #include <QLineEdit>
34
35 #include "debug.h"
36 #include "support/filetools.h"
37 #include "support/lstrings.h"
38
39 using std::vector;
40 using std::string;
41
42
43 namespace lyx {
44 namespace frontend {
45
46 using support::changeExtension;
47 using support::split;
48 using support::trim;
49
50
51 /////////////////////////////////////////////////////////////////////
52 //
53 // GuiBibtexDialog
54 //
55 /////////////////////////////////////////////////////////////////////
56
57 GuiBibtexDialog::GuiBibtexDialog(GuiBibtex * form)
58         : form_(form)
59 {
60         setupUi(this);
61         QDialog::setModal(true);
62
63         connect(okPB, SIGNAL(clicked()),
64                 form, SLOT(slotOK()));
65         connect(closePB, SIGNAL(clicked()),
66                 form, SLOT(slotClose()));
67         connect(stylePB, SIGNAL(clicked()),
68                 this, SLOT(browsePressed()));
69         connect(deletePB, SIGNAL(clicked()),
70                 this, SLOT(deletePressed()));
71         connect(styleCB, SIGNAL(editTextChanged (const QString &)),
72                 this, SLOT(change_adaptor()));
73         connect(databaseLW, SIGNAL(itemSelectionChanged()),
74                 this, SLOT(databaseChanged()));
75         connect(bibtocCB, SIGNAL(clicked()),
76                 this, SLOT(change_adaptor()));
77         connect(btPrintCO, SIGNAL(activated(int)),
78                 this, SLOT(change_adaptor()));
79         connect(addBibPB, SIGNAL(clicked()),
80                 this, SLOT(addPressed()));
81
82         add_ = new UiDialog<Ui::BibtexAddUi>(this, true);
83
84         Qt2BC * bcview = new Qt2BC(add_bc_);
85         add_bc_.view(bcview);
86         add_bc_.setPolicy(ButtonPolicy::OkCancelPolicy);
87
88         bcview->setOK(add_->addPB);
89         bcview->setCancel(add_->closePB);
90         bcview->addCheckedLineEdit(add_->bibED, 0);
91
92         connect(add_->bibED, SIGNAL(textChanged(const QString &)),
93                 this, SLOT(bibEDChanged()));
94         connect(add_->addPB, SIGNAL(clicked()),
95                 this, SLOT(addDatabase()));
96         connect(add_->addPB, SIGNAL(clicked()),
97                 add_, SLOT(accept()));
98         connect(add_->bibLW, SIGNAL(itemActivated(QListWidgetItem *)),
99                 this, SLOT(addDatabase()));
100         connect(add_->bibLW, SIGNAL(itemActivated(QListWidgetItem *)),
101                 add_, SLOT(accept()));
102         connect(add_->bibLW, SIGNAL(itemSelectionChanged()),
103                 this, SLOT(availableChanged()));
104         connect(add_->browsePB, SIGNAL(clicked()),
105                 this, SLOT(browseBibPressed()));
106         connect(add_->closePB, SIGNAL(clicked()),
107                 add_, SLOT(reject()));
108
109 }
110
111
112 void GuiBibtexDialog::bibEDChanged()
113 {
114         // Indicate to the button controller that the contents have
115         // changed. The actual test of validity is carried out by
116         // the checkedLineEdit.
117         add_bc_.valid(true);
118 }
119
120
121 void GuiBibtexDialog::change_adaptor()
122 {
123         form_->changed();
124 }
125
126
127 void GuiBibtexDialog::browsePressed()
128 {
129         docstring const file = form_->controller().browseBst(docstring());
130
131         if (!file.empty()) {
132                 // FIXME UNICODE
133                 docstring const filen = from_utf8(changeExtension(to_utf8(file), ""));
134                 bool present = false;
135                 unsigned int pres = 0;
136
137                 for (int i = 0; i != styleCB->count(); ++i) {
138                         if (qstring_to_ucs4(styleCB->itemText(i)) == filen) {
139                                 present = true;
140                                 pres = i;
141                         }
142                 }
143
144                 if (!present)
145                         styleCB->insertItem(0, toqstr(filen));
146
147                 styleCB->setCurrentIndex(pres);
148                 form_->changed();
149         }
150 }
151
152
153 void GuiBibtexDialog::browseBibPressed()
154 {
155         docstring const file = trim(form_->controller().browseBib(docstring()));
156
157         if (!file.empty()) {
158                 // FIXME UNICODE
159                 QString const f = toqstr(changeExtension(to_utf8(file), ""));
160                 bool present = false;
161
162                 for (int i = 0; i < add_->bibLW->count(); ++i) {
163                         if (add_->bibLW->item(i)->text() == f)
164                                 present = true;
165                 }
166
167                 if (!present) {
168                         add_->bibLW->addItem(f);
169                         form_->changed();
170                 }
171
172                 add_->bibED->setText(f);
173         }
174 }
175
176
177 void GuiBibtexDialog::addPressed()
178 {
179         add_bc_.valid(false);
180         add_->exec();
181 }
182
183
184 void GuiBibtexDialog::addDatabase()
185 {
186         int const sel = add_->bibLW->currentRow();
187         docstring const file = trim(qstring_to_ucs4(add_->bibED->text()));
188
189         if (sel < 0 && file.empty())
190                 return;
191
192         // Add the selected browser_bib keys to browser_database
193         // multiple selections are possible
194         for (int i = 0; i != add_->bibLW->count(); ++i) {
195                 QListWidgetItem * const item = add_->bibLW->item(i);
196                 if (add_->bibLW->isItemSelected(item)) {
197                         add_->bibLW->setItemSelected(item, false);
198                         QList<QListWidgetItem *> matches =
199                                 databaseLW->findItems(item->text(), Qt::MatchExactly);
200                         if (matches.empty())
201                                 databaseLW->addItem(item->text());
202                 }
203         }
204
205         if (!file.empty()) {
206                 add_->bibED->clear();
207                 QString const f = toqstr(from_utf8(changeExtension(to_utf8(file), "")));
208                 QList<QListWidgetItem *> matches =
209                         databaseLW->findItems(f, Qt::MatchExactly);
210                 if (matches.empty())
211                         databaseLW->addItem(f);
212         }
213
214         form_->changed();
215 }
216
217
218 void GuiBibtexDialog::deletePressed()
219 {
220         databaseLW->takeItem(databaseLW->currentRow());
221         form_->changed();
222 }
223
224
225
226 void GuiBibtexDialog::databaseChanged()
227 {
228         deletePB->setEnabled(!form_->readOnly() && databaseLW->currentRow() != -1);
229 }
230
231
232 void GuiBibtexDialog::availableChanged()
233 {
234         add_bc_.valid(true);
235 }
236
237
238 void GuiBibtexDialog::closeEvent(QCloseEvent *e)
239 {
240         form_->slotWMHide();
241         e->accept();
242 }
243
244
245 /////////////////////////////////////////////////////////////////////
246 //
247 // QBibTex
248 //
249 /////////////////////////////////////////////////////////////////////
250
251
252 GuiBibtex::GuiBibtex(Dialog & parent)
253         : GuiView<GuiBibtexDialog>(parent, _("BibTeX Bibliography"))
254 {
255 }
256
257
258 void GuiBibtex::build_dialog()
259 {
260         dialog_.reset(new GuiBibtexDialog(this));
261
262         bcview().setOK(dialog_->okPB);
263         bcview().setCancel(dialog_->closePB);
264         bcview().addReadOnly(dialog_->databaseLW);
265         bcview().addReadOnly(dialog_->stylePB);
266         bcview().addReadOnly(dialog_->styleCB);
267         bcview().addReadOnly(dialog_->bibtocCB);
268         bcview().addReadOnly(dialog_->addBibPB);
269         bcview().addReadOnly(dialog_->deletePB);
270 }
271
272
273 void GuiBibtex::update_contents()
274 {
275         bool bibtopic = controller().usingBibtopic();
276
277         dialog_->databaseLW->clear();
278
279         docstring bibs(controller().params()["bibfiles"]);
280         docstring bib;
281
282         while (!bibs.empty()) {
283                 bibs = split(bibs, bib, ',');
284                 bib = trim(bib);
285                 if (!bib.empty())
286                         dialog_->databaseLW->addItem(toqstr(bib));
287         }
288
289         dialog_->add_->bibLW->clear();
290
291         vector<string> bib_str;
292         controller().getBibFiles(bib_str);
293         for (vector<string>::const_iterator it = bib_str.begin();
294                 it != bib_str.end(); ++it) {
295                 string bibItem(changeExtension(*it, ""));
296                 dialog_->add_->bibLW->addItem(toqstr(bibItem));
297         }
298
299         string bibstyle(controller().getStylefile());
300
301         dialog_->bibtocCB->setChecked(controller().bibtotoc() && !bibtopic);
302         dialog_->bibtocCB->setEnabled(!bibtopic);
303
304         docstring btprint(controller().params()["btprint"]);
305         int btp = 0;
306         if (btprint == "btPrintNotCited")
307                 btp = 1;
308         else if (btprint == "btPrintAll")
309                 btp = 2;
310
311         dialog_->btPrintCO->setCurrentIndex(btp);
312         dialog_->btPrintCO->setEnabled(bibtopic);
313
314         dialog_->styleCB->clear();
315
316         int item_nr(-1);
317
318         vector<string> str;
319         controller().getBibStyles(str);
320         for (vector<string>::const_iterator it = str.begin();
321                 it != str.end(); ++it) {
322                 string item(changeExtension(*it, ""));
323                 if (item == bibstyle)
324                         item_nr = int(it - str.begin());
325                 dialog_->styleCB->addItem(toqstr(item));
326         }
327
328         if (item_nr == -1 && !bibstyle.empty()) {
329                 dialog_->styleCB->addItem(toqstr(bibstyle));
330                 item_nr = dialog_->styleCB->count() - 1;
331         }
332
333         if (item_nr != -1)
334                 dialog_->styleCB->setCurrentIndex(item_nr);
335         else
336                 dialog_->styleCB->clearEditText();
337 }
338
339
340 void GuiBibtex::apply()
341 {
342         docstring dbs(qstring_to_ucs4(dialog_->databaseLW->item(0)->text()));
343
344         unsigned int maxCount = dialog_->databaseLW->count();
345         for (unsigned int i = 1; i < maxCount; i++) {
346                 dbs += ',';
347                 dbs += qstring_to_ucs4(dialog_->databaseLW->item(i)->text());
348         }
349
350         controller().params()["bibfiles"] = dbs;
351
352         docstring const bibstyle(qstring_to_ucs4(dialog_->styleCB->currentText()));
353         bool const bibtotoc(dialog_->bibtocCB->isChecked());
354
355         if (bibtotoc && (!bibstyle.empty())) {
356                 // both bibtotoc and style
357                 controller().params()["options"] = "bibtotoc," + bibstyle;
358         } else if (bibtotoc) {
359                 // bibtotoc and no style
360                 controller().params()["options"] = from_ascii("bibtotoc");
361         } else {
362                 // only style. An empty one is valid, because some
363                 // documentclasses have an own \bibliographystyle{}
364                 // command!
365                 controller().params()["options"] = bibstyle;
366         }
367
368         // bibtopic allows three kinds of sections:
369         // 1. sections that include all cited references of the database(s)
370         // 2. sections that include all uncited references of the database(s)
371         // 3. sections that include all references of the database(s), cited or not
372         int btp = dialog_->btPrintCO->currentIndex();
373
374         switch (btp) {
375         case 0:
376                 controller().params()["btprint"] = from_ascii("btPrintCited");
377                 break;
378         case 1:
379                 controller().params()["btprint"] = from_ascii("btPrintNotCited");
380                 break;
381         case 2:
382                 controller().params()["btprint"] = from_ascii("btPrintAll");
383                 break;
384         }
385
386         if (!controller().usingBibtopic())
387                 controller().params()["btprint"] = docstring();
388 }
389
390
391 bool GuiBibtex::isValid()
392 {
393         return dialog_->databaseLW->count() != 0;
394 }
395
396 } // namespace frontend
397 } // namespace lyx
398
399 #include "GuiBibtex_moc.cpp"