Ejemplo n.º 1
0
// This function overrides the QWidget::event() and should return true if the
// event was recognized, otherwise it should return false. If the recognized
// event was accepted (see QEvent::accepted), any further processing such as
// event propagation to the parent widget stops.
bool TCommandLine::event(QEvent* event)
{
    const Qt::KeyboardModifiers allModifiers = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier | Qt::KeypadModifier | Qt::GroupSwitchModifier;
    if (event->type() == QEvent::KeyPress) {
        auto * ke = dynamic_cast<QKeyEvent*>(event);

        // Shortcut for keypad keys
        if ((ke->modifiers() & Qt::KeypadModifier) && mpKeyUnit->processDataStream(ke->key(), (int)ke->modifiers())) {
            ke->accept();
            return true;

        }

        switch (ke->key()) {
        case Qt::Key_Space:
            if ((ke->modifiers() & (allModifiers & ~(Qt::ShiftModifier))) == Qt::NoModifier) {
                // Ignore the <SHIFT> modifier only - keeps some users happy!
                mTabCompletionCount = -1;
                mAutoCompletionCount = -1;
                mTabCompletionTyped.clear();
                mAutoCompletionTyped.clear();
                if (mpHost->mAutoClearCommandLineAfterSend) {
                    mHistoryBuffer = -1;
                } else {
                    mHistoryBuffer = 0;
                }
                mLastCompletion.clear();
                break;

            } else {
                // Process as a possible key binding if there are ANY modifiers
                // other than just a <SHIFT> one; may actaully be configured as
                // a non-breaking space when used with a modifier!
                return processPotentialKeyBinding(ke);

            }

        case Qt::Key_Backtab:
            // <BACKTAB> is usually internally generated by SHIFT used in
            // conjunction with TAB - so ignore just the SHIFT key:
            if ((ke->modifiers() & (allModifiers & ~(Qt::ShiftModifier))) == Qt::ControlModifier) {
                // Switch to PREVIOUS profile tab when used with <CTRL> (and
                // implicit <SHIFT>):
                int currentIndex = mudlet::self()->mpTabBar->currentIndex();
                int count = mudlet::self()->mpTabBar->count();
                if (currentIndex - 1 < 0) {
                    mudlet::self()->mpTabBar->setCurrentIndex(count - 1);
                } else {
                    mudlet::self()->mpTabBar->setCurrentIndex(currentIndex - 1);
                }
                ke->accept();
                return true;

            } else if ((ke->modifiers() & (allModifiers & ~(Qt::ShiftModifier))) ==  Qt::NoModifier) {
                // Process as plain <BACKTAB> - (ignoring implicit <SHIFT>)
                handleTabCompletion(false);
                adjustHeight();
                ke->accept();
                return true;

            } else {
                // Process as a possible key binding if there are ANY modifiers
                // other than just the ignored <SHIFT> and the possible <CTRL>:
                return processPotentialKeyBinding(ke);

            }

        case Qt::Key_Tab:
            if ((ke->modifiers() & allModifiers) == Qt::ControlModifier) {
                // Switch to NEXT profile tab
                int currentIndex = mudlet::self()->mpTabBar->currentIndex();
                int count = mudlet::self()->mpTabBar->count();
                if (currentIndex + 1 < count) {
                    mudlet::self()->mpTabBar->setCurrentIndex(currentIndex + 1);
                } else {
                    mudlet::self()->mpTabBar->setCurrentIndex(0);
                }
                ke->accept();
                return true;

            } else if ((ke->modifiers() & allModifiers) == Qt::NoModifier) {
                handleTabCompletion(true);
                ke->accept();
                return true;

            } else {
                // Process as a possible key binding if there are ANY modifiers
                // other than just the Ctrl one
                // CHECKME: What about system foreground application switching?
                return processPotentialKeyBinding(ke);

            }

        case Qt::Key_unknown:
            qWarning() << "ERROR: key unknown!";
            break;

        case Qt::Key_Backspace:
            if ((ke->modifiers() & (allModifiers & ~(Qt::ControlModifier|Qt::ShiftModifier))) == Qt::NoModifier) {
                // Ignore state of <CTRL> and <SHIFT> keys
                if (mpHost->mAutoClearCommandLineAfterSend) {
                    mHistoryBuffer = -1;
                } else {
                    mHistoryBuffer = 0;
                }

                if (mTabCompletionTyped.size() >= 1) {
                    mTabCompletionTyped.chop(1);
                    mAutoCompletionTyped.chop(1);
                }
                mTabCompletionCount = -1;
                mAutoCompletionCount = -1;
                mLastCompletion.clear();
                QPlainTextEdit::event(event);

                adjustHeight();

                return true;
            } else {
                // Process as a possible key binding if there are ANY modifiers
                // other than <CTRL> and/or <SHIFT>
                return processPotentialKeyBinding(ke);

            }

        case Qt::Key_Delete:
            if ((ke->modifiers() & allModifiers) == Qt::NoModifier) {
                if (mpHost->mAutoClearCommandLineAfterSend) {
                    mHistoryBuffer = -1;
                } else {
                    mHistoryBuffer = 0;
                }

                if (mTabCompletionTyped.size() >= 1) {
                    mTabCompletionTyped.chop(1);
                    mAutoCompletionTyped.chop(1);
                } else {
                    mTabCompletionTyped.clear();
                    mAutoCompletionTyped.clear();
                    mUserKeptOnTyping = false;
                }
                mAutoCompletionCount = -1;
                mTabCompletionCount = -1;
                mLastCompletion.clear();
                QPlainTextEdit::event(event);
                adjustHeight();
                return true;

            } else {
                // Process as a possible key binding if there are ANY modifiers
                return processPotentialKeyBinding(ke);

            }

        case Qt::Key_Return: // This is the main one (not the keypad)
            if ((ke->modifiers() & allModifiers) == Qt::ControlModifier) {
                // If Ctrl-Return is pressed - scroll to the bottom of text:
                mpConsole->mLowerPane->mCursorY = mpConsole->buffer.size();
                mpConsole->mLowerPane->hide();
                mpConsole->buffer.mCursorY = mpConsole->buffer.size();
                mpConsole->mUpperPane->mCursorY = mpConsole->buffer.size();
                mpConsole->mUpperPane->mIsTailMode = true;
                mpConsole->mUpperPane->updateScreenView();
                mpConsole->mUpperPane->forceUpdate();
                ke->accept();
                return true;

            } else if ((ke->modifiers() & allModifiers) == Qt::ShiftModifier) {
                textCursor().insertBlock();
                ke->accept();
                return true;

            } else if ((ke->modifiers() & allModifiers) == Qt::NoModifier) {
                // Do the normal return key stuff only if NO modifiers are used:
                enterCommand(ke);
                mAutoCompletionCount = -1;
                mAutoCompletionTyped.clear();
                mLastCompletion.clear();
                mTabCompletionTyped.clear();
                mUserKeptOnTyping = false;
                mTabCompletionCount = -1;
                if (mpHost->mAutoClearCommandLineAfterSend) {
                    clear();
                    mHistoryBuffer = -1;
                } else {
                    mHistoryBuffer = 0;
                }
                adjustHeight();
                ke->accept();
                return true;

            } else {
                // Process as a possible key binding if there are ANY modifiers,
                // other than just the Shift or just the Control modifiers
                return processPotentialKeyBinding(ke);

            }

        case Qt::Key_Enter:
            // This is usually the Keypad one, so may come with
            // the keypad modifier - but if so it may never be reached because
            // of the keypad modifier interception done before this switch...
            if ((ke->modifiers() & (allModifiers & ~(Qt::KeypadModifier))) == Qt::NoModifier) {
                // Do the "normal" return key action if no or just the keypad
                // modifier is present:
                enterCommand(ke);
                mTabCompletionCount = -1;
                mAutoCompletionCount = -1;
                mLastCompletion.clear();
                mTabCompletionTyped.clear();
                mAutoCompletionTyped.clear();
                mUserKeptOnTyping = false;
                if (mpHost->mAutoClearCommandLineAfterSend) {
                    clear();
                    mHistoryBuffer = -1;
                } else {
                    mHistoryBuffer = 0;
                }
                adjustHeight();
                ke->accept();
                return true;

            } else {
                // Process as a possible key binding if there are ANY modifiers,
                // other than just the Keypad modifier
                return processPotentialKeyBinding(ke);

            }

        case Qt::Key_Down:
#if defined(Q_OS_MACOS)
            if ((ke->modifiers() & allModifiers) == (Qt::ControlModifier|Qt::KeypadModifier)) {
#else
            if ((ke->modifiers() & allModifiers) == Qt::ControlModifier) {
#endif
                // If EXACTLY <Ctrl>-Down is pressed (special case for macOs -
                // also sets KeyPad modifier)
                moveCursor(QTextCursor::Down, QTextCursor::MoveAnchor);
                ke->accept();
                return true;

#if defined(Q_OS_MACOS)
            } else if ((ke->modifiers() & allModifiers) == Qt::KeypadModifier) {
#else
            } else if ((ke->modifiers() & allModifiers) == Qt::NoModifier) {
#endif
                // If EXACTLY Down is pressed without modifiers (special case
                // for macOs - also sets KeyPad modifier)
                historyDown(ke);
                ke->accept();
                return true;

            } else {
                // Process as a possible key binding if there are ANY modifiers,
                // other than just the Control modifier (or keypad modifier on
                // macOs)
                return processPotentialKeyBinding(ke);

            }

        case Qt::Key_Up:
#if defined(Q_OS_MACOS)
            if ((ke->modifiers() & allModifiers) == (Qt::ControlModifier|Qt::KeypadModifier)) {
#else
            if ((ke->modifiers() & allModifiers) == Qt::ControlModifier) {
#endif
                // If EXACTLY <Ctrl>-Up is pressed (special case for macOs -
                // also sets KeyPad modifier)
                moveCursor(QTextCursor::Up, QTextCursor::MoveAnchor);
                ke->accept();
                return true;

#if defined(Q_OS_MACOS)
            } else if ((ke->modifiers() & allModifiers) == Qt::KeypadModifier) {
#else
            } else if ((ke->modifiers() & allModifiers) == Qt::NoModifier) {
#endif
                // If EXACTLY Up is pressed without modifiers (special case for
                // macOs - also sets KeyPad modifier)
                historyUp(ke);
                ke->accept();
                return true;

            } else {
                // Process as a possible key binding if there are ANY modifiers,
                // other than just the Control modifier (or keypad modifier on
                // macOs)
                return processPotentialKeyBinding(ke);

            }

        case Qt::Key_Escape:
            if ((ke->modifiers() & allModifiers) == Qt::NoModifier) {
                // Escape from tab completion mode if used with NO modifiers
                selectAll();
                mAutoCompletion = false;
                mTabCompletion = false;
                mTabCompletionTyped.clear();
                mAutoCompletionTyped.clear();
                mUserKeptOnTyping = false;
                mTabCompletionCount = -1;
                mAutoCompletionCount = -1;
                setPalette(mRegularPalette);
                if (mpHost->mAutoClearCommandLineAfterSend) {
                    mHistoryBuffer = -1;
                } else {
                    mHistoryBuffer = 0;
                }
                ke->accept();
                return true;

            } else {
                // Process as a possible key binding if there are ANY modifiers,
                return processPotentialKeyBinding(ke);

            }

        case Qt::Key_PageUp:
            if ((ke->modifiers() & allModifiers) == Qt::NoModifier) {
                mpConsole->scrollUp(mpHost->mScreenHeight);
                ke->accept();
                return true;

            } else {
                // Process as a possible key binding if there are ANY modifiers,
                return processPotentialKeyBinding(ke);

            }

        case Qt::Key_PageDown:
            if ((ke->modifiers() & allModifiers) == Qt::NoModifier) {
                mpConsole->scrollDown(mpHost->mScreenHeight);
                ke->accept();
                return true;

            } else {
                // Process as a possible key binding if there are ANY modifiers,
                return processPotentialKeyBinding(ke);

            }

        case Qt::Key_C:
            if (((ke->modifiers() & allModifiers) == Qt::ControlModifier)
                && (mpConsole->mUpperPane->mSelectedRegion != QRegion(0, 0, 0, 0))) {

                // Only process as a Control-C if it is EXACTLY those two keys
                // and no other AND there is a selection active in the TConsole
                mpConsole->mUpperPane->slot_copySelectionToClipboard();
                ke->accept();
                return true;

            } else {
                // Process as a possible key binding if there are ANY modifiers,
                if (processPotentialKeyBinding(ke)) {
                    return true;

                } else {
                    processNormalKey(event);
                    return false;

                }
            }

        default:
            // Process as a possible key binding if there are ANY modifiers,
            if (processPotentialKeyBinding(ke)) {
                return true;

            } else {
                processNormalKey(event);
                return false;

            }
        }
    }

    return QPlainTextEdit::event(event);
}

void TCommandLine::focusInEvent(QFocusEvent* event)
{
    textCursor().movePosition(QTextCursor::Start);
    textCursor().movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, mSelectedText.length());

    mpConsole->mUpperPane->forceUpdate();
    mpConsole->mLowerPane->forceUpdate();
    QPlainTextEdit::focusInEvent(event);
}
Ejemplo n.º 2
0
bool TCommandLine::event( QEvent * event )
{
    if( event->type() == QEvent::KeyPress )
    {
        QKeyEvent *ke = static_cast<QKeyEvent *>( event );
        //qDebug()<<"modifier="<<ke->modifiers()<<" key="<<ke->key();
        switch( ke->key() )
        {
            case Qt::Key_Space:
                mTabCompletionCount = -1;
                mAutoCompletionCount = -1;
                mTabCompletionTyped = "";
                mAutoCompletionTyped = "";
                if( mpHost->mAutoClearCommandLineAfterSend )
                    mHistoryBuffer = -1;
                else
                    mHistoryBuffer = 0;
                mLastCompletion = "";
                break;

            case Qt::Key_Backtab:
                handleTabCompletion( false );
                ke->accept();
                adjustHeight();
                return true;
                break;

            case Qt::Key_Tab:
                handleTabCompletion( true );
                ke->accept();
                return true;
                break;

            case Qt::Key_unknown:
                qWarning()<<"ERROR: key unknown!";
                break;

            case Qt::Key_Backspace:
                if( mpHost->mAutoClearCommandLineAfterSend )
                    mHistoryBuffer = -1;
                else
                    mHistoryBuffer = 0;
                if( mTabCompletionTyped.size() >= 1 )
                {
                    mTabCompletionTyped.chop(1);
                    mAutoCompletionTyped.chop(1);
                    mTabCompletionCount = -1;
                    mAutoCompletionCount = -1;
                    mLastCompletion = "";
                }
                else
                {
                    mTabCompletionCount = -1;
                    mAutoCompletionCount = -1;
                    mLastCompletion = "";
                }
                QPlainTextEdit::event(event);

                adjustHeight();

                return true;

            case Qt::Key_Delete:
                if( mpHost->mAutoClearCommandLineAfterSend )
                    mHistoryBuffer = -1;
                else
                    mHistoryBuffer = 0;
                if( mTabCompletionTyped.size() >= 1 )
                {
                    mTabCompletionTyped.chop(1);
                    mAutoCompletionTyped.chop(1);
                    mTabCompletionCount = -1;
                    mAutoCompletionCount = -1;
                    mLastCompletion = "";
                }
                else
                {
                    mTabCompletionCount = -1;
                    mAutoCompletionCount = -1;
                    mLastCompletion = "";
                    mTabCompletionTyped = "";
                    mAutoCompletionTyped = "";
                    mUserKeptOnTyping = false;
                    mTabCompletionCount = -1;
                    mAutoCompletionCount = -1;
                }
                QPlainTextEdit::event(event);
                adjustHeight();
                return true;
                break;

            case Qt::Key_Return:
                if( ke->modifiers() & Qt::ControlModifier )
                {
                    mpConsole->console2->mCursorY = mpConsole->buffer.size();//
                    mpConsole->console2->hide();
                    mpConsole->buffer.mCursorY = mpConsole->buffer.size();
                    mpConsole->console->mCursorY = mpConsole->buffer.size();//
                    mpConsole->console->mIsTailMode = true;
                    mpConsole->console->updateScreenView();
                    mpConsole->console->forceUpdate();
                    ke->accept();
                    return true;
                }
                else if( ke->modifiers() & Qt::ShiftModifier )
                {
                    textCursor().insertBlock();
                    /*if( ! textCursor().movePosition(QTextCursor::Down, QTextCursor::KeepAnchor) )
                    {
                        textCursor().insertBlock();
                    }*/
                    ke->accept();
                    return true;
                }
                else
                {
                    enterCommand(ke);
                    mTabCompletionCount = -1;
                    mAutoCompletionCount = -1;
                    mLastCompletion = "";
                    mTabCompletionTyped = "";
                    mAutoCompletionTyped = "";
                    mUserKeptOnTyping = false;
                    mTabCompletionCount = -1;
                    mAutoCompletionCount = -1;
                    if( mpHost->mAutoClearCommandLineAfterSend )
                    {
                        clear();
                        mHistoryBuffer = -1;
                    }
                    else
                        mHistoryBuffer = 0;
                    adjustHeight();
                    ke->accept();
                    return true;
                }
                break;

            case Qt::Key_Enter:
                enterCommand(ke);
                mTabCompletionCount = -1;
                mAutoCompletionCount = -1;
                mLastCompletion = "";
                mTabCompletionTyped = "";
                mAutoCompletionTyped = "";
                mUserKeptOnTyping = false;
                mTabCompletionCount = -1;
                mAutoCompletionCount = -1;
                if( mpHost->mAutoClearCommandLineAfterSend )
                {
                    clear();
                    mHistoryBuffer = -1;
                }
                else
                    mHistoryBuffer = 0;
                adjustHeight();
                ke->accept();
                return true;
                break;

            case Qt::Key_Down:
                if( ke->modifiers() & Qt::ControlModifier )
                {
                    moveCursor(QTextCursor::Down, QTextCursor::MoveAnchor);
                    ke->accept();
                    return true;
                }
                else
                {
                    historyDown(ke);
                    ke->accept();
                    return true;
                }
                break;

            case Qt::Key_Up:
                if( ke->modifiers() & Qt::ControlModifier )
                {
                    moveCursor(QTextCursor::Up, QTextCursor::MoveAnchor );
                    ke->accept();
                    return true;
                }
                else
                {
                    historyUp(ke);
                    ke->accept();
                    return true;
                }
                break;

            case Qt::Key_Escape:

                selectAll();
                mAutoCompletion = false;
                mTabCompletion = false;
                mTabCompletionTyped = "";
                mAutoCompletionTyped = "";
                mUserKeptOnTyping = false;
                mTabCompletionCount = -1;
                mAutoCompletionCount = -1;
                setPalette( mRegularPalette );
                if( mpHost->mAutoClearCommandLineAfterSend )
                    mHistoryBuffer = -1;
                else
                    mHistoryBuffer = 0;
                ke->accept();
                return true;
                break;

            case Qt::Key_PageUp:
                mpConsole->scrollUp( mpHost->mScreenHeight );
                ke->accept();
                return true;
                break;

            case Qt::Key_PageDown:
                mpConsole->scrollDown( mpHost->mScreenHeight );
                ke->accept();
                return true;
                break;

            case Qt::Key_C:
                if( ke->modifiers() & Qt::ControlModifier )
                {
                     if( mpConsole->console->mSelectedRegion != QRegion( 0, 0, 0, 0 ) )
                     {
                         mpConsole->console->copySelectionToClipboard();
                         ke->accept();
                         return true;
                     }
                }
                break;

            default:

                if( mpKeyUnit->processDataStream( ke->key(), (int)ke->modifiers() ) )
                {
                    ke->accept();
                    return true;
                }
                else
                {
                    QPlainTextEdit::event( event );
                    adjustHeight();

                    if( mpHost->mAutoClearCommandLineAfterSend )
                        mHistoryBuffer = -1;
                    else
                        mHistoryBuffer = 0;
                    if( mTabCompletionOld != toPlainText() )//text() )
                    {
                        mUserKeptOnTyping = true;
                        mAutoCompletionCount = -1;
                    }
                    else
                    {
                        mUserKeptOnTyping = false;
                    }
                    spellCheck();
                    return false;
                }
        }

    }

    return QPlainTextEdit::event( event );
}