Kate
katecompletiontree.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "katecompletiontree.h"
00021
00022 #include <QtGui/QHeaderView>
00023 #include <QtGui/QScrollBar>
00024 #include <QVector>
00025 #include <QTimer>
00026 #include <QApplication>
00027 #include <QDesktopWidget>
00028
00029 #include "kateview.h"
00030 #include "katerenderer.h"
00031 #include "kateconfig.h"
00032
00033 #include "katecompletionwidget.h"
00034 #include "katecompletiondelegate.h"
00035 #include "katecompletionmodel.h"
00036
00037 KateCompletionTree::KateCompletionTree(KateCompletionWidget* parent)
00038 : ExpandingTree(parent)
00039 {
00040 m_scrollingEnabled = true;
00041 header()->hide();
00042 setRootIsDecorated(false);
00043 setIndentation(0);
00044 setFrameStyle(QFrame::NoFrame);
00045 setAllColumnsShowFocus(true);
00046 setAlternatingRowColors(true);
00047
00048 setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
00049
00050 m_resizeTimer = new QTimer(this);
00051 m_resizeTimer->setSingleShot(true);
00052
00053 connect(m_resizeTimer, SIGNAL(timeout()), this, SLOT(resizeColumnsSlot()));
00054
00055
00056 setItemDelegate(new KateCompletionDelegate(widget()->model(), widget()));
00057
00059
00060
00061
00062 setItemsExpandable(false);
00063 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00064 }
00065
00066 void KateCompletionTree::currentChanged ( const QModelIndex & current, const QModelIndex & previous ) {
00067 widget()->model()->rowSelected(current);
00068 ExpandingTree::currentChanged(current, previous);
00069 }
00070
00071 void KateCompletionTree::setScrollingEnabled(bool enabled) {
00072 m_scrollingEnabled = enabled;
00073 }
00074
00075 void KateCompletionTree::scrollContentsBy( int dx, int dy )
00076 {
00077 if(m_scrollingEnabled)
00078 QTreeView::scrollContentsBy(dx, dy);
00079
00080 if (isVisible())
00081 m_resizeTimer->start(300);
00082 }
00083
00084 int KateCompletionTree::columnTextViewportPosition ( int column ) const {
00085 int ret = columnViewportPosition(column);
00086 QModelIndex i = model()->index(0, column, QModelIndex());
00087 QModelIndex base = model()->index(0, 0, QModelIndex());
00088
00089
00090 if(base.isValid() && model()->rowCount(base))
00091 i = base.child(0, column);
00092
00093 if(i.isValid()) {
00094 QIcon icon = i.data(Qt::DecorationRole).value<QIcon>();
00095 if(!icon.isNull())
00096 ret += icon.actualSize(sizeHintForIndex(i)).width();
00097 }
00098 return ret;
00099 }
00100
00101 KateCompletionWidget * KateCompletionTree::widget( ) const
00102 {
00103 return static_cast<KateCompletionWidget*>(const_cast<QObject*>(parent()));
00104 }
00105
00106 void KateCompletionTree::resizeColumnsSlot()
00107 {
00108 if(model())
00109 resizeColumns();
00110 }
00111
00112 void KateCompletionTree::resizeColumns(bool fromResizeEvent, bool firstShow, bool forceResize)
00113 {
00114 static bool preventRecursion = false;
00115 if (preventRecursion)
00116 return;
00117
00118 if(firstShow)
00119 forceResize = true;
00120
00121 preventRecursion = true;
00122
00123 widget()->setUpdatesEnabled(false);
00124
00125 int modelIndexOfName = kateModel()->translateColumn(KTextEditor::CodeCompletionModel::Name);
00126 int oldIndentWidth = columnViewportPosition(modelIndexOfName);
00127
00129
00130 int numColumns = model()->columnCount();
00131
00132 QVector<int> columnSize(numColumns, 5);
00133
00134 int currentYPos = 0;
00135
00136 QModelIndex current = indexAt(QPoint(1,1));
00137 if( current.child(0,0).isValid() ) {
00138 currentYPos += sizeHintForIndex(current).height();
00139 current = current.child(0,0);
00140 }
00141
00142 int num = 0;
00143 bool changed = false;
00144
00145 while( current.isValid() && currentYPos < height() )
00146 {
00147
00148 currentYPos += sizeHintForIndex(current).height();
00149
00150 changed = true;
00151 num++;
00152 for( int a = 0; a < numColumns; a++ )
00153 {
00154 QSize s = sizeHintForIndex (current.sibling(current.row(), a));
00155
00156 if( s.width() > columnSize[a] && s.width() < 2000 )
00157 columnSize[a] = s.width();
00158 else if( s.width() > 2000 )
00159 kDebug( 13035 ) << "got invalid size-hint of width " << s.width();
00160 }
00161
00162 QModelIndex oldCurrent = current;
00163 current = current.sibling(current.row()+1, 0);
00164
00165
00166 if( !current.isValid() && oldCurrent.parent().isValid() ) {
00167 current = oldCurrent.parent().sibling( oldCurrent.parent().row()+1, 0 );
00168 if( current.isValid() && current.child(0,0).isValid() ) {
00169 currentYPos += sizeHintForIndex(current).height();
00170 current = current.child(0,0);
00171 }
00172 }
00173 }
00174
00175 int totalColumnsWidth = 0, originalViewportWidth = viewport()->width();
00176
00177 int maxWidth = (QApplication::desktop()->screenGeometry(widget()->view()).width()*3) / 4;
00178
00180
00181
00182
00183 int minimumResize = 0;
00184 int maximumResize = 0;
00185
00186 if( changed ) {
00187
00188 for( int n = 0; n < numColumns; n++ ) {
00189 totalColumnsWidth += columnSize[n];
00190
00191 int diff = columnSize[n] - columnWidth(n);
00192 if( diff < minimumResize )
00193 minimumResize = diff;
00194 if( diff > maximumResize )
00195 maximumResize = diff;
00196 }
00197
00198 int noReduceTotalWidth = 0;
00199 for( int n = 0; n < numColumns; n++ ) {
00200 if(columnSize[n] < columnWidth(n))
00201 noReduceTotalWidth += columnWidth(n);
00202 else
00203 noReduceTotalWidth += columnSize[n];
00204 }
00205
00206
00207
00208 bool noReduce = noReduceTotalWidth < maxWidth && !forceResize;
00209
00210 if(noReduce) {
00211 totalColumnsWidth = 0;
00212 for( int n = 0; n < numColumns; n++ ) {
00213 if(columnSize[n] < columnWidth(n))
00214 columnSize[n] = columnWidth(n);
00215
00216 totalColumnsWidth += columnSize[n];
00217 }
00218 }
00219
00220 if( minimumResize > -40 && maximumResize == 0 && !forceResize ) {
00221
00222
00223 totalColumnsWidth = 0;
00224 for( int n = 0; n < numColumns; n++ ) {
00225 columnSize[n] = columnWidth(n);
00226 totalColumnsWidth += columnSize[n];
00227 }
00228 } else {
00229
00230 for( int n = 0; n < numColumns; n++ ) {
00231 setColumnWidth(n, columnSize[n]);
00232 }
00233
00234 viewport()->resize( totalColumnsWidth, viewport()->height() );
00235 }
00236 }
00237
00239
00240 int scrollBarWidth = verticalScrollBar()->width();
00241
00242 int newIndentWidth = columnViewportPosition(modelIndexOfName);
00243
00244 int newWidth = qMin(maxWidth, qMax(75, totalColumnsWidth));
00245
00246 if(newWidth == maxWidth)
00247 setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
00248 else
00249 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00250
00251 if(maximumResize > 0 || forceResize || oldIndentWidth != newIndentWidth) {
00252
00253
00254
00255 if((newWidth + scrollBarWidth) != width() && originalViewportWidth != totalColumnsWidth)
00256 {
00257 widget()->resize(newWidth + scrollBarWidth + 2, widget()->height());
00258 resize(newWidth + scrollBarWidth, widget()->height()- (2*widget()->frameWidth()));
00259 }
00260
00261
00262
00263 if( viewport()->width() > totalColumnsWidth )
00264 setColumnWidth(numColumns-1, viewport()->width() - columnViewportPosition(numColumns-1));
00265
00266
00267
00268
00269 if (oldIndentWidth != newIndentWidth)
00270 if(widget()->updatePosition() && !forceResize) {
00271 preventRecursion = false;
00272 resizeColumns(false, true, true);
00273 }
00274 }
00275
00276 widget()->setUpdatesEnabled(true);
00277
00278 preventRecursion = false;
00279 }
00280
00281 QStyleOptionViewItem KateCompletionTree::viewOptions( ) const
00282 {
00283 QStyleOptionViewItem opt = QTreeView::viewOptions();
00284
00285 opt.font = widget()->view()->renderer()->config()->font();
00286
00287 return opt;
00288 }
00289
00290 KateCompletionModel * KateCompletionTree::kateModel( ) const
00291 {
00292 return static_cast<KateCompletionModel*>(model());
00293 }
00294
00295 bool KateCompletionTree::nextCompletion()
00296 {
00297 QModelIndex current;
00298 QModelIndex firstCurrent = currentIndex();
00299
00300 do {
00301 QModelIndex oldCurrent = currentIndex();
00302
00303 current = moveCursor(MoveDown, Qt::NoModifier);
00304
00305 if (current != oldCurrent && current.isValid()) {
00306 setCurrentIndex(current);
00307 } else {
00308 if (firstCurrent.isValid())
00309 setCurrentIndex(firstCurrent);
00310 return false;
00311 }
00312
00313 } while (!kateModel()->indexIsItem(current));
00314
00315 return true;
00316 }
00317
00318 bool KateCompletionTree::previousCompletion()
00319 {
00320 QModelIndex current;
00321 QModelIndex firstCurrent = currentIndex();
00322
00323 do {
00324 QModelIndex oldCurrent = currentIndex();
00325
00326 current = moveCursor(MoveUp, Qt::NoModifier);
00327
00328 if (current != oldCurrent && current.isValid()) {
00329 setCurrentIndex(current);
00330
00331 } else {
00332 if (firstCurrent.isValid())
00333 setCurrentIndex(firstCurrent);
00334 return false;
00335 }
00336
00337 } while (!kateModel()->indexIsItem(current));
00338
00339 return true;
00340 }
00341
00342 bool KateCompletionTree::pageDown( )
00343 {
00344 QModelIndex old = currentIndex();
00345
00346 QModelIndex current = moveCursor(MovePageDown, Qt::NoModifier);
00347
00348 if (current.isValid()) {
00349 setCurrentIndex(current);
00350 if (!kateModel()->indexIsItem(current))
00351 if (!nextCompletion())
00352 previousCompletion();
00353 }
00354
00355 return current != old;
00356 }
00357
00358 bool KateCompletionTree::pageUp( )
00359 {
00360 QModelIndex old = currentIndex();
00361 QModelIndex current = moveCursor(MovePageUp, Qt::NoModifier);
00362
00363 if (current.isValid()) {
00364 setCurrentIndex(current);
00365 if (!kateModel()->indexIsItem(current))
00366 if (!previousCompletion())
00367 nextCompletion();
00368 }
00369 return current != old;
00370 }
00371
00372 void KateCompletionTree::top( )
00373 {
00374 QModelIndex current = moveCursor(MoveHome, Qt::NoModifier);
00375 setCurrentIndex(current);
00376
00377 if (current.isValid()) {
00378 setCurrentIndex(current);
00379 if (!kateModel()->indexIsItem(current))
00380 nextCompletion();
00381 }
00382 }
00383
00384 void KateCompletionTree::scheduleUpdate()
00385 {
00386 m_resizeTimer->start(300);
00387 }
00388
00389 void KateCompletionTree::bottom( )
00390 {
00391 QModelIndex current = moveCursor(MoveEnd, Qt::NoModifier);
00392 setCurrentIndex(current);
00393
00394 if (current.isValid()) {
00395 setCurrentIndex(current);
00396 if (!kateModel()->indexIsItem(current))
00397 previousCompletion();
00398 }
00399 }
00400
00401 #include "katecompletiontree.moc"