/*
* Copyright (C) 2016-2017 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 .
*/
#include "MirSurfaceListModel.h"
#include "ApplicationInfo.h"
#include
#define MIRSURFACELISTMODEL_DEBUG 0
#if MIRSURFACELISTMODEL_DEBUG
#include
#define DEBUG_MSG(params) qDebug().nospace() << "MirSurfaceListModel::" << __func__ << params
#else
#define DEBUG_MSG(params) ((void)0)
#endif
using namespace unity::shell::application;
MirSurfaceListModel::MirSurfaceListModel(QObject *parent) :
MirSurfaceListInterface(parent)
{
}
int MirSurfaceListModel::rowCount(const QModelIndex &parent) const
{
return !parent.isValid() ? m_surfaceList.size() : 0;
}
QVariant MirSurfaceListModel::data(const QModelIndex& index, int role) const
{
if (index.row() < 0 || index.row() >= m_surfaceList.size())
return QVariant();
if (role == SurfaceRole) {
MirSurfaceInterface *surface = m_surfaceList.at(index.row());
return QVariant::fromValue(static_cast(surface));
} else {
return QVariant();
}
}
void MirSurfaceListModel::raise(MirSurfaceInterface *surface)
{
DEBUG_MSG("(" << surface << ")");
int i = m_surfaceList.indexOf(surface);
if (i != -1) {
moveSurface(i, 0);
}
}
void MirSurfaceListModel::addSurface(MirSurfaceInterface *surface)
{
DEBUG_MSG("(" << surface << ")");
beginInsertRows(QModelIndex(), 0, 0);
m_surfaceList.prepend(surface);
connectSurface(surface);
endInsertRows();
Q_EMIT countChanged(m_surfaceList.count());
Q_EMIT firstChanged();
}
void MirSurfaceListModel::connectSurface(MirSurfaceInterface *surface)
{
connect(surface, &QObject::destroyed, this, [this, surface](){ this->removeSurface(surface); });
connect(surface, &MirSurfaceInterface::focusedChanged, this, [this, surface](bool surfaceFocused){
if (surfaceFocused) {
raise(surface);
}
});
}
void MirSurfaceListModel::removeSurface(MirSurfaceInterface *surface)
{
int i = m_surfaceList.indexOf(surface);
if (i != -1) {
beginRemoveRows(QModelIndex(), i, i);
m_surfaceList.removeAt(i);
endRemoveRows();
Q_EMIT countChanged(m_surfaceList.count());
if (m_surfaceList.count() == 0 || i == 0) {
Q_EMIT firstChanged();
}
}
}
void MirSurfaceListModel::moveSurface(int from, int to)
{
if (from == to) return;
if (from >= 0 && from < m_surfaceList.size() && to >= 0 && to < m_surfaceList.size()) {
QModelIndex parent;
/* When moving an item down, the destination index needs to be incremented
by one, as explained in the documentation:
http://qt-project.org/doc/qt-5.0/qtcore/qabstractitemmodel.html#beginMoveRows */
beginMoveRows(parent, from, from, parent, to + (to > from ? 1 : 0));
m_surfaceList.move(from, to);
endMoveRows();
}
if ((from == 0 || to == 0) && m_surfaceList.count() > 1) {
Q_EMIT firstChanged();
}
}
MirSurfaceInterface *MirSurfaceListModel::get(int index)
{
if (index >=0 && index < m_surfaceList.count()) {
return m_surfaceList[index];
} else {
return nullptr;
}
}
const MirSurfaceInterface *MirSurfaceListModel::get(int index) const
{
if (index >=0 && index < m_surfaceList.count()) {
return m_surfaceList.at(index);
} else {
return nullptr;
}
}