Bug 71577 - horizontal scroll bar obscures the last line
Summary: horizontal scroll bar obscures the last line
Status: RESOLVED FIXED
Alias: None
Product: kate
Classification: Applications
Component: part (show other bugs)
Version: SVN
Platform: unspecified Linux
: NOR normal
Target Milestone: ---
Assignee: KWrite Developers
URL:
Keywords:
: 78135 100477 (view as bug list)
Depends on:
Blocks:
 
Reported: 2004-01-01 04:34 UTC by Jon Smirl
Modified: 2005-11-06 13:57 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jon Smirl 2004-01-01 04:34:14 UTC
Version:           CVS (using KDE Devel)

Using KATE. Set config so that you don't autowrap.
Now shrink the window until you get a horizonal scrollbar.
Jump to the end of file. 
Note last line of file is obscured behind the scrollbar.
Comment 1 Jon Smirl 2004-01-01 04:41:24 UTC
This is more complicated that it appears. I can't consistently reproduce it, but I can sometimes get it back. It seems to be a function of how long the lines are above the last line and when they trigger the scrollbar to appear. KATE does the right thing most of the time. 

Not a high priority problem.
Comment 2 Jon Smirl 2004-01-01 04:45:42 UTC
I think this always works:
make all the lines on the first page short enough to not have a scrollbar
make a long line near the end of the file but not the end
Ctrl-home to the beginning.
Ctrl-end to the end
Last line will be behind the horiz scrollbar that appeared in the jump
Comment 3 Jon Smirl 2004-01-01 04:49:30 UTC
The bug might be in the jump to end code. In this condition when I jump to the scroll position is 2 lines off from the bottom. There might be a +/- 1 that has the wrong sign. By doing down arrows I can make the last line appear.
Comment 4 Jens Dagerbo 2004-01-02 14:52:24 UTC
Do you see this bug in Kate/KWrite as well?
Comment 5 Jon Smirl 2004-01-02 17:13:42 UTC
I only have kdevelop built so I can't tell.

I think I know what the bug is.

Start at the top of the file with the scroll bar off.
Jump to the bottom. 
The calculation for how many lines are visible has already been done.
It controls where the top of the window is for the last pages.
But now when the window paints the scrollbar is enabled.
This messes up the top of window calculation.
It only impact the last window full and text and when jumping from an area without a scrollbar to one with.

I have made this same bug in code I have written. The problem is that the last page of the file needs to be special cased. The general code doesn't work right on the last page.
Comment 6 Jon Smirl 2004-01-02 20:04:35 UTC
this bug is probably in Kate part
Comment 7 Jens Dagerbo 2004-03-21 17:59:35 UTC
*** Bug 78135 has been marked as a duplicate of this bug. ***
Comment 8 Anders Lund 2005-03-01 22:26:32 UTC
*** Bug 100477 has been marked as a duplicate of this bug. ***
Comment 9 Christoph Cullmann 2005-11-06 13:57:45 UTC
SVN commit 478300 by cullmann:

BUG: 56301
BUG: 71577

don't hide the horizontal scrollbar, just disable it if not needed, will forward port to KDE 4 trunk
soon, this should solve many problems at once, no artefacts while scrolling, no wrong positioning, no
hiding of lines, no probs, world peace :)

On kwrite-devel@kde.org, please review for any big faults ;)

CCMAIL: kwrite-devel@kde.org



 M  +37 -100   kateviewinternal.cpp  
 M  +4 -3      kateviewinternal.h  


--- branches/KDE/3.5/kdelibs/kate/part/kateviewinternal.cpp #478299:478300
@@ -64,7 +64,6 @@
   , m_madeVisible(false)
   , m_shiftKeyPressed (false)
   , m_autoCenterLines (false)
-  , m_columnScrollDisplayed(false)
   , m_selChangedByUser (false)
   , selectAnchor (-1, -1)
   , m_selectionMode( Default )
@@ -106,15 +105,17 @@
   m_colLayout->addWidget(m_lineScroll);
   m_lineLayout->addLayout(m_colLayout);
 
-  if (!m_view->dynWordWrap())
-  {
-    // bottom corner box
-    m_dummy = new QWidget(m_view);
-    m_dummy->setFixedHeight(style().scrollBarExtent().width());
+  // bottom corner box
+  m_dummy = new QWidget(m_view);
+  m_dummy->setFixedHeight(style().scrollBarExtent().width());
+
+  if (m_view->dynWordWrap())
+    m_dummy->hide();
+  else
     m_dummy->show();
-    m_lineLayout->addWidget(m_dummy);
-  }
 
