22 #include <QGridLayout>
25 #include <QVBoxLayout>
26 #include <QFormLayout>
28 #include <TelepathyQt/Contact>
29 #include <TelepathyQt/PendingContactInfo>
30 #include <TelepathyQt/AvatarData>
31 #include <TelepathyQt/Presence>
32 #include <TelepathyQt/SharedPtr>
33 #include <TelepathyQt/ContactManager>
34 #include <TelepathyQt/Connection>
35 #include <TelepathyQt/Account>
36 #include <TelepathyQt/PendingContacts>
39 #include <KMessageWidget>
40 #include <KTitleWidget>
41 #include <KLocalizedString>
42 #include <KPushButton>
44 #include <KDateComboBox>
45 #include <KFileDialog>
46 #include <KImageFilePreview>
47 #include <KMessageBox>
62 static struct InfoRow {
64 const QString fieldName;
67 {
FullName, QLatin1String(
"fn"), i18n(
"Full name:") },
68 {
Nickname, QLatin1String(
"nickname"), i18n(
"Nickname:") },
69 {
Email, QLatin1String(
"email"), i18n(
"Email:") },
70 {
Phone, QLatin1String(
"tel"), i18n(
"Phone:") },
71 {
Homepage, QLatin1String(
"url"), i18n(
"Homepage:") },
72 {
Birthday, QLatin1String(
"bday"), i18n(
"Birthday:") },
73 {
Organization, QLatin1String(
"org"), i18n(
"Organization:") }
76 class ContactInfoDialog::Private
81 infoDataChanged(false),
87 changeAvatarButton(0),
93 void onContactUpgraded(Tp::PendingOperation *op);
94 void onContactInfoReceived(Tp::PendingOperation *op);
95 void onChangeAvatarButtonClicked();
96 void onClearAvatarButtonClicked();
97 void onInfoDataChanged();
99 void addInfoRow(
InfoRowIndex index,
const QString &value);
100 void addStateRow(
const QString &description, Tp::Contact::PresenceState state);
102 Tp::AccountPtr account;
106 bool infoDataChanged;
108 QString newAvatarFile;
110 QMap<InfoRowIndex,QWidget*> infoValueWidgets;
112 KMessageWidget *messageWidget;
113 QHBoxLayout *columnsLayout;
114 QFormLayout *infoLayout;
115 QFormLayout *stateLayout;
116 KPushButton *changeAvatarButton;
117 KPushButton *clearAvatarButton;
124 void ContactInfoDialog::Private::onContactUpgraded(Tp::PendingOperation* op)
127 messageWidget->setMessageType(KMessageWidget::Error);
128 messageWidget->setText(op->errorMessage());
129 messageWidget->setCloseButtonVisible(
false);
130 messageWidget->setWordWrap(
true);
131 messageWidget->animatedShow();
135 Tp::PendingContacts *contacts = qobject_cast<Tp::PendingContacts*>(op);
136 Q_ASSERT(contacts->contacts().count() == 1);
138 contact = contacts->contacts().first();
141 if (contacts->features().contains(Tp::Contact::FeatureAvatarData)) {
142 QVBoxLayout *avatarLayout =
new QVBoxLayout();
143 avatarLayout->setSpacing(5);
144 avatarLayout->setAlignment(Qt::AlignHCenter);
145 columnsLayout->addLayout(avatarLayout);
147 avatarLabel =
new QLabel(q);
148 avatarLabel->setMaximumSize(150, 150);
149 avatarLayout->addWidget(avatarLabel, 0, Qt::AlignTop);
152 changeAvatarButton =
new KPushButton(i18n(
"Change Avatar"), q);
153 connect(changeAvatarButton, SIGNAL(clicked(
bool)),
154 q, SLOT(onChangeAvatarButtonClicked()));
155 avatarLayout->addWidget(changeAvatarButton);
157 clearAvatarButton =
new KPushButton(i18n(
"Clear Avatar"), q);
158 connect(clearAvatarButton, SIGNAL(clicked(
bool)),
159 q, SLOT(onClearAvatarButtonClicked()));
160 avatarLayout->addWidget(clearAvatarButton);
162 avatarLayout->addStretch(1);
165 QPixmap avatar(contact->avatarData().fileName);
166 if (avatar.isNull()) {
167 avatar = KIconLoader::global()->loadIcon(QLatin1String(
"im-user"), KIconLoader::Desktop, 128);
168 if (clearAvatarButton) {
169 clearAvatarButton->setEnabled(
false);
172 avatarLabel->setPixmap(avatar.scaled(avatarLabel->maximumSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
176 if (contacts->features().contains(Tp::Contact::FeatureInfo)) {
177 infoLayout =
new QFormLayout();
178 infoLayout->setSpacing(10);
179 columnsLayout->addLayout(infoLayout);
181 Tp::PendingContactInfo *op = contact->requestInfo();
182 connect(op, SIGNAL(finished(Tp::PendingOperation*)),
183 q, SLOT(onContactInfoReceived(Tp::PendingOperation*)));
187 void ContactInfoDialog::Private::onContactInfoReceived(Tp::PendingOperation* op)
190 messageWidget->setMessageType(KMessageWidget::Error);
191 messageWidget->setText(op->errorMessage());
192 messageWidget->setCloseButtonVisible(
false);
193 messageWidget->setWordWrap(
true);
194 messageWidget->animatedShow();
198 Tp::PendingContactInfo *ci = qobject_cast<Tp::PendingContactInfo*>(op);
199 const Tp::ContactInfoFieldList fieldList = ci->infoFields().allFields();
204 Q_FOREACH(
const Tp::ContactInfoField &field, fieldList) {
205 if (field.fieldValue.count() == 0) {
209 if (field.fieldName ==
InfoRows[index].fieldName) {
210 value = field.fieldValue.first();
216 if (!editable && value.isEmpty()) {
220 addInfoRow(index, value);
224 void ContactInfoDialog::Private::onChangeAvatarButtonClicked()
226 QPointer<KFileDialog> fileDialog =
new KFileDialog(KUrl(), QString(), q);
227 fileDialog->setOperationMode(KFileDialog::Opening);
228 fileDialog->setPreviewWidget(
new KImageFilePreview(fileDialog));
229 fileDialog->setMimeFilter(QStringList() << QLatin1String(
"image/*"));
231 int c = fileDialog->exec();
232 if (fileDialog && c) {
233 newAvatarFile = fileDialog->selectedFile();
235 QPixmap avatar(newAvatarFile);
236 if (avatar.isNull()) {
237 KMessageBox::error(q, i18n(
"Failed to load the new avatar image"));
238 newAvatarFile.clear();
242 avatarLabel->setPixmap(avatar.scaled(avatarLabel->maximumSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
243 avatarChanged =
true;
244 clearAvatarButton->setEnabled(
true);
250 void ContactInfoDialog::Private::onClearAvatarButtonClicked()
253 avatar = KIconLoader::global()->loadIcon(QLatin1String(
"im-user"), KIconLoader::Desktop, 128);
255 newAvatarFile.clear();
256 avatarChanged =
true;
259 void ContactInfoDialog::Private::onInfoDataChanged()
261 infoDataChanged =
true;
264 void ContactInfoDialog::Private::addInfoRow(
InfoRowIndex index,
const QString &value)
268 QLabel *descriptionLabel =
new QLabel(row->title, q);
269 QFont font = descriptionLabel->font();
271 descriptionLabel->setFont(font);
275 KDateComboBox *combo =
new KDateComboBox(q);
276 combo->setOptions(KDateComboBox::EditDate | KDateComboBox::SelectDate | KDateComboBox::DatePicker);
277 combo->setMinimumWidth(200);
278 combo->setDate(QDate::fromString(value));
279 connect(combo, SIGNAL(dateChanged(QDate)), q, SLOT(onInfoDataChanged()));
281 infoValueWidgets.insert(index, combo);
283 KLineEdit *edit =
new KLineEdit(q);
284 edit->setMinimumWidth(200);
285 edit->setText(value);
286 connect(edit, SIGNAL(textChanged(QString)), q, SLOT(onInfoDataChanged()));
288 infoValueWidgets.insert(index, edit);
291 QLabel *label =
new QLabel(q);
292 label->setOpenExternalLinks(
true);
293 label->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse);
294 if (index ==
Email) {
295 label->setText(QString::fromLatin1(
"<a href=\"mailto:%1\">%1</a>").arg(value));
298 if (!value.startsWith(QLatin1String(
"http"), Qt::CaseInsensitive)) {
299 format = QLatin1String(
"<a href=\"http://%1\">%1</a>");
301 format = QLatin1String(
"<a href=\"%1\">%1</a>");
303 label->setText(format.arg(value));
305 label->setText(value);
308 infoValueWidgets.insert(index, label);
311 infoLayout->addRow(descriptionLabel, infoValueWidgets.value(index));
314 void ContactInfoDialog::Private::addStateRow(
const QString& description, Tp::Contact::PresenceState state)
316 QLabel *descriptionLabel =
new QLabel(description, q);
320 case Tp::Contact::PresenceStateYes:
321 icon = KIcon(QLatin1String(
"task-complete"));
323 case Tp::Contact::PresenceStateNo:
324 icon = KIcon(QLatin1String(
"task-reject"));
326 case Tp::Contact::PresenceStateAsk:
328 icon = KIcon(QLatin1String(
"task-attempt"));
332 QLabel *stateLabel =
new QLabel(q);
333 stateLabel->setPixmap(icon.pixmap(16));
335 stateLayout->addRow(descriptionLabel, stateLabel);
340 , d(new Private(this))
342 #if 0 // Editing contacts is not yet supported in TpQt
344 d->editable = (contact == account->connection()->selfContact());
347 d->account = account;
348 d->contact = contact;
352 setButtons(User1 | Close);
353 setButtonGuiItem(User1, KGuiItem(i18n(
"Save"), QLatin1String(
"document-save")));
358 setMaximumSize(sizeHint());
360 QVBoxLayout *layout =
new QVBoxLayout(mainWidget());
361 layout->setSpacing(30);
364 KTitleWidget *titleWidget =
new KTitleWidget(
this);
366 titleWidget->setPixmap(presence.icon().pixmap(32, 32), KTitleWidget::ImageLeft);
367 titleWidget->setText(contact->alias());
368 titleWidget->setComment(contact->id());
369 layout->addWidget(titleWidget);
372 d->messageWidget =
new KMessageWidget(
this);
373 d->messageWidget->setVisible(
false);
374 layout->addWidget(d->messageWidget);
377 d->columnsLayout =
new QHBoxLayout();
378 d->columnsLayout->setSpacing(30);
379 layout->addLayout(d->columnsLayout);
382 Tp::PendingContacts *op = contact->manager()->upgradeContacts(
383 QList<Tp::ContactPtr>() << contact,
384 Tp::Features() << Tp::Contact::FeatureAvatarData
385 << Tp::Contact::FeatureInfo);
386 connect(op, SIGNAL(finished(Tp::PendingOperation*)), SLOT(onContactUpgraded(Tp::PendingOperation*)));
390 d->stateLayout =
new QFormLayout();
391 d->stateLayout->setSpacing(10);
392 layout->addLayout(d->stateLayout);
393 d->addStateRow(i18n(
"Contact can see when you are online:"), contact->publishState());
394 d->addStateRow(i18n(
"You can see when the contact is online:"), contact->subscriptionState());
395 d->addStateRow(i18n(
"Contact is blocked:"), contact->isBlocked() ? Tp::Contact::PresenceStateYes : Tp::Contact::PresenceStateNo);
406 if (button == User1) {
407 if (d->avatarChanged) {
409 if (!d->newAvatarFile.isEmpty()) {
410 QFile file(d->newAvatarFile);
411 file.open(QIODevice::ReadOnly);
415 avatar.avatarData = file.readAll();
417 avatar.MIMEType = KMimeType::findByNameAndContent(d->newAvatarFile, &file)->defaultMimeType();
420 d->account->setAvatar(avatar);
423 if (d->infoDataChanged) {
424 Tp::ContactInfoFieldList fieldList;
429 Tp::ContactInfoField field;
430 field.fieldName = row->fieldName;
433 KDateComboBox *combo = qobject_cast<KDateComboBox*>(d->infoValueWidgets.value(index));
434 field.fieldValue << combo->date().toString();
436 KLineEdit *lineEdit = qobject_cast<KLineEdit*>(d->infoValueWidgets.value(index));
437 field.fieldValue << lineEdit->text();
443 #if 0 // This method does not exist in TpQt (yet)
444 d->account->connection()->setContactInfo(fieldList);
458 #include "contact-info-dialog.moc"