summaryrefslogtreecommitdiffstats
path: root/src/gui/widgets/qcombobox_p.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2009-03-23 09:34:13 (GMT)
committerSimon Hausmann <simon.hausmann@nokia.com>2009-03-23 09:34:13 (GMT)
commit67ad0519fd165acee4a4d2a94fa502e9e4847bd0 (patch)
tree1dbf50b3dff8d5ca7e9344733968c72704eb15ff /src/gui/widgets/qcombobox_p.h
downloadQt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.zip
Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.gz
Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.bz2
Long live Qt!
Diffstat (limited to 'src/gui/widgets/qcombobox_p.h')
-rw-r--r--src/gui/widgets/qcombobox_p.h410
1 files changed, 410 insertions, 0 deletions
diff --git a/src/gui/widgets/qcombobox_p.h b/src/gui/widgets/qcombobox_p.h
new file mode 100644
index 0000000..f1203dc
--- /dev/null
+++ b/src/gui/widgets/qcombobox_p.h
@@ -0,0 +1,410 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOMBOBOX_P_H
+#define QCOMBOBOX_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtGui/qcombobox.h"
+
+#ifndef QT_NO_COMBOBOX
+#include "QtGui/qabstractslider.h"
+#include "QtGui/qapplication.h"
+#include "QtGui/qitemdelegate.h"
+#include "QtGui/qstandarditemmodel.h"
+#include "QtGui/qlineedit.h"
+#include "QtGui/qlistview.h"
+#include "QtGui/qpainter.h"
+#include "QtGui/qstyle.h"
+#include "QtGui/qstyleoption.h"
+#include "QtCore/qhash.h"
+#include "QtCore/qpair.h"
+#include "QtCore/qtimer.h"
+#include "private/qwidget_p.h"
+#include "QtCore/qpointer.h"
+#include "QtGui/qcompleter.h"
+#include "QtGui/qevent.h"
+#include "QtCore/qdebug.h"
+
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
+class QComboBoxListView : public QListView
+{
+ Q_OBJECT
+public:
+ QComboBoxListView(QComboBox *cmb = 0) : combo(cmb) {}
+
+protected:
+ void resizeEvent(QResizeEvent *event)
+ {
+ resizeContents(viewport()->width(), contentsSize().height());
+ QListView::resizeEvent(event);
+ }
+
+ QStyleOptionViewItem viewOptions() const
+ {
+ QStyleOptionViewItem option = QListView::viewOptions();
+ option.showDecorationSelected = true;
+ if (combo)
+ option.font = combo->font();
+ return option;
+ }
+
+ void paintEvent(QPaintEvent *e)
+ {
+ if (combo) {
+ QStyleOptionComboBox opt;
+ opt.initFrom(combo);
+ opt.editable = combo->isEditable();
+ if (combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo)) {
+ //we paint the empty menu area to avoid having blank space that can happen when scrolling
+ QStyleOptionMenuItem menuOpt;
+ menuOpt.initFrom(this);
+ menuOpt.palette = palette();
+ menuOpt.state = QStyle::State_None;
+ menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
+ menuOpt.menuRect = e->rect();
+ menuOpt.maxIconWidth = 0;
+ menuOpt.tabWidth = 0;
+ QPainter p(viewport());
+ combo->style()->drawControl(QStyle::CE_MenuEmptyArea, &menuOpt, &p, this);
+ }
+ }
+ QListView::paintEvent(e);
+ }
+
+private:
+ QComboBox *combo;
+};
+
+
+class QStandardItemModel;
+
+class Q_AUTOTEST_EXPORT QComboBoxPrivateScroller : public QWidget
+{
+ Q_OBJECT
+
+public:
+ QComboBoxPrivateScroller(QAbstractSlider::SliderAction action, QWidget *parent)
+ : QWidget(parent), sliderAction(action)
+ {
+ setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
+ setAttribute(Qt::WA_NoMousePropagation);
+ }
+ QSize sizeHint() const {
+ return QSize(20, style()->pixelMetric(QStyle::PM_MenuScrollerHeight));
+ }
+
+protected:
+ inline void stopTimer() {
+ timer.stop();
+ }
+
+ inline void startTimer() {
+ timer.start(100, this);
+ fast = false;
+ }
+
+ void enterEvent(QEvent *) {
+ startTimer();
+ }
+
+ void leaveEvent(QEvent *) {
+ stopTimer();
+ }
+ void timerEvent(QTimerEvent *e) {
+ if (e->timerId() == timer.timerId()) {
+ emit doScroll(sliderAction);
+ if (fast) {
+ emit doScroll(sliderAction);
+ emit doScroll(sliderAction);
+ }
+ }
+ }
+ void hideEvent(QHideEvent *) {
+ stopTimer();
+ }
+
+ void mouseMoveEvent(QMouseEvent *e)
+ {
+ // Enable fast scrolling if the cursor is directly above or below the popup.
+ const int mouseX = e->pos().x();
+ const int mouseY = e->pos().y();
+ const bool horizontallyInside = pos().x() < mouseX && mouseX < rect().right() + 1;
+ const bool verticallyOutside = (sliderAction == QAbstractSlider::SliderSingleStepAdd) ?
+ rect().bottom() + 1 < mouseY : mouseY < pos().y();
+
+ fast = horizontallyInside && verticallyOutside;
+ }
+
+ void paintEvent(QPaintEvent *) {
+ QPainter p(this);
+ QStyleOptionMenuItem menuOpt;
+ menuOpt.init(this);
+ menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
+ menuOpt.menuRect = rect();
+ menuOpt.maxIconWidth = 0;
+ menuOpt.tabWidth = 0;
+ menuOpt.menuItemType = QStyleOptionMenuItem::Scroller;
+ if (sliderAction == QAbstractSlider::SliderSingleStepAdd)
+ menuOpt.state |= QStyle::State_DownArrow;
+ p.eraseRect(rect());
+ style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p);
+ }
+
+Q_SIGNALS:
+ void doScroll(int action);
+
+private:
+ QAbstractSlider::SliderAction sliderAction;
+ QBasicTimer timer;
+ bool fast;
+};
+
+class Q_AUTOTEST_EXPORT QComboBoxPrivateContainer : public QFrame
+{
+ Q_OBJECT
+
+public:
+ QComboBoxPrivateContainer(QAbstractItemView *itemView, QComboBox *parent);
+ QAbstractItemView *itemView() const;
+ void setItemView(QAbstractItemView *itemView);
+ int spacing() const;
+ void updateTopBottomMargin();
+
+ QTimer blockMouseReleaseTimer;
+ QBasicTimer adjustSizeTimer;
+ QPoint initialClickPosition;
+
+public Q_SLOTS:
+ void scrollItemView(int action);
+ void updateScrollers();
+ void setCurrentIndex(const QModelIndex &index);
+ void viewDestroyed();
+
+protected:
+ void changeEvent(QEvent *e);
+ bool eventFilter(QObject *o, QEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void showEvent(QShowEvent *e);
+ void hideEvent(QHideEvent *e);
+ void timerEvent(QTimerEvent *timerEvent);
+ void leaveEvent(QEvent *e);
+ void resizeEvent(QResizeEvent *e);
+ QStyleOptionComboBox comboStyleOption() const;
+
+Q_SIGNALS:
+ void itemSelected(const QModelIndex &);
+ void resetButton();
+
+private:
+ QComboBox *combo;
+ QAbstractItemView *view;
+ QComboBoxPrivateScroller *top;
+ QComboBoxPrivateScroller *bottom;
+};
+
+class QComboMenuDelegate : public QAbstractItemDelegate
+{
+public:
+ QComboMenuDelegate(QObject *parent, QComboBox *cmb) : QAbstractItemDelegate(parent), mCombo(cmb) {}
+
+protected:
+ void paint(QPainter *painter,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const {
+ QStyleOptionMenuItem opt = getStyleOption(option, index);
+ painter->eraseRect(option.rect);
+ mCombo->style()->drawControl(QStyle::CE_MenuItem, &opt, painter, mCombo);
+ }
+ QSize sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const {
+ QStyleOptionMenuItem opt = getStyleOption(option, index);
+ return mCombo->style()->sizeFromContents(
+ QStyle::CT_MenuItem, &opt, option.rect.size(), mCombo);
+ }
+
+private:
+ QStyleOptionMenuItem getStyleOption(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+ QComboBox *mCombo;
+};
+
+// Note that this class is intentionally not using QStyledItemDelegate
+// Vista does not use the new theme for combo boxes and there might
+// be other side effects from using the new class
+class QComboBoxDelegate : public QItemDelegate
+{
+public:
+ QComboBoxDelegate(QObject *parent, QComboBox *cmb) : QItemDelegate(parent), mCombo(cmb) {}
+
+ static bool isSeparator(const QModelIndex &index) {
+ return index.data(Qt::AccessibleDescriptionRole).toString() == QString::fromLatin1("separator");
+ }
+ static void setSeparator(QAbstractItemModel *model, const QModelIndex &index) {
+ model->setData(index, QString::fromLatin1("separator"), Qt::AccessibleDescriptionRole);
+ if (QStandardItemModel *m = qobject_cast<QStandardItemModel*>(model))
+ if (QStandardItem *item = m->itemFromIndex(index))
+ item->setFlags(item->flags() & ~(Qt::ItemIsSelectable|Qt::ItemIsEnabled));
+ }
+
+protected:
+ void paint(QPainter *painter,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const {
+ if (isSeparator(index)) {
+ QRect rect = option.rect;
+ if (const QStyleOptionViewItemV3 *v3 = qstyleoption_cast<const QStyleOptionViewItemV3*>(&option))
+ if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView*>(v3->widget))
+ rect.setWidth(view->viewport()->width());
+ QStyleOption opt;
+ opt.rect = rect;
+ mCombo->style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, painter, mCombo);
+ } else {
+ QItemDelegate::paint(painter, option, index);
+ }
+ }
+
+ QSize sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const {
+ if (isSeparator(index)) {
+ int pm = mCombo->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, mCombo);
+ return QSize(pm, pm);
+ }
+ return QItemDelegate::sizeHint(option, index);
+ }
+private:
+ QComboBox *mCombo;
+};
+
+class QComboBoxPrivate : public QWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(QComboBox)
+public:
+ QComboBoxPrivate();
+ ~QComboBoxPrivate() {}
+ void init();
+ QComboBoxPrivateContainer* viewContainer();
+ void updateLineEditGeometry();
+ void _q_returnPressed();
+ void _q_complete();
+ void _q_itemSelected(const QModelIndex &item);
+ bool contains(const QString &text, int role);
+ void emitActivated(const QModelIndex&);
+ void _q_emitHighlighted(const QModelIndex&);
+ void _q_emitCurrentIndexChanged(const QModelIndex &index);
+ void _q_modelDestroyed();
+ void _q_modelReset();
+#ifdef QT_KEYPAD_NAVIGATION
+ void _q_completerActivated();
+#endif
+ void _q_resetButton();
+ void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void _q_rowsAboutToBeInserted(const QModelIndex & parent, int start, int end);
+ void _q_rowsInserted(const QModelIndex & parent, int start, int end);
+ void _q_rowsAboutToBeRemoved(const QModelIndex & parent, int start, int end);
+ void _q_rowsRemoved(const QModelIndex & parent, int start, int end);
+ void updateArrow(QStyle::StateFlag state);
+ bool updateHoverControl(const QPoint &pos);
+ QRect popupGeometry(int screen = -1) const;
+ QStyle::SubControl newHoverControl(const QPoint &pos);
+ int computeWidthHint() const;
+ QSize recomputeSizeHint(QSize &sh) const;
+ void adjustComboBoxSize();
+ QString itemText(const QModelIndex &index) const;
+ QIcon itemIcon(const QModelIndex &index) const;
+ int itemRole() const;
+ void updateLayoutDirection();
+ void setCurrentIndex(const QModelIndex &index);
+ void updateDelegate();
+ void keyboardSearchString(const QString &text);
+ void modelChanged();
+
+ QAbstractItemModel *model;
+ QLineEdit *lineEdit;
+ QComboBoxPrivateContainer *container;
+ QComboBox::InsertPolicy insertPolicy;
+ QComboBox::SizeAdjustPolicy sizeAdjustPolicy;
+ int minimumContentsLength;
+ QSize iconSize;
+ uint shownOnce : 1;
+ uint autoCompletion : 1;
+ uint duplicatesEnabled : 1;
+ uint frame : 1;
+ uint padding : 26;
+ int maxVisibleItems;
+ int maxCount;
+ int modelColumn;
+ bool inserting;
+ mutable QSize minimumSizeHint;
+ mutable QSize sizeHint;
+ QStyle::StateFlag arrowState;
+ QStyle::SubControl hoverControl;
+ QRect hoverRect;
+ QPersistentModelIndex currentIndex;
+ QPersistentModelIndex root;
+ Qt::CaseSensitivity autoCompletionCaseSensitivity;
+ int indexBeforeChange;
+#ifndef QT_NO_COMPLETER
+ QPointer<QCompleter> completer;
+#endif
+ static QPalette viewContainerPalette(QComboBox *cmb)
+ { return cmb->d_func()->viewContainer()->palette(); }
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_COMBOBOX
+
+#endif // QCOMBOBOX_P_H