source: qutecom-2.2/wengophone/src/presentation/qt/chat/QtChatWidget.cpp @ 587:a5603d5e5c5c

Last change on this file since 587:a5603d5e5c5c was 587:a5603d5e5c5c, checked in by laurent@…, 3 years ago

bug fix : log chat windows

File size: 19.8 KB
Line 
1/*
2 * WengoPhone, a voice over Internet phone
3 * Copyright (C) 2004-2007  Wengo
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19
20#include "QtChatWidget.h"
21#include "QtChatUtils.h"
22#include "chatroom/QtChatRoomInviteDlg.h"
23#include "emoticons/QtEmoticonsWidget.h"
24
25#include <coipmanager/CoIpManager.h>
26#include <filesessionmanager/SendFileSession.h>
27
28#include <model/config/Config.h>
29#include <model/config/ConfigManager.h>
30#include <model/WengoPhone.h>
31#include <model/profile/Profile.h>
32#include <model/profile/UserProfile.h>
33
34#include <control/CWengoPhone.h>
35#include <control/contactlist/CContactList.h>
36#include <control/profile/CUserProfile.h>
37#include <presentation/qt/QtWengoPhone.h>
38#include <presentation/qt/contactlist/QtContactList.h>
39#include <presentation/qt/contactlist/QtContactListManager.h>
40#include <presentation/qt/filetransfer/QtFileTransfer.h>
41
42#include <imwrapper/Account.h>
43#include <imwrapper/EnumIMProtocol.h>
44#include <imwrapper/IMContactSet.h>
45
46#include <util/File.h>
47#include <util/Logger.h>
48#include <util/SafeDelete.h>
49#include <cutil/global.h>
50#include <qtutil/SafeConnect.h>
51
52#include <string>
53
54#include <QtCore/QTime>
55#include <QtCore/QTimer>
56
57#include <QtGui/QColorDialog>
58#include <QtGui/QFontDialog>
59#include <QtGui/QKeyEvent>
60#include <QtGui/QPainter>
61
62static const int CHAT_STOPPED_TYPING_DELAY = 1000;
63
64static const int EMOTICON_OFFSET_X = 13;
65static const int EMOTICON_OFFSET_Y = 30;
66
67QString clearHtml( const QString & str)
68{
69        QString html = str;
70       
71        QRegExp htmlDocumentToHtmlSnippet(".*<body[^>]*>\\s*<p[^>]*>(.*)</p>\\s*</body>\\s*</html>");
72        QRegExp pTag("<p[^>]*>");
73
74        // toHtml() returns an HTML document, complete with html and body tags.
75        // This regexp strip those to produce an HTML snippet, which can be
76        // concatenated to the existing history
77        html.replace(htmlDocumentToHtmlSnippet, "\\1");
78        html.replace(pTag, "<div>");
79        html.replace("</p>", "</div>");
80       
81        return html;
82}
83
84QtChatWidget::QtChatWidget(CChatHandler & cChatHandler,
85        QtWengoPhone * qtWengoPhone, int sessionId,
86        QWidget * parent) :
87        QWidget(parent),
88        _cChatHandler(cChatHandler),
89        _qtWengoPhone(qtWengoPhone) {
90
91        //Default nickname for testing purpose
92        _nickName = "Wengo";
93        _sessionId = sessionId;
94        _imChatSession = NULL;
95
96        _bold = false;
97        _italic = false;
98        _underline = false;
99
100        _isContactConnected = true;
101
102        //setup ui
103        _ui.setupUi(this);
104        QPixmap pix = _ui.sendButton->icon().pixmap(50,50);
105        QPainter painter(&pix);
106        painter.setPen(Qt::white);
107        painter.drawText(pix.rect(),Qt::AlignCenter,tr("send"));
108        painter.end();
109        _ui.sendButton->setIcon(QIcon(pix));
110        _ui.editActionBar->setBackgroundRole(QPalette::Base);
111        _ui.editFrame->setBackgroundRole(QPalette::Base);
112        ////
113
114        //creates sub widgets
115        _emoticonsWidget = new EmoticonsWidget(this);
116        ////
117
118        //install event filters
119        _ui.chatHistory->installEventFilter(this);
120        _ui.chatEdit->installEventFilter(this);
121        ////
122       
123        //timer
124        _isTyping = false;
125        _stoppedTypingTimer = new QTimer(this);
126        _stoppedTypingTimer->setSingleShot(true);
127        SAFE_CONNECT_RECEIVER(_stoppedTypingTimer, SIGNAL(timeout()), this, SLOT(stoppedTypingSlot()));
128        ////
129
130        //signal connection
131        SAFE_CONNECT(_ui.sendButton, SIGNAL(clicked()), SLOT(sendMessage()));
132        SAFE_CONNECT(_ui.editActionBar, SIGNAL(fontLabelClicked()), SLOT(changeFont()));
133        SAFE_CONNECT(_ui.editActionBar, SIGNAL(emoticonsLabelClicked()), SLOT(chooseEmoticon()));
134        SAFE_CONNECT(_ui.editActionBar, SIGNAL(fontColorLabelClicked()), SLOT(changeFontColor()));
135        SAFE_CONNECT(_ui.editActionBar, SIGNAL(boldLabelClicked()), SLOT(boldClickedSlot()));
136        SAFE_CONNECT(_ui.editActionBar, SIGNAL(italicLabelClicked()), SLOT(italicClickedSlot()));
137        SAFE_CONNECT(_ui.editActionBar, SIGNAL(underlineLabelClicked()), SLOT(underlineClickedSlot()));
138        SAFE_CONNECT(_emoticonsWidget, SIGNAL(emoticonClicked(QtEmoticon)), SLOT(emoticonSelected(QtEmoticon)));
139        SAFE_CONNECT_RECEIVER(_emoticonsWidget, SIGNAL(closed()), _ui.chatEdit, SLOT(setFocus()));
140        SAFE_CONNECT(_ui.chatEdit, SIGNAL(textChanged()), SLOT(chatEditTextChanged()));
141        SAFE_CONNECT(_ui.chatEdit, SIGNAL(fileDragged(const QString &)), SLOT(sendFileToSession(const QString &)));
142        SAFE_CONNECT(this, SIGNAL(contactAddedEventSignal(const IMContact &)),
143                SLOT(contactAddedEventSlot(const IMContact &)));
144        SAFE_CONNECT(this, SIGNAL(contactRemovedEventSignal(const IMContact &)),
145                SLOT(contactRemovedEventSlot(const IMContact &)));
146        //SAFE_CONNECT(_ui.avatarFrameButton, SIGNAL(clicked()), SLOT(avatarFrameButtonClicked()));
147
148        QtContactList * qtContactList = _qtWengoPhone->getQtContactList();
149        SAFE_CONNECT(qtContactList, SIGNAL(contactChangedEventSignal(QString)), SLOT(contactChangedSlot(QString)));
150
151        _cChatHandler.getCUserProfile().getUserProfile().profileChangedEvent +=
152                boost::bind(&QtChatWidget::profileChangedEventHandler, this);
153        SAFE_CONNECT_TYPE(this, SIGNAL(profileChangedEventHandlerSignal()), 
154                SLOT(updateUserAvatar()), Qt::QueuedConnection);
155               
156        //send translate message
157        _webView = new QWebView;
158        _webView->page()->mainFrame()->addToJavaScriptWindowObject("parent",this);
159        Config & config = ConfigManager::getInstance().getCurrentConfig();
160        QFile file(QString::fromStdString(config.getResourcesDir())+"chat/base.html");
161        file.open(QIODevice::ReadOnly);
162        _webView->setHtml(file.readAll());     
163
164        //load theme
165        _ui.chatHistory->setTheme(QString::fromStdString(config.getChatTheme()),QString::fromStdString(config.getChatThemeVariant()));
166}
167
168QtChatWidget::~QtChatWidget() {
169        _imChatSession->close();
170       
171        _stoppedTypingTimer->stop();
172       
173        delete _webView;
174}
175
176void QtChatWidget::profileChangedEventHandler() {
177        profileChangedEventHandlerSignal();
178}
179
180void QtChatWidget::changeFont() {
181        bool ok;
182        QFont font = QFontDialog::getFont(&ok, _ui.chatEdit->currentFont(), this);
183        if (ok) {
184                _currentFont = font;
185                _ui.chatEdit->setCurrentFont(font);
186        }
187        _ui.chatEdit->setFocus();
188}
189
190void QtChatWidget::changeFontColor() {
191        bool ok;
192        QRgb color = QColorDialog::getRgba(_ui.chatEdit->textColor().rgba(), &ok, this);
193        if (ok) {
194                _currentColor = QColor(color);
195                _ui.chatEdit->setTextColor(_currentColor);
196        }
197        _ui.chatEdit->setFocus();
198}
199
200void QtChatWidget::boldClickedSlot() {
201        _bold = !_bold;
202        if (_bold) {
203                _ui.chatEdit->setFontWeight(QFont::Bold);
204        } else {
205                _ui.chatEdit->setFontWeight(QFont::Normal);
206        }
207}
208
209void QtChatWidget::italicClickedSlot() {
210        _italic = !_italic;
211        _ui.chatEdit->setFontItalic(_italic);
212}
213
214void QtChatWidget::underlineClickedSlot() {
215        _underline = !_underline;
216        _ui.chatEdit->setFontUnderline(_underline);
217}
218
219void QtChatWidget::translate(const QString & html)
220{
221        Config & config = ConfigManager::getInstance().getCurrentConfig();     
222        QString lang = QString::fromStdString(config.getTranslationSent());     
223        QString text = html;
224       
225        if(text.isEmpty())
226                return;
227       
228        text = text.replace("\"","\\\"");
229        text = text.replace("\'","\\\'");
230       
231        QString script = QString("translate(\"\",\"\",\"%1\",\"\",\"%2\")").arg(text).arg(lang);;
232        _webView->page ()->mainFrame ()->evaluateJavaScript(script);
233}
234
235void QtChatWidget::chooseEmoticon() {
236        QPoint p = _ui.editActionBar->pos();
237        QPoint offset(EMOTICON_OFFSET_X, EMOTICON_OFFSET_Y);
238        p += offset;
239        _emoticonsWidget->move(mapToGlobal(p));
240        _emoticonsWidget->show();
241}
242
243void QtChatWidget::setVisible(bool visible) {
244        QWidget::setVisible(visible);
245        if (visible) {
246                _ui.chatEdit->setFocus();
247        }
248}
249
250void QtChatWidget::showInviteDialog() {
251        if (canDoMultiChat()) {
252                QtChatRoomInviteDlg dlg(*_imChatSession,
253                        _cChatHandler.getCUserProfile().getCContactList(), this);
254                dlg.exec();
255        }
256}
257
258void QtChatWidget::contactAddedEventHandler(IMChatSession & sender, const IMContact & imContact) {
259        contactAddedEventSignal(imContact);
260}
261
262void QtChatWidget::contactRemovedEventHandler(IMChatSession & sender, const IMContact & imContact) {
263        contactRemovedEventSignal(imContact);
264}
265
266void QtChatWidget::contactAddedEventSlot(const IMContact & imContact) {
267
268        QtContactList * qtContactList = _qtWengoPhone->getQtContactList();
269        CContactList & cContactList = qtContactList->getCContactList();
270        std::string contactId = cContactList.findContactThatOwns(imContact);
271
272        /*if (_ui.avatarFrame->getContactIDList().contains(QString::fromStdString(contactId))) {
273                LOG_DEBUG("" + imContact.getContactId() + " deja dans la session !");
274                return;
275        }
276
277        ContactProfile profile = cContactList.getContactProfile(contactId);
278
279        std::string data = profile.getIcon().getData();
280        QPixmap pixmap;
281        pixmap.loadFromData((uchar *)data.c_str(), data.size());
282        _ui.avatarFrame->addRemoteContact(
283                QString::fromStdString(contactId),
284                QString::fromUtf8(profile.getDisplayName().c_str()),
285                QString::fromStdString(imContact.getContactId()),
286                pixmap
287        );*/
288
289        QString imContactId = QString::fromStdString(imContact.getContactId());
290        addStatusMessage(tr("%1 has joined the chat").arg(imContactId));
291}
292
293void QtChatWidget::contactRemovedEventSlot(const IMContact & imContact) {
294        QString imContactId = QString::fromStdString(imContact.getContactId());
295        addStatusMessage(tr("%1 has left the chat").arg(imContactId));
296
297        /*QtContactList * qtContactList = _qtWengoPhone->getQtContactList();
298        CContactList & cContactList = qtContactList->getCContactList();
299        std::string contactId = cContactList.findContactThatOwns(imContact);
300        _ui.avatarFrame->removeRemoteContact(QString::fromStdString(contactId));*/
301}
302
303void QtChatWidget::emoticonSelected(QtEmoticon emoticon) {
304        _ui.chatEdit->insertHtml(emoticon.getHtml());
305        _ui.chatEdit->ensureCursorVisible();
306}
307
308void QtChatWidget::avatarFrameButtonClicked() {
309        /*if (_ui.avatarFrame->isVisible()) {
310                hideAvatarFrame();
311        } else {
312                showAvatarFrame();
313        }*/
314}
315
316void QtChatWidget::hideAvatarFrame() {
317        //_ui.avatarFrame->hide();
318        //_ui.avatarFrameButton->setIcon(QIcon(":pics/chat/show_avatar_frame.png"));
319}
320
321void QtChatWidget::showAvatarFrame() {
322        //_ui.avatarFrame->show();
323        //_ui.avatarFrameButton->setIcon(QIcon(":pics/chat/hide_avatar_frame.png"));
324}
325
326void QtChatWidget::addToHistory(const QString & contactId, const QString & senderName, const QString & str, const QTime & time) {
327        QTime tmp;
328        if (time.isNull()) {
329                tmp = QTime::currentTime();
330        } else {
331                tmp = time;
332        }
333        _ui.chatHistory->insertMessage(contactId, senderName, str, tmp);
334}
335
336void QtChatWidget::addStatusMessage(const QString & statusMessage) {
337        _ui.chatHistory->insertStatusMessage(statusMessage, QTime::currentTime());
338}
339
340void QtChatWidget::sendMessage() 
341{
342        if(_ui.chatEdit->toPlainText().isEmpty())
343                return;
344       
345        Config & config = ConfigManager::getInstance().getCurrentConfig();
346        QString lang = QString::fromStdString(config.getTranslationSent());
347        QString html = clearHtml(_ui.chatEdit->toHtml());
348       
349        translate(html);
350}
351
352void QtChatWidget::setIMChatSession(IMChatSession * imChatSession) {
353        IMAccount * imAccount =
354                _cChatHandler.getCUserProfile().getUserProfile().getIMAccountManager().getIMAccount(imChatSession->getIMChat().getIMAccountId());
355
356        _imChatSession = imChatSession;
357        _emoticonsWidget->initButtons(QtChatUtils::getProtocol(imAccount->getProtocol()));
358       
359        _ui.chatHistory->setProtocol(imAccount->getProtocol());
360
361        OWSAFE_DELETE(imAccount);
362
363        updateAvatarFrame();
364        updateUserAvatar();
365        if (_imChatSession->getIMContactSet().size() == 1) {
366                // It's useless to show the avatar frame if there is only one contact,
367                // since we can see its avatar when he talks.
368                hideAvatarFrame();
369        }
370
371        _imChatSession->contactAddedEvent +=
372                boost::bind(&QtChatWidget::contactAddedEventHandler, this, _1, _2);
373        _imChatSession->contactRemovedEvent +=
374                boost::bind(&QtChatWidget::contactRemovedEventHandler, this, _1, _2);
375        _imChatSession->changeTypingState(IMChat::TypingStateNotTyping);
376}
377
378void QtChatWidget::chatEditTextChanged() {
379        // change typing state to Typing
380        if (!_isTyping) {
381                _imChatSession->changeTypingState(IMChat::TypingStateTyping);
382                _isTyping = true;
383        }
384        ////
385
386        // manage timers
387        _stoppedTypingTimer->start(CHAT_STOPPED_TYPING_DELAY);
388        ////
389}
390
391void QtChatWidget::stoppedTypingSlot() {
392        _imChatSession->changeTypingState(IMChat::TypingStateStopTyping);
393        _isTyping = false;
394}
395
396void QtChatWidget::translationFinishedSlot(const QVariant  & traduction, const QVariant  &, const QVariant  &, const QVariant  & message, const QVariant  & )
397{
398        QString tmp = traduction.toString().replace("&#39;","'");
399        IMAccount * imAccount = _cChatHandler.getCUserProfile().getUserProfile().getIMAccountManager().getIMAccount(_imChatSession->getIMChat().getIMAccountId());
400        QString msg;
401       
402        if(tmp.isEmpty())
403        {
404                msg = message.toString();
405                _imChatSession->sendMessage(QtChatUtils::encodeMessage(imAccount->getProtocol(), msg).toUtf8().constData());
406        }
407        else
408        {
409                QTextDocument doc;
410                doc.setHtml(tmp);
411                msg = "<div>"+message.toString()+"</div><div style=\"color:grey\">"+doc.toPlainText()+"</div>";
412                _imChatSession->sendMessage(QtChatUtils::encodeMessage(imAccount->getProtocol(), tmp).toUtf8().constData());
413        }
414       
415        addToHistory("self", _nickName, msg);
416       
417       
418        OWSAFE_DELETE(imAccount);
419       
420        _isTyping = true;
421        _ui.chatEdit->clear();
422        _ui.chatEdit->setFocus();
423        _ui.chatEdit->ensureCursorVisible();
424       
425        //Not typing anymore
426        _imChatSession->changeTypingState(IMChat::TypingStateStopTyping);
427        _isTyping = false;
428        _stoppedTypingTimer->stop();
429}
430
431void QtChatWidget::updateAvatarFrame() {
432        QMutexLocker locker(&_mutex);
433
434        QtContactList * qtContactList = _qtWengoPhone->getQtContactList();
435        CContactList & cContactList = qtContactList->getCContactList();
436
437        IMContactSet imContactSet = _imChatSession->getIMContactSet();
438        IMContactSet::iterator it;
439        for (it = imContactSet.begin(); it != imContactSet.end(); it++) {
440
441                std::string contactId = cContactList.findContactThatOwns(*it);
442                ContactProfile profile = cContactList.getContactProfile(contactId);
443
444                std::string data = profile.getIcon().getData();
445                QPixmap pixmap;
446                if (data.size() > 0) {
447                        pixmap.loadFromData((uchar *)data.c_str(), data.size());
448                        _ui.chatHistory->setAvatarPixmap(QString::fromStdString(contactId), pixmap);
449                }
450        }
451}
452
453void QtChatWidget::updateUserAvatar() {
454
455        QPixmap pixmap;
456        UserProfile& userProfile = _cChatHandler.getCUserProfile().getUserProfile();
457        std::string myData = userProfile.getIcon().getData();
458        pixmap.loadFromData((uchar *)myData.c_str(), myData.size());
459
460        _ui.chatHistory->setAvatarPixmap("self", pixmap);
461        //_ui.avatarFrame->setUserPixmap(pixmap);
462}
463
464void QtChatWidget::sendFileToSession(const QString & filename) {
465        Config & config = ConfigManager::getInstance().getCurrentConfig();
466
467        if (!canDoFileTransfer()) {
468
469                QtContactList * qtContactList = _qtWengoPhone->getQtContactList();
470                CContactList & cContactList = qtContactList->getCContactList();
471                ContactProfile contactProfile = cContactList.getContactProfile(_contactId.toStdString());
472
473                if (contactProfile.getFirstWengoId().empty()) {
474
475                        QString myMess = tr("Your file can not be sent: your contact must be connected on the @company@ network. ");
476                        //myMess += tr("An automatic message has been sent to him");
477                        addStatusMessage(myMess);
478
479                        QString hisMess = "<i>";
480                        QString url = QString::fromStdString(config.getCompanyWebSiteUrl());
481                        hisMess += tr("Your contact wishes to send a file with @company@. ");
482                        hisMess += tr("Go to %1 to install it").arg(url);
483                        hisMess += "</i>";
484                        _imChatSession->sendMessage(hisMess.toStdString());
485                }
486                return;
487        }
488
489        QtContactList * qtContactList = _qtWengoPhone->getQtContactList();
490        CContactList & cContactList = qtContactList->getCContactList();
491        QtFileTransfer * qtFileTransfer = _qtWengoPhone->getFileTransfer();
492        if (qtFileTransfer) {
493                qtFileTransfer->createSendFileSession(_imChatSession->getIMContactSet(), filename, cContactList);
494        }
495}
496
497void QtChatWidget::saveHistoryAsHtml() {
498        _ui.chatHistory->saveHistoryAsHtml();
499}
500
501void QtChatWidget::setContactConnected(bool connected) {
502        QtContactList * qtContactList = _qtWengoPhone->getQtContactList();
503        CContactList & cContactList = qtContactList->getCContactList();
504        ContactProfile profile = cContactList.getContactProfile(_contactId.toStdString());
505
506        QString contactName;
507        if (!profile.getShortDisplayName().empty()) {
508                contactName = QString::fromUtf8(profile.getShortDisplayName().c_str());
509        } else {
510                contactName = QString::fromUtf8(profile.getDisplayName().c_str());
511        }
512
513        if (connected && !_isContactConnected) {
514                addStatusMessage(QString(tr("%1 is connected.")).arg(contactName));
515        } else if (!connected && _isContactConnected) {
516                addStatusMessage(QString(tr("%1 is disconnected.")).arg(contactName));
517        }
518
519        _isContactConnected = connected;
520}
521
522void QtChatWidget::contactChangedSlot(QString contactId) {
523
524        /*QtContactList * qtContactList = _qtWengoPhone->getQtContactList();
525        CContactList & cContactList = qtContactList->getCContactList();
526        ContactProfile profile = cContactList.getContactProfile(contactId.toStdString());
527        std::string data = profile.getIcon().getData();
528        QPixmap pixmap;
529        pixmap.loadFromData((uchar *)data.c_str(), data.size());
530        _ui.avatarFrame->updateContact(contactId, pixmap, QString::fromStdString(profile.getDisplayName()));*/
531}
532
533bool QtChatWidget::canDoFileTransfer() {
534        QtContactList * qtContactList = _qtWengoPhone->getQtContactList();
535        CContactList & cContactList = qtContactList->getCContactList();
536        ContactProfile contactProfile = cContactList.getContactProfile(_contactId.toStdString());
537
538        if (!contactProfile.getFirstWengoId().empty() && contactProfile.isAvailable()) {
539                IMContact imContact = contactProfile.getFirstAvailableWengoIMContact();
540                if ( (imContact.getPresenceState() != EnumPresenceState::PresenceStateOffline) &&
541                                (imContact.getPresenceState() != EnumPresenceState::PresenceStateUnknown) &&
542                                (imContact.getPresenceState() != EnumPresenceState::PresenceStateUnavailable)) {
543       
544                                return true;
545                }
546        }
547        return false;
548}
549
550/**
551 * Helper method to clone a key event, so that it can be send to another widget
552 */
553static QKeyEvent* cloneKeyEvent(QKeyEvent* event) {
554        return new QKeyEvent(event->type(), event->key(), event->modifiers(), event->text());
555}
556
557bool QtChatWidget::eventFilter(QObject* object, QEvent* event) {
558        if (object == _ui.chatHistory && event->type() == QEvent::KeyPress) {
559                return historyKeyPressEventFilter(static_cast<QKeyEvent*>(event));
560        }
561        if (object == _ui.chatEdit && event->type() == QEvent::KeyPress) {
562                return editKeyPressEventFilter(static_cast<QKeyEvent*>(event));
563        }
564        return false;
565}
566
567bool QtChatWidget::historyKeyPressEventFilter(QKeyEvent* event) {
568        // Set focus on edit widget if the user types a "printable" character
569        if (event->text().size() > 0 && event->text().at(0).isPrint() && _ui.chatEdit->isEnabled()) {
570                _ui.chatEdit->setFocus();
571                QKeyEvent* newEvent = cloneKeyEvent(event);
572                QApplication::postEvent(_ui.chatEdit, newEvent);
573                return true;
574        }
575        return false;
576}
577
578bool QtChatWidget::editKeyPressEventFilter(QKeyEvent* event) {
579        int key = event->key();
580       
581        if (key == Qt::Key_PageUp || key == Qt::Key_PageDown) {
582                QKeyEvent* newEvent = cloneKeyEvent(event);
583                QApplication::postEvent(_ui.chatHistory, newEvent);
584                return true;
585        }
586
587        // Send message with Enter key, unless a modifier is pressed
588        if ((key == Qt::Key_Enter || key == Qt::Key_Return) && 
589                (event->modifiers() == Qt::NoModifier || event->modifiers() == Qt::KeypadModifier)) 
590        {
591                sendMessage();
592                return true;
593        }
594
595#ifdef OS_MACOSX
596        static const int REAL_CTRL_MODIFIER = Qt::MetaModifier;
597#else
598        static const int REAL_CTRL_MODIFIER = Qt::ControlModifier;
599#endif
600        bool realCtrlPressed = event->modifiers() & REAL_CTRL_MODIFIER;
601
602        if (key == Qt::Key_Tab && realCtrlPressed) {
603                // We use realCtrlPressed because on MacOS, Qt::ControlModifier
604                // corresponds to the Command key and Command + Tab is used to switch
605                // between applications, (like Alt + Tab on Windows)
606                ctrlTabPressed();
607                return true;
608        }
609
610        return false;
611}
Note: See TracBrowser for help on using the repository browser.