]> git.lyx.org Git - lyx.git/blobdiff - src/insets/insettext.C
The speed patch: redraw only rows that have changed
[lyx.git] / src / insets / insettext.C
index 144aa4fb4578f668634fd5281beaa1143b791e0e..2b11b8ed8a715d4afbaa166344aa1a6f69a4e5cd 100644 (file)
 
 #include "frontends/Alert.h"
 #include "frontends/font_metrics.h"
-#include "frontends/LyXView.h"
 #include "frontends/Painter.h"
 
 #include "support/lyxalgo.h" // lyx::count
 
 #include <boost/bind.hpp>
+#include <boost/current_function.hpp>
 
 using lyx::pos_type;
 
@@ -70,6 +70,9 @@ using std::ostream;
 using std::vector;
 
 
+int InsetText::border_ = 2;
+
+
 InsetText::InsetText(BufferParams const & bp)
        : drawFrame_(false), frame_color_(LColor::insetframe), text_(0)
 {
@@ -82,7 +85,7 @@ InsetText::InsetText(BufferParams const & bp)
 
 
 InsetText::InsetText(InsetText const & in)
-       : UpdatableInset(in), text_(in.text_.bv_owner)
+       : InsetOld(in), text_(in.text_.bv_owner)
 {
        text_.autoBreakRows_ = in.text_.autoBreakRows_;
        drawFrame_ = in.drawFrame_;
@@ -92,7 +95,8 @@ InsetText::InsetText(InsetText const & in)
 }
 
 
-InsetText::InsetText() : text_(0)
+InsetText::InsetText()
+       : text_(0)
 {}
 
 
@@ -100,18 +104,20 @@ void InsetText::init()
 {
        for_each(paragraphs().begin(), paragraphs().end(),
                 bind(&Paragraph::setInsetOwner, _1, this));
-       old_pit = -1;
 }
 
 
-void InsetText::clear(bool just_mark_erased)
+void InsetText::markErased(bool erased)
+{
+       ParagraphList & pars = paragraphs();
+       for_each(pars.begin(), pars.end(),
+                bind(&Paragraph::markErased, _1, erased));
+}
+
+
+void InsetText::clear()
 {
        ParagraphList & pars = paragraphs();
-       if (just_mark_erased) {
-               for_each(pars.begin(), pars.end(),
-                        bind(&Paragraph::markErased, _1));
-               return;
-       }
 
        // This is a gross hack...
        LyXLayout_ptr old_layout = pars.begin()->layout();
@@ -138,7 +144,7 @@ void InsetText::write(Buffer const & buf, ostream & os) const
 
 void InsetText::read(Buffer const & buf, LyXLex & lex)
 {
-       clear(false);
+       clear();
 
 #ifdef WITH_WARNINGS
 #warning John, look here. Doesnt make much sense.
@@ -168,9 +174,14 @@ void InsetText::metrics(MetricsInfo & mi, Dimension & dim) const
 {
        //lyxerr << "InsetText::metrics: width: " << mi.base.textwidth << endl;
        setViewCache(mi.base.bv);
+       mi.base.textwidth -= 2 * border_;
        font_ = mi.base.font;
        text_.font_ = mi.base.font;
        text_.metrics(mi, dim);
+       dim.asc += border_;
+       dim.des += border_;
+       dim.wid += 2 * border_;
+       mi.base.textwidth += 2 * border_;
        dim_ = dim;
 }
 
@@ -181,79 +192,33 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const
        // update our idea of where we are
        setPosCache(pi, x, y);
 
-       BufferView * bv = pi.base.bv;
-       bv->hideCursor();
+       text_.draw(pi, x + border_, y);
 
-       x += scroll();
-       //y -= text_.ascent();
-
-
-       text_.draw(pi, x, y);
-
-       if (drawFrame_)
-               drawFrame(pi.pain, x, y);
+       if (drawFrame_) {
+               int const w = text_.width() + 2 * border_;
+               int const a = text_.ascent() + border_;
+               int const h = a + text_.descent() + border_;
+               int const ww = pi.base.bv->workWidth();
+               if (w > ww - 40)  {
+                       pi.pain.line(0, y - a, ww, y - a, frameColor());
+                       pi.pain.line(0, y - a + h, ww, y - a + h, frameColor());
+               } else {
+                       pi.pain.rectangle(x, y - a, w, h, frameColor());
+               }
+       }
 }
 
 
 void InsetText::drawSelection(PainterInfo & pi, int x, int y) const
 {
-       // repaint the background if needed
-       if (backgroundColor() != LColor::background)
-               clearInset(pi.pain, x, y);
-       text_.drawSelection(pi, x, y);
-}
-
-
-void InsetText::drawFrame(Painter & pain, int x, int y) const
-{
-       int const w = max(1, text_.width());
-       int const h = text_.height();
-       int const a = text_.ascent();
-       pain.rectangle(x, y - a, w, h, frameColor());
-}
-
-
-void InsetText::clearInset(Painter & pain, int x, int y) const
-{
-       int const w = text_.width();
-       int const h = text_.height();
-       int const a = text_.ascent();
-       pain.fillRectangle(x, y - a, w, h, backgroundColor());
-}
-
-
-void InsetText::updateLocal(LCursor & cur)
-{
-       if (!text_.autoBreakRows_ && paragraphs().size() > 1) {
-               // collapse paragraphs
-               while (paragraphs().size() > 1) {
-                       ParagraphList::iterator const first = paragraphs().begin();
-                       ParagraphList::iterator second = first;
-                       ++second;
-                       size_t const first_par_size = first->size();
-
-                       if (!first->empty() &&
-                                       !second->empty() &&
-                                       !first->isSeparator(first_par_size - 1)) {
-                               first->insertChar(first_par_size, ' ');
-                       }
-
-                       cur.clearSelection();
-                       mergeParagraph(cur.buffer().params(), paragraphs(), 0);
-               }
-       }
-
-       if (!cur.selection())
-               cur.resetAnchor();
-
-       LyXView * lv = cur.bv().owner();
-       lv->view_state_changed();
-       lv->updateMenubar();
-       lv->updateToolbars();
-       if (old_pit != cur.pit()) {
-               lv->setLayout(text_.getPar(cur.pit()).layout()->name());
-               old_pit = cur.pit();
+       if (backgroundColor() != LColor::background) {
+               // repaint the background if needed
+               int const w = text_.width() + 2 * border_;
+               int const a = text_.ascent() + border_;
+               int const h = a + text_.descent() + border_;
+               pi.pain.fillRectangle(x, y - a, w, h, backgroundColor());
        }
+       text_.drawSelection(pi, x, y);
 }
 
 
@@ -266,37 +231,27 @@ string const InsetText::editMessage() const
 void InsetText::edit(LCursor & cur, bool left)
 {
        //lyxerr << "InsetText: edit left/right" << endl;
-       old_pit = -1;
        setViewCache(&cur.bv());
        int const pit = left ? 0 : paragraphs().size() - 1;
        int const pos = left ? 0 : paragraphs().back().size();
        text_.setCursor(cur.top(), pit, pos);
        cur.clearSelection();
        finishUndo();
-#ifdef WITH_WARNINGS
-#warning can someone check if/when this is needed?
-#endif
-//Andre?
-//     updateLocal(cur);
 }
 
 
-InsetBase * InsetText::editXY(LCursor & cur, int x, int y) const
+InsetBase * InsetText::editXY(LCursor & cur, int x, int y)
 {
-       old_pit = -1;
        return text_.editXY(cur, x, y);
-       //sanitizeEmptyText(cur.bv());
-       //updateLocal(cur);
 }
 
 
 void InsetText::doDispatch(LCursor & cur, FuncRequest & cmd)
 {
-       //lyxerr << "InsetText::doDispatch: " << cmd.action << " " << endl;
+       lyxerr[Debug::DEBUG] << BOOST_CURRENT_FUNCTION
+    << " [ cmd.action = " << cmd.action << ']' << endl;
        setViewCache(&cur.bv());
-
        text_.dispatch(cur, cmd);
-
 }
 
 
@@ -322,11 +277,12 @@ int InsetText::plaintext(Buffer const & buf, ostream & os,
        ParagraphList::const_iterator beg = paragraphs().begin();
        ParagraphList::const_iterator end = paragraphs().end();
        ParagraphList::const_iterator it = beg;
+       bool ref_printed = false;
        for (; it != end; ++it)
-               asciiParagraph(buf, *it, os, runparams, it == beg);
+               asciiParagraph(buf, *it, os, runparams, ref_printed);
 
        // FIXME: Give the total numbers of lines
-       return 0;
+       return 1;
 }
 
 
@@ -353,10 +309,11 @@ void InsetText::validate(LaTeXFeatures & features) const
 }
 
 
-void InsetText::getCursorPos(CursorSlice const & sl, int & x, int & y) const
+void InsetText::cursorPos
+       (CursorSlice const & sl, bool boundary, int & x, int & y) const
 {
-       x = text_.cursorX(sl);
-       y = text_.cursorY(sl);
+       x = text_.cursorX(sl, boundary) + border_;
+       y = text_.cursorY(sl, boundary);
 }
 
 
@@ -385,19 +342,17 @@ void InsetText::markNew(bool track_changes)
        ParagraphList::iterator pit = paragraphs().begin();
        ParagraphList::iterator end = paragraphs().end();
        for (; pit != end; ++pit) {
-               if (track_changes) {
+               if (track_changes)
                        pit->trackChanges();
-               } else {
-                       // no-op when not tracking
+               else // no-op when not tracking
                        pit->cleanChanges();
-               }
        }
 }
 
 
 void InsetText::setText(string const & data, LyXFont const & font)
 {
-       clear(false);
+       clear();
        Paragraph & first = paragraphs().front();
        for (unsigned int i = 0; i < data.length(); ++i)
                first.insertChar(i, data[i], font);
@@ -406,11 +361,20 @@ void InsetText::setText(string const & data, LyXFont const & font)
 
 void InsetText::setAutoBreakRows(bool flag)
 {
-       if (flag != text_.autoBreakRows_) {
-               text_.autoBreakRows_ = flag;
-               if (!flag)
-                       removeNewlines();
-       }
+       if (flag == text_.autoBreakRows_)
+               return;
+
+       text_.autoBreakRows_ = flag;
+       if (flag)
+               return;
+
+       // remove previously existing newlines
+       ParagraphList::iterator it = paragraphs().begin();
+       ParagraphList::iterator end = paragraphs().end();
+       for (; it != end; ++it)
+               for (int i = 0; i < it->size(); ++i)
+                       if (it->isNewline(i))
+                               it->erase(i);
 }
 
 
@@ -442,23 +406,6 @@ void InsetText::setViewCache(BufferView const * bv) const
 }
 
 
-void InsetText::removeNewlines()
-{
-       ParagraphList::iterator it = paragraphs().begin();
-       ParagraphList::iterator end = paragraphs().end();
-       for (; it != end; ++it)
-               for (int i = 0; i < it->size(); ++i)
-                       if (it->isNewline(i))
-                               it->erase(i);
-}
-
-
-LyXText * InsetText::getText(int i) const
-{
-       return (i == 0) ? const_cast<LyXText*>(&text_) : 0;
-}
-
-
 void InsetText::appendParagraphs(Buffer * buffer, ParagraphList & plist)
 {
 #ifdef WITH_WARNINGS
@@ -492,6 +439,15 @@ void InsetText::addPreview(PreviewLoader & loader) const
 }
 
 
+//FIXME: instead of this hack, which only works by chance,
+// cells should have their own insetcell type, which returns CELL_CODE!
+bool InsetText::neverIndent() const
+{
+       // this is only true for tabular cells
+       return !text_.isMainText() && lyxCode() == TEXT_CODE;
+}
+
+
 ParagraphList const & InsetText::paragraphs() const
 {
        return text_.paragraphs();