From d1823afd38df62887b0c5e9f1f01a50ab84f77ba Mon Sep 17 00:00:00 2001
From: Tobias Markmann <tm@ayena.de>
Date: Thu, 21 May 2015 00:15:32 +0200
Subject: Usability improvements to "Enter Room" dialog

Require valid room JID to proceed with entering a room.
Provide user feedback via tooltips on invalid input in the room and
nickname field.

Test-Information:

Tested with invalid room JID and empty nickanme on OS X 10.9.5
and Qt 5.4.0.

Change-Id: I8d8c75f5712f27cc72cce2d6dd16dbbea4fb504a

diff --git a/Swift/QtUI/QtJoinMUCWindow.cpp b/Swift/QtUI/QtJoinMUCWindow.cpp
index d111756..53944da 100644
--- a/Swift/QtUI/QtJoinMUCWindow.cpp
+++ b/Swift/QtUI/QtJoinMUCWindow.cpp
@@ -4,11 +4,12 @@
  * See the COPYING file for more information.
  */
 
-
 #include <Swift/QtUI/QtJoinMUCWindow.h>
 
 #include <boost/smart_ptr/make_shared.hpp>
 
+#include <QToolTip>
+
 #include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h>
 #include <Swift/Controllers/UIEvents/UIEventStream.h>
 
@@ -32,15 +33,16 @@ QtJoinMUCWindow::QtJoinMUCWindow(UIEventStream* uiEventStream) : uiEventStream(u
 #endif
 	ui.instantRoom->setChecked(true);
 	ui.nickName->setValidator(new NickValidator(this));
+	ui.room->setValidator(new RoomJIDValidator(this));
 }
 
 void QtJoinMUCWindow::handleJoin() {
-	if (ui.room->text().isEmpty()) {
-		// TODO: Error
+	if (ui.room->text().isEmpty() || !ui.room->hasAcceptableInput()) {
+		QToolTip::showText(ui.room->mapToGlobal(QPoint()), tr("Please enter a valid room address."), ui.room);
 		return;
 	}
-	if (ui.nickName->text().isEmpty()) {
-		// TODO: Error
+	if (ui.nickName->text().isEmpty() || !ui.nickName->hasAcceptableInput()) {
+		QToolTip::showText(ui.nickName->mapToGlobal(QPoint()), tr("Please enter a valid nickname."), ui.nickName);
 		return;
 	}
 
diff --git a/Swift/QtUI/QtJoinMUCWindow.h b/Swift/QtUI/QtJoinMUCWindow.h
index ba12b86..92580ff 100644
--- a/Swift/QtUI/QtJoinMUCWindow.h
+++ b/Swift/QtUI/QtJoinMUCWindow.h
@@ -1,16 +1,20 @@
 /*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
 
 #pragma once
 
-#include <QValidator>
+#include <Swift/QtUI/ui_QtJoinMUCWindow.h>
+
 #include <string>
-#include "QtSwiftUtil.h"
+
+#include <QValidator>
+
 #include <Swift/Controllers/UIInterfaces/JoinMUCWindow.h>
-#include <Swift/QtUI/ui_QtJoinMUCWindow.h>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
 
 namespace Swift {
 	class UIEventStream;
@@ -22,13 +26,34 @@ namespace Swift {
 
 			virtual QValidator::State validate(QString& input, int& /*pos*/) const {
 				if (input.isEmpty()) {
-					return QValidator::Acceptable;
+					return QValidator::Intermediate;
 				}
 				JID test("alice", "wonderland.lit", Q2PSTRING(input));
 
 				return test.isValid() ? QValidator::Acceptable : QValidator::Invalid;
 			}
 	};
+
+	class RoomJIDValidator : public QValidator {
+		Q_OBJECT
+		public:
+			RoomJIDValidator(QObject* parent) : QValidator(parent) {
+			}
+
+			virtual QValidator::State validate(QString& input, int& /*pos*/) const {
+				if (input.isEmpty()) {
+					return QValidator::Intermediate;
+				}
+				JID roomJID(Q2PSTRING(input));
+
+				if (roomJID.getNode().empty() || roomJID.getDomain().empty()) {
+					return QValidator::Intermediate;
+				}
+
+				return (roomJID.getResource().empty() && !roomJID.getNode().empty() && !roomJID.getDomain().empty() &&  roomJID.isValid()) ? QValidator::Acceptable : QValidator::Invalid;
+			}
+	};
+
 	class QtJoinMUCWindow : public QWidget, public JoinMUCWindow {
 			Q_OBJECT
 		public:
-- 
cgit v0.10.2-6-g49f6