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->save();
|
||||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
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;
|
bool hover = option.state & QStyle::State_MouseOver;
|
||||||
if (hover) {
|
if (hover) {
|
||||||
painter->save();
|
painter->save();
|
||||||
@ -50,13 +56,15 @@ void UI::KeyDelegate::paint(QPainter* painter, const QStyleOptionViewItem& optio
|
|||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect r;
|
QVariant dirtyV = index.data(UI::KeysModel::Dirty);
|
||||||
int maxRight = 0;
|
if (dirtyV.isValid() && dirtyV.toBool()) {
|
||||||
int leftOrigin = option.rect.left() + margin;
|
painter->save();
|
||||||
QColor q = painter->pen().color();
|
rect.setWidth(margin / 2);
|
||||||
q.setAlpha(180);
|
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);
|
rect.adjust(margin, margin, -margin, -margin);
|
||||||
QVariant labelV = index.data(UI::KeysModel::Label);
|
QVariant labelV = index.data(UI::KeysModel::Label);
|
||||||
if (labelV.isValid()) {
|
if (labelV.isValid()) {
|
||||||
@ -167,6 +175,7 @@ QSize UI::KeyDelegate::sizeHint(const QStyleOptionViewItem& option, const QModel
|
|||||||
firstLine = parts;
|
firstLine = parts;
|
||||||
|
|
||||||
width = std::max(width, firstLine * fingerPrintMetrics.horizontalAdvance(hex, partSize) + (firstLine - 1) * spaceWidth);
|
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);
|
QVariant lastV = index.data(UI::KeysModel::LastInteraction);
|
||||||
if (lastV.isValid()) {
|
if (lastV.isValid()) {
|
||||||
@ -186,6 +195,7 @@ QSize UI::KeyDelegate::sizeHint(const QStyleOptionViewItem& option, const QModel
|
|||||||
width += margin;
|
width += margin;
|
||||||
|
|
||||||
width += defaultMetrics.horizontalAdvance(levelName);
|
width += defaultMetrics.horizontalAdvance(levelName);
|
||||||
|
width += 1; //there is a mistake somewhere, this the cheapest way to compensate it
|
||||||
}
|
}
|
||||||
|
|
||||||
mw += width;
|
mw += width;
|
||||||
|
@ -24,12 +24,32 @@ const QHash<int, QByteArray> UI::KeysModel::roles = {
|
|||||||
|
|
||||||
UI::KeysModel::KeysModel(QObject* parent):
|
UI::KeysModel::KeysModel(QObject* parent):
|
||||||
QAbstractListModel(parent),
|
QAbstractListModel(parent),
|
||||||
keys()
|
keys(),
|
||||||
|
modified()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UI::KeysModel::~KeysModel() {
|
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) {
|
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 {
|
QVariant UI::KeysModel::data(const QModelIndex& index, int role) const {
|
||||||
int i = index.row();
|
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;
|
QVariant answer;
|
||||||
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
case Label:
|
case Label:
|
||||||
answer = keys[i]->label;
|
answer = info->label;
|
||||||
break;
|
break;
|
||||||
case FingerPrint:
|
case FingerPrint:
|
||||||
answer = keys[i]->fingerPrint;
|
answer = info->fingerPrint;
|
||||||
break;
|
break;
|
||||||
case TrustLevel:
|
case TrustLevel:
|
||||||
answer = static_cast<uint8_t>(keys[i]->trustLevel);
|
answer = static_cast<uint8_t>(info->trustLevel);
|
||||||
break;
|
break;
|
||||||
case LastInteraction:
|
case LastInteraction:
|
||||||
answer = keys[i]->lastInteraction;
|
answer = info->lastInteraction;
|
||||||
break;
|
break;
|
||||||
case Dirty:
|
case Dirty:
|
||||||
answer = false;
|
answer = dirty;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +108,34 @@ QModelIndex UI::KeysModel::index(int row, int column, const QModelIndex& parent)
|
|||||||
return createIndex(row, column, keys[row]);
|
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;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
QModelIndex index(int row, int column, const QModelIndex & parent) const override;
|
QModelIndex index(int row, int column, const QModelIndex & parent) const override;
|
||||||
|
|
||||||
|
std::deque<Shared::KeyInfo> modifiedKeys() const;
|
||||||
|
|
||||||
enum Roles {
|
enum Roles {
|
||||||
Label = Qt::UserRole + 1,
|
Label = Qt::UserRole + 1,
|
||||||
FingerPrint,
|
FingerPrint,
|
||||||
@ -48,8 +50,13 @@ public:
|
|||||||
Dirty
|
Dirty
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void revertKey(int index);
|
||||||
|
void setTrustLevel(int index, Shared::TrustLevel level);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::deque<Shared::KeyInfo*> keys;
|
std::deque<Shared::KeyInfo*> keys;
|
||||||
|
std::map<int, Shared::KeyInfo*> modified;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const QHash<int, QByteArray> roles;
|
static const QHash<int, QByteArray> roles;
|
||||||
|
@ -26,7 +26,8 @@ Omemo::Omemo(QWidget* parent):
|
|||||||
keysDelegate(),
|
keysDelegate(),
|
||||||
unusedKeysDelegate(),
|
unusedKeysDelegate(),
|
||||||
keysModel(),
|
keysModel(),
|
||||||
unusedKeysModel()
|
unusedKeysModel(),
|
||||||
|
contextMenu(new QMenu())
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
@ -36,15 +37,17 @@ Omemo::Omemo(QWidget* parent):
|
|||||||
m_ui->keysView->setModel(&keysModel);
|
m_ui->keysView->setModel(&keysModel);
|
||||||
m_ui->unusedKeysView->setItemDelegate(&unusedKeysDelegate);
|
m_ui->unusedKeysView->setItemDelegate(&unusedKeysDelegate);
|
||||||
m_ui->unusedKeysView->setModel(&unusedKeysModel);
|
m_ui->unusedKeysView->setModel(&unusedKeysModel);
|
||||||
|
|
||||||
|
m_ui->keysView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(m_ui->keysView, &QWidget::customContextMenuRequested, this, &Omemo::onActiveKeysContextMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
Omemo::~Omemo()
|
Omemo::~Omemo()
|
||||||
{
|
{
|
||||||
|
contextMenu->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Omemo::generateMockData()
|
void Omemo::generateMockData() {
|
||||||
{
|
|
||||||
std::random_device rd;
|
std::random_device rd;
|
||||||
std::uniform_int_distribution<char> dist(CHAR_MIN, CHAR_MAX);
|
std::uniform_int_distribution<char> dist(CHAR_MIN, CHAR_MAX);
|
||||||
for (int i = 0; i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
@ -63,3 +66,46 @@ void Omemo::generateMockData()
|
|||||||
keysModel.addKey(info);
|
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
|
#ifndef VCARD_OMEMO_H
|
||||||
#define VCARD_OMEMO_H
|
#define VCARD_OMEMO_H
|
||||||
|
|
||||||
#include <qwidget.h>
|
#include <QWidget>
|
||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
|
#include <QMenu>
|
||||||
|
|
||||||
#include "keysmodel.h"
|
#include "keysmodel.h"
|
||||||
#include "keydelegate.h"
|
#include "keydelegate.h"
|
||||||
|
#include "shared/icons.h"
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
||||||
@ -34,6 +36,9 @@ public:
|
|||||||
Omemo(QWidget* parent = nullptr);
|
Omemo(QWidget* parent = nullptr);
|
||||||
~Omemo();
|
~Omemo();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onActiveKeysContextMenu(const QPoint& pos);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void generateMockData();
|
void generateMockData();
|
||||||
|
|
||||||
@ -43,6 +48,7 @@ private:
|
|||||||
UI::KeyDelegate unusedKeysDelegate;
|
UI::KeyDelegate unusedKeysDelegate;
|
||||||
UI::KeysModel keysModel;
|
UI::KeysModel keysModel;
|
||||||
UI::KeysModel unusedKeysModel;
|
UI::KeysModel unusedKeysModel;
|
||||||
|
QMenu* contextMenu;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VCARD_OMEMO_H
|
#endif // VCARD_OMEMO_H
|
||||||
|
Loading…
Reference in New Issue
Block a user