diff --git a/NEWS.md b/NEWS.md index b5c4d0fb..ec311721 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,7 @@ Red Panda C++ Version 1.1.2 - fix: can't correctly compile when link params are seperated by line breaks - fix: select all shouldn't set file's modified flag - enhancement: add (return)type info for functions/varaibles/typedefs in the class browser panel + - enhancement: autolink add "force utf8" property (mainly for raylib) Red Panda C++ Version 1.1.1 - enhancement: adjust the appearance of problem case's input/output/expected control diff --git a/RedPandaIDE/autolinkmanager.cpp b/RedPandaIDE/autolinkmanager.cpp index fb4f04b3..1223bfc6 100644 --- a/RedPandaIDE/autolinkmanager.cpp +++ b/RedPandaIDE/autolinkmanager.cpp @@ -107,15 +107,17 @@ void AutolinkManager::save() } } -void AutolinkManager::setLink(const QString &header, const QString &linkOption) +void AutolinkManager::setLink(const QString &header, const QString &linkOption, bool execUseUTF8) { PAutolink link = mLinks.value(header,PAutolink()); if (link) { link->linkOption = linkOption; + link->execUseUTF8 = execUseUTF8; } else { link = std::make_shared(); link->header = header; link->linkOption = linkOption; + link->execUseUTF8 = execUseUTF8; mLinks.insert(header,link); } } @@ -137,6 +139,7 @@ QJsonArray AutolinkManager::toJson() QJsonObject autolink; autolink["header"]=header; autolink["links"]=mLinks[header]->linkOption; + autolink["execUseUTF8"]=mLinks[header]->execUseUTF8; result.append(autolink); } return result; @@ -147,6 +150,6 @@ void AutolinkManager::fromJson(QJsonArray json) clear(); for (int i=0;i; @@ -37,7 +38,8 @@ public: void load(); void save(); void setLink(const QString& header, - const QString& linkOption); + const QString& linkOption, + bool execUseUTF8); void removeLink(const QString& header); const QMap& links() const; void clear(); diff --git a/RedPandaIDE/compiler/compiler.cpp b/RedPandaIDE/compiler/compiler.cpp index 1c10133e..31f3315d 100644 --- a/RedPandaIDE/compiler/compiler.cpp +++ b/RedPandaIDE/compiler/compiler.cpp @@ -301,10 +301,38 @@ void Compiler::stopCompile() mStop = true; } -QString Compiler::getCharsetArgument(const QByteArray& encoding, bool checkSyntax) +QString Compiler::getCharsetArgument(const QByteArray& encoding,FileType fileType, bool checkSyntax) { QString result; - if (compilerSet()->autoAddCharsetParams() && encoding != ENCODING_ASCII + bool forceExecUTF8=false; + // test if force utf8 from autolink infos + if ((fileType == FileType::CSource || + fileType == FileType::CppSource) && pSettings->editor().enableAutolink() ){ + Editor* editor = pMainWindow->editorList()->getEditor(); + if (editor) { + PCppParser parser = editor->parser(); + if (parser) { + int waitCount = 0; + //wait parsing ends, at most 1 second + while(parser->parsing()) { + if (waitCount>10) + break; + waitCount++; + QThread::msleep(100); + QApplication *app=dynamic_cast( + QApplication::instance()); + app->processEvents(); + } + QSet parsedFiles; + forceExecUTF8 = parseForceUTF8ForAutolink( + editor->filename(), + parsedFiles, + parser); + } + } + + } + if ((forceExecUTF8 || compilerSet()->autoAddCharsetParams()) && encoding != ENCODING_ASCII && compilerSet()->compilerType()!=COMPILER_CLANG) { QString encodingName; QString execEncodingName; @@ -317,7 +345,9 @@ QString Compiler::getCharsetArgument(const QByteArray& encoding, bool checkSynta } else { encodingName = encoding; } - if (compilerSetExecCharset == ENCODING_SYSTEM_DEFAULT || compilerSetExecCharset.isEmpty()) { + if (forceExecUTF8) { + execEncodingName = "UTF-8"; + } else if (compilerSetExecCharset == ENCODING_SYSTEM_DEFAULT || compilerSetExecCharset.isEmpty()) { execEncodingName = systemEncodingName; } else { execEncodingName = compilerSetExecCharset; @@ -576,6 +606,35 @@ QString Compiler::parseFileIncludesForAutolink( return result; } +bool Compiler::parseForceUTF8ForAutolink(const QString &filename, QSet &parsedFiles, PCppParser &parser) +{ + bool result; + if (parsedFiles.contains(filename)) + return false; + parsedFiles.insert(filename); + PAutolink autolink = pAutolinkManager->getLink(filename); + if (autolink && autolink->execUseUTF8) { + return true; + } + QStringList includedFiles = parser->getFileDirectIncludes(filename); +// log(QString("File %1 included:").arg(filename)); +// for (int i=includedFiles.size()-1;i>=0;i--) { +// QString includeFilename = includedFiles[i]; +// log(includeFilename); +// } + + for (int i=includedFiles.size()-1;i>=0;i--) { + QString includeFilename = includedFiles[i]; + result = parseForceUTF8ForAutolink( + includeFilename, + parsedFiles, + parser); + if (result) + return true; + } + return false; +} + void Compiler::runCommand(const QString &cmd, const QString &arguments, const QString &workingDir, const QByteArray& inputText) { QProcess process; diff --git a/RedPandaIDE/compiler/compiler.h b/RedPandaIDE/compiler/compiler.h index df680b74..29da8ba7 100644 --- a/RedPandaIDE/compiler/compiler.h +++ b/RedPandaIDE/compiler/compiler.h @@ -64,7 +64,7 @@ protected: virtual bool prepareForCompile() = 0; virtual QByteArray pipedText(); virtual bool prepareForRebuild() = 0; - virtual QString getCharsetArgument(const QByteArray& encoding,bool onlyCheckSyntax); + virtual QString getCharsetArgument(const QByteArray& encoding, FileType fileType, bool onlyCheckSyntax); virtual QString getCCompileArguments(bool checkSyntax); virtual QString getCppCompileArguments(bool checkSyntax); virtual QString getCIncludeArguments(); @@ -75,6 +75,10 @@ protected: const QString& filename, QSet& parsedFiles, PCppParser& parser); + virtual bool parseForceUTF8ForAutolink( + const QString& filename, + QSet& parsedFiles, + PCppParser& parser); void log(const QString& msg); void error(const QString& msg); void runCommand(const QString& cmd, const QString& arguments, const QString& workingDir, const QByteArray& inputText=QByteArray()); diff --git a/RedPandaIDE/compiler/filecompiler.cpp b/RedPandaIDE/compiler/filecompiler.cpp index 04eadf38..8b436b2c 100644 --- a/RedPandaIDE/compiler/filecompiler.cpp +++ b/RedPandaIDE/compiler/filecompiler.cpp @@ -59,7 +59,7 @@ bool FileCompiler::prepareForCompile() } } - mArguments += getCharsetArgument(mEncoding, mOnlyCheckSyntax); + mArguments += getCharsetArgument(mEncoding, fileType, mOnlyCheckSyntax); QString strFileType; switch(fileType) { case FileType::CSource: diff --git a/RedPandaIDE/compiler/stdincompiler.cpp b/RedPandaIDE/compiler/stdincompiler.cpp index 2767933e..ad83111a 100644 --- a/RedPandaIDE/compiler/stdincompiler.cpp +++ b/RedPandaIDE/compiler/stdincompiler.cpp @@ -41,7 +41,7 @@ bool StdinCompiler::prepareForCompile() fileType = FileType::CppSource; QString strFileType; if (mEncoding!=ENCODING_ASCII) { - mArguments += getCharsetArgument(mEncoding, mOnlyCheckSyntax); + mArguments += getCharsetArgument(mEncoding,fileType, mOnlyCheckSyntax); } switch(fileType) { case FileType::CSource: diff --git a/RedPandaIDE/project.cpp b/RedPandaIDE/project.cpp index fbe595b9..20a84a52 100644 --- a/RedPandaIDE/project.cpp +++ b/RedPandaIDE/project.cpp @@ -646,31 +646,6 @@ void Project::saveAsTemplate(const QString &filename, ini.SetValue("Template", "Description", toByteArray(description)); ini.SetValue("Project", "Icon", toByteArray(options().icon)); //todo: save to template -// mOptions.type = static_cast(mIni->GetLongValue("Project", "Type", 0)); // default = gui -// mOptions.objFiles = fromByteArray(mIni->GetValue("Project", "ObjFiles", "")).split(";",QString::SkipEmptyParts); -// mOptions.includes = fromByteArray(mIni->GetValue("Project", "Includes", "")).split(";",QString::SkipEmptyParts); -// mOptions.libs = fromByteArray(mIni->GetValue("Project", "Libs", "")).split(";",QString::SkipEmptyParts); -// mOptions.resourceIncludes = fromByteArray(mIni->GetValue("Project", "ResourceIncludes", "")).split(";",QString::SkipEmptyParts); -// mOptions.compilerCmd = fromByteArray(mIni->GetValue("Project", "Compiler", "")); -// mOptions.cppCompilerCmd = fromByteArray(mIni->GetValue("Project", "CppCompiler", "")); -// mOptions.linkerCmd = fromByteArray(mIni->GetValue("Project", "Linker","")); -// mOptions.isCpp = mIni->GetBoolValue("Project", "IsCpp", false); -// mOptions.includeVersionInfo = mIni->GetBoolValue("Project", "IncludeVersionInfo", false); -// mOptions.supportXPThemes = mIni->GetBoolValue("Project", "SupportXPThemes", false); -// mOptions.exeOutput = fromByteArray(mIni->GetValue("Project", "ExeOutput", "")); -// mOptions.objectOutput = fromByteArray(mIni->GetValue("Project", "ObjectOutput", "")); -// mOptions.logOutput = fromByteArray(mIni->GetValue("Project", "LogOutput", "")); -// mOptions.staticLink = mIni->GetBoolValue("Project", "StaticLink",true); -// mOptions.addCharset = mIni->GetBoolValue("Project", "AddCharset",true); -// bool useUTF8 = mIni->GetBoolValue("Project", "UseUTF8", false); -// if (useUTF8) { -// mOptions.encoding = fromByteArray(mIni->GetValue("Project","Encoding", ENCODING_UTF8)); -// } else { -// mOptions.encoding = fromByteArray(mIni->GetValue("Project","Encoding", ENCODING_AUTO_DETECT)); -// } -// mOptions.modelType = (ProjectModelType)mIni->GetLongValue("Project", "ModelType", (int)ProjectModelType::FileSystem); - - } PProjectUnit Project::findUnitByFilename(const QString &filename) diff --git a/RedPandaIDE/projecttemplate.cpp b/RedPandaIDE/projecttemplate.cpp index 8fa5560f..57564fe5 100644 --- a/RedPandaIDE/projecttemplate.cpp +++ b/RedPandaIDE/projecttemplate.cpp @@ -143,6 +143,8 @@ void ProjectTemplate::readTemplateFile(const QString &fileName) mOptions.exeOutput = fromByteArray(mIni->GetValue("Project", "ExeOutput", "")); mOptions.objectOutput = fromByteArray(mIni->GetValue("Project", "ObjectOutput", "")); mOptions.logOutput = fromByteArray(mIni->GetValue("Project", "LogOutput", "")); + mOptions.execEncoding = mIni->GetValue("Project","ExecEncoding", ENCODING_SYSTEM_DEFAULT); + mOptions.staticLink = mIni->GetBoolValue("Project", "StaticLink",true); mOptions.addCharset = mIni->GetBoolValue("Project", "AddCharset",true); bool useUTF8 = mIni->GetBoolValue("Project", "UseUTF8", false); diff --git a/RedPandaIDE/resources/autolink-linux.json b/RedPandaIDE/resources/autolink-linux.json index 13458513..f7fd1804 100644 --- a/RedPandaIDE/resources/autolink-linux.json +++ b/RedPandaIDE/resources/autolink-linux.json @@ -1,5 +1,6 @@ [ { + "execUseUTF8": true, "header": "raylib.h", "links": "-lraylib -lGL -lm -lpthread -ldl -lrt -lX11" }, diff --git a/RedPandaIDE/resources/autolink.json b/RedPandaIDE/resources/autolink.json index 7b0f709f..97a07eb8 100644 --- a/RedPandaIDE/resources/autolink.json +++ b/RedPandaIDE/resources/autolink.json @@ -28,6 +28,7 @@ "links": "-lgraphics -luuid -lmsimg32 -lgdi32 -limm32 -lole32 -loleaut32 -lwinmm -lgdiplus" }, { + "execUseUTF8": true, "header": "raylib.h", "links": "-lraylib -lopengl32 -lgdi32 -lwinmm" }, diff --git a/RedPandaIDE/settingsdialog/compilerautolinkwidget.cpp b/RedPandaIDE/settingsdialog/compilerautolinkwidget.cpp index 0304127c..b11fc96f 100644 --- a/RedPandaIDE/settingsdialog/compilerautolinkwidget.cpp +++ b/RedPandaIDE/settingsdialog/compilerautolinkwidget.cpp @@ -51,7 +51,8 @@ void CompilerAutolinkWidget::doSave() if (!link->header.isEmpty()) { pAutolinkManager->setLink( link->header, - link->linkOption + link->linkOption, + link->execUseUTF8 ); } } @@ -79,7 +80,7 @@ int AutolinkModel::rowCount(const QModelIndex &) const int AutolinkModel::columnCount(const QModelIndex &) const { - return 2; + return 3; } QVariant AutolinkModel::headerData(int section, Qt::Orientation orientation, int role) const @@ -89,6 +90,8 @@ QVariant AutolinkModel::headerData(int section, Qt::Orientation orientation, int case 0: return tr("Header"); case 1: + return tr("UTF-8"); + case 2: return tr("Link options"); } } @@ -107,9 +110,17 @@ QVariant AutolinkModel::data(const QModelIndex &index, int role) const switch(index.column()) { case 0: return link->header; - case 1: + case 2: return link->linkOption; } + } else if (role == Qt::CheckStateRole && index.column()==1) { + int row = index.row(); + if (row<0 || row>=mLinks.count()) + return QVariant(); + PAutolink link = mLinks[row]; + return link->execUseUTF8 ? Qt::Checked : Qt::Unchecked; + } else if (role == Qt::TextAlignmentRole && index.column()==1) { + return Qt::AlignCenter; } return QVariant(); } @@ -118,7 +129,16 @@ bool AutolinkModel::setData(const QModelIndex &index, const QVariant &value, int { if (!index.isValid()) return false; - if (role == Qt::EditRole) { + if (role == Qt::CheckStateRole && index.column()==1) { + int row = index.row(); + if (row<0 || row>=mLinks.count()) + return false; + PAutolink link = mLinks[row]; + link->execUseUTF8 = (value == Qt::Checked); + mWidget->setSettingsChanged(); + return true; + } + else if (role == Qt::EditRole) { int row = index.row(); if (row<0 || row>=mLinks.count()) return false; @@ -143,7 +163,7 @@ bool AutolinkModel::setData(const QModelIndex &index, const QVariant &value, int mLinks[row]=newLink; mWidget->setSettingsChanged(); return true; - } else if (index.column() == 1) { + } else if (index.column() == 2) { //we must create a new link, becasue mList may share link pointer with the autolink manger PAutolink newLink = std::make_shared(); newLink->header = link->header; @@ -160,7 +180,10 @@ Qt::ItemFlags AutolinkModel::flags(const QModelIndex &index) const { Qt::ItemFlags flags = Qt::NoItemFlags; if (index.isValid()) { - flags = Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable ; + if (index.column()==1) + flags = Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; + else + flags = Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable ; } return flags; } diff --git a/windows/templates/raylib.template b/windows/templates/raylib.template index 5b4c3408..a196778a 100644 --- a/windows/templates/raylib.template +++ b/windows/templates/raylib.template @@ -25,4 +25,5 @@ UnitCount=3 Type=1 IsCpp=0 linker=-lraylib -lopengl32 -lgdi32 -lwinmm +ExecEncoding=UTF-8 diff --git a/windows/templates/raylib_3d.template b/windows/templates/raylib_3d.template index c863954a..745ffcda 100644 --- a/windows/templates/raylib_3d.template +++ b/windows/templates/raylib_3d.template @@ -17,4 +17,4 @@ UnitCount=1 Type=1 IsCpp=0 linker=-lraylib -lopengl32 -lgdi32 -lwinmm - +ExecEncoding=UTF-8 diff --git a/windows/templates/raylib_3d_shader.template b/windows/templates/raylib_3d_shader.template index c854c02a..3d0dfad9 100644 --- a/windows/templates/raylib_3d_shader.template +++ b/windows/templates/raylib_3d_shader.template @@ -25,4 +25,4 @@ UnitCount=3 Type=1 IsCpp=0 linker=-lraylib -lopengl32 -lgdi32 -lwinmm - +ExecEncoding=UTF-8 diff --git a/windows/templates/raylib_snake.template b/windows/templates/raylib_snake.template index 57943f7e..ccc5af02 100644 --- a/windows/templates/raylib_snake.template +++ b/windows/templates/raylib_snake.template @@ -17,4 +17,4 @@ UnitCount=1 Type=1 IsCpp=0 linker=-lraylib -lopengl32 -lgdi32 -lwinmm - +ExecEncoding=UTF-8 diff --git a/windows/templates/raylib_tetris.template b/windows/templates/raylib_tetris.template index dccb9cd9..6b2253e8 100644 --- a/windows/templates/raylib_tetris.template +++ b/windows/templates/raylib_tetris.template @@ -17,4 +17,4 @@ UnitCount=1 Type=1 IsCpp=0 linker=-lraylib -lopengl32 -lgdi32 -lwinmm - +ExecEncoding=UTF-8 diff --git a/windows/templates/rdrawing.template b/windows/templates/rdrawing.template index 7ddb9642..6b0a2a04 100644 --- a/windows/templates/rdrawing.template +++ b/windows/templates/rdrawing.template @@ -17,4 +17,4 @@ UnitCount=1 Type=1 IsCpp=0 linker=-lrdrawing -lraylib -lopengl32 -lgdi32 -lwinmm - +ExecEncoding=UTF-8 diff --git a/windows/templates/rdrawing_doraemon.template b/windows/templates/rdrawing_doraemon.template index 0838e10b..6d9ca521 100644 --- a/windows/templates/rdrawing_doraemon.template +++ b/windows/templates/rdrawing_doraemon.template @@ -17,4 +17,4 @@ UnitCount=1 Type=1 IsCpp=0 linker=-lrdrawing -lraylib -lopengl32 -lgdi32 -lwinmm - +ExecEncoding=UTF-8