Skip to content
Snippets Groups Projects
basetexteditor.cpp 177 KiB
Newer Older
    if (isReadOnly())
        return;

    if (source->hasFormat(QLatin1String("application/vnd.nokia.qtcreator.vblocktext"))) {
        QString text = QString::fromUtf8(source->data(QLatin1String("application/vnd.nokia.qtcreator.vblocktext")));
con's avatar
con committed
        if (text.isEmpty())
            return;
        QStringList lines = text.split(QLatin1Char('\n'));
        QTextCursor cursor = textCursor();
        cursor.beginEditBlock();
        int initialCursorPosition = cursor.position();
        int column = cursor.position() - cursor.block().position();
        cursor.insertText(lines.first());
        for (int i = 1; i < lines.count(); ++i) {
            QTextBlock next = cursor.block().next();
            if (next.isValid()) {
                cursor.setPosition(next.position() + qMin(column, next.length()-1));
            } else {
                cursor.movePosition(QTextCursor::EndOfBlock);
                cursor.insertBlock();
            }

            int actualColumn = cursor.position() - cursor.block().position();
            if (actualColumn < column)
                cursor.insertText(QString(column - actualColumn, QLatin1Char(' ')));
            cursor.insertText(lines.at(i));
        }
        cursor.setPosition(initialCursorPosition);
        cursor.endEditBlock();
        setTextCursor(cursor);
        ensureCursorVisible();
        return;
    }
    QString text = source->text();
    if (text.isEmpty())
        return;

    const TabSettings &ts = d->m_document->tabSettings();
    QTextCursor cursor = textCursor();
    if (!ts.m_autoIndent) {
        cursor.beginEditBlock();
        cursor.insertText(text);
        cursor.endEditBlock();
        setTextCursor(cursor);
        return;
    }

    cursor.beginEditBlock();
    cursor.removeSelectedText();
    bool insertAtBeginningOfLine = ts.cursorIsAtBeginningOfLine(cursor);

    if (insertAtBeginningOfLine
        && source->hasFormat(QLatin1String("application/vnd.nokia.qtcreator.blocktext"))) {
        text = QString::fromUtf8(source->data(QLatin1String("application/vnd.nokia.qtcreator.blocktext")));
        if (text.isEmpty())
            return;
    int reindentBlockStart = cursor.blockNumber() + (insertAtBeginningOfLine?0:1);
    bool hasFinalNewline = (text.endsWith(QLatin1Char('\n'))
                            || text.endsWith(QChar::ParagraphSeparator)
                            || text.endsWith(QLatin1Char('\r')));
    if (insertAtBeginningOfLine
        && hasFinalNewline) // since we'll add a final newline, preserve current line's indentation
        cursor.setPosition(cursor.block().position());
    int cursorPosition = cursor.position();
    cursor.insertText(text);

    int reindentBlockEnd = cursor.blockNumber() - (hasFinalNewline?1:0);

    if (reindentBlockStart < reindentBlockEnd
        || (reindentBlockStart == reindentBlockEnd
            && (!insertAtBeginningOfLine || hasFinalNewline))) {
        if (insertAtBeginningOfLine && !hasFinalNewline) {
            QTextCursor unnecessaryWhitespace = cursor;
            unnecessaryWhitespace.setPosition(cursorPosition);
            unnecessaryWhitespace.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor);
            unnecessaryWhitespace.removeSelectedText();
        QTextCursor c = cursor;
        c.setPosition(cursor.document()->findBlockByNumber(reindentBlockStart).position());
        c.setPosition(cursor.document()->findBlockByNumber(reindentBlockEnd).position(),
                      QTextCursor::KeepAnchor);
        reindent(document(), c);
    }

    cursor.endEditBlock();
    setTextCursor(cursor);
con's avatar
con committed
}

void BaseTextEditor::appendStandardContextMenuActions(QMenu *menu)
{
    menu->addSeparator();
    Core::ActionManager *am = Core::ICore::instance()->actionManager();

    QAction *a = am->command(Core::Constants::CUT)->action();
    if (a && a->isEnabled())
        menu->addAction(a);
    a = am->command(Core::Constants::COPY)->action();
    if (a && a->isEnabled())
        menu->addAction(a);
    a = am->command(Core::Constants::PASTE)->action();
    if (a && a->isEnabled())
        menu->addAction(a);
}


