Hi all,

This patch fixes bug 4935.
http://bugzilla.lyx.org/show_bug.cgi?id=4935

It allows the user to scroll down below the document, until the last line is at the top..

It can be turned on in the Tools->preferences->editing dialog.

PS. This is also a work-around around the recursive repaint bug.

Objections ?

Vincent
diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index fbe30f1..b32640c 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -517,7 +517,10 @@ void BufferView::updateScrollbar()
 
        d->scrollbarParameters_.position = 0;
        // The reference is the top position so we remove one page.
-       d->scrollbarParameters_.max -= d->scrollbarParameters_.page_step;
+       if (lyxrc.scroll_below_document)
+               d->scrollbarParameters_.max -= minVisiblePart();
+       else
+               d->scrollbarParameters_.max -= 
d->scrollbarParameters_.page_step;
 }
 
 
@@ -1758,6 +1761,12 @@ void BufferView::lfunScroll(FuncRequest const & cmd)
 }
 
 
+int BufferView::minVisiblePart()
+{
+       return 2 * defaultRowHeight();
+}
+
+
 int BufferView::scroll(int y)
 {
        if (y > 0)
@@ -1772,10 +1781,12 @@ int BufferView::scrollDown(int offset)
 {
        Text * text = &buffer_.text();
        TextMetrics & tm = d->text_metrics_[text];
-       int ymax = height_ + offset;
+       int const ymax = height_ + offset;
        while (true) {
                pair<pit_type, ParagraphMetrics const *> last = tm.last();
                int bottom_pos = last.second->position() + 
last.second->descent();
+               if (lyxrc.scroll_below_document)
+                       bottom_pos += height_ - minVisiblePart();
                if (last.first + 1 == int(text->paragraphs().size())) {
                        if (bottom_pos <= height_)
                                return 0;
diff --git a/src/BufferView.h b/src/BufferView.h
index 9335a85..a69abfc 100644
--- a/src/BufferView.h
+++ b/src/BufferView.h
@@ -170,6 +170,9 @@ public:
        void scrollDocView(int pixels);
        /// Set the cursor position based on the scrollbar one.
        void setCursorFromScrollbar();
+       /// The minimal size of the document that is visible. Used
+       /// when it is allowed to scroll below the document.
+       int minVisiblePart();
 
        /// return the pixel width of the document view.
        int workWidth() const;
diff --git a/src/LyXFunc.cpp b/src/LyXFunc.cpp
index 5fc04c1..17eaf64 100644
--- a/src/LyXFunc.cpp
+++ b/src/LyXFunc.cpp
@@ -1941,6 +1941,7 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC 
const & lyxrc_new)
        case LyXRC::RC_CONVERTER_CACHE_MAXAGE:
        case LyXRC::RC_COPIER:
        case LyXRC::RC_CURSOR_FOLLOWS_SCROLLBAR:
+       case LyXRC::RC_SCROLL_BELOW_DOCUMENT:
        case LyXRC::RC_CUSTOM_EXPORT_COMMAND:
        case LyXRC::RC_CUSTOM_EXPORT_FORMAT:
        case LyXRC::RC_DATE_INSERT_FORMAT:
diff --git a/src/LyXRC.cpp b/src/LyXRC.cpp
index 19bbb15..e458a0b 100644
--- a/src/LyXRC.cpp
+++ b/src/LyXRC.cpp
@@ -157,6 +157,7 @@ LexerKeyword lyxrcTags[] = {
        { "\\screen_font_typewriter", LyXRC::RC_SCREEN_FONT_TYPEWRITER },
        { "\\screen_font_typewriter_foundry", 
LyXRC::RC_SCREEN_FONT_TYPEWRITER_FOUNDRY },
        { "\\screen_zoom", LyXRC::RC_SCREEN_ZOOM },
+       { "\\scroll_below_document", LyXRC::RC_SCROLL_BELOW_DOCUMENT },
        { "\\serverpipe", LyXRC::RC_SERVERPIPE },
        { "\\set_color", LyXRC::RC_SET_COLOR },
        { "\\show_banner", LyXRC::RC_SHOW_BANNER },
@@ -288,6 +289,7 @@ void LyXRC::setDefaults()
        tex_allows_spaces = false;
        date_insert_format = "%x";
        cursor_follows_scrollbar = false;
+       scroll_below_document = false;
        mac_like_word_movement = false;
        macro_edit_style = MACRO_EDIT_INLINE_BOX;
        dialogs_iconify_with_main = false;
@@ -821,6 +823,10 @@ int LyXRC::read(Lexer & lexrc)
                        lexrc >> cursor_follows_scrollbar;
                        break;
 
+               case RC_SCROLL_BELOW_DOCUMENT:
+                       lexrc >> scroll_below_document;
+                       break;
+
                case RC_MAC_LIKE_WORD_MOVEMENT:
                        lexrc >> mac_like_word_movement;
                        break;
@@ -1518,6 +1524,15 @@ void LyXRC::write(ostream & os, bool 
ignore_system_lyxrc, string const & name) c
                }
                if (tag != RC_LAST)
                        break;
+       case RC_SCROLL_BELOW_DOCUMENT:
+               if (ignore_system_lyxrc ||
+                   scroll_below_document
+                   != system_lyxrc.scroll_below_document) {
+                       os << "\\scroll_below_document "
+                          << convert<string>(scroll_below_document) << '\n';
+               }
+               if (tag != RC_LAST)
+                       break;
        case RC_MAC_LIKE_WORD_MOVEMENT:
                if (ignore_system_lyxrc ||
                    mac_like_word_movement
@@ -2497,6 +2512,10 @@ string const LyXRC::getDescription(LyXRCTags tag)
                str = _("LyX normally doesn't update the cursor position if you 
move the scrollbar. Set to true if you'd prefer to always have the cursor on 
screen.");
                break;
 
+       case RC_SCROLL_BELOW_DOCUMENT:
+               str = _("LyX normally doesn't allow the user to scroll further 
than the bottom of the document. Set to true if you prefer to scroll the bottom 
of the document to the top of the screen");
+               break;
+
        case RC_MAC_LIKE_WORD_MOVEMENT:
                str = _("Use the Mac OS X conventions for the word-level cursor 
movement");
                break;
diff --git a/src/LyXRC.h b/src/LyXRC.h
index 3e513e3..9cb0d66 100644
--- a/src/LyXRC.h
+++ b/src/LyXRC.h
@@ -140,6 +140,7 @@ public:
                RC_SCREEN_FONT_TYPEWRITER,
                RC_SCREEN_FONT_TYPEWRITER_FOUNDRY,
                RC_SCREEN_ZOOM,
+               RC_SCROLL_BELOW_DOCUMENT,
                RC_SERVERPIPE,
                RC_SET_COLOR,
                RC_SHOW_BANNER,
@@ -371,6 +372,8 @@ public:
        ///
        bool cursor_follows_scrollbar;
        ///
+       bool scroll_below_document;
+       ///
        enum MacroEditStyle {
                MACRO_EDIT_INLINE_BOX = 0,
                MACRO_EDIT_INLINE,
diff --git a/src/frontends/qt4/GuiPrefs.cpp b/src/frontends/qt4/GuiPrefs.cpp
index 4b0da98..6f6c99c 100644
--- a/src/frontends/qt4/GuiPrefs.cpp
+++ b/src/frontends/qt4/GuiPrefs.cpp
@@ -1930,6 +1930,8 @@ PrefEdit::PrefEdit(GuiPreferences * form)
 
        connect(cursorFollowsCB, SIGNAL(clicked()),
                this, SIGNAL(changed()));
+       connect(scrollBelowCB, SIGNAL(clicked()),
+               this, SIGNAL(changed()));
        connect(sortEnvironmentsCB, SIGNAL(clicked()),
                this, SIGNAL(changed()));
        connect(groupEnvironmentsCB, SIGNAL(clicked()),
@@ -1952,6 +1954,7 @@ PrefEdit::PrefEdit(GuiPreferences * form)
 void PrefEdit::apply(LyXRC & rc) const
 {
        rc.cursor_follows_scrollbar = cursorFollowsCB->isChecked();
+       rc.scroll_below_document = scrollBelowCB->isChecked();
        rc.sort_layouts = sortEnvironmentsCB->isChecked();
        rc.group_layouts = groupEnvironmentsCB->isChecked();
        switch (macroEditStyleCO->currentIndex()) {
@@ -1970,6 +1973,7 @@ void PrefEdit::apply(LyXRC & rc) const
 void PrefEdit::update(LyXRC const & rc)
 {
        cursorFollowsCB->setChecked(rc.cursor_follows_scrollbar);
+       scrollBelowCB->setChecked(rc.scroll_below_document);
        sortEnvironmentsCB->setChecked(rc.sort_layouts);
        groupEnvironmentsCB->setChecked(rc.group_layouts);
        macroEditStyleCO->setCurrentIndex(rc.macro_edit_style);
diff --git a/src/frontends/qt4/ui/PrefEditUi.ui 
b/src/frontends/qt4/ui/PrefEditUi.ui
index 48570af..bf858c3 100644
--- a/src/frontends/qt4/ui/PrefEditUi.ui
+++ b/src/frontends/qt4/ui/PrefEditUi.ui
@@ -53,6 +53,13 @@
        </widget>
       </item>
       <item>
+       <widget class="QCheckBox" name="scrollBelowCB" >
+        <property name="text" >
+         <string>Scroll &amp;below end of document</string>
+        </property>
+       </widget>
+      </item>
+      <item>
        <widget class="QCheckBox" name="sortEnvironmentsCB" >
         <property name="text" >
          <string>Sort &amp;environments alphabetically</string>
@@ -213,6 +220,7 @@
  <layoutdefault spacing="4" margin="9" />
  <tabstops>
   <tabstop>cursorFollowsCB</tabstop>
+  <tabstop>scrollBelowCB</tabstop>
   <tabstop>sortEnvironmentsCB</tabstop>
   <tabstop>groupEnvironmentsCB</tabstop>
   <tabstop>macroEditStyleCO</tabstop>

Reply via email to