started refactoring of the VCard UI

This commit is contained in:
Blue 2023-02-01 18:56:00 +03:00
parent bb304ce774
commit 4af16b75bf
Signed by untrusted user: blue
GPG key ID: 9B203B252A63EE38
32 changed files with 1250 additions and 166 deletions

View file

@ -0,0 +1,27 @@
set(SOURCE_FILES
info.cpp
contactgeneral.cpp
contactcontacts.cpp
)
set(UI_FILES
info.ui
contactgeneral.ui
contactcontacts.ui
)
set(HEADER_FILES
info.h
contactgeneral.h
contactcontacts.h
)
target_sources(squawk PRIVATE
${SOURCE_FILES}
${UI_FILES}
${HEADER_FILES}
)
if (WITH_OMEMO)
add_subdirectory(omemo)
endif()

View file

@ -0,0 +1,31 @@
// Squawk messenger.
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
//
// This program 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.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
#include "contactcontacts.h"
#include "ui_contactcontacts.h"
UI::ContactContacts::ContactContacts(const QString& jid, QWidget* parent):
QWidget(parent),
m_ui(new Ui::ContactContacts)
{
m_ui->setupUi(this);
m_ui->jabberID->setText(jid);
m_ui->jabberID->setReadOnly(true);
}
UI::ContactContacts::~ContactContacts() {
}

View file

@ -0,0 +1,41 @@
// Squawk messenger.
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
//
// This program 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.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef UI_WIDGETS_CONTACTCONTACTS_H
#define UI_WIDGETS_CONTACTCONTACTS_H
#include <QWidget>
#include <QScopedPointer>
namespace UI {
namespace Ui
{
class ContactContacts;
}
class ContactContacts : public QWidget {
Q_OBJECT
public:
ContactContacts(const QString& jid, QWidget* parent = nullptr);
~ContactContacts();
private:
QScopedPointer<Ui::ContactContacts> m_ui;
};
}
#endif // UI_WIDGETS_CONTACTCONTACTS_H

View file

@ -0,0 +1,282 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>UI::ContactContacts</class>
<widget class="QWidget" name="Contacts">
<attribute name="title">
<string>Contacts</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="contactHeading">
<property name="styleSheet">
<string notr="true">font: 600 24pt ;</string>
</property>
<property name="text">
<string>Contact</string>
</property>
</widget>
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="contactScrollArea">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>545</width>
<height>544</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_3" columnstretch="1,3,1">
<item row="7" column="1">
<widget class="Line" name="phonesLine">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QTableView" name="emailsView">
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item row="10" column="1">
<widget class="Line" name="addressesLine">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="12">
<spacer name="contactLeftSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="Line" name="contactFormLine">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="Line" name="emailsLine">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="11" column="1">
<spacer name="contactBottomSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="8" column="1">
<widget class="QLabel" name="addressesHeading">
<property name="styleSheet">
<string notr="true">font: 600 16pt;</string>
</property>
<property name="text">
<string>Addresses</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QTableView" name="phonesView">
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="emailsHeading">
<property name="styleSheet">
<string notr="true">font: 600 16pt;</string>
</property>
<property name="text">
<string>E-Mail addresses</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QFormLayout" name="contactForm">
<property name="formAlignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
<item row="0" column="1">
<widget class="QLineEdit" name="jabberID">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>300</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="jabberIDLabel">
<property name="text">
<string>Jabber ID</string>
</property>
<property name="buddy">
<cstring>jabberID</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="url">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>300</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="urlLabel">
<property name="text">
<string>Web site</string>
</property>
<property name="buddy">
<cstring>url</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="2" rowspan="12">
<spacer name="contactRightSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="1">
<widget class="QLabel" name="phenesHeading">
<property name="styleSheet">
<string notr="true">font: 600 16pt;</string>
</property>
<property name="text">
<string>Phone numbers</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QTableView" name="addressesView">
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -0,0 +1,28 @@
// Squawk messenger.
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
//
// This program 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.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
#include "contactgeneral.h"
#include "ui_contactgeneral.h"
UI::ContactGeneral::ContactGeneral(QWidget* parent):
QWidget(parent),
m_ui(new Ui::ContactGeneral)
{
m_ui->setupUi(this);
}
UI::ContactGeneral::~ContactGeneral()
{}

View file

