diff --git a/NEWS.md b/NEWS.md index eb49c058..e37f9993 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,8 @@ +Red Panda C++ Version 1.5 + + - fix: project files that lies in project include folder is wrongly openned in Read-only mode + + Red Panda C++ Version 1.4 - fix: "Encode in UTF-8" is not correctly checked, when the editor is openned using UTF-8 encoding. diff --git a/RedPandaIDE/RedPandaIDE.pro b/RedPandaIDE/RedPandaIDE.pro index 85a642c5..b315ca0a 100644 --- a/RedPandaIDE/RedPandaIDE.pro +++ b/RedPandaIDE/RedPandaIDE.pro @@ -10,7 +10,7 @@ isEmpty(APP_NAME) { } isEmpty(APP_VERSION) { - APP_VERSION=1.4 + APP_VERSION=1.5 } macos: { diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index c3368f66..0375bb3e 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -125,8 +125,7 @@ Editor::Editor(QWidget *parent, const QString& filename, initParser(); } - if (pSettings->editor().readOnlySytemHeader() - && mParser && (mParser->isSystemHeaderFile(mFilename) || mParser->isProjectHeaderFile(mFilename))) { + if (shouldOpenInReadonly()) { this->setModified(false); setReadOnly(true); } @@ -394,8 +393,7 @@ bool Editor::saveAs(const QString &name, bool fromProject){ reparseTodo(); - if (pSettings->editor().readOnlySytemHeader() - && (!mParser->isSystemHeaderFile(mFilename) && !mParser->isProjectHeaderFile(mFilename))) { + if (!shouldOpenInReadonly()) { setReadOnly(false); updateCaption(); } @@ -1740,6 +1738,14 @@ bool Editor::isBraceChar(QChar ch) } } +bool Editor::shouldOpenInReadonly() +{ + if (pMainWindow->project() && pMainWindow->project()->findUnitByFilename(mFilename)) + return false; + return pSettings->editor().readOnlySytemHeader() + && mParser && (mParser->isSystemHeaderFile(mFilename) || mParser->isProjectHeaderFile(mFilename)); +} + void Editor::resetBookmarks() { mBookmarkLines=pMainWindow->bookmarkModel()->bookmarksInFile(mFilename); diff --git a/RedPandaIDE/editor.h b/RedPandaIDE/editor.h index a119c3c5..9ca4928c 100644 --- a/RedPandaIDE/editor.h +++ b/RedPandaIDE/editor.h @@ -239,6 +239,7 @@ private slots: private: bool isBraceChar(QChar ch); + bool shouldOpenInReadonly(); void resetBookmarks(); QChar getCurrentChar(); bool handleSymbolCompletion(QChar key); diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index c26ed3ba..fd7aa524 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -6155,7 +6155,7 @@ void MainWindow::newProjectUnitFile() PProjectUnit newUnit; if (mProject->modelType() == ProjectModelType::FileSystem) { PProjectModelNode modelTypeNode = pNode; - while (modelTypeNode && modelTypeNode->folderNodeType==ProjectSpecialFolderNode::NonSpecial) { + while (modelTypeNode && modelTypeNode->folderNodeType==ProjectModelNodeType::Folder) { modelTypeNode=modelTypeNode->parent.lock(); } if (!modelTypeNode) { @@ -6169,10 +6169,10 @@ void MainWindow::newProjectUnitFile() newProjectUnitDialog.setSuffix("c"); } else { switch (modelTypeNode->folderNodeType) { - case ProjectSpecialFolderNode::HEADERS: + case ProjectModelNodeType::DUMMY_HEADERS_FOLDER: newProjectUnitDialog.setSuffix("h"); break; - case ProjectSpecialFolderNode::SOURCES: + case ProjectModelNodeType::DUMMY_SOURCES_FOLDER: if (mProject->options().isCpp) newProjectUnitDialog.setSuffix("cpp"); else diff --git a/RedPandaIDE/project.cpp b/RedPandaIDE/project.cpp index 2f2e4704..f91aab0b 100644 --- a/RedPandaIDE/project.cpp +++ b/RedPandaIDE/project.cpp @@ -230,9 +230,9 @@ PProjectModelNode Project::makeNewFileNode(const QString &s, bool isFolder, PPro if (isFolder) { node->unitIndex = -1; node->priority = 0; - node->folderNodeType = ProjectSpecialFolderNode::NonSpecial; + node->folderNodeType = ProjectModelNodeType::Folder; } else { - node->folderNodeType = ProjectSpecialFolderNode::NotFolder; + node->folderNodeType = ProjectModelNodeType::File; } return node; } @@ -243,7 +243,7 @@ PProjectModelNode Project::makeProjectNode() node->text = mName; node->level = 0; node->unitIndex = -1; - node->folderNodeType = ProjectSpecialFolderNode::NonSpecial; + node->folderNodeType = ProjectModelNodeType::Folder; return node; } @@ -1499,29 +1499,29 @@ void Project::createFileSystemFolderNodes() } } PProjectModelNode node = makeNewFileNode(tr("Headers"),true,mRootNode); - node->folderNodeType = ProjectSpecialFolderNode::HEADERS; + node->folderNodeType = ProjectModelNodeType::DUMMY_HEADERS_FOLDER; node->priority = 1000; - createFileSystemFolderNode(ProjectSpecialFolderNode::HEADERS,folder(),node, headerFolders); + createFileSystemFolderNode(ProjectModelNodeType::DUMMY_HEADERS_FOLDER,folder(),node, headerFolders); mFolderNodes.append(node); - mSpecialNodes.insert(ProjectSpecialFolderNode::HEADERS,node); + mSpecialNodes.insert(ProjectModelNodeType::DUMMY_HEADERS_FOLDER,node); node = makeNewFileNode(tr("Sources"),true,mRootNode); - node->folderNodeType = ProjectSpecialFolderNode::SOURCES; + node->folderNodeType = ProjectModelNodeType::DUMMY_SOURCES_FOLDER; node->priority = 900; - createFileSystemFolderNode(ProjectSpecialFolderNode::SOURCES,folder(),node, sourceFolders); + createFileSystemFolderNode(ProjectModelNodeType::DUMMY_SOURCES_FOLDER,folder(),node, sourceFolders); mFolderNodes.append(node); - mSpecialNodes.insert(ProjectSpecialFolderNode::SOURCES,node); + mSpecialNodes.insert(ProjectModelNodeType::DUMMY_SOURCES_FOLDER,node); node = makeNewFileNode(tr("Others"),true,mRootNode); - node->folderNodeType = ProjectSpecialFolderNode::OTHERS; + node->folderNodeType = ProjectModelNodeType::DUMMY_OTHERS_FOLDER; node->priority = 800; - createFileSystemFolderNode(ProjectSpecialFolderNode::OTHERS,folder(),node, otherFolders); + createFileSystemFolderNode(ProjectModelNodeType::DUMMY_OTHERS_FOLDER,folder(),node, otherFolders); mFolderNodes.append(node); - mSpecialNodes.insert(ProjectSpecialFolderNode::OTHERS,node); + mSpecialNodes.insert(ProjectModelNodeType::DUMMY_OTHERS_FOLDER,node); } void Project::createFileSystemFolderNode( - ProjectSpecialFolderNode folderType, + ProjectModelNodeType folderType, const QString &folderName, PProjectModelNode parent, const QSet& validFolders) @@ -1554,7 +1554,7 @@ bool Project::fileAlreadyExists(const QString &s) return false; } -PProjectModelNode Project::findFolderNode(const QString &folderPath, ProjectSpecialFolderNode nodeType) +PProjectModelNode Project::findFolderNode(const QString &folderPath, ProjectModelNodeType nodeType) { PProjectModelNode node = mFileSystemFolderNodes.value(QString("%1/%2").arg((int)nodeType).arg(folderPath), PProjectModelNode()); @@ -1603,13 +1603,13 @@ int Project::getUnitFromString(const QString &s) PProjectModelNode Project::getParentFolderNode(const QString &filename) { QFileInfo fileInfo(filename); - ProjectSpecialFolderNode folderNodeType; + ProjectModelNodeType folderNodeType; if (isHFile(fileInfo.fileName())) { - folderNodeType = ProjectSpecialFolderNode::HEADERS; + folderNodeType = ProjectModelNodeType::DUMMY_HEADERS_FOLDER; } else if (isCFile(fileInfo.fileName())) { - folderNodeType = ProjectSpecialFolderNode::SOURCES; + folderNodeType = ProjectModelNodeType::DUMMY_SOURCES_FOLDER; } else { - folderNodeType = ProjectSpecialFolderNode::OTHERS; + folderNodeType = ProjectModelNodeType::DUMMY_OTHERS_FOLDER; } return findFolderNode(fileInfo.absolutePath(),folderNodeType); } @@ -1996,7 +1996,7 @@ QString Project::fileSystemNodeFolderPath(const PProjectModelNode &node) QString result; if (node != mRootNode) { PProjectModelNode pNode = node; - while (pNode && pNode->folderNodeType == ProjectSpecialFolderNode::NonSpecial) { + while (pNode && pNode->folderNodeType == ProjectModelNodeType::Folder) { result = node->text + "/" +result; pNode = pNode->parent.lock(); } @@ -2378,10 +2378,10 @@ QVariant ProjectModel::data(const QModelIndex &index, int role) const icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_GIT); } else { switch(p->folderNodeType) { - case ProjectSpecialFolderNode::HEADERS: + case ProjectModelNodeType::DUMMY_HEADERS_FOLDER: icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_HEADERS_FOLDER); break; - case ProjectSpecialFolderNode::SOURCES: + case ProjectModelNodeType::DUMMY_SOURCES_FOLDER: icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_SOURCES_FOLDER); break; default: @@ -2526,6 +2526,23 @@ bool ProjectModel::setData(const QModelIndex &index, const QVariant &value, int return false; } +QModelIndex ProjectModel::getNodeIndex(ProjectModelNode *node) const +{ + PProjectModelNode parent = node->parent.lock(); + if (!parent) // root node + return QModelIndex(); + int row = -1; + for (int i=0;ichildren.count();i++) { + const PProjectModelNode& pNode=parent->children[i]; + if (pNode.get()==node) { + row = i; + } + } + if (row<0) + return QModelIndex(); + return createIndex(row,0,node); +} + QModelIndex ProjectModel::getParentIndex(ProjectModelNode * node) const { PProjectModelNode parent = node->parent.lock(); diff --git a/RedPandaIDE/project.h b/RedPandaIDE/project.h index 499b1c39..cdfe19cb 100644 --- a/RedPandaIDE/project.h +++ b/RedPandaIDE/project.h @@ -29,13 +29,12 @@ class CppParser; class EditorList; class QFileSystemWatcher; - -enum ProjectSpecialFolderNode { - HEADERS, - SOURCES, - OTHERS, - NonSpecial, - NotFolder +enum ProjectModelNodeType { + DUMMY_HEADERS_FOLDER, + DUMMY_SOURCES_FOLDER, + DUMMY_OTHERS_FOLDER, + Folder, + File }; struct ProjectModelNode; @@ -46,7 +45,7 @@ struct ProjectModelNode { int unitIndex; int priority; QList children; - ProjectSpecialFolderNode folderNodeType; + ProjectModelNodeType folderNodeType; int level; }; @@ -129,8 +128,11 @@ public: Qt::ItemFlags flags(const QModelIndex &index) const override; bool setData(const QModelIndex &index, const QVariant &value, int role) override; + QModelIndex getNodeIndex(ProjectModelNode *node) const; + private: QModelIndex getParentIndex(ProjectModelNode * node) const; + // QAbstractItemModel interface public: bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override; @@ -253,9 +255,9 @@ private: void checkProjectFileForUpdate(SimpleIni& ini); void createFolderNodes(); void createFileSystemFolderNodes(); - void createFileSystemFolderNode(ProjectSpecialFolderNode folderType, const QString& folderName, PProjectModelNode parent, const QSet& validFolders); + void createFileSystemFolderNode(ProjectModelNodeType folderType, const QString& folderName, PProjectModelNode parent, const QSet& validFolders); PProjectModelNode getParentFolderNode(const QString& filename); - PProjectModelNode findFolderNode(const QString& folderPath, ProjectSpecialFolderNode nodeType); + PProjectModelNode findFolderNode(const QString& folderPath, ProjectModelNodeType nodeType); PProjectModelNode folderNodeFromName(const QString& name); void loadOptions(SimpleIni& ini); void loadLayout(); // load all [UnitX] @@ -279,7 +281,7 @@ private: std::shared_ptr mParser; QList mFolderNodes; PProjectModelNode mRootNode; - QHash mSpecialNodes; + QHash mSpecialNodes; QHash mFileSystemFolderNodes; ProjectModel mModel; EditorList *mEditorList; diff --git a/Red_Panda_CPP.pro b/Red_Panda_CPP.pro index b5a23865..5ffcfe41 100644 --- a/Red_Panda_CPP.pro +++ b/Red_Panda_CPP.pro @@ -33,7 +33,7 @@ RedPandaIDE.depends += redpanda-git-askpass APP_NAME = RedPandaCPP -APP_VERSION = 1.4 +APP_VERSION = 1.5 linux: { isEmpty(PREFIX) { diff --git a/libs/redpanda_qt_utils/qt_utils/utils.cpp b/libs/redpanda_qt_utils/qt_utils/utils.cpp index 89676f2b..8a3a3040 100644 --- a/libs/redpanda_qt_utils/qt_utils/utils.cpp +++ b/libs/redpanda_qt_utils/qt_utils/utils.cpp @@ -649,3 +649,10 @@ void decodeKey(const int combinedKey, int &key, Qt::KeyboardModifiers &modifiers } key = combinedKey & ~(Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier | Qt::KeypadModifier); } + +bool isInFolder(const QString &folderpath, const QString &filepath) +{ + QDir folder(folderpath); + QFileInfo fileInfo(filepath); + return fileInfo.absoluteFilePath().startsWith(includeTrailingPathDelimiter(folder.absolutePath())); +} diff --git a/libs/redpanda_qt_utils/qt_utils/utils.h b/libs/redpanda_qt_utils/qt_utils/utils.h index 912b4976..f2b5ce2b 100644 --- a/libs/redpanda_qt_utils/qt_utils/utils.h +++ b/libs/redpanda_qt_utils/qt_utils/utils.h @@ -114,6 +114,7 @@ bool directoryExists(const QString& file); bool removeFile(const QString& filename); void copyFolder(const QString &fromDir, const QString& toDir); bool copyFile(const QString &fromFile, const QString& toFile, bool overwrite); +bool isInFolder(const QString& folderpath, const QString& filepath); QString includeTrailingPathDelimiter(const QString& path); QString excludeTrailingPathDelimiter(const QString& path);