From e9f2f7675b11ce36b3f66250156b78fae524a351 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Sun, 18 Nov 2012 19:46:50 +0100
Subject: RTL support in chat dialog.

Change-Id: Id5604c65c6090783c79a45ee7c975ed4118a51f3

diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp
index 68af288..1fb45a9 100644
--- a/Swift/Controllers/Chat/ChatController.cpp
+++ b/Swift/Controllers/Chat/ChatController.cpp
@@ -77,7 +77,7 @@ ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQ
 	lastShownStatus_ = theirPresence ? theirPresence->getShow() : StatusShow::None;
 	chatStateNotifier_->setContactIsOnline(theirPresence && theirPresence->getType() == Presence::Available);
 	startMessage += ".";
-	chatWindow_->addSystemMessage(startMessage);
+	chatWindow_->addSystemMessage(startMessage, ChatWindow::DefaultDirection);
 	chatWindow_->onUserTyping.connect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
 	chatWindow_->onUserCancelsTyping.connect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_));
 	chatWindow_->onFileTransferStart.connect(boost::bind(&ChatController::handleFileTransferStart, this, _1, _2));
@@ -445,7 +445,7 @@ void ChatController::handlePresenceChange(boost::shared_ptr<Presence> newPresenc
 		if (lastWasPresence_) {
 			chatWindow_->replaceLastMessage(newStatusChangeString);
 		} else {
-			chatWindow_->addPresenceMessage(newStatusChangeString);
+			chatWindow_->addPresenceMessage(newStatusChangeString, ChatWindow::DefaultDirection);
 		}
 		lastStatusChangeString_ = newStatusChangeString;
 		lastWasPresence_ = true;
diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp
index b60162f..e469637 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.cpp
+++ b/Swift/Controllers/Chat/ChatControllerBase.cpp
@@ -75,7 +75,7 @@ void ChatControllerBase::createDayChangeTimer() {
 void ChatControllerBase::handleDayChangeTick() {
 	dateChangeTimer_->stop();
 	boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
-	chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "The day is now %1%")) % std::string(boost::posix_time::to_iso_extended_string(now)).substr(0,10)));
+	chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "The day is now %1%")) % std::string(boost::posix_time::to_iso_extended_string(now)).substr(0,10)), ChatWindow::DefaultDirection);
 	dayTicked();
 	createDayChangeTimer();
 }
@@ -238,7 +238,7 @@ void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> m
 			boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
 			std::ostringstream s;
 			s << "The following message took " << (now - delayPayloads[i]->getStamp()).total_milliseconds() / 1000.0 <<  " seconds to be delivered from " << delayPayloads[i]->getFrom()->toString() << ".";
-			chatWindow_->addSystemMessage(std::string(s.str()));
+			chatWindow_->addSystemMessage(std::string(s.str()), ChatWindow::DefaultDirection);
 		}
 		boost::shared_ptr<SecurityLabel> label = message->getPayload<SecurityLabel>();
 
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp
index 03c8810..b964bad 100644
--- a/Swift/Controllers/Chat/MUCController.cpp
+++ b/Swift/Controllers/Chat/MUCController.cpp
@@ -226,7 +226,7 @@ const std::string& MUCController::getNick() {
 
 void MUCController::handleJoinTimeoutTick() {
 	receivedActivity();
-	chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "Room %1% is not responding. This operation may never complete.")) % toJID_.toString()));
+	chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "Room %1% is not responding. This operation may never complete.")) % toJID_.toString()), ChatWindow::DefaultDirection);
 }
 
 void MUCController::receivedActivity() {
@@ -294,7 +294,7 @@ void MUCController::handleJoinComplete(const std::string& nick) {
 	joined_ = true;
 	std::string joinMessage = str(format(QT_TRANSLATE_NOOP("", "You have entered room %1% as %2%.")) % toJID_.toString() % nick);
 	setNick(nick);
-	chatWindow_->addSystemMessage(joinMessage);
+	chatWindow_->addSystemMessage(joinMessage, ChatWindow::DefaultDirection);
 
 #ifdef SWIFT_EXPERIMENTAL_HISTORY
 	addRecentLogs();
@@ -352,7 +352,6 @@ void MUCController::handleOccupantJoined(const MUCOccupant& occupant) {
 			updateJoinParts();
 		} else {
 			addPresenceMessage(joinString);
-
 		}
 	}
 	if (avatarManager_ != NULL) {
@@ -362,7 +361,7 @@ void MUCController::handleOccupantJoined(const MUCOccupant& occupant) {
 
 void MUCController::addPresenceMessage(const std::string& message) {
 	lastWasPresence_ = true;
-	chatWindow_->addPresenceMessage(message);
+	chatWindow_->addPresenceMessage(message, ChatWindow::DefaultDirection);
 }
 
 
@@ -449,7 +448,7 @@ void MUCController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> mes
 	joined_ = true;
 
 	if (message->hasSubject() && message->getBody().empty()) {
-		chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "The room subject is now: %1%")) % message->getSubject()));;
+		chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "The room subject is now: %1%")) % message->getSubject()), ChatWindow::DefaultDirection);;
 		chatWindow_->setSubject(message->getSubject());
 		doneGettingHistory_ = true;
 	}
@@ -486,7 +485,7 @@ void MUCController::handleOccupantRoleChanged(const std::string& nick, const MUC
 	std::string group(roleToGroupName(occupant.getRole()));
 	roster_->addContact(jid, realJID, nick, group, avatarManager_->getAvatarPath(jid).string());
 	roster_->getGroup(group)->setManualSort(roleToSortName(occupant.getRole()));
-	chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "%1% is now a %2%")) % nick % roleToFriendlyName(occupant.getRole())));
+	chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "%1% is now a %2%")) % nick % roleToFriendlyName(occupant.getRole())), ChatWindow::DefaultDirection);
 	if (nick == nick_) {
 		setAvailableRoomActions(occupant.getAffiliation(), occupant.getRole());
 	}
