mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 05:16:21 +00:00
#7789 unify and fix buffer statistics
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@40602 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
576e8d0497
commit
42dfd71197
@ -309,11 +309,27 @@ public:
|
||||
CloneList * clone_list_;
|
||||
/// are we in the process of exporting this buffer?
|
||||
mutable bool doing_export;
|
||||
|
||||
/// compute statistics
|
||||
/// \p from initial position
|
||||
/// \p to points to the end position
|
||||
void updateStatistics(DocIterator & from, DocIterator & to,
|
||||
bool skipNoOutput = true);
|
||||
/// statistics accessor functions
|
||||
int wordCount() const { return word_count_; }
|
||||
int charCount(bool with_blanks) const {
|
||||
return char_count_
|
||||
+ (with_blanks ? blank_count_ : 0);
|
||||
}
|
||||
|
||||
private:
|
||||
/// So we can force access via the accessors.
|
||||
mutable Buffer const * parent_buffer;
|
||||
|
||||
int word_count_;
|
||||
int char_count_;
|
||||
int blank_count_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -4427,6 +4443,77 @@ int Buffer::spellCheck(DocIterator & from, DocIterator & to,
|
||||
}
|
||||
|
||||
|
||||
void Buffer::Impl::updateStatistics(DocIterator & from, DocIterator & to, bool skipNoOutput)
|
||||
{
|
||||
bool inword = false;
|
||||
word_count_ = 0;
|
||||
char_count_ = 0;
|
||||
blank_count_ = 0;
|
||||
|
||||
for (DocIterator dit = from ; dit != to && !dit.atEnd(); ) {
|
||||
if (!dit.inTexted()) {
|
||||
dit.forwardPos();
|
||||
continue;
|
||||
}
|
||||
|
||||
Paragraph const & par = dit.paragraph();
|
||||
pos_type const pos = dit.pos();
|
||||
|
||||
// Copied and adapted from isWordSeparator() in Paragraph
|
||||
if (pos == dit.lastpos()) {
|
||||
inword = false;
|
||||
} else {
|
||||
Inset const * ins = par.getInset(pos);
|
||||
if (ins && skipNoOutput && !ins->producesOutput()) {
|
||||
// skip this inset
|
||||
++dit.top().pos();
|
||||
// stop if end of range was skipped
|
||||
if (!to.atEnd() && dit >= to)
|
||||
break;
|
||||
continue;
|
||||
} else if (!par.isDeleted(pos)) {
|
||||
if (par.isWordSeparator(pos))
|
||||
inword = false;
|
||||
else if (!inword) {
|
||||
++word_count_;
|
||||
inword = true;
|
||||
}
|
||||
if (ins && ins->isLetter())
|
||||
++char_count_;
|
||||
else if (ins && ins->isSpace())
|
||||
++blank_count_;
|
||||
else {
|
||||
char_type const c = par.getChar(pos);
|
||||
if (isPrintableNonspace(c))
|
||||
++char_count_;
|
||||
else if (isSpace(c))
|
||||
++blank_count_;
|
||||
}
|
||||
}
|
||||
}
|
||||
dit.forwardPos();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Buffer::updateStatistics(DocIterator & from, DocIterator & to, bool skipNoOutput) const
|
||||
{
|
||||
d->updateStatistics(from, to, skipNoOutput);
|
||||
}
|
||||
|
||||
|
||||
int Buffer::wordCount() const
|
||||
{
|
||||
return d->wordCount();
|
||||
}
|
||||
|
||||
|
||||
int Buffer::charCount(bool with_blanks) const
|
||||
{
|
||||
return d->charCount(with_blanks);
|
||||
}
|
||||
|
||||
|
||||
Buffer::ReadStatus Buffer::reload()
|
||||
{
|
||||
setBusy(true);
|
||||
|
10
src/Buffer.h
10
src/Buffer.h
@ -689,6 +689,16 @@ public:
|
||||
///
|
||||
void checkChildBuffers();
|
||||
|
||||
/// compute statistics between \p from and \p to
|
||||
/// \p from initial position
|
||||
/// \p to points to the end position
|
||||
/// \p skipNoOutput if notes etc. should be ignored
|
||||
void updateStatistics(DocIterator & from, DocIterator & to,
|
||||
bool skipNoOutput = true) const;
|
||||
/// statistics accessor functions
|
||||
int wordCount() const;
|
||||
int charCount(bool with_blanks) const;
|
||||
|
||||
private:
|
||||
class MarkAsExporting;
|
||||
friend class MarkAsExporting;
|
||||
|
@ -1655,9 +1655,10 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
|
||||
from = doc_iterator_begin(&buffer_);
|
||||
to = doc_iterator_end(&buffer_);
|
||||
}
|
||||
int const words = countWords(from, to);
|
||||
int const chars = countChars(from, to, false);
|
||||
int const chars_blanks = countChars(from, to, true);
|
||||
buffer_.updateStatistics(from, to);
|
||||
int const words = buffer_.wordCount();
|
||||
int const chars = buffer_.charCount(false);
|
||||
int const chars_blanks = buffer_.charCount(true);
|
||||
docstring message;
|
||||
if (cur.selection())
|
||||
message = _("Statistics for the selection:");
|
||||
|
@ -174,99 +174,6 @@ Buffer * newUnnamedFile(FileName const & path, string const & prefix,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FIXME : merge with countChars. The structures of the two functions
|
||||
* are similar but, unfortunately, they seem to have a different
|
||||
* notion of what to count. Since nobody ever complained about that,
|
||||
* this proves (again) that any number beats no number ! (JMarc)
|
||||
* We have two use cases:
|
||||
* 1. Count the words of the given range for document statistics
|
||||
* - ignore inset content without output. (skipNoOutput == true)
|
||||
* 2. Count the words to present a progress bar for the spell checker
|
||||
* - has to count whole content. (skipNoOutput == false)
|
||||
*/
|
||||
int countWords(DocIterator const & from, DocIterator const & to,
|
||||
bool skipNoOutput)
|
||||
{
|
||||
int count = 0;
|
||||
bool inword = false;
|
||||
|
||||
for (DocIterator dit = from ; dit != to && !dit.atEnd(); ) {
|
||||
if (!dit.inTexted()) {
|
||||
dit.forwardPos();
|
||||
continue;
|
||||
}
|
||||
|
||||
Paragraph const & par = dit.paragraph();
|
||||
pos_type const pos = dit.pos();
|
||||
|
||||
// Copied and adapted from isWordSeparator() in Paragraph
|
||||
if (pos == dit.lastpos()) {
|
||||
inword = false;
|
||||
} else if (!par.isDeleted(pos)) {
|
||||
Inset const * ins = par.getInset(pos);
|
||||
if (ins && skipNoOutput && !ins->producesOutput()) {
|
||||
// skip this inset
|
||||
++dit.top().pos();
|
||||
// stop if end of range was skipped
|
||||
if (!to.atEnd() && dit >= to)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (par.isWordSeparator(pos))
|
||||
inword = false;
|
||||
else if (!inword) {
|
||||
++count;
|
||||
inword = true;
|
||||
}
|
||||
}
|
||||
dit.forwardPos();
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
int countChars(DocIterator const & from, DocIterator const & to,
|
||||
bool with_blanks)
|
||||
{
|
||||
int chars = 0;
|
||||
int blanks = 0;
|
||||
for (DocIterator dit = from ; dit != to ; ) {
|
||||
if (!dit.inTexted()) {
|
||||
dit.forwardPos();
|
||||
continue;
|
||||
}
|
||||
|
||||
Paragraph const & par = dit.paragraph();
|
||||
pos_type const pos = dit.pos();
|
||||
|
||||
if (pos != dit.lastpos() && !par.isDeleted(pos)) {
|
||||
if (Inset const * ins = par.getInset(pos)) {
|
||||
if (!ins->producesOutput()) {
|
||||
//skip this inset
|
||||
++dit.top().pos();
|
||||
continue;
|
||||
}
|
||||
if (ins->isLetter())
|
||||
++chars;
|
||||
else if (with_blanks && ins->isSpace())
|
||||
++blanks;
|
||||
} else {
|
||||
char_type const c = par.getChar(pos);
|
||||
if (isPrintableNonspace(c))
|
||||
++chars;
|
||||
else if (isSpace(c) && with_blanks)
|
||||
++blanks;
|
||||
}
|
||||
}
|
||||
dit.forwardPos();
|
||||
}
|
||||
|
||||
return chars + blanks;
|
||||
}
|
||||
|
||||
|
||||
Buffer * loadIfNeeded(FileName const & fname)
|
||||
{
|
||||
Buffer * buffer = theBufferList().getBuffer(fname);
|
||||
|
@ -46,13 +46,6 @@ Buffer * newUnnamedFile(support::FileName const & path,
|
||||
/// file was already loaded it just returns the associated buffer.
|
||||
Buffer * loadIfNeeded(support::FileName const & fname);
|
||||
|
||||
/// Count the number of words in the text between these two iterators
|
||||
int countWords(DocIterator const & from, DocIterator const & to,
|
||||
bool skipNoOutput = true);
|
||||
|
||||
/// Count the number of chars in the text between these two iterators
|
||||
int countChars(DocIterator const & from, DocIterator const & to, bool with_blanks);
|
||||
|
||||
} // namespace lyx
|
||||
|
||||
#endif // BUFFER_FUNCS_H
|
||||
|
Loading…
Reference in New Issue
Block a user