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