diff --git a/RedPandaIDE/RedPandaIDE.pro b/RedPandaIDE/RedPandaIDE.pro index 9f4da50b..2d9ca9b2 100644 --- a/RedPandaIDE/RedPandaIDE.pro +++ b/RedPandaIDE/RedPandaIDE.pro @@ -14,6 +14,7 @@ QMAKE_CXXFLAGS_DEBUG += -Werror=return-type SOURCES += \ HighlighterManager.cpp \ + autolinkmanager.cpp \ caretlist.cpp \ codeformatter.cpp \ colorscheme.cpp \ @@ -89,6 +90,7 @@ SOURCES += \ HEADERS += \ HighlighterManager.h \ + autolinkmanager.h \ caretlist.h \ codeformatter.h \ colorscheme.h \ @@ -196,6 +198,7 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin RESOURCES += \ codes.qrc \ colorschemes.qrc \ + defaultconfigs.qrc \ themes/dark/dark.qrc \ themes/light/light.qrc \ themes/dracula/dracula.qrc \ diff --git a/RedPandaIDE/autolinkmanager.cpp b/RedPandaIDE/autolinkmanager.cpp new file mode 100644 index 00000000..8fc2ee0d --- /dev/null +++ b/RedPandaIDE/autolinkmanager.cpp @@ -0,0 +1,101 @@ +#include "autolinkmanager.h" +#include "settings.h" + +#include +#include +#include +#include + +AutolinkManager* pAutolinkManager; + +AutolinkManager::AutolinkManager() +{ + +} + +PAutolink AutolinkManager::getLink(const QString &header) const +{ + return mLinks.value(header,PAutolink()); +} + +void AutolinkManager::load() +{ + QDir dir(pSettings->dirs().config()); + QString filename=dir.filePath(AUTOLINK_CONFIG); + QFile file(filename); + if (!file.exists()) { + QFile::copy(":/config/autolink.json",filename); + if (!file.exists()) { + throw FileError(QObject::tr("Can't open file '%1' for write.") + .arg(filename)); + } + } + if (file.open(QFile::ReadOnly)) { + QByteArray content = file.readAll(); + QJsonDocument doc(QJsonDocument::fromJson(content)); + fromJson(doc.array()); + file.close(); + } else { + throw FileError(QObject::tr("Can't open file '%1' for read.") + .arg(filename)); + } +} + +void AutolinkManager::save() +{ + QDir dir(pSettings->dirs().config()); + QString filename=dir.filePath(AUTOLINK_CONFIG); + QFile file(filename); + if (file.open(QFile::WriteOnly|QFile::Truncate)) { + QJsonDocument doc(toJson()); + file.write(doc.toJson(QJsonDocument::Indented)); + file.close(); + } else { + throw FileError(QObject::tr("Can't open file '%1' for write.") + .arg(filename)); + } +} + +void AutolinkManager::setLink(const QString &header, const QString &linkOption) +{ + PAutolink link = mLinks.value(header,PAutolink()); + if (link) { + link->linkOption = linkOption; + } else { + link = std::make_shared(); + link->header = header; + link->linkOption = linkOption; + mLinks.insert(header,link); + } +} + +const QMap &AutolinkManager::links() const +{ + return mLinks; +} + +void AutolinkManager::clear() +{ + mLinks.clear(); +} + +QJsonArray AutolinkManager::toJson() +{ + QJsonArray result; + foreach (const QString& header, mLinks.keys()){ + QJsonObject autolink; + autolink["header"]=header; + autolink["links"]=mLinks[header]->linkOption; + result.append(autolink); + } + return result; +} + +void AutolinkManager::fromJson(QJsonArray json) +{ + clear(); + for (int i=0;i +#include +#include +#include +#include + +#define AUTOLINK_CONFIG "autolink.json" + +struct Autolink { + QString header; + QString linkOption; +}; +using PAutolink = std::shared_ptr; + +class AutolinkManager +{ +public: + explicit AutolinkManager(); + PAutolink getLink(const QString& header) const; + void load(); + void save(); + void setLink(const QString& header, + const QString& linkOption); + void removeLink(const QString& header); + const QMap& links() const; + void clear(); + QJsonArray toJson(); + void fromJson(QJsonArray json); +private: + QMap mLinks; +}; + +extern AutolinkManager* pAutolinkManager; + +#endif // AUTOLINKMANAGER_H diff --git a/RedPandaIDE/compiler/compiler.cpp b/RedPandaIDE/compiler/compiler.cpp index 0b38f397..873576fc 100644 --- a/RedPandaIDE/compiler/compiler.cpp +++ b/RedPandaIDE/compiler/compiler.cpp @@ -8,6 +8,12 @@ #include #include #include +#include +#include "../editor.h" +#include "../mainwindow.h" +#include "../editorlist.h" +#include "../parser/cppparser.h" +#include "../autolinkmanager.h" #include "../platform.h" #define COMPILE_PROCESS_END "---//END//----" @@ -336,6 +342,35 @@ QString Compiler::getLibraryArguments() result += QString(" -L\"%1\"").arg(folder); } + //Add auto links + // is file and auto link enabled + { + 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>0) + break; + waitCount++; + QThread::msleep(100); + QApplication *app=dynamic_cast( + QApplication::instance()); + app->processEvents(); + QSet parsedFiles; + result += parseFileIncludesForAutolink( + editor->filename(), + parsedFiles, + parser); + } + } + } + + } + + // Add global compiler linker extras if (compilerSet()->useCustomLinkParams() && !compilerSet()->customLinkParams().isEmpty()) { result += " "+compilerSet()->customCompileParams(); @@ -361,6 +396,30 @@ QString Compiler::getLibraryArguments() return result; } +QString Compiler::parseFileIncludesForAutolink( + const QString &filename, + QSet parsedFiles, + PCppParser& parser) +{ + QString result; + QString baseName = baseFileName(filename); + if (parsedFiles.contains(filename)) + return result; + parsedFiles.insert(filename); + PAutolink autolink = pAutolinkManager->getLink(baseName); + if (autolink) { + result += ' '+autolink->linkOption; + } + QSet includedFiles = parser->getFileDirectIncludes(filename); + foreach (const QString& includeFilename, includedFiles) { + result += parseFileIncludesForAutolink( + includeFilename, + parsedFiles, + parser); + } + return result; +} + void Compiler::runCommand(const QString &cmd, const QString &arguments, const QString &workingDir, const QString& inputText) { QProcess process; diff --git a/RedPandaIDE/compiler/compiler.h b/RedPandaIDE/compiler/compiler.h index e217280a..d5bf97d5 100644 --- a/RedPandaIDE/compiler/compiler.h +++ b/RedPandaIDE/compiler/compiler.h @@ -4,6 +4,7 @@ #include #include "settings.h" #include "../common.h" +#include "../parser/cppparser.h" class Compiler : public QThread { @@ -49,6 +50,10 @@ protected: virtual QString getCIncludeArguments(); virtual QString getCppIncludeArguments(); virtual QString getLibraryArguments(); + virtual QString parseFileIncludesForAutolink( + 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 QString& inputText=QString()); diff --git a/RedPandaIDE/defaultconfigs.qrc b/RedPandaIDE/defaultconfigs.qrc new file mode 100644 index 00000000..4016a836 --- /dev/null +++ b/RedPandaIDE/defaultconfigs.qrc @@ -0,0 +1,5 @@ + + + resources/autolink.json + + diff --git a/RedPandaIDE/main.cpp b/RedPandaIDE/main.cpp index 159818fc..b47c531a 100644 --- a/RedPandaIDE/main.cpp +++ b/RedPandaIDE/main.cpp @@ -12,6 +12,7 @@ #include "common.h" #include "colorscheme.h" #include "iconsmanager.h" +#include "autolinkmanager.h" #include "parser/parserutils.h" QString getSettingFilename(const QString& filepath = QString()) { @@ -82,6 +83,8 @@ int main(int argc, char *argv[]) //Color scheme settings must be loaded after translation pColorManager = new ColorManager(); pIconsManager = new IconsManager(); + pAutolinkManager = new AutolinkManager(); + pAutolinkManager->load(); MainWindow mainWindow; pMainWindow = &mainWindow;