The branch, biblatex2, has been updated.

- Log -----------------------------------------------------------------

commit 8e4bd6a497561b1dda99f0b75102a9f8a1ca46ff
Author: Juergen Spitzmueller <[email protected]>
Date:   Sat Dec 31 09:28:51 2016 +0100

    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.

diff --git a/lib/citeengines/basic.citeengine b/lib/citeengines/basic.citeengine
index dc4941b..7de5e35 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 13bbc6f..de292bb 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 63bf1cb..dcd160f 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 326d487..1e7f772 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<string, CiteEngineType> 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<string, Spacing::Space> 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<string>(use_bibtopic)
           << "\n\\use_indices " << convert<string>(use_indices)
diff --git a/src/CiteEnginesList.cpp b/src/CiteEnginesList.cpp
index 48222cb..209c8bc 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 <algorithm>
 
@@ -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<string, CiteEngineType> 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 0e6d119..17cfbb8 100644
--- a/src/CiteEnginesList.h
+++ b/src/CiteEnginesList.h
@@ -13,6 +13,8 @@
 #ifndef CITEENGINESLIST_H
 #define CITEENGINESLIST_H
 
+#include "Citation.h"
+
 #include <string>
 #include <vector>
 
@@ -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<std::string> const & getEngineType() const { return 
engine_types_; }
        ///
+       bool hasEngineType(CiteEngineType const &) const;
+       ///
        std::string const & getDescription() const { return description_; }
        ///
        std::vector<std::string> 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 6ef39dc..d971eeb 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<Ui::BiblioUi>;
-       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<string> 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<string> const & engs, CiteEngineType 
const & sel)
+{
+       biblioModule->citeStyleCO->clear();
+
+       vector<string>::const_iterator it  = engs.begin();
+       vector<string>::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");
-               bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
-       }
-       else
-       if (biblioModule->citeStyleCO->currentIndex())
-               bp_.setCiteEngineType(ENGINE_TYPE_NUMERICAL);
+       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_AUTHORYEAR);
+               bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
 
        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 c055378..e5aa4fa 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<std::string> 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 f0103cf..7cc821b 100644
--- a/src/frontends/qt4/ui/BiblioUi.ui
+++ b/src/frontends/qt4/ui/BiblioUi.ui
@@ -1,7 +1,8 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
  <class>BiblioUi</class>
- <widget class="QWidget" name="BiblioUi" >
-  <property name="geometry" >
+ <widget class="QWidget" name="BiblioUi">
+  <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
@@ -9,81 +10,93 @@
     <height>394</height>
    </rect>
   </property>
-  <property name="windowTitle" >
+  <property name="windowTitle">
    <string/>
   </property>
-  <layout class="QGridLayout" name="gridLayout_3" >
-   <item row="0" column="0" >
-    <widget class="QGroupBox" name="CiteStyleBG" >
-     <property name="title" >
+  <layout class="QGridLayout" name="gridLayout_3">
+   <item row="0" column="0">
+    <widget class="QGroupBox" name="CiteStyleBG">
+     <property name="title">
       <string>Citation Style</string>
      </property>
-     <property name="flat" >
+     <property name="flat">
       <bool>true</bool>
      </property>
-     <layout class="QGridLayout" name="gridLayout" >
-      <item row="0" column="0" >
-       <widget class="QRadioButton" name="citeDefaultRB" >
-        <property name="toolTip" >
-         <string>Use BibTeX's default numerical styles</string>
-        </property>
-        <property name="text" >
-         <string>&amp;Default (numerical)</string>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="0" column="0">
+       <layout class="QHBoxLayout">
+        <property name="spacing">
+         <number>6</number>
         </property>
-       </widget>
-      </item>
-      <item row="1" column="0" >
-       <widget class="QRadioButton" name="citeNatbibRB" >
-        <property name="toolTip" >
-         <string>Use the natbib styles for natural sciences and arts. Set 
additional parameters in document class options.</string>
+        <property name="leftMargin">
+         <number>0</number>
         </property>
-        <property name="text" >
-         <string>&amp;Natbib</string>
+        <property name="topMargin">
+         <number>0</number>
         </property>
-       </widget>
-      </item>
-      <item row="1" column="1" >
-       <layout class="QHBoxLayout" >
-        <property name="spacing" >
-         <number>6</number>
+        <property name="rightMargin">
+         <number>0</number>
         </property>
-        <property name="margin" >
+        <property name="bottomMargin">
          <number>0</number>
         </property>
         <item>
-         <widget class="QLabel" name="citationStyleL" >
-          <property name="enabled" >
+         <widget class="QLabel" name="citeEngineLA">
+          <property name="toolTip">
+           <string/>
+          </property>
+          <property name="text">
+           <string>Sty&amp;le Engine:</string>
+          </property>
+          <property name="buddy">
+           <cstring>citeEngineCO</cstring>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QComboBox" name="citeEngineCO">
+          <property name="toolTip">
+           <string>A selection of different style engines (such as natbib) 
that respectively provide support for specific citytion and bibliography 
styles. Expand to get more information.</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QLabel" name="citationStyleL">
+          <property name="enabled">
            <bool>false</bool>
           </property>
-          <property name="text" >
-           <string>Natbib &amp;style:</string>
+          <property name="text">
+           <string>&amp;Variant:</string>
           </property>
-          <property name="buddy" >
+          <property name="buddy">
            <cstring>citeStyleCO</cstring>
           </property>
          </widget>
         </item>
         <item>
-         <widget class="QComboBox" name="citeStyleCO" >
-          <property name="enabled" >
+         <widget class="QComboBox" name="citeStyleCO">
+          <property name="enabled">
            <bool>false</bool>
           </property>
-          <property name="sizePolicy" >
-           <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
             <horstretch>0</horstretch>
             <verstretch>0</verstretch>
            </sizepolicy>
           </property>
+          <property name="toolTip">
+           <string>Provides available cite style variants.</string>
+          </property>
          </widget>
         </item>
        </layout>
       </item>
-      <item row="1" column="2" >
+      <item row="0" column="1">
        <spacer>
-        <property name="orientation" >
+        <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
-        <property name="sizeHint" stdset="0" >
+        <property name="sizeHint" stdset="0">
          <size>
           <width>40</width>
           <height>20</height>
