diff --git a/RedPandaIDE/compiler/filecompiler.cpp b/RedPandaIDE/compiler/filecompiler.cpp
index ca9b723b..2d301280 100644
--- a/RedPandaIDE/compiler/filecompiler.cpp
+++ b/RedPandaIDE/compiler/filecompiler.cpp
@@ -63,7 +63,7 @@ bool FileCompiler::prepareForCompile()
}
mArguments += getLibraryArguments(fileType);
- if (!QFile(mCompiler).exists()) {
+ if (!fileExists(mCompiler)) {
throw CompileError(tr("The Compiler '%1' doesn't exists!").arg(mCompiler));
}
diff --git a/RedPandaIDE/compiler/stdincompiler.cpp b/RedPandaIDE/compiler/stdincompiler.cpp
index 18cea234..aef2a60a 100644
--- a/RedPandaIDE/compiler/stdincompiler.cpp
+++ b/RedPandaIDE/compiler/stdincompiler.cpp
@@ -52,7 +52,7 @@ bool StdinCompiler::prepareForCompile()
}
mArguments += getLibraryArguments(fileType);
- if (!QFile(mCompiler).exists()) {
+ if (!fileExists(mCompiler)) {
throw CompileError(tr("The Compiler '%1' doesn't exists!").arg(mCompiler));
}
diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp
index f1710652..8c2d3b25 100644
--- a/RedPandaIDE/editor.cpp
+++ b/RedPandaIDE/editor.cpp
@@ -2100,7 +2100,7 @@ void Editor::cancelHint()
QString Editor::getFileHint(const QString &s)
{
QString fileName = mParser->getHeaderFileName(mFilename, s);
- if (QFileInfo(fileName).exists()) {
+ if (fileExists(fileName)) {
return fileName + " - " + tr("Ctrl+click for more info");
}
return "";
diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp
index 94df0d4b..793ccf5c 100644
--- a/RedPandaIDE/mainwindow.cpp
+++ b/RedPandaIDE/mainwindow.cpp
@@ -661,7 +661,7 @@ bool MainWindow::compile(bool rebuild)
void MainWindow::runExecutable(const QString &exeName,const QString &filename)
{
// Check if it exists
- if (!QFile(exeName).exists()) {
+ if (!fileExists(exeName)) {
if (ui->actionCompile_Run->isEnabled()) {
if (QMessageBox::question(this,tr("Confirm"),
tr("Source file is not compiled.")
@@ -1417,7 +1417,7 @@ void MainWindow::onFileChanged(const QString &path)
{
Editor *e = mEditorList->getOpenedEditorByFilename(path);
if (e) {
- if (QFile(path).exists()) {
+ if (fileExists(path)) {
e->activate();
if (QMessageBox::question(this,tr("Compile"),
tr("File '%1' was changed.").arg(path)+"
" + tr("Reload its content from disk?"),
diff --git a/RedPandaIDE/project.cpp b/RedPandaIDE/project.cpp
index 6b84b50d..99752b5b 100644
--- a/RedPandaIDE/project.cpp
+++ b/RedPandaIDE/project.cpp
@@ -131,7 +131,6 @@ void Project::open()
}
mIniFile->endGroup();
}
- emit changed();
rebuildNodes();
}
@@ -154,8 +153,305 @@ void Project::setModified(bool value)
if (!file.exists()
|| (file.exists() && file.isWritable())) {
mModified=value;
+ emit modifyChanged(mModified);
+ }
+}
+
+void Project::addFolder(const QString &s)
+{
+ if (mFolders.indexOf(s)<0) {
+ mFolders.append(s);
+ rebuildNodes();
+ //todo: MainForm.ProjectView.Select(FolderNodeFromName(s));
+ //folderNodeFromName(s)->makeVisible();
+ setModified(true);
+ }
+}
+
+PProjectUnit Project::addUnit(const QString &inFileName, PFolderNode parentNode, bool rebuild)
+{
+ PProjectUnit newUnit;
+ // Don't add if it already exists
+ if (fileAlreadyExists(inFileName)) {
+ QMessageBox::critical(pMainWindow,
+ tr("File Exists"),
+ tr("File '%1' is already in the project"),
+ QMessageBox::Ok);
+ return newUnit;
+ }
+ newUnit = std::make_shared(this);
+
+ // Set all properties
+ newUnit->setFileName(QDir(directory()).filePath(inFileName));
+ newUnit->setNew(false);
+ newUnit->setEditor(nullptr);
+ newUnit->setFolder(getFolderPath(parentNode));
+ newUnit->setNode(makeNewFileNode(baseFileName(newUnit->fileName()), false, parentNode);
+ newUnit->node()->unitIndex = mUnits.count();
+ mUnits.append(newUnit);
+
+ // Determine compilation flags
+ switch(getFileType(inFileName)) {
+ case FileType::CSource:
+ newUnit->setCompile(true);
+ newUnit->setCompileCpp(mOptions.useGPP);
+ newUnit->setLink(true);
+ break;
+ case FileType::CppSource:
+ newUnit->setCompile(true);
+ newUnit->setCompileCpp(true);
+ newUnit->setLink(true);
+ break;
+ case FileType::WindowsResourceSource:
+ newUnit->setCompile(true);
+ newUnit->setCompileCpp(mOptions.useGPP);
+ newUnit->setLink(false);
+ break;
+ default:
+ newUnit->setCompile(false);
+ newUnit->setCompileCpp(false);
+ newUnit->setLink(false);
+ }
+ newUnit->setPriority(1000);
+ newUnit->setOverrideBuildCmd(false);
+ newUnit->setBuildCmd("");
+ if (rebuild)
+ rebuildNodes();
+ setModified(true);
+ return newUnit;
+}
+
+void Project::buildPrivateResource(bool forceSave)
+{
+ int comp = 0;
+ foreach (const PProjectUnit& unit,mUnits) {
+ if (
+ (getFileType(unit->fileName()) == FileType::WindowsResourceSource)
+ && unit->compile() )
+ comp++;
}
+ // if project has no other resources included
+ // and does not have an icon
+ // and does not include the XP style manifest
+ // and does not include version info
+ // then do not create a private resource file
+ if ((comp == 0) &&
+ (! mOptions.supportXPThemes)
+ && (! mOptions.includeVersionInfo)
+ && (mOptions.icon == "")) {
+ mOptions.privateResource="";
+ return;
+ }
+
+ // change private resource from .res
+ // to _private.res
+ //
+ // in many cases (like in importing a MSVC project)
+ // the project's resource file has already the
+ // .res filename.
+ QString res;
+ if (!mOptions.privateResource.isEmpty()) {
+ res = QDir(directory()).filePath(mOptions.privateResource);
+ if (changeFileExt(res, DEV_PROJECT_EXT) == mFilename)
+ res = changeFileExt(mFilename,QString("_private") + RC_EXT);
+ } else
+ res = changeFileExt(mFilename,QString("_private") + RC_EXT);
+ res = extractRelativePath(mFilename, res);
+ res.replace(' ','_');
+
+ // don't run the private resource file and header if not modified,
+ // unless ForceSave is true
+ if (!forceSave
+ && fileExists(res)
+ && fileExists(changeFileExt(res, H_EXT))
+ && !mModified)
+ return;
+
+ QStringList resFile;
+ resFile.append("/* THIS FILE WILL BE OVERWRITTEN BY DEV-C++ */");
+ resFile.append("/* DO NOT EDIT! */");
+ resFile.append("");
+
+ if (mOptions.includeVersionInfo) {
+ resFile.append("#include // include for version info constants");
+ resFile.append("");
+ end;
+
+ foreach (const PProjectUnit& unit, mUnits) {
+ if (
+ (getFileType(unit->fileName()) == FileType::WindowsResourceSource)
+ && unit->compile() )
+ resFile.append("#include \"" +
+ genMakePath(
+ extractRelativePath(directory(), unit->fileName()),
+ false,
+ false) + "\"");
+ }
+
+ if (!mOptions.icon.isEmpty()) {
+ resFile.append("");
+ QString icon = QDir(directory()).absoluteFilePath(mOptions.icon);
+ if (fileExists(icon)) {
+ icon = extractRelativePath(mFilename, icon);
+ icon.replace('\\', '/');
+ resFile.append("A ICON \"" + icon + '"');
+ } else
+ mOptions.icon = "";
+ }
+
+ if (mOptions.supportXPThemes) {
+ resFile.append("");
+ resFile.append("//");
+ resFile.append("// SUPPORT FOR WINDOWS XP THEMES:");
+ resFile.append("// THIS WILL MAKE THE PROGRAM USE THE COMMON CONTROLS");
+ resFile.append("// LIBRARY VERSION 6.0 (IF IT IS AVAILABLE)");
+ resFile.append("//");
+ if (!mOptions.exeOutput.isEmpty())
+ resFile.append(
+ "1 24 \"" +
+ genMakePath2(
+ includeTrailingPathDelimiter(mOptions.exeOutput)
+ + baseFileName(executable()))
+ + ".Manifest\"");
+ else
+ resFile.append("1 24 \"" + baseFileName(executable()) + ".Manifest\"");
+ }
+
+ if Options.IncludeVersionInfo then begin
+ resFile.append("');
+ resFile.append("//');
+ resFile.append("// TO CHANGE VERSION INFORMATION, EDIT PROJECT OPTIONS...');
+ resFile.append("//');
+ resFile.append("1 VERSIONINFO');
+ resFile.append("FILEVERSION ' + Format('%d,%d,%d,%d', [Options.VersionInfo.Major, Options.VersionInfo.Minor,
+ Options.VersionInfo.Release, Options.VersionInfo.Build]));
+ resFile.append("PRODUCTVERSION ' + Format('%d,%d,%d,%d', [Options.VersionInfo.Major, Options.VersionInfo.Minor,
+ Options.VersionInfo.Release, Options.VersionInfo.Build]));
+ case Options.typ of
+ dptGUI,
+ dptCon: resFile.append("FILETYPE VFT_APP');
+ dptStat: resFile.append("FILETYPE VFT_STATIC_LIB');
+ dptDyn: resFile.append("FILETYPE VFT_DLL');
+ end;
+ resFile.append("{');
+ resFile.append(" BLOCK "StringFileInfo"');
+ resFile.append(" {');
+ resFile.append(" BLOCK "' + Format('%4.4x%4.4x', [fOptions.VersionInfo.LanguageID, fOptions.VersionInfo.CharsetID])
+ +
+ '"');
+ resFile.append(" {');
+ resFile.append(" VALUE "CompanyName", "' + fOptions.VersionInfo.CompanyName + '"');
+ resFile.append(" VALUE "FileVersion", "' + fOptions.VersionInfo.FileVersion + '"');
+ resFile.append(" VALUE "FileDescription", "' + fOptions.VersionInfo.FileDescription + '"');
+ resFile.append(" VALUE "InternalName", "' + fOptions.VersionInfo.InternalName + '"');
+ resFile.append(" VALUE "LegalCopyright", "' + fOptions.VersionInfo.LegalCopyright + '"');
+ resFile.append(" VALUE "LegalTrademarks", "' + fOptions.VersionInfo.LegalTrademarks + '"');
+ resFile.append(" VALUE "OriginalFilename", "' + fOptions.VersionInfo.OriginalFilename + '"');
+ resFile.append(" VALUE "ProductName", "' + fOptions.VersionInfo.ProductName + '"');
+ resFile.append(" VALUE "ProductVersion", "' + fOptions.VersionInfo.ProductVersion + '"');
+ resFile.append(" }');
+ resFile.append(" }');
+
+ // additional block for windows 95->NT
+ resFile.append(" BLOCK "VarFileInfo"');
+ resFile.append(" {');
+ resFile.append(" VALUE "Translation", ' + Format('0x%4.4x, %4.4d', [fOptions.VersionInfo.LanguageID,
+ fOptions.VersionInfo.CharsetID]));
+ resFile.append(" }');
+
+ resFile.append("}');
+ end;
+
+ Res := GetRealPath(Res, Directory);
+ if resFile.Count > 3 then begin
+ if FileExists(Res) and not ForceSave then begin
+ Original := TStringList.Create;
+ Original.LoadFromFile(Res);
+ if CompareStr(Original.Text, resFile.Text) <> 0 then begin
+ resFile.SaveToFile(Res);
+ end;
+ Original.Free;
+ end else begin
+ resFile.SaveToFile(Res);
+ end;
+ fOptions.PrivateResource := ExtractRelativePath(Directory, Res);
+ end else begin
+ if FileExists(Res) then
+ DeleteFile(PAnsiChar(Res));
+ Res := ChangeFileExt(Res, RES_EXT);
+ if FileExists(Res) then
+ DeleteFile(PAnsiChar(Res));
+ fOptions.PrivateResource := '';
+ end;
+ if FileExists(Res) then
+ FileSetDate(Res, DateTimeToFileDate(Now)); // fix the "Clock skew detected" warning ;)
+
+ // create XP manifest
+ if fOptions.SupportXPThemes then begin
+ resFile.Clear;
+ resFile.append("');
+ resFile.append("');
+ resFile.append("');
+ resFile.append("' + Name + '');
+ resFile.append("');
+ resFile.append(" ');
+ resFile.append(" ');
+ resFile.append(" ');
+ resFile.append("');
+ resFile.append("');
+ resFile.SaveToFile(Executable + '.Manifest');
+ FileSetDate(Executable + '.Manifest', DateTimeToFileDate(Now)); // fix the "Clock skew detected" warning ;)
+ end else if FileExists(Executable + '.Manifest') then
+ DeleteFile(PAnsiChar(Executable + '.Manifest'));
+
+ // create private header file
+ Res := ChangeFileExt(Res, H_EXT);
+ resFile.Clear;
+ Def := StringReplace(ExtractFilename(UpperCase(Res)), '.', '_', [rfReplaceAll]);
+ resFile.append("/* THIS FILE WILL BE OVERWRITTEN BY DEV-C++ */');
+ resFile.append("/* DO NOT EDIT ! */');
+ resFile.append("');
+ resFile.append("#ifndef ' + Def);
+ resFile.append("#define ' + Def);
+ resFile.append("');
+ resFile.append("/* VERSION DEFINITIONS */');
+ resFile.append("#define VER_STRING'#9 + Format('"%d.%d.%d.%d"', [fOptions.VersionInfo.Major, fOptions.VersionInfo.Minor,
+ fOptions.VersionInfo.Release, fOptions.VersionInfo.Build]));
+ resFile.append("#define VER_MAJOR'#9 + IntToStr(fOptions.VersionInfo.Major));
+ resFile.append("#define VER_MINOR'#9 + IntToStr(fOptions.VersionInfo.Minor));
+ resFile.append("#define VER_RELEASE'#9 + IntToStr(fOptions.VersionInfo.Release));
+ resFile.append("#define VER_BUILD'#9 + IntToStr(fOptions.VersionInfo.Build));
+ resFile.append("#define COMPANY_NAME'#9'"' + fOptions.VersionInfo.CompanyName + '"');
+ resFile.append("#define FILE_VERSION'#9'"' + fOptions.VersionInfo.FileVersion + '"');
+ resFile.append("#define FILE_DESCRIPTION'#9'"' + fOptions.VersionInfo.FileDescription + '"');
+ resFile.append("#define INTERNAL_NAME'#9'"' + fOptions.VersionInfo.InternalName + '"');
+ resFile.append("#define LEGAL_COPYRIGHT'#9'"' + fOptions.VersionInfo.LegalCopyright + '"');
+ resFile.append("#define LEGAL_TRADEMARKS'#9'"' + fOptions.VersionInfo.LegalTrademarks + '"');
+ resFile.append("#define ORIGINAL_FILENAME'#9'"' + fOptions.VersionInfo.OriginalFilename + '"');
+ resFile.append("#define PRODUCT_NAME'#9'"' + fOptions.VersionInfo.ProductName + '"');
+ resFile.append("#define PRODUCT_VERSION'#9'"' + fOptions.VersionInfo.ProductVersion + '"');
+ resFile.append("');
+ resFile.append("#endif /*' + Def + '*/');
+ resFile.SaveToFile(Res);
+
+ if FileExists(Res) then
+ FileSetDate(Res, DateTimeToFileDate(Now)); // fix the "Clock skew detected" warning ;)
+
+ resFile.Free;
}
void Project::sortUnitsByPriority()
@@ -320,7 +616,7 @@ void ProjectUnit::setModified(bool value)
// If modified is set to true, mark project as modified too
if (value) {
- parent->setModified(true);
+ mParent->setModified(true);
}
}
@@ -331,7 +627,7 @@ bool ProjectUnit::save()
pMainWindow->fileSystemWatcher()->blockSignals(previous);
});
bool result=true;
- if (!mEditor && !QFile(mFileName).exists()) {
+ if (!mEditor && !fileExists(mFileName)) {
// file is neither open, nor saved
QStringList temp;
StringsToFile(temp,mFileName);
@@ -343,3 +639,13 @@ bool ProjectUnit::save()
}
return result;
}
+
+PFolderNode &ProjectUnit::node()
+{
+ return mNode;
+}
+
+void ProjectUnit::setNode(const PFolderNode &newNode)
+{
+ mNode = newNode;
+}
diff --git a/RedPandaIDE/project.h b/RedPandaIDE/project.h
index 48160c67..4ba66c83 100644
--- a/RedPandaIDE/project.h
+++ b/RedPandaIDE/project.h
@@ -59,6 +59,9 @@ public:
void setModified(bool value);
bool save();
+ PFolderNode &node();
+ void setNode(const PFolderNode &newNode);
+
private:
Project* mParent;
Editor* mEditor;
@@ -140,57 +143,59 @@ class Project : public QObject
public:
explicit Project(QObject *parent = nullptr);
QString directory();
- QString executableName();
+ QString executable();
QString makeFileName();
bool modified();
void setFileName(const QString& value);
void setModified(bool value);
- int newUnit(bool newProject,
- PFolderNode parentNode,
- const QString customFileName);
+ void addFolder(const QString& s);
PProjectUnit addUnit(const QString& inFileName,
PFolderNode parentNode,
bool rebuild);
- function GetFolderPath(Node: TTreeNode): AnsiString;
- procedure UpdateFolders;
- procedure AddFolder(const s: AnsiString);
- function OpenUnit(index: integer): TEditor;
- procedure CloseUnit(index: integer);
- procedure DoAutoOpen;
- procedure SaveUnitAs(i: integer; sFileName: AnsiString); // save single [UnitX]
- procedure SaveAll; // save [Project] and all [UnitX]
- procedure LoadLayout; // load all [UnitX]
- procedure LoadUnitLayout(e: TEditor; Index: integer); // load single [UnitX] cursor positions
- procedure SaveLayout; // save all [UnitX]
- procedure SaveUnitLayout(e: TEditor; Index: integer); // save single [UnitX] cursor positions
- function MakeProjectNode: TTreeNode;
- function MakeNewFileNode(const s: AnsiString; IsFolder: boolean; NewParent: TTreeNode): TTreeNode;
- procedure BuildPrivateResource(ForceSave: boolean = False);
- procedure LoadOptions;
- procedure SaveOptions;
- function SaveUnits: Boolean;
+ void buildPrivateResource(bool forceSave);
+
+ int newUnit(bool newProject,
+ PFolderNode parentNode,
+ const QString customFileName);
+ QString getFolderPath(PFolderNode node);
+ void updateFolders();
+ Editor* openUnit(int index);
+ void closeUnit(int index);
+ void doAutoOpen();
+ void saveUnitAs(int i, const QString& sFileName); // save single [UnitX]
+ void saveAll(); // save [Project] and all [UnitX]
+ void loadLayout(); // load all [UnitX]
+ void loadUnitLayout(Editor *e, int index); // load single [UnitX] cursor positions
+ void saveLayout(); // save all [UnitX]
+ void saveUnitLayout(Editor* e, int index); // save single [UnitX] cursor positions
+ PFolderNode makeProjectNode();
+ PFolderNode makeNewFileNode(const QString& s, bool isFolder, PFolderNode newParent);
+ void loadOptions();
+ void saveOptions();
+ bool saveUnits();
// procedure Open;
- function FileAlreadyExists(const s: AnsiString): boolean;
- function RemoveFolder(Node: TTreeNode): boolean;
- function RemoveEditor(index: integer; DoClose: boolean): boolean;
- function GetUnitFromString(const s: AnsiString): integer;
- procedure RebuildNodes;
- function ListUnitStr(Separator: char): AnsiString;
- procedure ExportToHTML;
- function ShowOptions: Integer;
- function AssignTemplate(const aFileName: AnsiString; aTemplate: TTemplate): boolean;
- function FolderNodeFromName(const name: AnsiString): TTreeNode;
- procedure CreateFolderNodes;
- procedure UpdateNodeIndexes;
- procedure SetNodeValue(value: TTreeNode);
- procedure CheckProjectFileForUpdate;
- procedure IncrementBuildNumber;
- function GetCompilerOption(const OptionString: AnsiString): Char;
- procedure SetCompilerOption(const OptionString: AnsiString; Value: Char);
- procedure SaveToLog;
+ bool fileAlreadyExists(const QString& s);
+ bool removeFolder(PFolderNode node);
+ bool removeEditor(int index, bool doClose);
+ int getUnitFromString(const QString& s);
+ void rebuildNodes();
+ QString listUnitStr(const QChar& separator);
+ void exportToHTML();
+ void showOptions();
+ // bool assignTemplate(const QString& aFileName, const PTemplate& aTemplate);
+ PFolderNode folderNodeFromName(const QString& name);
+ void createFolderNodes();
+ void updateNodeIndexes();
+ void setNodeValue(PFolderNode value);
+ void checkProjectFileForUpdate();
+ void incrementBuildNumber();
+ QChar getCompilerOption(const QString& optionString);
+ void setCompilerOption(const QString& optionString, const QChar& value);
+ void saveToLog();
signals:
- void changed();
+ void nodesChanged();
+ void modifyChanged(bool value);
private:
void open();
void sortUnitsByPriority();
diff --git a/RedPandaIDE/settings.cpp b/RedPandaIDE/settings.cpp
index 8161cf43..314e5fe6 100644
--- a/RedPandaIDE/settings.cpp
+++ b/RedPandaIDE/settings.cpp
@@ -1339,22 +1339,22 @@ bool Settings::CompilerSet::dirsValid(QString &msg)
bool Settings::CompilerSet::validateExes(QString &msg)
{
msg ="";
- if (!QFile(mCCompiler).exists()) {
+ if (!fileExists(mCCompiler)) {
msg += QObject::tr("Cannot find the %1 \"%2\"")
.arg("C Compiler")
.arg(mCCompiler);
}
- if (!QFile(mCppCompiler).exists()) {
+ if (!fileExists(mCppCompiler)) {
msg += QObject::tr("Cannot find the %1 \"%2\"")
.arg("C++ Compiler")
.arg(mCppCompiler);
}
- if (!QFile(mMake).exists()) {
+ if (!fileExists(mMake)) {
msg += QObject::tr("Cannot find the %1 \"%2\"")
.arg("Maker")
.arg(mMake);
}
- if (!QFile(mDebugger).exists()) {
+ if (!fileExists(mDebugger)) {
msg += QObject::tr("Cannot find the %1 \"%2\"")
.arg("Maker")
.arg(mDebugger);
diff --git a/RedPandaIDE/systemconsts.h b/RedPandaIDE/systemconsts.h
index 6c29d043..87f791ef 100644
--- a/RedPandaIDE/systemconsts.h
+++ b/RedPandaIDE/systemconsts.h
@@ -18,6 +18,10 @@
#error "Only support windows now!"
#endif
+#define DEV_PROJECT_EXT "dev"
+#define RC_EXT "rc"
+#define H_EXT "h"
+
#ifdef Q_OS_WIN
# define PATH_SENSITIVITY Qt::CaseInsensitive
# define NULL_FILE "NUL"
diff --git a/RedPandaIDE/utils.cpp b/RedPandaIDE/utils.cpp
index b8178fa5..f4693bdd 100644
--- a/RedPandaIDE/utils.cpp
+++ b/RedPandaIDE/utils.cpp
@@ -126,7 +126,7 @@ bool isNonPrintableAsciiChar(char ch)
bool fileExists(const QString &file)
{
- return QFileInfo(file).exists();
+ return fileExists(file);
}
bool fileExists(const QString &dir, const QString &fileName)
@@ -461,7 +461,7 @@ QString changeFileExt(const QString& filename, const QString& ext)
if (suffix.isEmpty()) {
return filename+"."+ext;
} else {
- return filename.mid(0,filename.length()-suffix.length()-1)+"."+ext;
+ return fileInfo.completeBaseName()+"."+ext;
}
}
@@ -621,3 +621,29 @@ QString baseFileName(const QString &fileName)
QFileInfo fileInfo(fileName);
return fileInfo.fileName();
}
+
+QString extractRelativePath(const QString &base, const QString &dest)
+{
+ QFileInfo baseInfo(base);
+ QDir baseDir;
+ if (baseInfo.isDir()) {
+ baseDir = baseInfo.absoluteDir();
+ } else {
+ baseDir = baseInfo.dir();
+ }
+ return baseDir.relativeFilePath(dest);
+}
+
+QString genMakePath(const QString &fileName, bool escapeSpaces, bool encloseInQuotes)
+{
+ QString result = fileName;
+
+ // Convert backslashes to slashes
+ result.replace('\\','/');
+ if (escapeSpaces) {
+ result.replace(' ',"\\ ");
+ }
+ if (encloseInQuotes)
+ result = '"'+result+'"';
+ return result;
+}
diff --git a/RedPandaIDE/utils.h b/RedPandaIDE/utils.h
index 7569bd34..05c7ecda 100644
--- a/RedPandaIDE/utils.h
+++ b/RedPandaIDE/utils.h
@@ -124,6 +124,8 @@ QString includeTrailingPathDelimiter(const QString& path);
QString excludeTrailingPathDelimiter(const QString& path);
FileType getFileType(const QString& filename);
QString changeFileExt(const QString& filename, const QString& ext);
+QString extractRelativePath(const QString& base, const QString& dest);
+QString genMakePath(const QString& fileName,bool escapeSpaces, bool encloseInQuotes);
QString getCompiledExecutableName(const QString& filename);
void splitStringArguments(const QString& arguments, QStringList& argumentList);
bool programHasConsole(const QString& filename);