diff options
| author | Tobias Markmann <tm@ayena.de> | 2012-02-26 14:32:39 (GMT) | 
|---|---|---|
| committer | Swift Review <review@swift.im> | 2013-01-12 09:38:51 (GMT) | 
| commit | 25b10f8d2b77bc5b3a40aac8d2edd5d42e1b6585 (patch) | |
| tree | db398f92b820ff03cb301c91ada51b226f212065 /Swift/QtUI/QtVCardWidget | |
| parent | 4ed137080a3d80d20a2cead47f741e3dd2f2d42e (diff) | |
| download | swift-contrib-25b10f8d2b77bc5b3a40aac8d2edd5d42e1b6585.zip swift-contrib-25b10f8d2b77bc5b3a40aac8d2edd5d42e1b6585.tar.bz2 | |
Adding basic vCard edit/show support.
Change-Id: I3104efcb9d56cfcaafda45eac2a51d2702f5245b
License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details.
Diffstat (limited to 'Swift/QtUI/QtVCardWidget')
41 files changed, 3193 insertions, 0 deletions
| diff --git a/Swift/QtUI/QtVCardWidget/QtCloseButton.cpp b/Swift/QtUI/QtVCardWidget/QtCloseButton.cpp new file mode 100644 index 0000000..a6afe81 --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtCloseButton.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 "QtCloseButton.h" + +#include <QMouseEvent> +#include <QPainter> +#include <QStyle> +#include <QStyleOption> + +namespace Swift { + +QtCloseButton::QtCloseButton(QWidget *parent) : QAbstractButton(parent) { +	lightPixmap = QPixmap(12,12); +	lightPixmap.fill(QColor(0,0,0,0)); +	QStyleOption opt; +	opt.init(this); +	opt.state = QStyle::State(0); +	opt.state |= QStyle::State_MouseOver; +	QPainter lightPixmapPainter(&lightPixmap); +	style()->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, &lightPixmapPainter); + +	darkPixmap = QPixmap(12,12); +	darkPixmap.fill(QColor(0,0,0,0)); +	opt.init(this); +	opt.state = QStyle::State(0); +	QPainter darkPixmapPainter(&darkPixmap); +	style()->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, &darkPixmapPainter); +} + +QSize QtCloseButton::sizeHint() const { +	return QSize(width(), height()); +} + +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); +	if (underMouse()) { +		painter.drawPixmap(0, 0, height(), height(), darkPixmap); +	} else { +		painter.drawPixmap(0, 0, height(), height(), lightPixmap); +	} +} + +} diff --git a/Swift/QtUI/QtVCardWidget/QtCloseButton.h b/Swift/QtUI/QtVCardWidget/QtCloseButton.h new file mode 100644 index 0000000..6ce8d30 --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtCloseButton.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 <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* ); + +		private: +			QPixmap lightPixmap; +			QPixmap darkPixmap; +	}; + +} diff --git a/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.cpp b/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.cpp new file mode 100644 index 0000000..b586444 --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "QtRemovableItemDelegate.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 = QStyle::State(0); +	opt.state |= QStyle::State_MouseOver; +	painter->save(); +	painter->fillRect(option.rect, option.state & QStyle::State_Selected ? option.palette.highlight() : option.palette.base()); +	painter->translate(option.rect.x(), option.rect.y()+(option.rect.height() - 12)/2); +	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); +	} +} + +} diff --git a/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h b/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h new file mode 100644 index 0000000..3d99ad8 --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h @@ -0,0 +1,27 @@ +/* + * 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; + +	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..efe04dc --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.cpp @@ -0,0 +1,49 @@ +/* + * 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))); +	setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); +	int marginHeight = 6; +	setMaximumHeight(fontMetrics().height() + marginHeight); +} + +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; +#if QT_VERSION >= 0x040700 +	int w = fontMetrics().boundingRect(text().isEmpty() ? placeholderText() : text()).width() + horizontalMargin; +#else +	int w = fontMetrics().boundingRect(text().isEmpty() ? QString("   ") : text()).width() + horizontalMargin; +#endif +	return QSize(w, height()); +} + +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..4d34e53 --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtVCardAddressField.cpp @@ -0,0 +1,165 @@ +/* + * 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) { +	if (streetLineEdit) streetLineEdit->setEditable(isEditable); +	if (poboxLineEdit) poboxLineEdit->setEditable(isEditable); +	if (addressextLineEdit) addressextLineEdit->setEditable(isEditable); +	if (cityLineEdit) cityLineEdit->setEditable(isEditable); +	if (pocodeLineEdit) pocodeLineEdit->setEditable(isEditable); +	if (regionLineEdit) regionLineEdit->setEditable(isEditable); +	if (countryLineEdit) countryLineEdit->setEditable(isEditable); + +	if (deliveryTypeLabel) { +		deliveryTypeLabel->setText(buttonGroup->checkedButton() == 0 ? "" : buttonGroup->checkedButton()->text()); +		deliveryTypeLabel->setVisible(!isEditable); +	} +	if (domesticRadioButton) domesticRadioButton->setVisible(isEditable); +	if (internationalRadioButton) internationalRadioButton->setVisible(isEditable); + +	foreach (QWidget* widget, textFields) { +		QtResizableLineEdit* lineEdit; +		if ((lineEdit = dynamic_cast<QtResizableLineEdit*>(widget))) { +			lineEdit->setShown(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..20f48b9 --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.cpp @@ -0,0 +1,97 @@ +/* + * 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) { +	if (addressLabelPlainTextEdit) { +		addressLabelPlainTextEdit->setReadOnly(!isEditable); +		addressLabelPlainTextEdit->setStyleSheet(isEditable ? "" : "QPlainTextEdit { background: transparent; }"); +	} + +	if (deliveryTypeLabel) { +		deliveryTypeLabel->setText(buttonGroup->checkedButton() == 0 ? "" : buttonGroup->checkedButton()->text()); +		deliveryTypeLabel->setVisible(!isEditable); +	} +	if (domesticRadioButton) domesticRadioButton->setVisible(isEditable); +	if (internationalRadioButton) internationalRadioButton->setVisible(isEditable); +} + +} diff --git a/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.h b/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.h new file mode 100644 index 0000000..0e097d9 --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.h @@ -0,0 +1,49 @@ +/* + * 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 "QtVCardFieldInfo.h" +#include "QtVCardGeneralField.h" +#include "QtVCardHomeWork.h" + +namespace Swift { + +class QtVCardAddressLabelField : public QtVCardGeneralField, public QtVCardHomeWork { +	Q_OBJECT + +	public: +		GENERIC_QT_VCARD_FIELD_INFO("AddressLabel", 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..f907d78 --- /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) { +	if (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..5b3ef87 --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtVCardGeneralField.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2012 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "QtVCardGeneralField.h" + +#include <QHBoxLayout> +#include <Swiften/Base/Log.h> + +namespace Swift { + +QtVCardGeneralField::QtVCardGeneralField(QWidget* parent, QGridLayout* layout, bool editable, int row, QString label, bool preferrable, bool taggable) : +	QWidget(parent), preferrable(preferrable), taggable(taggable), layout(layout), row(row), preferredCheckBox(0), label(0), labelText(label), +	tagComboBox(0), closeButton(0) { +	setEditable(editable); +} + +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; +} + +bool QtVCardGeneralField::isEditable() const { +	return editable; +} + +void QtVCardGeneralField::setEditable(bool editable) { +	this->editable = editable; +	if (tagComboBox) { +		if (taggable) { +			tagLabel->setText(tagComboBox->itemText(0)); +			tagComboBox->setVisible(editable); +			tagLabel->setVisible(!editable); +		} else { +			tagLabel->hide(); +			tagComboBox->hide(); +		} +	} +	if (closeButton) closeButton->setVisible(editable); +	if (preferredCheckBox) { +		if (editable) { +			preferredCheckBox->show(); +		} else if (!preferredCheckBox->isChecked()) { +			preferredCheckBox->hide(); +		} +		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..46f253f --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.cpp @@ -0,0 +1,80 @@ +/* + * 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> + +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) { +	if (isEditable) { +		if (emailLineEdit) emailLineEdit->show(); +		if (emailLabel) emailLabel->hide(); +	} else { +		if (emailLineEdit) emailLineEdit->hide(); +		if (emailLabel) { +			emailLabel->setText(QString("<a href=\"mailto:%1\">%1</a>").arg(Qt::escape(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..dbb4b7c --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtVCardJIDField.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 "QtVCardJIDField.h" + +#include <QGridLayout> +#include <QTextDocument> +#include <boost/algorithm/string.hpp> + +#include <Swift/QtUI/QtSwiftUtil.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) { +	if (isEditable) { +		if (jidLineEdit) jidLineEdit->show(); +		if (jidLabel) jidLabel->hide(); +	} else { +		if (jidLineEdit) jidLineEdit->hide(); +		if (jidLabel) { +			jidLabel->setText(QString("<a href=\"xmpp:%1\">%1</a>").arg(Qt::escape(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..5f231dc --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2012 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "QtVCardOrganizationField.h" + +#include <QGridLayout> +#include <QHBoxLayout> +#include <QHeaderView> +#include <boost/algorithm/string.hpp> + +#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); +	unitsTreeWidget->setColumnCount(2); +	unitsTreeWidget->header()->setStretchLastSection(false); +	int closeIconWidth = unitsTreeWidget->fontMetrics().height(); +	unitsTreeWidget->header()->resizeSection(1, closeIconWidth); +	unitsTreeWidget->header()->setResizeMode(0, QHeaderView::Stretch); +	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); +	} +} + +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))); +		} +	} + +	QTreeWidgetItem* item = new QTreeWidgetItem(QStringList("") << ""); +	item->setFlags(item->flags() | Qt::ItemIsEditable); +	unitsTreeWidget->addTopLevelItem(item); + +	return organization; +} + +void QtVCardOrganizationField::handleEditibleChanged(bool isEditable) { +	if (organizationLineEdit) { +		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); +		} +	} +	if (unitsTreeWidget) unitsTreeWidget->setVisible(isEditable); +} + +void QtVCardOrganizationField::handleItemChanged(QTreeWidgetItem *, int) { +	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); +	} +	getTagComboBox()->hide(); +} + +} diff --git a/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.h b/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.h new file mode 100644 index 0000000..917e22a --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.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 <Swiften/Elements/VCard.h> + +#include <QTreeWidget> + +#include "QtRemovableItemDelegate.h" +#include "QtResizableLineEdit.h" +#include "QtVCardFieldInfo.h" +#include "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); + +	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..3ddc86b --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2012 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "QtVCardPhotoAndNameFields.h" +#include "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 + +	addFieldMenu = new QMenu("Name", this); + +	actionSignalMapper = new QSignalMapper(this); + +	connect(actionSignalMapper, SIGNAL(mapped(const QString &)), this, SLOT(showField(const QString &))); +	prepareAddFieldMenu(); +} + +QtVCardPhotoAndNameFields::~QtVCardPhotoAndNameFields() { +	delete ui; +	delete actionSignalMapper; +} + +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); +	ui->labelFULLNAME->setText(	ui->lineEditPREFIX->text() + " " + ui->lineEditGIVEN->text() + " " + +								ui->lineEditMIDDLE->text() + " " + ui->lineEditFAMILY->text() + " " + ui->lineEditSUFFIX->text()); + +	prepareAddFieldMenu(); +} + +QMenu* QtVCardPhotoAndNameFields::getAddFieldMenu() const { +	return addFieldMenu; +} + +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(); +} + +void QtVCardPhotoAndNameFields::prepareAddFieldMenu() { +	foreach(QAction* action, addFieldMenu->actions()) { +		actionSignalMapper->removeMappings(action); +	} + +	addFieldMenu->clear(); +	foreach(QObject* obj, children()) { +		QLineEdit* lineEdit = 0; +		if (!(lineEdit = dynamic_cast<QLineEdit*>(obj))) continue; +		if (lineEdit->isHidden()) { +#if QT_VERSION >= 0x040700 +			QAction* action = addFieldMenu->addAction(QString("Add ") + lineEdit->placeholderText(), actionSignalMapper, SLOT(map())); +#else +			QAction* action = addFieldMenu->addAction(QString("Add ") + lineEdit->toolTip(), actionSignalMapper, SLOT(map())); +#endif +			actionSignalMapper->setMapping(action, lineEdit->objectName()); +		} +	} +} + +void QtVCardPhotoAndNameFields::showField(const QString& widgetName) { +	QLineEdit* lineEditToShow = findChild<QLineEdit*>(widgetName); +	if (lineEditToShow) lineEditToShow->show(); + +	prepareAddFieldMenu(); +} + +} diff --git a/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.h b/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.h new file mode 100644 index 0000000..f279701 --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.h @@ -0,0 +1,73 @@ +/* + * 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 <QSignalMapper> +#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); + +			QMenu* getAddFieldMenu() const; + +			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; + +		public slots: +			void showField(const QString& widgetName); + +		private: +			void prepareAddFieldMenu(); + +		private: +			Ui::QtVCardPhotoAndNameFields* ui; +			bool editable; + +			QMenu* addFieldMenu; +			QSignalMapper* actionSignalMapper; +	}; + +} 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..8af4e64 --- /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) { +	if (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..ee93c01 --- /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) { +	if (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..aac4e31 --- /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) { +	if (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..0b6f0c1 --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtVCardURLField.cpp @@ -0,0 +1,68 @@ +/* + * 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> + +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) { +	if (isEditable) { +		if (urlLineEdit) urlLineEdit->show(); +		if (urlLabel) urlLabel->hide(); +	} else { +		if (urlLineEdit) urlLineEdit->hide(); +		if (urlLabel) { +			urlLabel->setText(QString("<a href=\"%1\">%1</a>").arg(Qt::escape(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..1c80fa4 --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtVCardWidget.cpp @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2012 Tobias Markmann + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "QtVCardWidget.h" +#include "ui_QtVCardWidget.h" + +#include <QDebug> +#include <QLineEdit> +#include <QMenu> + +#include "QtVCardAddressField.h" +#include "QtVCardAddressLabelField.h" +#include "QtVCardBirthdayField.h" +#include "QtVCardDescriptionField.h" +#include "QtVCardGeneralField.h" +#include "QtVCardInternetEMailField.h" +#include "QtVCardJIDField.h" +#include "QtVCardOrganizationField.h" +#include "QtVCardRoleField.h" +#include "QtVCardTelephoneField.h" +#include "QtVCardTitleField.h" +#include "QtVCardURLField.h" + +#include <Swift/QtUI/QtSwiftUtil.h> + +#include <Swiften/Base/Log.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); + +	menu->addMenu(ui->photoAndName->getAddFieldMenu()); +	ui->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); +	} + +	if (editable) { +		ui->toolButton->show(); +		//if ((findChild<QtVCardBirthdayField*>() == 0)) { +		//} +	} else { +		ui->toolButton->hide(); +	} + +	editableChanged(editable); +} + +void QtVCardWidget::setVCard(VCard::ref vcard) { +	SWIFT_LOG(debug) << std::endl; +	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); +	} + +	setEditable(editable); +} + +VCard::ref QtVCardWidget::getVCard() { +	SWIFT_LOG(debug) << std::endl; +	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); +	} +} + +void QtVCardWidget::removeField(QtVCardGeneralField *field) { +	fields.remove(field); +	delete field; +} + +void QtVCardWidget::addFieldType(QMenu* menu, boost::shared_ptr<QtVCardFieldInfo> fieldType) { +	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()); +			} +			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); +} + +} diff --git a/Swift/QtUI/QtVCardWidget/QtVCardWidget.h b/Swift/QtUI/QtVCardWidget/QtVCardWidget.h new file mode 100644 index 0000000..07f528d --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtVCardWidget.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 <QWidget> +#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); + +		private: +			VCard::ref vcard; +			Ui::QtVCardWidget* ui; +			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..eae1006 --- /dev/null +++ b/Swift/QtUI/QtVCardWidget/QtVCardWidget.ui @@ -0,0 +1,137 @@ +<?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,0" columnstretch="1,0"> +   <property name="margin"> +    <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>76</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="margin"> +          <number>0</number> +         </property> +         <item> +          <layout class="QGridLayout" name="cardFields"> +          </layout> +         </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> +   <item row="1" column="1"> +    <widget class="QToolButton" name="toolButton"> +     <property name="text"> +      <string>Add Field</string> +     </property> +     <property name="popupMode"> +      <enum>QToolButton::InstantPopup</enum> +     </property> +     <property name="autoRaise"> +      <bool>false</bool> +     </property> +     <property name="arrowType"> +      <enum>Qt::NoArrow</enum> +     </property> +    </widget> +   </item> +  </layout> + </widget> + <customwidgets> +  <customwidget> +   <class>Swift::QtVCardPhotoAndNameFields</class> +   <extends>QWidget</extends> +   <header>QtVCardPhotoAndNameFields.h</header> +   <container>1</container> +  </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> | 
 Swift
 Swift