* moved text completion logic into Text class

* added completion support to InsetTabular


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23763 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Stefan Schimanski 2008-03-15 12:22:28 +00:00
parent 685970043e
commit cdbebdf093
8 changed files with 202 additions and 82 deletions

View File

@ -26,8 +26,8 @@
#include "BufferParams.h"
#include "BufferView.h"
#include "Changes.h"
#include "CompletionList.h"
#include "Cursor.h"
#include "ParIterator.h"
#include "CutAndPaste.h"
#include "DispatchResult.h"
#include "Encoding.h"
@ -42,10 +42,12 @@
#include "Paragraph.h"
#include "paragraph_funcs.h"
#include "ParagraphParameters.h"
#include "ParIterator.h"
#include "TextClass.h"
#include "TextMetrics.h"
#include "VSpace.h"
#include "WordLangTuple.h"
#include "WordList.h"
#include "insets/InsetText.h"
#include "insets/InsetBibitem.h"
@ -331,6 +333,35 @@ void readParagraph(Buffer const & buf, Paragraph & par, Lexer & lex,
} // namespace anon
class TextCompletionList : public CompletionList
{
public:
///
TextCompletionList(Cursor const & cur)
: buf_(cur.buffer()), pos_(0) {}
///
virtual ~TextCompletionList() {}
///
virtual bool sorted() const { return true; }
///
virtual size_t size() const
{
return theWordList().size();
}
///
virtual docstring const & data(size_t idx) const
{
return theWordList().word(idx);
}
private:
///
Buffer const & buf_;
///
size_t pos_;
};
bool Text::empty() const
{
@ -1449,4 +1480,48 @@ void Text::setMacrocontextPosition(DocIterator const & pos)
}
docstring Text::previousWord(CursorSlice const & sl) const
{
CursorSlice from = sl;
CursorSlice to = sl;
getWord(from, to, PREVIOUS_WORD);
if (sl == from || to == from)
return docstring();
Paragraph const & par = sl.paragraph();
return par.asString(from.pos(), to.pos(), false);
}
bool Text::completionSupported(Cursor const & cur) const
{
Paragraph const & par = cur.paragraph();
return cur.pos() > 0
&& (cur.pos() >= par.size() || !par.isLetter(cur.pos()))
&& par.isLetter(cur.pos() - 1);
}
CompletionList const * Text::createCompletionList(Cursor const & cur) const
{
return new TextCompletionList(cur);
}
bool Text::insertCompletion(Cursor & cur, docstring const & s, bool /*finished*/)
{
BOOST_ASSERT(cur.bv().cursor() == cur);
cur.insert(s);
cur.bv().cursor() = cur;
if (!(cur.disp_.update() & Update::Force))
cur.updateFlags(cur.disp_.update() | Update::SinglePar);
return true;
}
docstring Text::completionPrefix(Cursor const & cur) const
{
return previousWord(cur.top());
}
} // namespace lyx

View File

