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