@@ -91,55 +104,45 @@
         </property>
        </spacer>
       </item>
-      <item row="2" column="0" >
-       <widget class="QRadioButton" name="citeJurabibRB" >
-        <property name="toolTip" >
-         <string>Use the jurabib styles for law and humanities</string>
-        </property>
-        <property name="text" >
-         <string>&amp;Jurabib</string>
-        </property>
-       </widget>
-      </item>
      </layout>
     </widget>
    </item>
-   <item row="1" column="0" >
-    <widget class="QGroupBox" name="BiblioStyleBG" >
-     <property name="title" >
+   <item row="1" column="0">
+    <widget class="QGroupBox" name="BiblioStyleBG">
+     <property name="title">
       <string>Bibliography Style</string>
      </property>
-     <property name="flat" >
+     <property name="flat">
       <bool>true</bool>
      </property>
-     <layout class="QGridLayout" name="gridLayout_1" >
-      <item row="0" column="0" >
-       <layout class="QHBoxLayout" name="horizontalLayout_1" >
+     <layout class="QGridLayout" name="gridLayout_1">
+      <item row="0" column="0">
+       <layout class="QHBoxLayout" name="horizontalLayout_1">
         <item>
-         <widget class="QLabel" name="bibtexStyleLA" >
-          <property name="text" >
+         <widget class="QLabel" name="bibtexStyleLA">
+          <property name="text">
            <string>Default st&amp;yle:</string>
           </property>
-          <property name="buddy" >
+          <property name="buddy">
            <cstring>bibtexStyleLE</cstring>
           </property>
          </widget>
         </item>
         <item>
-         <widget class="QLineEdit" name="bibtexStyleLE" >
-          <property name="toolTip" >
+         <widget class="QLineEdit" name="bibtexStyleLE">
+          <property name="toolTip">
            <string>Define the default BibTeX style</string>
           </property>
          </widget>
         </item>
        </layout>
       </item>
-      <item row="1" column="0" >
-       <widget class="QCheckBox" name="bibtopicCB" >
-        <property name="toolTip" >
+      <item row="1" column="0">
+       <widget class="QCheckBox" name="bibtopicCB">
+        <property name="toolTip">
          <string>Select this if you want to split your bibliography into 
sections</string>
         </property>
-        <property name="text" >
+        <property name="text">
          <string>S&amp;ectioned bibliography</string>
         </property>
        </widget>
@@ -147,45 +150,45 @@
      </layout>
     </widget>
    </item>
-   <item row="2" column="0" >
-    <widget class="QGroupBox" name="bibtexGB" >
-     <property name="toolTip" >
+   <item row="2" column="0">
+    <widget class="QGroupBox" name="bibtexGB">
+     <property name="toolTip">
       <string>Here you can define an alternative program to or specific 
options of BibTeX.</string>
      </property>
-     <property name="title" >
+     <property name="title">
       <string>Bibliography Generation</string>
      </property>
-     <property name="flat" >
+     <property name="flat">
       <bool>true</bool>
      </property>
-     <layout class="QGridLayout" name="gridLayout_2" >
-      <item row="0" column="0" >
-       <layout class="QHBoxLayout" name="horizontalLayout" >
+     <layout class="QGridLayout" name="gridLayout_2">
+      <item row="0" column="0">
+       <layout class="QHBoxLayout" name="horizontalLayout">
         <item>
-         <widget class="QLabel" name="bibtexLA" >
-          <property name="text" >
+         <widget class="QLabel" name="bibtexLA">
+          <property name="text">
            <string>&amp;Processor:</string>
           </property>
-          <property name="buddy" >
+          <property name="buddy">
            <cstring>bibtexCO</cstring>
           </property>
          </widget>
         </item>
         <item>
-         <widget class="QComboBox" name="bibtexCO" >
-          <property name="toolTip" >
+         <widget class="QComboBox" name="bibtexCO">
+          <property name="toolTip">
            <string>Select a processor</string>
           </property>
          </widget>
         </item>
        </layout>
       </item>
-      <item rowspan="2" row="0" column="1" >
-       <spacer name="horizontalSpacer" >
-        <property name="orientation" >
+      <item row="0" column="1" rowspan="2">
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
-        <property name="sizeHint" stdset="0" >
+        <property name="sizeHint" stdset="0">
          <size>
           <width>183</width>
           <height>20</height>
@@ -193,21 +196,21 @@
         </property>
        </spacer>
       </item>
-      <item row="1" column="0" >
-       <layout class="QHBoxLayout" name="horizontalLayout_2" >
+      <item row="1" column="0">
+       <layout class="QHBoxLayout" name="horizontalLayout_2">
         <item>
-         <widget class="QLabel" name="bibtexOptionsLA" >
-          <property name="text" >
-           <string>&amp;Options:</string>
+         <widget class="QLabel" name="bibtexOptionsLA">
+          <property name="text">
+           <string>Op&amp;tions:</string>
           </property>
-          <property name="buddy" >
+          <property name="buddy">
            <cstring>bibtexOptionsLE</cstring>
           </property>
          </widget>
         </item>
         <item>
-         <widget class="QLineEdit" name="bibtexOptionsLE" >
-          <property name="toolTip" >
+         <widget class="QLineEdit" name="bibtexOptionsLE">
+          <property name="toolTip">
            <string>Define options such as --min-crossrefs (see the 
documentation of BibTeX)</string>
           </property>
          </widget>
@@ -217,15 +220,15 @@
      </layout>
     </widget>
    </item>
-   <item row="3" column="0" >
+   <item row="3" column="0">
     <spacer>
-     <property name="orientation" >
+     <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
-     <property name="sizeType" >
+     <property name="sizeType">
       <enum>QSizePolicy::Expanding</enum>
      </property>
-     <property name="sizeHint" stdset="0" >
+     <property name="sizeHint" stdset="0">
       <size>
        <width>20</width>
        <height>20</height>
@@ -236,7 +239,7 @@
   </layout>
  </widget>
  <includes>
-  <include location="local" >qt_i18n.h</include>
+  <include location="local">qt_i18n.h</include>
  </includes>
  <resources/>
  <connections/>

