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