summaryrefslogtreecommitdiffstats
path: root/Swift
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2014-10-29 14:02:39 (GMT)
committerSwift Review <review@swift.im>2014-10-30 15:41:49 (GMT)
commit5cf50d46aed4d2dac333e5e3b3bc2f57f7a1b835 (patch)
tree554e93a52e5c41e98b9e42e5d958819b87439b88 /Swift
parent4041cc4dd4f0abc6641fed5890120efa691a27ca (diff)
downloadswift-5cf50d46aed4d2dac333e5e3b3bc2f57f7a1b835.zip
swift-5cf50d46aed4d2dac333e5e3b3bc2f57f7a1b835.tar.bz2
Prevent user from adding contacts twice to a roster.
This removes roster JIDs from the suggesting in the 'Add User'-dialog. In addition, an indication is added when a manually entered JID is invalid or already on the roster. Test-Information: Tested scenarios with recent JIDs and JIDs from the roster. Tested that 'Start Chat'-dialog suggestions still work. Change-Id: I1ff51637adb4224184b78a1af9090a04b1e18fff
Diffstat (limited to 'Swift')
-rw-r--r--Swift/Controllers/Chat/UserSearchController.cpp23
-rw-r--r--Swift/Controllers/Chat/UserSearchController.h1
-rw-r--r--Swift/Controllers/UIInterfaces/UserSearchWindow.h2
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchFirstPage.cpp7
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchFirstPage.h1
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchWindow.cpp19
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchWindow.h2
7 files changed, 54 insertions, 1 deletions
diff --git a/Swift/Controllers/Chat/UserSearchController.cpp b/Swift/Controllers/Chat/UserSearchController.cpp
index f1849c9..2d3f1ae 100644
--- a/Swift/Controllers/Chat/UserSearchController.cpp
+++ b/Swift/Controllers/Chat/UserSearchController.cpp
@@ -15,12 +15,13 @@
#include <Swiften/Disco/GetDiscoItemsRequest.h>
#include <Swiften/Disco/DiscoServiceWalker.h>
#include <Swiften/VCards/VCardManager.h>
#include <Swiften/Presence/PresenceOracle.h>
#include <Swiften/Avatars/AvatarManager.h>
#include <Swift/Controllers/ContactEditController.h>
+#include <Swift/Controllers/Intl.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <Swift/Controllers/UIEvents/RequestChatWithUserDialogUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestInviteToMUCUIEvent.h>
#include <Swift/Controllers/UIInterfaces/UserSearchWindow.h>
#include <Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h>
@@ -191,12 +192,25 @@ void UserSearchController::handleNameSuggestionRequest(const JID &jid) {
VCard::ref vcard = vcardManager_->getVCardAndRequestWhenNeeded(jid);
if (vcard) {
handleVCardChanged(jid, vcard);
}
}
+void UserSearchController::handleJIDEditingFinished(const JID& jid) {
+ if (jid.isValid()) {
+ if (rosterController_->getItem(jid)) {
+ window_->setWarning(QT_TRANSLATE_NOOP("", "This contact is already on your contact list."));
+ } else {
+ window_->setWarning(boost::optional<std::string>());
+ }
+ }
+ else {
+ window_->setWarning(QT_TRANSLATE_NOOP("", "The address you have entered is invalid."));
+ }
+}
+
void UserSearchController::handleContactSuggestionsRequested(std::string text) {
const std::vector<JID> existingJIDs = window_->getJIDs();
std::vector<Contact::ref> suggestions = contactSuggester_->getSuggestions(text, false);
/* do not suggest contacts that have already been added to the chat list */
std::vector<Contact::ref>::iterator i = suggestions.begin();
while (i != suggestions.end()) {
@@ -204,12 +218,20 @@ void UserSearchController::handleContactSuggestionsRequested(std::string text) {
foreach (const JID& jid, existingJIDs) {
if ((*i)->jid == jid) {
found = true;
break;
}
}
+
+ // remove contact suggestions which are already on the contact list in add-contact-mode
+ if (type_ == AddContact) {
+ if (!found && !!rosterController_->getItem((*i)->jid)) {
+ found = true;
+ }
+ }
+
if (found) {
i = suggestions.erase(i);
} else {
i++;
}
}
@@ -304,12 +326,13 @@ void UserSearchController::initializeUserWindow() {
window_->onNameSuggestionRequested.connect(boost::bind(&UserSearchController::handleNameSuggestionRequest, this, _1));
window_->onFormRequested.connect(boost::bind(&UserSearchController::handleFormRequested, this, _1));
window_->onSearchRequested.connect(boost::bind(&UserSearchController::handleSearch, this, _1, _2));
window_->onContactSuggestionsRequested.connect(boost::bind(&UserSearchController::handleContactSuggestionsRequested, this, _1));
window_->onJIDUpdateRequested.connect(boost::bind(&UserSearchController::handleJIDUpdateRequested, this, _1));
window_->onJIDAddRequested.connect(boost::bind(&UserSearchController::handleJIDAddRequested, this, _1));
+ window_->onJIDEditFieldChanged.connect(boost::bind(&UserSearchController::handleJIDEditingFinished, this, _1));
window_->setSelectedService(JID(jid_.getDomain()));
window_->clear();
}
}
}
diff --git a/Swift/Controllers/Chat/UserSearchController.h b/Swift/Controllers/Chat/UserSearchController.h
index d630580..b89bffd 100644
--- a/Swift/Controllers/Chat/UserSearchController.h
+++ b/Swift/Controllers/Chat/UserSearchController.h
@@ -66,12 +66,13 @@ namespace Swift {
void handleContactSuggestionsRequested(std::string text);
void handleVCardChanged(const JID& jid, VCard::ref vcard);
void handleAvatarChanged(const JID& jid);
void handlePresenceChanged(Presence::ref presence);
void handleJIDUpdateRequested(const std::vector<JID>& jids);
void handleJIDAddRequested(const std::vector<JID>& jids);
+ void handleJIDEditingFinished(const JID& jid);
Contact::ref convertJIDtoContact(const JID& jid);
void endDiscoWalker();
void initializeUserWindow();
private:
Type type_;
diff --git a/Swift/Controllers/UIInterfaces/UserSearchWindow.h b/Swift/Controllers/UIInterfaces/UserSearchWindow.h
index 9a095aa..224c0b5 100644
--- a/Swift/Controllers/UIInterfaces/UserSearchWindow.h
+++ b/Swift/Controllers/UIInterfaces/UserSearchWindow.h
@@ -38,17 +38,19 @@ namespace Swift {
virtual std::string getReason() const = 0;
virtual std::vector<JID> getJIDs() const = 0;
virtual void setCanStartImpromptuChats(bool supportsImpromptu) = 0;
virtual void updateContacts(const std::vector<Contact::ref>& contacts) = 0;
virtual void addContacts(const std::vector<Contact::ref>& contacts) = 0;
virtual void setCanSupplyDescription(bool allowed) = 0;
+ virtual void setWarning(const boost::optional<std::string>& message) = 0;
virtual void show() = 0;
boost::signal<void (const JID&)> onFormRequested;
boost::signal<void (boost::shared_ptr<SearchPayload>, const JID&)> onSearchRequested;
boost::signal<void (const JID&)> onNameSuggestionRequested;
boost::signal<void (const std::string&)> onContactSuggestionsRequested;
boost::signal<void (const std::vector<JID>&)> onJIDUpdateRequested;
boost::signal<void (const std::vector<JID>&)> onJIDAddRequested;
+ boost::signal<void (const JID&)> onJIDEditFieldChanged;
};
}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchFirstPage.cpp b/Swift/QtUI/UserSearch/QtUserSearchFirstPage.cpp
index af53a26..f36ff2b 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchFirstPage.cpp
+++ b/Swift/QtUI/UserSearch/QtUserSearchFirstPage.cpp
@@ -15,23 +15,28 @@ namespace Swift {
QtUserSearchFirstPage::QtUserSearchFirstPage(UserSearchWindow::Type type, const QString& title, SettingsProvider* settings) {
setupUi(this);
setTitle(title);
setSubTitle(QString(tr("%1. If you know their address you can enter it directly, or you can search for them.")).arg(type == UserSearchWindow::AddContact ? tr("Add another user to your contact list") : tr("Chat to another user")));
jid_ = new QtSuggestingJIDInput(this, settings);
horizontalLayout_2->addWidget(jid_);
+ jidWarning_ = new QLabel(this);
+ jidWarning_->setPixmap(QPixmap(":icons/warn.png"));
+ jidWarning_->hide();
+ horizontalLayout_2->addWidget(jidWarning_);
setTabOrder(byJID_, jid_);
setTabOrder(jid_, byLocalSearch_);
setTabOrder(byLocalSearch_, byRemoteSearch_);
connect(jid_, SIGNAL(textChanged(const QString&)), this, SLOT(emitCompletenessCheck()));
+ connect(jid_, SIGNAL(editingDone()), this, SLOT(emitCompletenessCheck()));
connect(service_->lineEdit(), SIGNAL(textChanged(const QString&)), this, SLOT(emitCompletenessCheck()));
}
bool QtUserSearchFirstPage::isComplete() const {
bool complete = false;
if (byJID_->isChecked()) {
- complete = JID(Q2PSTRING(jid_->text().trimmed())).isValid();
+ complete = JID(Q2PSTRING(jid_->text().trimmed())).isValid() && jidWarning_->toolTip().isEmpty();
} else if (byLocalSearch_->isChecked()) {
complete = true;
} else if (byRemoteSearch_->isChecked()) {
complete = JID(Q2PSTRING(service_->currentText().trimmed())).isValid();
}
return complete;
diff --git a/Swift/QtUI/UserSearch/QtUserSearchFirstPage.h b/Swift/QtUI/UserSearch/QtUserSearchFirstPage.h
index d7487b0..32a7e70 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchFirstPage.h
+++ b/Swift/QtUI/UserSearch/QtUserSearchFirstPage.h
@@ -25,8 +25,9 @@ namespace Swift {
QtUserSearchFirstPage(UserSearchWindow::Type type, const QString& title, SettingsProvider* settings);
virtual bool isComplete() const;
public slots:
void emitCompletenessCheck();
public:
QtSuggestingJIDInput* jid_;
+ QLabel* jidWarning_;
};
}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp
index babe115..b197483 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp
+++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp
@@ -164,12 +164,26 @@ void QtUserSearchWindow::addContact() {
firstMultiJIDPage_->emitCompletenessCheck();
if (type_ == ChatToContact) {
firstMultiJIDPage_->groupBox->setEnabled(supportsImpromptu_ ? 1 : (contactVector_.size() < 1));
}
}
+void QtUserSearchWindow::setWarning(const boost::optional<std::string>& message) {
+ if (message) {
+ firstPage_->jidWarning_->setToolTip(P2QSTRING((*message)));
+ firstPage_->jidWarning_->setAccessibleDescription(P2QSTRING((*message)));
+ firstPage_->jidWarning_->show();
+ }
+ else {
+ firstPage_->jidWarning_->setToolTip("");
+ firstPage_->jidWarning_->setAccessibleDescription("");
+ firstPage_->jidWarning_->hide();
+ }
+ firstPage_->emitCompletenessCheck();
+}
+
int QtUserSearchWindow::nextId() const {
if (type_ == AddContact) {
switch (currentId()) {
case 1: return firstPage_->byJID_->isChecked() ? (type_ == AddContact ? 4 : -1) : 2;
case 2: return 3;
case 3: return type_ == AddContact ? 4 : -1;
@@ -463,19 +477,24 @@ void QtUserSearchWindow::setResultsForm(Form::ref results) {
}
void QtUserSearchWindow::setSelectedService(const JID& jid) {
myServer_ = jid;
}
+void QtUserSearchWindow::handleJIDEditingDone() {
+ onJIDEditFieldChanged(JID(Q2PSTRING(firstPage_->jid_->text())));
+}
+
void QtUserSearchWindow::setFirstPage(QString title) {
if (page(1) != 0) {
removePage(1);
}
if (type_ == AddContact) {
firstPage_ = new QtUserSearchFirstPage(type_, title.isEmpty() ? firstPage_->title() : title, settings_);
connect(firstPage_->jid_, SIGNAL(textEdited(QString)), this, SLOT(handleContactSuggestionRequested(QString)));
+ connect(firstPage_->jid_, SIGNAL(textEdited(QString)), this, SLOT(handleJIDEditingDone()), Qt::UniqueConnection);
firstPage_->jid_->onUserSelected.connect(boost::bind(&QtUserSearchWindow::handleOnSearchedJIDSelected, this, _1));
connect(firstPage_->byJID_, SIGNAL(toggled(bool)), this, SLOT(handleFirstPageRadioChange()));
connect(firstPage_->byLocalSearch_, SIGNAL(toggled(bool)), this, SLOT(handleFirstPageRadioChange()));
connect(firstPage_->byRemoteSearch_, SIGNAL(toggled(bool)), this, SLOT(handleFirstPageRadioChange()));
#if QT_VERSION >= 0x040700
firstPage_->jid_->setPlaceholderText(tr("alice@wonderland.lit"));
diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.h b/Swift/QtUI/UserSearch/QtUserSearchWindow.h
index 255b8fe..d1d29f2 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchWindow.h
+++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.h
@@ -49,12 +49,13 @@ namespace Swift {
virtual std::string getReason() const;
virtual std::vector<JID> getJIDs() const;
virtual void setCanStartImpromptuChats(bool supportsImpromptu);
virtual void updateContacts(const std::vector<Contact::ref> &contacts);
virtual void addContacts(const std::vector<Contact::ref>& contacts);
virtual void setCanSupplyDescription(bool allowed);
+ virtual void setWarning(const boost::optional<std::string>& message);
protected:
virtual int nextId() const;
private slots:
void handleFirstPageRadioChange();
@@ -62,12 +63,13 @@ namespace Swift {
virtual void handleAccepted();
void handleContactSuggestionRequested(const QString& text);
void addContact();
void handleAddViaSearch();
void handleListChanged(std::vector<Contact::ref> list);
void handleJIDsAdded(std::vector<JID> jids);
+ void handleJIDEditingDone();
private:
void setFirstPage(QString title = "");
void setSecondPage();
void setThirdPage();