void QCustomTableWidget::scrollTo(int row, int column) { repaint(); int row_count = rowCount(), column_count = columnCount(); if (row > -1 && row < row_count) { int y = rowViewportPosition(row); QScrollBar *bar = verticalScrollBar(); if (y < 0) { bar->setValue(bar->value()+y); } else { int dy = y + rowHeight(row) - viewport()->height(); if (columnViewportPosition(column_count-1) + columnWidth(column_count-1) > viewport()->width()) { dy += horizontalScrollBar()->height() + 3; } if (dy > 0) { int value = bar->value() + dy; if (value > bar->maximum()) { bar->setMaximum(value); } bar->setValue(value); } } } if (column > -1 && column < column_count) { int x = columnViewportPosition(column); QScrollBar *bar = horizontalScrollBar(); if (x < 0) { bar->setValue(bar->value()+x); } else { int dx = x + columnWidth(column) - viewport()->width(); if (dx > 0) { int value = bar->value() + dx; if (value > bar->maximum()) { bar->setMaximum(value); } bar->setValue(value); } } } }
int KateCompletionTree::columnTextViewportPosition(int column) const { int ret = columnViewportPosition(column); QModelIndex i = model()->index(0, column, QModelIndex()); QModelIndex base = model()->index(0, 0, QModelIndex()); //If it's just a group header, use the first child if (base.isValid() && model()->rowCount(base)) { i = base.child(0, column); } if (i.isValid()) { QIcon icon = i.data(Qt::DecorationRole).value<QIcon>(); if (!icon.isNull()) { ret += icon.actualSize(sizeHintForIndex(i)).width(); } } return ret; }
void KateCompletionTree::resizeColumns(bool firstShow, bool forceResize) { static bool preventRecursion = false; if (preventRecursion) { return; } m_resizeTimer->stop(); if (firstShow) { forceResize = true; } preventRecursion = true; widget()->setUpdatesEnabled(false); int modelIndexOfName = kateModel()->translateColumn(KTextEditor::CodeCompletionModel::Name); int oldIndentWidth = columnViewportPosition(modelIndexOfName); ///Step 1: Compute the needed column-sizes for the visible content const int numColumns = model()->columnCount(); QVarLengthArray<int, 8> columnSize(numColumns); for (int i = 0; i < numColumns; ++i) { columnSize[i] = 5; } QModelIndex current = indexAt(QPoint(1, 1)); const bool changed = current.isValid(); int currentYPos = 0; measureColumnSizes(this, current, columnSize, currentYPos, height()); int totalColumnsWidth = 0, originalViewportWidth = viewport()->width(); int maxWidth = (QApplication::desktop()->screenGeometry(widget()->view()).width() * 3) / 4; ///Step 2: Update column-sizes //This contains several hacks to reduce the amount of resizing that happens. Generally, //resizes only happen if a) More than a specific amount of space is saved by the resize, or //b) the resizing is required so the list can show all of its contents. int minimumResize = 0; int maximumResize = 0; if (changed) { for (int n = 0; n < numColumns; n++) { totalColumnsWidth += columnSize[n]; int diff = columnSize[n] - columnWidth(n); if (diff < minimumResize) { minimumResize = diff; } if (diff > maximumResize) { maximumResize = diff; } } int noReduceTotalWidth = 0; //The total width of the widget of no columns are reduced for (int n = 0; n < numColumns; n++) { if (columnSize[n] < columnWidth(n)) { noReduceTotalWidth += columnWidth(n); } else { noReduceTotalWidth += columnSize[n]; } } //Check whether we can afford to reduce none of the columns //Only reduce size if we widget would else be too wide. bool noReduce = noReduceTotalWidth < maxWidth && !forceResize; if (noReduce) { totalColumnsWidth = 0; for (int n = 0; n < numColumns; n++) { if (columnSize[n] < columnWidth(n)) { columnSize[n] = columnWidth(n); } totalColumnsWidth += columnSize[n]; } } if (minimumResize > -40 && maximumResize == 0 && !forceResize) { //No column needs to be exanded, and no column needs to be reduced by more than 40 pixels. //To prevent flashing, do not resize at all. totalColumnsWidth = 0; for (int n = 0; n < numColumns; n++) { columnSize[n] = columnWidth(n); totalColumnsWidth += columnSize[n]; } } else { // viewport()->resize( 5000, viewport()->height() ); for (int n = 0; n < numColumns; n++) { setColumnWidth(n, columnSize[n]); } // qCDebug(LOG_KTE) << "resizing viewport to" << totalColumnsWidth; viewport()->resize(totalColumnsWidth, viewport()->height()); } } ///Step 3: Update widget-size and -position int scrollBarWidth = verticalScrollBar()->width(); int newIndentWidth = columnViewportPosition(modelIndexOfName); int newWidth = qMin(maxWidth, qMax(75, totalColumnsWidth)); if (newWidth == maxWidth) { setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); } else { setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); } if (maximumResize > 0 || forceResize || oldIndentWidth != newIndentWidth) { // qCDebug(LOG_KTE) << geometry() << "newWidth" << newWidth << "current width" << width() << "target width" << newWidth + scrollBarWidth; if ((newWidth + scrollBarWidth) != width() && originalViewportWidth != totalColumnsWidth) { widget()->resize(newWidth + scrollBarWidth + 2, widget()->height()); resize(newWidth + scrollBarWidth, widget()->height() - (2 * widget()->frameWidth())); } // qCDebug(LOG_KTE) << "created geometry:" << widget()->geometry() << geometry() << "newWidth" << newWidth << "viewport" << viewport()->width(); if (viewport()->width() > totalColumnsWidth) { //Set the size of the last column to fill the whole rest of the widget setColumnWidth(numColumns - 1, viewport()->width() - columnViewportPosition(numColumns - 1)); } /* for(int a = 0; a < numColumns; ++a) qCDebug(LOG_KTE) << "column" << a << columnWidth(a) << "target:" << columnSize[a];*/ if (oldIndentWidth != newIndentWidth) if (widget()->updatePosition() && !forceResize) { preventRecursion = false; resizeColumns(true, true); } } widget()->setUpdatesEnabled(true); preventRecursion = false; }