+  m_lineLayout->addWidget(m_dummy);
+
   // Hijack the line scroller's controls, so we can scroll nicely for word-wrap
   connect(m_lineScroll, SIGNAL(prevPage()), SLOT(scrollPrevPage()));
   connect(m_lineScroll, SIGNAL(nextPage()), SLOT(scrollNextPage()));
@@ -132,7 +133,13 @@
   // scrollbar for columns
   //
   m_columnScroll = new QScrollBar(QScrollBar::Horizontal,m_view);
-  m_columnScroll->hide();
+  
+  // hide the column scrollbar in the dynamic word wrap mode
+  if (m_view->dynWordWrap())
+    m_columnScroll->hide();
+  else
+    m_columnScroll->show();
+
   m_columnScroll->setTracking(true);
   m_startX = 0;
   m_oldStartX = 0;
@@ -226,20 +233,13 @@
 {
   if (m_view->dynWordWrap())
   {
-    delete m_dummy;
-    m_dummy = 0;
     m_columnScroll->hide();
-    m_columnScrollDisplayed = false;
-
+    m_dummy->hide ();
   }
   else
   {
-    // bottom corner box
-    m_dummy = new QWidget(m_view);
-    m_dummy->setFixedSize( style().scrollBarExtent().width(),
-                                  style().scrollBarExtent().width() );
-    m_dummy->show();
-    m_lineLayout->addWidget(m_dummy);
+    m_columnScroll->show();
+    m_dummy->show ();
   }
 
   tagAll();
@@ -251,20 +251,7 @@
   // Determine where the cursor should be to get the cursor on the same view line
   if (m_wrapChangeViewLine != -1) {
     KateTextCursor newStart = viewLineOffset(displayCursor, -m_wrapChangeViewLine);
-
-    // Account for the scrollbar in non-dyn-word-wrap mode
-    if (!m_view->dynWordWrap() && scrollbarVisible(newStart.line())) {
-      int lines = linesDisplayed() - 1;
-
-      if (m_view->height() != height())
-        lines++;
-
-      if (newStart.line() + lines == displayCursor.line())
-        newStart = viewLineOffset(displayCursor, 1 - m_wrapChangeViewLine);
-    }
-
     makeVisible(newStart, newStart.col(), true);
-
   } else {
     update();
   }
@@ -385,14 +372,6 @@
     m_cachedMaxStartPos = viewLineOffset(end, -((int)linesDisplayed() - 1));
   }
 
-  // If we're not dynamic word-wrapping, the horizontal scrollbar is hidden and will appear, increment the maxStart by 1
-  if (!m_view->dynWordWrap() && m_columnScroll->isHidden() && scrollbarVisible(m_cachedMaxStartPos.line()))
-  {
-    KateTextCursor end(m_doc->numVisLines() - 1, m_doc->lineLength(m_doc->getRealLine(m_doc->numVisLines() - 1)));
-
-    return viewLineOffset(end, -(int)linesDisplayed());
-  }
-
   m_usePlainLines = false;
 
   return m_cachedMaxStartPos;
@@ -715,34 +694,23 @@
       lineRanges[z].clear();
     }
 
-    if (scrollbarVisible(startLine()))
-    {
-      m_columnScroll->blockSignals(true);
+    m_columnScroll->blockSignals(true);
 
-      int max = maxLen(startLine()) - width();
-      if (max < 0)
-        max = 0;
+    int max = maxLen(startLine()) - width();
+    if (max < 0)
+      max = 0;
 
-      m_columnScroll->setRange(0, max);
+    // disable scrollbar
+    m_columnScroll->setDisabled (max == 0);
 
-      m_columnScroll->setValue(m_startX);
+    m_columnScroll->setRange(0, max);
 
-      // Approximate linescroll
-      m_columnScroll->setSteps(m_view->renderer()->config()->fontMetrics()->width('a'), width());
+    m_columnScroll->setValue(m_startX);
 
-      m_columnScroll->blockSignals(false);
+    // Approximate linescroll
+    m_columnScroll->setSteps(m_view->renderer()->config()->fontMetrics()->width('a'), width());
 
-      if (!m_columnScroll->isVisible ()  && !m_suppressColumnScrollBar)
-      {
-        m_columnScroll->show();
-        m_columnScrollDisplayed = true;
-      }
-    }
-    else if (!m_suppressColumnScrollBar && (startX() == 0))
-    {
-      m_columnScroll->hide();
-      m_columnScrollDisplayed = false;
-    }
+    m_columnScroll->blockSignals(false);
   }
 
   m_updatingView = false;
