- fix: gliches in UI's left panel in some OS

- fix: correctly restore project layout when reopen it
  - fix: correctly handle rename unit
  - refactor: use filename as the primary key for project unit
This commit is contained in:
Roy Qu 2022-10-08 23:30:30 +08:00
parent 592d6bba32
commit 1e5a130def
9 changed files with 287 additions and 273 deletions

View File

@ -1,7 +1,9 @@
Red Panda C++ Version 1.5 Red Panda C++ Version 1.5
- fix: project files that lies in project include folder is wrongly openned in Read-only mode - fix: project files that lies in project include folder is wrongly openned in Read-only mode
- enhancement: add/new/remove project files won't rebuild project tree - enhancement: add/new/remove/rename project files won't rebuild project tree
- fix: gliches in UI's left panel in some OS
- fix: correctly restore project layout when reopen it
Red Panda C++ Version 1.4 Red Panda C++ Version 1.4

View File

@ -336,8 +336,8 @@ bool Editor::saveAs(const QString &name, bool fromProject){
} }
// Update project information // Update project information
if (mInProject && pMainWindow->project() && !fromProject) { if (mInProject && pMainWindow->project() && !fromProject) {
int unitId = pMainWindow->project()->findUnitId(newName); PProjectUnit unit = pMainWindow->project()->findUnit(newName);
if (unitId<0) { if (!unit) {
mInProject = false; mInProject = false;
} }
} }

View File