@ -0,0 +1,41 @@
// Squawk messenger.
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
//
// This program 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.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef UI_WIDGETS_CONTACTGENERAL_H
#define UI_WIDGETS_CONTACTGENERAL_H
#include <QWidget>
#include <QScopedPointer>
namespace UI {
namespace Ui
{
class ContactGeneral;
}
class ContactGeneral : public QWidget{
Q_OBJECT
public:
ContactGeneral(QWidget* parent = nullptr);
~ContactGeneral();
private:
QScopedPointer<Ui::ContactGeneral> m_ui;
};
}
#endif // UI_WIDGETS_CONTACTGENERAL_H

View file

@ -0,0 +1,448 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>UI::ContactGeneral</class>
<widget class="QWidget" name="General">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>340</width>
<height>625</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2" columnstretch="1,2,2,1">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="horizontalSpacing">
<number>6</number>
</property>
<item row="6" column="1" colspan="2">
<widget class="QLabel" name="organizationHeading">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">font: 600 16pt;</string>
</property>
<property name="text">
<string>Organization</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QFormLayout" name="personalForm">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="formAlignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
<item row="1" column="1">
<widget class="QLineEdit" name="middleName">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>350</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="firstName">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>350</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="middleNameLabel">
<property name="text">
<string>Middle name</string>
</property>
<property name="buddy">
<cstring>middleName</cstring>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="firstNameLabel">
<property name="text">
<string>First name</string>
</property>
<property name="buddy">
<cstring>firstName</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lastNameLabel">
<property name="text">
<string>Last name</string>
</property>
<property name="buddy">
<cstring>lastName</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lastName">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>350</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="nickNameLabel">
<property name="text">
<string>Nick name</string>
</property>
<property name="buddy">
<cstring>nickName</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="nickName">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>350</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="birthdayLabel">
<property name="text">
<string>Birthday</string>
</property>
<property name="buddy">
<cstring>birthday</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QDateEdit" name="birthday"/>
</item>
</layout>
</item>
<item row="7" column="1" colspan="2">
<layout class="QFormLayout" name="organizationForm">
<property name="formAlignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
<item row="0" column="0">
<widget class="QLabel" name="organizationNameLabel">
<property name="text">
<string>Organization name</string>
</property>
<property name="buddy">
<cstring>organizationName</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="organizationName">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>350</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="organizationDepartmentLabel">
<property name="text">
<string>Unit / Department</string>
</property>
<property name="buddy">
<cstring>organizationDepartment</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="organizationDepartment">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>350</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="roleLabel">
<property name="text">
<string>Role / Profession</string>
</property>
<property name="buddy">
<cstring>organizationRole</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="organizationRole">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>350</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="organizationTitleLabel">
<property name="text">
<string>Job title</string>
</property>
<property name="buddy">
<cstring>organizationTitle</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="organizationTitle">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>350</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item row="8" column="1" colspan="2">
<widget class="Line" name="organizationLine">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<layout class="QFormLayout" name="commonForm">
<item row="0" column="1">
<widget class="QLineEdit" name="fullName"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="fullNameLabel">
<property name="text">
<string>Full name</string>
</property>
<property name="buddy">
<cstring>fullName</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0" rowspan="7">
<spacer name="generalLeftHSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1" colspan="2">
<widget class="Line" name="personalLine">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="0" colspan="4">
<widget class="QLabel" name="generalHeading">
<property name="styleSheet">
<string notr="true">font: 600 24pt ;</string>
</property>
<property name="text">
<string>General</string>
</property>
</widget>
</item>
<item row="3" column="3" rowspan="7">
<spacer name="generalRightHSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1" colspan="2">
<widget class="QLabel" name="personalHeading">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">font: 600 16pt;</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="text">
<string>Personal information</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QToolButton" name="avatarButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset theme="user">
<normaloff>:/images/fallback/dark/big/user.svg</normaloff>:/images/fallback/dark/big/user.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonIconOnly</enum>
</property>
<property name="arrowType">
<enum>Qt::NoArrow</enum>
</property>
</widget>
</item>
<item row="9" column="1" colspan="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<tabstops>
<tabstop>fullName</tabstop>
<tabstop>firstName</tabstop>
<tabstop>middleName</tabstop>
<tabstop>lastName</tabstop>
<tabstop>nickName</tabstop>
<tabstop>birthday</tabstop>
<tabstop>avatarButton</tabstop>
<tabstop>organizationName</tabstop>
<tabstop>organizationDepartment</tabstop>
<tabstop>organizationRole</tabstop>
<tabstop>organizationTitle</tabstop>
</tabstops>
<resources>
<include location="../../../resources/resources.qrc"/>
</resources>
<connections/>
</ui>

30
ui/widgets/info/info.cpp Normal file
View file

