From 0ceff0203c1f38f32775135b36a1486220b5a13a Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Mon, 13 Feb 2017 01:02:09 +0100 Subject: [PATCH] ui: Revised project setup to customer feedback * Support environment variables in compilation database path * Moved advanced option (compiler flags & exclude paths) to separate dialog * Allow environment variables that contain multiple paths * Renamed 'Project Name' to 'Coati Project Name' * Renamed 'Project File Location' to 'Coati Project Location' * Renamed 'Project Paths' to 'Indexed Paths' * Make all paths chosen by path picker relative to the project location * Disabled name and location changing in project editing and removed project moving * Added sub-titles to project setup dialogs * Warn user when no Indexed Header Paths were set * Deprecated lazy include search: It's only useable and visible to projects holding the key * Split default file extensions for C++ and C bug ids = 234 254 283 293 312 335 --- bin/app/data/gui/window/window.css | 22 +- src/lib/settings/ApplicationSettings.cpp | 8 +- src/lib/settings/CxxProjectSettings.cpp | 55 +++- src/lib/settings/CxxProjectSettings.h | 3 + src/lib/settings/JavaProjectSettings.cpp | 5 +- src/lib/settings/ProjectSettings.cpp | 38 ++- src/lib/settings/ProjectSettings.h | 4 +- src/lib/settings/Settings.cpp | 29 +- src/lib/settings/Settings.h | 4 +- src/lib/utility/file/FilePath.cpp | 29 +- src/lib/utility/file/FilePath.h | 2 +- src/lib_cxx/CxxProject.cpp | 9 +- src/lib_gui/qt/element/QtDirectoryListBox.cpp | 21 ++ src/lib_gui/qt/element/QtDirectoryListBox.h | 5 + src/lib_gui/qt/element/QtLocationPicker.cpp | 24 ++ src/lib_gui/qt/element/QtLocationPicker.h | 7 + src/lib_gui/qt/window/QtMainWindow.cpp | 17 +- src/lib_gui/qt/window/QtWindow.cpp | 29 +- src/lib_gui/qt/window/QtWindow.h | 3 + .../project_wizzard/QtProjectWizzard.cpp | 254 ++++++++++-------- .../window/project_wizzard/QtProjectWizzard.h | 4 +- .../QtProjectWizzardContentBuildFile.cpp | 14 +- .../QtProjectWizzardContentCDBSource.cpp | 4 +- .../QtProjectWizzardContentData.cpp | 57 ++-- .../QtProjectWizzardContentData.h | 11 +- .../QtProjectWizzardContentPaths.cpp | 102 ++++--- .../QtProjectWizzardContentPaths.h | 11 +- .../QtProjectWizzardContentSimple.cpp | 6 +- .../QtProjectWizzardContentSummary.cpp | 125 +++------ .../QtProjectWizzardContentSummary.h | 22 +- .../QtProjectWizzardWindow.cpp | 2 +- src/test/FilePathTestSuite.h | 8 + 32 files changed, 568 insertions(+), 366 deletions(-) diff --git a/bin/app/data/gui/window/window.css b/bin/app/data/gui/window/window.css index 8ba21eab..6079d131 100644 --- a/bin/app/data/gui/window/window.css +++ b/bin/app/data/gui/window/window.css @@ -11,6 +11,12 @@ QLabel, QCheckBox { font-weight: bold; } +#subTitle { + font-size: 13px; + font-weight: bold; + color: gray; +} + #projectTitle { font-size: 14px; font-weight: bold; @@ -89,22 +95,30 @@ QLabel, QCheckBox { } #name, #picker { - background: white; + background: transparent; border-radius: 10px; border: 1px solid lightgrey; - color: black; + color: gray; padding: 2px 5px 0px; } +#name:enabled, #picker:enabled { + color: black; +} + #locationField { - background: white; + background: transparent; border: none; border-radius: 5px; - color: black; + color: gray; margin-left: 5px; margin-top: 2px; } +#locationField:enabled { + color: black; +} + #dotsButton, #refreshButton { margin-right: 2px; } diff --git a/src/lib/settings/ApplicationSettings.cpp b/src/lib/settings/ApplicationSettings.cpp index 8b2e5dc9..533ef859 100644 --- a/src/lib/settings/ApplicationSettings.cpp +++ b/src/lib/settings/ApplicationSettings.cpp @@ -254,9 +254,7 @@ std::vector ApplicationSettings::getHeaderSearchPaths() const std::vector ApplicationSettings::getHeaderSearchPathsExpanded() const { - std::vector paths = getHeaderSearchPaths(); - expandPaths(paths); - return paths; + return expandPaths(getHeaderSearchPaths()); } bool ApplicationSettings::setHeaderSearchPaths(const std::vector& headerSearchPaths) @@ -271,9 +269,7 @@ std::vector ApplicationSettings::getFrameworkSearchPaths() const std::vector ApplicationSettings::getFrameworkSearchPathsExpanded() const { - std::vector paths = getFrameworkSearchPaths(); - expandPaths(paths); - return paths; + return expandPaths(getFrameworkSearchPaths()); } bool ApplicationSettings::setFrameworkSearchPaths(const std::vector& frameworkSearchPaths) diff --git a/src/lib/settings/CxxProjectSettings.cpp b/src/lib/settings/CxxProjectSettings.cpp index 272e91c0..6455f0a0 100644 --- a/src/lib/settings/CxxProjectSettings.cpp +++ b/src/lib/settings/CxxProjectSettings.cpp @@ -105,10 +105,7 @@ std::vector CxxProjectSettings::getHeaderSearchPaths() const std::vector CxxProjectSettings::getAbsoluteHeaderSearchPaths() const { - std::vector paths = getHeaderSearchPaths(); - expandPaths(paths); - makePathsAbsolute(paths); - return paths; + return makePathsAbsolute(expandPaths(getHeaderSearchPaths())); } bool CxxProjectSettings::setHeaderSearchPaths(const std::vector& headerSearchPaths) @@ -123,10 +120,7 @@ std::vector CxxProjectSettings::getFrameworkSearchPaths() const std::vector CxxProjectSettings::getAbsoluteFrameworkSearchPaths() const { - std::vector paths = getFrameworkSearchPaths(); - expandPaths(paths); - makePathsAbsolute(paths); - return paths; + return makePathsAbsolute(expandPaths(getFrameworkSearchPaths())); } bool CxxProjectSettings::setFrameworkSearchPaths(const std::vector& frameworkSearchPaths) @@ -155,6 +149,11 @@ bool CxxProjectSettings::setUseSourcePathsForHeaderSearch(bool useSourcePathsFor return setValue("source/use_source_paths_for_header_search", useSourcePathsForHeaderSearch); } +bool CxxProjectSettings::getHasDefinedUseSourcePathsForHeaderSearch() const +{ + return isValueDefined("source/use_source_paths_for_header_search"); +} + FilePath CxxProjectSettings::getVisualStudioSolutionPath() const { return FilePath(getValue("source/build_file_path/vs_solution_path", "")); @@ -170,6 +169,11 @@ FilePath CxxProjectSettings::getCompilationDatabasePath() const return FilePath(getValue("source/build_file_path/compilation_db_path", "")); } +FilePath CxxProjectSettings::getAbsoluteCompilationDatabasePath() const +{ + return makePathAbsolute(expandPath(getCompilationDatabasePath())); +} + bool CxxProjectSettings::setCompilationDatabasePath(const FilePath& compilationDatabasePath) { return setValue("source/build_file_path/compilation_db_path", compilationDatabasePath.str()); @@ -178,14 +182,39 @@ bool CxxProjectSettings::setCompilationDatabasePath(const FilePath& compilationD std::vector CxxProjectSettings::getDefaultSourceExtensions() const { std::vector defaultValues; - defaultValues.push_back(".c"); - defaultValues.push_back(".cpp"); - defaultValues.push_back(".cxx"); - defaultValues.push_back(".cc"); + + switch (getLanguage()) + { + case LANGUAGE_CPP: + defaultValues.push_back(".cpp"); + defaultValues.push_back(".cxx"); + defaultValues.push_back(".cc"); + break; + + case LANGUAGE_C: + defaultValues.push_back(".c"); + break; + + default: + break; + } + return defaultValues; } std::string CxxProjectSettings::getDefaultStandard() const { - return "1z"; + switch (getLanguage()) + { + case LANGUAGE_CPP: + return "c++1z"; + + case LANGUAGE_C: + return "c1x"; + + default: + break; + } + + return ""; } diff --git a/src/lib/settings/CxxProjectSettings.h b/src/lib/settings/CxxProjectSettings.h index fc77de5c..c7e001d4 100644 --- a/src/lib/settings/CxxProjectSettings.h +++ b/src/lib/settings/CxxProjectSettings.h @@ -26,13 +26,16 @@ public: std::vector getCompilerFlags() const; bool setCompilerFlags(const std::vector& compilerFlags); + // deprecated bool getUseSourcePathsForHeaderSearch() const; bool setUseSourcePathsForHeaderSearch(bool useSourcePathsForHeaderSearch); + bool getHasDefinedUseSourcePathsForHeaderSearch() const; FilePath getVisualStudioSolutionPath() const; bool setVisualStudioSolutionPath(const FilePath& visualStudioSolutionPath); FilePath getCompilationDatabasePath() const; + FilePath getAbsoluteCompilationDatabasePath() const; bool setCompilationDatabasePath(const FilePath& compilationDatabasePath); private: diff --git a/src/lib/settings/JavaProjectSettings.cpp b/src/lib/settings/JavaProjectSettings.cpp index bb5bc088..5bc804db 100644 --- a/src/lib/settings/JavaProjectSettings.cpp +++ b/src/lib/settings/JavaProjectSettings.cpp @@ -48,10 +48,7 @@ std::vector JavaProjectSettings::getClasspaths() const std::vector JavaProjectSettings::getAbsoluteClasspaths() const { - std::vector paths = getClasspaths(); - expandPaths(paths); - makePathsAbsolute(paths); - return paths; + return makePathsAbsolute(expandPaths(getClasspaths())); } bool JavaProjectSettings::setClasspaths(const std::vector& paths) diff --git a/src/lib/settings/ProjectSettings.cpp b/src/lib/settings/ProjectSettings.cpp index 77df752e..e34be9bf 100644 --- a/src/lib/settings/ProjectSettings.cpp +++ b/src/lib/settings/ProjectSettings.cpp @@ -121,10 +121,7 @@ std::vector ProjectSettings::getSourcePaths() const std::vector ProjectSettings::getAbsoluteSourcePaths() const { - std::vector paths = getSourcePaths(); - expandPaths(paths); - makePathsAbsolute(paths); - return paths; + return makePathsAbsolute(expandPaths(getSourcePaths())); } bool ProjectSettings::setSourcePaths(const std::vector& sourcePaths) @@ -139,10 +136,7 @@ std::vector ProjectSettings::getExcludePaths() const std::vector ProjectSettings::getAbsoluteExcludePaths() const { - std::vector paths = getExcludePaths(); - expandPaths(paths); - makePathsAbsolute(paths); - return paths; + return makePathsAbsolute(expandPaths(getExcludePaths())); } bool ProjectSettings::setExcludePaths(const std::vector& excludePaths) @@ -160,16 +154,36 @@ bool ProjectSettings::setSourceExtensions(const std::vector &source return setValues("source/extensions/source_extensions", sourceExtensions); } -void ProjectSettings::makePathsAbsolute(std::vector& paths) const +std::vector ProjectSettings::makePathsAbsolute(const std::vector& paths) const { + std::vector absPaths; + FilePath basePath = getProjectFileLocation(); - for (size_t i = 0; i < paths.size(); i++) + for (const FilePath& path : paths) { - if (!paths[i].isAbsolute()) + if (path.isAbsolute()) { - paths[i] = basePath.concat(paths[i]).canonical(); + absPaths.push_back(path); + } + else + { + absPaths.push_back(basePath.concat(path).canonical()); } } + + return absPaths; +} + +FilePath ProjectSettings::makePathAbsolute(const FilePath& path) const +{ + FilePath basePath = getProjectFileLocation(); + + if (!path.isAbsolute()) + { + return basePath.concat(path).canonical(); + } + + return path; } std::vector ProjectSettings::getDefaultSourceExtensions() const diff --git a/src/lib/settings/ProjectSettings.h b/src/lib/settings/ProjectSettings.h index b8b6aaf4..7834f9d3 100644 --- a/src/lib/settings/ProjectSettings.h +++ b/src/lib/settings/ProjectSettings.h @@ -54,8 +54,8 @@ public: std::vector getSourceExtensions() const; bool setSourceExtensions(const std::vector& sourceExtensions); -protected: - void makePathsAbsolute(std::vector& paths) const; + std::vector makePathsAbsolute(const std::vector& paths) const; + FilePath makePathAbsolute(const FilePath& path) const; private: virtual std::vector getDefaultSourceExtensions() const; diff --git a/src/lib/settings/Settings.cpp b/src/lib/settings/Settings.cpp index 99ff0d04..92b6b1ce 100644 --- a/src/lib/settings/Settings.cpp +++ b/src/lib/settings/Settings.cpp @@ -4,6 +4,7 @@ #include "utility/logging/logging.h" #include "utility/text/TextAccess.h" #include "utility/utilityString.h" +#include "utility/utility.h" Settings::Settings(const Settings& other) : m_config(other.m_config->createCopy()) @@ -83,6 +84,26 @@ void Settings::setVersion(size_t version) setValue("version", version); } +FilePath Settings::expandPath(const FilePath& path) +{ + std::vector paths = path.expandEnvironmentVariables(); + if (paths.size() >= 1) + { + return paths[0]; + } + return FilePath(); +} + +std::vector Settings::expandPaths(const std::vector& paths) +{ + std::vector expanedPaths; + for (const FilePath& path : paths) + { + utility::append(expanedPaths, path.expandEnvironmentVariables()); + } + return expanedPaths; +} + Settings::Settings() { clear(); @@ -106,14 +127,6 @@ std::vector Settings::getPathValues(const std::string& key) const return paths; } -void Settings::expandPaths(std::vector& paths) const -{ - for (FilePath& path : paths) - { - path = path.expandEnvironmentVariables(); - } -} - bool Settings::setPathValues(const std::string& key, const std::vector& paths) { std::vector values; diff --git a/src/lib/settings/Settings.h b/src/lib/settings/Settings.h index 5d0008fc..fa82c49f 100644 --- a/src/lib/settings/Settings.h +++ b/src/lib/settings/Settings.h @@ -28,6 +28,9 @@ public: size_t getVersion() const; void setVersion(size_t version); + static FilePath expandPath(const FilePath& path); + static std::vector expandPaths(const std::vector& paths); + protected: Settings(); @@ -40,7 +43,6 @@ protected: std::vector getValues(const std::string& key, std::vector defaultValues) const; std::vector getPathValues(const std::string& key) const; - void expandPaths(std::vector& paths) const; template bool setValue(const std::string& key, T value); diff --git a/src/lib/utility/file/FilePath.cpp b/src/lib/utility/file/FilePath.cpp index 4914bcaa..2bf4c7d5 100644 --- a/src/lib/utility/file/FilePath.cpp +++ b/src/lib/utility/file/FilePath.cpp @@ -117,8 +117,9 @@ FilePath FilePath::canonical() const return result; } -FilePath FilePath::expandEnvironmentVariables() const +std::vector FilePath::expandEnvironmentVariables() const { + std::vector paths; std::string text = str(); static std::regex env("\\$\\{([^}]+)\\}|%([^%]+)%"); // ${VARIABLE_NAME} or %VARIABLE_NAME% @@ -128,18 +129,31 @@ FilePath FilePath::expandEnvironmentVariables() const const char * s = match[1].matched ? getenv(match[1].str().c_str()) : getenv(match[2].str().c_str()); if (s == nullptr) { - LOG_ERROR(match[1].str() + " is no a environment variable"); - return FilePath(); + LOG_ERROR(match[1].str() + " is not an environment variable"); + return paths; } text.replace( match.position(0), match.length(0), s); } - return FilePath(text); + char environmentVariablePathSeparator = ':'; + +#if defined(_WIN32) || defined(_WIN64) + environmentVariablePathSeparator = ';'; +#endif + + for (const std::string& str : utility::splitToVector(text, environmentVariablePathSeparator)) + { + if (str.size()) + { + paths.push_back(str); + } + } + + return paths; } FilePath FilePath::relativeTo(const FilePath& other) const { - boost::filesystem::path a = this->canonical().m_path; boost::filesystem::path b = other.canonical().m_path; @@ -161,7 +175,10 @@ FilePath FilePath::relativeTo(const FilePath& other) const if (itB != b.end()) { - itB++; + if (!boost::filesystem::is_directory(b)) + { + itB++; + } for (; itB != b.end(); itB++) { diff --git a/src/lib/utility/file/FilePath.h b/src/lib/utility/file/FilePath.h index 45066507..73b1a195 100644 --- a/src/lib/utility/file/FilePath.h +++ b/src/lib/utility/file/FilePath.h @@ -27,7 +27,7 @@ public: FilePath canonical() const; FilePath relativeTo(const FilePath& other) const; FilePath concat(const FilePath& other) const; - FilePath expandEnvironmentVariables() const; + std::vector expandEnvironmentVariables() const; bool contains(const FilePath& other) const; diff --git a/src/lib_cxx/CxxProject.cpp b/src/lib_cxx/CxxProject.cpp index dbb471fe..cce83e28 100644 --- a/src/lib_cxx/CxxProject.cpp +++ b/src/lib_cxx/CxxProject.cpp @@ -34,7 +34,7 @@ const std::shared_ptr CxxProject::getProjectSettings() const bool CxxProject::prepareRefresh() { - FilePath cdbPath = m_projectSettings->getCompilationDatabasePath(); + FilePath cdbPath = m_projectSettings->getAbsoluteCompilationDatabasePath(); if (!cdbPath.empty() && !cdbPath.exists()) { MessageStatus("Can't refresh project").dispatch(); @@ -72,9 +72,10 @@ void CxxProject::updateFileManager(FileManager& fileManager) std::vector sourceExtensions; - if (m_projectSettings->getCompilationDatabasePath().exists()) + FilePath cdbPath = m_projectSettings->getAbsoluteCompilationDatabasePath(); + if (cdbPath.exists()) { - sourcePaths = TaskParseCxx::getSourceFilesFromCDB(m_projectSettings->getCompilationDatabasePath()); + sourcePaths = TaskParseCxx::getSourceFilesFromCDB(cdbPath); } else { @@ -124,7 +125,7 @@ Parser::Arguments CxxProject::getParserArguments() const args.language = languageTypeToString(m_projectSettings->getLanguage()); args.languageStandard = m_projectSettings->getStandard(); - args.compilationDatabasePath = m_projectSettings->getCompilationDatabasePath(); + args.compilationDatabasePath = m_projectSettings->getAbsoluteCompilationDatabasePath(); return args; } diff --git a/src/lib_gui/qt/element/QtDirectoryListBox.cpp b/src/lib_gui/qt/element/QtDirectoryListBox.cpp index 2f29a469..0352410e 100644 --- a/src/lib_gui/qt/element/QtDirectoryListBox.cpp +++ b/src/lib_gui/qt/element/QtDirectoryListBox.cpp @@ -54,6 +54,17 @@ QString QtListItemWidget::getText() void QtListItemWidget::setText(QString text) { + FilePath relativeRoot = m_list->getRelativeRootDirectory(); + if (!relativeRoot.empty()) + { + FilePath path(text.toStdString()); + FilePath relPath(path.relativeTo(relativeRoot)); + if (relPath.str().size() < path.str().size()) + { + text = QString::fromStdString(relPath.str()); + } + } + m_data->setText(text); } @@ -283,6 +294,16 @@ bool QtDirectoryListBox::isForStrings() const return m_forStrings; } +const FilePath& QtDirectoryListBox::getRelativeRootDirectory() const +{ + return m_relativeRootDirectory; +} + +void QtDirectoryListBox::setRelativeRootDirectory(const FilePath& dir) +{ + m_relativeRootDirectory = dir; +} + void QtDirectoryListBox::resize() { int height = m_list->height() - m_list->viewport()->height(); diff --git a/src/lib_gui/qt/element/QtDirectoryListBox.h b/src/lib_gui/qt/element/QtDirectoryListBox.h index b93e50a9..c9d4f330 100644 --- a/src/lib_gui/qt/element/QtDirectoryListBox.h +++ b/src/lib_gui/qt/element/QtDirectoryListBox.h @@ -63,6 +63,9 @@ public: bool isForStrings() const; + const FilePath& getRelativeRootDirectory() const; + void setRelativeRootDirectory(const FilePath& dir); + protected: bool event(QEvent* event) override; @@ -88,6 +91,8 @@ private: bool m_forStrings; std::shared_ptr m_editDialog; + + FilePath m_relativeRootDirectory; }; #endif // QT_DIRECTORY_LIST_BOX_H diff --git a/src/lib_gui/qt/element/QtLocationPicker.cpp b/src/lib_gui/qt/element/QtLocationPicker.cpp index 99891770..1ab84506 100644 --- a/src/lib_gui/qt/element/QtLocationPicker.cpp +++ b/src/lib_gui/qt/element/QtLocationPicker.cpp @@ -1,5 +1,6 @@ #include "qt/element/QtLocationPicker.h" +#include #include #include #include @@ -72,6 +73,19 @@ void QtLocationPicker::setFileFilter(const QString& fileFilter) m_fileFilter = fileFilter; } +void QtLocationPicker::setRelativeRootDirectory(const FilePath& dir) +{ + m_relativeRootDirectory = dir; +} + +void QtLocationPicker::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::EnabledChange) + { + m_button->setVisible(isEnabled()); + } +} + void QtLocationPicker::handleButtonPress() { QString fileName; @@ -86,6 +100,16 @@ void QtLocationPicker::handleButtonPress() if (!fileName.isEmpty()) { + if (!m_relativeRootDirectory.empty()) + { + FilePath path(fileName.toStdString()); + FilePath relPath(path.relativeTo(m_relativeRootDirectory)); + if (relPath.str().size() < path.str().size()) + { + fileName = QString::fromStdString(relPath.str()); + } + } + m_data->setText(fileName); emit locationPicked(); } diff --git a/src/lib_gui/qt/element/QtLocationPicker.h b/src/lib_gui/qt/element/QtLocationPicker.h index 1d3ca25d..4b8f00bc 100644 --- a/src/lib_gui/qt/element/QtLocationPicker.h +++ b/src/lib_gui/qt/element/QtLocationPicker.h @@ -4,6 +4,7 @@ #include #include "qt/element/QtLineEdit.h" +#include "utility/file/FilePath.h" class QtLocationPicker : public QWidget @@ -23,9 +24,14 @@ public: void setPickDirectory(bool pickDirectory); void setFileFilter(const QString& fileFilter); + void setRelativeRootDirectory(const FilePath& dir); + signals: void locationPicked(); +protected: + void changeEvent(QEvent *event) override; + private slots: void handleButtonPress(); @@ -35,6 +41,7 @@ private: bool m_pickDirectory; QString m_fileFilter; + FilePath m_relativeRootDirectory; }; #endif // QT_LOCATION_PICKER_H diff --git a/src/lib_gui/qt/window/QtMainWindow.cpp b/src/lib_gui/qt/window/QtMainWindow.cpp index d1a8b2ed..d0f940af 100644 --- a/src/lib_gui/qt/window/QtMainWindow.cpp +++ b/src/lib_gui/qt/window/QtMainWindow.cpp @@ -362,22 +362,15 @@ void QtMainWindow::showLogFolder() void QtMainWindow::showStartScreen() { - QtStartScreen* startScreen = createWindow(); - LicenseChecker::LicenseState state = LicenseChecker::getInstance()->checkCurrentLicense(); bool licenseValid = (state == LicenseChecker::LICENSE_VALID); - startScreen->setupStartScreen(licenseValid); - setTrialActionsEnabled(licenseValid); - if (licenseValid) { MessageEnteredLicense().dispatch(); } - connect(startScreen, SIGNAL(openOpenProjectDialog()), this, SLOT(openProject())); - connect(startScreen, SIGNAL(openNewProjectDialog()), this, SLOT(newProject())); - connect(startScreen, SIGNAL(openEnterLicenseDialog()), this, SLOT(enterLicense())); + setTrialActionsEnabled(licenseValid); if (state == LicenseChecker::LICENSE_MOVED) { @@ -388,6 +381,14 @@ void QtMainWindow::showStartScreen() { forceEnterLicense(state == LicenseChecker::LICENSE_EXPIRED); } + + + QtStartScreen* startScreen = createWindow(); + startScreen->setupStartScreen(licenseValid); + + connect(startScreen, SIGNAL(openOpenProjectDialog()), this, SLOT(openProject())); + connect(startScreen, SIGNAL(openNewProjectDialog()), this, SLOT(newProject())); + connect(startScreen, SIGNAL(openEnterLicenseDialog()), this, SLOT(enterLicense())); } void QtMainWindow::hideStartScreen() diff --git a/src/lib_gui/qt/window/QtWindow.cpp b/src/lib_gui/qt/window/QtWindow.cpp index 71577551..da64b0f8 100644 --- a/src/lib_gui/qt/window/QtWindow.cpp +++ b/src/lib_gui/qt/window/QtWindow.cpp @@ -15,6 +15,7 @@ QtWindow::QtWindow(QWidget* parent) : QtWindowStackElement(parent) , m_window(nullptr) , m_title(nullptr) + , m_subTitle(nullptr) , m_nextButton(nullptr) , m_previousButton(nullptr) , m_closeButton(nullptr) @@ -81,9 +82,23 @@ void QtWindow::setup() QVBoxLayout* layout = new QVBoxLayout(); layout->setContentsMargins(25, 30, 25, 0); - m_title = new QLabel(); - m_title->setObjectName("title"); - layout->addWidget(m_title); + { + QHBoxLayout* hlayout = new QHBoxLayout(); + hlayout->setContentsMargins(0, 0, 0, 0); + + m_title = new QLabel(); + m_title->setObjectName("title"); + hlayout->addWidget(m_title); + + hlayout->addStretch(); + + m_subTitle = new QLabel(); + m_subTitle->setObjectName("subTitle"); + hlayout->addWidget(m_subTitle); + + layout->addLayout(hlayout); + } + layout->addSpacing(10); QWidget* contentWidget = new QWidget(); @@ -175,6 +190,14 @@ void QtWindow::updateTitle(QString title) } } +void QtWindow::updateSubTitle(QString subTitle) +{ + if (m_subTitle) + { + m_subTitle->setText(subTitle); + } +} + void QtWindow::updateNextButton(QString text) { if (m_nextButton) diff --git a/src/lib_gui/qt/window/QtWindow.h b/src/lib_gui/qt/window/QtWindow.h index 3b677b54..0848af8b 100644 --- a/src/lib_gui/qt/window/QtWindow.h +++ b/src/lib_gui/qt/window/QtWindow.h @@ -32,6 +32,8 @@ public: bool isScrollAble() const; void updateTitle(QString title); + void updateSubTitle(QString subTitle); + void updateNextButton(QString text); void updateCloseButton(QString text); @@ -80,6 +82,7 @@ protected: QWidget* m_content; QLabel* m_title; + QLabel* m_subTitle; QPushButton* m_nextButton; QPushButton* m_previousButton; diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.cpp index 0dae83e5..50012484 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.cpp @@ -24,6 +24,7 @@ #include "utility/messaging/type/MessageRefresh.h" #include "utility/messaging/type/MessageScrollSpeedChange.h" #include "utility/messaging/type/MessageStatus.h" +#include "utility/utility.h" #include "utility/utilityPathDetection.h" #include "utility/utilityString.h" @@ -81,6 +82,7 @@ void QtProjectWizzard::newProject() window->setNextEnabled(false); window->setPreviousEnabled(false); + window->updateSubTitle("Type Selection"); } void QtProjectWizzard::newProjectFromSolution(const std::string& ideId, const std::string& visualStudioSolutionPath) @@ -208,16 +210,6 @@ void QtProjectWizzard::editProject(std::shared_ptr settings) default: break; } - - QtProjectWizzardWindow* window = dynamic_cast(m_windowStack.getTopWindow()); - if (!window) - { - return; - } - - window->updateTitle("EDIT PROJECT"); - window->updateNextButton("Save"); - window->setPreviousVisible(false); } void QtProjectWizzard::showPreferences() @@ -227,12 +219,12 @@ void QtProjectWizzard::showPreferences() { summary->setIsForm(true); - summary->addContent(new QtProjectWizzardContentPreferences(m_settings, window), false, false); + summary->addContent(new QtProjectWizzardContentPreferences(m_settings, window)); - summary->addContent(new QtProjectWizzardContentPathsHeaderSearchGlobal(m_settings, window), false, false); + summary->addContent(new QtProjectWizzardContentPathsHeaderSearchGlobal(m_settings, window)); if (QSysInfo::macVersion() != QSysInfo::MV_None) { - summary->addContent(new QtProjectWizzardContentPathsFrameworkSearchGlobal(m_settings, window), false, false); + summary->addContent(new QtProjectWizzardContentPathsFrameworkSearchGlobal(m_settings, window)); } window->setup(); @@ -248,20 +240,24 @@ void QtProjectWizzard::showPreferences() bool QtProjectWizzard::applicationSettingsContainVisualStudioHeaderSearchPaths() { - std::vector usedExpandedGlobalHeaderSearchPaths = ApplicationSettings::getInstance()->getHeaderSearchPathsExpanded(); - + std::vector expandedPaths; const std::shared_ptr headerPathDetector = utility::getCxxVsHeaderPathDetector(); for (const std::string& detectorName: headerPathDetector->getWorkingDetectorNames()) { for (const FilePath& path: headerPathDetector->getPaths(detectorName)) { - const FilePath expandedPath = path.expandEnvironmentVariables(); - for (const FilePath& usedExpandedPath: usedExpandedGlobalHeaderSearchPaths) + utility::append(expandedPaths, path.expandEnvironmentVariables()); + } + } + + std::vector usedExpandedGlobalHeaderSearchPaths = ApplicationSettings::getInstance()->getHeaderSearchPathsExpanded(); + for (const FilePath& usedExpandedPath: usedExpandedGlobalHeaderSearchPaths) + { + for (const FilePath& expandedPath: expandedPaths) + { + if (expandedPath == usedExpandedPath) { - if (expandedPath == usedExpandedPath) - { - return true; - } + return true; } } } @@ -414,6 +410,7 @@ void QtProjectWizzard::selectedProjectType(LanguageType languageType, QtProjectW void QtProjectWizzard::emptyProject() { QtProjectWizzardWindow* window = createWindowWithContent(); + window->updateSubTitle("Project Data"); if (m_settings->getLanguage() == LANGUAGE_JAVA) { @@ -430,14 +427,16 @@ void QtProjectWizzard::sourcePaths() QtProjectWizzardWindow* window = createWindowWithSummary( [this](QtProjectWizzardWindow* window, QtProjectWizzardContentSummary* summary) { - summary->addContent(new QtProjectWizzardContentPathsSource(m_settings, window), false, false); - summary->addContent(new QtProjectWizzardContentExtensions(m_settings, window), false, true); + summary->addContent(new QtProjectWizzardContentPathsSource(m_settings, window)); + summary->addSpace(); + summary->addContent(new QtProjectWizzardContentExtensions(m_settings, window)); window->setup(); } ); connect(window, SIGNAL(next()), this, SLOT(headerSearchPaths())); + window->updateSubTitle("Indexed Paths"); } void QtProjectWizzard::headerSearchPaths() @@ -445,15 +444,16 @@ void QtProjectWizzard::headerSearchPaths() QtProjectWizzardWindow* window = createWindowWithSummary( [this](QtProjectWizzardWindow* window, QtProjectWizzardContentSummary* summary) { - summary->addContent(new QtProjectWizzardContentPathsHeaderSearch(m_settings, window), false, false); - summary->addContent(new QtProjectWizzardContentSimple(m_settings, window), false, true); - summary->addContent(new QtProjectWizzardContentPathsHeaderSearchGlobal(m_settings, window), false, true); + summary->addContent(new QtProjectWizzardContentPathsHeaderSearch(m_settings, window)); + summary->addSpace(); + summary->addContent(new QtProjectWizzardContentPathsHeaderSearchGlobal(m_settings, window)); window->setup(); } ); connect(window, SIGNAL(next()), this, SLOT(headerSearchPathsDone())); + window->updateSubTitle("Include Paths"); } void QtProjectWizzard::headerSearchPathsDone() @@ -464,7 +464,7 @@ void QtProjectWizzard::headerSearchPathsDone() } else { - showSummary(); + advancedSettingsCxx(); } } @@ -473,14 +473,16 @@ void QtProjectWizzard::frameworkSearchPaths() QtProjectWizzardWindow* window = createWindowWithSummary( [this](QtProjectWizzardWindow* window, QtProjectWizzardContentSummary* summary) { - summary->addContent(new QtProjectWizzardContentPathsFrameworkSearch(m_settings, window), false, false); - summary->addContent(new QtProjectWizzardContentPathsFrameworkSearchGlobal(m_settings, window), false, true); + summary->addContent(new QtProjectWizzardContentPathsFrameworkSearch(m_settings, window)); + summary->addSpace(); + summary->addContent(new QtProjectWizzardContentPathsFrameworkSearchGlobal(m_settings, window)); window->setup(); } ); - connect(window, SIGNAL(next()), this, SLOT(showSummary())); + connect(window, SIGNAL(next()), this, SLOT(advancedSettingsCxx())); + window->updateSubTitle("Framework Search Paths"); } void QtProjectWizzard::emptyProjectCDBVS() @@ -488,6 +490,7 @@ void QtProjectWizzard::emptyProjectCDBVS() QtProjectWizzardWindow* window = createWindowWithContent(); connect(window, SIGNAL(next()), this, SLOT(headerPathsCDB())); + window->updateSubTitle("Project Data"); } void QtProjectWizzard::emptyProjectCDB() @@ -495,6 +498,7 @@ void QtProjectWizzard::emptyProjectCDB() QtProjectWizzardWindow* window = createWindowWithContent(); connect(window, SIGNAL(next()), this, SLOT(headerPathsCDB())); + window->updateSubTitle("Project Data"); } void QtProjectWizzard::headerPathsCDB() @@ -502,14 +506,16 @@ void QtProjectWizzard::headerPathsCDB() QtProjectWizzardWindow* window = createWindowWithSummary( [this](QtProjectWizzardWindow* window, QtProjectWizzardContentSummary* summary) { - summary->addContent(new QtProjectWizzardContentCDBSource(m_settings, window), false, false); - summary->addContent(new QtProjectWizzardContentPathsCDBHeader(m_settings, window), false, true); + summary->addContent(new QtProjectWizzardContentCDBSource(m_settings, window)); + summary->addSpace(); + summary->addContent(new QtProjectWizzardContentPathsCDBHeader(m_settings, window)); window->setup(); } ); - connect(window, SIGNAL(next()), this, SLOT(showSummary())); + connect(window, SIGNAL(next()), this, SLOT(advancedSettingsCxx())); + window->updateSubTitle("Indexed Header Paths"); } void QtProjectWizzard::sourcePathsJava() @@ -517,14 +523,50 @@ void QtProjectWizzard::sourcePathsJava() QtProjectWizzardWindow* window = createWindowWithSummary( [this](QtProjectWizzardWindow* window, QtProjectWizzardContentSummary* summary) { - summary->addContent(new QtProjectWizzardContentPathsSourceJava(m_settings, window), false, false); - summary->addContent(new QtProjectWizzardContentPathsClassJava(m_settings, window), false, true); + summary->addContent(new QtProjectWizzardContentPathsSource(m_settings, window)); + summary->addSpace(); + summary->addContent(new QtProjectWizzardContentPathsClassJava(m_settings, window)); + + window->setup(); + } + ); + + connect(window, SIGNAL(next()), this, SLOT(advancedSettingsJava())); + window->updateSubTitle("Indexed Paths"); +} + +void QtProjectWizzard::advancedSettingsCxx() +{ + QtProjectWizzardWindow* window = createWindowWithSummary( + [this](QtProjectWizzardWindow* window, QtProjectWizzardContentSummary* summary) + { + summary->addContent(new QtProjectWizzardContentFlags(m_settings, window)); + summary->addSpace(); + summary->addContent(new QtProjectWizzardContentPathsExclude(m_settings, window)); + + window->setup(); + } + ); + + connect(window, SIGNAL(next()), this, SLOT(showSummary())); + window->updateSubTitle("Advanced (optional)"); +} + +void QtProjectWizzard::advancedSettingsJava() +{ + QtProjectWizzardWindow* window = createWindowWithSummary( + [this](QtProjectWizzardWindow* window, QtProjectWizzardContentSummary* summary) + { + summary->addContent(new QtProjectWizzardContentExtensions(m_settings, window)); + summary->addSpace(); + summary->addContent(new QtProjectWizzardContentPathsExclude(m_settings, window)); window->setup(); } ); connect(window, SIGNAL(next()), this, SLOT(showSummaryJava())); + window->updateSubTitle("Advanced (optional)"); } void QtProjectWizzard::showSummary() @@ -535,57 +577,72 @@ void QtProjectWizzard::showSummary() summary->setIsForm(true); QtProjectWizzardContentBuildFile* buildFile = new QtProjectWizzardContentBuildFile(m_settings, window); + bool isCDB = buildFile->getType() == QtProjectWizzardContentSelect::PROJECT_CDB; - if (buildFile->getType() != QtProjectWizzardContentSelect::PROJECT_CDB) + if (!isCDB) { - summary->addContent(new QtProjectWizzardContentData(m_settings, window), false, false); + summary->addContent(new QtProjectWizzardContentData(m_settings, window, m_editing)); + summary->addSpace(); if (buildFile->getType() == QtProjectWizzardContentSelect::PROJECT_MANAGED) { - summary->addContent(buildFile, false, true); + summary->addContent(buildFile); + summary->addSpace(); connect(dynamic_cast(buildFile), SIGNAL(refreshVisualStudioSolution(const std::string&, const std::string&)), this, SLOT(refreshProjectFromSolution(const std::string&, const std::string&))); } - summary->addContent(new QtProjectWizzardContentPathsSource(m_settings, window), false, true); - summary->addContent(new QtProjectWizzardContentPathsHeaderSearch(m_settings, window), false, true); - summary->addContent(new QtProjectWizzardContentSimple(m_settings, window), false, false); - summary->addContent(new QtProjectWizzardContentPathsHeaderSearchGlobal(m_settings, window), false, false); - - if (QSysInfo::macVersion() != QSysInfo::MV_None) - { - summary->addContent(new QtProjectWizzardContentPathsFrameworkSearch(m_settings, window), false, true); - summary->addContent(new QtProjectWizzardContentPathsFrameworkSearchGlobal(m_settings, window), false, false); - } - - summary->addContent(new QtProjectWizzardContentExtensions(m_settings, window), true, false); - summary->addContent(new QtProjectWizzardContentFlags(m_settings, window), true, true); - summary->addContent(new QtProjectWizzardContentPathsExclude(m_settings, window), true, true); + summary->addContent(new QtProjectWizzardContentPathsSource(m_settings, window)); + summary->addContent(new QtProjectWizzardContentExtensions(m_settings, window)); + summary->addSpace(); } else { - summary->addContent(new QtProjectWizzardContentDataCDB(m_settings, window), false, false); - summary->addContent(new QtProjectWizzardContentPathsCDBHeader(m_settings, window), false, true); + summary->addContent(new QtProjectWizzardContentDataCDB(m_settings, window, m_editing)); + summary->addSpace(); - summary->addContent(new QtProjectWizzardContentPathsHeaderSearch(m_settings, window, true), false, true); - summary->addContent(new QtProjectWizzardContentPathsHeaderSearchGlobal(m_settings, window), false, false); - - if (QSysInfo::macVersion() != QSysInfo::MV_None) - { - summary->addContent(new QtProjectWizzardContentPathsFrameworkSearch(m_settings, window, true), false, true); - summary->addContent(new QtProjectWizzardContentPathsFrameworkSearchGlobal(m_settings, window), false, false); - } - - summary->addContent(new QtProjectWizzardContentFlags(m_settings, window), true, false); - summary->addContent(new QtProjectWizzardContentPathsExclude(m_settings, window), true, true); + summary->addContent(new QtProjectWizzardContentPathsCDBHeader(m_settings, window)); + summary->addSpace(); } + summary->addContent(new QtProjectWizzardContentPathsHeaderSearch(m_settings, window, isCDB)); + + std::shared_ptr cxxSettings = std::dynamic_pointer_cast(m_settings); + if (!isCDB && cxxSettings && cxxSettings->getHasDefinedUseSourcePathsForHeaderSearch()) + { + summary->addSpace(); + summary->addContent(new QtProjectWizzardContentSimple(m_settings, window)); + } + + summary->addContent(new QtProjectWizzardContentPathsHeaderSearchGlobal(m_settings, window)); + summary->addSpace(); + + if (QSysInfo::macVersion() != QSysInfo::MV_None) + { + summary->addContent(new QtProjectWizzardContentPathsFrameworkSearch(m_settings, window, isCDB)); + summary->addContent(new QtProjectWizzardContentPathsFrameworkSearchGlobal(m_settings, window)); + summary->addSpace(); + } + + summary->addContent(new QtProjectWizzardContentFlags(m_settings, window)); + summary->addSpace(); + summary->addContent(new QtProjectWizzardContentPathsExclude(m_settings, window)); + window->setup(); - window->updateTitle("NEW PROJECT - SUMMARY"); - window->updateNextButton("Create"); + if (m_editing) + { + window->updateTitle("EDIT PROJECT"); + window->updateNextButton("Save"); + window->setPreviousVisible(false); + } + else + { + window->updateSubTitle("Summary"); + window->updateNextButton("Create"); + } } ); @@ -599,18 +656,32 @@ void QtProjectWizzard::showSummaryJava() { summary->setIsForm(true); - summary->addContent(new QtProjectWizzardContentData(m_settings, window), false, false); + summary->addContent(new QtProjectWizzardContentData(m_settings, window, m_editing)); + summary->addSpace(); - summary->addContent(new QtProjectWizzardContentPathsSourceJava(m_settings, window), false, true); - summary->addContent(new QtProjectWizzardContentPathsClassJava(m_settings, window), false, true); + summary->addContent(new QtProjectWizzardContentPathsSource(m_settings, window)); + summary->addSpace(); - summary->addContent(new QtProjectWizzardContentExtensions(m_settings, window), true, false); - summary->addContent(new QtProjectWizzardContentPathsExclude(m_settings, window), true, true); + summary->addContent(new QtProjectWizzardContentPathsClassJava(m_settings, window)); + summary->addSpace(); + + summary->addContent(new QtProjectWizzardContentExtensions(m_settings, window)); + summary->addSpace(); + summary->addContent(new QtProjectWizzardContentPathsExclude(m_settings, window)); window->setup(); - window->updateTitle("NEW PROJECT - SUMMARY"); - window->updateNextButton("Create"); + if (m_editing) + { + window->updateTitle("EDIT PROJECT"); + window->updateNextButton("Save"); + window->setPreviousVisible(false); + } + else + { + window->updateSubTitle("Summary"); + window->updateNextButton("Create"); + } } ); @@ -627,42 +698,9 @@ void QtProjectWizzard::createProject() bool forceRefreshProject = false; if (m_editing) { - std::shared_ptr application = Application::getInstance(); - FilePath oldPath; - - Project* currentProject = application->getCurrentProject().get(); - if (currentProject) - { - oldPath = currentProject->getProjectSettingsFilePath(); - } - - if (oldPath.exists() && oldPath != path) - { - std::vector options; - options.push_back("Yes"); - options.push_back("No"); - int result = application->handleDialog( - "You changed the project location. The project file (.coatiproject) and the database file (.coatidb) will " - "be moved to the new location. Do you want to keep a copy of the files in the previous location?" - , options - ); - - FilePath dbPath = FilePath(path).replaceExtension("coatidb"); - FilePath oldDbPath = FilePath(oldPath).replaceExtension("coatidb"); - - if (result == 0) - { - FileSystem::copyFile(oldDbPath, dbPath); - } - else - { - FileSystem::remove(oldPath); - FileSystem::rename(oldDbPath, dbPath); - } - } - bool settingsChanged = false; + Application* application = Application::getInstance().get(); if (application->getCurrentProject() != NULL) { settingsChanged = !(application->getCurrentProject()->settingsEqualExceptNameAndLocation(*(m_settings.get()))); diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.h b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.h index db006e6d..fd01e921 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.h +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.h @@ -76,12 +76,14 @@ private slots: void frameworkSearchPaths(); void emptyProjectCDBVS(); - void emptyProjectCDB(); void headerPathsCDB(); void sourcePathsJava(); + void advancedSettingsCxx(); + void advancedSettingsJava(); + void showSummary(); void showSummaryJava(); diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentBuildFile.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentBuildFile.cpp index e8dbdb0c..6a2bfe46 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentBuildFile.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentBuildFile.cpp @@ -57,6 +57,7 @@ void QtProjectWizzardContentBuildFile::populate(QGridLayout* layout, int& row) m_picker = new QtLocationPicker(this); m_picker->setFileFilter(filter); + m_picker->setRelativeRootDirectory(m_settings->getProjectFileLocation()); QPushButton* button = new QPushButton("", this); button->setObjectName("refreshButton"); @@ -108,11 +109,12 @@ void QtProjectWizzardContentBuildFile::save() case QtProjectWizzardContentSelect::PROJECT_CDB: { FilePath path = m_picker->getText().toStdString(); - if (!path.exists() || path.extension() != ".json") + FilePath absPath = m_settings->makePathAbsolute(m_settings->expandPath(path)); + if (!absPath.exists() || absPath.extension() != ".json") { return; } - cxxSettings->setCompilationDatabasePath(m_picker->getText().toStdString()); + cxxSettings->setCompilationDatabasePath(path); break; } } @@ -129,7 +131,8 @@ bool QtProjectWizzardContentBuildFile::check() case QtProjectWizzardContentSelect::PROJECT_CDB: { FilePath path = m_picker->getText().toStdString(); - if (!path.exists() || path.extension() != ".json") + FilePath absPath = m_settings->makePathAbsolute(m_settings->expandPath(path)); + if (!absPath.exists() || absPath.extension() != ".json") { QMessageBox msgBox; msgBox.setText("Please enter a valid compilation database file (*.json)."); @@ -144,8 +147,9 @@ bool QtProjectWizzardContentBuildFile::check() void QtProjectWizzardContentBuildFile::refreshClicked() { - FilePath path = FilePath(m_picker->getText().toStdString()); - if (!path.exists()) + FilePath path = m_picker->getText().toStdString(); + FilePath absPath = m_settings->makePathAbsolute(m_settings->expandPath(path)); + if (!absPath.exists()) { QMessageBox msgBox; msgBox.setText("Please enter a valid file path."); diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentCDBSource.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentCDBSource.cpp index 439d0284..d9d8e4db 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentCDBSource.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentCDBSource.cpp @@ -35,7 +35,9 @@ void QtProjectWizzardContentCDBSource::load() std::shared_ptr cxxSettings = std::dynamic_pointer_cast(m_settings); if (cxxSettings) { - std::vector filePaths = TaskParseCxx::getSourceFilesFromCDB(cxxSettings->getCompilationDatabasePath()); + std::vector filePaths = + TaskParseCxx::getSourceFilesFromCDB(cxxSettings->getAbsoluteCompilationDatabasePath()); + for (FilePath path : filePaths) { bool excluded = false; diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentData.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentData.cpp index 36a1c9a3..27793e5b 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentData.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentData.cpp @@ -8,8 +8,11 @@ #include "utility/messaging/type/MessageIDECreateCDB.h" #include "utility/logging/logging.h" -QtProjectWizzardContentData::QtProjectWizzardContentData(std::shared_ptr settings, QtProjectWizzardWindow* window) +QtProjectWizzardContentData::QtProjectWizzardContentData( + std::shared_ptr settings, QtProjectWizzardWindow* window, bool disableNameEditing +) : QtProjectWizzardContent(settings, window) + , m_disableNameEditing(disableNameEditing) , m_projectName(nullptr) , m_projectFileLocation(nullptr) , m_language(nullptr) @@ -105,12 +108,13 @@ bool QtProjectWizzardContentData::check() if (m_projectFileLocation->getText().isEmpty()) { QMessageBox msgBox; - msgBox.setText("Please define the location of the project file."); + msgBox.setText("Please define the location for the Coati project file."); msgBox.exec(); return false; } - if (!FilePath(m_projectFileLocation->getText().toStdString()).expandEnvironmentVariables().exists()) + std::vector paths = FilePath(m_projectFileLocation->getText().toStdString()).expandEnvironmentVariables(); + if (paths.size() != 1 || !paths[0].exists()) { QMessageBox msgBox; msgBox.setText("The specified location does not exist."); @@ -123,22 +127,24 @@ bool QtProjectWizzardContentData::check() void QtProjectWizzardContentData::addNameAndLocation(QGridLayout* layout, int& row) { - QLabel* nameLabel = createFormLabel("Project Name"); + QLabel* nameLabel = createFormLabel("Coati Project Name"); m_projectName = new QLineEdit(); m_projectName->setObjectName("name"); m_projectName->setAttribute(Qt::WA_MacShowFocusRect, 0); + m_projectName->setEnabled(!m_disableNameEditing); layout->addWidget(nameLabel, row, QtProjectWizzardWindow::FRONT_COL, Qt::AlignRight); layout->addWidget(m_projectName, row, QtProjectWizzardWindow::BACK_COL); row++; - - QLabel* locationLabel = createFormLabel("Project File Location"); + QLabel* locationLabel = createFormLabel("Coati Project Location"); m_projectFileLocation = new QtLocationPicker(this); m_projectFileLocation->setPickDirectory(true); + m_projectFileLocation->setEnabled(!m_disableNameEditing); layout->addWidget(locationLabel, row, QtProjectWizzardWindow::FRONT_COL, Qt::AlignRight); layout->addWidget(m_projectFileLocation, row, QtProjectWizzardWindow::BACK_COL, Qt::AlignTop); + addHelpButton("The directory where Coati project files will be saved to.", layout, row); layout->setRowMinimumHeight(row, 30); row++; } @@ -164,6 +170,7 @@ void QtProjectWizzardContentData::addBuildFilePicker( m_buildFilePicker = new QtLocationPicker(this); m_buildFilePicker->setFileFilter(filter); + connect(m_buildFilePicker, SIGNAL(locationPicked()), this, SLOT(pickedCDBPath())); layout->addWidget(m_buildFilePicker, row, QtProjectWizzardWindow::BACK_COL); @@ -181,8 +188,8 @@ void QtProjectWizzardContentData::addBuildFilePicker( QtProjectWizzardContentDataCDB::QtProjectWizzardContentDataCDB( - std::shared_ptr settings, QtProjectWizzardWindow* window) - : QtProjectWizzardContentData(settings, window) + std::shared_ptr settings, QtProjectWizzardWindow* window, bool disableNameEditing) + : QtProjectWizzardContentData(settings, window, disableNameEditing) { } @@ -224,7 +231,8 @@ void QtProjectWizzardContentDataCDB::save() QtProjectWizzardContentData::save(); FilePath path = m_buildFilePicker->getText().toStdString(); - if (!path.exists() || path.extension() != ".json") + FilePath absPath = m_settings->makePathAbsolute(m_settings->expandPath(path)); + if (!absPath.exists() || absPath.extension() != ".json") { return; } @@ -244,7 +252,8 @@ bool QtProjectWizzardContentDataCDB::check() } FilePath path = m_buildFilePicker->getText().toStdString(); - if (!path.exists() || path.extension() != ".json") + FilePath absPath = m_settings->makePathAbsolute(m_settings->expandPath(path)); + if (!absPath.exists() || absPath.extension() != ".json") { QMessageBox msgBox; msgBox.setText("Please enter a valid compilation database file (*.json)."); @@ -255,15 +264,29 @@ bool QtProjectWizzardContentDataCDB::check() return true; } -void QtProjectWizzardContentDataCDB::refreshClicked() +void QtProjectWizzardContentDataCDB::pickedCDBPath() { + FilePath projectPath = m_settings->getProjectFileLocation(); + if (m_projectFileLocation) + { + projectPath = FilePath(m_projectFileLocation->getText().toStdString()); + } + + FilePath cdbPath(m_buildFilePicker->getText().toStdString()); + + if (!projectPath.empty() && !cdbPath.empty()) + { + FilePath relPath(cdbPath.relativeTo(projectPath)); + if (relPath.str().size() < cdbPath.str().size()) + { + m_buildFilePicker->setText(relPath.str().c_str()); + } + } } - - QtProjectWizzardContentDataCDBVS::QtProjectWizzardContentDataCDBVS(std::shared_ptr settings, QtProjectWizzardWindow* window) - : QtProjectWizzardContentDataCDB(settings, window) + : QtProjectWizzardContentDataCDB(settings, window, false) { } @@ -299,7 +322,7 @@ Note: Coati's Visual Studio plugin has to be installed. Visual Studio has to be skipLabel->setAlignment(Qt::AlignmentFlag::AlignLeft); layout->addWidget(skipLabel, row, QtProjectWizzardWindow::BACK_COL); row++; - + QFrame* separator = new QFrame(); separator->setFrameShape(QFrame::HLine); @@ -328,10 +351,6 @@ Note: Coati's Visual Studio plugin has to be installed. Visual Studio has to be } } -void QtProjectWizzardContentDataCDBVS::refreshClicked() -{ -} - void QtProjectWizzardContentDataCDBVS::handleVSCDBClicked() { MessageIDECreateCDB().dispatch(); diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentData.h b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentData.h index 16402232..cec79253 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentData.h +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentData.h @@ -13,7 +13,8 @@ class QtProjectWizzardContentData Q_OBJECT public: - QtProjectWizzardContentData(std::shared_ptr settings, QtProjectWizzardWindow* window); + QtProjectWizzardContentData( + std::shared_ptr settings, QtProjectWizzardWindow* window, bool disableNameEditing = false); // QtProjectWizzardContent implementation virtual void populate(QGridLayout* layout, int& row) override; @@ -27,6 +28,7 @@ protected: virtual void addLanguageAndStandard(QGridLayout* layout, int& row); virtual void addBuildFilePicker(QGridLayout* layout, int& row, const QString& name, const QString& filter); + bool m_disableNameEditing; QLineEdit* m_projectName; QtLocationPicker* m_projectFileLocation; @@ -43,7 +45,8 @@ class QtProjectWizzardContentDataCDB Q_OBJECT public: - QtProjectWizzardContentDataCDB(std::shared_ptr settings, QtProjectWizzardWindow* window); + QtProjectWizzardContentDataCDB( + std::shared_ptr settings, QtProjectWizzardWindow* window, bool disableNameEditing = false); virtual void populate(QGridLayout* layout, int& row) override; @@ -52,9 +55,10 @@ public: virtual bool check() override; private slots: - void refreshClicked(); + void pickedCDBPath(); }; + class QtProjectWizzardContentDataCDBVS : public QtProjectWizzardContentDataCDB { @@ -66,7 +70,6 @@ public: virtual void populate(QGridLayout* layout, int& row) override; private slots: - void refreshClicked(); void handleVSCDBClicked(); }; diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp index fa07f35d..e0baa8c9 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp @@ -18,6 +18,7 @@ QtProjectWizzardContentPaths::QtProjectWizzardContentPaths(std::shared_ptr settings, QtProjectWizzardWindow* window) : QtProjectWizzardContent(settings, window) + , m_makePathsRelativeToProjectFileLocation(true) { } @@ -32,6 +33,12 @@ void QtProjectWizzardContentPaths::populate(QGridLayout* layout, int& row) } m_list = new QtDirectoryListBox(this, m_titleString); + + if (m_makePathsRelativeToProjectFileLocation) + { + m_list->setRelativeRootDirectory(m_settings->getProjectFileLocation()); + } + layout->addWidget(m_list, row, QtProjectWizzardWindow::BACK_COL); row++; @@ -51,25 +58,24 @@ void QtProjectWizzardContentPaths::populate(QGridLayout* layout, int& row) bool QtProjectWizzardContentPaths::check() { QString missingPaths; + for (FilePath f : m_list->getList()) { - FilePath fi = f.expandEnvironmentVariables(); - if (!fi.isAbsolute()) + for (FilePath fex : m_settings->makePathsAbsolute(f.expandEnvironmentVariables())) { - fi = FilePath(m_settings->getProjectFileLocation()).concat(fi); - } - - if (!fi.exists()) - { - missingPaths.append(f.str().c_str()); - missingPaths.append("\n"); + if (!fex.exists()) + { + missingPaths.append(f.str().c_str()); + missingPaths.append("\n"); + break; + } } } if (!missingPaths.isEmpty()) { QMessageBox msgBox; - msgBox.setText("Some project paths do not exist."); + msgBox.setText("Some provided paths do not exist."); msgBox.setDetailedText(missingPaths); msgBox.exec(); return false; @@ -136,10 +142,15 @@ QtProjectWizzardContentPathsSource::QtProjectWizzardContentPathsSource( { m_showFilesString = "show files"; - setTitleString("Project Paths"); + setTitleString("Indexed Paths"); setHelpString( - "Project Paths define the files and directories that will be indexed by Coati. Provide a directory to recursively " - "add all contained source and header files." + "Indexed Paths define the files and directories that will be indexed by Coati. Provide a directory to recursively " + "add all contained files.
" + "
" + "If your project's source code resides in one location, but generated source files are kept at a different location, " + "you will also need to add that directory.
" + "
" + "You can make use of environment variables with ${ENV_VAR}." ); } @@ -203,20 +214,6 @@ QString QtProjectWizzardContentPathsSource::getFileNamesDescription() const return " files will be indexed."; } -QtProjectWizzardContentPathsSourceJava::QtProjectWizzardContentPathsSourceJava( - std::shared_ptr settings, QtProjectWizzardWindow* window -) - : QtProjectWizzardContentPathsSource(settings, window) -{ - setHelpString( - "Project Paths define the files and directories that will be indexed by Coati. Provide a directory to recursively " - "add all contained files.
" - "
" - "If your project's source code resides in one location, but generated source files are kept at a different location, " - "you will also need to add that directory." - ); -} - QtProjectWizzardContentPathsCDBHeader::QtProjectWizzardContentPathsCDBHeader( std::shared_ptr settings, QtProjectWizzardWindow* window ) @@ -230,8 +227,9 @@ QtProjectWizzardContentPathsCDBHeader::QtProjectWizzardContentPathsCDBHeader( "Every time an included header is encountered, Coati will check if the file is part of the indexed headers to " "decide whether or not to index it.
" "
" - "So just enter the root path of your project if you want Coati to index all contained headers it encounters. " - "This way you prevent Coati from indexing files you may not be interested in." + "Just enter the root path of your project if you want Coati to index all contained headers it encounters.
" + "
" + "You can make use of environment variables with ${ENV_VAR}." ); } @@ -247,6 +245,27 @@ void QtProjectWizzardContentPathsCDBHeader::populate( QGridLayout* layout, int& row++; } +bool QtProjectWizzardContentPathsCDBHeader::check() +{ + if (!m_list->getList().size()) + { + QMessageBox msgBox; + msgBox.setText("You didn't specify any Indexed Header Paths."); + msgBox.setInformativeText( + "Coati will only index the source files listed in the compilation database file and none of the included " + "header files."); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Ok); + int ret = msgBox.exec(); + + return ret == QMessageBox::Ok; + } + else + { + return QtProjectWizzardContentPaths::check(); + } +} + void QtProjectWizzardContentPathsCDBHeader::buttonClicked() { save(); @@ -262,7 +281,9 @@ void QtProjectWizzardContentPathsCDBHeader::buttonClicked() m_filesDialog->setup(); - utility::CompilationDatabase cdb(dynamic_cast(m_settings.get())->getCompilationDatabasePath().str()); + utility::CompilationDatabase cdb( + dynamic_cast(m_settings.get())->getAbsoluteCompilationDatabasePath().str()); + std::vector cdbHeaderPaths = cdb.getAllHeaderPaths(); std::vector sourcePaths = m_settings->getSourcePaths(); @@ -292,7 +313,10 @@ QtProjectWizzardContentPathsExclude::QtProjectWizzardContentPathsExclude( : QtProjectWizzardContentPaths(settings, window) { setTitleString("Exclude Paths"); - setHelpString("Exclude Paths define the files and directories that will be left out from indexing."); + setHelpString( + "Exclude Paths define the files and directories that will be left out from indexing.
" + "
" + "You can make use of environment variables with ${ENV_VAR}."); } void QtProjectWizzardContentPathsExclude::load() @@ -317,11 +341,13 @@ QtProjectWizzardContentPathsHeaderSearch::QtProjectWizzardContentPathsHeaderSear "Include Paths are used for resolving #include directives in the indexed source and header files. These paths are " "usually passed to the compiler with the '-I' or '-iquote' flags.
" "
" - "Add all the paths the #include directives throughout your project are relative to. So if all #include directives are " + "Add all paths #include directives throughout your project are relative to. If all #include directives are " "specified relative to the project's root directory, please add that one.
" "
" "If your project also includes files from external libraries (e.g. boost), please add these directories as well " - "(e.g. add '<boost_home>/include').")).c_str() + "(e.g. add '<boost_home>/include').
" + "
" + "You can make use of environment variables with ${ENV_VAR}.")).c_str() ); } @@ -363,6 +389,7 @@ QtProjectWizzardContentPathsHeaderSearchGlobal::QtProjectWizzardContentPathsHead ); m_pathDetector = utility::getCxxHeaderPathDetector(); + m_makePathsRelativeToProjectFileLocation = false; } void QtProjectWizzardContentPathsHeaderSearchGlobal::load() @@ -385,7 +412,9 @@ QtProjectWizzardContentPathsFrameworkSearch::QtProjectWizzardContentPathsFramewo setTitleString(isCDB ? "Additional Framework Search Paths" : "Framework Search Paths"); setHelpString( "Framework Search Paths define where MacOS framework containers (.framework), that your project depends on, are " - "found. These paths are usually passed to the compiler with the '-iframework' flag." + "found. These paths are usually passed to the compiler with the '-iframework' flag.
" + "
" + "You can make use of environment variables with ${ENV_VAR}." ); } @@ -428,6 +457,7 @@ QtProjectWizzardContentPathsFrameworkSearchGlobal::QtProjectWizzardContentPathsF ); m_pathDetector = utility::getCxxFrameworkPathDetector(); + m_makePathsRelativeToProjectFileLocation = false; } void QtProjectWizzardContentPathsFrameworkSearchGlobal::load() @@ -450,7 +480,9 @@ QtProjectWizzardContentPathsClassJava::QtProjectWizzardContentPathsClassJava( setTitleString("Class Path"); setHelpString( "Enter all the .jar files your project depends on. If your project depends on uncompiled java code that should " - "not be indexed, please add the root directory of those .java files here (the one where all the package names are relative to)." + "not be indexed, please add the root directory of those .java files here (the one where all the package names are relative to).
" + "
" + "You can make use of environment variables with ${ENV_VAR}." ); } diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.h b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.h index 279354c7..37b0ebf2 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.h +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.h @@ -35,6 +35,8 @@ protected: QString m_showFilesString; std::shared_ptr m_pathDetector; + bool m_makePathsRelativeToProjectFileLocation; + private slots: void detectionClicked(); @@ -61,13 +63,6 @@ public: virtual QString getFileNamesDescription() const override; }; -class QtProjectWizzardContentPathsSourceJava - : public QtProjectWizzardContentPathsSource -{ -public: - QtProjectWizzardContentPathsSourceJava(std::shared_ptr settings, QtProjectWizzardWindow* window); -}; - class QtProjectWizzardContentPathsCDBHeader : public QtProjectWizzardContentPathsSource { @@ -78,6 +73,8 @@ public: virtual void populate(QGridLayout* layout, int& row) override; + virtual bool check() override; + private slots: void buttonClicked(); void savedFilesDialog(); diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSimple.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSimple.cpp index 2bb1b91d..7d4f888a 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSimple.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSimple.cpp @@ -13,7 +13,7 @@ QtProjectWizzardContentSimple::QtProjectWizzardContentSimple(std::shared_ptraddWidget(m_title, row, QtProjectWizzardWindow::FRONT_COL); m_checkBox = new QCheckBox("Search included files within the project paths"); @@ -25,7 +25,9 @@ void QtProjectWizzardContentSimple::populate(QGridLayout* layout, int& row) "Use this option when you know that the project is self contained but don't know which paths to " "specify as include paths.
" "
" - "Warning: This slows down indexing speed.", layout, row); + "Warning: This slows down indexing speed.
" + "
" + "Deprecated: This option will be removed in future versions.", layout, row); row++; } diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSummary.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSummary.cpp index 65e27348..a3840899 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSummary.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSummary.cpp @@ -1,27 +1,26 @@ #include "qt/window/project_wizzard/QtProjectWizzardContentSummary.h" -#include - QtProjectWizzardContentSummary::QtProjectWizzardContentSummary( std::shared_ptr settings, QtProjectWizzardWindow* window ) : QtProjectWizzardContent(settings, window) - , m_layout(nullptr) - , m_checkBox(nullptr) - , m_checkBoxRow(0) , m_isForm(false) { } -void QtProjectWizzardContentSummary::addContent(QtProjectWizzardContent* content, bool advanced, bool gapBefore) +void QtProjectWizzardContentSummary::addContent(QtProjectWizzardContent* content) { - Element element; - element.content = content; - element.advanced = advanced; - element.gapBefore = gapBefore; - m_elements.push_back(element); + m_contents.push_back(content); - content->setIsInForm(m_isForm); + if (content) + { + content->setIsInForm(m_isForm); + } +} + +void QtProjectWizzardContentSummary::addSpace() +{ + m_contents.push_back(nullptr); } void QtProjectWizzardContentSummary::setIsForm(bool isForm) @@ -39,19 +38,16 @@ void QtProjectWizzardContentSummary::populate(QGridLayout* layout, int& row) layout->setRowMinimumHeight(row++, 20); - for (const Element& element : m_elements) + for (QtProjectWizzardContent* content : m_contents) { - if (element.advanced) + if (content) { - continue; + content->populate(layout, row); } - - if (element.gapBefore) + else { layout->setRowMinimumHeight(row++, 20); } - - element.content->populate(layout, row); } layout->setRowMinimumHeight(row, 20); @@ -62,83 +58,49 @@ void QtProjectWizzardContentSummary::populateForm(QGridLayout* layout, int& row) { layout->setRowMinimumHeight(row++, 10); - bool hasAdvanced = false; - for (int i = 0; i < 2; i++) + for (QtProjectWizzardContent* content : m_contents) { - bool advanced = i > 0; - - for (const Element& element : m_elements) + if (content) { - if (element.advanced != advanced) - { - hasAdvanced = true; - continue; - } - - if (element.gapBefore) - { - layout->setRowMinimumHeight(row++, 15); - } - - element.content->populate(layout, row); + content->populate(layout, row); } - - if (i > 0 || !hasAdvanced) + else { - continue; + layout->setRowMinimumHeight(row++, 15); } - - QFrame* separator = new QFrame(); - separator->setFrameShape(QFrame::HLine); - - QPalette palette = separator->palette(); - palette.setColor(QPalette::WindowText, Qt::lightGray); - separator->setPalette(palette); - - layout->addWidget(separator, row++, 0, 1, -1); - - QLabel* advancedLabel = createFormLabel("ADVANCED"); - layout->addWidget(advancedLabel, row, QtProjectWizzardWindow::FRONT_COL, Qt::AlignTop); - - m_layout = layout; - m_checkBoxRow = row; - m_checkBox = new QCheckBox("Show advanced settings"); - layout->addWidget(m_checkBox, row++, QtProjectWizzardWindow::BACK_COL); - connect(m_checkBox, SIGNAL(clicked(bool)), this, SLOT(advancedToggled(bool))); - - row++; } layout->setRowMinimumHeight(row, 10); layout->setRowStretch(row, 1); - - if (m_checkBox) - { - advancedToggled(false); - } } void QtProjectWizzardContentSummary::load() { - for (const Element& element : m_elements) + for (QtProjectWizzardContent* content : m_contents) { - element.content->load(); + if (content) + { + content->load(); + } } } void QtProjectWizzardContentSummary::save() { - for (const Element& element : m_elements) + for (QtProjectWizzardContent* content : m_contents) { - element.content->save(); + if (content) + { + content->save(); + } } } bool QtProjectWizzardContentSummary::check() { - for (const Element& element : m_elements) + for (QtProjectWizzardContent* content : m_contents) { - if (!element.content->check()) + if (content && !content->check()) { return false; } @@ -151,26 +113,3 @@ bool QtProjectWizzardContentSummary::isScrollAble() const { return true; } - -void QtProjectWizzardContentSummary::advancedToggled(bool checked) -{ - for (int row = m_checkBoxRow + 1; row < m_layout->rowCount() - 1; row++) - { - m_layout->setRowMinimumHeight(row, checked ? 15 : 0); - } - - for (int i = m_layout->count() - 1; i >= 0; i--) - { - int r, c, rs, cs; - m_layout->getItemPosition(i, &r, &c, &rs, &cs); - - if (r > m_checkBoxRow) - { - QLayoutItem *item = m_layout->itemAt(i); - if (item && item->widget()) - { - item->widget()->setVisible(checked); - } - } - } -} diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSummary.h b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSummary.h index 9db61299..671f158e 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSummary.h +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSummary.h @@ -10,18 +10,12 @@ class QtProjectWizzardContentSummary { Q_OBJECT -private: - struct Element - { - QtProjectWizzardContent* content; - bool advanced; - bool gapBefore; - }; - public: QtProjectWizzardContentSummary(std::shared_ptr settings, QtProjectWizzardWindow* window); - void addContent(QtProjectWizzardContent* content, bool advanced, bool gapBefore); + void addContent(QtProjectWizzardContent* content); + void addSpace(); + void setIsForm(bool isForm); protected: @@ -35,16 +29,8 @@ protected: virtual bool isScrollAble() const override; -private slots: - void advancedToggled(bool checked); - private: - std::vector m_elements; - - QGridLayout* m_layout; - QCheckBox* m_checkBox; - int m_checkBoxRow; - + std::vector m_contents; bool m_isForm; }; diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardWindow.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardWindow.cpp index d4d2c8a4..7223595f 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardWindow.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardWindow.cpp @@ -44,7 +44,7 @@ void QtProjectWizzardWindow::populateWindow(QWidget* widget) { QGridLayout* layout = new QGridLayout(); layout->setContentsMargins(0, 0, 0, 0); - + layout->setColumnStretch(QtProjectWizzardWindow::FRONT_COL, 1); layout->setColumnStretch(QtProjectWizzardWindow::BACK_COL, 3); diff --git a/src/test/FilePathTestSuite.h b/src/test/FilePathTestSuite.h index 85b27dbc..30d468a2 100644 --- a/src/test/FilePathTestSuite.h +++ b/src/test/FilePathTestSuite.h @@ -91,6 +91,14 @@ public: TS_ASSERT_EQUALS(pathB.relativeTo(pathA).str(), "test/c.h"); } + void test_file_path_relative_to_other_directory() + { + FilePath pathA("data/FilePathTestSuite/a.cpp"); + FilePath pathB("data/FilePathTestSuite/test"); + + TS_ASSERT_EQUALS(pathA.relativeTo(pathB).str(), "../a.cpp"); + } + void test_file_path_file_name() { FilePath path("data/FilePathTestSuite/abc.h");