summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/QtUI/QtVCardWidget')
-rw-r--r--Swift/QtUI/QtVCardWidget/QtCloseButton.cpp45
-rw-r--r--Swift/QtUI/QtVCardWidget/QtCloseButton.h24
-rw-r--r--Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.cpp55
-rw-r--r--Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h28
-rw-r--r--Swift/QtUI/QtVCardWidget/QtResizableLineEdit.cpp51
-rw-r--r--Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h33
-rw-r--r--Swift/QtUI/QtVCardWidget/QtTagComboBox.cpp102
-rw-r--r--Swift/QtUI/QtVCardWidget/QtTagComboBox.h46
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardAddressField.cpp175
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardAddressField.h60
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.cpp99
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.h50
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.cpp61
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.h43
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.cpp64
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.h42
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h52
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardGeneralField.cpp114
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h77
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardHomeWork.cpp40
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardHomeWork.h31
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.cpp82
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.h43
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardJIDField.cpp73
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardJIDField.h42
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.cpp145
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.h54
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.cpp141
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.h62
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.ui251
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardRoleField.cpp50
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardRoleField.h41
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.cpp100
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.h42
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardTitleField.cpp51
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardTitleField.h41
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardURLField.cpp71
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardURLField.h42
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardWidget.cpp374
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardWidget.h63
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardWidget.ui138
41 files changed, 3198 insertions, 0 deletions
diff --git a/Swift/QtUI/QtVCardWidget/QtCloseButton.cpp b/Swift/QtUI/QtVCardWidget/QtCloseButton.cpp
new file mode 100644
index 0000000..ebd62bc
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtCloseButton.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtCloseButton.h"
+
+#include <QMouseEvent>
+#include <QPainter>
+#include <QStyle>
+#include <QStyleOption>
+
+namespace Swift {
+
+QtCloseButton::QtCloseButton(QWidget *parent) : QAbstractButton(parent) {
+
+}
+
+QSize QtCloseButton::sizeHint() const {
+ return QSize(style()->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, 0, 0), style()->pixelMetric(QStyle::PM_TabCloseIndicatorHeight, 0, 0));
+}
+
+bool QtCloseButton::event(QEvent *e) {
+ if (e->type() == QEvent::Enter || e->type() == QEvent::Leave) {
+ update();
+ }
+ return QAbstractButton::event(e);
+}
+
+void QtCloseButton::paintEvent(QPaintEvent *) {
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::HighQualityAntialiasing);
+ QStyleOption opt;
+ opt.init(this);
+ opt.state |= QStyle::State_AutoRaise;
+ if (underMouse() && !isDown()) {
+ opt.state |= QStyle::State_Raised;
+ } else if (isDown()) {
+ opt.state |= QStyle::State_Sunken;
+ }
+ style()->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, &painter, this);
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtCloseButton.h b/Swift/QtUI/QtVCardWidget/QtCloseButton.h
new file mode 100644
index 0000000..cb92e12
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtCloseButton.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QAbstractButton>
+
+namespace Swift {
+
+ class QtCloseButton : public QAbstractButton {
+ Q_OBJECT
+ public:
+ explicit QtCloseButton(QWidget *parent = 0);
+ virtual QSize sizeHint() const;
+
+ protected:
+ virtual bool event(QEvent *e);
+ virtual void paintEvent(QPaintEvent* );
+ };
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.cpp b/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.cpp
new file mode 100644
index 0000000..1cae00a
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtRemovableItemDelegate.h"
+#include <Swiften/Base/Platform.h>
+#include <QEvent>
+#include <QPainter>
+
+namespace Swift {
+
+QtRemovableItemDelegate::QtRemovableItemDelegate(const QStyle* style) : style(style) {
+
+}
+
+void QtRemovableItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex&) const {
+ QStyleOption opt;
+ opt.state = option.state;
+ opt.state |= QStyle::State_AutoRaise;
+ if (option.state.testFlag(QStyle::State_MouseOver)) {
+ opt.state |= QStyle::State_Raised;
+ }
+ opt.rect = option.rect;
+ painter->save();
+ painter->fillRect(option.rect, option.state & QStyle::State_Selected ? option.palette.highlight() : option.palette.base());
+#ifdef SWIFTEN_PLATFORM_MACOSX
+ // workaround for Qt not painting relative to the cell we're in, on OS X
+ int height = style->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, 0, 0);
+ painter->translate(option.rect.x(), option.rect.y() + (option.rect.height() - height)/2);
+#endif
+ style->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, painter);
+ painter->restore();
+}
+
+QWidget* QtRemovableItemDelegate::createEditor(QWidget*, const QStyleOptionViewItem&, const QModelIndex&) const {
+ return NULL;
+}
+
+bool QtRemovableItemDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index) {
+ if (event->type() == QEvent::MouseButtonRelease) {
+ model->removeRow(index.row());
+ return true;
+ } else {
+ return QItemDelegate::editorEvent(event, model, option, index);
+ }
+}
+
+QSize QtRemovableItemDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const {
+ QSize size(style->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, 0, 0) + 2, style->pixelMetric(QStyle::PM_TabCloseIndicatorHeight, 0, 0) + 2);
+ return size;
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h b/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h
new file mode 100644
index 0000000..75137e1
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QItemDelegate>
+
+namespace Swift {
+
+class QtRemovableItemDelegate : public QItemDelegate {
+ public:
+ QtRemovableItemDelegate(const QStyle* style);
+
+ virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex&) const;
+ virtual QWidget* createEditor(QWidget*, const QStyleOptionViewItem&, const QModelIndex&) const;
+ virtual QSize sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const;
+
+ protected:
+ virtual bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);
+
+ private:
+ const QStyle* style;
+};
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.cpp b/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.cpp
new file mode 100644
index 0000000..4f1d3ab
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtResizableLineEdit.h"
+
+namespace Swift {
+
+QtResizableLineEdit::QtResizableLineEdit(QWidget* parent) :
+ QLineEdit(parent) {
+ connect(this, SIGNAL(textChanged(QString)), SLOT(textChanged(QString)));
+ setMinimumWidth(30);
+}
+
+QtResizableLineEdit::~QtResizableLineEdit() {
+}
+
+bool QtResizableLineEdit::isEditable() const {
+ return editable;
+}
+void QtResizableLineEdit::setEditable(const bool editable) {
+ this->editable = editable;
+ if (editable) {
+ setReadOnly(false);
+ } else {
+ setReadOnly(true);
+ }
+}
+
+
+QSize QtResizableLineEdit::sizeHint() const {
+ int horizontalMargin = 10;
+ int verticalMargin = 6;
+ QSize textDimensions;
+#if QT_VERSION >= 0x040700
+ textDimensions = fontMetrics().boundingRect(text().isEmpty() ? placeholderText() : text()).size();
+#else
+ textDimensions = fontMetrics().boundingRect(text().isEmpty() ? QString(" ") : text()).size();
+#endif
+ textDimensions.setWidth(textDimensions.width() + horizontalMargin);
+ textDimensions.setHeight(textDimensions.height() + verticalMargin);
+ return textDimensions;
+}
+
+void QtResizableLineEdit::textChanged(QString) {
+ updateGeometry();
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h b/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h
new file mode 100644
index 0000000..9022d38
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QLineEdit>
+
+namespace Swift {
+
+ class QtResizableLineEdit : public QLineEdit {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+
+ public:
+ explicit QtResizableLineEdit(QWidget* parent = 0);
+ ~QtResizableLineEdit();
+
+ bool isEditable() const;
+ void setEditable(const bool);
+
+ virtual QSize sizeHint() const;
+
+ private slots:
+ void textChanged(QString);
+
+ private:
+ bool editable;
+ };
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtTagComboBox.cpp b/Swift/QtUI/QtVCardWidget/QtTagComboBox.cpp
new file mode 100644
index 0000000..bade009
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtTagComboBox.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtTagComboBox.h"
+
+#include <QAbstractItemView>
+#include <QtGui>
+
+namespace Swift {
+
+QtTagComboBox::QtTagComboBox(QWidget* parent) : QComboBox(parent) {
+ setEditable(false);
+ displayModel = new QStandardItemModel();
+ displayItem = new QStandardItem();
+ displayItem->setText("");
+ displayModel->insertRow(0, displayItem);
+ editMenu = new QMenu();
+ this->setModel(displayModel);
+ editable = true;
+}
+
+QtTagComboBox::~QtTagComboBox() {
+
+}
+
+bool QtTagComboBox::isEditable() const {
+ return editable;
+}
+
+void QtTagComboBox::setEditable(const bool editable) {
+ this->editable = editable;
+}
+
+void QtTagComboBox::addTag(const QString &id, const QString &label) {
+ QAction* tagAction = new QAction(editMenu);
+ tagAction->setText(label);
+ tagAction->setCheckable(true);
+ tagAction->setData(QString(id));
+ editMenu->addAction(tagAction);
+}
+
+void QtTagComboBox::setTag(const QString &id, bool value) {
+ QList<QAction*> tagActions = editMenu->actions();
+ foreach(QAction* action, tagActions) {
+ if (action->data() == id) {
+ action->setChecked(value);
+ updateDisplayItem();
+ return;
+ }
+ }
+}
+
+bool QtTagComboBox::isTagSet(const QString &id) const {
+ QList<QAction*> tagActions = editMenu->actions();
+ foreach(QAction* action, tagActions) {
+ if (action->data() == id) {
+ return action->isChecked();
+ }
+ }
+ return false;
+}
+
+void QtTagComboBox::showPopup() {
+
+}
+
+void QtTagComboBox::hidePopup() {
+
+}
+
+bool QtTagComboBox::event(QEvent* event) {
+ if (event->type() == QEvent::MouseButtonPress ||
+ event->type() == QEvent::KeyRelease) {
+ if (!editable) return true;
+
+ QPoint p = mapToGlobal(QPoint(0,0));
+ p += QPoint(0, height());
+ editMenu->exec(p);
+ updateDisplayItem();
+ return true;
+ }
+ return QComboBox::event(event);
+}
+
+void QtTagComboBox::updateDisplayItem() {
+ QList<QAction*> tagActions = editMenu->actions();
+ QString text = "";
+ foreach(QAction* action, tagActions) {
+ if (action->isChecked()) {
+ if (text != "") {
+ text += ", ";
+ }
+ text += action->text();
+ }
+ }
+ setItemText(0, text);
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtTagComboBox.h b/Swift/QtUI/QtVCardWidget/QtTagComboBox.h
new file mode 100644
index 0000000..37a60af
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtTagComboBox.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QComboBox>
+#include <QMenu>
+#include <QStandardItem>
+#include <QStandardItemModel>
+
+namespace Swift {
+
+class QtTagComboBox : public QComboBox {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+
+ public:
+ explicit QtTagComboBox(QWidget* parent = 0);
+ ~QtTagComboBox();
+
+ bool isEditable() const;
+ void setEditable(const bool);
+
+ void addTag(const QString& id, const QString& label);
+ void setTag(const QString& id, bool value);
+ bool isTagSet(const QString& id) const;
+
+ virtual void showPopup();
+ virtual void hidePopup();
+
+ virtual bool event(QEvent* event);
+
+ private:
+ void updateDisplayItem();
+
+ private:
+ bool editable;
+ QStandardItemModel* displayModel;
+ QStandardItem* displayItem;
+ QMenu* editMenu;
+};
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardAddressField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardAddressField.cpp
new file mode 100644
index 0000000..f394af0
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardAddressField.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardAddressField.h"
+
+#include <QGridLayout>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+
+namespace Swift {
+
+QtVCardAddressField::QtVCardAddressField(QWidget* parent, QGridLayout *layout, bool editable) :
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Address")) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+}
+
+QtVCardAddressField::~QtVCardAddressField() {
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
+}
+
+void QtVCardAddressField::setupContentWidgets() {
+ textFieldGridLayout = new QGridLayout();
+
+ streetLineEdit = new QtResizableLineEdit(this);
+ textFieldGridLayout->addWidget(streetLineEdit, 0, 0, Qt::AlignVCenter);
+
+ poboxLineEdit = new QtResizableLineEdit(this);
+ textFieldGridLayout->addWidget(poboxLineEdit, 0, 1, Qt::AlignVCenter);
+
+ addressextLineEdit = new QtResizableLineEdit(this);
+ textFieldGridLayout->addWidget(addressextLineEdit, 1, 0, Qt::AlignVCenter);
+
+ cityLineEdit = new QtResizableLineEdit(this);
+ textFieldGridLayout->addWidget(cityLineEdit, 2, 0, Qt::AlignVCenter);
+
+ pocodeLineEdit = new QtResizableLineEdit(this);
+ textFieldGridLayout->addWidget(pocodeLineEdit, 2, 1, Qt::AlignVCenter);
+
+ regionLineEdit = new QtResizableLineEdit(this);
+ textFieldGridLayout->addWidget(regionLineEdit, 3, 0, Qt::AlignVCenter);
+
+ countryLineEdit = new QtResizableLineEdit(this);
+ textFieldGridLayout->addWidget(countryLineEdit, 4, 0, Qt::AlignVCenter);
+ textFieldGridLayout->setVerticalSpacing(2);
+ getGridLayout()->addLayout(textFieldGridLayout, getGridLayout()->rowCount()-1, 2, 5, 2, Qt::AlignVCenter);
+ textFieldGridLayoutItem = getGridLayout()->itemAtPosition(getGridLayout()->rowCount()-1, 2);
+
+#if QT_VERSION >= 0x040700
+ streetLineEdit->setPlaceholderText(tr("Street"));
+ poboxLineEdit->setPlaceholderText(tr("PO Box"));
+ addressextLineEdit->setPlaceholderText(tr("Address Extension"));
+ cityLineEdit->setPlaceholderText(tr("City"));
+ pocodeLineEdit->setPlaceholderText(tr("Postal Code"));
+ regionLineEdit->setPlaceholderText(tr("Region"));
+ countryLineEdit->setPlaceholderText(tr("Country"));
+#endif
+
+ deliveryTypeLabel = new QLabel(this);
+ deliveryTypeLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
+ getGridLayout()->addWidget(deliveryTypeLabel, getGridLayout()->rowCount()-3, 4, Qt::AlignVCenter);
+
+ domesticRadioButton = new QRadioButton(tr("Domestic Delivery"), this);
+ getGridLayout()->addWidget(domesticRadioButton, getGridLayout()->rowCount()-2, 4, Qt::AlignVCenter);
+
+ internationalRadioButton = new QRadioButton(tr("International Delivery"), this);
+ getGridLayout()->addWidget(internationalRadioButton, getGridLayout()->rowCount()-1, 4, Qt::AlignVCenter);
+
+ buttonGroup = new QButtonGroup(this);
+ buttonGroup->addButton(domesticRadioButton);
+ buttonGroup->addButton(internationalRadioButton);
+
+ setTabOrder(internationalRadioButton, getTagComboBox());
+ getTagComboBox()->addTag("postal", tr("Postal"));
+ getTagComboBox()->addTag("parcel", tr("Parcel"));
+
+ QtVCardHomeWork::setTagComboBox(getTagComboBox());
+
+ textFields << streetLineEdit << poboxLineEdit << addressextLineEdit << cityLineEdit << pocodeLineEdit << regionLineEdit << countryLineEdit;
+ childWidgets << deliveryTypeLabel << domesticRadioButton << internationalRadioButton;
+}
+
+void QtVCardAddressField::customCleanup() {
+ foreach(QWidget* widget, textFields) {
+ widget->hide();
+ textFieldGridLayout->removeWidget(widget);
+ }
+ getGridLayout()->removeItem(textFieldGridLayoutItem);
+}
+
+
+
+bool QtVCardAddressField::isEmpty() const {
+ return streetLineEdit->text().isEmpty() &&
+ poboxLineEdit->text().isEmpty() &&
+ addressextLineEdit->text().isEmpty() &&
+ cityLineEdit->text().isEmpty() &&
+ pocodeLineEdit->text().isEmpty() &&
+ regionLineEdit->text().isEmpty() &&
+ countryLineEdit->text().isEmpty();
+}
+
+void QtVCardAddressField::setAddress(const VCard::Address& address) {
+ setPreferred(address.isPreferred);
+ setHome(address.isHome);
+ setWork(address.isWork);
+ getTagComboBox()->setTag("postal", address.isPostal);
+ getTagComboBox()->setTag("parcel", address.isParcel);
+ domesticRadioButton->setChecked(address.deliveryType == VCard::DomesticDelivery);
+ internationalRadioButton->setChecked(address.deliveryType == VCard::InternationalDelivery);
+ streetLineEdit->setText(P2QSTRING(address.street));
+ poboxLineEdit->setText(P2QSTRING(address.poBox));
+ addressextLineEdit->setText(P2QSTRING(address.addressExtension));
+ cityLineEdit->setText(P2QSTRING(address.locality));
+ pocodeLineEdit->setText(P2QSTRING(address.postalCode));
+ regionLineEdit->setText(P2QSTRING(address.region));
+ countryLineEdit->setText(P2QSTRING(address.country));
+}
+
+VCard::Address QtVCardAddressField::getAddress() const {
+ VCard::Address address;
+ address.isPreferred = getPreferred();
+ address.isHome = getHome();
+ address.isWork = getWork();
+ address.deliveryType = domesticRadioButton->isChecked() ? VCard::DomesticDelivery : (internationalRadioButton->isChecked() ? VCard::InternationalDelivery : VCard::None);
+ address.isPostal = getTagComboBox()->isTagSet("postal");
+ address.isParcel = getTagComboBox()->isTagSet("parcel");
+ address.street = Q2PSTRING(streetLineEdit->text());
+ address.poBox = Q2PSTRING(poboxLineEdit->text());
+ address.addressExtension = Q2PSTRING(addressextLineEdit->text());
+ address.locality = Q2PSTRING(cityLineEdit->text());
+ address.postalCode = Q2PSTRING(pocodeLineEdit->text());
+ address.region = Q2PSTRING(regionLineEdit->text());
+ address.country = Q2PSTRING(countryLineEdit->text());
+ return address;
+}
+
+void QtVCardAddressField::handleEditibleChanged(bool isEditable) {
+ assert(streetLineEdit);
+ assert(poboxLineEdit);
+ assert(addressextLineEdit);
+ assert(cityLineEdit);
+ assert(pocodeLineEdit);
+ assert(regionLineEdit);
+ assert(countryLineEdit);
+ assert(deliveryTypeLabel);
+ assert(domesticRadioButton);
+ assert(internationalRadioButton);
+
+ streetLineEdit->setEditable(isEditable);
+ poboxLineEdit->setEditable(isEditable);
+ addressextLineEdit->setEditable(isEditable);
+ cityLineEdit->setEditable(isEditable);
+ pocodeLineEdit->setEditable(isEditable);
+ regionLineEdit->setEditable(isEditable);
+ countryLineEdit->setEditable(isEditable);
+
+ deliveryTypeLabel->setText(buttonGroup->checkedButton() == 0 ? "" : buttonGroup->checkedButton()->text());
+ deliveryTypeLabel->setVisible(!isEditable);
+
+ domesticRadioButton->setVisible(isEditable);
+ internationalRadioButton->setVisible(isEditable);
+
+ foreach (QWidget* widget, textFields) {
+ QtResizableLineEdit* lineEdit;
+ if ((lineEdit = dynamic_cast<QtResizableLineEdit*>(widget))) {
+ lineEdit->setVisible(isEditable ? true : !lineEdit->text().isEmpty());
+ lineEdit->setStyleSheet(isEditable ? "" : "QLineEdit { border: none; background: transparent; }");
+ }
+ }
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardAddressField.h b/Swift/QtUI/QtVCardWidget/QtVCardAddressField.h
new file mode 100644
index 0000000..5a1256a
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardAddressField.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/VCard.h>
+
+#include <QButtonGroup>
+#include <QRadioButton>
+
+#include "QtResizableLineEdit.h"
+#include "QtVCardFieldInfo.h"
+#include "QtVCardGeneralField.h"
+#include "QtVCardHomeWork.h"
+
+namespace Swift {
+
+class QtVCardAddressField : public QtVCardGeneralField, public QtVCardHomeWork {
+ Q_OBJECT
+
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO("Address", UNLIMITED_INSTANCES, QtVCardAddressField)
+
+ QtVCardAddressField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
+ virtual ~QtVCardAddressField();
+
+ virtual bool isEmpty() const;
+
+ void setAddress(const VCard::Address& address);
+ VCard::Address getAddress() const;
+
+ protected:
+ virtual void setupContentWidgets();
+ virtual void customCleanup();
+
+ public slots:
+ void handleEditibleChanged(bool isEditable);
+
+ private:
+ QList<QWidget*> textFields;
+ QtResizableLineEdit* streetLineEdit;
+ QtResizableLineEdit* poboxLineEdit;
+ QtResizableLineEdit* addressextLineEdit;
+ QtResizableLineEdit* cityLineEdit;
+ QtResizableLineEdit* pocodeLineEdit;
+ QtResizableLineEdit* regionLineEdit;
+ QtResizableLineEdit* countryLineEdit;
+ QGridLayout* textFieldGridLayout;
+ QLayoutItem* textFieldGridLayoutItem;
+
+ QLabel* deliveryTypeLabel;
+ QRadioButton* domesticRadioButton;
+ QRadioButton* internationalRadioButton;
+ QButtonGroup* buttonGroup;
+};
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.cpp
new file mode 100644
index 0000000..98e313f
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardAddressLabelField.h"
+
+#include <QGridLayout>
+#include <boost/algorithm/string.hpp>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+
+namespace Swift {
+
+QtVCardAddressLabelField::QtVCardAddressLabelField(QWidget* parent, QGridLayout *layout, bool editable) :
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Address Label")) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+}
+
+QtVCardAddressLabelField::~QtVCardAddressLabelField() {
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
+}
+
+void QtVCardAddressLabelField::setupContentWidgets() {
+ addressLabelPlainTextEdit = new QPlainTextEdit(this);
+ addressLabelPlainTextEdit->setTabChangesFocus(true);
+ getGridLayout()->addWidget(addressLabelPlainTextEdit, getGridLayout()->rowCount()-1, 2, 3, 2, Qt::AlignVCenter);
+
+ deliveryTypeLabel = new QLabel(this);
+ deliveryTypeLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
+ getGridLayout()->addWidget(deliveryTypeLabel, getGridLayout()->rowCount()-2, 4, Qt::AlignVCenter);
+
+ domesticRadioButton = new QRadioButton(tr("Domestic Delivery"), this);
+ getGridLayout()->addWidget(domesticRadioButton, getGridLayout()->rowCount()-2, 4, Qt::AlignVCenter);
+
+ internationalRadioButton = new QRadioButton(tr("International Delivery"), this);
+ getGridLayout()->addWidget(internationalRadioButton, getGridLayout()->rowCount()-1, 4, Qt::AlignVCenter);
+
+ buttonGroup = new QButtonGroup(this);
+ buttonGroup->addButton(domesticRadioButton);
+ buttonGroup->addButton(internationalRadioButton);
+
+ setTabOrder(internationalRadioButton, getTagComboBox());
+ getTagComboBox()->addTag("postal", tr("Postal"));
+ getTagComboBox()->addTag("parcel", tr("Parcel"));
+
+ QtVCardHomeWork::setTagComboBox(getTagComboBox());
+ deliveryTypeLabel->hide();
+ childWidgets << addressLabelPlainTextEdit << deliveryTypeLabel << domesticRadioButton << internationalRadioButton;
+}
+
+bool QtVCardAddressLabelField::isEmpty() const {
+ return addressLabelPlainTextEdit->toPlainText().isEmpty();
+}
+
+void QtVCardAddressLabelField::setAddressLabel(const VCard::AddressLabel& addressLabel) {
+ setPreferred(addressLabel.isPreferred);
+ setHome(addressLabel.isHome);
+ setWork(addressLabel.isWork);
+ getTagComboBox()->setTag("postal", addressLabel.isPostal);
+ getTagComboBox()->setTag("parcel", addressLabel.isParcel);
+ domesticRadioButton->setChecked(addressLabel.deliveryType == VCard::DomesticDelivery);
+ internationalRadioButton->setChecked(addressLabel.deliveryType == VCard::InternationalDelivery);
+ std::string joinedLines = boost::algorithm::join(addressLabel.lines, "\n");
+ addressLabelPlainTextEdit->setPlainText(P2QSTRING(joinedLines));
+}
+
+VCard::AddressLabel QtVCardAddressLabelField::getAddressLabel() const {
+ VCard::AddressLabel addressLabel;
+ addressLabel.isPreferred = getPreferred();
+ addressLabel.isHome = getHome();
+ addressLabel.isWork = getWork();
+ addressLabel.deliveryType = domesticRadioButton->isChecked() ? VCard::DomesticDelivery : (internationalRadioButton->isChecked() ? VCard::InternationalDelivery : VCard::None);
+ addressLabel.isPostal = getTagComboBox()->isTagSet("postal");
+ addressLabel.isParcel = getTagComboBox()->isTagSet("parcel");
+
+ std::string lines = Q2PSTRING(addressLabelPlainTextEdit->toPlainText());
+ boost::split(addressLabel.lines, lines, boost::is_any_of("\n"));
+ return addressLabel;
+}
+
+void QtVCardAddressLabelField::handleEditibleChanged(bool isEditable) {
+ assert(addressLabelPlainTextEdit);
+ assert(deliveryTypeLabel);
+ assert(domesticRadioButton);
+ assert(internationalRadioButton);
+
+ addressLabelPlainTextEdit->setReadOnly(!isEditable);
+ addressLabelPlainTextEdit->setStyleSheet(isEditable ? "" : "QPlainTextEdit { background: transparent; }");
+
+ deliveryTypeLabel->setText(buttonGroup->checkedButton() == 0 ? "" : buttonGroup->checkedButton()->text());
+ deliveryTypeLabel->setVisible(!isEditable);
+
+ domesticRadioButton->setVisible(isEditable);
+ internationalRadioButton->setVisible(isEditable);
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.h b/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.h
new file mode 100644
index 0000000..a665d31
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QButtonGroup>
+#include <QPlainTextEdit>
+#include <QRadioButton>
+
+#include <Swiften/Elements/VCard.h>
+
+#include <Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardHomeWork.h>
+
+namespace Swift {
+
+class QtVCardAddressLabelField : public QtVCardGeneralField, public QtVCardHomeWork {
+ Q_OBJECT
+
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO("Address Label", UNLIMITED_INSTANCES, QtVCardAddressLabelField)
+
+ QtVCardAddressLabelField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
+ virtual ~QtVCardAddressLabelField();
+
+ virtual bool isEmpty() const;
+
+ void setAddressLabel(const VCard::AddressLabel& addressLabel);
+ VCard::AddressLabel getAddressLabel() const;
+
+ protected:
+ virtual void setupContentWidgets();
+
+ public slots:
+ void handleEditibleChanged(bool isEditable);
+
+ private:
+ QPlainTextEdit* addressLabelPlainTextEdit;
+
+ QLabel* deliveryTypeLabel;
+ QRadioButton* domesticRadioButton;
+ QRadioButton* internationalRadioButton;
+ QButtonGroup* buttonGroup;
+};
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.cpp
new file mode 100644
index 0000000..2afc2f6
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardBirthdayField.h"
+
+#include <QGridLayout>
+#include <QHBoxLayout>
+#include <boost/algorithm/string.hpp>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+
+namespace Swift {
+
+QtVCardBirthdayField::QtVCardBirthdayField(QWidget* parent, QGridLayout *layout, bool editable) :
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Birthday"), false, false) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+}
+
+QtVCardBirthdayField::~QtVCardBirthdayField() {
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
+}
+
+void QtVCardBirthdayField::setupContentWidgets() {
+ birthdayLabel = new QLabel(this);
+ birthdayLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
+ birthdayDateEdit = new QDateEdit(this);
+ birthdayDateEdit->setCalendarPopup(true);
+
+ QHBoxLayout* birthdayLayout = new QHBoxLayout();
+ birthdayLayout->addWidget(birthdayLabel);
+ birthdayLayout->addWidget(birthdayDateEdit);
+
+ getGridLayout()->addLayout(birthdayLayout, getGridLayout()->rowCount()-1, 2, Qt::AlignVCenter);
+
+ getTagComboBox()->hide();
+ birthdayLabel->hide();
+ childWidgets << birthdayLabel << birthdayDateEdit;
+}
+
+bool QtVCardBirthdayField::isEmpty() const {
+ return false;
+}
+
+void QtVCardBirthdayField::setBirthday(const boost::posix_time::ptime& birthday) {
+ birthdayDateEdit->setDate(B2QDATE(birthday).date());
+}
+
+boost::posix_time::ptime QtVCardBirthdayField::getBirthday() const {
+ return boost::posix_time::from_time_t(QDateTime(birthdayDateEdit->date()).toTime_t());
+}
+
+void QtVCardBirthdayField::handleEditibleChanged(bool isEditable) {
+ birthdayLabel->setText(birthdayDateEdit->date().toString(Qt::DefaultLocaleLongDate));
+ birthdayDateEdit->setVisible(isEditable);
+ birthdayLabel->setVisible(!isEditable);
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.h b/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.h
new file mode 100644
index 0000000..4be6e27
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QDateEdit>
+#include <Swiften/Elements/VCard.h>
+
+#include "QtCloseButton.h"
+#include "QtVCardFieldInfo.h"
+#include "QtVCardGeneralField.h"
+
+namespace Swift {
+
+class QtVCardBirthdayField : public QtVCardGeneralField {
+ Q_OBJECT
+
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO("Birthday", 1, QtVCardBirthdayField)
+
+ QtVCardBirthdayField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
+ virtual ~QtVCardBirthdayField();
+
+ virtual bool isEmpty() const;
+
+ void setBirthday(const boost::posix_time::ptime& addressLabel);
+ boost::posix_time::ptime getBirthday() const;
+
+ protected:
+ virtual void setupContentWidgets();
+
+ public slots:
+ void handleEditibleChanged(bool isEditable);
+
+ private:
+ QLabel* birthdayLabel;
+ QDateEdit* birthdayDateEdit;
+};
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.cpp
new file mode 100644
index 0000000..f16c351
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardDescriptionField.h"
+
+#include <boost/algorithm/string.hpp>
+#include <QFontMetrics>
+#include <QGridLayout>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+
+namespace Swift {
+
+QtVCardDescriptionField::QtVCardDescriptionField(QWidget* parent, QGridLayout *layout, bool editable) :
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Description"), false, false) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+}
+
+QtVCardDescriptionField::~QtVCardDescriptionField() {
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
+}
+
+void QtVCardDescriptionField::setupContentWidgets() {
+ descriptionPlainTextEdit = new QPlainTextEdit(this);
+ descriptionPlainTextEdit->setMinimumHeight(70);
+ getGridLayout()->addWidget(descriptionPlainTextEdit, getGridLayout()->rowCount()-1, 2, 2, 2, Qt::AlignVCenter);
+ getTagComboBox()->hide();
+ childWidgets << descriptionPlainTextEdit;
+}
+
+bool QtVCardDescriptionField::isEmpty() const {
+ return descriptionPlainTextEdit->toPlainText().isEmpty();
+}
+
+void QtVCardDescriptionField::setDescription(const std::string& description) {
+ descriptionPlainTextEdit->setPlainText(P2QSTRING(description));
+}
+
+std::string QtVCardDescriptionField::getDescription() const {
+ return Q2PSTRING(descriptionPlainTextEdit->toPlainText());
+}
+
+void QtVCardDescriptionField::handleEditibleChanged(bool isEditable) {
+ assert(descriptionPlainTextEdit);
+
+ if (isEditable) {
+ descriptionPlainTextEdit->setMinimumHeight(70);
+ } else {
+ QFontMetrics inputMetrics(descriptionPlainTextEdit->document()->defaultFont());
+ QRect horizontalBounds = contentsRect().adjusted(0,0,0,9999);
+ QRect boundingRect = inputMetrics.boundingRect(horizontalBounds, Qt::TextWordWrap, descriptionPlainTextEdit->toPlainText() + "A");
+ int left, top, right, bottom;
+ getContentsMargins(&left, &top, &right, &bottom);
+ int height = boundingRect.height() + top + bottom + inputMetrics.height();
+ descriptionPlainTextEdit->setMinimumHeight(height > 70 ? 70 : height);
+ }
+ descriptionPlainTextEdit->setReadOnly(!isEditable);
+ descriptionPlainTextEdit->setStyleSheet(isEditable ? "" : "QPlainTextEdit { background: transparent; }");
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.h b/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.h
new file mode 100644
index 0000000..3b1b3d9
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/VCard.h>
+
+#include <QPlainTextEdit>
+
+#include "QtVCardFieldInfo.h"
+#include "QtVCardGeneralField.h"
+
+namespace Swift {
+
+class QtVCardDescriptionField : public QtVCardGeneralField {
+ Q_OBJECT
+
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO("Description", 1, QtVCardDescriptionField)
+
+ QtVCardDescriptionField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
+ virtual ~QtVCardDescriptionField();
+
+ virtual bool isEmpty() const;
+
+ void setDescription(const std::string& description);
+ std::string getDescription() const;
+
+ protected:
+ virtual void setupContentWidgets();
+
+ public slots:
+ void handleEditibleChanged(bool isEditable);
+
+ private:
+ QPlainTextEdit* descriptionPlainTextEdit;
+};
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h b/Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h
new file mode 100644
index 0000000..168c01b
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QGridLayout>
+#include <QObject>
+#include <QString>
+#include <typeinfo>
+
+#define GENERIC_QT_VCARD_FIELD_INFO(MENU_NAME, ALLOWED_INSTANCES, FIELD_CLASS) \
+ class FieldInfo : public QtVCardFieldInfo { \
+ public: \
+ virtual ~FieldInfo() { \
+ } \
+ \
+ virtual QString getMenuName() const { \
+ return QObject::tr(MENU_NAME); \
+ } \
+ \
+ virtual int getAllowedInstances() const { \
+ return ALLOWED_INSTANCES; \
+ } \
+ \
+ virtual QWidget* createFieldInstance(QWidget* parent, QGridLayout* layout, bool editable) const { \
+ return new FIELD_CLASS(parent, layout, editable); \
+ } \
+ \
+ virtual bool testInstance(QWidget* widget) const { \
+ return dynamic_cast<FIELD_CLASS*>(widget) != 0; \
+ } \
+ };
+
+class QWidget;
+
+namespace Swift {
+
+ class QtVCardFieldInfo {
+ public:
+ static const int UNLIMITED_INSTANCES = -1;
+
+ virtual ~QtVCardFieldInfo() {
+ }
+ virtual QString getMenuName() const = 0;
+ virtual int getAllowedInstances() const = 0;
+ virtual QWidget* createFieldInstance(QWidget* parent, QGridLayout* layout, bool editable) const = 0;
+ virtual bool testInstance(QWidget*) const = 0;
+ };
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardGeneralField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardGeneralField.cpp
new file mode 100644
index 0000000..f8b9247
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardGeneralField.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h>
+
+#include <cassert>
+
+#include <QHBoxLayout>
+
+namespace Swift {
+
+QtVCardGeneralField::QtVCardGeneralField(QWidget* parent, QGridLayout* layout, bool editable, int row, QString label, bool preferrable, bool taggable) :
+ QWidget(parent), editable(editable), preferrable(preferrable), taggable(taggable), layout(layout), row(row), preferredCheckBox(0), label(0), labelText(label),
+ tagComboBox(0), closeButton(0) {
+}
+
+QtVCardGeneralField::~QtVCardGeneralField() {
+
+}
+
+void QtVCardGeneralField::initialize() {
+ if (preferrable) {
+ preferredCheckBox = new QCheckBox(this);
+ preferredCheckBox->setStyleSheet(
+ "QCheckBox::indicator { width: 18px; height: 18px; }"
+ "QCheckBox::indicator:checked { image: url(:/icons/star-checked.png); }"
+ "QCheckBox::indicator:unchecked { image: url(:/icons/star-unchecked); }"
+ );
+ layout->addWidget(preferredCheckBox, row, 0, Qt::AlignVCenter);
+ childWidgets << preferredCheckBox;
+ }
+ label = new QLabel(this);
+ label->setText(labelText);
+ layout->addWidget(label, row, 1, Qt::AlignVCenter | Qt::AlignRight);
+
+ tagLabel = new QLabel(this);
+ tagLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
+
+ tagComboBox = new QtTagComboBox(this);
+ closeButton = new QtCloseButton(this);
+ connect(closeButton, SIGNAL(clicked()), SLOT(handleCloseButtonClicked()));
+
+ QHBoxLayout* tagLayout = new QHBoxLayout();
+ tagLayout->addWidget(tagLabel);
+ tagLayout->addWidget(tagComboBox);
+
+ setupContentWidgets();
+ layout->addLayout(tagLayout, row, 4, Qt::AlignTop);
+ layout->addWidget(closeButton, row, 5, Qt::AlignCenter);
+ closeButton->resize(12, 12);
+ tagLabel->hide();
+
+ childWidgets << label << tagComboBox << tagLabel << closeButton;
+ setEditable(editable);
+}
+
+bool QtVCardGeneralField::isEditable() const {
+ return editable;
+}
+
+void QtVCardGeneralField::setEditable(bool editable) {
+ assert(tagComboBox);
+ assert(closeButton);
+
+ this->editable = editable;
+ if (taggable) {
+ tagLabel->setText(tagComboBox->itemText(0));
+ tagComboBox->setVisible(editable);
+ tagLabel->setVisible(!editable);
+ } else {
+ tagLabel->hide();
+ tagComboBox->hide();
+ }
+ closeButton->setVisible(editable);
+ if (preferrable) {
+ assert(preferredCheckBox);
+ preferredCheckBox->setVisible(editable ? true : preferredCheckBox->isChecked());
+ preferredCheckBox->setEnabled(editable);
+ }
+ editableChanged(this->editable);
+}
+
+void QtVCardGeneralField::setPreferred(const bool preferred) {
+ if (preferredCheckBox) preferredCheckBox->setChecked(preferred);
+}
+
+bool QtVCardGeneralField::getPreferred() const {
+ return preferredCheckBox ? preferredCheckBox->isChecked() : false;
+}
+
+void QtVCardGeneralField::customCleanup() {
+}
+
+QtTagComboBox* QtVCardGeneralField::getTagComboBox() const {
+ return tagComboBox;
+}
+
+QGridLayout* QtVCardGeneralField::getGridLayout() const {
+ return layout;
+}
+
+void QtVCardGeneralField::handleCloseButtonClicked() {
+ customCleanup();
+ foreach(QWidget* widget, childWidgets) {
+ widget->hide();
+ layout->removeWidget(widget);
+ }
+ deleteField(this);
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h b/Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h
new file mode 100644
index 0000000..4afe692
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QCheckBox>
+#include <QGridLayout>
+#include <QLabel>
+#include <QWidget>
+
+#include "QtCloseButton.h"
+#include "QtTagComboBox.h"
+
+namespace Swift {
+
+/*
+ * covers features like:
+ * - preffered (star ceckbox)
+ * - combo check boxh
+ * - label
+ * - remove button
+ */
+class QtVCardGeneralField : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable NOTIFY editableChanged)
+ Q_PROPERTY(bool empty READ isEmpty)
+
+ public:
+ explicit QtVCardGeneralField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false, int row = 0, QString label = QString(),
+ bool preferrable = true, bool taggable = true);
+ virtual ~QtVCardGeneralField();
+
+ void initialize();
+
+ virtual bool isEditable() const;
+ virtual void setEditable(bool);
+
+ virtual bool isEmpty() const = 0;
+
+ void setPreferred(const bool preferred);
+ bool getPreferred() const;
+
+ protected:
+ virtual void setupContentWidgets() = 0;
+ virtual void customCleanup();
+
+ QtTagComboBox* getTagComboBox() const;
+ QGridLayout* getGridLayout() const;
+
+ signals:
+ void editableChanged(bool);
+ void deleteField(QtVCardGeneralField*);
+
+ public slots:
+ void handleCloseButtonClicked();
+
+ protected:
+ QList<QWidget*> childWidgets;
+
+ private:
+ bool editable;
+ bool preferrable;
+ bool taggable;
+ QGridLayout* layout;
+ int row;
+ QCheckBox* preferredCheckBox;
+ QLabel* label;
+ QString labelText;
+ QtTagComboBox* tagComboBox;
+ QLabel* tagLabel;
+ QtCloseButton* closeButton;
+};
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardHomeWork.cpp b/Swift/QtUI/QtVCardWidget/QtVCardHomeWork.cpp
new file mode 100644
index 0000000..3119a80
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardHomeWork.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardHomeWork.h"
+
+namespace Swift {
+
+QtVCardHomeWork::QtVCardHomeWork() : tagComboBox(0) {
+}
+
+QtVCardHomeWork::~QtVCardHomeWork() {
+}
+
+void QtVCardHomeWork::setTagComboBox(QtTagComboBox* tagBox) {
+ tagComboBox = tagBox;
+ tagComboBox->addTag("home", QObject::tr("Home"));
+ tagComboBox->addTag("work", QObject::tr("Work"));
+}
+
+void QtVCardHomeWork::setHome(const bool home) {
+ tagComboBox->setTag("home", home);
+}
+
+bool QtVCardHomeWork::getHome() const {
+ return tagComboBox->isTagSet("home");
+}
+
+void QtVCardHomeWork::setWork(const bool work) {
+ tagComboBox->setTag("work", work);
+}
+
+bool QtVCardHomeWork::getWork() const {
+ return tagComboBox->isTagSet("work");
+}
+
+}
+
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardHomeWork.h b/Swift/QtUI/QtVCardWidget/QtVCardHomeWork.h
new file mode 100644
index 0000000..768d984
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardHomeWork.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QObject>
+
+#include "QtTagComboBox.h"
+
+namespace Swift {
+
+class QtVCardHomeWork {
+ public:
+ QtVCardHomeWork();
+ virtual ~QtVCardHomeWork();
+
+ void setTagComboBox(QtTagComboBox* tagBox);
+
+ void setHome(const bool home);
+ bool getHome() const;
+ void setWork(const bool work);
+ bool getWork() const;
+
+ private:
+ QtTagComboBox* tagComboBox;
+};
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.cpp
new file mode 100644
index 0000000..e6f8298
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardInternetEMailField.h"
+
+#include <QGridLayout>
+#include <QHBoxLayout>
+#include <QTextDocument>
+#include <Swiften/Base/Log.h>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/QtUtilities.h>
+
+namespace Swift {
+
+QtVCardInternetEMailField::QtVCardInternetEMailField(QWidget* parent, QGridLayout *layout, bool editable) :
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("E-Mail")) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+}
+
+QtVCardInternetEMailField::~QtVCardInternetEMailField() {
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
+}
+
+void QtVCardInternetEMailField::setupContentWidgets() {
+ emailLabel = new QLabel(this);
+ emailLabel->setOpenExternalLinks(true);
+ emailLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard);
+ emailLineEdit = new QtResizableLineEdit(this);
+#if QT_VERSION >= 0x040700
+ emailLineEdit->setPlaceholderText(tr("alice@wonderland.lit"));
+#endif
+ QHBoxLayout* emailLayout = new QHBoxLayout();
+ emailLayout->addWidget(emailLabel);
+ emailLayout->addWidget(emailLineEdit);
+ getGridLayout()->addLayout(emailLayout, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
+ setTabOrder(emailLineEdit, getTagComboBox());
+ QtVCardHomeWork::setTagComboBox(getTagComboBox());
+ emailLabel->hide();
+ childWidgets << emailLabel << emailLineEdit;
+}
+
+bool QtVCardInternetEMailField::isEmpty() const {
+ return emailLineEdit->text().isEmpty();
+}
+
+void QtVCardInternetEMailField::setInternetEMailAddress(const VCard::EMailAddress& address) {
+ assert(address.isInternet);
+ setPreferred(address.isPreferred);
+ setHome(address.isHome);
+ setWork(address.isWork);
+ emailLineEdit->setText(P2QSTRING(address.address));
+}
+
+VCard::EMailAddress QtVCardInternetEMailField::getInternetEMailAddress() const {
+ VCard::EMailAddress address;
+ address.isInternet = true;
+ address.isPreferred = getPreferred();
+ address.isHome = getHome();
+ address.isWork = getWork();
+ address.address = Q2PSTRING(emailLineEdit->text());
+ return address;
+}
+
+void QtVCardInternetEMailField::handleEditibleChanged(bool isEditable) {
+ assert(emailLineEdit);
+ assert(emailLabel);
+
+ if (isEditable) {
+ emailLineEdit->show();
+ emailLabel->hide();
+ } else {
+ emailLineEdit->hide();
+ emailLabel->setText(QString("<a href=\"mailto:%1\">%1</a>").arg(QtUtilities::htmlEscape(emailLineEdit->text())));
+ emailLabel->show();
+ }
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.h b/Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.h
new file mode 100644
index 0000000..3f8a27f
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/VCard.h>
+
+#include "QtResizableLineEdit.h"
+#include "QtVCardFieldInfo.h"
+#include "QtVCardGeneralField.h"
+#include "QtVCardHomeWork.h"
+
+namespace Swift {
+
+class QtVCardInternetEMailField : public QtVCardGeneralField, public QtVCardHomeWork {
+ Q_OBJECT
+
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO("E-Mail", UNLIMITED_INSTANCES, QtVCardInternetEMailField)
+
+ QtVCardInternetEMailField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
+ virtual ~QtVCardInternetEMailField();
+
+ virtual bool isEmpty() const;
+
+ void setInternetEMailAddress(const VCard::EMailAddress& address);
+ VCard::EMailAddress getInternetEMailAddress() const;
+
+ protected:
+ virtual void setupContentWidgets();
+
+ public slots:
+ void handleEditibleChanged(bool isEditable);
+
+ private:
+ QtResizableLineEdit* emailLineEdit;
+ QLabel* emailLabel;
+};
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardJIDField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardJIDField.cpp
new file mode 100644
index 0000000..23a2b5d
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardJIDField.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardJIDField.h"
+
+#include <QGridLayout>
+#include <QTextDocument>
+#include <boost/algorithm/string.hpp>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/QtUtilities.h>
+
+namespace Swift {
+
+QtVCardJIDField::QtVCardJIDField(QWidget* parent, QGridLayout *layout, bool editable) :
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("JID"), false, false) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+}
+
+QtVCardJIDField::~QtVCardJIDField() {
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
+}
+
+void QtVCardJIDField::setupContentWidgets() {
+ jidLabel = new QLabel(this);
+ jidLabel->setOpenExternalLinks(true);
+ jidLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard);
+ jidLineEdit = new QtResizableLineEdit(this);
+#if QT_VERSION >= 0x040700
+ jidLineEdit->setPlaceholderText(tr("alice@wonderland.lit"));
+#endif
+ QHBoxLayout* jidLayout = new QHBoxLayout();
+ jidLayout->addWidget(jidLabel);
+ jidLayout->addWidget(jidLineEdit);
+ getGridLayout()->addLayout(jidLayout, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
+
+ jidLabel->hide();
+ getTagComboBox()->hide();
+
+ childWidgets << jidLabel << jidLineEdit;
+}
+
+bool QtVCardJIDField::isEmpty() const {
+ return jidLineEdit->text().isEmpty();
+}
+
+void QtVCardJIDField::setJID(const JID& jid) {
+ std::string jidStr = jid.toBare().toString();
+ jidLineEdit->setText(P2QSTRING(jidStr));
+}
+
+JID QtVCardJIDField::getJID() const {
+ return JID(Q2PSTRING(jidLineEdit->text()));
+}
+
+void QtVCardJIDField::handleEditibleChanged(bool isEditable) {
+ assert(jidLineEdit);
+ assert(jidLabel);
+
+ if (isEditable) {
+ jidLineEdit->show();
+ jidLabel->hide();
+ } else {
+ jidLineEdit->hide();
+ jidLabel->setText(QString("<a href=\"xmpp:%1\">%1</a>").arg(QtUtilities::htmlEscape(jidLineEdit->text())));
+ jidLabel->show();
+ }
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardJIDField.h b/Swift/QtUI/QtVCardWidget/QtVCardJIDField.h
new file mode 100644
index 0000000..016bcf8
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardJIDField.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/VCard.h>
+
+#include "QtResizableLineEdit.h"
+#include "QtVCardFieldInfo.h"
+#include "QtVCardGeneralField.h"
+
+namespace Swift {
+
+class QtVCardJIDField : public QtVCardGeneralField {
+ Q_OBJECT
+
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO("JID", UNLIMITED_INSTANCES, QtVCardJIDField)
+
+ QtVCardJIDField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
+ virtual ~QtVCardJIDField();
+
+ virtual bool isEmpty() const;
+
+ void setJID(const JID& jid);
+ JID getJID() const;
+
+ protected:
+ virtual void setupContentWidgets();
+
+ public slots:
+ void handleEditibleChanged(bool isEditable);
+
+ private:
+ QLabel* jidLabel;
+ QtResizableLineEdit* jidLineEdit;
+};
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.cpp
new file mode 100644
index 0000000..98c8e8e
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.h>
+
+#include <boost/algorithm/string.hpp>
+
+#include <QGridLayout>
+#include <QHBoxLayout>
+#include <QHeaderView>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+
+namespace Swift {
+
+QtVCardOrganizationField::QtVCardOrganizationField(QWidget* parent, QGridLayout *layout, bool editable) :
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Organisation"), false, false) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+}
+
+QtVCardOrganizationField::~QtVCardOrganizationField() {
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
+}
+
+void QtVCardOrganizationField::setupContentWidgets() {
+ organizationLabel = new QLabel(this);
+ organizationLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
+ organizationLineEdit = new QtResizableLineEdit(this);
+ QHBoxLayout* organizationLayout = new QHBoxLayout();
+ organizationLayout->addWidget(organizationLabel);
+ organizationLayout->addWidget(organizationLineEdit);
+
+ getGridLayout()->addLayout(organizationLayout, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
+
+ itemDelegate = new QtRemovableItemDelegate(style());
+
+ unitsTreeWidget = new QTreeWidget(this);
+ connect(unitsTreeWidget->model(), SIGNAL(rowsRemoved(QModelIndex, int, int)), SLOT(handleRowsRemoved(QModelIndex,int,int)));
+ unitsTreeWidget->setColumnCount(2);
+ unitsTreeWidget->header()->setStretchLastSection(false);
+ unitsTreeWidget->header()->resizeSection(1, itemDelegate->sizeHint(QStyleOptionViewItem(), QModelIndex()).width());
+
+#if QT_VERSION >= 0x050000
+ unitsTreeWidget->header()->setSectionResizeMode(0, QHeaderView::Stretch);
+#else
+ unitsTreeWidget->header()->setResizeMode(0, QHeaderView::Stretch);
+#endif
+
+ unitsTreeWidget->setHeaderHidden(true);
+ unitsTreeWidget->setRootIsDecorated(false);
+ unitsTreeWidget->setEditTriggers(QAbstractItemView::DoubleClicked);
+ unitsTreeWidget->setItemDelegateForColumn(1, itemDelegate);
+ connect(unitsTreeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)), SLOT(handleItemChanged(QTreeWidgetItem*,int)));
+ getGridLayout()->addWidget(unitsTreeWidget, getGridLayout()->rowCount()-1, 4, 2, 1);
+
+ QTreeWidgetItem* item = new QTreeWidgetItem(QStringList("") << "");
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+ unitsTreeWidget->addTopLevelItem(item);
+
+ getTagComboBox()->hide();
+ organizationLabel->hide();
+ childWidgets << organizationLabel << organizationLineEdit << unitsTreeWidget;
+}
+
+bool QtVCardOrganizationField::isEmpty() const {
+ return organizationLineEdit->text().isEmpty() && unitsTreeWidget->model()->rowCount() != 0;
+}
+
+void QtVCardOrganizationField::setOrganization(const VCard::Organization& organization) {
+ organizationLineEdit->setText(P2QSTRING(organization.name));
+ unitsTreeWidget->clear();
+ foreach(std::string unit, organization.units) {
+ QTreeWidgetItem* item = new QTreeWidgetItem(QStringList(P2QSTRING(unit)) << "");
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+ unitsTreeWidget->addTopLevelItem(item);
+ }
+
+ QTreeWidgetItem* item = new QTreeWidgetItem(QStringList("") << "");
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+ unitsTreeWidget->addTopLevelItem(item);
+}
+
+VCard::Organization QtVCardOrganizationField::getOrganization() const {
+ VCard::Organization organization;
+ organization.name = Q2PSTRING(organizationLineEdit->text());
+ for(int i=0; i < unitsTreeWidget->topLevelItemCount(); ++i) {
+ QTreeWidgetItem* row = unitsTreeWidget->topLevelItem(i);
+ if (!row->text(0).isEmpty()) {
+ organization.units.push_back(Q2PSTRING(row->text(0)));
+ }
+ }
+
+ return organization;
+}
+
+void QtVCardOrganizationField::handleEditibleChanged(bool isEditable) {
+ assert(organizationLineEdit);
+ assert(unitsTreeWidget);
+
+ organizationLineEdit->setVisible(isEditable);
+ organizationLabel->setVisible(!isEditable);
+
+ if (!isEditable) {
+ QString label;
+ for(int i=0; i < unitsTreeWidget->topLevelItemCount(); ++i) {
+ QTreeWidgetItem* row = unitsTreeWidget->topLevelItem(i);
+ if (!row->text(0).isEmpty()) {
+ label += row->text(0) + ", ";
+ }
+ }
+ label += organizationLineEdit->text();
+ organizationLabel->setText(label);
+ }
+ unitsTreeWidget->setVisible(isEditable);
+}
+
+void QtVCardOrganizationField::handleItemChanged(QTreeWidgetItem *, int) {
+ guaranteeEmptyRow();
+}
+
+void QtVCardOrganizationField::handleRowsRemoved(const QModelIndex&, int, int) {
+ guaranteeEmptyRow();
+}
+
+void QtVCardOrganizationField::guaranteeEmptyRow() {
+ bool hasEmptyRow = false;
+ QList<QTreeWidgetItem*> rows = unitsTreeWidget->findItems("", Qt::MatchFixedString);
+ foreach(QTreeWidgetItem* row, rows) {
+ if (row->text(0).isEmpty()) {
+ hasEmptyRow = true;
+ }
+ }
+
+ if (!hasEmptyRow) {
+ QTreeWidgetItem* item = new QTreeWidgetItem(QStringList("") << "");
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+ unitsTreeWidget->addTopLevelItem(item);
+ unitsTreeWidget->setCurrentItem(item);
+ }
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.h b/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.h
new file mode 100644
index 0000000..47868a7
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QTreeWidget>
+
+#include <Swiften/Elements/VCard.h>
+
+#include <Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h>
+#include <Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h>
+
+namespace Swift {
+
+class QtVCardOrganizationField : public QtVCardGeneralField {
+ Q_OBJECT
+
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO("Organization", UNLIMITED_INSTANCES, QtVCardOrganizationField)
+
+ QtVCardOrganizationField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
+ virtual ~QtVCardOrganizationField();
+
+ virtual bool isEmpty() const;
+
+ void setOrganization(const VCard::Organization& organization);
+ VCard::Organization getOrganization() const;
+
+ protected:
+ virtual void setupContentWidgets();
+
+ public slots:
+ void handleEditibleChanged(bool isEditable);
+
+ private slots:
+ void handleItemChanged(QTreeWidgetItem*, int);
+ void handleRowsRemoved(const QModelIndex&, int, int);
+
+ private:
+ void guaranteeEmptyRow();
+
+ private:
+ QLabel* organizationLabel;
+ QtResizableLineEdit* organizationLineEdit;
+ QTreeWidget* unitsTreeWidget;
+ QtRemovableItemDelegate* itemDelegate;
+};
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.cpp b/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.cpp
new file mode 100644
index 0000000..aaea194
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.h>
+
+#include <Swift/QtUI/QtVCardWidget/ui_QtVCardPhotoAndNameFields.h>
+
+#include <QMenu>
+
+namespace Swift {
+
+QtVCardPhotoAndNameFields::QtVCardPhotoAndNameFields(QWidget* parent) :
+ QWidget(parent),
+ ui(new Ui::QtVCardPhotoAndNameFields) {
+ ui->setupUi(this);
+ ui->lineEditPREFIX->hide();
+ ui->lineEditMIDDLE->hide();
+ ui->lineEditSUFFIX->hide();
+ ui->lineEditFN->hide();
+ ui->lineEditNICKNAME->hide();
+ ui->labelFULLNAME->hide();
+
+#if QT_VERSION >= 0x040700
+ ui->lineEditFN->setPlaceholderText(tr("Formatted Name"));
+ ui->lineEditNICKNAME->setPlaceholderText(tr("Nickname"));
+ ui->lineEditPREFIX->setPlaceholderText(tr("Prefix"));
+ ui->lineEditGIVEN->setPlaceholderText(tr("Given Name"));
+ ui->lineEditMIDDLE->setPlaceholderText(tr("Middle Name"));
+ ui->lineEditFAMILY->setPlaceholderText(tr("Last Name"));
+ ui->lineEditSUFFIX->setPlaceholderText(tr("Suffix"));
+#endif
+
+}
+
+QtVCardPhotoAndNameFields::~QtVCardPhotoAndNameFields() {
+ delete ui;
+}
+
+bool QtVCardPhotoAndNameFields::isEditable() const {
+ return editable;
+}
+
+void QtVCardPhotoAndNameFields::setEditable(bool editable) {
+ this->editable = editable;
+
+ ui->avatarWidget->setEditable(editable);
+ ui->lineEditFN->setVisible(editable ? true : !ui->lineEditFN->text().isEmpty());
+ ui->lineEditFN->setEditable(editable);
+ ui->lineEditFN->setStyleSheet(editable ? "" : "QLineEdit {border: none; background-color: transparent;}");
+
+ ui->lineEditNICKNAME->setVisible(editable ? true : !ui->lineEditNICKNAME->text().isEmpty());
+ ui->lineEditNICKNAME->setEditable(editable);
+ ui->lineEditNICKNAME->setStyleSheet(editable ? "" : "QLineEdit {border: none; background-color: transparent;}");
+
+ // prefix given middle last suffix
+ ui->lineEditPREFIX->setVisible(editable);
+ ui->lineEditGIVEN->setVisible(editable);
+ ui->lineEditMIDDLE->setVisible(editable);
+ ui->lineEditFAMILY->setVisible(editable);
+ ui->lineEditSUFFIX->setVisible(editable);
+ ui->labelFULLNAME->setVisible(!editable);
+
+ QStringList fullname;
+ fullname << ui->lineEditPREFIX->text() << ui->lineEditGIVEN->text() << ui->lineEditMIDDLE->text();
+ fullname << ui->lineEditFAMILY->text() << ui->lineEditSUFFIX->text();
+ fullname = fullname.filter(".*\\S.*");
+ ui->labelFULLNAME->setText(fullname.join(" "));
+}
+
+void QtVCardPhotoAndNameFields::setAvatar(const ByteArray &data, const std::string &type) {
+ ui->avatarWidget->setAvatar(data, type);
+}
+
+ByteArray QtVCardPhotoAndNameFields::getAvatarData() const {
+ return ui->avatarWidget->getAvatarData();
+}
+
+std::string QtVCardPhotoAndNameFields::getAvatarType() const {
+ return ui->avatarWidget->getAvatarType();
+}
+
+void QtVCardPhotoAndNameFields::setFormattedName(const QString formattedName) {
+ ui->lineEditFN->setText(formattedName);
+}
+
+QString QtVCardPhotoAndNameFields::getFormattedName() const {
+ return ui->lineEditFN->text();
+}
+
+void QtVCardPhotoAndNameFields::setNickname(const QString nickname) {
+ ui->lineEditNICKNAME->setText(nickname);
+}
+
+QString QtVCardPhotoAndNameFields::getNickname() const {
+ return ui->lineEditNICKNAME->text();
+}
+
+void QtVCardPhotoAndNameFields::setPrefix(const QString prefix) {
+ ui->lineEditPREFIX->setText(prefix);
+}
+
+QString QtVCardPhotoAndNameFields::getPrefix() const {
+ return ui->lineEditPREFIX->text();
+}
+
+void QtVCardPhotoAndNameFields::setGivenName(const QString givenName) {
+ ui->lineEditGIVEN->setText(givenName);
+}
+
+QString QtVCardPhotoAndNameFields::getGivenName() const {
+ return ui->lineEditGIVEN->text();
+}
+
+void QtVCardPhotoAndNameFields::setMiddleName(const QString middleName) {
+ ui->lineEditMIDDLE->setText(middleName);
+}
+
+QString QtVCardPhotoAndNameFields::getMiddleName() const {
+ return ui->lineEditMIDDLE->text();
+}
+
+void QtVCardPhotoAndNameFields::setFamilyName(const QString familyName) {
+ ui->lineEditFAMILY->setText(familyName);
+}
+
+QString QtVCardPhotoAndNameFields::getFamilyName() const {
+ return ui->lineEditFAMILY->text();
+}
+
+void QtVCardPhotoAndNameFields::setSuffix(const QString suffix) {
+ ui->lineEditSUFFIX->setText(suffix);
+}
+
+QString QtVCardPhotoAndNameFields::getSuffix() const {
+ return ui->lineEditSUFFIX->text();
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.h b/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.h
new file mode 100644
index 0000000..6a5ae46
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QMenu>
+#include <QWidget>
+
+#include <Swiften/Base/ByteArray.h>
+
+namespace Ui {
+ class QtVCardPhotoAndNameFields;
+}
+
+
+namespace Swift {
+
+ class QtVCardPhotoAndNameFields : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+
+ public:
+ explicit QtVCardPhotoAndNameFields(QWidget* parent = 0);
+ ~QtVCardPhotoAndNameFields();
+
+ bool isEditable() const;
+ void setEditable(bool);
+
+ void setAvatar(const ByteArray& data, const std::string& type);
+ ByteArray getAvatarData() const;
+ std::string getAvatarType() const;
+
+ void setFormattedName(const QString formattedName);
+ QString getFormattedName() const;
+
+ void setNickname(const QString nickname);
+ QString getNickname() const;
+
+ void setPrefix(const QString prefix);
+ QString getPrefix() const;
+
+ void setGivenName(const QString givenName);
+ QString getGivenName() const;
+
+ void setMiddleName(const QString middleName);
+ QString getMiddleName() const;
+
+ void setFamilyName(const QString familyName);
+ QString getFamilyName() const;
+
+ void setSuffix(const QString suffix);
+ QString getSuffix() const;
+
+ private:
+ Ui::QtVCardPhotoAndNameFields* ui;
+ bool editable;
+ };
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.ui b/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.ui
new file mode 100644
index 0000000..04da2bc
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.ui
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QtVCardPhotoAndNameFields</class>
+ <widget class="QWidget" name="QtVCardPhotoAndNameFields">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>522</width>
+ <height>81</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0,0" rowminimumheight="0,0,0,0,0">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinimumSize</enum>
+ </property>
+ <property name="horizontalSpacing">
+ <number>5</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>1</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item row="0" column="0" rowspan="5">
+ <widget class="Swift::QtAvatarWidget" name="avatarWidget" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" stdset="0">
+ <string/>
+ </property>
+ <property name="flat" stdset="0">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="Swift::QtResizableLineEdit" name="lineEditFN">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>18</pointsize>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="toolTip">
+ <string>Formatted Name</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <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>
+ </item>
+ <item row="1" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="Swift::QtResizableLineEdit" name="lineEditNICKNAME">
+ <property name="toolTip">
+ <string>Nickname</string>
+ </property>
+ <property name="frame">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <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>
+ </item>
+ <item row="2" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>2</number>
+ </property>
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinimumSize</enum>
+ </property>
+ <item>
+ <widget class="QLabel" name="labelFULLNAME">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Swift::QtResizableLineEdit" name="lineEditPREFIX">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Prefix</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Swift::QtResizableLineEdit" name="lineEditGIVEN">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Given Name</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="readOnly">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Swift::QtResizableLineEdit" name="lineEditMIDDLE">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Middle Name</string>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="frame">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Swift::QtResizableLineEdit" name="lineEditFAMILY">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Last Name</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Swift::QtResizableLineEdit" name="lineEditSUFFIX">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Suffix</string>
+ </property>
+ <property name="readOnly">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <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>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Swift::QtResizableLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>QtResizableLineEdit.h</header>
+ </customwidget>
+ <customwidget>
+ <class>Swift::QtAvatarWidget</class>
+ <extends>QWidget</extends>
+ <header>Swift/QtUI/QtAvatarWidget.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardRoleField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardRoleField.cpp
new file mode 100644
index 0000000..b9da767
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardRoleField.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardRoleField.h"
+
+#include <QGridLayout>
+#include <boost/algorithm/string.hpp>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+
+namespace Swift {
+
+QtVCardRoleField::QtVCardRoleField(QWidget* parent, QGridLayout *layout, bool editable) :
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Role"), false, false) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+}
+
+QtVCardRoleField::~QtVCardRoleField() {
+}
+
+void QtVCardRoleField::setupContentWidgets() {
+ roleLineEdit = new QtResizableLineEdit(this);
+ getGridLayout()->addWidget(roleLineEdit, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
+ getTagComboBox()->hide();
+ childWidgets << roleLineEdit;
+}
+
+bool QtVCardRoleField::isEmpty() const {
+ return roleLineEdit->text().isEmpty();
+}
+
+void QtVCardRoleField::setRole(const std::string& role) {
+ roleLineEdit->setText(P2QSTRING(role));
+}
+
+std::string QtVCardRoleField::getRole() const {
+ return Q2PSTRING(roleLineEdit->text());
+}
+
+void QtVCardRoleField::handleEditibleChanged(bool isEditable) {
+ assert(roleLineEdit);
+
+ roleLineEdit->setEditable(isEditable);
+ roleLineEdit->setStyleSheet(isEditable ? "" : "QLineEdit { border: none; background: transparent; }");
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardRoleField.h b/Swift/QtUI/QtVCardWidget/QtVCardRoleField.h
new file mode 100644
index 0000000..3c819ed
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardRoleField.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/VCard.h>
+
+#include "QtResizableLineEdit.h"
+#include "QtVCardFieldInfo.h"
+#include "QtVCardGeneralField.h"
+
+namespace Swift {
+
+class QtVCardRoleField : public QtVCardGeneralField {
+ Q_OBJECT
+
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO("Role", UNLIMITED_INSTANCES, QtVCardRoleField)
+
+ QtVCardRoleField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
+ virtual ~QtVCardRoleField();
+
+ virtual bool isEmpty() const;
+
+ void setRole(const std::string& role);
+ std::string getRole() const;
+
+ protected:
+ virtual void setupContentWidgets();
+
+ public slots:
+ void handleEditibleChanged(bool isEditable);
+
+ private:
+ QtResizableLineEdit* roleLineEdit;
+};
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.cpp
new file mode 100644
index 0000000..063319e
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardTelephoneField.h"
+
+#include <QGridLayout>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+
+namespace Swift {
+
+QtVCardTelephoneField::QtVCardTelephoneField(QWidget* parent, QGridLayout *layout, bool editable) :
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Telephone")) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+}
+
+QtVCardTelephoneField::~QtVCardTelephoneField() {
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
+}
+
+void QtVCardTelephoneField::setupContentWidgets() {
+ telephoneLineEdit = new QtResizableLineEdit(this);
+#if QT_VERSION >= 0x040700
+ telephoneLineEdit->setPlaceholderText(tr("0118 999 881 999 119 7253"));
+#endif
+ getGridLayout()->addWidget(telephoneLineEdit, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
+ setTabOrder(telephoneLineEdit, getTagComboBox());
+ QtVCardHomeWork::setTagComboBox(getTagComboBox());
+
+ getTagComboBox()->addTag("voice", QObject::tr("Voice"));
+ getTagComboBox()->addTag("fax", QObject::tr("Fax"));
+ getTagComboBox()->addTag("pager", QObject::tr("Pager"));
+ getTagComboBox()->addTag("msg", QObject::tr("Voice Messaging"));
+ getTagComboBox()->addTag("cell", QObject::tr("Cell"));
+ getTagComboBox()->addTag("video", QObject::tr("Video"));
+ getTagComboBox()->addTag("bbs", QObject::tr("Bulletin Board System"));
+ getTagComboBox()->addTag("modem", QObject::tr("Modem"));
+ getTagComboBox()->addTag("isdn", QObject::tr("ISDN"));
+ getTagComboBox()->addTag("pcs", QObject::tr("Personal Communication Services"));
+
+ childWidgets << telephoneLineEdit;
+}
+
+bool QtVCardTelephoneField::isEmpty() const {
+ return telephoneLineEdit->text().isEmpty();
+}
+
+void QtVCardTelephoneField::setTelephone(const VCard::Telephone& telephone) {
+ setPreferred(telephone.isPreferred);
+ setHome(telephone.isHome);
+ setWork(telephone.isWork);
+
+ telephoneLineEdit->setText(P2QSTRING(telephone.number));
+
+ getTagComboBox()->setTag("voice", telephone.isVoice);
+ getTagComboBox()->setTag("fax", telephone.isFax);
+ getTagComboBox()->setTag("pager", telephone.isPager);
+ getTagComboBox()->setTag("msg", telephone.isMSG);
+ getTagComboBox()->setTag("cell", telephone.isCell);
+ getTagComboBox()->setTag("video", telephone.isVideo);
+ getTagComboBox()->setTag("bbs", telephone.isBBS);
+ getTagComboBox()->setTag("modem", telephone.isModem);
+ getTagComboBox()->setTag("isdn", telephone.isISDN);
+ getTagComboBox()->setTag("pcs", telephone.isPCS);
+}
+
+VCard::Telephone QtVCardTelephoneField::getTelephone() const {
+ VCard::Telephone telephone;
+
+ telephone.number = Q2PSTRING(telephoneLineEdit->text());
+
+ telephone.isPreferred = getPreferred();
+ telephone.isHome = getHome();
+ telephone.isWork = getWork();
+
+ telephone.isVoice = getTagComboBox()->isTagSet("voice");
+ telephone.isFax = getTagComboBox()->isTagSet("fax");
+ telephone.isPager = getTagComboBox()->isTagSet("pager");
+ telephone.isMSG = getTagComboBox()->isTagSet("msg");
+ telephone.isCell = getTagComboBox()->isTagSet("cell");
+ telephone.isVideo = getTagComboBox()->isTagSet("video");
+ telephone.isBBS = getTagComboBox()->isTagSet("bbs");
+ telephone.isModem = getTagComboBox()->isTagSet("modem");
+ telephone.isISDN = getTagComboBox()->isTagSet("isdn");
+ telephone.isPCS = getTagComboBox()->isTagSet("pcs");
+
+ return telephone;
+}
+
+void QtVCardTelephoneField::handleEditibleChanged(bool isEditable) {
+ assert(telephoneLineEdit);
+
+ telephoneLineEdit->setEditable(isEditable);
+ telephoneLineEdit->setStyleSheet(isEditable ? "" : "QLineEdit { border: none; background: transparent; }");
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.h b/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.h
new file mode 100644
index 0000000..b433e3c
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/VCard.h>
+
+#include "QtResizableLineEdit.h"
+#include "QtVCardFieldInfo.h"
+#include "QtVCardGeneralField.h"
+#include "QtVCardHomeWork.h"
+
+namespace Swift {
+
+class QtVCardTelephoneField : public QtVCardGeneralField, public QtVCardHomeWork {
+ Q_OBJECT
+
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO("Telephone", UNLIMITED_INSTANCES, QtVCardTelephoneField)
+
+ QtVCardTelephoneField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
+ virtual ~QtVCardTelephoneField();
+
+ virtual bool isEmpty() const;
+
+ void setTelephone(const VCard::Telephone& telephone);
+ VCard::Telephone getTelephone() const;
+
+ protected:
+ virtual void setupContentWidgets();
+
+ public slots:
+ void handleEditibleChanged(bool isEditable);
+
+ private:
+ QtResizableLineEdit* telephoneLineEdit;
+};
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardTitleField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardTitleField.cpp
new file mode 100644
index 0000000..43972d0
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardTitleField.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardTitleField.h"
+
+#include <QGridLayout>
+#include <boost/algorithm/string.hpp>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+
+namespace Swift {
+
+QtVCardTitleField::QtVCardTitleField(QWidget* parent, QGridLayout *layout, bool editable) :
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Title"), false, false) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+}
+
+QtVCardTitleField::~QtVCardTitleField() {
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
+}
+
+void QtVCardTitleField::setupContentWidgets() {
+ titleLineEdit = new QtResizableLineEdit(this);
+ getGridLayout()->addWidget(titleLineEdit, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
+ getTagComboBox()->hide();
+ childWidgets << titleLineEdit;
+}
+
+bool QtVCardTitleField::isEmpty() const {
+ return titleLineEdit->text().isEmpty();
+}
+
+void QtVCardTitleField::setTitle(const std::string& title) {
+ titleLineEdit->setText(P2QSTRING(title));
+}
+
+std::string QtVCardTitleField::getTitle() const {
+ return Q2PSTRING(titleLineEdit->text());
+}
+
+void QtVCardTitleField::handleEditibleChanged(bool isEditable) {
+ assert(titleLineEdit);
+
+ titleLineEdit->setEditable(isEditable);
+ titleLineEdit->setStyleSheet(isEditable ? "" : "QLineEdit { border: none; background: transparent; }");
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardTitleField.h b/Swift/QtUI/QtVCardWidget/QtVCardTitleField.h
new file mode 100644
index 0000000..28dc603
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardTitleField.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/VCard.h>
+
+#include "QtResizableLineEdit.h"
+#include "QtVCardFieldInfo.h"
+#include "QtVCardGeneralField.h"
+
+namespace Swift {
+
+class QtVCardTitleField : public QtVCardGeneralField {
+ Q_OBJECT
+
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO("Title", UNLIMITED_INSTANCES, QtVCardTitleField)
+
+ QtVCardTitleField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
+ virtual ~QtVCardTitleField();
+
+ virtual bool isEmpty() const;
+
+ void setTitle(const std::string& title);
+ std::string getTitle() const;
+
+ protected:
+ virtual void setupContentWidgets();
+
+ public slots:
+ void handleEditibleChanged(bool isEditable);
+
+ private:
+ QtResizableLineEdit* titleLineEdit;
+};
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardURLField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardURLField.cpp
new file mode 100644
index 0000000..b39eeaa
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardURLField.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardURLField.h"
+
+#include <QGridLayout>
+#include <QHBoxLayout>
+#include <QTextDocument>
+#include <boost/algorithm/string.hpp>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/QtUtilities.h>
+
+
+namespace Swift {
+
+QtVCardURLField::QtVCardURLField(QWidget* parent, QGridLayout *layout, bool editable) :
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("URL"), false, false) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+}
+
+QtVCardURLField::~QtVCardURLField() {
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
+}
+
+void QtVCardURLField::setupContentWidgets() {
+ urlLabel = new QLabel(this);
+ urlLabel->setOpenExternalLinks(true);
+ urlLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard);
+ urlLineEdit = new QtResizableLineEdit(this);
+
+ QHBoxLayout* urlLayout = new QHBoxLayout();
+ urlLayout->addWidget(urlLabel);
+ urlLayout->addWidget(urlLineEdit);
+
+ getGridLayout()->addLayout(urlLayout, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
+ getTagComboBox()->hide();
+ urlLabel->hide();
+ childWidgets << urlLabel << urlLineEdit;
+}
+
+bool QtVCardURLField::isEmpty() const {
+ return urlLineEdit->text().isEmpty();
+}
+
+void QtVCardURLField::setURL(const std::string& url) {
+ urlLineEdit->setText(P2QSTRING(url));
+}
+
+std::string QtVCardURLField::getURL() const {
+ return Q2PSTRING(urlLineEdit->text());
+}
+
+void QtVCardURLField::handleEditibleChanged(bool isEditable) {
+ assert(urlLineEdit);
+ assert(urlLabel);
+
+ if (isEditable) {
+ urlLineEdit->show();
+ urlLabel->hide();
+ } else {
+ urlLineEdit->hide();
+ urlLabel->setText(QString("<a href=\"%1\">%1</a>").arg(QtUtilities::htmlEscape(urlLineEdit->text())));
+ urlLabel->show();
+ }
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardURLField.h b/Swift/QtUI/QtVCardWidget/QtVCardURLField.h
new file mode 100644
index 0000000..2c011d8
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardURLField.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/VCard.h>
+
+#include "QtResizableLineEdit.h"
+#include "QtVCardFieldInfo.h"
+#include "QtVCardGeneralField.h"
+
+namespace Swift {
+
+class QtVCardURLField : public QtVCardGeneralField {
+ Q_OBJECT
+
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO("URL", UNLIMITED_INSTANCES, QtVCardURLField)
+
+ QtVCardURLField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
+ virtual ~QtVCardURLField();
+
+ virtual bool isEmpty() const;
+
+ void setURL(const std::string& url);
+ std::string getURL() const;
+
+ protected:
+ virtual void setupContentWidgets();
+
+ public slots:
+ void handleEditibleChanged(bool isEditable);
+
+ private:
+ QLabel* urlLabel;
+ QtResizableLineEdit* urlLineEdit;
+};
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardWidget.cpp b/Swift/QtUI/QtVCardWidget/QtVCardWidget.cpp
new file mode 100644
index 0000000..d681fe9
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardWidget.cpp
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swift/QtUI/QtVCardWidget/QtVCardWidget.h>
+
+#include <QDebug>
+#include <QLineEdit>
+#include <QMenu>
+
+#include <Swift/QtUI/QtVCardWidget/ui_QtVCardWidget.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardAddressField.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardJIDField.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardRoleField.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardTitleField.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardURLField.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
+
+namespace Swift {
+
+QtVCardWidget::QtVCardWidget(QWidget* parent) :
+ QWidget(parent),
+ ui(new ::Ui::QtVCardWidget) {
+ ui->setupUi(this);
+
+ ui->cardFields->setColumnStretch(0,0);
+ ui->cardFields->setColumnStretch(1,0);
+ ui->cardFields->setColumnStretch(2,2);
+ ui->cardFields->setColumnStretch(3,1);
+ ui->cardFields->setColumnStretch(4,2);
+ menu = new QMenu(this);
+
+ toolButton = new QToolButton(this);
+ toolButton->setText(tr("Add Field"));
+ toolButton->setArrowType(Qt::NoArrow);
+ toolButton->setAutoRaise(false);
+ toolButton->setPopupMode(QToolButton::InstantPopup);
+ toolButton->hide();
+ toolButton->setMenu(menu);
+
+ addFieldType(menu, boost::make_shared<QtVCardInternetEMailField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardTelephoneField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardAddressField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardAddressLabelField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardBirthdayField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardJIDField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardDescriptionField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardRoleField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardTitleField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardOrganizationField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardURLField::FieldInfo>());
+
+ setEditable(false);
+}
+
+QtVCardWidget::~QtVCardWidget() {
+ delete ui;
+}
+
+bool QtVCardWidget::isEditable() const {
+ return editable;
+}
+
+void QtVCardWidget::setEditable(bool editable) {
+ this->editable = editable;
+
+ ui->photoAndName->setProperty("editable", QVariant(editable));
+
+ foreach(QtVCardGeneralField* field, fields) {
+ field->setEditable(editable);
+ }
+ toolButton->setVisible(editable);
+
+ editableChanged(editable);
+}
+
+void QtVCardWidget::setVCard(VCard::ref vcard) {
+ clearFields();
+ this->vcard = vcard;
+ ui->photoAndName->setFormattedName(P2QSTRING(vcard->getFullName()));
+ ui->photoAndName->setNickname(P2QSTRING(vcard->getNickname()));
+ ui->photoAndName->setPrefix(P2QSTRING(vcard->getPrefix()));
+ ui->photoAndName->setGivenName(P2QSTRING(vcard->getGivenName()));
+ ui->photoAndName->setMiddleName(P2QSTRING(vcard->getMiddleName()));
+ ui->photoAndName->setFamilyName(P2QSTRING(vcard->getFamilyName()));
+ ui->photoAndName->setSuffix(P2QSTRING(vcard->getSuffix()));
+ ui->photoAndName->setAvatar(vcard->getPhoto(), vcard->getPhotoType());
+
+ foreach (const VCard::EMailAddress& address, vcard->getEMailAddresses()) {
+ if (address.isInternet) {
+ QtVCardInternetEMailField* internetEmailField = new QtVCardInternetEMailField(this, ui->cardFields);
+ internetEmailField->initialize();
+ internetEmailField->setInternetEMailAddress(address);
+ appendField(internetEmailField);
+ }
+ }
+
+ foreach (const VCard::Telephone& telephone, vcard->getTelephones()) {
+ QtVCardTelephoneField* telField = new QtVCardTelephoneField(this, ui->cardFields);
+ telField->initialize();
+ telField->setTelephone(telephone);
+ appendField(telField);
+ }
+
+ foreach (const VCard::Address& address, vcard->getAddresses()) {
+ QtVCardAddressField* addressField = new QtVCardAddressField(this, ui->cardFields);
+ addressField->initialize();
+ addressField->setAddress(address);
+ appendField(addressField);
+ }
+
+ foreach (const VCard::AddressLabel& label, vcard->getAddressLabels()) {
+ QtVCardAddressLabelField* addressLabelField = new QtVCardAddressLabelField(this, ui->cardFields);
+ addressLabelField->initialize();
+ addressLabelField->setAddressLabel(label);
+ appendField(addressLabelField);
+ }
+
+ if (!vcard->getBirthday().is_not_a_date_time()) {
+ QtVCardBirthdayField* bdayField = new QtVCardBirthdayField(this, ui->cardFields);
+ bdayField->initialize();
+ bdayField->setBirthday(vcard->getBirthday());
+ appendField(bdayField);
+ }
+
+ foreach (const JID& jid, vcard->getJIDs()) {
+ QtVCardJIDField* jidField = new QtVCardJIDField(this, ui->cardFields);
+ jidField->initialize();
+ jidField->setJID(jid);
+ appendField(jidField);
+ }
+
+ if (!vcard->getDescription().empty()) {
+ QtVCardDescriptionField* descField = new QtVCardDescriptionField(this, ui->cardFields);
+ descField->initialize();
+ descField->setDescription(vcard->getDescription());
+ appendField(descField);
+ }
+
+ foreach (const VCard::Organization& org, vcard->getOrganizations()) {
+ QtVCardOrganizationField* orgField = new QtVCardOrganizationField(this, ui->cardFields);
+ orgField->initialize();
+ orgField->setOrganization(org);
+ appendField(orgField);
+ }
+
+ foreach (const std::string& role, vcard->getRoles()) {
+ QtVCardRoleField* roleField = new QtVCardRoleField(this, ui->cardFields);
+ roleField->initialize();
+ roleField->setRole(role);
+ appendField(roleField);
+ }
+
+ foreach (const std::string& title, vcard->getTitles()) {
+ QtVCardTitleField* titleField = new QtVCardTitleField(this, ui->cardFields);
+ titleField->initialize();
+ titleField->setTitle(title);
+ appendField(titleField);
+ }
+
+ foreach (const std::string& url, vcard->getURLs()) {
+ QtVCardURLField* urlField = new QtVCardURLField(this, ui->cardFields);
+ urlField->initialize();
+ urlField->setURL(url);
+ appendField(urlField);
+ }
+
+ relayoutToolButton();
+ setEditable(editable);
+ window()->resize(sizeHint().width(), size().height() < 200 ? 200 : size().height());
+}
+
+VCard::ref QtVCardWidget::getVCard() {
+ clearEmptyFields();
+ vcard->setFullName(Q2PSTRING(ui->photoAndName->getFormattedName()));
+ vcard->setNickname(Q2PSTRING(ui->photoAndName->getNickname()));
+ vcard->setPrefix(Q2PSTRING(ui->photoAndName->getPrefix()));
+ vcard->setGivenName(Q2PSTRING(ui->photoAndName->getGivenName()));
+ vcard->setMiddleName(Q2PSTRING(ui->photoAndName->getMiddleName()));
+ vcard->setFamilyName(Q2PSTRING(ui->photoAndName->getFamilyName()));
+ vcard->setSuffix(Q2PSTRING(ui->photoAndName->getSuffix()));
+ vcard->setPhoto(ui->photoAndName->getAvatarData());
+ vcard->setPhotoType(ui->photoAndName->getAvatarType());
+
+ vcard->clearEMailAddresses();
+ vcard->clearJIDs();
+ vcard->clearURLs();
+ vcard->clearTelephones();
+ vcard->clearRoles();
+ vcard->clearTitles();
+ vcard->clearOrganizations();
+ vcard->clearAddresses();
+ vcard->clearAddressLabels();
+
+
+ QtVCardBirthdayField* bdayField = NULL;
+ QtVCardDescriptionField* descriptionField = NULL;
+
+ foreach(QtVCardGeneralField* field, fields) {
+ QtVCardInternetEMailField* emailField;
+ if ((emailField = dynamic_cast<QtVCardInternetEMailField*>(field))) {
+ vcard->addEMailAddress(emailField->getInternetEMailAddress());
+ continue;
+ }
+
+ QtVCardTelephoneField* telephoneField;
+ if ((telephoneField = dynamic_cast<QtVCardTelephoneField*>(field))) {
+ vcard->addTelephone(telephoneField->getTelephone());
+ continue;
+ }
+
+ QtVCardAddressField* addressField;
+ if ((addressField = dynamic_cast<QtVCardAddressField*>(field))) {
+ vcard->addAddress(addressField->getAddress());
+ continue;
+ }
+
+ QtVCardAddressLabelField* addressLabelField;
+ if ((addressLabelField = dynamic_cast<QtVCardAddressLabelField*>(field))) {
+ vcard->addAddressLabel(addressLabelField->getAddressLabel());
+ continue;
+ }
+
+ if ((bdayField = dynamic_cast<QtVCardBirthdayField*>(field))) {
+ continue;
+ }
+
+ QtVCardJIDField* jidField;
+ if ((jidField = dynamic_cast<QtVCardJIDField*>(field))) {
+ vcard->addJID(jidField->getJID());
+ continue;
+ }
+
+ if ((descriptionField = dynamic_cast<QtVCardDescriptionField*>(field))) {
+ continue;
+ }
+
+ QtVCardOrganizationField* orgField;
+ if ((orgField = dynamic_cast<QtVCardOrganizationField*>(field))) {
+ vcard->addOrganization(orgField->getOrganization());
+ continue;
+ }
+
+ QtVCardRoleField* roleField;
+ if ((roleField = dynamic_cast<QtVCardRoleField*>(field))) {
+ vcard->addRole(roleField->getRole());
+ continue;
+ }
+
+ QtVCardTitleField* titleField;
+ if ((titleField = dynamic_cast<QtVCardTitleField*>(field))) {
+ vcard->addTitle(titleField->getTitle());
+ continue;
+ }
+
+ QtVCardURLField* urlField;
+ if ((urlField = dynamic_cast<QtVCardURLField*>(field))) {
+ vcard->addURL(urlField->getURL());
+ continue;
+ }
+ }
+
+ if (bdayField) {
+ vcard->setBirthday(bdayField->getBirthday());
+ } else {
+ vcard->setBirthday(boost::posix_time::ptime());
+ }
+
+ if (descriptionField) {
+ vcard->setDescription(descriptionField->getDescription());
+ } else {
+ vcard->setDescription("");
+ }
+
+ return vcard;
+}
+
+void QtVCardWidget::addField() {
+ QAction* action = NULL;
+ if ((action = dynamic_cast<QAction*>(sender()))) {
+ boost::shared_ptr<QtVCardFieldInfo> fieldInfo = actionFieldInfo[action];
+ QWidget* newField = fieldInfo->createFieldInstance(this, ui->cardFields, true);
+ QtVCardGeneralField* newGeneralField = dynamic_cast<QtVCardGeneralField*>(newField);
+ if (newGeneralField) {
+ newGeneralField->initialize();
+ }
+ appendField(newGeneralField);
+ relayoutToolButton();
+ }
+}
+
+void QtVCardWidget::removeField(QtVCardGeneralField *field) {
+ fields.remove(field);
+ delete field;
+}
+
+void QtVCardWidget::addFieldType(QMenu* menu, boost::shared_ptr<QtVCardFieldInfo> fieldType) {
+ if (!fieldType->getMenuName().isEmpty()) {
+ QAction* action = new QAction(tr("Add ") + fieldType->getMenuName(), this);
+ actionFieldInfo[action] = fieldType;
+ connect(action, SIGNAL(triggered()), this, SLOT(addField()));
+ menu->addAction(action);
+ }
+}
+
+int QtVCardWidget::fieldTypeInstances(boost::shared_ptr<QtVCardFieldInfo> fieldType) {
+ int instances = 0;
+ for (int n = 0; n < ui->cardFields->count(); n++) {
+ if (fieldType->testInstance(ui->cardFields->itemAt(n)->widget())) instances++;
+ }
+ return instances;
+}
+
+void layoutDeleteChildren(QLayout *layout) {
+ while(layout->count() > 0) {
+ QLayoutItem* child;
+ if ((child = layout->takeAt(0)) != 0) {
+ if (child->layout()) {
+ layoutDeleteChildren(child->layout());
+ }
+ if (dynamic_cast<QToolButton*>(child->widget())) {
+ delete child;
+ break;
+ }
+ delete child->widget();
+ delete child;
+ }
+ }
+}
+
+void QtVCardWidget::clearFields() {
+ foreach(QtVCardGeneralField* field, fields) {
+ delete field;
+ }
+ fields.clear();
+
+ assert(ui->cardFields->count() >= 0);
+ layoutDeleteChildren(ui->cardFields);
+}
+
+void QtVCardWidget::clearEmptyFields() {
+ std::vector<QtVCardGeneralField*> items_to_remove;
+ foreach (QtVCardGeneralField* field, fields) {
+ if (field->property("empty").isValid() && field->property("empty").toBool()) {
+ ui->cardFields->removeWidget(field);
+ items_to_remove.push_back(field);
+ delete field;
+ }
+ }
+
+ foreach(QtVCardGeneralField* field, items_to_remove) {
+ fields.remove(field);
+ }
+}
+
+void QtVCardWidget::appendField(QtVCardGeneralField *field) {
+ connect(field, SIGNAL(deleteField(QtVCardGeneralField*)), SLOT(removeField(QtVCardGeneralField*)));
+ fields.push_back(field);
+}
+
+void QtVCardWidget::relayoutToolButton() {
+ ui->cardFields->addWidget(toolButton, ui->cardFields->rowCount(), ui->cardFields->columnCount()-2, 1, 1, Qt::AlignRight);
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardWidget.h b/Swift/QtUI/QtVCardWidget/QtVCardWidget.h
new file mode 100644
index 0000000..29ed499
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardWidget.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QWidget>
+#include <QToolButton>
+#include <Swiften/Elements/VCard.h>
+#include <boost/smart_ptr/make_shared.hpp>
+
+#include "QtVCardFieldInfo.h"
+#include "QtVCardGeneralField.h"
+#include "QtVCardPhotoAndNameFields.h"
+
+namespace Ui {
+ class QtVCardWidget;
+}
+
+namespace Swift {
+
+ class QtVCardWidget : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+
+ public :
+ explicit QtVCardWidget(QWidget* parent = 0);
+ ~QtVCardWidget();
+
+ bool isEditable() const;
+ void setEditable(bool);
+
+ void setVCard(VCard::ref vcard);
+ VCard::ref getVCard();
+
+ signals:
+ void editableChanged(bool editable);
+
+ private slots:
+ void addField();
+ void removeField(QtVCardGeneralField* field);
+
+ private:
+ void addFieldType(QMenu*, boost::shared_ptr<QtVCardFieldInfo>);
+ int fieldTypeInstances(boost::shared_ptr<QtVCardFieldInfo>);
+ void clearFields();
+ void clearEmptyFields();
+ void appendField(QtVCardGeneralField* field);
+ void relayoutToolButton();
+
+ private:
+ VCard::ref vcard;
+ Ui::QtVCardWidget* ui;
+ QToolButton* toolButton;
+ bool editable;
+ QMenu* menu;
+ std::list<QtVCardGeneralField*> fields;
+ std::map<QAction*, boost::shared_ptr<QtVCardFieldInfo> > actionFieldInfo;
+ };
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardWidget.ui b/Swift/QtUI/QtVCardWidget/QtVCardWidget.ui
new file mode 100644
index 0000000..4fc8605
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardWidget.ui
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QtVCardWidget</class>
+ <widget class="QWidget" name="QtVCardWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>535</width>
+ <height>126</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout" rowstretch="1" columnstretch="1,0">
+ <property name="leftMargin">
+ <number>5</number>
+ </property>
+ <property name="topMargin">
+ <number>5</number>
+ </property>
+ <property name="rightMargin">
+ <number>5</number>
+ </property>
+ <property name="bottomMargin">
+ <number>5</number>
+ </property>
+ <item row="0" column="0" colspan="2">
+ <layout class="QVBoxLayout" name="card" stretch="0,0,1">
+ <property name="spacing">
+ <number>2</number>
+ </property>
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <item>
+ <widget class="Swift::QtVCardPhotoAndNameFields" name="photoAndName" native="true"/>
+ </item>
+ <item>
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>523</width>
+ <height>110</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinAndMaxSize</enum>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QGridLayout" name="cardFields"/>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Preferred</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>1000</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Swift::QtVCardPhotoAndNameFields</class>
+ <extends>QWidget</extends>
+ <header>QtVCardPhotoAndNameFields.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>