]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiCitation.cpp
On Linux show in crash message box the backtrace
[lyx.git] / src / frontends / qt4 / GuiCitation.cpp
1
2 /**
3  * \file GuiCitation.cpp
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Angus Leeming
8  * \author Kalle Dalheimer
9  * \author Abdelrazak Younes
10  * \author Richard Heck
11  *
12  * Full author contact details are available in file CREDITS.
13  */
14
15 #include <config.h>
16
17 #include "GuiCitation.h"
18
19 #include "GuiSelectionManager.h"
20 #include "qt_helpers.h"
21
22 #include "Buffer.h"
23 #include "BufferView.h"
24 #include "BiblioInfo.h"
25 #include "BufferParams.h"
26 #include "FuncRequest.h"
27
28 #include "insets/InsetCommand.h"
29
30 #include "support/debug.h"
31 #include "support/docstring.h"
32 #include "support/gettext.h"
33 #include "support/lstrings.h"
34
35 #include <QCloseEvent>
36 #include <QSettings>
37 #include <QShowEvent>
38 #include <QVariant>
39
40 #include <vector>
41 #include <string>
42
43 #undef KeyPress
44
45 #include "support/regex.h"
46
47 #include <algorithm>
48 #include <string>
49 #include <vector>
50
51 using namespace std;
52 using namespace lyx::support;
53
54 namespace lyx {
55 namespace frontend {
56
57 // FIXME THREAD
58 // I am guessing that it would not hurt to make these private members.
59 static vector<string> citeCmds_;
60 static vector<CitationStyle> citeStyles_;
61
62
63 template<typename String>
64 static QStringList to_qstring_list(vector<String> const & v)
65 {
66         QStringList qlist;
67
68         for (size_t i = 0; i != v.size(); ++i) {
69                 if (v[i].empty())
70                         continue;
71                 qlist.append(lyx::toqstr(v[i]));
72         }
73         return qlist;
74 }
75
76
77 static vector<lyx::docstring> to_docstring_vector(QStringList const & qlist)
78 {
79         vector<lyx::docstring> v;
80         for (int i = 0; i != qlist.size(); ++i) {
81                 if (qlist[i].isEmpty())
82                         continue;
83                 v.push_back(lyx::qstring_to_ucs4(qlist[i]));
84         }
85         return v;
86 }
87
88
89 GuiCitation::GuiCitation(GuiView & lv)
90         : DialogView(lv, "citation", qt_("Citation")),
91           params_(insetCode("citation"))
92 {
93         setupUi(this);
94
95         connect(citationStyleCO, SIGNAL(activated(int)),
96                 this, SLOT(on_citationStyleCO_currentIndexChanged(int)));
97         connect(fulllistCB, SIGNAL(clicked()),
98                 this, SLOT(changed()));
99         connect(forceuppercaseCB, SIGNAL(clicked()),
100                 this, SLOT(changed()));
101         connect(textBeforeED, SIGNAL(textChanged(QString)),
102                 this, SLOT(updateStyles()));
103         connect(textAfterED, SIGNAL(textChanged(QString)),
104                 this, SLOT(updateStyles()));
105         connect(findLE, SIGNAL(returnPressed()),
106                 this, SLOT(on_searchPB_clicked()));
107         connect(textBeforeED, SIGNAL(returnPressed()),
108                 this, SLOT(on_okPB_clicked()));
109         connect(textAfterED, SIGNAL(returnPressed()),
110                 this, SLOT(on_okPB_clicked()));
111
112         selectionManager = new GuiSelectionManager(availableLV, selectedLV,
113                         addPB, deletePB, upPB, downPB, &available_model_, &selected_model_);
114         connect(selectionManager, SIGNAL(selectionChanged()),
115                 this, SLOT(setCitedKeys()));
116         connect(selectionManager, SIGNAL(updateHook()),
117                 this, SLOT(updateControls()));
118         connect(selectionManager, SIGNAL(okHook()),
119                 this, SLOT(on_okPB_clicked()));
120
121         setFocusProxy(availableLV);
122 }
123
124
125 GuiCitation::~GuiCitation()
126 {
127         delete selectionManager;
128 }
129
130
131 void GuiCitation::closeEvent(QCloseEvent * e)
132 {
133         clearSelection();
134         DialogView::closeEvent(e);
135 }
136
137
138 void GuiCitation::applyView()
139 {
140         int const choice = max(0, citationStyleCO->currentIndex());
141         style_ = choice;
142         bool const full  = fulllistCB->isChecked();
143         bool const force = forceuppercaseCB->isChecked();
144
145         QString const before = textBeforeED->text();
146         QString const after = textAfterED->text();
147
148         apply(choice, full, force, before, after);
149 }
150
151
152 void GuiCitation::showEvent(QShowEvent * e)
153 {
154         findLE->clear();
155         availableLV->setFocus();
156         DialogView::showEvent(e);
157 }
158
159
160 void GuiCitation::on_okPB_clicked()
161 {
162         applyView();
163         clearSelection();
164         hide();
165 }
166
167
168 void GuiCitation::on_cancelPB_clicked()
169 {
170         clearSelection();
171         hide();
172 }
173
174
175 void GuiCitation::on_applyPB_clicked()
176 {
177         applyView();
178 }
179
180
181 void GuiCitation::on_restorePB_clicked()
182 {
183         init();
184 }
185
186
187 void GuiCitation::updateControls()
188 {
189         BiblioInfo const & bi = bibInfo();
190         updateControls(bi);
191 }
192
193
194 // The main point of separating this out is that the fill*() methods
195 // called in update() do not need to be called for INTERNAL updates,
196 // such as when addPB is pressed, as the list of fields, entries, etc,
197 // will not have changed.
198 void GuiCitation::updateControls(BiblioInfo const & bi)
199 {
200         QModelIndex idx = selectionManager->getSelectedIndex();
201         updateInfo(bi, idx);
202         selectionManager->update();
203 }
204
205
206 void GuiCitation::updateFormatting(CitationStyle currentStyle)
207 {
208         bool const force = currentStyle.forceUpperCase;
209         bool const full = currentStyle.fullAuthorList &&
210                 documentBuffer().params().fullAuthorList();
211         bool const textbefore = currentStyle.textBefore;
212         bool const textafter = currentStyle.textAfter;
213
214         bool const haveSelection =
215                 selectedLV->model()->rowCount() > 0;
216
217         forceuppercaseCB->setEnabled(force && haveSelection);
218         fulllistCB->setEnabled(full && haveSelection);
219         textBeforeED->setEnabled(textbefore && haveSelection);
220         textBeforeLA->setEnabled(textbefore && haveSelection);
221         textAfterED->setEnabled(textafter && haveSelection);
222         textAfterLA->setEnabled(textafter && haveSelection);
223         citationStyleCO->setEnabled(haveSelection);
224         citationStyleLA->setEnabled(haveSelection);
225 }
226
227
228 // Update the styles for the style combo, citationStyleCO, and mark the
229 // settings as changed. Called upon changing the cited keys (including
230 // merely reordering the keys) or editing the text before/after fields.
231 void GuiCitation::updateStyles()
232 {
233         BiblioInfo const & bi = bibInfo();
234         updateStyles(bi);
235         changed();
236 }
237
238
239 // Update the styles for the style combo, citationStyleCO.
240 void GuiCitation::updateStyles(BiblioInfo const & bi)
241 {
242         QStringList selected_keys = selected_model_.stringList();
243         int curr = selectedLV->model()->rowCount() - 1;
244
245         if (curr < 0 || selected_keys.empty()) {
246                 citationStyleCO->clear();
247                 citationStyleCO->setEnabled(false);
248                 citationStyleLA->setEnabled(false);
249                 return;
250         }
251
252         if (!selectedLV->selectionModel()->selectedIndexes().empty())
253                 curr = selectedLV->selectionModel()->selectedIndexes()[0].row();
254
255         static const size_t max_length = 80;
256         QStringList sty = citationStyles(bi, max_length);
257
258         if (sty.isEmpty()) {
259                 // some error
260                 citationStyleCO->setEnabled(false);
261                 citationStyleLA->setEnabled(false);
262                 citationStyleCO->clear();
263                 return;
264         }
265
266         citationStyleCO->blockSignals(true);
267
268         // save old index
269         int const oldIndex = citationStyleCO->currentIndex();
270         citationStyleCO->clear();
271         citationStyleCO->insertItems(0, sty);
272         citationStyleCO->setEnabled(true);
273         citationStyleLA->setEnabled(true);
274         // restore old index
275         if (oldIndex != -1 && oldIndex < citationStyleCO->count())
276                 citationStyleCO->setCurrentIndex(oldIndex);
277
278         citationStyleCO->blockSignals(false);
279 }
280
281
282 void GuiCitation::fillFields(BiblioInfo const & bi)
283 {
284         fieldsCO->blockSignals(true);
285         int const oldIndex = fieldsCO->currentIndex();
286         fieldsCO->clear();
287         QStringList const fields = to_qstring_list(bi.getFields());
288         fieldsCO->insertItem(0, qt_("All fields"));
289         fieldsCO->insertItem(1, qt_("Keys"));
290         fieldsCO->insertItems(2, fields);
291         if (oldIndex != -1 && oldIndex < fieldsCO->count())
292                 fieldsCO->setCurrentIndex(oldIndex);
293         fieldsCO->blockSignals(false);
294 }
295
296
297 void GuiCitation::fillEntries(BiblioInfo const & bi)
298 {
299         entriesCO->blockSignals(true);
300         int const oldIndex = entriesCO->currentIndex();
301         entriesCO->clear();
302         QStringList const entries = to_qstring_list(bi.getEntries());
303         entriesCO->insertItem(0, qt_("All entry types"));
304         entriesCO->insertItems(1, entries);
305         if (oldIndex != -1 && oldIndex < entriesCO->count())
306                 entriesCO->setCurrentIndex(oldIndex);
307         entriesCO->blockSignals(false);
308 }
309
310
311 bool GuiCitation::isSelected(QModelIndex const & idx)
312 {
313         QString const str = idx.data().toString();
314         return selected_model_.stringList().contains(str);
315 }
316
317
318 void GuiCitation::setButtons()
319 {
320         int const srows = selectedLV->model()->rowCount();
321         applyPB->setEnabled(srows > 0);
322         okPB->setEnabled(srows > 0);
323 }
324
325
326 void GuiCitation::updateInfo(BiblioInfo const & bi, QModelIndex const & idx)
327 {
328         if (!idx.isValid() || bi.empty()) {
329                 infoML->document()->clear();
330                 return;
331         }
332
333         QString const keytxt = toqstr(
334                 bi.getInfo(qstring_to_ucs4(idx.data().toString()), documentBuffer(), true));
335         infoML->document()->setHtml(keytxt);
336 }
337
338
339 void GuiCitation::findText(QString const & text, bool reset)
340 {
341         //"All Fields" and "Keys" are the first two
342         int index = fieldsCO->currentIndex() - 2;
343         BiblioInfo const & bi = bibInfo();
344         vector<docstring> const & fields = bi.getFields();
345         docstring field;
346
347         if (index <= -1 || index >= int(fields.size()))
348                 //either "All Fields" or "Keys" or an invalid value
349                 field = from_ascii("");
350         else
351                 field = fields[index];
352
353         //Was it "Keys"?
354         bool const onlyKeys = index == -1;
355
356         //"All Entry Types" is first.
357         index = entriesCO->currentIndex() - 1;
358         vector<docstring> const & entries = bi.getEntries();
359         docstring entry_type;
360         if (index < 0 || index >= int(entries.size()))
361                 entry_type = from_ascii("");
362         else
363                 entry_type = entries[index];
364
365         bool const case_sentitive = caseCB->checkState();
366         bool const reg_exp = regexCB->checkState();
367         findKey(bi, text, onlyKeys, field, entry_type,
368                        case_sentitive, reg_exp, reset);
369         //FIXME
370         //It'd be nice to save and restore the current selection in
371         //availableLV. Currently, we get an automatic reset, since the
372         //model is reset.
373
374         updateControls(bi);
375 }
376
377
378 void GuiCitation::on_fieldsCO_currentIndexChanged(int /*index*/)
379 {
380         findText(findLE->text(), true);
381 }
382
383
384 void GuiCitation::on_entriesCO_currentIndexChanged(int /*index*/)
385 {
386         findText(findLE->text(), true);
387 }
388
389
390 void GuiCitation::on_citationStyleCO_currentIndexChanged(int index)
391 {
392         if (index >= 0 && index < citationStyleCO->count()) {
393                 vector<CitationStyle> const & styles = citeStyles_;
394                 updateFormatting(styles[index]);
395                 changed();
396         }
397 }
398
399
400 void GuiCitation::on_findLE_textChanged(const QString & text)
401 {
402         bool const searchAsWeGo = (asTypeCB->checkState() == Qt::Checked);
403         searchPB->setDisabled(text.isEmpty() || searchAsWeGo);
404         if (!text.isEmpty()) {
405                 if (searchAsWeGo)
406                         findText(findLE->text());
407                 return;
408         }
409         findText(findLE->text());
410         findLE->setFocus();
411 }
412
413 void GuiCitation::on_searchPB_clicked()
414 {
415         findText(findLE->text(), true);
416 }
417
418
419 void GuiCitation::on_caseCB_stateChanged(int)
420 {
421         findText(findLE->text());
422 }
423
424
425 void GuiCitation::on_regexCB_stateChanged(int)
426 {
427         findText(findLE->text());
428 }
429
430
431 void GuiCitation::on_asTypeCB_stateChanged(int)
432 {
433         bool const searchAsWeGo = (asTypeCB->checkState() == Qt::Checked);
434         searchPB->setDisabled(findLE->text().isEmpty() || searchAsWeGo);
435         if (searchAsWeGo)
436                 findText(findLE->text(), true);
437 }
438
439
440 void GuiCitation::changed()
441 {
442         setButtons();
443 }
444
445
446 void GuiCitation::apply(int const choice, bool full, bool force,
447         QString before, QString after)
448 {
449         if (cited_keys_.isEmpty())
450                 return;
451
452         vector<CitationStyle> const & styles = citeStyles_;
453
454         CitationStyle cs = styles[choice];
455
456         if (!cs.textBefore)
457                 before.clear();
458         if (!cs.textAfter)
459                 after.clear();
460
461         cs.forceUpperCase &= force;
462         cs.fullAuthorList &= full;
463         string const command = citationStyleToString(cs);
464
465         params_.setCmdName(command);
466         params_["key"] = qstring_to_ucs4(cited_keys_.join(","));
467         params_["before"] = qstring_to_ucs4(before);
468         params_["after"] = qstring_to_ucs4(after);
469         dispatchParams();
470 }
471
472
473 void GuiCitation::clearSelection()
474 {
475         cited_keys_.clear();
476         selected_model_.setStringList(cited_keys_);
477 }
478
479
480 void GuiCitation::init()
481 {
482         // Make the list of all available bibliography keys
483         BiblioInfo const & bi = bibInfo();
484         all_keys_ = to_qstring_list(bi.getKeys());
485         available_model_.setStringList(all_keys_);
486
487         // Ditto for the keys cited in this inset
488         QString str = toqstr(params_["key"]);
489         if (str.isEmpty())
490                 cited_keys_.clear();
491         else
492                 cited_keys_ = str.split(",");
493         selected_model_.setStringList(cited_keys_);
494
495         // Initialize the drop downs
496         fillEntries(bi);
497         fillFields(bi);
498
499         // Initialize the citation formatting
500         string const & cmd = params_.getCmdName();
501         CitationStyle const cs = citationStyleFromString(cmd);
502         forceuppercaseCB->setChecked(cs.forceUpperCase);
503         fulllistCB->setChecked(cs.fullAuthorList &&
504                 documentBuffer().params().fullAuthorList());
505         textBeforeED->setText(toqstr(params_["before"]));
506         textAfterED->setText(toqstr(params_["after"]));
507
508         // Update the interface
509         updateControls(bi);
510         updateStyles(bi);
511         if (selected_model_.rowCount()) {
512                 selectedLV->blockSignals(true);
513                 selectedLV->setFocus();
514                 QModelIndex idx = selected_model_.index(0, 0);
515                 selectedLV->selectionModel()->select(idx,
516                                 QItemSelectionModel::ClearAndSelect);
517                 selectedLV->blockSignals(false);
518
519                 // Find the citation style
520                 vector<string> const & cmds = citeCmds_;
521                 vector<string>::const_iterator cit =
522                         std::find(cmds.begin(), cmds.end(), cs.cmd);
523                 int i = 0;
524                 if (cit != cmds.end())
525                         i = int(cit - cmds.begin());
526
527                 // Set the style combo appropriately
528                 citationStyleCO->blockSignals(true);
529                 citationStyleCO->setCurrentIndex(i);
530                 citationStyleCO->blockSignals(false);
531                 updateFormatting(citeStyles_[i]);
532         } else
533                 availableLV->setFocus();
534
535         applyPB->setEnabled(false);
536         okPB->setEnabled(false);
537 }
538
539
540 void GuiCitation::findKey(BiblioInfo const & bi,
541         QString const & str, bool only_keys,
542         docstring field, docstring entry_type,
543         bool case_sensitive, bool reg_exp, bool reset)
544 {
545         // FIXME THREAD
546         // Used for optimisation: store last searched string.
547         static QString last_searched_string;
548         // Used to disable the above optimisation.
549         static bool last_case_sensitive;
550         static bool last_reg_exp;
551         // Reset last_searched_string in case of changed option.
552         if (last_case_sensitive != case_sensitive
553                 || last_reg_exp != reg_exp) {
554                         LYXERR(Debug::GUI, "GuiCitation::findKey: optimisation disabled!");
555                 last_searched_string.clear();
556         }
557         // save option for next search.
558         last_case_sensitive = case_sensitive;
559         last_reg_exp = reg_exp;
560
561         Qt::CaseSensitivity qtcase = case_sensitive ?
562                         Qt::CaseSensitive: Qt::CaseInsensitive;
563         QStringList keys;
564         // If new string (str) contains the last searched one...
565         if (!reset &&
566                 !last_searched_string.isEmpty() &&
567                 str.size() > 1 &&
568                 str.contains(last_searched_string, qtcase))
569                 // ... then only search within already found list.
570                 keys = available_model_.stringList();
571         else
572                 // ... else search all keys.
573                 keys = all_keys_;
574         // save searched string for next search.
575         last_searched_string = str;
576
577         QStringList result;
578
579         // First, filter by entry_type, which will be faster than
580         // what follows, so we may get to do that on less.
581         vector<docstring> keyVector = to_docstring_vector(keys);
582         filterByEntryType(bi, keyVector, entry_type);
583
584         if (str.isEmpty())
585                 result = to_qstring_list(keyVector);
586         else
587                 result = to_qstring_list(searchKeys(bi, keyVector, only_keys,
588                         qstring_to_ucs4(str), field, case_sensitive, reg_exp));
589
590         available_model_.setStringList(result);
591 }
592
593
594 QStringList GuiCitation::citationStyles(BiblioInfo const & bi, size_t max_size)
595 {
596         docstring const before = qstring_to_ucs4(textBeforeED->text());
597         docstring const after = qstring_to_ucs4(textAfterED->text());
598         vector<docstring> const keys = to_docstring_vector(cited_keys_);
599         vector<CitationStyle> styles = citeStyles_;
600         // FIXME: pass a dictionary instead of individual before, after, dialog, etc.
601         vector<docstring> ret = bi.getCiteStrings(keys, styles, documentBuffer(),
602                 before, after, from_utf8("dialog"), max_size);
603         return to_qstring_list(ret);
604 }
605
606
607 void GuiCitation::setCitedKeys()
608 {
609         cited_keys_ = selected_model_.stringList();
610         updateStyles();
611 }
612
613
614 bool GuiCitation::initialiseParams(string const & data)
615 {
616         InsetCommand::string2params(data, params_);
617         citeCmds_ = documentBuffer().params().citeCommands();
618         citeStyles_ = documentBuffer().params().citeStyles();
619         init();
620         return true;
621 }
622
623
624 void GuiCitation::clearParams()
625 {
626         params_.clear();
627 }
628
629
630 void GuiCitation::filterByEntryType(BiblioInfo const & bi,
631         vector<docstring> & keyVector, docstring entry_type)
632 {
633         if (entry_type.empty())
634                 return;
635
636         vector<docstring>::iterator it = keyVector.begin();
637         vector<docstring>::iterator end = keyVector.end();
638
639         vector<docstring> result;
640         for (; it != end; ++it) {
641                 docstring const key = *it;
642                 BiblioInfo::const_iterator cit = bi.find(key);
643                 if (cit == bi.end())
644                         continue;
645                 if (cit->second.entryType() == entry_type)
646                         result.push_back(key);
647         }
648         keyVector = result;
649 }
650
651
652 // Escape special chars.
653 // All characters are literals except: '.|*?+(){}[]^$\'
654 // These characters are literals when preceded by a "\", which is done here
655 // @todo: This function should be moved to support, and then the test in tests
656 //        should be moved there as well.
657 static docstring escape_special_chars(docstring const & expr)
658 {
659         // Search for all chars '.|*?+(){}[^$]\'
660         // Note that '[' and '\' must be escaped.
661         // This is a limitation of lyx::regex, but all other chars in BREs
662         // are assumed literal.
663         static const lyx::regex reg("[].|*?+(){}^$\\[\\\\]");
664
665         // $& is a perl-like expression that expands to all
666         // of the current match
667         // The '$' must be prefixed with the escape character '\' for
668         // boost to treat it as a literal.
669         // Thus, to prefix a matched expression with '\', we use:
670         // FIXME: UNICODE
671         return from_utf8(lyx::regex_replace(to_utf8(expr), reg, string("\\\\$&")));
672 }
673
674
675 vector<docstring> GuiCitation::searchKeys(BiblioInfo const & bi,
676         vector<docstring> const & keys_to_search, bool only_keys,
677         docstring const & search_expression, docstring field,
678         bool case_sensitive, bool regex)
679 {
680         vector<docstring> foundKeys;
681
682         docstring expr = trim(search_expression);
683         if (expr.empty())
684                 return foundKeys;
685
686         if (!regex)
687                 // We must escape special chars in the search_expr so that
688                 // it is treated as a simple string by lyx::regex.
689                 expr = escape_special_chars(expr);
690
691         lyx::regex reg_exp;
692         try {
693                 reg_exp.assign(to_utf8(expr), case_sensitive ?
694                         lyx::regex_constants::ECMAScript : lyx::regex_constants::icase);
695         } catch (lyx::regex_error const & e) {
696                 // lyx::regex throws an exception if the regular expression is not
697                 // valid.
698                 LYXERR(Debug::GUI, e.what());
699                 return vector<docstring>();
700         }
701
702         vector<docstring>::const_iterator it = keys_to_search.begin();
703         vector<docstring>::const_iterator end = keys_to_search.end();
704         for (; it != end; ++it ) {
705                 BiblioInfo::const_iterator info = bi.find(*it);
706                 if (info == bi.end())
707                         continue;
708
709                 BibTeXInfo const & kvm = info->second;
710                 string data;
711                 if (only_keys)
712                         data = to_utf8(*it);
713                 else if (field.empty())
714                         data = to_utf8(*it) + ' ' + to_utf8(kvm.allData());
715                 else
716                         data = to_utf8(kvm[field]);
717
718                 if (data.empty())
719                         continue;
720
721                 try {
722                         if (lyx::regex_search(data, reg_exp))
723                                 foundKeys.push_back(*it);
724                 }
725                 catch (lyx::regex_error const & e) {
726                         LYXERR(Debug::GUI, e.what());
727                         return vector<docstring>();
728                 }
729         }
730         return foundKeys;
731 }
732
733
734 void GuiCitation::dispatchParams()
735 {
736         std::string const lfun = InsetCommand::params2string(params_);
737         dispatch(FuncRequest(getLfun(), lfun));
738 }
739
740
741 BiblioInfo const & GuiCitation::bibInfo() const
742 {
743         Buffer const & buf = documentBuffer();
744         buf.reloadBibInfoCache();
745         return buf.masterBibInfo();
746 }
747
748
749 void GuiCitation::saveSession() const
750 {
751         Dialog::saveSession();
752         QSettings settings;
753         settings.setValue(
754                 sessionKey() + "/regex", regexCB->isChecked());
755         settings.setValue(
756                 sessionKey() + "/casesensitive", caseCB->isChecked());
757         settings.setValue(
758                 sessionKey() + "/autofind", asTypeCB->isChecked());
759 }
760
761
762 void GuiCitation::restoreSession()
763 {
764         Dialog::restoreSession();
765         QSettings settings;
766         regexCB->setChecked(
767                 settings.value(sessionKey() + "/regex").toBool());
768         caseCB->setChecked(
769                 settings.value(sessionKey() + "/casesensitive").toBool());
770         asTypeCB->setChecked(
771                 settings.value(sessionKey() + "/autofind").toBool());
772 }
773
774
775 Dialog * createGuiCitation(GuiView & lv) { return new GuiCitation(lv); }
776
777
778 } // namespace frontend
779 } // namespace lyx
780
781 #include "moc_GuiCitation.cpp"
782