work save: header completion

This commit is contained in:
royqh1979@gmail.com 2021-08-29 00:48:23 +08:00
parent 05f686d61e
commit f1ae5bfdfd
21 changed files with 623 additions and 254 deletions

View File

@ -29,7 +29,8 @@ SOURCES += \
qsynedit/SearchRegex.cpp \
settingsdialog/debuggeneralwidget.cpp \
widgets/classbrowser.cpp \
widgets/codecompletionview.cpp \
widgets/codecompletionlistview.cpp \
widgets/codecompletionpopup.cpp \
widgets/cpudialog.cpp \
debugger.cpp \
editor.cpp \
@ -69,7 +70,7 @@ SOURCES += \
utils.cpp \
widgets/coloredit.cpp \
widgets/consolewidget.cpp \
widgets/elidedlabel.cpp \
widgets/headercompletionpopup.cpp \
widgets/issuestable.cpp \
widgets/qconsole.cpp \
widgets/qpatchedcombobox.cpp \
@ -94,7 +95,8 @@ HEADERS += \
qsynedit/SearchRegex.h \
settingsdialog/debuggeneralwidget.h \
widgets/classbrowser.h \
widgets/codecompletionview.h \
widgets/codecompletionlistview.h \
widgets/codecompletionpopup.h \
widgets/cpudialog.h \
debugger.h \
editor.h \
@ -135,7 +137,7 @@ HEADERS += \
common.h \
widgets/coloredit.h \
widgets/consolewidget.h \
widgets/elidedlabel.h \
widgets/headercompletionpopup.h \
widgets/issuestable.h \
widgets/qconsole.h \
widgets/qpatchedcombobox.h \

View File

@ -97,7 +97,7 @@ Editor::Editor(QWidget *parent, const QString& filename,
} else {
initParser();
}
mCompletionPopup = std::make_shared<CodeCompletionView>();
mCompletionPopup = std::make_shared<CodeCompletionPopup>();
applySettings();
applyColorScheme(pSettings->editor().colorScheme());

View File

