#include "DecodeHighlightingModel.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include "pimpl_impl.hpp" #include "moc_DecodeHighlightingModel.cpp" class DecodeHighlightingModel::impl final { public: explicit impl () : data_ {defaults_} { } HighlightItems static const defaults_; HighlightItems data_; QFont font_; }; QList const DecodeHighlightingModel::impl::defaults_ = { {Highlight::MyCall, true, {}, {{0xff, 0x66, 0x66}}} , {Highlight::Continent, true, {}, {{0xff, 0x00, 0x63}}} , {Highlight::ContinentBand, true, {}, {{0xff, 0x99, 0xc2}}} , {Highlight::CQZone, true, {}, {{0xff, 0xbf, 0x00}}} , {Highlight::CQZoneBand, true, {}, {{0xff, 0xe4, 0x99}}} , {Highlight::ITUZone, false, {}, {{0xa6, 0xff, 0x00}}} , {Highlight::ITUZoneBand, false, {}, {{0xdd, 0xff, 0x99}}} , {Highlight::DXCC, true, {}, {{0xff, 0x00, 0xff}}} , {Highlight::DXCCBand, true, {}, {{0xff, 0xaa, 0xff}}} , {Highlight::Grid, false, {}, {{0xff, 0x80, 0x00}}} , {Highlight::GridBand, false, {}, {{0xff, 0xcc, 0x99}}} , {Highlight::Call, false, {}, {{0x00, 0xff, 0xff}}} , {Highlight::CallBand, false, {}, {{0x99, 0xff, 0xff}}} , {Highlight::LotW, false, {{0x99, 0x00, 0x00}}, {}} , {Highlight::CQ, true, {}, {{0x66, 0xff, 0x66}}} , {Highlight::Tx, true, {}, {Qt::yellow}} }; bool operator == (DecodeHighlightingModel::HighlightInfo const& lhs, DecodeHighlightingModel::HighlightInfo const& rhs) { return lhs.type_ == rhs.type_ && lhs.enabled_ == rhs.enabled_ && lhs.foreground_ == rhs.foreground_ && lhs.background_ == rhs.background_; } QDataStream& operator << (QDataStream& os, DecodeHighlightingModel::HighlightInfo const& item) { return os << item.type_ << item.enabled_ << item.foreground_ << item.background_; } QDataStream& operator >> (QDataStream& is, DecodeHighlightingModel::HighlightInfo& item) { return is >> item.type_ >> item.enabled_ >> item.foreground_ >> item.background_; } QString DecodeHighlightingModel::HighlightInfo::toString () const { QString string; QTextStream ots {&string}; ots << "HighlightInfo(" << highlight_name (type_) << ", " << enabled_ << ", " << foreground_.color ().name () << ", " << background_.color ().name () << ')'; return string; } #if !defined (QT_NO_DEBUG_STREAM) QDebug operator << (QDebug debug, DecodeHighlightingModel::HighlightInfo const& item) { QDebugStateSaver save {debug}; return debug.nospace () << item.toString (); } #endif ENUM_QDATASTREAM_OPS_IMPL (DecodeHighlightingModel, Highlight); ENUM_CONVERSION_OPS_IMPL (DecodeHighlightingModel, Highlight); DecodeHighlightingModel::DecodeHighlightingModel (QObject * parent) : QAbstractListModel {parent} { } DecodeHighlightingModel::~DecodeHighlightingModel () { } QString DecodeHighlightingModel::highlight_name (Highlight h) { switch (h) { case Highlight::CQ: return tr ("CQ in message"); case Highlight::MyCall: return tr ("My Call in message"); case Highlight::Tx: return tr ("Transmitted message"); case Highlight::DXCC: return tr ("New DXCC"); case Highlight::DXCCBand: return tr ("New DXCC on Band"); case Highlight::Grid: return tr ("New Grid"); case Highlight::GridBand: return tr ("New Grid on Band"); case Highlight::Call: return tr ("New Call"); case Highlight::CallBand: return tr ("New Call on Band"); case Highlight::Continent: return tr ("New Continent"); case Highlight::ContinentBand: return tr ("New Continent on Band"); case Highlight::CQZone: return tr ("New CQ Zone"); case Highlight::CQZoneBand: return tr ("New CQ Zone on Band"); case Highlight::ITUZone: return tr ("New ITU Zone"); case Highlight::ITUZoneBand: return tr ("New ITU Zone on Band"); case Highlight::LotW: return tr ("LoTW User"); } return "Unknown"; } auto DecodeHighlightingModel::default_items () -> HighlightItems const& { return impl::defaults_; } auto DecodeHighlightingModel::items () const -> HighlightItems const& { return m_->data_; } void DecodeHighlightingModel::items (HighlightItems const& items) { m_->data_ = items; QVector roles; roles << Qt::CheckStateRole << Qt::ForegroundRole << Qt::BackgroundRole; Q_EMIT dataChanged (index (0, 0), index (rowCount () - 1, 0), roles); } void DecodeHighlightingModel::set_font (QFont const& font) { m_->font_ = font; } int DecodeHighlightingModel::rowCount (const QModelIndex& parent) const { return parent.isValid () ? 0 : m_->data_.size (); } QVariant DecodeHighlightingModel::data (const QModelIndex& index, int role) const { QVariant result; if (index.isValid () && index.row () < rowCount ()) { auto const& item = m_->data_[index.row ()]; auto fg_unset = Qt::NoBrush == item.foreground_.style (); auto bg_unset = Qt::NoBrush == item.background_.style (); switch (role) { case Qt::CheckStateRole: result = item.enabled_ ? Qt::Checked : Qt::Unchecked; break; case Qt::DisplayRole: return QString {"%1%2%3%4%4%5%6"} .arg (highlight_name (item.type_)) .arg (fg_unset || bg_unset ? QString {" ["} : QString {}) .arg (fg_unset ? tr ("f/g unset") : QString {}) .arg (fg_unset && bg_unset ? QString {" "} : QString {}) .arg (bg_unset ? tr ("b/g unset") : QString {}) .arg (fg_unset || bg_unset ? QString {"]"} : QString {}); break; case Qt::ForegroundRole: if (!fg_unset) { result = item.foreground_; } break; case Qt::BackgroundRole: if (!bg_unset) { result = item.background_; } break; case Qt::FontRole: result = m_->font_; break; case TypeRole: result = static_cast (item.type_); break; case EnabledDefaultRole: for (auto const& default_item : impl::defaults_) { if (default_item.type_ == item.type_) { result = default_item.enabled_ ? Qt::Checked : Qt::Unchecked; } } break; case ForegroundDefaultRole: for (auto const& default_item : impl::defaults_) { if (default_item.type_ == item.type_) { result = default_item.foreground_; } } break; case BackgroundDefaultRole: for (auto const& default_item : impl::defaults_) { if (default_item.type_ == item.type_) { result = default_item.background_; } } break; } } return result; } // Override QAbstractItemModel::itemData() as it is used by the // default mime encode routine used in drag'n'drop operations and we // want to transport the type role, this is because the display role // is derived from the type role. QMap DecodeHighlightingModel::itemData (QModelIndex const& index) const { auto roles = QAbstractListModel::itemData (index); QVariant variantData = data (index, TypeRole); if (variantData.isValid ()) { roles.insert (TypeRole, variantData); } return roles; } QVariant DecodeHighlightingModel::headerData (int /*section*/, Qt::Orientation orientation, int role) const { QVariant header; if (Qt::DisplayRole == role && Qt::Horizontal == orientation) { header = tr ("Highlight Type"); } return header; } Qt::ItemFlags DecodeHighlightingModel::flags (QModelIndex const& index) const { auto flags = QAbstractListModel::flags (index) | Qt::ItemIsDragEnabled; if (index.isValid ()) { flags |= Qt::ItemIsUserCheckable; } else { flags |= Qt::ItemIsDropEnabled; } return flags; } bool DecodeHighlightingModel::setData (QModelIndex const& index, QVariant const& value, int role) { bool ok {false}; if (index.isValid () && index.row () < rowCount ()) { auto& item = m_->data_[index.row ()]; QVector roles; roles << role; switch (role) { case Qt::DisplayRole: case Qt::FontRole: ok = true; break; case Qt::CheckStateRole: if (item.enabled_ != (Qt::Checked == value)) { item.enabled_ = Qt::Checked == value; Q_EMIT dataChanged (index, index, roles); } ok = true; break; case Qt::ForegroundRole: if (item.foreground_ != value.value ()) { item.foreground_ = value.value (); Q_EMIT dataChanged (index, index, roles); } ok = true; break; case Qt::BackgroundRole: if (item.background_ != value.value ()) { item.background_ = value.value (); Q_EMIT dataChanged (index, index, roles); } ok = true; break; case TypeRole: if (item.type_ != static_cast (value.toInt ())) { item.type_ = static_cast (value.toInt ()); roles << Qt::DisplayRole; Q_EMIT dataChanged (index, index, roles); } ok = true; break; } } return ok; } Qt::DropActions DecodeHighlightingModel::supportedDropActions () const { return Qt::MoveAction; } bool DecodeHighlightingModel::insertRows (int row, int count, QModelIndex const& parent) { beginInsertRows (parent, row, row + count - 1); for (int index = 0; index < count; ++index) { m_->data_.insert (row, HighlightInfo {Highlight::CQ, false, {}, {}}); } endInsertRows (); return true; } bool DecodeHighlightingModel::removeRows (int row, int count, QModelIndex const& parent) { beginRemoveRows (parent, row, row + count - 1); for (int index = 0; index < count; ++index) { m_->data_.removeAt (row); } endRemoveRows (); return true; }