modelmenu.cpp
上传用户:huahtool
上传日期:2015-12-10
资源大小:1089k
文件大小:6k
源码类别:

浏览器

开发平台:

Visual C++

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
  4. ** Contact: Qt Software Information (qt-info@nokia.com)
  5. **
  6. ** This file is part of the demonstration applications of the Qt Toolkit.
  7. **
  8. ** Commercial Usage
  9. ** Licensees holding valid Qt Commercial licenses may use this file in
  10. ** accordance with the Qt Commercial License Agreement provided with the
  11. ** Software or, alternatively, in accordance with the terms contained in
  12. ** a written agreement between you and Nokia.
  13. **
  14. **
  15. ** GNU General Public License Usage
  16. ** Alternatively, this file may be used under the terms of the GNU
  17. ** General Public License versions 2.0 or 3.0 as published by the Free
  18. ** Software Foundation and appearing in the file LICENSE.GPL included in
  19. ** the packaging of this file.  Please review the following information
  20. ** to ensure GNU General Public Licensing requirements will be met:
  21. ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
  22. ** http://www.gnu.org/copyleft/gpl.html.  In addition, as a special
  23. ** exception, Nokia gives you certain additional rights. These rights
  24. ** are described in the Nokia Qt GPL Exception version 1.3, included in
  25. ** the file GPL_EXCEPTION.txt in this package.
  26. **
  27. ** Qt for Windows(R) Licensees
  28. ** As a special exception, Nokia, as the sole copyright holder for Qt
  29. ** Designer, grants users of the Qt/Eclipse Integration plug-in the
  30. ** right for the Qt/Eclipse Integration to link to functionality
  31. ** provided by Qt Designer and its related libraries.
  32. **
  33. ** If you are unsure which license is appropriate for your use, please
  34. ** contact the sales department at qt-sales@nokia.com.
  35. **
  36. ****************************************************************************/
  37. #include "modelmenu.h"
  38. #include <QtCore/QAbstractItemModel>
  39. #include <qdebug.h>
  40. ModelMenu::ModelMenu(QWidget * parent)
  41.     : QMenu(parent)
  42.     , m_maxRows(7)
  43.     , m_firstSeparator(-1)
  44.     , m_maxWidth(-1)
  45.     , m_hoverRole(0)
  46.     , m_separatorRole(0)
  47.     , m_model(0)
  48. {
  49.     connect(this, SIGNAL(aboutToShow()), this, SLOT(aboutToShow()));
  50. }
  51. bool ModelMenu::prePopulated()
  52. {
  53.     return false;
  54. }
  55. void ModelMenu::postPopulated()
  56. {
  57. }
  58. void ModelMenu::setModel(QAbstractItemModel *model)
  59. {
  60.     m_model = model;
  61. }
  62. QAbstractItemModel *ModelMenu::model() const
  63. {
  64.     return m_model;
  65. }
  66. void ModelMenu::setMaxRows(int max)
  67. {
  68.     m_maxRows = max;
  69. }
  70. int ModelMenu::maxRows() const
  71. {
  72.     return m_maxRows;
  73. }
  74. void ModelMenu::setFirstSeparator(int offset)
  75. {
  76.     m_firstSeparator = offset;
  77. }
  78. int ModelMenu::firstSeparator() const
  79. {
  80.     return m_firstSeparator;
  81. }
  82. void ModelMenu::setRootIndex(const QModelIndex &index)
  83. {
  84.     m_root = index;
  85. }
  86. QModelIndex ModelMenu::rootIndex() const
  87. {
  88.     return m_root;
  89. }
  90. void ModelMenu::setHoverRole(int role)
  91. {
  92.     m_hoverRole = role;
  93. }
  94. int ModelMenu::hoverRole() const
  95. {
  96.     return m_hoverRole;
  97. }
  98. void ModelMenu::setSeparatorRole(int role)
  99. {
  100.     m_separatorRole = role;
  101. }
  102. int ModelMenu::separatorRole() const
  103. {
  104.     return m_separatorRole;
  105. }
  106. Q_DECLARE_METATYPE(QModelIndex)
  107. void ModelMenu::aboutToShow()
  108. {
  109.     if (QMenu *menu = qobject_cast<QMenu*>(sender())) {
  110.         QVariant v = menu->menuAction()->data();
  111.         if (v.canConvert<QModelIndex>()) {
  112.             QModelIndex idx = qvariant_cast<QModelIndex>(v);
  113.             createMenu(idx, -1, menu, menu);
  114.             disconnect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShow()));
  115.             return;
  116.         }
  117.     }
  118.     clear();
  119.     if (prePopulated())
  120.         addSeparator();
  121.     int max = m_maxRows;
  122.     if (max != -1)
  123.         max += m_firstSeparator;
  124.     createMenu(m_root, max, this, this);
  125.     postPopulated();
  126. }
  127. void ModelMenu::createMenu(const QModelIndex &parent, int max, QMenu *parentMenu, QMenu *menu)
  128. {
  129.     if (!menu) {
  130.         QString title = parent.data().toString();
  131.         menu = new QMenu(title, this);
  132.         QIcon icon = qvariant_cast<QIcon>(parent.data(Qt::DecorationRole));
  133.         menu->setIcon(icon);
  134.         parentMenu->addMenu(menu);
  135.         QVariant v;
  136.         v.setValue(parent);
  137.         menu->menuAction()->setData(v);
  138.         connect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShow()));
  139.         return;
  140.     }
  141.     int end = m_model->rowCount(parent);
  142.     if (max != -1)
  143.         end = qMin(max, end);
  144.     connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(triggered(QAction*)));
  145.     connect(menu, SIGNAL(hovered(QAction*)), this, SLOT(hovered(QAction*)));
  146.     for (int i = 0; i < end; ++i) {
  147.         QModelIndex idx = m_model->index(i, 0, parent);
  148.         if (m_model->hasChildren(idx)) {
  149.             createMenu(idx, -1, menu);
  150.         } else {
  151.             if (m_separatorRole != 0
  152.                 && idx.data(m_separatorRole).toBool())
  153.                 addSeparator();
  154.             else
  155.                 menu->addAction(makeAction(idx));
  156.         }
  157.         if (menu == this && i == m_firstSeparator - 1)
  158.             addSeparator();
  159.     }
  160. }
  161. QAction *ModelMenu::makeAction(const QModelIndex &index)
  162. {
  163.     QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
  164.     QAction *action = makeAction(icon, index.data().toString(), this);
  165.     QVariant v;
  166.     v.setValue(index);
  167.     action->setData(v);
  168.     return action;
  169. }
  170. QAction *ModelMenu::makeAction(const QIcon &icon, const QString &text, QObject *parent)
  171. {
  172.     QFontMetrics fm(font());
  173.     if (-1 == m_maxWidth)
  174.         m_maxWidth = fm.width(QLatin1Char('m')) * 30;
  175.     QString smallText = fm.elidedText(text, Qt::ElideMiddle, m_maxWidth);
  176.     return new QAction(icon, smallText, parent);
  177. }
  178. void ModelMenu::triggered(QAction *action)
  179. {
  180.     QVariant v = action->data();
  181.     if (v.canConvert<QModelIndex>()) {
  182.         QModelIndex idx = qvariant_cast<QModelIndex>(v);
  183.         emit activated(idx);
  184.     }
  185. }
  186. void ModelMenu::hovered(QAction *action)
  187. {
  188.     QVariant v = action->data();
  189.     if (v.canConvert<QModelIndex>()) {
  190.         QModelIndex idx = qvariant_cast<QModelIndex>(v);
  191.         QString hoveredString = idx.data(m_hoverRole).toString();
  192.         if (!hoveredString.isEmpty())
  193.             emit hovered(hoveredString);
  194.     }
  195. }