#include "utils.h" #include "systemconsts.h" #include #include #include #include "editor.h" #include "editorlist.h" #include "settings.h" #include "mainwindow.h" #include "project.h" #include "parser/cppparser.h" #include "compiler/executablerunner.h" #include #ifdef Q_OS_WIN #include #endif QStringList splitProcessCommand(const QString &cmd) { QStringList result; SplitProcessCommandQuoteType quoteType = SplitProcessCommandQuoteType::None; int i=0; QString current; while (ieditorList()->getEditor(); result.replace("", localizePath(QDir::currentPath())); result.replace("", localizePath(pSettings->dirs().executable())); result.replace("", REDPANDA_CPP_VERSION); result.replace("", localizePath(pSettings->dirs().appDir())); QDate today = QDate::currentDate(); QDateTime now = QDateTime::currentDateTime(); result.replace("", today.toString("yyyy-MM-dd")); result.replace("", now.toString("yyyy-MM-dd hh:mm:ss")); Settings::PCompilerSet compilerSet = pSettings->compilerSets().defaultSet(); if (compilerSet) { // Only provide the first cpp include dir if (compilerSet->defaultCppIncludeDirs().count()>0) result.replace("", localizePath(compilerSet->defaultCppIncludeDirs().front())); else result.replace("",""); // Only provide the first lib dir if (compilerSet->defaultLibDirs().count()>0) result.replace("", localizePath(compilerSet->defaultLibDirs().front())); else result.replace("",""); } if (e!=nullptr && !e->inProject()) { // Non-project editor macros QString exeSuffix; Settings::PCompilerSet compilerSet = pSettings->compilerSets().defaultSet(); if (compilerSet) { exeSuffix = compilerSet->executableSuffix(); } else { exeSuffix = DEFAULT_EXECUTABLE_SUFFIX; } result.replace("", extractFileName(changeFileExt(e->filename(), exeSuffix))); result.replace("", localizePath(changeFileExt(e->filename(), exeSuffix))); result.replace("", extractFileName(e->filename())); result.replace("", localizePath(e->filename())); result.replace("", extractFileName(e->filename())); result.replace("", localizePath(extractFileDir(e->filename()))); } else if (pMainWindow->project()) { result.replace("", extractFileName(pMainWindow->project()->executable())); result.replace("", localizePath(pMainWindow->project()->executable())); result.replace("", pMainWindow->project()->name()); result.replace("", localizePath(pMainWindow->project()->filename())); result.replace("", extractFileName(pMainWindow->project()->filename())); result.replace("", localizePath(pMainWindow->project()->directory())); } else { result.replace("", ""); result.replace("", ""); result.replace("", ""); result.replace("", ""); result.replace("", ""); result.replace("", ""); } // Editor macros if (e!=nullptr) { result.replace("", extractFileName(e->filename())); result.replace("", localizePath(e->filename())); result.replace("", localizePath(extractFileDir(e->filename()))); result.replace("", e->wordAtCursor()); } else { result.replace("", ""); result.replace("", ""); result.replace("", ""); result.replace("", ""); } return result; } void resetCppParser(std::shared_ptr parser, int compilerSetIndex) { if (!parser) return; // Configure parser parser->resetParser(); //paser->enabled = pSettings-> devCodeCompletion.Enabled; // CppParser.ParseLocalHeaders := devCodeCompletion.ParseLocalHeaders; // CppParser.ParseGlobalHeaders := devCodeCompletion.ParseGlobalHeaders; parser->setEnabled(true); parser->setParseGlobalHeaders(true); parser->setParseLocalHeaders(true); // Set options depending on the current compiler set if (compilerSetIndex<0) { compilerSetIndex=pSettings->compilerSets().defaultIndex(); } Settings::PCompilerSet compilerSet = pSettings->compilerSets().getSet(compilerSetIndex); parser->clearIncludePaths(); bool isCpp = parser->language()==ParserLanguage::CPlusPlus; if (compilerSet) { if (isCpp) { foreach (const QString& file,compilerSet->CppIncludeDirs()) { parser->addIncludePath(file); } } foreach (const QString& file,compilerSet->CIncludeDirs()) { parser->addIncludePath(file); } if (isCpp) { foreach (const QString& file,compilerSet->defaultCppIncludeDirs()) { parser->addIncludePath(file); } } foreach (const QString& file,compilerSet->defaultCIncludeDirs()) { parser->addIncludePath(file); } //TODO: Add default include dirs last, just like gcc does // Set defines if (parser->language()==ParserLanguage::C) { for (QString define:compilerSet->CDefines()) { parser->addHardDefineByLine(define); // predefined constants from -dM -E } } else { for (QString define:compilerSet->CppDefines()) { parser->addHardDefineByLine(define); // predefined constants from -dM -E } } // add a Red Pand C++ 's own macro parser->addHardDefineByLine("#define EGE_FOR_AUTO_CODE_COMPLETETION_ONLY"); // add C/C++ default macro parser->addHardDefineByLine("#define __FILE__ 1"); parser->addHardDefineByLine("#define __LINE__ 1"); parser->addHardDefineByLine("#define __DATE__ 1"); parser->addHardDefineByLine("#define __TIME__ 1"); } parser->parseHardDefines(); pMainWindow->disconnect(parser.get(), &CppParser::onStartParsing, pMainWindow, &MainWindow::onStartParsing); pMainWindow->disconnect(parser.get(), &CppParser::onProgress, pMainWindow, &MainWindow::onParserProgress); pMainWindow->disconnect(parser.get(), &CppParser::onEndParsing, pMainWindow, &MainWindow::onEndParsing); pMainWindow->connect(parser.get(), &CppParser::onStartParsing, pMainWindow, &MainWindow::onStartParsing); pMainWindow->connect(parser.get(), &CppParser::onProgress, pMainWindow, &MainWindow::onParserProgress); pMainWindow->connect(parser.get(), &CppParser::onEndParsing, pMainWindow, &MainWindow::onEndParsing); } int getNewFileNumber() { static int count = 0; count++; return count; } #ifdef Q_OS_WIN static bool gIsGreenEdition = true; static bool gIsGreenEditionInited = false; #endif bool isGreenEdition() { #ifdef Q_OS_WIN if (!gIsGreenEditionInited) { QString keyString = QString("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\RedPanda-C++"); QString value; if (!readRegistry(HKEY_LOCAL_MACHINE,keyString.toLocal8Bit(),"UninstallString",value)) { keyString = "SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\RedPanda-C++"; if (!readRegistry(HKEY_LOCAL_MACHINE,keyString.toLocal8Bit(),"UninstallString",value)) { value=""; } } if (!value.isEmpty()) { QString regPath = extractFileDir(value); QString appPath = QApplication::instance()->applicationDirPath(); gIsGreenEdition = excludeTrailingPathDelimiter(regPath).compare(excludeTrailingPathDelimiter(appPath), Qt::CaseInsensitive)!=0; } gIsGreenEditionInited = true; } return gIsGreenEdition; #else return false; #endif } QByteArray runAndGetOutput(const QString &cmd, const QString& workingDir, const QStringList& arguments, const QByteArray &inputContent, bool inheritEnvironment, const QProcessEnvironment& env) { QProcess process; QByteArray result; if (env.isEmpty()) { if (inheritEnvironment) { process.setProcessEnvironment(QProcessEnvironment::systemEnvironment()); } else { process.setProcessEnvironment(QProcessEnvironment()); } } else { process.setProcessEnvironment(env); } process.setWorkingDirectory(workingDir); process.connect(&process,&QProcess::readyReadStandardError, [&](){ result.append(process.readAllStandardError()); }); process.connect(&process,&QProcess::readyReadStandardOutput, [&](){ result.append(process.readAllStandardOutput()); }); process.start(cmd,arguments); if (!inputContent.isEmpty()) { process.write(inputContent); } process.closeWriteChannel(); process.waitForFinished(); return result; } void executeFile(const QString &fileName, const QString ¶ms, const QString &workingDir, const QString &tempFile) { ExecutableRunner* runner=new ExecutableRunner( fileName, params, workingDir); runner->connect(runner, &QThread::finished, [runner,tempFile](){ if (!tempFile.isEmpty()) { QFile::remove(tempFile); } runner->deleteLater(); }); runner->connect(runner, &Runner::runErrorOccurred, [](const QString&){ //todo }); runner->setStartConsole(true); runner->start(); } #ifdef Q_OS_WIN bool readRegistry(HKEY key,const QByteArray& subKey, const QByteArray& name, QString& value) { DWORD dataSize; LONG result; result = RegGetValueA(key,subKey, name, RRF_RT_REG_SZ | RRF_RT_REG_MULTI_SZ, NULL, NULL, &dataSize); if (result!=ERROR_SUCCESS) return false; char * buffer = new char[dataSize+10]; result = RegGetValueA(key,subKey, name, RRF_RT_REG_SZ | RRF_RT_REG_MULTI_SZ, NULL, buffer, &dataSize); if (result!=ERROR_SUCCESS) { delete[] buffer; return false; } value=QString::fromLocal8Bit(buffer); delete [] buffer; return true; } #endif qulonglong stringToHex(const QString &str, bool &isOk) { qulonglong value = str.toULongLong(&isOk,16); return value; } bool findComplement(const QString &s, const QChar &fromToken, const QChar &toToken, int &curPos, int increment) { int curPosBackup = curPos; int level = 0; //todo: skip comment, char and strings while ((curPos < s.length()) && (curPos >= 0)) { if (s[curPos] == fromToken) { level++; } else if (s[curPos] == toToken) { level--; if (level == 0) return true; } curPos += increment; } curPos = curPosBackup; return false; } bool haveGoodContrast(const QColor& c1, const QColor &c2) { int lightness1 = qGray(c1.rgb()); int lightness2 = qGray(c2.rgb()); return std::abs(lightness1 - lightness2)>=120; } QByteArray getHTTPBody(const QByteArray& content) { int i= content.indexOf("\r\n\r\n"); if (i>=0) { return content.mid(i+4); } return ""; } QString getSizeString(int size) { if (size < 1024) { return QString("%1 ").arg(size)+QObject::tr("bytes"); } else if (size < 1024 * 1024) { return QString("%1 ").arg(size / 1024.0)+QObject::tr("KB"); } else if (size < 1024 * 1024 * 1024) { return QString("%1 ").arg(size / 1024.0 / 1024.0)+QObject::tr("MB"); } else { return QString("%1 ").arg(size / 1024.0 / 1024.0 / 1024.0)+QObject::tr("GB"); } } void saveComboHistory(QComboBox* cb,const QString& text) { QString s = text.trimmed(); if (s.isEmpty()) return; int i = cb->findText(s); if (i>=0) { cb->removeItem(i); } cb->insertItem(0,s); cb->setCurrentText(s); }