From 8e4bd6a497561b1dda99f0b75102a9f8a1ca46ff Mon Sep 17 00:00:00 2001 From: Juergen Spitzmueller Date: Sat, 31 Dec 2016 09:28:51 +0100 Subject: [PATCH] Properly support the cite engines in the GUI Instead of hardcoding 3 engines, we now support all engines which are defined in the *.citeengines files. --- lib/citeengines/basic.citeengine | 5 +- lib/citeengines/jurabib.citeengine | 8 +- lib/citeengines/natbib.citeengine | 10 +- src/BufferParams.cpp | 26 +--- src/CiteEnginesList.cpp | 46 +++++++ src/CiteEnginesList.h | 18 ++- src/frontends/qt4/GuiDocument.cpp | 136 ++++++++++--------- src/frontends/qt4/GuiDocument.h | 3 + src/frontends/qt4/ui/BiblioUi.ui | 207 +++++++++++++++-------------- 9 files changed, 253 insertions(+), 206 deletions(-) diff --git a/lib/citeengines/basic.citeengine b/lib/citeengines/basic.citeengine index dc4941b42d..7de5e35d52 100644 --- a/lib/citeengines/basic.citeengine +++ b/lib/citeengines/basic.citeengine @@ -1,6 +1,7 @@ -# \DeclareLyXCiteEngine{BibTeX (basic)} +# \DeclareLyXCiteEngine{Basic (BibTeX)} # DescriptionBegin -# Use the basic citation capabilities provided by plain LaTeX. +# The basic citation capabilities provided by BibTeX. +# Mainly simple numeric styles primarily suitable for science and maths. # DescriptionEnd # Excludes: jurabib | natbib diff --git a/lib/citeengines/jurabib.citeengine b/lib/citeengines/jurabib.citeengine index 13bbc6f9d3..de292bbe98 100644 --- a/lib/citeengines/jurabib.citeengine +++ b/lib/citeengines/jurabib.citeengine @@ -1,8 +1,8 @@ -# \DeclareLyXCiteEngine[jurabib.sty]{Jurabib} +# \DeclareLyXCiteEngine[jurabib.sty]{Jurabib (BibTeX)} # DescriptionBegin -# Loads the LaTeX package jurabib, a citation engine. Jurabib supports annotations, -# author-year style citations and hyphenation patterns for bibliography entries in -# English, German, French, Dutch, Spanish and Italian. +# Jurabib supports a range of author-year styles primarily suitable for law studies +# and the Humanities. It includes localizations for English, German, French, Dutch, +# Spanish and Italian. # DescriptionEnd # Excludes: basic | natbib diff --git a/lib/citeengines/natbib.citeengine b/lib/citeengines/natbib.citeengine index 63bf1cb2c8..dcd160f903 100644 --- a/lib/citeengines/natbib.citeengine +++ b/lib/citeengines/natbib.citeengine @@ -1,9 +1,9 @@ -# \DeclareLyXCiteEngine[natbib.sty]{Natbib} +# \DeclareLyXCiteEngine[natbib.sty]{Natbib (BibTeX)} # DescriptionBegin -# Loads the LaTeX package natbib, a citation engine. Natbib supports -# both author-year and numerical styles for citations, automatic sorting -# and merging of numerical citations, annotations, capitalization of the -# `van' part of author names, shortened and full author lists, and more. +# Natbib supports a range of both author-year and numerical styles mainly +# aimed at the Humanities. It features automatic sorting and merging of +# numerical citations, annotations, capitalization of the `van' part of +# author names, shortened and full author lists, and more. # DescriptionEnd # Excludes: basic | jurabib diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index 326d487645..1e7f77283f 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -23,6 +23,7 @@ #include "Buffer.h" #include "buffer_funcs.h" #include "Bullet.h" +#include "CiteEnginesList.h" #include "Color.h" #include "ColorSet.h" #include "Converter.h" @@ -272,27 +273,6 @@ PackageTranslator const & packagetranslator() } -// Cite engine -typedef Translator CiteEngineTypeTranslator; - - -CiteEngineTypeTranslator const init_citeenginetypetranslator() -{ - CiteEngineTypeTranslator translator("authoryear", ENGINE_TYPE_AUTHORYEAR); - translator.addPair("numerical", ENGINE_TYPE_NUMERICAL); - translator.addPair("default", ENGINE_TYPE_DEFAULT); - return translator; -} - - -CiteEngineTypeTranslator const & citeenginetypetranslator() -{ - static CiteEngineTypeTranslator const translator = - init_citeenginetypetranslator(); - return translator; -} - - // Spacing typedef Translator SpaceTranslator; @@ -863,7 +843,7 @@ string BufferParams::readToken(Lexer & lex, string const & token, } else if (token == "\\cite_engine_type") { string engine_type; lex >> engine_type; - cite_engine_type_ = citeenginetypetranslator().find(engine_type); + cite_engine_type_ = theCiteEnginesList.getType(engine_type); } else if (token == "\\biblio_style") { lex.eatLine(); biblio_style = lex.getString(); @@ -1234,7 +1214,7 @@ void BufferParams::writeFile(ostream & os, Buffer const * buf) const os << "basic"; } - os << "\n\\cite_engine_type " << citeenginetypetranslator().find(cite_engine_type_) + os << "\n\\cite_engine_type " << theCiteEnginesList.getTypeAsString(cite_engine_type_) << "\n\\biblio_style " << biblio_style << "\n\\use_bibtopic " << convert(use_bibtopic) << "\n\\use_indices " << convert(use_indices) diff --git a/src/CiteEnginesList.cpp b/src/CiteEnginesList.cpp index 48222cbb23..209c8bc840 100644 --- a/src/CiteEnginesList.cpp +++ b/src/CiteEnginesList.cpp @@ -14,6 +14,7 @@ #include "CiteEnginesList.h" +#include "Citation.h" #include "LaTeXFeatures.h" #include "Lexer.h" @@ -22,6 +23,7 @@ #include "support/gettext.h" #include "support/filetools.h" #include "support/lstrings.h" +#include "support/Translator.h" #include @@ -76,6 +78,13 @@ bool LyXCiteEngine::isAvailable() const } +bool LyXCiteEngine::hasEngineType(CiteEngineType const & et) const +{ + return std::find(engine_types_.begin(), engine_types_.end(), + theCiteEnginesList.getTypeAsString(et)) != engine_types_.end(); +} + + bool LyXCiteEngine::isCompatible(string const & cename) const { // do we exclude it? @@ -119,6 +128,43 @@ public: }; +// Local translators +namespace { + +typedef Translator CiteEngineTypeTranslator; + + +CiteEngineTypeTranslator const init_citeenginetypetranslator() +{ + CiteEngineTypeTranslator translator("authoryear", ENGINE_TYPE_AUTHORYEAR); + translator.addPair("numerical", ENGINE_TYPE_NUMERICAL); + translator.addPair("default", ENGINE_TYPE_DEFAULT); + return translator; +} + + +CiteEngineTypeTranslator const & citeenginetypetranslator() +{ + static CiteEngineTypeTranslator const translator = + init_citeenginetypetranslator(); + return translator; +} + +} // namespace anon + + +string CiteEnginesList::getTypeAsString(CiteEngineType const & et) const +{ + return citeenginetypetranslator().find(et); +} + + +CiteEngineType CiteEnginesList::getType(string const & et) const +{ + return citeenginetypetranslator().find(et); +} + + // Much of this is borrowed from LayoutFileList::read() bool CiteEnginesList::read() { diff --git a/src/CiteEnginesList.h b/src/CiteEnginesList.h index 0e6d119128..17cfbb8089 100644 --- a/src/CiteEnginesList.h +++ b/src/CiteEnginesList.h @@ -13,6 +13,8 @@ #ifndef CITEENGINESLIST_H #define CITEENGINESLIST_H +#include "Citation.h" + #include #include @@ -29,13 +31,13 @@ namespace lyx { * which must begin roughly so: * # \DeclareLyXCiteEngine[natbib.sty]{Natbib} * # DescriptionBegin - * # Loads the LaTeX package natbib, a citation engine. Natbib supports - * # both author-year and numerical styles for citations, automatic sorting - * # and merging of numerical citations, annotations, capitalization of the - * # `van' part of author names, shortened and full author lists, and more. + * # Natbib supports a range of both author-year and numerical styles mainly + * # aimed at the Humanities. It features automatic sorting and merging of + * # numerical citations, annotations, capitalization of the `van' part of + * # author names, shortened and full author lists, and more. * # DescriptionEnd * # Excludes: basic | jurabib - * The description might be used in the gui to give information to the user. The + * The description will be used in the gui to give information to the user. The * Requires and Excludes lines are read by the configuration script * and written to a file citeengines.lst in the user configuration directory. * That file is then read on startup to populate the CiteEnginesList, below. @@ -66,6 +68,8 @@ public: /// std::vector const & getEngineType() const { return engine_types_; } /// + bool hasEngineType(CiteEngineType const &) const; + /// std::string const & getDescription() const { return description_; } /// std::vector const & getPackageList() const @@ -121,6 +125,10 @@ class CiteEnginesList { public: /// CiteEnginesList() {} + /// + std::string getTypeAsString(CiteEngineType const &) const; + /// + CiteEngineType getType(std::string const &) const; /// reads the engines from a file generated by configure.py bool read(); /// diff --git a/src/frontends/qt4/GuiDocument.cpp b/src/frontends/qt4/GuiDocument.cpp index 6ef39dcb4d..d971eebe7b 100644 --- a/src/frontends/qt4/GuiDocument.cpp +++ b/src/frontends/qt4/GuiDocument.cpp @@ -29,6 +29,7 @@ #include "Buffer.h" #include "BufferParams.h" #include "BufferView.h" +#include "CiteEnginesList.h" #include "Color.h" #include "ColorCache.h" #include "Converter.h" @@ -1126,22 +1127,10 @@ GuiDocument::GuiDocument(GuiView & lv) // biblio biblioModule = new UiWidget; - connect(biblioModule->citeDefaultRB, SIGNAL(toggled(bool)), - this, SLOT(setNumerical(bool))); - connect(biblioModule->citeJurabibRB, SIGNAL(toggled(bool)), - this, SLOT(setAuthorYear(bool))); - connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)), - biblioModule->citationStyleL, SLOT(setEnabled(bool))); - connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)), - biblioModule->citeStyleCO, SLOT(setEnabled(bool))); - connect(biblioModule->citeDefaultRB, SIGNAL(clicked()), - this, SLOT(biblioChanged())); - connect(biblioModule->citeNatbibRB, SIGNAL(clicked()), - this, SLOT(biblioChanged())); + connect(biblioModule->citeEngineCO, SIGNAL(activated(int)), + this, SLOT(citeEngineChanged(int))); connect(biblioModule->citeStyleCO, SIGNAL(activated(int)), this, SLOT(biblioChanged())); - connect(biblioModule->citeJurabibRB, SIGNAL(clicked()), - this, SLOT(biblioChanged())); connect(biblioModule->bibtopicCB, SIGNAL(clicked()), this, SLOT(biblioChanged())); connect(biblioModule->bibtexCO, SIGNAL(activated(int)), @@ -1151,15 +1140,19 @@ GuiDocument::GuiDocument(GuiView & lv) connect(biblioModule->bibtexStyleLE, SIGNAL(textChanged(QString)), this, SLOT(biblioChanged())); + biblioModule->citeEngineCO->clear(); + for (LyXCiteEngine const & cet : theCiteEnginesList) { + biblioModule->citeEngineCO->addItem(qt_(cet.getName()), toqstr(cet.getID())); + int const i = biblioModule->citeEngineCO->findData(toqstr(cet.getID())); + biblioModule->citeEngineCO->setItemData(i, qt_(cet.getDescription()), + Qt::ToolTipRole); + } + biblioModule->bibtexOptionsLE->setValidator(new NoNewLineValidator( biblioModule->bibtexOptionsLE)); biblioModule->bibtexStyleLE->setValidator(new NoNewLineValidator( biblioModule->bibtexStyleLE)); - biblioModule->citeStyleCO->addItem(qt_("Author-year")); - biblioModule->citeStyleCO->addItem(qt_("Numerical")); - biblioModule->citeStyleCO->setCurrentIndex(0); - // NOTE: we do not provide "custom" here for security reasons! biblioModule->bibtexCO->clear(); biblioModule->bibtexCO->addItem(qt_("Default"), QString("default")); @@ -2278,6 +2271,19 @@ void GuiDocument::biblioChanged() } +void GuiDocument::citeEngineChanged(int n) +{ + QString const engine = biblioModule->citeEngineCO->itemData(n).toString(); + + vector const engs = + theCiteEnginesList[fromqstr(engine)]->getEngineType(); + + updateCiteStyles(engs); + + biblioChanged(); +} + + void GuiDocument::bibtexChanged(int n) { biblioModule->bibtexOptionsLE->setEnabled( @@ -2289,7 +2295,8 @@ void GuiDocument::bibtexChanged(int n) void GuiDocument::setAuthorYear(bool authoryear) { if (authoryear) - biblioModule->citeStyleCO->setCurrentIndex(0); + biblioModule->citeStyleCO->setCurrentIndex( + biblioModule->citeStyleCO->findData(ENGINE_TYPE_AUTHORYEAR)); biblioChanged(); } @@ -2297,11 +2304,39 @@ void GuiDocument::setAuthorYear(bool authoryear) void GuiDocument::setNumerical(bool numerical) { if (numerical) - biblioModule->citeStyleCO->setCurrentIndex(1); + biblioModule->citeStyleCO->setCurrentIndex( + biblioModule->citeStyleCO->findData(ENGINE_TYPE_NUMERICAL)); biblioChanged(); } +void GuiDocument::updateCiteStyles(vector const & engs, CiteEngineType const & sel) +{ + biblioModule->citeStyleCO->clear(); + + vector::const_iterator it = engs.begin(); + vector::const_iterator end = engs.end(); + for (; it != end; ++it) { + if (*it == "default") + biblioModule->citeStyleCO->addItem(qt_("Basic numerical"), + ENGINE_TYPE_DEFAULT); + else if (*it == "authoryear") + biblioModule->citeStyleCO->addItem(qt_("Author-year"), + ENGINE_TYPE_AUTHORYEAR); + else if (*it == "numerical") + biblioModule->citeStyleCO->addItem(qt_("Author-number"), + ENGINE_TYPE_NUMERICAL); + } + int i = biblioModule->citeStyleCO->findData(sel); + if (biblioModule->citeStyleCO->findData(sel) == -1) + i = 0; + biblioModule->citeStyleCO->setCurrentIndex(i); + + biblioModule->citationStyleL->setEnabled(engs.size() > 1); + biblioModule->citeStyleCO->setEnabled(engs.size() > 1); +} + + void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel) { engine_types_.clear(); @@ -2314,28 +2349,7 @@ void GuiDocument::updateEngineType(string const & items, CiteEngineType const & engine_types_.push_back(style); } - switch (sel) { - case ENGINE_TYPE_AUTHORYEAR: - biblioModule->citeStyleCO->setCurrentIndex(0); - break; - case ENGINE_TYPE_NUMERICAL: - case ENGINE_TYPE_DEFAULT: - biblioModule->citeStyleCO->setCurrentIndex(1); - break; - } - - biblioModule->citationStyleL->setEnabled(nn > 1); - biblioModule->citeStyleCO->setEnabled(nn > 1); - - if (nn != 1) - return; - - // If the textclass allows only one of authoryear or numerical, - // we have no choice but to force that engine type. - if (engine_types_[0] == "authoryear") - biblioModule->citeStyleCO->setCurrentIndex(0); - else - biblioModule->citeStyleCO->setCurrentIndex(1); + updateCiteStyles(engine_types_, sel); } @@ -2588,19 +2602,17 @@ void GuiDocument::applyView() bp_.use_refstyle = latexModule->refstyleCB->isChecked(); // biblio - if (biblioModule->citeNatbibRB->isChecked()) - bp_.setCiteEngine("natbib"); - else if (biblioModule->citeJurabibRB->isChecked()) - bp_.setCiteEngine("jurabib"); - if (biblioModule->citeDefaultRB->isChecked()) { - bp_.setCiteEngine("basic"); + string const engine = + fromqstr(biblioModule->citeEngineCO->itemData( + biblioModule->citeEngineCO->currentIndex()).toString()); + bp_.setCiteEngine(engine); + + CiteEngineType const style = CiteEngineType(biblioModule->citeStyleCO->itemData( + biblioModule->citeStyleCO->currentIndex()).toInt()); + if (theCiteEnginesList[engine]->hasEngineType(style)) + bp_.setCiteEngineType(style); + else bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT); - } - else - if (biblioModule->citeStyleCO->currentIndex()) - bp_.setCiteEngineType(ENGINE_TYPE_NUMERICAL); - else - bp_.setCiteEngineType(ENGINE_TYPE_AUTHORYEAR); bp_.use_bibtopic = biblioModule->bibtopicCB->isChecked(); @@ -3016,21 +3028,15 @@ void GuiDocument::paramsToDialog() // biblio string const cite_engine = bp_.citeEngine().list().front(); - biblioModule->citeDefaultRB->setChecked( - cite_engine == "basic"); - - biblioModule->citeJurabibRB->setChecked( - cite_engine == "jurabib"); - - biblioModule->citeNatbibRB->setChecked( - cite_engine == "natbib"); - - biblioModule->citeStyleCO->setCurrentIndex( - bp_.citeEngineType() & ENGINE_TYPE_NUMERICAL); + biblioModule->citeEngineCO->setCurrentIndex( + biblioModule->citeEngineCO->findData(toqstr(cite_engine))); updateEngineType(documentClass().opt_enginetype(), bp_.citeEngineType()); + biblioModule->citeStyleCO->setCurrentIndex( + biblioModule->citeStyleCO->findData(bp_.citeEngineType())); + biblioModule->bibtopicCB->setChecked( bp_.use_bibtopic); diff --git a/src/frontends/qt4/GuiDocument.h b/src/frontends/qt4/GuiDocument.h index c055378429..e5aa4fa553 100644 --- a/src/frontends/qt4/GuiDocument.h +++ b/src/frontends/qt4/GuiDocument.h @@ -75,6 +75,8 @@ public: void updateFontsize(std::string const &, std::string const &); void updateFontlist(); void updateDefaultFormat(); + void updateCiteStyles(std::vector const &, + CiteEngineType const & sel = ENGINE_TYPE_AUTHORYEAR); void updateEngineType(std::string const &, CiteEngineType const &); void updatePagestyle(std::string const &, std::string const &); bool isChildIncluded(std::string const &); @@ -113,6 +115,7 @@ private Q_SLOTS: void classChanged_adaptor(); void languagePackageChanged(int); void biblioChanged(); + void citeEngineChanged(int); void bibtexChanged(int); void setAuthorYear(bool); void setNumerical(bool); diff --git a/src/frontends/qt4/ui/BiblioUi.ui b/src/frontends/qt4/ui/BiblioUi.ui index f0103cfc83..7cc821b8c9 100644 --- a/src/frontends/qt4/ui/BiblioUi.ui +++ b/src/frontends/qt4/ui/BiblioUi.ui @@ -1,7 +1,8 @@ - + + BiblioUi - - + + 0 0 @@ -9,81 +10,93 @@ 394 - + - - - - + + + + Citation Style - + true - - - - - Use BibTeX's default numerical styles - - - &Default (numerical) - - - - - - - Use the natbib styles for natural sciences and arts. Set additional parameters in document class options. - - - &Natbib - - - - - - + + + + 6 - + + 0 + + + 0 + + + 0 + + 0 - - + + + + + + Sty&le Engine: + + + citeEngineCO + + + + + + + A selection of different style engines (such as natbib) that respectively provide support for specific citytion and bibliography styles. Expand to get more information. + + + + + + false - - Natbib &style: + + &Variant: - + citeStyleCO - - + + false - - + + 0 0 + + Provides available cite style variants. + - + - + Qt::Horizontal - + 40 20 @@ -91,55 +104,45 @@ - - - - Use the jurabib styles for law and humanities - - - &Jurabib - - - - - - + + + Bibliography Style - + true - - - + + + - - + + Default st&yle: - + bibtexStyleLE - - + + Define the default BibTeX style - - - + + + Select this if you want to split your bibliography into sections - + S&ectioned bibliography @@ -147,45 +150,45 @@ - - - + + + Here you can define an alternative program to or specific options of BibTeX. - + Bibliography Generation - + true - - - + + + - - + + &Processor: - + bibtexCO - - + + Select a processor - - - + + + Qt::Horizontal - + 183 20 @@ -193,21 +196,21 @@ - - + + - - - &Options: + + + Op&tions: - + bibtexOptionsLE - - + + Define options such as --min-crossrefs (see the documentation of BibTeX) @@ -217,15 +220,15 @@ - + - + Qt::Vertical - + QSizePolicy::Expanding - + 20 20 @@ -236,7 +239,7 @@ - qt_i18n.h + qt_i18n.h