@ -169,10 +169,8 @@ bool EditorList::closeEditor(Editor* editor, bool transferFocus, bool force) {
// } // }
if (editor->inProject() && pMainWindow->project()) { if (editor->inProject() && pMainWindow->project()) {
int unitId = pMainWindow->project()->findUnitId(editor); PProjectUnit unit = pMainWindow->project()->findUnit(editor);
if (unitId>=0) { pMainWindow->project()->closeUnit(unit);
pMainWindow->project()->closeUnit(unitId);
}
} else { } else {
if (pSettings->history().addToOpenedFiles(editor->filename())) { if (pSettings->history().addToOpenedFiles(editor->filename())) {
pMainWindow->rebuildOpenedFileHisotryMenu(); pMainWindow->rebuildOpenedFileHisotryMenu();

View File

@ -2224,6 +2224,10 @@ void MainWindow::loadLastOpens()
QByteArray encoding = unit ? unit->encoding() : QByteArray encoding = unit ? unit->encoding() :
(pSettings->editor().autoDetectFileEncoding()? ENCODING_AUTO_DETECT : pSettings->editor().defaultEncoding()); (pSettings->editor().autoDetectFileEncoding()? ENCODING_AUTO_DETECT : pSettings->editor().defaultEncoding());
Editor * editor = mEditorList->newEditor(editorFilename, encoding, inProject,false,page); Editor * editor = mEditorList->newEditor(editorFilename, encoding, inProject,false,page);
if (inProject && editor) {
mProject->loadUnitLayout(editor);
}
// if (mProject) { // if (mProject) {
// mProject->associateEditorToUnit(editor,unit); // mProject->associateEditorToUnit(editor,unit);
// } // }
@ -2943,15 +2947,13 @@ void MainWindow::onProjectViewContextMenu(const QPoint &pos)
bool onRoot = false; bool onRoot = false;
bool folderEmpty = false; bool folderEmpty = false;
bool multiSelection = ui->projectView->selectionModel()->selectedRows().count()>1; bool multiSelection = ui->projectView->selectionModel()->selectedRows().count()>1;
int unitIndex = -1;
QModelIndex current = mProjectProxyModel->mapToSource(ui->projectView->selectionModel()->currentIndex()); QModelIndex current = mProjectProxyModel->mapToSource(ui->projectView->selectionModel()->currentIndex());
if (current.isValid() && mProject) { if (current.isValid() && mProject) {
ProjectModelNode * node = static_cast<ProjectModelNode*>(current.internalPointer()); ProjectModelNode * node = static_cast<ProjectModelNode*>(current.internalPointer());
PProjectModelNode pNode = mProject->pointerToNode(node); PProjectModelNode pNode = mProject->pointerToNode(node);
if (pNode) { if (pNode) {
unitIndex = pNode->unitIndex; onFolder = (!pNode->isUnit);
onFolder = (unitIndex<0); onUnit = (pNode->isUnit);
onUnit = (unitIndex >= 0);
onRoot = false; onRoot = false;
if (onFolder && !onRoot) { if (onFolder && !onRoot) {
folderEmpty = pNode->children.isEmpty(); folderEmpty = pNode->children.isEmpty();
@ -3022,11 +3024,11 @@ void MainWindow::onProjectViewContextMenu(const QPoint &pos)
} }
QModelIndex realIndex = mProjectProxyModel->mapToSource(index); QModelIndex realIndex = mProjectProxyModel->mapToSource(index);
ProjectModelNode * node = static_cast<ProjectModelNode*>(realIndex.internalPointer()); ProjectModelNode * node = static_cast<ProjectModelNode*>(realIndex.internalPointer());
if (!node || node->unitIndex<0) { if (!node || !node->isUnit) {
shouldAdd=false; shouldAdd=false;
break; break;
} }
PProjectUnit pUnit=mProject->findUnitById(node->unitIndex); PProjectUnit pUnit=node->pUnit.lock();
if (mProject->model()->iconProvider()->VCSRepository()->isFileInRepository( if (mProject->model()->iconProvider()->VCSRepository()->isFileInRepository(
pUnit->fileName() pUnit->fileName()
) )
@ -3893,7 +3895,7 @@ void MainWindow::onProjectRemoveFolder()
PProjectModelNode folderNode = mProject->pointerToNode(node); PProjectModelNode folderNode = mProject->pointerToNode(node);
if (!folderNode) if (!folderNode)
return; return;
if (folderNode->unitIndex>=0) if (folderNode->isUnit)
return; return;
mProject->removeFolder(folderNode); mProject->removeFolder(folderNode);
mProject->saveOptions(); mProject->saveOptions();
@ -3919,7 +3921,7 @@ void MainWindow::onProjectAddFolder()
PProjectModelNode folderNode = mProject->pointerToNode(node); PProjectModelNode folderNode = mProject->pointerToNode(node);
if (!folderNode) if (!folderNode)
folderNode = mProject->rootNode(); folderNode = mProject->rootNode();
if (folderNode->unitIndex>=0) if (folderNode->isUnit)
return; return;
QString s=tr("New folder"); QString s=tr("New folder");
int i=1; int i=1;
@ -4267,6 +4269,7 @@ void MainWindow::closeProject(bool refreshEditor)
auto action3 = finally([this]{ auto action3 = finally([this]{
mEditorList->endUpdate(); mEditorList->endUpdate();
}); });
mProject->closeAllUnits();
mProject.reset(); mProject.reset();
if (!mQuitting && refreshEditor) { if (!mQuitting && refreshEditor) {
@ -4294,9 +4297,8 @@ void MainWindow::updateProjectView()
if (mProjectProxyModel->sourceModel()!=mProject->model()) { if (mProjectProxyModel->sourceModel()!=mProject->model()) {
mProjectProxyModel->setSourceModel(mProject->model()); mProjectProxyModel->setSourceModel(mProject->model());
mProjectProxyModel->sort(0); mProjectProxyModel->sort(0);
// connect(mProject->model(), &ProjectModel::dataChanged, connect(mProject.get(), &Project::nodeRenamed,
// this, &MainWindow::invalidateProjectProxyModel); this, &MainWindow::onProjectViewNodeRenamed);
// connect(mProject->model(), &ProjectModel::rowsRemoved,
// this, &MainWindow::invalidateProjectProxyModel); // this, &MainWindow::invalidateProjectProxyModel);
// connect(mProject->model(), &ProjectModel::rowsInserted, // connect(mProject->model(), &ProjectModel::rowsInserted,
// this, &MainWindow::invalidateProjectProxyModel); // this, &MainWindow::invalidateProjectProxyModel);
@ -5760,8 +5762,9 @@ void MainWindow::on_projectView_doubleClicked(const QModelIndex &index)
ProjectModelNode * node = static_cast<ProjectModelNode*>(sourceIndex.internalPointer()); ProjectModelNode * node = static_cast<ProjectModelNode*>(sourceIndex.internalPointer());
if (!node) if (!node)
return; return;
if (node->unitIndex>=0) { if (node->isUnit) {
mProject->openUnit(node->unitIndex); PProjectUnit unit = node->pUnit.lock();
mProject->openUnit(unit);
} }
} }
@ -5967,7 +5970,8 @@ void MainWindow::on_actionRemove_from_project_triggered()
PProjectModelNode folderNode = mProject->pointerToNode(node); PProjectModelNode folderNode = mProject->pointerToNode(node);
if (!folderNode) if (!folderNode)
continue; continue;
mProject->removeUnit(folderNode->unitIndex, true, removeFile); PProjectUnit unit = folderNode->pUnit.lock();
mProject->removeUnit(unit, true, removeFile);
}; };
ui->projectView->selectionModel()->clearSelection(); ui->projectView->selectionModel()->clearSelection();
mProject->saveAll(); mProject->saveAll();
@ -6159,7 +6163,7 @@ void MainWindow::newProjectUnitFile()
} }
PProjectModelNode pNode = mProject->pointerToNode(node); PProjectModelNode pNode = mProject->pointerToNode(node);
while (pNode && pNode->unitIndex>0) { while (pNode && pNode->isUnit) {
pNode = pNode->parent.lock(); pNode = pNode->parent.lock();
} }
@ -6235,13 +6239,8 @@ void MainWindow::newProjectUnitFile()
setProjectViewCurrentUnit(newUnit); setProjectViewCurrentUnit(newUnit);
// mProject->rebuildNodes();
mProject->saveAll(); mProject->saveAll();
// updateProjectView(); Editor * editor = mProject->openUnit(newUnit, false);
// idx = newUnit->id;
Editor * editor = mProject->openUnit(newUnit->id(), false);
//editor->setUseCppSyntax(mProject->options().useGPP);
//editor->setModified(true);
if (editor) if (editor)
editor->activate(); editor->activate();
QString branch; QString branch;
@ -6311,6 +6310,11 @@ void MainWindow::setProjectViewCurrentUnit(std::shared_ptr<ProjectUnit> unit) {
} }
} }
void MainWindow::onProjectViewNodeRenamed()
{
updateProjectView();
}
void MainWindow::setProjectViewCurrentNode(PProjectModelNode node) void MainWindow::setProjectViewCurrentNode(PProjectModelNode node)
{ {
if (node) { if (node) {
@ -7576,8 +7580,8 @@ void MainWindow::on_actionGit_Add_Files_triggered()
PProjectModelNode folderNode = mProject->pointerToNode(node); PProjectModelNode folderNode = mProject->pointerToNode(node);
if (!folderNode) if (!folderNode)
continue; continue;
if (folderNode->unitIndex>=0) { if (folderNode->isUnit) {
PProjectUnit unit = mProject->findUnitById(folderNode->unitIndex); PProjectUnit unit = folderNode->pUnit.lock();
QFileInfo info(unit->fileName()); QFileInfo info(unit->fileName());
QString output; QString output;
vcsManager.add(info.absolutePath(),info.fileName(),output); vcsManager.add(info.absolutePath(),info.fileName(),output);

View File

@ -276,6 +276,7 @@ private:
void setProjectViewCurrentUnit(std::shared_ptr<ProjectUnit> unit); void setProjectViewCurrentUnit(std::shared_ptr<ProjectUnit> unit);
private slots: private slots:
void onProjectViewNodeRenamed();
void setDockExplorerToArea(const Qt::DockWidgetArea &area); void setDockExplorerToArea(const Qt::DockWidgetArea &area);
void setDockMessagesToArea(const Qt::DockWidgetArea &area); void setDockMessagesToArea(const Qt::DockWidgetArea &area);
void updateVCSActions(); void updateVCSActions();

View File

@ -473,12 +473,15 @@
<enum>QTabWidget::West</enum> <enum>QTabWidget::West</enum>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>1</number> <number>4</number>
</property> </property>
<property name="usesScrollButtons"> <property name="usesScrollButtons">
<bool>true</bool> <bool>true</bool>
</property> </property>
<widget class="QWidget" name="tabFiles"> <widget class="QWidget" name="tabFiles">
<property name="autoFillBackground">
<bool>true</bool>
</property>
<attribute name="icon"> <attribute name="icon">
<iconset resource="icons.qrc"> <iconset resource="icons.qrc">
<normaloff>:/icons/images/newlook24/018-copy.png</normaloff>:/icons/images/newlook24/018-copy.png</iconset> <normaloff>:/icons/images/newlook24/018-copy.png</normaloff>:/icons/images/newlook24/018-copy.png</iconset>
@ -561,6 +564,9 @@
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tabProject"> <widget class="QWidget" name="tabProject">
<property name="autoFillBackground">
<bool>true</bool>
</property>
<attribute name="icon"> <attribute name="icon">
<iconset resource="icons.qrc"> <iconset resource="icons.qrc">
<normaloff>:/icons/images/newlook24/049-newproj.png</normaloff>:/icons/images/newlook24/049-newproj.png</iconset> <normaloff>:/icons/images/newlook24/049-newproj.png</normaloff>:/icons/images/newlook24/049-newproj.png</iconset>
@ -612,6 +618,9 @@
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tabWatch"> <widget class="QWidget" name="tabWatch">
<property name="autoFillBackground">
<bool>true</bool>
</property>
<attribute name="icon"> <attribute name="icon">
<iconset resource="icons.qrc"> <iconset resource="icons.qrc">
<normaloff>:/icons/images/newlook24/088-watch.png</normaloff>:/icons/images/newlook24/088-watch.png</iconset> <normaloff>:/icons/images/newlook24/088-watch.png</normaloff>:/icons/images/newlook24/088-watch.png</iconset>
@ -654,6 +663,9 @@
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tabStructure"> <widget class="QWidget" name="tabStructure">
<property name="autoFillBackground">
<bool>true</bool>
</property>
<attribute name="icon"> <attribute name="icon">
<iconset resource="icons.qrc"> <iconset resource="icons.qrc">
<normaloff>:/icons/images/newlook24/087-update.png</normaloff>:/icons/images/newlook24/087-update.png</iconset> <normaloff>:/icons/images/newlook24/087-update.png</normaloff>:/icons/images/newlook24/087-update.png</iconset>
@ -693,6 +705,9 @@
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tabProblemSet"> <widget class="QWidget" name="tabProblemSet">
<property name="autoFillBackground">
<bool>true</bool>
</property>
<attribute name="icon"> <attribute name="icon">
<iconset resource="icons.qrc"> <iconset resource="icons.qrc">
<normaloff>:/icons/images/newlook24/014-compopt.png</normaloff>:/icons/images/newlook24/014-compopt.png</iconset> <normaloff>:/icons/images/newlook24/014-compopt.png</normaloff>:/icons/images/newlook24/014-compopt.png</iconset>

View File

@ -36,6 +36,9 @@
#include <QDirIterator> #include <QDirIterator>
#include <QMimeDatabase> #include <QMimeDatabase>
#include <QDesktopServices> #include <QDesktopServices>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include "customfileiconprovider.h" #include "customfileiconprovider.h"
#include <QMimeData> #include <QMimeData>
#include "settings.h" #include "settings.h"
@ -193,22 +196,19 @@ void Project::open()
newUnit->setEncoding(ENCODING_AUTO_DETECT); newUnit->setEncoding(ENCODING_AUTO_DETECT);
} }
newUnit->setNew(false); newUnit->setNew(false);
newUnit->setParent(this);
PProjectModelNode parentNode; PProjectModelNode parentNode;
if (mOptions.modelType==ProjectModelType::FileSystem) { if (mOptions.modelType==ProjectModelType::FileSystem) {
parentNode = getParentFileSystemFolderNode(newUnit->fileName()); parentNode = getParentFileSystemFolderNode(newUnit->fileName());
} else { } else {
parentNode = getCustomeFolderNodeFromName(newUnit->folder()); parentNode = getCustomeFolderNodeFromName(newUnit->folder());
} }
PProjectModelNode node = makeNewFileNode(extractFileName(newUnit->fileName()), PProjectModelNode node = makeNewFileNode(newUnit,
newUnit->id(),
newUnit->priority(), newUnit->priority(),
parentNode parentNode
); );
newUnit->setNode(node); newUnit->setNode(node);
mUnits.insert(newUnit->id(),newUnit); mUnits.insert(newUnit->fileName(),newUnit);
} }
//rebuildNodes();
} }
void Project::setFileName(QString value) void Project::setFileName(QString value)
@ -242,7 +242,7 @@ PProjectModelNode Project::makeNewFolderNode(
if (newParent) { if (newParent) {
node->level = newParent->level+1; node->level = newParent->level+1;
} }
node->unitIndex = -1; node->isUnit=false;
node->priority = priority; node->priority = priority;
node->folderNodeType = nodeType; node->folderNodeType = nodeType;
QModelIndex parentIndex=mModel.getNodeIndex(newParent.get()); QModelIndex parentIndex=mModel.getNodeIndex(newParent.get());
@ -251,18 +251,19 @@ PProjectModelNode Project::makeNewFolderNode(
return node; return node;
} }
PProjectModelNode Project::makeNewFileNode(const QString &fileName, int unitId,int priority, PProjectModelNode newParent) PProjectModelNode Project::makeNewFileNode(PProjectUnit unit,int priority, PProjectModelNode newParent)
{ {
PProjectModelNode node = std::make_shared<ProjectModelNode>(); PProjectModelNode node = std::make_shared<ProjectModelNode>();
if (!newParent) { if (!newParent) {
newParent = mRootNode; newParent = mRootNode;
} }
node->parent = newParent; node->parent = newParent;
node->text = fileName; node->text = extractFileName(unit->fileName());
if (newParent) { if (newParent) {
node->level = newParent->level+1; node->level = newParent->level+1;
} }
node->unitIndex = unitId; node->isUnit = true;
node->pUnit = unit;
node->priority = priority; node->priority = priority;
node->folderNodeType = ProjectModelNodeType::File; node->folderNodeType = ProjectModelNodeType::File;
@ -277,7 +278,7 @@ PProjectModelNode Project::makeProjectNode()
PProjectModelNode node = std::make_shared<ProjectModelNode>(); PProjectModelNode node = std::make_shared<ProjectModelNode>();
node->text = mName; node->text = mName;
node->level = 0; node->level = 0;
node->unitIndex = -1; node->isUnit = false;
node->folderNodeType = ProjectModelNodeType::Folder; node->folderNodeType = ProjectModelNodeType::Folder;
return node; return node;
} }
@ -290,7 +291,7 @@ PProjectUnit Project::newUnit(PProjectModelNode parentNode, const QString& custo
if (!parentNode) if (!parentNode)
parentNode = mRootNode; // project root node parentNode = mRootNode; // project root node
if (parentNode->unitIndex>=0) { //it's a file if (parentNode->isUnit) { //it's a file
parentNode = mRootNode; parentNode = mRootNode;
} }
QString s; QString s;
@ -313,11 +314,9 @@ PProjectUnit Project::newUnit(PProjectModelNode parentNode, const QString& custo
newUnit->setFileName(s); newUnit->setFileName(s);
newUnit->setNew(true); newUnit->setNew(true);
newUnit->setFolder(getNodePath(parentNode)); newUnit->setFolder(getNodePath(parentNode));
PProjectModelNode node = makeNewFileNode(extractFileName(newUnit->fileName()), PProjectModelNode node = makeNewFileNode(newUnit,newUnit->priority(),parentNode);
newUnit->id(),newUnit->priority(),parentNode);
node->unitIndex = newUnit->id();
newUnit->setNode(node); newUnit->setNode(node);
mUnits.insert(newUnit->id(), newUnit); mUnits.insert(newUnit->fileName(), newUnit);
//parentNode.Expand(True); //parentNode.Expand(True);
switch(getFileType(customFileName)) { switch(getFileType(customFileName)) {
@ -349,12 +348,7 @@ PProjectUnit Project::newUnit(PProjectModelNode parentNode, const QString& custo
return newUnit; return newUnit;
} }
Editor *Project::openUnit(int index, bool forceOpen) Editor* Project::openUnit(PProjectUnit& unit, bool forceOpen) {
{
PProjectUnit unit = mUnits.value(index,PProjectUnit());
if (!unit)
return nullptr;
if (!unit->fileName().isEmpty() && fileExists(unit->fileName())) { if (!unit->fileName().isEmpty() && fileExists(unit->fileName())) {
if (getFileType(unit->fileName())==FileType::Other) { if (getFileType(unit->fileName())==FileType::Other) {
@ -375,22 +369,16 @@ Editor *Project::openUnit(int index, bool forceOpen)
if (editor) { if (editor) {
editor->setInProject(true); editor->setInProject(true);
//unit->setEncoding(encoding); //unit->setEncoding(encoding);
editor->activate();
loadUnitLayout(editor); loadUnitLayout(editor);
editor->activate();
return editor; return editor;
} }
} }
return nullptr; return nullptr;
} }
Editor *Project::openUnit(PProjectEditorLayout editorLayout) Editor *Project::openUnit(PProjectUnit &unit, const PProjectEditorLayout &layout)
{ {
if (!editorLayout)
return nullptr;
PProjectUnit unit = findUnit(editorLayout->filename);
if (!unit)
return nullptr;
if (!unit->fileName().isEmpty() && fileExists(unit->fileName())) { if (!unit->fileName().isEmpty() && fileExists(unit->fileName())) {
if (getFileType(unit->fileName())==FileType::Other) { if (getFileType(unit->fileName())==FileType::Other) {
return nullptr; return nullptr;
@ -407,26 +395,28 @@ Editor *Project::openUnit(PProjectEditorLayout editorLayout)
editor = mEditorList->newEditor(unit->fileName(), encoding, true, unit->isNew()); editor = mEditorList->newEditor(unit->fileName(), encoding, true, unit->isNew());
if (editor) { if (editor) {
editor->setInProject(true); editor->setInProject(true);
//unit->setEncoding(encoding); editor->setCaretY(layout->caretY);
editor->setCaretX(layout->caretX);
editor->setTopLine(layout->topLine);
editor->setLeftChar(layout->leftChar);
editor->activate(); editor->activate();
editor->setTopLine(editorLayout->topLine);
editor->setLeftChar(editorLayout->leftChar);
editor->setCaretX(editorLayout->caretX);
editor->setCaretY(editorLayout->caretY);
return editor; return editor;
} }
} }
return nullptr; return nullptr;
} }
Editor *Project::unitEditor(const PProjectUnit &unit) const Editor *Project::unitEditor(const PProjectUnit &unit) const
{ {
if (!unit)
return nullptr;
return mEditorList->getOpenedEditorByFilename(unit->fileName()); return mEditorList->getOpenedEditorByFilename(unit->fileName());
} }
Editor *Project::unitEditor(const ProjectUnit *unit) const Editor *Project::unitEditor(const ProjectUnit *unit) const
{ {
if (!unit)
return nullptr;
return mEditorList->getOpenedEditorByFilename(unit->fileName()); return mEditorList->getOpenedEditorByFilename(unit->fileName());
} }
@ -456,13 +446,11 @@ void Project::rebuildNodes()
QFileInfo fileInfo(pUnit->fileName()); QFileInfo fileInfo(pUnit->fileName());
pUnit->setNode( pUnit->setNode(
makeNewFileNode( makeNewFileNode(
fileInfo.fileName(), pUnit,
pUnit->id(),
pUnit->priority(), pUnit->priority(),
getCustomeFolderNodeFromName(pUnit->folder()) getCustomeFolderNodeFromName(pUnit->folder())
) )
); );
pUnit->node()->priority = pUnit->priority();
} }
break; break;
case ProjectModelType::FileSystem: case ProjectModelType::FileSystem:
@ -472,26 +460,22 @@ void Project::rebuildNodes()
QFileInfo fileInfo(pUnit->fileName()); QFileInfo fileInfo(pUnit->fileName());
pUnit->setNode( pUnit->setNode(
makeNewFileNode( makeNewFileNode(
fileInfo.fileName(), pUnit,
pUnit->id(),
pUnit->priority(), pUnit->priority(),
getParentFileSystemFolderNode( getParentFileSystemFolderNode(
pUnit->fileName()) pUnit->fileName())
) )
); );
pUnit->node()->priority = pUnit->priority();
} }
break; break;
} }
mModel.endUpdate(); mModel.endUpdate();
emit nodesChanged();
} }
bool Project::removeUnit(int id, bool doClose , bool removeFile) bool Project::removeUnit(PProjectUnit& unit, bool doClose , bool removeFile)
{ {
PProjectUnit unit = findUnitById(id);
if (!unit) if (!unit)
return false; return false;
@ -514,20 +498,20 @@ bool Project::removeUnit(int id, bool doClose , bool removeFile)
PProjectModelNode node = unit->node(); PProjectModelNode node = unit->node();
PProjectModelNode parentNode = node->parent.lock(); PProjectModelNode parentNode = node->parent.lock();
if (!parentNode) { if (!parentNode) {
mUnits.remove(unit->id()); mUnits.remove(unit->fileName());
return true; return true;
} }
int row = parentNode->children.indexOf(unit->node()); int row = parentNode->children.indexOf(unit->node());
if (row<0) { if (row<0) {
mUnits.remove(unit->id()); mUnits.remove(unit->fileName());
return true; return true;
} }
QModelIndex parentIndex = mModel.getNodeIndex(parentNode.get()); QModelIndex parentIndex = mModel.getNodeIndex(parentNode.get());
mModel.removeRow(row,parentIndex); mModel.removeRow(row,parentIndex);
mUnits.remove(unit->id()); mUnits.remove(unit->fileName());
//remove empty parent node //remove empty parent node
PProjectModelNode currentNode = parentNode; PProjectModelNode currentNode = parentNode;
@ -558,7 +542,7 @@ bool Project::removeFolder(PProjectModelNode node)
return false; return false;
// Check if this is actually a folder // Check if this is actually a folder
if (node->unitIndex>=0 || node->level<1) if (node->isUnit || node->level<1)
return false; return false;
// Let this function call itself // Let this function call itself
@ -594,7 +578,7 @@ void Project::saveAll()
void Project::saveLayout() void Project::saveLayout()
{ {
SimpleIni layIni; QJsonObject jsonRoot;
QHash<QString,int> editorOrderSet; QHash<QString,int> editorOrderSet;
// Write list of open project files // Write list of open project files
int order=0; int order=0;
@ -611,52 +595,61 @@ void Project::saveLayout()
// Remember what files were visible // Remember what files were visible
mEditorList->getVisibleEditors(e, e2); mEditorList->getVisibleEditors(e, e2);
if (e) if (e)
layIni.SetValue("Editors","Focused", e->filename().toUtf8()); jsonRoot["focused"]=e->filename();
QJsonArray jsonLayouts;
// save editor info // save editor info
foreach (const PProjectUnit& unit,mUnits) { foreach (const PProjectUnit& unit,mUnits) {
Editor* editor = unitEditor(unit); Editor* editor = unitEditor(unit);
if (editor) { if (editor) {
QByteArray groupName = QString("E_%1").arg(editor->filename()).toUtf8(); QJsonObject jsonLayout;
layIni.SetLongValue(groupName,"CursorCol", editor->caretX()); jsonLayout["filename"]=unit->fileName();
layIni.SetLongValue(groupName,"CursorRow", editor->caretY()); jsonLayout["caretX"]=editor->caretX();
layIni.SetLongValue(groupName,"TopLine", editor->topLine()); jsonLayout["caretY"]=editor->caretY();
layIni.SetLongValue(groupName,"LeftChar", editor->leftChar()); jsonLayout["topLine"]=editor->topLine();
jsonLayout["leftChar"]=editor->leftChar();
int order=editorOrderSet.value(editor->filename(),-1); int order=editorOrderSet.value(editor->filename(),-1);
if (order>=0) { if (order>=0) {
layIni.SetLongValue(groupName,"Order",order); jsonLayout["order"]=order;
} }
jsonLayouts.append(jsonLayout);
} }
// remove old data from project file
// SimpleIni ini;
// ini.LoadFile(filename().toLocal8Bit());
// groupName = toByteArray(QString("Unit%1").arg(i+1));
// ini.Delete(groupName,"Open");
// ini.Delete(groupName,"Top");
// ini.Delete(groupName,"CursorCol");
// ini.Delete(groupName,"CursorRow");
// ini.Delete(groupName,"TopLine");
// ini.Delete(groupName,"LeftChar");
// ini.SaveFile(filename().toLocal8Bit());
} }
layIni.SaveFile(changeFileExt(filename(), "layout").toLocal8Bit()); jsonRoot["editorLayouts"]=jsonLayouts;
QString jsonFilename=changeFileExt(filename(), "layout");
QFile file(jsonFilename);
if (file.open(QFile::WriteOnly|QFile::Truncate)) {
QJsonDocument doc(jsonRoot);
file.write(doc.toJson(QJsonDocument::Indented));
file.close();
} else {
throw FileError(QObject::tr("Can't open file '%1' for write.")
.arg(jsonFilename));
}
} }
void Project::renameUnit(int idx, const QString &sFileName) void Project::renameUnit(PProjectUnit& unit, const QString &sFileName)
{ {
PProjectUnit unit = findUnitById(idx);
if (!unit) if (!unit)
return; return;
if (sFileName.compare(unit->fileName(),PATH_SENSITIVITY)==0)
return;
if (fileExists(unit->fileName())) { if (fileExists(unit->fileName())) {
unit->setNew(false); unit->setNew(false);
} }
Editor * editor=unitEditor(unit); Editor * editor=unitEditor(unit);
if (editor) { if (editor) {
//prevent recurse //prevent recurse
editor->saveAs(sFileName,true); editor->saveAs(sFileName,true);
} }
unit->setNew(false); removeUnit(unit,false,false);
unit->setFileName(sFileName); PProjectModelNode parentNode = unit->node()->parent.lock();
unit = addUnit(sFileName,parentNode);
setModified(true); setModified(true);
emit nodeRenamed();
} }
bool Project::saveUnits() bool Project::saveUnits()
@ -725,18 +718,9 @@ bool Project::saveUnits()
return true; return true;
} }
PProjectUnit Project::findUnitById(int id)
{
return mUnits.value(id,PProjectUnit());
}
PProjectUnit Project::findUnit(const QString &filename) PProjectUnit Project::findUnit(const QString &filename)
{ {
foreach(PProjectUnit unit, mUnits) { return mUnits.value(filename,PProjectUnit());
if (QString::compare(unit->fileName(),filename, PATH_SENSITIVITY)==0)
return unit;
}
return PProjectUnit();
} }
PProjectUnit Project::findUnit(const Editor *editor) PProjectUnit Project::findUnit(const Editor *editor)
@ -854,6 +838,9 @@ bool Project::assignTemplate(const std::shared_ptr<ProjectTemplate> aTemplate, b
if (!aTemplate) { if (!aTemplate) {
return true; return true;
} }
mModel.beginUpdate();
mRootNode = makeProjectNode();
mOptions = aTemplate->options(); mOptions = aTemplate->options();
mOptions.compilerSet = pSettings->compilerSets().defaultIndex(); mOptions.compilerSet = pSettings->compilerSets().defaultIndex();
mOptions.isCpp = useCpp; mOptions.isCpp = useCpp;
@ -921,7 +908,7 @@ bool Project::assignTemplate(const std::shared_ptr<ProjectTemplate> aTemplate, b
} }
} }
} }
rebuildNodes(); mModel.endUpdate();
return true; return true;
} }
@ -1188,17 +1175,16 @@ PProjectUnit Project::addUnit(const QString &inFileName, PProjectModelNode paren
newUnit->setCompileCpp(false); newUnit->setCompileCpp(false);
newUnit->setLink(false); newUnit->setLink(false);
} }
newUnit->setFolder(getNodePath(parentNode)); if (mOptions.modelType == ProjectModelType::FileSystem)
newUnit->setFolder(getNodePath(parentNode));
newUnit->setPriority(1000); newUnit->setPriority(1000);
newUnit->setOverrideBuildCmd(false); newUnit->setOverrideBuildCmd(false);
newUnit->setBuildCmd(""); newUnit->setBuildCmd("");
PProjectModelNode node = makeNewFileNode(extractFileName(newUnit->fileName()), PProjectModelNode node = makeNewFileNode(newUnit,
newUnit->id(),
newUnit->priority(), parentNode); newUnit->priority(), parentNode);
node->unitIndex = newUnit->id();
newUnit->setNode(node); newUnit->setNode(node);
mUnits.insert(newUnit->id(),newUnit); mUnits.insert(newUnit->fileName(),newUnit);
setModified(true); setModified(true);
return newUnit; return newUnit;
@ -1487,6 +1473,17 @@ void Project::buildPrivateResource(bool forceSave)
stringsToFile(contents,hFile); stringsToFile(contents,hFile);
} }
void Project::closeAllUnits()
{
foreach (PProjectUnit unit, mUnits) {
Editor * editor = unitEditor(unit);
if (editor) {
editor->setInProject(false);
mEditorList->forceCloseEditor(editor);
}
}
}
void Project::checkProjectFileForUpdate(SimpleIni &ini) void Project::checkProjectFileForUpdate(SimpleIni &ini)
{ {
bool cnvt = false; bool cnvt = false;
@ -1537,10 +1534,10 @@ void Project::checkProjectFileForUpdate(SimpleIni &ini)
QMessageBox::Ok); QMessageBox::Ok);
} }
void Project::closeUnit(int id) void Project::closeUnit(PProjectUnit& unit)
{ {
PProjectUnit unit = findUnitById(id); saveLayout();
Editor * editor =unitEditor(unit); Editor * editor = unitEditor(unit);
if (editor) { if (editor) {
editor->setInProject(false); editor->setInProject(false);
mEditorList->forceCloseEditor(editor); mEditorList->forceCloseEditor(editor);
@ -1563,12 +1560,14 @@ void Project::createFolderNodes()
node = makeNewFolderNode(s.mid(0,i),node); node = makeNewFolderNode(s.mid(0,i),node);
else else
node = findnode; node = findnode;
node->unitIndex = -1; if (!node->isUnit) {
qDebug()<<"node "<<node->text<<"is not a folder:"<<s;
node = mRootNode;
}
s.remove(0,i+1); s.remove(0,i+1);
i = s.indexOf('/'); i = s.indexOf('/');
} }
node = makeNewFolderNode(s, node); node = makeNewFolderNode(s, node);
node->unitIndex = -1;
mCustomFolderNodes.append(node); mCustomFolderNodes.append(node);
} }
} }
@ -1715,11 +1714,11 @@ QString Project::getNodePath(PProjectModelNode node)
if (!node) if (!node)
return result; return result;
if (node->unitIndex>=0) // not a folder if (node->isUnit) // not a folder
return result; return result;
PProjectModelNode p = node; PProjectModelNode p = node;
while (p && p->unitIndex==-1 && p!=mRootNode) { while (p && !p->isUnit && p!=mRootNode) {
if (!result.isEmpty()) if (!result.isEmpty())
result = p->text + "/" + result; result = p->text + "/" + result;
else else
@ -1729,11 +1728,6 @@ QString Project::getNodePath(PProjectModelNode node)
return result; return result;
} }
int Project::getUnitFromString(const QString &s)
{
return findUnitId(s);
}
PProjectModelNode Project::getParentFileSystemFolderNode(const QString &filename) PProjectModelNode Project::getParentFileSystemFolderNode(const QString &filename)
{ {
QFileInfo fileInfo(filename); QFileInfo fileInfo(filename);
@ -1763,47 +1757,59 @@ void Project::incrementBuildNumber()
PProjectUnit Project::loadLayout() PProjectUnit Project::loadLayout()
{ {
SimpleIni layIni; QString jsonFilename = changeFileExt(filename(), "layout");
SI_Error error = layIni.LoadFile(changeFileExt(filename(), "layout").toLocal8Bit()); qDebug()<<"read file"<<jsonFilename;
if (error!=SI_OK) QFile file(jsonFilename);
if (!file.open(QIODevice::ReadOnly))
return PProjectUnit(); return PProjectUnit();
QString focusedFilename = fromByteArray(layIni.GetValue("Editors","Focused")); QByteArray content = file.readAll();
//TopRight := layIni.ReadInteger('Editors', 'FocusedRight', -1); QJsonParseError parseError;
QJsonDocument doc(QJsonDocument::fromJson(content,&parseError));
file.close();
if (parseError.error!=QJsonParseError::NoError)
return PProjectUnit();
QJsonObject jsonRoot=doc.object();
QJsonArray jsonLayouts=jsonRoot["editorLayouts"].toArray();
QHash<int,PProjectEditorLayout> opennedMap; QHash<int,PProjectEditorLayout> opennedMap;
SimpleIni::TNamesDepend sections; for (int i=0;i<jsonLayouts.size();i++) {
layIni.GetAllSections(sections); QJsonObject jsonLayout = jsonLayouts[i].toObject();
QSet<QString> sectionNames; QString unitFilename = jsonLayout["filename"].toString();
for(const SimpleIni::Entry& entry:sections) { if (mUnits.contains(unitFilename)) {
QString key(entry.pItem);
sectionNames.insert(key);
}
foreach (PProjectUnit unit,mUnits) {
QByteArray groupName = QString("E_%1").arg(unit->fileName()).toUtf8();
if (sectionNames.contains(groupName)) {
PProjectEditorLayout editorLayout = std::make_shared<ProjectEditorLayout>(); PProjectEditorLayout editorLayout = std::make_shared<ProjectEditorLayout>();
editorLayout->filename=unit->fileName(); editorLayout->filename=unitFilename;
editorLayout->topLine=layIni.GetLongValue(groupName,"TopLine"); editorLayout->topLine=jsonLayout["topLine"].toInt();
editorLayout->leftChar=layIni.GetLongValue(groupName,"LeftChar"); editorLayout->leftChar=jsonLayout["leftChar"].toInt();
editorLayout->caretX=layIni.GetLongValue(groupName,"CursorCol"); editorLayout->caretX=jsonLayout["caretX"].toInt();
editorLayout->caretY=layIni.GetLongValue(groupName,"CursorRow"); editorLayout->caretY=jsonLayout["caretY"].toInt();
int order = layIni.GetLongValue(groupName,"Order",-1); int order = jsonLayout["order"].toInt(-1);
if (order>=0) if (order>=0)
opennedMap.insert(order,editorLayout); opennedMap.insert(order,editorLayout);
} }
} }
for (int i=0;i<mUnits.count();i++) { for (int i=0;i<mUnits.count();i++) {
PProjectEditorLayout editorLayout = opennedMap.value(i,PProjectEditorLayout()); PProjectEditorLayout editorLayout = opennedMap.value(i,PProjectEditorLayout());
if (editorLayout) { if (editorLayout) {
openUnit(editorLayout); PProjectUnit unit = findUnit(editorLayout->filename);
openUnit(unit,editorLayout);
} }
} }
PProjectUnit unit = findUnit(focusedFilename);
if (unit) { QString focusedFilename = jsonRoot["focused"].toString();
Editor * editor = unitEditor(unit);
if (editor) if (!focusedFilename.isEmpty()) {
editor->activate(); PProjectUnit unit = findUnit(focusedFilename);
if (unit) {
Editor * editor = unitEditor(unit);
if (editor)
editor->activate();
}
return unit;
} }
return unit; return PProjectUnit();
} }
void Project::loadOptions(SimpleIni& ini) void Project::loadOptions(SimpleIni& ini)
@ -2050,16 +2056,37 @@ void Project::loadUnitLayout(Editor *e)
{ {
if (!e) if (!e)
return; return;
SimpleIni layIni;
SI_Error error; QString jsonFilename = changeFileExt(filename(), "layout");
error = layIni.LoadFile(changeFileExt(filename(), "layout").toLocal8Bit()); QFile file(jsonFilename);
if (error != SI_Error::SI_OK) if (!file.open(QIODevice::ReadOnly))
return; return;
QByteArray groupName = (QString("E_%1").arg(e->filename())).toUtf8(); QByteArray content = file.readAll();
e->setCaretY(layIni.GetLongValue(groupName,"CursorRow",1)); QJsonParseError parseError;
e->setCaretX(layIni.GetLongValue(groupName,"CursorCol",1)); QJsonDocument doc{QJsonDocument::fromJson(content,&parseError)};
e->setTopLine(layIni.GetLongValue(groupName,"TopLine",1)); file.close();
e->setLeftChar(layIni.GetLongValue(groupName,"LeftChar",1)); if (parseError.error!=QJsonParseError::NoError)
return;
QJsonObject jsonRoot=doc.object();
QJsonArray jsonLayouts=jsonRoot["editorLayouts"].toArray();
QHash<int,PProjectEditorLayout> opennedMap;
for (int i=0;i<jsonLayouts.size();i++) {
QJsonObject jsonLayout = jsonLayouts[i].toObject();
QString unitFilename = jsonLayout["filename"].toString();
if (unitFilename.compare(e->filename(),PATH_SENSITIVITY)==0) {
qDebug()<<i<<unitFilename<<e->filename();
e->setCaretY(jsonLayout["caretY"].toInt());
e->setCaretX(jsonLayout["caretX"].toInt());
e->setTopLine(jsonLayout["topLine"].toInt());
e->setLeftChar(jsonLayout["leftChar"].toInt());
return;
}
}
} }
PCppParser Project::cppParser() PCppParser Project::cppParser()
@ -2067,23 +2094,6 @@ PCppParser Project::cppParser()
return mParser; return mParser;
} }
int Project::findUnitId(const QString &fileName) const
{
QDir dir(directory());
foreach (const PProjectUnit& unit, mUnits) {
if (dir.absoluteFilePath(fileName) == dir.absoluteFilePath(unit->fileName()))
return unit->id();
}
return -1;
}
int Project::findUnitId(const Editor *editor) const
{
if (!editor)
return -1;
return findUnitId(editor->filename());
}
void Project::removeFolderRecurse(PProjectModelNode node) void Project::removeFolderRecurse(PProjectModelNode node)
{ {
if (!node) if (!node)
@ -2092,13 +2102,13 @@ void Project::removeFolderRecurse(PProjectModelNode node)
for (int i=node->children.count()-1;i>=0;i++) { for (int i=node->children.count()-1;i>=0;i++) {
PProjectModelNode childNode = node->children[i]; PProjectModelNode childNode = node->children[i];
// Remove folder inside folder // Remove folder inside folder
if (childNode->unitIndex<0 && childNode->level>0) { if (!childNode->isUnit && childNode->level>0) {
removeFolderRecurse(childNode); removeFolderRecurse(childNode);
// Or remove editors at this level // Or remove editors at this level
} else if (childNode->unitIndex >= 0 && childNode->level > 0) { } else if (childNode->isUnit && childNode->level > 0) {
// Remove editor in folder from project // Remove editor in folder from project
int editorIndex = childNode->unitIndex; PProjectUnit unit = childNode->pUnit.lock();
if (!removeUnit(editorIndex,true)) if (!removeUnit(unit,true))
return; return;
} }
} }
@ -2113,7 +2123,7 @@ void Project::updateFolderNode(PProjectModelNode node)
{ {
for (int i=0;i<node->children.count();i++){ for (int i=0;i<node->children.count();i++){
PProjectModelNode child = node->children[i]; PProjectModelNode child = node->children[i];
if (child->unitIndex<0) { if (!child->isUnit) {
mFolders.append(getNodePath(child)); mFolders.append(getNodePath(child));
updateFolderNode(child); updateFolderNode(child);
} }
@ -2162,6 +2172,18 @@ QStringList Project::binDirs()
return lst; return lst;
} }
void Project::renameFolderNode(PProjectModelNode node, const QString newName)
{
if (!node)
return;
if (node->isUnit)
return;
node->text = newName;
updateFolders();
setModified(true);
emit nodeRenamed();
}
EditorList *Project::editorList() const EditorList *Project::editorList() const
{ {
return mEditorList; return mEditorList;
@ -2214,14 +2236,11 @@ const QString &Project::filename() const
return mFilename; return mFilename;
} }
int ProjectUnit::mIdGenerator=0;
ProjectUnit::ProjectUnit(Project* parent) ProjectUnit::ProjectUnit(Project* parent)
{ {
mNode = nullptr; mNode = nullptr;
mParent = parent; mParent = parent;
mFileMissing = false; mFileMissing = false;
mId=mIdGenerator++;
mPriority=0; mPriority=0;
} }
@ -2230,11 +2249,6 @@ Project *ProjectUnit::parent() const
return mParent; return mParent;
} }
void ProjectUnit::setParent(Project* newParent)
{
mParent = newParent;
}
const QString &ProjectUnit::fileName() const const QString &ProjectUnit::fileName() const
{ {
return mFileName; return mFileName;
@ -2416,16 +2430,6 @@ void ProjectUnit::setFileMissing(bool newDontSave)
mFileMissing = newDontSave; mFileMissing = newDontSave;
} }
int ProjectUnit::id() const
{
return mId;
}
void ProjectUnit::setId(int newId)
{
mId = newId;
}
ProjectModel::ProjectModel(Project *project, QObject *parent): ProjectModel::ProjectModel(Project *project, QObject *parent):
QAbstractItemModel(parent), QAbstractItemModel(parent),
mProject(project) mProject(project)
@ -2547,8 +2551,10 @@ QVariant ProjectModel::data(const QModelIndex &index, int role) const
return p->text; return p->text;
} else if (role == Qt::DecorationRole) { } else if (role == Qt::DecorationRole) {
QIcon icon; QIcon icon;
if (p->unitIndex>=0) { if (p->isUnit) {
icon = mIconProvider->icon(mProject->findUnitById(p->unitIndex)->fileName()); PProjectUnit unit = p->pUnit.lock();
if (unit)
icon = mIconProvider->icon(unit->fileName());
} else { } else {
if (p == mProject->rootNode().get()) { if (p == mProject->rootNode().get()) {
QString branch; QString branch;
@ -2585,12 +2591,12 @@ Qt::ItemFlags ProjectModel::flags(const QModelIndex &index) const
return Qt::ItemIsEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEditable; return Qt::ItemIsEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEditable;
if (mProject && mProject->modelType() == ProjectModelType::FileSystem) { if (mProject && mProject->modelType() == ProjectModelType::FileSystem) {
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
if (p->unitIndex>=0) if (p->isUnit)
flags.setFlag(Qt::ItemIsEditable); flags.setFlag(Qt::ItemIsEditable);
return flags; return flags;
} else { } else {
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled; Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
if (p->unitIndex<0) { if (!p->isUnit) {
flags.setFlag(Qt::ItemIsDropEnabled); flags.setFlag(Qt::ItemIsDropEnabled);
flags.setFlag(Qt::ItemIsDragEnabled,false); flags.setFlag(Qt::ItemIsDragEnabled,false);
} }
@ -2615,10 +2621,10 @@ bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int
emit dataChanged(index,index); emit dataChanged(index,index);
return true; return true;
} }
int idx = node->unitIndex; PProjectUnit unit = node->pUnit.lock();
if (idx >= 0) { if (unit) {
//change unit name //change unit name
PProjectUnit unit = mProject->findUnitById(idx);
QString newName = value.toString().trimmed(); QString newName = value.toString().trimmed();
if (newName.isEmpty()) if (newName.isEmpty())
return false; return false;
@ -2642,9 +2648,9 @@ bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int
mProject->editorList()->closeEditor(e); mProject->editorList()->closeEditor(e);
// Remove it from the current project... // Remove it from the current project...
int projindex = mProject->findUnitId(newName); PProjectUnit unit = mProject->findUnit(newName);
if (projindex>=0) { if (unit) {
mProject->removeUnit(projindex,false); mProject->removeUnit(unit,false);
} }
// All references to the file are removed. Delete the file from disk // All references to the file are removed. Delete the file from disk
@ -2674,17 +2680,13 @@ bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int
QMessageBox::Ok); QMessageBox::Ok);
return false; return false;
} }
mProject->renameUnit(idx,newName); mProject->renameUnit(unit,newName);
// Add new filename to file minitor // Add new filename to file minitor
mProject->fileSystemWatcher()->addPath(newName); mProject->fileSystemWatcher()->addPath(newName);
//suffix changed mProject->saveAll();
if (mProject && mProject->modelType() == ProjectModelType::FileSystem
&& QFileInfo(oldName).suffix()!=QFileInfo(newName).suffix()) {
mProject->rebuildNodes();
} else
emit dataChanged(index,index);
return true; return true;
} else { } else {
//change folder name //change folder name
@ -2693,10 +2695,11 @@ bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int
return false; return false;
if (newName == node->text) if (newName == node->text)
return false; return false;
node->text = newName; mProject->renameFolderNode(node,newName);
mProject->updateFolders();
mProject->saveAll();
emit dataChanged(index,index); emit dataChanged(index,index);
mProject->saveAll();
return true; return true;
} }
@ -2767,7 +2770,7 @@ bool ProjectModel::canDropMimeData(const QMimeData * data, Qt::DropAction action
// } // }
ProjectModelNode* p= static_cast<ProjectModelNode*>(idx.internalPointer()); ProjectModelNode* p= static_cast<ProjectModelNode*>(idx.internalPointer());
PProjectModelNode node = mProject->pointerToNode(p); PProjectModelNode node = mProject->pointerToNode(p);
if (node->unitIndex>=0) if (node->isUnit)
return false; return false;
QByteArray encoded = data->data(format); QByteArray encoded = data->data(format);
QDataStream stream(&encoded, QIODevice::ReadOnly); QDataStream stream(&encoded, QIODevice::ReadOnly);
@ -2835,8 +2838,8 @@ bool ProjectModel::dropMimeData(const QMimeData *data, Qt::DropAction action, in
beginInsertRows(newParentIndex,node->children.count(),node->children.count()); beginInsertRows(newParentIndex,node->children.count(),node->children.count());
droppedNode->parent = node; droppedNode->parent = node;
node->children.append(droppedNode); node->children.append(droppedNode);
if (droppedNode->unitIndex>=0) { if (droppedNode->isUnit) {
PProjectUnit unit = mProject->findUnitById(droppedNode->unitIndex); PProjectUnit unit = droppedNode->pUnit.lock();
unit->setFolder(mProject->getNodePath(node)); unit->setFolder(mProject->getNodePath(node));
} }
endInsertRows(); endInsertRows();
@ -2863,8 +2866,10 @@ QMimeData *ProjectModel::mimeData(const QModelIndexList &indexes) const
for (; it != indexes.end(); ++it) { for (; it != indexes.end(); ++it) {
stream << (qint32)((*it).row()) << (qint32)((*it).column()) << (quintptr)((*it).internalPointer()); stream << (qint32)((*it).row()) << (qint32)((*it).column()) << (quintptr)((*it).internalPointer());
ProjectModelNode* p = static_cast<ProjectModelNode*>((*it).internalPointer()); ProjectModelNode* p = static_cast<ProjectModelNode*>((*it).internalPointer());
if (p && p->unitIndex>=0) { if (p && p->isUnit) {
urls.append(QUrl::fromLocalFile(mProject->findUnitById(p->unitIndex)->fileName())); PProjectUnit unit = p->pUnit.lock();
if (unit)
urls.append(QUrl::fromLocalFile(unit->fileName()));
} }
} }
if (!urls.isEmpty()) if (!urls.isEmpty())
@ -2893,9 +2898,9 @@ bool ProjectModelSortFilterProxy::lessThan(const QModelIndex &source_left, const
return true; return true;
if (!pRight) if (!pRight)
return false; return false;
if (pLeft->unitIndex<0 && pRight->unitIndex>=0) if (!pLeft->isUnit && pRight->isUnit)
return true; return true;
if (pLeft->unitIndex>=0 && pRight->unitIndex<0) if (pLeft->isUnit && !pRight->isUnit)
return false; return false;
if (pLeft->priority!=pRight->priority) if (pLeft->priority!=pRight->priority)
return pLeft->priority>pRight->priority; return pLeft->priority>pRight->priority;

View File

@ -44,12 +44,15 @@ struct ProjectModelItemRecord {
QString fullPath; QString fullPath;
}; };
class ProjectUnit;
struct ProjectModelNode; struct ProjectModelNode;
using PProjectModelNode = std::shared_ptr<ProjectModelNode>; using PProjectModelNode = std::shared_ptr<ProjectModelNode>;
struct ProjectModelNode { struct ProjectModelNode {
QString text; QString text;
std::weak_ptr<ProjectModelNode> parent; std::weak_ptr<ProjectModelNode> parent;
int unitIndex; bool isUnit;
std::weak_ptr<ProjectUnit> pUnit;
int priority; int priority;
QList<PProjectModelNode> children; QList<PProjectModelNode> children;
ProjectModelNodeType folderNodeType; ProjectModelNodeType folderNodeType;
@ -71,7 +74,6 @@ class ProjectUnit {
public: public:
explicit ProjectUnit(Project* parent); explicit ProjectUnit(Project* parent);
Project* parent() const; Project* parent() const;
void setParent(Project* newParent);
const QString &fileName() const; const QString &fileName() const;
void setFileName(QString newFileName); void setFileName(QString newFileName);
bool isNew() const; bool isNew() const;
@ -102,10 +104,6 @@ public:
bool FileMissing() const; bool FileMissing() const;
void setFileMissing(bool newDontSave); void setFileMissing(bool newDontSave);
int id() const;
void setId(int newId);
private: private:
Project* mParent; Project* mParent;
QString mFileName; QString mFileName;
@ -120,8 +118,6 @@ private:
QByteArray mEncoding; QByteArray mEncoding;
PProjectModelNode mNode; PProjectModelNode mNode;
bool mFileMissing; bool mFileMissing;
int mId;
static int mIdGenerator;
}; };
using PProjectUnit = std::shared_ptr<ProjectUnit>; using PProjectUnit = std::shared_ptr<ProjectUnit>;
@ -206,46 +202,37 @@ public:
PProjectModelNode parentNode); PProjectModelNode parentNode);
QString folder(); QString folder();
void buildPrivateResource(bool forceSave=false); void buildPrivateResource(bool forceSave=false);
void closeUnit(int id); void closeAllUnits();
void closeUnit(PProjectUnit& unit);
PProjectUnit doAutoOpen(); PProjectUnit doAutoOpen();
bool fileAlreadyExists(const QString& s); bool fileAlreadyExists(const QString& s);
QString getNodePath(PProjectModelNode node); QString getNodePath(PProjectModelNode node);
int getUnitFromString(const QString& s);
void incrementBuildNumber(); void incrementBuildNumber();
PProjectUnit newUnit(PProjectModelNode parentNode, PProjectUnit newUnit(PProjectModelNode parentNode,
const QString& customFileName=""); const QString& customFileName="");
Editor* openUnit(int index, bool forceOpen=true); Editor* openUnit(PProjectUnit& unit, bool forceOpen=true);
Editor* openUnit(PProjectEditorLayout editorLayout); Editor* openUnit(PProjectUnit& unit, const PProjectEditorLayout& layout);
Editor* unitEditor(const PProjectUnit& unit) const; Editor* unitEditor(const PProjectUnit& unit) const;
Editor* unitEditor(const ProjectUnit* unit) const; Editor* unitEditor(const ProjectUnit* unit) const;
Editor* unitEditor(int id) const {
PProjectUnit unit=mUnits.value(id,PProjectUnit());
if (!unit)
return nullptr;
return unitEditor(unit);
}
QList<PProjectUnit> unitList(); QList<PProjectUnit> unitList();
PProjectModelNode pointerToNode(ProjectModelNode * p, PProjectModelNode parent=PProjectModelNode()); PProjectModelNode pointerToNode(ProjectModelNode * p, PProjectModelNode parent=PProjectModelNode());
void rebuildNodes(); void rebuildNodes();
bool removeUnit(int id, bool doClose, bool removeFile = false); bool removeUnit(PProjectUnit& unit, bool doClose, bool removeFile = false);
bool removeFolder(PProjectModelNode node); bool removeFolder(PProjectModelNode node);
void resetParserProjectFiles(); void resetParserProjectFiles();
void saveAll(); // save [Project] and all [UnitX] void saveAll(); // save [Project] and all [UnitX]
void saveLayout(); // save all [UnitX] void saveLayout(); // save all [UnitX]
void saveOptions(); void saveOptions();
void renameUnit(int idx, const QString& sFileName); void renameUnit(PProjectUnit& unit, const QString& sFileName);
bool saveUnits(); bool saveUnits();
PProjectUnit findUnitById(int id);
PProjectUnit findUnit(const QString& filename); PProjectUnit findUnit(const QString& filename);
PProjectUnit findUnit(const Editor* editor); PProjectUnit findUnit(const Editor* editor);
int findUnitId(const QString& fileName) const;
int findUnitId(const Editor* editor) const;
void associateEditor(Editor* editor); void associateEditor(Editor* editor);
void associateEditorToUnit(Editor* editor, PProjectUnit unit); void associateEditorToUnit(Editor* editor, PProjectUnit unit);
bool setCompileOption(const QString &key, const QString &value); bool setCompileOption(const QString &key, const QString &value);
@ -283,9 +270,12 @@ public:
QStringList binDirs(); QStringList binDirs();
void renameFolderNode(PProjectModelNode node, const QString newName);
void loadUnitLayout(Editor *e);
signals: signals:
void nodesChanged(); void nodeRenamed();
void modifyChanged(bool value); void modifyChanged(bool value);
private: private:
void checkProjectFileForUpdate(SimpleIni& ini); void checkProjectFileForUpdate(SimpleIni& ini);
void createFolderNodes(); void createFolderNodes();
@ -296,7 +286,6 @@ private:
PProjectModelNode getCustomeFolderNodeFromName(const QString& name); PProjectModelNode getCustomeFolderNodeFromName(const QString& name);
void loadOptions(SimpleIni& ini); void loadOptions(SimpleIni& ini);
PProjectUnit loadLayout(); PProjectUnit loadLayout();
void loadUnitLayout(Editor *e);
PProjectModelNode makeNewFolderNode( PProjectModelNode makeNewFolderNode(
const QString& folderName, const QString& folderName,
@ -304,8 +293,8 @@ private:
ProjectModelNodeType nodeType=ProjectModelNodeType::Folder, ProjectModelNodeType nodeType=ProjectModelNodeType::Folder,
int priority=0); int priority=0);
PProjectModelNode makeNewFileNode( PProjectModelNode makeNewFileNode(
const QString& fileName, //const QString& fileName,
int unitId, PProjectUnit unit,
int priority, int priority,
PProjectModelNode newParent); PProjectModelNode newParent);
PProjectModelNode makeProjectNode(); PProjectModelNode makeProjectNode();
@ -315,7 +304,7 @@ private:
void updateCompilerSetType(); void updateCompilerSetType();
private: private:
QHash<int,PProjectUnit> mUnits; QHash<QString,PProjectUnit> mUnits;
ProjectOptions mOptions; ProjectOptions mOptions;
QString mFilename; QString mFilename;
QString mName; QString mName;

View File

@ -47,7 +47,7 @@ void ProjectFilesWidget::doSave()
{ {
for (int i=0;i<mUnits.count();i++) { for (int i=0;i<mUnits.count();i++) {
PProjectUnit unitCopy = mUnits[i]; PProjectUnit unitCopy = mUnits[i];
PProjectUnit unit = pMainWindow->project()->findUnitById(unitCopy->id()); PProjectUnit unit = pMainWindow->project()->findUnit(unitCopy->fileName());
unit->setPriority(unitCopy->priority()); unit->setPriority(unitCopy->priority());
unit->setCompile(unitCopy->compile()); unit->setCompile(unitCopy->compile());
unit->setLink(unitCopy->link()); unit->setLink(unitCopy->link());
@ -70,11 +70,13 @@ PProjectUnit ProjectFilesWidget::currentUnit()
ProjectModelNode* node = static_cast<ProjectModelNode*>(index.internalPointer()); ProjectModelNode* node = static_cast<ProjectModelNode*>(index.internalPointer());
if (!node) if (!node)
return PProjectUnit(); return PProjectUnit();
int idx = node->unitIndex; if (!node->isUnit)
if (idx>=0) { return PProjectUnit();
foreach (PProjectUnit unit, mUnits) { PProjectUnit unit=node->pUnit.lock();
if (unit->id() == idx) if (unit) {
return unit; foreach (PProjectUnit tmpUnit, mUnits) {
if (tmpUnit->fileName() == unit->fileName())
return tmpUnit;
} }
} }
return PProjectUnit(); return PProjectUnit();
@ -88,7 +90,6 @@ void ProjectFilesWidget::copyUnits()
mUnits.clear(); mUnits.clear();
foreach (const PProjectUnit& unit, project->unitList()) { foreach (const PProjectUnit& unit, project->unitList()) {
PProjectUnit unitCopy = std::make_shared<ProjectUnit>(project.get()); PProjectUnit unitCopy = std::make_shared<ProjectUnit>(project.get());
unitCopy->setId(unit->id());
unitCopy->setPriority(unit->priority()); unitCopy->setPriority(unit->priority());
unitCopy->setCompile(unit->compile()); unitCopy->setCompile(unit->compile());
unitCopy->setLink(unit->link()); unitCopy->setLink(unit->link());
@ -145,9 +146,8 @@ void ProjectFilesWidget::on_treeProject_doubleClicked(const QModelIndex &index)
disableFileOptions(); disableFileOptions();
return; return;
} }
int i = node->unitIndex; PProjectUnit unit = node->pUnit.lock();
if (i>=0) { if (unit) {
PProjectUnit unit = mUnits[i];
ui->grpFileOptions->setEnabled(true); ui->grpFileOptions->setEnabled(true);
ui->spinPriority->setValue(unit->priority()); ui->spinPriority->setValue(unit->priority());
ui->chkCompile->setChecked(unit->compile()); ui->chkCompile->setChecked(unit->compile());