mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-14 08:01:49 -05:00
349 lines
10 KiB
C++
349 lines
10 KiB
C++
#include "DecodeHighlightingModel.hpp"
|
|
|
|
#include <QString>
|
|
#include <QVariant>
|
|
#include <QList>
|
|
#include <QBrush>
|
|
#include <QColor>
|
|
#include <QFont>
|
|
#include <QMap>
|
|
#include <QVector>
|
|
#include <QTextStream>
|
|
#include <QDataStream>
|
|
#include <QMetaType>
|
|
#include <QDebug>
|
|
|
|
#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<DecodeHighlightingModel::HighlightInfo> 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<int> 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<int> (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<int, QVariant> 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<int> 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<QBrush> ())
|
|
{
|
|
item.foreground_ = value.value<QBrush> ();
|
|
Q_EMIT dataChanged (index, index, roles);
|
|
}
|
|
ok = true;
|
|
break;
|
|
case Qt::BackgroundRole:
|
|
if (item.background_ != value.value<QBrush> ())
|
|
{
|
|
item.background_ = value.value<QBrush> ();
|
|
Q_EMIT dataChanged (index, index, roles);
|
|
}
|
|
ok = true;
|
|
break;
|
|
case TypeRole:
|
|
if (item.type_ != static_cast<Highlight> (value.toInt ()))
|
|
{
|
|
item.type_ = static_cast<Highlight> (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;
|
|
}
|