diff --git a/src/libs/utils/treeviewcombobox.cpp b/src/libs/utils/treeviewcombobox.cpp new file mode 100644 index 00000000000..804b0e6eb8c --- /dev/null +++ b/src/libs/utils/treeviewcombobox.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "treeviewcombobox.h" + +#include + +using namespace Utils; + +TreeViewComboBoxView::TreeViewComboBoxView(QWidget *parent) + : QTreeView(parent) +{ + // TODO: Disable the root for all items (with a custom delegate?) + setRootIsDecorated(false); +} + +void TreeViewComboBoxView::adjustWidth(int width) +{ + setMaximumWidth(width); + setMinimumWidth(qMin(qMax(sizeHintForColumn(0), minimumSizeHint().width()), width)); +} + + +TreeViewComboBox::TreeViewComboBox(QWidget *parent) + : QComboBox(parent), m_skipNextHide(false) +{ + m_view = new TreeViewComboBoxView; + m_view->setHeaderHidden(true); + m_view->setItemsExpandable(true); + setView(m_view); + m_view->viewport()->installEventFilter(this); +} + +void TreeViewComboBox::wheelEvent(QWheelEvent *e) +{ + QModelIndex index = m_view->currentIndex(); + if (e->delta() > 0) { + do + index = m_view->indexAbove(index); + while (index.isValid() && !(model()->flags(index) & Qt::ItemIsSelectable)); + } else if (e->delta() < 0) { + do + index = m_view->indexBelow(index); + while (index.isValid() && !(model()->flags(index) & Qt::ItemIsSelectable)); + } + e->accept(); + if (!index.isValid()) + return; + + setCurrentIndex(index); + + // for compatibility we emit activated with a useless row parameter + emit activated(index.row()); +} + +void TreeViewComboBox::setCurrentIndex(const QModelIndex &index) +{ + setRootModelIndex(model()->parent(index)); + QComboBox::setCurrentIndex(index.row()); + setRootModelIndex(QModelIndex()); + m_view->setCurrentIndex(index); +} + +bool TreeViewComboBox::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::MouseButtonPress && object == view()->viewport()) { + QMouseEvent* mouseEvent = static_cast(event); + QModelIndex index = view()->indexAt(mouseEvent->pos()); + if (!view()->visualRect(index).contains(mouseEvent->pos())) + m_skipNextHide = true; + } + return false; +} + +void TreeViewComboBox::showPopup() +{ + m_view->adjustWidth(topLevelWidget()->geometry().width()); + QComboBox::showPopup(); +} + +void TreeViewComboBox::hidePopup() +{ + if (m_skipNextHide) + m_skipNextHide = false; + else + QComboBox::hidePopup(); +} + +TreeViewComboBoxView *TreeViewComboBox::view() const +{ + return m_view; +} diff --git a/src/libs/utils/treeviewcombobox.h b/src/libs/utils/treeviewcombobox.h new file mode 100644 index 00000000000..4ea180bc7d3 --- /dev/null +++ b/src/libs/utils/treeviewcombobox.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef TREEVIEWCOMBOBOX_H +#define TREEVIEWCOMBOBOX_H + +#include "utils_global.h" + +#include +#include + +namespace Utils { + +class QTCREATOR_UTILS_EXPORT TreeViewComboBoxView : public QTreeView +{ +public: + TreeViewComboBoxView(QWidget *parent = 0); + void adjustWidth(int width); +}; + +class QTCREATOR_UTILS_EXPORT TreeViewComboBox : public QComboBox +{ +public: + TreeViewComboBox(QWidget *parent = 0); + + void wheelEvent(QWheelEvent *e); + void setCurrentIndex(const QModelIndex &index); + bool eventFilter(QObject* object, QEvent* event); + void showPopup(); + void hidePopup(); + + TreeViewComboBoxView *view() const; + +private: + TreeViewComboBoxView *m_view; + bool m_skipNextHide; +}; +} + +#endif // TREEVIEWCOMBOBOX_H diff --git a/src/libs/utils/utils-lib.pri b/src/libs/utils/utils-lib.pri index f634d596cff..d79a4303ddc 100644 --- a/src/libs/utils/utils-lib.pri +++ b/src/libs/utils/utils-lib.pri @@ -88,7 +88,8 @@ SOURCES += $$PWD/environment.cpp \ $$PWD/execmenu.cpp \ $$PWD/completinglineedit.cpp \ $$PWD/winutils.cpp \ - $$PWD/itemviews.cpp + $$PWD/itemviews.cpp \ + $$PWD/treeviewcombobox.cpp win32:SOURCES += $$PWD/consoleprocess_win.cpp else:SOURCES += $$PWD/consoleprocess_unix.cpp @@ -180,7 +181,8 @@ HEADERS += \ $$PWD/completinglineedit.h \ $$PWD/logging.h \ $$PWD/winutils.h \ - $$PWD/itemviews.h + $$PWD/itemviews.h \ + $$PWD/treeviewcombobox.h FORMS += $$PWD/filewizardpage.ui \ $$PWD/projectintropage.ui \ diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs index b707ac690b0..c80f13e6b7f 100644 --- a/src/libs/utils/utils.qbs +++ b/src/libs/utils/utils.qbs @@ -171,6 +171,8 @@ QtcLibrary { "tcpportsgatherer.h", "textfileformat.cpp", "textfileformat.h", + "treeviewcombobox.cpp", + "treeviewcombobox.h", "headerviewstretcher.cpp", "headerviewstretcher.h", "uncommentselection.cpp", diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index b6e1612a065..d77313f1888 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -65,6 +65,7 @@ #include #include +#include #include #include @@ -79,8 +80,6 @@ #include #include #include -#include -#include #include #include @@ -96,97 +95,6 @@ using namespace CppEditor::Internal; namespace { -class OverviewTreeView : public QTreeView -{ -public: - OverviewTreeView(QWidget *parent = 0) - : QTreeView(parent) - { - // TODO: Disable the root for all items (with a custom delegate?) - setRootIsDecorated(false); - } - - void adjustWidth(int width) - { - setMaximumWidth(width); - setMinimumWidth(qMin(qMax(sizeHintForColumn(0), minimumSizeHint().width()), width)); - } -}; - -class OverviewCombo : public QComboBox -{ -public: - OverviewCombo(QWidget *parent = 0) - : QComboBox(parent), m_skipNextHide(false) - { - m_view = new OverviewTreeView; - m_view->setHeaderHidden(true); - m_view->setItemsExpandable(true); - setView(m_view); - m_view->viewport()->installEventFilter(this); - } - - void wheelEvent(QWheelEvent *e) - { - QModelIndex index = m_view->currentIndex(); - if (e->delta() > 0) { - do - index = m_view->indexAbove(index); - while (index.isValid() && !(model()->flags(index) & Qt::ItemIsSelectable)); - } else if (e->delta() < 0) { - do - index = m_view->indexBelow(index); - while (index.isValid() && !(model()->flags(index) & Qt::ItemIsSelectable)); - } - e->accept(); - if (!index.isValid()) - return; - - setCurrentIndex(index); - - // for compatibility we emit activated with a useless row parameter - emit activated(index.row()); - } - void setCurrentIndex(const QModelIndex &index) - { - setRootModelIndex(model()->parent(index)); - QComboBox::setCurrentIndex(index.row()); - setRootModelIndex(QModelIndex()); - m_view->setCurrentIndex(index); - } - bool eventFilter(QObject* object, QEvent* event) - { - if (event->type() == QEvent::MouseButtonPress && object == view()->viewport()) { - QMouseEvent* mouseEvent = static_cast(event); - QModelIndex index = view()->indexAt(mouseEvent->pos()); - if (!view()->visualRect(index).contains(mouseEvent->pos())) - m_skipNextHide = true; - } - return false; - } - void showPopup() - { - m_view->adjustWidth(topLevelWidget()->geometry().width()); - QComboBox::showPopup(); - } - void hidePopup() - { - if (m_skipNextHide) - m_skipNextHide = false; - else - QComboBox::hidePopup(); - } - - OverviewTreeView *view() const - { - return m_view; - } - -private: - OverviewTreeView *m_view; - bool m_skipNextHide; -}; - class OverviewProxyModel : public QSortFilterProxyModel { Q_OBJECT @@ -627,7 +535,7 @@ TextEditor::BaseTextEditor *CPPEditorWidget::createEditor() void CPPEditorWidget::createToolBar(CPPEditor *editor) { - m_outlineCombo = new OverviewCombo; + m_outlineCombo = new Utils::TreeViewComboBox; m_outlineCombo->setMinimumContentsLength(22); // Make the combo box prefer to expand @@ -1097,7 +1005,7 @@ void CPPEditorWidget::updateOutlineNow() m_outlineModel->rebuild(document); - static_cast(m_outlineCombo->view())->expandAll(); + m_outlineCombo->view()->expandAll(); updateOutlineIndexNow(); } @@ -1153,7 +1061,7 @@ void CPPEditorWidget::updateOutlineIndexNow() if (comboIndex.isValid()) { bool blocked = m_outlineCombo->blockSignals(true); - static_cast(m_outlineCombo)->setCurrentIndex(m_proxyModel->mapFromSource(comboIndex)); + m_outlineCombo->setCurrentIndex(m_proxyModel->mapFromSource(comboIndex)); updateOutlineToolTip(); diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h index ef1c3949884..86fab946aef 100644 --- a/src/plugins/cppeditor/cppeditor.h +++ b/src/plugins/cppeditor/cppeditor.h @@ -65,6 +65,7 @@ class CppRefactoringFile; } namespace TextEditor { class FontSettings; } +namespace Utils { class TreeViewComboBox; } namespace CppEditor { namespace Internal { @@ -235,7 +236,7 @@ private: QPointer m_modelManager; CPPEditorDocument *m_cppEditorDocument; - QComboBox *m_outlineCombo; + Utils::TreeViewComboBox *m_outlineCombo; CPlusPlus::OverviewModel *m_outlineModel; QModelIndex m_outlineModelIndex; QSortFilterProxyModel *m_proxyModel;