commit 0e6a3ac40427ec3107cb88aa678fbe92473e7d45
Author: Juergen Spitzmueller <[email protected]>
Date:   Fri Dec 30 16:22:08 2016 +0100

    Disentangle CiteEngines and Modules
    
    These two are different beasts and thus should be handled differently.

diff --git a/lib/Makefile.am b/lib/Makefile.am
index ee7e2b1..36c9c0c 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -2107,7 +2107,6 @@ dist_layouts_DATA =\
        layouts/arab-article.layout \
        layouts/article.layout \
        layouts/article-beamer.layout \
-       layouts/basic.module \
        layouts/beamer.layout \
        layouts/beamerposter.layout \
        layouts/bicaption.module \
@@ -2185,7 +2184,6 @@ dist_layouts_DATA =\
        layouts/jsarticle.layout \
        layouts/jsbook.layout \
        layouts/jss.layout \
-       layouts/jurabib.module \
        layouts/kluwer.layout \
        layouts/knitr.module \
        layouts/latex8.layout \
@@ -2205,7 +2203,6 @@ dist_layouts_DATA =\
        layouts/mwart.layout \
        layouts/mwbk.layout \
        layouts/mwrep.layout \
-       layouts/natbib.module \
        layouts/natbibapa.module \
        layouts/noweb.module \
        layouts/numarticle.inc \
@@ -2302,6 +2299,12 @@ dist_layouts_DATA =\
        layouts/tufte-handout.layout \
        layouts/varwidth.module
 
+citeenginesdir = $(pkgdatadir)/citeengines
+dist_citeengines_DATA = \
+       citeengines/basic.citeengine \
+        citeengines/jurabib.citeengine \
+        citeengines/natbib.citeengine
+
 scriptsdir = $(pkgdatadir)/scripts
 dist_scripts_DATA = \
        scripts/bash_completion \
diff --git a/lib/chkconfig.ltx b/lib/chkconfig.ltx
index 140014a..9daca8f 100644
--- a/lib/chkconfig.ltx
+++ b/lib/chkconfig.ltx
@@ -492,6 +492,7 @@
 % configure script.
 \input{chklayouts}
 \input{chkmodules}
+\input{chkciteengines}
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%% END ACTUAL CONFIGURATION INSPECTION CODE %%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/layouts/basic.module b/lib/citeengines/basic.citeengine
similarity index 93%
rename from lib/layouts/basic.module
rename to lib/citeengines/basic.citeengine
index 8e0ed1c..dc4941b 100644
--- a/lib/layouts/basic.module
+++ b/lib/citeengines/basic.citeengine
@@ -1,9 +1,8 @@
-# \DeclareLyXModule{Default (basic)}
+# \DeclareLyXCiteEngine{BibTeX (basic)}
 # DescriptionBegin
 #   Use the basic citation capabilities provided by plain LaTeX.
 # DescriptionEnd
 # Excludes: jurabib | natbib
-# Category: Citation engine
 
 # Author: Julien Rioux <[email protected]>
 
diff --git a/lib/layouts/jurabib.module b/lib/citeengines/jurabib.citeengine
similarity index 98%
rename from lib/layouts/jurabib.module
rename to lib/citeengines/jurabib.citeengine
index 63bae5a..13bbc6f 100644
--- a/lib/layouts/jurabib.module
+++ b/lib/citeengines/jurabib.citeengine
@@ -1,11 +1,10 @@
-# \DeclareLyXModule[jurabib.sty]{Jurabib}
+# \DeclareLyXCiteEngine[jurabib.sty]{Jurabib}
 # 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.
 # DescriptionEnd
 # Excludes: basic | natbib
-# Category: Citation engine
 
 # Author: Julien Rioux <[email protected]>
 
diff --git a/lib/layouts/natbib.module b/lib/citeengines/natbib.citeengine
similarity index 97%
rename from lib/layouts/natbib.module
rename to lib/citeengines/natbib.citeengine
index d4d250e..63bf1cb 100644
--- a/lib/layouts/natbib.module
+++ b/lib/citeengines/natbib.citeengine
@@ -1,4 +1,4 @@
-# \DeclareLyXModule[natbib.sty]{Natbib}
+# \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
@@ -6,7 +6,6 @@
 #   `van' part of author names, shortened and full author lists, and more.
 # DescriptionEnd
 # Excludes: basic | jurabib
-# Category: Citation engine
 
 # Author: Julien Rioux <[email protected]>
 
