forked from blue/squawk
context menu to trust or distrust keys
This commit is contained in:
parent
b72a837754
commit
73d83f55af
@ -43,6 +43,12 @@ void UI::KeyDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio
|
||||
painter->save();
|
||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||
|
||||
QRect r;
|
||||
int maxRight = 0;
|
||||
int leftOrigin = option.rect.left() + margin;
|
||||
QColor q = painter->pen().color();
|
||||
q.setAlpha(180);
|
||||
QRect rect = option.rect;
|
||||
bool hover = option.state & QStyle::State_MouseOver;
|
||||
if (hover) {
|
||||
painter->save();
|
||||
@ -50,13 +56,15 @@ void UI::KeyDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QRect r;
|
||||
int maxRight = 0;
|
||||
int leftOrigin = option.rect.left() + margin;
|
||||
QColor q = painter->pen().color();
|
||||
q.setAlpha(180);
|
||||
QVariant dirtyV = index.data(UI::KeysModel::Dirty);
|
||||
if (dirtyV.isValid() && dirtyV.toBool()) {
|
||||
painter->save();
|
||||
rect.setWidth(margin / 2);
|
||||
painter->fillRect(rect, option.palette.brush(QPalette::Active, QPalette::Highlight));
|
||||
rect.setWidth(option.rect.width());
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QRect rect = option.rect;
|
||||
rect.adjust(margin, margin, -margin, -margin);
|
||||
QVariant labelV = index.data(UI::KeysModel::Label);
|
||||
if (labelV.isValid()) {
|
||||
@ -167,6 +175,7 @@ QSize UI::KeyDelegate::sizeHint(const QStyleOptionViewItem& option, const QModel
|
||||
firstLine = parts;
|
||||
|
||||
width = std::max(width, firstLine * fingerPrintMetrics.horizontalAdvance(hex, partSize) + (firstLine - 1) * spaceWidth);
|
||||
width += 1; //there is a mistake somewhere, this the cheapest way to compensate it
|
||||
}
|
||||
QVariant lastV = index.data(UI::KeysModel::LastInteraction);
|
||||
if (lastV.isValid()) {
|
||||
@ -186,6 +195,7 @@ QSize UI::KeyDelegate::sizeHint(const QStyleOptionViewItem& option, const QModel
|
||||
width += margin;
|
||||
|
||||
width += defaultMetrics.horizontalAdvance(levelName);
|
||||
width += 1; //there is a mistake somewhere, this the cheapest way to compensate it
|
||||
}
|
||||
|
||||
mw += width;
|
||||
|
@ -24,12 +24,32 @@ const QHash<int, QByteArray> UI::KeysModel::roles = {
|
||||
|
||||
UI::KeysModel::KeysModel(QObject* parent):
|
||||
QAbstractListModel(parent),
|
||||
keys()
|
||||
keys(),
|
||||
modified()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UI::KeysModel::~KeysModel() {
|
||||
for (Shared::KeyInfo* key : keys) {
|
||||
delete key;
|
||||
}
|
||||
|
||||
for (std::pair<const int, Shared::KeyInfo*>& pair: modified) {
|
||||
delete pair.second;
|
||||
}
|
||||
}
|
||||
|
||||
std::deque<Shared::KeyInfo> UI::KeysModel::modifiedKeys() const {
|
||||
std::deque<Shared::KeyInfo> response(modified.size());
|
||||
|
||||
int i = 0;
|
||||
for (const std::pair<const int, Shared::KeyInfo*>& pair: modified) {
|
||||
response[i] = *(pair.second);
|
||||
++i;
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
void UI::KeysModel::addKey(const Shared::KeyInfo& info) {
|
||||
@ -40,24 +60,34 @@ void UI::KeysModel::addKey(const Shared::KeyInfo& info) {
|
||||
|
||||
QVariant UI::KeysModel::data(const QModelIndex& index, int role) const {
|
||||
int i = index.row();
|
||||
const Shared::KeyInfo* info;
|
||||
bool dirty;
|
||||
std::map<int, Shared::KeyInfo*>::const_iterator itr = modified.find(i);
|
||||
if (itr != modified.end()) {
|
||||
info = itr->second;
|
||||
dirty = true;
|
||||
} else {
|
||||
dirty = false;
|
||||
info = keys[i];
|
||||
}
|
||||
QVariant answer;
|
||||
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
case Label:
|
||||
answer = keys[i]->label;
|
||||
answer = info->label;
|
||||
break;
|
||||
case FingerPrint:
|
||||
answer = keys[i]->fingerPrint;
|
||||
answer = info->fingerPrint;
|
||||
break;
|
||||
case TrustLevel:
|
||||
answer = static_cast<uint8_t>(keys[i]->trustLevel);
|
||||
answer = static_cast<uint8_t>(info->trustLevel);
|
||||
break;
|
||||
case LastInteraction:
|
||||
answer = keys[i]->lastInteraction;
|
||||
answer = info->lastInteraction;
|
||||
break;
|
||||
case Dirty:
|
||||
answer = false;
|
||||
answer = dirty;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -78,7 +108,34 @@ QModelIndex UI::KeysModel::index(int row, int column, const QModelIndex& parent)
|
||||
return createIndex(row, column, keys[row]);
|
||||
}
|
||||
|
||||
|
||||
void UI::KeysModel::revertKey(int row) {
|
||||
std::map<int, Shared::KeyInfo*>::const_iterator itr = modified.find(row);
|
||||
if (itr != modified.end()) {
|
||||
modified.erase(itr);
|
||||
QModelIndex index = createIndex(row, 0, keys[row]);
|
||||
dataChanged(index, index);
|
||||
}
|
||||
}
|
||||
|
||||
void UI::KeysModel::setTrustLevel(int row, Shared::TrustLevel level) {
|
||||
std::map<int, Shared::KeyInfo*>::const_iterator itr = modified.find(row);
|
||||
Shared::KeyInfo* info;
|
||||
if (itr == modified.end()) {
|
||||
if (row < rowCount()) {
|
||||
info = new Shared::KeyInfo(*(keys[row]));
|
||||
modified.insert(std::make_pair(row, info));
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
info = itr->second;
|
||||
}
|
||||
|
||||
info->trustLevel = level;
|
||||
|
||||
QModelIndex index = createIndex(row, 0, info);
|
||||
dataChanged(index, index, {KeysModel::Dirty});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -40,6 +40,8 @@ public:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
QModelIndex index(int row, int column, const QModelIndex & parent) const override;
|
||||
|
||||
std::deque<Shared::KeyInfo> modifiedKeys() const;
|
||||
|
||||
enum Roles {
|
||||
Label = Qt::UserRole + 1,
|
||||
FingerPrint,
|
||||
@ -48,8 +50,13 @@ public:
|
||||
Dirty
|
||||
};
|
||||
|
||||
public slots:
|
||||
void revertKey(int index);
|
||||
void setTrustLevel(int index, Shared::TrustLevel level);
|
||||
|
||||
private:
|
||||
std::deque<Shared::KeyInfo*> keys;
|
||||
std::map<int, Shared::KeyInfo*> modified;
|
||||
|
||||
private:
|
||||
static const QHash<int, QByteArray> roles;
|
||||
|
@ -26,7 +26,8 @@ Omemo::Omemo(QWidget* parent):
|
||||
keysDelegate(),
|
||||
unusedKeysDelegate(),
|
||||
keysModel(),
|
||||
unusedKeysModel()
|
||||
unusedKeysModel(),
|
||||
contextMenu(new QMenu())
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
@ -36,15 +37,17 @@ Omemo::Omemo(QWidget* parent):
|
||||
m_ui->keysView->setModel(&keysModel);
|
||||
m_ui->unusedKeysView->setItemDelegate(&unusedKeysDelegate);
|
||||
m_ui->unusedKeysView->setModel(&unusedKeysModel);
|
||||
|
||||
m_ui->keysView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(m_ui->keysView, &QWidget::customContextMenuRequested, this, &Omemo::onActiveKeysContextMenu);
|
||||
}
|
||||
|
||||
Omemo::~Omemo()
|
||||
{
|
||||
|
||||
contextMenu->deleteLater();
|
||||
}
|
||||
|
||||
void Omemo::generateMockData()
|
||||
{
|
||||
void Omemo::generateMockData() {
|
||||
std::random_device rd;
|
||||
std::uniform_int_distribution<char> dist(CHAR_MIN, CHAR_MAX);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
@ -63,3 +66,46 @@ void Omemo::generateMockData()
|
||||
keysModel.addKey(info);
|
||||
}
|
||||
}
|
||||
|
||||
void Omemo::onActiveKeysContextMenu(const QPoint& pos) {
|
||||
contextMenu->clear();
|
||||
QModelIndex index = m_ui->keysView->indexAt(pos);
|
||||
if (index.isValid()) {
|
||||
QVariant dirtyV = index.data(UI::KeysModel::Dirty);
|
||||
if (dirtyV.isValid() && dirtyV.toBool()) {
|
||||
QAction* rev = contextMenu->addAction(Shared::icon("clean"), tr("Revert changes"));
|
||||
connect(rev, &QAction::triggered, std::bind(&UI::KeysModel::revertKey, &keysModel, index.row()));
|
||||
}
|
||||
|
||||
QVariant levelV = index.data(UI::KeysModel::TrustLevel);
|
||||
if (levelV.isValid()) {
|
||||
Shared::TrustLevel level = static_cast<Shared::TrustLevel>(levelV.toUInt());
|
||||
if (level == Shared::TrustLevel::undecided ||
|
||||
level == Shared::TrustLevel::automaticallyDistrusted ||
|
||||
level == Shared::TrustLevel::manuallyDistrusted
|
||||
) {
|
||||
QAction* rev = contextMenu->addAction(Shared::icon("favorite"), tr("Trust"));
|
||||
connect(rev, &QAction::triggered,
|
||||
std::bind(&UI::KeysModel::setTrustLevel, &keysModel,
|
||||
index.row(), Shared::TrustLevel::manuallyTrusted
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (level == Shared::TrustLevel::undecided ||
|
||||
level == Shared::TrustLevel::automaticallyTrusted ||
|
||||
level == Shared::TrustLevel::manuallyTrusted ||
|
||||
level == Shared::TrustLevel::authenticated
|
||||
) {
|
||||
QAction* rev = contextMenu->addAction(Shared::icon("unfavorite"), tr("Distrust"));
|
||||
connect(rev, &QAction::triggered,
|
||||
std::bind(&UI::KeysModel::setTrustLevel, &keysModel,
|
||||
index.row(), Shared::TrustLevel::manuallyDistrusted
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contextMenu->popup(m_ui->keysView->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
@ -17,11 +17,13 @@
|
||||
#ifndef VCARD_OMEMO_H
|
||||
#define VCARD_OMEMO_H
|
||||
|
||||
#include <qwidget.h>
|
||||
#include <QWidget>
|
||||
#include <QScopedPointer>
|
||||
#include <QMenu>
|
||||
|
||||
#include "keysmodel.h"
|
||||
#include "keydelegate.h"
|
||||
#include "shared/icons.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
@ -34,6 +36,9 @@ public:
|
||||
Omemo(QWidget* parent = nullptr);
|
||||
~Omemo();
|
||||
|
||||
private slots:
|
||||
void onActiveKeysContextMenu(const QPoint& pos);
|
||||
|
||||
private:
|
||||
void generateMockData();
|
||||
|
||||
@ -43,6 +48,7 @@ private:
|
||||
UI::KeyDelegate unusedKeysDelegate;
|
||||
UI::KeysModel keysModel;
|
||||
UI::KeysModel unusedKeysModel;
|
||||
QMenu* contextMenu;
|
||||
};
|
||||
|
||||
#endif // VCARD_OMEMO_H
|
||||
|
Loading…
Reference in New Issue
Block a user