@ -0,0 +1,30 @@
// Squawk messenger.
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
//
// This program 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.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
#include "info.h"
#include "ui_info.h"
UI::Info::Info(const Shared::Info& info, QWidget* parent):
QWidget(parent),
m_ui(new Ui::Info())
{
m_ui->setupUi(this);
}
UI::Info::~Info()
{}

45
ui/widgets/info/info.h Normal file
View file

@ -0,0 +1,45 @@
// Squawk messenger.
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
//
// This program 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.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef UI_WIDGETS_INFO_H
#define UI_WIDGETS_INFO_H
#include <QWidget>
#include <QScopedPointer>
#include <shared/info.h>
#include "contactgeneral.h"
namespace UI {
namespace Ui
{
class Info;
}
class Info : public QWidget {
Q_OBJECT
public:
Info(const Shared::Info& info, QWidget* parent = nullptr);
~Info();
private:
QScopedPointer<Ui::Info> m_ui;
};
}
#endif // UI_WIDGETS_INFO_H

137
ui/widgets/info/info.ui Normal file
View file

@ -0,0 +1,137 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>UI::Info</class>
<widget class="QWidget" name="UI::Info">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QLabel" name="title">
<property name="styleSheet">
<string notr="true">font: 16pt </string>
</property>
<property name="text">
<string notr="true">Contact john@dow.org card</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="receivingTimeLabel">
<property name="styleSheet">
<string notr="true">font: italic 8pt;</string>
</property>
<property name="text">
<string>Received 12.07.2007 at 17.35</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="enabled">
<bool>true</bool>
</property>
<property name="focusPolicy">
<enum>Qt::TabFocus</enum>
</property>
<property name="tabPosition">
<enum>QTabWidget::North</enum>
</property>
<property name="tabShape">
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex">
<number>1</number>
</property>
<property name="elideMode">
<enum>Qt::ElideNone</enum>
</property>
<property name="documentMode">
<bool>true</bool>
</property>
<property name="tabBarAutoHide">
<bool>false</bool>
</property>
<widget class="QWidget" name="Description">
<attribute name="title">
<string>Description</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="horizontalSpacing">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="descriptionHeading">
<property name="styleSheet">
<string notr="true">font: 600 24pt ;</string>
</property>
<property name="text">
<string>Description</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QTextEdit" name="description">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextEditable|Qt::TextEditorInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Close|QDialogButtonBox::Save</set>
</property>
<property name="centerButtons">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -0,0 +1,7 @@
target_sources(squawk PRIVATE
omemo.cpp
omemo.h
omemo.ui
keydelegate.cpp
keydelegate.h
)

View file

