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