#include "Author.h"
+#include "support/convert.h"
#include "support/lassert.h"
#include "support/lstrings.h"
Author::Author(docstring const & name, docstring const & email)
- : name_(name), email_(email), used_(true)
+ : name_(name), email_(email), used_(true),
+ buffer_id_(computeHash(name, email))
+{}
+
+
+Author::Author(int buffer_id)
+ : name_(convert<docstring>(buffer_id)), email_(docstring()), used_(false),
+ buffer_id_(buffer_id)
+{}
+
+
+bool Author::valid() const
{
- buffer_id_ = computeHash(name_, email_);
+ //this cannot be equal if the buffer_id was produced by the hash function.
+ return name_ != convert<docstring>(buffer_id_);
}
AuthorList::AuthorList()
- : last_id_(0)
{}
int AuthorList::record(Author const & a)
{
+ bool const valid = a.valid();
// If we record an author which equals the current
// author, we copy the buffer_id, so that it will
// keep the same id in the file.
- if (!authors_.empty() && a == authors_[0])
+ if (valid && !authors_.empty() && a == authors_[0])
authors_[0].setBufferId(a.bufferId());
- Authors::const_iterator it(authors_.begin());
- Authors::const_iterator itend(authors_.end());
- for (int i = 0; it != itend; ++it, ++i) {
- if (*it == a)
- return i;
+ Authors::const_iterator it = authors_.begin();
+ Authors::const_iterator const beg = it;
+ Authors::const_iterator const end = authors_.end();
+ for (; it != end; ++it) {
+ if (valid && *it == a)
+ return it - beg;
+ if (it->bufferId() == a.bufferId()) {
+ int id = it - beg;
+ if (!it->valid())
+ // we need to handle the case of a valid author being registred
+ // after an invalid one. For instance, because "buffer-reload"
+ // does not clear the buffer's author list.
+ record(id, a);
+ return id;
+ }
}
authors_.push_back(a);
- return last_id_++;
+ return authors_.size() - 1;
}
sorted.sort();
AuthorList::Authors::const_iterator a_it = sorted.begin();
- AuthorList::Authors::const_iterator a_end = sorted.end();
-
- for (a_it = sorted.begin(); a_it != a_end; ++a_it) {
- if (a_it->used())
+ AuthorList::Authors::const_iterator const a_end = sorted.end();
+
+ for (; a_it != a_end; ++a_it) {
+ if (a_it->used() && a_it->valid())
os << "\\author " << *a_it << "\n";
}
return os;
Author() : used_(false), buffer_id_(0) {};
///
Author(docstring const & name, docstring const & email);
+ /// For when the \author line is missing (#9854)
+ Author(int buffer_id);
///
docstring name() const { return name_; }
///
void setUsed(bool u) const { used_ = u; }
///
bool used() const { return used_; }
+ /// Was the author line not missing?
+ bool valid() const;
///
friend std::istream & operator>>(std::istream & os, Author & a);
///
friend
std::ostream & operator<<(std::ostream & os, AuthorList const & a);
private:
- ///
- int last_id_;
///
Authors authors_;
};
output_sync = false;
use_refstyle = true;
+
+ // map current author
+ author_map_[pimpl_->authorlist.get(0).bufferId()] = 0;
}
}
+void BufferParams::addAuthor(Author a)
+{
+ author_map_[a.bufferId()] = pimpl_->authorlist.record(a);
+}
+
+
BranchList & BufferParams::branchlist()
{
return pimpl_->branchlist;
istringstream ss(lex.getString());
Author a;
ss >> a;
- author_map[a.bufferId()] = pimpl_->authorlist.record(a);
+ addAuthor(a);
} else if (token == "\\paperorientation") {
string orient;
lex >> orient;
#ifndef BUFFERPARAMS_H
#define BUFFERPARAMS_H
+#include "Author.h"
#include "Citation.h"
#include "DocumentClassPtr.h"
#include "Format.h"
namespace support { class FileName; }
-class AuthorList;
class BranchList;
class Bullet;
class DocumentClass;
/// the author list for the document
AuthorList & authors();
AuthorList const & authors() const;
+ void addAuthor(Author a);
/// map of the file's author IDs to AuthorList indexes
typedef std::map<int, int> AuthorMap;
- AuthorMap author_map;
+ AuthorMap author_map_;
+
/// the buffer's active font encoding
std::string const font_encoding() const;
/// all font encodings requested by the prefs/document/main language.
string const & token, Font & font, Change & change, ErrorList & errorList)
{
Buffer * buf = const_cast<Buffer *>(&owner_->buffer());
- BufferParams const & bp = buf->params();
+ BufferParams & bp = buf->params();
if (token[0] != '\\') {
docstring dstr = lex.getDocString();
int aid;
time_t ct;
is >> aid >> ct;
- BufferParams::AuthorMap const & am = bp.author_map;
+ BufferParams::AuthorMap const & am = bp.author_map_;
if (am.find(aid) == am.end()) {
- errorList.push_back(ErrorItem(_("Change tracking error"),
- bformat(_("Unknown author index for change: %1$d\n"), aid),
- par.id(), 0, par.size()));
- change = Change(Change::UNCHANGED);
- } else {
- if (token == "\\change_inserted")
- change = Change(Change::INSERTED, am.find(aid)->second, ct);
- else
- change = Change(Change::DELETED, am.find(aid)->second, ct);
+ errorList.push_back(ErrorItem(
+ _("Change tracking author index missing"),
+ bformat(_("A change tracking author information for index "
+ "%1$d is missing. This can happen after a wrong "
+ "merge by a version control system. In this case, "
+ "either fix the merge, or have this information "
+ "missing until the corresponding tracked changes "
+ "are merged or this user edits the file again.\n"),
+ aid),
+ par.id(), par.size(), par.size() + 1
+ ));
+ bp.addAuthor(Author(aid));
}
+ if (token == "\\change_inserted")
+ change = Change(Change::INSERTED, am.find(aid)->second, ct);
+ else
+ change = Change(Change::DELETED, am.find(aid)->second, ct);
} else {
lex.eatLine();
errorList.push_back(ErrorItem(_("Unknown token"),