⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qtreeview.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        }    }    return height;}/*!  \reimp*/void QTreeView::horizontalScrollbarAction(int action){    QAbstractItemView::horizontalScrollbarAction(action);}/*!  \reimp*/bool QTreeView::isIndexHidden(const QModelIndex &index) const{    return (isColumnHidden(index.column()) || isRowHidden(index.row(), index.parent()));}/*  private implementation*/void QTreeViewPrivate::initialize(){    Q_Q(QTreeView);    q->setSelectionBehavior(QAbstractItemView::SelectRows);    q->setSelectionMode(QAbstractItemView::SingleSelection);    QHeaderView *header = new QHeaderView(Qt::Horizontal, q);    header->setMovable(true);    header->setStretchLastSection(true);    q->setHeader(header);}void QTreeViewPrivate::expand(int i, bool emitSignal){    Q_Q(QTreeView);    if (!model || i == -1 || viewItems.at(i).expanded)        return;    q->setState(QAbstractItemView::ExpandingState);    QModelIndex index = viewItems.at(i).index;    expandedIndexes.append(index);    viewItems[i].expanded = true;    layout(i);    // make sure we expand children that were previously expanded    if (model->hasChildren(index))        reexpandChildren(index);    q->setState(QAbstractItemView::NoState);    if (emitSignal)        emit q->expanded(index);}void QTreeViewPrivate::collapse(int item, bool emitSignal){    Q_Q(QTreeView);    if (!model || item == -1 || expandedIndexes.isEmpty())        return;    q->setState(QAbstractItemView::CollapsingState);    int total = viewItems.at(item).total;    QModelIndex modelIndex = viewItems.at(item).index;    int index = expandedIndexes.indexOf(modelIndex);    if (index == -1 || viewItems.at(item).expanded == false)        return; // nothing to do    expandedIndexes.remove(index);    viewItems[item].expanded = false;    index = item;    QModelIndex parent = modelIndex;    while (parent.isValid() && parent != root) {        Q_ASSERT(index > -1);        viewItems[index].total -= total;        parent = parent.parent();        index = viewIndex(parent);    }    viewItems.remove(item + 1, total); // collapse    q->setState(QAbstractItemView::NoState);    if (emitSignal)        emit q->collapsed(modelIndex);}void QTreeViewPrivate::layout(int i){    Q_Q(QTreeView);    QModelIndex current;    QModelIndex parent = modelIndex(i);    int count = 0;    if (model->hasChildren(parent))        count = model->rowCount(parent);    if (i == -1)        viewItems.resize(count);    else        viewItems.insert(i + 1, count, QTreeViewItem()); // expand    int first = i + 1;    int level = (i >= 0 ? viewItems.at(i).level + 1 : 0);    int hidden = 0;    int last = 0;    int firstColumn = 0;    while (q->isColumnHidden(firstColumn) && firstColumn < q->header()->count())        ++firstColumn;    for (int j = first; j < first + count; ++j) {        current = model->index(j - first, firstColumn, parent);        if (q->isRowHidden(current.row(), parent)) { // slow with lots of hidden rows            ++hidden;            last = j - hidden;        } else {            last = j - hidden;            viewItems[last].index = current;            viewItems[last].level = level;        }    }    // remove hidden items    if (hidden > 0)        viewItems.remove(last + 1, hidden); // collapse    QModelIndex root = q->rootIndex();    while (parent != root) {        Q_ASSERT(i > -1);        viewItems[i].total += count - hidden;        parent = parent.parent();        i = viewIndex(parent);    }}int QTreeViewPrivate::pageUp(int i) const{    int index = item(coordinate(i) - viewport->height());    return index == -1 ? 0 : index;}int QTreeViewPrivate::pageDown(int i) const{    int index = item(coordinate(i) + viewport->height());    return index == -1 ? viewItems.count() - 1 : index;}int QTreeViewPrivate::indentation(int i) const{    if (i < 0 || i >= viewItems.count())        return 0;    int level = viewItems.at(i).level;    if (rootDecoration)        ++level;    return level * indent;}/*!  \internal  Returns the y coordinate for item  Note: if this is ever changed to not estimate then update item()*/int QTreeViewPrivate::coordinate(int item) const{    Q_Q(const QTreeView);    int scrollbarValue = q->verticalScrollBar()->value();    int topViewItemIndex = itemAt(scrollbarValue);    if (topViewItemIndex == -1) {        const_cast<QTreeViewPrivate*>(this)->updateScrollbars();        scrollbarValue = q->verticalScrollBar()->value();        topViewItemIndex = itemAt(scrollbarValue);    }    Q_ASSERT(topViewItemIndex != -1);    int viewItemIndex = topViewItemIndex; // first item (may start above the page)    int viewItemHeight = height(viewItemIndex);    int topItemCoordinate = topItemDelta(scrollbarValue, viewItemHeight);    int viewItemCoordinate = topItemCoordinate;    int viewportHeight = viewport->height();    if (viewItemIndex <= item) {        // search in the visible area first        while (viewItemCoordinate < viewportHeight && viewItemIndex < viewItems.count()) {            if (viewItemIndex == item)                return viewItemCoordinate; // item is visible - actual y in viewport            viewItemCoordinate += height(viewItemIndex);            ++viewItemIndex;        }        // the item is below the viewport        if (editors.isEmpty()) // optimized; estimate the coordinate            return viewItemCoordinate + (itemHeight * (item - viewItemIndex));        // non-optimized        for (;viewItemIndex < viewItems.count(); ++viewItemIndex) {            if (viewItemIndex == item)                return viewItemCoordinate;            viewItemCoordinate += height(viewItemIndex);        }        // below the last item in the view        // Q_ASSERT(false);        return viewItemCoordinate;    }    // the item is above the viewport    if (editors.isEmpty()) // optimized; estimate the coordinate        return viewItemCoordinate - (itemHeight * (viewItemIndex - item));    // non-optimized    viewItemCoordinate = topItemCoordinate;    viewItemIndex = topViewItemIndex;    for (; viewItemIndex >= 0; --viewItemIndex) {        if (viewItemIndex == item)            return viewItemCoordinate;        viewItemCoordinate -= height(viewItemIndex);    }    // above the first item in the view    // Q_ASSERT(false);    return viewItemCoordinate;}/*!  \internal  Returns the visual index at \a coordinate or -1  \sa modelIndex()*/int QTreeViewPrivate::item(int yCoordinate) const{    Q_Q(const QTreeView);    int scrollbarValue = q->verticalScrollBar()->value();    int viewItemIndex = itemAt(scrollbarValue);    if (viewItemIndex < 0) // couldn't find first visible item        return -1;    int viewItemHeight = height(viewItemIndex);    int viewportHeight = viewport->height();    int y = topItemDelta(scrollbarValue, viewItemHeight);    if (yCoordinate >= y) {        // search for item in viewport        while (y < viewportHeight && viewItemIndex < viewItems.count()) {            y += height(viewItemIndex);            if (yCoordinate < y)                return viewItemIndex;            ++viewItemIndex;        }    }    if (itemHeight <= 0)        return -1;    // item is above the viewport - find via binary search    // If coordinate() is ever changed to not estimate    // the value then change this to just walk the tree    int start = 0;    int end = viewItems.count();    int i = (start + end + 1) >> 1;    while (end - start > 0) {        if (yCoordinate < coordinate(i))            end = i - 1;        else            start = i;        i = (start + end + 1) >> 1;    }    return (i < viewItems.count() ? i : -1);}int QTreeViewPrivate::viewIndex(const QModelIndex &index) const{    Q_Q(const QTreeView);    if (!index.isValid())        return -1;    int totalCount = viewItems.count();    QModelIndex parent = index.parent();    // A quick check near the last item to see if we are just incrimenting    int start = lastViewedItem > 2 ? lastViewedItem - 2 : 0;    int end = lastViewedItem < totalCount - 2 ? lastViewedItem + 2 : totalCount;    for (int i = start; i < end; ++i) {        const QModelIndex idx = viewItems.at(i).index;        if (idx.row() == index.row()) {            if (idx.internalId() == index.internalId() || idx.parent() == parent) {// ignore column                lastViewedItem = i;                return i;            }        }    }    // NOTE: this function is slow if the item is outside the visible area    // search in visible items first and below    int t = itemAt(q->verticalScrollBar()->value());    t = t > 100 ? t - 100 : 0; // start 100 items above the visible area    for (int i = t; i < totalCount; ++i) {        const QModelIndex idx = viewItems.at(i).index;        if (idx.row() == index.row()) {            if (idx.internalId() == index.internalId() || idx.parent() == parent) {// ignore column                lastViewedItem = i;                return i;            }        }    }    // search from top to first visible    for (int j = 0; j < t; ++j) {        const QModelIndex idx = viewItems.at(j).index;        if (idx.row() == index.row()) {            if (idx.internalId() == index.internalId() || idx.parent() == parent) { // ignore column                lastViewedItem = j;                return j;            }        }    }    // nothing found    return -1;}QModelIndex QTreeViewPrivate::modelIndex(int i) const{    return ((i < 0 || i >= viewItems.count())            ? (QModelIndex)root : viewItems.at(i).index);}int QTreeViewPrivate::itemAt(int value) const{    int i = value / verticalStepsPerItem;    return (i < 0 || i >= viewItems.count()) ? -1 : i;}int QTreeViewPrivate::topItemDelta(int value, int iheight) const{    int above = (value % verticalStepsPerItem) * iheight; // what's left; in "item units"    return -(above / verticalStepsPerItem); // above the page}int QTreeViewPrivate::columnAt(int x) const{    return header->logicalIndexAt(x);}void QTreeViewPrivate::relayout(const QModelIndex &parent){    Q_Q(QTreeView);    // do a local relayout of the items    if (parent.isValid()) {        int parentViewIndex = viewIndex(parent);        if (parentViewIndex > -1 && viewItems.at(parentViewIndex).expanded) {            collapse(parentViewIndex, false); // remove the current layout            expand(parentViewIndex, false); // do the relayout            q->updateGeometries();            viewport->update();        }    } else {        viewItems.clear();        q->doItemsLayout();    }}void QTreeViewPrivate::reexpandChildren(const QModelIndex &parent){    if (!model)        return;    // FIXME: this is slow: optimize    QVector<QPersistentModelIndex> o = expandedIndexes;    for (int j = 0; j < o.count(); ++j) {        QModelIndex index = o.at(j);        if (!index.isValid()){            int k = expandedIndexes.indexOf(index);            if (k >= 0)                expandedIndexes.remove(k);        } else if (model->parent(index) == parent) {            int v = viewIndex(index);            if (v < 0)                continue;            int k = expandedIndexes.indexOf(index);            expandedIndexes.remove(k);            expand(v, false);        }    }}void QTreeViewPrivate::updateScrollbars(){    Q_Q(QTreeView);    QSize viewportSize = viewport->size();    // TODO why is there an assert when you remove this if in the file dialog?    if (!viewport->isVisible()) {        q->verticalScrollBar()->setRange(0, 0);        q->verticalScrollBar()->setPageStep(0);        return;    }    // set page step size    int verticalScrollBarValue = q->verticalScrollBar()->value();    int itemsInViewport = 0;    if (uniformRowHeights) {        itemsInViewport = viewportSize.height() / itemHeight;    } else {        int topItemInViewport = qMax(0, itemAt(verticalScrollBarValue));        int h = height(topItemInViewport);        int y = topItemDelta(verticalScrollBarValue, h);        int i = topItemInViewport;        for (; y < viewportSize.height() && i < viewItems.count(); ++i)            y += height(i);        itemsInViewport = i - topItemInViewport;    }    q->verticalScrollBar()->setPageStep(itemsInViewport * verticalStepsPerItem);    // set the scroller range    int y = viewportSize.height();    int i = viewItems.count();    while (y > 0 && i > 0) // subtract the bottom screen        y -= height(--i);    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -