From 5b851c72510ef88feb059455033915588fa6fb8c Mon Sep 17 00:00:00 2001
From: Tobias Markmann <tm@ayena.de>
Date: Sun, 31 May 2015 11:25:48 +0200
Subject: Open profile windows in their ideal size so everything is readable

Test-Information:

Tested on OS X 10.9.5 with Qt 5.4.1	and Windows 8 with Qt 5.3.2 and
KUbuntu 14.04 with Qt 5.4.1.

Change-Id: Ia6cf54baad3020d05be94c6159aa623f7a619816

diff --git a/Swift/QtUI/QtProfileWindow.cpp b/Swift/QtUI/QtProfileWindow.cpp
index 31a530f..71d4281 100644
--- a/Swift/QtUI/QtProfileWindow.cpp
+++ b/Swift/QtUI/QtProfileWindow.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2014 Isode Limited.
+ * Copyright (c) 2011-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -10,13 +10,14 @@
  * See Documentation/Licenses/BSD-simplified.txt for more information.
  */
 
-#include "QtProfileWindow.h"
-#include "ui_QtProfileWindow.h"
+#include <Swift/QtUI/QtProfileWindow.h>
+#include <Swift/QtUI/ui_QtProfileWindow.h>
 
 #include <QCloseEvent>
 #include <QMovie>
 #include <QShortcut>
 #include <QTextDocument>
+#include <QTimer>
 
 #include <Swift/QtUI/QtSwiftUtil.h>
 #include <Swift/QtUI/QtUtilities.h>
@@ -39,6 +40,10 @@ QtProfileWindow::QtProfileWindow() :
 	connect(ui->savePushButton, SIGNAL(clicked()), SLOT(handleSave()));
 	setEditable(false);
 	setAttribute(Qt::WA_DeleteOnClose);
+	setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
+
+	adjustSizeTimer.setSingleShot(true);
+	connect(&adjustSizeTimer, SIGNAL(timeout()), SLOT(handleAdjustSizeTimeout()));
 }
 
 QtProfileWindow::~QtProfileWindow() {
@@ -59,7 +64,6 @@ void QtProfileWindow::setVCard(VCard::ref vcard) {
 		ui->vcard->setVisible(true);
 		ui->emptyLabel->setVisible(false);
 	}
-
 	updateWindowSize();
 }
 
@@ -74,6 +78,7 @@ void QtProfileWindow::setEditable(bool b) {
 	ui->savePushButton->setVisible(b);
 	ui->vcard->setEditable(b);
 	updateTitle();
+	updateWindowSize();
 }
 
 void QtProfileWindow::setProcessing(bool processing) {
@@ -89,8 +94,6 @@ void QtProfileWindow::setProcessing(bool processing) {
 		ui->statusLabel->setVisible(false);
 		ui->vcard->setVisible(true);
 	}
-
-	updateWindowSize();
 }
 
 void QtProfileWindow::setError(const std::string& error) {
@@ -112,6 +115,10 @@ void QtProfileWindow::hide() {
 	QWidget::hide();
 }
 
+QSize QtProfileWindow::sizeHint() const {
+	return QWidget::sizeHint() + QSize(0, 15);
+}
+
 void QtProfileWindow::updateTitle() {
 	QString jidString;
 	if (jid.isValid()) {
@@ -126,22 +133,14 @@ void QtProfileWindow::updateTitle() {
 }
 
 void QtProfileWindow::updateWindowSize() {
-	int width = 0;
-	int height = 0;
-
-	QSize size = ui->statusLabel->size();
-	width = std::max(width, size.width());
-	height = std::max(height, size.height() * 3);
-
-	size = ui->emptyLabel->size();
-	width = std::max(width, size.width());
-	height = std::max(height, size.height() * 3);
-
-	size = ui->vcard->size();
-	width = std::max(width, size.width());
-	height = std::max(height, size.height());
-
-	resize(width, height);
+	// Delay resizing to the end of the event loop, because Qt calculates the correct layout asynchronously.
+	// Qt will post LayoutRequests for widgets on the event loop on show and widgets will recaluclate their
+	// layout as they process these events.
+	// We use the complete and correct size hint from the freshly calculated layout by delaying execution of
+	// the resize code to the end of Qt's event loop.
+	if (!adjustSizeTimer.isActive()) {
+		adjustSizeTimer.start(0);
+	}
 }
 
 void QtProfileWindow::closeEvent(QCloseEvent* event) {
@@ -153,4 +152,16 @@ void QtProfileWindow::handleSave() {
 	onVCardChangeRequest(ui->vcard->getVCard());
 }
 
+void QtProfileWindow::handleAdjustSizeTimeout() {
+	// Force recaluclation of all layout geometry in children widgets.
+	// This is required on Windows to have the correct size even on first show.
+	QList<QWidget *> children = findChildren<QWidget*>();
+	foreach(QWidget* child, children) {
+		child->updateGeometry();
+	}
+
+	updateGeometry();
+	adjustSize();
+}
+
 }
diff --git a/Swift/QtUI/QtProfileWindow.h b/Swift/QtUI/QtProfileWindow.h
index d1eed99..0821444 100644
--- a/Swift/QtUI/QtProfileWindow.h
+++ b/Swift/QtUI/QtProfileWindow.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -12,12 +12,13 @@
 
 #pragma once
 
+#include <QTimer>
+#include <QWidget>
+
 #include <Swiften/JID/JID.h>
 
 #include <Swift/Controllers/UIInterfaces/ProfileWindow.h>
 
-#include <QWidget>
-
 namespace Ui {
 	class QtProfileWindow;
 }
@@ -42,6 +43,8 @@ class QtProfileWindow : public QWidget, public ProfileWindow {
 		virtual void show();
 		virtual void hide();
 
+		virtual QSize sizeHint() const;
+
 	private:
 		void updateTitle();
 		void updateWindowSize();
@@ -49,10 +52,12 @@ class QtProfileWindow : public QWidget, public ProfileWindow {
 
 	private slots:
 		void handleSave();
+		void handleAdjustSizeTimeout();
 
 	private:
 		Ui::QtProfileWindow* ui;
 		JID jid;
+		QTimer adjustSizeTimer;
 };
 
 }
-- 
cgit v0.10.2-6-g49f6