@@ -519,7 +518,7 @@ void MUCController::setOnline(bool online) {
 	} else {
 		if (shouldJoinOnReconnect_) {
 			renameCounter_ = 0;
-			chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "Trying to enter room %1%")) % toJID_.toString()));
+			chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "Trying to enter room %1%")) % toJID_.toString()), ChatWindow::DefaultDirection);
 			if (loginCheckTimer_) {
 				loginCheckTimer_->start();
 			}
diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h
index 93a1376..a845cbe 100644
--- a/Swift/Controllers/UIInterfaces/ChatWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatWindow.h
@@ -40,6 +40,8 @@ namespace Swift {
 			enum FileTransferState {WaitingForAccept, Negotiating, Transferring, Canceled, Finished, FTFailed};
 			enum WhiteboardSessionState {WhiteboardAccepted, WhiteboardTerminated, WhiteboardRejected};
 			enum BlockingState {BlockingUnsupported, IsBlocked, IsUnblocked};
+			enum Direction { UnknownDirection, DefaultDirection };
+
 			ChatWindow() {}
 			virtual ~ChatWindow() {}
 
@@ -51,8 +53,10 @@ namespace Swift {
 			 * @return id of added message (for acks);
 			 */
 			virtual std::string addAction(const std::string& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) = 0;
-			virtual void addSystemMessage(const std::string& message) = 0;
-			virtual void addPresenceMessage(const std::string& message) = 0;
+
+			virtual void addSystemMessage(const std::string& message, Direction direction) = 0;
+			virtual void addPresenceMessage(const std::string& message, Direction direction) = 0;
+
 			virtual void addErrorMessage(const std::string& message) = 0;
 			virtual void replaceMessage(const std::string& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight) = 0;
 			virtual void replaceWithAction(const std::string& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight) = 0;
diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h
index 8af65f7..4eb3bb6 100644
--- a/Swift/Controllers/UnitTest/MockChatWindow.h
+++ b/Swift/Controllers/UnitTest/MockChatWindow.h
@@ -16,9 +16,9 @@ namespace Swift {
 
 			virtual std::string addMessage(const std::string& message, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime&, const HighlightAction&) {lastMessageBody_ = message; return "";}
 			virtual std::string addAction(const std::string& message, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime&, const HighlightAction&) {lastMessageBody_ = message; return "";}
-			virtual void addSystemMessage(const std::string& /*message*/) {}
+			virtual void addSystemMessage(const std::string& /*message*/, Direction) {}
 			virtual void addErrorMessage(const std::string& /*message*/) {}
-			virtual void addPresenceMessage(const std::string& /*message*/) {}
+			virtual void addPresenceMessage(const std::string& /*message*/, Direction) {}
 
 			// File transfer related stuff
 			virtual std::string addFileTransfer(const std::string& /*senderName*/, bool /*senderIsSelf*/,const std::string& /*filename*/, const boost::uintmax_t /*sizeInBytes*/) { return 0; }
diff --git a/Swift/QtUI/ChatSnippet.cpp b/Swift/QtUI/ChatSnippet.cpp
index 4a0560b..666dd00 100644
--- a/Swift/QtUI/ChatSnippet.cpp
+++ b/Swift/QtUI/ChatSnippet.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2013 Kevin Smith
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -7,6 +7,7 @@
 #include <QFile>
 
 #include "ChatSnippet.h"
+#include <Swift/QtUI/QtSwiftUtil.h>
 
 namespace Swift {
 
@@ -39,4 +40,46 @@ QString ChatSnippet::wrapResizable(const QString& text) {
 	return "<span class='swift_resizable'>" + text + "</span>";
 }
 
+QString ChatSnippet::directionToCSS(Direction direction) {
+	return direction == RTL ? QString("rtl") : QString("ltr");
+}
+
+ChatSnippet::Direction ChatSnippet::getDirection(const std::string& message) {
+	return getDirection(P2QSTRING(message));
+}
+
+ChatSnippet::Direction ChatSnippet::getDirection(const QString& message) {
+	/*
+	for (int i = 0; i < message.size(); ++i) {
+		switch (message.at(i).direction()) {
+			case QChar::DirL:
+			case QChar::DirLRE:
+			case QChar::DirLRO:
+				return ChatSnippet::LTR;
+			case QChar::DirR:
+			case QChar::DirAL:
+			case QChar::DirRLE:
+			case QChar::DirRLO:
+				return ChatSnippet::RTL;
+			case QChar::DirEN:
+			case QChar::DirES:
+			case QChar::DirET:
+			case QChar::DirAN:
+			case QChar::DirCS:
+			case QChar::DirB:
+			case QChar::DirWS:
+			case QChar::DirON:
+			case QChar::DirS:
+			case QChar::DirPDF:
+			case QChar::DirNSM:
+			case QChar::DirBN:
+				break;
+		}
+	}
+	return ChatSnippet::LTR;
+	*/
+	return message.isRightToLeft() ? ChatSnippet::RTL : ChatSnippet::LTR;
+}
+
+
 }
diff --git a/Swift/QtUI/ChatSnippet.h b/Swift/QtUI/ChatSnippet.h
index 78e0b88..d43947f 100644
--- a/Swift/QtUI/ChatSnippet.h
+++ b/Swift/QtUI/ChatSnippet.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2013 Kevin Smith
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -15,6 +15,11 @@
 namespace Swift {
 	class ChatSnippet {
 		public:
+			enum Direction {
+				RTL,
+				LTR
+			};
+
 			ChatSnippet(bool appendToPrevious);
 			virtual ~ChatSnippet();
 
@@ -42,7 +47,12 @@ namespace Swift {
 
 			static QString timeToEscapedString(const QDateTime& time);
 
+			static Direction getDirection(const std::string& message);
+			static Direction getDirection(const QString& message);
+
 		protected:
+			static QString directionToCSS(Direction direction);
+
 			QString wrapResizable(const QString& text);
 			void setContinuationFallbackSnippet(boost::shared_ptr<ChatSnippet> continuationFallback) {
 				continuationFallback_ = continuationFallback;
diff --git a/Swift/QtUI/MessageSnippet.cpp b/Swift/QtUI/MessageSnippet.cpp
index 47aa9f8..28c44c4 100644
--- a/Swift/QtUI/MessageSnippet.cpp
+++ b/Swift/QtUI/MessageSnippet.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2013 Kevin Smith
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -11,9 +11,9 @@
 
 namespace Swift {
 
-MessageSnippet::MessageSnippet(const QString& message, const QString& sender, const QDateTime& time, const QString& iconURI, bool isIncoming, bool appendToPrevious, QtChatTheme* theme, const QString& id) : ChatSnippet(appendToPrevious) {
+MessageSnippet::MessageSnippet(const QString& message, const QString& sender, const QDateTime& time, const QString& iconURI, bool isIncoming, bool appendToPrevious, QtChatTheme* theme, const QString& id, Direction direction) : ChatSnippet(appendToPrevious) {
 	if (appendToPrevious) {
-		setContinuationFallbackSnippet(boost::shared_ptr<ChatSnippet>(new MessageSnippet(message, sender, time, iconURI, isIncoming, false, theme, id)));
+		setContinuationFallbackSnippet(boost::shared_ptr<ChatSnippet>(new MessageSnippet(message, sender, time, iconURI, isIncoming, false, theme, id, direction)));
 	}
 	if (isIncoming) {
 		if (appendToPrevious) {
@@ -32,12 +32,13 @@ MessageSnippet::MessageSnippet(const QString& message, const QString& sender, co
 		}
 	}
 
+	content_.replace("%direction%", directionToCSS(direction));
 	content_.replace("%message%", wrapResizable("<span class='swift_message'>" + escape(message) + "</span><span class='swift_ack'></span><span class='swift_receipt'></span>"));
 	content_.replace("%wrapped_sender%", wrapResizable(escape(sender)));
 	content_.replace("%sender%", escape(sender));
 	content_.replace("%time%", wrapResizable("<span class='swift_time'>" + timeToEscapedString(time) + "</span>"));
 	content_.replace("%userIconPath%", escape(iconURI));
-	content_ = "<div id='" + id + "'>" + content_ + "</div>";
+	content_ = QString("<div id='%1'>%2</div>").arg(id).arg(content_);
 	content_ = "<span class='date" + time.date().toString(Qt::ISODate) + "'>" + content_ + "</span>";
 }
 
diff --git a/Swift/QtUI/MessageSnippet.h b/Swift/QtUI/MessageSnippet.h
index 2a0ec6e..8186d19 100644
--- a/Swift/QtUI/MessageSnippet.h
+++ b/Swift/QtUI/MessageSnippet.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2013 Kevin Smith
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -15,7 +15,7 @@ class QDateTime;
 namespace Swift {
 	class MessageSnippet : public ChatSnippet {
 		public:
-			MessageSnippet(const QString& message, const QString& sender, const QDateTime& time, const QString& iconURI, bool isIncoming, bool appendToPrevious, QtChatTheme* theme, const QString& id);
+			MessageSnippet(const QString& message, const QString& sender, const QDateTime& time, const QString& iconURI, bool isIncoming, bool appendToPrevious, QtChatTheme* theme, const QString& id, Direction direction);
 			virtual ~MessageSnippet();
 			const QString& getContent() const {
 				return content_;
diff --git a/Swift/QtUI/QtChatView.cpp b/Swift/QtUI/QtChatView.cpp
index ad3ba2a..18c6e91 100644
--- a/Swift/QtUI/QtChatView.cpp
+++ b/Swift/QtUI/QtChatView.cpp
@@ -142,6 +142,7 @@ QWebElement QtChatView::snippetToDOM(boost::shared_ptr<ChatSnippet> snippet) {
 }
 
 void QtChatView::addToDOM(boost::shared_ptr<ChatSnippet> snippet) {
+	//qDebug() << snippet->getContent();
 	rememberScrolledToBottom();
 	bool insert = snippet->getAppendToPrevious();
 	QWebElement continuationElement = lastElement_.findFirst("#insert");
@@ -164,6 +165,8 @@ void QtChatView::addToDOM(boost::shared_ptr<ChatSnippet> snippet) {
 			span.setStyleProperty("font-size", sizeString);
 		}
 	}
+	//qDebug() << "-----------------";
+	//qDebug() << webPage_->mainFrame()->toHtml();
 }
 
 void QtChatView::addLastSeenLine() {
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index 237d78c..6dde1cc 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012 Kevin Smith
+ * Copyright (c) 2010-2013 Kevin Smith
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -29,6 +29,7 @@
 
 #include <boost/cstdint.hpp>
 #include <boost/format.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
 #include <boost/lexical_cast.hpp>
 
 #include <QLabel>
@@ -221,6 +222,15 @@ bool QtChatWindow::appendToPreviousCheck(QtChatWindow::PreviousMessageKind messa
 	return previousMessageKind_ == messageKind && ((senderIsSelf && previousMessageWasSelf_) || (!senderIsSelf && !previousMessageWasSelf_&& previousSenderName_ == P2QSTRING(senderName)));
 }
 
+ChatSnippet::Direction QtChatWindow::getActualDirection(const std::string& message, Direction direction) {
+	if (direction == DefaultDirection) {
+		return QCoreApplication::translate("QApplication", "QT_LAYOUT_DIRECTION") == "RTL" ? ChatSnippet::RTL : ChatSnippet::LTR;
+	}
+	else {
+		return ChatSnippet::getDirection(message);
+	}
+}
+
 void QtChatWindow::handleFontResized(int fontSizeSteps) {
 	messageLog_->resizeFont(fontSizeSteps);
 }
@@ -486,8 +496,19 @@ void QtChatWindow::updateTitleWithUnreadCount() {
 	emit titleUpdated();
 }
 
-std::string QtChatWindow::addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
-	return addMessage(linkimoticonify(P2QSTRING(message)), senderName, senderIsSelf, label, avatarPath, "", time, highlight);
+std::string QtChatWindow::addMessage(
+		const std::string& message, 
+		const std::string& senderName, 
+		bool senderIsSelf, 
+		boost::shared_ptr<SecurityLabel> label, 
+		const std::string& avatarPath, 
+		const boost::posix_time::ptime& time, 
+		const HighlightAction& highlight) {
+	return addMessage(linkimoticonify(message), senderName, senderIsSelf, label, avatarPath, "", time, highlight, ChatSnippet::getDirection(message));
+}
+
+QString QtChatWindow::linkimoticonify(const std::string& message) const {
+	return linkimoticonify(P2QSTRING(message));
 }
 
 QString QtChatWindow::linkimoticonify(const QString& message) const {
@@ -520,7 +541,17 @@ QString QtChatWindow::getHighlightSpanStart(const HighlightAction& highlight) {
 	return QString("<span style=\"color: %1; background: %2\">").arg(color).arg(background);
 }
 
-std::string QtChatWindow::addMessage(const QString &message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const QString& style, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
+std::string QtChatWindow::addMessage(
+		const QString& message, 
+		const std::string& senderName, 
+		bool senderIsSelf, 
+		boost::shared_ptr<SecurityLabel> label, 
+		const std::string& avatarPath, 
+		const QString& style, 
+		const boost::posix_time::ptime& time, 
+		const HighlightAction& highlight,
+		ChatSnippet::Direction direction) {
+
 	if (isWidgetSelected()) {
 		onAllMessagesRead();
 	}
@@ -547,7 +578,7 @@ std::string QtChatWindow::addMessage(const QString &message, const std::string &
 	}
 	QString qAvatarPath =  scaledAvatarPath.isEmpty() ? "qrc:/icons/avatar.png" : QUrl::fromLocalFile(scaledAvatarPath).toEncoded();
 	std::string id = "id" + boost::lexical_cast<std::string>(idCounter_++);
-	messageLog_->addMessageBottom(boost::shared_ptr<ChatSnippet>(new MessageSnippet(htmlString, QtUtilities::htmlEscape(P2QSTRING(senderName)), B2QDATE(time), qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id))));
+	messageLog_->addMessageBottom(boost::make_shared<MessageSnippet>(htmlString, QtUtilities::htmlEscape(P2QSTRING(senderName)), B2QDATE(time), qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id), direction));
 
 	previousMessageWasSelf_ = senderIsSelf;
 	previousSenderName_ = P2QSTRING(senderName);
@@ -593,7 +624,7 @@ int QtChatWindow::getCount() {
 }
 
 std::string QtChatWindow::addAction(const std::string &message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
-	return addMessage(" *" + linkimoticonify(P2QSTRING(message)) + "*", senderName, senderIsSelf, label, avatarPath, "font-style:italic ", time, highlight);
+	return addMessage(" *" + linkimoticonify(message) + "*", senderName, senderIsSelf, label, avatarPath, "font-style:italic ", time, highlight, ChatSnippet::getDirection(message));
 }
 
 // FIXME: Move this to a different file
@@ -627,11 +658,13 @@ std::string QtChatWindow::addFileTransfer(const std::string& senderName, bool se
 	SWIFT_LOG(debug) << "addFileTransfer" << std::endl;
 	QString ft_id = QString("ft%1").arg(P2QSTRING(boost::lexical_cast<std::string>(idCounter_++)));
 	
+	QString actionText;
 	QString htmlString;
 	QString formattedFileSize = P2QSTRING(formatSize(sizeInBytes));
 	if (senderIsSelf) {
 		// outgoing
-		htmlString = tr("Send file") + ": " + P2QSTRING(filename) + " ( " + formattedFileSize + ") <br/>" +
+		actionText = tr("Send file");
+		htmlString = actionText + ": " + P2QSTRING(filename) + " ( " + formattedFileSize + ") <br/>" +
 			"<div id='" + ft_id + "'>" +
 				buildChatWindowButton(tr("Cancel"), ButtonFileTransferCancel, ft_id) +
 				buildChatWindowButton(tr("Set Description"), ButtonFileTransferSetDescription, ft_id) +
@@ -639,7 +672,8 @@ std::string QtChatWindow::addFileTransfer(const std::string& senderName, bool se
 			"</div>";
 	} else {
 		// incoming
-		htmlString = tr("Receiving file") + ": " + P2QSTRING(filename) + " ( " + formattedFileSize  + ") <br/>" +
+		actionText = tr("Receiving file");
+		htmlString = actionText + ": " + P2QSTRING(filename) + " ( " + formattedFileSize  + ") <br/>" +
 			"<div id='" + ft_id + "'>" +
 				buildChatWindowButton(tr("Cancel"), ButtonFileTransferCancel, ft_id) +
 				buildChatWindowButton(tr("Accept"), ButtonFileTransferAcceptRequest, ft_id, P2QSTRING(filename)) +
@@ -657,7 +691,7 @@ std::string QtChatWindow::addFileTransfer(const std::string& senderName, bool se
 	}
 	QString qAvatarPath = "qrc:/icons/avatar.png";
 	std::string id = "ftmessage" + boost::lexical_cast<std::string>(idCounter_++);
-	messageLog_->addMessageBottom(boost::shared_ptr<ChatSnippet>(new MessageSnippet(htmlString, QtUtilities::htmlEscape(P2QSTRING(senderName)), B2QDATE(boost::posix_time::second_clock::local_time()), qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id))));
+	messageLog_->addMessageBottom(boost::make_shared<MessageSnippet>(htmlString, QtUtilities::htmlEscape(P2QSTRING(senderName)), B2QDATE(boost::posix_time::second_clock::local_time()), qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id), ChatSnippet::getDirection(actionText)));
 
 	previousMessageWasSelf_ = senderIsSelf;
 	previousSenderName_ = P2QSTRING(senderName);
@@ -676,12 +710,15 @@ void QtChatWindow::setFileTransferStatus(std::string id, const FileTransferState
 std::string QtChatWindow::addWhiteboardRequest(bool senderIsSelf) {
 	QString wb_id = QString("wb%1").arg(P2QSTRING(boost::lexical_cast<std::string>(idCounter_++)));
 	QString htmlString;
+	QString actionText;
 	if (senderIsSelf) {
-		htmlString = "<div id='" + wb_id + "'>" + tr("Starting whiteboard chat") + "<br />"+
+		actionText = tr("Starting whiteboard chat");
+		htmlString = "<div id='" + wb_id + "'>" + actionText + "<br />"+
 				buildChatWindowButton(tr("Cancel"), ButtonWhiteboardSessionCancel, wb_id) +
 			"</div>";
 	} else {
-		htmlString = "<div id='" + wb_id + "'>" + tr("%1 would like to start a whiteboard chat").arg(QtUtilities::htmlEscape(contact_)) + ": <br/>" +
+		actionText = tr("%1 would like to start a whiteboard chat");
+		htmlString = "<div id='" + wb_id + "'>" + actionText.arg(QtUtilities::htmlEscape(contact_)) + ": <br/>" +
 				buildChatWindowButton(tr("Cancel"), ButtonWhiteboardSessionCancel, wb_id) +
 				buildChatWindowButton(tr("Accept"), ButtonWhiteboardSessionAcceptRequest, wb_id) +
 			"</div>";
@@ -695,7 +732,7 @@ std::string QtChatWindow::addWhiteboardRequest(bool senderIsSelf) {
 	}
 	QString qAvatarPath = "qrc:/icons/avatar.png";
 	std::string id = "wbmessage" + boost::lexical_cast<std::string>(idCounter_++);
-	messageLog_->addMessageBottom(boost::shared_ptr<ChatSnippet>(new MessageSnippet(htmlString, QtUtilities::htmlEscape(contact_), B2QDATE(boost::posix_time::second_clock::local_time()), qAvatarPath, false, false, theme_, P2QSTRING(id))));
+	messageLog_->addMessageBottom(boost::make_shared<MessageSnippet>(htmlString, QtUtilities::htmlEscape(contact_), B2QDATE(boost::posix_time::second_clock::local_time()), qAvatarPath, false, false, theme_, P2QSTRING(id), ChatSnippet::getDirection(actionText)));
 
 	previousMessageWasSelf_ = false;
 	previousSenderName_ = contact_;
@@ -770,32 +807,31 @@ void QtChatWindow::addErrorMessage(const std::string& errorMessage) {
 		onAllMessagesRead();
 	}
 
-	QString errorMessageHTML(QtUtilities::htmlEscape(P2QSTRING(errorMessage)));
+	QString errorMessageHTML(linkimoticonify(errorMessage));
 	errorMessageHTML.replace("\n","<br/>");
-	messageLog_->addMessageBottom(boost::shared_ptr<ChatSnippet>(new SystemMessageSnippet("<span class=\"error\">" + errorMessageHTML + "</span>", QDateTime::currentDateTime(), false, theme_)));
+	messageLog_->addMessageBottom(boost::make_shared<SystemMessageSnippet>("<span class=\"error\">" + errorMessageHTML + "</span>", QDateTime::currentDateTime(), false, theme_, ChatSnippet::getDirection(errorMessage)));
 
 	previousMessageWasSelf_ = false;
 	previousMessageKind_ = PreviousMessageWasSystem;
 }
 
-void QtChatWindow::addSystemMessage(const std::string& message) {
+void QtChatWindow::addSystemMessage(const std::string& message, Direction direction) {
 	if (isWidgetSelected()) {
 		onAllMessagesRead();
 	}
 
-	QString messageHTML(P2QSTRING(message));
-	messageHTML = linkimoticonify(messageHTML);
-	messageLog_->addMessageBottom(boost::shared_ptr<ChatSnippet>(new SystemMessageSnippet(messageHTML, QDateTime::currentDateTime(), false, theme_)));
+	QString messageHTML = linkimoticonify(message);
+	messageLog_->addMessageBottom(boost::make_shared<SystemMessageSnippet>(messageHTML, QDateTime::currentDateTime(), false, theme_, getActualDirection(message, direction)));
 
 	previousMessageKind_ = PreviousMessageWasSystem;
 }
 
 void QtChatWindow::replaceWithAction(const std::string& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
-	replaceMessage(" *" + linkimoticonify(P2QSTRING(message)) + "*", id, time, "font-style:italic ", highlight);
+	replaceMessage(" *" + linkimoticonify(message) + "*", id, time, "font-style:italic ", highlight);
 }
 
 void QtChatWindow::replaceMessage(const std::string& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
-	replaceMessage(linkimoticonify(P2QSTRING(message)), id, time, "", highlight);
+	replaceMessage(linkimoticonify(message), id, time, "", highlight);
 }
 
 void QtChatWindow::replaceMessage(const QString& message, const std::string& id, const boost::posix_time::ptime& time, const QString& style, const HighlightAction& highlight) {
@@ -819,14 +855,13 @@ void QtChatWindow::replaceMessage(const QString& message, const std::string& id,
 	}
 }
 
-void QtChatWindow::addPresenceMessage(const std::string& message) {
+void QtChatWindow::addPresenceMessage(const std::string& message, Direction direction) {
 	if (isWidgetSelected()) {
 		onAllMessagesRead();
 	}
 
-	QString messageHTML(P2QSTRING(message));
-	messageHTML = linkimoticonify(messageHTML);
-	messageLog_->addMessageBottom(boost::shared_ptr<ChatSnippet>(new SystemMessageSnippet(messageHTML, QDateTime::currentDateTime(), false, theme_)));
+	QString messageHTML = linkimoticonify(message);
+	messageLog_->addMessageBottom(boost::make_shared<SystemMessageSnippet>(messageHTML, QDateTime::currentDateTime(), false, theme_, getActualDirection(message, direction)));
 
 	previousMessageKind_ = PreviousMessageWasPresence;
 }
@@ -897,12 +932,13 @@ void QtChatWindow::dropEvent(QDropEvent *event) {
 	if (event->mimeData()->urls().size() == 1) {
 		onSendFileRequest(Q2PSTRING(event->mimeData()->urls().at(0).toLocalFile()));
 	} else {
-		addSystemMessage("Sending of multiple files at once isn't supported at this time.");
+		std::string message(Q2PSTRING(tr("Sending of multiple files at once isn't supported at this time.")));
+		addSystemMessage(message, DefaultDirection);
 	}
 }
 
 void QtChatWindow::replaceLastMessage(const std::string& message) {
-	messageLog_->replaceLastMessage(linkimoticonify(P2QSTRING(message)));
+	messageLog_->replaceLastMessage(linkimoticonify(message));
 }
 
 void QtChatWindow::setAvailableOccupantActions(const std::vector<OccupantAction>& actions) {
@@ -1022,18 +1058,20 @@ void QtChatWindow::addMUCInvitation(const std::string& senderName, const JID& ji
 		onAllMessagesRead();
 	}
 
-	QString htmlString = QObject::tr("You've been invited to enter the %1 room.").arg(P2QSTRING(jid.toString())) + " <br/>";
+	QString message = QObject::tr("You've been invited to enter the %1 room.").arg(P2QSTRING(jid.toString())) + "\n";
+	QString htmlString = message;
 	if (!reason.empty()) {
-		htmlString += QObject::tr("Reason: %1").arg(P2QSTRING(reason)) + "<br/>";
+		htmlString += QObject::tr("Reason: %1").arg(P2QSTRING(reason)) + "\n";
 	}
 	if (!direct) {
-		htmlString += QObject::tr("This person may not have really sent this invitation!") + "<br/>";
+		htmlString += QObject::tr("This person may not have really sent this invitation!") + "\n";
 	}
+	htmlString = linkimoticonify(htmlString);
 
-	QString id = QString(ButtonMUCInvite + "%1").arg(P2QSTRING(boost::lexical_cast<std::string>(idCounter_++)));
 
+	QString id = QString(ButtonMUCInvite + "%1").arg(P2QSTRING(boost::lexical_cast<std::string>(idCounter_++)));
 	htmlString += "<div id='" + id + "'>" +
-			buildChatWindowButton(tr("Accept Invite"), ButtonMUCInvite, QtUtilities::htmlEscape(P2QSTRING(jid.toString())), QtUtilities::htmlEscape(P2QSTRING(password)), id) +
+			buildChatWindowButton(linkimoticonify(tr("Accept Invite")), ButtonMUCInvite, QtUtilities::htmlEscape(P2QSTRING(jid.toString())), QtUtilities::htmlEscape(P2QSTRING(password)), id) +
 		"</div>";
 
 	bool appendToPrevious = appendToPreviousCheck(PreviousMessageWasMUCInvite, senderName, false);
@@ -1045,7 +1083,7 @@ void QtChatWindow::addMUCInvitation(const std::string& senderName, const JID& ji
 	}
 	QString qAvatarPath = "qrc:/icons/avatar.png";
 
-	messageLog_->addMessageBottom(boost::shared_ptr<ChatSnippet>(new MessageSnippet(htmlString, QtUtilities::htmlEscape(P2QSTRING(senderName)), B2QDATE(boost::posix_time::second_clock::local_time()), qAvatarPath, false, appendToPrevious, theme_, id)));
+	messageLog_->addMessageBottom(boost::make_shared<MessageSnippet>(htmlString, QtUtilities::htmlEscape(P2QSTRING(senderName)), B2QDATE(boost::posix_time::second_clock::local_time()), qAvatarPath, false, appendToPrevious, theme_, id, ChatSnippet::getDirection(message)));
 	previousMessageWasSelf_ = false;
 	previousSenderName_ = P2QSTRING(senderName);
 	previousMessageKind_ = PreviousMessageWasMUCInvite;
diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h
index 3ccea31..a9600d4 100644
--- a/Swift/QtUI/QtChatWindow.h
+++ b/Swift/QtUI/QtChatWindow.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012 Kevin Smith
+ * Copyright (c) 2010-2013 Kevin Smith
  * Licensed under the GNU General Public License v3.
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
@@ -10,6 +10,7 @@
 #include <Swift/QtUI/QtMUCConfigurationWindow.h>
 #include <Swift/QtUI/QtAffiliationEditor.h>
 #include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/ChatSnippet.h>
 
 #include <QtTabbable.h>
 
@@ -90,9 +91,11 @@ namespace Swift {
 			~QtChatWindow();
 			std::string addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight);
 			std::string addAction(const std::string &message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight);
-			void addSystemMessage(const std::string& message);
-			void addPresenceMessage(const std::string& message);
+
+			void addSystemMessage(const std::string& message, Direction direction);
+			void addPresenceMessage(const std::string& message, Direction direction);
 			void addErrorMessage(const std::string& errorMessage);
+
 			void replaceMessage(const std::string& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight);
 			void replaceWithAction(const std::string& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight);
 			// File transfer related stuff
@@ -193,10 +196,26 @@ namespace Swift {
 			void beginCorrection();
 			void cancelCorrection();
 			void handleSettingChanged(const std::string& setting);
-			std::string addMessage(const QString& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const QString& style, const boost::posix_time::ptime& time, const HighlightAction& highlight);
-			void replaceMessage(const QString& message, const std::string& id, const boost::posix_time::ptime& time, const QString& style, const HighlightAction& highlight);
+			std::string addMessage(
+					const QString& message, 
+					const std::string& senderName, 
+					bool senderIsSelf, 
+					boost::shared_ptr<SecurityLabel> label, 
+					const std::string& avatarPath, 
+					const QString& style, 
+					const boost::posix_time::ptime& time, 
+					const HighlightAction& highlight,
+					ChatSnippet::Direction direction);
+			void replaceMessage(
+					const QString& message, 
+					const std::string& id, 
+					const boost::posix_time::ptime& time, 
+					const QString& style, 
+					const HighlightAction& highlight);
 			void handleOccupantSelectionChanged(RosterItem* item);
 			bool appendToPreviousCheck(PreviousMessageKind messageKind, const std::string& senderName, bool senderIsSelf) const;
+			static ChatSnippet::Direction getActualDirection(const std::string& message, Direction direction);
+			QString linkimoticonify(const std::string& message) const;
 			QString linkimoticonify(const QString& message) const;
 			QString getHighlightSpanStart(const HighlightAction& highlight);
 
diff --git a/Swift/QtUI/QtHistoryWindow.cpp b/Swift/QtUI/QtHistoryWindow.cpp
index 23621c6..6f22b76 100644
--- a/Swift/QtUI/QtHistoryWindow.cpp
+++ b/Swift/QtUI/QtHistoryWindow.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Catalin Badea
+ * Copyright (c) 2012-2013 Catalin Badea
  * Licensed under the simplified BSD license.
  * See Documentation/Licenses/BSD-simplified.txt for more information.
  */
@@ -13,6 +13,7 @@
 #include <string>
 
 #include <boost/shared_ptr.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
 
 #include <QTime>
 #include <QUrl>
@@ -20,6 +21,7 @@
 #include <QTextDocument>
 #include <QDateTime>
 #include <Swift/QtUI/QtScaledAvatarCache.h>
+#include <Swift/QtUI/ChatSnippet.h>
 #include <QLineEdit>
 #include "QtUtilities.h"
 
@@ -126,14 +128,14 @@ void QtHistoryWindow::addMessage(const std::string &message, const std::string &
 
 	if (addAtTheTop) {
 		bool appendToPrevious = ((senderIsSelf && previousTopMessageWasSelf_) || (!senderIsSelf && !previousTopMessageWasSelf_&& previousTopSenderName_ == P2QSTRING(senderName)));
-		conversation_->addMessageTop(boost::shared_ptr<ChatSnippet>(new MessageSnippet(messageHTML, QtUtilities::htmlEscape(P2QSTRING(senderName)), qTime, qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id))));
+		conversation_->addMessageTop(boost::shared_ptr<ChatSnippet>(new MessageSnippet(messageHTML, QtUtilities::htmlEscape(P2QSTRING(senderName)), qTime, qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id), ChatSnippet::getDirection(message))));
 
 		previousTopMessageWasSelf_ = senderIsSelf;
 		previousTopSenderName_ = P2QSTRING(senderName);
 	}
 	else {
 		bool appendToPrevious = ((senderIsSelf && previousBottomMessageWasSelf_) || (!senderIsSelf && !previousBottomMessageWasSelf_&& previousBottomSenderName_ == P2QSTRING(senderName)));
-		conversation_->addMessageBottom(boost::shared_ptr<ChatSnippet>(new MessageSnippet(messageHTML, QtUtilities::htmlEscape(P2QSTRING(senderName)), qTime, qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id))));
+		conversation_->addMessageBottom(boost::make_shared<MessageSnippet>(messageHTML, QtUtilities::htmlEscape(P2QSTRING(senderName)), qTime, qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id), ChatSnippet::getDirection(message)));
 		previousBottomMessageWasSelf_ = senderIsSelf;
 		previousBottomSenderName_ = P2QSTRING(senderName);
 	}
diff --git a/Swift/QtUI/SystemMessageSnippet.cpp b/Swift/QtUI/SystemMessageSnippet.cpp
index c78fe36..39349bc 100644
--- a/Swift/QtUI/SystemMessageSnippet.cpp
+++ b/Swift/QtUI/SystemMessageSnippet.cpp
@@ -10,12 +10,13 @@
 
 namespace Swift {
 
-SystemMessageSnippet::SystemMessageSnippet(const QString& message, const QDateTime& time, bool appendToPrevious, QtChatTheme* theme) : ChatSnippet(appendToPrevious) {
+SystemMessageSnippet::SystemMessageSnippet(const QString& message, const QDateTime& time, bool appendToPrevious, QtChatTheme* theme, Direction direction) : ChatSnippet(appendToPrevious) {
 	if (appendToPrevious) {
-		setContinuationFallbackSnippet(boost::shared_ptr<ChatSnippet>(new SystemMessageSnippet(message, time, false, theme)));
+		setContinuationFallbackSnippet(boost::shared_ptr<ChatSnippet>(new SystemMessageSnippet(message, time, false, theme, direction)));
 	}
 	content_ = theme->getStatus();
 
+	content_.replace("%direction%", directionToCSS(direction));
 	content_.replace("%message%", wrapResizable("<span class='swift_message'>" + escape(message) + "</span>"));
 	content_.replace("%shortTime%", wrapResizable(escape(time.toString("h:mm"))));
 	content_.replace("%time%", wrapResizable("<span class='swift_time'>" + timeToEscapedString(time) + "</span>"));
diff --git a/Swift/QtUI/SystemMessageSnippet.h b/Swift/QtUI/SystemMessageSnippet.h
index 69d231f..34b0d40 100644
--- a/Swift/QtUI/SystemMessageSnippet.h
+++ b/Swift/QtUI/SystemMessageSnippet.h
@@ -15,7 +15,7 @@ class QDateTime;
 namespace Swift {
 	class SystemMessageSnippet : public ChatSnippet {
 		public:
-			SystemMessageSnippet(const QString& message, const QDateTime& time, bool appendToPrevious, QtChatTheme* theme);
+			SystemMessageSnippet(const QString& message, const QDateTime& time, bool appendToPrevious, QtChatTheme* theme, Direction direction);
 			virtual ~SystemMessageSnippet();
 
 			const QString& getContent() const {return content_;}
diff --git a/Swift/resources/themes/Default/Incoming/Content.html b/Swift/resources/themes/Default/Incoming/Content.html
index eb5bdea..fb4795f 100755
--- a/Swift/resources/themes/Default/Incoming/Content.html
+++ b/Swift/resources/themes/Default/Incoming/Content.html
@@ -11,7 +11,7 @@
 							<td class="tr"></td>
 						</tr>
 						<tr>
-							<td class="message">
+							<td class="message" style="direction: %direction%">
 								%message%
 								<div class="timeStamp"><span class="name">%wrapped_sender% @</span> %time%</div>
 								<span id="insert"></span>
diff --git a/Swift/resources/themes/Default/Incoming/Context.html b/Swift/resources/themes/Default/Incoming/Context.html
index b1aca27..c6fa61c 100755
--- a/Swift/resources/themes/Default/Incoming/Context.html
+++ b/Swift/resources/themes/Default/Incoming/Context.html
@@ -11,7 +11,7 @@
 							<td class="tr"></td>
 						</tr>
 						<tr>
-							<td class="message">
+							<td class="message" style="direction: %direction%">
 									%message%
 									<div class="timeStamp"><span class="name">%sender% @</span> %time%</div>
 								<span id="insert"></span>
diff --git a/Swift/resources/themes/Default/Incoming/NextContent.html b/Swift/resources/themes/Default/Incoming/NextContent.html
index 4aec8ab..aff669b 100755
--- a/Swift/resources/themes/Default/Incoming/NextContent.html
+++ b/Swift/resources/themes/Default/Incoming/NextContent.html
@@ -1,6 +1,6 @@
 <div>
 	<div class="followUp"></div>
-	<div>
+	<div style="direction: %direction%">
 		
 		%message%
 		<div class="timeStamp">%time%</div>
diff --git a/Swift/resources/themes/Default/Incoming/NextContext.html b/Swift/resources/themes/Default/Incoming/NextContext.html
index 18b8dc4..c0a8846 100755
--- a/Swift/resources/themes/Default/Incoming/NextContext.html
+++ b/Swift/resources/themes/Default/Incoming/NextContext.html
@@ -1,5 +1,5 @@
 			<div class="followUp"></div>
-			<div>
+			<div style="direction: %direction%">
 				
 				%message%
 				<div class="timeStamp">%time%</div>
diff --git a/Swift/resources/themes/Default/Outgoing/Content.html b/Swift/resources/themes/Default/Outgoing/Content.html
index f855f56..87ca272 100755
--- a/Swift/resources/themes/Default/Outgoing/Content.html
+++ b/Swift/resources/themes/Default/Outgoing/Content.html
@@ -11,7 +11,7 @@
 							<td class="tr"></td>
 						</tr>
 						<tr>
-							<td class="message">
+							<td class="message" style="direction: %direction%">
 								%message%
 								<div class="timeStamp"><span class="name">%wrapped_sender% @</span> %time%</div>
 								<span id="insert"></span>
diff --git a/Swift/resources/themes/Default/Outgoing/Context.html b/Swift/resources/themes/Default/Outgoing/Context.html
index 7822cac..229c592 100755
--- a/Swift/resources/themes/Default/Outgoing/Context.html
+++ b/Swift/resources/themes/Default/Outgoing/Context.html
@@ -11,7 +11,7 @@
 							<td class="tr"></td>
 						</tr>
 						<tr>
-							<td class="message">
+							<td class="message" style="direction: %direction%">
 								
 								%message%
 								<div class="timeStamp"><span class="name">%sender% @</span> %time%</div>
diff --git a/Swift/resources/themes/Default/Outgoing/NextContent.html b/Swift/resources/themes/Default/Outgoing/NextContent.html
index 4367197..fe6490e 100755
--- a/Swift/resources/themes/Default/Outgoing/NextContent.html
+++ b/Swift/resources/themes/Default/Outgoing/NextContent.html
@@ -1,6 +1,6 @@
 <div>
 	<div class="followUp"></div>
-	<div>
+	<div style="direction: %direction%">
 		%message%
 		<div class="timeStamp">%time%</div>
 	</div>
diff --git a/Swift/resources/themes/Default/Outgoing/NextContext.html b/Swift/resources/themes/Default/Outgoing/NextContext.html
index 1f84771..f66aeeb 100755
--- a/Swift/resources/themes/Default/Outgoing/NextContext.html
+++ b/Swift/resources/themes/Default/Outgoing/NextContext.html
@@ -1,5 +1,5 @@
 <div class="followUp"></div>
-<div>
+<div style="direction: %direction%">
 	%message%
 	<div class="timeStamp">%time%</div>
 </div><span id="insert"></span>
diff --git a/Swift/resources/themes/Default/Status.html b/Swift/resources/themes/Default/Status.html
index b8168e8..e7add89 100755
--- a/Swift/resources/themes/Default/Status.html
+++ b/Swift/resources/themes/Default/Status.html
@@ -9,7 +9,7 @@
 							<td class="tr"></td>
 						</tr>
 						<tr>
-							<td class="message">
+							<td class="message" style="direction: %direction%">
 								%message%
 								<div class="timeStamp">%time%</div>
 							</td>
-- 
cgit v0.10.2-6-g49f6