browsercore/appfw/Api/Bookmarks/modelmenu.cpp
branchGCC_SURGE
changeset 8 2e16851ffecd
parent 2 bf4420e9fa4d
parent 6 1c3b8676e58c
equal deleted inserted replaced
2:bf4420e9fa4d 8:2e16851ffecd
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "modelmenu.h"
       
    20 
       
    21 #include <QtCore/QAbstractItemModel>
       
    22 #include <qdebug.h>
       
    23 
       
    24 
       
    25 ModelMenu::ModelMenu(QWidget * parent)
       
    26     : QMenu(parent)
       
    27     , m_maxRows(7)
       
    28     , m_firstSeparator(-1)
       
    29     , m_maxWidth(-1)
       
    30     , m_hoverRole(0)
       
    31     , m_separatorRole(0)
       
    32     , m_model(0)
       
    33 {
       
    34     connect(this, SIGNAL(aboutToShow()), this, SLOT(aboutToShow()));
       
    35 }
       
    36 
       
    37 bool ModelMenu::prePopulated()
       
    38 {
       
    39     return false;
       
    40 }
       
    41 
       
    42 void ModelMenu::postPopulated()
       
    43 {
       
    44 }
       
    45 
       
    46 void ModelMenu::setModel(QAbstractItemModel *model)
       
    47 {
       
    48     m_model = model;
       
    49 }
       
    50 
       
    51 QAbstractItemModel *ModelMenu::model() const
       
    52 {
       
    53     return m_model;
       
    54 }
       
    55 
       
    56 void ModelMenu::setMaxRows(int max)
       
    57 {
       
    58     m_maxRows = max;
       
    59 }
       
    60 
       
    61 int ModelMenu::maxRows() const
       
    62 {
       
    63     return m_maxRows;
       
    64 }
       
    65 
       
    66 void ModelMenu::setFirstSeparator(int offset)
       
    67 {
       
    68     m_firstSeparator = offset;
       
    69 }
       
    70 
       
    71 int ModelMenu::firstSeparator() const
       
    72 {
       
    73     return m_firstSeparator;
       
    74 }
       
    75 
       
    76 void ModelMenu::setRootIndex(const QModelIndex &index)
       
    77 {
       
    78     m_root = index;
       
    79 }
       
    80 
       
    81 QModelIndex ModelMenu::rootIndex() const
       
    82 {
       
    83     return m_root;
       
    84 }
       
    85 
       
    86 void ModelMenu::setHoverRole(int role)
       
    87 {
       
    88     m_hoverRole = role;
       
    89 }
       
    90 
       
    91 int ModelMenu::hoverRole() const
       
    92 {
       
    93     return m_hoverRole;
       
    94 }
       
    95 
       
    96 void ModelMenu::setSeparatorRole(int role)
       
    97 {
       
    98     m_separatorRole = role;
       
    99 }
       
   100 
       
   101 int ModelMenu::separatorRole() const
       
   102 {
       
   103     return m_separatorRole;
       
   104 }
       
   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 
       
   119     clear();
       
   120     if (prePopulated())
       
   121         addSeparator();
       
   122     int max = m_maxRows;
       
   123     if (max != -1)
       
   124         max += m_firstSeparator;
       
   125     createMenu(m_root, max, this, this);
       
   126     postPopulated();
       
   127 }
       
   128 
       
   129 void ModelMenu::createMenu(const QModelIndex &parent, int max, QMenu *parentMenu, QMenu *menu)
       
   130 {
       
   131     if (!menu) {
       
   132         QString title = parent.data().toString();
       
   133         menu = new QMenu(title, this);
       
   134         QIcon icon = qvariant_cast<QIcon>(parent.data(Qt::DecorationRole));
       
   135         menu->setIcon(icon);
       
   136         parentMenu->addMenu(menu);
       
   137         QVariant v;
       
   138         v.setValue(parent);
       
   139         menu->menuAction()->setData(v);
       
   140         connect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShow()));
       
   141         return;
       
   142     }
       
   143 
       
   144     int end = m_model->rowCount(parent);
       
   145     if (max != -1)
       
   146         end = qMin(max, end);
       
   147 
       
   148     connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(triggered(QAction*)));
       
   149     connect(menu, SIGNAL(hovered(QAction*)), this, SLOT(hovered(QAction*)));
       
   150 
       
   151     for (int i = 0; i < end; ++i) {
       
   152         QModelIndex idx = m_model->index(i, 0, parent);
       
   153         if (m_model->hasChildren(idx)) {
       
   154             createMenu(idx, -1, menu);
       
   155         } else {
       
   156             if (m_separatorRole != 0
       
   157                 && idx.data(m_separatorRole).toBool())
       
   158                 addSeparator();
       
   159             else
       
   160                 menu->addAction(makeAction(idx));
       
   161         }
       
   162         if (menu == this && i == m_firstSeparator - 1)
       
   163             addSeparator();
       
   164     }
       
   165 }
       
   166 
       
   167 QAction *ModelMenu::makeAction(const QModelIndex &index)
       
   168 {
       
   169     QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
       
   170     QAction *action = makeAction(icon, index.data().toString(), this);
       
   171     QVariant v;
       
   172     v.setValue(index);
       
   173     action->setData(v);
       
   174     return action;
       
   175 }
       
   176 
       
   177 QAction *ModelMenu::makeAction(const QIcon &icon, const QString &text, QObject *parent)
       
   178 {
       
   179     QFontMetrics fm(font());
       
   180     if (-1 == m_maxWidth)
       
   181         m_maxWidth = fm.width(QLatin1Char('m')) * 30;
       
   182     QString smallText = fm.elidedText(text, Qt::ElideMiddle, m_maxWidth);
       
   183     return new QAction(icon, smallText, parent);
       
   184 }
       
   185 
       
   186 void ModelMenu::triggered(QAction *action)
       
   187 {
       
   188     QVariant v = action->data();
       
   189     if (v.canConvert<QModelIndex>()) {
       
   190         QModelIndex idx = qvariant_cast<QModelIndex>(v);
       
   191         emit activated(idx);
       
   192     }
       
   193 }
       
   194 
       
   195 void ModelMenu::hovered(QAction *action)
       
   196 {
       
   197     QVariant v = action->data();
       
   198     if (v.canConvert<QModelIndex>()) {
       
   199         QModelIndex idx = qvariant_cast<QModelIndex>(v);
       
   200         QString hoveredString = idx.data(m_hoverRole).toString();
       
   201         if (!hoveredString.isEmpty())
       
   202             emit hovered(hoveredString);
       
   203     }
       
   204 }
       
   205