示例#1
0
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;
}
示例#2
0
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 );
}
示例#3
0
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;
}
示例#4
0
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
}
示例#5
0
// -------------------------------------------------------------------------
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);
}