2021-09-05 23:45:05 +08:00
|
|
|
#include "project.h"
|
|
|
|
#include "editor.h"
|
|
|
|
#include "mainwindow.h"
|
2021-09-06 08:45:53 +08:00
|
|
|
#include "utils.h"
|
|
|
|
#include "systemconsts.h"
|
2021-09-07 16:49:35 +08:00
|
|
|
#include "editorlist.h"
|
|
|
|
#include <parser/cppparser.h>
|
|
|
|
#include "utils.h"
|
2021-09-06 08:45:53 +08:00
|
|
|
|
|
|
|
#include <QDir>
|
2021-09-09 00:15:12 +08:00
|
|
|
#include <QFileDialog>
|
2021-09-06 08:45:53 +08:00
|
|
|
#include <QFileInfo>
|
2021-09-06 12:58:29 +08:00
|
|
|
#include <QMessageBox>
|
2021-09-09 11:47:04 +08:00
|
|
|
#include "settings.h"
|
2021-09-05 23:45:05 +08:00
|
|
|
|
2021-09-07 16:49:35 +08:00
|
|
|
Project::Project(const QString &filename, const QString &name, QObject *parent) : QObject(parent)
|
2021-09-05 23:45:05 +08:00
|
|
|
{
|
2021-09-07 16:49:35 +08:00
|
|
|
mFilename = filename;
|
|
|
|
mIniFile = std::make_shared<QSettings>(filename,QSettings::IniFormat);
|
|
|
|
mParser = std::make_shared<CppParser>();
|
|
|
|
mParser->setOnGetFileStream(
|
|
|
|
std::bind(
|
|
|
|
&EditorList::getContentFromOpenedEditor,pMainWindow->editorList(),
|
|
|
|
std::placeholders::_1, std::placeholders::_2));
|
|
|
|
resetCppParser(mParser);
|
|
|
|
if (name == DEV_INTERNAL_OPEN)
|
|
|
|
open();
|
|
|
|
else {
|
|
|
|
mName = name;
|
|
|
|
mIniFile->beginGroup("Project");
|
|
|
|
mIniFile->setValue("filename", mFilename);
|
|
|
|
mIniFile->setValue("name", mName);
|
|
|
|
mIniFile->endGroup();
|
|
|
|
mNode = makeProjectNode();
|
|
|
|
}
|
2021-09-05 23:45:05 +08:00
|
|
|
}
|
|
|
|
|
2021-09-09 11:47:04 +08:00
|
|
|
QString Project::directory() const
|
2021-09-06 08:45:53 +08:00
|
|
|
{
|
|
|
|
QFileInfo fileInfo(mFilename);
|
|
|
|
return fileInfo.absolutePath();
|
|
|
|
}
|
|
|
|
|
2021-09-09 11:47:04 +08:00
|
|
|
QString Project::executable() const
|
2021-09-06 08:45:53 +08:00
|
|
|
{
|
|
|
|
QString exeFileName;
|
|
|
|
if (mOptions.overrideOutput && !mOptions.overridenOutput.isEmpty()) {
|
|
|
|
exeFileName = mOptions.overridenOutput;
|
|
|
|
} else {
|
|
|
|
switch(mOptions.type) {
|
|
|
|
case ProjectType::StaticLib:
|
2021-09-10 12:37:02 +08:00
|
|
|
exeFileName = changeFileExt(extractFileName(mFilename),STATIC_LIB_EXT);
|
2021-09-06 08:45:53 +08:00
|
|
|
break;
|
|
|
|
case ProjectType::DynamicLib:
|
2021-09-10 12:37:02 +08:00
|
|
|
exeFileName = changeFileExt(extractFileName(mFilename),DYNAMIC_LIB_EXT);
|
2021-09-06 08:45:53 +08:00
|
|
|
break;
|
|
|
|
default:
|
2021-09-10 12:37:02 +08:00
|
|
|
exeFileName = changeFileExt(extractFileName(mFilename),EXECUTABLE_EXT);
|
2021-09-06 08:45:53 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
QString exePath;
|
|
|
|
if (!mOptions.exeOutput.isEmpty()) {
|
|
|
|
QDir baseDir(directory());
|
|
|
|
exePath = baseDir.filePath(mOptions.exeOutput);
|
|
|
|
} else {
|
|
|
|
exePath = directory();
|
|
|
|
}
|
|
|
|
QDir exeDir(exePath);
|
|
|
|
return exeDir.filePath(exeFileName);
|
|
|
|
}
|
|
|
|
|
|
|
|
QString Project::makeFileName()
|
|
|
|
{
|
2021-09-06 12:58:29 +08:00
|
|
|
if (mOptions.useCustomMakefile)
|
|
|
|
return mOptions.customMakefile;
|
2021-09-06 08:45:53 +08:00
|
|
|
else
|
2021-09-06 12:58:29 +08:00
|
|
|
return QDir(directory()).filePath(MAKEFILE_NAME);
|
|
|
|
}
|
|
|
|
|
2021-09-09 11:47:04 +08:00
|
|
|
bool Project::modified() const
|
2021-09-06 12:58:29 +08:00
|
|
|
{
|
|
|
|
// Project file modified? Done
|
|
|
|
if (mModified)
|
|
|
|
return true;// quick exit avoids loop over all units
|
|
|
|
|
|
|
|
// Otherwise, check all units
|
|
|
|
foreach (const PProjectUnit& unit, mUnits){
|
|
|
|
if (unit->modified())
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::open()
|
|
|
|
{
|
|
|
|
QFile fileInfo(mFilename);
|
|
|
|
if (fileInfo.exists()
|
|
|
|
&& !fileInfo.isWritable()) {
|
|
|
|
if (QMessageBox::question(pMainWindow,
|
|
|
|
tr("Remove Readonly Attribute"),
|
|
|
|
tr("Project file '%1' is readonly.<br /> Remove the readonly attribute?")
|
|
|
|
.arg(mFilename),
|
|
|
|
QMessageBox::Yes | QMessageBox::No,
|
|
|
|
QMessageBox::Yes) == QMessageBox::Yes) {
|
|
|
|
fileInfo.setPermissions(
|
|
|
|
QFileDevice::WriteOwner
|
|
|
|
| QFileDevice::WriteGroup
|
|
|
|
| QFileDevice::WriteUser
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
loadOptions();
|
|
|
|
|
2021-09-07 00:32:16 +08:00
|
|
|
mNode = makeProjectNode();
|
2021-09-06 12:58:29 +08:00
|
|
|
|
|
|
|
checkProjectFileForUpdate();
|
|
|
|
|
2021-09-07 00:32:16 +08:00
|
|
|
mIniFile->beginGroup("Project");
|
|
|
|
int uCount = mIniFile->value("UnitCount",0).toInt();
|
|
|
|
mIniFile->endGroup();
|
2021-09-06 12:58:29 +08:00
|
|
|
//createFolderNodes;
|
|
|
|
QDir dir(directory());
|
|
|
|
for (int i=0;i<uCount;i++) {
|
|
|
|
PProjectUnit newUnit = std::make_shared<ProjectUnit>();
|
2021-09-07 00:32:16 +08:00
|
|
|
mIniFile->beginGroup(QString("Unit%1").arg(i));
|
|
|
|
newUnit->setFileName(dir.filePath(mIniFile->value("FileName","").toString()));
|
2021-09-06 12:58:29 +08:00
|
|
|
if (!QFileInfo(newUnit->fileName()).exists()) {
|
|
|
|
QMessageBox::critical(pMainWindow,
|
|
|
|
tr("File Not Found"),
|
|
|
|
tr("Project file '%1' can't be found!")
|
|
|
|
.arg(newUnit->fileName()),
|
|
|
|
QMessageBox::Ok);
|
|
|
|
newUnit->setModified(true);
|
|
|
|
} else {
|
2021-09-07 00:32:16 +08:00
|
|
|
newUnit->setFolder(mIniFile->value("Folder","").toString());
|
|
|
|
newUnit->setCompile(mIniFile->value("Compile", true).toBool());
|
2021-09-06 18:59:06 +08:00
|
|
|
newUnit->setCompileCpp(
|
2021-09-07 00:32:16 +08:00
|
|
|
mIniFile->value("CompileCpp",mOptions.useGPP).toBool());
|
|
|
|
|
|
|
|
newUnit->setLink(mIniFile->value("Link", true).toBool());
|
|
|
|
newUnit->setPriority(mIniFile->value("Priority", 1000).toInt());
|
|
|
|
newUnit->setOverrideBuildCmd(mIniFile->value("OverrideBuildCmd", false).toInt());
|
|
|
|
newUnit->setBuildCmd(mIniFile->value("BuildCmd", "").toString());
|
|
|
|
newUnit->setDetectEncoding(mIniFile->value("DetectEncoding", mOptions.useUTF8).toBool());
|
|
|
|
newUnit->setEncoding(mIniFile->value("Encoding",ENCODING_SYSTEM_DEFAULT).toByteArray());
|
|
|
|
|
|
|
|
newUnit->setEditor(nullptr);
|
|
|
|
newUnit->setNew(false);
|
|
|
|
newUnit->setParent(this);
|
2021-09-10 12:37:02 +08:00
|
|
|
newUnit->setNode(makeNewFileNode(extractFileName(newUnit->fileName()), false, folderNodeFromName(newUnit->folder())));
|
2021-09-07 00:32:16 +08:00
|
|
|
newUnit->node()->unitIndex = mUnits.count();
|
|
|
|
mUnits.append(newUnit);
|
|
|
|
}
|
|
|
|
mIniFile->endGroup();
|
|
|
|
}
|
|
|
|
rebuildNodes();
|
|
|
|
}
|
2021-09-06 18:59:06 +08:00
|
|
|
|
2021-09-07 00:32:16 +08:00
|
|
|
void Project::setFileName(const QString &value)
|
|
|
|
{
|
|
|
|
if (mFilename!=value) {
|
|
|
|
mIniFile->sync();
|
|
|
|
mIniFile.reset();
|
|
|
|
QFile::copy(mFilename,value);
|
|
|
|
mFilename = value;
|
|
|
|
setModified(true);
|
2021-09-10 21:37:52 +08:00
|
|
|
mIniFile = std::make_shared<QSettings>(mFilename, QSettings::IniFormat);
|
2021-09-07 00:32:16 +08:00
|
|
|
}
|
|
|
|
}
|
2021-09-06 12:58:29 +08:00
|
|
|
|
2021-09-07 00:32:16 +08:00
|
|
|
void Project::setModified(bool value)
|
|
|
|
{
|
|
|
|
QFile file(mFilename);
|
|
|
|
// only mark modified if *not* read-only
|
|
|
|
if (!file.exists()
|
|
|
|
|| (file.exists() && file.isWritable())) {
|
|
|
|
mModified=value;
|
2021-09-07 10:28:40 +08:00
|
|
|
emit modifyChanged(mModified);
|
2021-09-07 00:32:16 +08:00
|
|
|
}
|
2021-09-07 10:28:40 +08:00
|
|
|
}
|
2021-09-06 12:58:29 +08:00
|
|
|
|
2021-09-10 10:27:01 +08:00
|
|
|
PFolderNode Project::makeNewFileNode(const QString &s, bool isFolder, PFolderNode newParent)
|
|
|
|
{
|
|
|
|
PFolderNode node = std::make_shared<FolderNode>();
|
|
|
|
node->parent = newParent;
|
|
|
|
node->text = s;
|
2021-09-10 21:37:52 +08:00
|
|
|
if (newParent) {
|
|
|
|
node->level = newParent->level+1;
|
|
|
|
}
|
|
|
|
if (isFolder)
|
|
|
|
node->unitIndex = -1;
|
2021-09-10 10:27:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
PFolderNode Project::makeProjectNode()
|
|
|
|
{
|
|
|
|
PFolderNode node = std::make_shared<FolderNode>();
|
|
|
|
node->text = mName;
|
2021-09-10 21:37:52 +08:00
|
|
|
node->level = 0;
|
2021-09-10 10:27:01 +08:00
|
|
|
}
|
|
|
|
|
2021-09-10 21:37:52 +08:00
|
|
|
int Project::newUnit(PFolderNode parentNode, const QString customFileName)
|
2021-09-10 12:37:02 +08:00
|
|
|
{
|
|
|
|
PProjectUnit newUnit = std::make_shared<ProjectUnit>();
|
|
|
|
|
|
|
|
// Select folder to add unit to
|
|
|
|
if (!parentNode)
|
|
|
|
parentNode = mNode; // project root node
|
|
|
|
|
|
|
|
if (parentNode->unitIndex>=0) { //it's a file
|
|
|
|
parentNode = mNode;
|
|
|
|
}
|
|
|
|
QString s;
|
|
|
|
QDir dir(directory());
|
|
|
|
// Find unused 'new' filename
|
|
|
|
if (customFileName.isEmpty()) {
|
|
|
|
do {
|
|
|
|
s = dir.absoluteFilePath(tr("untitled")+QString("%1").arg(getNewFileNumber()));
|
|
|
|
} while (fileExists(s));
|
|
|
|
} else {
|
|
|
|
s = dir.absoluteFilePath(customFileName);
|
|
|
|
}
|
|
|
|
// Add
|
|
|
|
int result = mUnits.count();
|
|
|
|
mUnits.append(newUnit);
|
|
|
|
|
|
|
|
// Set all properties
|
|
|
|
newUnit->setFileName(s);
|
|
|
|
newUnit->setNew(true);
|
|
|
|
newUnit->setEditor(nullptr);
|
|
|
|
newUnit->setFolder(getFolderPath(parentNode));
|
|
|
|
newUnit->setNode(makeNewFileNode(extractFileName(newUnit->fileName()),
|
|
|
|
false, parentNode));
|
|
|
|
newUnit->node()->unitIndex = result;
|
|
|
|
//parentNode.Expand(True);
|
|
|
|
newUnit->setCompile(true);
|
|
|
|
newUnit->setCompileCpp(mOptions.useGPP);
|
|
|
|
newUnit->setLink(true);
|
|
|
|
newUnit->setPriority(1000);
|
|
|
|
newUnit->setOverrideBuildCmd(false);
|
|
|
|
newUnit->setBuildCmd("");
|
|
|
|
newUnit->setModified(true);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
Editor *Project::openUnit(int index)
|
|
|
|
{
|
|
|
|
if ((index < 0) || (index >= mUnits.count()))
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
PProjectUnit unit = mUnits[index];
|
|
|
|
|
|
|
|
if (!unit->fileName().isEmpty()) {
|
|
|
|
QDir dir(directory());
|
|
|
|
QString fullPath = dir.absoluteFilePath(unit->fileName());
|
|
|
|
Editor * editor = pMainWindow->editorList()->getOpenedEditorByFilename(fullPath);
|
|
|
|
if (editor) {//already opened in the editors
|
|
|
|
editor->setInProject(true);
|
|
|
|
return editor;
|
|
|
|
}
|
2021-09-10 15:03:47 +08:00
|
|
|
QByteArray encoding;
|
|
|
|
if (mOptions.useUTF8) {
|
|
|
|
encoding = ENCODING_UTF8;
|
|
|
|
} else
|
|
|
|
encoding = mOptions.encoding.toLocal8Bit();
|
|
|
|
editor = pMainWindow->editorList()->newEditor(fullPath, encoding, true, false);
|
|
|
|
editor->setInProject(true);
|
|
|
|
unit->setEditor(editor);
|
|
|
|
unit->setEncoding(encoding);
|
|
|
|
loadUnitLayout(editor,index);
|
|
|
|
return editor;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::rebuildNodes()
|
|
|
|
{
|
|
|
|
// Remember if folder nodes were expanded or collapsed
|
|
|
|
// Create a list of expanded folder nodes
|
|
|
|
// QStringList oldPaths := TStringList.Create;
|
|
|
|
// with MainForm.ProjectView do
|
|
|
|
// for idx := 0 to Items.Count - 1 do begin
|
|
|
|
// tempnode := Items[idx];
|
|
|
|
// if tempnode.Expanded and (tempnode.Data = Pointer(-1)) then // data=pointer(-1) - it's folder
|
|
|
|
// oldPaths.Add(GetFolderPath(tempnode));
|
|
|
|
// end;
|
2021-09-10 12:37:02 +08:00
|
|
|
|
2021-09-10 15:03:47 +08:00
|
|
|
// Delete everything
|
|
|
|
mNode->children.clear();
|
|
|
|
|
|
|
|
// Recreate everything
|
|
|
|
createFolderNodes();
|
|
|
|
|
|
|
|
for (int idx=0;idx<mUnits.count();idx++) {
|
|
|
|
mUnits[idx]->setNode(
|
|
|
|
makeNewFileNode(
|
|
|
|
extractRelativePath(filename(),mUnits[idx]->fileName()),
|
|
|
|
false,
|
|
|
|
folderNodeFromName(mUnits[idx]->folder())
|
|
|
|
)
|
|
|
|
);
|
|
|
|
mUnits[idx]->node()->unitIndex = idx;
|
2021-09-10 12:37:02 +08:00
|
|
|
}
|
|
|
|
|
2021-09-10 15:03:47 +08:00
|
|
|
// // expand nodes expanded before recreating the project tree
|
|
|
|
// fNode.Collapse(True);
|
|
|
|
// with MainForm.ProjectView do
|
|
|
|
// for idx := 0 to Items.Count - 1 do begin
|
|
|
|
// tempnode := Items[idx];
|
|
|
|
// if (tempnode.Data = Pointer(-1)) then //it's a folder
|
|
|
|
// if oldPaths.IndexOf(GetFolderPath(tempnode)) >= 0 then
|
|
|
|
// tempnode.Expand(False);
|
|
|
|
// end;
|
|
|
|
// FreeAndNil(oldPaths);
|
|
|
|
|
|
|
|
// fNode.Expand(False);
|
|
|
|
|
|
|
|
emit nodesChanged();
|
2021-09-10 12:37:02 +08:00
|
|
|
}
|
|
|
|
|
2021-09-10 21:37:52 +08:00
|
|
|
bool Project::removeEditor(int index, bool doClose)
|
|
|
|
{
|
|
|
|
if (index<0 || index>=mUnits.count())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
PProjectUnit unit = mUnits[index];
|
|
|
|
|
|
|
|
// Attempt to close it
|
|
|
|
if (doClose && (unit->editor())) {
|
|
|
|
if (!pMainWindow->editorList()->closeEditor(unit->editor()))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//if not fUnits.GetItem(index).fNew then
|
|
|
|
mIniFile->remove("Unit"+QString("%1").arg(index+1));
|
|
|
|
PFolderNode node = unit->node();
|
|
|
|
PFolderNode parent = node->parent.lock();
|
|
|
|
if (parent) {
|
|
|
|
parent->children.removeAll(node);
|
|
|
|
}
|
|
|
|
mUnits.removeAt(index);
|
|
|
|
updateNodeIndexes();
|
|
|
|
setModified(true);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Project::removeFolder(PFolderNode node)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Sanity check
|
|
|
|
if (!node)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Check if this is actually a folder
|
|
|
|
if (node->unitIndex>=0 || node->level<1)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Let this function call itself
|
|
|
|
removeFolderRecurse(node);
|
|
|
|
|
|
|
|
// Update list of folders (sets modified)
|
|
|
|
updateFolders();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::saveAll()
|
|
|
|
{
|
|
|
|
if (!saveUnits())
|
|
|
|
return;
|
|
|
|
saveOptions(); // update other data, and save to disk
|
|
|
|
saveLayout(); // save current opened files, and which is "active".
|
|
|
|
|
|
|
|
// We have saved everything to disk, so mark unmodified
|
|
|
|
setModified(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::saveLayout()
|
|
|
|
{
|
|
|
|
QString s = changeFileExt(mFilename, "layout");
|
|
|
|
QSettings layIni(mFilename,QSettings::IniFormat);
|
|
|
|
QStringList sl;
|
|
|
|
// Write list of open project files
|
|
|
|
for (int i=0;i<pMainWindow->editorList()->pageCount();i++) {
|
|
|
|
Editor* e= (*(pMainWindow->editorList()))[i];
|
|
|
|
if (e && e->inProject())
|
|
|
|
sl.append(QString("%1").arg(indexInUnits(e)));
|
|
|
|
}
|
|
|
|
layIni.beginGroup("Editors");
|
|
|
|
layIni.setValue("Order",sl.join(","));
|
|
|
|
|
|
|
|
Editor *e, *e2;
|
|
|
|
// Remember what files were visible
|
|
|
|
pMainWindow->editorList()->getVisibleEditors(e, e2);
|
|
|
|
if (e)
|
|
|
|
layIni.setValue("Focused", indexInUnits(e));
|
|
|
|
layIni.endGroup();
|
|
|
|
// save editor info
|
|
|
|
for (int i=0;i<mUnits.count();i++) {
|
|
|
|
layIni.beginGroup(QString("Editor_%1").arg(i));
|
|
|
|
PProjectUnit unit = mUnits[i];
|
|
|
|
Editor* editor = unit->editor();
|
|
|
|
if (editor) {
|
|
|
|
layIni.setValue("CursorCol", editor->caretX());
|
|
|
|
layIni.setValue("CursorRow", editor->caretY());
|
|
|
|
layIni.setValue("TopLine", editor->topLine());
|
|
|
|
layIni.setValue("LeftChar", editor->leftChar());
|
|
|
|
}
|
|
|
|
layIni.endGroup();
|
|
|
|
// remove old data from project file
|
|
|
|
mIniFile->beginGroup(QString("Unit%1").arg(i+1));
|
|
|
|
mIniFile->remove("Open");
|
|
|
|
mIniFile->remove("Top");
|
|
|
|
mIniFile->remove("CursorCol");
|
|
|
|
mIniFile->remove("CursorRow");
|
|
|
|
mIniFile->remove("TopLine");
|
|
|
|
mIniFile->remove("LeftChar");
|
|
|
|
mIniFile->endGroup();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::saveOptions()
|
|
|
|
{
|
|
|
|
with finiFile do begin
|
|
|
|
WriteString('Project', 'FileName', ExtractRelativePath(Directory, fFileName));
|
|
|
|
WriteString('Project', 'Name', fName);
|
|
|
|
WriteInteger('Project', 'Type', fOptions.typ);
|
|
|
|
WriteInteger('Project', 'Ver', 2); // Is 2 as of Dev-C++ 5.2.0.3
|
|
|
|
WriteString('Project', 'ObjFiles', fOptions.ObjFiles.DelimitedText);
|
|
|
|
WriteString('Project', 'Includes', fOptions.Includes.DelimitedText);
|
|
|
|
WriteString('Project', 'Libs', fOptions.Libs.DelimitedText);
|
|
|
|
WriteString('Project', 'PrivateResource', fOptions.PrivateResource);
|
|
|
|
WriteString('Project', 'ResourceIncludes', fOptions.ResourceIncludes.DelimitedText);
|
|
|
|
WriteString('Project', 'MakeIncludes', fOptions.MakeIncludes.DelimitedText);
|
|
|
|
WriteString('Project', 'Compiler', fOptions.CompilerCmd);
|
|
|
|
WriteString('Project', 'CppCompiler', fOptions.CppCompilerCmd);
|
|
|
|
WriteString('Project', 'Linker', fOptions.LinkerCmd);
|
|
|
|
WriteBool('Project', 'IsCpp', fOptions.UseGpp);
|
|
|
|
WriteString('Project', 'Icon', ExtractRelativePath(Directory, fOptions.Icon));
|
|
|
|
WriteString('Project', 'ExeOutput', fOptions.ExeOutput);
|
|
|
|
WriteString('Project', 'ObjectOutput', fOptions.ObjectOutput);
|
|
|
|
WriteString('Project', 'LogOutput', fOptions.LogOutput);
|
|
|
|
WriteBool('Project', 'LogOutputEnabled', fOptions.LogOutputEnabled);
|
|
|
|
WriteBool('Project', 'OverrideOutput', fOptions.OverrideOutput);
|
|
|
|
WriteString('Project', 'OverrideOutputName', fOptions.OverridenOutput);
|
|
|
|
WriteString('Project', 'HostApplication', fOptions.HostApplication);
|
|
|
|
WriteBool('Project', 'UseCustomMakefile', fOptions.UseCustomMakefile);
|
|
|
|
WriteString('Project', 'CustomMakefile', fOptions.CustomMakefile);
|
|
|
|
WriteBool('Project', 'UsePrecompiledHeader', fOptions.UsePrecompiledHeader);
|
|
|
|
WriteString('Project', 'PrecompiledHeader', fOptions.PrecompiledHeader);
|
|
|
|
WriteString('Project', 'CommandLine', fOptions.CmdLineArgs);
|
|
|
|
WriteString('Project', 'Folders', fFolders.CommaText);
|
|
|
|
WriteBool('Project', 'IncludeVersionInfo', fOptions.IncludeVersionInfo);
|
|
|
|
WriteBool('Project', 'SupportXPThemes', fOptions.SupportXPThemes);
|
|
|
|
WriteInteger('Project', 'CompilerSet', fOptions.CompilerSet);
|
|
|
|
WriteString('Project', 'CompilerSettings', fOptions.CompilerOptions);
|
|
|
|
WriteBool('Project','StaticLink', fOptions.StaticLink);
|
|
|
|
WriteBool('Project','AddCharset', fOptions.AddCharset);
|
|
|
|
WriteBool('Project', 'UseUTF8', fOptions.UseUTF8);
|
|
|
|
|
|
|
|
WriteInteger('VersionInfo', 'Major', fOptions.VersionInfo.Major);
|
|
|
|
WriteInteger('VersionInfo', 'Minor', fOptions.VersionInfo.Minor);
|
|
|
|
WriteInteger('VersionInfo', 'Release', fOptions.VersionInfo.Release);
|
|
|
|
WriteInteger('VersionInfo', 'Build', fOptions.VersionInfo.Build);
|
|
|
|
WriteInteger('VersionInfo', 'LanguageID', fOptions.VersionInfo.LanguageID);
|
|
|
|
WriteInteger('VersionInfo', 'CharsetID', fOptions.VersionInfo.CharsetID);
|
|
|
|
WriteString('VersionInfo', 'CompanyName', fOptions.VersionInfo.CompanyName);
|
|
|
|
WriteString('VersionInfo', 'FileVersion', fOptions.VersionInfo.FileVersion);
|
|
|
|
WriteString('VersionInfo', 'FileDescription', fOptions.VersionInfo.FileDescription);
|
|
|
|
WriteString('VersionInfo', 'InternalName', fOptions.VersionInfo.InternalName);
|
|
|
|
WriteString('VersionInfo', 'LegalCopyright', fOptions.VersionInfo.LegalCopyright);
|
|
|
|
WriteString('VersionInfo', 'LegalTrademarks', fOptions.VersionInfo.LegalTrademarks);
|
|
|
|
WriteString('VersionInfo', 'OriginalFilename', fOptions.VersionInfo.OriginalFilename);
|
|
|
|
WriteString('VersionInfo', 'ProductName', fOptions.VersionInfo.ProductName);
|
|
|
|
WriteString('VersionInfo', 'ProductVersion', fOptions.VersionInfo.ProductVersion);
|
|
|
|
WriteBool('VersionInfo', 'AutoIncBuildNr', fOptions.VersionInfo.AutoIncBuildNr);
|
|
|
|
WriteBool('VersionInfo', 'SyncProduct', fOptions.VersionInfo.SyncProduct);
|
|
|
|
|
|
|
|
if fOptions.Ver <= 0 then begin
|
|
|
|
//delete outdated dev4 project options
|
|
|
|
DeleteKey('Project', 'NoConsole');
|
|
|
|
DeleteKey('Project', 'IsDLL');
|
|
|
|
DeleteKey('Project', 'ResFiles');
|
|
|
|
DeleteKey('Project', 'IncludeDirs');
|
|
|
|
DeleteKey('Project', 'CompilerOptions');
|
|
|
|
DeleteKey('Project', 'StaticLink');
|
|
|
|
DeleteKey('Project', 'StaticLink');
|
|
|
|
DeleteKey('Project', 'UseUTF8');
|
|
|
|
DeleteKey('Project', 'Use_GPP');
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
fINIFile.UpdateFile; // force flush
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-09-07 10:28:40 +08:00
|
|
|
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<ProjectUnit>(this);
|
|
|
|
|
|
|
|
// Set all properties
|
|
|
|
newUnit->setFileName(QDir(directory()).filePath(inFileName));
|
|
|
|
newUnit->setNew(false);
|
|
|
|
newUnit->setEditor(nullptr);
|
|
|
|
newUnit->setFolder(getFolderPath(parentNode));
|
2021-09-10 12:37:02 +08:00
|
|
|
newUnit->setNode(makeNewFileNode(extractFileName(newUnit->fileName()), false, parentNode));
|
2021-09-07 10:28:40 +08:00
|
|
|
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 <project_filename>.res
|
|
|
|
// to <project_filename>_private.res
|
|
|
|
//
|
|
|
|
// in many cases (like in importing a MSVC project)
|
|
|
|
// the project's resource file has already the
|
|
|
|
// <project_filename>.res filename.
|
2021-09-07 14:04:48 +08:00
|
|
|
QString rcFile;
|
2021-09-07 10:28:40 +08:00
|
|
|
if (!mOptions.privateResource.isEmpty()) {
|
2021-09-07 14:04:48 +08:00
|
|
|
rcFile = QDir(directory()).filePath(mOptions.privateResource);
|
|
|
|
if (changeFileExt(rcFile, DEV_PROJECT_EXT) == mFilename)
|
|
|
|
rcFile = changeFileExt(mFilename,QString("_private") + RC_EXT);
|
2021-09-07 10:28:40 +08:00
|
|
|
} else
|
2021-09-07 14:04:48 +08:00
|
|
|
rcFile = changeFileExt(mFilename,QString("_private") + RC_EXT);
|
|
|
|
rcFile = extractRelativePath(mFilename, rcFile);
|
|
|
|
rcFile.replace(' ','_');
|
2021-09-07 10:28:40 +08:00
|
|
|
|
|
|
|
// don't run the private resource file and header if not modified,
|
|
|
|
// unless ForceSave is true
|
|
|
|
if (!forceSave
|
2021-09-07 14:04:48 +08:00
|
|
|
&& fileExists(rcFile)
|
|
|
|
&& fileExists(changeFileExt(rcFile, H_EXT))
|
2021-09-07 10:28:40 +08:00
|
|
|
&& !mModified)
|
|
|
|
return;
|
|
|
|
|
2021-09-07 16:49:35 +08:00
|
|
|
QStringList contents;
|
|
|
|
contents.append("/* THIS FILE WILL BE OVERWRITTEN BY DEV-C++ */");
|
|
|
|
contents.append("/* DO NOT EDIT! */");
|
|
|
|
contents.append("");
|
2021-09-07 10:28:40 +08:00
|
|
|
|
|
|
|
if (mOptions.includeVersionInfo) {
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append("#include <windows.h> // include for version info constants");
|
|
|
|
contents.append("");
|
2021-09-07 14:04:48 +08:00
|
|
|
}
|
2021-09-07 10:28:40 +08:00
|
|
|
|
|
|
|
foreach (const PProjectUnit& unit, mUnits) {
|
|
|
|
if (
|
|
|
|
(getFileType(unit->fileName()) == FileType::WindowsResourceSource)
|
|
|
|
&& unit->compile() )
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append("#include \"" +
|
2021-09-07 10:28:40 +08:00
|
|
|
genMakePath(
|
|
|
|
extractRelativePath(directory(), unit->fileName()),
|
|
|
|
false,
|
|
|
|
false) + "\"");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mOptions.icon.isEmpty()) {
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append("");
|
2021-09-07 10:28:40 +08:00
|
|
|
QString icon = QDir(directory()).absoluteFilePath(mOptions.icon);
|
|
|
|
if (fileExists(icon)) {
|
|
|
|
icon = extractRelativePath(mFilename, icon);
|
|
|
|
icon.replace('\\', '/');
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append("A ICON \"" + icon + '"');
|
2021-09-07 10:28:40 +08:00
|
|
|
} else
|
|
|
|
mOptions.icon = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mOptions.supportXPThemes) {
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append("");
|
|
|
|
contents.append("//");
|
|
|
|
contents.append("// SUPPORT FOR WINDOWS XP THEMES:");
|
|
|
|
contents.append("// THIS WILL MAKE THE PROGRAM USE THE COMMON CONTROLS");
|
|
|
|
contents.append("// LIBRARY VERSION 6.0 (IF IT IS AVAILABLE)");
|
|
|
|
contents.append("//");
|
2021-09-07 10:28:40 +08:00
|
|
|
if (!mOptions.exeOutput.isEmpty())
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(
|
2021-09-07 10:28:40 +08:00
|
|
|
"1 24 \"" +
|
|
|
|
genMakePath2(
|
|
|
|
includeTrailingPathDelimiter(mOptions.exeOutput)
|
2021-09-10 12:37:02 +08:00
|
|
|
+ extractFileName(executable()))
|
2021-09-07 10:28:40 +08:00
|
|
|
+ ".Manifest\"");
|
|
|
|
else
|
2021-09-10 12:37:02 +08:00
|
|
|
contents.append("1 24 \"" + extractFileName(executable()) + ".Manifest\"");
|
2021-09-07 14:04:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (mOptions.includeVersionInfo) {
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append("");
|
|
|
|
contents.append("//");
|
|
|
|
contents.append("// TO CHANGE VERSION INFORMATION, EDIT PROJECT OPTIONS...");
|
|
|
|
contents.append("//");
|
|
|
|
contents.append("1 VERSIONINFO");
|
|
|
|
contents.append("FILEVERSION " +
|
2021-09-07 14:04:48 +08:00
|
|
|
QString("%1,%2,%3,%4")
|
|
|
|
.arg(mOptions.versionInfo.major)
|
|
|
|
.arg(mOptions.versionInfo.minor)
|
|
|
|
.arg(mOptions.versionInfo.release)
|
|
|
|
.arg(mOptions.versionInfo.build));
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append("PRODUCTVERSION " +
|
2021-09-07 14:04:48 +08:00
|
|
|
QString("%1,%2,%3,%4")
|
|
|
|
.arg(mOptions.versionInfo.major)
|
|
|
|
.arg(mOptions.versionInfo.minor)
|
|
|
|
.arg(mOptions.versionInfo.release)
|
|
|
|
.arg(mOptions.versionInfo.build));
|
|
|
|
switch(mOptions.type) {
|
|
|
|
case ProjectType::GUI:
|
|
|
|
case ProjectType::Console:
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append("FILETYPE VFT_APP");
|
2021-09-07 14:04:48 +08:00
|
|
|
break;
|
|
|
|
case ProjectType::StaticLib:
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append("FILETYPE VFT_STATIC_LIB");
|
2021-09-07 14:04:48 +08:00
|
|
|
break;
|
|
|
|
case ProjectType::DynamicLib:
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append("FILETYPE VFT_DLL");
|
2021-09-07 14:04:48 +08:00
|
|
|
break;
|
|
|
|
}
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append("{");
|
|
|
|
contents.append(" BLOCK \"StringFileInfo\"");
|
|
|
|
contents.append(" {");
|
|
|
|
contents.append(" BLOCK \"" +
|
2021-09-07 14:04:48 +08:00
|
|
|
QString("%1%2")
|
|
|
|
.arg(mOptions.versionInfo.languageID,4,16,QChar('0'))
|
|
|
|
.arg(mOptions.versionInfo.charsetID,4,16,QChar('0'))
|
|
|
|
+ '"');
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(" {");
|
|
|
|
contents.append(" VALUE \"CompanyName\", \""
|
2021-09-07 14:04:48 +08:00
|
|
|
+ mOptions.versionInfo.companyName
|
|
|
|
+ "\"");
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(" VALUE \"FileVersion\", \""
|
2021-09-07 14:04:48 +08:00
|
|
|
+ mOptions.versionInfo.fileVersion
|
|
|
|
+ "\"");
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(" VALUE \"FileDescription\", \""
|
2021-09-07 14:04:48 +08:00
|
|
|
+ mOptions.versionInfo.fileDescription
|
|
|
|
+ "\"");
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(" VALUE \"InternalName\", \""
|
2021-09-07 14:04:48 +08:00
|
|
|
+ mOptions.versionInfo.internalName
|
|
|
|
+ "\"");
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(" VALUE \"LegalCopyright\", \""
|
2021-09-07 14:04:48 +08:00
|
|
|
+ mOptions.versionInfo.legalCopyright
|
|
|
|
+ '"');
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(" VALUE \"LegalTrademarks\", \""
|
2021-09-07 14:04:48 +08:00
|
|
|
+ mOptions.versionInfo.legalTrademarks
|
|
|
|
+ "\"");
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(" VALUE \"OriginalFilename\", \""
|
2021-09-07 14:04:48 +08:00
|
|
|
+ mOptions.versionInfo.originalFilename
|
|
|
|
+ "\"");
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(" VALUE \"ProductName\", \""
|
2021-09-07 14:04:48 +08:00
|
|
|
+ mOptions.versionInfo.productName + "\"");
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(" VALUE \"ProductVersion\", \""
|
2021-09-07 14:04:48 +08:00
|
|
|
+ mOptions.versionInfo.productVersion + "\"");
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(" }");
|
|
|
|
contents.append(" }");
|
2021-09-07 14:04:48 +08:00
|
|
|
|
|
|
|
// additional block for windows 95->NT
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(" BLOCK \"VarFileInfo\"");
|
|
|
|
contents.append(" {");
|
|
|
|
contents.append(" VALUE \"Translation\", " +
|
2021-09-07 14:04:48 +08:00
|
|
|
QString("0x%1, %2")
|
|
|
|
.arg(mOptions.versionInfo.languageID,4,16,QChar('0'))
|
|
|
|
.arg(mOptions.versionInfo.charsetID));
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(" }");
|
2021-09-07 14:04:48 +08:00
|
|
|
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append("}");
|
2021-09-07 10:28:40 +08:00
|
|
|
}
|
|
|
|
|
2021-09-07 14:04:48 +08:00
|
|
|
rcFile = QDir(directory()).absoluteFilePath(rcFile);
|
2021-09-07 16:49:35 +08:00
|
|
|
if (contents.count() > 3) {
|
|
|
|
StringsToFile(contents,rcFile);
|
2021-09-07 14:04:48 +08:00
|
|
|
mOptions.privateResource = extractRelativePath(directory(), rcFile);
|
|
|
|
} else {
|
|
|
|
if (fileExists(rcFile))
|
|
|
|
QFile::remove(rcFile);
|
|
|
|
QString resFile = changeFileExt(rcFile, RES_EXT);
|
|
|
|
if (fileExists(resFile))
|
|
|
|
QFile::remove(resFile);
|
|
|
|
mOptions.privateResource = "";
|
|
|
|
}
|
|
|
|
// if fileExists(Res) then
|
|
|
|
// FileSetDate(Res, DateTimeToFileDate(Now)); // fix the "Clock skew detected" warning ;)
|
2021-09-07 10:28:40 +08:00
|
|
|
|
|
|
|
// create XP manifest
|
2021-09-07 14:04:48 +08:00
|
|
|
if (mOptions.supportXPThemes) {
|
|
|
|
QStringList content;
|
|
|
|
content.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
|
|
|
|
content.append("<assembly");
|
|
|
|
content.append(" xmlns=\"urn:schemas-microsoft-com:asm.v1\"");
|
|
|
|
content.append(" manifestVersion=\"1.0\">");
|
|
|
|
content.append("<assemblyIdentity");
|
|
|
|
QString name = mName;
|
|
|
|
name.replace(' ','_');
|
|
|
|
content.append(" name=\"DevCpp.Apps." + name + '\"');
|
|
|
|
content.append(" processorArchitecture=\"*\"");
|
|
|
|
content.append(" version=\"1.0.0.0\"");
|
|
|
|
content.append(" type=\"win32\"/>");
|
|
|
|
content.append("<description>" + name + "</description>");
|
|
|
|
content.append("<dependency>");
|
|
|
|
content.append(" <dependentAssembly>");
|
|
|
|
content.append(" <assemblyIdentity");
|
|
|
|
content.append(" type=\"win32\"");
|
|
|
|
content.append(" name=\"Microsoft.Windows.Common-Controls\"");
|
|
|
|
content.append(" version=\"6.0.0.0\"");
|
|
|
|
content.append(" processorArchitecture=\"*\"");
|
|
|
|
content.append(" publicKeyToken=\"6595b64144ccf1df\"");
|
|
|
|
content.append(" language=\"*\"");
|
|
|
|
content.append(" />");
|
|
|
|
content.append(" </dependentAssembly>");
|
|
|
|
content.append("</dependency>");
|
|
|
|
content.append("</assembly>");
|
|
|
|
StringsToFile(content,executable() + ".Manifest");
|
|
|
|
} else if (fileExists(executable() + ".Manifest"))
|
|
|
|
QFile::remove(executable() + ".Manifest");
|
2021-09-07 10:28:40 +08:00
|
|
|
|
|
|
|
// create private header file
|
2021-09-07 14:04:48 +08:00
|
|
|
QString hFile = changeFileExt(rcFile, H_EXT);
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.clear();
|
2021-09-10 12:37:02 +08:00
|
|
|
QString def = extractFileName(rcFile);
|
2021-09-07 14:04:48 +08:00
|
|
|
def.replace(".","_");
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append("/* THIS FILE WILL BE OVERWRITTEN BY DEV-C++ */");
|
|
|
|
contents.append("/* DO NOT EDIT ! */");
|
|
|
|
contents.append("");
|
|
|
|
contents.append("#ifndef " + def);
|
|
|
|
contents.append("#define " + def);
|
|
|
|
contents.append("");
|
|
|
|
contents.append("/* VERSION DEFINITIONS */");
|
|
|
|
contents.append("#define VER_STRING\t" +
|
2021-09-07 14:04:48 +08:00
|
|
|
QString("\"%d.%d.%d.%d\"")
|
|
|
|
.arg(mOptions.versionInfo.major)
|
|
|
|
.arg(mOptions.versionInfo.minor)
|
|
|
|
.arg(mOptions.versionInfo.release)
|
|
|
|
.arg(mOptions.versionInfo.build));
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(QString("#define VER_MAJOR\t%1").arg(mOptions.versionInfo.major));
|
|
|
|
contents.append(QString("#define VER_MINOR\t%1").arg(mOptions.versionInfo.minor));
|
|
|
|
contents.append(QString("#define VER_RELEASE\t").arg(mOptions.versionInfo.release));
|
|
|
|
contents.append(QString("#define VER_BUILD\t").arg(mOptions.versionInfo.build));
|
|
|
|
contents.append(QString("#define COMPANY_NAME\t\"%1\"")
|
2021-09-07 14:04:48 +08:00
|
|
|
.arg(mOptions.versionInfo.companyName));
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(QString("#define FILE_VERSION\t\"%1\"")
|
2021-09-07 14:04:48 +08:00
|
|
|
.arg(mOptions.versionInfo.fileVersion));
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(QString("#define FILE_DESCRIPTION\t\"%1\"")
|
2021-09-07 14:04:48 +08:00
|
|
|
.arg(mOptions.versionInfo.fileDescription));
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(QString("#define INTERNAL_NAME\t\"%1\"")
|
2021-09-07 14:04:48 +08:00
|
|
|
.arg(mOptions.versionInfo.internalName));
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(QString("#define LEGAL_COPYRIGHT\t\"%1\"")
|
2021-09-07 14:04:48 +08:00
|
|
|
.arg(mOptions.versionInfo.legalCopyright));
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(QString("#define LEGAL_TRADEMARKS\t\"%1\"")
|
2021-09-07 14:04:48 +08:00
|
|
|
.arg(mOptions.versionInfo.legalTrademarks));
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(QString("#define ORIGINAL_FILENAME\t\"%1\"")
|
2021-09-07 14:04:48 +08:00
|
|
|
.arg(mOptions.versionInfo.originalFilename));
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(QString("#define PRODUCT_NAME\t\"%1\"")
|
2021-09-07 14:04:48 +08:00
|
|
|
.arg(mOptions.versionInfo.productName));
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append(QString("#define PRODUCT_VERSION\t\"%1\"")
|
2021-09-07 14:04:48 +08:00
|
|
|
.arg(mOptions.versionInfo.productVersion));
|
2021-09-07 16:49:35 +08:00
|
|
|
contents.append("");
|
|
|
|
contents.append("#endif /*" + def + "*/");
|
|
|
|
StringsToFile(contents,hFile);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::checkProjectFileForUpdate()
|
|
|
|
{
|
|
|
|
bool cnvt = false;
|
|
|
|
mIniFile->beginGroup("Project");
|
|
|
|
int uCount = mIniFile->value("UnitCount", 0).toInt();
|
|
|
|
mIniFile->endGroup();
|
|
|
|
// check if using old way to store resources and fix it
|
|
|
|
QString oldRes = mIniFile->value("Resources", "").toString();
|
|
|
|
if (!oldRes.isEmpty()) {
|
|
|
|
QFile::copy(mFilename,mFilename+".bak");
|
|
|
|
QStringList sl;
|
|
|
|
sl = oldRes.split(';');
|
|
|
|
for (int i=0;i<sl.count();i++){
|
|
|
|
const QString& s = sl[i];
|
|
|
|
mIniFile->beginGroup(QString("Unit%1").arg(uCount+i));
|
|
|
|
mIniFile->setValue("Filename", s);
|
|
|
|
mIniFile->setValue("Folder", "Resources");
|
|
|
|
mIniFile->setValue("Compile",true);
|
|
|
|
mIniFile->endGroup();
|
|
|
|
}
|
|
|
|
mIniFile->beginGroup("Project");
|
|
|
|
mIniFile->setValue("UnitCount",uCount+sl.count());
|
|
|
|
QString folders = mIniFile->value("Folders","").toString();
|
|
|
|
if (!folders.isEmpty())
|
|
|
|
folders += ",Resources";
|
|
|
|
else
|
|
|
|
folders = "Resources";
|
|
|
|
mIniFile->setValue("Folders",folders);
|
|
|
|
mIniFile->endGroup();
|
|
|
|
}
|
|
|
|
|
|
|
|
mIniFile->beginGroup("Project");
|
|
|
|
mIniFile->remove("Resources");
|
|
|
|
mIniFile->remove("Focused");
|
|
|
|
mIniFile->remove("Order");
|
|
|
|
mIniFile->remove("DebugInfo");
|
|
|
|
mIniFile->remove("ProfileInfo");
|
|
|
|
|
|
|
|
if (cnvt)
|
|
|
|
QMessageBox::information(
|
|
|
|
pMainWindow,
|
|
|
|
tr("Project Updated"),
|
|
|
|
tr("Your project was succesfully updated to a newer file format!")
|
|
|
|
+"<br />"
|
|
|
|
+tr("If something has gone wrong, we kept a backup-file: '%1'...")
|
|
|
|
.arg(mFilename+".bak"),
|
|
|
|
QMessageBox::Ok);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::closeUnit(int index)
|
|
|
|
{
|
|
|
|
PProjectUnit unit = mUnits[index];
|
|
|
|
if (unit->editor()) {
|
|
|
|
saveUnitLayout(unit->editor(),index);
|
|
|
|
pMainWindow->editorList()->forceCloseEditor(unit->editor());
|
|
|
|
unit->setEditor(nullptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::createFolderNodes()
|
|
|
|
{
|
|
|
|
mFolderNodes.clear();
|
|
|
|
for (int idx=0;idx<mFolders.count();idx++) {
|
|
|
|
PFolderNode node = mNode;
|
|
|
|
QString s = mFolders[idx];
|
|
|
|
int i = s.indexOf('/');
|
|
|
|
while (i>=0) {
|
|
|
|
PFolderNode findnode;
|
|
|
|
for (int c=0;c<node->children.count();c++) {
|
|
|
|
if (node->children[c]->text == s.mid(0,i))
|
|
|
|
findnode = node->children[c];
|
|
|
|
}
|
|
|
|
if (!findnode)
|
|
|
|
node = makeNewFileNode(s.mid(0,i),true,node);
|
|
|
|
else
|
|
|
|
node = findnode;
|
|
|
|
node->unitIndex = -1;
|
|
|
|
s.remove(0,i);
|
|
|
|
i = s.indexOf('/');
|
|
|
|
}
|
|
|
|
node = makeNewFileNode(s, true, node);
|
|
|
|
node->unitIndex = -1;
|
|
|
|
mFolderNodes.append(node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::doAutoOpen()
|
|
|
|
{
|
|
|
|
//todo:
|
|
|
|
// case devData.AutoOpen of
|
|
|
|
// 0: begin
|
|
|
|
// for i := 0 to pred(fUnits.Count) do
|
|
|
|
// OpenUnit(i); // Open all
|
|
|
|
// if fUnits.Count > 0 then
|
|
|
|
// fUnits[0].Editor.Activate; // Show first
|
|
|
|
// end;
|
|
|
|
// 1:
|
|
|
|
// if fUnits.Count > 0 then
|
|
|
|
// OpenUnit(0).Activate; // Open and show first
|
|
|
|
// 2:
|
|
|
|
// LoadLayout; // Open previous selection
|
|
|
|
// end;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-09-09 00:15:12 +08:00
|
|
|
bool Project::fileAlreadyExists(const QString &s)
|
|
|
|
{
|
|
|
|
foreach (const PProjectUnit& unit, mUnits) {
|
|
|
|
if (unit->fileName() == s)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
PFolderNode Project::folderNodeFromName(const QString &name)
|
|
|
|
{
|
|
|
|
int index = mFolders.indexOf(name);
|
|
|
|
if (index>=0) {
|
|
|
|
return mFolderNodes[index];
|
|
|
|
}
|
|
|
|
return mNode;
|
|
|
|
}
|
|
|
|
|
2021-09-09 11:47:04 +08:00
|
|
|
QChar Project::getCompilerOption(const QString &optionString)
|
|
|
|
{
|
|
|
|
// Does the option exist?
|
|
|
|
Settings::PCompilerSet compilerSet = pSettings->compilerSets().getSet(mOptions.compilerSet);
|
|
|
|
if (!compilerSet)
|
|
|
|
return '0';
|
|
|
|
int index = compilerSet->findOptionIndex(optionString);
|
|
|
|
if (index>=0 && index<mOptions.compilerOptions.length()) {
|
|
|
|
return mOptions.compilerOptions[index];
|
|
|
|
}
|
|
|
|
return '0';
|
|
|
|
}
|
|
|
|
|
|
|
|
QString Project::getFolderPath(PFolderNode node)
|
|
|
|
{
|
|
|
|
QString result;
|
|
|
|
if (!node)
|
|
|
|
return result;
|
|
|
|
|
|
|
|
if (node->unitIndex>=0) // not a folder
|
|
|
|
return result;
|
|
|
|
|
2021-09-10 10:27:01 +08:00
|
|
|
PFolderNode p = node;
|
2021-09-09 11:47:04 +08:00
|
|
|
while (p && p->unitIndex==-1) {
|
|
|
|
if (!result.isEmpty())
|
|
|
|
result = p->text + "/" + result;
|
2021-09-10 10:27:01 +08:00
|
|
|
p = p->parent.lock();
|
2021-09-09 11:47:04 +08:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Project::getUnitFromString(const QString &s)
|
|
|
|
{
|
|
|
|
return indexInUnits(s);
|
|
|
|
}
|
|
|
|
|
2021-09-09 18:36:54 +08:00
|
|
|
void Project::incrementBuildNumber()
|
|
|
|
{
|
|
|
|
mOptions.versionInfo.build++;
|
|
|
|
mOptions.versionInfo.fileVersion = QString("%1.%2.%3.%3")
|
|
|
|
.arg(mOptions.versionInfo.major)
|
|
|
|
.arg(mOptions.versionInfo.minor)
|
|
|
|
.arg(mOptions.versionInfo.release)
|
|
|
|
.arg(mOptions.versionInfo.build);
|
|
|
|
if (mOptions.versionInfo.syncProduct)
|
|
|
|
mOptions.versionInfo.productVersion = mOptions.versionInfo.fileVersion;
|
|
|
|
setModified(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
QString Project::listUnitStr(const QChar &separator)
|
|
|
|
{
|
|
|
|
QStringList units;
|
|
|
|
foreach (const PProjectUnit& unit, mUnits) {
|
|
|
|
units.append('"'+unit->fileName()+'"');
|
|
|
|
}
|
|
|
|
return units.join(separator);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::loadLayout()
|
|
|
|
{
|
|
|
|
QSettings layIni = QSettings(changeFileExt(filename(), "layout"),QSettings::IniFormat);
|
|
|
|
layIni.beginGroup("Editors");
|
|
|
|
int topLeft = layIni.value("Focused", -1).toInt();
|
|
|
|
//TopRight := layIni.ReadInteger('Editors', 'FocusedRight', -1);
|
|
|
|
QString temp =layIni.value("Order", "").toString();
|
|
|
|
layIni.endGroup();
|
|
|
|
QStringList sl = temp.split(",");
|
|
|
|
|
|
|
|
foreach (const QString& s,sl) {
|
|
|
|
bool ok;
|
|
|
|
int currIdx = s.toInt(&ok);
|
|
|
|
if (ok) {
|
|
|
|
openUnit(currIdx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (topLeft>=0 && topLeft<mUnits.count() && mUnits[topLeft]->editor()) {
|
|
|
|
mUnits[topLeft]->editor()->activate();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-09-09 23:20:00 +08:00
|
|
|
void Project::loadOptions()
|
|
|
|
{
|
|
|
|
mIniFile->beginGroup("Project");
|
|
|
|
mName = mIniFile->value("name", "").toString();
|
|
|
|
mOptions.icon = mIniFile->value("icon", "").toString();
|
|
|
|
mOptions.version = mIniFile->value("Ver", 0).toInt();
|
|
|
|
if (mOptions.version > 0) { // ver > 0 is at least a v5 project
|
|
|
|
if (mOptions.version < 2) {
|
|
|
|
mOptions.version = 2;
|
|
|
|
QMessageBox::information(pMainWindow,
|
|
|
|
tr("Settings need update"),
|
|
|
|
tr("The compiler settings format of Dev-C++ has changed.")
|
|
|
|
+"<BR /><BR />"
|
|
|
|
+tr("Please update your settings at Project >> Project Options >> Compiler and save your project."),
|
|
|
|
QMessageBox::Ok);
|
|
|
|
}
|
|
|
|
|
|
|
|
mOptions.type = static_cast<ProjectType>(mIniFile->value("type", 0).toInt());
|
|
|
|
mOptions.compilerCmd = mIniFile->value("Compiler", "").toString();
|
|
|
|
mOptions.cppCompilerCmd = mIniFile->value("CppCompiler", "").toString();
|
2021-09-10 10:27:01 +08:00
|
|
|
mOptions.linkerCmd = mIniFile->value("Linker", "").toString();
|
|
|
|
mOptions.objFiles = mIniFile->value("ObjFiles", "").toString().split(";");
|
|
|
|
mOptions.libs = mIniFile->value("Libs", "").toString().split(";");
|
|
|
|
mOptions.includes = mIniFile->value("Includes", "").toString().split(";");
|
|
|
|
mOptions.privateResource = mIniFile->value("PrivateResource", "").toString();
|
|
|
|
mOptions.resourceIncludes = mIniFile->value("ResourceIncludes", "").toString().split(";");
|
|
|
|
mOptions.makeIncludes = mIniFile->value("MakeIncludes","").toString().split(";");
|
|
|
|
mOptions.useGPP = mIniFile->value("IsCpp", false).toBool();
|
|
|
|
mOptions.exeOutput = mIniFile->value("ExeOutput", "").toString();
|
|
|
|
mOptions.objectOutput = mIniFile->value("ObjectOutput", "").toString();
|
|
|
|
mOptions.logOutput = mIniFile->value("LogOutput","").toString();
|
|
|
|
mOptions.logOutputEnabled = mIniFile->value("LogOutputEnabled", false).toBool();
|
|
|
|
mOptions.overrideOutput = mIniFile->value("OverrideOutput", false).toBool();
|
|
|
|
mOptions.overridenOutput = mIniFile->value("OverrideOutputName","").toString();
|
|
|
|
mOptions.hostApplication = mIniFile->value("HostApplication","").toString();
|
|
|
|
mOptions.useCustomMakefile = mIniFile->value("UseCustomMakefile", false).toBool();
|
|
|
|
mOptions.customMakefile = mIniFile->value("CustomMakefile","").toString();
|
|
|
|
mOptions.usePrecompiledHeader = mIniFile->value("UsePrecompiledHeader", false).toBool();
|
|
|
|
mOptions.precompiledHeader = mIniFile->value("PrecompiledHeader","").toString();
|
|
|
|
mOptions.cmdLineArgs = mIniFile->value("CommandLine","").toString();
|
|
|
|
mFolders = mIniFile->value("Folders","").toString().split(";");
|
|
|
|
mOptions.includeVersionInfo = mIniFile->value("IncludeVersionInfo", false).toBool();
|
|
|
|
mOptions.supportXPThemes = mIniFile->value("SupportXPThemes", false).toBool();
|
|
|
|
mOptions.compilerSet = mIniFile->value("CompilerSet", pSettings->compilerSets().defaultIndex()).toInt();
|
|
|
|
|
|
|
|
if (mOptions.compilerSet >= pSettings->compilerSets().size()
|
|
|
|
|| mOptions.compilerSet < 0) { // TODO: change from indices to names
|
|
|
|
QMessageBox::critical(
|
|
|
|
pMainWindow,
|
|
|
|
tr("Compiler not found"),
|
|
|
|
tr("The compiler set you have selected for this project, no longer exists.")
|
|
|
|
+"<BR />"
|
|
|
|
+tr("It will be substituted by the global compiler set."),
|
|
|
|
QMessageBox::Ok
|
|
|
|
);
|
|
|
|
mOptions.compilerSet = pSettings->compilerSets().defaultIndex();
|
|
|
|
setModified(true);
|
|
|
|
}
|
|
|
|
mOptions.compilerOptions = mIniFile->value("CompilerSettings","").toString();
|
|
|
|
mOptions.staticLink = mIniFile->value("StaticLink", true).toBool();
|
|
|
|
mOptions.addCharset = mIniFile->value("AddCharset", true).toBool();
|
|
|
|
mOptions.useUTF8 = mIniFile->value("UseUTF8", false).toBool();
|
2021-09-10 15:03:47 +08:00
|
|
|
mOptions.encoding = mIniFile->value("Encoding", ENCODING_SYSTEM_DEFAULT).toString();
|
2021-09-10 10:27:01 +08:00
|
|
|
mOptions.versionInfo.major = mIniFile->value("Major", 0).toInt();
|
|
|
|
mOptions.versionInfo.minor = mIniFile->value("Minor", 1).toInt();
|
|
|
|
mOptions.versionInfo.release = mIniFile->value("Release", 1).toInt();
|
|
|
|
mOptions.versionInfo.build = mIniFile->value("Build", 1).toInt();
|
|
|
|
mOptions.versionInfo.languageID = mIniFile->value("LanguageID", 0x0409).toInt();
|
|
|
|
mOptions.versionInfo.charsetID = mIniFile->value("CharsetID", 0x04E4).toInt();
|
|
|
|
mOptions.versionInfo.companyName = mIniFile->value("CompanyName","").toString();
|
|
|
|
mOptions.versionInfo.fileVersion = mIniFile->value("FileVersion", "0.1").toString();
|
|
|
|
mOptions.versionInfo.fileDescription = mIniFile->value("FileDescription",
|
|
|
|
tr("Developed using the Red Panda Dev-C++ IDE")).toString();
|
|
|
|
mOptions.versionInfo.internalName = mIniFile->value("InternalName","").toString();
|
|
|
|
mOptions.versionInfo.legalCopyright = mIniFile->value("LegalCopyright","").toString();
|
|
|
|
mOptions.versionInfo.legalTrademarks = mIniFile->value("LegalTrademarks","").toString();
|
|
|
|
mOptions.versionInfo.originalFilename = mIniFile->value("OriginalFilename",
|
2021-09-10 12:37:02 +08:00
|
|
|
extractFileName(executable())).toString();
|
2021-09-10 10:27:01 +08:00
|
|
|
mOptions.versionInfo.productName = mIniFile->value("ProductName", mName).toString();
|
|
|
|
mOptions.versionInfo.productVersion = mIniFile->value("ProductVersion", "0.1.1.1").toString();
|
|
|
|
mOptions.versionInfo.autoIncBuildNr = mIniFile->value("AutoIncBuildNr", false).toBool();
|
|
|
|
mOptions.versionInfo.syncProduct = mIniFile->value("SyncProduct", false).toBool();
|
|
|
|
} else { // dev-c < 4
|
|
|
|
mOptions.version = -1;
|
|
|
|
if (!mIniFile->value("NoConsole", true).toBool())
|
|
|
|
mOptions.type = ProjectType::Console;
|
|
|
|
else if (mIniFile->value("IsDLL", false).toBool())
|
|
|
|
mOptions.type = ProjectType::DynamicLib;
|
2021-09-09 23:20:00 +08:00
|
|
|
else
|
2021-09-10 10:27:01 +08:00
|
|
|
mOptions.type = ProjectType::GUI;
|
|
|
|
|
|
|
|
mOptions.privateResource = mIniFile->value("PrivateResource","").toString();
|
|
|
|
mOptions.resourceIncludes = mIniFile->value("ResourceIncludes","").toString().split(";");
|
|
|
|
mOptions.objFiles = mIniFile->value("ObjFiles","").toString().split(";");
|
|
|
|
mOptions.includes = mIniFile->value("IncludeDirs","").toString().split(";");
|
|
|
|
mOptions.compilerCmd = mIniFile->value("CompilerOptions","").toString();
|
|
|
|
mOptions.useGPP = mIniFile->value("Use_GPP", false).toBool();
|
|
|
|
mOptions.exeOutput = mIniFile->value("ExeOutput","").toString();
|
|
|
|
mOptions.objectOutput = mIniFile->value("ObjectOutput","").toString();
|
|
|
|
mOptions.overrideOutput = mIniFile->value("OverrideOutput", false).toBool();
|
|
|
|
mOptions.overridenOutput = mIniFile->value("OverrideOutputName","").toString();
|
|
|
|
mOptions.hostApplication = mIniFile->value("HostApplication","").toString();
|
|
|
|
}
|
2021-09-09 23:20:00 +08:00
|
|
|
}
|
|
|
|
|
2021-09-10 15:03:47 +08:00
|
|
|
void Project::loadUnitLayout(Editor *e, int index)
|
|
|
|
{
|
|
|
|
if (!e)
|
|
|
|
return;
|
2021-09-10 21:37:52 +08:00
|
|
|
QSettings layIni(changeFileExt(filename(), "layout"), QSettings::IniFormat);
|
2021-09-10 15:03:47 +08:00
|
|
|
layIni.beginGroup(QString("Editor_%1").arg(index));
|
|
|
|
e->setCaretY(layIni.value("CursorRow",1).toInt());
|
|
|
|
e->setCaretX(layIni.value("CursorCol",1).toInt());
|
|
|
|
e->setTopLine(layIni.value("TopLine",1).toInt());
|
|
|
|
e->setLeftChar(layIni.value("LeftChar",1).toInt());
|
|
|
|
layIni.endGroup();
|
|
|
|
}
|
|
|
|
|
2021-09-07 16:49:35 +08:00
|
|
|
PCppParser Project::cppParser()
|
|
|
|
{
|
|
|
|
return mParser;
|
2021-09-07 00:32:16 +08:00
|
|
|
}
|
2021-09-06 12:58:29 +08:00
|
|
|
|
2021-09-07 00:32:16 +08:00
|
|
|
void Project::sortUnitsByPriority()
|
|
|
|
{
|
|
|
|
std::sort(mUnits.begin(),mUnits.end(),[](const PProjectUnit& u1, const PProjectUnit& u2)->bool{
|
|
|
|
return (u1->priority()>u2->priority());
|
|
|
|
});
|
|
|
|
}
|
2021-09-06 12:58:29 +08:00
|
|
|
|
2021-09-09 11:47:04 +08:00
|
|
|
int Project::indexInUnits(const QString &fileName) const
|
|
|
|
{
|
|
|
|
QDir dir(directory());
|
|
|
|
for (int i=0;i<mUnits.count();i++) {
|
|
|
|
PProjectUnit unit = mUnits[i];
|
|
|
|
if (dir.absoluteFilePath(fileName) == dir.absoluteFilePath(unit->fileName()))
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Project::indexInUnits(const Editor *editor) const
|
|
|
|
{
|
|
|
|
if (!editor)
|
|
|
|
return -1;
|
|
|
|
return indexInUnits(editor->filename());
|
|
|
|
}
|
|
|
|
|
2021-09-10 21:37:52 +08:00
|
|
|
void Project::removeFolderRecurse(PFolderNode node)
|
|
|
|
{
|
|
|
|
if (!node)
|
|
|
|
return ;
|
|
|
|
// Recursively remove folders
|
|
|
|
for (int i=node->children.count()-1;i>=0;i++) {
|
|
|
|
PFolderNode childNode = node->children[i];
|
|
|
|
// Remove folder inside folder
|
|
|
|
if (childNode->unitIndex<0 && childNode->level>0) {
|
|
|
|
removeFolderRecurse(childNode);
|
|
|
|
// Or remove editors at this level
|
|
|
|
} else if (childNode->unitIndex >= 0 && childNode->level > 0) {
|
|
|
|
// Remove editor in folder from project
|
|
|
|
int editorIndex = childNode->unitIndex;
|
|
|
|
if (!removeEditor(editorIndex,true))
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PFolderNode parent = node->parent.lock();
|
|
|
|
if (parent) {
|
|
|
|
parent->children.removeAll(node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-10 15:03:47 +08:00
|
|
|
const ProjectOptions &Project::options() const
|
|
|
|
{
|
|
|
|
return mOptions;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::setOptions(const ProjectOptions &newOptions)
|
|
|
|
{
|
|
|
|
mOptions = newOptions;
|
|
|
|
}
|
|
|
|
|
2021-09-10 12:37:02 +08:00
|
|
|
const PFolderNode &Project::node() const
|
|
|
|
{
|
|
|
|
return mNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::setNode(const PFolderNode &newNode)
|
|
|
|
{
|
|
|
|
mNode = newNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QString &Project::name() const
|
|
|
|
{
|
|
|
|
return mName;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::setName(const QString &newName)
|
|
|
|
{
|
|
|
|
mName = newName;
|
|
|
|
}
|
|
|
|
|
2021-09-09 18:36:54 +08:00
|
|
|
std::shared_ptr<QSettings> &Project::iniFile()
|
|
|
|
{
|
|
|
|
return mIniFile;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Project::setIniFile(const std::shared_ptr<QSettings> &newIniFile)
|
|
|
|
{
|
|
|
|
mIniFile = newIniFile;
|
|
|
|
}
|
|
|
|
|
2021-09-09 00:15:12 +08:00
|
|
|
const QString &Project::filename() const
|
|
|
|
{
|
|
|
|
return mFilename;
|
|
|
|
}
|
|
|
|
|
2021-09-07 00:32:16 +08:00
|
|
|
ProjectUnit::ProjectUnit(Project* parent)
|
|
|
|
{
|
|
|
|
mEditor = nullptr;
|
|
|
|
mNode = nullptr;
|
|
|
|
mParent = parent;
|
2021-09-06 08:45:53 +08:00
|
|
|
}
|
|
|
|
|
2021-09-07 00:32:16 +08:00
|
|
|
Project *ProjectUnit::parent() const
|
2021-09-05 23:45:05 +08:00
|
|
|
{
|
|
|
|
return mParent;
|
|
|
|
}
|
|
|
|
|
2021-09-07 00:32:16 +08:00
|
|
|
void ProjectUnit::setParent(Project* newParent)
|
2021-09-05 23:45:05 +08:00
|
|
|
{
|
|
|
|
mParent = newParent;
|
|
|
|
}
|
|
|
|
|
|
|
|
Editor *ProjectUnit::editor() const
|
|
|
|
{
|
|
|
|
return mEditor;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectUnit::setEditor(Editor *newEditor)
|
|
|
|
{
|
|
|
|
mEditor = newEditor;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QString &ProjectUnit::fileName() const
|
|
|
|
{
|
|
|
|
return mFileName;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectUnit::setFileName(const QString &newFileName)
|
|
|
|
{
|
|
|
|
mFileName = newFileName;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectUnit::isNew() const
|
|
|
|
{
|
|
|
|
return mNew;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectUnit::setNew(bool newNew)
|
|
|
|
{
|
|
|
|
mNew = newNew;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QString &ProjectUnit::folder() const
|
|
|
|
{
|
|
|
|
return mFolder;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectUnit::setFolder(const QString &newFolder)
|
|
|
|
{
|
|
|
|
mFolder = newFolder;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectUnit::compile() const
|
|
|
|
{
|
|
|
|
return mCompile;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectUnit::setCompile(bool newCompile)
|
|
|
|
{
|
|
|
|
mCompile = newCompile;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectUnit::compileCpp() const
|
|
|
|
{
|
|
|
|
return mCompileCpp;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectUnit::setCompileCpp(bool newCompileCpp)
|
|
|
|
{
|
|
|
|
mCompileCpp = newCompileCpp;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectUnit::overrideBuildCmd() const
|
|
|
|
{
|
|
|
|
return mOverrideBuildCmd;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectUnit::setOverrideBuildCmd(bool newOverrideBuildCmd)
|
|
|
|
{
|
|
|
|
mOverrideBuildCmd = newOverrideBuildCmd;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QString &ProjectUnit::buildCmd() const
|
|
|
|
{
|
|
|
|
return mBuildCmd;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectUnit::setBuildCmd(const QString &newBuildCmd)
|
|
|
|
{
|
|
|
|
mBuildCmd = newBuildCmd;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectUnit::link() const
|
|
|
|
{
|
|
|
|
return mLink;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectUnit::setLink(bool newLink)
|
|
|
|
{
|
|
|
|
mLink = newLink;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ProjectUnit::priority() const
|
|
|
|
{
|
|
|
|
return mPriority;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectUnit::setPriority(int newPriority)
|
|
|
|
{
|
|
|
|
mPriority = newPriority;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectUnit::detectEncoding() const
|
|
|
|
{
|
|
|
|
return mDetectEncoding;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectUnit::setDetectEncoding(bool newDetectEncoding)
|
|
|
|
{
|
|
|
|
mDetectEncoding = newDetectEncoding;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QByteArray &ProjectUnit::encoding() const
|
|
|
|
{
|
|
|
|
return mEncoding;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectUnit::setEncoding(const QByteArray &newEncoding)
|
|
|
|
{
|
|
|
|
mEncoding = newEncoding;
|
|
|
|
}
|
|
|
|
|
2021-09-06 12:58:29 +08:00
|
|
|
bool ProjectUnit::modified() const
|
2021-09-05 23:45:05 +08:00
|
|
|
{
|
|
|
|
if (mEditor) {
|
|
|
|
return mEditor->modified();
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectUnit::setModified(bool value)
|
|
|
|
{
|
|
|
|
// Mark the change in the coupled editor
|
|
|
|
if (mEditor) {
|
|
|
|
return mEditor->setModified(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If modified is set to true, mark project as modified too
|
|
|
|
if (value) {
|
2021-09-07 10:28:40 +08:00
|
|
|
mParent->setModified(true);
|
2021-09-05 23:45:05 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProjectUnit::save()
|
|
|
|
{
|
|
|
|
bool previous=pMainWindow->fileSystemWatcher()->blockSignals(true);
|
|
|
|
auto action = finally([&previous](){
|
|
|
|
pMainWindow->fileSystemWatcher()->blockSignals(previous);
|
|
|
|
});
|
|
|
|
bool result=true;
|
2021-09-07 10:28:40 +08:00
|
|
|
if (!mEditor && !fileExists(mFileName)) {
|
2021-09-05 23:45:05 +08:00
|
|
|
// file is neither open, nor saved
|
|
|
|
QStringList temp;
|
|
|
|
StringsToFile(temp,mFileName);
|
|
|
|
} else if (mEditor and modified()) {
|
|
|
|
result = mEditor->save();
|
|
|
|
}
|
2021-09-07 00:32:16 +08:00
|
|
|
if (mNode) {
|
2021-09-10 12:37:02 +08:00
|
|
|
mNode->text = extractFileName(mFileName);
|
2021-09-07 00:32:16 +08:00
|
|
|
}
|
2021-09-05 23:45:05 +08:00
|
|
|
return result;
|
|
|
|
}
|
2021-09-07 10:28:40 +08:00
|
|
|
|
|
|
|
PFolderNode &ProjectUnit::node()
|
|
|
|
{
|
|
|
|
return mNode;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectUnit::setNode(const PFolderNode &newNode)
|
|
|
|
{
|
|
|
|
mNode = newNode;
|
|
|
|
}
|