diff --git a/NEWS.md b/NEWS.md index d86c3065..8f64fcde 100644 --- a/NEWS.md +++ b/NEWS.md @@ -15,6 +15,10 @@ Red Panda C++ Version 2.4 - fix: function args not correctly handled in code parser; - fix: crash when alt+mouse drag selection - enhancement: show completion tips for when define a function that already has a declaration. + - enhancement: Use relative paths to save project settings + - fix: Layout for project options dialog's general page is not correct. + - fix: modifitions in the project options dialogs's dll host page is not correctly saved. + - enhancement: In the project options dialog, autoset the default folder in the openning dialog when choosing file/directory paths. Red Panda C++ Version 2.3 diff --git a/RedPandaIDE/project.cpp b/RedPandaIDE/project.cpp index b721e86e..ad48110e 100644 --- a/RedPandaIDE/project.cpp +++ b/RedPandaIDE/project.cpp @@ -1009,11 +1009,11 @@ bool Project::saveAsTemplate(const QString &templateFolder, if (mOptions.supportXPThemes) ini->SetBoolValue("Project", "SupportXPThemes", true); if (!mOptions.exeOutput.isEmpty()) - ini->SetValue("Project", "ExeOutput", mOptions.exeOutput.toUtf8()); + ini->SetValue("Project", "ExeOutput", extractRelativePath(directory(),mOptions.exeOutput).toUtf8()); if (!mOptions.objectOutput.isEmpty()) - ini->SetValue("Project", "ObjectOutput", mOptions.objectOutput.toUtf8()); + ini->SetValue("Project", "ObjectOutput", extractRelativePath(directory(),mOptions.objectOutput).toUtf8()); if (!mOptions.logOutput.isEmpty()) - ini->SetValue("Project", "LogOutput", mOptions.logOutput.toUtf8()); + ini->SetValue("Project", "LogOutput", extractRelativePath(directory(),mOptions.logOutput).toUtf8()); if (mOptions.execEncoding!=ENCODING_SYSTEM_DEFAULT) ini->SetValue("Project","ExecEncoding", mOptions.execEncoding); @@ -1089,9 +1089,9 @@ void Project::saveOptions() ini.SetValue("Project","Linker", toByteArray(mOptions.linkerCmd)); ini.SetLongValue("Project","IsCpp", mOptions.isCpp); ini.SetValue("Project","Icon", toByteArray(extractRelativePath(directory(), mOptions.icon))); - ini.SetValue("Project","ExeOutput", toByteArray(mOptions.exeOutput)); - ini.SetValue("Project","ObjectOutput", toByteArray(mOptions.objectOutput)); - ini.SetValue("Project","LogOutput", toByteArray(mOptions.logOutput)); + ini.SetValue("Project","ExeOutput", toByteArray(extractRelativePath(directory(),mOptions.exeOutput))); + ini.SetValue("Project","ObjectOutput", toByteArray(extractRelativePath(directory(),mOptions.objectOutput))); + ini.SetValue("Project","LogOutput", toByteArray(extractRelativePath(directory(),mOptions.logOutput))); ini.SetLongValue("Project","LogOutputEnabled", mOptions.logOutputEnabled); ini.SetLongValue("Project","OverrideOutput", mOptions.overrideOutput); ini.SetValue("Project","OverrideOutputName", toByteArray(mOptions.overridenOutput)); @@ -1929,9 +1929,9 @@ void Project::loadOptions(SimpleIni& ini) #endif )); mOptions.isCpp = ini.GetBoolValue("Project", "IsCpp", false); - mOptions.exeOutput = fromByteArray(ini.GetValue("Project", "ExeOutput", "")); - mOptions.objectOutput = fromByteArray(ini.GetValue("Project", "ObjectOutput", "")); - mOptions.logOutput = fromByteArray(ini.GetValue("Project", "LogOutput", "")); + mOptions.exeOutput = absolutePath(directory(), fromByteArray(ini.GetValue("Project", "ExeOutput", ""))); + mOptions.objectOutput = absolutePath(directory(), fromByteArray(ini.GetValue("Project", "ObjectOutput", ""))); + mOptions.logOutput = absolutePath(directory(), fromByteArray(ini.GetValue("Project", "LogOutput", ""))); mOptions.logOutputEnabled = ini.GetBoolValue("Project", "LogOutputEnabled", false); mOptions.overrideOutput = ini.GetBoolValue("Project", "OverrideOutput", false); mOptions.overridenOutput = fromByteArray(ini.GetValue("Project", "OverrideOutputName", "")); @@ -2068,37 +2068,6 @@ void Project::loadOptions(SimpleIni& ini) mOptions.versionInfo.autoIncBuildNr = ini.GetBoolValue("VersionInfo", "AutoIncBuildNr", false); mOptions.versionInfo.syncProduct = ini.GetBoolValue("VersionInfo", "SyncProduct", false); - } else { // dev-c < 4 - mOptions.version = 3; - if (!ini.GetBoolValue("VersionInfo", "NoConsole", true)) - mOptions.type = ProjectType::Console; - else if (ini.GetBoolValue("VersionInfo", "IsDLL", false)) - mOptions.type = ProjectType::DynamicLib; - else - mOptions.type = ProjectType::GUI; - - mOptions.privateResource = fromByteArray(ini.GetValue("Project", "PrivateResource", "")); - mOptions.resourceIncludes = fromByteArray(ini.GetValue("Project", "ResourceIncludes", "")).split(";", -#if QT_VERSION >= QT_VERSION_CHECK(5,15,0) - Qt::SkipEmptyParts -#else - QString::SkipEmptyParts -#endif - ); - mOptions.includeDirs = fromByteArray(ini.GetValue("Project", "IncludeDirs", "")).split(";", -#if QT_VERSION >= QT_VERSION_CHECK(5,15,0) - Qt::SkipEmptyParts -#else - QString::SkipEmptyParts -#endif - ); - mOptions.compilerCmd = fromByteArray(ini.GetValue("Project", "CompilerOptions", "")); - mOptions.isCpp = ini.GetBoolValue("Project", "Use_GPP", false); - mOptions.exeOutput = fromByteArray(ini.GetValue("Project", "ExeOutput", "")); - mOptions.objectOutput = fromByteArray(ini.GetValue("Project", "ObjectOutput", "")); - mOptions.overrideOutput = ini.GetBoolValue("Project", "OverrideOutput", false); - mOptions.overridenOutput = fromByteArray(ini.GetValue("Project", "OverrideOutputName", "")); - mOptions.hostApplication = absolutePath(directory(), fromByteArray(ini.GetValue("Project", "HostApplication", ""))); } } diff --git a/RedPandaIDE/settingsdialog/projectdllhostwidget.cpp b/RedPandaIDE/settingsdialog/projectdllhostwidget.cpp index d76165a9..1d75f7ea 100644 --- a/RedPandaIDE/settingsdialog/projectdllhostwidget.cpp +++ b/RedPandaIDE/settingsdialog/projectdllhostwidget.cpp @@ -43,14 +43,19 @@ void ProjectDLLHostWidget::doLoad() void ProjectDLLHostWidget::doSave() { pMainWindow->project()->options().hostApplication = ui->txtHost->text(); + pMainWindow->project()->saveOptions(); } void ProjectDLLHostWidget::on_btnBrowse_clicked() { + QString currentFile=ui->txtHost->text(); + if (currentFile.isEmpty()) { + currentFile = pMainWindow->project()->directory(); + } QString filename = QFileDialog::getOpenFileName( this, tr("Choose host application"), - pMainWindow->project()->directory(), + currentFile, tr("All files (%1)").arg(ALL_FILE_WILDCARD)); if (!filename.isEmpty() && fileExists(filename)) { ui->txtHost->setText(filename); diff --git a/RedPandaIDE/settingsdialog/projectgeneralwidget.ui b/RedPandaIDE/settingsdialog/projectgeneralwidget.ui index 889b4c56..9a6f7fbb 100644 --- a/RedPandaIDE/settingsdialog/projectgeneralwidget.ui +++ b/RedPandaIDE/settingsdialog/projectgeneralwidget.ui @@ -21,19 +21,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - diff --git a/RedPandaIDE/settingsdialog/projectmakefilewidget.cpp b/RedPandaIDE/settingsdialog/projectmakefilewidget.cpp index be7866a4..98c0cc5a 100644 --- a/RedPandaIDE/settingsdialog/projectmakefilewidget.cpp +++ b/RedPandaIDE/settingsdialog/projectmakefilewidget.cpp @@ -58,10 +58,14 @@ void ProjectMakefileWidget::doSave() void ProjectMakefileWidget::on_btnBrowse_clicked() { + QString currentFile=ui->txtCustomMakefile->text(); + if (currentFile.isEmpty()) { + currentFile = pMainWindow->project()->directory(); + } QString fileName = QFileDialog::getOpenFileName( this, tr("Custom makefile"), - pMainWindow->project()->directory(), + currentFile, tr("All files (%1)").arg(ALL_FILE_WILDCARD)); if (!fileName.isEmpty() && QFileInfo(fileName).exists()) { ui->txtCustomMakefile->setText(fileName); diff --git a/RedPandaIDE/settingsdialog/projectoutputwidget.cpp b/RedPandaIDE/settingsdialog/projectoutputwidget.cpp index c564fa8b..2571fc7b 100644 --- a/RedPandaIDE/settingsdialog/projectoutputwidget.cpp +++ b/RedPandaIDE/settingsdialog/projectoutputwidget.cpp @@ -59,35 +59,47 @@ void ProjectOutputWidget::doSave() void ProjectOutputWidget::on_btnOutputDir_clicked() { + QString currentName = ui->txtOutputDir->text(); + if (currentName.isEmpty()) + currentName = pMainWindow->project()->directory(); QString dirName = QFileDialog::getExistingDirectory( this, tr("Executable output directory"), - pMainWindow->project()->directory()); + currentName); if (!dirName.isEmpty()) - ui->txtOutputDir->setText(extractRelativePath(pMainWindow->project()->folder(),dirName)); + ui->txtOutputDir->setText(dirName); } void ProjectOutputWidget::on_btnObjOutputDir_clicked() { + QString currentName = ui->txtObjOutputDir->text(); + if (currentName.isEmpty()) + currentName = pMainWindow->project()->directory(); QString dirName = QFileDialog::getExistingDirectory( this, tr("Object files output directory"), - pMainWindow->project()->directory()); + currentName); if (!dirName.isEmpty()) - ui->txtObjOutputDir->setText(extractRelativePath(pMainWindow->project()->folder(),dirName)); + ui->txtObjOutputDir->setText(dirName); } void ProjectOutputWidget::on_btnCompileLog_clicked() { - QString fileName = QFileDialog::getOpenFileName( + QString currentFile=ui->txtCompileLog->text(); + if (currentFile.isEmpty()) { + currentFile = pMainWindow->project()->directory(); + } + QString fileName = QFileDialog::getSaveFileName( this, tr("Log file"), - pMainWindow->project()->directory(), - tr("All files (%1)").arg(ALL_FILE_WILDCARD)); + currentFile, + tr("All files (%1)").arg(ALL_FILE_WILDCARD), + nullptr, + QFileDialog::Options() | QFileDialog::DontConfirmOverwrite); if (!fileName.isEmpty() ) { - ui->txtCompileLog->setText(extractRelativePath(pMainWindow->project()->folder(),fileName)); + ui->txtCompileLog->setText(fileName); } } diff --git a/RedPandaIDE/settingsdialog/projectprecompilewidget.cpp b/RedPandaIDE/settingsdialog/projectprecompilewidget.cpp index 647a5371..a2f34002 100644 --- a/RedPandaIDE/settingsdialog/projectprecompilewidget.cpp +++ b/RedPandaIDE/settingsdialog/projectprecompilewidget.cpp @@ -49,12 +49,21 @@ void ProjectPreCompileWidget::doSave() void ProjectPreCompileWidget::on_btnBrowse_clicked() { - QString fileName = QFileDialog::getOpenFileName( + QString currentFile=ui->txtPrecompileHeader->text(); + QString currentDir; + if (currentFile.isEmpty()) { + currentDir = pMainWindow->project()->directory(); + } else { + currentDir = extractFilePath(currentFile); + } + QString fileName = QFileDialog::getSaveFileName( this, tr("Precompiled header"), - pMainWindow->project()->directory(), - tr("header files (*.h)")); - if (!fileName.isEmpty() && QFileInfo(fileName).exists()) { + currentDir, + tr("precompiled header files (*.pch)"), + nullptr, + QFileDialog::Options()|QFileDialog::DontConfirmOverwrite); + if (!fileName.isEmpty()) { ui->txtPrecompileHeader->setText(fileName); } } diff --git a/libs/redpanda_qt_utils/qt_utils/utils.cpp b/libs/redpanda_qt_utils/qt_utils/utils.cpp index 3c41fd57..ed840bab 100644 --- a/libs/redpanda_qt_utils/qt_utils/utils.cpp +++ b/libs/redpanda_qt_utils/qt_utils/utils.cpp @@ -542,6 +542,9 @@ QString changeFileExt(const QString& filename, QString ext) QString extractRelativePath(const QString &base, const QString &dest) { + if (dest.isEmpty()) + return QString(); + QFileInfo baseInfo(base); QDir baseDir; if (baseInfo.isDir()) { @@ -687,6 +690,8 @@ QString cleanPath(const QString &dirPath) QString absolutePath(const QString &dirPath, const QString &relativePath) { + if (relativePath.isEmpty()) + return QString(); return QDir::cleanPath(QDir(dirPath).absoluteFilePath(relativePath)); } @@ -695,3 +700,21 @@ QString escapeSpacesInString(const QString &str) QString result=str; return result.replace(' ',"%20"); } + +QStringList extractRelativePaths(const QString &base, const QStringList &destList) +{ + QStringList list; + foreach(const QString& dest,destList) { + list.append(extractRelativePath(base,dest)); + } + return list; +} + +QStringList absolutePaths(const QString &dirPath, const QStringList &relativePaths) +{ + QStringList list; + foreach(const QString& path,relativePaths) { + list.append(absolutePath(dirPath,path)); + } + return list; +} diff --git a/libs/redpanda_qt_utils/qt_utils/utils.h b/libs/redpanda_qt_utils/qt_utils/utils.h index 4034c912..a3377040 100644 --- a/libs/redpanda_qt_utils/qt_utils/utils.h +++ b/libs/redpanda_qt_utils/qt_utils/utils.h @@ -124,12 +124,14 @@ QString changeFileExt(const QString& filename, QString ext); QString localizePath(const QString& path); QString extractRelativePath(const QString& base, const QString& dest); +QStringList extractRelativePaths(const QString& base, const QStringList& destList); QString extractFileName(const QString& fileName); QString extractFileDir(const QString& fileName); QString extractFilePath(const QString& filePath); QString extractAbsoluteFilePath(const QString& filePath); QString cleanPath(const QString& dirPath); QString absolutePath(const QString& dirPath, const QString& relativePath); +QStringList absolutePaths(const QString& dirPath, const QStringList& relativePaths); QString escapeSpacesInString(const QString& str);