/* * Copyright (C) 2012, 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // self #include "visibleindicatorsmodel.h" #include "rootactionstate.h" #include "indicators.h" #include "cachedunitymenumodel.h" #include // Qt #include VisibleIndicatorsModel::VisibleIndicatorsModel(QObject *parent) : QIdentityProxyModel(parent) { connect(this, SIGNAL(modelReset()), SIGNAL(countChanged())); connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(countChanged())); connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(countChanged())); } VisibleIndicatorsModel::~VisibleIndicatorsModel() { qDeleteAll(m_rootActions); m_rootActions.clear(); qDeleteAll(m_cachedModels); m_cachedModels.clear(); m_visible.clear(); } QHash VisibleIndicatorsModel::roleNames() const { return sourceModel() ? sourceModel()->roleNames() : QHash(); } QString VisibleIndicatorsModel::profile() const { return m_profile; } void VisibleIndicatorsModel::setProfile(const QString& profile) { if (m_profile != profile) { m_profile = profile; Q_EMIT profileChanged(); } } void VisibleIndicatorsModel::setModel(QAbstractItemModel *itemModel) { if (itemModel != sourceModel()) { if (sourceModel() != NULL) { sourceModel()->disconnect(this); } setSourceModel(itemModel); if (sourceModel() != NULL) { // ... and use our own connect(sourceModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(sourceRowsInserted(QModelIndex,int,int))); connect(sourceModel(), SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), SLOT(sourceRowsAboutToBeRemoved(QModelIndex,int,int))); connect(sourceModel(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(sourceDataChanged(QModelIndex,QModelIndex))); } Q_EMIT modelChanged(); } } void VisibleIndicatorsModel::sourceRowsInserted(const QModelIndex&, int start, int end) { for (int row = start; row <= end; row++) { RootActionState* actionState = new RootActionState(); connect(actionState, SIGNAL(updated()), SLOT(onActionStateUpdated())); m_rootActions.insert(row, actionState); m_visible.insert(row, false); m_cachedModels.insert(row, new CachedUnityMenuModel); updateCachedModel(sourceModel()->index(row, 0)); } } void VisibleIndicatorsModel::sourceRowsAboutToBeRemoved(const QModelIndex&, int start, int end) { for (int row = start; row <= end; row++) { if (m_rootActions.count() > start) { delete m_rootActions[start]; m_rootActions.removeAt(start); } if (m_visible.count() > start) { m_visible.removeAt(start); } if (m_cachedModels.count() > start) { delete m_cachedModels[start]; m_cachedModels.removeAt(start); } } } void VisibleIndicatorsModel::sourceDataChanged(const QModelIndex& topRight, const QModelIndex& bottomRight) { for (int row = topRight.row(); row <= bottomRight.row(); row++) { updateCachedModel(sourceModel()->index(row, 0)); } } void VisibleIndicatorsModel::onActionStateUpdated() { RootActionState* actionState = qobject_cast(sender()); int changedRow = m_rootActions.indexOf(actionState); QModelIndex modelIndex = this->index(changedRow, 0); if (!modelIndex.isValid()) { return; } while (m_visible.count() <= changedRow) { m_visible.append(false); } if (actionState->isVisible() != m_visible[changedRow]) { m_visible[changedRow] = actionState->isVisible(); Q_EMIT dataChanged(modelIndex, modelIndex, QVector() << IndicatorsModelRole::IsVisible); } } QVariant VisibleIndicatorsModel::data(const QModelIndex &index, int role) const { if (role != IndicatorsModelRole::IsVisible) return QIdentityProxyModel::data(index, role); if (!index.isValid() || m_visible.count() <= index.row()) return false; return m_visible[index.row()]; } void VisibleIndicatorsModel::updateCachedModel(const QModelIndex& index) { if (!index.isValid()) { return; } QVariant data = sourceModel()->data(index, IndicatorsModelRole::IndicatorProperties); if (!data.isValid()) { return; } int row = index.row(); if (m_cachedModels.count() <= row) { return; } CachedUnityMenuModel* cachedModel = m_cachedModels[row]; QVariantMap properties = data.toMap(); QVariantMap menuObjectPaths = properties["menuObjectPaths"].toMap(); if (!menuObjectPaths.contains(m_profile)) { return; } QString menuObjectPath = menuObjectPaths[m_profile].toString(); QString busName = properties["busName"].toString(); QString actionsObjectPath = properties["actionsObjectPath"].toString(); cachedModel->setBusName(busName); cachedModel->setMenuObjectPath(menuObjectPath); QVariantMap actions; actions["indicator"] = actionsObjectPath; cachedModel->setActions(actions); if (m_rootActions.count() > row) { m_rootActions[row]->setMenu(cachedModel->model()); } }