@ -22,6 +22,7 @@ namespace lyx {
class Buffer;
class BufferParams;
class BufferView;
class CompletionList;
class CursorSlice;
class DocIterator;
class ErrorList;
@ -137,7 +138,9 @@ public:
void getWord(CursorSlice & from, CursorSlice & to, word_location const) const;
/// just selects the word the cursor is in
void selectWord(Cursor & cur, word_location loc);
/// convenience function get the previous word or an empty string
docstring previousWord(CursorSlice const & sl) const;
/// what type of change operation to make
enum ChangeOp {
ACCEPT,
@ -282,6 +285,15 @@ public:
///
void setMacrocontextPosition(DocIterator const & pos);
///
bool completionSupported(Cursor const & cur) const;
///
CompletionList const * createCompletionList(Cursor const & cur) const;
///
bool insertCompletion(Cursor & cur, docstring const & s, bool /*finished*/);
///
docstring completionPrefix(Cursor const & cur) const;
public:
///
ParagraphList pars_;

View File

@ -2088,6 +2088,33 @@ void TextMetrics::drawRowSelection(PainterInfo & pi, int x, Row const & row,
}
}
void TextMetrics::completionPosAndDim(Cursor const & cur, int & x, int & y,
Dimension & dim) const
{
Cursor const & bvcur = cur.bv().cursor();
// get word in front of cursor
docstring word = text_->previousWord(bvcur.top());
DocIterator wordStart = bvcur;
wordStart.pos() -= word.length();
// get position on screen of the word start and end
Point lxy = cur.bv().getPos(wordStart, false);
Point rxy = cur.bv().getPos(bvcur, bvcur.boundary());
// calculate dimensions of the word
dim = rowHeight(bvcur.pit(), wordStart.pos(), bvcur.pos(), false);
dim.wid = abs(rxy.x_ - lxy.x_);
// calculate position of word
y = lxy.y_;
x = min(rxy.x_, lxy.x_);
//lyxerr << "wid=" << dim.width() << " x=" << x << " y=" << y << " lxy.x_=" << lxy.x_ << " rxy.x_=" << rxy.x_ << " word=" << word << std::endl;
//lyxerr << " wordstart=" << wordStart << " bvcur=" << bvcur << " cur=" << cur << std::endl;
}
//int TextMetrics::pos2x(pit_type pit, pos_type pos) const
//{
// ParagraphMetrics const & pm = par_metrics_[pit];

View File

@ -238,6 +238,10 @@ public:
int leftMargin(int max_width, pit_type pit, pos_type pos) const;
int leftMargin(int max_width, pit_type pit) const;
/// calculates the position of a completion popup
void completionPosAndDim(Cursor const & cur, int & x, int & y,
Dimension & dim) const;
private:
friend class BufferView;

View File

@ -35,6 +35,7 @@
#include "LaTeXFeatures.h"
#include "Lexer.h"
#include "LyXFunc.h"
#include "LyXRC.h"
#include "MetricsInfo.h"
#include "OutputParams.h"
#include "paragraph_funcs.h"
@ -4797,6 +4798,62 @@ bool InsetTabular::tablemode(Cursor & cur) const
}
bool InsetTabular::completionSupported(Cursor const & cur) const
{
Cursor const & bvCur = cur.bv().cursor();
if (&bvCur.inset() != this)
return false;
return cur.text()->completionSupported(cur);
}
bool InsetTabular::inlineCompletionSupported(Cursor const & cur) const
{
return completionSupported(cur);
}
bool InsetTabular::automaticInlineCompletion() const
{
return lyxrc.completion_inline_text;
}
bool InsetTabular::automaticPopupCompletion() const
{
return lyxrc.completion_popup_text;
}
CompletionList const * InsetTabular::createCompletionList(Cursor const & cur) const
{
return completionSupported(cur) ? cur.text()->createCompletionList(cur) : 0;
}
docstring InsetTabular::completionPrefix(Cursor const & cur) const
{
if (!completionSupported(cur))
return docstring();
return cur.text()->completionPrefix(cur);
}
bool InsetTabular::insertCompletion(Cursor & cur, docstring const & s, bool finished)
{
if (!completionSupported(cur))
return false;
return cur.text()->insertCompletion(cur, s, finished);
}
void InsetTabular::completionPosAndDim(Cursor const & cur, int & x, int & y,
Dimension & dim) const
{
TextMetrics const & tm = cur.bv().textMetrics(cur.text());
tm.completionPosAndDim(cur, x, y, dim);
}
string const InsetTabularMailer::name_("tabular");

View File

@ -55,6 +55,7 @@ class BufferView;
class Buffer;
class BufferParams;
class Paragraph;
class CompletionList;
class CursorSlice;
namespace frontend { class Painter; }
@ -750,6 +751,23 @@ public:
// Update the counters of this inset and of its contents
void updateLabels(ParIterator const &);
///
bool completionSupported(Cursor const &) const;
///
bool inlineCompletionSupported(Cursor const & cur) const;
///
bool automaticInlineCompletion() const;
///
bool automaticPopupCompletion() const;
///
CompletionList const * createCompletionList(Cursor const & cur) const;
///
docstring completionPrefix(Cursor const & cur) const;
///
bool insertCompletion(Cursor & cur, docstring const & s, bool finished);
///
void completionPosAndDim(Cursor const &, int & x, int & y, Dimension & dim) const;
//
// Public structures and variables
///

View File

