QString Editor::toHtml(const QString& title, const QString& lang) { Tokenizer* tokenizer = new Tokenizer(); tokenizer->initialize(editor->document()->toPlainText()); QString html = QString(); QTextCharFormat* format; Token* token = tokenizer->getToken(); while (token->type() != Token::EndOfInput) { QString escaped; switch (token->type()) { case Token::EndOfLine: escaped = "<br />"; break; case Token::WhiteSpace: escaped = ""; for (int n = 0; n < token->look().length(); n++) { escaped += " "; } break; default: escaped = token->look().toHtmlEscaped(); break; } format = highlighter->tokenToFormat(token); if (format != 0) { bool bold = format->fontWeight() > 50; html += QString("<span style=\"color: %1;%2\">%3</span>") .arg(format->foreground().color().name()) .arg(bold ? " font-weight: bold;" : "") .arg(escaped); } else { html += escaped; } token = tokenizer->getToken(); } delete tokenizer; return QString("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"%1\" lang=\"%1\">" "<head><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\" />" "<title>%2</title></head>" "<body style=\"font-family: monospace;\">%3</body></html>").arg(lang).arg(title).arg(html); }
bool Editor::saveFile(const QUrl &targetUrl) { QUrl url(targetUrl); bool result = false; if (url.isEmpty() && currentUrl().isEmpty()) { result = saveFileAs(); } else { if (url.isEmpty()) url = currentUrl(); QTemporaryFile tmp; // only used for network export tmp.setAutoRemove(false); tmp.open(); QString filename = url.isLocalFile() ? url.toLocalFile() : tmp.fileName(); QSaveFile *savefile = new QSaveFile(filename); if (savefile->open(QIODevice::WriteOnly)) { QTextStream outputStream(savefile); // store commands in their generic @(...) notation format, to be translatable when reopened // this allows sharing of scripts written in different languages Tokenizer tokenizer; tokenizer.initialize(editor->document()->toPlainText()); const QStringList localizedLooks(Translator::instance()->allLocalizedLooks()); QString unstranslated; Token* t; bool pendingEOL = false; // to avoid writing a final EOL token while ((t = tokenizer.getToken())->type() != Token::EndOfInput) { if (pendingEOL) { unstranslated.append('\n'); pendingEOL = false; } if (localizedLooks.contains(t->look())) { QString defaultLook(Translator::instance()->defaultLook(t->look())); unstranslated.append(QString("@(%1)").arg(defaultLook)); } else { if (t->type() == Token::EndOfLine) pendingEOL = true; else unstranslated.append(t->look()); } } outputStream << KTURTLE_MAGIC_1_0 << '\n'; outputStream << unstranslated; outputStream.flush(); savefile->commit(); // check for error here? } delete savefile; if (!url.isLocalFile()) { KIO::StoredTransferJob *job = KIO::storedPut(savefile, url, -1, 0); if(job->exec()){ setCurrentUrl(url); editor->document()->setModified(false); // MainWindow will add us to the recent file list emit fileSaved(url); result = true; // fix GUI for saveAs and saveExamples. TODO: check 5 lines above } } } return result; }
void QSGShaderSourceBuilder::removeVersion() { Tokenizer tok; const char *input = m_source.constData(); tok.initialize(input); // First find #version beginning and end (if present) const char *versionStartPos = 0; const char *versionEndPos = 0; bool inSingleLineComment = false; bool inMultiLineComment = false; bool foundVersionStart = false; Tokenizer::Token lt = Tokenizer::Token_Unspecified; Tokenizer::Token t = tok.next(); while (t != Tokenizer::Token_EOF) { // Handle comment blocks if (t == Tokenizer::Token_MultiLineCommentStart ) inMultiLineComment = true; if (t == Tokenizer::Token_MultiLineCommentEnd) inMultiLineComment = false; if (t == Tokenizer::Token_SingleLineComment) inSingleLineComment = true; if (t == Tokenizer::Token_NewLine && inSingleLineComment && !inMultiLineComment) inSingleLineComment = false; // Have we found #version, #extension or void main()? if (t == Tokenizer::Token_Version && !inSingleLineComment && !inMultiLineComment) { versionStartPos = tok.pos - 1; foundVersionStart = true; } else if (foundVersionStart && t == Tokenizer::Token_NewLine) { versionEndPos = tok.pos; break; } else if (lt == Tokenizer::Token_Void && t == Tokenizer::Token_Identifier) { if (qstrncmp("main", tok.identifier, 4) == 0) break; } // Scan to next token lt = t; t = tok.next(); } if (versionStartPos == 0) return; // Construct a new shader string, inserting the definition QByteArray newSource; newSource.reserve(m_source.size() - (versionEndPos - versionStartPos)); newSource += QByteArray::fromRawData(input, versionStartPos - input); newSource += QByteArray::fromRawData(versionEndPos, m_source.size() - (versionEndPos - versionStartPos)); m_source = newSource; }
void QSGShaderSourceBuilder::addDefinition(const QByteArray &definition) { if (definition.isEmpty()) return; Tokenizer tok; const char *input = m_source.constData(); tok.initialize(input); // First find #version, #extension's and "void main() { ... " const char *versionPos = 0; const char *extensionPos = 0; bool inSingleLineComment = false; bool inMultiLineComment = false; bool foundVersionStart = false; bool foundExtensionStart = false; Tokenizer::Token lt = Tokenizer::Token_Unspecified; Tokenizer::Token t = tok.next(); while (t != Tokenizer::Token_EOF) { // Handle comment blocks if (t == Tokenizer::Token_MultiLineCommentStart ) inMultiLineComment = true; if (t == Tokenizer::Token_MultiLineCommentEnd) inMultiLineComment = false; if (t == Tokenizer::Token_SingleLineComment) inSingleLineComment = true; if (t == Tokenizer::Token_NewLine && inSingleLineComment && !inMultiLineComment) inSingleLineComment = false; // Have we found #version, #extension or void main()? if (t == Tokenizer::Token_Version && !inSingleLineComment && !inMultiLineComment) foundVersionStart = true; if (t == Tokenizer::Token_Extension && !inSingleLineComment && !inMultiLineComment) foundExtensionStart = true; if (foundVersionStart && t == Tokenizer::Token_NewLine) { versionPos = tok.pos; foundVersionStart = false; } else if (foundExtensionStart && t == Tokenizer::Token_NewLine) { extensionPos = tok.pos; foundExtensionStart = false; } else if (lt == Tokenizer::Token_Void && t == Tokenizer::Token_Identifier) { if (qstrncmp("main", tok.identifier, 4) == 0) break; } // Scan to next token lt = t; t = tok.next(); } // Determine where to insert the definition. // If we found #extension directives, insert after last one, // else, if we found #version insert after #version // otherwise, insert at beginning. const char *insertionPos = extensionPos ? extensionPos : (versionPos ? versionPos : input); // Construct a new shader string, inserting the definition QByteArray newSource; newSource.reserve(m_source.size() + definition.size() + 9); newSource += QByteArray::fromRawData(input, insertionPos - input); newSource += QByteArrayLiteral("#define ") + definition + QByteArrayLiteral("\n"); newSource += QByteArray::fromRawData(insertionPos, m_source.size() - (insertionPos - input)); m_source = newSource; }
QByteArray qsgShaderRewriter_insertZAttributes(const char *input, QSurfaceFormat::OpenGLContextProfile profile) { Tokenizer tok; tok.initialize(input); Tokenizer::Token lt = tok.next(); Tokenizer::Token t = tok.next(); // First find "void main() { ... " const char* voidPos = input; while (t != Tokenizer::Token_EOF) { if (lt == Tokenizer::Token_Void && t == Tokenizer::Token_Identifier) { if (qstrncmp("main", tok.identifier, 4) == 0) break; } voidPos = tok.pos - 4; lt = t; t = tok.next(); } QByteArray result; result.reserve(1024); result += QByteArray::fromRawData(input, voidPos - input); switch (profile) { case QSurfaceFormat::NoProfile: case QSurfaceFormat::CompatibilityProfile: result += QByteArrayLiteral("attribute highp float _qt_order;\n"); result += QByteArrayLiteral("uniform highp float _qt_zRange;\n"); break; case QSurfaceFormat::CoreProfile: result += QByteArrayLiteral("in float _qt_order;\n"); result += QByteArrayLiteral("uniform float _qt_zRange;\n"); break; } // Find first brace '{' while (t != Tokenizer::Token_EOF && t != Tokenizer::Token_OpenBrace) t = tok.next(); int braceDepth = 1; t = tok.next(); // Find matching brace and insert our code there... while (t != Tokenizer::Token_EOF) { switch (t) { case Tokenizer::Token_CloseBrace: braceDepth--; if (braceDepth == 0) { result += QByteArray::fromRawData(voidPos, tok.pos - 1 - voidPos); result += QByteArrayLiteral(" gl_Position.z = (gl_Position.z * _qt_zRange + _qt_order) * gl_Position.w;\n"); result += QByteArray(tok.pos - 1); return result; } break; case Tokenizer::Token_OpenBrace: ++braceDepth; break; default: break; } t = tok.next(); } return QByteArray(); }