void SyntaxHighlighter::colorize(QString text) { Row *currentRow; TextField *field = NULL; enum {IDLE, MULTI_COMMENT, SPACES, WORD, GLOBAL_INCLUDE_FILE, COMMENT1,COMMENT, STRING, ESCAPED_CHAR, INC_STRING } state = IDLE; char c = '\n'; char prevC = ' '; char prevPrevC = ' '; bool isEscaped = false; reset(); currentRow = new Row; m_rows.push_back(currentRow); for(int i = 0;i < text.size();i++) { c = text[i].toLatin1(); // Was the last character an escape? if(prevC == '\\' && prevPrevC != '\\') isEscaped = true; else isEscaped = false; prevPrevC = prevC; prevC = c; switch(state) { case IDLE: { if(c == '/') { state = COMMENT1; field = new TextField; field->m_type = TextField::WORD; field->m_color = Qt::white; currentRow->appendField(field); field->m_text = c; } else if(c == ' ' || c == '\t') { state = SPACES; field = new TextField; field->m_type = TextField::SPACES; field->m_color = Qt::white; currentRow->appendField(field); field->m_text = c; } else if(c == '\'') { state = ESCAPED_CHAR; field = new TextField; field->m_type = TextField::STRING; currentRow->appendField(field); field->m_text = c; } else if(c == '"') { state = STRING; field = new TextField; if(currentRow->isCppRow) field->m_type = TextField::INC_STRING; else field->m_type = TextField::STRING; currentRow->appendField(field); field->m_text = c; } else if(c == '<' && currentRow->isCppRow) { // Is it a include string? bool isIncString = false; TextField *lastField = currentRow->getLastNonSpaceField(); if(lastField) { if(lastField->m_text == "include") isIncString = true; } // Add the field field = new TextField; field->m_text = c; if(isIncString) { state = INC_STRING; field->m_type = TextField::INC_STRING; } else { field->m_type = TextField::WORD; field->m_color = Qt::white; } currentRow->appendField(field); } else if(c == '#') { // Only spaces before the '#' at the line? bool onlySpaces = true; for(int j = 0;onlySpaces == true && j < currentRow->m_fields.size();j++) { if(currentRow->m_fields[j]->m_type != TextField::SPACES && currentRow->m_fields[j]->m_type != TextField::COMMENT) { onlySpaces = false; } } currentRow->isCppRow = onlySpaces ? true : false; // Create a new field structure field = new TextField; if(currentRow->isCppRow) field->m_type = TextField::CPP_KEYWORD; else field->m_type = TextField::WORD; field->m_color = Qt::white; currentRow->appendField(field); field->m_text = c; } else if(isSpecialChar(c)) { field = new TextField; field->m_type = TextField::WORD; field->m_color = Qt::white; currentRow->appendField(field); field->m_text = c; } else if(c == '\n') { currentRow = new Row; m_rows.push_back(currentRow); state = IDLE; } else { state = WORD; field = new TextField; if(QChar(c).isDigit()) field->m_type = TextField::NUMBER; else field->m_type = TextField::WORD; field->m_color = Qt::white; currentRow->appendField(field); field->m_text = c; } };break; case COMMENT1: { if(c == '*') { field->m_text += c; field->m_type = TextField::COMMENT; field->m_color = Qt::green; state = MULTI_COMMENT; } else if(c == '/') { field->m_text += c; field->m_type = TextField::COMMENT; field->m_color = Qt::green; state = COMMENT; } else { i--; state = IDLE; } };break; case MULTI_COMMENT: { if(c == '\n') { currentRow = new Row; m_rows.push_back(currentRow); field = new TextField; field->m_type = TextField::COMMENT; currentRow->appendField(field); } else if(text[i-1].toLatin1() == '*' && c == '/') { field->m_text += c; state = IDLE; } else { field->m_text += c; } };break; case COMMENT: { if(c == '\n') { i--; state = IDLE; } else field->m_text += c; };break; case SPACES: { if(c == ' ' || c == '\t') { field->m_text += c; } else { i--; field = NULL; state = IDLE; } };break; case GLOBAL_INCLUDE_FILE: { if(!isEscaped && c == '\n') { state = IDLE; } else { field->m_text += c; if(c == '>') { state = IDLE; } } };break; case ESCAPED_CHAR: { field->m_text += c; if(!isEscaped && c == '\'') { field = NULL; state = IDLE; } };break; case INC_STRING: { if(!isEscaped && c == '\n') { i--; field = NULL; state = IDLE; } else { field->m_text += c; if(!isEscaped && c == '>') { field = NULL; state = IDLE; } } };break; case STRING: { field->m_text += c; if(!isEscaped && c == '"') { field = NULL; state = IDLE; } };break; case WORD: { if(isSpecialChar(c) || c == ' ' || c == '\t' || c == '\n') { i--; if(currentRow->isCppRow) { if(isCppKeyword(field->m_text)) field->m_type = TextField::CPP_KEYWORD; } else { if(isKeyword(field->m_text)) field->m_type = TextField::KEYWORD; } field = NULL; state = IDLE; } else { field->m_text += c; } };break; } } for(int r = 0;r < m_rows.size();r++) { Row *currentRow = m_rows[r]; for(int j = 0;j < currentRow->m_fields.size();j++) { TextField* currentField = currentRow->m_fields[j]; pickColor(currentField); } } }