From 73f845a3f380c5a1adbac2cf29e9f36cc9b498cf Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Sun, 11 Apr 2010 16:03:54 +0100
Subject: Proper handling of keypresses in the chat input that're meant for the
 chat log.

Resolves: #284

diff --git a/Swift/QtUI/QtChatView.cpp b/Swift/QtUI/QtChatView.cpp
index 55f9fee..3324108 100644
--- a/Swift/QtUI/QtChatView.cpp
+++ b/Swift/QtUI/QtChatView.cpp
@@ -10,11 +10,12 @@
 #include <QFile>
 #include <QDesktopServices>
 #include <QVBoxLayout>
-#include <QWebView>
 #include <QWebFrame>
 #include <QKeyEvent>
 #include <QStackedWidget>
 
+#include "QtWebView.h"
+
 namespace Swift {
 
 QtChatView::QtChatView(QWidget* parent) : QWidget(parent) {
@@ -23,7 +24,7 @@ QtChatView::QtChatView(QWidget* parent) : QWidget(parent) {
 	QVBoxLayout* mainLayout = new QVBoxLayout(this);
 	mainLayout->setSpacing(0);
 	mainLayout->setContentsMargins(0,0,0,0);
-	webView_ = new QWebView(this);
+	webView_ = new QtWebView(this);
 	webView_->setFocusPolicy(Qt::NoFocus);
 	connect(webView_, SIGNAL(linkClicked(const QUrl&)), SLOT(handleLinkClicked(const QUrl&)));
 	connect(webView_, SIGNAL(loadFinished(bool)), SLOT(handleViewLoadFinished(bool)));
@@ -62,6 +63,10 @@ QtChatView::QtChatView(QWidget* parent) : QWidget(parent) {
 	webPage_->mainFrame()->setHtml(pageHTML);
 }
 
+void QtChatView::handleKeyPressEvent(QKeyEvent* event) {
+	webView_->keyPressEvent(event);
+}
+
 void QtChatView::addMessage(const ChatSnippet& snippet) {
 	//bool wasScrolledToBottom = isScrolledToBottom();
 	
diff --git a/Swift/QtUI/QtChatView.h b/Swift/QtUI/QtChatView.h
index b2c1ac3..ea64265 100644
--- a/Swift/QtUI/QtChatView.h
+++ b/Swift/QtUI/QtChatView.h
@@ -12,11 +12,11 @@
 
 #include "ChatSnippet.h"
 
-class QWebView;
 class QWebPage;
 class QUrl;
 
 namespace Swift {
+	class QtWebView;
 	class QtChatView : public QWidget {
 			Q_OBJECT
 		public:
@@ -29,13 +29,14 @@ namespace Swift {
 			void copySelectionToClipboard();
 			void scrollToBottom();
 			void handleLinkClicked(const QUrl&);
+			void handleKeyPressEvent(QKeyEvent* event);
 
 		private slots:
 			void handleViewLoadFinished(bool);
 
 		private:
 			bool viewReady_;
-			QWebView* webView_;
+			QtWebView* webView_;
 			QWebPage* webPage_;
 			QString previousContinuationElementID_;
 			QString queuedMessages_;
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index dd1bf98..5bedc22 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -39,6 +39,7 @@ QtChatWindow::QtChatWindow(const QString &contact, QtTreeWidgetFactory *treeWidg
 	layout->addWidget(logRosterSplitter);
 
 	messageLog_ = new QtChatView(this);
+	messageLog_->setFocusPolicy(Qt::NoFocus);
 	logRosterSplitter->addWidget(messageLog_);
 
 	treeWidget_ = dynamic_cast<QtTreeWidget*>(treeWidgetFactory->createTreeWidget());
@@ -65,6 +66,7 @@ QtChatWindow::QtChatWindow(const QString &contact, QtTreeWidgetFactory *treeWidg
 	inputClearing_ = false;
 	contactIsTyping_ = false;
 
+	connect(input_, SIGNAL(unhandledKeyPressEvent(QKeyEvent*)), messageLog_, SLOT(handleKeyPressEvent(QKeyEvent*)));
 	connect(input_, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
 	connect(input_, SIGNAL(textChanged()), this, SLOT(handleInputChanged()));
 	setFocusProxy(input_);
diff --git a/Swift/QtUI/QtTextEdit.cpp b/Swift/QtUI/QtTextEdit.cpp
index 215fbc0..70f7aca 100644
--- a/Swift/QtUI/QtTextEdit.cpp
+++ b/Swift/QtUI/QtTextEdit.cpp
@@ -17,9 +17,14 @@ QtTextEdit::QtTextEdit(QWidget* parent) : QTextEdit(parent){
 };
 
 void QtTextEdit::keyPressEvent(QKeyEvent* event) {
-	if ((event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)
-		&& (event->modifiers() == Qt::NoModifier || event->modifiers() == Qt::KeypadModifier)) {
+	int key = event->key();
+	Qt::KeyboardModifiers modifiers = event->modifiers();
+	if ((key == Qt::Key_Enter || key == Qt::Key_Return)
+		&& (modifiers == Qt::NoModifier || modifiers == Qt::KeypadModifier)) {
 		emit returnPressed();
+	} else if (((key == Qt::Key_PageUp || key == Qt::Key_PageDown) && modifiers == Qt::ShiftModifier)
+			   || (key == Qt::Key_C && modifiers == Qt::ControlModifier && textCursor().selectedText().isEmpty())) {
+		emit unhandledKeyPressEvent(event);
 	} else {
 		QTextEdit::keyPressEvent(event);
 	}
diff --git a/Swift/QtUI/QtTextEdit.h b/Swift/QtUI/QtTextEdit.h
index 5ab2990..075728b 100644
--- a/Swift/QtUI/QtTextEdit.h
+++ b/Swift/QtUI/QtTextEdit.h
@@ -15,6 +15,7 @@ namespace Swift {
 		virtual QSize sizeHint() const;
 	signals:
 		void returnPressed();
+		void unhandledKeyPressEvent(QKeyEvent* event);
 	protected:
 		virtual void keyPressEvent(QKeyEvent* event);
 	private slots:
diff --git a/Swift/QtUI/QtWebView.h b/Swift/QtUI/QtWebView.h
new file mode 100644
index 0000000..8ed5842
--- /dev/null
+++ b/Swift/QtUI/QtWebView.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+
+#pragma once
+
+#include <QWebView>
+
+namespace Swift {
+	class QtWebView : public QWebView {
+		public:
+			QtWebView(QWidget* parent) : QWebView(parent) {}
+			void keyPressEvent(QKeyEvent* event) {
+				Qt::KeyboardModifiers modifiers = event->modifiers();
+				int key = event->key();
+				if (modifiers == Qt::ShiftModifier && (key == Qt::Key_PageUp || key == Qt::Key_PageDown)) {
+					modifiers = Qt::NoModifier;
+				}
+				QKeyEvent* translatedEvent = new QKeyEvent(QEvent::KeyPress,
+										   key,
+										   modifiers,
+										   event->text(),
+										   event->isAutoRepeat(),
+										   event->count());
+				QWebView::keyPressEvent(translatedEvent);
+				delete translatedEvent;
+			};
+	};
+}
-- 
cgit v0.10.2-6-g49f6