diff options
Diffstat (limited to 'Swift/QtUI/QtHistoryWindow.cpp')
-rw-r--r-- | Swift/QtUI/QtHistoryWindow.cpp | 250 |
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); +} + +} |