diff --git a/lib/configure.py b/lib/configure.py
index fb1abd3..680e32a 100644
--- a/lib/configure.py
+++ b/lib/configure.py
@@ -1502,6 +1502,132 @@ def processModuleFile(file, filename, bool_docbook):
     return '"%s" "%s" "%s" "%s" "%s" "%s" "%s"\n' % (modname, filename, desc, 
pkgs, req, excl, catgy)
 
 
+def checkCiteEnginesConfig():
+  removeFiles(['lyxciteengines.lst', 'chkciteengines.tex'])
+
+  logger.info('+checking list of cite engines... ')
+  tx = open('lyxciteengines.lst', 'w')
+  tx.write('''## This file declares cite engines and their associated 
definition files.
+## It has been automatically generated by configure
+## Use "Options/Reconfigure" if you need to update it after a
+## configuration change.
+## "CiteEngineName" "filename" "CiteEngineType" "Description" "Packages" 
"Requires" "Excludes"
+''')
+
+  # build the list of available modules
+  seen = []
+  # note that this searches the local directory first, then the
+  # system directory. that way, we pick up the user's version first.
+  for file in glob.glob( os.path.join('citeengines', '*.citeengine') ) + \
+      glob.glob( os.path.join(srcdir, 'citeengines', '*.citeengine' ) ) :
+      # valid file?
+      logger.info(file)
+      if not os.path.isfile(file):
+          continue
+
+      filename = file.split(os.sep)[-1]
+      filename = filename[:-11]
+      if seen.count(filename):
+          continue
+
+      seen.append(filename)
+      retval = processCiteEngineFile(file, filename, bool_docbook)
+      if retval != "":
+          tx.write(retval)
+  tx.close()
+  logger.info('\tdone')
+
+
+def processCiteEngineFile(file, filename, bool_docbook):
+    ''' process cite engines file and get a line of result
+
+        The top of a cite engine file should look like this:
+          #\DeclareLyXCiteEngine[LaTeX Packages]{CiteEngineName}
+          #DescriptionBegin
+          #...body of description...
+          #DescriptionEnd
+          #Requires: [list of required engines]
+          #Excludes: [list of excluded engines]
+        The last two lines are optional.
+        We expect output:
+          "CiteEngineName" "filename" "CiteEngineType" "Description" 
"Packages" "Requires" "Excludes"
+    '''
+    remods = re.compile(r'\DeclareLyXCiteEngine\s*(?:\[([^]]*?)\])?{(.*)}')
+    rereqs = re.compile(r'#+\s*Requires: (.*)')
+    reexcs = re.compile(r'#+\s*Excludes: (.*)')
+    redbeg = re.compile(r'#+\s*DescriptionBegin\s*$')
+    redend = re.compile(r'#+\s*DescriptionEnd\s*$')
+    recet = re.compile(r'\s*CiteEngineType (.*)')
+
+    modname = desc = pkgs = req = excl = cet = ""
+    readingDescription = False
+    descLines = []
+
+    for line in open(file).readlines():
+      if readingDescription:
+        res = redend.search(line)
+        if res != None:
+          readingDescription = False
+          desc = " ".join(descLines)
+          # Escape quotes.
+          desc = desc.replace('"', '\\"')
+          continue
+        descLines.append(line[1:].strip())
+        continue
+      res = redbeg.search(line)
+      if res != None:
+        readingDescription = True
+        continue
+      res = remods.search(line)
+      if res != None:
+          (pkgs, modname) = res.groups()
+          if pkgs == None:
+            pkgs = ""
+          else:
+            tmp = [s.strip() for s in pkgs.split(",")]
+            pkgs = ",".join(tmp)
+          continue
+      res = rereqs.search(line)
+      if res != None:
+        req = res.group(1)
+        tmp = [s.strip() for s in req.split("|")]
+        req = "|".join(tmp)
+        continue
+      res = reexcs.search(line)
+      if res != None:
+        excl = res.group(1)
+        tmp = [s.strip() for s in excl.split("|")]
+        excl = "|".join(tmp)
+        continue
+      res = recet.search(line)
+      if res != None:
+        cet = res.group(1)
+        continue
+
+    if modname == "":
+      logger.warning("Cite Engine File file without \DeclareLyXCiteEngine 
line. ")
+      return ""
+
+    if pkgs != "":
+        # this cite engine has some latex dependencies:
+        # append the dependencies to chkciteengines.tex,
+        # which is \input'ed by chkconfig.ltx
+        testpackages = list()
+        for pkg in pkgs.split(","):
+            if "->" in pkg:
+                # this is a converter dependency: skip
+                continue
+            if pkg.endswith(".sty"):
+                pkg = pkg[:-4]
+            testpackages.append("\\TestPackage{%s}" % (pkg,))
+        cm = open('chkciteengines.tex', 'a')
+        for line in testpackages:
+            cm.write(line + '\n')
+        cm.close()
+
+    return '"%s" "%s" "%s" "%s" "%s" "%s" "%s"\n' % (modname, filename, cet, 
desc, pkgs, req, excl)
+
+
 def checkTeXAllowSpaces():
     ''' Let's check whether spaces are allowed in TeX file names '''
     tex_allows_spaces = 'false'
@@ -1543,8 +1669,8 @@ def removeTempFiles():
     # Final clean-up
     if not lyx_keep_temps:
         removeFiles(['chkconfig.vars', 'chklatex.ltx', 'chklatex.log',
-            'chklayouts.tex', 'chkmodules.tex', 'missfont.log',
-            'wrap_chkconfig.ltx', 'wrap_chkconfig.log'])
+            'chklayouts.tex', 'chkmodules.tex', 'chkciteengines.tex',
+            'missfont.log', 'wrap_chkconfig.ltx', 'wrap_chkconfig.log'])
 
 
 if __name__ == '__main__':
@@ -1623,6 +1749,7 @@ Format %i
     if lyx_kpsewhich:
         rescanTeXFiles()
     checkModulesConfig()
+    checkCiteEnginesConfig()
     # --without-latex-config can disable lyx_check_config
     ret = checkLatexConfig(lyx_check_config and LATEX != '', bool_docbook)
     removeTempFiles()
