deprecation fix about qxmpp, beginning of adding email addresses in VCards

This commit is contained in:
Blue 2019-11-02 23:50:25 +03:00
parent c067835b00
commit 9d491e9e93
17 changed files with 610 additions and 227 deletions

View file

@ -10,6 +10,8 @@ set(CMAKE_AUTOUIC ON)
find_package(Qt5Widgets CONFIG REQUIRED)
find_package(Qt5DBus CONFIG REQUIRED)
add_subdirectory(widgets)
set(squawkUI_SRC
squawk.cpp
models/accounts.cpp
@ -22,14 +24,6 @@ set(squawkUI_SRC
models/room.cpp
models/abstractparticipant.cpp
models/participant.cpp
widgets/conversation.cpp
widgets/chat.cpp
widgets/room.cpp
widgets/newcontact.cpp
widgets/accounts.cpp
widgets/account.cpp
widgets/joinconference.cpp
widgets/vcard.cpp
utils/messageline.cpp
utils//message.cpp
utils/resizer.cpp
@ -37,11 +31,13 @@ set(squawkUI_SRC
utils/flowlayout.cpp
utils/badge.cpp
utils/progress.cpp
utils/comboboxdelegate.cpp
)
# Tell CMake to create the helloworld executable
add_library(squawkUI ${squawkUI_SRC})
# Use the Widgets module from Qt 5.
target_link_libraries(squawkUI squawkWidgets)
target_link_libraries(squawkUI Qt5::Widgets)
target_link_libraries(squawkUI Qt5::DBus)

View file

@ -47,14 +47,14 @@ Squawk::Squawk(QWidget *parent) :
}
m_ui->comboBox->setCurrentIndex(Shared::offline);
connect(m_ui->actionAccounts, SIGNAL(triggered()), this, SLOT(onAccounts()));
connect(m_ui->actionAddContact, SIGNAL(triggered()), this, SLOT(onNewContact()));
connect(m_ui->actionAddConference, SIGNAL(triggered()), this, SLOT(onNewConference()));
connect(m_ui->comboBox, SIGNAL(activated(int)), this, SLOT(onComboboxActivated(int)));
connect(m_ui->roster, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(onRosterItemDoubleClicked(const QModelIndex&)));
connect(m_ui->roster, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(onRosterContextMenu(const QPoint&)));
connect(m_ui->actionAccounts, &QAction::triggered, this, &Squawk::onAccounts);
connect(m_ui->actionAddContact, &QAction::triggered, this, &Squawk::onNewContact);
connect(m_ui->actionAddConference, &QAction::triggered, this, &Squawk::onNewConference);
connect(m_ui->comboBox, qOverload<int>(&QComboBox::activated), this, &Squawk::onComboboxActivated);
connect(m_ui->roster, &QTreeView::doubleClicked, this, &Squawk::onRosterItemDoubleClicked);
connect(m_ui->roster, &QTreeView::customContextMenuRequested, this, &Squawk::onRosterContextMenu);
connect(rosterModel.accountsModel, SIGNAL(sizeChanged(unsigned int)), this, SLOT(onAccountsSizeChanged(unsigned int)));
connect(rosterModel.accountsModel, &Models::Accounts::sizeChanged, this, &Squawk::onAccountsSizeChanged);
//m_ui->mainToolBar->addWidget(m_ui->comboBox);
setWindowTitle(tr("Contact list"));

View file

@ -33,10 +33,10 @@
#include "widgets/room.h"
#include "widgets/newcontact.h"
#include "widgets/joinconference.h"
#include "widgets/vcard.h"
#include "models/roster.h"
#include "widgets/vcard/vcard.h"
#include "../global.h"
#include "global.h"
namespace Ui {
class Squawk;

View file

@ -0,0 +1,64 @@
/*
* 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 "comboboxdelegate.h"
ComboboxDelegate::ComboboxDelegate(QObject *parent):
QStyledItemDelegate(parent),
entries()
{
}
ComboboxDelegate::~ComboboxDelegate()
{
}
QWidget* ComboboxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QComboBox *cb = new QComboBox(parent);
for (const std::pair<QString, QIcon> pair : entries) {
cb->addItem(pair.second, pair.first);
}
return cb;
}
void ComboboxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QComboBox *cb = static_cast<QComboBox*>(editor);
int currentIndex = index.data(Qt::EditRole).toInt();
if (currentIndex >= 0) {
cb->setCurrentIndex(currentIndex);
}
}
void ComboboxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QComboBox *cb = static_cast<QComboBox *>(editor);
model->setData(index, cb->currentIndex(), Qt::EditRole);
}
void ComboboxDelegate::addEntry(const QString& title, const QIcon& icon)
{
entries.emplace_back(title, icon);
}

View file

@ -0,0 +1,47 @@
/*
* 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 COMBOBOXDELEGATE_H
#define COMBOBOXDELEGATE_H
#include <QStyledItemDelegate>
#include <QComboBox>
#include <deque>
/**
* @todo write docs
*/
class ComboboxDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
ComboboxDelegate(QObject *parent = nullptr);
~ComboboxDelegate();
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
void addEntry(const QString& title, const QIcon& icon = QIcon());
private:
std::deque<std::pair<QString, QIcon>> entries;
};
#endif // COMBOBOXDELEGATE_H

29
ui/widgets/CMakeLists.txt Normal file
View file

@ -0,0 +1,29 @@
cmake_minimum_required(VERSION 3.0)
project(squawkWidgets)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
# Instruct CMake to create code from Qt designer ui files
set(CMAKE_AUTOUIC ON)
# Find the QtWidgets library
find_package(Qt5Widgets CONFIG REQUIRED)
add_subdirectory(vcard)
set(squawkWidgets_SRC
conversation.cpp
chat.cpp
room.cpp
newcontact.cpp
accounts.cpp
account.cpp
joinconference.cpp
)
# Tell CMake to create the helloworld executable
add_library(squawkWidgets ${squawkWidgets_SRC})
# Use the Widgets module from Qt 5.
target_link_libraries(squawkWidgets vCardUI)
target_link_libraries(squawkWidgets Qt5::Widgets)

View file

@ -0,0 +1,21 @@
cmake_minimum_required(VERSION 3.0)
project(vCardUI)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
# Instruct CMake to create code from Qt designer ui files
set(CMAKE_AUTOUIC ON)
# Find the QtWidgets library
find_package(Qt5Widgets CONFIG REQUIRED)
set(vCardUI_SRC
vcard.cpp
emailsmodel.cpp
)
# Tell CMake to create the helloworld executable
add_library(vCardUI ${vCardUI_SRC})
# Use the Widgets module from Qt 5.
target_link_libraries(vCardUI Qt5::Widgets)

View file

@ -0,0 +1,145 @@
/*
* 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 "emailsmodel.h"
UI::VCard::EMailsModel::EMailsModel(bool p_edit, QObject* parent):
QAbstractTableModel(parent),
edit(p_edit),
deque()
{
}
int UI::VCard::EMailsModel::columnCount(const QModelIndex& parent) const
{
return 3;
}
int UI::VCard::EMailsModel::rowCount(const QModelIndex& parent) const
{
return deque.size();
}
QVariant UI::VCard::EMailsModel::data(const QModelIndex& index, int role) const
{
if (index.isValid()) {
int col = index.column();
switch (col) {
case 0:
switch (role) {
case Qt::DisplayRole:
return deque[index.row()].address;
default:
return QVariant();
}
break;
case 1:
switch (role) {
case Qt::DisplayRole:
return tr(Shared::VCard::Email::roleNames[deque[index.row()].role].toStdString().c_str());
case Qt::EditRole:
return deque[index.row()].role;
default:
return QVariant();
}
break;
case 2:
switch (role) {
case Qt::DisplayRole:
return QVariant();
case Qt::DecorationRole:
if (deque[index.row()].prefered) {
return Shared::icon("favorite", false);
}
return QVariant();
default:
return QVariant();
}
break;
default:
return QVariant();
}
}
return QVariant();
}
Qt::ItemFlags UI::VCard::EMailsModel::flags(const QModelIndex& index) const
{
Qt::ItemFlags f = QAbstractTableModel::flags(index);
if (edit && index.column() != 2) {
f = Qt::ItemIsEditable | f;
}
return f;
}
bool UI::VCard::EMailsModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
if (role == Qt::EditRole && checkIndex(index)) {
Shared::VCard::Email& item = deque[index.row()];
switch (index.column()) {
case 0:
item.address = value.toString();
return true;
case 1: {
quint8 newRole = value.toUInt();
if (newRole > Shared::VCard::Email::work) {
return false;
}
item.role = static_cast<Shared::VCard::Email::Role>(newRole);
return true;
}
case 2: {
bool newDef = value.toBool();
if (newDef != item.prefered) {
if (newDef) {
dropPrefered();
}
item.prefered = newDef;
return true;
}
}
}
return true;
}
return false;
}
bool UI::VCard::EMailsModel::dropPrefered()
{
bool dropped = false;
int i = 0;
for (Shared::VCard::Email& email : deque) {
if (email.prefered) {
email.prefered = false;
QModelIndex ci = createIndex(i, 2, &email);
emit dataChanged(ci, ci);
dropped = true;
}
++i;
}
return dropped;
}
QModelIndex UI::VCard::EMailsModel::addNewEmptyLine()
{
beginInsertRows(QModelIndex(), deque.size(), deque.size());
deque.emplace_back("");
endInsertRows();
return createIndex(deque.size() - 1, 0, &(deque.back()));
}

View file

@ -0,0 +1,57 @@
/*
* 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_VCARD_EMAILSMODEL_H
#define UI_VCARD_EMAILSMODEL_H
#include <QAbstractTableModel>
#include <QIcon>
#include <deque>
#include "global.h"
namespace UI {
namespace VCard {
class EMailsModel : public QAbstractTableModel
{
Q_OBJECT
public:
EMailsModel(bool edit = false, QObject *parent = nullptr);
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
public slots:
QModelIndex addNewEmptyLine();
private:
bool edit;
std::deque<Shared::VCard::Email> deque;
private:
bool dropPrefered();
};
}}
#endif // UI_VCARD_EMAILSMODEL_H

View file

@ -33,7 +33,10 @@ VCard::VCard(const QString& jid, bool edit, QWidget* parent):
currentAvatarPath(""),
progress(new Progress(100)),
progressLabel(new QLabel()),
overlay(new QWidget())
overlay(new QWidget()),
contextMenu(new QMenu()),
emails(edit),
roleDelegate(new ComboboxDelegate())
{
m_ui->setupUi(this);
m_ui->jabberID->setText(jid);
@ -48,6 +51,18 @@ VCard::VCard(const QString& jid, bool edit, QWidget* parent):
setAvatar->setEnabled(true);
clearAvatar->setEnabled(false);
roleDelegate->addEntry(tr(Shared::VCard::Email::roleNames[0].toStdString().c_str()));
roleDelegate->addEntry(tr(Shared::VCard::Email::roleNames[1].toStdString().c_str()));
roleDelegate->addEntry(tr(Shared::VCard::Email::roleNames[2].toStdString().c_str()));
m_ui->emailsView->setContextMenuPolicy(Qt::CustomContextMenu);
m_ui->emailsView->setModel(&emails);
m_ui->emailsView->setItemDelegateForColumn(1, roleDelegate);
m_ui->emailsView->horizontalHeader()->setStretchLastSection(false);
m_ui->emailsView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
connect(m_ui->emailsView, &QWidget::customContextMenuRequested, this, &VCard::onContextMenu);
if (edit) {
avatarMenu = new QMenu();
m_ui->avatarButton->setMenu(avatarMenu);
@ -69,10 +84,6 @@ VCard::VCard(const QString& jid, bool edit, QWidget* parent):
m_ui->description->setReadOnly(true);
m_ui->url->setReadOnly(true);
m_ui->title->setText(tr("Contact %1 card").arg(jid));
m_ui->addAddressButton->hide();
m_ui->addPhoneButton->hide();
m_ui->addEmailButton->hide();
}
connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &VCard::onButtonBoxAccepted);
@ -106,6 +117,9 @@ VCard::~VCard()
if (editable) {
avatarMenu->deleteLater();
}
roleDelegate->deleteLater();
contextMenu->deleteLater();
}
void VCard::setVCard(const QString& jid, const Shared::VCard& card)
@ -253,3 +267,46 @@ void VCard::hideProgress()
overlay->hide();
progress->stop();
}
void VCard::onContextMenu(const QPoint& point)
{
contextMenu->clear();
bool hasMenu = false;
QAbstractItemView* snd = static_cast<QAbstractItemView*>(sender());
if (snd == m_ui->emailsView) {
if (editable) {
hasMenu = true;
QAction* add = contextMenu->addAction(Shared::icon("list-add"), tr("Add email address"));
connect(add, &QAction::triggered, this, &VCard::onAddEmail);
}
}
if (hasMenu) {
contextMenu->popup(snd->viewport()->mapToGlobal(point));
}
}
void VCard::onAddEmail()
{
QModelIndex index = emails.addNewEmptyLine();
m_ui->emailsView->setCurrentIndex(index);
m_ui->emailsView->edit(index);
}
void VCard::onAddAddress()
{
}
void VCard::onAddPhone()
{
}
void VCard::onRemoveAddress()
{
}
void VCard::onRemoveEmail()
{
}
void VCard::onRemovePhone()
{
}

View file

@ -30,11 +30,14 @@
#include <QLabel>
#include <QGraphicsOpacityEffect>
#include <QVBoxLayout>
#include <QMenu>
#include <set>
#include "../../global.h"
#include "../utils/progress.h"
#include "global.h"
#include "emailsmodel.h"
#include "ui/utils/progress.h"
#include "ui/utils/comboboxdelegate.h"
namespace Ui
{
@ -65,6 +68,13 @@ private slots:
void onClearAvatar();
void onSetAvatar();
void onAvatarSelected();
void onAddAddress();
void onRemoveAddress();
void onAddEmail();
void onRemoveEmail();
void onAddPhone();
void onRemovePhone();
void onContextMenu(const QPoint& point);
private:
QScopedPointer<Ui::VCard> m_ui;
@ -76,6 +86,9 @@ private:
Progress* progress;
QLabel* progressLabel;
QWidget* overlay;
QMenu* contextMenu;
UI::VCard::EMailsModel emails;
ComboboxDelegate* roleDelegate;
static const std::set<QString> supportedTypes;

View file

@ -9,8 +9,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>526</width>
<height>662</height>
<width>578</width>
<height>671</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_4">
@ -84,7 +84,7 @@
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<property name="elideMode">
<enum>Qt::ElideNone</enum>
@ -560,42 +560,72 @@
<rect>
<x>0</x>
<y>0</y>
<width>514</width>
<height>488</height>
<width>566</width>
<height>497</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_3" columnstretch="1,2,2,1">
<item row="2" column="2">
<widget class="QPushButton" name="addEmailButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset theme="list-add"/>
<layout class="QGridLayout" name="gridLayout_3" columnstretch="1,3,1,0">
<item row="7" column="1">
<widget class="Line" name="phonesLine">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="6" column="1" colspan="2">
<layout class="QVBoxLayout" name="phonesLayout">
<item>
<widget class="QLabel" name="emptyPhonesPlaceholder">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;User has no contact e-mail addresses&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
<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="11" column="1" colspan="2">
<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>
@ -608,21 +638,43 @@
</property>
</spacer>
</item>
<item row="9" column="1" colspan="2">
<layout class="QVBoxLayout" name="addressesLayout">
<item>
<widget class="QLabel" name="emptyAddressesPlaceholder">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;User has no contact e-mail addresses&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
<item row="8" column="1">
<widget class="QLabel" name="addressesHeading">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:16pt; font-weight:600;&quot;&gt;Addresses&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<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="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:16pt; font-weight:600;&quot;&gt;E-Mail addresses&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QFormLayout" name="contactForm">
<property name="formAlignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
@ -681,124 +733,7 @@
</item>
</layout>
</item>
<item row="8" column="1">
<widget class="QLabel" name="addressesHeading">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:16pt; font-weight:600;&quot;&gt;Addresses&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="Line" name="contactFormLine">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="8" column="2">
<widget class="QPushButton" name="addAddressButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset theme="list-add"/>
</property>
</widget>
</item>
<item row="10" column="1" colspan="2">
<widget class="Line" name="addressesLine">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QPushButton" name="addPhoneButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset theme="list-add"/>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="emailsHeading">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:16pt; font-weight:600;&quot;&gt;E-Mail addresses&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="phenesHeading">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:16pt; font-weight:600;&quot;&gt;Phone numbers&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="Line" name="emailsLine">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<layout class="QVBoxLayout" name="emailsLayout">
<item>
<widget class="QLabel" name="emptyEmailsPlaceholder">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;User has no contact e-mail addresses&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="1" colspan="2">
<widget class="Line" name="phonesLine">
<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="0" column="3" rowspan="12">
<item row="0" column="2" rowspan="12">
<spacer name="contactRightSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -811,6 +746,32 @@
</property>
</spacer>
</item>
<item row="5" column="1">
<widget class="QLabel" name="phenesHeading">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:16pt; font-weight:600;&quot;&gt;Phone numbers&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</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>
@ -905,7 +866,6 @@
<tabstop>jabberID</tabstop>
<tabstop>url</tabstop>
<tabstop>description</tabstop>
<tabstop>scrollArea</tabstop>
</tabstops>
<resources>
<include location="../../resources/resources.qrc"/>