@ -0,0 +1,226 @@
// Squawk messenger.
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
//
// This program 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.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
#include "keydelegate.h"
#include <QPainter>
#include <QDebug>
#include "ui/models/info/omemo/keys.h"
#include <shared/global.h>
constexpr uint8_t margin = 10;
constexpr uint8_t partSize = 8;
constexpr uint8_t maxSingleLineParts = 3;
UI::KeyDelegate::KeyDelegate(QObject* parent):
QStyledItemDelegate(parent),
defaultFont(Shared::Global::getInstance()->defaultFont),
fingerPrintFont(Shared::Global::getInstance()->monospaceFont),
labelFont(Shared::Global::getInstance()->smallFont),
defaultMetrics(Shared::Global::getInstance()->defaultFontMetrics),
fingerPrintMetrics(Shared::Global::getInstance()->monospaceMetrics),
labelMetrics(Shared::Global::getInstance()->smallFontMetrics),
spaceWidth(fingerPrintMetrics.horizontalAdvance(" "))
{}
UI::KeyDelegate::~KeyDelegate() {}
void UI::KeyDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
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();
painter->fillRect(option.rect, option.palette.brush(QPalette::Inactive, QPalette::Highlight));
painter->restore();
}
QVariant dirtyV = index.data(Models::Keys::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();
}
rect.adjust(margin, margin, -margin, -margin);
QVariant labelV = index.data(Models::Keys::Label);
if (labelV.isValid()) {
QString label = labelV.toString();
if (label.size() > 0) {
painter->save();
painter->setFont(labelFont);
painter->setPen(q);
painter->drawText(rect, Qt::AlignLeft | Qt::AlignTop, label, &r);
rect.adjust(0, labelMetrics.lineSpacing(), 0, 0);
maxRight = std::max(r.width(), maxRight);
painter->restore();
}
}
QVariant fingerPrintV = index.data(Models::Keys::FingerPrint);
if (fingerPrintV.isValid()) {
painter->save();
painter->setFont(fingerPrintFont);
QByteArray fingerPrint = fingerPrintV.toByteArray();
std::vector<QString> parts = getParts(fingerPrint);
uint8_t partsLength = parts.size();
uint8_t firstLine;
if (partsLength > maxSingleLineParts)
firstLine = partsLength / 2 + partsLength % 2;
else
firstLine = partsLength;
for (uint8_t i = 0; i < partsLength; ++i) {
if (i == firstLine) {
maxRight = std::max(rect.left() - leftOrigin - margin, maxRight);
rect.setLeft(leftOrigin);
rect.adjust(0, r.height() + fingerPrintMetrics.leading(), 0, 0);
}
painter->drawText(rect, Qt::AlignLeft | Qt::AlignTop, parts[i], &r);
rect.adjust(r.width() + spaceWidth ,0, 0, 0);
}
maxRight = std::max(rect.left() - leftOrigin - margin, maxRight);
rect.adjust(0, r.height() + fingerPrintMetrics.leading(), 0, 0);
rect.setLeft(leftOrigin);
painter->restore();
}
QVariant lastV = index.data(Models::Keys::LastInteraction);
if (lastV.isValid()) {
QDateTime last = lastV.toDateTime();
if (last.isValid()) {
painter->save();
painter->setFont(labelFont);
painter->setPen(q);
painter->drawText(rect, Qt::AlignLeft | Qt::AlignTop, last.toString(), &r);
rect.adjust(0, labelMetrics.lineSpacing(), 0, 0);
maxRight = std::max(r.width(), maxRight);
painter->restore();
}
}
QVariant levelV = index.data(Models::Keys::TrustLevel);
if (levelV.isValid()) {
Shared::TrustLevel level = static_cast<Shared::TrustLevel>(levelV.toUInt());
QString levelName = Shared::Global::getName(level);
if (maxRight > 0)
maxRight += margin;
rect.setLeft(leftOrigin + maxRight);
rect.setTop(option.rect.top() + maxRight);
rect.setBottom(option.rect.bottom() - maxRight);
painter->setFont(defaultFont);
painter->drawText(rect, Qt::AlignLeft | Qt::AlignVCenter, levelName, &r);
}
painter->restore();
}
QSize UI::KeyDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const {
QSize size = QStyledItemDelegate::sizeHint(option, index);
int mh = margin * 2;
int mw = margin * 2;
int width = 0;
QVariant labelV = index.data(Models::Keys::Label);
if (labelV.isValid()) {
QString label = labelV.toString();
if (label.size() > 0) {
mh += labelMetrics.lineSpacing();
width = labelMetrics.horizontalAdvance(label);
}
}
QVariant fingerPrintV = index.data(Models::Keys::FingerPrint);
if (fingerPrintV.isValid()) {
QString hex = fingerPrintV.toByteArray().toHex();
uint8_t parts = hex.size() / partSize;
mh += fingerPrintMetrics.height();
if (parts > maxSingleLineParts)
mh += fingerPrintMetrics.height() + fingerPrintMetrics.leading();
uint8_t firstLine;
if (parts > maxSingleLineParts)
firstLine = parts / 2 + parts % 2;
else
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(Models::Keys::LastInteraction);
if (lastV.isValid()) {
QDateTime last = lastV.toDateTime();
if (last.isValid()) {
mh += labelMetrics.lineSpacing();
QString dt = last.toString();
width = std::max(labelMetrics.horizontalAdvance(dt), width);
}
}
QVariant levelV = index.data(Models::Keys::TrustLevel);
if (levelV.isValid()) {
Shared::TrustLevel level = static_cast<Shared::TrustLevel>(levelV.toUInt());
QString levelName = Shared::Global::getName(level);
if (width > 0)
width += margin;
width += defaultMetrics.horizontalAdvance(levelName);
width += 1; //there is a mistake somewhere, this the cheapest way to compensate it
}
mw += width;
if (size.width() < mw)
size.setWidth(mw);
if (size.height() < mh)
size.setHeight(mh);
return size;
}
std::vector<QString> UI::KeyDelegate::getParts(const QByteArray& data) {
QString hex = data.toHex();
uint8_t parts = hex.size() / partSize;
std::vector<QString> result(parts);
for (uint8_t i = 0; i < parts; ++i) {
uint16_t index = i * partSize;
uint8_t length = partSize;
if (index + length > hex.size())
length = hex.size() - index;
QStringRef part(&hex, index, length);
result[i] = part.toString();
}
return result;
}

View file

@ -0,0 +1,50 @@
// Squawk messenger.
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
//
// This program 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.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef UI_KEYDELEGATE_H
#define UI_KEYDELEGATE_H
#include <QStyledItemDelegate>
#include <QString>
#include <vector>
namespace UI {
class KeyDelegate : public QStyledItemDelegate
{
public:
KeyDelegate(QObject *parent = nullptr);
~KeyDelegate();
QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const override;
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
private:
const QFont& defaultFont;
const QFont& fingerPrintFont;
const QFont& labelFont;
const QFontMetrics& defaultMetrics;
const QFontMetrics& fingerPrintMetrics;
const QFontMetrics& labelMetrics;
int spaceWidth;
private:
static std::vector<QString> getParts(const QByteArray& data);
};
}
#endif // UI_KEYDELEGATE_H

View file

@ -0,0 +1,111 @@
// Squawk messenger.
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
//
// This program 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.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
#include "omemo.h"
#include "ui_omemo.h"
#include <random>
constexpr uint8_t fingerprintLength = 32;
Omemo::Omemo(QWidget* parent):
QWidget(parent),
m_ui(new Ui::Omemo()),
keysDelegate(),
unusedKeysDelegate(),
keysModel(),
unusedKeysModel(),
contextMenu(new QMenu())
{
m_ui->setupUi(this);
generateMockData();
m_ui->keysView->setItemDelegate(&keysDelegate);
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() {
std::random_device rd;
std::uniform_int_distribution<char> dist(CHAR_MIN, CHAR_MAX);
for (int i = 0; i < 5; ++i) {
QByteArray fp(fingerprintLength, 0);
for (int i = 0; i < fingerprintLength; ++i) {
fp[i] = dist(rd);
}
Shared::KeyInfo info;
info.id = i;
if (i % 3 == 0)
info.label = QString("test_") + std::to_string(i).c_str();
info.fingerPrint = fp;
if (i % 2 == 0)
info.lastInteraction = QDateTime::currentDateTime();
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(Models::Keys::Dirty);
if (dirtyV.isValid() && dirtyV.toBool()) {
QAction* rev = contextMenu->addAction(Shared::icon("clean"), tr("Revert changes"));
connect(rev, &QAction::triggered, std::bind(&Models::Keys::revertKey, &keysModel, index.row()));
}
QVariant levelV = index.data(Models::Keys::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(&Models::Keys::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(&Models::Keys::setTrustLevel, &keysModel,
index.row(), Shared::TrustLevel::manuallyDistrusted
)
);
}
}
}
contextMenu->popup(m_ui->keysView->viewport()->mapToGlobal(pos));
}

View file

@ -0,0 +1,54 @@
// Squawk messenger.
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
//
// This program 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.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef VCARD_OMEMO_H
#define VCARD_OMEMO_H
#include <QWidget>
#include <QScopedPointer>
#include <QMenu>
#include "ui/models/info/omemo/keys.h"
#include "keydelegate.h"
#include "shared/icons.h"
namespace Ui
{
class Omemo;
}
class Omemo : public QWidget {
Q_OBJECT
public:
Omemo(QWidget* parent = nullptr);
~Omemo();
private slots:
void onActiveKeysContextMenu(const QPoint& pos);
private:
void generateMockData();
private:
QScopedPointer<Ui::Omemo> m_ui;
UI::KeyDelegate keysDelegate;
UI::KeyDelegate unusedKeysDelegate;
Models::Keys keysModel;
Models::Keys unusedKeysModel;
QMenu* contextMenu;
};
#endif // VCARD_OMEMO_H

View file

@ -0,0 +1,194 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Omemo</class>
<widget class="QWidget" name="Omemo">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>473</width>
<height>657</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="OMEMOHeading">
<property name="font">
<font>
<pointsize>24</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>OMEMO</string>
</property>
</widget>
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>473</width>
<height>592</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="1,3,1">
<item row="1" column="1">
<widget class="ExpandingList" name="keysView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="uniformItemSizes">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="keysHeading">
<property name="font">
<font>
<pointsize>16</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Active keys</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="unusedKeysHeading">
<property name="font">
<font>
<pointsize>16</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Unused keys</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="ExpandingList" name="unusedKeysView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="uniformItemSizes">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="6">
<spacer name="spacerLeft">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="2" rowspan="6">
<spacer name="spacerRight">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ExpandingList</class>
<extends>QListView</extends>
<header location="global">ui/utils/expandinglist.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>