diff --git a/po/Rules-lyx b/po/Rules-lyx
index 42998f2..23d4c06 100644
--- a/po/Rules-lyx
+++ b/po/Rules-lyx
@@ -34,7 +34,7 @@ layouts_l10n.pot: $(top_srcdir)/lib/layouts/*.layout \
 # Read translatable strings from layouts and translations from the po files and
 # create the layouttranslations file containing all LaTeX relevant translations
 $(top_srcdir)/lib/layouttranslations: $(POFILES) 
$(top_srcdir)/lib/layouts/*.layout \
-                $(top_srcdir)/lib/layouts/*.inc 
$(top_srcdir)/lib/layouts/*.module
+                $(top_srcdir)/lib/layouts/*.inc 
$(top_srcdir)/lib/layouts/*.module $(top_srcdir)/lib/citeengines/*.citeengines
        $(LYX_POT) -o $@ -t layouttranslations 
${top_srcdir}/lib/layouts/*.layout ${top_srcdir}/lib/layouts/*.inc 
${top_srcdir}/lib/layouts/*.module
 
 languages_l10n.pot: $(top_srcdir)/lib/languages
diff --git a/po/lyx_pot.py b/po/lyx_pot.py
index 761e3dd..0fc7ee4 100755
--- a/po/lyx_pot.py
+++ b/po/lyx_pot.py
@@ -91,6 +91,7 @@ def layouts_l10n(input_files, output, base, 
layouttranslations):
     ListName = re.compile(r'^\s*ListName\s+(.*\S)\s*$', re.IGNORECASE)
     CategoryName = re.compile(r'^\s*Category\s+(.*\S)\s*$', re.IGNORECASE)
     NameRE = re.compile(r'^\s*#\s*\\DeclareLyXModule.*{(.*)}$', re.IGNORECASE)
+    CiteNameRE = re.compile(r'^\s*#\s*\\DeclareLyXCiteEngine.*{(.*)}$', 
re.IGNORECASE)
     InsetLayout = re.compile(r'^InsetLayout\s+\"?(.*)\"?\s*$', re.IGNORECASE)
     FlexCheck = re.compile(r'^Flex:(.*)', re.IGNORECASE)
     CaptionCheck = re.compile(r'^Caption:(.*)', re.IGNORECASE)
@@ -234,6 +235,12 @@ def layouts_l10n(input_files, output, base, 
layouttranslations):
                 if not layouttranslations:
                     writeString(out, src, base, lineno + 1, string)
                 continue
+            res = CiteNameRE.search(line)
+            if res != None:
+                string = res.group(1)
+                if not layouttranslations:
+                    writeString(out, src, base, lineno + 1, string)
+                continue
             res = Style.search(line)
             if res != None:
                 string = res.group(1)
diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp
index fa0b7c3..326d487 100644
--- a/src/BufferParams.cpp
+++ b/src/BufferParams.cpp
@@ -2333,6 +2333,7 @@ void BufferParams::makeDocumentClass(bool const clone)
 
        invalidateConverterCache();
        LayoutModuleList mods;
+       LayoutModuleList ces;
        LayoutModuleList::iterator it = layout_modules_.begin();
        LayoutModuleList::iterator en = layout_modules_.end();
        for (; it != en; ++it)
@@ -2341,9 +2342,9 @@ void BufferParams::makeDocumentClass(bool const clone)
        it = cite_engine_.begin();
        en = cite_engine_.end();
        for (; it != en; ++it)
-               mods.push_back(*it);
+               ces.push_back(*it);
 
-       doc_class_ = getDocumentClass(*baseClass(), mods, clone);
+       doc_class_ = getDocumentClass(*baseClass(), mods, ces, clone);
 
        TextClass::ReturnValues success = TextClass::OK;
        if (!forced_local_layout_.empty())
diff --git a/src/CiteEnginesList.cpp b/src/CiteEnginesList.cpp
new file mode 100644
index 0000000..48222cb
--- /dev/null
+++ b/src/CiteEnginesList.cpp
@@ -0,0 +1,280 @@
+// -*- C++ -*-
+/**
+ * \file CiteEnginesList.cpp
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Richard Heck
+ * \author Jürgen Spitzmüller
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "CiteEnginesList.h"
+
+#include "LaTeXFeatures.h"
+#include "Lexer.h"
+
+#include "support/debug.h"
+#include "support/FileName.h"
+#include "support/gettext.h"
+#include "support/filetools.h"
+#include "support/lstrings.h"
+
+#include <algorithm>
+
+using namespace std;
+using namespace lyx::support;
+
+namespace lyx {
+
+
+//global variable: cite engine list
+CiteEnginesList theCiteEnginesList;
+
+
+LyXCiteEngine::LyXCiteEngine(string const & n, string const & i,
+                            vector<string> const & cet, string const & d,
+                            vector<string> const & p,
+                            vector<string> const & r, vector<string> const & 
e):
+       name_(n), id_(i), engine_types_(cet), description_(d), package_list_(p),
+       required_engines_(r), excluded_engines_(e),
+       checked_(false), available_(false)
+{
+       filename_ = id_ + ".citeengine";
+}
+
+
+vector<string> LyXCiteEngine::prerequisites() const
+{
+       if (!checked_)
+               isAvailable();
+       return prerequisites_;
+}
+
+
+bool LyXCiteEngine::isAvailable() const
+{
+       if (package_list_.empty())
+               return true;
+       if (checked_)
+               return available_;
+       checked_ = true;
+       available_ = true;
+       //check whether all of the required packages are available
+       vector<string>::const_iterator it  = package_list_.begin();
+       vector<string>::const_iterator end = package_list_.end();
+       for (; it != end; ++it) {
+               if (!LaTeXFeatures::isAvailable(*it)) {
+                       available_ = false;
+                       prerequisites_.push_back(*it);
+               }
+       }
+       return available_;
+}
+
+
+bool LyXCiteEngine::isCompatible(string const & cename) const
+{
+       // do we exclude it?
+       if (find(excluded_engines_.begin(), excluded_engines_.end(), cename) !=
+                       excluded_engines_.end())
+               return false;
+
+       LyXCiteEngine const * const lm = theCiteEnginesList[cename];
+       if (!lm)
+               return true;
+
+       // does it exclude us?
+       vector<string> const excengs = lm->getExcludedEngines();
+       if (find(excengs.begin(), excengs.end(), id_) != excengs.end())
+               return false;
+
+       return true;
+}
+
+
+bool LyXCiteEngine::areCompatible(string const & eng1, string const & eng2)
+{
+       LyXCiteEngine const * const lm1 = theCiteEnginesList[eng1];
+       if (lm1)
+               return lm1->isCompatible(eng2);
+       LyXCiteEngine const * const lm2 = theCiteEnginesList[eng2];
+       if (lm2)
+               return lm2->isCompatible(eng1);
+       // Can't check it either way.
+       return true;
+}
+
+
+// used when sorting the cite engine list.
+class EngineSorter {
+public:
+       int operator()(LyXCiteEngine const & ce1, LyXCiteEngine const & ce2) 
const
+       {
+               return _(ce1.getName()) < _(ce2.getName());
+       }
+};
+
+
+// Much of this is borrowed from LayoutFileList::read()
+bool CiteEnginesList::read()
+{
+       FileName const real_file = libFileSearch("", "lyxciteengines.lst");
+       LYXERR(Debug::TCLASS, "Reading cite engines from `" << real_file << 
'\'');
+
+       if (real_file.empty()) {
+               LYXERR0("unable to find cite engines file `citeengines.lst'.\n"
+                       << "No cite engines will be available.");
+               return false;
+       }
+
+       Lexer lex;
+       if (!lex.setFile(real_file)) {
+               LYXERR0("lyxlex was not able to set file: "
+                       << real_file << ".\nNo cite engines will be 
available.");
+               return false;
+       }
+
+       if (!lex.isOK()) {
+               LYXERR0("unable to open cite engines file  `"
+                       << to_utf8(makeDisplayPath(real_file.absFileName(), 
1000))
+                       << "'\nNo cite engines will be available.");
+               return false;
+       }
+
+       bool finished = false;
+       // Parse cite engines files
+       LYXERR(Debug::TCLASS, "Starting parsing of lyxciteengines.lst");
+       while (lex.isOK() && !finished) {
+               LYXERR(Debug::TCLASS, "\tline by line");
+               switch (lex.lex()) {
+               case Lexer::LEX_FEOF:
+                       finished = true;
+                       break;
+               default:
+                       string const cename = lex.getString();
+                       LYXERR(Debug::TCLASS, "Engine name: " << cename);
+                       if (!lex.next())
+                               break;
+                       string const fname = lex.getString();
+                       LYXERR(Debug::TCLASS, "Filename: " << fname);
+                       if (!lex.next(true))
+                               break;
+                       string cet = lex.getString();
+                       LYXERR(Debug::TCLASS, "Engine Type: " << cet);
+                       vector<string> cets;
+                       while (!cet.empty()) {
+                               string p;
+                               cet = split(cet, p, '|');
+                               cets.push_back(p);
+                       }
+                       if (!lex.next(true))
+                               break;
+                       string const desc = lex.getString();
+                       LYXERR(Debug::TCLASS, "Description: " << desc);
+                       //FIXME Add packages
+                       if (!lex.next())
+                               break;
+                       string str = lex.getString();
+                       LYXERR(Debug::TCLASS, "Packages: " << str);
+                       vector<string> pkgs;
+                       while (!str.empty()) {
+                               string p;
+                               str = split(str, p, ',');
+                               pkgs.push_back(p);
+                       }
+                       if (!lex.next())
+                               break;
+                       str = lex.getString();
+                       LYXERR(Debug::TCLASS, "Required: " << str);
+                       vector<string> req;
+                       while (!str.empty()) {
+                               string p;
+                               str = split(str, p, '|');
+                               req.push_back(p);
+                       }
+                       if (!lex.next())
+                               break;
+                       str = lex.getString();
+                       LYXERR(Debug::TCLASS, "Excluded: " << str);
+                       vector<string> exc;
+                       while (!str.empty()) {
+                               string p;
+                               str = split(str, p, '|');
+                               exc.push_back(p);
+                       }
+                       // This code is run when we have
+                       // cename, fname, desc, pkgs, req and exc
+                       addCiteEngine(cename, fname, cets, desc, pkgs, req, 
exc);
+               } // end switch
+       } //end while
+
+       LYXERR(Debug::TCLASS, "End of parsing of lyxciteengines.lst");
+
+       if (!theCiteEnginesList.empty())
+               sort(theCiteEnginesList.begin(), theCiteEnginesList.end(), 
EngineSorter());
+       return true;
+}
+
+
+void CiteEnginesList::addCiteEngine(string const & cename,
+       string const & filename, vector<string> const & cets, string const & 
description,
+       vector<string> const & pkgs, vector<string> const & req,
+       vector<string> const & exc)
+{
+       LyXCiteEngine ce(cename, filename, cets, description, pkgs, req, exc);
+       englist_.push_back(ce);
+}
+
+
+LyXCiteEnginesList::const_iterator CiteEnginesList::begin() const
+{
+       return englist_.begin();
+}
+
+
+LyXCiteEnginesList::iterator CiteEnginesList::begin()
+{
+       return englist_.begin();
+}
+
+
+LyXCiteEnginesList::const_iterator CiteEnginesList::end() const
+{
+       return englist_.end();
+}
+
+
+LyXCiteEnginesList::iterator CiteEnginesList::end()
+{
+       return englist_.end();
+}
+
+
+LyXCiteEngine const * CiteEnginesList::operator[](string const & str) const
+{
+       LyXCiteEnginesList::const_iterator it = englist_.begin();
+       for (; it != englist_.end(); ++it)
+               if (it->getID() == str) {
+                       LyXCiteEngine const & eng = *it;
+                       return &eng;
+               }
+       return 0;
+}
+
+
+LyXCiteEngine * CiteEnginesList::operator[](string const & str)
+{
+       LyXCiteEnginesList::iterator it = englist_.begin();
+       for (; it != englist_.end(); ++it)
+               if (it->getID() == str) {
+                       LyXCiteEngine & eng = *it;
+                       return &eng;
+               }
+       return 0;
+}
+
+} // namespace lyx
diff --git a/src/CiteEnginesList.h b/src/CiteEnginesList.h
new file mode 100644
index 0000000..0e6d119
--- /dev/null
+++ b/src/CiteEnginesList.h
@@ -0,0 +1,156 @@
+// -*- C++ -*-
+/**
+ * \file CiteEnginesList.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Richard Heck
+ * \author Jürgen Spitzmüller
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef CITEENGINESLIST_H
+#define CITEENGINESLIST_H
+
+#include <string>
+#include <vector>
+
+namespace lyx {
+
+/**
+ *  This class represents a particular LyX "cite engine", which defines the 
features
+ * of a particular citation backend such as natbib or biblatex. In that sense, 
it is more like
+ *  a LaTeX package, where a layout file corresponds to a LaTeX class.
+ *
+ *  In general, a given cite engine can be used with any document class. That 
said,
+ *  one cite engine may `require' another, or it may `exclude' some other cite 
engine.
+ *  The requires and excludes are given in comments within the cite engine 
file,
+ *  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.
+ *  # DescriptionEnd
+ *  # Excludes: basic | jurabib
+ *  The description might 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.
+ *
+ *  Engines can also be "provided" or "excluded" by document classes, using
+ *  the ProvidesEngine and ExcludesEngine tags.
+ */
+
+class LyXCiteEngine {
+public:
+       ///
+       LyXCiteEngine(std::string const & name, std::string const & id,
+                     std::vector<std::string> const & enginetypes,
+                     std::string const & description,
+                     std::vector<std::string> const & packagelist,
+                     std::vector<std::string> const & requires,
+                     std::vector<std::string> const & excludes);
+       /// whether the required packages are available
+       bool isAvailable() const;
+       /// the missing prerequisites, if any
+       std::vector<std::string> prerequisites() const;
+       ///
+       std::string const & getName() const { return name_; }
+       ///
+       std::string const & getID() const { return id_; }
+       ///
+       std::string const & getFilename() const { return filename_; }
+       ///
+       std::vector<std::string> const & getEngineType() const { return 
engine_types_; }
+       ///
+       std::string const & getDescription() const { return description_; }
+       ///
+       std::vector<std::string> const & getPackageList() const
+               { return package_list_; }
+       ///
+       std::vector<std::string> const & getRequiredEngines() const
+               { return required_engines_; }
+       /// Engines this one excludes: the list should be treated disjunctively
+       std::vector<std::string> const & getExcludedEngines() const
+               { return excluded_engines_; }
+       /// \return true if the engine is compatible with this one, i.e.,
+       /// it does not exclude us and we do not exclude it.
+       /// this will also return true if cename is unknown and we do not
+       /// exclude it, since in that case we cannot check its exclusions.
+       bool isCompatible(std::string const & cename) const;
+       ///
+       static bool areCompatible(std::string const & eng1, std::string const & 
eng2);
+private:
+       /// what appears in the ui
+       std::string name_;
+       /// the engine's unique identifier
+       /// at present, this is the filename, without the extension
+       std::string id_;
+       /// the filename
+       std::string filename_;
+       /// the engine type(s)
+       std::vector<std::string> engine_types_;
+       /// a short description for use in the ui
+       std::string description_;
+       /// the LaTeX packages on which this depends, if any
+       std::vector<std::string> package_list_;
+       /// Engines this one requires: at least one
+       std::vector<std::string> required_engines_;
+       /// Engines this one excludes: none of these
+       std::vector<std::string> excluded_engines_;
+       // these are mutable because they are used to cache the results
+       // or an otherwise const operation.
+       ///
+       mutable bool checked_;
+       ///
+       mutable bool available_;
+       ///
+       mutable std::vector<std::string> prerequisites_;
+};
+
+typedef std::vector<LyXCiteEngine> LyXCiteEnginesList;
+
+/**
+ *  The CiteEnginesList represents the various LyXCiteEngine's that are 
available at
+ *  present.
+ */
+class CiteEnginesList {
+public:
+       ///
+       CiteEnginesList() {}
+       /// reads the engines from a file generated by configure.py
+       bool read();
+       ///
+       LyXCiteEnginesList::const_iterator begin() const;
+       ///
+       LyXCiteEnginesList::iterator begin();
+       ///
+       LyXCiteEnginesList::const_iterator end() const;
+       ///
+       LyXCiteEnginesList::iterator end();
+       ///
+       bool empty() const { return englist_.empty(); }
+       /// Returns a pointer to the LyXCiteEngine with filename str.
+       /// Returns a null pointer if no such engine is found.
+       LyXCiteEngine const * operator[](std::string const & str) const;
+       ///
+       LyXCiteEngine * operator[](std::string const & str);
+       private:
+       /// noncopyable
+       CiteEnginesList(CiteEnginesList const &);
+       ///
+       void operator=(CiteEnginesList const &);
+       /// add an engine to the list
+       void addCiteEngine(std::string const &, std::string const &,
+               std::vector<std::string> const &, std::string const &, 
std::vector<std::string> const &,
+               std::vector<std::string> const &, std::vector<std::string> 
const &);
+       ///
+       std::vector<LyXCiteEngine> englist_;
+};
+
+extern CiteEnginesList theCiteEnginesList;
+}
+#endif
diff --git a/src/LyX.cpp b/src/LyX.cpp
index 047e265..157d432 100644
--- a/src/LyX.cpp
+++ b/src/LyX.cpp
@@ -22,6 +22,7 @@
 #include "Buffer.h"
 #include "BufferList.h"
 #include "CmdDef.h"