@ -43,7 +43,6 @@
#include "TextClass.h"
#include "Text.h"
#include "TextMetrics.h"
#include "WordList.h"
#include "frontends/alert.h"
#include "frontends/Painter.h"
@ -66,36 +65,6 @@ namespace lyx {
using graphics::PreviewLoader;
class TextCompletionList : public CompletionList
{
public:
///
TextCompletionList(Cursor const & cur)
: buf_(cur.buffer()), pos_(0) {}
///
virtual ~TextCompletionList() {}
///
virtual bool sorted() const { return true; }
///
virtual size_t size() const
{
return theWordList().size();
}
///
virtual docstring const & data(size_t idx) const
{
return theWordList().word(idx);
}
private:
///
Buffer const & buf_;
///
size_t pos_;
};
/////////////////////////////////////////////////////////////////////
InsetText::InsetText(Buffer const & buf)
@ -504,10 +473,7 @@ bool InsetText::completionSupported(Cursor const & cur) const
Cursor const & bvCur = cur.bv().cursor();
if (&bvCur.inset() != this)
return false;
Paragraph const & par = cur.paragraph();
return cur.pos() > 0
&& (cur.pos() >= par.size() || !par.isLetter(cur.pos()))
&& par.isLetter(cur.pos() - 1);
return text_.completionSupported(cur);
}
@ -531,20 +497,7 @@ bool InsetText::automaticPopupCompletion() const
CompletionList const * InsetText::createCompletionList(Cursor const & cur) const
{
return completionSupported(cur) ? new TextCompletionList(cur) : 0;
}
docstring InsetText::previousWord(CursorSlice const & sl) const
{
CursorSlice from = sl;
CursorSlice to = sl;
text_.getWord(from, to, PREVIOUS_WORD);
if (sl == from || to == from)
return docstring();
Paragraph const & par = sl.paragraph();
return par.asString(from.pos(), to.pos(), false);
return completionSupported(cur) ? text_.createCompletionList(cur) : 0;
}
@ -552,50 +505,25 @@ docstring InsetText::completionPrefix(Cursor const & cur) const
{
if (!completionSupported(cur))
return docstring();
return previousWord(cur.top());
return text_.completionPrefix(cur);
}
bool InsetText::insertCompletion(Cursor & cur, docstring const & s,
bool /*finished*/)
bool finished)
{
if (!completionSupported(cur))
return false;
BOOST_ASSERT(cur.bv().cursor() == cur);
cur.insert(s);
cur.bv().cursor() = cur;
if (!(cur.disp_.update() & Update::Force))
cur.updateFlags(cur.disp_.update() | Update::SinglePar);
return true;
return text_.insertCompletion(cur, s, finished);
}
void InsetText::completionPosAndDim(Cursor const & cur, int & x, int & y,
Dimension & dim) const
{
Cursor const & bvcur = cur.bv().cursor();
// get word in front of cursor
docstring word = previousWord(bvcur.top());
DocIterator wordStart = bvcur;
wordStart.pos() -= word.length();
// get position on screen of the word start and end
Point lxy = cur.bv().getPos(wordStart, false);
Point rxy = cur.bv().getPos(bvcur, bvcur.boundary());
// calculate dimensions of the word
TextMetrics const & tm = cur.bv().textMetrics(&text_);
dim = tm.rowHeight(bvcur.pit(), wordStart.pos(), bvcur.pos(), false);
dim.wid = abs(rxy.x_ - lxy.x_);
// calculate position of word
y = lxy.y_;
x = min(rxy.x_, lxy.x_);
//lyxerr << "wid=" << dim.width() << " x=" << x << " y=" << y << " lxy.x_=" << lxy.x_ << " rxy.x_=" << rxy.x_ << " word=" << word << std::endl;
//lyxerr << " wordstart=" << wordStart << " bvcur=" << bvcur << " cur=" << cur << std::endl;
tm.completionPosAndDim(cur, x, y, dim);
}

View File

@ -22,6 +22,7 @@ namespace lyx {
class Buffer;
class BufferParams;
class BufferView;
class CompletionList;
class CursorSlice;
class Dimension;
class ParagraphList;
@ -174,8 +175,6 @@ private:
ColorCode frame_color_;
///
mutable pit_type old_pit;
///
docstring previousWord(CursorSlice const & sl) const;
public:
///