From adc93015f9c356d4e5d594df86c888faaab8ad8b Mon Sep 17 00:00:00 2001 From: Juergen Spitzmueller Date: Sat, 31 Dec 2016 14:57:09 +0100 Subject: [PATCH] Rework default bibliography style UI * Use a combo with all available styles * Correctly reset default on engine change * Consider that EngineTypes might have different defaults --- lib/citeengines/natbib.citeengine | 2 +- lib/configure.py | 19 +++-- src/BufferParams.cpp | 3 +- src/CiteEnginesList.cpp | 52 ++++++++++-- src/CiteEnginesList.h | 10 ++- src/TextClass.cpp | 17 +++- src/TextClass.h | 5 +- src/frontends/qt4/GuiDocument.cpp | 128 ++++++++++++++++++++++++------ src/frontends/qt4/GuiDocument.h | 8 +- src/frontends/qt4/ui/BiblioUi.ui | 82 +++++++++++++------ src/insets/InsetBibtex.cpp | 2 +- 11 files changed, 256 insertions(+), 72 deletions(-) diff --git a/lib/citeengines/natbib.citeengine b/lib/citeengines/natbib.citeengine index dcd160f903..c738e513c8 100644 --- a/lib/citeengines/natbib.citeengine +++ b/lib/citeengines/natbib.citeengine @@ -14,7 +14,7 @@ Format 62 Requires natbib CiteEngineType authoryear|numerical -DefaultBiblio plainnat +DefaultBiblio authoryear:plainnat|numerical:plainnat CiteEngine authoryear Citet*[][] diff --git a/lib/configure.py b/lib/configure.py index 680e32a26f..fb5dcc6473 100644 --- a/lib/configure.py +++ b/lib/configure.py @@ -1511,7 +1511,7 @@ def checkCiteEnginesConfig(): ## 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" +## "CiteEngineName" "filename" "CiteEngineType" "DefaultBiblio" "Description" "Packages" "Requires" "Excludes" ''') # build the list of available modules @@ -1550,16 +1550,17 @@ def processCiteEngineFile(file, filename, bool_docbook): #Excludes: [list of excluded engines] The last two lines are optional. We expect output: - "CiteEngineName" "filename" "CiteEngineType" "Description" "Packages" "Requires" "Excludes" + "CiteEngineName" "filename" "CiteEngineType" "DefaultBiblio" "Description" "Packages" "Requires" "Excludes" ''' remods = re.compile(r'\DeclareLyXCiteEngine\s*(?:\[([^]]*?)\])?{(.*)}') - rereqs = re.compile(r'#+\s*Requires: (.*)') - reexcs = re.compile(r'#+\s*Excludes: (.*)') + rereqs = re.compile(r'#+\s*Requires:\s*(.*)') + reexcs = re.compile(r'#+\s*Excludes:\s*(.*)') redbeg = re.compile(r'#+\s*DescriptionBegin\s*$') redend = re.compile(r'#+\s*DescriptionEnd\s*$') - recet = re.compile(r'\s*CiteEngineType (.*)') + recet = re.compile(r'\s*CiteEngineType\s*(.*)') + redb = re.compile(r'\s*DefaultBiblio\s*(.*)') - modname = desc = pkgs = req = excl = cet = "" + modname = desc = pkgs = req = excl = cet = db = "" readingDescription = False descLines = [] @@ -1603,6 +1604,10 @@ def processCiteEngineFile(file, filename, bool_docbook): if res != None: cet = res.group(1) continue + res = redb.search(line) + if res != None: + db = res.group(1) + continue if modname == "": logger.warning("Cite Engine File file without \DeclareLyXCiteEngine line. ") @@ -1625,7 +1630,7 @@ def processCiteEngineFile(file, filename, bool_docbook): cm.write(line + '\n') cm.close() - return '"%s" "%s" "%s" "%s" "%s" "%s" "%s"\n' % (modname, filename, cet, desc, pkgs, req, excl) + return '"%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s"\n' % (modname, filename, cet, db, desc, pkgs, req, excl) def checkTeXAllowSpaces(): diff --git a/src/BufferParams.cpp b/src/BufferParams.cpp index 1e7f77283f..9cab407613 100644 --- a/src/BufferParams.cpp +++ b/src/BufferParams.cpp @@ -3240,7 +3240,8 @@ bool BufferParams::addCiteEngine(vector const & engine) string const & BufferParams::defaultBiblioStyle() const { - return documentClass().defaultBiblioStyle(); + map bs = documentClass().defaultBiblioStyle(); + return bs[documentClass().opt_enginetype()]; } diff --git a/src/CiteEnginesList.cpp b/src/CiteEnginesList.cpp index 209c8bc840..0e3f45543d 100644 --- a/src/CiteEnginesList.cpp +++ b/src/CiteEnginesList.cpp @@ -38,11 +38,11 @@ CiteEnginesList theCiteEnginesList; LyXCiteEngine::LyXCiteEngine(string const & n, string const & i, - vector const & cet, string const & d, - vector const & p, + vector const & cet, vector const & dbs, + string const & d, vector const & p, vector const & r, vector const & e): - name_(n), id_(i), engine_types_(cet), description_(d), package_list_(p), - required_engines_(r), excluded_engines_(e), + name_(n), id_(i), engine_types_(cet), default_biblios_(dbs), description_(d), + package_list_(p), required_engines_(r), excluded_engines_(e), checked_(false), available_(false) { filename_ = id_ + ".citeengine"; @@ -118,6 +118,33 @@ bool LyXCiteEngine::areCompatible(string const & eng1, string const & eng2) } +string LyXCiteEngine::getDefaultBiblio(CiteEngineType const & cet) const +{ + string res; + string const etp = theCiteEnginesList.getTypeAsString(cet) + ":"; + //check whether all of the required packages are available + vector::const_iterator it = default_biblios_.begin(); + vector::const_iterator end = default_biblios_.end(); + for (; it != end; ++it) { + string const s = *it; + if (prefixIs(s, etp)) + res = split(s, ':'); + else if (!contains(s, ':') && res.empty()) + res = s; + } + return res; +} + + +bool LyXCiteEngine::isDefaultBiblio(string const & bf) const +{ + if (find(default_biblios_.begin(), default_biblios_.end(), bf) != default_biblios_.end()) + return true; + string const bfp = ":" + bf; + return find(default_biblios_.begin(), default_biblios_.end(), bfp) != default_biblios_.end(); +} + + // used when sorting the cite engine list. class EngineSorter { public: @@ -217,6 +244,16 @@ bool CiteEnginesList::read() cet = split(cet, p, '|'); cets.push_back(p); } + if (!lex.next(true)) + break; + string db = lex.getString(); + LYXERR(Debug::TCLASS, "Default Biblio: " << db); + vector dbs; + while (!db.empty()) { + string p; + db = split(db, p, '|'); + dbs.push_back(p); + } if (!lex.next(true)) break; string const desc = lex.getString(); @@ -254,7 +291,7 @@ bool CiteEnginesList::read() } // This code is run when we have // cename, fname, desc, pkgs, req and exc - addCiteEngine(cename, fname, cets, desc, pkgs, req, exc); + addCiteEngine(cename, fname, cets, dbs, desc, pkgs, req, exc); } // end switch } //end while @@ -267,11 +304,12 @@ bool CiteEnginesList::read() void CiteEnginesList::addCiteEngine(string const & cename, - string const & filename, vector const & cets, string const & description, + string const & filename, vector const & cets, + vector const & dbs, string const & description, vector const & pkgs, vector const & req, vector const & exc) { - LyXCiteEngine ce(cename, filename, cets, description, pkgs, req, exc); + LyXCiteEngine ce(cename, filename, cets, dbs, description, pkgs, req, exc); englist_.push_back(ce); } diff --git a/src/CiteEnginesList.h b/src/CiteEnginesList.h index 17cfbb8089..f1fc04b442 100644 --- a/src/CiteEnginesList.h +++ b/src/CiteEnginesList.h @@ -51,6 +51,7 @@ public: /// LyXCiteEngine(std::string const & name, std::string const & id, std::vector const & enginetypes, + std::vector const & defaultbiblios, std::string const & description, std::vector const & packagelist, std::vector const & requires, @@ -70,6 +71,10 @@ public: /// bool hasEngineType(CiteEngineType const &) const; /// + std::string getDefaultBiblio(CiteEngineType const &) const; + /// + bool isDefaultBiblio(std::string const &) const; + /// std::string const & getDescription() const { return description_; } /// std::vector const & getPackageList() const @@ -97,6 +102,8 @@ private: std::string filename_; /// the engine type(s) std::vector engine_types_; + /// default bibliography styles + std::vector default_biblios_; /// a short description for use in the ui std::string description_; /// the LaTeX packages on which this depends, if any @@ -153,7 +160,8 @@ public: void operator=(CiteEnginesList const &); /// add an engine to the list void addCiteEngine(std::string const &, std::string const &, - std::vector const &, std::string const &, std::vector const &, + std::vector const &, std::vector const &, + std::string const &, std::vector const &, std::vector const &, std::vector const &); /// std::vector englist_; diff --git a/src/TextClass.cpp b/src/TextClass.cpp index d14ef2994a..73f3cd194a 100644 --- a/src/TextClass.cpp +++ b/src/TextClass.cpp @@ -759,8 +759,21 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt) break; case TC_DEFAULTBIBLIO: - if (lexrc.next()) - cite_default_biblio_style_ = rtrim(lexrc.getString()); + if (lexrc.next()) { + vector const dbs = + getVectorFromString(rtrim(lexrc.getString()), "|"); + vector::const_iterator it = dbs.begin(); + vector::const_iterator end = dbs.end(); + for (; it != end; ++it) { + if (!contains(*it, ':')) + cite_default_biblio_style_[opt_enginetype_] = *it; + else { + string eng; + string const db = split(*it, eng, ':'); + cite_default_biblio_style_[eng] = db; + } + } + } break; case TC_FULLAUTHORLIST: diff --git a/src/TextClass.h b/src/TextClass.h index d082e10258..3f83216aaf 100644 --- a/src/TextClass.h +++ b/src/TextClass.h @@ -330,7 +330,7 @@ protected: /// Citation macros std::map > cite_macros_; /// The default BibTeX bibliography style file - std::string cite_default_biblio_style_; + std::map cite_default_biblio_style_; /// Whether full author lists are supported bool cite_full_author_list_; /// The possible citation styles @@ -487,7 +487,8 @@ public: /// std::vector const & citeStyles(CiteEngineType const &) const; /// - std::string const & defaultBiblioStyle() const { return cite_default_biblio_style_; } + std::map const & defaultBiblioStyle() const + { return cite_default_biblio_style_; } /// bool const & fullAuthorList() const { return cite_full_author_list_; } protected: diff --git a/src/frontends/qt4/GuiDocument.cpp b/src/frontends/qt4/GuiDocument.cpp index d971eebe7b..34b2fc0b91 100644 --- a/src/frontends/qt4/GuiDocument.cpp +++ b/src/frontends/qt4/GuiDocument.cpp @@ -1130,15 +1130,23 @@ GuiDocument::GuiDocument(GuiView & lv) connect(biblioModule->citeEngineCO, SIGNAL(activated(int)), this, SLOT(citeEngineChanged(int))); connect(biblioModule->citeStyleCO, SIGNAL(activated(int)), - this, SLOT(biblioChanged())); + this, SLOT(citeStyleChanged())); connect(biblioModule->bibtopicCB, SIGNAL(clicked()), this, SLOT(biblioChanged())); connect(biblioModule->bibtexCO, SIGNAL(activated(int)), this, SLOT(bibtexChanged(int))); connect(biblioModule->bibtexOptionsLE, SIGNAL(textChanged(QString)), this, SLOT(biblioChanged())); - connect(biblioModule->bibtexStyleLE, SIGNAL(textChanged(QString)), + connect(biblioModule->defaultBiblioCO, SIGNAL(activated(int)), this, SLOT(biblioChanged())); + connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)), + this, SLOT(biblioChanged())); + connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)), + this, SLOT(updateResetDefaultBiblio())); + connect(biblioModule->rescanBibliosPB, SIGNAL(clicked()), + this, SLOT(rescanBibFiles())); + connect(biblioModule->resetDefaultBiblioPB, SIGNAL(clicked()), + this, SLOT(resetDefaultBibfile())); biblioModule->citeEngineCO->clear(); for (LyXCiteEngine const & cet : theCiteEnginesList) { @@ -1150,8 +1158,8 @@ GuiDocument::GuiDocument(GuiView & lv) biblioModule->bibtexOptionsLE->setValidator(new NoNewLineValidator( biblioModule->bibtexOptionsLE)); - biblioModule->bibtexStyleLE->setValidator(new NoNewLineValidator( - biblioModule->bibtexStyleLE)); + biblioModule->defaultBiblioCO->lineEdit()->setValidator(new NoNewLineValidator( + biblioModule->defaultBiblioCO->lineEdit())); // NOTE: we do not provide "custom" here for security reasons! biblioModule->bibtexCO->clear(); @@ -2271,14 +2279,49 @@ void GuiDocument::biblioChanged() } +void GuiDocument::rescanBibFiles() +{ + rescanTexStyles("bst"); +} + + +void GuiDocument::resetDefaultBibfile() +{ + QString const engine = + biblioModule->citeEngineCO->itemData( + biblioModule->citeEngineCO->currentIndex()).toString(); + + CiteEngineType const cet = + CiteEngineType(biblioModule->citeStyleCO->itemData( + biblioModule->citeStyleCO->currentIndex()).toInt()); + + updateDefaultBiblio(theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet)); +} + + void GuiDocument::citeEngineChanged(int n) { - QString const engine = biblioModule->citeEngineCO->itemData(n).toString(); + QString const engine = + biblioModule->citeEngineCO->itemData(n).toString(); vector const engs = theCiteEnginesList[fromqstr(engine)]->getEngineType(); updateCiteStyles(engs); + resetDefaultBibfile(); + + biblioChanged(); +} + + +void GuiDocument::citeStyleChanged() +{ + QString const engine = + biblioModule->citeEngineCO->itemData( + biblioModule->citeEngineCO->currentIndex()).toString(); + if (theCiteEnginesList[fromqstr(engine)]->isDefaultBiblio( + fromqstr(biblioModule->defaultBiblioCO->currentText()))) + resetDefaultBibfile(); biblioChanged(); } @@ -2292,24 +2335,6 @@ void GuiDocument::bibtexChanged(int n) } -void GuiDocument::setAuthorYear(bool authoryear) -{ - if (authoryear) - biblioModule->citeStyleCO->setCurrentIndex( - biblioModule->citeStyleCO->findData(ENGINE_TYPE_AUTHORYEAR)); - biblioChanged(); -} - - -void GuiDocument::setNumerical(bool numerical) -{ - if (numerical) - biblioModule->citeStyleCO->setCurrentIndex( - biblioModule->citeStyleCO->findData(ENGINE_TYPE_NUMERICAL)); - biblioChanged(); -} - - void GuiDocument::updateCiteStyles(vector const & engs, CiteEngineType const & sel) { biblioModule->citeStyleCO->clear(); @@ -2617,7 +2642,7 @@ void GuiDocument::applyView() bp_.use_bibtopic = biblioModule->bibtopicCB->isChecked(); - bp_.biblio_style = fromqstr(biblioModule->bibtexStyleLE->text()); + bp_.biblio_style = fromqstr(biblioModule->defaultBiblioCO->currentText()); string const bibtex_command = fromqstr(biblioModule->bibtexCO->itemData( @@ -3040,7 +3065,7 @@ void GuiDocument::paramsToDialog() biblioModule->bibtopicCB->setChecked( bp_.use_bibtopic); - biblioModule->bibtexStyleLE->setText(toqstr(bp_.biblio_style)); + updateDefaultBiblio(bp_.defaultBiblioStyle()); string command; string options = @@ -3626,6 +3651,59 @@ void GuiDocument::updateIncludeonlys() } +void GuiDocument::updateDefaultBiblio(string const & style) +{ + QString const bibstyle = toqstr(style); + biblioModule->defaultBiblioCO->clear(); + + int item_nr = -1; + + QStringList str = texFileList("bstFiles.lst"); + // test whether we have a valid list, otherwise run rescan + if (str.isEmpty()) { + rescanTexStyles("bst"); + str = texFileList("bstFiles.lst"); + } + for (int i = 0; i != str.size(); ++i) + str[i] = onlyFileName(str[i]); + // sort on filename only (no path) + str.sort(); + + for (int i = 0; i != str.count(); ++i) { + QString item = changeExtension(str[i], ""); + if (item == bibstyle) + item_nr = i; + biblioModule->defaultBiblioCO->addItem(item); + } + + if (item_nr == -1 && !bibstyle.isEmpty()) { + biblioModule->defaultBiblioCO->addItem(bibstyle); + item_nr = biblioModule->defaultBiblioCO->count() - 1; + } + + if (item_nr != -1) + biblioModule->defaultBiblioCO->setCurrentIndex(item_nr); + else + biblioModule->defaultBiblioCO->clearEditText(); + + updateResetDefaultBiblio(); +} + + +void GuiDocument::updateResetDefaultBiblio() +{ + QString const engine = + biblioModule->citeEngineCO->itemData( + biblioModule->citeEngineCO->currentIndex()).toString(); + CiteEngineType const cet = + CiteEngineType(biblioModule->citeStyleCO->itemData( + biblioModule->citeStyleCO->currentIndex()).toInt()); + biblioModule->resetDefaultBiblioPB->setEnabled( + theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet) + != fromqstr(biblioModule->defaultBiblioCO->currentText())); +} + + void GuiDocument::updateContents() { // Nothing to do here as the document settings is not cursor dependant. diff --git a/src/frontends/qt4/GuiDocument.h b/src/frontends/qt4/GuiDocument.h index e5aa4fa553..012a7a15ce 100644 --- a/src/frontends/qt4/GuiDocument.h +++ b/src/frontends/qt4/GuiDocument.h @@ -115,10 +115,12 @@ private Q_SLOTS: void classChanged_adaptor(); void languagePackageChanged(int); void biblioChanged(); + void rescanBibFiles(); + void resetDefaultBibfile(); void citeEngineChanged(int); + void citeStyleChanged(); void bibtexChanged(int); - void setAuthorYear(bool); - void setNumerical(bool); + void updateResetDefaultBiblio(); void updateModuleInfo(); void modulesChanged(); void changeBackgroundColor(); @@ -181,6 +183,8 @@ private: void updateSelectedModules(); /// void updateIncludeonlys(); + /// + void updateDefaultBiblio(std::string const & style); /// save as default template void saveDocDefault(); /// reset to default params diff --git a/src/frontends/qt4/ui/BiblioUi.ui b/src/frontends/qt4/ui/BiblioUi.ui index 7cc821b8c9..b6ce417432 100644 --- a/src/frontends/qt4/ui/BiblioUi.ui +++ b/src/frontends/qt4/ui/BiblioUi.ui @@ -6,7 +6,7 @@ 0 0 - 418 + 475 394 @@ -46,7 +46,7 @@ - Sty&le Engine: + Sty&le engine: citeEngineCO @@ -116,27 +116,6 @@ true - - - - - - Default st&yle: - - - bibtexStyleLE - - - - - - - Define the default BibTeX style - - - - - @@ -147,6 +126,63 @@ + + + + + + Default BibTeX st&yle: + + + defaultBiblioCO + + + + + + + Here, you can define a BibTeX style that is suggested in the BibTeX dialog by default + + + true + + + + + + + Rescan style files + + + Re&scan + + + + + + + Reset to the preset default + + + &Reset + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + diff --git a/src/insets/InsetBibtex.cpp b/src/insets/InsetBibtex.cpp index 13c91b0739..1c4090a350 100644 --- a/src/insets/InsetBibtex.cpp +++ b/src/insets/InsetBibtex.cpp @@ -328,7 +328,7 @@ void InsetBibtex::latex(otexstream & os, OutputParams const & runparams) const } if (style == "default") - style = buffer().params().biblio_style; + style = buffer().params().defaultBiblioStyle(); if (!style.empty() && !buffer().params().use_bibtopic) { string base = normalizeName(buffer(), runparams, style, ".bst");