diff --git a/RedPandaIDE/compiler/projectcompiler.cpp b/RedPandaIDE/compiler/projectcompiler.cpp index 0bc52934..42384314 100644 --- a/RedPandaIDE/compiler/projectcompiler.cpp +++ b/RedPandaIDE/compiler/projectcompiler.cpp @@ -141,8 +141,7 @@ void ProjectCompiler::writeMakeDefines(QFile &file) QString cleanObjects; // Create a list of object files - for (int i=0;iunits().count();i++) { - PProjectUnit unit = mProject->units()[i]; + foreach(const PProjectUnit &unit, mProject->unitList()) { if (!unit->compile() && !unit->link()) continue; @@ -324,8 +323,8 @@ void ProjectCompiler::writeMakeObjFilesRules(QFile &file) if (mProject->options().usePrecompiledHeader) precompileStr = " $(PCH) "; - for (int i = 0;iunits().count();i++) { - PProjectUnit unit = mProject->units()[i]; + QList projectUnits; + foreach(const PProjectUnit &unit, projectUnits) { FileType fileType = getFileType(unit->fileName()); // Only process source files if (fileType!=FileType::CSource && fileType!=FileType::CppSource) @@ -343,8 +342,7 @@ void ProjectCompiler::writeMakeObjFilesRules(QFile &file) continue; if (!parser->isSystemHeaderFile(headerName) && ! parser->isProjectHeaderFile(headerName)) { - for (int j = 0;junits().count();j++) { - PProjectUnit unit2 = mProject->units()[j]; + foreach(const PProjectUnit &unit2, projectUnits) { if (unit2->fileName()==headerName) { objStr = objStr + ' ' + genMakePath2(extractRelativePath(mProject->makeFileName(),headerName)); break; @@ -353,10 +351,10 @@ void ProjectCompiler::writeMakeObjFilesRules(QFile &file) } } } else { - foreach (const PProjectUnit& u, mProject->units()) { - FileType fileType = getFileType(u->fileName()); + foreach(const PProjectUnit &unit2, projectUnits) { + FileType fileType = getFileType(unit2->fileName()); if (fileType == FileType::CHeader || fileType==FileType::CppHeader) - objStr = objStr + ' ' + genMakePath2(extractRelativePath(mProject->makeFileName(),u->fileName())); + objStr = objStr + ' ' + genMakePath2(extractRelativePath(mProject->makeFileName(),unit2->fileName())); } } QString ObjFileName; @@ -449,7 +447,7 @@ void ProjectCompiler::writeMakeObjFilesRules(QFile &file) QString ResFiles; // Concatenate all resource filenames (not created when syntax checking) if (!mOnlyCheckSyntax) { - foreach(const PProjectUnit& unit, mProject->units()) { + foreach(const PProjectUnit& unit, mProject->unitList()) { if (getFileType(unit->fileName())!=FileType::WindowsResourceSource) continue; if (fileExists(unit->fileName())) { diff --git a/RedPandaIDE/cpprefacter.cpp b/RedPandaIDE/cpprefacter.cpp index 281ba875..7d9330fd 100644 --- a/RedPandaIDE/cpprefacter.cpp +++ b/RedPandaIDE/cpprefacter.cpp @@ -177,7 +177,7 @@ void CppRefacter::doFindOccurenceInProject(PStatement statement, std::shared_ptr statement->fullName, SearchFileScope::wholeProject ); - foreach (const PProjectUnit& unit, project->units()) { + foreach (const PProjectUnit& unit, project->unitList()) { if (isCFile(unit->fileName()) || isHFile(unit->fileName())) { PSearchResultTreeItem item = findOccurenceInFile( unit->fileName(), diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index 0375bb3e..151891a2 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -336,8 +336,8 @@ bool Editor::saveAs(const QString &name, bool fromProject){ } // Update project information if (mInProject && pMainWindow->project() && !fromProject) { - int unitIndex = pMainWindow->project()->indexInUnits(newName); - if (unitIndex<0) { + int unitId = pMainWindow->project()->findUnitId(newName); + if (unitId<0) { mInProject = false; } } @@ -423,9 +423,8 @@ void Editor::setEncodingOption(const QByteArray& encoding) noexcept{ if (mInProject) { std::shared_ptr project = pMainWindow->project(); if (project) { - int index = project->indexInUnits(this); - if (index>=0) { - PProjectUnit unit = project->units()[index]; + PProjectUnit unit = project->findUnit(this); + if (unit) { unit->setEncoding(mEncodingOption); } } @@ -1740,7 +1739,7 @@ bool Editor::isBraceChar(QChar ch) bool Editor::shouldOpenInReadonly() { - if (pMainWindow->project() && pMainWindow->project()->findUnitByFilename(mFilename)) + if (pMainWindow->project() && pMainWindow->project()->findUnit(mFilename)) return false; return pSettings->editor().readOnlySytemHeader() && mParser && (mParser->isSystemHeaderFile(mFilename) || mParser->isProjectHeaderFile(mFilename)); diff --git a/RedPandaIDE/editorlist.cpp b/RedPandaIDE/editorlist.cpp index a626b4e7..1d7c789e 100644 --- a/RedPandaIDE/editorlist.cpp +++ b/RedPandaIDE/editorlist.cpp @@ -56,7 +56,7 @@ Editor* EditorList::newEditor(const QString& filename, const QByteArray& encodin connect(e, &Editor::renamed, this, &EditorList::onEditorRenamed); updateLayout(); if (pMainWindow->project()){ - PProjectUnit unit = pMainWindow->project()->findUnitByFilename(filename); + PProjectUnit unit = pMainWindow->project()->findUnit(filename); if (unit) { pMainWindow->project()->associateEditorToUnit(e,unit); e->setInProject(true); @@ -169,9 +169,9 @@ bool EditorList::closeEditor(Editor* editor, bool transferFocus, bool force) { // } if (editor->inProject() && pMainWindow->project()) { - int projIndex = pMainWindow->project()->indexInUnits(editor); - if (projIndex>=0) { - pMainWindow->project()->closeUnit(projIndex); + int unitId = pMainWindow->project()->findUnitId(editor); + if (unitId>=0) { + pMainWindow->project()->closeUnit(unitId); } } else { if (pSettings->history().addToOpenedFiles(editor->filename())) { diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index fd7aa524..45ebb9e9 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -1186,7 +1186,7 @@ void MainWindow::openFile(const QString &filename, bool activate, QTabWidget* pa pSettings->history().removeFile(filename); PProjectUnit unit; if (mProject) { - unit = mProject->findUnitByFilename(filename); + unit = mProject->findUnit(filename); } bool inProject = (mProject && unit); QByteArray encoding = unit ? unit->encoding() : @@ -1260,8 +1260,7 @@ void MainWindow::openProject(const QString &filename, bool openFiles) mProject->doAutoOpen(); //update editor's inproject flag - for (int i=0;iunits().count();i++) { - PProjectUnit unit = mProject->units()[i]; + foreach (PProjectUnit unit, mProject->unitList()) { Editor* e = mEditorList->getOpenedEditorByFilename(unit->fileName()); mProject->associateEditorToUnit(e,unit); } @@ -2214,7 +2213,7 @@ void MainWindow::loadLastOpens() page = mEditorList->rightPageWidget(); PProjectUnit unit; if (mProject) { - unit = mProject->findUnitByFilename(editorFilename); + unit = mProject->findUnit(editorFilename); } bool inProject = (mProject && unit); QByteArray encoding = unit ? unit->encoding() : @@ -3022,7 +3021,7 @@ void MainWindow::onProjectViewContextMenu(const QPoint &pos) shouldAdd=false; break; } - PProjectUnit pUnit=mProject->units()[node->unitIndex]; + PProjectUnit pUnit=mProject->findUnitById(node->unitIndex); if (mProject->model()->iconProvider()->VCSRepository()->isFileInRepository( pUnit->fileName() ) @@ -3919,7 +3918,7 @@ void MainWindow::onProjectAddFolder() QLineEdit::Normal, s, &ok).trimmed(); if (ok && !s.isEmpty()) { - QString path = mProject->getFolderPath(folderNode); + QString path = mProject->getNodePath(folderNode); if (path.isEmpty()) { mProject->addFolder(s); } else { @@ -5915,10 +5914,9 @@ void MainWindow::on_actionAdd_to_project_triggered() ); } } - mProject->rebuildNodes(); mProject->saveUnits(); + updateProjectActions(); parseFileList(mProject->cppParser()); - updateProjectView(); } } @@ -5929,8 +5927,11 @@ void MainWindow::on_actionRemove_from_project_triggered() return; if (!ui->projectView->selectionModel()->hasSelection()) return; - mProject->model()->beginUpdate(); - QSet selected; + + bool removeFile = (QMessageBox::question(this,tr("Remove file"), + tr("Remove the file from disk?"), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes); + foreach (const QModelIndex& index, ui->projectView->selectionModel()->selectedIndexes()){ if (!index.isValid()) continue; @@ -5939,22 +5940,10 @@ void MainWindow::on_actionRemove_from_project_triggered() PProjectModelNode folderNode = mProject->pointerToNode(node); if (!folderNode) continue; - selected.insert(folderNode->unitIndex); + mProject->removeUnit(folderNode->unitIndex, true, removeFile); }; - - bool removeFile = (QMessageBox::question(this,tr("Remove file"), - tr("Remove the file from disk?"), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes); - - for (int i=mProject->units().count()-1;i>=0;i--) { - if (selected.contains(i)) { - mProject->removeUnit(i,true,removeFile); - } - } - mProject->saveUnits(); - mProject->model()->endUpdate(); - updateProjectView(); + updateProjectActions(); } @@ -6135,7 +6124,6 @@ void MainWindow::newProjectUnitFile() { if (!mProject) return; - int idx = -1; QModelIndex current = mProjectProxyModel->mapToSource(ui->projectView->currentIndex()); ProjectModelNode * node = nullptr; if (current.isValid()) { @@ -6217,11 +6205,11 @@ void MainWindow::newProjectUnitFile() newUnit = mProject->newUnit( pNode,newFileName); - mProject->rebuildNodes(); +// mProject->rebuildNodes(); mProject->saveAll(); - updateProjectView(); - idx = mProject->units().count()-1; - Editor * editor = mProject->openUnit(idx, false); +// updateProjectView(); +// idx = newUnit->id; + Editor * editor = mProject->openUnit(newUnit->id(), false); //editor->setUseCppSyntax(mProject->options().useGPP); //editor->setModified(true); if (editor) @@ -6233,7 +6221,7 @@ void MainWindow::newProjectUnitFile() mProject->model()->beginUpdate(); mProject->model()->endUpdate(); } - updateProjectView(); + updateProjectActions(); } void MainWindow::fillProblemCaseInputAndExpected(const POJProblemCase &problemCase) @@ -7484,7 +7472,7 @@ void MainWindow::on_actionGit_Create_Repository_triggered() QString output; vcsManager.add(mProject->folder(), extractFileName(mProject->filename()), output); vcsManager.add(mProject->folder(), extractFileName(mProject->options().icon), output); - foreach (PProjectUnit pUnit, mProject->units()) { + foreach (PProjectUnit pUnit, mProject->unitList()) { vcsManager.add(mProject->folder(),extractRelativePath(mProject->folder(),pUnit->fileName()),output); } //update project view @@ -7528,7 +7516,7 @@ void MainWindow::on_actionGit_Add_Files_triggered() if (!folderNode) continue; if (folderNode->unitIndex>=0) { - PProjectUnit unit = mProject->units()[folderNode->unitIndex]; + PProjectUnit unit = mProject->findUnitById(folderNode->unitIndex); QFileInfo info(unit->fileName()); QString output; vcsManager.add(info.absolutePath(),info.fileName(),output); diff --git a/RedPandaIDE/mainwindow.ui b/RedPandaIDE/mainwindow.ui index b1a08985..301dca55 100644 --- a/RedPandaIDE/mainwindow.ui +++ b/RedPandaIDE/mainwindow.ui @@ -473,7 +473,7 @@ QTabWidget::West - 4 + 1 true diff --git a/RedPandaIDE/project.cpp b/RedPandaIDE/project.cpp index f91aab0b..06be81cd 100644 --- a/RedPandaIDE/project.cpp +++ b/RedPandaIDE/project.cpp @@ -190,9 +190,12 @@ void Project::open() } newUnit->setNew(false); newUnit->setParent(this); - newUnit->setNode(makeNewFileNode(extractFileName(newUnit->fileName()), false, folderNodeFromName(newUnit->folder()))); - newUnit->node()->unitIndex = mUnits.count(); - mUnits.append(newUnit); + PProjectModelNode node = makeNewFileNode(extractFileName(newUnit->fileName()), + newUnit->id(), + newUnit->priority(), + folderNodeFromName(newUnit->folder())); + newUnit->setNode(node); + mUnits.insert(newUnit->id(),newUnit); } rebuildNodes(); } @@ -215,7 +218,9 @@ void Project::setModified(bool value) } } -PProjectModelNode Project::makeNewFileNode(const QString &s, bool isFolder, PProjectModelNode newParent) +PProjectModelNode Project::makeNewFolderNode( + const QString &folderName, PProjectModelNode newParent, + ProjectModelNodeType nodeType,int priority) { PProjectModelNode node = std::make_shared(); if (!newParent) { @@ -223,17 +228,35 @@ PProjectModelNode Project::makeNewFileNode(const QString &s, bool isFolder, PPro } newParent->children.append(node); node->parent = newParent; - node->text = s; + node->text = folderName; if (newParent) { node->level = newParent->level+1; } - if (isFolder) { - node->unitIndex = -1; - node->priority = 0; - node->folderNodeType = ProjectModelNodeType::Folder; - } else { - node->folderNodeType = ProjectModelNodeType::File; + node->unitIndex = -1; + node->priority = priority; + node->folderNodeType = nodeType; + QModelIndex parentIndex=mModel.getNodeIndex(newParent.get()); + mModel.insertRow(newParent->children.count(),parentIndex); + return node; +} + +PProjectModelNode Project::makeNewFileNode(const QString &fileName, int unitId,int priority, PProjectModelNode newParent) +{ + PProjectModelNode node = std::make_shared(); + if (!newParent) { + newParent = mRootNode; } + newParent->children.append(node); + node->parent = newParent; + node->text = fileName; + if (newParent) { + node->level = newParent->level+1; + } + node->unitIndex = unitId; + node->priority = priority; + node->folderNodeType = ProjectModelNodeType::File; + QModelIndex parentIndex=mModel.getNodeIndex(newParent.get()); + mModel.insertRow(newParent->children.count(),parentIndex); return node; } @@ -269,16 +292,17 @@ PProjectUnit Project::newUnit(PProjectModelNode parentNode, const QString& custo s = dir.absoluteFilePath(customFileName); } // Add - int count = mUnits.count(); - mUnits.append(newUnit); // Set all properties newUnit->setFileName(s); newUnit->setNew(true); - newUnit->setFolder(getFolderPath(parentNode)); - newUnit->setNode(makeNewFileNode(extractFileName(newUnit->fileName()), - false, parentNode)); - newUnit->node()->unitIndex = count; + newUnit->setFolder(getNodePath(parentNode)); + PProjectModelNode node = makeNewFileNode(extractFileName(newUnit->fileName()), + newUnit->id(),newUnit->priority(),parentNode); + node->unitIndex = newUnit->id(); + newUnit->setNode(node); + mUnits.insert(newUnit->id(), newUnit); + //parentNode.Expand(True); switch(getFileType(customFileName)) { case FileType::CSource: @@ -311,10 +335,10 @@ PProjectUnit Project::newUnit(PProjectModelNode parentNode, const QString& custo Editor *Project::openUnit(int index, bool forceOpen) { - if ((index < 0) || (index >= mUnits.count())) - return nullptr; - PProjectUnit unit = mUnits[index]; + PProjectUnit unit = mUnits.value(index,PProjectUnit()); + if (!unit) + return nullptr; if (!unit->fileName().isEmpty() && fileExists(unit->fileName())) { if (getFileType(unit->fileName())==FileType::Other) { @@ -353,6 +377,15 @@ Editor *Project::unitEditor(const ProjectUnit *unit) const return mEditorList->getOpenedEditorByFilename(unit->fileName()); } +QList Project::unitList() +{ + QList units; + foreach(PProjectUnit unit, mUnits) { + units.append(unit); + } + return units; +} + void Project::rebuildNodes() { mModel.beginUpdate(); @@ -366,35 +399,34 @@ void Project::rebuildNodes() switch(mOptions.modelType) { case ProjectModelType::Custom: createFolderNodes(); - - for (int idx=0;idxfileName()); - mUnits[idx]->setNode( + foreach (PProjectUnit pUnit, mUnits) { + QFileInfo fileInfo(pUnit->fileName()); + pUnit->setNode( makeNewFileNode( fileInfo.fileName(), - false, - folderNodeFromName(mUnits[idx]->folder()) + pUnit->id(), + pUnit->priority(), + folderNodeFromName(pUnit->folder()) ) ); - mUnits[idx]->node()->unitIndex = idx; - mUnits[idx]->node()->priority = mUnits[idx]->priority(); + pUnit->node()->priority = pUnit->priority(); } break; case ProjectModelType::FileSystem: createFileSystemFolderNodes(); - for (int idx=0;idxfileName()); - mUnits[idx]->setNode( + foreach (PProjectUnit pUnit, mUnits) { + QFileInfo fileInfo(pUnit->fileName()); + pUnit->setNode( makeNewFileNode( fileInfo.fileName(), - false, + pUnit->id(), + pUnit->priority(), getParentFolderNode( - mUnits[idx]->fileName()) + pUnit->fileName()) ) ); - mUnits[idx]->node()->unitIndex = idx; - mUnits[idx]->node()->priority = mUnits[idx]->priority(); + pUnit->node()->priority = pUnit->priority(); } break; @@ -404,17 +436,12 @@ void Project::rebuildNodes() emit nodesChanged(); } -bool Project::removeUnit(int index, bool doClose , bool removeFile) +bool Project::removeUnit(int id, bool doClose , bool removeFile) { - mModel.beginUpdate(); - auto action = finally([this]{ - mModel.endUpdate(); - }); - if (index<0 || index>=mUnits.count()) + PProjectUnit unit = findUnitById(id); + if (!unit) return false; - PProjectUnit unit = mUnits[index]; - // qDebug()<fileName(); // qDebug()<<(qint64)unit->editor(); // Attempt to close it @@ -432,12 +459,20 @@ bool Project::removeUnit(int index, bool doClose , bool removeFile) //if not fUnits.GetItem(index).fNew then PProjectModelNode node = unit->node(); - PProjectModelNode parent = node->parent.lock(); - if (parent) { - parent->children.removeAll(node); - } - mUnits.removeAt(index); - updateNodeIndexes(); + PProjectModelNode parentNode = node->parent.lock(); + if (!parentNode) + return true; + QModelIndex parentIndex = mModel.getParentIndex(unit->node().get()); + + int row = parentNode->children.indexOf(unit->node()); + if (row<0) + return true; + parentNode->children.removeAt(row); + + mUnits.remove(unit->id()); + + mModel.removeRow(row,parentIndex); + setModified(true); return true; } @@ -495,7 +530,7 @@ void Project::saveLayout() for (int i=0;ipageCount();i++) { Editor* e= (*mEditorList)[i]; if (e && e->inProject()) - sl.append(QString("%1").arg(indexInUnits(e))); + sl.append(QString("%1").arg(findUnitId(e))); } layIni.SetValue("Editors","Order",sl.join(",").toUtf8()); @@ -503,11 +538,10 @@ void Project::saveLayout() // Remember what files were visible mEditorList->getVisibleEditors(e, e2); if (e) - layIni.SetLongValue("Editors","Focused", indexInUnits(e)); + layIni.SetLongValue("Editors","Focused", findUnitId(e)); // save editor info - for (int i=0;iid()).toUtf8(); Editor* editor = unitEditor(unit); if (editor) { layIni.SetLongValue(groupName,"CursorCol", editor->caretX()); @@ -530,51 +564,22 @@ void Project::saveLayout() layIni.SaveFile(changeFileExt(filename(), "layout").toLocal8Bit()); } -void Project::saveUnitAs(int i, const QString &sFileName, bool syncEditor) +void Project::renameUnit(int idx, const QString &sFileName) { - if ((i < 0) || (i >= mUnits.count())) + PProjectUnit unit = findUnitById(idx); + if (!unit) return; - PProjectUnit unit = mUnits[i]; if (fileExists(unit->fileName())) { unit->setNew(false); } Editor * editor=unitEditor(unit); - if (editor && syncEditor) { + if (editor) { //prevent recurse editor->saveAs(sFileName,true); } unit->setNew(false); unit->setFileName(sFileName); - SimpleIni ini; - ini.LoadFile(mFilename.toLocal8Bit()); - QByteArray groupName = toByteArray(QString("Unit%1").arg(i+1)); - ini.SetValue( - groupName, - "FileName", - toByteArray( - extractRelativePath( - directory(), - sFileName))); - ini.SaveFile(mFilename.toLocal8Bit()); setModified(true); - if (!syncEditor) { - //the call it's from editor, we need to update model - mModel.beginUpdate(); - mModel.endUpdate(); - } -} - -void Project::saveUnitLayout(Editor *e, int index) -{ - if (!e) - return; - SimpleIni layIni; - QByteArray groupName = (QString("Editor_%1").arg(index)).toUtf8(); - layIni.SetLongValue(groupName,"CursorCol", e->caretX()); - layIni.SetLongValue(groupName,"CursorRow", e->caretY()); - layIni.SetLongValue(groupName,"TopLine", e->topLine()); - layIni.SetLongValue(groupName,"LeftChar", e->leftChar()); - layIni.SaveFile((changeFileExt(filename(), "layout")).toLocal8Bit()); } bool Project::saveUnits() @@ -584,9 +589,10 @@ bool Project::saveUnits() SI_Error error = ini.LoadFile(mFilename.toLocal8Bit()); if (error != SI_Error::SI_OK) return false; - for (int idx = 0; idx < mUnits.count(); idx++) { - PProjectUnit unit = mUnits[idx]; - QByteArray groupName = toByteArray(QString("Unit%1").arg(count+1)); + int i=0; + foreach (const PProjectUnit& unit, mUnits) { + i++; + QByteArray groupName = toByteArray(QString("Unit%1").arg(i)); if (!unit->FileMissing()) { bool rd_only = false; if (unit->modified() && fileExists(unit->fileName()) @@ -642,7 +648,12 @@ bool Project::saveUnits() return true; } -PProjectUnit Project::findUnitByFilename(const QString &filename) +PProjectUnit Project::findUnitById(int id) +{ + return mUnits.value(id,PProjectUnit()); +} + +PProjectUnit Project::findUnit(const QString &filename) { foreach(PProjectUnit unit, mUnits) { if (QString::compare(unit->fileName(),filename, PATH_SENSITIVITY)==0) @@ -651,11 +662,16 @@ PProjectUnit Project::findUnitByFilename(const QString &filename) return PProjectUnit(); } -void Project::associateEditor(Editor *editor) +PProjectUnit Project::findUnit(const Editor *editor) { if (!editor) - return; - PProjectUnit unit = findUnitByFilename(editor->filename()); + return PProjectUnit(); + return findUnit(editor->filename()); +} + +void Project::associateEditor(Editor *editor) +{ + PProjectUnit unit = findUnit(editor); associateEditorToUnit(editor,unit); } @@ -718,21 +734,16 @@ void Project::updateFolders() { mFolders.clear(); updateFolderNode(mRootNode); - for (int idx = 0; idx < mUnits.count();idx++) - mUnits[idx]->setFolder( - getFolderPath( - mUnits[idx]->node()->parent.lock() + foreach (PProjectUnit unit, mUnits) { + unit->setFolder( + getNodePath( + unit->node()->parent.lock() ) ); + } setModified(true); } -void Project::updateNodeIndexes() -{ - for (int idx = 0;idxnode()->unitIndex = idx; -} - PProjectModelNode Project::pointerToNode(ProjectModelNode *p, PProjectModelNode parent) { if (!p) @@ -906,8 +917,8 @@ bool Project::saveAsTemplate(const QString &templateFolder, if (mOptions.modelType!=ProjectModelType::FileSystem) ini->SetLongValue("Project", "ModelType", (int)mOptions.modelType); - for (int i=0;ifileName()); QByteArray section = toByteArray(QString("Unit%1").arg(i)); if (!copyFile(unit->fileName(), dir.absoluteFilePath(unitName),true)) { @@ -936,6 +947,7 @@ bool Project::saveAsTemplate(const QString &templateFolder, ini->SetValue(section,"Source", unitName.toUtf8()); ini->SetValue(section,"Target", unitName.toUtf8()); } + i++; } ini->SetLongValue("Project","UnitCount",mUnits.count()); if (ini->SaveFile(fileName.toLocal8Bit())!=SI_OK) { @@ -1066,10 +1078,13 @@ PProjectUnit Project::addUnit(const QString &inFileName, PProjectModelNode paren } else { newUnit->setEncoding(options().encoding.toUtf8()); } - newUnit->setFolder(getFolderPath(parentNode)); - newUnit->setNode(makeNewFileNode(extractFileName(newUnit->fileName()), false, parentNode)); - newUnit->node()->unitIndex = mUnits.count(); - mUnits.append(newUnit); + newUnit->setFolder(getNodePath(parentNode)); + PProjectModelNode node = makeNewFileNode(extractFileName(newUnit->fileName()), + newUnit->id(), + newUnit->priority(), parentNode); + node->unitIndex = newUnit->id(); + newUnit->setNode(node); + mUnits.insert(newUnit->id(),newUnit); // Determine compilation flags switch(getFileType(inFileName)) { @@ -1436,12 +1451,11 @@ void Project::checkProjectFileForUpdate(SimpleIni &ini) QMessageBox::Ok); } -void Project::closeUnit(int index) +void Project::closeUnit(int id) { - PProjectUnit unit = mUnits[index]; + PProjectUnit unit = findUnitById(id); Editor * editor =unitEditor(unit); if (editor) { - saveUnitLayout(editor,index); editor->setInProject(false); mEditorList->forceCloseEditor(editor); } @@ -1460,14 +1474,14 @@ void Project::createFolderNodes() findnode = node->children[c]; } if (!findnode) - node = makeNewFileNode(s.mid(0,i),true,node); + node = makeNewFolderNode(s.mid(0,i),node); else node = findnode; node->unitIndex = -1; s.remove(0,i+1); i = s.indexOf('/'); } - node = makeNewFileNode(s, true, node); + node = makeNewFolderNode(s, node); node->unitIndex = -1; mFolderNodes.append(node); } @@ -1488,8 +1502,8 @@ void Project::createFileSystemFolderNodes() QSet headerFolders; QSet sourceFolders; QSet otherFolders; - for (int idx=0;idxfileName()); + foreach (const PProjectUnit& unit, mUnits) { + QFileInfo fileInfo(unit->fileName()); if (isHFile(fileInfo.fileName())) { addFolderRecursively(headerFolders,fileInfo.absolutePath()); } else if (isCFile(fileInfo.fileName())) { @@ -1498,23 +1512,26 @@ void Project::createFileSystemFolderNodes() addFolderRecursively(otherFolders,fileInfo.absolutePath()); } } - PProjectModelNode node = makeNewFileNode(tr("Headers"),true,mRootNode); - node->folderNodeType = ProjectModelNodeType::DUMMY_HEADERS_FOLDER; - node->priority = 1000; + PProjectModelNode node = makeNewFolderNode(tr("Headers"), + mRootNode, + ProjectModelNodeType::DUMMY_HEADERS_FOLDER, + 1000); createFileSystemFolderNode(ProjectModelNodeType::DUMMY_HEADERS_FOLDER,folder(),node, headerFolders); mFolderNodes.append(node); mSpecialNodes.insert(ProjectModelNodeType::DUMMY_HEADERS_FOLDER,node); - node = makeNewFileNode(tr("Sources"),true,mRootNode); - node->folderNodeType = ProjectModelNodeType::DUMMY_SOURCES_FOLDER; - node->priority = 900; + node = makeNewFolderNode(tr("Sources"), + mRootNode, + ProjectModelNodeType::DUMMY_SOURCES_FOLDER, + 900); createFileSystemFolderNode(ProjectModelNodeType::DUMMY_SOURCES_FOLDER,folder(),node, sourceFolders); mFolderNodes.append(node); mSpecialNodes.insert(ProjectModelNodeType::DUMMY_SOURCES_FOLDER,node); - node = makeNewFileNode(tr("Others"),true,mRootNode); - node->folderNodeType = ProjectModelNodeType::DUMMY_OTHERS_FOLDER; - node->priority = 800; + node = makeNewFolderNode(tr("Others"), + mRootNode, + ProjectModelNodeType::DUMMY_OTHERS_FOLDER, + 800); createFileSystemFolderNode(ProjectModelNodeType::DUMMY_OTHERS_FOLDER,folder(),node, otherFolders); mFolderNodes.append(node); mSpecialNodes.insert(ProjectModelNodeType::DUMMY_OTHERS_FOLDER,node); @@ -1533,7 +1550,7 @@ void Project::createFileSystemFolderNode( if (fileInfo.isHidden() || fileInfo.fileName().startsWith('.')) continue; if (fileInfo.isDir() && validFolders.contains(fileInfo.absoluteFilePath())) { - PProjectModelNode node = makeNewFileNode(fileInfo.fileName(),true,parent); + PProjectModelNode node = makeNewFolderNode(fileInfo.fileName(),parent); mFileSystemFolderNodes.insert(QString("%1/%2").arg((int)folderType).arg(fileInfo.absoluteFilePath()),node); createFileSystemFolderNode(folderType,fileInfo.absoluteFilePath(), node, validFolders); } @@ -1575,7 +1592,7 @@ PProjectModelNode Project::folderNodeFromName(const QString &name) return mRootNode; } -QString Project::getFolderPath(PProjectModelNode node) +QString Project::getNodePath(PProjectModelNode node) { QString result; if (!node) @@ -1597,7 +1614,7 @@ QString Project::getFolderPath(PProjectModelNode node) int Project::getUnitFromString(const QString &s) { - return indexInUnits(s); + return findUnitId(s); } PProjectModelNode Project::getParentFolderNode(const QString &filename) @@ -1651,8 +1668,9 @@ void Project::loadLayout() openUnit(currIdx); } } - if (topLeft>=0 && topLeftactivate(); } @@ -1919,22 +1937,21 @@ PCppParser Project::cppParser() return mParser; } -int Project::indexInUnits(const QString &fileName) const +int Project::findUnitId(const QString &fileName) const { QDir dir(directory()); - for (int i=0;ifileName())) - return i; + return unit->id(); } return -1; } -int Project::indexInUnits(const Editor *editor) const +int Project::findUnitId(const Editor *editor) const { if (!editor) return -1; - return indexInUnits(editor->filename()); + return findUnitId(editor->filename()); } void Project::removeFolderRecurse(PProjectModelNode node) @@ -1967,7 +1984,7 @@ void Project::updateFolderNode(PProjectModelNode node) for (int i=0;ichildren.count();i++){ PProjectModelNode child = node->children[i]; if (child->unitIndex<0) { - mFolders.append(getFolderPath(child)); + mFolders.append(getNodePath(child)); updateFolderNode(child); } } @@ -2020,11 +2037,6 @@ EditorList *Project::editorList() const return mEditorList; } -const QList &Project::units() const -{ - return mUnits; -} - ProjectModelType Project::modelType() const { return mOptions.modelType; @@ -2072,11 +2084,15 @@ const QString &Project::filename() const return mFilename; } +int ProjectUnit::mIdGenerator=0; + ProjectUnit::ProjectUnit(Project* parent) { mNode = nullptr; mParent = parent; mFileMissing = false; + mId=mIdGenerator++; + mPriority=0; } Project *ProjectUnit::parent() const @@ -2270,6 +2286,16 @@ void ProjectUnit::setFileMissing(bool newDontSave) mFileMissing = newDontSave; } +int ProjectUnit::id() const +{ + return mId; +} + +void ProjectUnit::setId(int newId) +{ + mId = newId; +} + ProjectModel::ProjectModel(Project *project, QObject *parent): QAbstractItemModel(parent), mProject(project) @@ -2305,6 +2331,23 @@ CustomFileIconProvider *ProjectModel::iconProvider() const return mIconProvider; } +bool ProjectModel::insertRows(int row, int count, const QModelIndex &parent) +{ + qDebug()<<"insert rows"; + qDebug()<unitIndex>=0) { - icon = mIconProvider->icon(mProject->units()[p->unitIndex]->fileName()); + icon = mIconProvider->icon(mProject->findUnitById(p->unitIndex)->fileName()); } else { if (p == mProject->rootNode().get()) { QString branch; @@ -2440,7 +2483,7 @@ bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int int idx = node->unitIndex; if (idx >= 0) { //change unit name - PProjectUnit unit = mProject->units()[idx]; + PProjectUnit unit = mProject->findUnitById(idx); QString newName = value.toString().trimmed(); if (newName.isEmpty()) return false; @@ -2464,7 +2507,7 @@ bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int mProject->editorList()->closeEditor(e); // Remove it from the current project... - int projindex = mProject->indexInUnits(newName); + int projindex = mProject->findUnitId(newName); if (projindex>=0) { mProject->removeUnit(projindex,false); } @@ -2496,7 +2539,7 @@ bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int QMessageBox::Ok); return false; } - mProject->saveUnitAs(idx,newName); + mProject->renameUnit(idx,newName); // Add new filename to file minitor mProject->fileSystemWatcher()->addPath(newName); @@ -2528,9 +2571,11 @@ bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int QModelIndex ProjectModel::getNodeIndex(ProjectModelNode *node) const { + if (!node) + return QModelIndex(); PProjectModelNode parent = node->parent.lock(); if (!parent) // root node - return QModelIndex(); + return createIndex(0,0,node); int row = -1; for (int i=0;ichildren.count();i++) { const PProjectModelNode& pNode=parent->children[i]; @@ -2648,8 +2693,8 @@ bool ProjectModel::dropMimeData(const QMimeData *data, Qt::DropAction action, in droppedNode->parent = node; node->children.append(droppedNode); if (droppedNode->unitIndex>=0) { - PProjectUnit unit = mProject->units()[droppedNode->unitIndex]; - unit->setFolder(mProject->getFolderPath(node)); + PProjectUnit unit = mProject->findUnitById(droppedNode->unitIndex); + unit->setFolder(mProject->getNodePath(node)); } QModelIndex newParentIndex = getParentIndex(droppedPointer); beginInsertRows(newParentIndex,node->children.count()-1,node->children.count()-1); @@ -2678,7 +2723,7 @@ QMimeData *ProjectModel::mimeData(const QModelIndexList &indexes) const stream << (qint32)((*it).row()) << (qint32)((*it).column()) << (quintptr)((*it).internalPointer()); ProjectModelNode* p = static_cast((*it).internalPointer()); if (p && p->unitIndex>=0) { - urls.append(QUrl::fromLocalFile(mProject->units()[p->unitIndex]->fileName())); + urls.append(QUrl::fromLocalFile(mProject->findUnitById(p->unitIndex)->fileName())); } } if (!urls.isEmpty()) diff --git a/RedPandaIDE/project.h b/RedPandaIDE/project.h index cdfe19cb..ece8e176 100644 --- a/RedPandaIDE/project.h +++ b/RedPandaIDE/project.h @@ -18,6 +18,8 @@ #define PROJECT_H #include +#include +#include #include #include #include "projectoptions.h" @@ -37,6 +39,11 @@ enum ProjectModelNodeType { File }; +struct ProjectModelItemRecord { + ProjectModelNodeType type; + QString fullPath; +}; + struct ProjectModelNode; using PProjectModelNode = std::shared_ptr; struct ProjectModelNode { @@ -85,6 +92,10 @@ public: bool FileMissing() const; void setFileMissing(bool newDontSave); + int id() const; + + void setId(int newId); + private: Project* mParent; QString mFileName; @@ -99,6 +110,8 @@ private: QByteArray mEncoding; PProjectModelNode mNode; bool mFileMissing; + int mId; + static int mIdGenerator; }; using PProjectUnit = std::shared_ptr; @@ -129,9 +142,9 @@ public: bool setData(const QModelIndex &index, const QVariant &value, int role) override; QModelIndex getNodeIndex(ProjectModelNode *node) const; + QModelIndex getParentIndex(ProjectModelNode * node) const; private: - QModelIndex getParentIndex(ProjectModelNode * node) const; // QAbstractItemModel interface public: @@ -141,6 +154,11 @@ public: QMimeData *mimeData(const QModelIndexList &indexes) const override; Project *project() const; CustomFileIconProvider *iconProvider() const; + + // QAbstractItemModel interface +public: + bool insertRows(int row, int count, const QModelIndex &parent) override; + bool removeRows(int row, int count, const QModelIndex &parent) override; }; class ProjectModelSortFilterProxy : public QSortFilterProxyModel @@ -177,44 +195,51 @@ public: bool rebuild); QString folder(); void buildPrivateResource(bool forceSave=false); - void closeUnit(int index); + void closeUnit(int id); void doAutoOpen(); bool fileAlreadyExists(const QString& s); - QString getFolderPath(PProjectModelNode node); + QString getNodePath(PProjectModelNode node); int getUnitFromString(const QString& s); void incrementBuildNumber(); - int indexInUnits(const QString& fileName) const; - int indexInUnits(const Editor* editor) const; + PProjectUnit newUnit(PProjectModelNode parentNode, const QString& customFileName=""); Editor* openUnit(int index, bool forceOpen=true); Editor* unitEditor(const PProjectUnit& unit) const; Editor* unitEditor(const ProjectUnit* unit) const; - Editor* unitEditor(int index) const { - if (index<0 || index>=mUnits.count()) + Editor* unitEditor(int id) const { + PProjectUnit unit=mUnits.value(id,PProjectUnit()); + if (!unit) return nullptr; - return unitEditor(mUnits[index]); + return unitEditor(unit); } + + QList unitList(); + PProjectModelNode pointerToNode(ProjectModelNode * p, PProjectModelNode parent=PProjectModelNode()); void rebuildNodes(); - bool removeUnit(int index, bool doClose, bool removeFile = false); + bool removeUnit(int id, bool doClose, bool removeFile = false); bool removeFolder(PProjectModelNode node); void resetParserProjectFiles(); void saveAll(); // save [Project] and all [UnitX] void saveLayout(); // save all [UnitX] void saveOptions(); - void saveUnitAs(int i, const QString& sFileName, bool syncEditor = true); // save single [UnitX] + void renameUnit(int idx, const QString& sFileName); bool saveUnits(); - PProjectUnit findUnitByFilename(const QString& filename); + PProjectUnit findUnitById(int id); + PProjectUnit findUnit(const QString& filename); + PProjectUnit findUnit(const Editor* editor); + + int findUnitId(const QString& fileName) const; + int findUnitId(const Editor* editor) const; void associateEditor(Editor* editor); void associateEditorToUnit(Editor* editor, PProjectUnit unit); bool setCompileOption(const QString &key, const QString &value); QString getCompileOption(const QString &key) const; void updateFolders(); - void updateNodeIndexes(); void setCompilerSet(int compilerSetIndex); bool assignTemplate(const std::shared_ptr aTemplate, bool useCpp); @@ -235,8 +260,6 @@ public: ProjectModel* model() ; - const QList &units() const; - ProjectModelType modelType() const; void setModelType(ProjectModelType type); @@ -263,16 +286,24 @@ private: void loadLayout(); // load all [UnitX] void loadUnitLayout(Editor *e, int index); // load single [UnitX] cursor positions - PProjectModelNode makeNewFileNode(const QString& s, bool isFolder, PProjectModelNode newParent); + PProjectModelNode makeNewFolderNode( + const QString& folderName, + PProjectModelNode newParent, + ProjectModelNodeType nodeType=ProjectModelNodeType::Folder, + int priority=0); + PProjectModelNode makeNewFileNode( + const QString& fileName, + int unitId, + int priority, + PProjectModelNode newParent); PProjectModelNode makeProjectNode(); void open(); void removeFolderRecurse(PProjectModelNode node); - void saveUnitLayout(Editor* e, int index); // save single [UnitX] cursor positions void updateFolderNode(PProjectModelNode node); void updateCompilerSetType(); private: - QList mUnits; + QHash mUnits; ProjectOptions mOptions; QString mFilename; QString mName; diff --git a/RedPandaIDE/settingsdialog/projectfileswidget.cpp b/RedPandaIDE/settingsdialog/projectfileswidget.cpp index 3039b698..494b2db1 100644 --- a/RedPandaIDE/settingsdialog/projectfileswidget.cpp +++ b/RedPandaIDE/settingsdialog/projectfileswidget.cpp @@ -47,7 +47,7 @@ void ProjectFilesWidget::doSave() { for (int i=0;iproject()->units()[i]; + PProjectUnit unit = pMainWindow->project()->findUnitById(unitCopy->id()); unit->setPriority(unitCopy->priority()); unit->setCompile(unitCopy->compile()); unit->setLink(unitCopy->link()); @@ -70,11 +70,14 @@ PProjectUnit ProjectFilesWidget::currentUnit() ProjectModelNode* node = static_cast(index.internalPointer()); if (!node) return PProjectUnit(); - int i = node->unitIndex; - if (i>=0) { - return mUnits[i]; - } else - return PProjectUnit(); + int idx = node->unitIndex; + if (idx>=0) { + foreach (PProjectUnit unit, mUnits) { + if (unit->id() == idx) + return unit; + } + } + return PProjectUnit(); } void ProjectFilesWidget::copyUnits() @@ -83,8 +86,9 @@ void ProjectFilesWidget::copyUnits() if (!project) return; mUnits.clear(); - foreach (const PProjectUnit& unit, project->units()) { + foreach (const PProjectUnit& unit, project->unitList()) { PProjectUnit unitCopy = std::make_shared(project.get()); + unitCopy->setId(unit->id()); unitCopy->setPriority(unit->priority()); unitCopy->setCompile(unit->compile()); unitCopy->setLink(unit->link()); diff --git a/RedPandaIDE/settingsdialog/projectgeneralwidget.cpp b/RedPandaIDE/settingsdialog/projectgeneralwidget.cpp index 8276127a..9401dd8e 100644 --- a/RedPandaIDE/settingsdialog/projectgeneralwidget.cpp +++ b/RedPandaIDE/settingsdialog/projectgeneralwidget.cpp @@ -57,7 +57,7 @@ void ProjectGeneralWidget::doLoad() ui->txtOutputFile->setText(project->executable()); int srcCount=0,headerCount=0,resCount=0,otherCount=0, totalCount=0; - foreach (const PProjectUnit& unit, project->units()) { + foreach (const PProjectUnit& unit, project->unitList()) { switch(getFileType(unit->fileName())) { case FileType::CSource: case FileType::CppSource: diff --git a/RedPandaIDE/widgets/searchdialog.cpp b/RedPandaIDE/widgets/searchdialog.cpp index c7a3de25..e9a70beb 100644 --- a/RedPandaIDE/widgets/searchdialog.cpp +++ b/RedPandaIDE/widgets/searchdialog.cpp @@ -362,9 +362,9 @@ void SearchDialog::on_btnExecute_clicked() mSearchOptions, SearchFileScope::wholeProject ); - for (int i=0;iproject()->units().count();i++) { - Editor * e = pMainWindow->project()->unitEditor(i); - QString curFilename = pMainWindow->project()->units()[i]->fileName(); + foreach (PProjectUnit unit, pMainWindow->project()->unitList()) { + Editor * e = pMainWindow->project()->unitEditor(unit); + QString curFilename = unit->fileName(); if (e) { fileSearched++; PSearchResultTreeItem parentItem = batchFindInEditor(