con's avatar
con committed
BaseTextEditorEditable::BaseTextEditorEditable(BaseTextEditor *editor)
  : e(editor)
{
    using namespace Find;
    Aggregation::Aggregate *aggregate = new Aggregation::Aggregate;
    BaseTextFind *baseTextFind = new BaseTextFind(editor);
    connect(baseTextFind, SIGNAL(highlightAll(QString, Find::IFindSupport::FindFlags)),
            editor, SLOT(highlightSearchResults(QString, Find::IFindSupport::FindFlags)));
mae's avatar
mae committed
    connect(baseTextFind, SIGNAL(findScopeChanged(QTextCursor, QTextCursor, int)),
            editor, SLOT(setFindScope(QTextCursor, QTextCursor, int)));
con's avatar
con committed
    aggregate->add(baseTextFind);
    aggregate->add(editor);

    m_cursorPositionLabel = new Utils::LineColumnLabel;
con's avatar
con committed

    QHBoxLayout *l = new QHBoxLayout;
    QWidget *w = new QWidget;
    l->setMargin(0);
    l->setContentsMargins(5, 0, 5, 0);
con's avatar
con committed
    l->addWidget(m_cursorPositionLabel);
    w->setLayout(l);

    m_toolBar = new QToolBar;
    m_toolBar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
    m_toolBar->addWidget(w);

    connect(editor, SIGNAL(cursorPositionChanged()), this, SLOT(updateCursorPosition()));
}

BaseTextEditorEditable::~BaseTextEditorEditable()
{
    delete m_toolBar;
    delete e;
}

con's avatar
con committed
QWidget *BaseTextEditorEditable::toolBar()
con's avatar
con committed
{
    return m_toolBar;
}

int BaseTextEditorEditable::find(const QString &) const
{
    return 0;
}

int BaseTextEditorEditable::currentLine() const
{
    return e->textCursor().blockNumber() + 1;
}

int BaseTextEditorEditable::currentColumn() const
{
    QTextCursor cursor = e->textCursor();
    return cursor.position() - cursor.block().position() + 1;
}

QRect BaseTextEditorEditable::cursorRect(int pos) const
{
    QTextCursor tc = e->textCursor();
    if (pos >= 0)
        tc.setPosition(pos);
    QRect result = e->cursorRect(tc);
    result.moveTo(e->viewport()->mapToGlobal(result.topLeft()));
    return result;
}

QString BaseTextEditorEditable::contents() const
{
    return e->toPlainText();
}

QString BaseTextEditorEditable::selectedText() const
{
    if (e->textCursor().hasSelection())
        return e->textCursor().selectedText();
    return QString();
}

QString BaseTextEditorEditable::textAt(int pos, int length) const
{
    QTextCursor c = e->textCursor();

    if (pos < 0)
        pos = 0;
    c.movePosition(QTextCursor::End);
    if (pos + length > c.position())
        length = c.position() - pos;

    c.setPosition(pos);
    c.setPosition(pos + length, QTextCursor::KeepAnchor);

    return c.selectedText();
}

void BaseTextEditorEditable::remove(int length)
{
    QTextCursor tc = e->textCursor();
    tc.setPosition(tc.position() + length, QTextCursor::KeepAnchor);
    tc.removeSelectedText();
}

void BaseTextEditorEditable::insert(const QString &string)
{
    QTextCursor tc = e->textCursor();
    tc.insertText(string);
}

void BaseTextEditorEditable::replace(int length, const QString &string)
{
    QTextCursor tc = e->textCursor();
    tc.setPosition(tc.position() + length, QTextCursor::KeepAnchor);
    tc.insertText(string);
}

void BaseTextEditorEditable::setCurPos(int pos)
{
    QTextCursor tc = e->textCursor();
    tc.setPosition(pos);
    e->setTextCursor(tc);
}

void BaseTextEditorEditable::select(int toPos)
{
    QTextCursor tc = e->textCursor();
    tc.setPosition(toPos, QTextCursor::KeepAnchor);
    e->setTextCursor(tc);
}

void BaseTextEditorEditable::updateCursorPosition()
{
    const QTextCursor cursor = e->textCursor();
    const QTextBlock block = cursor.block();
    const int line = block.blockNumber() + 1;
    const int column = cursor.position() - block.position();
    m_cursorPositionLabel->setText(tr("Line: %1, Col: %2").arg(line).arg(e->tabSettings().columnAt(block.text(), column)+1),
                                   tr("Line: %1, Col: 999").arg(e->blockCount()));
con's avatar
con committed
    m_contextHelpId.clear();

    if (!block.isVisible())
        e->ensureCursorVisible();

}

QString BaseTextEditorEditable::contextHelpId() const
{
    if (m_contextHelpId.isEmpty())
        emit const_cast<BaseTextEditorEditable*>(this)->contextHelpIdRequested(e->editableInterface(),
                                                                               e->textCursor().position());
    return m_contextHelpId;
}