From 5cf50d46aed4d2dac333e5e3b3bc2f57f7a1b835 Mon Sep 17 00:00:00 2001 From: Tobias Markmann Date: Wed, 29 Oct 2014 15:02:39 +0100 Subject: 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 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 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -194,6 +195,19 @@ void UserSearchController::handleNameSuggestionRequest(const JID &jid) { } } +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()); + } + } + else { + window_->setWarning(QT_TRANSLATE_NOOP("", "The address you have entered is invalid.")); + } +} + void UserSearchController::handleContactSuggestionsRequested(std::string text) { const std::vector existingJIDs = window_->getJIDs(); std::vector suggestions = contactSuggester_->getSuggestions(text, false); @@ -207,6 +221,14 @@ void UserSearchController::handleContactSuggestionsRequested(std::string text) { 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 { @@ -307,6 +329,7 @@ void UserSearchController::initializeUserWindow() { 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 @@ -69,6 +69,7 @@ namespace Swift { void handlePresenceChanged(Presence::ref presence); void handleJIDUpdateRequested(const std::vector& jids); void handleJIDAddRequested(const std::vector& jids); + void handleJIDEditingFinished(const JID& jid); Contact::ref convertJIDtoContact(const JID& jid); void endDiscoWalker(); void initializeUserWindow(); 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 @@ -41,6 +41,7 @@ namespace Swift { virtual void updateContacts(const std::vector& contacts) = 0; virtual void addContacts(const std::vector& contacts) = 0; virtual void setCanSupplyDescription(bool allowed) = 0; + virtual void setWarning(const boost::optional& message) = 0; virtual void show() = 0; @@ -50,5 +51,6 @@ namespace Swift { boost::signal onContactSuggestionsRequested; boost::signal&)> onJIDUpdateRequested; boost::signal&)> onJIDAddRequested; + boost::signal 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 @@ -18,17 +18,22 @@ QtUserSearchFirstPage::QtUserSearchFirstPage(UserSearchWindow::Type type, const 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()) { 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 @@ -28,5 +28,6 @@ namespace Swift { 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 @@ -167,6 +167,20 @@ void QtUserSearchWindow::addContact() { } } +void QtUserSearchWindow::setWarning(const boost::optional& 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()) { @@ -466,6 +480,10 @@ 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); @@ -473,6 +491,7 @@ void QtUserSearchWindow::setFirstPage(QString title) { 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())); 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 @@ -52,6 +52,7 @@ namespace Swift { virtual void updateContacts(const std::vector &contacts); virtual void addContacts(const std::vector& contacts); virtual void setCanSupplyDescription(bool allowed); + virtual void setWarning(const boost::optional& message); protected: virtual int nextId() const; @@ -65,6 +66,7 @@ namespace Swift { void handleAddViaSearch(); void handleListChanged(std::vector list); void handleJIDsAdded(std::vector jids); + void handleJIDEditingDone(); private: void setFirstPage(QString title = ""); -- cgit v0.10.2-6-g49f6