[SCM] ktp-common-internals packaging branch, master, updated. debian/15.12.1-2-1839-gf0635e9
Maximiliano Curia
maxy at moszumanska.debian.org
Mon May 9 09:06:16 UTC 2016
Gitweb-URL: http://git.debian.org/?p=pkg-kde/applications/ktp-common-internals.git;a=commitdiff;h=4e0c9f9
The following commit has been merged in the master branch:
commit 4e0c9f95f0e43ce22d37e4811af7b8d196925f46
Author: Dan Vrátil <dvratil at redhat.com>
Date: Sun Jan 27 16:47:50 2013 +0100
Implement KTp::ContactInfoDialog
KTp::ContactInfoDialog provides detailed information about given contact.
REVIEW: 108498
---
KTp/CMakeLists.txt | 3 +
KTp/contact-info-dialog.cpp | 431 +++++++++++++++++++++
...ts-tree-proxy-model.h => contact-info-dialog.h} | 40 +-
3 files changed, 458 insertions(+), 16 deletions(-)
diff --git a/KTp/CMakeLists.txt b/KTp/CMakeLists.txt
index 10c17bf..ed2ab3e 100644
--- a/KTp/CMakeLists.txt
+++ b/KTp/CMakeLists.txt
@@ -5,6 +5,7 @@ set (ktp_common_internals_private_SRCS
abstract-message-filter.cpp
actions.cpp
capabilities-hack-private.cpp
+ contact-info-dialog.cpp
circular-countdown.cpp
contact.cpp
contact-factory.cpp
@@ -34,6 +35,7 @@ set (ktp_common_internals_private_HDRS
actions.h
circular-countdown.h
contact.h
+ contact-info-dialog.h
contact-factory.h
debug.h
error-dictionary.h
@@ -66,6 +68,7 @@ set_target_properties(ktpcommoninternalsprivate PROPERTIES
target_link_libraries (ktpcommoninternalsprivate
${KDE4_KDECORE_LIBS}
+ ${KDE4_KIO_LIBS}
${TELEPATHY_QT4_LIBRARIES}
${TELEPATHY_LOGGER_QT4_LIBRARIES}
${KDE4_KDEUI_LIBS}
diff --git a/KTp/contact-info-dialog.cpp b/KTp/contact-info-dialog.cpp
new file mode 100644
index 0000000..b625065
--- /dev/null
+++ b/KTp/contact-info-dialog.cpp
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2013 Dan Vrátil <dvratil at redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "contact-info-dialog.h"
+#include "contact.h"
+
+#include <QGridLayout>
+#include <QPicture>
+#include <QLabel>
+#include <QVBoxLayout>
+#include <QFormLayout>
+
+#include <TelepathyQt/Contact>
+#include <TelepathyQt/PendingContactInfo>
+#include <TelepathyQt/AvatarData>
+#include <TelepathyQt/Presence>
+#include <TelepathyQt/SharedPtr>
+#include <TelepathyQt/ContactManager>
+#include <TelepathyQt/Connection>
+#include <TelepathyQt/Account>
+
+#include <KDebug>
+#include <KMessageWidget>
+#include <KTitleWidget>
+#include <KLocalizedString>
+#include <KPushButton>
+#include <KLineEdit>
+#include <KDateComboBox>
+#include <KFileDialog>
+#include <KImageFilePreview>
+#include <KMessageBox>
+
+namespace KTp {
+
+enum InfoRowIndex {
+ FullName = 0,
+ Nickname,
+ Email,
+ Phone,
+ Homepage,
+ Birthday,
+ Organization,
+ _InfoRowCount
+};
+
+static struct InfoRow {
+ const InfoRowIndex index;
+ const QString fieldName;
+ const QString title;
+} InfoRows[] = {
+ { FullName, QLatin1String("fn"), i18n("Full name:") },
+ { Nickname, QLatin1String("nickname"), i18n("Nickname:") },
+ { Email, QLatin1String("email"), i18n("Email:") },
+ { Phone, QLatin1String("tel"), i18n("Phone:") },
+ { Homepage, QLatin1String("url"), i18n("Homepage:") },
+ { Birthday, QLatin1String("bday"), i18n("Birthday:") },
+ { Organization, QLatin1String("org"), i18n("Organization:") }
+};
+
+class ContactInfoDialog::Private
+{
+ public:
+ Private(ContactInfoDialog *parent):
+ editable(false),
+ infoDataChanged(false),
+ avatarChanged(false),
+ messageWidget(0),
+ infoLayout(0),
+ stateLayout(0),
+ changeAvatarButton(0),
+ clearAvatarButton(0),
+ avatarLabel(0),
+ q(parent)
+ {}
+
+ void onContactInfoReceived(Tp::PendingOperation *op);
+ void onChangeAvatarButtonClicked();
+ void onClearAvatarButtonClicked();
+ void onInfoDataChanged();
+
+ void addInfoRow(InfoRowIndex index, const QString &value);
+ void addStateRow(const QString &description, Tp::Contact::PresenceState state);
+
+ Tp::AccountPtr account;
+ Tp::ContactPtr contact;
+ bool editable;
+
+ bool infoDataChanged;
+ bool avatarChanged;
+ QString newAvatarFile;
+
+ QMap<InfoRowIndex,QWidget*> infoValueWidgets;
+
+ KMessageWidget *messageWidget;
+ QFormLayout *infoLayout;
+ QFormLayout *stateLayout;
+ KPushButton *changeAvatarButton;
+ KPushButton *clearAvatarButton;
+ QLabel *avatarLabel;
+
+ private:
+ ContactInfoDialog *q;
+};
+
+void ContactInfoDialog::Private::onContactInfoReceived(Tp::PendingOperation* op)
+{
+ if (op->isError()) {
+ messageWidget->setMessageType(KMessageWidget::Error);
+ messageWidget->setText(op->errorMessage());
+ messageWidget->setCloseButtonVisible(false);
+ messageWidget->setWordWrap(true);
+ messageWidget->animatedShow();
+ return;
+ }
+
+ Tp::PendingContactInfo *ci = qobject_cast<Tp::PendingContactInfo*>(op);
+ const Tp::ContactInfoFieldList fieldList = ci->infoFields().allFields();
+
+ for (InfoRowIndex index = (InfoRowIndex) 0; index < _InfoRowCount; index = (InfoRowIndex)(index + 1)) {
+ QString value;
+
+ Q_FOREACH(const Tp::ContactInfoField &field, fieldList) {
+ if (field.fieldValue.count() == 0) {
+ continue;
+ }
+
+ if (field.fieldName == InfoRows[index].fieldName) {
+ value = field.fieldValue.first();
+ break;
+ }
+ }
+
+ /* Show edits for all values when in editable mode */
+ if (!editable && value.isEmpty()) {
+ continue;
+ }
+
+ addInfoRow(index, value);
+ }
+}
+
+void ContactInfoDialog::Private::onChangeAvatarButtonClicked()
+{
+ QPointer<KFileDialog> fileDialog = new KFileDialog(KUrl(), QString(), q);
+ fileDialog->setOperationMode(KFileDialog::Opening);
+ fileDialog->setPreviewWidget(new KImageFilePreview(fileDialog));
+ fileDialog->setMimeFilter(QStringList() << QLatin1String("image/*"));
+
+ int c = fileDialog->exec();
+ if (fileDialog && c) {
+ newAvatarFile = fileDialog->selectedFile();
+
+ QPixmap avatar(newAvatarFile);
+ if (avatar.isNull()) {
+ KMessageBox::error(q, i18n("Failed to load the new avatar image"));
+ newAvatarFile.clear();
+ delete fileDialog;
+ return;
+ }
+ avatarLabel->setPixmap(avatar.scaled(avatarLabel->maximumSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
+ avatarChanged = true;
+ clearAvatarButton->setEnabled(true);
+ }
+
+ delete fileDialog;
+}
+
+void ContactInfoDialog::Private::onClearAvatarButtonClicked()
+{
+ QPixmap avatar;
+ avatar = KIconLoader::global()->loadIcon(QLatin1String("im-user"), KIconLoader::Desktop, 128);
+
+ newAvatarFile.clear();
+ avatarChanged = true;
+}
+
+void ContactInfoDialog::Private::onInfoDataChanged()
+{
+ infoDataChanged = true;
+}
+
+void ContactInfoDialog::Private::addInfoRow(InfoRowIndex index, const QString &value)
+{
+ InfoRow *row = &InfoRows[index];
+
+ QLabel *descriptionLabel = new QLabel(row->title, q);
+ QFont font = descriptionLabel->font();
+ font.setBold(true);
+ descriptionLabel->setFont(font);
+
+ if (editable) {
+ if (index == Birthday) {
+ KDateComboBox *combo = new KDateComboBox(q);
+ combo->setOptions(KDateComboBox::EditDate | KDateComboBox::SelectDate | KDateComboBox::DatePicker);
+ combo->setMinimumWidth(200);
+ combo->setDate(QDate::fromString(value));
+ connect(combo, SIGNAL(dateChanged(QDate)), q, SLOT(onInfoDataChanged()));
+
+ infoValueWidgets.insert(index, combo);
+ } else {
+ KLineEdit *edit = new KLineEdit(q);
+ edit->setMinimumWidth(200);
+ edit->setText(value);
+ connect(edit, SIGNAL(textChanged(QString)), q, SLOT(onInfoDataChanged()));
+
+ infoValueWidgets.insert(index, edit);
+ }
+ } else {
+ QLabel *label = new QLabel(q);
+ label->setOpenExternalLinks(true);
+ label->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse);
+ if (index == Email) {
+ label->setText(QString::fromLatin1("<a href=\"mailto:%1\">%1</a>").arg(value));
+ } else if (index == Homepage) {
+ QString format;
+ if (!value.startsWith(QLatin1String("http"), Qt::CaseInsensitive)) {
+ format = QLatin1String("<a href=\"http://%1\">%1</a>");
+ } else {
+ format = QLatin1String("<a href=\"%1\">%1</a>");
+ }
+ label->setText(format.arg(value));
+ } else {
+ label->setText(value);
+ }
+
+ infoValueWidgets.insert(index, label);
+ }
+
+ infoLayout->addRow(descriptionLabel, infoValueWidgets.value(index));
+}
+
+void ContactInfoDialog::Private::addStateRow(const QString& description, Tp::Contact::PresenceState state)
+{
+ QLabel *descriptionLabel = new QLabel(description, q);
+
+ KIcon icon;
+ switch (state) {
+ case Tp::Contact::PresenceStateYes:
+ icon = KIcon(QLatin1String("task-complete"));
+ break;
+ case Tp::Contact::PresenceStateNo:
+ icon = KIcon(QLatin1String("task-reject"));
+ break;
+ case Tp::Contact::PresenceStateAsk:
+ default:
+ icon = KIcon(QLatin1String("task-attempt"));
+ break;
+ }
+
+ QLabel *stateLabel = new QLabel(q);
+ stateLabel->setPixmap(icon.pixmap(16));
+
+ stateLayout->addRow(descriptionLabel, stateLabel);
+}
+
+ContactInfoDialog::ContactInfoDialog(const Tp::AccountPtr& account, const Tp::ContactPtr& contact, QWidget* parent)
+ : KDialog(parent)
+ , d(new Private(this))
+{
+#if 0 // Editing contacts is not yet supported in TpQt
+ /* Whether contact is the user himself */
+ d->editable = (contact == account->connection()->selfContact());
+#endif
+ d->editable = false;
+ d->account = account;
+ d->contact = contact;
+
+
+ if (d->editable) {
+ setButtons(User1 | Close);
+ setButtonGuiItem(User1, KGuiItem(i18n("Save"), QLatin1String("document-save")));
+ } else {
+ setButtons(Close);
+ }
+
+ setMaximumSize(sizeHint());
+
+ QVBoxLayout *layout = new QVBoxLayout(mainWidget());
+ layout->setSpacing(30);
+
+ /* Title - presence icon, alias, id */
+ KTitleWidget *titleWidget = new KTitleWidget(this);
+ KTp::Presence presence(contact->presence());
+ titleWidget->setPixmap(presence.icon().pixmap(32, 32), KTitleWidget::ImageLeft);
+ titleWidget->setText(contact->alias());
+ titleWidget->setComment(contact->id());
+ layout->addWidget(titleWidget);
+
+ /* Error message to show when an async operation fails */
+ d->messageWidget = new KMessageWidget(this);
+ d->messageWidget->setVisible(false);
+ layout->addWidget(d->messageWidget);
+
+ /* 1st column: avatar; 2nd column: details */
+ QHBoxLayout *hBoxLayout = new QHBoxLayout();
+ hBoxLayout->setSpacing(30);
+ layout->addLayout(hBoxLayout);
+
+ /* Avatar */
+ if (contact->actualFeatures().contains(Tp::Contact::FeatureAvatarData)) {
+
+ QVBoxLayout *avatarLayout = new QVBoxLayout();
+ avatarLayout->setSpacing(5);
+ avatarLayout->setAlignment(Qt::AlignHCenter);
+ hBoxLayout->addLayout(avatarLayout);
+
+ d->avatarLabel = new QLabel(this);
+ d->avatarLabel->setMaximumSize(150, 150);
+ avatarLayout->addWidget(d->avatarLabel, 0, Qt::AlignTop);
+
+ if (d->editable) {
+ d->changeAvatarButton = new KPushButton(i18n("Change Avatar"), this);
+ connect(d->changeAvatarButton, SIGNAL(clicked(bool)),
+ this, SLOT(onChangeAvatarButtonClicked()));
+ avatarLayout->addWidget(d->changeAvatarButton);
+
+ d->clearAvatarButton = new KPushButton(i18n("Clear Avatar"), this);
+ connect(d->clearAvatarButton, SIGNAL(clicked(bool)),
+ this, SLOT(onClearAvatarButtonClicked()));
+ avatarLayout->addWidget(d->clearAvatarButton);
+
+ avatarLayout->addStretch(1);
+ }
+
+ QPixmap avatar(contact->avatarData().fileName);
+ if (avatar.isNull()) {
+ avatar = KIconLoader::global()->loadIcon(QLatin1String("im-user"), KIconLoader::Desktop, 128);
+ if (d->clearAvatarButton) {
+ d->clearAvatarButton->setEnabled(false);
+ }
+ }
+ d->avatarLabel->setPixmap(avatar.scaled(d->avatarLabel->maximumSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
+ }
+
+ /* Details */
+ if (contact->actualFeatures().contains(Tp::Contact::FeatureInfo)) {
+ d->infoLayout = new QFormLayout();
+ d->infoLayout->setSpacing(10);
+ hBoxLayout->addLayout(d->infoLayout);
+
+ Tp::PendingContactInfo *op = contact->requestInfo();
+ connect(op, SIGNAL(finished(Tp::PendingOperation*)),
+ this, SLOT(onContactInfoReceived(Tp::PendingOperation*)));
+ }
+
+ /* State Info - there is no point showing this information when it's about ourselves */
+ if (!d->editable) {
+ d->stateLayout = new QFormLayout();
+ d->stateLayout->setSpacing(10);
+ layout->addLayout(d->stateLayout);
+ d->addStateRow(i18n("Contact can see when you are online:"), contact->publishState());
+ d->addStateRow(i18n("You can see when the contact is online:"), contact->subscriptionState());
+ d->addStateRow(i18n("Contact is blocked:"), contact->isBlocked() ? Tp::Contact::PresenceStateYes : Tp::Contact::PresenceStateNo);
+ }
+}
+
+ContactInfoDialog::~ContactInfoDialog()
+{
+ delete d;
+}
+
+void ContactInfoDialog::slotButtonClicked(int button)
+{
+ if (button == User1) {
+ if (d->avatarChanged) {
+ Tp::Avatar avatar;
+ if (!d->newAvatarFile.isEmpty()) {
+ QFile file(d->newAvatarFile);
+ file.open(QIODevice::ReadOnly);
+
+ QFileInfo fi(file);
+
+ avatar.avatarData = file.readAll();
+ file.seek(0); // reset before passing to KMimeType
+ avatar.MIMEType = KMimeType::findByNameAndContent(d->newAvatarFile, &file)->defaultMimeType();
+ }
+
+ d->account->setAvatar(avatar);
+ }
+
+ if (d->infoDataChanged) {
+ Tp::ContactInfoFieldList fieldList;
+
+ for (InfoRowIndex index = (InfoRowIndex) 0; index < _InfoRowCount; index = (InfoRowIndex) (index + 1)) {
+ InfoRow *row = &InfoRows[index];
+
+ Tp::ContactInfoField field;
+ field.fieldName = row->fieldName;
+
+ if (index == Birthday) {
+ KDateComboBox *combo = qobject_cast<KDateComboBox*>(d->infoValueWidgets.value(index));
+ field.fieldValue << combo->date().toString();
+ } else {
+ KLineEdit *lineEdit = qobject_cast<KLineEdit*>(d->infoValueWidgets.value(index));
+ field.fieldValue << lineEdit->text();
+ }
+
+ fieldList << field;
+ }
+
+#if 0 // This method does not exist in TpQt (yet)
+ d->account->connection()->setContactInfo(fieldList);
+#endif
+ }
+
+ accept();
+ return;
+ }
+
+ KDialog::slotButtonClicked(button);
+}
+
+
+} /* namespace KTp */
+
+#include "contact-info-dialog.moc"
diff --git a/KTp/Models/accounts-tree-proxy-model.h b/KTp/contact-info-dialog.h
similarity index 52%
copy from KTp/Models/accounts-tree-proxy-model.h
copy to KTp/contact-info-dialog.h
index 9f0eec3..dd320ad 100644
--- a/KTp/Models/accounts-tree-proxy-model.h
+++ b/KTp/contact-info-dialog.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 David Edmundson <kde at davidedmundson.co.uk>
+ * Copyright (C) 2013 Dan Vrátil <dvratil at redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -16,36 +16,44 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef KTP_ACCOUNTS_TREE_PROXY_MODEL_H
-#define KTP_ACCOUNTS_TREE_PROXY_MODEL_H
+#ifndef KTP_CONTACTINFODIALOG_H
+#define KTP_CONTACTINFODIALOG_H
-#include "abstract-grouping-proxy-model.h"
+#include <KDialog>
#include <KTp/ktp-export.h>
#include <TelepathyQt/Types>
+namespace Tp {
+class PendingOperation;
+}
+
namespace KTp {
-class KTP_EXPORT AccountsTreeProxyModel : public KTp::AbstractGroupingProxyModel
+class KTP_EXPORT ContactInfoDialog : public KDialog
{
+
Q_OBJECT
-public:
- AccountsTreeProxyModel(QAbstractItemModel *sourceModel, const Tp::AccountManagerPtr &accountManager);
- virtual QSet<QString> groupsForIndex(const QModelIndex &sourceIndex) const;
- virtual QVariant dataForGroup(const QString &group, int role) const;
+ public:
+ explicit ContactInfoDialog(const Tp::AccountPtr &account, const Tp::ContactPtr &contact, QWidget* parent = 0);
+ virtual ~ContactInfoDialog();
-private Q_SLOTS:
- void onAccountAdded(const Tp::AccountPtr &account);
- void onAccountRemoved(const Tp::AccountPtr &account);
+ protected:
+ virtual void slotButtonClicked(int button);
-private:
+ private:
class Private;
- Private *d;
+ Private * const d;
+ Q_PRIVATE_SLOT(d, void onContactInfoReceived(Tp::PendingOperation*));
+ Q_PRIVATE_SLOT(d, void onChangeAvatarButtonClicked());
+ Q_PRIVATE_SLOT(d, void onClearAvatarButtonClicked());
+ Q_PRIVATE_SLOT(d, void onInfoDataChanged());
+;
};
-}
+} // namespace KTp
-#endif // ACCOUNTSTREEPROXYMODEL_H
+#endif // KTP_CONTACTINFODIALOG_H
--
ktp-common-internals packaging
More information about the pkg-kde-commits
mailing list