From cc6459b1b5b4f8d7853623fe9d85817f0d14ca26 Mon Sep 17 00:00:00 2001 From: Catalin Badea Date: Mon, 16 Jul 2012 12:42:35 +0300 Subject: Allow adding top messages in the chatview. diff --git a/Swift/QtUI/QtChatView.cpp b/Swift/QtUI/QtChatView.cpp index 153e3f9..0a58517 100644 --- a/Swift/QtUI/QtChatView.cpp +++ b/Swift/QtUI/QtChatView.cpp @@ -86,13 +86,31 @@ void QtChatView::handleKeyPressEvent(QKeyEvent* event) { webView_->keyPressEvent(event); } -void QtChatView::addMessage(boost::shared_ptr snippet) { +void QtChatView::addMessageBottom(boost::shared_ptr snippet) { if (viewReady_) { addToDOM(snippet); } else { /* If this asserts, the previous queuing code was necessary and should be reinstated */ assert(false); } + + if (firstElement_.isNull()) { + firstElement_ = lastElement_; + } +} +void QtChatView::addMessageTop(boost::shared_ptr snippet) { + // save scrollbar maximum value + if (!topMessageAdded_) { + scrollBarMaximum_ = webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical); + } + topMessageAdded_ = true; + + QWebElement newElement = snippetToDOM(snippet); + firstElement_.prependOutside(newElement); + firstElement_ = newElement; + if (lastElement_.isNull()) { + lastElement_ = firstElement_; + } } QWebElement QtChatView::snippetToDOM(boost::shared_ptr snippet) { @@ -241,6 +259,13 @@ void QtChatView::scrollToBottom() { } void QtChatView::handleFrameSizeChanged() { + if (topMessageAdded_) { + // adjust new scrollbar position + int newMaximum = webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical); + webPage_->mainFrame()->setScrollBarValue(Qt::Vertical, newMaximum - scrollBarMaximum_); + topMessageAdded_ = false; + } + if (isAtBottom_) { scrollToBottom(); } @@ -283,6 +308,9 @@ void QtChatView::resizeFont(int fontSizeSteps) { void QtChatView::resetView() { lastElement_ = QWebElement(); + firstElement_ = lastElement_; + topMessageAdded_ = false; + scrollBarMaximum_ = 0; QString pageHTML = theme_->getTemplate(); pageHTML.replace("==bodyBackground==", "background-color:#e3e3e3"); pageHTML.replace(pageHTML.indexOf("%@"), 2, theme_->getBase()); @@ -386,8 +414,17 @@ void QtChatView::setMUCInvitationJoined(QString id) { } void QtChatView::handleScrollRequested(int, int dy, const QRect&) { - int pos = webPage_->mainFrame()->scrollBarValue(Qt::Vertical); - emit scrollRequested(pos - dy); + rememberScrolledToBottom(); + + int pos = webPage_->mainFrame()->scrollBarValue(Qt::Vertical) - dy; + emit scrollRequested(pos); + + if (pos == 0) { + emit scrollReachedTop(); + } + else if (pos == webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical)) { + emit scrollReachedBottom(); + } } int QtChatView::getSnippetPositionByDate(const QDate& date) { diff --git a/Swift/QtUI/QtChatView.h b/Swift/QtUI/QtChatView.h index 84771ee..d778f6f 100644 --- a/Swift/QtUI/QtChatView.h +++ b/Swift/QtUI/QtChatView.h @@ -29,7 +29,8 @@ namespace Swift { Q_OBJECT public: QtChatView(QtChatTheme* theme, QWidget* parent); - void addMessage(boost::shared_ptr snippet); + void addMessageTop(boost::shared_ptr snippet); + void addMessageBottom(boost::shared_ptr snippet); void addLastSeenLine(); void replaceLastMessage(const QString& newMessage); void replaceLastMessage(const QString& newMessage, const QString& note); @@ -51,6 +52,8 @@ namespace Swift { void fontResized(int); void logCleared(); void scrollRequested(int pos); + void scrollReachedTop(); + void scrollReachedBottom(); public slots: void copySelectionToClipboard(); @@ -76,6 +79,8 @@ namespace Swift { bool viewReady_; bool isAtBottom_; + bool topMessageAdded_; + int scrollBarMaximum_; QtWebView* webView_; QWebPage* webPage_; int fontSizeSteps_; @@ -83,6 +88,7 @@ namespace Swift { QWebElement newInsertPoint_; QWebElement lineSeparator_; QWebElement lastElement_; + QWebElement firstElement_; QWebElement document_; }; } diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index d3abaa6..82f3961 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -492,7 +492,7 @@ std::string QtChatWindow::addMessage(const std::string &message, const std::stri } QString qAvatarPath = scaledAvatarPath.isEmpty() ? "qrc:/icons/avatar.png" : QUrl::fromLocalFile(scaledAvatarPath).toEncoded(); std::string id = "id" + boost::lexical_cast(idCounter_++); - messageLog_->addMessage(boost::shared_ptr(new MessageSnippet(htmlString, Qt::escape(P2QSTRING(senderName)), B2QDATE(time), qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id)))); + messageLog_->addMessageBottom(boost::shared_ptr(new MessageSnippet(htmlString, Qt::escape(P2QSTRING(senderName)), B2QDATE(time), qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id)))); previousMessageWasSelf_ = senderIsSelf; previousSenderName_ = P2QSTRING(senderName); @@ -601,7 +601,7 @@ std::string QtChatWindow::addFileTransfer(const std::string& senderName, bool se } QString qAvatarPath = "qrc:/icons/avatar.png"; std::string id = "ftmessage" + boost::lexical_cast(idCounter_++); - messageLog_->addMessage(boost::shared_ptr(new MessageSnippet(htmlString, Qt::escape(P2QSTRING(senderName)), B2QDATE(boost::posix_time::second_clock::local_time()), qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id)))); + messageLog_->addMessageBottom(boost::shared_ptr(new MessageSnippet(htmlString, Qt::escape(P2QSTRING(senderName)), B2QDATE(boost::posix_time::second_clock::local_time()), qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id)))); previousMessageWasSelf_ = senderIsSelf; previousSenderName_ = P2QSTRING(senderName); @@ -669,7 +669,7 @@ void QtChatWindow::addErrorMessage(const std::string& errorMessage) { QString errorMessageHTML(Qt::escape(P2QSTRING(errorMessage))); errorMessageHTML.replace("\n","
"); - messageLog_->addMessage(boost::shared_ptr(new SystemMessageSnippet("" + errorMessageHTML + "", QDateTime::currentDateTime(), false, theme_))); + messageLog_->addMessageBottom(boost::shared_ptr(new SystemMessageSnippet("" + errorMessageHTML + "", QDateTime::currentDateTime(), false, theme_))); previousMessageWasSelf_ = false; previousMessageKind_ = PreviousMessageWasSystem; @@ -683,7 +683,7 @@ void QtChatWindow::addSystemMessage(const std::string& message) { QString messageHTML(Qt::escape(P2QSTRING(message))); messageHTML = P2QSTRING(Linkify::linkify(Q2PSTRING(messageHTML))); messageHTML.replace("\n","
"); - messageLog_->addMessage(boost::shared_ptr(new SystemMessageSnippet(messageHTML, QDateTime::currentDateTime(), false, theme_))); + messageLog_->addMessageBottom(boost::shared_ptr(new SystemMessageSnippet(messageHTML, QDateTime::currentDateTime(), false, theme_))); previousMessageKind_ = PreviousMessageWasSystem; } @@ -725,7 +725,7 @@ void QtChatWindow::addPresenceMessage(const std::string& message) { QString messageHTML(Qt::escape(P2QSTRING(message))); messageHTML = P2QSTRING(Linkify::linkify(Q2PSTRING(messageHTML))); messageHTML.replace("\n","
"); - messageLog_->addMessage(boost::shared_ptr(new SystemMessageSnippet(messageHTML, QDateTime::currentDateTime(), false, theme_))); + messageLog_->addMessageBottom(boost::shared_ptr(new SystemMessageSnippet(messageHTML, QDateTime::currentDateTime(), false, theme_))); previousMessageKind_ = PreviousMessageWasPresence; } @@ -922,7 +922,7 @@ void QtChatWindow::addMUCInvitation(const std::string& senderName, const JID& ji } QString qAvatarPath = "qrc:/icons/avatar.png"; - messageLog_->addMessage(boost::shared_ptr(new MessageSnippet(htmlString, Qt::escape(P2QSTRING(senderName)), B2QDATE(boost::posix_time::second_clock::local_time()), qAvatarPath, false, appendToPrevious, theme_, id))); + messageLog_->addMessageBottom(boost::shared_ptr(new MessageSnippet(htmlString, Qt::escape(P2QSTRING(senderName)), B2QDATE(boost::posix_time::second_clock::local_time()), qAvatarPath, false, appendToPrevious, theme_, id))); previousMessageWasSelf_ = false; previousSenderName_ = P2QSTRING(senderName); previousMessageKind_ = PreviousMessageWasMUCInvite; diff --git a/Swift/QtUI/QtHistoryWindow.cpp b/Swift/QtUI/QtHistoryWindow.cpp index 95a47ac..36c899c 100644 --- a/Swift/QtUI/QtHistoryWindow.cpp +++ b/Swift/QtUI/QtHistoryWindow.cpp @@ -29,6 +29,7 @@ QtHistoryWindow::QtHistoryWindow(SettingsProvider* settings, UIEventStream* even ui_.setupUi(this); theme_ = new QtChatTheme(""); + idCounter_ = 0; delete ui_.conversation_; conversation_ = new QtChatView(theme_, this); @@ -53,6 +54,8 @@ QtHistoryWindow::QtHistoryWindow(SettingsProvider* settings, UIEventStream* even 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())); } QtHistoryWindow::~QtHistoryWindow() { @@ -90,9 +93,11 @@ void QtHistoryWindow::addMessage(const std::string &message, const std::string & QDateTime qTime = B2QDATE(time); QDate date = qTime.date(); + std::string id = "id" + boost::lexical_cast(idCounter_++); + QString qAvatarPath = scaledAvatarPath.isEmpty() ? "qrc:/icons/avatar.png" : QUrl::fromLocalFile(scaledAvatarPath).toEncoded(); - conversation_->addMessage(boost::shared_ptr(new MessageSnippet(messageHTML, Qt::escape(P2QSTRING(senderName)), qTime, qAvatarPath, senderIsSelf, false, theme_, "id"))); + conversation_->addMessageBottom(boost::shared_ptr(new MessageSnippet(messageHTML, Qt::escape(P2QSTRING(senderName)), qTime, qAvatarPath, senderIsSelf, false, theme_, P2QSTRING(id)))); // keep track of the days viewable in the chatView if (!dates_.count(date)) { @@ -128,5 +133,10 @@ void QtHistoryWindow::handleScrollRequested(int pos) { ui_.calendarWidget_->setSelectedDate(currentDate_); } } +void QtHistoryWindow::handleScrollReachedTop() { +} + +void QtHistoryWindow::handleScrollReachedBottom() { +} } diff --git a/Swift/QtUI/QtHistoryWindow.h b/Swift/QtUI/QtHistoryWindow.h index 448780f..f9d9a30 100644 --- a/Swift/QtUI/QtHistoryWindow.h +++ b/Swift/QtUI/QtHistoryWindow.h @@ -31,6 +31,8 @@ namespace Swift { protected slots: void handleScrollRequested(int pos); + void handleScrollReachedTop(); + void handleScrollReachedBottom(); private: void handleSomethingSelectedChanged(RosterItem* item); @@ -41,5 +43,6 @@ namespace Swift { QtTreeWidget* conversationRoster_; std::set dates_; QDate currentDate_; + int idCounter_; }; } -- cgit v0.10.2-6-g49f6