@@ -820,11 +788,6 @@
   else if ( c > viewLineOffset(endPos(), -m_minLinesVisible) )
   {
     KateTextCursor scroll = viewLineOffset(c, -((int)linesDisplayed() - m_minLinesVisible - 1));
-
-    if (!m_view->dynWordWrap() && m_columnScroll->isHidden())
-      if (scrollbarVisible(scroll.line()))
-        scroll.setLine(scroll.line() + 1);
-
     scrollPos(scroll, false, calledExternally);
   }
   else if ( c < viewLineOffset(startPos(), m_minLinesVisible) )
@@ -1859,19 +1822,6 @@
   int linesToScroll = -QMAX( ((int)linesDisplayed() - 1) - lineadj, 0 );
   m_preserveMaxX = true;
 
-  // don't scroll the full view in case the scrollbar appears
-  if (!m_view->dynWordWrap()) {
-    if (scrollbarVisible(startLine() + linesToScroll + viewLine)) {
-      if (!m_columnScrollDisplayed) {
-        linesToScroll++;
-      }
-    } else {
-      if (m_columnScrollDisplayed) {
-        linesToScroll--;
-      }
-    }
-  }
-
   if (!m_doc->pageUpDownMovesCursor () && !atTop) {
     int xPos = m_view->renderer()->textWidth(cursor) - currentRange().startX;
 
@@ -1921,19 +1871,6 @@
   int linesToScroll = QMAX( (linesDisplayed() - 1) - lineadj, 0 );
   m_preserveMaxX = true;
 
-  // don't scroll the full view in case the scrollbar appears
-  if (!m_view->dynWordWrap()) {
-    if (scrollbarVisible(startLine() + linesToScroll + viewLine - (linesDisplayed() - 1))) {
-      if (!m_columnScrollDisplayed) {
-        linesToScroll--;
-      }
-    } else {
-      if (m_columnScrollDisplayed) {
-        linesToScroll--;
-      }
-    }
-  }
-
   if (!m_doc->pageUpDownMovesCursor () && !atEnd) {
     int xPos = m_view->renderer()->textWidth(cursor) - currentRange().startX;
 
@@ -1962,11 +1899,6 @@
   }
 }
 
-bool KateViewInternal::scrollbarVisible(uint startLine)
-{
-  return maxLen(startLine) > width() - 8;
-}
-
 int KateViewInternal::maxLen(uint startLine)
 {
 //  Q_ASSERT(!m_view->dynWordWrap());
@@ -3108,7 +3040,7 @@
       leftBorder->update();
     }
 
-  } else if (!m_columnScroll->isHidden()) {
+  } else if (columnScrollingPossible()) {
     QWheelEvent copy = *e;
     QApplication::sendEvent(m_columnScroll, &copy);
 
@@ -3154,7 +3086,7 @@
   if (dy)
     scrollLines(startPos().line() + dy);
 
-  if (!m_view->dynWordWrap() && m_columnScrollDisplayed && dx)
+  if (columnScrollingPossible () && dx)
     scrollColumns(kMin (m_startX + dx, m_columnScroll->maxValue()));
 
   if (!dy && !dx)
@@ -3174,6 +3106,11 @@
   m_textHintTimer.stop ();
 }
 
+bool KateViewInternal::columnScrollingPossible ()
+{
+  return !m_view->dynWordWrap() && m_columnScroll->isEnabled() && (m_columnScroll->maxValue() > 0);
+}
+
 //BEGIN EDIT STUFF
 void KateViewInternal::editStart()
 {
--- branches/KDE/3.5/kdelibs/kate/part/kateviewinternal.h #478299:478300
@@ -268,7 +268,6 @@
     // column scrollbar + x position
     //
     QScrollBar *m_columnScroll;
-    bool m_columnScrollDisplayed;
     int m_startX;
     int m_oldStartX;
 
@@ -289,9 +288,11 @@
     //
     QMemArray<KateLineRange> lineRanges;
 
-    // Used to determine if the scrollbar will appear/disappear in non-wrapped mode
-    bool scrollbarVisible(uint startLine);
+    // maximal lenght of textlines visible from given startLine
     int maxLen(uint startLine);
+    
+    // are we allowed to scroll columns?
+    bool columnScrollingPossible ();
 
     // returns the maximum X value / col value a cursor can take for a specific line range
     int lineMaxCursorX(const KateLineRange& range);