]> git.lyx.org Git - lyx.git/blobdiff - src/BufferView.cpp
* There are cases where updateLabels is not called because no
[lyx.git] / src / BufferView.cpp
index 4884fe9993402c2b36c52e4210acb62490d8a45f..3518d0b7e8c5c18a9186ccc8d51790124849d287 100644 (file)
@@ -508,22 +508,44 @@ void BufferView::scrollDocView(int value)
                return;
        }
 
-       int par_pos = 0;
-       for (size_t i = 0; i != d->par_height_.size(); ++i) {
+       // cut off at the top
+       if (value <= d->scrollbarParameters_.min) {
+               DocIterator dit = doc_iterator_begin(buffer_.inset());
+               showCursor(dit);
+               LYXERR(Debug::SCROLLING, "scroll to top");
+               return;
+       }
+
+       // cut off at the bottom
+       if (value >= d->scrollbarParameters_.max) {
+               DocIterator dit = doc_iterator_end(buffer_.inset());
+               dit.backwardPos();
+               showCursor(dit);
+               LYXERR(Debug::SCROLLING, "scroll to bottom");
+               return;
+       }
+
+       // find paragraph at target position
+       int par_pos = d->scrollbarParameters_.min;
+       pit_type i = 0;
+       for (; i != d->par_height_.size(); ++i) {
                par_pos += d->par_height_[i];
-               if (par_pos >= value) {
-                       d->anchor_pit_ = pit_type(i);
+               if (par_pos >= value)
                        break;
-               }
        }
 
-       LYXERR(Debug::SCROLLING, "value = " << value
-               << "\tanchor_ref_ = " << d->anchor_pit_
-               << "\tpar_pos = " << par_pos);
+       if (par_pos < value) {
+               // It seems we didn't find the correct pit so stay on the safe side and
+               // scroll to bottom.
+               LYXERR0("scrolling position not found!");
+               scrollDocView(d->scrollbarParameters_.max);
+               return;
+       }
 
-       d->anchor_ypos_ = par_pos - value;
-       updateMetrics();
-       buffer_.changed();
+       DocIterator dit = doc_iterator_begin(buffer_.inset());
+       dit.pit() = i;
+       LYXERR(Debug::SCROLLING, "value = " << value << " -> scroll to pit " << i);
+       showCursor(dit);
 }
 
 
@@ -690,6 +712,12 @@ int BufferView::workWidth() const
 
 
 void BufferView::showCursor()
