int TreeView::isExpanded(lua_State * L) // ( const QModelIndex & index ) const : bool { QTreeView* obj = QtObject<QTreeView>::check( L, 1); QModelIndex* index = QtValue<QModelIndex>::check( L, 2 ); Util::push( L, obj->isExpanded( *index ) ); return 1; }
void TreeCtrl::handleExpand(Root::Action & t) { QTreeView* tv = wnd(); QModelIndex i = tv->currentIndex(); ENABLED_IF( t, i.isValid() && ! tv->isExpanded( i ) ); tv->setExpanded( i, true ); }
bool RichTextDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { if (event->type() == QEvent::MouseButtonPress) { QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); if (mouseEvent->button() == Qt::LeftButton && mouseEvent->x() - option.rect.left() < 18 && model->hasChildren(index)) { QTreeView *tree = static_cast<QTreeView *>(parent()); tree->setExpanded(index, !tree->isExpanded(index)); return true; } } return false; }
void pTreeComboBox::calculPopupGeometry() { if ( !mView ) { return; } QStyle * const style = this->style(); // set current item and select it view()->selectionModel()->setCurrentIndex( mCurrentIndex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows ); QFrame* container = mFrame; QStyleOptionComboBox opt; initStyleOption( &opt ); QRect listRect( style->subControlRect( QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxListBoxPopup, this ) ); QRect screen = popupGeometry( QApplication::desktop()->screenNumber( this ) ); QPoint below = mapToGlobal( listRect.bottomLeft() ); int belowHeight = screen.bottom() -below.y(); QPoint above = mapToGlobal( listRect.topLeft() ); int aboveHeight = above.y() -screen.y(); bool boundToScreen = !window()->testAttribute( Qt::WA_DontShowOnScreen ); listRect.moveTopLeft( mapToGlobal( rect().bottomLeft() ) ); listRect.setSize( QSize( qMax( qMax( view()->viewport()->width(), mFrame->width() ), width() ) , qMax( view()->viewport()->height(), mFrame->height() ) ) ); const bool usePopup = style->styleHint( QStyle::SH_ComboBox_Popup, &opt, this ); { int listHeight = 0; int count = 0; QStack<QModelIndex> toCheck; toCheck.push( view()->rootIndex() ); #ifndef QT_NO_TREEVIEW QTreeView* treeView = qobject_cast<QTreeView*>( view() ); if ( treeView && treeView->header() && !treeView->header()->isHidden() ) listHeight += treeView->header()->height(); #endif while ( !toCheck.isEmpty() ) { QModelIndex parent = toCheck.pop(); for ( int i = 0; i < model()->rowCount( parent ); ++i ) { QModelIndex idx = model()->index( i, mModelColumn, parent ); if ( !idx.isValid() ) continue; listHeight += view()->visualRect( idx ).height(); #ifndef QT_NO_TREEVIEW if ( model()->hasChildren( idx ) && treeView && treeView->isExpanded( idx ) ) toCheck.push( idx ); #endif ++count; if ( !usePopup && count > mMaxVisibleItems ) { toCheck.clear(); break; } } } listRect.setHeight( listHeight ); } { // add the spacing for the grid on the top and the bottom; int heightMargin = 0; // add the frame of the container int marginTop, marginBottom; container->getContentsMargins( 0, &marginTop, 0, &marginBottom ); heightMargin += marginTop +marginBottom; //add the frame of the view view()->getContentsMargins( 0, &marginTop, 0, &marginBottom ); marginTop += 0/*static_cast<QAbstractScrollAreaPrivate *>(QObjectPrivate::get(view()))->top*/; marginBottom += 0/*static_cast<QAbstractScrollAreaPrivate *>(QObjectPrivate::get(view()))->bottom*/; heightMargin += marginTop +marginBottom; listRect.setHeight( listRect.height() +heightMargin ); } // Add space for margin at top and bottom if the style wants it. if ( usePopup ) listRect.setHeight( listRect.height() +style->pixelMetric( QStyle::PM_MenuVMargin, &opt, this ) *2 ); // Make sure the popup is wide enough to display its contents. if ( usePopup ) { const int diff = sizeHint().width() /*d->computeWidthHint()*/ -width(); if ( diff > 0 ) listRect.setWidth( listRect.width() +diff ); } //we need to activate the layout to make sure the min/maximum size are set when the widget was not yet show container->layout()->activate(); //takes account of the minimum/maximum size of the container listRect.setSize( listRect.size().expandedTo(container->minimumSize()) .boundedTo(container->maximumSize())); // make sure the widget fits on screen if (boundToScreen) { if (listRect.width() > screen.width() ) listRect.setWidth(screen.width()); if (/*mapToGlobal(*/listRect/*.bottomRight())*/.x() > screen.right()) { below.setX(screen.x() + screen.width() - listRect.width()); above.setX(screen.x() + screen.width() - listRect.width()); } if (/*mapToGlobal(*/listRect/*.topLeft())*/.x() < screen.x() ) { below.setX(screen.x()); above.setX(screen.x()); } } if ( usePopup ) { // Position horizontally. listRect.moveLeft( above.x() ); // Position vertically so the curently selected item lines up // with the combo box. /*const QRect currentItemRect = view()->visualRect( view()->currentIndex() ); const int offset = listRect.top() -currentItemRect.top(); listRect.moveTop( above.y() +offset -listRect.top() );*/ // Clamp the listRect height and vertical position so we don't expand outside the // available screen geometry.This may override the vertical position, but it is more // important to show as much as possible of the popup. const int height = !boundToScreen ? listRect.height() : qMin(listRect.height(), screen.height()); listRect.setHeight(height); if (boundToScreen) { if (listRect.top() < screen.top()) listRect.moveTop(screen.top()); if (listRect.bottom() > screen.bottom()) listRect.moveBottom(screen.bottom()); } } else if (!boundToScreen || listRect.height() <= belowHeight) { listRect.moveTopLeft(below); } else if (listRect.height() <= aboveHeight) { listRect.moveBottomLeft(above); } else if (belowHeight >= aboveHeight) { listRect.setHeight(belowHeight); listRect.moveTopLeft(below); } else { listRect.setHeight(aboveHeight); listRect.moveBottomLeft(above); } #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) #ifndef QT_NO_IM if ( QInputContext *qic = inputContext() ) qic->reset(); #endif #endif QScrollBar* sb = view()->horizontalScrollBar(); Qt::ScrollBarPolicy policy = view()->horizontalScrollBarPolicy(); bool needHorizontalScrollBar = ( policy == Qt::ScrollBarAsNeeded || policy == Qt::ScrollBarAlwaysOn ) && sb->minimum() < sb->maximum(); if ( needHorizontalScrollBar ) { listRect.adjust( 0, 0, 0, sb->height() ); } container->setGeometry( listRect ); #ifndef Q_WS_MAC const bool updatesEnabled = container->updatesEnabled(); #endif #if defined( Q_WS_WIN ) && !defined( QT_NO_EFFECTS ) // FIXME Fix me ASAP /*bool scrollDown = ( listRect.topLeft() == below ); if ( QApplication::isEffectEnabled( Qt::UI_AnimateCombo ) && !style->styleHint( QStyle::SH_ComboBox_Popup, &opt, this ) && !window()->testAttribute( Qt::WA_DontShowOnScreen ) ) qScrollEffect( container, scrollDown ? QEffects::DownScroll : QEffects::UpScroll, 150 );*/ #endif // Don't disable updates on Mac OS X. Windows are displayed immediately on this platform, // which means that the window will be visible before the call to container->show() returns. // If updates are disabled at this point we'll miss our chance at painting the popup // menu before it's shown, causing flicker since the window then displays the standard gray // background. #ifndef Q_WS_MAC container->setUpdatesEnabled( false ); #endif container->raise(); container->show(); //container->updateScrollers(); view()->setFocus(); view()->scrollTo( view()->currentIndex(), style->styleHint( QStyle::SH_ComboBox_Popup, &opt, this ) ? QAbstractItemView::PositionAtCenter : QAbstractItemView::EnsureVisible ); #ifndef Q_WS_MAC container->setUpdatesEnabled( updatesEnabled ); #endif container->update(); #ifdef QT_KEYPAD_NAVIGATION if ( QApplication::keypadNavigationEnabled() ) view()->setEditFocus( true ); #endif }
// ------------------------------------------------------------------------- void ctkTreeComboBox::resizePopup() { // copied from QComboBox.cpp Q_D(ctkTreeComboBox); QStyle * const style = this->style(); QWidget* container = qobject_cast<QWidget*>(this->view()->parent()); QStyleOptionComboBox opt; this->initStyleOption(&opt); QRect listRect(style->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxListBoxPopup, this)); QRect screen = QApplication::desktop()->availableGeometry( QApplication::desktop()->screenNumber(this)); QPoint below = this->mapToGlobal(listRect.bottomLeft()); int belowHeight = screen.bottom() - below.y(); QPoint above = this->mapToGlobal(listRect.topLeft()); int aboveHeight = above.y() - screen.y(); bool boundToScreen = !this->window()->testAttribute(Qt::WA_DontShowOnScreen); const bool usePopup = style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this); { int listHeight = 0; int count = 0; QStack<QModelIndex> toCheck; toCheck.push(this->view()->rootIndex()); #ifndef QT_NO_TREEVIEW QTreeView *treeView = qobject_cast<QTreeView*>(this->view()); if (treeView && treeView->header() && !treeView->header()->isHidden()) listHeight += treeView->header()->height(); #endif while (!toCheck.isEmpty()) { QModelIndex parent = toCheck.pop(); for (int i = 0; i < this->model()->rowCount(parent); ++i) { QModelIndex idx = this->model()->index(i, this->modelColumn(), parent); if (!idx.isValid()) { continue; } listHeight += this->view()->visualRect(idx).height(); /* + container->spacing() */; #ifndef QT_NO_TREEVIEW if (this->model()->hasChildren(idx) && treeView && treeView->isExpanded(idx)) { toCheck.push(idx); } #endif ++count; if (!usePopup && count > this->maxVisibleItems()) { toCheck.clear(); break; } } } listRect.setHeight(listHeight); } { // add the spacing for the grid on the top and the bottom; int heightMargin = 0;//2*container->spacing(); // add the frame of the container int marginTop, marginBottom; container->getContentsMargins(0, &marginTop, 0, &marginBottom); heightMargin += marginTop + marginBottom; //add the frame of the view this->view()->getContentsMargins(0, &marginTop, 0, &marginBottom); //marginTop += static_cast<QAbstractScrollAreaPrivate *>(QObjectPrivate::get(this->view()))->top; //marginBottom += static_cast<QAbstractScrollAreaPrivate *>(QObjectPrivate::get(this->view()))->bottom; heightMargin += marginTop + marginBottom; listRect.setHeight(listRect.height() + heightMargin); } // Add space for margin at top and bottom if the style wants it. if (usePopup) { listRect.setHeight(listRect.height() + style->pixelMetric(QStyle::PM_MenuVMargin, &opt, this) * 2); } // Make sure the popup is wide enough to display its contents. if (usePopup) { const int diff = d->computeWidthHint() - this->width(); if (diff > 0) { listRect.setWidth(listRect.width() + diff); } } //we need to activate the layout to make sure the min/maximum size are set when the widget was not yet show container->layout()->activate(); //takes account of the minimum/maximum size of the container listRect.setSize( listRect.size().expandedTo(container->minimumSize()) .boundedTo(container->maximumSize())); // make sure the widget fits on screen if (boundToScreen) { if (listRect.width() > screen.width() ) { listRect.setWidth(screen.width()); } if (this->mapToGlobal(listRect.bottomRight()).x() > screen.right()) { below.setX(screen.x() + screen.width() - listRect.width()); above.setX(screen.x() + screen.width() - listRect.width()); } if (this->mapToGlobal(listRect.topLeft()).x() < screen.x() ) { below.setX(screen.x()); above.setX(screen.x()); } } if (usePopup) { // Position horizontally. listRect.moveLeft(above.x()); #ifndef Q_WS_S60 // Position vertically so the curently selected item lines up // with the combo box. const QRect currentItemRect = this->view()->visualRect(this->view()->currentIndex()); const int offset = listRect.top() - currentItemRect.top(); listRect.moveTop(above.y() + offset - listRect.top()); #endif // Clamp the listRect height and vertical position so we don't expand outside the // available screen geometry.This may override the vertical position, but it is more // important to show as much as possible of the popup. const int height = !boundToScreen ? listRect.height() : qMin(listRect.height(), screen.height()); #ifdef Q_WS_S60 //popup needs to be stretched with screen minimum dimension listRect.setHeight(qMin(screen.height(), screen.width())); #else listRect.setHeight(height); #endif if (boundToScreen) { if (listRect.top() < screen.top()) { listRect.moveTop(screen.top()); } if (listRect.bottom() > screen.bottom()) { listRect.moveBottom(screen.bottom()); } } #ifdef Q_WS_S60 if (screen.width() < screen.height()) { // in portait, menu should be positioned above softkeys listRect.moveBottom(screen.bottom()); } else { TRect staConTopRect = TRect(); AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStaconTop, staConTopRect); listRect.setWidth(listRect.height()); //by default popup is centered on screen in landscape listRect.moveCenter(screen.center()); if (staConTopRect.IsEmpty()) { // landscape without stacon, menu should be at the right (opt.direction == Qt::LeftToRight) ? listRect.setRight(screen.right()) : listRect.setLeft(screen.left()); } } #endif } else if (!boundToScreen || listRect.height() <= belowHeight) { listRect.moveTopLeft(below); } else if (listRect.height() <= aboveHeight) { listRect.moveBottomLeft(above); } else if (belowHeight >= aboveHeight) { listRect.setHeight(belowHeight); listRect.moveTopLeft(below); } else { listRect.setHeight(aboveHeight); listRect.moveBottomLeft(above); } #if QT_VERSION < QT_VERSION_CHECK(5,0,0) && !defined QT_NO_IM if (QInputContext *qic = this->inputContext()) { qic->reset(); } #endif QScrollBar *sb = this->view()->horizontalScrollBar(); Qt::ScrollBarPolicy policy = this->view()->horizontalScrollBarPolicy(); bool needHorizontalScrollBar = (policy == Qt::ScrollBarAsNeeded || policy == Qt::ScrollBarAlwaysOn) && sb->minimum() < sb->maximum(); if (needHorizontalScrollBar) { listRect.adjust(0, 0, 0, sb->height()); } container->setGeometry(listRect); }