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