summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2012-02-26 14:32:39 (GMT)
committerTobias Markmann <tm@ayena.de>2012-11-11 16:38:00 (GMT)
commit684559ff499077e33d3d5e4b9ecb39afa240d067 (patch)
tree7c0f03ddb4c73e1d2d2ddd54fe3f3b9640291e75
parentbe6fd0b4b580d81bfe33975c28ee7a939d6c6723 (diff)
downloadswift-contrib-684559ff499077e33d3d5e4b9ecb39afa240d067.zip
swift-contrib-684559ff499077e33d3d5e4b9ecb39afa240d067.tar.bz2
Adding basic vCard edit/show support.
License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details.
-rw-r--r--Swift/Controllers/Chat/MUCController.cpp3
-rw-r--r--Swift/Controllers/MainController.cpp5
-rw-r--r--Swift/Controllers/MainController.h2
-rw-r--r--Swift/Controllers/ProfileController.cpp1
-rw-r--r--Swift/Controllers/SConscript1
-rw-r--r--Swift/Controllers/ShowProfileController.cpp84
-rw-r--r--Swift/Controllers/ShowProfileController.h36
-rw-r--r--Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h25
-rw-r--r--Swift/Controllers/UIInterfaces/ChatWindow.h2
-rw-r--r--Swift/Controllers/UIInterfaces/ProfileWindow.h5
-rw-r--r--Swift/QtUI/QtAvatarWidget.cpp3
-rw-r--r--Swift/QtUI/QtAvatarWidget.h10
-rw-r--r--Swift/QtUI/QtProfileWindow.cpp155
-rw-r--r--Swift/QtUI/QtProfileWindow.h77
-rw-r--r--Swift/QtUI/QtProfileWindow.ui85
-rw-r--r--Swift/QtUI/QtSwiftUtil.h2
-rw-r--r--Swift/QtUI/QtVCardWidget/QtResizableLineEdit.cpp44
-rw-r--r--Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h33
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardAddressField.cpp104
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardAddressField.h104
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardAddressField.ui229
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.cpp67
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.h89
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.ui152
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.cpp65
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.h65
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.ui76
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.cpp44
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.h60
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.ui59
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardEMailField.cpp127
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardEMailField.h84
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardEMailField.ui139
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h27
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardJIDField.cpp67
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardJIDField.h63
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardJIDField.ui79
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardOrganisationField.cpp100
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardOrganisationField.h68
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardOrganisationField.ui169
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.cpp162
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.h74
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.ui260
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardRoleField.cpp55
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardRoleField.h63
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardRoleField.ui76
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.cpp95
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.h93
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.ui174
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardTitleField.cpp55
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardTitleField.h63
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardTitleField.ui76
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardURLField.cpp65
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardURLField.h63
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardURLField.ui79
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardWidget.cpp429
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardWidget.h58
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardWidget.ui143
-rw-r--r--Swift/QtUI/Roster/QtOccupantListWidget.cpp1
-rw-r--r--Swift/QtUI/Roster/QtRosterWidget.cpp5
-rw-r--r--Swift/QtUI/SConscript34
-rw-r--r--Swiften/Elements/VCard.h193
-rw-r--r--Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp73
-rw-r--r--Swiften/Parser/PayloadParsers/VCardParser.cpp166
-rw-r--r--Swiften/Parser/PayloadParsers/VCardParser.h4
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/VCardSerializerTest.cpp80
-rw-r--r--Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp172
67 files changed, 5282 insertions, 139 deletions
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp
index 50eee68..192946e 100644
--- a/Swift/Controllers/Chat/MUCController.cpp
+++ b/Swift/Controllers/Chat/MUCController.cpp
@@ -24,6 +24,7 @@
#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h>
+#include <Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h>
#include <Swift/Controllers/Roster/GroupRosterItem.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
#include <Swiften/Avatars/AvatarManager.h>
@@ -146,6 +147,7 @@ void MUCController::handleWindowOccupantSelectionChanged(ContactRosterItem* item
if (muc_->getOccupant(item->getJID().getResource()).getRealJID()) {
actions.push_back(ChatWindow::AddContact);
}
+ actions.push_back(ChatWindow::ShowProfile);
}
chatWindow_->setAvailableOccupantActions(actions);
}
@@ -164,6 +166,7 @@ void MUCController::handleActionRequestedOnOccupant(ChatWindow::OccupantAction a
case ChatWindow::MakeParticipant: muc_->changeOccupantRole(mucJID, MUCOccupant::Participant);break;
case ChatWindow::MakeVisitor: muc_->changeOccupantRole(mucJID, MUCOccupant::Visitor);break;
case ChatWindow::AddContact: if (occupant.getRealJID()) events_->send(boost::make_shared<RequestAddUserDialogUIEvent>(realJID, occupant.getNick()));break;
+ case ChatWindow::ShowProfile: events_->send(boost::make_shared<ShowProfileForRosterItemUIEvent>(mucJID));break;
}
}
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 1b0b595..de4f727 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -69,6 +69,7 @@
#include "Swift/Controllers/Storages/CertificateStorageTrustChecker.h"
#include "Swiften/Network/NetworkFactories.h"
#include <Swift/Controllers/ProfileController.h>
+#include <Swift/Controllers/ShowProfileController.h>
#include <Swift/Controllers/ContactEditController.h>
#include <Swift/Controllers/XMPPURIController.h>
#include "Swift/Controllers/AdHocManager.h"
@@ -121,6 +122,7 @@ MainController::MainController(
historyViewController_ = NULL;
eventWindowController_ = NULL;
profileController_ = NULL;
+ showProfileController_ = NULL;
contactEditController_ = NULL;
userSearchControllerChat_ = NULL;
userSearchControllerAdd_ = NULL;
@@ -225,6 +227,8 @@ void MainController::resetClient() {
contactEditController_ = NULL;
delete profileController_;
profileController_ = NULL;
+ delete showProfileController_;
+ showProfileController_ = NULL;
delete eventWindowController_;
eventWindowController_ = NULL;
delete chatsManager_;
@@ -297,6 +301,7 @@ void MainController::handleConnected() {
myStatusLooksOnline_ = true;
if (freshLogin) {
profileController_ = new ProfileController(client_->getVCardManager(), uiFactory_, uiEventStream_);
+ showProfileController_ = new ShowProfileController(client_->getVCardManager(), uiFactory_, uiEventStream_);
srand(time(NULL));
int randomPort = 10000 + rand() % 10000;
client_->getFileTransferManager()->startListeningOnPort(randomPort);
diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h
index 2e5bd05..efe092f 100644
--- a/Swift/Controllers/MainController.h
+++ b/Swift/Controllers/MainController.h
@@ -43,6 +43,7 @@ namespace Swift {
class MUCController;
class Notifier;
class ProfileController;
+ class ShowProfileController;
class ContactEditController;
class TogglableNotifier;
class PresenceNotifier;
@@ -153,6 +154,7 @@ namespace Swift {
FileTransferListController* fileTransferListController_;
ChatsManager* chatsManager_;
ProfileController* profileController_;
+ ShowProfileController* showProfileController_;
ContactEditController* contactEditController_;
JID jid_;
JID boundJID_;
diff --git a/Swift/Controllers/ProfileController.cpp b/Swift/Controllers/ProfileController.cpp
index 101e283..e641988 100644
--- a/Swift/Controllers/ProfileController.cpp
+++ b/Swift/Controllers/ProfileController.cpp
@@ -37,6 +37,7 @@ void ProfileController::handleUIEvent(UIEvent::ref event) {
if (!profileWindow) {
profileWindow = profileWindowFactory->createProfileWindow();
+ profileWindow->setEditable(true);
profileWindow->onVCardChangeRequest.connect(boost::bind(&ProfileController::handleVCardChangeRequest, this, _1));
vcardManager->onOwnVCardChanged.connect(boost::bind(&ProfileController::handleOwnVCardChanged, this, _1));
}
diff --git a/Swift/Controllers/SConscript b/Swift/Controllers/SConscript
index 7cd017b..954067e 100644
--- a/Swift/Controllers/SConscript
+++ b/Swift/Controllers/SConscript
@@ -30,6 +30,7 @@ if env["SCONS_STAGE"] == "build" :
"Chat/UserSearchController.cpp",
"MainController.cpp",
"ProfileController.cpp",
+ "ShowProfileController.cpp",
"ContactEditController.cpp",
"FileTransfer/FileTransferController.cpp",
"FileTransfer/FileTransferOverview.cpp",
diff --git a/Swift/Controllers/ShowProfileController.cpp b/Swift/Controllers/ShowProfileController.cpp
new file mode 100644
index 0000000..462ac42
--- /dev/null
+++ b/Swift/Controllers/ShowProfileController.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "ShowProfileController.h"
+
+#include <boost/bind.hpp>
+
+#include <Swiften/Base/foreach.h>
+#include <Swiften/VCards/VCardManager.h>
+
+#include <Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h>
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
+#include <Swift/Controllers/UIInterfaces/ProfileWindowFactory.h>
+
+namespace Swift {
+
+ShowProfileController::ShowProfileController(VCardManager* vcardManager, ProfileWindowFactory* profileWindowFactory, UIEventStream* uiEventStream) : vcardManager(vcardManager), profileWindowFactory(profileWindowFactory), uiEventStream(uiEventStream) {
+ uiEventStream->onUIEvent.connect(boost::bind(&ShowProfileController::handleUIEvent, this, _1));
+ vcardManager->onVCardChanged.connect(boost::bind(&ShowProfileController::handleVCardChanged, this, _1, _2));
+}
+
+ShowProfileController::~ShowProfileController() {
+ typedef std::pair<JID, ProfileWindow*> JIDProfileWindowPair;
+ foreach(const JIDProfileWindowPair& jidWndPair, openedProfileWindows) {
+ jidWndPair.second->onWindowClosed.disconnect(boost::bind(&ShowProfileController::handleProfileWindowClosed, this, _1));
+ delete jidWndPair.second;
+ }
+
+ vcardManager->onVCardChanged.disconnect(boost::bind(&ShowProfileController::handleVCardChanged, this, _1, _2));
+ uiEventStream->onUIEvent.disconnect(boost::bind(&ShowProfileController::handleUIEvent, this, _1));
+}
+
+void ShowProfileController::handleUIEvent(UIEvent::ref event) {
+ ShowProfileForRosterItemUIEvent::ref showProfileEvent;
+ if (!(showProfileEvent = boost::dynamic_pointer_cast<ShowProfileForRosterItemUIEvent>(event))) {
+ return;
+ }
+
+ if (openedProfileWindows.find(showProfileEvent->getJID()) == openedProfileWindows.end()) {
+ ProfileWindow* newProfileWindow = profileWindowFactory->createProfileWindow();
+ newProfileWindow->setJID(showProfileEvent->getJID());
+ newProfileWindow->onWindowClosed.connect(boost::bind(&ShowProfileController::handleProfileWindowClosed, this, _1));
+ openedProfileWindows[showProfileEvent->getJID()] = newProfileWindow;
+ VCard::ref vcard = vcardManager->getVCardAndRequestWhenNeeded(showProfileEvent->getJID());
+ if (vcard) {
+ newProfileWindow->setVCard(vcard);
+ } else {
+ newProfileWindow->setProcessing(true);
+ }
+ newProfileWindow->show();
+ } else {
+ openedProfileWindows[showProfileEvent->getJID()]->show();
+ }
+}
+
+void ShowProfileController::handleVCardChanged(const JID& jid, VCard::ref vcard) {
+ if (openedProfileWindows.find(jid) == openedProfileWindows.end()) {
+ return;
+ }
+
+ ProfileWindow* profileWindow = openedProfileWindows[jid];
+ profileWindow->setVCard(vcard);
+ profileWindow->setProcessing(false);
+ profileWindow->show();
+}
+
+void ShowProfileController::handleProfileWindowClosed(ProfileWindow* profileWindow) {
+ profileWindow->onWindowClosed.disconnect(boost::bind(&ShowProfileController::handleProfileWindowClosed, this, _1));
+ JID profileJid;
+ for(std::map<JID, ProfileWindow*>::iterator i = openedProfileWindows.begin(); i != openedProfileWindows.end(); i++) {
+ if (i->second == profileWindow) {
+ profileJid = i->first;
+ break;
+ }
+ }
+ openedProfileWindows.erase(profileJid);
+ profileWindow->hide();
+ delete profileWindow;
+}
+
+}
diff --git a/Swift/Controllers/ShowProfileController.h b/Swift/Controllers/ShowProfileController.h
new file mode 100644
index 0000000..238946e
--- /dev/null
+++ b/Swift/Controllers/ShowProfileController.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/JID/JID.h>
+#include <Swiften/Elements/VCard.h>
+
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+
+namespace Swift {
+ class VCardManager;
+ class ProfileWindow;
+ class ProfileWindowFactory;
+ class UIEventStream;
+
+ class ShowProfileController {
+ public:
+ ShowProfileController(VCardManager* vcardManager, ProfileWindowFactory* profileWindowFactory, UIEventStream* uiEventStream);
+ ~ShowProfileController();
+
+ private:
+ void handleUIEvent(UIEvent::ref event);
+ void handleVCardChanged(const JID&, VCard::ref);
+ void handleProfileWindowClosed(ProfileWindow* profileWindow);
+
+ private:
+ VCardManager* vcardManager;
+ ProfileWindowFactory* profileWindowFactory;
+ UIEventStream* uiEventStream;
+ std::map<JID, ProfileWindow*> openedProfileWindows;
+ };
+}
diff --git a/Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h b/Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h
new file mode 100644
index 0000000..4941501
--- /dev/null
+++ b/Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include "Swiften/JID/JID.h"
+#include "Swift/Controllers/UIEvents/UIEvent.h"
+
+namespace Swift {
+
+class ShowProfileForRosterItemUIEvent : public UIEvent {
+ public:
+ typedef boost::shared_ptr<ShowProfileForRosterItemUIEvent> ref;
+ public:
+ ShowProfileForRosterItemUIEvent(const JID& jid) : jid_(jid) {}
+ virtual ~ShowProfileForRosterItemUIEvent() {}
+ JID getJID() {return jid_;}
+ private:
+ JID jid_;
+};
+
+}
diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h
index 5db1a54..2a2078c 100644
--- a/Swift/Controllers/UIInterfaces/ChatWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatWindow.h
@@ -34,7 +34,7 @@ namespace Swift {
enum AckState {Pending, Received, Failed};
enum ReceiptState {ReceiptRequested, ReceiptReceived};
enum Tristate {Yes, No, Maybe};
- enum OccupantAction {Kick, Ban, MakeModerator, MakeParticipant, MakeVisitor, AddContact};
+ enum OccupantAction {Kick, Ban, MakeModerator, MakeParticipant, MakeVisitor, AddContact, ShowProfile};
enum RoomAction {ChangeSubject, Configure, Affiliations, Destroy, Invite};
enum FileTransferState {WaitingForAccept, Negotiating, Transferring, Canceled, Finished, FTFailed};
enum WhiteboardSessionState {WhiteboardAccepted, WhiteboardTerminated, WhiteboardRejected};
diff --git a/Swift/Controllers/UIInterfaces/ProfileWindow.h b/Swift/Controllers/UIInterfaces/ProfileWindow.h
index 5d5c754..90d8584 100644
--- a/Swift/Controllers/UIInterfaces/ProfileWindow.h
+++ b/Swift/Controllers/UIInterfaces/ProfileWindow.h
@@ -12,19 +12,24 @@
#include <Swiften/Elements/VCard.h>
namespace Swift {
+ class JID;
+
class ProfileWindow {
public:
virtual ~ProfileWindow() {};
+ virtual void setJID(const JID& jid) = 0;
virtual void setVCard(VCard::ref vcard) = 0;
virtual void setEnabled(bool b) = 0;
virtual void setProcessing(bool b) = 0;
virtual void setError(const std::string&) = 0;
+ virtual void setEditable(bool b) = 0;
virtual void show() = 0;
virtual void hide() = 0;
boost::signal<void (VCard::ref)> onVCardChangeRequest;
+ boost::signal<void (ProfileWindow*)> onWindowClosed;
};
}
diff --git a/Swift/QtUI/QtAvatarWidget.cpp b/Swift/QtUI/QtAvatarWidget.cpp
index f0bdf3c..ae9559a 100644
--- a/Swift/QtUI/QtAvatarWidget.cpp
+++ b/Swift/QtUI/QtAvatarWidget.cpp
@@ -68,6 +68,9 @@ void QtAvatarWidget::setAvatar(const ByteArray& data, const std::string& type) {
}
void QtAvatarWidget::mousePressEvent(QMouseEvent* event) {
+ if (!editable) {
+ return;
+ }
QMenu menu;
QAction* selectPicture = new QAction(tr("Select picture ..."), this);
diff --git a/Swift/QtUI/QtAvatarWidget.h b/Swift/QtUI/QtAvatarWidget.h
index 8830d82..f4ac4cf 100644
--- a/Swift/QtUI/QtAvatarWidget.h
+++ b/Swift/QtUI/QtAvatarWidget.h
@@ -15,6 +15,7 @@ class QLabel;
namespace Swift {
class QtAvatarWidget : public QWidget {
Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
public:
QtAvatarWidget(QWidget* parent);
@@ -28,9 +29,18 @@ namespace Swift {
return type;
}
+ void setEditable(bool b) {
+ editable = b;
+ }
+
+ bool isEditable() const {
+ return editable;
+ }
+
void mousePressEvent(QMouseEvent* event);
private:
+ bool editable;
ByteArray data;
std::string type;
QLabel* label;
diff --git a/Swift/QtUI/QtProfileWindow.cpp b/Swift/QtUI/QtProfileWindow.cpp
index 0faa78f..558d685 100644
--- a/Swift/QtUI/QtProfileWindow.cpp
+++ b/Swift/QtUI/QtProfileWindow.cpp
@@ -1,100 +1,76 @@
/*
- * Copyright (c) 2011 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
*/
#include "QtProfileWindow.h"
+#include "ui_QtProfileWindow.h"
-#include <QImage>
-#include <QPixmap>
-#include <QSizePolicy>
-#include <QGridLayout>
-#include <QLabel>
-#include <QLineEdit>
-#include <QPushButton>
+#include <QCloseEvent>
#include <QMovie>
+#include <QShortcut>
#include "QtSwiftUtil.h"
-#include "QtAvatarWidget.h"
namespace Swift {
-QtProfileWindow::QtProfileWindow() {
- setWindowTitle(tr("Edit Profile"));
-
- QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
- sizePolicy.setHorizontalStretch(0);
- sizePolicy.setVerticalStretch(0);
- sizePolicy.setHeightForWidth(this->sizePolicy().hasHeightForWidth());
- setSizePolicy(sizePolicy);
-
- QVBoxLayout* layout = new QVBoxLayout(this);
- layout->setContentsMargins(10, 10, 10, 10);
-
- QHBoxLayout* topLayout = new QHBoxLayout();
-
- avatar = new QtAvatarWidget(this);
- topLayout->addWidget(avatar);
-
- QVBoxLayout* fieldsLayout = new QVBoxLayout();
-
- QHBoxLayout* horizontalLayout_2 = new QHBoxLayout();
- nicknameLabel = new QLabel(tr("Nickname:"), this);
- horizontalLayout_2->addWidget(nicknameLabel);
- nickname = new QLineEdit(this);
- horizontalLayout_2->addWidget(nickname);
-
- fieldsLayout->addLayout(horizontalLayout_2);
-
- errorLabel = new QLabel(this);
- errorLabel->setAlignment(Qt::AlignHCenter);
- fieldsLayout->addWidget(errorLabel);
-
- fieldsLayout->addItem(new QSpacerItem(198, 17, QSizePolicy::Minimum, QSizePolicy::Expanding));
- topLayout->addLayout(fieldsLayout);
-
- layout->addLayout(topLayout);
-
- QHBoxLayout* horizontalLayout = new QHBoxLayout();
- horizontalLayout->setContentsMargins(0, 0, 0, 0);
- horizontalLayout->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
-
- throbberLabel = new QLabel(this);
- throbberLabel->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), this));
- horizontalLayout->addWidget(throbberLabel);
-
- saveButton = new QPushButton(tr("Save"), this);
- saveButton->setDefault( true );
- connect(saveButton, SIGNAL(clicked()), SLOT(handleSave()));
- horizontalLayout->addWidget(saveButton);
+QtProfileWindow::QtProfileWindow(QWidget* parent) :
+ QWidget(parent),
+ ui(new Ui::QtProfileWindow) {
+ ui->setupUi(this);
+ new QShortcut(QKeySequence::Close, this, SLOT(close()));
+ ui->throbberLabel->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), this));
+ connect(ui->savePushButton, SIGNAL(clicked()), SLOT(handleSave()));
+ setEditable(false);
+}
- fieldsLayout->addLayout(horizontalLayout);
+QtProfileWindow::~QtProfileWindow() {
+ delete ui;
+}
- resize(360, 120);
+void QtProfileWindow::setJID(const JID& jid) {
+ this->jid = jid;
+ updateTitle();
}
-void QtProfileWindow::setVCard(Swift::VCard::ref vcard) {
- this->vcard = vcard;
- nickname->setText(P2QSTRING(vcard->getNickname()));
- avatar->setAvatar(vcard->getPhoto(), vcard->getPhotoType());
+void QtProfileWindow::setVCard(VCard::ref vcard) {
+ ui->vcard->setVCard(vcard);
}
void QtProfileWindow::setEnabled(bool b) {
- nickname->setEnabled(b);
- nicknameLabel->setEnabled(b);
- avatar->setEnabled(b);
- saveButton->setEnabled(b);
+ ui->vcard->setEnabled(b);
+ ui->savePushButton->setEnabled(b);
+}
+
+void QtProfileWindow::setEditable(bool b) {
+ if (b) {
+ ui->savePushButton->show();
+ ui->vcard->setEditable(true);
+ } else {
+ ui->savePushButton->hide();
+ ui->vcard->setEditable(false);
+ }
+ updateTitle();
}
void QtProfileWindow::setProcessing(bool processing) {
if (processing) {
- throbberLabel->movie()->start();
- throbberLabel->show();
+ ui->throbberLabel->movie()->start();
+ ui->throbberLabel->show();
}
else {
- throbberLabel->hide();
- throbberLabel->movie()->stop();
+ ui->throbberLabel->hide();
+ ui->throbberLabel->movie()->stop();
+ }
+}
+
+void QtProfileWindow::setError(const std::string& error) {
+ if (!error.empty()) {
+ ui->errorLabel->setText("<font color='red'>" + P2QSTRING(error) + "</font>");
+ }
+ else {
+ ui->errorLabel->setText("");
}
}
@@ -103,31 +79,30 @@ void QtProfileWindow::show() {
QWidget::activateWindow();
}
-void QtProfileWindow::hideEvent(QHideEvent* event) {
- QWidget::hideEvent(event);
-}
-
void QtProfileWindow::hide() {
QWidget::hide();
}
-void QtProfileWindow::handleSave() {
- assert(vcard);
- vcard->setNickname(Q2PSTRING(nickname->text()));
- vcard->setPhoto(avatar->getAvatarData());
- vcard->setPhotoType(avatar->getAvatarType());
- onVCardChangeRequest(vcard);
-}
-
-void QtProfileWindow::setError(const std::string& error) {
- if (!error.empty()) {
- errorLabel->setText("<font color='red'>" + P2QSTRING(error) + "</font>");
+void QtProfileWindow::updateTitle() {
+ QString jidString;
+ if (jid.isValid()) {
+ jidString = QString(" ( %1 )").arg(P2QSTRING(jid.toString()));
}
- else {
- errorLabel->setText("");
+
+ if (ui->vcard->isEditable()) {
+ setWindowTitle(tr("Edit Profile") + jidString);
+ } else {
+ setWindowTitle(tr("Show Profile") + jidString);
}
}
+void QtProfileWindow::closeEvent(QCloseEvent* event) {
+ event->accept();
+ onWindowClosed(this);
+}
+void QtProfileWindow::handleSave() {
+ onVCardChangeRequest(ui->vcard->getVCard());
+}
}
diff --git a/Swift/QtUI/QtProfileWindow.h b/Swift/QtUI/QtProfileWindow.h
index edb9cce..29a832d 100644
--- a/Swift/QtUI/QtProfileWindow.h
+++ b/Swift/QtUI/QtProfileWindow.h
@@ -1,48 +1,51 @@
/*
- * Copyright (c) 2011 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * 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/JID/JID.h>
#include <Swift/Controllers/UIInterfaces/ProfileWindow.h>
-class QLabel;
-class QLineEdit;
-class QHBoxLayout;
-class QPushButton;
+#include <QWidget>
+
+namespace Ui {
+ class QtProfileWindow;
+}
namespace Swift {
- class QtAvatarWidget;
-
- class QtProfileWindow : public QWidget, public ProfileWindow {
- Q_OBJECT
- public:
- QtProfileWindow();
-
- void setVCard(Swift::VCard::ref);
- void setEnabled(bool);
- void setProcessing(bool);
- virtual void setError(const std::string&);
- void show();
- void hide();
-
- void hideEvent (QHideEvent* event);
-
- private slots:
- void handleSave();
-
- private:
- VCard::ref vcard;
- QtAvatarWidget* avatar;
- QLabel* nicknameLabel;
- QLineEdit* nickname;
- QLabel* throbberLabel;
- QLabel* errorLabel;
- QHBoxLayout* horizontalLayout;
- QPushButton* saveButton;
- };
+
+class QtProfileWindow : public QWidget, public ProfileWindow {
+ Q_OBJECT
+
+ public:
+ explicit QtProfileWindow(QWidget* parent = 0);
+ virtual ~QtProfileWindow();
+
+ virtual void setJID(const JID& jid);
+ virtual void setVCard(VCard::ref vcard);
+
+ virtual void setEnabled(bool b);
+ virtual void setProcessing(bool processing);
+ virtual void setError(const std::string& error);
+ virtual void setEditable(bool b);
+
+ virtual void show();
+ virtual void hide();
+
+ private:
+ void updateTitle();
+ virtual void closeEvent(QCloseEvent* event);
+
+ private slots:
+ void handleSave();
+
+ private:
+ Ui::QtProfileWindow* ui;
+ JID jid;
+};
+
}
diff --git a/Swift/QtUI/QtProfileWindow.ui b/Swift/QtUI/QtProfileWindow.ui
new file mode 100644
index 0000000..68a36da
--- /dev/null
+++ b/Swift/QtUI/QtProfileWindow.ui
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QtProfileWindow</class>
+ <widget class="QWidget" name="QtProfileWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>334</width>
+ <height>197</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Edit Profile</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="1,0">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="Swift::QtVCardWidget" name="vcard" native="true"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ <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>
+ <item>
+ <widget class="QLabel" name="errorLabel">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="throbberLabel">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::NoTextInteraction</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="savePushButton">
+ <property name="text">
+ <string>Save</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Swift::QtVCardWidget</class>
+ <extends>QWidget</extends>
+ <header>Swift/QtUI/QtVCardWidget/QtVCardWidget.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Swift/QtUI/QtSwiftUtil.h b/Swift/QtUI/QtSwiftUtil.h
index 2d0f970..c903af1 100644
--- a/Swift/QtUI/QtSwiftUtil.h
+++ b/Swift/QtUI/QtSwiftUtil.h
@@ -9,4 +9,6 @@
#define P2QSTRING(a) QString::fromUtf8(a.c_str())
#define Q2PSTRING(a) std::string(a.toUtf8())
+#include <boost/date_time/posix_time/posix_time.hpp>
+
#define B2QDATE(a) QDateTime::fromTime_t((a - boost::posix_time::from_time_t(0)).total_seconds())
diff --git a/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.cpp b/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.cpp
new file mode 100644
index 0000000..d4357cb
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtResizableLineEdit.h"
+
+#include <QDebug>
+
+namespace Swift {
+
+QtResizableLineEdit::QtResizableLineEdit(QWidget* parent) :
+ QLineEdit(parent) {
+ connect(this, SIGNAL(textChanged(QString)), SLOT(textChanged(QString)));
+ setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+}
+
+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 w = fontMetrics().boundingRect(text().isEmpty() ? placeholderText() : text()).width() + 10;
+ 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/QtVCardAddressField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardAddressField.cpp
new file mode 100644
index 0000000..c1a08f1
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardAddressField.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardAddressField.h"
+#include "ui_QtVCardAddressField.h"
+
+#define GETTER_SETTER_CHECKBOX_IMPL( METHOD_NAME, UI_NAME ) \
+ void QtVCardAddressField::set##METHOD_NAME(const bool METHOD_NAME) { \
+ ui->checkBox##UI_NAME->setChecked(METHOD_NAME); \
+ } \
+ \
+ bool QtVCardAddressField::get##METHOD_NAME() const { \
+ return ui->checkBox##UI_NAME->checkState() == Qt::Checked; \
+ }
+
+#define GETTER_SETTER_LINEEDIT_IMPL( METHOD_NAME, UI_NAME ) \
+ void QtVCardAddressField::set##METHOD_NAME(const QString METHOD_NAME) { \
+ ui->lineEdit##UI_NAME->setText(METHOD_NAME); \
+ } \
+ \
+ QString QtVCardAddressField::get##METHOD_NAME() const { \
+ return ui->lineEdit##UI_NAME->text(); \
+ }
+
+namespace Swift {
+
+QtVCardAddressField::QtVCardAddressField(QWidget* parent, bool editable) :
+ QWidget(parent),
+ ui(new Ui::QtVCardAddressField) {
+ ui->setupUi(this);
+ setEditable(editable);
+}
+
+QtVCardAddressField::~QtVCardAddressField() {
+ delete ui;
+}
+
+bool QtVCardAddressField::isEditable() const {
+ return editable;
+}
+
+void QtVCardAddressField::setEditable(bool editable) {
+ this->editable = editable;
+ QList<QCheckBox*> allCheckBoxes = findChildren<QCheckBox*>();
+ foreach(QCheckBox* checkbox, allCheckBoxes) {
+ if (editable) {
+ checkbox->setEnabled(true);
+ } else {
+ checkbox->setEnabled(false);
+ }
+ }
+
+ QList<QtResizableLineEdit*> allLineEdits = findChildren<QtResizableLineEdit*>();
+ foreach(QtResizableLineEdit* lineEdit, allLineEdits) {
+ if (editable) {
+ lineEdit->show();
+ lineEdit->setEditable(true);
+ } else {
+ lineEdit->setEditable(false);
+ if (lineEdit->text().isEmpty()) {
+ lineEdit->hide();
+ } else {
+ lineEdit->show();
+ }
+ }
+ }
+
+ if (editable) {
+ ui->comboBoxDOM_INTL->setEnabled(true);
+ } else {
+ ui->comboBoxDOM_INTL->setEnabled(false);
+ }
+}
+
+bool QtVCardAddressField::isEmpty() const {
+ return false;
+}
+
+GETTER_SETTER_CHECKBOX_IMPL(Home, HOME)
+GETTER_SETTER_CHECKBOX_IMPL(Work, WORK)
+GETTER_SETTER_CHECKBOX_IMPL(Postal, POSTAL)
+GETTER_SETTER_CHECKBOX_IMPL(Parcel, PARCEL)
+GETTER_SETTER_CHECKBOX_IMPL(Preferred, PREF)
+
+void QtVCardAddressField::setDeliveryType(DeliveryType type) {
+ ui->comboBoxDOM_INTL->setCurrentIndex(type);
+}
+
+QtVCardAddressField::DeliveryType QtVCardAddressField::getDeliveryType() const {
+ return ui->comboBoxDOM_INTL->currentIndex() == 1 ? InternationalDelivery : DomesticDelivery;
+}
+
+GETTER_SETTER_LINEEDIT_IMPL(POBox, POBOX)
+GETTER_SETTER_LINEEDIT_IMPL(AddressExtension, EXTADD)
+GETTER_SETTER_LINEEDIT_IMPL(Street, STREET)
+GETTER_SETTER_LINEEDIT_IMPL(Locality, LOCALITY)
+GETTER_SETTER_LINEEDIT_IMPL(Region, REGION)
+GETTER_SETTER_LINEEDIT_IMPL(PostalCode, PCODE)
+GETTER_SETTER_LINEEDIT_IMPL(Country, CTRY)
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardAddressField.h b/Swift/QtUI/QtVCardWidget/QtVCardAddressField.h
new file mode 100644
index 0000000..9f2c83b
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardAddressField.h
@@ -0,0 +1,104 @@
+/*
+ * 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 "QtVCardFieldInfo.h"
+
+namespace Swift {
+
+ namespace Ui {
+ class QtVCardAddressField;
+ }
+
+ class QtVCardAddressField : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+ Q_PROPERTY(bool empty READ isEmpty)
+
+ public :
+ class FieldInfo : public QtVCardFieldInfo {
+ public:
+ virtual ~FieldInfo() {
+ }
+ virtual QString getMenuName() const {
+ return tr("Address");
+ }
+ virtual int getAllowedInstances() const {
+ return UNLIMITED_INSTANCES;
+ }
+ virtual QWidget* createFieldInstance(QWidget* parent, bool editable) const {
+ return new QtVCardAddressField(parent, editable);
+ }
+ virtual bool testInstance(QWidget* widget) const {
+ return dynamic_cast<QtVCardAddressField*>(widget) != 0;
+ }
+ };
+
+ public:
+ enum DeliveryType {
+ DomesticDelivery = 0,
+ InternationalDelivery
+ };
+
+ public:
+ explicit QtVCardAddressField(QWidget* parent = 0, bool editable = false);
+ ~QtVCardAddressField();
+
+ bool isEditable() const;
+ void setEditable(bool);
+
+ bool isEmpty() const;
+
+ void setHome(const bool);
+ bool getHome() const;
+
+ void setWork(const bool);
+ bool getWork() const;
+
+ void setPostal(const bool);
+ bool getPostal() const;
+
+ void setParcel(const bool);
+ bool getParcel() const;
+
+ void setPreferred(const bool);
+ bool getPreferred() const;
+
+ void setPOBox(const QString);
+ QString getPOBox() const;
+
+ void setDeliveryType(DeliveryType type);
+ DeliveryType getDeliveryType() const;
+
+ void setAddressExtension(const QString);
+ QString getAddressExtension() const;
+
+ void setStreet(const QString);
+ QString getStreet() const;
+
+ void setLocality(const QString);
+ QString getLocality() const;
+
+ void setRegion(const QString);
+ QString getRegion() const;
+
+ void setPostalCode(const QString);
+ QString getPostalCode() const;
+
+ void setCountry(const QString);
+ QString getCountry() const;
+
+ private slots:
+
+ private:
+ Ui::QtVCardAddressField* ui;
+ bool editable;
+ };
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardAddressField.ui b/Swift/QtUI/QtVCardWidget/QtVCardAddressField.ui
new file mode 100644
index 0000000..f5dffc8
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardAddressField.ui
@@ -0,0 +1,229 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Swift::QtVCardAddressField</class>
+ <widget class="QWidget" name="Swift::QtVCardAddressField">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>524</width>
+ <height>120</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>2</number>
+ </property>
+ <item row="0" column="1">
+ <widget class="Swift::QtResizableLineEdit" name="lineEditSTREET">
+ <property name="toolTip">
+ <string>Street</string>
+ </property>
+ <property name="placeholderText">
+ <string>Street</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="Swift::QtResizableLineEdit" name="lineEditREGION">
+ <property name="toolTip">
+ <string>Region</string>
+ </property>
+ <property name="placeholderText">
+ <string>Region</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="Swift::QtResizableLineEdit" name="lineEditCTRY">
+ <property name="toolTip">
+ <string>Country</string>
+ </property>
+ <property name="placeholderText">
+ <string>Country</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="3">
+ <widget class="Swift::QtResizableLineEdit" name="lineEditPCODE">
+ <property name="toolTip">
+ <string>Postal Code</string>
+ </property>
+ <property name="placeholderText">
+ <string>Postal Code</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="Swift::QtResizableLineEdit" name="lineEditLOCALITY">
+ <property name="toolTip">
+ <string>City</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="placeholderText">
+ <string>City</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="Swift::QtResizableLineEdit" name="lineEditEXTADD">
+ <property name="toolTip">
+ <string>Address Extension</string>
+ </property>
+ <property name="placeholderText">
+ <string>Address Extension</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="Swift::QtResizableLineEdit" name="lineEditPOBOX">
+ <property name="toolTip">
+ <string>PO Box</string>
+ </property>
+ <property name="placeholderText">
+ <string>PO Box</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="checkBoxPREF">
+ <property name="toolTip">
+ <string>Preferred</string>
+ </property>
+ <property name="text">
+ <string>Preferred</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QCheckBox" name="checkBoxHOME">
+ <property name="toolTip">
+ <string>Home</string>
+ </property>
+ <property name="text">
+ <string>Home</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QCheckBox" name="checkBoxWORK">
+ <property name="toolTip">
+ <string>Work</string>
+ </property>
+ <property name="text">
+ <string>Work</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QCheckBox" name="checkBoxPOSTAL">
+ <property name="toolTip">
+ <string>Postal</string>
+ </property>
+ <property name="text">
+ <string>Postal</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QCheckBox" name="checkBoxPARCEL">
+ <property name="toolTip">
+ <string>Parcel</string>
+ </property>
+ <property name="text">
+ <string>Parcel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="3">
+ <widget class="QComboBox" name="comboBoxDOM_INTL">
+ <property name="toolTip">
+ <string>Delivery Type</string>
+ </property>
+ <property name="sizeAdjustPolicy">
+ <enum>QComboBox::AdjustToMinimumContentsLength</enum>
+ </property>
+ <item>
+ <property name="text">
+ <string>Domestic Delivery</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>International Delivery</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <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>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Swift::QtResizableLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>QtResizableLineEdit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.cpp
new file mode 100644
index 0000000..79e4440
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardAddressLabelField.h"
+#include "ui_QtVCardAddressLabelField.h"
+
+#define GETTER_SETTER_CHECKBOX_IMPL( METHOD_NAME, UI_NAME ) \
+ void QtVCardAddressLabelField::set##METHOD_NAME(const bool METHOD_NAME) { \
+ ui->checkBox##UI_NAME->setChecked(METHOD_NAME); \
+ } \
+ \
+ bool QtVCardAddressLabelField::get##METHOD_NAME() const { \
+ return ui->checkBox##UI_NAME->checkState() == Qt::Checked; \
+ }
+
+namespace Swift {
+
+QtVCardAddressLabelField::QtVCardAddressLabelField(QWidget* parent, bool editable) :
+ QWidget(parent),
+ ui(new Ui::QtVCardAddressLabelField) {
+ ui->setupUi(this);
+ setEditable(editable);
+}
+
+QtVCardAddressLabelField::~QtVCardAddressLabelField() {
+ delete ui;
+}
+
+bool QtVCardAddressLabelField::isEditable() const {
+ return editable;
+}
+
+void QtVCardAddressLabelField::setEditable(bool editable) {
+ this->editable = editable;
+ ui->plainTextEditLINES->setReadOnly(!editable);
+}
+
+bool QtVCardAddressLabelField::isEmpty() const {
+ return false;
+}
+
+GETTER_SETTER_CHECKBOX_IMPL(Home, HOME)
+GETTER_SETTER_CHECKBOX_IMPL(Work, WORK)
+GETTER_SETTER_CHECKBOX_IMPL(Postal, POSTAL)
+GETTER_SETTER_CHECKBOX_IMPL(Parcel, PARCEL)
+GETTER_SETTER_CHECKBOX_IMPL(Preferred, PREF)
+
+void QtVCardAddressLabelField::setDeliveryType(DeliveryType type) {
+ ui->comboBoxDOM_INTL->setCurrentIndex(type);
+}
+
+QtVCardAddressLabelField::DeliveryType QtVCardAddressLabelField::getDeliveryType() const {
+ return ui->comboBoxDOM_INTL->currentIndex() == 1 ? InternationalDelivery : DomesticDelivery;
+}
+
+void QtVCardAddressLabelField::setLines(const QString& lines) {
+ ui->plainTextEditLINES->setPlainText(lines);
+}
+
+QString QtVCardAddressLabelField::getLines() const {
+ return ui->plainTextEditLINES->toPlainText();
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.h b/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.h
new file mode 100644
index 0000000..868fbce
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.h
@@ -0,0 +1,89 @@
+/*
+ * 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 "QtVCardFieldInfo.h"
+
+namespace Swift {
+
+ namespace Ui {
+ class QtVCardAddressLabelField;
+ }
+
+ class QtVCardAddressLabelField : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+ Q_PROPERTY(bool empty READ isEmpty)
+
+ public :
+ class FieldInfo : public QtVCardFieldInfo {
+ public:
+ virtual ~FieldInfo() {
+ }
+ virtual QString getMenuName() const {
+ return tr("Address Label");
+ }
+ virtual int getAllowedInstances() const {
+ return UNLIMITED_INSTANCES;
+ }
+ virtual QWidget* createFieldInstance(QWidget* parent, bool editable) const {
+ return new QtVCardAddressLabelField(parent, editable);
+ }
+ virtual bool testInstance(QWidget* widget) const {
+ return dynamic_cast<QtVCardAddressLabelField*>(widget) != 0;
+ }
+ };
+
+ public:
+ enum DeliveryType {
+ DomesticDelivery = 0,
+ InternationalDelivery
+ };
+
+ public:
+ explicit QtVCardAddressLabelField(QWidget* parent = 0, bool editable = false);
+ ~QtVCardAddressLabelField();
+
+ bool isEditable() const;
+ void setEditable(bool);
+
+ bool isEmpty() const;
+
+ void setHome(const bool);
+ bool getHome() const;
+
+ void setWork(const bool);
+ bool getWork() const;
+
+ void setPostal(const bool);
+ bool getPostal() const;
+
+ void setParcel(const bool);
+ bool getParcel() const;
+
+ void setPreferred(const bool);
+ bool getPreferred() const;
+
+ void setPOBox(const QString);
+ QString getPOBox() const;
+
+ void setDeliveryType(DeliveryType type);
+ DeliveryType getDeliveryType() const;
+
+ void setLines(const QString&);
+ QString getLines() const;
+
+ private slots:
+
+ private:
+ Ui::QtVCardAddressLabelField* ui;
+ bool editable;
+ };
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.ui b/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.ui
new file mode 100644
index 0000000..dc1de27
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.ui
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Swift::QtVCardAddressLabelField</class>
+ <widget class="QWidget" name="Swift::QtVCardAddressLabelField">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>614</width>
+ <height>80</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPlainTextEdit" name="plainTextEditLINES">
+ <property name="toolTip">
+ <string>Address Label</string>
+ </property>
+ <property name="autoFillBackground">
+ <bool>false</bool>
+ </property>
+ <property name="lineWrapMode">
+ <enum>QPlainTextEdit::NoWrap</enum>
+ </property>
+ <property name="backgroundVisible">
+ <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>146</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="checkBoxPREF">
+ <property name="toolTip">
+ <string>Preferred</string>
+ </property>
+ <property name="text">
+ <string>Preferred</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QCheckBox" name="checkBoxHOME">
+ <property name="toolTip">
+ <string>Home</string>
+ </property>
+ <property name="text">
+ <string>Home</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QCheckBox" name="checkBoxWORK">
+ <property name="toolTip">
+ <string>Work</string>
+ </property>
+ <property name="text">
+ <string>Work</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QCheckBox" name="checkBoxPOSTAL">
+ <property name="toolTip">
+ <string>Postal</string>
+ </property>
+ <property name="text">
+ <string>Postal</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QCheckBox" name="checkBoxPARCEL">
+ <property name="toolTip">
+ <string>Parcel</string>
+ </property>
+ <property name="text">
+ <string>Parcel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="3">
+ <widget class="QComboBox" name="comboBoxDOM_INTL">
+ <property name="toolTip">
+ <string>Delivery Type</string>
+ </property>
+ <property name="sizeAdjustPolicy">
+ <enum>QComboBox::AdjustToMinimumContentsLength</enum>
+ </property>
+ <item>
+ <property name="text">
+ <string>Domestic Delivery</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>International Delivery</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <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>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.cpp
new file mode 100644
index 0000000..3cad247
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardBirthdayField.h"
+#include "ui_QtVCardBirthdayField.h"
+
+#include <QLayout>
+
+namespace Swift {
+
+QtVCardBirthdayField::QtVCardBirthdayField(QWidget* parent, bool editable) :
+ QWidget(parent),
+ ui(new Ui::QtVCardBirthdayField) {
+ ui->setupUi(this);
+ connect(ui->deleteField, SIGNAL(clicked()), SLOT(onDeleteFieldPressed()));
+ setEditable(editable);
+}
+
+QtVCardBirthdayField::~QtVCardBirthdayField() {
+ delete ui;
+}
+
+bool QtVCardBirthdayField::isEditable() const {
+ return editable;
+}
+
+void QtVCardBirthdayField::setEditable(bool editable) {
+ if (editable) {
+ ui->labelBDAY->hide();
+ ui->dateEditBDAY->show();
+ ui->deleteField->show();
+ } else {
+ ui->dateEditBDAY->hide();
+ ui->deleteField->hide();
+ ui->labelBDAY->show();
+ }
+ this->editable = editable;
+}
+
+bool QtVCardBirthdayField::isEmpty() const {
+ return false;
+}
+
+void QtVCardBirthdayField::setBirthday(const QDate& date) {
+ ui->labelBDAY->setText(date.toString());
+ ui->dateEditBDAY->setDate(date);
+}
+
+QDate QtVCardBirthdayField::getBirthday() const {
+ return ui->dateEditBDAY->date();
+}
+
+void QtVCardBirthdayField::onDateChanged(QDate date) {
+ ui->labelBDAY->setText(date.toString());
+}
+
+void QtVCardBirthdayField::onDeleteFieldPressed() {
+ delete this;
+}
+
+}
+
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.h b/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.h
new file mode 100644
index 0000000..28197c0
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.h
@@ -0,0 +1,65 @@
+/*
+ * 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 <QDate>
+
+#include "QtVCardFieldInfo.h"
+
+namespace Swift {
+
+ namespace Ui {
+ class QtVCardBirthdayField;
+ }
+
+ class QtVCardBirthdayField : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+ Q_PROPERTY(bool empty READ isEmpty)
+
+ public :
+ class FieldInfo : public QtVCardFieldInfo {
+ public:
+ virtual ~FieldInfo() {
+ }
+ virtual QString getMenuName() const {
+ return tr("Birthday");
+ }
+ virtual int getAllowedInstances() const {
+ return 1;
+ }
+ virtual QWidget* createFieldInstance(QWidget* parent, bool editable) const {
+ return new QtVCardBirthdayField(parent, editable);
+ }
+ virtual bool testInstance(QWidget* widget) const {
+ return dynamic_cast<QtVCardBirthdayField*>(widget) != 0;
+ }
+ };
+
+ public:
+ explicit QtVCardBirthdayField(QWidget* parent = 0, bool editable = false);
+ virtual ~QtVCardBirthdayField();
+
+ bool isEditable() const;
+ void setEditable(bool);
+
+ bool isEmpty() const;
+
+ void setBirthday(const QDate& date);
+ QDate getBirthday() const;
+
+ private slots:
+ void onDateChanged(QDate date);
+ void onDeleteFieldPressed();
+
+ private:
+ Ui::QtVCardBirthdayField* ui;
+ bool editable;
+ };
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.ui b/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.ui
new file mode 100644
index 0000000..bb6ddd4
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.ui
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Swift::QtVCardBirthdayField</class>
+ <widget class="QWidget" name="Swift::QtVCardBirthdayField">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>392</width>
+ <height>38</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="labelBDAY">
+ <property name="toolTip">
+ <string>Birthday</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDateEdit" name="dateEditBDAY">
+ <property name="toolTip">
+ <string>Birthday</string>
+ </property>
+ <property name="displayFormat">
+ <string>dd.MM.yyyy</string>
+ </property>
+ <property name="calendarPopup">
+ <bool>true</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>
+ <item>
+ <widget class="QPushButton" name="deleteField">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>X</string>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.cpp
new file mode 100644
index 0000000..c86d72e
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardDescriptionField.h"
+#include "ui_QtVCardDescriptionField.h"
+
+namespace Swift {
+
+QtVCardDescriptionField::QtVCardDescriptionField(QWidget* parent, bool editable) :
+ QWidget(parent),
+ ui(new Ui::QtVCardDescriptionField) {
+ ui->setupUi(this);
+ setEditable(editable);
+}
+
+QtVCardDescriptionField::~QtVCardDescriptionField() {
+ delete ui;
+}
+
+bool QtVCardDescriptionField::isEditable() const {
+ return editable;
+}
+
+void QtVCardDescriptionField::setEditable(bool editable) {
+ this->editable = editable;
+ ui->plainTextEditDESC->setReadOnly(!editable);
+}
+
+bool QtVCardDescriptionField::isEmpty() const {
+ return ui->plainTextEditDESC->toPlainText().isEmpty();
+}
+
+void QtVCardDescriptionField::setDescription(const QString description) {
+ ui->plainTextEditDESC->setPlainText(description);
+}
+
+QString QtVCardDescriptionField::getDescription() const {
+ return ui->plainTextEditDESC->toPlainText();
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.h b/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.h
new file mode 100644
index 0000000..22c3a72
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.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 "QtVCardFieldInfo.h"
+
+namespace Swift {
+
+ namespace Ui {
+ class QtVCardDescriptionField;
+ }
+
+ class QtVCardDescriptionField : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+ Q_PROPERTY(bool empty READ isEmpty)
+
+ public :
+ class FieldInfo : public QtVCardFieldInfo {
+ public:
+ virtual ~FieldInfo() {
+ }
+ virtual QString getMenuName() const {
+ return tr("Description");
+ }
+ virtual int getAllowedInstances() const {
+ return 1;
+ }
+ virtual QWidget* createFieldInstance(QWidget* parent, bool editable) const {
+ return new QtVCardDescriptionField(parent, editable);
+ }
+ virtual bool testInstance(QWidget* widget) const {
+ return dynamic_cast<QtVCardDescriptionField*>(widget) != 0;
+ }
+ };
+
+ public:
+ explicit QtVCardDescriptionField(QWidget* parent = 0, bool editable = false);
+ ~QtVCardDescriptionField();
+
+ bool isEditable() const;
+ void setEditable(bool);
+
+ bool isEmpty() const;
+
+ void setDescription(const QString description);
+ QString getDescription() const;
+
+ private:
+ Ui::QtVCardDescriptionField* ui;
+ bool editable;
+ };
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.ui b/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.ui
new file mode 100644
index 0000000..9ca3fe5
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.ui
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Swift::QtVCardDescriptionField</class>
+ <widget class="QWidget" name="Swift::QtVCardDescriptionField">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>488</width>
+ <height>170</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPlainTextEdit" name="plainTextEditDESC">
+ <property name="toolTip">
+ <string>Description</string>
+ </property>
+ <property name="documentTitle">
+ <string/>
+ </property>
+ <property name="lineWrapMode">
+ <enum>QPlainTextEdit::NoWrap</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardEMailField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardEMailField.cpp
new file mode 100644
index 0000000..58372c2
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardEMailField.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardEMailField.h"
+#include "ui_QtVCardEMailField.h"
+
+#include <QVariant>
+
+namespace Swift {
+
+QtVCardEMailField::QtVCardEMailField(QWidget* parent, bool editable) :
+ QWidget(parent),
+ ui(new Ui::QtVCardEMailField) {
+ ui->setupUi(this);
+ connect(ui->lineEditEMAIL, SIGNAL(textChanged(QString)), SLOT(onTextChanged(QString)));
+ connect(ui->comboBoxType, SIGNAL(currentIndexChanged(int)), SLOT(onEMailTypeChanged(int)));
+ setEditable(editable);
+}
+
+QtVCardEMailField::~QtVCardEMailField() {
+ delete ui;
+}
+
+bool QtVCardEMailField::isEditable() const {
+ return editable;
+}
+
+void QtVCardEMailField::setEditable(bool editable) {
+ this->editable = editable;
+ if (this->editable) {
+ ui->label->show();
+ ui->comboBoxType->show();
+ ui->lineEditEMAIL->show();
+ ui->labelEMAIL->hide();
+ } else {
+ ui->label->hide();
+ ui->comboBoxType->hide();
+ ui->lineEditEMAIL->hide();
+ ui->labelEMAIL->show();
+ }
+
+ foreach(QObject* widget, children()) {
+ if (!dynamic_cast<QWidget*>(widget)) continue;
+ if (widget->property("editable").isValid()) {
+ widget->setProperty("editable", QVariant(editable));
+ }
+
+ if (widget->property("readOnly").isValid()) {
+ widget->setProperty("readOnly", QVariant(!editable));
+ widget->setProperty("frame", QVariant(editable));
+ }
+
+ QCheckBox* checkbox;
+ if ((checkbox = dynamic_cast<QCheckBox*>(widget))) {
+ checkbox->setProperty("enabled", QVariant(editable));
+ }
+ }
+}
+
+bool QtVCardEMailField::isEmpty() const {
+ return ui->lineEditEMAIL->text().isEmpty();
+}
+
+void QtVCardEMailField::setAddress(const QString address) {
+ ui->lineEditEMAIL->setText(address);
+}
+
+QString QtVCardEMailField::getAddress() const {
+ return ui->lineEditEMAIL->text();
+}
+
+void QtVCardEMailField::setPreferred(const bool preferred) {
+ ui->checkBoxPREF->setChecked(preferred);
+}
+
+bool QtVCardEMailField::getPreferred() const {
+ return ui->checkBoxPREF->checkState() == Qt::Checked;
+}
+
+void QtVCardEMailField::setHome(const bool home) {
+ ui->checkBoxHOME->setChecked(home);
+}
+
+bool QtVCardEMailField::getHome() const {
+ return ui->checkBoxHOME->checkState() == Qt::Checked;
+}
+
+void QtVCardEMailField::setWork(const bool work) {
+ ui->checkBoxWORK->setChecked(work);
+}
+
+bool QtVCardEMailField::getWork() const {
+ return ui->checkBoxWORK->checkState() == Qt::Checked;
+}
+
+void QtVCardEMailField::setType(EMailType type) {
+ ui->comboBoxType->setCurrentIndex(type);
+}
+
+QtVCardEMailField::EMailType QtVCardEMailField::getType() const {
+ return ui->comboBoxType->currentIndex() == 1 ? X_400 : Internet;
+}
+
+void QtVCardEMailField::onTextChanged(const QString& text) {
+ if (ui->comboBoxType->currentIndex() == Internet && isEmailAddress(text)) {
+ ui->labelEMAIL->setText(QString("<a href=\"mailto:%1\">%1</a>").arg(text));
+ } else {
+ ui->labelEMAIL->setText(text);
+ }
+}
+
+void QtVCardEMailField::onEMailTypeChanged(int) {
+ onTextChanged(ui->labelEMAIL->text());
+}
+
+bool QtVCardEMailField::isEmailAddress(const QString& emailAddress) {
+ if ( emailAddress.length() == 0 ) {
+ return false;
+ }
+ QRegExp regex(QString("\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b"), Qt::CaseInsensitive);
+ return regex.exactMatch(emailAddress);
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardEMailField.h b/Swift/QtUI/QtVCardWidget/QtVCardEMailField.h
new file mode 100644
index 0000000..ff486a1
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardEMailField.h
@@ -0,0 +1,84 @@
+/*
+ * 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 "QtVCardFieldInfo.h"
+
+namespace Swift {
+
+ namespace Ui {
+ class QtVCardEMailField;
+ }
+
+ class QtVCardEMailField : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+ Q_PROPERTY(bool empty READ isEmpty)
+
+ public :
+ class FieldInfo : public QtVCardFieldInfo {
+ public:
+ virtual ~FieldInfo() {
+ }
+ virtual QString getMenuName() const {
+ return tr("EMail");
+ }
+ virtual int getAllowedInstances() const {
+ return UNLIMITED_INSTANCES;
+ }
+ virtual QWidget* createFieldInstance(QWidget* parent, bool editable) const {
+ return new QtVCardEMailField(parent, editable);
+ }
+ virtual bool testInstance(QWidget* widget) const {
+ return dynamic_cast<QtVCardEMailField*>(widget) != 0;
+ }
+ };
+
+ enum EMailType {
+ Internet = 0,
+ X_400
+ };
+
+ public:
+ explicit QtVCardEMailField(QWidget* parent = 0, bool editable = false);
+ ~QtVCardEMailField();
+
+ bool isEditable() const;
+ void setEditable(bool);
+
+ bool isEmpty() const;
+
+ void setAddress(const QString address);
+ QString getAddress() const;
+
+ void setPreferred(const bool preferred);
+ bool getPreferred() const;
+
+ void setHome(const bool home);
+ bool getHome() const;
+
+ void setWork(const bool work);
+ bool getWork() const;
+
+ void setType(EMailType type);
+ EMailType getType() const;
+
+ private slots:
+ void onTextChanged(const QString&);
+ void onEMailTypeChanged(int);
+
+ private:
+ bool isEmailAddress(const QString& emailAddress);
+
+ private:
+ Ui::QtVCardEMailField* ui;
+ bool editable;
+ };
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardEMailField.ui b/Swift/QtUI/QtVCardWidget/QtVCardEMailField.ui
new file mode 100644
index 0000000..abf0fa1
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardEMailField.ui
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Swift::QtVCardEMailField</class>
+ <widget class="QWidget" name="Swift::QtVCardEMailField">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>517</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Type:</string>
+ </property>
+ <property name="buddy">
+ <cstring>comboBoxType</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboBoxType">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="editable">
+ <bool>false</bool>
+ </property>
+ <property name="sizeAdjustPolicy">
+ <enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
+ </property>
+ <property name="minimumContentsLength">
+ <number>1</number>
+ </property>
+ <item>
+ <property name="text">
+ <string>Internet</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>X.400</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelEMAIL">
+ <property name="toolTip">
+ <string>E-Mail</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Swift::QtResizableLineEdit" name="lineEditEMAIL">
+ <property name="toolTip">
+ <string>E-Mail</string>
+ </property>
+ <property name="placeholderText">
+ <string>E-Mail</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBoxPREF">
+ <property name="text">
+ <string>Preferred</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBoxHOME">
+ <property name="text">
+ <string>Home</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBoxWORK">
+ <property name="text">
+ <string>Work</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Swift::QtResizableLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>QtResizableLineEdit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h b/Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h
new file mode 100644
index 0000000..8a9d089
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.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 <typeinfo>
+
+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, bool editable) const = 0;
+ virtual bool testInstance(QWidget*) const = 0;
+ };
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardJIDField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardJIDField.cpp
new file mode 100644
index 0000000..69e2285
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardJIDField.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardJIDField.h"
+#include "ui_QtVCardJIDField.h"
+
+#include <Swiften/JID/JID.h>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+
+namespace Swift {
+
+QtVCardJIDField::QtVCardJIDField(QWidget* parent, bool editable) :
+ QWidget(parent),
+ ui(new Ui::QtVCardJIDField) {
+ ui->setupUi(this);
+ connect(ui->lineEditJID, SIGNAL(textChanged(QString)), SLOT(onTextChanged(QString)));
+ setEditable(editable);
+}
+
+QtVCardJIDField::~QtVCardJIDField() {
+ delete ui;
+}
+
+bool QtVCardJIDField::isEditable() const {
+ return editable;
+}
+
+void QtVCardJIDField::setEditable(bool editable) {
+ this->editable = editable;
+ if (this->editable) {
+ ui->lineEditJID->show();
+ ui->labelJID->hide();
+ } else {
+ ui->lineEditJID->hide();
+ ui->labelJID->show();
+ }
+}
+
+bool QtVCardJIDField::isEmpty() const {
+ return ui->lineEditJID->text().isEmpty();
+}
+
+void QtVCardJIDField::setJID(const QString jid) {
+ ui->lineEditJID->setText(jid);
+}
+
+QString QtVCardJIDField::getJID() const {
+ return ui->lineEditJID->text();
+}
+
+void QtVCardJIDField::onTextChanged(const QString& text) {
+ if (text.isEmpty()) {
+ ui->labelJID->setText("");
+ } else {
+ if (JID(Q2PSTRING(text)).isValid()) {
+ ui->labelJID->setText(QString("<a href=\"xmpp:%1\">%1</a>").arg(text));
+ } else {
+ ui->labelJID->setText(text);
+ }
+ }
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardJIDField.h b/Swift/QtUI/QtVCardWidget/QtVCardJIDField.h
new file mode 100644
index 0000000..bd697de
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardJIDField.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QWidget>
+
+#include "QtVCardFieldInfo.h"
+
+namespace Swift {
+
+ namespace Ui {
+ class QtVCardJIDField;
+ }
+
+ class QtVCardJIDField : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+ Q_PROPERTY(bool empty READ isEmpty)
+
+ public :
+ class FieldInfo : public QtVCardFieldInfo {
+ public:
+ virtual ~FieldInfo() {
+ }
+ virtual QString getMenuName() const {
+ return tr("JID");
+ }
+ virtual int getAllowedInstances() const {
+ return UNLIMITED_INSTANCES;
+ }
+ virtual QWidget* createFieldInstance(QWidget* parent, bool editable) const {
+ return new QtVCardJIDField(parent, editable);
+ }
+ virtual bool testInstance(QWidget* widget) const {
+ return dynamic_cast<QtVCardJIDField*>(widget) != 0;
+ }
+ };
+
+ public:
+ explicit QtVCardJIDField(QWidget* parent = 0, bool editable = false);
+ ~QtVCardJIDField();
+
+ bool isEditable() const;
+ void setEditable(bool);
+
+ bool isEmpty() const;
+
+ void setJID(const QString jid);
+ QString getJID() const;
+
+ private slots:
+ void onTextChanged(const QString&);
+
+ private:
+ Ui::QtVCardJIDField* ui;
+ bool editable;
+ };
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardJIDField.ui b/Swift/QtUI/QtVCardWidget/QtVCardJIDField.ui
new file mode 100644
index 0000000..7215578
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardJIDField.ui
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Swift::QtVCardJIDField</class>
+ <widget class="QWidget" name="Swift::QtVCardJIDField">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>517</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="labelJID">
+ <property name="toolTip">
+ <string>JID</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Swift::QtResizableLineEdit" name="lineEditJID">
+ <property name="toolTip">
+ <string>JID</string>
+ </property>
+ <property name="placeholderText">
+ <string>JID</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Swift::QtResizableLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>QtResizableLineEdit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardOrganisationField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardOrganisationField.cpp
new file mode 100644
index 0000000..37d35d9
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardOrganisationField.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 "QtVCardOrganisationField.h"
+#include "ui_QtVCardOrganisationField.h"
+
+namespace Swift {
+
+QtVCardOrganisationField::QtVCardOrganisationField(QWidget* parent, bool editable) :
+ QWidget(parent),
+ ui(new Ui::QtVCardOrganisationField) {
+ ui->setupUi(this);
+ connect(ui->lineEditORGNAME, SIGNAL(textChanged(QString)), SLOT(onTextChanged(QString)));
+ connect(ui->pushButtonAddUnit, SIGNAL(clicked()), SLOT(onAddUnitButtonPressed()));
+ connect(ui->pushButtonRemoveUnit, SIGNAL(clicked()), SLOT(onRemoveUnitButtonPressed()));
+ setEditable(editable);
+}
+
+QtVCardOrganisationField::~QtVCardOrganisationField() {
+ delete ui;
+}
+
+bool QtVCardOrganisationField::isEditable() const {
+ return editable;
+}
+
+void QtVCardOrganisationField::setEditable(bool editable) {
+ this->editable = editable;
+ if (this->editable) {
+ ui->lineEditORGNAME->show();
+ ui->labelORGNAME->hide();
+ ui->listWidgetORGUNIT->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);
+ ui->listWidgetORGUNIT->setEnabled(true);
+ ui->pushButtonAddUnit->show();
+ ui->pushButtonRemoveUnit->show();
+ } else {
+ ui->lineEditORGNAME->hide();
+ ui->labelORGNAME->show();
+ if (ui->listWidgetORGUNIT->count() > 0) {
+ ui->listWidgetORGUNIT->setEditTriggers(0);
+ ui->listWidgetORGUNIT->show();
+ } else {
+ ui->listWidgetORGUNIT->hide();
+ }
+ ui->pushButtonAddUnit->hide();
+ ui->pushButtonRemoveUnit->hide();
+ }
+}
+
+bool QtVCardOrganisationField::isEmpty() const {
+ return ui->lineEditORGNAME->text().isEmpty() && getUnits().empty();
+}
+
+void QtVCardOrganisationField::setName(const QString name) {
+ ui->lineEditORGNAME->setText(name);
+}
+
+QString QtVCardOrganisationField::getName() const {
+ return ui->lineEditORGNAME->text();
+}
+
+void QtVCardOrganisationField::setUnits(const QList<QString> units) {
+ ui->listWidgetORGUNIT->clear();
+ foreach(const QString& unit, units) {
+ QListWidgetItem* item = new QListWidgetItem(unit);
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+ ui->listWidgetORGUNIT->addItem(item);
+ }
+}
+
+QList<QString> QtVCardOrganisationField::getUnits() const {
+ QList<QString> units;
+ for (int n = 0; n < ui->listWidgetORGUNIT->count(); n++) {
+ QListWidgetItem* item = ui->listWidgetORGUNIT->item(n);
+ units.push_back(item->text());
+ }
+ return units;
+}
+
+void QtVCardOrganisationField::onTextChanged(const QString& text) {
+ ui->labelORGNAME->setText(text);
+}
+
+void QtVCardOrganisationField::onAddUnitButtonPressed() {
+ QListWidgetItem* item = new QListWidgetItem("Doubleclick to edit.");
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+ ui->listWidgetORGUNIT->addItem(item);
+}
+
+void QtVCardOrganisationField::onRemoveUnitButtonPressed() {
+ foreach (QListWidgetItem* item, ui->listWidgetORGUNIT->selectedItems()) {
+ ui->listWidgetORGUNIT->removeItemWidget(item);
+ delete item;
+ }
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardOrganisationField.h b/Swift/QtUI/QtVCardWidget/QtVCardOrganisationField.h
new file mode 100644
index 0000000..0743823
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardOrganisationField.h
@@ -0,0 +1,68 @@
+/*
+ * 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 "QtVCardFieldInfo.h"
+
+namespace Swift {
+
+ namespace Ui {
+ class QtVCardOrganisationField;
+ }
+
+ class QtVCardOrganisationField : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+ Q_PROPERTY(bool empty READ isEmpty)
+
+ public :
+ class FieldInfo : public QtVCardFieldInfo {
+ public:
+ virtual ~FieldInfo() {
+ }
+ virtual QString getMenuName() const {
+ return tr("Organisation");
+ }
+ virtual int getAllowedInstances() const {
+ return UNLIMITED_INSTANCES;
+ }
+ virtual QWidget* createFieldInstance(QWidget* parent, bool editable) const {
+ return new QtVCardOrganisationField(parent, editable);
+ }
+ virtual bool testInstance(QWidget* widget) const {
+ return dynamic_cast<QtVCardOrganisationField*>(widget) != 0;
+ }
+ };
+
+ public:
+ explicit QtVCardOrganisationField(QWidget* parent = 0, bool editable = false);
+ ~QtVCardOrganisationField();
+
+ bool isEditable() const;
+ void setEditable(bool);
+
+ bool isEmpty() const;
+
+ void setName(const QString name);
+ QString getName() const;
+
+ void setUnits(const QList<QString> units);
+ QList<QString> getUnits() const;
+
+ private slots:
+ void onTextChanged(const QString&);
+ void onAddUnitButtonPressed();
+ void onRemoveUnitButtonPressed();
+
+ private:
+ Ui::QtVCardOrganisationField* ui;
+ bool editable;
+ };
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardOrganisationField.ui b/Swift/QtUI/QtVCardWidget/QtVCardOrganisationField.ui
new file mode 100644
index 0000000..1caf2b1
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardOrganisationField.ui
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Swift::QtVCardOrganisationField</class>
+ <widget class="QWidget" name="Swift::QtVCardOrganisationField">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>455</width>
+ <height>112</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="labelORGNAME">
+ <property name="toolTip">
+ <string>Organisation Name</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Swift::QtResizableLineEdit" name="lineEditORGNAME">
+ <property name="toolTip">
+ <string>Organisation Name</string>
+ </property>
+ <property name="placeholderText">
+ <string>Organisation Name</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item row="1" column="0" colspan="2">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>5</number>
+ </property>
+ <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>
+ <item>
+ <widget class="QPushButton" name="pushButtonRemoveUnit">
+ <property name="text">
+ <string>Remove Unit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButtonAddUnit">
+ <property name="text">
+ <string>Add Unit</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="0">
+ <widget class="QListWidget" name="listWidgetORGUNIT">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Organisation Units</string>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::MultiSelection</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Swift::QtResizableLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>QtResizableLineEdit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.cpp b/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.cpp
new file mode 100644
index 0000000..2c6ef22
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.cpp
@@ -0,0 +1,162 @@
+/*
+ * 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 <QDebug>
+#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();
+
+ 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;
+
+ foreach(QObject *widget, children()) {
+ if (!dynamic_cast<QWidget*>(widget)) continue;
+ if (widget->property("editable").isValid()) {
+ widget->setProperty("editable", QVariant(editable));
+ }
+
+ if (widget->property("readOnly").isValid()) {
+ widget->setProperty("readOnly", QVariant(!editable));
+ widget->setProperty("frame", QVariant(editable));
+ }
+ QLineEdit* lineEdit = 0;
+ if ((lineEdit = dynamic_cast<QLineEdit*>(widget))) {
+ if (lineEdit->text().isEmpty()) {
+ lineEdit->hide();
+ } else {
+ lineEdit->show();
+ }
+ }
+ }
+ 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()) {
+ QAction* action = addFieldMenu->addAction(QString("Add ") + lineEdit->placeholderText(), actionSignalMapper, SLOT(map()));
+ 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..2fb7e0a
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.h
@@ -0,0 +1,74 @@
+/*
+ * 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..a30878e
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.ui
@@ -0,0 +1,260 @@
+<?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>
+ </font>
+ </property>
+ <property name="toolTip">
+ <string>Formatted Name</string>
+ </property>
+ <property name="placeholderText">
+ <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>
+ <property name="placeholderText">
+ <string>Nickname</string>
+ </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="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>
+ <property name="placeholderText">
+ <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>
+ <property name="placeholderText">
+ <string>Given Name</string>
+ </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>
+ <property name="placeholderText">
+ <string>Middle Name</string>
+ </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>
+ <property name="placeholderText">
+ <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>
+ <property name="placeholderText">
+ <string>Suffix</string>
+ </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..d35f732
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardRoleField.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 "QtVCardRoleField.h"
+#include "ui_QtVCardRoleField.h"
+
+namespace Swift {
+
+QtVCardRoleField::QtVCardRoleField(QWidget* parent, bool editable) :
+ QWidget(parent),
+ ui(new Ui::QtVCardRoleField) {
+ ui->setupUi(this);
+ connect(ui->lineEditROLE, SIGNAL(textChanged(QString)), SLOT(onTextChanged(QString)));
+ setEditable(editable);
+}
+
+QtVCardRoleField::~QtVCardRoleField() {
+ delete ui;
+}
+
+bool QtVCardRoleField::isEditable() const {
+ return editable;
+}
+
+void QtVCardRoleField::setEditable(bool editable) {
+ this->editable = editable;
+ if (this->editable) {
+ ui->lineEditROLE->show();
+ ui->labelROLE->hide();
+ } else {
+ ui->lineEditROLE->hide();
+ ui->labelROLE->show();
+ }
+}
+
+bool QtVCardRoleField::isEmpty() const {
+ return ui->lineEditROLE->text().isEmpty();
+}
+
+void QtVCardRoleField::setRole(const QString role) {
+ ui->lineEditROLE->setText(role);
+}
+
+QString QtVCardRoleField::getRole() const {
+ return ui->lineEditROLE->text();
+}
+
+void QtVCardRoleField::onTextChanged(const QString& text) {
+ ui->labelROLE->setText(text);
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardRoleField.h b/Swift/QtUI/QtVCardWidget/QtVCardRoleField.h
new file mode 100644
index 0000000..f728170
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardRoleField.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QWidget>
+
+#include "QtVCardFieldInfo.h"
+
+namespace Swift {
+
+ namespace Ui {
+ class QtVCardRoleField;
+ }
+
+ class QtVCardRoleField : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+ Q_PROPERTY(bool empty READ isEmpty)
+
+ public :
+ class FieldInfo : public QtVCardFieldInfo {
+ public:
+ virtual ~FieldInfo() {
+ }
+ virtual QString getMenuName() const {
+ return tr("Role");
+ }
+ virtual int getAllowedInstances() const {
+ return UNLIMITED_INSTANCES;
+ }
+ virtual QWidget* createFieldInstance(QWidget* parent, bool editable) const {
+ return new QtVCardRoleField(parent, editable);
+ }
+ virtual bool testInstance(QWidget* widget) const {
+ return dynamic_cast<QtVCardRoleField*>(widget) != 0;
+ }
+ };
+
+ public:
+ explicit QtVCardRoleField(QWidget* parent = 0, bool editable = false);
+ ~QtVCardRoleField();
+
+ bool isEditable() const;
+ void setEditable(bool);
+
+ bool isEmpty() const;
+
+ void setRole(const QString role);
+ QString getRole() const;
+
+ private slots:
+ void onTextChanged(const QString&);
+
+ private:
+ Ui::QtVCardRoleField* ui;
+ bool editable;
+ };
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardRoleField.ui b/Swift/QtUI/QtVCardWidget/QtVCardRoleField.ui
new file mode 100644
index 0000000..f6c482b
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardRoleField.ui
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Swift::QtVCardRoleField</class>
+ <widget class="QWidget" name="Swift::QtVCardRoleField">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>517</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="labelROLE">
+ <property name="toolTip">
+ <string>Role</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Swift::QtResizableLineEdit" name="lineEditROLE">
+ <property name="toolTip">
+ <string>Role</string>
+ </property>
+ <property name="placeholderText">
+ <string>Role</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Swift::QtResizableLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>QtResizableLineEdit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.cpp
new file mode 100644
index 0000000..cbc16bd
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardTelephoneField.h"
+#include "ui_QtVCardTelephoneField.h"
+
+#define GETTER_SETTER_IMPL( METHOD_NAME, UI_NAME ) \
+ void QtVCardTelephoneField::set##METHOD_NAME(const bool METHOD_NAME) { \
+ ui->checkBox##UI_NAME->setChecked(METHOD_NAME); \
+ } \
+ \
+ bool QtVCardTelephoneField::get##METHOD_NAME() const { \
+ return ui->checkBox##UI_NAME->checkState() == Qt::Checked; \
+ }
+
+namespace Swift {
+
+QtVCardTelephoneField::QtVCardTelephoneField(QWidget* parent, bool editable) :
+ QWidget(parent),
+ ui(new Ui::QtVCardTelephoneField) {
+ ui->setupUi(this);
+ connect(ui->lineEditTEL, SIGNAL(textChanged(QString)), SLOT(onTextChanged(QString)));
+ setEditable(editable);
+}
+
+QtVCardTelephoneField::~QtVCardTelephoneField() {
+ delete ui;
+}
+
+bool QtVCardTelephoneField::isEditable() const {
+ return editable;
+}
+
+void QtVCardTelephoneField::setEditable(bool editable) {
+ this->editable = editable;
+ if (this->editable) {
+ ui->lineEditTEL->show();
+ ui->labelTEL->hide();
+ } else {
+ ui->lineEditTEL->hide();
+ ui->labelTEL->show();
+ }
+
+ foreach(QObject *widget, children()) {
+ if (!dynamic_cast<QWidget*>(widget)) continue;
+ if (widget->property("editable").isValid()) {
+ widget->setProperty("editable", QVariant(editable));
+ }
+
+ if (widget->property("readOnly").isValid()) {
+ widget->setProperty("readOnly", QVariant(!editable));
+ widget->setProperty("frame", QVariant(editable));
+ }
+
+ QCheckBox* checkbox;
+ if ((checkbox = dynamic_cast<QCheckBox*>(widget))) {
+ checkbox->setProperty("enabled", QVariant(editable));
+ }
+ }
+}
+
+bool QtVCardTelephoneField::isEmpty() const {
+ return ui->lineEditTEL->text().isEmpty();
+}
+
+void QtVCardTelephoneField::setNumber(const QString number) {
+ ui->lineEditTEL->setText(number);
+}
+
+QString QtVCardTelephoneField::getNumber() const {
+ return ui->lineEditTEL->text();
+}
+
+GETTER_SETTER_IMPL(Preferred, PREF)
+GETTER_SETTER_IMPL(Home, HOME)
+GETTER_SETTER_IMPL(Work, WORK)
+GETTER_SETTER_IMPL(Voice, VOICE)
+GETTER_SETTER_IMPL(Fax, FAX)
+GETTER_SETTER_IMPL(Pager, PAGER)
+GETTER_SETTER_IMPL(MSG, MSG)
+GETTER_SETTER_IMPL(Cell, CELL)
+GETTER_SETTER_IMPL(Video, VIDEO)
+GETTER_SETTER_IMPL(BBS, BBS)
+GETTER_SETTER_IMPL(Modem, MODEM)
+GETTER_SETTER_IMPL(ISDN, ISDN)
+GETTER_SETTER_IMPL(PCS, PCS)
+
+void QtVCardTelephoneField::onTextChanged(const QString& text) {
+ ui->labelTEL->setText(text);
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.h b/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.h
new file mode 100644
index 0000000..d3c6bb2
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.h
@@ -0,0 +1,93 @@
+/*
+ * 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 "QtVCardFieldInfo.h"
+
+namespace Swift {
+
+ namespace Ui {
+ class QtVCardTelephoneField;
+ }
+
+ class QtVCardTelephoneField : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+ Q_PROPERTY(bool empty READ isEmpty)
+
+ public :
+ class FieldInfo : public QtVCardFieldInfo {
+ public:
+ virtual ~FieldInfo() {
+ }
+ virtual QString getMenuName() const {
+ return tr("Telephone");
+ }
+ virtual int getAllowedInstances() const {
+ return UNLIMITED_INSTANCES;
+ }
+ virtual QWidget* createFieldInstance(QWidget* parent, bool editable) const {
+ return new QtVCardTelephoneField(parent, editable);
+ }
+ virtual bool testInstance(QWidget* widget) const {
+ return dynamic_cast<QtVCardTelephoneField*>(widget) != 0;
+ }
+ };
+
+ public:
+ explicit QtVCardTelephoneField(QWidget* parent = 0, bool editable = false);
+ ~QtVCardTelephoneField();
+
+ bool isEditable() const;
+ void setEditable(bool);
+
+ bool isEmpty() const;
+
+ void setNumber(const QString address);
+ QString getNumber() const;
+
+ void setPreferred(const bool preferred);
+ bool getPreferred() const;
+
+ void setHome(const bool home);
+ bool getHome() const;
+
+ void setWork(const bool work);
+ bool getWork() const;
+
+ void setVoice(const bool);
+ bool getVoice() const;
+ void setFax(const bool);
+ bool getFax() const;
+ void setPager(const bool);
+ bool getPager() const;
+ void setMSG(const bool);
+ bool getMSG() const;
+ void setCell(const bool);
+ bool getCell() const;
+ void setVideo(const bool);
+ bool getVideo() const;
+ void setBBS(const bool);
+ bool getBBS() const;
+ void setModem(const bool);
+ bool getModem() const;
+ void setISDN(const bool);
+ bool getISDN() const;
+ void setPCS(const bool);
+ bool getPCS() const;
+
+ private slots:
+ void onTextChanged(const QString&);
+
+ private:
+ Ui::QtVCardTelephoneField* ui;
+ bool editable;
+ };
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.ui b/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.ui
new file mode 100644
index 0000000..3b100bb
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.ui
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Swift::QtVCardTelephoneField</class>
+ <widget class="QWidget" name="Swift::QtVCardTelephoneField">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>629</width>
+ <height>174</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="labelTEL">
+ <property name="toolTip">
+ <string>Telephone</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Swift::QtResizableLineEdit" name="lineEditTEL">
+ <property name="toolTip">
+ <string>Telephone</string>
+ </property>
+ <property name="placeholderText">
+ <string>Telephone</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="checkBoxPREF">
+ <property name="text">
+ <string>Preferred</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QCheckBox" name="checkBoxHOME">
+ <property name="text">
+ <string>Home</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QCheckBox" name="checkBoxWORK">
+ <property name="text">
+ <string>Work</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="checkBoxVOICE">
+ <property name="text">
+ <string>Voice</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QCheckBox" name="checkBoxCELL">
+ <property name="text">
+ <string>Cell</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QCheckBox" name="checkBoxPAGER">
+ <property name="text">
+ <string>Pager</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QCheckBox" name="checkBoxISDN">
+ <property name="text">
+ <string>ISDN</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QCheckBox" name="checkBoxVIDEO">
+ <property name="text">
+ <string>Video</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QCheckBox" name="checkBoxMSG">
+ <property name="text">
+ <string>Voice Messaging Service</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QCheckBox" name="checkBoxFAX">
+ <property name="text">
+ <string>Fax</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QCheckBox" name="checkBoxMODEM">
+ <property name="text">
+ <string>Modem</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" colspan="2">
+ <widget class="QCheckBox" name="checkBoxPCS">
+ <property name="text">
+ <string>Personal Communication Service</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2" colspan="2">
+ <widget class="QCheckBox" name="checkBoxBBS">
+ <property name="text">
+ <string>Bulletin Board System</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Swift::QtResizableLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>QtResizableLineEdit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardTitleField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardTitleField.cpp
new file mode 100644
index 0000000..52b8103
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardTitleField.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 "QtVCardTitleField.h"
+#include "ui_QtVCardTitleField.h"
+
+namespace Swift {
+
+QtVCardTitleField::QtVCardTitleField(QWidget* parent, bool editable) :
+ QWidget(parent),
+ ui(new Ui::QtVCardTitleField) {
+ ui->setupUi(this);
+ connect(ui->lineEditTITLE, SIGNAL(textChanged(QString)), SLOT(onTextChanged(QString)));
+ setEditable(editable);
+}
+
+QtVCardTitleField::~QtVCardTitleField() {
+ delete ui;
+}
+
+bool QtVCardTitleField::isEditable() const {
+ return editable;
+}
+
+void QtVCardTitleField::setEditable(bool editable) {
+ this->editable = editable;
+ if (this->editable) {
+ ui->lineEditTITLE->show();
+ ui->labelTITLE->hide();
+ } else {
+ ui->lineEditTITLE->hide();
+ ui->labelTITLE->show();
+ }
+}
+
+bool QtVCardTitleField::isEmpty() const {
+ return ui->lineEditTITLE->text().isEmpty();
+}
+
+void QtVCardTitleField::setTitle(const QString title) {
+ ui->lineEditTITLE->setText(title);
+}
+
+QString QtVCardTitleField::getTitle() const {
+ return ui->lineEditTITLE->text();
+}
+
+void QtVCardTitleField::onTextChanged(const QString& text) {
+ ui->labelTITLE->setText(text);
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardTitleField.h b/Swift/QtUI/QtVCardWidget/QtVCardTitleField.h
new file mode 100644
index 0000000..1de56e7
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardTitleField.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QWidget>
+
+#include "QtVCardFieldInfo.h"
+
+namespace Swift {
+
+ namespace Ui {
+ class QtVCardTitleField;
+ }
+
+ class QtVCardTitleField : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+ Q_PROPERTY(bool empty READ isEmpty)
+
+ public :
+ class FieldInfo : public QtVCardFieldInfo {
+ public:
+ virtual ~FieldInfo() {
+ }
+ virtual QString getMenuName() const {
+ return tr("Title");
+ }
+ virtual int getAllowedInstances() const {
+ return UNLIMITED_INSTANCES;
+ }
+ virtual QWidget* createFieldInstance(QWidget* parent, bool editable) const {
+ return new QtVCardTitleField(parent, editable);
+ }
+ virtual bool testInstance(QWidget* widget) const {
+ return dynamic_cast<QtVCardTitleField*>(widget) != 0;
+ }
+ };
+
+ public:
+ explicit QtVCardTitleField(QWidget* parent = 0, bool editable = false);
+ ~QtVCardTitleField();
+
+ bool isEditable() const;
+ void setEditable(bool);
+
+ bool isEmpty() const;
+
+ void setTitle(const QString title);
+ QString getTitle() const;
+
+ private slots:
+ void onTextChanged(const QString&);
+
+ private:
+ Ui::QtVCardTitleField* ui;
+ bool editable;
+ };
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardTitleField.ui b/Swift/QtUI/QtVCardWidget/QtVCardTitleField.ui
new file mode 100644
index 0000000..e5c9013
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardTitleField.ui
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Swift::QtVCardTitleField</class>
+ <widget class="QWidget" name="Swift::QtVCardTitleField">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>517</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="labelTITLE">
+ <property name="toolTip">
+ <string>Title</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Swift::QtResizableLineEdit" name="lineEditTITLE">
+ <property name="toolTip">
+ <string>Title</string>
+ </property>
+ <property name="placeholderText">
+ <string>Title</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Swift::QtResizableLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>QtResizableLineEdit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardURLField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardURLField.cpp
new file mode 100644
index 0000000..028d729
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardURLField.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "QtVCardURLField.h"
+#include "ui_QtVCardURLField.h"
+
+#include <QUrl>
+
+namespace Swift {
+
+QtVCardURLField::QtVCardURLField(QWidget* parent, bool editable) :
+ QWidget(parent),
+ ui(new Ui::QtVCardURLField) {
+ ui->setupUi(this);
+ connect(ui->lineEditURL, SIGNAL(textChanged(QString)), SLOT(onTextChanged(QString)));
+ setEditable(editable);
+}
+
+QtVCardURLField::~QtVCardURLField() {
+ delete ui;
+}
+
+bool QtVCardURLField::isEditable() const {
+ return editable;
+}
+
+void QtVCardURLField::setEditable(bool editable) {
+ this->editable = editable;
+ if (this->editable) {
+ ui->lineEditURL->show();
+ ui->labelURL->hide();
+ } else {
+ ui->lineEditURL->hide();
+ ui->labelURL->show();
+ }
+}
+
+bool QtVCardURLField::isEmpty() const {
+ return ui->lineEditURL->text().isEmpty();
+}
+
+void QtVCardURLField::setURL(const QString url) {
+ ui->lineEditURL->setText(url);
+}
+
+QString QtVCardURLField::getURL() const {
+ return ui->lineEditURL->text();
+}
+
+void QtVCardURLField::onTextChanged(const QString& text) {
+ if (text.isEmpty()) {
+ ui->labelURL->setText("");
+ } else {
+ if (QUrl(text).isValid()) {
+ ui->labelURL->setText(QString("<a href=\"%1\">%1</a>").arg(text));
+ } else {
+ ui->labelURL->setText(text);
+ }
+ }
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardURLField.h b/Swift/QtUI/QtVCardWidget/QtVCardURLField.h
new file mode 100644
index 0000000..cb73345
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardURLField.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <QWidget>
+
+#include "QtVCardFieldInfo.h"
+
+namespace Swift {
+
+ namespace Ui {
+ class QtVCardURLField;
+ }
+
+ class QtVCardURLField : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+ Q_PROPERTY(bool empty READ isEmpty)
+
+ public :
+ class FieldInfo : public QtVCardFieldInfo {
+ public:
+ virtual ~FieldInfo() {
+ }
+ virtual QString getMenuName() const {
+ return tr("URL");
+ }
+ virtual int getAllowedInstances() const {
+ return UNLIMITED_INSTANCES;
+ }
+ virtual QWidget* createFieldInstance(QWidget* parent, bool editable) const {
+ return new QtVCardURLField(parent, editable);
+ }
+ virtual bool testInstance(QWidget* widget) const {
+ return dynamic_cast<QtVCardURLField*>(widget) != 0;
+ }
+ };
+
+ public:
+ explicit QtVCardURLField(QWidget* parent = 0, bool editable = false);
+ ~QtVCardURLField();
+
+ bool isEditable() const;
+ void setEditable(bool);
+
+ bool isEmpty() const;
+
+ void setURL(const QString url);
+ QString getURL() const;
+
+ private slots:
+ void onTextChanged(const QString&);
+
+ private:
+ Ui::QtVCardURLField* ui;
+ bool editable;
+ };
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardURLField.ui b/Swift/QtUI/QtVCardWidget/QtVCardURLField.ui
new file mode 100644
index 0000000..984d0b0
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardURLField.ui
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Swift::QtVCardURLField</class>
+ <widget class="QWidget" name="Swift::QtVCardURLField">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>517</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="labelURL">
+ <property name="toolTip">
+ <string>URL</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Swift::QtResizableLineEdit" name="lineEditURL">
+ <property name="toolTip">
+ <string>URL</string>
+ </property>
+ <property name="placeholderText">
+ <string>URL</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Swift::QtResizableLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>QtResizableLineEdit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardWidget.cpp b/Swift/QtUI/QtVCardWidget/QtVCardWidget.cpp
new file mode 100644
index 0000000..ac4fca5
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardWidget.cpp
@@ -0,0 +1,429 @@
+/*
+ * 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 "QtVCardEMailField.h"
+#include "QtVCardJIDField.h"
+#include "QtVCardOrganisationField.h"
+#include "QtVCardRoleField.h"
+#include "QtVCardTelephoneField.h"
+#include "QtVCardTitleField.h"
+#include "QtVCardURLField.h"
+
+#include "QtSwiftUtil.h"
+
+#include <boost/algorithm/string.hpp>
+
+#include <Swiften/Base/Log.h>
+
+namespace Swift {
+
+QtVCardWidget::QtVCardWidget(QWidget* parent) :
+ QWidget(parent),
+ ui(new ::Ui::QtVCardWidget) {
+ ui->setupUi(this);
+
+ menu = new QMenu(this);
+
+ menu->addMenu(ui->photoAndName->getAddFieldMenu());
+ ui->toolButton->setMenu(menu);
+
+ addFieldType(menu, boost::make_shared<QtVCardAddressField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardEMailField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardJIDField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardBirthdayField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardTelephoneField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardRoleField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardTitleField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardOrganisationField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardURLField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardDescriptionField::FieldInfo>());
+ addFieldType(menu, boost::make_shared<QtVCardAddressLabelField::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));
+ //ui->photoAndName->setStyleSheet(editable ? "" : "background: transparent;");
+
+ for(int n = 0; n < ui->cardFields->count(); n++) {
+ QWidget* widget = ui->cardFields->itemAt(n)->widget();
+ if (!widget) continue;
+ if (widget->property("editable").isValid()) {
+ widget->setProperty("editable", QVariant(editable));
+ //widget->setStyleSheet(editable ? "" : "background: transparent;");
+ }
+ }
+ 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()) {
+ QtVCardEMailField* emailField = new QtVCardEMailField(this);
+ emailField->setAddress(P2QSTRING(address.address));
+ emailField->setType(address.isX400 ? QtVCardEMailField::X_400 : QtVCardEMailField::Internet);
+ emailField->setWork(address.isWork);
+ emailField->setHome(address.isHome);
+ emailField->setPreferred(address.isPreferred);
+ ui->cardFields->insertWidget(ui->cardFields->count(), emailField);
+ }
+
+ if (!vcard->getBirthday().is_not_a_date_time()) {
+ QtVCardBirthdayField* bdayField = new QtVCardBirthdayField(this);
+ bdayField->setBirthday(B2QDATE(vcard->getBirthday()).date());
+ ui->cardFields->insertWidget(ui->cardFields->count(), bdayField);
+ }
+
+ foreach (const JID& jid, vcard->getJIDs()) {
+ QtVCardJIDField* jidField = new QtVCardJIDField(this);
+ jidField->setJID(P2QSTRING(jid.toString()));
+ ui->cardFields->insertWidget(ui->cardFields->count(), jidField);
+ }
+
+ foreach (const std::string& url, vcard->getURLs()) {
+ QtVCardURLField* urlField = new QtVCardURLField(this);
+ urlField->setURL(P2QSTRING(url));
+ ui->cardFields->insertWidget(ui->cardFields->count(), urlField);
+ }
+
+ foreach (const VCard::Telephone& telephone, vcard->getTelephones()) {
+ QtVCardTelephoneField* telField = new QtVCardTelephoneField(this);
+ telField->setNumber(P2QSTRING(telephone.number));
+ telField->setHome(telephone.isHome);
+ telField->setWork(telephone.isWork);
+ telField->setVoice(telephone.isVoice);
+ telField->setFax(telephone.isFax);
+ telField->setPager(telephone.isPager);
+ telField->setMSG(telephone.isMSG);
+ telField->setCell(telephone.isCell);
+ telField->setVideo(telephone.isVideo);
+ telField->setBBS(telephone.isBBS);
+ telField->setModem(telephone.isModem);
+ telField->setISDN(telephone.isISDN);
+ telField->setPCS(telephone.isPCS);
+ telField->setPreferred(telephone.isPreferred);
+ ui->cardFields->insertWidget(ui->cardFields->count(), telField);
+ }
+
+ if (!vcard->getDescription().empty()) {
+ QtVCardDescriptionField* descriptionField = new QtVCardDescriptionField(this);
+ descriptionField->setDescription(P2QSTRING(vcard->getDescription()));
+ ui->cardFields->insertWidget(ui->cardFields->count(), descriptionField);
+ }
+
+ foreach (const std::string& role, vcard->getRoles()) {
+ QtVCardRoleField* roleField = new QtVCardRoleField(this);
+ roleField->setRole(P2QSTRING(role));
+ ui->cardFields->insertWidget(ui->cardFields->count(), roleField);
+ }
+
+ foreach (const std::string& title, vcard->getTitles()) {
+ QtVCardTitleField* titleField = new QtVCardTitleField(this);
+ titleField->setTitle(P2QSTRING(title));
+ ui->cardFields->insertWidget(ui->cardFields->count(), titleField);
+ }
+
+ foreach (const VCard::Organization organisation, vcard->getOrganizations()) {
+ QtVCardOrganisationField* organisationField = new QtVCardOrganisationField(this);
+ organisationField->setName(P2QSTRING(organisation.name));
+
+ QList<QString> units;
+ foreach(const std::string& unit, organisation.units) {
+ units.push_back(P2QSTRING(unit));
+ }
+ organisationField->setUnits(units);
+ ui->cardFields->insertWidget(ui->cardFields->count(), organisationField);
+ }
+
+ foreach (const VCard::Address& address, vcard->getAddresses()) {
+ QtVCardAddressField* addressField = new QtVCardAddressField(this);
+ addressField->setHome(address.isHome);
+ addressField->setWork(address.isWork);
+ addressField->setPostal(address.isPostal);
+ addressField->setParcel(address.isParcel);
+ addressField->setDeliveryType(address.deliveryType == VCard::InternationalDelivery ? QtVCardAddressField::InternationalDelivery : QtVCardAddressField::DomesticDelivery);
+ addressField->setPreferred(address.isPreferred);
+
+ addressField->setPOBox(P2QSTRING(address.POBox));
+ addressField->setAddressExtension(P2QSTRING(address.addressExtension));
+ addressField->setStreet(P2QSTRING(address.street));
+ addressField->setLocality(P2QSTRING(address.locality));
+ addressField->setRegion(P2QSTRING(address.region));
+ addressField->setPostalCode(P2QSTRING(address.postalCode));
+ addressField->setCountry(P2QSTRING(address.country));
+
+ ui->cardFields->insertWidget(ui->cardFields->count(), addressField);
+ }
+
+ foreach (const VCard::AddressLabel& addressLabel, vcard->getAddressLabels()) {
+ QtVCardAddressLabelField* addressLabelField = new QtVCardAddressLabelField(this);
+ addressLabelField->setHome(addressLabel.isHome);
+ addressLabelField->setWork(addressLabel.isWork);
+ addressLabelField->setPostal(addressLabel.isPostal);
+ addressLabelField->setParcel(addressLabel.isParcel);
+ addressLabelField->setDeliveryType(addressLabel.deliveryType == VCard::InternationalDelivery ? QtVCardAddressLabelField::InternationalDelivery : QtVCardAddressLabelField::DomesticDelivery);
+ addressLabelField->setPreferred(addressLabel.isPreferred);
+
+ std::string joinedLines = boost::algorithm::join(addressLabel.lines, "\n");
+ addressLabelField->setLines(P2QSTRING(joinedLines));
+
+ ui->cardFields->insertWidget(ui->cardFields->count(), addressLabelField);
+ }
+
+ 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;
+ for(int n = 0; n < ui->cardFields->count(); n++) {
+ QWidget* widget = ui->cardFields->itemAt(n)->widget();
+
+ QtVCardEMailField* emailField;
+ if ((emailField = dynamic_cast<QtVCardEMailField*>(widget))) {
+ VCard::EMailAddress address;
+ address.address = Q2PSTRING(emailField->getAddress());
+ address.isInternet = emailField->getType() == QtVCardEMailField::Internet;
+ address.isX400 = emailField->getType() == QtVCardEMailField::X_400;
+ address.isHome = emailField->getHome();
+ address.isWork = emailField->getWork();
+ address.isPreferred = emailField->getPreferred();
+ vcard->addEMailAddress(address);
+ continue;
+ }
+
+ QtVCardJIDField* jidField;
+ if ((jidField = dynamic_cast<QtVCardJIDField*>(widget))) {
+ JID jid(Q2PSTRING(jidField->getJID()));
+ if (jid.isValid()) {
+ vcard->addJID(jid);
+ }
+ continue;
+ }
+
+ QtVCardURLField* urlField;
+ if ((urlField = dynamic_cast<QtVCardURLField*>(widget))) {
+ vcard->addURL(Q2PSTRING(urlField->getURL()));
+ continue;
+ }
+
+ QtVCardTelephoneField* telephoneField;
+ if ((telephoneField = dynamic_cast<QtVCardTelephoneField*>(widget))) {
+ VCard::Telephone telephone;
+ telephone.number = Q2PSTRING(telephoneField->getNumber());
+ telephone.isHome = telephoneField->getHome();
+ telephone.isWork = telephoneField->getWork();
+ telephone.isVoice = telephoneField->getVoice();
+ telephone.isFax = telephoneField->getFax();
+ telephone.isPager = telephoneField->getPager();
+ telephone.isMSG = telephoneField->getMSG();
+ telephone.isCell = telephoneField->getCell();
+ telephone.isVideo = telephoneField->getVideo();
+ telephone.isBBS = telephoneField->getBBS();
+ telephone.isModem = telephoneField->getModem();
+ telephone.isISDN = telephoneField->getISDN();
+ telephone.isPCS = telephoneField->getPCS();
+ telephone.isPreferred = telephoneField->getPreferred();
+ vcard->addTelephone(telephone);
+ continue;
+ }
+
+ if (dynamic_cast<QtVCardBirthdayField*>(widget)) {
+ bdayField = dynamic_cast<QtVCardBirthdayField*>(widget);
+ continue;
+ }
+
+ if (dynamic_cast<QtVCardDescriptionField*>(widget)) {
+ descriptionField = dynamic_cast<QtVCardDescriptionField*>(widget);
+ continue;
+ }
+
+ QtVCardRoleField* roleField;
+ if ((roleField = dynamic_cast<QtVCardRoleField*>(widget))) {
+ vcard->addRole(Q2PSTRING(roleField->getRole()));
+ continue;
+ }
+
+ QtVCardTitleField* titleField;
+ if ((titleField = dynamic_cast<QtVCardTitleField*>(widget))) {
+ vcard->addTitle(Q2PSTRING(titleField->getTitle()));
+ continue;
+ }
+
+ QtVCardOrganisationField* organisationField;
+ if ((organisationField = dynamic_cast<QtVCardOrganisationField*>(widget))) {
+ VCard::Organization organisation;
+ organisation.name = Q2PSTRING(organisationField->getName());
+ foreach(const QString &unit, organisationField->getUnits()) {
+ organisation.units.push_back(Q2PSTRING(unit));
+ }
+ vcard->addOrganization(organisation);
+ continue;
+ }
+
+ QtVCardAddressField* addressField;
+ if ((addressField = dynamic_cast<QtVCardAddressField*>(widget))) {
+ VCard::Address address;
+ address.isHome = addressField->getHome();
+ address.isWork = addressField->getWork();
+ address.isPostal = addressField->getPostal();
+ address.isParcel = addressField->getParcel();
+ address.deliveryType = addressField->getDeliveryType() == QtVCardAddressField::InternationalDelivery ? VCard::InternationalDelivery : VCard::DomesticDelivery;
+ address.isPreferred = addressField->getPreferred();
+
+ address.POBox = Q2PSTRING(addressField->getPOBox());
+ address.addressExtension = Q2PSTRING(addressField->getAddressExtension());
+ address.street = Q2PSTRING(addressField->getStreet());
+ address.locality = Q2PSTRING(addressField->getLocality());
+ address.region = Q2PSTRING(addressField->getRegion());
+ address.postalCode = Q2PSTRING(addressField->getPostalCode());
+ address.country = Q2PSTRING(addressField->getCountry());
+ vcard->addAddress(address);
+ continue;
+ }
+
+ QtVCardAddressLabelField* addressLabelField;
+ if ((addressLabelField = dynamic_cast<QtVCardAddressLabelField*>(widget))) {
+ VCard::AddressLabel addressLabel;
+ addressLabel.isHome = addressLabelField->getHome();
+ addressLabel.isWork = addressLabelField->getWork();
+ addressLabel.isPostal = addressLabelField->getPostal();
+ addressLabel.isParcel = addressLabelField->getParcel();
+ addressLabel.deliveryType = addressLabelField->getDeliveryType() == QtVCardAddressLabelField::InternationalDelivery ? VCard::InternationalDelivery : VCard::DomesticDelivery;
+ addressLabel.isPreferred = addressLabelField->getPreferred();
+
+ std::string lines = Q2PSTRING(addressLabelField->getLines());
+ boost::split(addressLabel.lines,lines, boost::is_any_of("\n"));
+
+ vcard->addAddressLabel(addressLabel);
+ continue;
+ }
+ }
+
+ if (bdayField) {
+ vcard->setBirthday(boost::posix_time::from_time_t(QDateTime(bdayField->getBirthday()).toTime_t()));
+ } else {
+ vcard->setBirthday(boost::posix_time::ptime());
+ }
+
+ if (descriptionField) {
+ vcard->setDescription(Q2PSTRING(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];
+ ui->cardFields->insertWidget(ui->cardFields->count(), fieldInfo->createFieldInstance(this, true));
+ }
+}
+
+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 QtVCardWidget::clearFields() {
+ assert(ui->cardFields->count() >= 0);
+ while(ui->cardFields->count() > 0) {
+ QLayoutItem* child;
+ if ((child = ui->cardFields->takeAt(0)) != 0) {
+ delete child->widget();
+ delete child;
+ }
+ }
+}
+
+void QtVCardWidget::clearEmptyFields() {
+ for (int n = 0; n < ui->cardFields->count(); n++) {
+ QWidget* field = ui->cardFields->itemAt(n)->widget();
+ if (field->property("empty").isValid() && field->property("empty").toBool()) {
+ ui->cardFields->removeWidget(field);
+ delete field;
+ n--;
+ }
+ }
+}
+
+}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardWidget.h b/Swift/QtUI/QtVCardWidget/QtVCardWidget.h
new file mode 100644
index 0000000..74850fb
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardWidget.h
@@ -0,0 +1,58 @@
+/*
+ * 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 <boost/smart_ptr/make_shared.hpp>
+
+#include "QtVCardFieldInfo.h"
+#include "QtVCardPhotoAndNameFields.h"
+
+#include <Swiften/Elements/VCard.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();
+
+ private:
+ void addFieldType(QMenu*, boost::shared_ptr<QtVCardFieldInfo>);
+ int fieldTypeInstances(boost::shared_ptr<QtVCardFieldInfo>);
+ void clearFields();
+ void clearEmptyFields();
+
+ private:
+ VCard::ref vcard;
+ Ui::QtVCardWidget* ui;
+ bool editable;
+ QMenu* menu;
+ 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..d005f01
--- /dev/null
+++ b/Swift/QtUI/QtVCardWidget/QtVCardWidget.ui
@@ -0,0 +1,143 @@
+<?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="QVBoxLayout" name="cardFields">
+ <property name="spacing">
+ <number>2</number>
+ </property>
+ <property name="margin">
+ <number>5</number>
+ </property>
+ </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>
diff --git a/Swift/QtUI/Roster/QtOccupantListWidget.cpp b/Swift/QtUI/Roster/QtOccupantListWidget.cpp
index 5d26c46..12dc1e4 100644
--- a/Swift/QtUI/Roster/QtOccupantListWidget.cpp
+++ b/Swift/QtUI/Roster/QtOccupantListWidget.cpp
@@ -58,6 +58,7 @@ void QtOccupantListWidget::contextMenuEvent(QContextMenuEvent* event) {
case ChatWindow::MakeParticipant: text = tr("Make participant"); break;
case ChatWindow::MakeVisitor: text = tr("Remove voice"); break;
case ChatWindow::AddContact: text = tr("Add to contacts"); break;
+ case ChatWindow::ShowProfile: text = tr("Show profile"); break;
}
QAction* action = contextMenu.addAction(text);
actions[action] = availableAction;
diff --git a/Swift/QtUI/Roster/QtRosterWidget.cpp b/Swift/QtUI/Roster/QtRosterWidget.cpp
index 1cf073b..b783ff6 100644
--- a/Swift/QtUI/Roster/QtRosterWidget.cpp
+++ b/Swift/QtUI/Roster/QtRosterWidget.cpp
@@ -16,6 +16,7 @@
#include "Swift/Controllers/UIEvents/RenameGroupUIEvent.h"
#include "Swift/Controllers/UIEvents/SendFileUIEvent.h"
#include "Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h"
+#include "Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h"
#include "QtContactEditWindow.h"
#include "Swift/Controllers/Roster/ContactRosterItem.h"
#include "Swift/Controllers/Roster/GroupRosterItem.h"
@@ -57,6 +58,7 @@ void QtRosterWidget::contextMenuEvent(QContextMenuEvent* event) {
if (ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item)) {
QAction* editContact = contextMenu.addAction(tr("Edit…"));
QAction* removeContact = contextMenu.addAction(tr("Remove"));
+ QAction* showProfileForContact = contextMenu.addAction(tr("Show Profile"));
#ifdef SWIFT_EXPERIMENTAL_FT
QAction* sendFile = NULL;
if (contact->supportsFeature(ContactRosterItem::FileTransferFeature)) {
@@ -78,6 +80,9 @@ void QtRosterWidget::contextMenuEvent(QContextMenuEvent* event) {
eventStream_->send(boost::make_shared<RemoveRosterItemUIEvent>(contact->getJID()));
}
}
+ else if (result == showProfileForContact) {
+ eventStream_->send(boost::make_shared<ShowProfileForRosterItemUIEvent>(contact->getJID()));
+ }
#ifdef SWIFT_EXPERIMENTAL_FT
else if (sendFile && result == sendFile) {
QString fileName = QFileDialog::getOpenFileName(this, tr("Send File"), "", tr("All Files (*);;"));
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index 70a1038..35eda5b 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -164,6 +164,40 @@ sources = [
"QtUISettingConstants.cpp"
]
+# QtVCardWidget
+sources.extend([
+ "QtVCardWidget/QtResizableLineEdit.cpp",
+ "QtVCardWidget/QtVCardAddressField.cpp",
+ "QtVCardWidget/QtVCardAddressLabelField.cpp",
+ "QtVCardWidget/QtVCardBirthdayField.cpp",
+ "QtVCardWidget/QtVCardDescriptionField.cpp",
+ "QtVCardWidget/QtVCardEMailField.cpp",
+ "QtVCardWidget/QtVCardJIDField.cpp",
+ "QtVCardWidget/QtVCardOrganisationField.cpp",
+ "QtVCardWidget/QtVCardPhotoAndNameFields.cpp",
+ "QtVCardWidget/QtVCardRoleField.cpp",
+ "QtVCardWidget/QtVCardTelephoneField.cpp",
+ "QtVCardWidget/QtVCardTitleField.cpp",
+ "QtVCardWidget/QtVCardURLField.cpp",
+ "QtVCardWidget/QtVCardWidget.cpp"
+])
+
+myenv.Uic4("QtVCardWidget/QtVCardAddressField.ui")
+myenv.Uic4("QtVCardWidget/QtVCardAddressLabelField.ui")
+myenv.Uic4("QtVCardWidget/QtVCardBirthdayField.ui")
+myenv.Uic4("QtVCardWidget/QtVCardDescriptionField.ui")
+myenv.Uic4("QtVCardWidget/QtVCardEMailField.ui")
+myenv.Uic4("QtVCardWidget/QtVCardJIDField.ui")
+myenv.Uic4("QtVCardWidget/QtVCardOrganisationField.ui")
+myenv.Uic4("QtVCardWidget/QtVCardPhotoAndNameFields.ui")
+myenv.Uic4("QtVCardWidget/QtVCardRoleField.ui")
+myenv.Uic4("QtVCardWidget/QtVCardTelephoneField.ui")
+myenv.Uic4("QtVCardWidget/QtVCardTitleField.ui")
+myenv.Uic4("QtVCardWidget/QtVCardURLField.ui")
+myenv.Uic4("QtVCardWidget/QtVCardWidget.ui")
+myenv.Uic4("QtProfileWindow.ui")
+
+
myenv["SWIFT_VERSION"] = Version.getBuildVersion(env.Dir("#").abspath, "swift")
version_match = re.match("(\d+)\.(\d+).*", myenv["SWIFT_VERSION"])
myenv["SWIFT_VERSION_MAJOR"] = int(version_match.group(1)) if version_match else 0
diff --git a/Swiften/Elements/VCard.h b/Swiften/Elements/VCard.h
index f9822c9..41f2623 100644
--- a/Swiften/Elements/VCard.h
+++ b/Swiften/Elements/VCard.h
@@ -7,8 +7,10 @@
#pragma once
#include <boost/shared_ptr.hpp>
+#include <boost/date_time/posix_time/ptime.hpp>
#include <string>
+#include <Swiften/JID/JID.h>
#include <Swiften/Base/ByteArray.h>
#include <Swiften/Elements/Payload.h>
@@ -29,6 +31,71 @@ namespace Swift {
std::string address;
};
+ struct Telephone {
+ Telephone() : isHome(false), isWork(false), isVoice(false), isFax(false), isPager(false), isMSG(false), isCell(false),
+ isVideo(false), isBBS(false), isModem(false), isISDN(false), isPCS(false), isPreferred(false) {
+ }
+
+ bool isHome;
+ bool isWork;
+ bool isVoice;
+ bool isFax;
+ bool isPager;
+ bool isMSG;
+ bool isCell;
+ bool isVideo;
+ bool isBBS;
+ bool isModem;
+ bool isISDN;
+ bool isPCS;
+ bool isPreferred;
+ std::string number;
+ };
+
+ enum DeliveryType {
+ DomesticDelivery,
+ InternationalDelivery,
+ None
+ };
+
+ struct Address {
+ Address() : isHome(false), isWork(false), isPostal(false), isParcel(false), deliveryType(None), isPreferred(false) {
+ }
+
+ bool isHome;
+ bool isWork;
+ bool isPostal;
+ bool isParcel;
+ DeliveryType deliveryType;
+ bool isPreferred;
+
+ std::string POBox;
+ std::string addressExtension;
+ std::string street;
+ std::string locality;
+ std::string region;
+ std::string postalCode;
+ std::string country;
+ };
+
+ struct AddressLabel {
+ AddressLabel() : isHome(false), isWork(false), isPostal(false), isParcel(false), deliveryType(None), isPreferred(false) {
+ }
+
+ bool isHome;
+ bool isWork;
+ bool isPostal;
+ bool isParcel;
+ DeliveryType deliveryType;
+ bool isPreferred;
+ std::vector<std::string> lines;
+ };
+
+ struct Organization {
+ std::string name;
+ std::vector<std::string> units;
+ };
+
VCard() {}
void setVersion(const std::string& version) { version_ = version; }
@@ -78,8 +145,124 @@ namespace Swift {
emailAddresses_.push_back(email);
}
+ void clearEMailAddresses() {
+ emailAddresses_.clear();
+ }
+
EMailAddress getPreferredEMailAddress() const;
+ void setBirthday(const boost::posix_time::ptime& birthday) {
+ birthday_ = birthday;
+ }
+
+ const boost::posix_time::ptime& getBirthday() const {
+ return birthday_;
+ }
+
+ const std::vector<Telephone>& getTelephones() const {
+ return telephones_;
+ }
+
+ void addTelephone(const Telephone& phone) {
+ telephones_.push_back(phone);
+ }
+
+ void clearTelephones() {
+ telephones_.clear();
+ }
+
+ const std::vector<Address>& getAddresses() const {
+ return addresses_;
+ }
+
+ void addAddress(const Address& address) {
+ addresses_.push_back(address);
+ }
+
+ void clearAddresses() {
+ addresses_.clear();
+ }
+
+ const std::vector<AddressLabel>& getAddressLabels() const {
+ return addressLabels_;
+ }
+
+ void addAddressLabel(const AddressLabel& addressLabel) {
+ addressLabels_.push_back(addressLabel);
+ }
+
+ void clearAddressLabels() {
+ addressLabels_.clear();
+ }
+
+ const std::vector<JID>& getJIDs() const {
+ return jids_;
+ }
+
+ void addJID(const JID& jid) {
+ jids_.push_back(jid);
+ }
+
+ void clearJIDs() {
+ jids_.clear();
+ }
+
+ const std::string& getDescription() const {
+ return description_;
+ }
+
+ void setDescription(const std::string& description) {
+ this->description_ = description;
+ }
+
+ const std::vector<Organization>& getOrganizations() const {
+ return organizations_;
+ }
+
+ void addOrganization(const Organization& organization) {
+ organizations_.push_back(organization);
+ }
+
+ void clearOrganizations() {
+ organizations_.clear();
+ }
+
+ const std::vector<std::string>& getTitles() const {
+ return titles_;
+ }
+
+ void addTitle(const std::string& title) {
+ titles_.push_back(title);
+ }
+
+ void clearTitles() {
+ titles_.clear();
+ }
+
+ const std::vector<std::string>& getRoles() const {
+ return roles_;
+ }
+
+ void addRole(const std::string& role) {
+ roles_.push_back(role);
+ }
+
+ void clearRoles() {
+ roles_.clear();
+ }
+
+ const std::vector<std::string>& getURLs() const {
+ return urls_;
+ }
+
+ void addURL(const std::string& url) {
+ urls_.push_back(url);
+ }
+
+ void clearURLs() {
+ urls_.clear();
+ }
+
private:
std::string version_;
std::string fullName_;
@@ -92,7 +275,17 @@ namespace Swift {
ByteArray photo_;
std::string photoType_;
std::string nick_;
+ boost::posix_time::ptime birthday_;
std::string unknownContent_;
std::vector<EMailAddress> emailAddresses_;
+ std::vector<Telephone> telephones_;
+ std::vector<Address> addresses_;
+ std::vector<AddressLabel> addressLabels_;
+ std::vector<JID> jids_;
+ std::string description_;
+ std::vector<Organization> organizations_;
+ std::vector<std::string> titles_;
+ std::vector<std::string> roles_;
+ std::vector<std::string> urls_;
};
}
diff --git a/Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp
index f1e6635..eda2547 100644
--- a/Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp
+++ b/Swiften/Parser/PayloadParsers/UnitTest/VCardParserTest.cpp
@@ -7,6 +7,8 @@
#include <Swiften/Base/ByteArray.h>
#include <QA/Checker/IO.h>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
@@ -48,8 +50,36 @@ class VCardParserTest : public CppUnit::TestFixture {
"<WORK/>"
"<X400/>"
"</EMAIL>"
+ "<TEL>"
+ "<NUMBER>555-6273</NUMBER>"
+ "<HOME/>"
+ "<VOICE/>"
+ "</TEL>"
+ "<ADR>"
+ "<LOCALITY>Any Town</LOCALITY>"
+ "<STREET>Fake Street 123</STREET>"
+ "<PCODE>12345</PCODE>"
+ "<CTRY>USA</CTRY>"
+ "<HOME/>"
+ "</ADR>"
+ "<LABEL>"
+ "<LINE>Fake Street 123</LINE>"
+ "<LINE>12345 Any Town</LINE>"
+ "<LINE>USA</LINE>"
+ "<HOME/>"
+ "</LABEL>"
"<NICKNAME>DreamGirl</NICKNAME>"
- "<BDAY>1234</BDAY>"
+ "<BDAY>1865-05-04</BDAY>"
+ "<JID>alice@teaparty.lit</JID>"
+ "<JID>alice@wonderland.lit</JID>"
+ "<DESC>I once fell down a rabbit hole.</DESC>"
+ "<ORG>"
+ "<ORGNAME>Alice In Wonderland Inc.</ORGNAME>"
+ "</ORG>"
+ "<TITLE>Some Title</TITLE>"
+ "<ROLE>Main Character</ROLE>"
+ "<URL>http://wonderland.lit/~alice</URL>"
+ "<URL>http://teaparty.lit/~alice2</URL>"
"<MAILER>mutt</MAILER>"
"</vCard>"));
@@ -62,7 +92,7 @@ class VCardParserTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(std::string("Mrs"), payload->getPrefix());
CPPUNIT_ASSERT_EQUAL(std::string("PhD"), payload->getSuffix());
CPPUNIT_ASSERT_EQUAL(std::string("DreamGirl"), payload->getNickname());
- CPPUNIT_ASSERT_EQUAL(std::string("<BDAY xmlns=\"vcard-temp\">1234</BDAY><MAILER xmlns=\"vcard-temp\">mutt</MAILER>"), payload->getUnknownContent());
+ CPPUNIT_ASSERT_EQUAL(boost::posix_time::ptime(boost::gregorian::date(1865, 5, 4)), payload->getBirthday());
CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(payload->getEMailAddresses().size()));
CPPUNIT_ASSERT_EQUAL(std::string("alice@wonderland.lit"), payload->getEMailAddresses()[0].address);
CPPUNIT_ASSERT(payload->getEMailAddresses()[0].isHome);
@@ -76,6 +106,45 @@ class VCardParserTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT(!payload->getEMailAddresses()[1].isPreferred);
CPPUNIT_ASSERT(payload->getEMailAddresses()[1].isWork);
CPPUNIT_ASSERT(payload->getEMailAddresses()[1].isX400);
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(payload->getTelephones().size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("555-6273"), payload->getTelephones()[0].number);
+ CPPUNIT_ASSERT(payload->getTelephones()[0].isHome);
+ CPPUNIT_ASSERT(payload->getTelephones()[0].isVoice);
+ CPPUNIT_ASSERT(!payload->getTelephones()[0].isPreferred);
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(payload->getAddresses().size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("Any Town"), payload->getAddresses()[0].locality);
+ CPPUNIT_ASSERT_EQUAL(std::string("Fake Street 123"), payload->getAddresses()[0].street);
+ CPPUNIT_ASSERT_EQUAL(std::string("12345"), payload->getAddresses()[0].postalCode);
+ CPPUNIT_ASSERT_EQUAL(std::string("USA"), payload->getAddresses()[0].country);
+ CPPUNIT_ASSERT(payload->getAddresses()[0].isHome);
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(payload->getAddressLabels().size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("Fake Street 123"), payload->getAddressLabels()[0].lines[0]);
+ CPPUNIT_ASSERT_EQUAL(std::string("12345 Any Town"), payload->getAddressLabels()[0].lines[1]);
+ CPPUNIT_ASSERT_EQUAL(std::string("USA"), payload->getAddressLabels()[0].lines[2]);
+ CPPUNIT_ASSERT(payload->getAddressLabels()[0].isHome);
+
+ CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(payload->getJIDs().size()));
+ CPPUNIT_ASSERT_EQUAL(JID("alice@teaparty.lit"), payload->getJIDs()[0]);
+ CPPUNIT_ASSERT_EQUAL(JID("alice@wonderland.lit"), payload->getJIDs()[1]);
+
+ CPPUNIT_ASSERT_EQUAL(std::string("I once fell down a rabbit hole."), payload->getDescription());
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(payload->getOrganizations().size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("Alice In Wonderland Inc."), payload->getOrganizations()[0].name);
+ CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(payload->getOrganizations()[0].units.size()));
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(payload->getTitles().size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("Some Title"), payload->getTitles()[0]);
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(payload->getRoles().size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("Main Character"), payload->getRoles()[0]);
+ CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(payload->getURLs().size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("http://wonderland.lit/~alice"), payload->getURLs()[0]);
+ CPPUNIT_ASSERT_EQUAL(std::string("http://teaparty.lit/~alice2"), payload->getURLs()[1]);
+
+ CPPUNIT_ASSERT_EQUAL(std::string("<MAILER xmlns=\"vcard-temp\">mutt</MAILER>"), payload->getUnknownContent());
}
void testParse_Photo() {
diff --git a/Swiften/Parser/PayloadParsers/VCardParser.cpp b/Swiften/Parser/PayloadParsers/VCardParser.cpp
index 553d26a..9640787 100644
--- a/Swiften/Parser/PayloadParsers/VCardParser.cpp
+++ b/Swiften/Parser/PayloadParsers/VCardParser.cpp
@@ -6,6 +6,7 @@
#include <Swiften/Parser/PayloadParsers/VCardParser.h>
#include <Swiften/Base/foreach.h>
+#include <Swiften/Base/DateTime.h>
#include <Swiften/StringCodecs/Base64.h>
#include <Swiften/Parser/SerializingParser.h>
@@ -20,6 +21,18 @@ void VCardParser::handleStartElement(const std::string& element, const std::stri
if (elementHierarchy == "/vCard/EMAIL") {
currentEMailAddress_ = VCard::EMailAddress();
}
+ if (elementHierarchy == "/vCard/TEL") {
+ currentTelephone_ = VCard::Telephone();
+ }
+ if (elementHierarchy == "/vCard/ADR") {
+ currentAddress_ = VCard::Address();
+ }
+ if (elementHierarchy == "/vCard/LABEL") {
+ currentAddressLabel_ = VCard::AddressLabel();
+ }
+ if (elementHierarchy == "/vCard/ORG") {
+ currentOrganization_ = VCard::Organization();
+ }
if (elementStack_.size() == 2) {
assert(!unknownContentParser_);
unknownContentParser_ = new SerializingParser();
@@ -90,9 +103,160 @@ void VCardParser::handleEndElement(const std::string& element, const std::string
else if (elementHierarchy == "/vCard/EMAIL/PREF") {
currentEMailAddress_.isPreferred = true;
}
- else if (elementHierarchy == "/vCard/EMAIL") {
+ else if (elementHierarchy == "/vCard/EMAIL" && !currentEMailAddress_.address.empty()) {
getPayloadInternal()->addEMailAddress(currentEMailAddress_);
}
+ else if (elementHierarchy == "/vCard/BDAY" && !currentText_.empty()) {
+ getPayloadInternal()->setBirthday(stringToDateTime(currentText_));
+ }
+ else if (elementHierarchy == "/vCard/TEL/NUMBER") {
+ currentTelephone_.number = currentText_;
+ }
+ else if (elementHierarchy == "/vCard/TEL/HOME") {
+ currentTelephone_.isHome = true;
+ }
+ else if (elementHierarchy == "/vCard/TEL/WORK") {
+ currentTelephone_.isWork = true;
+ }
+ else if (elementHierarchy == "/vCard/TEL/VOICE") {
+ currentTelephone_.isVoice = true;
+ }
+ else if (elementHierarchy == "/vCard/TEL/FAX") {
+ currentTelephone_.isFax = true;
+ }
+ else if (elementHierarchy == "/vCard/TEL/PAGER") {
+ currentTelephone_.isPager = true;
+ }
+ else if (elementHierarchy == "/vCard/TEL/MSG") {
+ currentTelephone_.isMSG = true;
+ }
+ else if (elementHierarchy == "/vCard/TEL/CELL") {
+ currentTelephone_.isCell = true;
+ }
+ else if (elementHierarchy == "/vCard/TEL/VIDEO") {
+ currentTelephone_.isVideo = true;
+ }
+ else if (elementHierarchy == "/vCard/TEL/BBS") {
+ currentTelephone_.isBBS = true;
+ }
+ else if (elementHierarchy == "/vCard/TEL/MODEM") {
+ currentTelephone_.isModem = true;
+ }
+ else if (elementHierarchy == "/vCard/TEL/ISDN") {
+ currentTelephone_.isISDN = true;
+ }
+ else if (elementHierarchy == "/vCard/TEL/PCS") {
+ currentTelephone_.isPCS = true;
+ }
+ else if (elementHierarchy == "/vCard/TEL/PREF") {
+ currentTelephone_.isPreferred = true;
+ }
+ else if (elementHierarchy == "/vCard/TEL" && !currentTelephone_.number.empty()) {
+ getPayloadInternal()->addTelephone(currentTelephone_);
+ }
+ else if (elementHierarchy == "/vCard/ADR/HOME") {
+ currentAddress_.isHome = true;
+ }
+ else if (elementHierarchy == "/vCard/ADR/WORK") {
+ currentAddress_.isWork = true;
+ }
+ else if (elementHierarchy == "/vCard/ADR/POSTAL") {
+ currentAddress_.isPostal = true;
+ }
+ else if (elementHierarchy == "/vCard/ADR/PARCEL") {
+ currentAddress_.isParcel = true;
+ }
+ else if (elementHierarchy == "/vCard/ADR/DOM") {
+ currentAddress_.deliveryType = VCard::DomesticDelivery;
+ }
+ else if (elementHierarchy == "/vCard/ADR/INTL") {
+ currentAddress_.deliveryType = VCard::InternationalDelivery;
+ }
+ else if (elementHierarchy == "/vCard/ADR/PREF") {
+ currentAddress_.isPreferred = true;
+ }
+ else if (elementHierarchy == "/vCard/ADR/POBOX") {
+ currentAddress_.POBox = currentText_;
+ }
+ else if (elementHierarchy == "/vCard/ADR/EXTADD") {
+ currentAddress_.addressExtension = currentText_;
+ }
+ else if (elementHierarchy == "/vCard/ADR/STREET") {
+ currentAddress_.street = currentText_;
+ }
+ else if (elementHierarchy == "/vCard/ADR/LOCALITY") {
+ currentAddress_.locality = currentText_;
+ }
+ else if (elementHierarchy == "/vCard/ADR/REGION") {
+ currentAddress_.region = currentText_;
+ }
+ else if (elementHierarchy == "/vCard/ADR/PCODE") {
+ currentAddress_.postalCode = currentText_;
+ }
+ else if (elementHierarchy == "/vCard/ADR/CTRY") {
+ currentAddress_.country = currentText_;
+ }
+ else if (elementHierarchy == "/vCard/ADR") {
+ if (!currentAddress_.POBox.empty() || !currentAddress_.addressExtension.empty() ||
+ !currentAddress_.street.empty() || !currentAddress_.locality.empty() ||
+ !currentAddress_.region.empty() || !currentAddress_.region.empty() ||
+ !currentAddress_.postalCode.empty() || !currentAddress_.country.empty()) {
+ getPayloadInternal()->addAddress(currentAddress_);
+ }
+ }
+ else if (elementHierarchy == "/vCard/LABEL/HOME") {
+ currentAddressLabel_.isHome = true;
+ }
+ else if (elementHierarchy == "/vCard/LABEL/WORK") {
+ currentAddressLabel_.isWork = true;
+ }
+ else if (elementHierarchy == "/vCard/LABEL/POSTAL") {
+ currentAddressLabel_.isPostal = true;
+ }
+ else if (elementHierarchy == "/vCard/LABEL/PARCEL") {
+ currentAddressLabel_.isParcel = true;
+ }
+ else if (elementHierarchy == "/vCard/LABEL/DOM") {
+ currentAddressLabel_.deliveryType = VCard::DomesticDelivery;
+ }
+ else if (elementHierarchy == "/vCard/LABEL/INTL") {
+ currentAddressLabel_.deliveryType = VCard::InternationalDelivery;
+ }
+ else if (elementHierarchy == "/vCard/LABEL/PREF") {
+ currentAddressLabel_.isPreferred = true;
+ }
+ else if (elementHierarchy == "/vCard/LABEL/LINE") {
+ currentAddressLabel_.lines.push_back(currentText_);
+ }
+ else if (elementHierarchy == "/vCard/LABEL") {
+ getPayloadInternal()->addAddressLabel(currentAddressLabel_);
+ }
+ else if (elementHierarchy == "/vCard/JID" && !currentText_.empty()) {
+ getPayloadInternal()->addJID(JID(currentText_));
+ }
+ else if (elementHierarchy == "/vCard/DESC") {
+ getPayloadInternal()->setDescription(currentText_);
+ }
+ else if (elementHierarchy == "/vCard/ORG/ORGNAME") {
+ currentOrganization_.name = currentText_;
+ }
+ else if (elementHierarchy == "/vCard/ORG/ORGUNIT" && !currentText_.empty()) {
+ currentOrganization_.units.push_back(currentText_);
+ }
+ else if (elementHierarchy == "/vCard/ORG") {
+ if (!currentOrganization_.name.empty() || !currentOrganization_.units.empty()) {
+ getPayloadInternal()->addOrganization(currentOrganization_);
+ }
+ }
+ else if (elementHierarchy == "/vCard/TITLE" && !currentText_.empty()) {
+ getPayloadInternal()->addTitle(currentText_);
+ }
+ else if (elementHierarchy == "/vCard/ROLE" && !currentText_.empty()) {
+ getPayloadInternal()->addRole(currentText_);
+ }
+ else if (elementHierarchy == "/vCard/URL" && !currentText_.empty()) {
+ getPayloadInternal()->addURL(currentText_);
+ }
else if (elementStack_.size() == 2 && unknownContentParser_) {
getPayloadInternal()->addUnknownContent(unknownContentParser_->getResult());
}
diff --git a/Swiften/Parser/PayloadParsers/VCardParser.h b/Swiften/Parser/PayloadParsers/VCardParser.h
index b1c47a3..f10d639 100644
--- a/Swiften/Parser/PayloadParsers/VCardParser.h
+++ b/Swiften/Parser/PayloadParsers/VCardParser.h
@@ -28,6 +28,10 @@ namespace Swift {
private:
std::vector<std::string> elementStack_;
VCard::EMailAddress currentEMailAddress_;
+ VCard::Telephone currentTelephone_;
+ VCard::Address currentAddress_;
+ VCard::AddressLabel currentAddressLabel_;
+ VCard::Organization currentOrganization_;
SerializingParser* unknownContentParser_;
std::string currentText_;
};
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/VCardSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/VCardSerializerTest.cpp
index 3ac1d77..01c8e77 100644
--- a/Swiften/Serializer/PayloadSerializers/UnitTest/VCardSerializerTest.cpp
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/VCardSerializerTest.cpp
@@ -31,14 +31,15 @@ class VCardSerializerTest : public CppUnit::TestFixture
vcard->setNickname("DreamGirl");
vcard->setPhoto(createByteArray("abcdef"));
vcard->setPhotoType("image/png");
- vcard->addUnknownContent("<BDAY>1234</BDAY><MAILER>mutt</MAILER>");
+ vcard->setBirthday(boost::posix_time::ptime(boost::gregorian::date(1865, 5, 4)));
+ vcard->addUnknownContent("<MAILER>mutt</MAILER>");
- VCard::EMailAddress address1;
- address1.address = "alice@wonderland.lit";
- address1.isHome = true;
- address1.isPreferred = true;
- address1.isInternet = true;
- vcard->addEMailAddress(address1);
+ VCard::EMailAddress emailAddress1;
+ emailAddress1.address = "alice@wonderland.lit";
+ emailAddress1.isHome = true;
+ emailAddress1.isPreferred = true;
+ emailAddress1.isInternet = true;
+ vcard->addEMailAddress(emailAddress1);
VCard::EMailAddress address2;
address2.address = "alice@teaparty.lit";
@@ -46,6 +47,41 @@ class VCardSerializerTest : public CppUnit::TestFixture
address2.isX400 = true;
vcard->addEMailAddress(address2);
+ VCard::Telephone telephone1;
+ telephone1.number = "555-6273";
+ telephone1.isHome = true;
+ telephone1.isVoice = true;
+ vcard->addTelephone(telephone1);
+
+ VCard::Address address1;
+ address1.locality = "Any Town";
+ address1.street = "Fake Street 123";
+ address1.postalCode = "12345";
+ address1.country = "USA";
+ address1.isHome = true;
+ vcard->addAddress(address1);
+
+ VCard::AddressLabel label1;
+ label1.lines.push_back("Fake Street 123");
+ label1.lines.push_back("12345 Any Town");
+ label1.lines.push_back("USA");
+ label1.isHome = true;
+ vcard->addAddressLabel(label1);
+
+ vcard->addJID(JID("alice@teaparty.lit"));
+ vcard->addJID(JID("alice@wonderland.lit"));
+
+ vcard->setDescription("I once fell down a rabbit hole.");
+
+ VCard::Organization org1;
+ org1.name = "Alice In Wonderland Inc.";
+ vcard->addOrganization(org1);
+
+ vcard->addTitle("Some Title");
+ vcard->addRole("Main Character");
+ vcard->addURL("http://wonderland.lit/~alice");
+ vcard->addURL("http://teaparty.lit/~alice2");
+
std::string expectedResult =
"<vCard xmlns=\"vcard-temp\">"
"<VERSION>2.0</VERSION>"
@@ -73,7 +109,35 @@ class VCardSerializerTest : public CppUnit::TestFixture
"<TYPE>image/png</TYPE>"
"<BINVAL>YWJjZGVm</BINVAL>"
"</PHOTO>"
- "<BDAY>1234</BDAY>"
+ "<BDAY>1865-05-04T00:00:00Z</BDAY>"
+ "<TEL>"
+ "<NUMBER>555-6273</NUMBER>"
+ "<HOME/>"
+ "<VOICE/>"
+ "</TEL>"
+ "<ADR>"
+ "<STREET>Fake Street 123</STREET>"
+ "<LOCALITY>Any Town</LOCALITY>"
+ "<PCODE>12345</PCODE>"
+ "<CTRY>USA</CTRY>"
+ "<HOME/>"
+ "</ADR>"
+ "<LABEL>"
+ "<LINE>Fake Street 123</LINE>"
+ "<LINE>12345 Any Town</LINE>"
+ "<LINE>USA</LINE>"
+ "<HOME/>"
+ "</LABEL>"
+ "<JID>alice@teaparty.lit</JID>"
+ "<JID>alice@wonderland.lit</JID>"
+ "<DESC>I once fell down a rabbit hole.</DESC>"
+ "<ORG>"
+ "<ORGNAME>Alice In Wonderland Inc.</ORGNAME>"
+ "</ORG>"
+ "<TITLE>Some Title</TITLE>"
+ "<ROLE>Main Character</ROLE>"
+ "<URL>http://wonderland.lit/~alice</URL>"
+ "<URL>http://teaparty.lit/~alice2</URL>"
"<MAILER>mutt</MAILER>"
"</vCard>";
diff --git a/Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp b/Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp
index 1512c6c..2676a02 100644
--- a/Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp
+++ b/Swiften/Serializer/PayloadSerializers/VCardSerializer.cpp
@@ -13,10 +13,17 @@
#include <Swiften/Serializer/XML/XMLTextNode.h>
#include <Swiften/Serializer/XML/XMLRawTextNode.h>
#include <Swiften/StringCodecs/Base64.h>
+#include <Swiften/Base/DateTime.h>
#include <Swiften/Base/foreach.h>
namespace Swift {
+boost::shared_ptr<XMLElement> createTextElement(const std::string& elementName, const std::string& text) {
+ boost::shared_ptr<XMLElement> element = boost::make_shared<XMLElement>(elementName);
+ element->addNode(boost::make_shared<XMLTextNode>(text));
+ return element;
+}
+
VCardSerializer::VCardSerializer() : GenericPayloadSerializer<VCard>() {
}
@@ -102,6 +109,171 @@ std::string VCardSerializer::serializePayload(boost::shared_ptr<VCard> vcard) c
}
queryElement.addNode(photoElement);
}
+ if (!vcard->getBirthday().is_not_a_date_time()) {
+ XMLElement::ref bdayElement(new XMLElement("BDAY"));
+ bdayElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(dateTimeToString(vcard->getBirthday()))));
+ queryElement.addNode(bdayElement);
+ }
+
+ foreach(const VCard::Telephone& telephone, vcard->getTelephones()) {
+ boost::shared_ptr<XMLElement> telElement(new XMLElement("TEL"));
+ boost::shared_ptr<XMLElement> numberElement(new XMLElement("NUMBER"));
+ numberElement->addNode(boost::shared_ptr<XMLTextNode>(new XMLTextNode(telephone.number)));
+ telElement->addNode(numberElement);
+ if (telephone.isHome) {
+ telElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("HOME")));
+ }
+ if (telephone.isWork) {
+ telElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("WORK")));
+ }
+ if (telephone.isVoice) {
+ telElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("VOICE")));
+ }
+ if (telephone.isFax) {
+ telElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("FAX")));
+ }
+ if (telephone.isPager) {
+ telElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("PAGER")));
+ }
+ if (telephone.isMSG) {
+ telElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("MSG")));
+ }
+ if (telephone.isCell) {
+ telElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("CELL")));
+ }
+ if (telephone.isVideo) {
+ telElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("VIDEO")));
+ }
+ if (telephone.isBBS) {
+ telElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("BBS")));
+ }
+ if (telephone.isModem) {
+ telElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("MODEM")));
+ }
+ if (telephone.isISDN) {
+ telElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("ISDN")));
+ }
+ if (telephone.isPCS) {
+ telElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("PCS")));
+ }
+ if (telephone.isPreferred) {
+ telElement->addNode(boost::shared_ptr<XMLElement>(new XMLElement("PREF")));
+ }
+ queryElement.addNode(telElement);
+ }
+
+ foreach(const VCard::Address& address, vcard->getAddresses()) {
+ boost::shared_ptr<XMLElement> adrElement(new XMLElement("ADR"));
+ if (!address.POBox.empty()) {
+ adrElement->addNode(createTextElement("POBOX", address.POBox));
+ }
+ if (!address.addressExtension.empty()) {
+ adrElement->addNode(createTextElement("EXTADD", address.addressExtension));
+ }
+ if (!address.street.empty()) {
+ adrElement->addNode(createTextElement("STREET", address.street));
+ }
+ if (!address.locality.empty()) {
+ adrElement->addNode(createTextElement("LOCALITY", address.locality));
+ }
+ if (!address.region.empty()) {
+ adrElement->addNode(createTextElement("REGION", address.region));
+ }
+ if (!address.postalCode.empty()) {
+ adrElement->addNode(createTextElement("PCODE", address.postalCode));
+ }
+ if (!address.country.empty()) {
+ adrElement->addNode(createTextElement("CTRY", address.country));
+ }
+
+ if (address.isHome) {
+ adrElement->addNode(boost::make_shared<XMLElement>("HOME"));
+ }
+ if (address.isWork) {
+ adrElement->addNode(boost::make_shared<XMLElement>("WORK"));
+ }
+ if (address.isPostal) {
+ adrElement->addNode(boost::make_shared<XMLElement>("POSTAL"));
+ }
+ if (address.isParcel) {
+ adrElement->addNode(boost::make_shared<XMLElement>("PARCEL"));
+ }
+ if (address.deliveryType == VCard::DomesticDelivery) {
+ adrElement->addNode(boost::make_shared<XMLElement>("DOM"));
+ }
+ if (address.deliveryType == VCard::InternationalDelivery) {
+ adrElement->addNode(boost::make_shared<XMLElement>("INTL"));
+ }
+ if (address.isPreferred) {
+ adrElement->addNode(boost::make_shared<XMLElement>("PREF"));
+ }
+ queryElement.addNode(adrElement);
+ }
+
+ foreach(const VCard::AddressLabel& addressLabel, vcard->getAddressLabels()) {
+ boost::shared_ptr<XMLElement> labelElement(new XMLElement("LABEL"));
+
+ foreach(const std::string& line, addressLabel.lines) {
+ labelElement->addNode(createTextElement("LINE", line));
+ }
+
+ if (addressLabel.isHome) {
+ labelElement->addNode(boost::make_shared<XMLElement>("HOME"));
+ }
+ if (addressLabel.isWork) {
+ labelElement->addNode(boost::make_shared<XMLElement>("WORK"));
+ }
+ if (addressLabel.isPostal) {
+ labelElement->addNode(boost::make_shared<XMLElement>("POSTAL"));
+ }
+ if (addressLabel.isParcel) {
+ labelElement->addNode(boost::make_shared<XMLElement>("PARCEL"));
+ }
+ if (addressLabel.deliveryType == VCard::DomesticDelivery) {
+ labelElement->addNode(boost::make_shared<XMLElement>("DOM"));
+ }
+ if (addressLabel.deliveryType == VCard::InternationalDelivery) {
+ labelElement->addNode(boost::make_shared<XMLElement>("INTL"));
+ }
+ if (addressLabel.isPreferred) {
+ labelElement->addNode(boost::make_shared<XMLElement>("PREF"));
+ }
+ queryElement.addNode(labelElement);
+ }
+
+ foreach(const JID& jid, vcard->getJIDs()) {
+ queryElement.addNode(createTextElement("JID", jid.toString()));
+ }
+
+ if (!vcard->getDescription().empty()) {
+ queryElement.addNode(createTextElement("DESC", vcard->getDescription()));
+ }
+
+ foreach(const VCard::Organization& org, vcard->getOrganizations()) {
+ boost::shared_ptr<XMLElement> orgElement(new XMLElement("ORG"));
+ if (!org.name.empty()) {
+ orgElement->addNode(createTextElement("ORGNAME", org.name));
+ }
+ if (!org.units.empty()) {
+ foreach(const std::string& unit, org.units) {
+ orgElement->addNode(createTextElement("ORGUNIT", unit));
+ }
+ }
+ queryElement.addNode(orgElement);
+ }
+
+ foreach(const std::string& title, vcard->getTitles()) {
+ queryElement.addNode(createTextElement("TITLE", title));
+ }
+
+ foreach(const std::string& role, vcard->getRoles()) {
+ queryElement.addNode(createTextElement("ROLE", role));
+ }
+
+ foreach(const std::string& url, vcard->getURLs()) {
+ queryElement.addNode(createTextElement("URL", url));
+ }
+
if (!vcard->getUnknownContent().empty()) {
queryElement.addNode(boost::make_shared<XMLRawTextNode>(vcard->getUnknownContent()));
}