+#include "CiteEnginesList.h"
 #include "ColorSet.h"
 #include "ConverterCache.h"
 #include "Converter.h"
@@ -935,8 +936,10 @@ bool LyX::init()
        LYXERR(Debug::INIT, "Reading layouts...");
        // Load the layouts
        LayoutFileList::get().read();
-       //...and the modules
+       //... the modules
        theModuleList.read();
+       //... and the cite engines
+       theCiteEnginesList.read();
 
        // read keymap and ui files in batch mode as well
        // because InsetInfo needs to know these to produce
@@ -1020,7 +1023,8 @@ bool LyX::queryUserLyXDir(bool explicit_userdir)
                return configFileNeedsUpdate("lyxrc.defaults")
                        || configFileNeedsUpdate("lyxmodules.lst")
                        || configFileNeedsUpdate("textclass.lst")
-                       || configFileNeedsUpdate("packages.lst");
+                       || configFileNeedsUpdate("packages.lst")
+                       || configFileNeedsUpdate("lyxciteengines.lst");
        }
 
        first_start = !explicit_userdir;
diff --git a/src/Makefile.am b/src/Makefile.am
index f87d029..4cb38b5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -108,6 +108,7 @@ SOURCEFILESCORE = \
        Bullet.cpp \
        Changes.cpp \
        Chktex.cpp \
