diff --git a/NEWS.md b/NEWS.md index 2d62d808..0ce389c3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,7 @@ Red Panda C++ Version 0.14.3 - fix: wrong code completion font size, when screen dpi changed - enhancement: replace Files View Panel's path lineedit control with combo box + - enhancement: custome icons for project view Red Panda C++ Version 0.14.2 - enhancement: file system view mode for project diff --git a/RedPandaIDE/RedPandaIDE.pro b/RedPandaIDE/RedPandaIDE.pro index d85ec5b3..12e4592b 100644 --- a/RedPandaIDE/RedPandaIDE.pro +++ b/RedPandaIDE/RedPandaIDE.pro @@ -10,7 +10,7 @@ isEmpty(APP_NAME) { } isEmpty(APP_VERSION) { - APP_VERSION=0.14.2 + APP_VERSION=0.14.3 } isEmpty(PREFIX) { @@ -40,6 +40,7 @@ SOURCES += \ compiler/ojproblemcasesrunner.cpp \ compiler/projectcompiler.cpp \ compiler/runner.cpp \ + customfileiconprovider.cpp \ gdbmiresultparser.cpp \ platform.cpp \ compiler/compiler.cpp \ @@ -176,6 +177,7 @@ HEADERS += \ compiler/runner.h \ compiler/stdincompiler.h \ cpprefacter.h \ + customfileiconprovider.h \ gdbmiresultparser.h \ parser/cppparser.h \ parser/cpppreprocessor.h \ diff --git a/RedPandaIDE/cpprefacter.cpp b/RedPandaIDE/cpprefacter.cpp index d92130fb..1ba6d5c7 100644 --- a/RedPandaIDE/cpprefacter.cpp +++ b/RedPandaIDE/cpprefacter.cpp @@ -178,7 +178,7 @@ void CppRefacter::doFindOccurenceInProject(PStatement statement, std::shared_ptr SearchFileScope::wholeProject ); foreach (const PProjectUnit& unit, project->units()) { - if (isCfile(unit->fileName()) || isHfile(unit->fileName())) { + if (isCFile(unit->fileName()) || isHFile(unit->fileName())) { PSearchResultTreeItem item = findOccurenceInFile( unit->fileName(), statement, diff --git a/RedPandaIDE/customfileiconprovider.cpp b/RedPandaIDE/customfileiconprovider.cpp new file mode 100644 index 00000000..c28af730 --- /dev/null +++ b/RedPandaIDE/customfileiconprovider.cpp @@ -0,0 +1,35 @@ +#include "customfileiconprovider.h" +#include "iconsmanager.h" + +CustomFileIconProvider::CustomFileIconProvider() +{ + +} + +QIcon CustomFileIconProvider::icon(IconType type) const +{ + if (type == IconType::Folder) { + QIcon icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_FOLDER); + if (!icon.isNull()) + return icon; + } + return QFileIconProvider::icon(type); + +} + +QIcon CustomFileIconProvider::icon(const QFileInfo &info) const +{ + QIcon icon; + if (isHFile(info.fileName())) + icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_HFILE); + else if (isCppFile(info.fileName())) { + icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_CPPFILE); + } else if (isCFile(info.fileName())) { + icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_CFILE); + } else if (info.suffix()=="dev") { + icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_PROJECTFILE); + } + if (!icon.isNull()) + return icon; + return QFileIconProvider::icon(info); +} diff --git a/RedPandaIDE/customfileiconprovider.h b/RedPandaIDE/customfileiconprovider.h new file mode 100644 index 00000000..890ca9f9 --- /dev/null +++ b/RedPandaIDE/customfileiconprovider.h @@ -0,0 +1,17 @@ +#ifndef CUSTOMFILEICONPROVIDER_H +#define CUSTOMFILEICONPROVIDER_H + +#include + +class CustomFileIconProvider : public QFileIconProvider +{ +public: + CustomFileIconProvider(); + + // QFileIconProvider interface +public: + QIcon icon(IconType type) const override; + QIcon icon(const QFileInfo &info) const override; +}; + +#endif // CUSTOMFILEICONPROVIDER_H diff --git a/RedPandaIDE/iconsmanager.cpp b/RedPandaIDE/iconsmanager.cpp index 6c3e83e7..12e2be12 100644 --- a/RedPandaIDE/iconsmanager.cpp +++ b/RedPandaIDE/iconsmanager.cpp @@ -180,6 +180,14 @@ void IconsManager::updateFileSystemIcons(const QString &iconSet, int size) QString iconFolder = mIconSetTemplate.arg( iconSetsFolder(),iconSet,"filesystem"); updateMakeDisabledIconDarker(iconSet); mIconPixmaps.insert(FILESYSTEM_GIT, createSVGIcon(iconFolder+"git.svg",size,size)); + mIconPixmaps.insert(FILESYSTEM_FOLDER, createSVGIcon(iconFolder+"folder.svg",size,size)); + mIconPixmaps.insert(FILESYSTEM_FILE, createSVGIcon(iconFolder+"file.svg",size,size)); + mIconPixmaps.insert(FILESYSTEM_CFILE, createSVGIcon(iconFolder+"cfile.svg",size,size)); + mIconPixmaps.insert(FILESYSTEM_HFILE, createSVGIcon(iconFolder+"hfile.svg",size,size)); + mIconPixmaps.insert(FILESYSTEM_CPPFILE, createSVGIcon(iconFolder+"cppfile.svg",size,size)); + mIconPixmaps.insert(FILESYSTEM_PROJECTFILE, createSVGIcon(iconFolder+"projectfile.svg",size,size)); + mIconPixmaps.insert(FILESYSTEM_HEADERS_FOLDER, createSVGIcon(iconFolder+"headerfolder.svg",size,size)); + mIconPixmaps.insert(FILESYSTEM_SOURCES_FOLDER, createSVGIcon(iconFolder+"sourcefolder.svg",size,size)); } IconsManager::PPixmap IconsManager::getPixmap(IconName iconName) const @@ -187,14 +195,17 @@ IconsManager::PPixmap IconsManager::getPixmap(IconName iconName) const return mIconPixmaps.value(iconName, mDefaultIconPixmap); } -QIcon IconsManager::getIcon(IconName iconName) const +QIcon IconsManager:: getIcon(IconName iconName) const { + PPixmap pixmap = getPixmap(iconName); + if (pixmap == mDefaultIconPixmap) + return QIcon(); if (mMakeDisabledIconDarker) { QIcon icon(new CustomDisabledIconEngine()); - icon.addPixmap(*getPixmap(iconName)); + icon.addPixmap(*pixmap); return icon; } else - return QIcon(*getPixmap(iconName)); + return QIcon(*pixmap); } void IconsManager::setIcon(QToolButton *btn, IconName iconName) const @@ -212,6 +223,8 @@ void IconsManager::setIcon(QPushButton *btn, IconName iconName) const IconsManager::PPixmap IconsManager::createSVGIcon(const QString &filename, int width, int height) { QSvgRenderer renderer(filename); + if (!renderer.isValid()) + return mDefaultIconPixmap; PPixmap icon = std::make_shared(width,height); icon->fill(Qt::transparent); QPainter painter(icon.get()); diff --git a/RedPandaIDE/iconsmanager.h b/RedPandaIDE/iconsmanager.h index ad612012..13138c6f 100644 --- a/RedPandaIDE/iconsmanager.h +++ b/RedPandaIDE/iconsmanager.h @@ -66,6 +66,15 @@ public: PARSER_LOCAL_VAR, FILESYSTEM_GIT, + FILESYSTEM_FOLDER, + FILESYSTEM_FILE, + FILESYSTEM_CFILE, + FILESYSTEM_HFILE, + FILESYSTEM_PROJECTFILE, + FILESYSTEM_CPPFILE, + FILESYSTEM_HEADERS_FOLDER, + FILESYSTEM_SOURCES_FOLDER, + ACTION_MISC_BACK, ACTION_MISC_FORWARD, diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index 38e9ede7..3ffc4cdf 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -287,6 +287,7 @@ MainWindow::MainWindow(QWidget *parent) //files view ui->treeFiles->setModel(&mFileSystemModel); mFileSystemModel.setReadOnly(false); + mFileSystemModel.setIconProvider(&mFileIconProvider); setFilesViewRoot(pSettings->environment().currentFolder()); for (int i=1;itreeFiles->hideColumn(i); diff --git a/RedPandaIDE/mainwindow.h b/RedPandaIDE/mainwindow.h index 4b66aede..169736a0 100644 --- a/RedPandaIDE/mainwindow.h +++ b/RedPandaIDE/mainwindow.h @@ -38,6 +38,7 @@ #include "widgets/labelwithmenu.h" #include "widgets/bookmarkmodel.h" #include "widgets/ojproblemsetmodel.h" +#include "customfileiconprovider.h" QT_BEGIN_NAMESPACE @@ -615,6 +616,7 @@ private: PTodoParser mTodoParser; PToolsManager mToolsManager; QFileSystemModel mFileSystemModel; + CustomFileIconProvider mFileIconProvider; OJProblemSetModel mOJProblemSetModel; OJProblemModel mOJProblemModel; int mOJProblemSetNameCounter; diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index 6bfcc71f..e1ef3359 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -752,7 +752,7 @@ void CppParser::parseFile(const QString &fileName, bool inProject, bool onlyIfNo // parse header files in the first parse foreach (const QString& file,files) { - if (isHfile(file)) { + if (isHFile(file)) { mFilesScannedCount++; emit onProgress(file,mFilesToScanCount,mFilesScannedCount); if (!mPreprocessor.scannedFiles().contains(file)) { @@ -762,7 +762,7 @@ void CppParser::parseFile(const QString &fileName, bool inProject, bool onlyIfNo } //we only parse CFile in the second parse foreach (const QString& file,files) { - if (!isHfile(file)) { + if (!isHFile(file)) { mFilesScannedCount++; emit onProgress(file,mFilesToScanCount,mFilesScannedCount); if (!mPreprocessor.scannedFiles().contains(file)) { @@ -800,7 +800,7 @@ void CppParser::parseFileList(bool updateView) mFilesToScanCount = mFilesToScan.count(); // parse header files in the first parse foreach (const QString& file, mFilesToScan) { - if (isHfile(file)) { + if (isHFile(file)) { mFilesScannedCount++; emit onProgress(mCurrentFile,mFilesToScanCount,mFilesScannedCount); if (!mPreprocessor.scannedFiles().contains(file)) { @@ -810,7 +810,7 @@ void CppParser::parseFileList(bool updateView) } //we only parse CFile in the second parse foreach (const QString& file,mFilesToScan) { - if (isCfile(file)) { + if (isCFile(file)) { mFilesScannedCount++; emit onProgress(mCurrentFile,mFilesToScanCount,mFilesScannedCount); if (!mPreprocessor.scannedFiles().contains(file)) { @@ -2496,7 +2496,7 @@ void CppParser::handlePreprocessor() if (delimPos>=0) { mCurrentFile = s.mid(0,delimPos); mIsSystemHeader = isSystemHeaderFile(mCurrentFile) || isProjectHeaderFile(mCurrentFile); - mIsProjectFile = mProjectFiles.contains(mCurrentFile); mIsHeader = isHfile(mCurrentFile); + mIsProjectFile = mProjectFiles.contains(mCurrentFile); mIsHeader = isHFile(mCurrentFile); // Mention progress to user if we enter a NEW file bool ok; diff --git a/RedPandaIDE/parser/parserutils.cpp b/RedPandaIDE/parser/parserutils.cpp index eaa3607b..ba4d66d4 100644 --- a/RedPandaIDE/parser/parserutils.cpp +++ b/RedPandaIDE/parser/parserutils.cpp @@ -418,7 +418,7 @@ bool isCppKeyword(const QString &word) return CppKeywords.contains(word); } -bool isHfile(const QString& filename) +bool isHFile(const QString& filename) { if (filename.isEmpty()) return false; @@ -428,7 +428,7 @@ bool isHfile(const QString& filename) } -bool isCfile(const QString& filename) +bool isCFile(const QString& filename) { if (filename.isEmpty()) return false; @@ -614,3 +614,10 @@ StatementKind getKindOfStatement(const PStatement& statement) } return statement->kind; } + +bool isCppFile(const QString &filename) +{ + if (isCFile(filename) && !filename.endsWith(".c")) + return true; + return false; +} diff --git a/RedPandaIDE/parser/parserutils.h b/RedPandaIDE/parser/parserutils.h index 2d3b0c79..5e7d2b4d 100644 --- a/RedPandaIDE/parser/parserutils.h +++ b/RedPandaIDE/parser/parserutils.h @@ -264,8 +264,9 @@ QString getLocalHeaderFilename(const QString& relativeTo, const QString& fileNam QString getSystemHeaderFilename(const QString& fileName, const QStringList& includePaths); bool isSystemHeaderFile(const QString& fileName, const QSet& includePaths); -bool isHfile(const QString& filename); -bool isCfile(const QString& filename); +bool isHFile(const QString& filename); +bool isCFile(const QString& filename); +bool isCppFile(const QString& filename); bool isCppKeyword(const QString& word); bool isScopeTypeKind(StatementKind kind); MemberOperatorType getOperatorType(const QString& phrase, int index); diff --git a/RedPandaIDE/project.cpp b/RedPandaIDE/project.cpp index 631d818d..6db736ff 100644 --- a/RedPandaIDE/project.cpp +++ b/RedPandaIDE/project.cpp @@ -33,7 +33,7 @@ #include #include #include -#include +#include "customfileiconprovider.h" #include #include "settings.h" @@ -222,6 +222,9 @@ PProjectModelNode Project::makeNewFileNode(const QString &s, bool isFolder, PPro if (isFolder) { node->unitIndex = -1; node->priority = 0; + node->folderNodeType = ProjectSpecialFolderNode::NonSpecial; + } else { + node->folderNodeType = ProjectSpecialFolderNode::NotFolder; } return node; } @@ -232,6 +235,7 @@ PProjectModelNode Project::makeProjectNode() node->text = mName; node->level = 0; node->unitIndex = -1; + node->folderNodeType = ProjectSpecialFolderNode::NonSpecial; return node; } @@ -1276,20 +1280,23 @@ void Project::createFolderNodes() void Project::createFileSystemFolderNodes() { PProjectModelNode node = makeNewFileNode(tr("Headers"),true,mRootNode); - createFileSystemFolderNode(ProjectSpecialFolderNode::HEADERS,folder(),node); + node->folderNodeType = ProjectSpecialFolderNode::HEADERS; node->priority = 1000; + createFileSystemFolderNode(ProjectSpecialFolderNode::HEADERS,folder(),node); mFolderNodes.append(node); mSpecialNodes.insert(ProjectSpecialFolderNode::HEADERS,node); node = makeNewFileNode(tr("Sources"),true,mRootNode); - createFileSystemFolderNode(ProjectSpecialFolderNode::SOURCES,folder(),node); + node->folderNodeType = ProjectSpecialFolderNode::SOURCES; node->priority = 900; + createFileSystemFolderNode(ProjectSpecialFolderNode::SOURCES,folder(),node); mFolderNodes.append(node); mSpecialNodes.insert(ProjectSpecialFolderNode::SOURCES,node); node = makeNewFileNode(tr("Others"),true,mRootNode); - createFileSystemFolderNode(ProjectSpecialFolderNode::OTHERS,folder(),node); + node->folderNodeType = ProjectSpecialFolderNode::OTHERS; node->priority = 800; + createFileSystemFolderNode(ProjectSpecialFolderNode::OTHERS,folder(),node); mFolderNodes.append(node); mSpecialNodes.insert(ProjectSpecialFolderNode::OTHERS,node); } @@ -1387,9 +1394,9 @@ PProjectModelNode Project::getParentFolderNode(const QString &filename) { QFileInfo fileInfo(filename); ProjectSpecialFolderNode folderNodeType; - if (isHfile(fileInfo.fileName())) { + if (isHFile(fileInfo.fileName())) { folderNodeType = ProjectSpecialFolderNode::HEADERS; - } else if (isCfile(fileInfo.fileName())) { + } else if (isCFile(fileInfo.fileName())) { folderNodeType = ProjectSpecialFolderNode::SOURCES; } else { folderNodeType = ProjectSpecialFolderNode::OTHERS; @@ -1976,15 +1983,25 @@ QVariant ProjectModel::data(const QModelIndex &index, int role) const if (role == Qt::DisplayRole || role==Qt::EditRole) { return p->text; } else if (role == Qt::DecorationRole) { - QFileIconProvider provider; + CustomFileIconProvider provider; + QIcon icon; if (p->unitIndex>=0) { - return provider.icon(mProject->units()[p->unitIndex]->fileName()); + icon = provider.icon(mProject->units()[p->unitIndex]->fileName()); } else { - QIcon icon = provider.icon(QFileIconProvider::Folder); + switch(p->folderNodeType) { + case ProjectSpecialFolderNode::HEADERS: + icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_HEADERS_FOLDER); + break; + case ProjectSpecialFolderNode::SOURCES: + icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_SOURCES_FOLDER); + break; + default: + icon = pIconsManager->getIcon(IconsManager::FILESYSTEM_FOLDER); + } if (icon.isNull()) - return pIconsManager->getIcon(IconsManager::ACTION_MISC_FOLDER); - return icon; + icon = provider.icon(QFileIconProvider::Folder); } + return icon; } return QVariant(); } diff --git a/RedPandaIDE/project.h b/RedPandaIDE/project.h index 1739dbce..73927200 100644 --- a/RedPandaIDE/project.h +++ b/RedPandaIDE/project.h @@ -27,6 +27,15 @@ class Project; class Editor; class CppParser; + +enum ProjectSpecialFolderNode { + HEADERS, + SOURCES, + OTHERS, + NonSpecial, + NotFolder +}; + struct ProjectModelNode; using PProjectModelNode = std::shared_ptr; struct ProjectModelNode { @@ -35,6 +44,7 @@ struct ProjectModelNode { int unitIndex; int priority; QList children; + ProjectSpecialFolderNode folderNodeType; int level; }; @@ -133,12 +143,6 @@ protected: bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override; }; -enum ProjectSpecialFolderNode { - HEADERS, - SOURCES, - OTHERS, - NonSpecial -}; class ProjectTemplate; class Project : public QObject diff --git a/RedPandaIDE/qsynedit/SynEdit.cpp b/RedPandaIDE/qsynedit/SynEdit.cpp index 9174f354..b2546491 100644 --- a/RedPandaIDE/qsynedit/SynEdit.cpp +++ b/RedPandaIDE/qsynedit/SynEdit.cpp @@ -1244,7 +1244,7 @@ BufferCoord SynEdit::getPreviousLeftBrace(int x, int y) int SynEdit::charColumns(QChar ch) const { - if (ch == ' ' || ch == '\t') + if (ch.unicode()<=32) return 1; //return std::ceil((int)(fontMetrics().horizontalAdvance(ch) * dpiFactor()) / (double)mCharWidth); return std::ceil((int)(fontMetrics().horizontalAdvance(ch)) / (double)mCharWidth); diff --git a/RedPandaIDE/resources/iconsets/newlook/filesystem/cfile.svg b/RedPandaIDE/resources/iconsets/newlook/filesystem/cfile.svg new file mode 100644 index 00000000..650c0de9 --- /dev/null +++ b/RedPandaIDE/resources/iconsets/newlook/filesystem/cfile.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RedPandaIDE/resources/iconsets/newlook/filesystem/cppfile.svg b/RedPandaIDE/resources/iconsets/newlook/filesystem/cppfile.svg new file mode 100644 index 00000000..d7d2c0a8 --- /dev/null +++ b/RedPandaIDE/resources/iconsets/newlook/filesystem/cppfile.svg @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RedPandaIDE/resources/iconsets/newlook/filesystem/file.svg b/RedPandaIDE/resources/iconsets/newlook/filesystem/file.svg new file mode 100644 index 00000000..819de1ed --- /dev/null +++ b/RedPandaIDE/resources/iconsets/newlook/filesystem/file.svg @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RedPandaIDE/resources/iconsets/newlook/filesystem/folder.svg b/RedPandaIDE/resources/iconsets/newlook/filesystem/folder.svg new file mode 100644 index 00000000..714caabb --- /dev/null +++ b/RedPandaIDE/resources/iconsets/newlook/filesystem/folder.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/RedPandaIDE/resources/iconsets/newlook/filesystem/headerfolder.svg b/RedPandaIDE/resources/iconsets/newlook/filesystem/headerfolder.svg new file mode 100644 index 00000000..5021a799 --- /dev/null +++ b/RedPandaIDE/resources/iconsets/newlook/filesystem/headerfolder.svg @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/RedPandaIDE/resources/iconsets/newlook/filesystem/hfile.svg b/RedPandaIDE/resources/iconsets/newlook/filesystem/hfile.svg new file mode 100644 index 00000000..dec5a3f6 --- /dev/null +++ b/RedPandaIDE/resources/iconsets/newlook/filesystem/hfile.svg @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RedPandaIDE/resources/iconsets/newlook/filesystem/projectfile.svg b/RedPandaIDE/resources/iconsets/newlook/filesystem/projectfile.svg new file mode 100644 index 00000000..03095458 --- /dev/null +++ b/RedPandaIDE/resources/iconsets/newlook/filesystem/projectfile.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RedPandaIDE/resources/iconsets/newlook/filesystem/sourcefolder.svg b/RedPandaIDE/resources/iconsets/newlook/filesystem/sourcefolder.svg new file mode 100644 index 00000000..7712f510 --- /dev/null +++ b/RedPandaIDE/resources/iconsets/newlook/filesystem/sourcefolder.svg @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/Red_Panda_CPP.pro b/Red_Panda_CPP.pro index 2dd6616e..085083ef 100644 --- a/Red_Panda_CPP.pro +++ b/Red_Panda_CPP.pro @@ -7,7 +7,7 @@ SUBDIRS += \ APP_NAME = RedPandaCPP -APP_VERSION = 0.14.2 +APP_VERSION = 0.14.3 linux: {