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

Kate

  • kde-4.14
  • applications
  • kate
  • part
  • completion
katecompletiontree.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE libraries and the Kate part.
2  *
3  * Copyright (C) 2006 Hamish Rodda <rodda@kde.org>
4  * Copyright (C) 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 
22 #include "katecompletiontree.h"
23 
24 #include <QtGui/QHeaderView>
25 #include <QtGui/QScrollBar>
26 #include <QVector>
27 #include <QTimer>
28 #include <QApplication>
29 #include <QDesktopWidget>
30 
31 #include "kateview.h"
32 #include "katerenderer.h"
33 #include "kateconfig.h"
34 
35 #include "katecompletionwidget.h"
36 #include "katecompletiondelegate.h"
37 #include "katecompletionmodel.h"
38 
39 KateCompletionTree::KateCompletionTree(KateCompletionWidget* parent)
40  : ExpandingTree(parent)
41 {
42  m_scrollingEnabled = true;
43  header()->hide();
44  setRootIsDecorated(false);
45  setIndentation(0);
46  setFrameStyle(QFrame::NoFrame);
47  setAllColumnsShowFocus(true);
48  setAlternatingRowColors(true);
49  //We need ScrollPerItem, because ScrollPerPixel is too slow with a very large competion-list(see KDevelop).
50  setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
51 
52  m_resizeTimer = new QTimer(this);
53  m_resizeTimer->setSingleShot(true);
54 
55  connect(m_resizeTimer, SIGNAL(timeout()), this, SLOT(resizeColumnsSlot()));
56 
57  // Provide custom highlighting to completion entries
58  setItemDelegate(new KateCompletionDelegate(widget()->model(), widget()));
59 
61  //connect(widget()->model(), SIGNAL(contentGeometryChanged()), this, SLOT(resizeColumnsSlot()));
62 
63  // Prevent user from expanding / collapsing with the mouse
64  setItemsExpandable(false);
65  setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
66 }
67 
68 void KateCompletionTree::currentChanged ( const QModelIndex & current, const QModelIndex & previous ) {
69  widget()->model()->rowSelected(current);
70  ExpandingTree::currentChanged(current, previous);
71 }
72 
73 void KateCompletionTree::setScrollingEnabled(bool enabled) {
74  m_scrollingEnabled = enabled;
75 }
76 
77 void KateCompletionTree::scrollContentsBy( int dx, int dy )
78 {
79  if(m_scrollingEnabled)
80  QTreeView::scrollContentsBy(dx, dy);
81 
82  if (isVisible())
83  m_resizeTimer->start(300);
84 }
85 
86 int KateCompletionTree::columnTextViewportPosition ( int column ) const {
87  int ret = columnViewportPosition(column);
88  QModelIndex i = model()->index(0, column, QModelIndex());
89  QModelIndex base = model()->index(0, 0, QModelIndex());
90 
91  //If it's just a group header, use the first child
92  if(base.isValid() && model()->rowCount(base))
93  i = base.child(0, column);
94 
95  if(i.isValid()) {
96  QIcon icon = i.data(Qt::DecorationRole).value<QIcon>();
97  if(!icon.isNull())
98  ret += icon.actualSize(sizeHintForIndex(i)).width();
99  }
100  return ret;
101 }
102 
103 KateCompletionWidget * KateCompletionTree::widget( ) const
104 {
105  return static_cast<KateCompletionWidget*>(const_cast<QObject*>(parent()));
106 }
107 
108 void KateCompletionTree::resizeColumnsSlot()
109 {
110  if(model())
111  resizeColumns();
112 }
113 
114 void KateCompletionTree::resizeColumns(bool firstShow, bool forceResize)
115 {
116  static bool preventRecursion = false;
117  if (preventRecursion)
118  return;
119 
120  if(firstShow)
121  forceResize = true;
122 
123  preventRecursion = true;
124 
125  widget()->setUpdatesEnabled(false);
126 
127  int modelIndexOfName = kateModel()->translateColumn(KTextEditor::CodeCompletionModel::Name);
128  int oldIndentWidth = columnViewportPosition(modelIndexOfName);
129 
131 
132  int numColumns = model()->columnCount();
133 
134  QVector<int> columnSize(numColumns, 5);
135 
136  int currentYPos = 0;
137 
138  QModelIndex current = indexAt(QPoint(1,1));
139  if( current.child(0,0).isValid() ) { //If the index has children, it is a group-label. Then we should start with it's first child.
140  currentYPos += sizeHintForIndex(current).height();
141  current = current.child(0,0);
142  }
143 
144  int num = 0;
145  bool changed = false;
146 
147  while( current.isValid() && currentYPos < height() )
148  {
149 // kDebug() << current.row() << "out of" << model()->rowCount(current.parent()) << "in" << current.parent().data(Qt::DisplayRole);
150  currentYPos += sizeHintForIndex(current).height();
151 // itemDelegate()->sizeHint(QStyleOptionViewItem(), current).isValid() && itemDelegate()->sizeHint(QStyleOptionViewItem(), current).intersects(visibleViewportRect)
152  changed = true;
153  num++;
154  for( int a = 0; a < numColumns; a++ )
155  {
156  QSize s = sizeHintForIndex (current.sibling(current.row(), a));
157 // kDebug() << "size-hint for" << current.row() << a << ":" << s << current.sibling(current.row(), a).data(Qt::DisplayRole);
158  if( s.width() > columnSize[a] && s.width() < 2000 )
159  columnSize[a] = s.width();
160  else if( s.width() > 2000 )
161  kDebug( 13035 ) << "got invalid size-hint of width " << s.width();
162  }
163 
164  QModelIndex oldCurrent = current;
165  current = current.sibling(current.row()+1, 0);
166 
167  //Are we at the end of a group? If yes, move on into the next group
168  if( !current.isValid() && oldCurrent.parent().isValid() ) {
169  current = oldCurrent.parent().sibling( oldCurrent.parent().row()+1, 0 );
170  if( current.isValid() && current.child(0,0).isValid() ) {
171  currentYPos += sizeHintForIndex(current).height();
172  current = current.child(0,0);
173  }
174  }
175  }
176 
177  int totalColumnsWidth = 0, originalViewportWidth = viewport()->width();
178 
179  int maxWidth = (QApplication::desktop()->screenGeometry(widget()->view()).width()*3) / 4;
180 
182  //This contains several hacks to reduce the amount of resizing that happens. Generally,
183  //resizes only happen if a) More than a specific amount of space is saved by the resize, or
184  //b) the resizing is required so the list can show all of its contents.
185  int minimumResize = 0;
186  int maximumResize = 0;
187 
188  if( changed ) {
189 
190  for( int n = 0; n < numColumns; n++ ) {
191  totalColumnsWidth += columnSize[n];
192 
193  int diff = columnSize[n] - columnWidth(n);
194  if( diff < minimumResize )
195  minimumResize = diff;
196  if( diff > maximumResize )
197  maximumResize = diff;
198  }
199 
200  int noReduceTotalWidth = 0; //The total width of the widget of no columns are reduced
201  for( int n = 0; n < numColumns; n++ ) {
202  if(columnSize[n] < columnWidth(n))
203  noReduceTotalWidth += columnWidth(n);
204  else
205  noReduceTotalWidth += columnSize[n];
206  }
207 
208  //Check whether we can afford to reduce none of the columns
209  //Only reduce size if we widget would else be too wide.
210  bool noReduce = noReduceTotalWidth < maxWidth && !forceResize;
211 
212  if(noReduce) {
213  totalColumnsWidth = 0;
214  for( int n = 0; n < numColumns; n++ ) {
215  if(columnSize[n] < columnWidth(n))
216  columnSize[n] = columnWidth(n);
217 
218  totalColumnsWidth += columnSize[n];
219  }
220  }
221 
222  if( minimumResize > -40 && maximumResize == 0 && !forceResize ) {
223  //No column needs to be exanded, and no column needs to be reduced by more than 40 pixels.
224  //To prevent flashing, do not resize at all.
225  totalColumnsWidth = 0;
226  for( int n = 0; n < numColumns; n++ ) {
227  columnSize[n] = columnWidth(n);
228  totalColumnsWidth += columnSize[n];
229  }
230  } else {
231 // viewport()->resize( 5000, viewport()->height() );
232  for( int n = 0; n < numColumns; n++ ) {
233  setColumnWidth(n, columnSize[n]);
234  }
235 // kDebug() << "resizing viewport to" << totalColumnsWidth;
236  viewport()->resize( totalColumnsWidth, viewport()->height() );
237  }
238  }
239 
241 
242  int scrollBarWidth = verticalScrollBar()->width();
243 
244  int newIndentWidth = columnViewportPosition(modelIndexOfName);
245 
246  int newWidth = qMin(maxWidth, qMax(75, totalColumnsWidth));
247 
248  if(newWidth == maxWidth)
249  setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
250  else
251  setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
252 
253  if(maximumResize > 0 || forceResize || oldIndentWidth != newIndentWidth) {
254 
255  // kDebug() << geometry() << "newWidth" << newWidth << "current width" << width() << "target width" << newWidth + scrollBarWidth;
256 
257  if((newWidth + scrollBarWidth) != width() && originalViewportWidth != totalColumnsWidth)
258  {
259  widget()->resize(newWidth + scrollBarWidth + 2, widget()->height());
260  resize(newWidth + scrollBarWidth, widget()->height()- (2*widget()->frameWidth()));
261  }
262 
263  // kDebug() << "created geometry:" << widget()->geometry() << geometry() << "newWidth" << newWidth << "viewport" << viewport()->width();
264 
265  if( viewport()->width() > totalColumnsWidth ) //Set the size of the last column to fill the whole rest of the widget
266  setColumnWidth(numColumns-1, viewport()->width() - columnViewportPosition(numColumns-1));
267 
268  /* for(int a = 0; a < numColumns; ++a)
269  kDebug() << "column" << a << columnWidth(a) << "target:" << columnSize[a];*/
270 
271  if (oldIndentWidth != newIndentWidth)
272  if(widget()->updatePosition() && !forceResize) {
273  preventRecursion = false;
274  resizeColumns(true, true);
275  }
276  }
277 
278  widget()->setUpdatesEnabled(true);
279 
280  preventRecursion = false;
281 }
282 
283 QStyleOptionViewItem KateCompletionTree::viewOptions( ) const
284 {
285  QStyleOptionViewItem opt = QTreeView::viewOptions();
286 
287  opt.font = widget()->view()->renderer()->config()->font();
288 
289  return opt;
290 }
291 
292 KateCompletionModel * KateCompletionTree::kateModel( ) const
293 {
294  return static_cast<KateCompletionModel*>(model());
295 }
296 
297 bool KateCompletionTree::nextCompletion()
298 {
299  QModelIndex current;
300  QModelIndex firstCurrent = currentIndex();
301 
302  do {
303  QModelIndex oldCurrent = currentIndex();
304 
305  current = moveCursor(MoveDown, Qt::NoModifier);
306 
307  if (current != oldCurrent && current.isValid()) {
308  setCurrentIndex(current);
309  } else {
310  if (firstCurrent.isValid())
311  setCurrentIndex(firstCurrent);
312  return false;
313  }
314 
315  } while (!kateModel()->indexIsItem(current));
316 
317  return true;
318 }
319 
320 bool KateCompletionTree::previousCompletion()
321 {
322  QModelIndex current;
323  QModelIndex firstCurrent = currentIndex();
324 
325  do {
326  QModelIndex oldCurrent = currentIndex();
327 
328  current = moveCursor(MoveUp, Qt::NoModifier);
329 
330  if (current != oldCurrent && current.isValid()) {
331  setCurrentIndex(current);
332 
333  } else {
334  if (firstCurrent.isValid())
335  setCurrentIndex(firstCurrent);
336  return false;
337  }
338 
339  } while (!kateModel()->indexIsItem(current));
340 
341  return true;
342 }
343 
344 bool KateCompletionTree::pageDown( )
345 {
346  QModelIndex old = currentIndex();
347 
348  QModelIndex current = moveCursor(MovePageDown, Qt::NoModifier);
349 
350  if (current.isValid()) {
351  setCurrentIndex(current);
352  if (!kateModel()->indexIsItem(current))
353  if (!nextCompletion())
354  previousCompletion();
355  }
356 
357  return current != old;
358 }
359 
360 bool KateCompletionTree::pageUp( )
361 {
362  QModelIndex old = currentIndex();
363  QModelIndex current = moveCursor(MovePageUp, Qt::NoModifier);
364 
365  if (current.isValid()) {
366  setCurrentIndex(current);
367  if (!kateModel()->indexIsItem(current))
368  if (!previousCompletion())
369  nextCompletion();
370  }
371  return current != old;
372 }
373 
374 void KateCompletionTree::top( )
375 {
376  QModelIndex current = moveCursor(MoveHome, Qt::NoModifier);
377  setCurrentIndex(current);
378 
379  if (current.isValid()) {
380  setCurrentIndex(current);
381  if (!kateModel()->indexIsItem(current))
382  nextCompletion();
383  }
384 }
385 
386 void KateCompletionTree::scheduleUpdate()
387 {
388  m_resizeTimer->start(300);
389 }
390 
391 void KateCompletionTree::bottom( )
392 {
393  QModelIndex current = moveCursor(MoveEnd, Qt::NoModifier);
394  setCurrentIndex(current);
395 
396  if (current.isValid()) {
397  setCurrentIndex(current);
398  if (!kateModel()->indexIsItem(current))
399  previousCompletion();
400  }
401 }
402 
403 #include "katecompletiontree.moc"
KateCompletionTree::widget
KateCompletionWidget * widget() const
Definition: katecompletiontree.cpp:103
KateCompletionModel::indexIsItem
virtual bool indexIsItem(const QModelIndex &index) const
Should return true if the given row should be painted like a contained item(as opposed to label-rows ...
Definition: katecompletionmodel.cpp:1144
QModelIndex
QAbstractItemModel::rowCount
virtual int rowCount(const QModelIndex &parent) const =0
kateview.h
QDesktopWidget::screenGeometry
const QRect screenGeometry(int screen) const
QAbstractItemModel::index
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const =0
QAbstractItemView::setAlternatingRowColors
void setAlternatingRowColors(bool enable)
QSize::width
int width() const
KateCompletionTree::setScrollingEnabled
void setScrollingEnabled(bool)
Definition: katecompletiontree.cpp:73
QAbstractItemView::setCurrentIndex
void setCurrentIndex(const QModelIndex &index)
KateView::renderer
KateRenderer * renderer()
Definition: kateview.cpp:1664
katerenderer.h
QTreeView::moveCursor
virtual QModelIndex moveCursor(CursorAction cursorAction, QFlags< Qt::KeyboardModifier > modifiers)
QTreeView::currentChanged
virtual void currentChanged(const QModelIndex &current, const QModelIndex &previous)
katecompletiontree.h
katecompletiondelegate.h
ExpandingTree
Definition: expandingtree.h:28
QTreeView::scrollContentsBy
virtual void scrollContentsBy(int dx, int dy)
QWidget::isVisible
bool isVisible() const
KateCompletionTree::currentChanged
virtual void currentChanged(const QModelIndex &current, const QModelIndex &previous)
Definition: katecompletiontree.cpp:68
QVariant::value
T value() const
QAbstractScrollArea::viewport
QWidget * viewport() const
KateCompletionModel
This class has the responsibility for filtering, sorting, and manipulating code completion data provi...
Definition: katecompletionmodel.h:48
QWidget::icon
const QPixmap * icon() const
QPoint
QAbstractItemView::setVerticalScrollMode
void setVerticalScrollMode(ScrollMode mode)
QFrame::setFrameStyle
void setFrameStyle(int style)
KateCompletionWidget::model
const KateCompletionModel * model() const
Definition: katecompletionwidget.cpp:252
KateCompletionTree::top
void top()
Definition: katecompletiontree.cpp:374
QWidget::width
width
QWidget::resize
void resize(int w, int h)
QModelIndex::isValid
bool isValid() const
QTreeView::columnWidth
int columnWidth(int column) const
QTreeView::setColumnWidth
void setColumnWidth(int column, int width)
QWidget::enabled
enabled
KateCompletionWidget
This is the code completion's main widget, and also contains the core interface logic.
Definition: katecompletionwidget.h:55
QTimer
KateRenderer::config
KateRendererConfig * config() const
Configuration.
Definition: katerenderer.h:362
QStyleOptionViewItem
KateCompletionModel::rowSelected
virtual void rowSelected(const QModelIndex &row)
Notifies underlying models that the item was selected, collapses any previous partially expanded line...
Definition: katecompletionmodel.cpp:2246
QWidget::setUpdatesEnabled
void setUpdatesEnabled(bool enable)
QObject
KateCompletionWidget::view
KateView * view() const
Definition: katecompletionwidget.cpp:271
QAbstractScrollArea::setHorizontalScrollBarPolicy
void setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy)
katecompletionmodel.h
QAbstractItemView::setItemDelegate
void setItemDelegate(QAbstractItemDelegate *delegate)
QModelIndex::row
int row() const
KateCompletionTree::viewOptions
virtual QStyleOptionViewItem viewOptions() const
Definition: katecompletiontree.cpp:283
QIcon::actualSize
QSize actualSize(const QSize &size, Mode mode, State state) const
katecompletionwidget.h
QTreeView::setAllColumnsShowFocus
void setAllColumnsShowFocus(bool enable)
QWidget::hide
void hide()
QModelIndex::parent
QModelIndex parent() const
QAbstractItemView::sizeHintForIndex
QSize sizeHintForIndex(const QModelIndex &index) const
QAbstractScrollArea::verticalScrollBar
QScrollBar * verticalScrollBar() const
QTreeView::setIndentation
void setIndentation(int i)
KateCompletionTree::kateModel
KateCompletionModel * kateModel() const
Definition: katecompletiontree.cpp:292
KateCompletionTree::bottom
void bottom()
Definition: katecompletiontree.cpp:391
KateCompletionTree::pageUp
bool pageUp()
Definition: katecompletiontree.cpp:360
QSize
KateCompletionModel::translateColumn
int translateColumn(int sourceColumn) const
Definition: katecompletionmodel.cpp:1258
QModelIndex::child
QModelIndex child(int row, int column) const
KateCompletionTree::resizeColumns
void resizeColumns(bool firstShow=false, bool forceResize=false)
Definition: katecompletiontree.cpp:114
KateCompletionTree::scrollContentsBy
virtual void scrollContentsBy(int dx, int dy)
Not available as a signal in this way.
Definition: katecompletiontree.cpp:77
QRect::width
int width() const
QFrame::frameWidth
int frameWidth() const
QVector< int >
QModelIndex::data
QVariant data(int role) const
KateRendererConfig::font
const QFont & font() const
Definition: kateconfig.cpp:2276
QApplication::desktop
QDesktopWidget * desktop()
QIcon::isNull
bool isNull() const
QModelIndex::sibling
QModelIndex sibling(int row, int column) const
KateCompletionTree::scheduleUpdate
void scheduleUpdate()
Definition: katecompletiontree.cpp:386
KateCompletionTree::nextCompletion
bool nextCompletion()
Definition: katecompletiontree.cpp:297
QAbstractItemModel::columnCount
virtual int columnCount(const QModelIndex &parent) const =0
KateCompletionTree::KateCompletionTree
KateCompletionTree(KateCompletionWidget *parent)
Definition: katecompletiontree.cpp:39
QSize::height
int height() const
QAbstractItemView::viewOptions
virtual QStyleOptionViewItem viewOptions() const
QTreeView::columnViewportPosition
int columnViewportPosition(int column) const
QTimer::start
void start(int msec)
KateCompletionTree::columnTextViewportPosition
int columnTextViewportPosition(int column) const
Returns the approximated viewport position of the text in the given column, skipping an eventual icon...
Definition: katecompletiontree.cpp:86
QTreeView::header
QHeaderView * header() const
KateCompletionTree::previousCompletion
bool previousCompletion()
Definition: katecompletiontree.cpp:320
QAbstractItemView::model
QAbstractItemModel * model() const
QAbstractItemView::currentIndex
QModelIndex currentIndex() const
QTreeView::setRootIsDecorated
void setRootIsDecorated(bool show)
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject::parent
QObject * parent() const
KateCompletionDelegate
Definition: katecompletiondelegate.h:26
KateCompletionTree::pageDown
bool pageDown()
Definition: katecompletiontree.cpp:344
kateconfig.h
QTreeView::setItemsExpandable
void setItemsExpandable(bool enable)
QWidget::height
int height() const
QTreeView::indexAt
virtual QModelIndex indexAt(const QPoint &point) const
QIcon
QTimer::setSingleShot
void setSingleShot(bool singleShot)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sat May 9 2020 03:56:58 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Kate

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

applications API Reference

Skip menu "applications API Reference"
  •   kate
  •       kate
  •   KTextEditor
  •   Kate
  • Konsole

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