+       CiteEnginesList.cpp \
        CmdDef.cpp \
        Color.cpp \
        ConverterCache.cpp \
@@ -201,6 +202,7 @@ HEADERFILESCORE = \
        BufferView.h \
        Bullet.h \
        Citation.h \
+       CiteEnginesList.h \
        Changes.h \
        Chktex.h \
        CmdDef.h \
diff --git a/src/TextClass.cpp b/src/TextClass.cpp
index 46a96e4..d14ef29 100644
--- a/src/TextClass.cpp
+++ b/src/TextClass.cpp
@@ -17,6 +17,7 @@
 #include "TextClass.h"
 
 #include "LayoutFile.h"
+#include "CiteEnginesList.h"
 #include "Color.h"
 #include "Counters.h"
 #include "Floating.h"
@@ -123,6 +124,8 @@ string translateReadType(TextClass::ReadType rt)
                return "input file";
        case TextClass::MODULE:
                return "module file";
+       case TextClass::CITE_ENGINE:
+               return "cite engine";
        case TextClass::VALIDATION:
                return "validation";
        }
@@ -1585,6 +1588,7 @@ Layout TextClass::createBasicLayout(docstring const & 
name, bool unknown) const
 
 DocumentClassPtr getDocumentClass(
                LayoutFile const & baseClass, LayoutModuleList const & modlist,
+               LayoutModuleList const & celist,
                bool const clone)
 {
        DocumentClassPtr doc_class =
@@ -1623,6 +1627,42 @@ DocumentClassPtr getDocumentClass(
                        frontend::Alert::warning(_("Read Error"), msg);
                }
        }
