From cdbebdf0933d5acb9880b5fafa6584e4fcb7cfbb Mon Sep 17 00:00:00 2001 From: Stefan Schimanski Date: Sat, 15 Mar 2008 12:22:28 +0000 Subject: [PATCH] * 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 --- src/Text.cpp | 77 +++++++++++++++++++++++++++++++++- src/Text.h | 14 ++++++- src/TextMetrics.cpp | 27 ++++++++++++ src/TextMetrics.h | 4 ++ src/insets/InsetTabular.cpp | 57 +++++++++++++++++++++++++ src/insets/InsetTabular.h | 18 ++++++++ src/insets/InsetText.cpp | 84 +++---------------------------------- src/insets/InsetText.h | 3 +- 8 files changed, 202 insertions(+), 82 deletions(-) diff --git a/src/Text.cpp b/src/Text.cpp index bf80ba3dad..675ab8f768 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -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 diff --git a/src/Text.h b/src/Text.h index 027fd0e804..526fa2ee85 100644 --- a/src/Text.h +++ b/src/Text.h @@ -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_; diff --git a/src/TextMetrics.cpp b/src/TextMetrics.cpp index 5163bf8c2c..73e50a8f8e 100644 --- a/src/TextMetrics.cpp +++ b/src/TextMetrics.cpp @@ -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]; diff --git a/src/TextMetrics.h b/src/TextMetrics.h index d42759d842..1a0945d4ff 100644 --- a/src/TextMetrics.h +++ b/src/TextMetrics.h @@ -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; diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp index faa7d27c90..3dbded7f29 100644 --- a/src/insets/InsetTabular.cpp +++ b/src/insets/InsetTabular.cpp @@ -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"); diff --git a/src/insets/InsetTabular.h b/src/insets/InsetTabular.h index aaa593fca6..c5af279f35 100644 --- a/src/insets/InsetTabular.h +++ b/src/insets/InsetTabular.h @@ -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 /// diff --git a/src/insets/InsetText.cpp b/src/insets/InsetText.cpp index 0288f36fa4..1b0435b0a0 100644 --- a/src/insets/InsetText.cpp +++ b/src/insets/InsetText.cpp @@ -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); } diff --git a/src/insets/InsetText.h b/src/insets/InsetText.h index eb57b63cfa..5bb93e3e7c 100644 --- a/src/insets/InsetText.h +++ b/src/insets/InsetText.h @@ -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: ///