diff --git a/src/lib/utility/solution/SolutionParserCompilationDatabase.cpp b/src/lib/utility/solution/SolutionParserCompilationDatabase.cpp index 63080b63..13021e97 100644 --- a/src/lib/utility/solution/SolutionParserCompilationDatabase.cpp +++ b/src/lib/utility/solution/SolutionParserCompilationDatabase.cpp @@ -31,19 +31,11 @@ std::vector SolutionParserCompilationDatabase::getProjectItems() std::vector SolutionParserCompilationDatabase::getIncludePaths() { - if(m_searchPaths.empty()) - { - parseDatabase(); - } return m_searchPaths; } std::vector SolutionParserCompilationDatabase::getFrameworkPaths() { - if(m_searchPaths.empty()) - { - parseDatabase(); - } return m_frameworkPaths; } @@ -89,6 +81,11 @@ void SolutionParserCompilationDatabase::parseDatabase() { m_searchPaths.push_back(p); } + + for(std::string p : frameworkPaths) + { + m_frameworkPaths.push_back(p); + } } diff --git a/src/lib/utility/solution/SolutionParserCompilationDatabase.h b/src/lib/utility/solution/SolutionParserCompilationDatabase.h index 9acb16b9..fc07050b 100644 --- a/src/lib/utility/solution/SolutionParserCompilationDatabase.h +++ b/src/lib/utility/solution/SolutionParserCompilationDatabase.h @@ -28,14 +28,16 @@ public: virtual std::vector getIncludePaths(); std::vector getFrameworkPaths(); + void parseDatabase(); + private: - std::shared_ptr m_database; - void parseDatabase(); - bool m_parsed; clang::tooling::JSONCompilationDatabase* getDatabase(); - std::vector m_searchPaths; - std::vector m_frameworkPaths; std::string getIncludePath(const std::string& argument, const std::string& dir); + + std::shared_ptr m_database; + + std::vector m_searchPaths; + std::vector m_frameworkPaths; }; diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.cpp index 1b2447c2..fe1c345e 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.cpp @@ -13,6 +13,7 @@ #include "qt/window/project_wizzard/QtProjectWizzardContentSummary.h" #include "qt/window/project_wizzard/QtProjectWizzardWindow.h" #include "utility/messaging/type/MessageLoadProject.h" +#include "utility/solution/SolutionParserCompilationDatabase.h" #include "utility/solution/SolutionParserVisualStudio.h" QtProjectWizzard::QtProjectWizzard(QWidget* parent) @@ -91,6 +92,38 @@ void QtProjectWizzard::refreshProjectFromVisualStudioSolution(const std::string& } } +void QtProjectWizzard::newProjectFromCompilationDatabase(const std::string& compilationDatabasePath) +{ + m_settings = getSettingsForCompilationDatabase(compilationDatabasePath); + + QtProjectWizzardWindow* window = createWindowWithContent(); + connect(window, SIGNAL(next()), this, SLOT(showSummary())); + + connect(dynamic_cast(window->content()), + SIGNAL(showSourceFiles()), this, SLOT(showSourceFiles())); +} + +void QtProjectWizzard::refreshProjectFromCompilationDatabase(const std::string& compilationDatabasePath) +{ + QtProjectWizzardWindow* window = dynamic_cast(m_windowStack.getTopWindow()); + if (window) + { + window->content()->save(); + } + + ProjectSettings settings = getSettingsForCompilationDatabase(compilationDatabasePath); + + m_settings.setSourcePaths(settings.getSourcePaths()); + m_settings.setHeaderSearchPaths(settings.getHeaderSearchPaths()); + m_settings.setFrameworkSearchPaths(settings.getFrameworkSearchPaths()); + m_settings.setCompilationDatabasePath(FilePath(compilationDatabasePath)); + + if (window) + { + window->content()->load(); + } +} + void QtProjectWizzard::editProject(const ProjectSettings& settings) { m_settings = settings; @@ -194,6 +227,45 @@ ProjectSettings QtProjectWizzard::getSettingsForVisualStudioSolution(const std:: return settings; } +ProjectSettings QtProjectWizzard::getSettingsForCompilationDatabase(const std::string& compilationDatabasePath) const +{ + SolutionParserCompilationDatabase parser; + parser.openSolutionFile(compilationDatabasePath); + parser.parseDatabase(); + + ProjectSettings settings; + settings.setProjectName(parser.getSolutionName()); + settings.setProjectFileLocation(parser.getSolutionPath()); + settings.setCompilationDatabasePath(FilePath(compilationDatabasePath)); + + std::vector sourceFiles = parser.getProjectItems(); + std::vector sourcePaths; + for (const std::string& p : sourceFiles) + { + sourcePaths.push_back(FilePath(p)); + } + + std::vector includePaths = parser.getIncludePaths(); + std::vector headerPaths; + for (const std::string& p : includePaths) + { + headerPaths.push_back(FilePath(p)); + } + + std::vector frameworkPaths = parser.getFrameworkPaths(); + std::vector frameworkSearchPaths; + for (const std::string& p : frameworkPaths) + { + frameworkSearchPaths.push_back(FilePath(p)); + } + + settings.setSourcePaths(sourcePaths); + settings.setHeaderSearchPaths(headerPaths); + settings.setFrameworkSearchPaths(frameworkSearchPaths); + + return settings; +} + void QtProjectWizzard::cancelWizzard() { m_windowStack.clearWindows(); @@ -242,9 +314,17 @@ void QtProjectWizzard::selectedProjectType(QtProjectWizzardContentSelect::Projec } case QtProjectWizzardContentSelect::PROJECT_CDB: - QMessageBox msgBox; - msgBox.setText("Project type not implemented yet!"); - msgBox.exec(); + { + QString fileName = QFileDialog::getOpenFileName( + this, tr("Open JSON Compilation Database"), "", "JSON Compilation Database (*.json)" + ); + + if (!fileName.isNull()) + { + newProjectFromCompilationDatabase(fileName.toStdString()); + } + break; + } break; } } @@ -344,6 +424,10 @@ void QtProjectWizzard::showSummary() SIGNAL(refreshVisualStudioSolution(const std::string&)), this, SLOT(refreshProjectFromVisualStudioSolution(const std::string&))); + connect(dynamic_cast(summary->contentBuildFile()), + SIGNAL(refreshCompilationDatabase(const std::string&)), + this, SLOT(refreshProjectFromCompilationDatabase(const std::string&))); + connect(dynamic_cast(summary->contentPathsSource()), SIGNAL(showSourceFiles()), this, SLOT(showSourceFiles())); } diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.h b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.h index 0aed7f81..41f1bc5f 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.h +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.h @@ -29,6 +29,8 @@ public slots: void newProject(); void newProjectFromVisualStudioSolution(const std::string& visualStudioSolutionPath); void refreshProjectFromVisualStudioSolution(const std::string& visualStudioSolutionPath); + void newProjectFromCompilationDatabase(const std::string& compilationDatabasePath); + void refreshProjectFromCompilationDatabase(const std::string& compilationDatabasePath); void editProject(const ProjectSettings& settings); void showPreferences(); @@ -39,6 +41,7 @@ private: QtProjectWizzardWindow* createPopupWithContent(); ProjectSettings getSettingsForVisualStudioSolution(const std::string& visualStudioSolutionPath) const; + ProjectSettings getSettingsForCompilationDatabase(const std::string& compilationDatabasePath) const; QtWindowStack m_windowStack; std::shared_ptr m_popup; diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentBuildFile.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentBuildFile.cpp index 20d94d54..404eec98 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentBuildFile.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentBuildFile.cpp @@ -38,6 +38,7 @@ void QtProjectWizzardContentBuildFile::populateForm(QGridLayout* layout, int& ro break; case QtProjectWizzardContentSelect::PROJECT_CDB: name = "Compilation Database"; + filter = "JSON Compilation Database (*.json)"; break; } @@ -107,6 +108,7 @@ void QtProjectWizzardContentBuildFile::refreshClicked() break; } case QtProjectWizzardContentSelect::PROJECT_CDB: + emit refreshCompilationDatabase(path.str()); break; } } diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentBuildFile.h b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentBuildFile.h index e2bd25fb..06d2b7e8 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentBuildFile.h +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentBuildFile.h @@ -14,6 +14,7 @@ class QtProjectWizzardContentBuildFile signals: void refreshVisualStudioSolution(const std::string&); + void refreshCompilationDatabase(const std::string&); public: QtProjectWizzardContentBuildFile(ProjectSettings* settings, QtProjectWizzardWindow* window); diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp index 273711fa..20ab0bf6 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp @@ -6,6 +6,8 @@ #include "qt/element/QtDirectoryListBox.h" #include "settings/ApplicationSettings.h" +#include "utility/file/FileSystem.h" +#include "utility/utility.h" QtProjectWizzardContentPaths::QtProjectWizzardContentPaths(ProjectSettings* settings, QtProjectWizzardWindow* window) @@ -106,7 +108,12 @@ void QtProjectWizzardContentPaths::save() if (m_subPaths) { - return m_subPaths->savePaths(); + m_subPaths->savePaths(); + + if (dynamic_cast(m_subPaths)) + { + loadPaths(); + } } } @@ -238,6 +245,75 @@ QtProjectWizzardContentPathsSourceSimple::QtProjectWizzardContentPathsSourceSimp } +QtProjectWizzardContentPathsCDBSource::QtProjectWizzardContentPathsCDBSource( + ProjectSettings* settings, QtProjectWizzardWindow* window +) + : QtProjectWizzardContentPaths(settings, window) +{ + m_addShowSourcesButton = true; + + setInfo( + "Compilation Database Files", + "These files were found within the provided compilation database. You can add or remove files here.", + "" + ); + + m_subPaths = new QtProjectWizzardContentPathsCDBHeaders(settings, window); +} + +void QtProjectWizzardContentPathsCDBSource::loadPaths() +{ + m_list->setList(m_settings->getSourcePaths()); +} + +void QtProjectWizzardContentPathsCDBSource::savePaths() +{ + m_settings->setSourcePaths(m_list->getList()); +} + +bool QtProjectWizzardContentPathsCDBSource::isScrollAble() const +{ + return true; +} + +QtProjectWizzardContentPathsCDBHeaders::QtProjectWizzardContentPathsCDBHeaders( + ProjectSettings* settings, QtProjectWizzardWindow* window +) + : QtProjectWizzardContentPaths(settings, window) +{ + setTitleString("Header Files"); + setDescriptionString( + "Coati works best if you analyze both your source and header files, but the Compilation Database only contains " + "source files. Add the header files, or the directories containing them here. They will be added to the source " + "files above" + ); +} + +void QtProjectWizzardContentPathsCDBHeaders::loadPaths() +{ + m_list->clear(); +} + +void QtProjectWizzardContentPathsCDBHeaders::savePaths() +{ + std::vector headerPaths = m_list->getList(); + std::vector extensions = m_settings->getHeaderExtensions(); + std::vector fileInfos = FileSystem::getFileInfosFromPaths(headerPaths, extensions); + + headerPaths.clear(); + for (const FileInfo& info : fileInfos) + { + headerPaths.push_back(info.path); + } + + std::vector sourcePaths = m_settings->getSourcePaths(); + utility::append(sourcePaths, headerPaths); + m_settings->setSourcePaths(sourcePaths); + + m_list->clear(); +} + + QtProjectWizzardContentPathsHeaderSearch::QtProjectWizzardContentPathsHeaderSearch( ProjectSettings* settings, QtProjectWizzardWindow* window ) @@ -289,7 +365,7 @@ QtProjectWizzardContentPathsHeaderSearchGlobal::QtProjectWizzardContentPathsHead setInfo( "Global Header Search Paths", "These header search paths will be used in all your projects. Use it to add system header and Standard Library " - "header paths (See Finding " + "header paths (See Finding " "System Header Locations).", "Header Search Paths define where additional headers, that your project depends on, are found. Usually they are " "header files of frameworks or libraries that your project uses. These files won't be analyzed, but Coati needs " @@ -347,7 +423,7 @@ QtProjectWizzardContentPathsFrameworkSearchGlobal::QtProjectWizzardContentPathsF setInfo( "Global Framework Search Paths", "These framework search paths will be used in all your projects. Use it to add system frameworks " - "(See " + "(See " "Finding System Header Locations).", "Framework Search Paths define where MacOS framework containers (.framework), that your project depends on, are " "found.\n\n" diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.h b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.h index f0127878..41413f44 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.h +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.h @@ -80,6 +80,31 @@ public: }; +class QtProjectWizzardContentPathsCDBSource + : public QtProjectWizzardContentPaths +{ +public: + QtProjectWizzardContentPathsCDBSource(ProjectSettings* settings, QtProjectWizzardWindow* window); + + // QtProjectWizzardContentPaths implementation + virtual void loadPaths() override; + virtual void savePaths() override; + + virtual bool isScrollAble() const override; +}; + +class QtProjectWizzardContentPathsCDBHeaders + : public QtProjectWizzardContentPaths +{ +public: + QtProjectWizzardContentPathsCDBHeaders(ProjectSettings* settings, QtProjectWizzardWindow* window); + + // QtProjectWizzardContentPaths implementation + virtual void loadPaths() override; + virtual void savePaths() override; +}; + + class QtProjectWizzardContentPathsHeaderSearch : public QtProjectWizzardContentPaths {