• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdesdk API Reference
  • KDE Home
  • Contact Us
 

okteta

  • sources
  • kde-4.12
  • kdesdk
  • okteta
  • gui
  • libcolumnsview
columnsview.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the Okteta Gui library, made within the KDE community.
3 
4  Copyright 2003,2007,2008 Friedrich W. H. Kossebau <kossebau@kde.org>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (at your option) version 3, or any
10  later version accepted by the membership of KDE e.V. (or its
11  successor approved by the membership of KDE e.V.), which shall
12  act as a proxy defined in Section 6 of version 3 of the license.
13 
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public
20  License along with this library. If not, see <http://www.gnu.org/licenses/>.
21 */
22 
23 #include "columnsview.h"
24 
25 // lib
26 #include "abstractcolumnrenderer.h"
27 // Qt
28 #include <QtCore/QListIterator>
29 #include <QtGui/QPaintEvent>
30 #include <QtGui/QPainter>
31 #include <QtGui/QStyle>
32 #include <QtGui/QScrollBar>
33 
34 
35 namespace Okteta
36 {
37 
38 static const int DefaultSingleStep = 20;
39 
40 class ColumnsViewPrivate
41 {
42  public:
43  ColumnsViewPrivate( /*bool R,*/ );
44  ~ColumnsViewPrivate();
45  public:
46  void updateWidths();
47  public: // calculated
49  QList<AbstractColumnRenderer*> Columns;
51  LineSize NoOfLines;
53  PixelY LineHeight;
55  PixelX ColumnsWidth;
56 
57  public:
58 // bool Reversed;
59 };
60 
61 
62 ColumnsViewPrivate::ColumnsViewPrivate( /*bool R,*/)
63  : NoOfLines( 0 ),
64  LineHeight( 0 ),
65  ColumnsWidth( 0 )
66 // Reversed( R )
67 {}
68 
69 void ColumnsViewPrivate::updateWidths()
70 {
71  ColumnsWidth = 0;
72  QListIterator<AbstractColumnRenderer*> it( Columns );
73  while( it.hasNext() )
74  {
75  AbstractColumnRenderer *column = it.next();
76  column->setX( ColumnsWidth );
77  ColumnsWidth += column->visibleWidth();
78  }
79 }
80 
81 ColumnsViewPrivate::~ColumnsViewPrivate()
82 {
83  while( !Columns.isEmpty() )
84  delete Columns.takeFirst();
85 }
86 
87 ColumnsView::ColumnsView( /*bool R,*/ QWidget *parent )
88  : QAbstractScrollArea( parent ),
89  d( new ColumnsViewPrivate() )
90 {
91  viewport()->setAttribute( Qt::WA_StaticContents );
92  viewport()->setBackgroundRole ( QPalette::Base );
93  horizontalScrollBar()->setSingleStep( DefaultSingleStep );
94  verticalScrollBar()->setSingleStep( DefaultSingleStep );
95 
96  viewport()->setFocusProxy( this );
97  viewport()->setFocusPolicy( Qt::WheelFocus );
98 }
99 
100 
101 LineSize ColumnsView::noOfLines() const { return d->NoOfLines; }
102 PixelY ColumnsView::lineHeight() const { return d->LineHeight; }
103 Line ColumnsView::lineAt( PixelY y ) const { return (d->LineHeight!=0) ? y / d->LineHeight : 0; }
104 LineRange ColumnsView::visibleLines() const
105 {
106  const PixelYRange ySpan = PixelYRange::fromWidth( yOffset(), visibleHeight() );
107  return LineRange( lineAt(ySpan.start()), lineAt(ySpan.end()) );
108 }
109 LineRange ColumnsView::visibleLines( const PixelYRange& yPixels ) const
110 {
111  return LineRange( lineAt(yPixels.start()), lineAt(yPixels.end()) );
112 }
113 
114 PixelX ColumnsView::visibleWidth() const { return viewport()->width(); }
115 PixelY ColumnsView::visibleHeight() const { return viewport()->height(); }
116 
117 PixelY ColumnsView::columnsHeight() const { return d->NoOfLines*d->LineHeight; }
118 PixelX ColumnsView::columnsWidth() const { return d->ColumnsWidth; }
119 
120 QPoint ColumnsView::viewportToColumns( const QPoint& point ) const
121 {
122  return QPoint(xOffset(),yOffset()) + point;
123 }
124 
125 
126 PixelX ColumnsView::xOffset() const { return horizontalScrollBar()->value(); }
127 PixelY ColumnsView::yOffset() const { return verticalScrollBar()->value(); }
128 PixelY ColumnsView::yOffsetOfLine( Line lineIndex ) const
129 {
130  return lineIndex * d->LineHeight - yOffset();
131 }
132 
133 
134 void ColumnsView::setColumnsPos( PixelX x, PixelY y )
135 {
136  horizontalScrollBar()->setValue( x );
137  verticalScrollBar()->setValue( y );
138 }
139 
140 
141 void ColumnsView::setNoOfLines( LineSize newNoOfLines )
142 {
143  if( d->NoOfLines == newNoOfLines )
144  return;
145 
146  d->NoOfLines = newNoOfLines;
147 
148  updateScrollBars();
149 }
150 
151 
152 void ColumnsView::setLineHeight( PixelY newLineHeight )
153 {
154  if( newLineHeight == d->LineHeight )
155  return;
156 
157  d->LineHeight = newLineHeight;
158 
159  QListIterator<AbstractColumnRenderer*> it( d->Columns );
160  while( it.hasNext() )
161  it.next()->setLineHeight( d->LineHeight );
162 
163  verticalScrollBar()->setSingleStep( d->LineHeight );
164  updateScrollBars();
165 }
166 
167 
168 void ColumnsView::updateWidths()
169 {
170  d->updateWidths();
171 
172  updateScrollBars();
173 }
174 
175 
176 void ColumnsView::updateScrollBars()
177 {
178  QSize viewSize = maximumViewportSize();
179 
180  const bool needsVerticalBar = ( columnsHeight() > viewSize.height() );
181  const bool needsHorizontalBar = ( columnsWidth() > viewSize.width() );
182  const int scrollBarWidth = style()->pixelMetric( QStyle::PM_ScrollBarExtent );
183 
184  if( needsVerticalBar )
185  viewSize.rwidth() -= scrollBarWidth;
186  if( needsHorizontalBar )
187  viewSize.rheight() -= scrollBarWidth;
188 
189  verticalScrollBar()->setRange( 0, columnsHeight()-viewSize.height() );
190  verticalScrollBar()->setPageStep( viewSize.height() );
191  horizontalScrollBar()->setRange( 0, columnsWidth()-viewSize.width() );
192  horizontalScrollBar()->setPageStep( viewSize.width() );
193 }
194 
195 
196 void ColumnsView::updateColumn( AbstractColumnRenderer& columnRenderer )
197 {
198  if( columnRenderer.isVisible() )
199  viewport()->update( columnRenderer.x()-xOffset(), 0, columnRenderer.width(), visibleHeight() );
200 }
201 
202 void ColumnsView::updateColumn( AbstractColumnRenderer& columnRenderer, const LineRange& lines )
203 {
204  if( columnRenderer.isVisible() ) // TODO: catch hidden range && columnRenderer.overlaps(Xs) )
205  {
206  LineRange linesToUpdate = visibleLines();
207  linesToUpdate.restrictTo( lines );
208  if( linesToUpdate.isValid() )
209  {
210  const PixelX x = columnRenderer.x() - xOffset();
211  const PixelY y = yOffsetOfLine( linesToUpdate.start() );
212  const int width = columnRenderer.width();
213  const int height = d->LineHeight * linesToUpdate.width();
214  viewport()->update( x, y, width, height );
215  }
216  }
217 }
218 
219 
220 LineSize ColumnsView::noOfLinesPerPage() const
221 {
222  if( d->LineHeight < 1 )
223  return 1;
224 
225  LineSize result = (visibleHeight()-1) / d->LineHeight; // -1 ensures to get always the last visible line
226 
227  if( result < 1 )
228  // ensure to move down at least one line
229  result = 1;
230 
231  return result;
232 }
233 
234 
235 void ColumnsView::addColumn( AbstractColumnRenderer* columnRenderer )
236 {
237 // if( Reversed )
238 // Columns.prepend( C );
239 // else
240  d->Columns.append( columnRenderer );
241 
242  updateWidths();
243 }
244 
245 
246 void ColumnsView::removeColumn( AbstractColumnRenderer* columnRenderer )
247 {
248  const int columnRendererIndex = d->Columns.indexOf( columnRenderer );
249  if( columnRendererIndex != -1 )
250  d->Columns.removeAt( columnRendererIndex );
251 
252  delete columnRenderer;
253 
254  updateWidths();
255 }
256 
257 
258 void ColumnsView::scrollContentsBy( int dx, int dy )
259 {
260  viewport()->scroll( dx, dy );
261 }
262 
263 bool ColumnsView::event( QEvent* event )
264 {
265  if( event->type() == QEvent::StyleChange || event->type() == QEvent::LayoutRequest )
266  updateScrollBars();
267 
268  return QAbstractScrollArea::event( event );
269 }
270 
271 
272 void ColumnsView::resizeEvent( QResizeEvent* event )
273 {
274  updateScrollBars();
275 
276  QAbstractScrollArea::resizeEvent( event );
277 }
278 
279 void ColumnsView::paintEvent( QPaintEvent* paintEvent )
280 {
281  QAbstractScrollArea::paintEvent( paintEvent );
282 
283  const PixelX x = xOffset();
284  const PixelY y = yOffset();
285 
286  QRect dirtyRect = paintEvent->rect();
287  dirtyRect.translate( x, y );
288 
289  QPainter painter( viewport() );
290  painter.translate( -x, -y );
291 
292  renderColumns( &painter, dirtyRect.x(),dirtyRect.y(), dirtyRect.width(), dirtyRect.height() );
293 }
294 
295 
296 void ColumnsView::renderColumns( QPainter* painter, int cx, int cy, int cw, int ch )
297 {
298  PixelXRange dirtyXs = PixelXRange::fromWidth( cx, cw );
299 
300  // content to be shown?
301  if( dirtyXs.startsBefore(d->ColumnsWidth) )
302  {
303  PixelYRange dirtyYs = PixelYRange::fromWidth( cy, ch );
304 
305  // collect affected columns
306  QList<AbstractColumnRenderer*> dirtyColumns;
307  QListIterator<AbstractColumnRenderer*> it( d->Columns );
308  while( it.hasNext() )
309  {
310  AbstractColumnRenderer *column = it.next();
311  if( column->isVisible() && column->overlaps(dirtyXs) )
312  dirtyColumns.append( column );
313  }
314 
315  // any lines of any columns to be drawn?
316  if( d->NoOfLines > 0 )
317  {
318  // calculate affected lines
319  LineRange dirtyLines = visibleLines( dirtyYs );
320  dirtyLines.restrictEndTo( d->NoOfLines - 1 );
321 
322  if( dirtyLines.isValid() )
323  {
324  // paint full columns
325  QListIterator<AbstractColumnRenderer*> fit( d->Columns ); // TODO: reuse later, see some lines below
326  while( fit.hasNext() )
327  fit.next()->renderColumn( painter, dirtyXs, dirtyYs );
328 
329  PixelY cy = dirtyLines.start() * d->LineHeight;
330  //kDebug()<<"Dirty lines: "<<dirtyLines.start()<<"-"<<dirtyLines.end();
331  // starting painting with the first line
332  Line line = dirtyLines.start();
333  QListIterator<AbstractColumnRenderer*> it( dirtyColumns );
334  AbstractColumnRenderer *column = it.next();
335  painter->translate( column->x(), cy );
336 
337  while( true )
338  {
339  column->renderFirstLine( painter, dirtyXs, line );
340  if( !it.hasNext() )
341  break;
342  painter->translate( column->width(), 0 );
343  column = it.next();
344  }
345  painter->translate( -column->x(), 0 );
346 
347  // Go through the other lines
348  while( true )
349  {
350  ++line;
351 
352  if( line > dirtyLines.end() )
353  break;
354 
355  QListIterator<AbstractColumnRenderer*> it( dirtyColumns );
356  column = it.next();
357  painter->translate( column->x(), d->LineHeight );
358 
359  while( true )
360  {
361  column->renderNextLine( painter );
362  if( !it.hasNext() )
363  break;
364  painter->translate( column->width(), 0 );
365  column = it.next();
366  }
367  painter->translate( -column->x(), 0 );
368  }
369  cy = dirtyLines.end() * d->LineHeight;
370 
371  painter->translate( 0, -cy );
372  }
373  }
374 
375  // draw empty columns?
376  dirtyYs.setStart( columnsHeight() );
377  if( dirtyYs.isValid() )
378  {
379  QListIterator<AbstractColumnRenderer*> it( dirtyColumns );
380  while( it.hasNext() )
381  it.next()->renderEmptyColumn( painter, dirtyXs, dirtyYs );
382  }
383  }
384 
385  // painter empty rects
386  dirtyXs.setStart( d->ColumnsWidth );
387  if( dirtyXs.isValid() )
388  renderEmptyArea( painter, dirtyXs.start(), cy, dirtyXs.width(), ch );
389 }
390 
391 
392 void ColumnsView::renderEmptyArea( QPainter* painter, int cx ,int cy, int cw, int ch)
393 {
394  painter->fillRect( cx,cy, cw,ch, viewport()->palette().brush(QPalette::Base) ); // TODO: use stylist here, too
395 }
396 
397 
398 ColumnsView::~ColumnsView()
399 {
400  delete d;
401 }
402 
403 }
Okteta::ColumnsView::noOfLines
LineSize noOfLines() const
returns the number of all lines
Definition: columnsview.cpp:101
Okteta::ColumnsView::updateWidths
void updateWidths()
recalculates the positions of the columns and the total width
Definition: columnsview.cpp:168
Okteta::ColumnsView::visibleHeight
PixelY visibleHeight() const
Definition: columnsview.cpp:115
Okteta::ColumnsView::viewportToColumns
QPoint viewportToColumns(const QPoint &point) const
translates the point to coordinates in the columns
Definition: columnsview.cpp:120
columnsview.h
QWidget
KDE::NumberRange< Line, LineSize >
Okteta::ColumnsView::paintEvent
virtual void paintEvent(QPaintEvent *paintEvent)
Definition: columnsview.cpp:279
KDE::Range::start
T start() const
Definition: range.h:86
Okteta::ColumnsView::event
virtual bool event(QEvent *event)
Definition: columnsview.cpp:263
QAbstractScrollArea
KDE::Range::restrictTo
void restrictTo(const Range &Limit)
restricts the range to Limit.
Definition: range.h:64
Okteta::ColumnsView::lineAt
Line lineAt(PixelY y) const
gives the index of the line that would include y in pixel coord.
Definition: columnsview.cpp:103
Okteta::ColumnsView::updateColumn
void updateColumn(AbstractColumnRenderer &columnRenderer)
calls updateContent for the Column
Definition: columnsview.cpp:196
Okteta::Line
qint32 Line
Definition: line.h:33
KDE::NumberRange::width
S width() const
Definition: numberrange.h:141
Okteta::ColumnsView::scrollContentsBy
virtual void scrollContentsBy(int dx, int dy)
Definition: columnsview.cpp:258
Okteta::ColumnsView::setColumnsPos
void setColumnsPos(PixelX x, PixelY y)
Definition: columnsview.cpp:134
Okteta::PixelX
int PixelX
Definition: kadds.h:34
KDE::Range::restrictEndTo
void restrictEndTo(T Limit)
restricts the end to Limit.
Definition: range.h:69
abstractcolumnrenderer.h
Okteta::ColumnsView::columnsHeight
PixelY columnsHeight() const
returns the height of all lines together
Definition: columnsview.cpp:117
Okteta::ColumnsView::addColumn
void addColumn(AbstractColumnRenderer *columnRenderer)
Definition: columnsview.cpp:235
Okteta::ColumnsView::setLineHeight
virtual void setLineHeight(PixelY lineHeight)
sets height of all lines and propagates this information to all columns doesn't update the content si...
Definition: columnsview.cpp:152
KDE::Range::end
T end() const
Definition: range.h:88
KDE::NumberRange::fromWidth
static NumberRange fromWidth(N startIndex, S width)
constructs a range by width
Definition: numberrange.h:130
Okteta::ColumnsView::updateScrollBars
void updateScrollBars()
Definition: columnsview.cpp:176
Okteta::DefaultSingleStep
static const int DefaultSingleStep
Definition: columnsview.cpp:38
Okteta::ColumnsView::renderColumns
virtual void renderColumns(QPainter *painter, int cx, int cy, int cw, int ch)
draws all columns in columns coordinates
Definition: columnsview.cpp:296
Okteta::ColumnsView::resizeEvent
virtual void resizeEvent(QResizeEvent *event)
Definition: columnsview.cpp:272
Okteta::ColumnsView::yOffset
PixelY yOffset() const
Definition: columnsview.cpp:127
Okteta::ColumnsView::setNoOfLines
virtual void setNoOfLines(LineSize noOfLines)
sets the number of lines doesn't update the content size
Definition: columnsview.cpp:141
Okteta::ColumnsView::visibleLines
LineRange visibleLines() const
gives the index of the first and the last line that would be visible these lines might not contain an...
Definition: columnsview.cpp:104
Okteta::ColumnsView::lineHeight
PixelY lineHeight() const
returns the height of each line
Definition: columnsview.cpp:102
Okteta::AbstractColumnRenderer::renderNextLine
virtual void renderNextLine(QPainter *painter)
the actual painting call for a column's line.
Definition: abstractcolumnrenderer.cpp:67
Okteta::ColumnsView::xOffset
PixelX xOffset() const
Definition: columnsview.cpp:126
Okteta::LineRange
KDE::NumberRange< Line, LineSize > LineRange
Definition: linerange.h:34
Okteta::ColumnsView::yOffsetOfLine
PixelY yOffsetOfLine(Line lineIndex) const
Definition: columnsview.cpp:128
Okteta::ColumnsView::removeColumn
void removeColumn(AbstractColumnRenderer *columnRenderer)
Definition: columnsview.cpp:246
Okteta::AbstractColumnRenderer::width
PixelX width() const
total width in pixel
Definition: abstractcolumnrenderer.cpp:44
Okteta::AbstractColumnRenderer::renderFirstLine
virtual void renderFirstLine(QPainter *painter, const PixelXRange &xSpan, int firstLineIndex)
Before an update of the columns view each column that intersects with the area to be painted will be ...
Definition: abstractcolumnrenderer.cpp:59
KDE::Range::startsBefore
bool startsBefore(T Value) const
returns true is the range starts before index.
Definition: range.h:99
Okteta::ColumnsView::columnsWidth
PixelX columnsWidth() const
returns the width of all visible columns together
Definition: columnsview.cpp:118
Okteta::AbstractColumnRenderer::x
PixelX x() const
left offset x in pixel
Definition: abstractcolumnrenderer.cpp:42
Okteta::AbstractColumnRenderer
base class for columns of the ColumnsView
Definition: abstractcolumnrenderer.h:46
Okteta::AbstractColumnRenderer::overlaps
bool overlaps(const PixelXRange &xSpan) const
true if column overlaps with pixels between x-positions x1, x2
Definition: abstractcolumnrenderer.cpp:56
Okteta::ColumnsView::noOfLinesPerPage
LineSize noOfLinesPerPage() const
returns number of fully visible lines, at least 1 (as needed by page down/up) doesn't care about the ...
Definition: columnsview.cpp:220
Okteta::AbstractColumnRenderer::isVisible
bool isVisible() const
should Column be displayed?
Definition: abstractcolumnrenderer.cpp:45
KDE::Range::setStart
void setStart(T S)
sets the first index of the range
Definition: range.h:58
Okteta::ColumnsView::renderEmptyArea
virtual void renderEmptyArea(QPainter *painter, int cx, int cy, int cw, int ch)
draws area without columns in columns coordinates
Definition: columnsview.cpp:392
Okteta::ColumnsView::visibleWidth
PixelX visibleWidth() const
Definition: columnsview.cpp:114
Okteta::ColumnsView::~ColumnsView
virtual ~ColumnsView()
Definition: columnsview.cpp:398
KDE::Range::isValid
bool isValid() const
returns true if the range covers at least one index
Definition: range.h:122
Okteta::LineSize
qint32 LineSize
Definition: line.h:34
Okteta::PixelY
int PixelY
Definition: kadds.h:35
QList
Definition: bookmarkable.h:29
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:04:07 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

okteta

Skip menu "okteta"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdesdk API Reference

Skip menu "kdesdk API Reference"
  • kapptemplate
  • kcachegrind
  • kompare
  • lokalize
  • okteta
  • umbrello
  •   umbrello

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal