summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/QtUI/QtChatWindow.cpp')
-rw-r--r--Swift/QtUI/QtChatWindow.cpp59
1 files changed, 36 insertions, 23 deletions
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index 47eeac0..574a0a2 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -25,107 +25,95 @@
#include <QMimeData>
#include <QPushButton>
#include <QSplitter>
#include <QString>
#include <QTextDocument>
#include <QTextEdit>
#include <QTime>
#include <QToolButton>
#include <QUrl>
#include <QMimeData>
#include <Swiften/Base/Log.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
#include <Swift/Controllers/Roster/Roster.h>
#include <Swift/Controllers/Roster/RosterItem.h>
#include <Swift/Controllers/Settings/SettingsProvider.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <Swift/Controllers/UIEvents/SendFileUIEvent.h>
#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h>
#include <SwifTools/TabComplete.h>
#include <Swift/QtUI/Roster/QtOccupantListWidget.h>
#include <Swift/QtUI/QtAddBookmarkWindow.h>
#include <Swift/QtUI/QtPlainChatView.h>
#include <Swift/QtUI/QtSettingsProvider.h>
#include <Swift/QtUI/QtScaledAvatarCache.h>
#include <Swift/QtUI/QtTextEdit.h>
#include <Swift/QtUI/QtUISettingConstants.h>
#include <Swift/QtUI/QtUtilities.h>
#include <Swift/QtUI/QtWebKitChatView.h>
namespace Swift {
-QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings) : QtTabbable(), contact_(contact), eventStream_(eventStream), blockingState_(BlockingUnsupported), isMUC_(false), supportsImpromptuChat_(false) {
+QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings) : QtTabbable(), contact_(contact), nextAlertId_(0), eventStream_(eventStream), blockingState_(BlockingUnsupported), isMUC_(false), supportsImpromptuChat_(false) {
settings_ = settings;
unreadCount_ = 0;
inputEnabled_ = true;
completer_ = NULL;
affiliationEditor_ = NULL;
theme_ = theme;
isCorrection_ = false;
labelModel_ = NULL;
correctionEnabled_ = Maybe;
fileTransferEnabled_ = Maybe;
updateTitleWithUnreadCount();
#ifdef SWIFT_EXPERIMENTAL_FT
setAcceptDrops(true);
#endif
alertStyleSheet_ = "background: rgb(255, 255, 153); color: black";
QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, this);
layout->setContentsMargins(0,0,0,0);
layout->setSpacing(2);
- alertWidget_ = new QWidget(this);
- QHBoxLayout* alertLayout = new QHBoxLayout(alertWidget_);
- layout->addWidget(alertWidget_);
- alertLabel_ = new QLabel(this);
- alertLayout->addWidget(alertLabel_);
- alertButton_ = new QPushButton(this);
- connect (alertButton_, SIGNAL(clicked()), this, SLOT(handleAlertButtonClicked()));
- alertLayout->addWidget(alertButton_);
- QPalette palette = alertWidget_->palette();
- palette.setColor(QPalette::Window, QColor(Qt::yellow));
- palette.setColor(QPalette::WindowText, QColor(Qt::black));
- alertWidget_->setStyleSheet(alertStyleSheet_);
- alertLabel_->setStyleSheet(alertStyleSheet_);
- alertWidget_->hide();
+ alertLayout_ = new QVBoxLayout(this);
+ layout->addLayout(alertLayout_);
subjectLayout_ = new QBoxLayout(QBoxLayout::LeftToRight);
subject_ = new QLineEdit(this);
subjectLayout_->addWidget(subject_);
setSubject("");
subject_->setReadOnly(true);
QPushButton* actionButton_ = new QPushButton(this);
actionButton_->setIcon(QIcon(":/icons/actions.png"));
connect(actionButton_, SIGNAL(clicked()), this, SLOT(handleActionButtonClicked()));
subject_->hide();
layout->addLayout(subjectLayout_);
logRosterSplitter_ = new QSplitter(this);
logRosterSplitter_->setAutoFillBackground(true);
layout->addWidget(logRosterSplitter_);
if (settings_->getSetting(QtUISettingConstants::USE_PLAIN_CHATS) || settings_->getSetting(QtUISettingConstants::USE_SCREENREADER)) {
messageLog_ = new QtPlainChatView(this, eventStream_);
}
else {
messageLog_ = new QtWebKitChatView(this, eventStream_, theme, this); // I accept that passing the ChatWindow in so that the view can call the signals is somewhat inelegant, but it saves a lot of boilerplate. This patch is unpleasant enough already. So let's fix this soon (it at least needs fixing by the time history is sorted), but not now.
}
logRosterSplitter_->addWidget(messageLog_);
treeWidget_ = new QtOccupantListWidget(eventStream_, settings_, QtTreeWidget::MessageDefaultJID, this);
treeWidget_->hide();
logRosterSplitter_->addWidget(treeWidget_);
logRosterSplitter_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
connect(logRosterSplitter_, SIGNAL(splitterMoved(int, int)), this, SLOT(handleSplitterMoved(int, int)));
midBar_ = new QWidget(this);
//layout->addWidget(midBar);
midBar_->setAutoFillBackground(true);
QHBoxLayout *midBarLayout = new QHBoxLayout(midBar_);
@@ -182,129 +170,154 @@ QtChatWindow::QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventSt
settings_->onSettingChanged.connect(boost::bind(&QtChatWindow::handleSettingChanged, this, _1));
messageLog_->showEmoticons(settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS));
}
QtChatWindow::~QtChatWindow() {
if (mucConfigurationWindow_) {
delete mucConfigurationWindow_.data();
}
}
void QtChatWindow::handleSettingChanged(const std::string& setting) {
if (setting == QtUISettingConstants::SHOW_EMOTICONS.getKey()) {
bool showEmoticons = settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS);
messageLog_->showEmoticons(showEmoticons);
}
}
void QtChatWindow::handleLogCleared() {
onLogCleared();
}
void QtChatWindow::handleOccupantSelectionChanged(RosterItem* item) {
onOccupantSelectionChanged(dynamic_cast<ContactRosterItem*>(item));
}
void QtChatWindow::handleFontResized(int fontSizeSteps) {
messageLog_->resizeFont(fontSizeSteps);
}
void QtChatWindow::handleAlertButtonClicked() {
onAlertButtonClicked();
}
-void QtChatWindow::setAlert(const std::string& alertText, const std::string& buttonText) {
- alertLabel_->setText(alertText.c_str());
+QtChatWindow::AlertID QtChatWindow::addAlert(const std::string& alertText, const std::string& buttonText) {
+ QWidget* alertWidget = new QWidget(this);
+ QHBoxLayout* alertLayout = new QHBoxLayout(alertWidget);
+ alertLayout_->addWidget(alertWidget);
+ QLabel* alertLabel = new QLabel(this);
+ alertLayout->addWidget(alertLabel);
+ alertButton_ = new QPushButton(this);
+ connect (alertButton_, SIGNAL(clicked()), this, SLOT(handleAlertButtonClicked()));
+ alertLayout->addWidget(alertButton_);
+ QPalette palette = alertWidget->palette();
+ palette.setColor(QPalette::Window, QColor(Qt::yellow));
+ palette.setColor(QPalette::WindowText, QColor(Qt::black));
+ alertWidget->setStyleSheet(alertStyleSheet_);
+ alertLabel->setStyleSheet(alertStyleSheet_);
+
+ alertLabel->setText(alertText.c_str());
if (buttonText.empty()) {
alertButton_->hide();
} else {
alertButton_->setText(buttonText.c_str());
alertButton_->show();
}
- alertWidget_->show();
+
+ AlertID id = nextAlertId_++;
+ alertWidgets_[id] = alertWidget;
+ return id;
}
-void QtChatWindow::cancelAlert() {
- alertWidget_->hide();
+void QtChatWindow::removeAlert(const AlertID id) {
+ std::map<AlertID, QWidget*>::iterator i = alertWidgets_.find(id);
+ if (i != alertWidgets_.end()) {
+ alertLayout_->removeWidget(i->second);
+ delete i->second;
+ alertWidgets_.erase(i);
+ }
}
void QtChatWindow::setTabComplete(TabComplete* completer) {
completer_ = completer;
}
void QtChatWindow::handleKeyPressEvent(QKeyEvent* event) {
event->ignore();
if (event->isAccepted()) {
return;
}
event->accept();
int key = event->key();
if (key == Qt::Key_Tab) {
tabComplete();
} else if ((key == Qt::Key_Up) && input_->toPlainText().isEmpty() && !(lastSentMessage_.isEmpty())) {
beginCorrection();
} else if (key == Qt::Key_Down && isCorrection_ && input_->textCursor().atBlockEnd()) {
cancelCorrection();
} else if (key == Qt::Key_Down || key == Qt::Key_Up) {
/* Drop */
} else {
messageLog_->handleKeyPressEvent(event);
}
}
void QtChatWindow::beginCorrection() {
if (correctionEnabled_ == ChatWindow::Maybe) {
- setAlert(Q2PSTRING(tr("This chat may not support message correction. If you send a correction anyway, it may appear as a duplicate message")));
+ correctingAlert_ = addAlert(Q2PSTRING(tr("This chat may not support message correction. If you send a correction anyway, it may appear as a duplicate message")));
} else if (correctionEnabled_ == ChatWindow::No) {
- setAlert(Q2PSTRING(tr("This chat does not support message correction. If you send a correction anyway, it will appear as a duplicate message")));
+ correctingAlert_ = addAlert(Q2PSTRING(tr("This chat does not support message correction. If you send a correction anyway, it will appear as a duplicate message")));
}
QTextCursor cursor = input_->textCursor();
cursor.select(QTextCursor::Document);
cursor.beginEditBlock();
cursor.insertText(QString(lastSentMessage_));
cursor.endEditBlock();
isCorrection_ = true;
correctingLabel_->show();
input_->setStyleSheet(alertStyleSheet_);
labelsWidget_->setEnabled(false);
}
void QtChatWindow::cancelCorrection() {
- cancelAlert();
+ if (correctingAlert_) {
+ removeAlert(*correctingAlert_);
+ correctingAlert_.reset();
+ }
QTextCursor cursor = input_->textCursor();
cursor.select(QTextCursor::Document);
cursor.removeSelectedText();
isCorrection_ = false;
correctingLabel_->hide();
input_->setStyleSheet(qApp->styleSheet());
labelsWidget_->setEnabled(true);
}
QByteArray QtChatWindow::getSplitterState() {
return logRosterSplitter_->saveState();
}
void QtChatWindow::handleChangeSplitterState(QByteArray state) {
logRosterSplitter_->restoreState(state);
}
void QtChatWindow::handleSplitterMoved(int, int) {
emit splitterMoved();
}
void QtChatWindow::tabComplete() {
if (!completer_) {
return;
}
QTextCursor cursor;
if (tabCompleteCursor_.hasSelection()) {
cursor = tabCompleteCursor_;
} else {
cursor = input_->textCursor();
while(cursor.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor) && cursor.document()->characterAt(cursor.position() - 1) != ' ') { }
}
QString root = cursor.selectedText();
if (root.isEmpty()) {