summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCătălin Badea <catalin.badea392@gmail.com>2012-08-21 19:06:05 (GMT)
committerKevin Smith <git@kismith.co.uk>2012-08-30 20:54:18 (GMT)
commit7d0cd94de71d9e55e573e28206470439ecde3db5 (patch)
treec361caa96dac71d53a74ba76aa3dc1d349a0c59e /Swift/QtUI/QtHistoryWindow.cpp
parent6856199274e9c5e581220fccf520b8f011519d17 (diff)
downloadswift-contrib-7d0cd94de71d9e55e573e28206470439ecde3db5.zip
swift-contrib-7d0cd94de71d9e55e573e28206470439ecde3db5.tar.bz2
History dialog
Add history dialog as an experimental feature. License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details.
Diffstat (limited to 'Swift/QtUI/QtHistoryWindow.cpp')
-rw-r--r--Swift/QtUI/QtHistoryWindow.cpp250
1 files changed, 250 insertions, 0 deletions
diff --git a/Swift/QtUI/QtHistoryWindow.cpp b/Swift/QtUI/QtHistoryWindow.cpp
new file mode 100644
index 0000000..e54bd51
--- /dev/null
+++ b/Swift/QtUI/QtHistoryWindow.cpp
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2012 Catalin Badea
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <QtHistoryWindow.h>
+#include <QtTabbable.h>
+
+#include <QtSwiftUtil.h>
+#include <MessageSnippet.h>
+#include <Swiften/History/HistoryMessage.h>
+#include <string>
+
+#include <boost/shared_ptr.hpp>
+
+#include <QTime>
+#include <QUrl>
+#include <QMenu>
+#include <QTextDocument>
+#include <QDateTime>
+#include <Swift/QtUI/QtScaledAvatarCache.h>
+#include <QLineEdit>
+
+#include <boost/smart_ptr/make_shared.hpp>
+#include <boost/date_time/gregorian/gregorian.hpp>
+
+namespace Swift {
+
+QtHistoryWindow::QtHistoryWindow(SettingsProvider* settings, UIEventStream* eventStream) :
+ previousTopMessageWasSelf_(false),
+ previousBottomMessageWasSelf_(false) {
+ ui_.setupUi(this);
+
+ theme_ = new QtChatTheme("");
+ idCounter_ = 0;
+
+ delete ui_.conversation_;
+ conversation_ = new QtChatView(theme_, this, true);
+ QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ sizePolicy.setHorizontalStretch(80);
+ sizePolicy.setVerticalStretch(0);
+ conversation_->setSizePolicy(sizePolicy);
+
+ ui_.conversation_ = conversation_;
+ ui_.bottomLayout_->addWidget(conversation_);
+
+ delete ui_.conversationRoster_;
+ conversationRoster_ = new QtTreeWidget(eventStream, settings, this);
+ QSizePolicy sizePolicy2(QSizePolicy::Preferred, QSizePolicy::Expanding);
+ sizePolicy2.setVerticalStretch(80);
+ conversationRoster_->setSizePolicy(sizePolicy2);
+ ui_.conversationRoster_ = conversationRoster_;
+ ui_.bottomLeftLayout_->setDirection(QBoxLayout::BottomToTop);
+ ui_.bottomLeftLayout_->addWidget(conversationRoster_);
+
+ setWindowTitle(tr("History"));
+
+ conversationRoster_->onSomethingSelectedChanged.connect(boost::bind(&QtHistoryWindow::handleSomethingSelectedChanged, this, _1));
+ connect(conversation_, SIGNAL(scrollRequested(int)), this, SLOT(handleScrollRequested(int)));
+ connect(conversation_, SIGNAL(scrollReachedTop()), this, SLOT(handleScrollReachedTop()));
+ connect(conversation_, SIGNAL(scrollReachedBottom()), this, SLOT(handleScrollReachedBottom()));
+ connect(conversation_, SIGNAL(fontResized(int)), this, SLOT(handleFontResized(int)));
+ connect(ui_.searchBox_->lineEdit(), SIGNAL(returnPressed()), this, SLOT(handleReturnPressed()));
+ connect(ui_.calendarWidget_, SIGNAL(clicked(const QDate&)), this, SLOT(handleCalendarClicked(const QDate&)));
+ connect(ui_.calendarWidget_, SIGNAL(activated(const QDate&)), this, SLOT(handleCalendarClicked(const QDate&)));
+ connect(ui_.previousButton_, SIGNAL(clicked(bool)), this, SLOT(handlePreviousButtonClicked()));
+ connect(ui_.nextButton_, SIGNAL(clicked(bool)), this, SLOT(handleNextButtonClicked()));
+}
+
+QtHistoryWindow::~QtHistoryWindow() {
+ disconnect(conversation_, SIGNAL(scrollRequested(int)), this, SLOT(handleScrollRequested(int)));
+ disconnect(conversation_, SIGNAL(scrollReachedTop()), this, SLOT(handleScrollReachedTop()));
+ disconnect(conversation_, SIGNAL(scrollReachedBottom()), this, SLOT(handleScrollReachedBottom()));
+ disconnect(conversation_, SIGNAL(fontResized(int)), this, SLOT(handleFontResized(int)));
+ disconnect(ui_.searchBox_->lineEdit(), SIGNAL(returnPressed()), this, SLOT(handleReturnPressed()));
+ disconnect(ui_.calendarWidget_, SIGNAL(clicked(const QDate&)), this, SLOT(handleCalendarClicked(const QDate&)));
+ disconnect(ui_.calendarWidget_, SIGNAL(activated(const QDate&)), this, SLOT(handleCalendarClicked(const QDate&)));
+ disconnect(ui_.previousButton_, SIGNAL(clicked(bool)), this, SLOT(handlePreviousButtonClicked()));
+ disconnect(ui_.nextButton_, SIGNAL(clicked(bool)), this, SLOT(handleNextButtonClicked()));
+
+ delete theme_;
+ delete conversation_;
+ // TODO: delete ui_
+}
+
+void QtHistoryWindow::activate() {
+ emit wantsToActivate();
+}
+
+void QtHistoryWindow::showEvent(QShowEvent* event) {
+ emit windowOpening();
+ emit titleUpdated();
+ QWidget::showEvent(event);
+}
+
+void QtHistoryWindow::closeEvent(QCloseEvent* event) {
+ emit windowClosing();
+ event->accept();
+}
+
+void QtHistoryWindow::setRosterModel(Roster* model) {
+ conversationRoster_->setRosterModel(model);
+}
+
+void QtHistoryWindow::addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, const std::string& avatarPath, const boost::posix_time::ptime& time, bool addAtTheTop) {
+ QString scaledAvatarPath = QtScaledAvatarCache(32).getScaledAvatarPath(avatarPath.c_str());
+
+ QString messageHTML(P2QSTRING(message));
+ messageHTML = Qt::escape(messageHTML);
+ QString searchTerm = ui_.searchBox_->lineEdit()->text();
+ if (searchTerm.length()) {
+ messageHTML.replace(searchTerm, "<span style='background-color: yellow'>" + searchTerm + "</span>");
+ }
+
+ // note: time uses localtime
+ QDate date = QDate(time.date().year(), time.date().month(), time.date().day());
+ QTime dayTime = QTime(time.time_of_day().hours(), time.time_of_day().minutes(), time.time_of_day().seconds());
+ QDateTime qTime = QDateTime(date, dayTime);
+
+ std::string id = "id" + boost::lexical_cast<std::string>(idCounter_++);
+
+ QString qAvatarPath = scaledAvatarPath.isEmpty() ? "qrc:/icons/avatar.png" : QUrl::fromLocalFile(scaledAvatarPath).toEncoded();
+
+ if (addAtTheTop) {
+ bool appendToPrevious = ((senderIsSelf && previousTopMessageWasSelf_) || (!senderIsSelf && !previousTopMessageWasSelf_&& previousTopSenderName_ == P2QSTRING(senderName)));
+ conversation_->addMessageTop(boost::shared_ptr<ChatSnippet>(new MessageSnippet(messageHTML, Qt::escape(P2QSTRING(senderName)), qTime, qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id))));
+
+ previousTopMessageWasSelf_ = senderIsSelf;
+ previousTopSenderName_ = P2QSTRING(senderName);
+ }
+ else {
+ bool appendToPrevious = ((senderIsSelf && previousBottomMessageWasSelf_) || (!senderIsSelf && !previousBottomMessageWasSelf_&& previousBottomSenderName_ == P2QSTRING(senderName)));
+ conversation_->addMessageBottom(boost::shared_ptr<ChatSnippet>(new MessageSnippet(messageHTML, Qt::escape(P2QSTRING(senderName)), qTime, qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id))));
+ previousBottomMessageWasSelf_ = senderIsSelf;
+ previousBottomSenderName_ = P2QSTRING(senderName);
+ }
+
+ // keep track of the days viewable in the chatView
+ if (!dates_.count(date)) {
+ dates_.insert(date);
+ }
+}
+
+void QtHistoryWindow::handleSomethingSelectedChanged(RosterItem* item) {
+ onSelectedContactChanged(item);
+}
+
+void QtHistoryWindow::resetConversationView() {
+ previousTopMessageWasSelf_ = false;
+ previousBottomMessageWasSelf_ = false;
+ previousTopSenderName_.clear();
+ previousBottomSenderName_.clear();
+
+ dates_.clear();
+ conversation_->resetView();
+}
+
+void QtHistoryWindow::handleScrollRequested(int pos) {
+ // first message starts with offset 5
+ if (pos < 5) {
+ pos = 5;
+ }
+
+ QDate currentDate;
+ foreach (const QDate& date, dates_) {
+ int snippetPosition = conversation_->getSnippetPositionByDate(date);
+ if (snippetPosition <= pos) {
+ currentDate = date;
+ }
+ }
+
+ if (ui_.calendarWidget_->selectedDate() != currentDate) {
+ ui_.calendarWidget_->setSelectedDate(currentDate);
+ }
+}
+
+void QtHistoryWindow::handleScrollReachedTop() {
+ if (dates_.empty()) {
+ return;
+ }
+
+ int year, month, day;
+ QDate firstDate = *dates_.begin();
+ firstDate.getDate(&year, &month, &day);
+ onScrollReachedTop(boost::gregorian::date(year, month, day));
+}
+
+void QtHistoryWindow::handleScrollReachedBottom() {
+ if (dates_.empty()) {
+ return;
+ }
+
+ int year, month, day;
+ QDate lastDate = *dates_.rbegin();
+ lastDate.getDate(&year, &month, &day);
+ onScrollReachedBottom(boost::gregorian::date(year, month, day));
+}
+
+void QtHistoryWindow::handleReturnPressed() {
+ onReturnPressed(ui_.searchBox_->lineEdit()->text().toStdString());
+}
+
+void QtHistoryWindow::handleCalendarClicked(const QDate& date) {
+ int year, month, day;
+ QDate tempDate = date; // getDate discards const qualifier
+ tempDate.getDate(&year, &month, &day);
+ onCalendarClicked(boost::gregorian::date(year, month, day));
+}
+
+void QtHistoryWindow::setDate(const boost::gregorian::date& date) {
+ ui_.calendarWidget_->setSelectedDate(QDate::fromJulianDay(date.julian_day()));
+}
+
+void QtHistoryWindow::handleNextButtonClicked() {
+ onNextButtonClicked();
+}
+
+void QtHistoryWindow::handlePreviousButtonClicked() {
+ onPreviousButtonClicked();
+}
+
+void QtHistoryWindow::handleFontResized(int fontSizeSteps) {
+ conversation_->resizeFont(fontSizeSteps);
+
+ emit fontResized(fontSizeSteps);
+}
+
+void QtHistoryWindow::resetConversationViewTopInsertPoint() {
+ previousTopMessageWasSelf_ = false;
+ previousTopSenderName_ = QString();
+ conversation_->resetTopInsertPoint();
+}
+
+std::string QtHistoryWindow::getSearchBoxText() {
+ return ui_.searchBox_->lineEdit()->text().toStdString();
+}
+
+boost::gregorian::date QtHistoryWindow::getLastVisibleDate() {
+ if (!dates_.empty()) {
+ QDate lastDate = *dates_.rbegin();
+ int year, month, day;
+ lastDate.getDate(&year, &month, &day);
+
+ return boost::gregorian::date(year, month, day);
+ }
+ return boost::gregorian::date(boost::gregorian::not_a_date_time);
+}
+
+}