Improvements to the citation dialog UI. It is now possible to search particular fields (author, title, etc) and to filter keys by entry types (article, book, etc).

The changes are essentially of three types. 

First, the std::maps previously used here for storing BibTeX data have become full-fledged classes and so what were previously just a bunch of functions have now become methods of these new  classes. This leads to a lot of minor changes in other files, to adapt to the  new signature. The changes in insets/ are mostly of this kind.

Second, there are some slightly more substantial changes in src/insets/InsetBibtex.cpp. We now store lists of the field names and entry types that have been used.

Finally, there are the changes to the citation UI. These are mostly straightforward, though adding the new functionality exposed some inadequacies in the previous code that also had to be fixed.

One other change: BibTeX keys are now docstring. This solves some Unicode issues.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19657 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Richard Heck 2007-08-20 16:30:02 +00:00
parent 96336caed7
commit b3bff4232a
22 changed files with 1047 additions and 910 deletions

View File

@ -34,7 +34,6 @@ src_header_files = Split('''
ASpell_local.h
Author.h
Biblio.h
Biblio_typedefs.h
Bidi.h
Box.h
BranchList.h

View File

@ -1,11 +1,11 @@
/**
* \file Biblio.cpp
* \file BiblioInfo.cpp
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Angus Leeming
* \author Herbert Voß
* \author Richard Heck (re-write of BibTeX representation)
* \author Richard Heck
*
* Full author contact details are available in file CREDITS.
*/
@ -13,7 +13,8 @@
#include <config.h>
#include "Biblio.h"
#include "Buffer.h"
#include "BufferParams.h"
#include "buffer_funcs.h"
#include "gettext.h"
#include "InsetIterator.h"
@ -32,297 +33,150 @@ using std::string;
using std::vector;
using std::pair;
using std::endl;
using std::set;
namespace lyx {
using support::ascii_lowercase;
using support::bformat;
using support::compare_ascii_no_case;
using support::contains;
using support::compare_no_case;
using support::getVectorFromString;
using support::ltrim;
using support::prefixIs;
using support::rtrim;
using support::split;
using support::subst;
using support::token;
using support::trim;
namespace biblio {
////////////////////////////////////////
//
// BibTeXInfo
//
////////////////////////////////////////
BibTeXInfo::BibTeXInfo(): isBibTeX(true)
BibTeXInfo::BibTeXInfo() : isBibTeX(true)
{}
BibTeXInfo::BibTeXInfo(bool isBibTeX): isBibTeX(isBibTeX)
{};
bool BibTeXInfo::hasKey(docstring const & key)
bool BibTeXInfo::hasField(docstring const & field) const
{
const_iterator it = find(key);
return it == end();
return count(field) == 1;
}
docstring const & BibTeXInfo::getValueForField(docstring const & field) const
{
BibTeXInfo::const_iterator it = find(field);
if (it != end())
return it->second;
static docstring const empty_value = docstring();
return empty_value;
}
docstring const & BibTeXInfo::getValueForField(string const & field) const
{
return getValueForField(from_ascii(field));
}
namespace {
vector<string> const init_possible_cite_commands()
docstring const familyName(docstring const & name)
{
char const * const pos[] = {
"cite", "citet", "citep", "citealt", "citealp",
"citeauthor", "citeyear", "citeyearpar",
"citet*", "citep*", "citealt*", "citealp*", "citeauthor*",
"Citet", "Citep", "Citealt", "Citealp", "Citeauthor",
"Citet*", "Citep*", "Citealt*", "Citealp*", "Citeauthor*",
"fullcite",
"footcite", "footcitet", "footcitep", "footcitealt",
"footcitealp", "footciteauthor", "footciteyear", "footciteyearpar",
"citefield", "citetitle", "cite*"
};
size_t const size_pos = sizeof(pos) / sizeof(pos[0]);
if (name.empty())
return docstring();
return vector<string>(pos, pos + size_pos);
// Very simple parser
docstring fname = name;
// possible authorname combinations are:
// "Surname, FirstName"
// "Surname, F."
// "FirstName Surname"
// "F. Surname"
docstring::size_type idx = fname.find(',');
if (idx != docstring::npos)
return ltrim(fname.substr(0, idx));
idx = fname.rfind('.');
if (idx != docstring::npos && idx + 1 < fname.size())
fname = ltrim(fname.substr(idx + 1));
// test if we have a LaTeX Space in front
if (fname[0] == '\\')
return fname.substr(2);
return rtrim(fname);
}
vector<string> const & possible_cite_commands()
{
static vector<string> const pos = init_possible_cite_commands();
return pos;
}
bool is_possible_cite_command(string const & input)
{
vector<string> const & possibles = possible_cite_commands();
vector<string>::const_iterator const end = possibles.end();
return std::find(possibles.begin(), end, input) != end;
}
string const default_cite_command(CiteEngine engine)
{
string str;
switch (engine) {
case ENGINE_BASIC:
str = "cite";
break;
case ENGINE_NATBIB_AUTHORYEAR:
str = "citet";
break;
case ENGINE_NATBIB_NUMERICAL:
str = "citep";
break;
case ENGINE_JURABIB:
str = "cite";
break;
}
return str;
}
} // namespace anon
string const asValidLatexCommand(string const & input,
CiteEngine const engine)
docstring const BibTeXInfo::getAbbreviatedAuthor() const
{
string const default_str = default_cite_command(engine);
if (!is_possible_cite_command(input))
return default_str;
string output;
switch (engine) {
case ENGINE_BASIC:
output = default_str;
break;
case ENGINE_NATBIB_AUTHORYEAR:
case ENGINE_NATBIB_NUMERICAL:
if (input == "cite" || input == "citefield" ||
input == "citetitle" || input == "cite*")
output = default_str;
else if (prefixIs(input, "foot"))
output = input.substr(4);
else
output = input;
break;
case ENGINE_JURABIB: {
// Jurabib does not support the 'uppercase' natbib style.
if (input[0] == 'C')
output = string(1, 'c') + input.substr(1);
else
output = input;
// Jurabib does not support the 'full' natbib style.
string::size_type const n = output.size() - 1;
if (output != "cite*" && output[n] == '*')
output = output.substr(0, n);
break;
}
}
return output;
}
docstring const familyName(docstring const & name)
{
if (name.empty())
return docstring();
// Very simple parser
docstring fname = name;
// possible authorname combinations are:
// "Surname, FirstName"
// "Surname, F."
// "FirstName Surname"
// "F. Surname"
docstring::size_type idx = fname.find(',');
if (idx != docstring::npos)
return ltrim(fname.substr(0, idx));
idx = fname.rfind('.');
if (idx != docstring::npos && idx + 1 < fname.size())
fname = ltrim(fname.substr(idx + 1));
// test if we have a LaTeX Space in front
if (fname[0] == '\\')
return fname.substr(2);
return rtrim(fname);
}
docstring const getAbbreviatedAuthor(BibKeyList const & map, string const & key)
{
BOOST_ASSERT(!map.empty());
BibKeyList::const_iterator it = map.find(key);
if (it == map.end())
return docstring();
BibTeXInfo const & data = it->second;
if (!data.isBibTeX)
if (!isBibTeX)
return docstring();
docstring author = getValueForKey(data, "author");
docstring author = getValueForField("author");
if (author.empty()) {
author = getValueForKey(data, "editor");
if (author.empty()) {
author = getValueForKey(data, "key");
if (author.empty())
// FIXME UNICODE
return from_utf8(key);
else
return author; //this is the key
}
author = getValueForField("editor");
if (author.empty())
return bibKey;
}
//OK, we've got some names. Let's format them.
//try to split the author list on " and "
vector<docstring> const authors = getVectorFromString(author, from_ascii(" and "));
//Try to split the author list on " and "
vector<docstring> const authors =
getVectorFromString(author, from_ascii(" and "));
if (authors.size() == 2)
return bformat(_("%1$s and %2$s"),
familyName(authors[0]), familyName(authors[1]));
familyName(authors[0]), familyName(authors[1]));
else if (authors.size() > 2)
return bformat(_("%1$s et al."), familyName(authors[0]));
else
return familyName(authors[0]);
}
docstring const getYear(BibKeyList const & map, string const & key)
docstring const BibTeXInfo::getYear() const
{
BOOST_ASSERT(!map.empty());
BibKeyList::const_iterator it = map.find(key);
if (it == map.end())
return docstring();
BibTeXInfo const & data = it->second;
if (!data.isBibTeX)
if (!isBibTeX)
return docstring();
docstring year = getValueForKey(data, "year");
docstring year = getValueForField("year");
if (year.empty())
year = _("No year");
return year;
}
namespace {
// A functor for use with std::sort, leading to case insensitive sorting
class compareNoCase: public std::binary_function<string, string, bool>
docstring const BibTeXInfo::getInfo() const
{
public:
bool operator()(string const & s1, string const & s2) const {
return compare_ascii_no_case(s1, s2) < 0;
}
};
} // namespace anon
vector<string> const getKeys(BibKeyList const & map)
{
vector<string> bibkeys;
BibKeyList::const_iterator it = map.begin();
BibKeyList::const_iterator end = map.end();
for (; it != end; ++it) {
bibkeys.push_back(it->first);
}
std::sort(bibkeys.begin(), bibkeys.end(), compareNoCase());
return bibkeys;
}
docstring const getInfo(BibKeyList const & map, string const & key)
{
BOOST_ASSERT(!map.empty());
BibKeyList::const_iterator it = map.find(key);
if (it == map.end())
return docstring();
BibTeXInfo const & data = it->second;
if (!data.isBibTeX) {
BibTeXInfo::const_iterator it3 = data.find(from_ascii("ref"));
return it3->second;
if (!isBibTeX) {
BibTeXInfo::const_iterator it = find(from_ascii("ref"));
return it->second;
}
//FIXME
//This could be made alot better using the biblio::TheEntryType
//This could be made alot better using the entryType
//field to customize the output based upon entry type.
//Search for all possible "required" fields
docstring author = getValueForKey(data, "author");
docstring author = getValueForField("author");
if (author.empty())
author = getValueForKey(data, "editor");
author = getValueForField("editor");
docstring year = getValueForKey(data, "year");
docstring title = getValueForKey(data, "title");
docstring docLoc = getValueForKey(data, "pages");
docstring year = getValueForField("year");
docstring title = getValueForField("title");
docstring docLoc = getValueForField("pages");
if (docLoc.empty()) {
docLoc = getValueForKey(data, "chapter");
docLoc = getValueForField("chapter");
if (!docLoc.empty())
docLoc = from_ascii("Ch. ") + docLoc;
} else
docLoc = from_ascii("pp. ") + docLoc;
docstring media = getValueForKey(data, "journal");
docstring media = getValueForField("journal");
if (media.empty()) {
media = getValueForKey(data, "publisher");
media = getValueForField("publisher");
if (media.empty()) {
media = getValueForKey(data, "school");
media = getValueForField("school");
if (media.empty())
media = getValueForKey(data, "institution");
media = getValueForField("institution");
}
}
docstring volume = getValueForKey(data, "volume");
docstring volume = getValueForField("volume");
odocstringstream result;
if (!author.empty())
@ -341,121 +195,246 @@ docstring const getInfo(BibKeyList const & map, string const & key)
return result_str;
// This should never happen (or at least be very unusual!)
return docstring();
return docstring();
}
////////////////////////////////////////
//
// BiblioInfo
//
////////////////////////////////////////
namespace {
// Escape special chars.
// All characters are literals except: '.|*?+(){}[]^$\'
// These characters are literals when preceded by a "\", which is done here
// @todo: This function should be moved to support, and then the test in tests
// should be moved there as well.
string const escape_special_chars(string const & expr)
{
// Search for all chars '.|*?+(){}[^$]\'
// Note that '[' and '\' must be escaped.
// This is a limitation of boost::regex, but all other chars in BREs
// are assumed literal.
boost::regex reg("[].|*?+(){}^$\\[\\\\]");
// $& is a perl-like expression that expands to all
// of the current match
// The '$' must be prefixed with the escape character '\' for
// boost to treat it as a literal.
// Thus, to prefix a matched expression with '\', we use:
return boost::regex_replace(expr, reg, "\\\\$&");
}
// A functor for use with std::find_if, used to ascertain whether a
// data entry matches the required regex_
// @throws: boost::regex_error if the supplied regex pattern is not valid
// @todo: This function should be moved to support.
class RegexMatch : public std::unary_function<string, bool>
{
public:
// re and icase are used to construct an instance of boost::RegEx.
// if icase is true, then matching is insensitive to case
RegexMatch(BibKeyList const & m, string const & re, bool icase)
: map_(m), regex_(re, icase) {}
bool operator()(string const & key) const {
//FIXME This should search the monolith.
BibKeyList::const_iterator info = map_.find(key);
if (info == map_.end())
return false;
BibTeXInfo const kvm = info->second;
string const data = key + ' ' + to_utf8(kvm.allData);
return boost::regex_search(data, regex_);
}
private:
BibKeyList const map_;
mutable boost::regex regex_;
};
// A functor for use with std::sort, leading to case insensitive sorting
class compareNoCase: public std::binary_function<docstring, docstring, bool>
{
public:
bool operator()(docstring const & s1, docstring const & s2) const {
return compare_no_case(s1, s2) < 0;
}
};
} // namespace anon
vector<string>::const_iterator searchKeys(BibKeyList const & theMap,
vector<string> const & keys,
string const & search_expr,
vector<string>::const_iterator start,
Search type, Direction dir, bool caseSensitive)
vector<docstring> const BiblioInfo::getKeys() const
{
// Preliminary checks
if (start < keys.begin() || start >= keys.end())
return keys.end();
string expr = trim(search_expr);
if (expr.empty())
return keys.end();
if (type == SIMPLE)
// We must escape special chars in the search_expr so that
// it is treated as a simple string by boost::regex.
expr = escape_special_chars(expr);
try {
// Build the functor that will be passed to find_if.
RegexMatch const match(theMap, expr, !caseSensitive);
// Search the vector of 'keys' from 'start' for one
// that matches the predicate 'match'. Searching can
// be forward or backward from start.
if (dir == FORWARD)
return std::find_if(start, keys.end(), match);
vector<string>::const_reverse_iterator rit(start);
vector<string>::const_reverse_iterator rend = keys.rend();
rit = std::find_if(rit, rend, match);
if (rit == rend)
return keys.end();
// This is correct and always safe.
// (See Meyer's Effective STL, Item 28.)
return (++rit).base();
}
catch (boost::regex_error &) {
return keys.end();
}
vector<docstring> bibkeys;
BiblioInfo::const_iterator it = begin();
for (; it != end(); ++it)
bibkeys.push_back(it->first);
std::sort(bibkeys.begin(), bibkeys.end(), compareNoCase());
return bibkeys;
}
docstring const getValueForKey(BibTeXInfo const & data, string const & findkey)
vector<docstring> const BiblioInfo::getFields() const
{
docstring key = from_ascii(findkey);
BibTeXInfo::const_iterator it = data.find(key);
if (it == data.end())
vector<docstring> bibfields;
set<docstring>::const_iterator it = fieldNames.begin();
set<docstring>::const_iterator end = fieldNames.end();
for (; it != end; ++it)
bibfields.push_back(*it);
std::sort(bibfields.begin(), bibfields.end());
return bibfields;
}
vector<docstring> const BiblioInfo::getEntries() const
{
vector<docstring> bibentries;
set<docstring>::const_iterator it = entryTypes.begin();
set<docstring>::const_iterator end = entryTypes.end();
for (; it != end; ++it)
bibentries.push_back(*it);
std::sort(bibentries.begin(), bibentries.end());
return bibentries;
}
docstring const BiblioInfo::getAbbreviatedAuthor(docstring const & key) const
{
BiblioInfo::const_iterator it = find(key);
if (it == end())
return docstring();
//FIXME ?? return it->second??
BibTeXInfo & data2 = const_cast<BibTeXInfo &>(data);
return data2[key];
BibTeXInfo const & data = it->second;
return data.getAbbreviatedAuthor();
}
docstring const BiblioInfo::getYear(docstring const & key) const
{
BiblioInfo::const_iterator it = find(key);
if (it == end())
return docstring();
BibTeXInfo const & data = it->second;
return data.getYear();
}
docstring const BiblioInfo::getInfo(docstring const & key) const
{
BiblioInfo::const_iterator it = find(key);
if (it == end())
return docstring();
BibTeXInfo const & data = it->second;
return data.getInfo();
}
vector<docstring> const BiblioInfo::getCiteStrings(
docstring const & key, Buffer const & buf) const
{
biblio::CiteEngine const engine = buf.params().getEngine();
if (engine == biblio::ENGINE_NATBIB_NUMERICAL)
return getNumericalStrings(key, buf);
else
return getAuthorYearStrings(key, buf);
}
vector<docstring> const BiblioInfo::getNumericalStrings(
docstring const & key, Buffer const & buf) const
{
if (empty())
return vector<docstring>();
docstring const author = getAbbreviatedAuthor(key);
docstring const year = getYear(key);
if (author.empty() || year.empty())
return vector<docstring>();
vector<biblio::CiteStyle> const & styles =
biblio::getCiteStyles(buf.params().getEngine());
vector<docstring> vec(styles.size());
for (vector<docstring>::size_type i = 0; i != vec.size(); ++i) {
docstring str;
switch (styles[i]) {
case biblio::CITE:
case biblio::CITEP:
str = from_ascii("[#ID]");
break;
case biblio::CITET:
str = author + " [#ID]";
break;
case biblio::CITEALT:
str = author + " #ID";
break;
case biblio::CITEALP:
str = from_ascii("#ID");
break;
case biblio::CITEAUTHOR:
str = author;
break;
case biblio::CITEYEAR:
str = year;
break;
case biblio::CITEYEARPAR:
str = '(' + year + ')';
break;
}
vec[i] = str;
}
return vec;
}
vector<docstring> const BiblioInfo::getAuthorYearStrings(
docstring const & key, Buffer const & buf) const
{
if (empty())
return vector<docstring>();
docstring const author = getAbbreviatedAuthor(key);
docstring const year = getYear(key);
if (author.empty() || year.empty())
return vector<docstring>();
vector<biblio::CiteStyle> const & styles =
getCiteStyles(buf.params().getEngine());
vector<docstring> vec(styles.size());
for (vector<docstring>::size_type i = 0; i != vec.size(); ++i) {
docstring str;
switch (styles[i]) {
case biblio::CITE:
// jurabib only: Author/Annotator
// (i.e. the "before" field, 2nd opt arg)
str = author + "/<" + _("before") + '>';
break;
case biblio::CITET:
str = author + " (" + year + ')';
break;
case biblio::CITEP:
str = '(' + author + ", " + year + ')';
break;
case biblio::CITEALT:
str = author + ' ' + year ;
break;
case biblio::CITEALP:
str = author + ", " + year ;
break;
case biblio::CITEAUTHOR:
str = author;
break;
case biblio::CITEYEAR:
str = year;
break;
case biblio::CITEYEARPAR:
str = '(' + year + ')';
break;
}
vec[i] = str;
}
return vec;
}
void BiblioInfo::fillWithBibKeys(Buffer const * const buf)
{
/// if this is a child document and the parent is already loaded
/// use the parent's list instead [ale990412]
Buffer const * const tmp = buf->getMasterBuffer();
BOOST_ASSERT(tmp);
if (tmp != buf) {
this->fillWithBibKeys(tmp);
return;
}
// Pre-load all child documents.
loadChildDocuments(*buf);
for (InsetIterator it = inset_iterator_begin(buf->inset()); it; ++it)
it->fillWithBibKeys(*buf, *this, it);
}
namespace biblio {
////////////////////////////////////////
//
// CitationStyle
//
////////////////////////////////////////
namespace {
@ -567,138 +546,6 @@ vector<CiteStyle> const getCiteStyles(CiteEngine const engine)
return styles;
}
vector<docstring> const
getNumericalStrings(string const & key,
BibKeyList const & map, vector<CiteStyle> const & styles)
{
if (map.empty())
return vector<docstring>();
docstring const author = getAbbreviatedAuthor(map, key);
docstring const year = getYear(map, key);
if (author.empty() || year.empty())
return vector<docstring>();
vector<docstring> vec(styles.size());
for (vector<docstring>::size_type i = 0; i != vec.size(); ++i) {
docstring str;
switch (styles[i]) {
case CITE:
case CITEP:
str = from_ascii("[#ID]");
break;
case CITET:
str = author + " [#ID]";
break;
case CITEALT:
str = author + " #ID";
break;
case CITEALP:
str = from_ascii("#ID");
break;
case CITEAUTHOR:
str = author;
break;
case CITEYEAR:
str = year;
break;
case CITEYEARPAR:
str = '(' + year + ')';
break;
}
vec[i] = str;
}
return vec;
}
vector<docstring> const
getAuthorYearStrings(string const & key,
BibKeyList const & map, vector<CiteStyle> const & styles)
{
if (map.empty())
return vector<docstring>();
docstring const author = getAbbreviatedAuthor(map, key);
docstring const year = getYear(map, key);
if (author.empty() || year.empty())
return vector<docstring>();
vector<docstring> vec(styles.size());
for (vector<docstring>::size_type i = 0; i != vec.size(); ++i) {
docstring str;
switch (styles[i]) {
case CITE:
// jurabib only: Author/Annotator
// (i.e. the "before" field, 2nd opt arg)
str = author + "/<" + _("before") + '>';
break;
case CITET:
str = author + " (" + year + ')';
break;
case CITEP:
str = '(' + author + ", " + year + ')';
break;
case CITEALT:
str = author + ' ' + year ;
break;
case CITEALP:
str = author + ", " + year ;
break;
case CITEAUTHOR:
str = author;
break;
case CITEYEAR:
str = year;
break;
case CITEYEARPAR:
str = '(' + year + ')';
break;
}
vec[i] = str;
}
return vec;
}
void fillWithBibKeys(Buffer const * const buf,
BibKeyList & keys)
{
/// if this is a child document and the parent is already loaded
/// use the parent's list instead [ale990412]
Buffer const * const tmp = buf->getMasterBuffer();
BOOST_ASSERT(tmp);
if (tmp != buf) {
fillWithBibKeys(tmp, keys);
return;
}
// Pre-load all child documents.
loadChildDocuments(*buf);
for (InsetIterator it = inset_iterator_begin(buf->inset()); it; ++it)
it->fillWithBibKeys(*buf, keys, it);
}
} // namespace biblio
} // namespace lyx

View File

@ -6,6 +6,7 @@
*
* \author Angus Leeming
* \author Herbert Voß
* \author Richard Heck
*
* Full author contact details are available in file CREDITS.
*/
@ -13,154 +14,149 @@
#ifndef BIBLIO_H
#define BIBLIO_H
#include "Biblio_typedefs.h"
#include "Buffer.h"
#include "support/docstring.h"
#include <vector>
#include <map>
#include <set>
namespace lyx {
class Buffer;
namespace biblio {
enum CiteEngine {
ENGINE_BASIC,
ENGINE_NATBIB_AUTHORYEAR,
ENGINE_NATBIB_NUMERICAL,
ENGINE_JURABIB
};
enum CiteEngine {
ENGINE_BASIC,
ENGINE_NATBIB_AUTHORYEAR,
ENGINE_NATBIB_NUMERICAL,
ENGINE_JURABIB
};
enum CiteStyle {
CITE,
CITET,
CITEP,
CITEALT,
CITEALP,
CITEAUTHOR,
CITEYEAR,
CITEYEARPAR
};
enum CiteStyle {
CITE,
CITET,
CITEP,
CITEALT,
CITEALP,
CITEAUTHOR,
CITEYEAR,
CITEYEARPAR
};
enum Search {
SIMPLE,
REGEX
};
enum Direction {
FORWARD,
BACKWARD
};
/** Fills keys with BibTeX information derived from the various
* in this document or its master document.
*/
void fillWithBibKeys(Buffer const * const buf, BibKeyList & keys);
/** Each citation engine recognizes only a subset of all possible
* citation commands. Given a latex command \c input, this function
* returns an appropriate command, valid for \c engine.
*/
std::string const asValidLatexCommand(std::string const & input,
CiteEngine const engine);
/// Returns a vector of bibliography keys
std::vector<std::string> const getKeys(BibKeyList const &);
/** Returns the BibTeX data associated with a given key.
Empty if no info exists. */
docstring const getInfo(BibKeyList const &, std::string const & key);
/// return the year from the bibtex data record
docstring const getYear(BibKeyList const & map, std::string const & key);
/// return the short form of an authorlist
docstring const getAbbreviatedAuthor(BibKeyList const & map, std::string const & key);
/// return only the family name
docstring const familyName(docstring const & name);
/** Search a BibTeX info field for the given key and return the
associated field. */
docstring const getValueForKey(BibTeXInfo const & data, std::string const & findkey);
/** Returns an iterator to the first key that meets the search
criterion, or end() if unsuccessful.
User supplies :
the BibKeyList of bibliography info,
the vector of keys to be searched,
the search criterion,
an iterator defining the starting point of the search,
an enum defining a Simple or Regex search,
an enum defining the search direction.
*/
std::vector<std::string>::const_iterator
searchKeys(BibKeyList const & map,
std::vector<std::string> const & keys_to_search,
docstring const & search_expression,
std::vector<std::string>::const_iterator start,
Search, Direction, bool caseSensitive=false);
class CitationStyle {
public:
///
CitationStyle(CiteStyle s = CITE, bool f = false, bool force = false)
: style(s), full(f), forceUCase(force) {}
/// \param latex_str a LaTeX command, "cite", "Citep*", etc
CitationStyle(std::string const & latex_str);
///
std::string const asLatexStr() const;
///
CiteStyle style;
///
bool full;
///
bool forceUCase;
};
class CitationStyle {
public:
///
CitationStyle(CiteStyle s = CITE, bool f = false, bool force = false)
: style(s), full(f), forceUCase(force) {}
/// \param latex_str a LaTeX command, "cite", "Citep*", etc
CitationStyle(std::string const & latex_str);
///
std::string const asLatexStr() const;
///
CiteStyle style;
///
bool full;
///
bool forceUCase;
};
/// Returns a vector of available Citation styles.
std::vector<CiteStyle> const getCiteStyles(CiteEngine const );
/**
"Translates" the available Citation Styles into strings for this key.
The returned string is displayed by the GUI.
[XX] is used in place of the actual reference
Eg, the vector will contain: [XX], Jones et al. [XX], ...
User supplies :
the key,
the BibKeyList of bibkeys info,
the available citation styles
*/
std::vector<docstring> const
getNumericalStrings(std::string const & key,
BibKeyList const & map,
std::vector<CiteStyle> const & styles);
/**
"Translates" the available Citation Styles into strings for this key.
The returned string is displayed by the GUI.
Eg, the vector will contain:
Jones et al. (1990), (Jones et al. 1990), Jones et al. 1990, ...
User supplies :
the key,
the BibKeyList of bibkeys info,
the available citation styles
*/
std::vector<docstring> const
getAuthorYearStrings(std::string const & key,
BibKeyList const & map,
std::vector<CiteStyle> const & styles);
std::vector<CiteStyle> const getCiteStyles(CiteEngine const );
} // namespace biblio
/// Class to represent information about a BibTeX or
/// bibliography entry.
/// The keys are BibTeX fields (e.g., author, title, etc),
/// and the values are the associated field values.
class BibTeXInfo : public std::map<docstring, docstring> {
public:
///
BibTeXInfo();
///Search for the given field and return the associated info.
///The point of this is that BibTeXInfo::operator[] has no const
///form.
docstring const & getValueForField(docstring const & field) const;
///
docstring const & getValueForField(std::string const & field) const;
///
bool hasField(docstring const & field) const;
/// return the short form of an authorlist
docstring const getAbbreviatedAuthor() const;
///
docstring const getYear() const;
/// Returns formatted BibTeX data suitable for framing.
docstring const getInfo() const;
/// the BibTeX key for this entry
docstring bibKey;
/// a single string containing all BibTeX data associated with this key
docstring allData;
/// the BibTeX entry type (article, book, incollection, ...)
docstring entryType;
/// true if from BibTeX; false if from bibliography environment
bool isBibTeX;
};
/// Class to represent a collection of bibliographical data, whether
/// from BibTeX or from bibliography environments.
/// BiblioInfo.first is the bibliography key
/// BiblioInfo.second is the data for that key
class BiblioInfo : public std::map<docstring, BibTeXInfo> {
public:
/// Returns a sorted vector of bibliography keys
std::vector<docstring> const getKeys() const;
/// Returns a sorted vector of present BibTeX fields
std::vector<docstring> const getFields() const;
/// Returns a sorted vector of BibTeX entry types in use
std::vector<docstring> const getEntries() const;
/// Fills keys with BibTeX information derived from the various insets
/// in a given buffer, in its master document.
void fillWithBibKeys(Buffer const * const buf);
/// return the short form of an authorlist
docstring const getAbbreviatedAuthor(docstring const & key) const;
/// return the year from the bibtex data record
docstring const getYear(docstring const & key) const;
/// Returns formatted BibTeX data associated with a given key.
/// Empty if no info exists.
docstring const getInfo(docstring const & key) const;
/**
* "Translates the available Citation Styles into strings for a given key,
* either numerical or author-year depending upon the active engine. (See
* below for those methods.)
*/
std::vector<docstring> const
getCiteStrings(docstring const & key, Buffer const & buf) const;
/**
* "Translates" the available Citation Styles into strings for a given key.
* The returned string is displayed by the GUI.
* [XX] is used in place of the actual reference
* Eg, the vector will contain: [XX], Jones et al. [XX], ...
* User supplies :
* the key,
* the buffer
*/
std::vector<docstring> const
getNumericalStrings(docstring const & key, Buffer const & buf) const;
/**
* "Translates" the available Citation Styles into strings for a given key.
* The returned string is displayed by the GUI.
* Eg, the vector will contain:
* Jones et al. (1990), (Jones et al. 1990), Jones et al. 1990, ...
* User supplies :
* the key,
* the buffer
*/
std::vector<docstring> const
getAuthorYearStrings(docstring const & key, Buffer const & buf) const;
std::set<docstring> fieldNames;
std::set<docstring> entryTypes;
};
} // namespace lyx
#endif

View File

@ -1,51 +0,0 @@
// -*- C++ -*-
/**
* \file Biblio_typedef.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Richard Heck
*
* Full author contact details are available in file CREDITS.
*/
#ifndef BIBLIO_TYPEDEFS_H
#define BIBLIO_TYPEDEFS_H
#include "support/docstring.h"
#include <map>
namespace lyx {
namespace biblio {
/// Class to represent information about a BibTeX or
/// bibliography entry.
/// The keys are BibTeX fields, and the values are the
/// associated field values.
/// \param isBibTex false if this is from an InsetBibitem
/// \param allData the entire BibTeX entry, more or less
/// \param entryType the BibTeX entry type
class BibTeXInfo : public std::map<docstring, docstring> {
public:
BibTeXInfo();
BibTeXInfo(bool isBibTeX);
bool hasKey(docstring const & key);
bool isBibTeX;
docstring allData;
docstring entryType;
};
/*
class BibKeyList : public std::set<std::string, BibTeXInfo> {
public:
std::set<string> keys;
}
*/
/// First entry is the bibliography key, second the data
typedef std::map<std::string, BibTeXInfo> BibKeyList;
}
}
#endif

View File

@ -1359,14 +1359,6 @@ void Buffer::getLabelList(vector<docstring> & list) const
}
// This is also a buffer property (ale)
void Buffer::fillWithBibKeys(biblio::BibKeyList & keys)
const
{
biblio::fillWithBibKeys(this, keys);
}
void Buffer::updateBibfilesCache()
{
// if this is a child document and the parent is already loaded
@ -1731,14 +1723,14 @@ void Buffer::changeRefsIfUnique(docstring const & from, docstring const & to,
vector<docstring> labels;
if (code == Inset::CITE_CODE) {
biblio::BibKeyList keys;
fillWithBibKeys(keys);
biblio::BibKeyList::const_iterator bit = keys.begin();
biblio::BibKeyList::const_iterator bend = keys.end();
BiblioInfo keys;
keys.fillWithBibKeys(this);
BiblioInfo::const_iterator bit = keys.begin();
BiblioInfo::const_iterator bend = keys.end();
for (; bit != bend; ++bit)
// FIXME UNICODE
labels.push_back(from_utf8(bit->first));
labels.push_back(bit->first);
} else
getLabelList(labels);

View File

@ -12,7 +12,6 @@
#ifndef BUFFER_H
#define BUFFER_H
#include "Biblio_typedefs.h"
#include "DocIterator.h"
#include "support/FileName.h"
@ -302,8 +301,6 @@ public:
*/
void validate(LaTeXFeatures &) const;
/// return all bibkeys from buffer and its childs
void fillWithBibKeys(biblio::BibKeyList & keys) const;
/// Update the cache with all bibfiles in use (including bibfiles
/// of loaded child documents).
void updateBibfilesCache();

View File

@ -78,7 +78,6 @@ endif
liblyxcore_la_SOURCES = \
Author.cpp \
Author.h \
Biblio_typedefs.h \
Biblio.h \
Biblio.cpp \
Bidi.cpp \

View File

@ -48,7 +48,7 @@ bool ControlCitation::initialiseParams(string const & data)
bool use_styles = engine != biblio::ENGINE_BASIC;
kernel().buffer().fillWithBibKeys(bibkeysInfo_);
bibkeysInfo_.fillWithBibKeys(&(kernel().buffer()));
if (citeStyles_.empty())
citeStyles_ = biblio::getCiteStyles(engine);
@ -70,9 +70,43 @@ void ControlCitation::clearParams()
}
vector<string> const ControlCitation::availableKeys() const
vector<docstring> const ControlCitation::availableKeys() const
{
return biblio::getKeys(bibkeysInfo_);
return bibkeysInfo_.getKeys();
}
vector<docstring> const ControlCitation::availableFields() const
{
return bibkeysInfo_.getFields();
}
vector<docstring> const ControlCitation::availableEntries() const
{
return bibkeysInfo_.getEntries();
}
void ControlCitation::filterByEntryType(
vector<docstring> & keyVector, docstring entryType)
{
if (entryType.empty())
return;
vector<docstring>::iterator it = keyVector.begin();
vector<docstring>::iterator end = keyVector.end();
vector<docstring> result;
for (; it != end; ++it) {
docstring const key = *it;
BiblioInfo::const_iterator cit = bibkeysInfo_.find(key);
if (cit == bibkeysInfo_.end())
continue;
if (cit->second.entryType == entryType)
result.push_back(key);
}
keyVector = result;
}
@ -82,12 +116,12 @@ biblio::CiteEngine const ControlCitation::getEngine() const
}
docstring const ControlCitation::getInfo(std::string const & key) const
docstring const ControlCitation::getInfo(docstring const & key) const
{
if (bibkeysInfo_.empty())
return docstring();
return biblio::getInfo(bibkeysInfo_, key);
return bibkeysInfo_.getInfo(key);
}
namespace {
@ -117,12 +151,12 @@ docstring const escape_special_chars(docstring const & expr)
} // namespace anon
vector<string> ControlCitation::searchKeys(
vector<string> const & keys_to_search,
docstring const & search_expression,
vector<docstring> ControlCitation::searchKeys(
vector<docstring> const & keys_to_search, bool only_keys,
docstring const & search_expression, docstring field,
bool case_sensitive, bool regex)
{
vector<string> foundKeys;
vector<docstring> foundKeys;
docstring expr = support::trim(search_expression);
if (expr.empty())
@ -136,37 +170,40 @@ vector<string> ControlCitation::searchKeys(
boost::regex reg_exp(to_utf8(expr), case_sensitive ?
boost::regex_constants::normal : boost::regex_constants::icase);
vector<string>::const_iterator it = keys_to_search.begin();
vector<string>::const_iterator end = keys_to_search.end();
vector<docstring>::const_iterator it = keys_to_search.begin();
vector<docstring>::const_iterator end = keys_to_search.end();
for (; it != end; ++it ) {
biblio::BibKeyList::const_iterator info = bibkeysInfo_.find(*it);
BiblioInfo::const_iterator info = bibkeysInfo_.find(*it);
if (info == bibkeysInfo_.end())
continue;
biblio::BibTeXInfo const kvm = info->second;
string const data = *it + ' ' + to_utf8(kvm.allData);
BibTeXInfo const & kvm = info->second;
string data;
if (only_keys)
data = to_utf8(*it);
else if (field.empty())
data = to_utf8(*it) + ' ' + to_utf8(kvm.allData);
else if (kvm.hasField(field))
data = to_utf8(kvm.getValueForField(field));
if (data.empty())
continue;
try {
if (boost::regex_search(data, reg_exp))
foundKeys.push_back(*it);
}
catch (boost::regex_error &) {
return vector<string>();
return vector<docstring>();
}
}
return foundKeys;
}
vector<docstring> const ControlCitation::getCiteStrings(string const & key) const
vector<docstring> const ControlCitation::getCiteStrings(docstring const & key) const
{
biblio::CiteEngine const engine = kernel().buffer().params().getEngine();
vector<biblio::CiteStyle> const cs = biblio::getCiteStyles(engine);
if (engine == biblio::ENGINE_NATBIB_NUMERICAL)
return biblio::getNumericalStrings(key, bibkeysInfo_, cs);
else
return biblio::getAuthorYearStrings(key, bibkeysInfo_, cs);
return bibkeysInfo_.getCiteStrings(key, kernel().buffer());
}
} // namespace frontend

View File

@ -37,32 +37,41 @@ public:
virtual bool disconnectOnApply() const { return true; }
/// \return the list of all available bibliography keys.
std::vector<std::string> const availableKeys() const;
std::vector<docstring> const availableKeys() const;
/// \return the list of all used BibTeX fields
std::vector<docstring> const availableFields() const;
/// \return the list of all used BibTeX entry types
std::vector<docstring> const availableEntries() const;
///
void filterByEntryType(
std::vector<docstring> & keyVector, docstring entryType);
///
biblio::CiteEngine const getEngine() const;
/// \return information for this key.
docstring const getInfo(std::string const & key) const;
docstring const getInfo(docstring const & key) const;
/// Search a given string within the passed keys.
/// \return the vector of matched keys.
std::vector<std::string> searchKeys(
std::vector<std::string> const & keys_to_search, //< Keys to search.
std::vector<docstring> searchKeys(
std::vector<docstring> const & keys_to_search, //< Keys to search.
bool only_keys, //< whether to search only the keys
docstring const & search_expression, //< Search expression (regex possible)
bool case_sensitive = false, // set to true is the search should be case sensitive
bool regex = false /// \set to true if \c search_expression is a regex
docstring field, //< field to search, empty for all fields
bool case_sensitive = false, //< set to true is the search should be case sensitive
bool regex = false //< \set to true if \c search_expression is a regex
); //
/// \return possible citations based on this key.
std::vector<docstring> const getCiteStrings(std::string const & key) const;
std::vector<docstring> const getCiteStrings(docstring const & key) const;
/// available CiteStyle-s (depends on availability of Natbib/Jurabib)
static std::vector<biblio::CiteStyle> const & getCiteStyles() {
return citeStyles_;
}
private:
/// The info associated with each key
biblio::BibKeyList bibkeysInfo_;
/// The BibTeX information available to the dialog
BiblioInfo bibkeysInfo_;
///
static std::vector<biblio::CiteStyle> citeStyles_;

View File

@ -17,6 +17,7 @@
#include "qt_helpers.h"
#include "support/lstrings.h"
#include "support/docstring.h"
#include "debug.h"
@ -40,13 +41,13 @@ template<typename String> static QStringList to_qstring_list(vector<String> cons
}
static vector<string> const to_string_vector(QStringList const & qlist)
static vector<lyx::docstring> const to_docstring_vector(QStringList const & qlist)
{
vector<string> v;
vector<lyx::docstring> v;
for (int i = 0; i != qlist.size(); ++i) {
if (qlist[i].isEmpty())
continue;
v.push_back(lyx::fromqstr(qlist[i]));
v.push_back(lyx::qstring_to_ucs4(qlist[i]));
}
return v;
}
@ -123,19 +124,14 @@ void QCitation::init()
cited_keys_.clear();
else
cited_keys_ = str.split(",");
selected_model_.setStringList(cited_keys_);
}
void QCitation::findKey(QString const & str, bool only_keys,
bool case_sensitive, bool reg_exp)
docstring field, docstring entryType,
bool case_sensitive, bool reg_exp, bool reset)
{
if (str.isEmpty()) {
available_model_.setStringList(all_keys_);
return;
}
// Used for optimisation: store last searched string.
static QString last_searched_string;
// Used to disable the above optimisation.
@ -155,8 +151,10 @@ void QCitation::findKey(QString const & str, bool only_keys,
Qt::CaseSensitive: Qt::CaseInsensitive;
QStringList keys;
// If new string (str) contains the last searched one...
if (!last_searched_string.isEmpty() && str.size() > 1
&& str.contains(last_searched_string, qtcase))
if (!reset &&
!last_searched_string.isEmpty() &&
str.size() > 1 &&
str.contains(last_searched_string, qtcase))
// ... then only search within already found list.
keys = available_model_.stringList();
else
@ -166,18 +164,32 @@ void QCitation::findKey(QString const & str, bool only_keys,
last_searched_string = str;
QStringList result;
if (only_keys)
// Search only within the matching keys:
result = keys.filter(str, qtcase);
//First, filter by entryType, which will be faster than
//what follows, so we may get to do that on less.
vector<docstring> keyVector = to_docstring_vector(keys);
filterByEntryType(keyVector, entryType);
if (str.isEmpty())
result = to_qstring_list(keyVector);
else
// Search within matching keys and associated info.
result = to_qstring_list(searchKeys(to_string_vector(keys),
qstring_to_ucs4(str), case_sensitive, reg_exp));
result = to_qstring_list(searchKeys(keyVector, only_keys,
qstring_to_ucs4(str), field, case_sensitive, reg_exp));
available_model_.setStringList(result);
}
QStringList QCitation::getFieldsAsQStringList() {
return to_qstring_list(availableFields());
}
QStringList QCitation::getEntriesAsQStringList() {
return to_qstring_list(availableEntries());
}
void QCitation::addKey(QModelIndex const & index)
{
cited_keys_.append(index.data().toString());
@ -210,14 +222,14 @@ void QCitation::downKey(QModelIndex const & index)
QStringList QCitation::citationStyles(int sel)
{
string const key = fromqstr(cited_keys_[sel]);
docstring const key = qstring_to_ucs4(cited_keys_[sel]);
return to_qstring_list(getCiteStrings(key));
}
QString QCitation::getKeyInfo(QString const & sel)
{
return toqstr(getInfo(fromqstr(sel)));
return toqstr(getInfo(qstring_to_ucs4(sel)));
}

View File

@ -15,6 +15,7 @@
#define QCITATION_H
#include "frontends/controllers/ControlCitation.h"
#include "support/docstring.h"
#include <QStringList>
#include <QStringListModel>
@ -50,13 +51,22 @@ public:
/// Clear selected keys
void clearSelection();
/// Return a list of available fields
QStringList getFieldsAsQStringList();
/// Return a list of available fields
QStringList getEntriesAsQStringList();
/// Find keys containing a string.
void findKey(
QString const & str, //< string expression
bool only_keys, //< set to true if only keys shall be searched.
docstring field, //<field to search, empty for all fields
docstring entryType, //<entry type to display, empty for all
bool case_sensitive, //< set to true for case sensitive search.
bool reg_exp //< set to true if \c str is a regular expression.
bool reg_exp, //< set to true if \c str is a regular expression.
bool reset = false //< whether to reset and search all keys
);
/// Add key to selected keys
@ -87,7 +97,7 @@ private:
/// All keys.
QStringList all_keys_;
/// Cited keys.
QStringList cited_keys_;
};

View File

@ -20,6 +20,8 @@
#include "frontends/controllers/frontend_helpers.h"
#include "frontends/controllers/ControlCitation.h"
#include "support/docstring.h"
#include "debug.h"
#include "gettext.h"
@ -70,6 +72,7 @@ QCitationDialog::QCitationDialog(Dialog & dialog, QCitation * form)
connect(this, SIGNAL(rejected()), this, SLOT(cleanUp()));
availableLV->installEventFilter(this);
selectedLV->installEventFilter(this);
availableFocused_ = true;
}
@ -120,7 +123,7 @@ bool QCitationDialog::eventFilter(QObject * obj, QEvent * event)
on_deletePB_clicked();
else if (keyModifiers == Qt::ControlModifier) {
form_->clearSelection();
update();
updateDialog();
} else
//ignore it otherwise
return QObject::eventFilter(obj, event);
@ -215,19 +218,33 @@ void QCitationDialog::on_restorePB_clicked()
void QCitationDialog::update()
{
if (selectedLV->selectionModel()->selectedIndexes().isEmpty()) {
fillFields();
fillEntries();
updateDialog();
}
//The main point of separating this out is that the fill*() methods
//called in update() do not need to be called for INTERNAL updates,
//such as when addPB is pressed, as the list of fields, entries, etc,
//will not have changed. At the moment, however, the division between
//fillStyles() and updateStyles() doesn't lend itself to dividing the
//two methods, though they should be divisible.
void QCitationDialog::updateDialog()
{
if (availableFocused_ ||
selectedLV->selectionModel()->selectedIndexes().isEmpty()) {
if (availableLV->selectionModel()->selectedIndexes().isEmpty()
&& availableLV->model()->rowCount() > 0)
availableLV->setCurrentIndex(availableLV->model()->index(0,0));
updateInfo(availableLV->currentIndex());
&& availableLV->model()->rowCount() > 0)
availableLV->setCurrentIndex(availableLV->model()->index(0,0));
updateInfo(availableLV);
} else
updateInfo(selectedLV->currentIndex());
updateInfo(selectedLV);
setButtons();
textBeforeED->setText(form_->textBefore());
textAfterED->setText(form_->textAfter());
fillStyles();
updateStyle();
}
@ -241,10 +258,16 @@ void QCitationDialog::updateStyle()
engine == biblio::ENGINE_NATBIB_NUMERICAL;
bool const basic_engine = engine == biblio::ENGINE_BASIC;
fulllistCB->setEnabled(natbib_engine);
forceuppercaseCB->setEnabled(natbib_engine);
textBeforeED->setEnabled(!basic_engine);
textBeforeLA->setEnabled(!basic_engine);
bool const haveSelection =
selectedLV->model()->rowCount() > 0;
fulllistCB->setEnabled(natbib_engine && haveSelection);
forceuppercaseCB->setEnabled(natbib_engine && haveSelection);
textBeforeED->setEnabled(!basic_engine && haveSelection);
textBeforeLA->setEnabled(!basic_engine && haveSelection);
textAfterED->setEnabled(haveSelection);
textAfterLA->setEnabled(haveSelection);
citationStyleCO->setEnabled(!basic_engine && haveSelection);
citationStyleLA->setEnabled(!basic_engine && haveSelection);
string const & command = form_->params().getCmdName();
@ -262,21 +285,24 @@ void QCitationDialog::updateStyle()
else
citationStyleCO->setCurrentIndex(0);
fulllistCB->setChecked(false);
forceuppercaseCB->setChecked(false);
if (cit != styles.end()) {
int const i = int(cit - styles.begin());
citationStyleCO->setCurrentIndex(i);
fulllistCB->setChecked(cs.full);
forceuppercaseCB->setChecked(cs.forceUCase);
} else {
fulllistCB->setChecked(false);
forceuppercaseCB->setChecked(false);
}
}
//This one needs to be called whenever citationStyleCO needs
//to be updated---and this would be on anything that changes the
//selection in selectedLV, or on a general update.
void QCitationDialog::fillStyles()
{
int const orig = citationStyleCO->currentIndex();
int const oldIndex = citationStyleCO->currentIndex();
citationStyleCO->clear();
@ -297,7 +323,7 @@ void QCitationDialog::fillStyles()
QStringList sty = form_->citationStyles(curr);
bool const basic_engine =
(form_->getEngine() == biblio::ENGINE_BASIC);
(form_->getEngine() == biblio::ENGINE_BASIC);
citationStyleCO->setEnabled(!sty.isEmpty() && !basic_engine);
citationStyleLA->setEnabled(!sty.isEmpty() && !basic_engine);
@ -307,8 +333,37 @@ void QCitationDialog::fillStyles()
citationStyleCO->insertItems(0, sty);
if (orig != -1 && orig < citationStyleCO->count())
citationStyleCO->setCurrentIndex(orig);
if (oldIndex != -1 && oldIndex < citationStyleCO->count())
citationStyleCO->setCurrentIndex(oldIndex);
}
void QCitationDialog::fillFields()
{
fieldsCO->blockSignals(true);
int const oldIndex = fieldsCO->currentIndex();
fieldsCO->clear();
QStringList const & fields = form_->getFieldsAsQStringList();
fieldsCO->insertItem(0, qt_("All Fields"));
fieldsCO->insertItem(1, qt_("Keys"));
fieldsCO->insertItems(2, fields);
if (oldIndex != -1 && oldIndex < fieldsCO->count())
fieldsCO->setCurrentIndex(oldIndex);
fieldsCO->blockSignals(false);
}
void QCitationDialog::fillEntries()
{
entriesCO->blockSignals(true);
int const oldIndex = entriesCO->currentIndex();
entriesCO->clear();
QStringList const & entries = form_->getEntriesAsQStringList();
entriesCO->insertItem(0, qt_("All Entry Types"));
entriesCO->insertItems(1, entries);
if (oldIndex != -1 && oldIndex < entriesCO->count())
entriesCO->setCurrentIndex(oldIndex);
entriesCO->blockSignals(false);
}
@ -338,8 +393,9 @@ void QCitationDialog::setButtons()
}
void QCitationDialog::updateInfo(const QModelIndex & idx)
void QCitationDialog::updateInfo(QListView const * const qlv)
{
QModelIndex idx = qlv->currentIndex();
if (idx.isValid()) {
QString const keytxt = form_->getKeyInfo(idx.data().toString());
infoML->document()->setPlainText(keytxt);
@ -350,7 +406,8 @@ void QCitationDialog::updateInfo(const QModelIndex & idx)
void QCitationDialog::on_selectedLV_clicked(const QModelIndex &)
{
update();
availableFocused_ = false;
updateDialog();
}
@ -358,13 +415,14 @@ void QCitationDialog::selectedChanged(const QModelIndex & idx, const QModelIndex
{
if (!idx.isValid())
return;
update();
updateDialog();
}
void QCitationDialog::on_availableLV_clicked(const QModelIndex &)
{
update();
availableFocused_ = true;
updateDialog();
}
@ -372,7 +430,8 @@ void QCitationDialog::availableChanged(const QModelIndex & idx, const QModelInde
{
if (!idx.isValid())
return;
update();
availableFocused_ = true;
updateDialog();
}
@ -380,6 +439,7 @@ void QCitationDialog::on_availableLV_doubleClicked(const QModelIndex & idx)
{
if (isSelected(idx))
return;
availableFocused_ = true;
on_addPB_clicked();
}
@ -407,7 +467,8 @@ void QCitationDialog::on_addPB_clicked()
form_->addKey(idxToAdd);
if (idx.isValid())
selectedLV->setCurrentIndex(idx);
update();
availableFocused_ = true;
updateDialog();
}
@ -425,8 +486,8 @@ void QCitationDialog::on_deletePB_clicked()
if (nrows>1)
selectedLV->setCurrentIndex(idx);
update();
availableFocused_ = true;
updateDialog();
}
@ -436,7 +497,8 @@ void QCitationDialog::on_upPB_clicked()
form_->upKey(idx);
selectedLV->setCurrentIndex(idx.sibling(idx.row() - 1, idx.column()));
availableLV->selectionModel()->reset();
update();
availableFocused_ = false;
updateDialog();
}
@ -446,17 +508,58 @@ void QCitationDialog::on_downPB_clicked()
form_->downKey(idx);
selectedLV->setCurrentIndex(idx.sibling(idx.row() + 1, idx.column()));
availableLV->selectionModel()->reset();
update();
availableFocused_ = false;
updateDialog();
}
void QCitationDialog::findText(QString const & text)
void QCitationDialog::findText(QString const & text, bool reset)
{
//"All Fields" and "Keys" are the first two
int index = fieldsCO->currentIndex() - 2;
vector<docstring> const & fields = form_->availableFields();
docstring field;
if (index <= -1 || index >= fields.size())
//either "All Fields" or "Keys" or an invalid value
field = from_ascii("");
else
field = fields[index];
//Was it "Keys"?
bool const onlyKeys = index == -1;
//"All Entry Types" is first.
index = entriesCO->currentIndex() - 1;
vector<docstring> const & entries = form_->availableEntries();
docstring entryType;
if (index < 0 || index >= entries.size())
entryType = from_ascii("");
else
entryType = entries[index];
bool const case_sentitive = caseCB->checkState();
bool const reg_exp = regexCB->checkState();
form_->findKey(text, false, case_sentitive, reg_exp);
selectedLV->selectionModel()->reset();
update();
form_->findKey(text, onlyKeys, field, entryType,
case_sentitive, reg_exp, reset);
//FIXME
//It'd be nice to save and restore the current selection in
//availableLV. Currently, we get an automatic reset, since the
//model is reset.
updateDialog();
}
void QCitationDialog::on_fieldsCO_currentIndexChanged(int /*index*/)
{
findText(findLE->text(), true);
}
void QCitationDialog::on_entriesCO_currentIndexChanged(int /*index*/)
{
findText(findLE->text(), true);
}

View File

@ -54,7 +54,13 @@ public:
protected:
void closeEvent (QCloseEvent * e);
void findText(QString const & text);
/// prepares a call to QCitation::searchKeys when we
/// are ready to search the BibTeX entries
void findText(QString const & text, bool reset = false);
/// check whether key is already selected
bool isSelected(const QModelIndex &);
/// update the display of BibTeX information
void updateInfo(QListView const * const);
protected Q_SLOTS:
void cleanUp();
@ -67,6 +73,8 @@ protected Q_SLOTS:
void on_upPB_clicked();
void on_downPB_clicked();
void on_findLE_textChanged(const QString & text);
void on_fieldsCO_currentIndexChanged(int index);
void on_entriesCO_currentIndexChanged(int index);
void on_caseCB_stateChanged(int);
void on_regexCB_stateChanged(int);
void on_selectedLV_clicked(const QModelIndex &);
@ -75,23 +83,26 @@ protected Q_SLOTS:
void on_availableLV_doubleClicked(const QModelIndex &);
void availableChanged(const QModelIndex &, const QModelIndex &);
virtual void changed();
/// check whether key is already selected
bool isSelected(const QModelIndex &);
/// update infobox
void updateInfo(const QModelIndex &);
private:
/// enable/disable buttons
void setButtons();
/// fill the styles combo
void fillStyles();
/// fill the fields combo
void fillFields();
/// fill the entries combo
void fillEntries();
/// set the styles combo
void updateStyle();
/// performs a limited update, suitable for internal call
void updateDialog();
/// last used citation style
int style_;
/// which of available and selected is "focused", in the sense
/// of which one should be used for updating the info via updateInfo().
/// true, obviously, if it is availableLV.
bool availableFocused_;
QCitation * form_;
};

View File

@ -5,14 +5,12 @@
<rect>
<x>0</x>
<y>0</y>
<width>369</width>
<height>509</height>
<width>449</width>
<height>617</height>
</rect>
</property>
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>1</hsizetype>
<vsizetype>1</vsizetype>
<sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -24,26 +22,30 @@
<bool>true</bool>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item row="0" column="0" >
<layout class="QGridLayout" >
<property name="margin" >
<property name="leftMargin" >
<number>0</number>
</property>
<property name="spacing" >
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<number>0</number>
</property>
<property name="horizontalSpacing" >
<number>6</number>
</property>
<property name="verticalSpacing" >
<number>6</number>
</property>
<item row="4" column="1" >
<widget class="QPushButton" name="upPB" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>0</hsizetype>
<vsizetype>0</vsizetype>
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -62,9 +64,7 @@
<item row="5" column="1" >
<widget class="QPushButton" name="downPB" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>0</hsizetype>
<vsizetype>0</vsizetype>
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -156,6 +156,141 @@
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<string>Search Citation</string>
</property>
<property name="flat" >
<bool>true</bool>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="findKeysLA" >
<property name="text" >
<string>F&amp;ind:</string>
</property>
<property name="alignment" >
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>findLE</cstring>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3" >
<widget class="QLineEdit" name="findLE" >
<property name="text" >
<string/>
</property>
</widget>
</item>
<item row="0" column="4" >
<widget class="QPushButton" name="clearPB" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>&lt;- C&amp;lear</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="fieldsLA" >
<property name="text" >
<string>Search Field:</string>
</property>
<property name="buddy" >
<cstring>fieldsCO</cstring>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QComboBox" name="fieldsCO" >
<property name="maxVisibleItems" >
<number>16</number>
</property>
<property name="insertPolicy" >
<enum>QComboBox::NoInsert</enum>
</property>
<property name="sizeAdjustPolicy" >
<enum>QComboBox::AdjustToContents</enum>
</property>
<item>
<property name="text" >
<string>All Fields</string>
</property>
</item>
</widget>
</item>
<item row="1" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="3" colspan="2" >
<widget class="QCheckBox" name="regexCB" >
<property name="text" >
<string>Regular E&amp;xpression</string>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="entriesLA" >
<property name="text" >
<string>Entry Types:</string>
</property>
<property name="buddy" >
<cstring>entriesCO</cstring>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QComboBox" name="entriesCO" >
<property name="insertPolicy" >
<enum>QComboBox::NoInsert</enum>
</property>
<property name="sizeAdjustPolicy" >
<enum>QComboBox::AdjustToContents</enum>
</property>
<item>
<property name="text" >
<string>All Entry Types</string>
</property>
</item>
</widget>
</item>
<item row="2" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="3" colspan="2" >
<widget class="QCheckBox" name="caseCB" >
<property name="text" >
<string>Case Se&amp;nsitive</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0" >
<widget class="QGroupBox" name="styleGB" >
<property name="title" >
@ -165,18 +300,28 @@
<bool>true</bool>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<property name="leftMargin" >
<number>9</number>
</property>
<property name="spacing" >
<property name="topMargin" >
<number>9</number>
</property>
<property name="rightMargin" >
<number>9</number>
</property>
<property name="bottomMargin" >
<number>9</number>
</property>
<property name="horizontalSpacing" >
<number>6</number>
</property>
<property name="verticalSpacing" >
<number>6</number>
</property>
<item row="0" column="1" colspan="2" >
<widget class="QComboBox" name="citationStyleCO" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>3</hsizetype>
<vsizetype>0</vsizetype>
<sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -229,9 +374,7 @@
<item row="2" column="1" colspan="2" >
<widget class="QLineEdit" name="textAfterED" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>5</hsizetype>
<vsizetype>0</vsizetype>
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -254,9 +397,7 @@
<item row="1" column="1" colspan="2" >
<widget class="QLineEdit" name="textBeforeED" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>5</hsizetype>
<vsizetype>0</vsizetype>
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -271,12 +412,21 @@
</item>
<item row="4" column="0" >
<layout class="QHBoxLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="restorePB" >
<property name="text" >
@ -329,78 +479,6 @@
</item>
</layout>
</item>
<item row="2" column="0" >
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<string>Search Citation</string>
</property>
<property name="flat" >
<bool>true</bool>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item row="1" column="1" >
<layout class="QHBoxLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QCheckBox" name="caseCB" >
<property name="text" >
<string>Case Se&amp;nsitive</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="regexCB" >
<property name="text" >
<string>Regular E&amp;xpression</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="2" >
<widget class="QPushButton" name="clearPB" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>&lt;- C&amp;lear</string>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QLineEdit" name="findLE" >
<property name="text" >
<string/>
</property>
</widget>
</item>
<item row="0" column="0" >
<widget class="QLabel" name="findKeysLA" >
<property name="text" >
<string>F&amp;ind:</string>
</property>
<property name="alignment" >
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<cstring>findLE</cstring>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<tabstops>

View File

@ -15,7 +15,7 @@
#ifndef INSETBASE_H
#define INSETBASE_H
#include "Biblio_typedefs.h"
#include "Biblio.h"
#include "Changes.h"
#include "Dimension.h"
@ -441,7 +441,7 @@ public:
virtual void addToToc(TocList &, Buffer const &, ParConstIterator const &) const {}
/// Fill keys with BibTeX information
virtual void fillWithBibKeys(Buffer const &,
biblio::BibKeyList &, InsetIterator const &) const { return; }
BiblioInfo &, InsetIterator const &) const { return; }
/// Update the counters of this inset and of its contents
virtual void updateLabels(Buffer const &, ParIterator const &) {}

View File

@ -12,7 +12,6 @@
#include "InsetBibitem.h"
#include "Biblio.h"
#include "Buffer.h"
#include "BufferParams.h"
#include "BufferView.h"
@ -183,14 +182,14 @@ docstring const bibitemWidest(Buffer const & buffer)
void InsetBibitem::fillWithBibKeys(Buffer const & buf,
biblio::BibKeyList & keys, InsetIterator const & it) const
BiblioInfo & keys, InsetIterator const & it) const
{
string const key = to_utf8(getParam("key"));
biblio::BibTeXInfo keyvalmap;
docstring const key = getParam("key");
BibTeXInfo keyvalmap;
keyvalmap[from_ascii("label")] = getParam("label");
DocIterator doc_it(it);
doc_it.forwardPos();
keyvalmap [from_ascii("ref")] = doc_it.paragraph().asString(buf, false);
keyvalmap[from_ascii("ref")] = doc_it.paragraph().asString(buf, false);
keyvalmap.isBibTeX = false;
keys[key] = keyvalmap;
}

View File

@ -14,7 +14,7 @@
#include "InsetCommand.h"
#include "Biblio_typedefs.h"
#include "Biblio.h"
namespace lyx {
@ -42,7 +42,7 @@ public:
int plaintext(Buffer const &, odocstream &, OutputParams const &) const;
///
virtual void fillWithBibKeys(Buffer const &,
biblio::BibKeyList &, InsetIterator const &) const;
BiblioInfo &, InsetIterator const &) const;
/// Update the counter of this inset
virtual void updateLabels(Buffer const &, ParIterator const &);

View File

@ -580,7 +580,7 @@ namespace {
// This method returns a comma separated list of Bibtex entries
void InsetBibtex::fillWithBibKeys(Buffer const & buffer,
biblio::BibKeyList & keys, InsetIterator const & /*di*/) const
BiblioInfo & keylist, InsetIterator const & /*di*/) const
{
vector<FileName> const files = getFiles(buffer);
for (vector<FileName>::const_iterator it = files.begin();
@ -695,7 +695,7 @@ void InsetBibtex::fillWithBibKeys(Buffer const & buffer,
docstring value;
docstring commaNewline;
docstring data;
biblio::BibTeXInfo keyvalmap;
BibTeXInfo keyvalmap;
keyvalmap.entryType = entryType;
bool readNext = removeWSAndComma(ifs);
@ -722,14 +722,16 @@ void InsetBibtex::fillWithBibKeys(Buffer const & buffer,
keyvalmap[name] = value;
data += "\n\n" + value;
keylist.fieldNames.insert(name);
readNext = removeWSAndComma(ifs);
}
// add the new entry
keylist.entryTypes.insert(entryType);
keyvalmap.allData = data;
keyvalmap.isBibTeX = true;
keys[to_utf8(key)] = keyvalmap;
keyvalmap.bibKey = key;
keylist[key] = keyvalmap;
}
} //< searching '@'
} //< for loop over files

View File

@ -14,7 +14,7 @@
#include <map>
#include "InsetCommand.h"
#include "Biblio_typedefs.h"
#include "Biblio.h"
#include "support/FileName.h"
@ -39,7 +39,7 @@ public:
int latex(Buffer const &, odocstream &, OutputParams const &) const;
///
virtual void fillWithBibKeys(Buffer const &,
biblio::BibKeyList &, InsetIterator const &) const;
BiblioInfo &, InsetIterator const &) const;
///
std::vector<support::FileName> const getFiles(Buffer const &) const;
///

View File

@ -13,6 +13,7 @@
#include "InsetCitation.h"
#include "Biblio.h"
#include "Buffer.h"
#include "BufferParams.h"
#include "debug.h"
@ -39,6 +40,7 @@ using support::FileName;
using support::getStringFromVector;
using support::getVectorFromString;
using support::ltrim;
using support::prefixIs;
using support::rtrim;
using support::split;
using support::tokenPos;
@ -55,8 +57,107 @@ namespace fs = boost::filesystem;
namespace {
vector<string> const init_possible_cite_commands()
{
char const * const pos[] = {
"cite", "citet", "citep", "citealt", "citealp",
"citeauthor", "citeyear", "citeyearpar",
"citet*", "citep*", "citealt*", "citealp*", "citeauthor*",
"Citet", "Citep", "Citealt", "Citealp", "Citeauthor",
"Citet*", "Citep*", "Citealt*", "Citealp*", "Citeauthor*",
"fullcite",
"footcite", "footcitet", "footcitep", "footcitealt",
"footcitealp", "footciteauthor", "footciteyear", "footciteyearpar",
"citefield", "citetitle", "cite*"
};
size_t const size_pos = sizeof(pos) / sizeof(pos[0]);
return vector<string>(pos, pos + size_pos);
}
vector<string> const & possible_cite_commands()
{
static vector<string> const pos = init_possible_cite_commands();
return pos;
}
bool is_possible_cite_command(string const & input)
{
vector<string> const & possibles = possible_cite_commands();
vector<string>::const_iterator const end = possibles.end();
return std::find(possibles.begin(), end, input) != end;
}
string const default_cite_command(biblio::CiteEngine engine)
{
string str;
switch (engine) {
case biblio::ENGINE_BASIC:
str = "cite";
break;
case biblio::ENGINE_NATBIB_AUTHORYEAR:
str = "citet";
break;
case biblio::ENGINE_NATBIB_NUMERICAL:
str = "citep";
break;
case biblio::ENGINE_JURABIB:
str = "cite";
break;
}
return str;
}
string const
asValidLatexCommand(string const & input, biblio::CiteEngine const engine)
{
string const default_str = default_cite_command(engine);
if (!is_possible_cite_command(input))
return default_str;
string output;
switch (engine) {
case biblio::ENGINE_BASIC:
output = default_str;
break;
case biblio::ENGINE_NATBIB_AUTHORYEAR:
case biblio::ENGINE_NATBIB_NUMERICAL:
if (input == "cite" || input == "citefield" ||
input == "citetitle" || input == "cite*")
output = default_str;
else if (prefixIs(input, "foot"))
output = input.substr(4);
else
output = input;
break;
case biblio::ENGINE_JURABIB: {
// Jurabib does not support the 'uppercase' natbib style.
if (input[0] == 'C')
output = string(1, 'c') + input.substr(1);
else
output = input;
// Jurabib does not support the 'full' natbib style.
string::size_type const n = output.size() - 1;
if (output != "cite*" && output[n] == '*')
output = output.substr(0, n);
break;
}
}
return output;
}
docstring const getNatbibLabel(Buffer const & buffer,
string const & citeType, string const & keyList,
string const & citeType, docstring const & keyList,
docstring const & before, docstring const & after,
biblio::CiteEngine engine)
{
@ -65,13 +166,13 @@ docstring const getNatbibLabel(Buffer const & buffer,
return docstring();
// Cache the labels
typedef std::map<Buffer const *, biblio::BibKeyList> CachedMap;
typedef std::map<Buffer const *, BiblioInfo> CachedMap;
static CachedMap cached_keys;
// and cache the timestamp of the bibliography files.
static std::map<FileName, time_t> bibfileStatus;
biblio::BibKeyList keylist;
BiblioInfo biblist;
vector<FileName> const & bibfilesCache = buffer.getBibfilesCache();
// compare the cached timestamps with the actual ones.
@ -95,15 +196,15 @@ docstring const getNatbibLabel(Buffer const & buffer,
}
}
// build the keylist only if the bibfiles have been changed
// build the list only if the bibfiles have been changed
if (cached_keys[&buffer].empty() || bibfileStatus.empty() || changed) {
buffer.fillWithBibKeys(keylist);
cached_keys[&buffer] = keylist;
biblist.fillWithBibKeys(&buffer);
cached_keys[&buffer] = biblist;
} else
// use the cached keys
keylist = cached_keys[&buffer];
biblist = cached_keys[&buffer];
if (keylist.empty())
if (biblist.empty())
return docstring();
// the natbib citation-styles
@ -118,10 +219,12 @@ docstring const getNatbibLabel(Buffer const & buffer,
// CITE: author/<before field>
// We don't currently use the full or forceUCase fields.
string cite_type = biblio::asValidLatexCommand(citeType, engine);
string cite_type = asValidLatexCommand(citeType, engine);
if (cite_type[0] == 'C')
//If we were going to use them, this would mean ForceUCase
cite_type = string(1, 'c') + cite_type.substr(1);
if (cite_type[cite_type.size() - 1] == '*')
//and this would mean FULL
cite_type = cite_type.substr(0, cite_type.size() - 1);
docstring before_str;
@ -161,13 +264,13 @@ docstring const getNatbibLabel(Buffer const & buffer,
docstring const sep_str(from_ascii(sep) + ' ');
docstring label;
vector<string> keys = getVectorFromString(keyList);
vector<string>::const_iterator it = keys.begin();
vector<string>::const_iterator end = keys.end();
vector<docstring> keys = getVectorFromString(keyList);
vector<docstring>::const_iterator it = keys.begin();
vector<docstring>::const_iterator end = keys.end();
for (; it != end; ++it) {
// get the bibdata corresponding to the key
docstring const author(biblio::getAbbreviatedAuthor(keylist, *it));
docstring const year(biblio::getYear(keylist, *it));
docstring const author(biblist.getAbbreviatedAuthor(*it));
docstring const year(biblist.getYear(*it));
// Something isn't right. Fail safely.
if (author.empty() || year.empty())
@ -190,9 +293,7 @@ docstring const getNatbibLabel(Buffer const & buffer,
year + cp + sep_str;
break;
case biblio::ENGINE_NATBIB_NUMERICAL:
// FIXME UNICODE
label += author + op_str + before_str +
'#' + from_utf8(*it) + cp + sep_str;
label += author + op_str + before_str + '#' + *it + cp + sep_str;
break;
case biblio::ENGINE_JURABIB:
label += before_str + author + op_str +
@ -206,8 +307,7 @@ docstring const getNatbibLabel(Buffer const & buffer,
} else if (cite_type == "citep" ||
cite_type == "citealp") {
if (engine == biblio::ENGINE_NATBIB_NUMERICAL) {
// FIXME UNICODE
label += from_utf8(*it) + sep_str;
label += *it + sep_str;
} else {
label += author + ", " + year + sep_str;
}
@ -221,9 +321,7 @@ docstring const getNatbibLabel(Buffer const & buffer,
year + sep_str;
break;
case biblio::ENGINE_NATBIB_NUMERICAL:
// FIXME UNICODE
label += author + ' ' + before_str +
'#' + from_utf8(*it) + sep_str;
label += author + ' ' + before_str + '#' + *it + sep_str;
break;
case biblio::ENGINE_JURABIB:
label += before_str + author + ' ' +
@ -310,8 +408,7 @@ docstring const InsetCitation::generateLabel(Buffer const & buffer) const
docstring label;
biblio::CiteEngine const engine = buffer.params().getEngine();
if (engine != biblio::ENGINE_BASIC) {
// FIXME UNICODE
label = getNatbibLabel(buffer, getCmdName(), to_utf8(getParam("key")),
label = getNatbibLabel(buffer, getCmdName(), getParam("key"),
before, after, engine);
}
@ -415,7 +512,7 @@ int InsetCitation::latex(Buffer const & buffer, odocstream & os,
biblio::CiteEngine cite_engine = buffer.params().getEngine();
// FIXME UNICODE
docstring const cite_str = from_utf8(
biblio::asValidLatexCommand(getCmdName(), cite_engine));
asValidLatexCommand(getCmdName(), cite_engine));
os << "\\" << cite_str;

View File

@ -727,14 +727,14 @@ void InsetInclude::getLabelList(Buffer const & buffer,
void InsetInclude::fillWithBibKeys(Buffer const & buffer,
biblio::BibKeyList & keys, InsetIterator const & /*di*/) const
BiblioInfo & keys, InsetIterator const & /*di*/) const
{
if (loadIfNeeded(buffer, params_)) {
string const included_file = includedFilename(buffer, params_).absFilename();
Buffer * tmp = theBufferList().getBuffer(included_file);
//FIXME This is kind of a dirty hack and should be made reasonable.
tmp->setParentName("");
tmp->fillWithBibKeys(keys);
keys.fillWithBibKeys(tmp);
tmp->setParentName(parentFilename(buffer));
}
}

View File

@ -12,7 +12,7 @@
#ifndef INSET_INCLUDE_H
#define INSET_INCLUDE_H
#include "Biblio_typedefs.h"
#include "Biblio.h"
#include "Inset.h"
#include "InsetCommandParams.h"
#include "RenderButton.h"
@ -62,7 +62,7 @@ public:
* \param it not used here
*/
virtual void fillWithBibKeys(Buffer const & buffer,
biblio::BibKeyList & keys, InsetIterator const & it) const;
BiblioInfo & keys, InsetIterator const & it) const;
/** Update the cache with all bibfiles in use of the child buffer
* (including bibfiles of grandchild documents).