/* Copyright © 2017 Hasan Yavuz Özderya This file is part of serialplot. serialplot 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, either version 3 of the License, or (at your option) any later version. serialplot 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 serialplot. If not, see . */ #include "channelinfomodel.h" #include "setting_defines.h" const QColor colors[8] = { QColor(237,97,68), QColor(92,200,96), QColor(225,98,207), QColor(163,195,58), QColor(148,123,239), QColor(212,182,52), QColor(238,82,133), QColor(219,136,44) }; ChannelInfoModel::ChannelInfoModel(unsigned numberOfChannels, QObject* parent) : QAbstractTableModel(parent) { _numOfChannels = 0; setNumOfChannels(numberOfChannels); } int ChannelInfoModel::rowCount(const QModelIndex &parent) const { return _numOfChannels; } int ChannelInfoModel::columnCount(const QModelIndex & parent) const { return COLUMN_COUNT; } Qt::ItemFlags ChannelInfoModel::flags(const QModelIndex &index) const { if (index.column() == COLUMN_NAME) { return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable; } else if (index.column() == COLUMN_VISIBILITY) { return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable; } return Qt::NoItemFlags; } QVariant ChannelInfoModel::data(const QModelIndex &index, int role) const { // check index if (index.row() >= (int) _numOfChannels || index.row() < 0) { return QVariant(); } // get color if (role == Qt::ForegroundRole) { return infos[index.row()].color; } // get name if (index.column() == COLUMN_NAME) { if (role == Qt::DisplayRole || role == Qt::EditRole) { return QVariant(infos[index.row()].name); } } // get visibility else if (index.column() == COLUMN_VISIBILITY) { if (role == Qt::CheckStateRole) { bool visible = infos[index.row()].visibility; return visible ? Qt::Checked : Qt::Unchecked; } } return QVariant(); } QVariant ChannelInfoModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal) { if (role == Qt::DisplayRole) { if (section == COLUMN_NAME) { return tr("Channel"); } else if (section == COLUMN_VISIBILITY) { return tr("Visible"); } } } else // vertical { if (section < (int) _numOfChannels && role == Qt::DisplayRole) { return QString::number(section + 1); } } return QVariant(); } bool ChannelInfoModel::setData(const QModelIndex &index, const QVariant &value, int role) { // check index if (index.row() >= (int) _numOfChannels || index.row() < 0) { return false; } // set color if (role == Qt::ForegroundRole) { infos[index.row()].color = value.value(); emit dataChanged(index, index, QVector({Qt::ForegroundRole})); return true; } // set name if (index.column() == COLUMN_NAME) { if (role == Qt::DisplayRole || role == Qt::EditRole) { infos[index.row()].name = value.toString(); emit dataChanged(index, index, QVector({role})); return true; } } // set visibility else if (index.column() == COLUMN_VISIBILITY) { if (role == Qt::CheckStateRole) { bool checked = value.toInt() == Qt::Checked; infos[index.row()].visibility = checked; emit dataChanged(index, index, QVector({role})); return true; } } // invalid index/role return false; } void ChannelInfoModel::setNumOfChannels(unsigned number) { if (number == _numOfChannels) return; bool isInserting = number > _numOfChannels; if (isInserting) { beginInsertRows(QModelIndex(), _numOfChannels, number-1); } else { beginRemoveRows(QModelIndex(), number, _numOfChannels-1); } // we create channel info but never remove channel info to // remember user entered info if ((int) number > infos.length()) { for (unsigned ci = _numOfChannels; ci < number; ci++) { infos.append({QString("Channel %1").arg(ci+1), true, colors[ci % 8]}); } } // make sure newly available channels are visible, we don't // remember visibility option intentionally so that user doesn't // get confused if (number > _numOfChannels) { for (unsigned ci = _numOfChannels; ci < number; ci++) { infos[ci].visibility = true; } } _numOfChannels = number; if (isInserting) { endInsertRows(); } else { endRemoveRows(); } } void ChannelInfoModel::saveSettings(QSettings* settings) { settings->beginGroup(SettingGroup_Channels); settings->beginWriteArray(SG_Channels_Channel); // save all channel information regardless of current number of channels for (unsigned ci = 0; (int) ci < infos.length(); ci++) { settings->setArrayIndex(ci); settings->setValue(SG_Channels_Name, infos[ci].name); settings->setValue(SG_Channels_Color, infos[ci].color); settings->setValue(SG_Channels_Visible, infos[ci].visibility); } settings->endArray(); settings->endGroup(); } void ChannelInfoModel::loadSettings(QSettings* settings) { settings->beginGroup(SettingGroup_Channels); unsigned size = settings->beginReadArray(SG_Channels_Channel); for (unsigned ci = 0; ci < size; ci++) { settings->setArrayIndex(ci); ChannelInfo chanInfo; chanInfo.name = settings->value(SG_Channels_Name, QString(tr("Channel %1")).arg(ci+1)).toString(); chanInfo.color = settings->value(SG_Channels_Color, colors[ci % 8]).value(); chanInfo.visibility = settings->value(SG_Channels_Visible, true).toBool(); if ((int) ci < infos.size()) { infos[ci] = chanInfo; if (ci < _numOfChannels) { auto roles = QVector({ Qt::DisplayRole, Qt::EditRole, Qt::ForegroundRole, Qt::CheckStateRole}); emit dataChanged(index(ci, 0), index(ci, COLUMN_COUNT-1), roles); } } else { infos.append(chanInfo); } } settings->endArray(); settings->endGroup(); }