+
+       LayoutModuleList::const_iterator cit = celist.begin();
+       LayoutModuleList::const_iterator cen = celist.end();
+       for (; cit != cen; ++cit) {
+               string const ceName = *cit;
+               LyXCiteEngine * ce = theCiteEnginesList[ceName];
+               if (!ce) {
+                       docstring const msg =
+                                               bformat(_("The cite engine %1$s 
has been requested by\n"
+                                               "this document but has not been 
found in the list of\n"
+                                               "available engines. If you 
recently installed it, you\n"
+                                               "probably need to reconfigure 
LyX.\n"), from_utf8(ceName));
+                       if (!clone)
+                               frontend::Alert::warning(_("Cite Engine not 
available"), msg);
+                       continue;
+               }
+               if (!ce->isAvailable() && !clone) {
+                       docstring const prereqs = 
from_utf8(getStringFromVector(ce->prerequisites(), "\n\t"));
+                       docstring const msg =
+                               bformat(_("The cite engine %1$s requires a 
package that is not\n"
+                                       "available in your LaTeX installation, 
or a converter that\n"
+                                       "you have not installed. LaTeX output 
may not be possible.\n"
+                                       "Missing prerequisites:\n"
+                                               "\t%2$s\n"
+                                       "See section 3.1.2.3 (Modules) of the 
User's Guide for more information."),
+                               from_utf8(ceName), prereqs);
+                       frontend::Alert::warning(_("Package not available"), 
msg, true);
+               }
+               FileName layout_file = libFileSearch("citeengines", 
ce->getFilename());
+               if (!doc_class->read(layout_file, TextClass::CITE_ENGINE)) {
+                       docstring const msg =
+                                               bformat(_("Error reading cite 
engine %1$s\n"), from_utf8(ceName));
+                       frontend::Alert::warning(_("Read Error"), msg);
+               }
+       }
+
        return doc_class;
 }
 
diff --git a/src/TextClass.h b/src/TextClass.h
index 22d426c..d082e10 100644
--- a/src/TextClass.h
+++ b/src/TextClass.h
@@ -151,6 +151,7 @@ public:
                BASECLASS, //>This is a base class, i.e., top-level layout file
                MERGE, //>This is a file included in a layout file
                MODULE, //>This is a layout module
+               CITE_ENGINE, //>This is a cite engine
                VALIDATION //>We're just validating
        };
        /// return values for read()
@@ -498,6 +499,7 @@ private:
        /// The only way to make a DocumentClass is to call this function.
        friend DocumentClassPtr
                getDocumentClass(LayoutFile const &, LayoutModuleList const &,
+                                LayoutModuleList const &,
                                 bool const clone);
 };
 
@@ -508,6 +510,7 @@ private:
 /// on the CutStack.
 DocumentClassPtr getDocumentClass(LayoutFile const & baseClass,
                        LayoutModuleList const & modlist,
+                       LayoutModuleList const & celist,
                        bool const clone = false);
 
 /// convert page sides option to text 1 or 2
diff --git a/src/tex2lyx/Makefile.am b/src/tex2lyx/Makefile.am
index bf2d66d..a4a5fdc 100644
--- a/src/tex2lyx/Makefile.am
+++ b/src/tex2lyx/Makefile.am
@@ -83,6 +83,7 @@ updatetests: tex2lyx
 
 LINKED_FILES = \
        ../Author.cpp \
+       ../CiteEnginesList.cpp \
        ../Color.cpp \
        ../Counters.cpp \
        ../Encoding.cpp \
diff --git a/src/tex2lyx/tex2lyx.cpp b/src/tex2lyx/tex2lyx.cpp
index 7a6bbb0..3f6fe73 100644
--- a/src/tex2lyx/tex2lyx.cpp
+++ b/src/tex2lyx/tex2lyx.cpp
@@ -282,10 +282,11 @@ void initModules()
                for (; it != end; ++it) {
                        string const module = it->getID();
                        LayoutModuleList m;
+                       LayoutModuleList c;
                        vector<string> v;
                        if (!addModule(module, baseClass, m, v))
                                continue;
-                       modules[module] = getDocumentClass(baseClass, m);
+                       modules[module] = getDocumentClass(baseClass, m, c);
                }
                init = false;
        }

-----------------------------------------------------------------------

Summary of changes:
 lib/Makefile.am                                    |    9 +-
 lib/chkconfig.ltx                                  |    1 +
 .../basic.module => citeengines/basic.citeengine}  |    6 +-
 .../jurabib.citeengine}                            |    9 +-
 .../natbib.citeengine}                             |   11 +-
 lib/configure.py                                   |  131 ++++++++-
 po/Rules-lyx                                       |    2 +-
 po/lyx_pot.py                                      |    7 +
 src/BufferParams.cpp                               |   31 +--
 src/CiteEnginesList.cpp                            |  326 ++++++++++++++++++++
 src/CiteEnginesList.h                              |  164 ++++++++++
 src/LyX.cpp                                        |    8 +-
 src/Makefile.am                                    |    2 +
 src/TextClass.cpp                                  |   40 +++
 src/TextClass.h                                    |    3 +
 src/frontends/qt4/GuiDocument.cpp                  |  136 +++++----
 src/frontends/qt4/GuiDocument.h                    |    3 +
 src/frontends/qt4/ui/BiblioUi.ui                   |  203 ++++++------
 src/tex2lyx/Makefile.am                            |    1 +
 src/tex2lyx/tex2lyx.cpp                            |    3 +-
 20 files changed, 883 insertions(+), 213 deletions(-)
 rename lib/{layouts/basic.module => citeengines/basic.citeengine} (83%)
 rename lib/{layouts/jurabib.module => citeengines/jurabib.citeengine} (91%)
 rename lib/{layouts/natbib.module => citeengines/natbib.citeengine} (89%)
 create mode 100644 src/CiteEnginesList.cpp
 create mode 100644 src/CiteEnginesList.h


hooks/post-receive
-- 
Repository for new features

Reply via email to