vCard #29
@ -1361,6 +1361,23 @@ void Core::Account::onVCardReceived(const QXmppVCardIq& card)
|
||||
vCard.setOrgUnit(org.unit());
|
||||
vCard.setOrgTitle(org.title());
|
||||
|
||||
QList<QXmppVCardEmail> emails = card.emails();
|
||||
std::deque<Shared::VCard::Email>& myEmails = vCard.getEmails();
|
||||
for (const QXmppVCardEmail& em : emails) {
|
||||
Shared::VCard::Email mEm(em.address());
|
||||
QXmppVCardEmail::Type et = em.type();
|
||||
if (et & QXmppVCardEmail::Preferred) {
|
||||
mEm.prefered = true;
|
||||
}
|
||||
if (et & QXmppVCardEmail::Home && !(et & QXmppVCardEmail::Work)) {
|
||||
mEm.role = Shared::VCard::Email::home;
|
||||
} else if (!(et & QXmppVCardEmail::Home) && et & QXmppVCardEmail::Work) {
|
||||
mEm.role = Shared::VCard::Email::work;
|
||||
}
|
||||
|
||||
myEmails.emplace_back(mEm);
|
||||
}
|
||||
|
||||
if (item->hasAvatar()) {
|
||||
if (!item->isAvatarAutoGenerated()) {
|
||||
vCard.setAvatarType(Shared::Avatar::valid);
|
||||
@ -1483,6 +1500,24 @@ void Core::Account::onOwnVCardReceived(const QXmppVCardIq& card)
|
||||
vCard.setAvatarType(Shared::Avatar::empty);
|
||||
}
|
||||
|
||||
|
||||
QList<QXmppVCardEmail> emails = card.emails();
|
||||
std::deque<Shared::VCard::Email>& myEmails = vCard.getEmails();
|
||||
for (const QXmppVCardEmail& em : emails) {
|
||||
Shared::VCard::Email mEm(em.address());
|
||||
QXmppVCardEmail::Type et = em.type();
|
||||
if (et & QXmppVCardEmail::Preferred) {
|
||||
mEm.prefered = true;
|
||||
}
|
||||
if (et & QXmppVCardEmail::Home && !(et & QXmppVCardEmail::Work)) {
|
||||
mEm.role = Shared::VCard::Email::home;
|
||||
} else if (!(et & QXmppVCardEmail::Home) && et & QXmppVCardEmail::Work) {
|
||||
mEm.role = Shared::VCard::Email::work;
|
||||
}
|
||||
|
||||
myEmails.emplace_back(mEm);
|
||||
}
|
||||
|
||||
emit receivedVCard(getLogin() + "@" + getServer(), vCard);
|
||||
}
|
||||
|
||||
@ -1535,6 +1570,27 @@ void Core::Account::uploadVCard(const Shared::VCard& card)
|
||||
org.setTitle(card.getOrgTitle());
|
||||
iq.setOrganization(org);
|
||||
|
||||
const std::deque<Shared::VCard::Email>& myEmails = card.getEmails();
|
||||
QList<QXmppVCardEmail> emails;
|
||||
for (const Shared::VCard::Email& mEm : myEmails) {
|
||||
QXmppVCardEmail em;
|
||||
QXmppVCardEmail::Type t = QXmppVCardEmail::Internet;
|
||||
if (mEm.prefered) {
|
||||
t = t | QXmppVCardEmail::Preferred;
|
||||
}
|
||||
if (mEm.role == Shared::VCard::Email::home) {
|
||||
t = t | QXmppVCardEmail::Home;
|
||||
} else if (mEm.role == Shared::VCard::Email::work) {
|
||||
t = t | QXmppVCardEmail::Work;
|
||||
}
|
||||
em.setType(t);
|
||||
em.setAddress(mEm.address);
|
||||
|
||||
emails.push_back(em);
|
||||
}
|
||||
|
||||
iq.setEmails(emails);
|
||||
|
||||
bool avatarChanged = false;
|
||||
if (card.getAvatarType() == Shared::Avatar::empty) {
|
||||
if (avatarType.size() > 0) {
|
||||
|
30
global.cpp
30
global.cpp
@ -538,6 +538,36 @@ QDateTime Shared::VCard::getReceivingTime() const
|
||||
return receivingTime;
|
||||
}
|
||||
|
||||
std::deque<Shared::VCard::Email> & Shared::VCard::getEmails()
|
||||
{
|
||||
return emails;
|
||||
}
|
||||
|
||||
std::deque<Shared::VCard::Address> & Shared::VCard::getAddresses()
|
||||
{
|
||||
return addresses;
|
||||
}
|
||||
|
||||
std::deque<Shared::VCard::Phone> & Shared::VCard::getPhones()
|
||||
{
|
||||
return phones;
|
||||
}
|
||||
|
||||
const std::deque<Shared::VCard::Email> & Shared::VCard::getEmails() const
|
||||
{
|
||||
return emails;
|
||||
}
|
||||
|
||||
const std::deque<Shared::VCard::Address> & Shared::VCard::getAddresses() const
|
||||
{
|
||||
return addresses;
|
||||
}
|
||||
|
||||
const std::deque<Shared::VCard::Phone> & Shared::VCard::getPhones() const
|
||||
{
|
||||
return phones;
|
||||
}
|
||||
|
||||
const std::deque<QString>Shared::VCard::Contact::roleNames = {"Not specified", "Personal", "Business"};
|
||||
|
||||
QIcon Shared::availabilityIcon(Shared::Availability av, bool big)
|
||||
|
6
global.h
6
global.h
@ -302,6 +302,12 @@ public:
|
||||
QString getOrgTitle() const;
|
||||
void setOrgTitle(const QString& title);
|
||||
QDateTime getReceivingTime() const;
|
||||
std::deque<Email>& getEmails();
|
||||
const std::deque<Email>& getEmails() const;
|
||||
std::deque<Phone>& getPhones();
|
||||
const std::deque<Phone>& getPhones() const;
|
||||
std::deque<Address>& getAddresses();
|
||||
const std::deque<Address>& getAddresses() const;
|
||||
|
||||
private:
|
||||
QString fullName;
|
||||
|
@ -15,18 +15,21 @@
|
||||
* 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 "QTimer"
|
||||
|
||||
#include "comboboxdelegate.h"
|
||||
|
||||
ComboboxDelegate::ComboboxDelegate(QObject *parent):
|
||||
QStyledItemDelegate(parent),
|
||||
entries()
|
||||
entries(),
|
||||
ff(new FocusFilter())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ComboboxDelegate::~ComboboxDelegate()
|
||||
{
|
||||
delete ff;
|
||||
}
|
||||
|
||||
|
||||
@ -48,6 +51,7 @@ void ComboboxDelegate::setEditorData(QWidget *editor, const QModelIndex &index)
|
||||
int currentIndex = index.data(Qt::EditRole).toInt();
|
||||
if (currentIndex >= 0) {
|
||||
cb->setCurrentIndex(currentIndex);
|
||||
cb->installEventFilter(ff);
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,3 +66,20 @@ void ComboboxDelegate::addEntry(const QString& title, const QIcon& icon)
|
||||
{
|
||||
entries.emplace_back(title, icon);
|
||||
}
|
||||
|
||||
bool ComboboxDelegate::FocusFilter::eventFilter(QObject* src, QEvent* evt)
|
||||
{
|
||||
if (evt->type() == QEvent::FocusIn) {
|
||||
QComboBox* cb = static_cast<QComboBox*>(src);
|
||||
cb->removeEventFilter(this);
|
||||
QTimer* timer = new QTimer; //TODO that is ridiculous! I refuse to believe there is no better way than that one!
|
||||
QObject::connect(timer, &QTimer::timeout, [timer, cb]() {
|
||||
cb->showPopup();
|
||||
timer->deleteLater();
|
||||
});
|
||||
|
||||
timer->setSingleShot(true);
|
||||
timer->start(100);
|
||||
}
|
||||
return QObject::eventFilter(src, evt);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QComboBox>
|
||||
#include <QFocusEvent>
|
||||
|
||||
#include <deque>
|
||||
|
||||
@ -30,6 +31,12 @@
|
||||
class ComboboxDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class FocusFilter : public QObject {
|
||||
public:
|
||||
bool eventFilter(QObject *src, QEvent *evt) override;
|
||||
};
|
||||
|
||||
public:
|
||||
ComboboxDelegate(QObject *parent = nullptr);
|
||||
~ComboboxDelegate();
|
||||
@ -42,6 +49,9 @@ public:
|
||||
|
||||
private:
|
||||
std::deque<std::pair<QString, QIcon>> entries;
|
||||
FocusFilter* ff;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // COMBOBOXDELEGATE_H
|
||||
|
@ -43,6 +43,7 @@ QVariant UI::VCard::EMailsModel::data(const QModelIndex& index, int role) const
|
||||
case 0:
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
case Qt::EditRole:
|
||||
return deque[index.row()].address;
|
||||
default:
|
||||
return QVariant();
|
||||
@ -143,3 +144,57 @@ QModelIndex UI::VCard::EMailsModel::addNewEmptyLine()
|
||||
endInsertRows();
|
||||
return createIndex(deque.size() - 1, 0, &(deque.back()));
|
||||
}
|
||||
|
||||
bool UI::VCard::EMailsModel::isPreferred(int row) const
|
||||
{
|
||||
if (row < deque.size()) {
|
||||
return deque[row].prefered;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void UI::VCard::EMailsModel::removeLines(int index, int count)
|
||||
{
|
||||
if (index < deque.size()) {
|
||||
int maxCount = deque.size() - index;
|
||||
if (count > maxCount) {
|
||||
count = maxCount;
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
beginRemoveRows(QModelIndex(), index, index + count - 1);
|
||||
std::deque<Shared::VCard::Email>::const_iterator itr = deque.begin() + index;
|
||||
std::deque<Shared::VCard::Email>::const_iterator end = itr + count;
|
||||
deque.erase(itr, end);
|
||||
endRemoveRows();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UI::VCard::EMailsModel::getEmails(std::deque<Shared::VCard::Email>& emails) const
|
||||
{
|
||||
for (const Shared::VCard::Email& my : deque) {
|
||||
emails.emplace_back(my);
|
||||
}
|
||||
}
|
||||
|
||||
void UI::VCard::EMailsModel::setEmails(const std::deque<Shared::VCard::Email>& emails)
|
||||
{
|
||||
if (deque.size() > 0) {
|
||||
removeLines(0, deque.size());
|
||||
}
|
||||
|
||||
if (emails.size() > 0) {
|
||||
beginInsertRows(QModelIndex(), 0, emails.size() - 1);
|
||||
for (const Shared::VCard::Email& comming : emails) {
|
||||
deque.emplace_back(comming);
|
||||
}
|
||||
endInsertRows();
|
||||
}
|
||||
}
|
||||
|
||||
void UI::VCard::EMailsModel::revertPreferred(int row)
|
||||
{
|
||||
setData(createIndex(row, 2), !isPreferred(row));
|
||||
}
|
||||
|
@ -40,9 +40,15 @@ public:
|
||||
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;
|
||||
bool isPreferred(int row) const;
|
||||
|
||||
void removeLines(int index, int count);
|
||||
void setEmails(const std::deque<Shared::VCard::Email>& emails);
|
||||
void getEmails(std::deque<Shared::VCard::Email>& emails) const;
|
||||
|
||||
public slots:
|
||||
QModelIndex addNewEmptyLine();
|
||||
void revertPreferred(int row);
|
||||
|
||||
private:
|
||||
bool edit;
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
const std::set<QString> VCard::supportedTypes = {"image/jpeg", "image/png"};
|
||||
|
||||
VCard::VCard(const QString& jid, bool edit, QWidget* parent):
|
||||
@ -58,6 +60,7 @@ VCard::VCard(const QString& jid, bool edit, QWidget* parent):
|
||||
m_ui->emailsView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_ui->emailsView->setModel(&emails);
|
||||
m_ui->emailsView->setItemDelegateForColumn(1, roleDelegate);
|
||||
m_ui->emailsView->setColumnWidth(2, 30);
|
||||
m_ui->emailsView->horizontalHeader()->setStretchLastSection(false);
|
||||
m_ui->emailsView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
|
||||
@ -68,7 +71,7 @@ VCard::VCard(const QString& jid, bool edit, QWidget* parent):
|
||||
m_ui->avatarButton->setMenu(avatarMenu);
|
||||
avatarMenu->addAction(setAvatar);
|
||||
avatarMenu->addAction(clearAvatar);
|
||||
m_ui->title->setText(tr("Your card"));
|
||||
m_ui->title->setText(tr("Account %1 card").arg(jid));
|
||||
} else {
|
||||
m_ui->buttonBox->hide();
|
||||
m_ui->fullName->setReadOnly(true);
|
||||
@ -149,6 +152,9 @@ void VCard::setVCard(const Shared::VCard& card)
|
||||
currentAvatarPath = card.getAvatarPath();
|
||||
|
||||
updateAvatar();
|
||||
|
||||
const std::deque<Shared::VCard::Email>& ems = card.getEmails();
|
||||
emails.setEmails(ems);
|
||||
}
|
||||
|
||||
QString VCard::getJid() const
|
||||
@ -174,6 +180,8 @@ void VCard::onButtonBoxAccepted()
|
||||
card.setAvatarPath(currentAvatarPath);
|
||||
card.setAvatarType(currentAvatarType);
|
||||
|
||||
emails.getEmails(card.getEmails());
|
||||
|
||||
emit saveVCard(card);
|
||||
}
|
||||
|
||||
@ -278,6 +286,25 @@ void VCard::onContextMenu(const QPoint& point)
|
||||
hasMenu = true;
|
||||
QAction* add = contextMenu->addAction(Shared::icon("list-add"), tr("Add email address"));
|
||||
connect(add, &QAction::triggered, this, &VCard::onAddEmail);
|
||||
|
||||
QItemSelectionModel* sm = m_ui->emailsView->selectionModel();
|
||||
int selectionSize = sm->selectedRows().size();
|
||||
|
||||
if (selectionSize > 0) {
|
||||
if (selectionSize == 1) {
|
||||
int row = sm->selectedRows().at(0).row();
|
||||
if (emails.isPreferred(row)) {
|
||||
QAction* rev = contextMenu->addAction(Shared::icon("view-media-favorite"), tr("Unset this email as preferred"));
|
||||
connect(rev, &QAction::triggered, std::bind(&UI::VCard::EMailsModel::revertPreferred, &emails, row));
|
||||
} else {
|
||||
QAction* rev = contextMenu->addAction(Shared::icon("favorite"), tr("Set this email as preferred"));
|
||||
connect(rev, &QAction::triggered, std::bind(&UI::VCard::EMailsModel::revertPreferred, &emails, row));
|
||||
}
|
||||
}
|
||||
|
||||
QAction* del = contextMenu->addAction(Shared::icon("remove"), tr("Remove selected email addresses"));
|
||||
connect(del, &QAction::triggered, this, &VCard::onRemoveEmail);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,6 +332,23 @@ void VCard::onRemoveAddress()
|
||||
}
|
||||
void VCard::onRemoveEmail()
|
||||
{
|
||||
QItemSelection selection(m_ui->emailsView->selectionModel()->selection());
|
||||
|
||||
QList<int> rows;
|
||||
for (const QModelIndex& index : selection.indexes()) {
|
||||
rows.append(index.row());
|
||||
}
|
||||
|
||||
std::sort(rows.begin(), rows.end());
|
||||
|
||||
int prev = -1;
|
||||
for (int i = rows.count() - 1; i >= 0; i -= 1) {
|
||||
int current = rows[i];
|
||||
if (current != prev) {
|
||||
emails.removeLines(current, 1);
|
||||
prev = current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VCard::onRemovePhone()
|
||||
|
@ -84,7 +84,7 @@
|
||||
<enum>QTabWidget::Rounded</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="elideMode">
|
||||
<enum>Qt::ElideNone</enum>
|
||||
@ -564,7 +564,7 @@
|
||||
<height>497</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3" columnstretch="1,3,1,0">
|
||||
<layout class="QGridLayout" name="gridLayout_3" columnstretch="1,3,1">
|
||||
<item row="7" column="1">
|
||||
<widget class="Line" name="phonesLine">
|
||||
<property name="orientation">
|
||||
@ -644,7 +644,7 @@
|
||||
<string><html><head/><body><p><span style=" font-size:16pt; font-weight:600;">Addresses</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -670,7 +670,7 @@
|
||||
<string><html><head/><body><p><span style=" font-size:16pt; font-weight:600;">E-Mail addresses</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -752,7 +752,7 @@
|
||||
<string><html><head/><body><p><span style=" font-size:16pt; font-weight:600;">Phone numbers</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
Loading…
Reference in New Issue
Block a user