|  | Home · All Classes · Main Classes · Grouped Classes · Modules · Functions |

# modelmenu.cpp Example File
demos/browser/modelmenu.cpp

     /****************************************************************************
     **
     ** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved.
     **
     ** This file is part of the documentation of the Qt Toolkit.
     **
     ** This file may be used under the terms of the GNU General Public
    ** License versions 2.0 or 3.0 as published by the Free Software
    ** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
    ** included in the packaging of this file.  Alternatively you may (at
    ** your option) use any later version of the GNU General Public
    ** License if such license has been publicly approved by Trolltech ASA
    ** (or its successors, if any) and the KDE Free Qt Foundation. In
    ** addition, as a special exception, Trolltech gives you certain
    ** additional rights. These rights are described in the Trolltech GPL
    ** Exception version 1.2, which can be found at
    ** http://www.trolltech.com/products/qt/gplexception/ and in the file
    ** GPL_EXCEPTION.txt in this package.
    **
    ** Please review the following information to ensure GNU General
    ** Public Licensing requirements will be met:
    ** http://trolltech.com/products/qt/licenses/licensing/opensource/. If
    ** you are unsure which license is appropriate for your use, please
    ** review the following information:
    ** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
    ** or contact the sales department at sales@trolltech.com.
    **
    ** In addition, as a special exception, Trolltech, as the sole
    ** copyright holder for Qt Designer, grants users of the Qt/Eclipse
    ** Integration plug-in the right for the Qt/Eclipse Integration to
    ** link to functionality provided by Qt Designer and its related
    ** libraries.
    **
    ** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
    ** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
    ** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly
    ** granted herein.
     **
     ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
     ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
     **
     ****************************************************************************/

     #include "modelmenu.h"

     #include <QtCore/QAbstractItemModel>
     #include <qdebug.h>

     ModelMenu::ModelMenu(QAbstractItemModel *model, QWidget * parent): QMenu(parent),
         m_maxRows(7),
         m_maxWidth(-1),
         m_model(model)
     {
         connect(this, SIGNAL(aboutToShow()), this, SLOT(aboutToShow()));
     }

     bool ModelMenu::prePopulated()
     {
         return false;
     }

     void ModelMenu::postPopulated()
     {
     }

     QAbstractItemModel *ModelMenu::model() const
     {
         return m_model;
     }

     void ModelMenu::setMaxRows(int max)
     {
         m_maxRows = max;
     }

     int ModelMenu::maxRows() const
     {
         return m_maxRows;
     }

     Q_DECLARE_METATYPE(QModelIndex)
     void ModelMenu::aboutToShow()
     {
         if (QMenu *menu = qobject_cast<QMenu*>(sender())) {
             QVariant v = menu->menuAction()->data();
             if (v.canConvert<int>()) {
                 int row = v.toInt();
                 QModelIndex idx = m_model->index(row, 0);
                 createMenu(idx, -1, menu);
                 disconnect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShow()));
                 return;
             }
         }

         clear();
         if (prePopulated())
             addSeparator();
         createMenu(QModelIndex(), m_maxRows, this);
         postPopulated();
     }

     void ModelMenu::createMenu(const QModelIndex &parent, int max, QMenu *menu)
     {
         // for history, remove somehow
         if (parent.row() == 0 && !menu && m_model->rowCount(parent) < 20)
             return;

         if (!menu) {
             QString title = parent.data().toString();
             menu = new QMenu(title, this);
             addMenu(menu);
             menu->menuAction()->setData(parent.row());
             connect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShow()));
             return;
         }

         int end = m_model->rowCount(parent);
         if (max != -1)
             end = qMin(max, end);

         connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(triggered(QAction*)));

         // for history, remove somehow
         int start = 0;
         if (parent.row() == 0 && menu != this)
             start = 20;

         for (int i = start; i < end; ++i) {
             QModelIndex idx = m_model->index(i, 0, parent);
             if (m_model->hasChildren(idx))
                 createMenu(idx, -1);
             else
                 menu->addAction(makeAction(idx));
         }
     }

     QAction *ModelMenu::makeAction(const QModelIndex &index)
     {
         QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
         QAction *action = makeAction(icon, index.data().toString(), this);
         QVariant v;
         v.setValue(index);
         action->setData(v);
         return action;
     }

     QAction *ModelMenu::makeAction(const QIcon &icon, const QString &text, QObject *parent)
     {
         QFontMetrics fm(font());
         if (-1 == m_maxWidth)
             m_maxWidth = fm.width("m") * 30;
         QString smallText = fm.elidedText(text, Qt::ElideMiddle, m_maxWidth);
         return new QAction(icon, smallText, parent);
     }

     void ModelMenu::triggered(QAction *action)
     {
         QVariant v = action->data();
         if (v.canConvert<QModelIndex>()) {
             QModelIndex idx = qvariant_cast<QModelIndex>(v);
             emit activated(idx);
         }
     }