+{
+       showCursor(d->cursor_);
+}
+
+
+void BufferView::showCursor(DocIterator const & dit)
 {
        // We are not properly started yet, delay until resizing is
        // done.
@@ -698,11 +726,11 @@ void BufferView::showCursor()
 
        LYXERR(Debug::SCROLLING, "recentering!");
 
-       CursorSlice & bot = d->cursor_.bottom();
+       CursorSlice const & bot = dit.bottom();
        TextMetrics & tm = d->text_metrics_[bot.text()];
 
        pos_type const max_pit = pos_type(bot.text()->paragraphs().size() - 1);
-       int bot_pit = d->cursor_.bottom().pit();
+       int bot_pit = bot.pit();
        if (bot_pit > max_pit) {
                // FIXME: Why does this happen?
                LYXERR0("bottom pit is greater that max pit: "
@@ -717,9 +745,13 @@ void BufferView::showCursor()
 
        if (tm.has(bot_pit)) {
                ParagraphMetrics const & pm = tm.parMetrics(bot_pit);
-               int offset = coordOffset(d->cursor_, d->cursor_.boundary()).y_;
+               BOOST_ASSERT(!pm.rows().empty());
+               // FIXME: smooth scrolling doesn't work in mathed.
+               CursorSlice const & cs = dit.innerTextSlice();
+               int offset = coordOffset(dit, dit.boundary()).y_;
                int ypos = pm.position() + offset;
-               Dimension const & row_dim = d->cursor_.textRow().dimension();
+               Dimension const & row_dim =
+                       pm.getRow(cs.pos(), dit.boundary()).dimension();
                if (ypos - row_dim.ascent() < 0)
                        scrollUp(- ypos + row_dim.ascent());
                else if (ypos + row_dim.descent() > height_)
@@ -730,10 +762,12 @@ void BufferView::showCursor()
 
        tm.redoParagraph(bot_pit);
        ParagraphMetrics const & pm = tm.parMetrics(bot_pit);
-       int offset = coordOffset(d->cursor_, d->cursor_.boundary()).y_;
+       int offset = coordOffset(dit, dit.boundary()).y_;
 
        d->anchor_pit_ = bot_pit;
-       Dimension const & row_dim = d->cursor_.textRow().dimension();
+       CursorSlice const & cs = dit.innerTextSlice();
+       Dimension const & row_dim =
+               pm.getRow(cs.pos(), dit.boundary()).dimension();
 
        if (d->anchor_pit_ == 0)
                d->anchor_ypos_ = offset + pm.ascent();
@@ -1143,23 +1177,26 @@ bool BufferView::dispatch(FuncRequest const & cmd)
                int const chars_blanks = countChars(from, to, true);
                docstring message;
                if (cur.selection())
-                       message = _("Statistics for the selection:\n");
+                       message = _("Statistics for the selection:");
                else
-                       message = _("Statistics for the document:\n");
+                       message = _("Statistics for the document:");
+               message += "\n\n";
                if (words != 1)
-                       message += bformat(_("\n%1$d words"), words);
+                       message += bformat(_("%1$d words"), words);
                else
-                       message += _("\nOne word");
+                       message += _("One word");
+               message += "\n";
                if (chars_blanks != 1)
-                       message += bformat(_("\n%1$d characters (including blanks)"),
+                       message += bformat(_("%1$d characters (including blanks)"),
                                          chars_blanks);
                else
-                       message += _("\nOne character (including blanks)");
+                       message += _("One character (including blanks)");
+               message += "\n";
                if (chars != 1)
-                       message += bformat(_("\n%1$d characters (excluding blanks)"),
+                       message += bformat(_("%1$d characters (excluding blanks)"),
                                          chars);
                else
-                       message += _("\nOne character (excluding blanks)");
+                       message += _("One character (excluding blanks)");
 
                Alert::information(_("Statistics"), message);
        }
@@ -1299,6 +1336,8 @@ void BufferView::clearSelection()
 
 void BufferView::resize(int width, int height)
 {
+       bool initialResize = (height_ == 0);
+       
        // Update from work area
        width_ = width;
        height_ = height;
@@ -1307,6 +1346,13 @@ void BufferView::resize(int width, int height)
        d->par_height_.clear();
 
        updateMetrics();
+
+       // view got his initial size, make sure that
+       // the cursor has a proper position
+       if (initialResize) {
+               updateScrollbar();
+               showCursor();
+       }
 }
 
 
@@ -1731,6 +1777,19 @@ void BufferView::updateMetrics()
        // Rebreak anchor paragraph.
        tm.redoParagraph(d->anchor_pit_);
        ParagraphMetrics & anchor_pm = tm.par_metrics_[d->anchor_pit_];
+       
+       // position anchor
+       if (d->anchor_pit_ == 0) {
+               int scrollRange = d->scrollbarParameters_.max - d->scrollbarParameters_.min;
+               
+               // Complete buffer visible? Then it's easy.
+               if (scrollRange == 0)
+                       d->anchor_ypos_ = anchor_pm.ascent();
+       
+               // FIXME: Some clever handling needed to show
+               // the _first_ paragraph up to the top if the cursor is
+               // in the first line.
+       }               
        anchor_pm.setPosition(d->anchor_ypos_);
 
        LYXERR(Debug::PAINTING, "metrics: "