@ -8,7 +8,7 @@
#include "colorscheme.h"
#include "common.h"
#include "parser/cppparser.h"
#include "widgets/codecompletionview.h"
#include "widgets/codecompletionpopup.h"
class SaveException: public std::exception {
@ -192,7 +192,7 @@ private:
QSet<int> mBreakpointLines;
int mActiveBreakpointLine;
PCppParser mParser;
std::shared_ptr<CodeCompletionView> mCompletionPopup;
std::shared_ptr<CodeCompletionPopup> mCompletionPopup;
int mLastIdCharPressed;
bool mUseCppSyntax;

View File

@ -121,6 +121,8 @@ MainWindow::MainWindow(QWidget *parent)
//class browser
ui->classBrowser->setModel(&mClassBrowserModel);
updateAppTitle();
}
MainWindow::~MainWindow()
@ -340,8 +342,8 @@ void MainWindow::updateAppTitle()
// Application.Title := Format('%s - %s', [fProject.Name, appName]);
// end;
else {
setWindowTitle(QString("%s %s").arg(appName).arg(DEVCPP_VERSION));
app->setApplicationName(QString("%s").arg(appName));
setWindowTitle(QString("%1 %2").arg(appName).arg(DEVCPP_VERSION));
app->setApplicationName(QString("%1").arg(appName));
}
}
@ -1598,7 +1600,7 @@ void MainWindow::onStartParsing()
void MainWindow::onEndParsing(int total, int)
{
double parseTime = mParserTimer.elapsed() / 1000;
double parseTime = mParserTimer.elapsed() / 1000.0;
double parsingFrequency;

View File

@ -5,7 +5,6 @@
#include "common.h"
#include "widgets/searchresultview.h"
#include "widgets/classbrowser.h"
#include "widgets/elidedlabel.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }

View File

@ -104,7 +104,7 @@ void CppParser::fillListOfFunctions(const QString &fileName, const QString &phra
if (parentScope && parentScope->kind == StatementKind::skNamespace) {
PStatementList namespaceStatementsList = findNamespace(parentScope->command);
if (namespaceStatementsList) {
for (PStatement namespaceStatement : *namespaceStatementsList) {
for (PStatement& namespaceStatement : *namespaceStatementsList) {
fillListOfFunctions(fileName,line,statement,namespaceStatement,list);
}
}
@ -135,10 +135,9 @@ PFileIncludes CppParser::findFileIncludes(const QString &filename, bool deleteIt
return fileIncludes;
}
QString CppParser::findFirstTemplateParamOf(const QString &fileName, const QString &phrase, PStatement currentScope)
QString CppParser::findFirstTemplateParamOf(const QString &fileName, const QString &phrase, const PStatement& currentScope)
{
QMutexLocker locker(&mMutex);
QString result = "";
if (mParsing)
return "";
// Remove pointer stuff from type
@ -168,7 +167,7 @@ PStatement CppParser::findFunctionAt(const QString &fileName, int line)
PFileIncludes fileIncludes = mPreprocessor.includesList().value(fileName);
if (!fileIncludes)
return PStatement();
for (PStatement statement : fileIncludes->statements) {
for (PStatement& statement : fileIncludes->statements) {
if (statement->kind != StatementKind::skFunction
&& statement->kind != StatementKind::skConstructor
&& statement->kind != StatementKind::skDestructor)
@ -209,7 +208,7 @@ PStatement CppParser::findStatementOf(const QString &fileName, const QString &ph
return findStatementOf(fileName,phrase,findAndScanBlockAt(fileName,line));
}
PStatement CppParser::findStatementOf(const QString &fileName, const QString &phrase, PStatement currentScope, PStatement &parentScopeType, bool force)
PStatement CppParser::findStatementOf(const QString &fileName, const QString &phrase, const PStatement& currentScope, PStatement &parentScopeType, bool force)
{
QMutexLocker locker(&mMutex);
PStatement result;
@ -233,7 +232,7 @@ PStatement CppParser::findStatementOf(const QString &fileName, const QString &ph
remainder = splitPhrase(remainder,nextScopeWord,operatorToken,memberName);
for (PStatement currentNamespace: *namespaceList) {
for (PStatement& currentNamespace: *namespaceList) {
statement = findMemberOfStatement(nextScopeWord,currentNamespace);
if (statement)
break;
@ -259,7 +258,7 @@ PStatement CppParser::findStatementOf(const QString &fileName, const QString &ph
PStatementList namespaceList = mNamespaces.value(currentScope->fullName);
if (!namespaceList || namespaceList->isEmpty())
return PStatement();
for (PStatement currentNamespace:*namespaceList){
for (PStatement& currentNamespace:*namespaceList){
statement = findMemberOfStatement(nextScopeWord,currentNamespace);
if (statement)
break;
@ -359,13 +358,13 @@ PStatement CppParser::findStatementOf(const QString &fileName, const QString &ph
return statement;
}
PStatement CppParser::findStatementOf(const QString &fileName, const QString &phrase, PStatement currentClass, bool force)
PStatement CppParser::findStatementOf(const QString &fileName, const QString &phrase, const PStatement& currentClass, bool force)
{
PStatement statementParentType;
return findStatementOf(fileName,phrase,currentClass,statementParentType,force);
}
PStatement CppParser::findStatementStartingFrom(const QString &fileName, const QString &phrase, PStatement startScope, bool force)
PStatement CppParser::findStatementStartingFrom(const QString &fileName, const QString &phrase, const PStatement& startScope, bool force)
{
QMutexLocker locker(&mMutex);
if (mParsing && !force)
@ -382,7 +381,7 @@ PStatement CppParser::findStatementStartingFrom(const QString &fileName, const Q
return result;
// not found
// search members of all usings (in current scope )
for (QString namespaceName:scopeStatement->usingList) {
for (const QString& namespaceName:scopeStatement->usingList) {
result = findStatementInNamespace(phrase,namespaceName);
if (result)
return result;
@ -398,7 +397,7 @@ PStatement CppParser::findStatementStartingFrom(const QString &fileName, const Q
//Find in all global usings
const QSet<QString>& fileUsings = getFileUsings(fileName);
// add members of all fusings
for (QString namespaceName:fileUsings) {
for (const QString& namespaceName:fileUsings) {
result = findStatementInNamespace(phrase,namespaceName);
if (result)
return result;
@ -406,7 +405,7 @@ PStatement CppParser::findStatementStartingFrom(const QString &fileName, const Q
return PStatement();
}
PStatement CppParser::findTypeDefinitionOf(const QString &fileName, const QString &aType, PStatement currentClass)
PStatement CppParser::findTypeDefinitionOf(const QString &fileName, const QString &aType, const PStatement& currentClass)
{
QMutexLocker locker(&mMutex);
@ -463,17 +462,16 @@ bool CppParser::freeze(const QString &serialId)
QStringList CppParser::getClassesList()
{
QMutexLocker locker(&mMutex);
if (mParsing)
return QStringList();
QStringList list;
return list;
// fills List with a list of all the known classes
QQueue<PStatement> queue;
queue.enqueue(PStatement());
while (!queue.isEmpty()) {
PStatement statement = queue.dequeue();
StatementMap statementMap = mStatementList.childrenStatements(statement);
for (PStatement child:statementMap) {
for (PStatement& child:statementMap) {
if (child->kind == StatementKind::skClass)
list.append(child->command);
if (!child->children.isEmpty())
@ -516,7 +514,7 @@ QSet<QString> CppParser::getFileIncludes(const QString &filename)
PFileIncludes fileIncludes = mPreprocessor.includesList().value(filename,PFileIncludes());
if (fileIncludes) {
for (QString file: fileIncludes->includeFiles.keys()) {
for (const QString& file: fileIncludes->includeFiles.keys()) {
list.insert(file);
}
}
@ -544,7 +542,7 @@ QString CppParser::getHeaderFileName(const QString &relativeTo, const QString &l
mPreprocessor.projectIncludePaths());
}
StatementKind CppParser::getKindOfStatement(PStatement statement)
StatementKind CppParser::getKindOfStatement(const PStatement& statement)
{
if (!statement)
return StatementKind::skUnknown;
@ -638,7 +636,7 @@ void CppParser::parseFile(const QString &fileName, bool inProject, bool onlyIfNo
mFilesScannedCount = 0;
// parse header files in the first parse
for (QString file:files) {
for (const QString& file:files) {
if (isHfile(file)) {
mFilesScannedCount++;
emit onProgress(file,mFilesToScanCount,mFilesScannedCount);
@ -648,7 +646,7 @@ void CppParser::parseFile(const QString &fileName, bool inProject, bool onlyIfNo
}
}
//we only parse CFile in the second parse
for (QString file:files) {
for (const QString& file:files) {
if (isCfile(file)) {
mFilesScannedCount++;
emit onProgress(file,mFilesToScanCount,mFilesScannedCount);
@ -686,7 +684,7 @@ void CppParser::parseFileList(bool updateView)
mFilesScannedCount = 0;
mFilesToScanCount = mFilesToScan.count();
// parse header files in the first parse
for (QString file:mFilesToScan) {
for (const QString& file:mFilesToScan) {
if (isHfile(file)) {
mFilesScannedCount++;
emit onProgress(mCurrentFile,mFilesToScanCount,mFilesScannedCount);
@ -696,7 +694,7 @@ void CppParser::parseFileList(bool updateView)
}
}
//we only parse CFile in the second parse
for (QString file:mFilesToScan) {
for (const QString& file:mFilesToScan) {
if (isCfile(file)) {
mFilesScannedCount++;
emit onProgress(mCurrentFile,mFilesToScanCount,mFilesScannedCount);
@ -722,7 +720,7 @@ void CppParser::parseHardDefines()
mParsing = false;
mIsSystemHeader=oldIsSystemHeader;
});
for (PDefine define:mPreprocessor.hardDefines()) {
for (const PDefine& define:mPreprocessor.hardDefines()) {
QString hintText = "#define";
if (define->name != "")
hintText += ' ' + define->name;
@ -813,13 +811,16 @@ void CppParser::unFreeze()
mLockCount--;
}
QString CppParser::prettyPrintStatement(PStatement statement, int line)
QString CppParser::prettyPrintStatement(const PStatement& statement, int line)
{
//TODO: implement it
return "not implemented yet";
}
QString CppParser::getFirstTemplateParam(PStatement statement, const QString& filename, const QString& phrase, PStatement currentScope)
QString CppParser::getFirstTemplateParam(const PStatement& statement,
const QString& filename,
const QString& phrase,
const PStatement& currentScope)
{
if (!statement)
return "";
@ -852,7 +853,7 @@ int CppParser::getFirstTemplateParamEnd(const QString &s, int startAt)
return startAt;
}
void CppParser::addFileToScan(QString value, bool inProject)
void CppParser::addFileToScan(const QString& value, bool inProject)
{
QMutexLocker locker(&mMutex);
//value.replace('/','\\'); // only accept full file names
@ -868,7 +869,7 @@ void CppParser::addFileToScan(QString value, bool inProject)
}
PStatement CppParser::addInheritedStatement(PStatement derived, PStatement inherit, StatementClassScope access)
PStatement CppParser::addInheritedStatement(const PStatement& derived, const PStatement& inherit, StatementClassScope access)
{
PStatement statement = addStatement(
@ -890,7 +891,12 @@ PStatement CppParser::addInheritedStatement(PStatement derived, PStatement inher
return statement;
}
PStatement CppParser::addChildStatement(PStatement parent, const QString &fileName, const QString &hintText, const QString &aType, const QString &command, const QString &args, const QString &value, int line, StatementKind kind, StatementScope scope, StatementClassScope classScope, bool isDefinition, bool isStatic)
PStatement CppParser::addChildStatement(const PStatement& parent, const QString &fileName,
const QString &hintText, const QString &aType,
const QString &command, const QString &args,
const QString &value, int line, StatementKind kind,
const StatementScope& scope, const StatementClassScope& classScope,
bool isDefinition, bool isStatic)
{
return addStatement(
parent,
@ -908,7 +914,16 @@ PStatement CppParser::addChildStatement(PStatement parent, const QString &fileNa
isStatic);
}
PStatement CppParser::addStatement(PStatement parent, const QString &fileName, const QString &hintText, const QString &aType, const QString &command, const QString &args, const QString &value, int line, StatementKind kind, StatementScope scope, StatementClassScope classScope, bool isDefinition, bool isStatic)
PStatement CppParser::addStatement(const PStatement& parent,
const QString &fileName,
const QString &hintText,
const QString &aType,
const QString &command,
const QString &args,
const QString &value,
int line, StatementKind kind,
const StatementScope& scope,
const StatementClassScope& classScope, bool isDefinition, bool isStatic)
{
// Move '*', '&' to type rather than cmd (it's in the way for code-completion)
QString newType = aType;
@ -1002,7 +1017,7 @@ PStatement CppParser::addStatement(PStatement parent, const QString &fileName, c
return result;
}
void CppParser::setInheritance(int index, PStatement classStatement, bool isStruct)
void CppParser::setInheritance(int index, const PStatement& classStatement, bool isStruct)
{
// Clear it. Assume it is assigned
classStatement->inheritanceList.clear();
@ -1054,7 +1069,7 @@ bool CppParser::isCurrentScope(const QString &command)
return (statement->command == s);
}
void CppParser::addSoloScopeLevel(PStatement statement, int line)
void CppParser::addSoloScopeLevel(PStatement& statement, int line)
{
// Add class list
@ -1542,7 +1557,7 @@ void CppParser::getFullNamespace(const QString &phrase, QString &sNamespace, QSt
}
}
QString CppParser::getFullStatementName(const QString &command, PStatement parent)
QString CppParser::getFullStatementName(const QString &command, const PStatement& parent)
{
PStatement scopeStatement=parent;
while (scopeStatement && !isNamedScope(scopeStatement->kind))
@ -1553,7 +1568,7 @@ QString CppParser::getFullStatementName(const QString &command, PStatement paren
return command;
}
PStatement CppParser::getIncompleteClass(const QString &command, PStatement parentScope)
PStatement CppParser::getIncompleteClass(const QString &command, const PStatement& parentScope)
{
QString s=command;
//remove template parameter
@ -1586,7 +1601,8 @@ QString CppParser::getStatementKey(const QString &sName, const QString &sType, c
return sName + "--" + sType + "--" + sNoNameArgs;
}
PStatement CppParser::getTypeDef(PStatement statement, const QString& fileName, const QString& aType)
PStatement CppParser::getTypeDef(const PStatement& statement,
const QString& fileName, const QString& aType)
{
if (!statement) {
return PStatement();
@ -2975,7 +2991,8 @@ void CppParser::internalParse(const QString &fileName)
}
}
void CppParser::inheritClassStatement(PStatement derived, bool isStruct, PStatement base, StatementClassScope access)
void CppParser::inheritClassStatement(const PStatement& derived, bool isStruct,
const PStatement& base, StatementClassScope access)
{
PFileIncludes fileIncludes1=mPreprocessor.includesList().value(derived->fileName);
PFileIncludes fileIncludes2=mPreprocessor.includesList().value(base->fileName);
@ -2991,7 +3008,7 @@ void CppParser::inheritClassStatement(PStatement derived, bool isStruct, PStatem
else
access = StatementClassScope::scsPrivate;
}
for (PStatement statement : base->children) {
for (const PStatement& statement : base->children) {
if (statement->classScope == StatementClassScope::scsPrivate
|| statement->kind == StatementKind::skConstructor
|| statement->kind == StatementKind::skDestructor)
@ -3021,10 +3038,12 @@ QString CppParser::expandMacroType(const QString &name)
return name;
}
void CppParser::fillListOfFunctions(const QString& fileName, int line,PStatement statement, PStatement scopeStatement, QStringList &list)
void CppParser::fillListOfFunctions(const QString& fileName, int line,
const PStatement& statement,
const PStatement& scopeStatement, QStringList &list)
{
StatementMap children = mStatementList.childrenStatements(scopeStatement);
for (PStatement child:children) {
for (const PStatement& child:children) {
if ((statement->command == child->command)
#ifdef Q_OS_WIN
|| (statement->command +'A' == child->command)
@ -3038,7 +3057,8 @@ void CppParser::fillListOfFunctions(const QString& fileName, int line,PStatement
}
}
PStatement CppParser::findMemberOfStatement(const QString &phrase, PStatement scopeStatement)
PStatement CppParser::findMemberOfStatement(const QString &phrase,
const PStatement& scopeStatement)
{
const StatementMap& statementMap =mStatementList.childrenStatements(scopeStatement);
if (statementMap.isEmpty())
@ -3058,13 +3078,14 @@ PStatement CppParser::findMemberOfStatement(const QString &phrase, PStatement sc
return statementMap.value(s,PStatement());
}
PStatement CppParser::findStatementInScope(const QString &name, const QString &noNameArgs, StatementKind kind, PStatement scope)
PStatement CppParser::findStatementInScope(const QString &name, const QString &noNameArgs,
StatementKind kind, const PStatement& scope)
{
if (scope && scope->kind == StatementKind::skNamespace) {
PStatementList namespaceStatementsList = findNamespace(scope->command);
if (!namespaceStatementsList)
return PStatement();
for (PStatement namespaceStatement: *namespaceStatementsList) {
for (const PStatement& namespaceStatement: *namespaceStatementsList) {
PStatement result=doFindStatementInScope(name,noNameArgs,kind,namespaceStatement);
if (result)
return result;
@ -3075,7 +3096,7 @@ PStatement CppParser::findStatementInScope(const QString &name, const QString &n
return PStatement();
}
PStatement CppParser::findStatementInScope(const QString &name, PStatement scope)
PStatement CppParser::findStatementInScope(const QString &name, const PStatement& scope)
{
if (!scope)
return findMemberOfStatement(name,scope);
@ -3091,7 +3112,7 @@ PStatement CppParser::findStatementInNamespace(const QString &name, const QStrin
PStatementList namespaceStatementsList=findNamespace(namespaceName);
if (!namespaceStatementsList)
return PStatement();
for (PStatement namespaceStatement:*namespaceStatementsList) {
for (const PStatement& namespaceStatement:*namespaceStatementsList) {
PStatement result = findMemberOfStatement(name,namespaceStatement);
if (result)
return result;
@ -3118,15 +3139,14 @@ int CppParser::getBracketEnd(const QString &s, int startAt)
return startAt;
}
PStatement CppParser::doFindStatementInScope(const QString &name, const QString &noNameArgs, StatementKind kind, PStatement scope)
PStatement CppParser::doFindStatementInScope(const QString &name,
const QString &noNameArgs,
StatementKind kind,
const PStatement& scope)
{
const StatementMap& statementMap =mStatementList.childrenStatements(scope);
if (statementMap.isEmpty())
return PStatement();
QList<PStatement> statementList = statementMap.values(name);
for (PStatement statement: statementList) {
for (const PStatement& statement: statementMap.values(name)) {
if (statement->kind == kind && statement->noNameArgs == noNameArgs) {
return statement;
}
@ -3140,8 +3160,8 @@ void CppParser::internalInvalidateFile(const QString &fileName)
return;
//remove all statements in the file
QList<QString> keys=mNamespaces.keys();
for (QString key:keys) {
const QList<QString>& keys=mNamespaces.keys();
for (const QString& key:keys) {
PStatementList statements = mNamespaces.value(key);
for (int i=statements->size()-1;i>=0;i--) {
PStatement statement = statements->at(i);
@ -3163,7 +3183,7 @@ void CppParser::internalInvalidateFile(const QString &fileName)
//fPreprocessor.InvalidDefinesInFile(FileName); //we don't need this, since we reset defines after each parse
//p->includeFiles.clear();
//p->usings.clear();
for (PStatement statement:p->statements) {
for (PStatement& statement:p->statements) {
if ((statement->kind == StatementKind::skFunction
|| statement->kind == StatementKind::skConstructor
|| statement->kind == StatementKind::skDestructor
@ -3173,7 +3193,7 @@ void CppParser::internalInvalidateFile(const QString &fileName)
}
}
for (PStatement statement:p->declaredStatements) {
for (PStatement& statement:p->declaredStatements) {
mStatementList.deleteStatement(statement);
}
@ -3204,7 +3224,7 @@ QSet<QString> CppParser::calculateFilesToBeReparsed(const QString &fileName)
PFileIncludes p=mPreprocessor.includesList().value(name);
if (!p)
continue;
for (QString s:p->dependedFiles) {
for (const QString& s:p->dependedFiles) {
if (!processed.contains(s)) {
queue.enqueue(s);
}
@ -3223,7 +3243,7 @@ int CppParser::calcKeyLenForStruct(const QString &word)
return -1;
}
void CppParser::scanMethodArgs(PStatement functionStatement, const QString &argStr)
void CppParser::scanMethodArgs(const PStatement& functionStatement, const QString &argStr)
{
// Split up argument string by ,
int i = 1; // assume it starts with ( and ends with )
@ -3596,6 +3616,16 @@ void CppParser::setParseGlobalHeaders(bool newParseGlobalHeaders)
mParseGlobalHeaders = newParseGlobalHeaders;
}
const QSet<QString> &CppParser::includePaths()
{
return mPreprocessor.includePaths();
}
const QSet<QString> &CppParser::projectIncludePaths()
{
return mPreprocessor.projectIncludePaths();
}
bool CppParser::parseLocalHeaders() const
{
return mParseLocalHeaders;
@ -3680,7 +3710,7 @@ void CppFileListParserThread::run()
}
}
void parseFile(PCppParser parser, QString fileName, bool inProject, bool onlyIfNotParsed, bool updateView)
void parseFile(PCppParser parser, const QString& fileName, bool inProject, bool onlyIfNotParsed, bool updateView)
{
CppFileParserThread* thread = new CppFileParserThread(parser,fileName,inProject,onlyIfNotParsed,updateView);
thread->connect(thread,

View File

@ -18,7 +18,7 @@ public:
~CppParser();
void addHardDefineByLine(const QString& line);
void addFileToScan(QString value, bool inProject = false);
void addFileToScan(const QString& value, bool inProject = false);
void addIncludePath(const QString& value);
void addProjectIncludePath(const QString& value);
void clearIncludePaths();
@ -32,7 +32,7 @@ public:
PFileIncludes findFileIncludes(const QString &filename, bool deleteIt = false);
QString findFirstTemplateParamOf(const QString& fileName,
const QString& phrase,
PStatement currentScope);
const PStatement& currentScope);
PStatement findFunctionAt(const QString& fileName,
int line);
int findLastOperator(const QString& phrase) const;
@ -42,21 +42,21 @@ public:
int line);
PStatement findStatementOf(const QString& fileName,
const QString& phrase,
PStatement currentScope,
const PStatement& currentScope,
PStatement& parentScopeType,
bool force = false);
PStatement findStatementOf(const QString& fileName,
const QString& phrase,
PStatement currentClass,
const PStatement& currentClass,
bool force = false);
//{Find statement starting from startScope}
PStatement findStatementStartingFrom(const QString& fileName,
const QString& phrase,
PStatement startScope,
const PStatement& startScope,
bool force = false);
PStatement findTypeDefinitionOf(const QString& fileName,
const QString& aType,
PStatement currentClass);
const PStatement& currentClass);
bool freeze(); // Freeze/Lock (stop reparse while searching)
bool freeze(const QString& serialId); // Freeze/Lock (stop reparse while searching)
QStringList getClassesList();
@ -65,7 +65,7 @@ public:
QSet<QString> getFileUsings(const QString& filename);
QString getHeaderFileName(const QString& relativeTo, const QString& line);// both
StatementKind getKindOfStatement(PStatement statement);
StatementKind getKindOfStatement(const PStatement& statement);
void invalidateFile(const QString& fileName);
bool isIncludeLine(const QString &line);
bool isProjectHeaderFile(const QString& fileName);
@ -78,6 +78,8 @@ public:
void reset();
void unFreeze(); // UnFree/UnLock (reparse while searching)
//void getSourcePair(const QString& fName, QString& CFile, QString& HFile);
// int suggestMemberInsertionLine(PStatement parentStatement,
@ -91,7 +93,7 @@ public:
//QString statementKindStr(StatementKind value);
//QString statementClassScopeStr(StatementClassScope value);
QString prettyPrintStatement(PStatement statement, int line = -1);
QString prettyPrintStatement(const PStatement& statement, int line = -1);
@ -119,6 +121,9 @@ public:
bool parseGlobalHeaders() const;
void setParseGlobalHeaders(bool newParseGlobalHeaders);
const QSet<QString>& includePaths();
const QSet<QString>& projectIncludePaths();
const StatementModel &statementList() const;
signals:
@ -128,13 +133,13 @@ signals:
void onEndParsing(int total, int updateView);
private:
PStatement addInheritedStatement(
PStatement derived,
PStatement inherit,
const PStatement& derived,
const PStatement& inherit,
StatementClassScope access);
PStatement addChildStatement(
// support for multiple parents (only typedef struct/union use multiple parents)
PStatement parent,
const PStatement& parent,
const QString& fileName,
const QString& hintText,
const QString& aType, // "Type" is already in use
@ -143,12 +148,12 @@ private:
const QString& value,
int line,
StatementKind kind,
StatementScope scope,
StatementClassScope classScope,
const StatementScope& scope,
const StatementClassScope& classScope,
bool isDefinition,
bool isStatic); // TODO: InheritanceList not supported
PStatement addStatement(
PStatement parent,
const PStatement& parent,
const QString &fileName,
const QString &hintText,
const QString &aType, // "Type" is already in use
@ -157,13 +162,13 @@ private:
const QString& value,
int line,
StatementKind kind,
StatementScope scope,
StatementClassScope classScope,
const StatementScope& scope,
const StatementClassScope& classScope,
bool isDefinition,
bool isStatic);
void setInheritance(int index, PStatement classStatement, bool isStruct);
void setInheritance(int index, const PStatement& classStatement, bool isStruct);
bool isCurrentScope(const QString& command);
void addSoloScopeLevel(PStatement statement, int line); // adds new solo level
void addSoloScopeLevel(PStatement& statement, int line); // adds new solo level
void removeScopeLevel(int line); // removes level
int skipBraces(int startAt);
int skipBracket(int startAt);
@ -185,18 +190,20 @@ private:
bool checkForVar();
QString expandMacroType(const QString& name);
//{procedure ResetDefines;}
void fillListOfFunctions(const QString& fileName, int line,PStatement statement, PStatement scopeStatement, QStringList& list);
void fillListOfFunctions(const QString& fileName, int line,
const PStatement& statement,
const PStatement& scopeStatement, QStringList& list);
PStatement findMemberOfStatement(
const QString& phrase,
PStatement scopeStatement);
const PStatement& scopeStatement);
PStatement findStatementInScope(
const QString& name,
const QString& noNameArgs,
StatementKind kind,
PStatement scope);
const PStatement& scope);
PStatement findStatementInScope(
const QString& name,
PStatement scope);
const PStatement& scope);
PStatement findStatementInNamespace(
const QString& name,
const QString& namespaceName);
@ -206,8 +213,8 @@ private:
int getCurrentBlockEndSkip();
int getCurrentInlineNamespaceEndSkip();
PStatement getCurrentScope(); // gets last item from last level
QString getFirstTemplateParam(PStatement statement, const QString& filename,
const QString& phrase, PStatement currentScope);
QString getFirstTemplateParam(const PStatement& statement, const QString& filename,
const QString& phrase, const PStatement& currentScope);
int getFirstTemplateParamEnd(const QString& s, int startAt);
void getFullNamespace(
@ -216,15 +223,16 @@ private:
QString& member);
QString getFullStatementName(
const QString& command,
PStatement parent);
const PStatement& parent);
PStatement getIncompleteClass(
const QString& command,
PStatement parentScope);
const PStatement& parentScope);
StatementScope getScope();
QString getStatementKey(const QString& sName,
const QString& sType,
const QString& sNoNameArgs);
PStatement getTypeDef(PStatement statement, const QString& fileName, const QString& aType);
PStatement getTypeDef(const PStatement& statement,
const QString& fileName, const QString& aType);
void handleCatchBlock();
void handleEnum();
void handleForBlock();
@ -246,14 +254,14 @@ private:
void internalParse(const QString& fileName);
// function FindMacroDefine(const Command: AnsiString): PStatement;
void inheritClassStatement(
PStatement derived,
const PStatement& derived,
bool isStruct,
PStatement base,
const PStatement& base,
StatementClassScope access);
PStatement doFindStatementInScope(const QString& name,
const QString& noNameArgs,
StatementKind kind,
PStatement scope);
const PStatement& scope);
void internalInvalidateFile(const QString& fileName);
void internalInvalidateFiles(const QSet<QString>& files);
QSet<QString> calculateFilesToBeReparsed(const QString& fileName);
@ -265,7 +273,7 @@ private:
// function GetRemainder(const Phrase: AnsiString): AnsiString;
// }
void scanMethodArgs(
PStatement functionStatement,
const PStatement& functionStatement,
const QString& argStr);
QString splitPhrase(const QString& phrase, QString& sClazz, QString &sMember,
QString& sOperator);
@ -401,7 +409,7 @@ protected:
void parseFile(
PCppParser parser,
QString fileName,
const QString& fileName,
bool inProject,
bool onlyIfNotParsed = false,
bool updateView = true);

View File

@ -154,8 +154,8 @@ void CppPreprocessor::invalidDefinesInFile(const QString &fileName)
{
PDefineMap defineMap = mFileDefines.value(fileName,PDefineMap());
if (defineMap) {
for (PDefine define:*defineMap) {
PDefine p = mDefines.value(define->name);
for (const PDefine& define:*defineMap) {
const PDefine& p = mDefines.value(define->name);
if (p == define) {
mDefines.remove(define->name);
}
@ -169,9 +169,9 @@ void CppPreprocessor::dumpDefinesTo(const QString &fileName) const
QFile file(fileName);
if (file.open(QIODevice::WriteOnly|QIODevice::Truncate)) {
QTextStream stream(&file);
for (PDefine define:mDefines) {
stream<<QString("%1 %2 %3 %4 %5\n").arg(define->name)
.arg(define->args).arg(define->value)
for (const PDefine& define:mDefines) {
stream<<QString("%1 %2 %3 %4 %5\n")
.arg(define->name,define->args,define->value)
.arg(define->hardCoded).arg(define->formatValue)
<<Qt::endl;
}
@ -183,27 +183,26 @@ void CppPreprocessor::dumpIncludesListTo(const QString &fileName) const
QFile file(fileName);
if (file.open(QIODevice::WriteOnly|QIODevice::Truncate)) {
QTextStream stream(&file);
for (PFileIncludes fileIncludes:mIncludesList) {
for (const PFileIncludes& fileIncludes:mIncludesList) {
stream<<fileIncludes->baseFile<<" : "<<Qt::endl;
stream<<"\t**includes:**"<<Qt::endl;
for (QString s:fileIncludes->includeFiles.keys()) {
for (const QString& s:fileIncludes->includeFiles.keys()) {
stream<<"\t--"+s<<Qt::endl;
}
stream<<"\t**depends on:**"<<Qt::endl;
for (QString s:fileIncludes->dependingFiles) {
for (const QString& s:fileIncludes->dependingFiles) {
stream<<"\t^^"+s<<Qt::endl;
}
stream<<"\t**depended by:**"<<Qt::endl;
for (QString s:fileIncludes->dependedFiles) {
for (const QString& s:fileIncludes->dependedFiles) {
stream<<"\t&&"+s<<Qt::endl;
}
stream<<"\t**using:**"<<Qt::endl;
for (QString s:fileIncludes->usings) {
for (const QString& s:fileIncludes->usings) {
stream<<"\t++"+s<<Qt::endl;
}
stream<<"\t**statements:**"<<Qt::endl;
for (std::weak_ptr<Statement> p:fileIncludes->statements) {
PStatement statement = p.lock();
for (PStatement& statement:fileIncludes->statements) {
if (statement) {
stream<<QString("\t**%1 , %2").arg(statement->command)
.arg(statement->fullName)<<Qt::endl;
@ -540,7 +539,7 @@ void CppPreprocessor::openInclude(const QString &fileName, QStringList bufferedT
if (topFile->fileIncludes->includeFiles.contains(fileName)) {
return; //already included
}
for (PParsedFile parsedFile:mIncludes) {
for (PParsedFile& parsedFile:mIncludes) {
parsedFile->fileIncludes->includeFiles.insert(fileName,false);
}
}
@ -611,7 +610,7 @@ void CppPreprocessor::openInclude(const QString &fileName, QStringList bufferedT
//add defines of already parsed including headers;
addDefinesInFile(fileName);
PFileIncludes fileIncludes = getFileIncludesEntry(fileName);
for (PParsedFile file:mIncludes) {
for (PParsedFile& file:mIncludes) {
file->fileIncludes->includeFiles.insert(fileIncludes->includeFiles);
}
}
@ -710,7 +709,7 @@ void CppPreprocessor::addDefinesInFile(const QString &fileName)
//first add the defines in the files it included
PFileIncludes fileIncludes = getFileIncludesEntry(fileName);
if (fileIncludes) {
for (QString s:fileIncludes->includeFiles.keys()) {
for (const QString& s:fileIncludes->includeFiles.keys()) {
addDefinesInFile(s);
}
}
@ -718,7 +717,7 @@ void CppPreprocessor::addDefinesInFile(const QString &fileName)
// then add the defines defined in it
PDefineMap defineList = mFileDefines.value(fileName, PDefineMap());
if (defineList) {
for (PDefine define: defineList->values()) {
for (const PDefine& define: defineList->values()) {
mDefines.insert(define->name,define);
}
}
@ -740,7 +739,7 @@ void CppPreprocessor::parseArgs(PDefine define)
QString formatStr = "";
DefineArgTokenType lastTokenType=DefineArgTokenType::Other;
int index;
for (PDefineArgToken token: tokens) {
for (const PDefineArgToken& token: tokens) {
switch(token->type) {
case DefineArgTokenType::Identifier:
index = define->argList.indexOf(token->value);
@ -851,7 +850,7 @@ QStringList CppPreprocessor::removeComments(const QStringList &text)
ContentType currentType = ContentType::Other;
QString delimiter;
for (QString line:text) {
for (const QString& line:text) {
QString s;
int pos = 0;
bool stopProcess=false;

View File

@ -50,7 +50,7 @@ void CppTokenizer::dumpTokens(const QString &fileName)
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
QTextStream stream(&file);
for (PToken token:mTokenList) {
for (const PToken& token:mTokenList) {
stream<<QString("%1,%2").arg(token->line).arg(token->text)<<Qt::endl;
}
}
@ -357,7 +357,7 @@ void CppTokenizer::simplify(QString &output)
{
//remove \n \r;
QString temp;
for (QChar ch:output) {
for (const QChar& ch:output) {
if (!isLineChar(ch))
temp+=ch;
}
@ -369,7 +369,7 @@ void CppTokenizer::simplifyArgs(QString &output)
QString temp;
QString lastSpace = "";
bool parentheseStart = true;
for (QChar ch:output.trimmed()) {
for (const QChar& ch:output.trimmed()) {
if (isSpaceChar(ch)) {
if (!parentheseStart)
lastSpace+=ch;

View File

@ -343,7 +343,7 @@ QString getSystemHeaderFilename(const QString &fileName, const QSet<QString>& in
{
// Search compiler include directories
for (QString path:includePaths) {
for (const QString& path:includePaths) {
QDir dir(path);
if (dir.exists(fileName))
return dir.absoluteFilePath(fileName);
@ -373,7 +373,7 @@ bool isSystemHeaderFile(const QString &fileName, const QSet<QString> &includePat
}
} else {
//check if it's in the include dir
for (QString includePath: includePaths) {
for (const QString& includePath: includePaths) {
QDir dir(includePath);
if (dir.exists(fileName))
return true;
@ -387,7 +387,7 @@ bool isKeyword(const QString &word)
return CppKeywords.contains(word);
}
bool isHfile(const QString filename)
bool isHfile(const QString& filename)
{
if (filename.isEmpty())
return false;
@ -397,7 +397,7 @@ bool isHfile(const QString filename)
}
bool isCfile(const QString filename)
bool isCfile(const QString& filename)
{
if (filename.isEmpty())
return false;
@ -464,7 +464,6 @@ void CppScopes::clear()
MemberOperatorType getOperatorType(const QString &phrase, int index)
{
MemberOperatorType result=MemberOperatorType::otOther;
if (index>=phrase.length())
return MemberOperatorType::otOther;
if (phrase[index] == '.')

View File

@ -200,8 +200,8 @@ QString getLocalHeaderFilename(const QString& relativeTo, const QString& fileNam
QString getSystemHeaderFilename(const QString& fileName, const QSet<QString>& includePaths);
bool isSystemHeaderFile(const QString& fileName, const QSet<QString>& includePaths);
bool isHfile(const QString filename);
bool isCfile(const QString filename);
bool isHfile(const QString& filename);
bool isCfile(const QString& filename);
bool isKeyword(const QString& word);
bool isScopeTypeKind(StatementKind kind);
MemberOperatorType getOperatorType(const QString& phrase, int index);

View File

@ -8,7 +8,7 @@ StatementModel::StatementModel(QObject *parent) : QObject(parent)
mCount = 0;
}
void StatementModel::add(PStatement statement)
void StatementModel::add(const PStatement& statement)
{
if (!statement) {
return ;
@ -26,7 +26,7 @@ void StatementModel::add(PStatement statement)
}
void StatementModel::deleteStatement(PStatement statement)
void StatementModel::deleteStatement(const PStatement& statement)
{
if (!statement) {
return ;
@ -45,7 +45,7 @@ void StatementModel::deleteStatement(PStatement statement)
}
const StatementMap &StatementModel::childrenStatements(PStatement statement) const
const StatementMap &StatementModel::childrenStatements(const PStatement& statement) const
{
if (!statement) {
return mGlobalStatements;
@ -97,7 +97,7 @@ void StatementModel::dumpAll(const QString &logFile)
}
#endif
void StatementModel::addMember(StatementMap &map, PStatement statement)
void StatementModel::addMember(StatementMap &map, const PStatement& statement)
{
if (!statement)
return ;
@ -110,7 +110,7 @@ void StatementModel::addMember(StatementMap &map, PStatement statement)
// lst->append(statement);
}
int StatementModel::deleteMember(StatementMap &map, PStatement statement)
int StatementModel::deleteMember(StatementMap &map, const PStatement& statement)
{
if (!statement)
return 0;

View File

@ -11,11 +11,11 @@ class StatementModel : public QObject
public:
explicit StatementModel(QObject *parent = nullptr);
void add(PStatement statement);
void add(const PStatement& statement);
// function DeleteFirst: Integer;
// function DeleteLast: Integer;
void deleteStatement(PStatement statement);
const StatementMap& childrenStatements(PStatement statement = PStatement()) const;
void deleteStatement(const PStatement& statement);
const StatementMap& childrenStatements(const PStatement& statement = PStatement()) const;
const StatementMap& childrenStatements(std::weak_ptr<Statement> statement) const;
void clear();
void dump(const QString& logFile);
@ -25,8 +25,8 @@ public:
signals:
private:
void addMember(StatementMap& map, PStatement statement);
int deleteMember(StatementMap& map, PStatement statement);
void addMember(StatementMap& map, const PStatement& statement);
int deleteMember(StatementMap& map, const PStatement& statement);
void dumpStatementMap(StatementMap& map, QTextStream& out, int level);
private:
int mCount;

View File

@ -1965,15 +1965,14 @@ void Settings::CompilerSets::loadSets()
.arg(pCurrentSet->name())
+"<br /><br />"
+msg
+"Would you like Dev-C++ to remove them for you and add the default paths to the valid paths?<br /><br />Leaving those directories will lead to problems during compilation.<br /><br />Unless you know exactly what you're doing, it is recommended that you click Yes.",
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+"Would you like Red Panda C++ to remove them for you and add the default paths to the valid paths?<br /><br />Leaving those directories will lead to problems during compilation.<br /><br />Unless you know exactly what you're doing, it is recommended that you click Yes.",
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
return;
}
findSets();
saveSets();
if ( mList.size() <= mDefaultIndex)
mDefaultIndex = mList.size()-1;
} else {
return;
}
pCurrentSet = defaultSet();
if (!pCurrentSet) {
return;
@ -1982,8 +1981,29 @@ void Settings::CompilerSets::loadSets()
if (pCurrentSet->binDirs().count()>0) {
pCurrentSet->setProperties(pCurrentSet->binDirs()[0]);
}
} else {
return;
}
} else {
if (QMessageBox::warning(nullptr,tr("Confirm"),
QObject::tr("Compiler set not configuared.")
+"<br /><br />"
+QObject::tr("Would you like Red Panda C++ to search for compilers in the following locations: <BR />'%1'<BR />'%2'? ")
.arg(includeTrailingPathDelimiter(pSettings->dirs().app()) + "MinGW32")
.arg(includeTrailingPathDelimiter(pSettings->dirs().app()) + "MinGW64"),
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
return;
}
clearSets();
findSets();
mDefaultIndex = mList.size()-1;
pCurrentSet = defaultSet();
if (!pCurrentSet) {
return;
}
saveSets();
}
}
void Settings::CompilerSets::saveDefaultIndex()

View File

@ -30,7 +30,7 @@
#error "Only support windows and linux now!"
#endif
#define DEVCPP_VERSION "0.01"
#define DEVCPP_VERSION "0.05"
class SystemConsts
{

View File

@ -0,0 +1,29 @@
#include "codecompletionlistview.h"
CodeCompletionListView::CodeCompletionListView(QWidget *parent) : QListView(parent)
{
}
void CodeCompletionListView::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Up
|| event->key() == Qt::Key_Down) {
QListView::keyPressEvent(event);
return;
}
if (!mKeypressedCallback || !mKeypressedCallback(event)) {
QListView::keyPressEvent(event);
}
}
const KeyPressedCallback &CodeCompletionListView::keypressedCallback() const
{
return mKeypressedCallback;
}
void CodeCompletionListView::setKeypressedCallback(const KeyPressedCallback &newKeypressedCallback)
{
mKeypressedCallback = newKeypressedCallback;
}

View File

@ -0,0 +1,26 @@
#ifndef CODECOMPLETIONLISTVIEW_H
#define CODECOMPLETIONLISTVIEW_H
#include <QListView>
#include <QKeyEvent>
#include "../parser/parserutils.h"
using KeyPressedCallback = std::function<bool (QKeyEvent *)>;
class CodeCompletionListView: public QListView {
Q_OBJECT
public:
explicit CodeCompletionListView(QWidget *parent = nullptr);
// QWidget interface
const KeyPressedCallback &keypressedCallback() const;
void setKeypressedCallback(const KeyPressedCallback &newKeypressedCallback);
protected:
void keyPressEvent(QKeyEvent *event) override;
private:
KeyPressedCallback mKeypressedCallback;
};
using ColorCallback = std::function<QColor (PStatement)>;
#endif // CODECOMPLETIONLISTVIEW_H

View File

@ -1,4 +1,4 @@
#include "codecompletionview.h"
#include "codecompletionpopup.h"
#include "../utils.h"
#include <QKeyEvent>
@ -6,7 +6,7 @@
#include <QDebug>
#include <QApplication>
CodeCompletionView::CodeCompletionView(QWidget *parent) :
CodeCompletionPopup::CodeCompletionPopup(QWidget *parent) :
QWidget(parent)
{
setWindowFlags(Qt::Popup);
@ -39,18 +39,18 @@ CodeCompletionView::CodeCompletionView(QWidget *parent) :
}
CodeCompletionView::~CodeCompletionView()
CodeCompletionPopup::~CodeCompletionPopup()
{
delete mListView;
delete mModel;
}
void CodeCompletionView::setKeypressedCallback(const KeyPressedCallback &newKeypressedCallback)
void CodeCompletionPopup::setKeypressedCallback(const KeyPressedCallback &newKeypressedCallback)
{
mListView->setKeypressedCallback(newKeypressedCallback);
}
void CodeCompletionView::prepareSearch(const QString &phrase, const QString &filename, int line)
void CodeCompletionPopup::prepareSearch(const QString &phrase, const QString &filename, int line)
{
QMutexLocker locker(&mMutex);
if (!isEnabled())
@ -71,7 +71,7 @@ void CodeCompletionView::prepareSearch(const QString &phrase, const QString &fil
setCursor(oldCursor);
}
bool CodeCompletionView::search(const QString &phrase, bool autoHideOnSingleResult)
bool CodeCompletionPopup::search(const QString &phrase, bool autoHideOnSingleResult)
{
QMutexLocker locker(&mMutex);
@ -118,7 +118,7 @@ bool CodeCompletionView::search(const QString &phrase, bool autoHideOnSingleResu
return false;
}
PStatement CodeCompletionView::selectedStatement()
PStatement CodeCompletionPopup::selectedStatement()
{
if (isEnabled()) {
int index = mListView->currentIndex().row();
@ -135,7 +135,7 @@ PStatement CodeCompletionView::selectedStatement()
return PStatement();
}
void CodeCompletionView::addChildren(PStatement scopeStatement, const QString &fileName, int line)
void CodeCompletionPopup::addChildren(PStatement scopeStatement, const QString &fileName, int line)
{
if (scopeStatement && !isIncluded(scopeStatement->fileName)
&& !isIncluded(scopeStatement->definitionFileName))
@ -145,7 +145,7 @@ void CodeCompletionView::addChildren(PStatement scopeStatement, const QString &f
return;
if (!scopeStatement) { //Global scope
for (PStatement childStatement: children) {
for (const PStatement& childStatement: children) {
if (childStatement->fileName.isEmpty()) {
// hard defines
addStatement(childStatement,fileName,-1);
@ -163,7 +163,7 @@ void CodeCompletionView::addChildren(PStatement scopeStatement, const QString &f
}
}
} else {
for (PStatement childStatement: children) {
for (const PStatement& childStatement: children) {
if (!( childStatement->kind == StatementKind::skConstructor
|| childStatement->kind == StatementKind::skDestructor
|| childStatement->kind == StatementKind::skBlock)
@ -173,7 +173,7 @@ void CodeCompletionView::addChildren(PStatement scopeStatement, const QString &f
}
}
void CodeCompletionView::addStatement(PStatement statement, const QString &fileName, int line)
void CodeCompletionPopup::addStatement(PStatement statement, const QString &fileName, int line)
{
if (mAddedStatements.contains(statement->command))
return;
@ -303,7 +303,7 @@ static bool sortByScopeWithUsageComparator(PStatement statement1,PStatement stat
return statement1->command < statement2->command;
}
void CodeCompletionView::filterList(const QString &member)
void CodeCompletionPopup::filterList(const QString &member)
{
QMutexLocker locker(&mMutex);
mCompletionStatementList.clear();
@ -326,7 +326,7 @@ void CodeCompletionView::filterList(const QString &member)
mCompletionStatementList.clear();
if (!member.isEmpty()) { // filter
mCompletionStatementList.reserve(mFullCompletionStatementList.size());
for (PStatement statement:mFullCompletionStatementList) {
foreach (const PStatement& statement, mFullCompletionStatementList) {
Qt::CaseSensitivity cs = (mIgnoreCase?
Qt::CaseInsensitive:
Qt::CaseSensitive);
@ -340,7 +340,7 @@ void CodeCompletionView::filterList(const QString &member)
int secondCount = 0;
int thirdCount = 0;
int usageCount;
for (PStatement statement:mCompletionStatementList) {
foreach (const PStatement& statement,mCompletionStatementList) {
if (statement->usageCount == 0) {
usageCount = mSymbolUsage.value(statement->fullName,0);
if (usageCount == 0)
@ -363,7 +363,7 @@ void CodeCompletionView::filterList(const QString &member)
thirdCount = usageCount;
}
}
for (PStatement statement:mCompletionStatementList) {
foreach (const PStatement& statement, mCompletionStatementList) {
if (statement->usageCount == 0) {
statement->freqTop = 0;
} else if (statement->usageCount == topCount) {
@ -395,7 +395,7 @@ void CodeCompletionView::filterList(const QString &member)
// }
}
void CodeCompletionView::getCompletionFor(const QString &fileName, const QString &phrase, int line)
void CodeCompletionPopup::getCompletionFor(const QString &fileName, const QString &phrase, int line)
{
if(!mParser)
return;
@ -412,7 +412,7 @@ void CodeCompletionView::getCompletionFor(const QString &fileName, const QString
//C++ preprocessor directives
if (phrase.startsWith('#')) {
if (mShowKeywords) {
for (QString keyword:CppDirectives) {
foreach (const QString& keyword, CppDirectives) {
PStatement statement = std::make_shared<Statement>();
statement->command = keyword;
statement->kind = StatementKind::skKeyword;
@ -428,7 +428,7 @@ void CodeCompletionView::getCompletionFor(const QString &fileName, const QString
//docstring tags (javadoc style)
if (phrase.startsWith('@')) {
if (mShowKeywords) {
for (QString keyword:JavadocTags) {
foreach (const QString& keyword,JavadocTags) {
PStatement statement = std::make_shared<Statement>();
statement->command = keyword;
statement->kind = StatementKind::skKeyword;
@ -448,7 +448,7 @@ void CodeCompletionView::getCompletionFor(const QString &fileName, const QString
if (mShowCodeIns) {
//add custom code templates
for (PCodeIns codeIn:mCodeInsList) {
foreach (const PCodeIns& codeIn,mCodeInsList) {
PStatement statement = std::make_shared<Statement>();
statement->command = codeIn->prefix;
statement->kind = StatementKind::skUserCodeIn;
@ -462,7 +462,7 @@ void CodeCompletionView::getCompletionFor(const QString &fileName, const QString
if (mShowKeywords) {
//add keywords
if (mUseCppKeyword) {
for (QString keyword:CppKeywords.keys()) {
foreach (const QString& keyword,CppKeywords.keys()) {
PStatement statement = std::make_shared<Statement>();
statement->command = keyword;
statement->kind = StatementKind::skKeyword;
@ -472,7 +472,7 @@ void CodeCompletionView::getCompletionFor(const QString &fileName, const QString
mFullCompletionStatementList.append(statement);
}
} else {
for (QString keyword:CKeywords) {
foreach (const QString& keyword,CKeywords) {
PStatement statement = std::make_shared<Statement>();
statement->command = keyword;
statement->kind = StatementKind::skKeyword;
@ -495,12 +495,12 @@ void CodeCompletionView::getCompletionFor(const QString &fileName, const QString
}
// add members of all usings (in current scope ) and not added before
for (QString namespaceName:scopeStatement->usingList) {
foreach (const QString& namespaceName,scopeStatement->usingList) {
PStatementList namespaceStatementsList =
mParser->findNamespace(namespaceName);
if (!namespaceStatementsList)
continue;
for (PStatement namespaceStatement:*namespaceStatementsList) {
foreach (const PStatement& namespaceStatement,*namespaceStatementsList) {
addChildren(namespaceStatement, fileName, line);
}
}
@ -512,12 +512,12 @@ void CodeCompletionView::getCompletionFor(const QString &fileName, const QString
// add members of all fusings
mUsings = mParser->getFileUsings(fileName);
for (QString namespaceName:mUsings) {
foreach (const QString& namespaceName, mUsings) {
PStatementList namespaceStatementsList =
mParser->findNamespace(namespaceName);
if (!namespaceStatementsList)
continue;
for (PStatement namespaceStatement:*namespaceStatementsList) {
foreach (const PStatement& namespaceStatement, *namespaceStatementsList) {
addChildren(namespaceStatement, fileName, line);
}
}
@ -535,7 +535,7 @@ void CodeCompletionView::getCompletionFor(const QString &fileName, const QString
PStatementList namespaceStatementsList =
mParser->findNamespace(scopeName);
if (namespaceStatementsList) {
for (PStatement namespaceStatement:*namespaceStatementsList) {
foreach (const PStatement& namespaceStatement, *namespaceStatementsList) {
addChildren(namespaceStatement, fileName, line);
}
return;
@ -633,7 +633,7 @@ void CodeCompletionView::getCompletionFor(const QString &fileName, const QString
const StatementMap& children = mParser->statementList().childrenStatements(classTypeStatement);
if (children.isEmpty())
return;
for (PStatement childStatement:children) {
foreach (const PStatement& childStatement, children) {
if ((childStatement->classScope==StatementClassScope::scsPublic)
&& !(
childStatement->kind == StatementKind::skConstructor
@ -654,7 +654,7 @@ void CodeCompletionView::getCompletionFor(const QString &fileName, const QString
return;
const StatementMap& children =
mParser->statementList().childrenStatements(classTypeStatement);
for (PStatement child:children) {
foreach (const PStatement& child,children) {
addStatement(child,fileName,line);
}
} else if ((opType == MemberOperatorType::otDColon)
@ -667,7 +667,7 @@ void CodeCompletionView::getCompletionFor(const QString &fileName, const QString
//we can use all static members
const StatementMap& children =
mParser->statementList().childrenStatements(classTypeStatement);
for (PStatement childStatement: children) {
foreach (const PStatement& childStatement, children) {
if (
(childStatement->isStatic)
|| (childStatement->kind == StatementKind::skTypedef
@ -683,7 +683,7 @@ void CodeCompletionView::getCompletionFor(const QString &fileName, const QString
// we can only use public static members
const StatementMap& children =
mParser->statementList().childrenStatements(classTypeStatement);
for (PStatement childStatement: children) {
foreach (const PStatement& childStatement,children) {
if (
(childStatement->isStatic)
|| (childStatement->kind == StatementKind::skTypedef
@ -703,122 +703,122 @@ void CodeCompletionView::getCompletionFor(const QString &fileName, const QString
}
}
bool CodeCompletionView::isIncluded(const QString &fileName)
bool CodeCompletionPopup::isIncluded(const QString &fileName)
{
return mIncludedFiles.contains(fileName);
}
void CodeCompletionView::showEvent(QShowEvent *)
void CodeCompletionPopup::showEvent(QShowEvent *)
{
mListView->setFocus();
}
const PStatement &CodeCompletionView::currentStatement() const
const PStatement &CodeCompletionPopup::currentStatement() const
{
return mCurrentStatement;
}
void CodeCompletionView::setCurrentStatement(const PStatement &newCurrentStatement)
void CodeCompletionPopup::setCurrentStatement(const PStatement &newCurrentStatement)
{
mCurrentStatement = newCurrentStatement;
}
QHash<StatementKind, QColor> &CodeCompletionView::colors()
QHash<StatementKind, QColor> &CodeCompletionPopup::colors()
{
return mColors;
}
bool CodeCompletionView::useCppKeyword() const
bool CodeCompletionPopup::useCppKeyword() const
{
return mUseCppKeyword;
}
void CodeCompletionView::setUseCppKeyword(bool newUseCppKeyword)
void CodeCompletionPopup::setUseCppKeyword(bool newUseCppKeyword)
{
mUseCppKeyword = newUseCppKeyword;
}
bool CodeCompletionView::sortByScope() const
bool CodeCompletionPopup::sortByScope() const
{
return mSortByScope;
}
void CodeCompletionView::setSortByScope(bool newSortByScope)
void CodeCompletionPopup::setSortByScope(bool newSortByScope)
{
mSortByScope = newSortByScope;
}
bool CodeCompletionView::ignoreCase() const
bool CodeCompletionPopup::ignoreCase() const
{
return mIgnoreCase;
}
void CodeCompletionView::setIgnoreCase(bool newIgnoreCase)
void CodeCompletionPopup::setIgnoreCase(bool newIgnoreCase)
{
mIgnoreCase = newIgnoreCase;
}
bool CodeCompletionView::showCodeIns() const
bool CodeCompletionPopup::showCodeIns() const
{
return mShowCodeIns;
}
void CodeCompletionView::setShowCodeIns(bool newShowCodeIns)
void CodeCompletionPopup::setShowCodeIns(bool newShowCodeIns)
{
mShowCodeIns = newShowCodeIns;
}
bool CodeCompletionView::showKeywords() const
bool CodeCompletionPopup::showKeywords() const
{
return mShowKeywords;
}
void CodeCompletionView::setShowKeywords(bool newShowKeywords)
void CodeCompletionPopup::setShowKeywords(bool newShowKeywords)
{
mShowKeywords = newShowKeywords;
}
bool CodeCompletionView::recordUsage() const
bool CodeCompletionPopup::recordUsage() const
{
return mRecordUsage;
}
void CodeCompletionView::setRecordUsage(bool newRecordUsage)
void CodeCompletionPopup::setRecordUsage(bool newRecordUsage)
{
mRecordUsage = newRecordUsage;
}
bool CodeCompletionView::onlyGlobals() const
bool CodeCompletionPopup::onlyGlobals() const
{
return mOnlyGlobals;
}
void CodeCompletionView::setOnlyGlobals(bool newOnlyGlobals)
void CodeCompletionPopup::setOnlyGlobals(bool newOnlyGlobals)
{
mOnlyGlobals = newOnlyGlobals;
}
int CodeCompletionView::showCount() const
int CodeCompletionPopup::showCount() const
{
return mShowCount;
}
void CodeCompletionView::setShowCount(int newShowCount)
void CodeCompletionPopup::setShowCount(int newShowCount)
{
mShowCount = newShowCount;
}
const PCppParser &CodeCompletionView::parser() const
const PCppParser &CodeCompletionPopup::parser() const
{
return mParser;
}
void CodeCompletionView::setParser(const PCppParser &newParser)
void CodeCompletionPopup::setParser(const PCppParser &newParser)
{
mParser = newParser;
}
void CodeCompletionView::hideEvent(QHideEvent *event)
void CodeCompletionPopup::hideEvent(QHideEvent *event)
{
QMutexLocker locker(&mMutex);
mListView->setKeypressedCallback(nullptr);
@ -830,7 +830,7 @@ void CodeCompletionView::hideEvent(QHideEvent *event)
QWidget::hideEvent(event);
}
bool CodeCompletionView::event(QEvent *event)
bool CodeCompletionPopup::event(QEvent *event)
{
bool result = QWidget::event(event);
if (event->type() == QEvent::FontChange) {
@ -839,34 +839,7 @@ bool CodeCompletionView::event(QEvent *event)
return result;
}
CodeCompletionListView::CodeCompletionListView(QWidget *parent) : QListView(parent)
{
}
void CodeCompletionListView::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Up
|| event->key() == Qt::Key_Down) {
QListView::keyPressEvent(event);
return;
}
if (!mKeypressedCallback || !mKeypressedCallback(event)) {
QListView::keyPressEvent(event);
}
}
const KeyPressedCallback &CodeCompletionListView::keypressedCallback() const
{
return mKeypressedCallback;
}
void CodeCompletionListView::setKeypressedCallback(const KeyPressedCallback &newKeypressedCallback)
{
mKeypressedCallback = newKeypressedCallback;
}
CodeCompletionListModel::CodeCompletionListModel(StatementList *statements, QObject *parent):
CodeCompletionListModel::CodeCompletionListModel(const StatementList *statements, QObject *parent):
QAbstractListModel(parent),
mStatements(statements)
{

View File

@ -1,33 +1,15 @@
#ifndef CODECOMPLETIONVIEW_H
#define CODECOMPLETIONVIEW_H
#ifndef CODECOMPLETIONPOPUP_H
#define CODECOMPLETIONPOPUP_H
#include <QListView>
#include <QWidget>
#include "parser/cppparser.h"
using KeyPressedCallback = std::function<bool (QKeyEvent *)>;
class CodeCompletionListView: public QListView {
Q_OBJECT
public:
explicit CodeCompletionListView(QWidget *parent = nullptr);
// QWidget interface
const KeyPressedCallback &keypressedCallback() const;
void setKeypressedCallback(const KeyPressedCallback &newKeypressedCallback);
protected:
void keyPressEvent(QKeyEvent *event) override;
private:
KeyPressedCallback mKeypressedCallback;
};
using ColorCallback = std::function<QColor (PStatement)>;
#include "codecompletionlistview.h"
class CodeCompletionListModel : public QAbstractListModel {
Q_OBJECT
public:
explicit CodeCompletionListModel(StatementList* statements,QObject *parent = nullptr);
explicit CodeCompletionListModel(const StatementList* statements,QObject *parent = nullptr);
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
void notifyUpdated();
@ -39,13 +21,13 @@ private:
ColorCallback mColorCallback;
};
class CodeCompletionView : public QWidget
class CodeCompletionPopup : public QWidget
{
Q_OBJECT
public:
explicit CodeCompletionView(QWidget *parent = nullptr);
~CodeCompletionView();
explicit CodeCompletionPopup(QWidget *parent = nullptr);
~CodeCompletionPopup();
void setKeypressedCallback(const KeyPressedCallback &newKeypressedCallback);
void prepareSearch(const QString& phrase, const QString& filename, int line);
@ -127,4 +109,4 @@ public:
bool event(QEvent *event) override;
};
#endif // CODECOMPLETIONVIEW_H
#endif // CODECOMPLETIONPOPUP_H

View File

@ -0,0 +1,236 @@
#include "headercompletionpopup.h"
#include <QCoreApplication>
#include <QDir>
#include <QFileInfo>
#include <QVBoxLayout>
HeaderCompletionPopup::HeaderCompletionPopup(QWidget* parent):QWidget(parent)
{
setWindowFlags(Qt::Popup);
mListView = new CodeCompletionListView(this);
mModel=new HeaderCompletionListModel(&mCompletionList);
mListView->setModel(mModel);
setLayout(new QVBoxLayout());
layout()->addWidget(mListView);
layout()->setMargin(0);
mSearchLocal = false;
mCurrentFile = "";
mPhrase = "";
mIgnoreCase = false;
}
HeaderCompletionPopup::~HeaderCompletionPopup()
{
delete mModel;
}
void HeaderCompletionPopup::prepareSearch(const QString &phrase, const QString &fileName)
{
QCursor oldCursor = cursor();
setCursor(Qt::WaitCursor);
mCurrentFile = fileName;
mPhrase = phrase;
getCompletionFor(phrase);
setCursor(oldCursor);
}
bool HeaderCompletionPopup::search(const QString &phrase, bool autoHideOnSingleResult)
{
mPhrase = phrase;
if (mPhrase.isEmpty()) {
hide();
return false;
}
if(!isEnabled())
return false;
QCursor oldCursor = cursor();
setCursor(Qt::WaitCursor);
int i = mPhrase.lastIndexOf('\\');
if (i<0) {
i = mPhrase.lastIndexOf('/');
}
QString symbol = mPhrase;
if (i>=0) {
symbol = mPhrase.mid(i+1);
}
// filter fFullCompletionList to fCompletionList
filterList(symbol);
mModel->notifyUpdated();
setCursor(oldCursor);
if (!mCompletionList.isEmpty()) {
if (mCompletionList.count() == 1) {
// if only one suggestion and auto hide , don't show the frame
if (autoHideOnSingleResult)
return true;
// if only one suggestion, and is exactly the symbol to search, hide the frame (the search is over)
if (symbol == mCompletionList.front())
return true;
}
} else {
hide();
}
return false;
}
void HeaderCompletionPopup::setKeypressedCallback(const KeyPressedCallback &newKeypressedCallback)
{
mListView->setKeypressedCallback(newKeypressedCallback);
}
void HeaderCompletionPopup::setSuggestionColor(const QColor &color)
{
mModel->setColor(color);
}
void HeaderCompletionPopup::filterList(const QString &member)
{
mCompletionList.clear();
if (member.isEmpty()) {
foreach (const QString& s,mFullCompletionList) {
mCompletionList.append(s);
}
} else {
foreach (const QString& s,mFullCompletionList) {
if (mIgnoreCase && s.startsWith(member, Qt::CaseInsensitive)) {
mCompletionList.append(s);
} else if (s.startsWith(member, Qt::CaseSensitive)){
mCompletionList.append(s);
}
}
}
std::sort(mCompletionList.begin(),mCompletionList.end());
}
void HeaderCompletionPopup::getCompletionFor(const QString &phrase)
{
int idx = phrase.lastIndexOf('\\');
if (idx<0) {
idx = phrase.lastIndexOf('/');
}
mFullCompletionList.clear();
if (idx < 0) { // dont have basedir
if (mSearchLocal) {
QFileInfo fileInfo(mCurrentFile);
addFilesInPath(fileInfo.absolutePath());
};
for (const QString& path: mParser->includePaths()) {
addFilesInPath(path);
}
for (const QString& path: mParser->projectIncludePaths()) {
addFilesInPath(path);
}
} else {
QString current = phrase.mid(0,idx);
if (mSearchLocal) {
QFileInfo fileInfo(mCurrentFile);
addFilesInSubDir(fileInfo.absolutePath(),current);
}
for (const QString& path: mParser->includePaths()) {
addFilesInSubDir(path,current);
}
for (const QString& path: mParser->projectIncludePaths()) {
addFilesInSubDir(path,current);
}
}
}
void HeaderCompletionPopup::addFilesInPath(const QString &path)
{
QDir dir(path);
if (!dir.exists())
return;
foreach (const QFileInfo& fileInfo, dir.entryInfoList()) {
QString suffix = fileInfo.suffix().toLower();
if (suffix == ".h" || suffix == ".hpp" || suffix == "") {
addFile(fileInfo.fileName());
}
}
}
void HeaderCompletionPopup::addFile(const QString &fileName)
{
if (fileName.isEmpty())
return;
if (fileName.startsWith('.'))
return;
mFullCompletionList.insert(fileName);
}
void HeaderCompletionPopup::addFilesInSubDir(const QString &baseDirPath, const QString &subDirName)
{
QDir baseDir(baseDirPath);
QString subDirPath = baseDir.filePath(subDirName);
addFilesInPath(subDirPath);
}
void HeaderCompletionPopup::showEvent(QShowEvent *)
{
mListView->setFocus();
}
void HeaderCompletionPopup::hideEvent(QHideEvent *)
{
mCompletionList.clear();
mFullCompletionList.clear();
}
bool HeaderCompletionPopup::event(QEvent *event)
{
bool result = QWidget::event(event);
switch (event->type()) {
case QEvent::FontChange:
mListView->setFont(font());
break;
}
return result;
}
HeaderCompletionListModel::HeaderCompletionListModel(const QStringList *files, QObject *parent):
QAbstractListModel(parent),
mFiles(files)
{
}
int HeaderCompletionListModel::rowCount(const QModelIndex &) const
{
return mFiles->count();
}
QVariant HeaderCompletionListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (index.row()>=mFiles->count())
return QVariant();
switch(role) {
case Qt::DisplayRole: {
return mFiles->at(index.row());
}
case Qt::ForegroundRole:
return mColor;
break;
}
return QVariant();
}
void HeaderCompletionListModel::notifyUpdated()
{
beginResetModel();
endResetModel();
}
void HeaderCompletionListModel::setColor(const QColor &newColor)
{
mColor = newColor;
}

View File

@ -0,0 +1,64 @@
#ifndef HEADERCOMPLETIONPOPUP_H
#define HEADERCOMPLETIONPOPUP_H
#include <QWidget>
#include "codecompletionlistview.h"
#include "../parser/cppparser.h"
class HeaderCompletionListModel: public QAbstractListModel {
Q_OBJECT
public:
explicit HeaderCompletionListModel(const QStringList* files,QObject *parent = nullptr);
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
void notifyUpdated();
void setColor(const QColor &newColor);
private:
const QStringList* mFiles;
QColor mColor;
};
class HeaderCompletionPopup : public QWidget
{
Q_OBJECT
public:
HeaderCompletionPopup(QWidget* parent=nullptr);
~HeaderCompletionPopup();
void prepareSearch(const QString& phrase, const QString& fileName);
bool search(const QString& phrase, bool autoHideOnSingleResult);
void setKeypressedCallback(const KeyPressedCallback &newKeypressedCallback);
void setSuggestionColor(const QColor& color);
private:
void filterList(const QString& member);
void getCompletionFor(const QString& phrase);
void addFilesInPath(const QString& path);
void addFile(const QString& fileName);
void addFilesInSubDir(const QString& baseDirPath, const QString& subDirName);
private:
CodeCompletionListView* mListView;
HeaderCompletionListModel* mModel;
QSet<QString> mFullCompletionList;
QStringList mCompletionList;
int mShowCount;
QSet<QString> mAddedFileNames;
PCppParser mParser;
QString mPhrase;
bool mIgnoreCase;
bool mSearchLocal;
QString mCurrentFile;
// QWidget interface
protected:
void showEvent(QShowEvent *event) override;
void hideEvent(QHideEvent *event) override;
// QObject interface
public:
bool event(QEvent *event) override;
};
#endif // HEADERCOMPLETIONPOPUP_H