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);