source: qutecom-2.2/wengophone/src/presentation/qt/chat/QtChatWidget.cpp @ 564:378697c2381b

Last change on this file since 564:378697c2381b was 564:378697c2381b, checked in by laurent@…, 3 years ago

minor bug with google translation automator

File size: 19.6 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        _webView = new QWebView;
157        _webView->page()->mainFrame()->addToJavaScriptWindowObject("parent",this);
158        Config & config = ConfigManager::getInstance().getCurrentConfig();
159        QFile file(QString::fromStdString(config.getResourcesDir())+"chat/base.html");
160        file.open(QIODevice::ReadOnly);
161        _webView->setHtml(file.readAll());     
162}
163
164QtChatWidget::~QtChatWidget() {
165        _imChatSession->close();
166       
167        _stoppedTypingTimer->stop();
168       
169        delete _webView;
170}
171
172void QtChatWidget::profileChangedEventHandler() {
173        profileChangedEventHandlerSignal();
174}
175
176void QtChatWidget::changeFont() {
177        bool ok;
178        QFont font = QFontDialog::getFont(&ok, _ui.chatEdit->currentFont(), this);
179        if (ok) {
180                _currentFont = font;
181                _ui.chatEdit->setCurrentFont(font);
182        }
183        _ui.chatEdit->setFocus();
184}
185
186void QtChatWidget::changeFontColor() {
187        bool ok;
188        QRgb color = QColorDialog::getRgba(_ui.chatEdit->textColor().rgba(), &ok, this);
189        if (ok) {
190                _currentColor = QColor(color);
191                _ui.chatEdit->setTextColor(_currentColor);
192        }
193        _ui.chatEdit->setFocus();
194}
195
196void QtChatWidget::boldClickedSlot() {
197        _bold = !_bold;
198        if (_bold) {
199                _ui.chatEdit->setFontWeight(QFont::Bold);
200        } else {
201                _ui.chatEdit->setFontWeight(QFont::Normal);
202        }
203}
204
205void QtChatWidget::italicClickedSlot() {
206        _italic = !_italic;
207        _ui.chatEdit->setFontItalic(_italic);
208}
209
210void QtChatWidget::underlineClickedSlot() {
211        _underline = !_underline;
212        _ui.chatEdit->setFontUnderline(_underline);
213}
214
215void QtChatWidget::translate(const QString & html)
216{
217        Config & config = ConfigManager::getInstance().getCurrentConfig();     
218        QString lang = QString::fromStdString(config.getTranslationSent());     
219        QString text = html;
220       
221        if(text.isEmpty())
222                return;
223       
224        text = text.replace("\"","\\\"");
225        text = text.replace("\'","\\\'");
226       
227        QString script = QString("translate(\"\",\"\",\"%1\",\"\",\"%2\")").arg(text).arg(lang);;
228        _webView->page ()->mainFrame ()->evaluateJavaScript(script);
229}
230
231void QtChatWidget::chooseEmoticon() {
232        QPoint p = _ui.editActionBar->pos();
233        QPoint offset(EMOTICON_OFFSET_X, EMOTICON_OFFSET_Y);
234        p += offset;
235        _emoticonsWidget->move(mapToGlobal(p));
236        _emoticonsWidget->show();
237}
238
239void QtChatWidget::setVisible(bool visible) {
240        QWidget::setVisible(visible);
241        if (visible) {
242                _ui.chatEdit->setFocus();
243        }
244}
245
246void QtChatWidget::showInviteDialog() {
247        if (canDoMultiChat()) {
248                QtChatRoomInviteDlg dlg(*_imChatSession,
249                        _cChatHandler.getCUserProfile().getCContactList(), this);
250                dlg.exec();
251        }
252}
253
254void QtChatWidget::contactAddedEventHandler(IMChatSession & sender, const IMContact & imContact) {
255        contactAddedEventSignal(imContact);
256}
257
258void QtChatWidget::contactRemovedEventHandler(IMChatSession & sender, const IMContact & imContact) {
259        contactRemovedEventSignal(imContact);
260}
261
262void QtChatWidget::contactAddedEventSlot(const IMContact & imContact) {
263
264        QtContactList * qtContactList = _qtWengoPhone->getQtContactList();
265        CContactList & cContactList = qtContactList->getCContactList();
266        std::string contactId = cContactList.findContactThatOwns(imContact);
267
268        /*if (_ui.avatarFrame->getContactIDList().contains(QString::fromStdString(contactId))) {
269                LOG_DEBUG("" + imContact.getContactId() + " deja dans la session !");
270                return;
271        }
272
273        ContactProfile profile = cContactList.getContactProfile(contactId);
274
275        std::string data = profile.getIcon().getData();
276        QPixmap pixmap;
277        pixmap.loadFromData((uchar *)data.c_str(), data.size());
278        _ui.avatarFrame->addRemoteContact(
279                QString::fromStdString(contactId),
280                QString::fromUtf8(profile.getDisplayName().c_str()),
281                QString::fromStdString(imContact.getContactId()),
282                pixmap
283        );*/
284
285        QString imContactId = QString::fromStdString(imContact.getContactId());
286        addStatusMessage(tr("%1 has joined the chat").arg(imContactId));
287}
288
289void QtChatWidget::contactRemovedEventSlot(const IMContact & imContact) {
290        QString imContactId = QString::fromStdString(imContact.getContactId());
291        addStatusMessage(tr("%1 has left the chat").arg(imContactId));
292
293        /*QtContactList * qtContactList = _qtWengoPhone->getQtContactList();
294        CContactList & cContactList = qtContactList->getCContactList();
295        std::string contactId = cContactList.findContactThatOwns(imContact);
296        _ui.avatarFrame->removeRemoteContact(QString::fromStdString(contactId));*/
297}
298
299void QtChatWidget::emoticonSelected(QtEmoticon emoticon) {
300        _ui.chatEdit->insertHtml(emoticon.getHtml());
301        _ui.chatEdit->ensureCursorVisible();
302}
303
304void QtChatWidget::avatarFrameButtonClicked() {
305        /*if (_ui.avatarFrame->isVisible()) {
306                hideAvatarFrame();
307        } else {
308                showAvatarFrame();
309        }*/
310}
311
312void QtChatWidget::hideAvatarFrame() {
313        //_ui.avatarFrame->hide();
314        //_ui.avatarFrameButton->setIcon(QIcon(":pics/chat/show_avatar_frame.png"));
315}
316
317void QtChatWidget::showAvatarFrame() {
318        //_ui.avatarFrame->show();
319        //_ui.avatarFrameButton->setIcon(QIcon(":pics/chat/hide_avatar_frame.png"));
320}
321
322void QtChatWidget::addToHistory(const QString & contactId, const QString & senderName, const QString & str, const QTime & time) {
323        QTime tmp;
324        if (time.isNull()) {
325                tmp = QTime::currentTime();
326        } else {
327                tmp = time;
328        }
329        _ui.chatHistory->insertMessage(contactId, senderName, str, tmp);
330}
331
332void QtChatWidget::addStatusMessage(const QString & statusMessage) {
333        _ui.chatHistory->insertStatusMessage(statusMessage, QTime::currentTime());
334}
335
336void QtChatWidget::sendMessage() 
337{
338        if(_ui.chatEdit->toPlainText().isEmpty())
339                return;
340       
341        Config & config = ConfigManager::getInstance().getCurrentConfig();
342        QString lang = QString::fromStdString(config.getTranslationSent());
343        QString html = clearHtml(_ui.chatEdit->toHtml());
344       
345        translate(html);
346}
347
348void QtChatWidget::setIMChatSession(IMChatSession * imChatSession) {
349        IMAccount * imAccount =
350                _cChatHandler.getCUserProfile().getUserProfile().getIMAccountManager().getIMAccount(imChatSession->getIMChat().getIMAccountId());
351
352        _imChatSession = imChatSession;
353        _emoticonsWidget->initButtons(QtChatUtils::getProtocol(imAccount->getProtocol()));
354       
355        _ui.chatHistory->setProtocol(imAccount->getProtocol());
356
357        OWSAFE_DELETE(imAccount);
358
359        updateAvatarFrame();
360        updateUserAvatar();
361        if (_imChatSession->getIMContactSet().size() == 1) {
362                // It's useless to show the avatar frame if there is only one contact,
363                // since we can see its avatar when he talks.
364                hideAvatarFrame();
365        }
366
367        _imChatSession->contactAddedEvent +=
368                boost::bind(&QtChatWidget::contactAddedEventHandler, this, _1, _2);
369        _imChatSession->contactRemovedEvent +=
370                boost::bind(&QtChatWidget::contactRemovedEventHandler, this, _1, _2);
371        _imChatSession->changeTypingState(IMChat::TypingStateNotTyping);
372}
373
374void QtChatWidget::chatEditTextChanged() {
375        // change typing state to Typing
376        if (!_isTyping) {
377                _imChatSession->changeTypingState(IMChat::TypingStateTyping);
378                _isTyping = true;
379        }
380        ////
381
382        // manage timers
383        _stoppedTypingTimer->start(CHAT_STOPPED_TYPING_DELAY);
384        ////
385}
386
387void QtChatWidget::stoppedTypingSlot() {
388        _imChatSession->changeTypingState(IMChat::TypingStateStopTyping);
389        _isTyping = false;
390}
391
392void QtChatWidget::translationFinishedSlot(const QVariant  & traduction, const QVariant  &, const QVariant  &, const QVariant  & message, const QVariant  & )
393{
394        QString tmp = traduction.toString().replace("&#39;","'");
395        IMAccount * imAccount = _cChatHandler.getCUserProfile().getUserProfile().getIMAccountManager().getIMAccount(_imChatSession->getIMChat().getIMAccountId());
396        QString msg;
397       
398        if(tmp.isEmpty())
399        {
400                msg = message.toString();
401                _imChatSession->sendMessage(QtChatUtils::encodeMessage(imAccount->getProtocol(), msg).toUtf8().constData());
402        }
403        else
404        {
405                QTextDocument doc;
406                doc.setHtml(tmp);
407                msg = "<div>"+message.toString()+"</div><div style=\"color:grey\">"+doc.toPlainText()+"</div>";
408                _imChatSession->sendMessage(QtChatUtils::encodeMessage(imAccount->getProtocol(), tmp).toUtf8().constData());
409        }
410       
411        addToHistory("self", _nickName, msg);
412       
413       
414        OWSAFE_DELETE(imAccount);
415       
416        _isTyping = true;
417        _ui.chatEdit->clear();
418        _ui.chatEdit->setFocus();
419        _ui.chatEdit->ensureCursorVisible();
420       
421        //Not typing anymore
422        _imChatSession->changeTypingState(IMChat::TypingStateStopTyping);
423        _isTyping = false;
424        _stoppedTypingTimer->stop();
425}
426
427void QtChatWidget::updateAvatarFrame() {
428        QMutexLocker locker(&_mutex);
429
430        QtContactList * qtContactList = _qtWengoPhone->getQtContactList();
431        CContactList & cContactList = qtContactList->getCContactList();
432
433        IMContactSet imContactSet = _imChatSession->getIMContactSet();
434        IMContactSet::iterator it;
435        for (it = imContactSet.begin(); it != imContactSet.end(); it++) {
436
437                std::string contactId = cContactList.findContactThatOwns(*it);
438                ContactProfile profile = cContactList.getContactProfile(contactId);
439
440                std::string data = profile.getIcon().getData();
441                QPixmap pixmap;
442                if (data.size() > 0) {
443                        pixmap.loadFromData((uchar *)data.c_str(), data.size());
444                        _ui.chatHistory->setAvatarPixmap(QString::fromStdString(contactId), pixmap);
445                }
446        }
447}
448
449void QtChatWidget::updateUserAvatar() {
450
451        QPixmap pixmap;
452        UserProfile& userProfile = _cChatHandler.getCUserProfile().getUserProfile();
453        std::string myData = userProfile.getIcon().getData();
454        pixmap.loadFromData((uchar *)myData.c_str(), myData.size());
455
456        _ui.chatHistory->setAvatarPixmap("self", pixmap);
457        //_ui.avatarFrame->setUserPixmap(pixmap);
458}
459
460void QtChatWidget::sendFileToSession(const QString & filename) {
461        Config & config = ConfigManager::getInstance().getCurrentConfig();
462
463        if (!canDoFileTransfer()) {
464
465                QtContactList * qtContactList = _qtWengoPhone->getQtContactList();
466                CContactList & cContactList = qtContactList->getCContactList();
467                ContactProfile contactProfile = cContactList.getContactProfile(_contactId.toStdString());
468
469                if (contactProfile.getFirstWengoId().empty()) {
470
471                        QString myMess = tr("Your file can not be sent: your contact must be connected on the @company@ network. ");
472                        //myMess += tr("An automatic message has been sent to him");
473                        addStatusMessage(myMess);
474
475                        QString hisMess = "<i>";
476                        QString url = QString::fromStdString(config.getCompanyWebSiteUrl());
477                        hisMess += tr("Your contact wishes to send a file with @company@. ");
478                        hisMess += tr("Go to %1 to install it").arg(url);
479                        hisMess += "</i>";
480                        _imChatSession->sendMessage(hisMess.toStdString());
481                }
482                return;
483        }
484
485        QtContactList * qtContactList = _qtWengoPhone->getQtContactList();
486        CContactList & cContactList = qtContactList->getCContactList();
487        QtFileTransfer * qtFileTransfer = _qtWengoPhone->getFileTransfer();
488        if (qtFileTransfer) {
489                qtFileTransfer->createSendFileSession(_imChatSession->getIMContactSet(), filename, cContactList);
490        }
491}
492
493void QtChatWidget::saveHistoryAsHtml() {
494        _ui.chatHistory->saveHistoryAsHtml();
495}
496
497void QtChatWidget::setContactConnected(bool connected) {
498        QtContactList * qtContactList = _qtWengoPhone->getQtContactList();
499        CContactList & cContactList = qtContactList->getCContactList();
500        ContactProfile profile = cContactList.getContactProfile(_contactId.toStdString());
501
502        QString contactName;
503        if (!profile.getShortDisplayName().empty()) {
504                contactName = QString::fromUtf8(profile.getShortDisplayName().c_str());
505        } else {
506                contactName = QString::fromUtf8(profile.getDisplayName().c_str());
507        }
508
509        if (connected && !_isContactConnected) {
510                addStatusMessage(QString(tr("%1 is connected.")).arg(contactName));
511        } else if (!connected && _isContactConnected) {
512                addStatusMessage(QString(tr("%1 is disconnected.")).arg(contactName));
513        }
514
515        _isContactConnected = connected;
516}
517
518void QtChatWidget::contactChangedSlot(QString contactId) {
519
520        /*QtContactList * qtContactList = _qtWengoPhone->getQtContactList();
521        CContactList & cContactList = qtContactList->getCContactList();
522        ContactProfile profile = cContactList.getContactProfile(contactId.toStdString());
523        std::string data = profile.getIcon().getData();
524        QPixmap pixmap;
525        pixmap.loadFromData((uchar *)data.c_str(), data.size());
526        _ui.avatarFrame->updateContact(contactId, pixmap, QString::fromStdString(profile.getDisplayName()));*/
527}
528
529bool QtChatWidget::canDoFileTransfer() {
530        QtContactList * qtContactList = _qtWengoPhone->getQtContactList();
531        CContactList & cContactList = qtContactList->getCContactList();
532        ContactProfile contactProfile = cContactList.getContactProfile(_contactId.toStdString());
533
534        if (!contactProfile.getFirstWengoId().empty() && contactProfile.isAvailable()) {
535                IMContact imContact = contactProfile.getFirstAvailableWengoIMContact();
536                if ( (imContact.getPresenceState() != EnumPresenceState::PresenceStateOffline) &&
537                                (imContact.getPresenceState() != EnumPresenceState::PresenceStateUnknown) &&
538                                (imContact.getPresenceState() != EnumPresenceState::PresenceStateUnavailable)) {
539       
540                                return true;
541                }
542        }
543        return false;
544}
545
546/**
547 * Helper method to clone a key event, so that it can be send to another widget
548 */
549static QKeyEvent* cloneKeyEvent(QKeyEvent* event) {
550        return new QKeyEvent(event->type(), event->key(), event->modifiers(), event->text());
551}
552
553bool QtChatWidget::eventFilter(QObject* object, QEvent* event) {
554        if (object == _ui.chatHistory && event->type() == QEvent::KeyPress) {
555                return historyKeyPressEventFilter(static_cast<QKeyEvent*>(event));
556        }
557        if (object == _ui.chatEdit && event->type() == QEvent::KeyPress) {
558                return editKeyPressEventFilter(static_cast<QKeyEvent*>(event));
559        }
560        return false;
561}
562
563bool QtChatWidget::historyKeyPressEventFilter(QKeyEvent* event) {
564        // Set focus on edit widget if the user types a "printable" character
565        if (event->text().size() > 0 && event->text().at(0).isPrint() && _ui.chatEdit->isEnabled()) {
566                _ui.chatEdit->setFocus();
567                QKeyEvent* newEvent = cloneKeyEvent(event);
568                QApplication::postEvent(_ui.chatEdit, newEvent);
569                return true;
570        }
571        return false;
572}
573
574bool QtChatWidget::editKeyPressEventFilter(QKeyEvent* event) {
575        int key = event->key();
576       
577        if (key == Qt::Key_PageUp || key == Qt::Key_PageDown) {
578                QKeyEvent* newEvent = cloneKeyEvent(event);
579                QApplication::postEvent(_ui.chatHistory, newEvent);
580                return true;
581        }
582
583        // Send message with Enter key, unless a modifier is pressed
584        if ((key == Qt::Key_Enter || key == Qt::Key_Return) && 
585                (event->modifiers() == Qt::NoModifier || event->modifiers() == Qt::KeypadModifier)) 
586        {
587                sendMessage();
588                return true;
589        }
590
591#ifdef OS_MACOSX
592        static const int REAL_CTRL_MODIFIER = Qt::MetaModifier;
593#else
594        static const int REAL_CTRL_MODIFIER = Qt::ControlModifier;
595#endif
596        bool realCtrlPressed = event->modifiers() & REAL_CTRL_MODIFIER;
597
598        if (key == Qt::Key_Tab && realCtrlPressed) {
599                // We use realCtrlPressed because on MacOS, Qt::ControlModifier
600                // corresponds to the Command key and Command + Tab is used to switch
601                // between applications, (like Alt + Tab on Windows)
602                ctrlTabPressed();
603                return true;
604        }
605
606        return false;
607}
Note: See TracBrowser for help on using the repository browser.