mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 13:18:28 +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_;
|
CloneList * clone_list_;
|
||||||
/// are we in the process of exporting this buffer?
|
/// are we in the process of exporting this buffer?
|
||||||
mutable bool doing_export;
|
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:
|
private:
|
||||||
/// So we can force access via the accessors.
|
/// So we can force access via the accessors.
|
||||||
mutable Buffer const * parent_buffer;
|
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()
|
Buffer::ReadStatus Buffer::reload()
|
||||||
{
|
{
|
||||||
setBusy(true);
|
setBusy(true);
|
||||||
|
10
src/Buffer.h
10
src/Buffer.h
@ -689,6 +689,16 @@ public:
|
|||||||
///
|
///
|
||||||
void checkChildBuffers();
|
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:
|
private:
|
||||||
class MarkAsExporting;
|
class MarkAsExporting;
|
||||||
friend class MarkAsExporting;
|
friend class MarkAsExporting;
|
||||||
|
@ -1655,9 +1655,10 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
|
|||||||
from = doc_iterator_begin(&buffer_);
|
from = doc_iterator_begin(&buffer_);
|
||||||
to = doc_iterator_end(&buffer_);
|
to = doc_iterator_end(&buffer_);
|
||||||
}
|
}
|
||||||
int const words = countWords(from, to);
|
buffer_.updateStatistics(from, to);
|
||||||
int const chars = countChars(from, to, false);
|
int const words = buffer_.wordCount();
|
||||||
int const chars_blanks = countChars(from, to, true);
|
int const chars = buffer_.charCount(false);
|
||||||
|
int const chars_blanks = buffer_.charCount(true);
|
||||||
docstring message;
|
docstring message;
|
||||||
if (cur.selection())
|
if (cur.selection())
|
||||||
message = _("Statistics for the 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 * loadIfNeeded(FileName const & fname)
|
||||||
{
|
{
|
||||||
Buffer * buffer = theBufferList().getBuffer(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.
|
/// file was already loaded it just returns the associated buffer.
|
||||||
Buffer * loadIfNeeded(support::FileName const & fname);
|
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
|
} // namespace lyx
|
||||||
|
|
||||||
#endif // BUFFER_FUNCS_H
|
#endif // BUFFER_FUNCS_H
|
||||||
|
Loading…
Reference in New Issue
Block a user