示例#1
0
文件: editor.cpp 项目: KDE/abakus
void Editor::autoComplete( const QString& item )
{
    if( !d->autoCompleteEnabled || item.isEmpty() )
        return;

    int para = 0, curPos = 0;
    getCursorPosition( &para, &curPos );

    QString subtext = text().left( curPos );
    Tokens tokens = Evaluator::scan( subtext );

    if( !tokens.valid() || tokens.count() < 1 )
        return;

    Token lastToken = tokens[ tokens.count()-1 ];
    if( !lastToken.isIdentifier() )
        return;

    QStringList str = QStringList::split( ':', item );

    blockSignals( true );
    setSelection( 0, lastToken.pos(), 0, lastToken.pos()+lastToken.text().length() );
    insert( str[0] );
    blockSignals( false );
}
示例#2
0
void Editor::doMatchingRight()
{
    // Tokenize the expression.
    const int currentPosition = textCursor().position();

    // Check for left par.
    QString subtext = text().right(text().length() - currentPosition);
    Tokens tokens = m_evaluator->scan(subtext);
    if (!tokens.valid() || tokens.count() < 1)
        return;
    Token firstToken = tokens.at(0);

    // Left par?
    if (firstToken.type() == Token::stxOpenPar && firstToken.pos() == 0) {
        // Find the matching right par.
        unsigned par = 1;
        int k = 0;
        Token matchToken;
        int matchPosition = -1;

        for (k = 1; k < tokens.count() && par > 0; ++k) {
            const Token matchToken = tokens.at(k);
            switch (matchToken.type()) {
                case Token::stxOpenPar : ++par; break;
                case Token::stxClosePar: --par; break;
                default:;
            }
            matchPosition = matchToken.pos();
        }

        if (par == 0) {
            QTextEdit::ExtraSelection hilite1;
            hilite1.cursor = textCursor();
            hilite1.cursor.setPosition(currentPosition+matchPosition);
            hilite1.cursor.setPosition(currentPosition+matchPosition + 1, QTextCursor::KeepAnchor);
            hilite1.format.setBackground(m_highlighter->colorForRole(SyntaxHighlighter::Matched));

            QTextEdit::ExtraSelection hilite2;
            hilite2.cursor = textCursor();
            hilite2.cursor.setPosition(currentPosition+firstToken.pos());
            hilite2.cursor.setPosition(currentPosition+firstToken.pos() + 1, QTextCursor::KeepAnchor);
            hilite2.format.setBackground(m_highlighter->colorForRole(SyntaxHighlighter::Matched));

            QList<QTextEdit::ExtraSelection> extras;
            extras << hilite1;
            extras << hilite2;
            setExtraSelections(extras);
        }
    }
}
示例#3
0
文件: editor.cpp 项目: KDE/abakus
void Editor::doMatchingRight()
{
    if( !d->syntaxHighlightEnabled ) return;

    // tokenize the expression
    int para = 0, curPos = 0;
    getCursorPosition( &para, &curPos );

    // check for left par
    QString subtext = text().right( text().length() - curPos );
    Tokens tokens = Evaluator::scan( subtext );
    if( !tokens.valid() ) return;
    if( tokens.count()<1 ) return;
    Token firstToken = tokens[ 0 ];

    // left par ?
    if( firstToken.isOperator() )
    if( firstToken.asOperator() == Token::LeftPar )
    if( firstToken.pos() == 0 )
    {
        // find the matching right par
        unsigned par = 1;
        unsigned int k = 0;
        Token matchToken;
        int matchPos = -1;

        for( k = 1; k < tokens.count(); k++ )
        {
            if( par < 1 ) break;
            Token matchToken = tokens[k];
            if( matchToken.isOperator() )
            {
    if( matchToken.asOperator() == Token::LeftPar )
        par++;
    if( matchToken.asOperator() == Token::RightPar )
        par--;
    if( par == 0 ) matchPos = matchToken.pos();
            }
        }

        if( matchPos >= 0 )
        {
            setSelection( 0, curPos+matchPos, 0, curPos+matchPos+1, 2 );
            setSelection( 0, curPos+firstToken.pos(), 0, curPos+firstToken.pos()+1, 1 );
            setCursorPosition( para, curPos );
        }
    }

}
示例#4
0
static QString tokenizeFormula(const QString& formula)
{
  Formula f;
  QString expr = formula;
  expr.prepend( '=' );
  f.setExpression( expr );
  Tokens tokens = f.tokens();

  QString resultCodes;
  if( tokens.valid() )
    for( int i = 0; i < tokens.count(); i++ )
      resultCodes.append( encodeTokenType( tokens[i] ) );

  return resultCodes;
}
示例#5
0
void Editor::doMatchingLeft()
{
    // Tokenize the expression.
    const int currentPosition = textCursor().position();

    // Check for right par.
    QString subtext = text().left(currentPosition);
    Tokens tokens = m_evaluator->scan(subtext, Evaluator::NoAutoFix);
    if (!tokens.valid() || tokens.count() < 1)
        return;
    Token lastToken = tokens.at(tokens.count() - 1);

    // Right par?
    if (lastToken.type() == Token::stxClosePar && lastToken.pos() == currentPosition - 1) {
        // Find the matching left par.
        unsigned par = 1;
        int matchPosition = -1;

        for (int i = tokens.count() - 2; i >= 0 && par > 0; --i) {
            Token matchToken = tokens.at(i);
            switch (matchToken.type()) {
                case Token::stxOpenPar : --par; break;
                case Token::stxClosePar: ++par; break;
                default:;
            }
            matchPosition = matchToken.pos();
        }

        if (par == 0) {
            QTextEdit::ExtraSelection hilite1;
            hilite1.cursor = textCursor();
            hilite1.cursor.setPosition(matchPosition);
            hilite1.cursor.setPosition(matchPosition + 1, QTextCursor::KeepAnchor);
            hilite1.format.setBackground(m_highlighter->colorForRole(SyntaxHighlighter::Matched));

            QTextEdit::ExtraSelection hilite2;
            hilite2.cursor = textCursor();
            hilite2.cursor.setPosition(lastToken.pos());
            hilite2.cursor.setPosition(lastToken.pos() + 1, QTextCursor::KeepAnchor);
            hilite2.format.setBackground(m_highlighter->colorForRole(SyntaxHighlighter::Matched));

            QList<QTextEdit::ExtraSelection> extras;
            extras << hilite1;
            extras << hilite2;
            setExtraSelections(extras);
        }
    }
}
示例#6
0
void Editor::autoComplete(const QString& item)
{
    if (!m_isAutoCompletionEnabled || item.isEmpty())
        return;

    const int currentPosition = textCursor().position();
    const QString subtext = text().left(currentPosition);
    const Tokens tokens = m_evaluator->scan(subtext);
    if (!tokens.valid() || tokens.count() < 1)
        return;

    const Token lastToken = tokens.at(tokens.count() - 1);
    if (!lastToken.isIdentifier())
        return;

    const QStringList str = item.split(':');

    blockSignals(true);
    QTextCursor cursor = textCursor();
    cursor.setPosition(lastToken.pos());
    cursor.setPosition(lastToken.pos() + lastToken.text().length(), QTextCursor::KeepAnchor);
    setTextCursor(cursor);
    insert(str.at(0));
    blockSignals(false);

    cursor = textCursor();
    bool hasParensAlready;
    if ((hasParensAlready = cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor))) {
        QString nextChar = cursor.selectedText();
        hasParensAlready = (nextChar == "(");
    }
    bool shouldAutoInsertParens = (FunctionRepo::instance()->find(str.at(0))
                                   || m_evaluator->hasUserFunction(str.at(0)))
                                  && !hasParensAlready;
    if (shouldAutoInsertParens) {
        insert(QString::fromLatin1("()"));
        cursor = textCursor();
        cursor.movePosition(QTextCursor::PreviousCharacter);
        setTextCursor(cursor);
    }
}
示例#7
0
QString Calligra::Sheets::Odf::encodeFormula(const QString& expr, const KLocale* locale)
{
    // use locale settings
    const QString decimal = locale ? locale->decimalSymbol() : ".";

    QString result('=');

    Formula formula;
    Tokens tokens = formula.scan(expr, locale);

    if (!tokens.valid() || tokens.count() == 0)
        return expr; // no altering on error

    for (int i = 0; i < tokens.count(); ++i) {
        const QString tokenText = tokens[i].text();
        const Token::Type type = tokens[i].type();

        switch (type) {
        case Token::Cell:
        case Token::Range: {
            result.append('[');
            // FIXME Stefan: Hack to get the apostrophes right. Fix and remove!
            const int pos = tokenText.lastIndexOf('!');
            if (pos != -1 && tokenText.left(pos).contains(' '))
                result.append(Region::saveOdf('\'' + tokenText.left(pos) + '\'' + tokenText.mid(pos)));
            else
                result.append(Region::saveOdf(tokenText));
            result.append(']');
            break;
        }
        case Token::Float: {
            QString tmp(tokenText);
            result.append(tmp.replace(decimal, "."));
            break;
        }
        case Token::Operator: {
            if (tokens[i].asOperator() == Token::Equal)
                result.append('=');
            else
                result.append(tokenText);
            break;
        }
        case Token::Identifier: {
            if (tokenText == "ERRORTYPE") {
                // need to replace this
                result.append("ERROR.TYPE");
            } else if (tokenText == "LEGACYNORMSDIST") {
                result.append("LEGACY.NORMSDIST");
            } else if (tokenText == "LEGACYNORMSINV") {
                result.append("LEGACY.NORMSINV");
            } else {
                // dump it out unchanged
                result.append(tokenText);
            }
            break;

        }
        case Token::Boolean:
        case Token::Integer:
        case Token::String:
        default:
            result.append(tokenText);
            break;
        }
    }
    return result;
}
示例#8
0
文件: editor.cpp 项目: KDE/abakus
void Editor::triggerAutoComplete()
{
    if( !d->autoCompleteEnabled ) return;

    // tokenize the expression (don't worry, this is very fast)
    // faster now that it uses flex. ;)
    int para = 0, curPos = 0;
    getCursorPosition( &para, &curPos );
    QString subtext = text().left( curPos );
    Tokens tokens = Evaluator::scan( subtext );
    if(!tokens.valid())
    {
        kdWarning() << "invalid tokens.\n";
        return;
    }

    if(tokens.isEmpty() || subtext.endsWith(" "))
        return;

    Token lastToken = tokens[ tokens.count()-1 ];

    // last token must be an identifier
    if( !lastToken.isIdentifier() )
        return;

    QString id = lastToken.text();
    if( id.isEmpty() )
        return;

    // find matches in function names
    QStringList fnames = FunctionManager::instance()->functionList(FunctionManager::All);
    QStringList choices;

    for( unsigned i=0; i<fnames.count(); i++ )
        if( fnames[i].startsWith( id, false ) )
        {
            QString str = fnames[i];

            ::Function* f = FunctionManager::instance()->function( str );
            if( f && !f->description.isEmpty() )
    str.append( ':' ).append( f->description );

            choices.append( str );
        }

    choices.sort();

    // find matches in variables names
    QStringList vchoices;
    QStringList values = NumeralModel::instance()->valueNames();

    for(QStringList::ConstIterator it = values.begin(); it != values.end(); ++it)
        if( (*it).startsWith( id, false ) )
        {
            QString choice = NumeralModel::description(*it);
            if(choice.isEmpty())
    choice = NumeralModel::instance()->value(*it).toString();

            vchoices.append( QString("%1:%2").arg( *it, choice ) );
        }

    vchoices.sort();
    choices += vchoices;

    // no match, don't bother with completion
    if( !choices.count() ) return;

    // one match, complete it for the user
    if( choices.count()==1 )
    {
        QString str = QStringList::split( ':', choices[0] )[0];

        // single perfect match, no need to give choices.
        if(str == id.lower())
            return;

        str = str.remove( 0, id.length() );
        int para = 0, curPos = 0;
        getCursorPosition( &para, &curPos );
        blockSignals( true );
        insert( str );
        setSelection( 0, curPos, 0, curPos+str.length() );
        blockSignals( false );
        return;
    }

    // present the user with completion choices
    d->completion->showCompletion( choices );
}
示例#9
0
void Editor::triggerAutoComplete()
{
    if (!m_isAutoCompletionEnabled)
        return;

    // Tokenize the expression (this is very fast).
    const int currentPosition = textCursor().position();
    QString subtext = text().left(currentPosition);
    const Tokens tokens = m_evaluator->scan(subtext, Evaluator::NoAutoFix);
    if (!tokens.valid() || tokens.count() < 1)
        return;

    Token lastToken = tokens.at(tokens.count()-1);

    // Last token must be an identifier.
    if (!lastToken.isIdentifier())
        return;
    const QString id = lastToken.text();
    if (id.length() < 1)
        return;

    // No space after identifier.
    if (lastToken.pos() + id.length() < subtext.length())
        return;

    // Find matches in function names.
    const QStringList fnames = FunctionRepo::instance()->getIdentifiers();
    QStringList choices;
    for (int i = 0; i < fnames.count(); ++i) {
        if (fnames.at(i).startsWith(id, Qt::CaseInsensitive)) {
            QString str = fnames.at(i);
            Function* f = FunctionRepo::instance()->find(str);
            if (f)
                str.append(':').append(f->name());
            choices.append(str);
        }
    }
    choices.sort();

    // Find matches in variables names.
    QStringList vchoices;
    QList<Evaluator::Variable> variables = m_evaluator->getVariables();
    for (int i = 0; i < variables.count(); ++i)
        if (variables.at(i).name.startsWith(id, Qt::CaseInsensitive))
            vchoices.append(QString("%1:%2").arg(variables.at(i).name)
                .arg(NumberFormatter::format(variables.at(i).value)));
    vchoices.sort();
    choices += vchoices;

    // Find matches in user functions.
    QStringList ufchoices;
    QList<Evaluator::UserFunctionDescr> userFunctions = m_evaluator->getUserFunctions();
    for (int i = 0; i < userFunctions.count(); ++i)
        if (userFunctions.at(i).name.startsWith(id, Qt::CaseInsensitive))
            ufchoices.append(QString("%1:User function").arg(userFunctions.at(i).name));
    ufchoices.sort();
    choices += ufchoices;

    // TODO: if we are assigning a user function, find matches in its arguments names and
    //       replace variables names that collide. But we cannot know if we are assigning
    //       a user function without evaluating the expression (a token scan will not be enough).

    // No match, don't bother with completion.
    if (!choices.count())
        return;

    // Single perfect match, no need to give choices.
    if (choices.count() == 1)
        if (choices.at(0).toLower() == id.toLower())
            return;

    // Present the user with completion choices.
    m_completion->showCompletion(choices);
}