Merge branch 'master' of github.com:royqh1979/RedPanda-CPP

This commit is contained in:
Roy Qu 2022-11-06 18:39:32 +08:00
commit d642ff3b74
28 changed files with 2639 additions and 1520 deletions

16
NEWS.md
View File

@ -1,3 +1,19 @@
Red Panda C++ Version 2.2
- enhancement: basic code completion support for C++ lambdas
- enhancement: slightly reduce parsing time
- fix: Wrong charset name returned when saving file
- fix: 'using =' / 'namespace =' not correctly handled
- fix: Pressing '*' at begin of line will crash app
- enhancement: switch header/source in editor's context menu
- enhancement: base class dropdown list in new class dialog now works
- fix: Edting / show context menu when code analysis is turned on may crash app.
- fix: Show context menu when edting non c/c++ file may crash app.
- fix: Project Options Dialog's Files panel will crash app.
- fix: Memory usage of undo system is not correctly calculated
- fix: Set max undo memory usage to 0 don't really remove limit of undo
- fix: Set max undo times to 0 don't really remove limit of undo
Red Panda C++ Version 2.1
- fix: editors that not in the editing panel shouldn't trigger switch breakpoint

View File

@ -6,7 +6,7 @@ Simplified Chinese Website: [https://royqh1979.gitee.io/redpandacpp/](https://ro
English Website: [https://sourceforge.net/projects/redpanda-cpp](https://sourceforge.net/projects/redpanda-cpp)
New Features (Compared with Red Panda Dev-C++ 6):
* Cross Platform (Windows/Linux)
* Cross Platform (Windows/Linux/MacOS)
* Problem Set (run and test program against predefined input / expected output data)
* Competitve Companion support ( It's an chrome/firefox extension that can fetch problems from OJ websites)
* Find symbol occurrences
@ -36,5 +36,6 @@ Code Intellisense Improvements:
* Support C++ 14 using type alias
* Support C-Style enum variable definitions
* Support MACRO with arguments
* Support C++ lambdas
And many other improvements and bug fixes. See NEWS.md for full informantion.

View File

@ -10,7 +10,7 @@ isEmpty(APP_NAME) {
}
isEmpty(APP_VERSION) {
APP_VERSION = 2.1
APP_VERSION = 2.2
}
macos: {

View File

@ -915,7 +915,7 @@ void Editor::onPreparePaintHighlightToken(int line, int aChar, const QString &to
if (token.isEmpty())
return;
if (mParser && mParser->enabled() && highlighter()) {
if (mParser && highlighter()) {
QString lineText = document()->getString(line-1);
if (mParser->isIncludeLine(lineText)) {
if (cursor() == Qt::PointingHandCursor) {
@ -932,7 +932,7 @@ void Editor::onPreparePaintHighlightToken(int line, int aChar, const QString &to
}
}
}
} else if (attr == highlighter()->identifierAttribute()) {
} else if (mParser->enabled() && attr == highlighter()->identifierAttribute()) {
QSynedit::BufferCoord p{aChar,line};
// BufferCoord pBeginPos,pEndPos;
// QString s= getWordAtPosition(this,p, pBeginPos,pEndPos, WordPurpose::wpInformation);
@ -1057,18 +1057,19 @@ bool Editor::event(QEvent *event)
switch (reason) {
case TipType::Preprocessor:
// When hovering above a preprocessor line, determine if we want to show an include or a identifier hint
if (mParser) {
s = document()->getString(p.line - 1);
isIncludeNextLine = mParser->isIncludeNextLine(s);
if (!isIncludeNextLine)
isIncludeLine = mParser->isIncludeLine(s);
if (!isIncludeNextLine &&!isIncludeLine)
s = wordAtRowCol(p);
}
break;
case TipType::Identifier:
if (pMainWindow->debugger()->executing() && !pMainWindow->debugger()->inferiorRunning())
s = getWordAtPosition(this,p, pBeginPos,pEndPos, WordPurpose::wpEvaluation); // debugging
else if (//devEditor.ParserHints and
!mCompletionPopup->isVisible()
else if (!mCompletionPopup->isVisible()
&& !mHeaderCompletionPopup->isVisible()) {
expression = getExpressionAtPosition(p);
s = expression.join(""); // information during coding
@ -1090,7 +1091,9 @@ bool Editor::event(QEvent *event)
s = s.trimmed();
if ((s == mCurrentWord) && (mCurrentTipType == reason)) {
if (qApp->queryKeyboardModifiers() == Qt::ControlModifier) {
if (mParser
&& mParser->enabled()
&& qApp->queryKeyboardModifiers() == Qt::ControlModifier) {
if (!hasFocus())
activate();
setCursor(Qt::PointingHandCursor);
@ -1148,7 +1151,9 @@ bool Editor::event(QEvent *event)
if (!hint.isEmpty()) {
// QApplication* app = dynamic_cast<QApplication *>(QApplication::instance());
// if (app->keyboardModifiers().testFlag(Qt::ControlModifier)) {
if (qApp->queryKeyboardModifiers() == Qt::ControlModifier) {
if (mParser
&& mParser->enabled()
&& qApp->queryKeyboardModifiers() == Qt::ControlModifier) {
if (!hasFocus())
activate();
setCursor(Qt::PointingHandCursor);
@ -1201,7 +1206,7 @@ void Editor::mouseReleaseEvent(QMouseEvent *event)
&& (event->button() == Qt::LeftButton)) {
QSynedit::BufferCoord p;
if (pointToCharLine(event->pos(),p)) {
if (mParser && pointToCharLine(event->pos(),p)) {
QString s = document()->getString(p.line - 1);
if (mParser->isIncludeNextLine(s)) {
QString filename = mParser->getHeaderFileName(mFilename,s, true);
@ -1211,7 +1216,7 @@ void Editor::mouseReleaseEvent(QMouseEvent *event)
QString filename = mParser->getHeaderFileName(mFilename,s);
pMainWindow->openFile(filename);
return;
} else {
} else if (mParser->enabled()) {
gotoDefinition(p);
return;
}
@ -2338,7 +2343,7 @@ bool Editor::handleBracketSkip()
bool Editor::handleMultilineCommentCompletion()
{
if ((caretX()-2 < lineText().length()) && (lineText()[caretX() - 2] == '/')) {
if ((caretX()-2>=0) && (caretX()-2 < lineText().length()) && (lineText()[caretX() - 2] == '/')) {
QString text=selText();
beginUpdate();
beginUndoBlock();
@ -3457,7 +3462,7 @@ bool Editor::onCompletionInputMethod(QInputMethodEvent *event)
Editor::TipType Editor::getTipType(QPoint point, QSynedit::BufferCoord& pos)
{
// Only allow in the text area...
if (pointToCharLine(point, pos)) {
if (pointToCharLine(point, pos) && highlighter()) {
if (!pMainWindow->debugger()->executing()
&& getSyntaxIssueAtPosition(pos)) {
return TipType::Error;
@ -3628,6 +3633,9 @@ void Editor::updateFunctionTip(bool showTip)
if (!highlighter())
return;
if (!mParser || !mParser->enabled())
return;
bool isFunction = false;
auto action = finally([&isFunction]{
if (!isFunction)

View File

@ -296,18 +296,18 @@ QPixmap IconsManager::getPixmapForStatement(PStatement statement)
case StatementKind::skFunction:
case StatementKind::skConstructor:
case StatementKind::skDestructor:
if (statement->scope == StatementScope::ssGlobal)
if (statement->scope == StatementScope::Global)
return *(pIconsManager->getPixmap(IconsManager::PARSER_GLOBAL_METHOD));
if (statement->isInherited) {
if (statement->classScope == StatementClassScope::scsProtected) {
if (statement->classScope == StatementClassScope::Protected) {
return *(pIconsManager->getPixmap(IconsManager::PARSER_INHERITED_PROTECTED_METHOD));
} else if (statement->classScope == StatementClassScope::scsPublic) {
} else if (statement->classScope == StatementClassScope::Public) {
return *(pIconsManager->getPixmap(IconsManager::PARSER_INHERITED_METHOD));
}
} else {
if (statement->classScope == StatementClassScope::scsProtected) {
if (statement->classScope == StatementClassScope::Protected) {
return *(pIconsManager->getPixmap(IconsManager::PARSER_PROTECTED_METHOD));
} else if (statement->classScope == StatementClassScope::scsPublic) {
} else if (statement->classScope == StatementClassScope::Public) {
return *(pIconsManager->getPixmap(IconsManager::PARSER_PUBLIC_METHOD));
} else {
return *(pIconsManager->getPixmap(IconsManager::PARSER_PRIVATE_METHOD));
@ -320,15 +320,15 @@ QPixmap IconsManager::getPixmapForStatement(PStatement statement)
return *(pIconsManager->getPixmap(IconsManager::PARSER_LOCAL_VAR));
case StatementKind::skVariable:
if (statement->isInherited) {
if (statement->classScope == StatementClassScope::scsProtected) {
if (statement->classScope == StatementClassScope::Protected) {
return *(pIconsManager->getPixmap(IconsManager::PARSER_INHERITED_PROTECTD_VAR));
} else if (statement->classScope == StatementClassScope::scsPublic) {
} else if (statement->classScope == StatementClassScope::Public) {
return *(pIconsManager->getPixmap(IconsManager::PARSER_INHERITED_VAR));
}
} else {
if (statement->classScope == StatementClassScope::scsProtected) {
if (statement->classScope == StatementClassScope::Protected) {
return *(pIconsManager->getPixmap(IconsManager::PARSER_PROTECTED_VAR));
} else if (statement->classScope == StatementClassScope::scsPublic) {
} else if (statement->classScope == StatementClassScope::Public) {
return *(pIconsManager->getPixmap(IconsManager::PARSER_PUBLIC_VAR));
} else {
return *(pIconsManager->getPixmap(IconsManager::PARSER_PRIVATE_VAR));

View File

@ -4416,13 +4416,20 @@ void MainWindow::onEditorContextMenu(const QPoint& pos)
int line;
if (editor->getPositionOfMouse(p)) {
line=p.line;
if (!switchHeaderSourceTarget(editor).isEmpty()) {
menu.addAction(ui->actionSwitchHeaderSource);
menu.addSeparator();
}
//mouse on editing area
menu.addAction(ui->actionCompile_Run);
menu.addAction(ui->actionDebug);
if (editor->parser() && editor->parser()->enabled()) {
menu.addSeparator();
menu.addAction(ui->actionGoto_Declaration);
menu.addAction(ui->actionGoto_Definition);
menu.addAction(ui->actionFind_references);
}
menu.addSeparator();
menu.addAction(ui->actionOpen_Containing_Folder);
@ -4449,9 +4456,11 @@ void MainWindow::onEditorContextMenu(const QPoint& pos)
menu.addAction(ui->actionFile_Properties);
//these actions needs parser
if (editor->parser() && editor->parser()->enabled()) {
ui->actionGoto_Declaration->setEnabled(!editor->parser()->parsing());
ui->actionGoto_Definition->setEnabled(!editor->parser()->parsing());
ui->actionFind_references->setEnabled(!editor->parser()->parsing());
}
} else {
//mouse on gutter
@ -6781,6 +6790,51 @@ void MainWindow::reparseNonProjectEditors()
}
}
QString MainWindow::switchHeaderSourceTarget(Editor *editor)
{
QString filename=editor->filename();
if (getFileType(filename)==FileType::CHeader
|| getFileType(filename)==FileType::CppHeader) {
QStringList lst;
lst.push_back("c");
lst.push_back("cc");
lst.push_back("cpp");
lst.push_back("cxx");
lst.push_back("C");
lst.push_back("CC");
foreach(const QString& suffix,lst) {
QString newFile=changeFileExt(filename,suffix);
if (fileExists(newFile)) {
return newFile;
}
}
} else if (getFileType(filename)==FileType::CSource) {
QStringList lst;
lst.push_back("h");
foreach(const QString& suffix,lst) {
QString newFile=changeFileExt(filename,suffix);
if (fileExists(newFile)) {
return newFile;
}
}
} else if (getFileType(filename)==FileType::CppSource) {
QStringList lst;
lst.push_back("h");
lst.push_back("hpp");
lst.push_back("hxx");
lst.push_back("HH");
lst.push_back("H");
foreach(const QString& suffix,lst) {
QString newFile=changeFileExt(filename,suffix);
if (fileExists(newFile)) {
return newFile;
}
}
}
return QString();
}
void MainWindow::onProjectViewNodeRenamed()
{
updateProjectView();
@ -7913,7 +7967,7 @@ void MainWindow::on_actionNew_Class_triggered()
{
if (!mProject)
return;
NewClassDialog dialog;
NewClassDialog dialog(mProject->cppParser());
dialog.setPath(mProject->folder());
if (dialog.exec()==QDialog::Accepted) {
QDir dir(dialog.path());
@ -7947,6 +8001,13 @@ void MainWindow::on_actionNew_Class_triggered()
header.append(QString("#ifndef %1").arg(header_macro));
header.append(QString("#define %1").arg(header_macro));
header.append("");
if (dialog.baseClass()) {
header.append(QString("#include \"%1\"").arg(extractRelativePath(mProject->directory(),
dialog.baseClass()->fileName)));
header.append("");
header.append(QString("class %1 : public %2 {").arg(dialog.className(),
dialog.baseClass()->fullName));
} else
header.append(QString("class %1 {").arg(dialog.className()));
header.append("public:");
header.append("");
@ -8655,3 +8716,13 @@ void MainWindow::on_actionGoto_block_end_triggered()
editor->gotoBlockEnd();
}
void MainWindow::on_actionSwitchHeaderSource_triggered()
{
Editor *editor=mEditorList->getEditor();
QString file=switchHeaderSourceTarget(editor);
if (!file.isEmpty()) {
openFile(file);
}
}

View File

@ -290,6 +290,7 @@ private:
void setProjectViewCurrentUnit(std::shared_ptr<ProjectUnit> unit);
void reparseNonProjectEditors();
QString switchHeaderSourceTarget(Editor *editor);
private slots:
void onProjectViewNodeRenamed();
@ -732,6 +733,8 @@ private slots:
void on_actionGoto_block_end_triggered();
void on_actionSwitchHeaderSource_triggered();
private:
Ui::MainWindow *ui;
EditorList *mEditorList;

View File

@ -3255,6 +3255,14 @@
<string>Ctrl+Alt+Down</string>
</property>
</action>
<action name="actionSwitchHeaderSource">
<property name="text">
<string>Switch header/source</string>
</property>
<property name="toolTip">
<string>Switch Header/Source</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

File diff suppressed because it is too large Load Diff

View File

@ -160,6 +160,7 @@ private:
const QString& aType, // "Type" is already in use
const QString& command,
const QString& args,
const QString& noNameArgs,
const QString& value,
int line,
StatementKind kind,
@ -173,6 +174,21 @@ private:
const QString &aType, // "Type" is already in use
const QString &command,
const QString &args,
const QString &noNameArgs,
const QString& value,
int line,
StatementKind kind,
const StatementScope& scope,
const StatementClassScope& classScope,
bool isDefinition,
bool isStatic);
PStatement addStatement(
const PStatement& parent,
const QString &fileName,
const QString &aType, // "Type" is already in use
const QString &command,
int argStart,
int argEnd,
const QString& value,
int line,
StatementKind kind,
@ -182,32 +198,30 @@ private:
bool isStatic);
void setInheritance(int index, const PStatement& classStatement, bool isStruct);
bool isCurrentScope(const QString& command);
void addSoloScopeLevel(PStatement& statement, int line, bool shouldResetBlock = true); // adds new solo level
void addSoloScopeLevel(PStatement& statement, int line, bool shouldResetBlock=false); // adds new solo level
void removeScopeLevel(int line); // removes level
int skipBraces(int startAt);
int skipBracket(int startAt);
int indexOfMatchingBrace(int startAt) {
return mTokenizer[startAt]->matchIndex;
}
void internalClear();
QStringList sortFilesByIncludeRelations(const QSet<QString> &files);
bool checkForCatchBlock();
bool checkForEnum();
bool checkForForBlock();
bool checkForKeyword();
bool checkForMethod(QString &sType, QString &sName, QString &sArgs,
bool &isStatic, bool &isFriend); // caching of results
bool checkForNamespace();
bool checkForKeyword(KeywordType &keywordType);
bool checkForMethod(QString &sType, QString &sName, int &argStartIndex,
int &argEndIndex, bool &isStatic, bool &isFriend); // caching of results
bool checkForNamespace(KeywordType keywordType);
bool checkForPreprocessor();
bool checkForScope();
void checkForSkipStatement();
bool checkForStructs();
bool checkForTypedef();
// bool checkForLambda();
bool checkForScope(KeywordType keywordType);
bool checkForStructs(KeywordType keywordType);
bool checkForTypedefEnum();
bool checkForTypedefStruct();
bool checkForUsing();
bool checkForVar();
QString expandMacroType(const QString& name);
bool checkForUsing(KeywordType keywordType);
void checkAndHandleMethodOrVar(KeywordType keywordType);
void fillListOfFunctions(const QString& fileName, int line,
const PStatement& statement,
@ -308,10 +322,23 @@ private:
void doSkipInExpression(const QStringList& expression, int&pos, const QString& startSymbol, const QString& endSymbol);
bool isIdentifier(const QString& token) const {
return (!token.isEmpty() && isLetterChar(token.front())
return (!token.isEmpty() && isIdentChar(token.front())
&& !token.contains('\"'));
}
bool isIdentifierOrPointer(const QString& term) const {
switch(term[0].unicode()) {
case '*':
return true;
case '\"':
case '\'':
return false;
default:
return isIdentChar(term[0]);
}
}
bool isIntegerLiteral(const QString& token) const {
if (token.isEmpty())
return false;
@ -335,6 +362,24 @@ private:
return false;
return (token.startsWith('\''));
}
bool isKeyword(const QString& token) const {
return mCppKeywords.contains(token);
}
bool tokenIsIdentifier(const QString& token) const {
//token won't be empty
return isIdentChar(token[0]);
}
bool tokenIsTypeOrNonKeyword(const QString& token) const {
return tokenIsIdentifier(token) &&
(mCppTypeKeywords.contains(token)
|| !mCppKeywords.contains(token)
|| token=="const");
}
PStatement doParseEvalTypeInfo(
const QString& fileName,
const PStatement& scope,
@ -343,7 +388,8 @@ private:
int& pointerLevel);
int getBracketEnd(const QString& s, int startAt);
StatementClassScope getClassScope(int index);
StatementClassScope getClassScope(const QString& text);
StatementClassScope getClassScope(KeywordType keywordType);
int getCurrentBlockBeginSkip();
int getCurrentBlockEndSkip();
int getCurrentInlineNamespaceEndSkip();
@ -370,23 +416,25 @@ private:
PStatement getTypeDef(const PStatement& statement,
const QString& fileName, const QString& aType);
void handleCatchBlock();
void handleEnum();
void handleEnum(bool isTypedef);
void handleForBlock();
void handleKeyword();
void handleKeyword(KeywordType skipType);
void handleLambda(int index, int endIndex);
void handleMethod(
StatementKind functionKind,
const QString& sType,
const QString& sName,
const QString& sArgs,
int argStart,
bool isStatic,
bool isFriend);
void handleNamespace();
void handleNamespace(KeywordType skipType);
void handleOtherTypedefs();
void handlePreprocessor();
void handleScope();
void handleScope(KeywordType keywordType);
bool handleStatement();
void handleStructs(bool isTypedef = false);
void handleUsing();
void handleVar();
void handleVar(const QString& typePrefix,bool isExtern,bool isStatic);
void internalParse(const QString& fileName);
// function FindMacroDefine(const Command: AnsiString): PStatement;
void inheritClassStatement(
@ -410,11 +458,12 @@ private:
// }
void scanMethodArgs(
const PStatement& functionStatement,
const QString& argStr);
int argStart);
QString splitPhrase(const QString& phrase, QString& sClazz,
QString& sOperator, QString &sMember);
QString removeTemplateParams(const QString& phrase);
QString removeArgNames(const QString& args);
bool splitLastMember(const QString& token, QString& lastMember, QString& remaining);
bool isSpaceChar(const QChar& ch) const {
return ch==' ' || ch =='\t';
@ -427,7 +476,14 @@ private:
|| ch == '&';
}
bool isLetterChar(const QChar& ch) const {
bool isIdentifier(const QChar& ch) const {
return ch.isLetter()
|| ch == '_'
|| ch == '~'
;
}
bool isIdentChar(const QChar& ch) const {
return ch.isLetter()
|| ch == '_';
}
@ -436,6 +492,24 @@ private:
return (ch>='0' && ch<='9');
}
bool isInvalidFunctionArgsSuffixChar(const QChar& ch) const {
// &&
switch(ch.unicode()){
case '.':
case '-':
case '+':
case '/':
case '%':
case '*':
case '|':
case '?':
return true;
default:
return false;
}
}
/*'(', ';', ':', '{', '}', '#' */
bool isSeperator(const QChar& ch) const {
switch(ch.unicode()){
@ -493,7 +567,7 @@ private:
return ch=='\n' || ch=='\r';
}
bool isNotFuncArgs(const QString& args);
bool isNotFuncArgs(int startIndex);
/**
* @brief Test if a statement is a class/struct/union/namespace/function
@ -511,7 +585,20 @@ private:
void updateSerialId();
int indexOfNextSemicolon(int index, int endIndex=-1);
int indexOfNextSemicolonOrLeftBrace(int index);
int indexOfNextColon(int index);
int indexOfNextLeftBrace(int index);
int indexPassParenthesis(int index);
int indexPassBraces(int index);
int skipAssignment(int index, int endIndex);
void skipNextSemicolon(int index);
int moveToNextBraceOrSkipNextSemicolon(int index, bool checkLambda, int endIndex=-1);
void skipParenthesis(int index);
QString mergeArgs(int startIndex, int endIndex);
void parseCommandTypeAndArgs(QString& command,
QString& typeSuffix,
QString& args);
private:
int mParserId;
ParserLanguage mLanguage;
@ -528,9 +615,6 @@ private:
QVector<PStatement> mCurrentScope;
QVector<StatementClassScope> mCurrentClassScope;
// the start index in tokens to skip to ; when parsing typedef struct we need to skip
// the names after the closing bracket because we have processed it
QVector<int> mSkipList; // TList<Integer>
StatementClassScope mClassScope;
StatementModel mStatementList;
//It's used in preprocessor, so we can't use fIncludeList instead
@ -554,7 +638,7 @@ private:
QMutex mMutex;
GetFileStreamCallBack mOnGetFileStream;
QMap<QString,SkipType> mCppKeywords;
QMap<QString,KeywordType> mCppKeywords;
QSet<QString> mCppTypeKeywords;
};
using PCppParser = std::shared_ptr<CppParser>;

View File

@ -18,6 +18,7 @@
#include <QFile>
#include <QTextStream>
#include <QDebug>
CppTokenizer::CppTokenizer()
{
@ -30,6 +31,10 @@ void CppTokenizer::clear()
mBuffer.clear();
mBufferStr.clear();
mLastToken.clear();
mUnmatchedBraces.clear();
mUnmatchedBrackets.clear();
mUnmatchedParenthesis.clear();
mLambdas.clear();
}
void CppTokenizer::tokenize(const QStringList &buffer)
@ -48,16 +53,26 @@ void CppTokenizer::tokenize(const QStringList &buffer)
mCurrent = mStart;
mLineCount = mStart;
QString s = "";
bool bSkipBlocks = false;
mCurrentLine = 1;
TokenType tokenType;
while (true) {
mLastToken = s;
s = getNextToken(true, true, bSkipBlocks);
s = getNextToken(&tokenType, true, false);
simplify(s);
if (s.isEmpty())
break;
else
addToken(s,mCurrentLine);
addToken(s,mCurrentLine,tokenType);
}
while (!mUnmatchedBraces.isEmpty()) {
addToken("}",mCurrentLine,TokenType::RightBrace);
}
while (!mUnmatchedBrackets.isEmpty()) {
addToken("]",mCurrentLine,TokenType::RightBracket);
}
while (!mUnmatchedParenthesis.isEmpty()) {
addToken(")",mCurrentLine,TokenType::RightParenthesis);
}
}
@ -68,7 +83,7 @@ void CppTokenizer::dumpTokens(const QString &fileName)
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
QTextStream stream(&file);
foreach (const PToken& token,mTokenList) {
stream<<QString("%1,%2").arg(token->line).arg(token->text)
stream<<QString("%1,%2,%3").arg(token->line).arg(token->text).arg(token->matchIndex)
#if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
<<Qt::endl;
#else
@ -93,11 +108,59 @@ int CppTokenizer::tokenCount()
return mTokenList.count();
}
void CppTokenizer::addToken(const QString &sText, int iLine)
void CppTokenizer::addToken(const QString &sText, int iLine, TokenType tokenType)
{
PToken token = std::make_shared<Token>();
token->text = sText;
token->line = iLine;
#ifdef Q_DEBUG
token->matchIndex = 1000000000;
#endif
switch(tokenType) {
case TokenType::LeftBrace:
token->matchIndex=-1;
mUnmatchedBraces.push_back(mTokenList.count());
break;
case TokenType::RightBrace:
if (mUnmatchedBraces.isEmpty()) {
token->matchIndex=-1;
} else {
token->matchIndex = mUnmatchedBraces.last();
mTokenList[token->matchIndex]->matchIndex=mTokenList.count();
mUnmatchedBraces.pop_back();
}
break;
case TokenType::LeftBracket:
token->matchIndex=-1;
mUnmatchedBrackets.push_back(mTokenList.count());
break;
case TokenType::RightBracket:
if (mUnmatchedBrackets.isEmpty()) {
token->matchIndex=-1;
} else {
token->matchIndex = mUnmatchedBrackets.last();
mTokenList[token->matchIndex]->matchIndex=mTokenList.count();
mUnmatchedBrackets.pop_back();
}
break;
case TokenType::LeftParenthesis:
token->matchIndex=-1;
mUnmatchedParenthesis.push_back(mTokenList.count());
break;
case TokenType::RightParenthesis:
if (mUnmatchedParenthesis.isEmpty()) {
token->matchIndex=-1;
} else {
token->matchIndex = mUnmatchedParenthesis.last();
mTokenList[token->matchIndex]->matchIndex=mTokenList.count();
mUnmatchedParenthesis.pop_back();
}
break;
case TokenType::LambdaCaptures:
mLambdas.push_back(mTokenList.count());
default:
break;
}
mTokenList.append(token);
}
@ -110,28 +173,6 @@ void CppTokenizer::countLines()
}
}
QString CppTokenizer::getArguments()
{
QChar* offset = mCurrent;
skipPair('(', ')');
QString result(offset,mCurrent-offset);
simplifyArgs(result);
if ((*mCurrent == '.') || ((*mCurrent == '-') && (*(mCurrent + 1) == '>'))) {
// skip '.' and '->'
while ( !( *mCurrent == 0
|| *mCurrent == '('
|| *mCurrent == ';'
|| *mCurrent == '{'
|| *mCurrent == '}'
|| *mCurrent == ')'
|| isLineChar(*mCurrent)
|| isSpaceChar(*mCurrent)) )
mCurrent++;
}
skipToNextToken();
return result;
}
QString CppTokenizer::getForInit()
{
QChar* startOffset = mCurrent;
@ -139,12 +180,13 @@ QString CppTokenizer::getForInit()
// Step into the init statement
mCurrent++;
TokenType tokenType;
// Process until ; or end of file
while (true) {
QString s = getNextToken(true, true, false);
QString s = getNextToken(&tokenType, true, false);
simplify(s);
if (!s.isEmpty())
addToken(s,mCurrentLine);
addToken(s,mCurrentLine,tokenType);
if ( (s == "") || (s == ";") || (s==":"))
break;
// : is used in for-each loop
@ -156,10 +198,12 @@ QString CppTokenizer::getForInit()
return "";
}
QString CppTokenizer::getNextToken(bool /* bSkipParenthesis */, bool bSkipArray, bool bSkipBlock)
QString CppTokenizer::getNextToken(TokenType *pTokenType, bool bSkipArray, bool bSkipBlock)
{
QString result;
int backupIndex;
bool done = false;
*pTokenType=TokenType::Normal;
while (true) {
skipToNextToken();
if (*mCurrent == 0)
@ -179,13 +223,18 @@ QString CppTokenizer::getNextToken(bool /* bSkipParenthesis */, bool bSkipArray,
countLines();
result = getForInit();
done = (result != "");
} else if (isArguments()) {
countLines();
result = getArguments();
done = (result != "");
// } else if (isArguments()) {
// countLines();
// result = getArguments();
// done = (result != "");
} else if (isWord()) {
countLines();
result = getWord(false, bSkipArray, bSkipBlock);
// if (result=="noexcept" || result == "throw") {
// result="";
// if (*mCurrent=='(')
// skipPair('(',')');
// }
done = (result != "");
} else if (isNumber()) {
countLines();
@ -196,49 +245,119 @@ QString CppTokenizer::getNextToken(bool /* bSkipParenthesis */, bool bSkipArray,
case 0:
done = true;
break;
case '/':
advance();
break;
case ':':
if (*(mCurrent + 1) == ':') {
countLines();
mCurrent+=2;
result = "::";
skipToNextToken();
// Append next token to this one
result = "::"+getWord(true, bSkipArray, bSkipBlock);
if (isIdentChar(*mCurrent))
result+=getWord(true, bSkipArray, bSkipBlock);
done = true;
} else {
countLines();
result = *mCurrent;
advance();
mCurrent++;
done = true;
}
break;
case '{':
*pTokenType=TokenType::LeftBrace;
countLines();
result = *mCurrent;
mCurrent++;
done = true;
break;
case '}':
*pTokenType=TokenType::RightBrace;
countLines();
result = *mCurrent;
mCurrent++;
done = true;
break;
case '(':
*pTokenType=TokenType::LeftParenthesis;
countLines();
result = *mCurrent;
mCurrent++;
done = true;
break;
case '[':
if (*(mCurrent+1)!='[') {
*pTokenType=TokenType::LambdaCaptures;
countLines();
QChar* backup=mCurrent;
skipPair('[',']');
result = QString(backup,mCurrent-backup);
done = true;
} else {
skipPair('[',']'); // attribute, skipit
}
break;
case ')':
*pTokenType=TokenType::RightParenthesis;
countLines();
result = *mCurrent;
mCurrent++;
done = true;
break;
case ';':
case ',': //just return the brace or the ';'
countLines();
result = *mCurrent;
advance();
mCurrent++;
done = true;
break;
case '>': // keep stream operators
if (*(mCurrent + 1) == '>') {
countLines();
result = ">>";
advance();
mCurrent+=2;
done = true;
} else
advance();
mCurrent+=1;
break;
case '<':
if (*(mCurrent + 1) == '<') {
countLines();
result = "<<";
advance();
mCurrent+=2;
done = true;
} else
advance();
mCurrent+=1;
break;
case '=': {
if (*(mCurrent+1)=='=') {
// skip '=='
skipAssignment();
} else {
countLines();
mCurrent+=1;
result = "=";
done = true;
}
break;
}
break;
case '!':
if (*(mCurrent+1)=='=') {
skipAssignment();
} else
mCurrent++;
break;
case '/':
case '%':
case '&':
case '*':
case '|':
case '+':
case '-':
case '~':
if (*(mCurrent + 1) == '=') {
skipAssignment();
} else
mCurrent++;
break;
default:
advance();
@ -256,7 +375,8 @@ QString CppTokenizer::getNumber()
if (isDigitChar(*mCurrent)) {
while (isDigitChar(*mCurrent) || isHexChar(*mCurrent)) {
advance();
mCurrent++;
//advance();
}
}
@ -321,10 +441,11 @@ QString CppTokenizer::getWord(bool bSkipParenthesis, bool bSkipArray, bool bSkip
// Skip template contents, but keep template variable types
if (*mCurrent == '<') {
offset = mCurrent; //we don't skip
skipTemplateArgs();
offset = mCurrent;
if (!bFoundTemplate) {
if (bFoundTemplate) {
skipTemplateArgs();
} else if (skipAngleBracketPair()){
result += QString(offset, mCurrent-offset);
skipToNextToken();
}
@ -355,12 +476,15 @@ QString CppTokenizer::getWord(bool bSkipParenthesis, bool bSkipArray, bool bSkip
if (result != "using") {
result+=QString(mCurrent,2);
mCurrent+=2;
skipToNextToken();
if (isIdentChar(*mCurrent)) {
// Append next token to this one
QString s = getWord(bSkipParenthesis, bSkipArray, bSkipBlock);
result += s;
}
}
}
}
return result;
}
@ -480,18 +604,18 @@ void CppTokenizer::skipDoubleQuotes()
}
}
void CppTokenizer::skipPair(const QChar &cStart, const QChar cEnd, const QSet<QChar>& failChars)
void CppTokenizer::skipPair(const QChar &cStart, const QChar cEnd)
{
mCurrent++;
while (*mCurrent != 0) {
if ((*mCurrent == '(') && !failChars.contains('(')) {
skipPair('(', ')', failChars);
} else if ((*mCurrent == '[') && !failChars.contains('[')) {
skipPair('[', ']', failChars);
} else if ((*mCurrent == '{') && !failChars.contains('{')) {
skipPair('{', '}', failChars);
if (*mCurrent == '(') {
skipPair('(', ')');
} else if (*mCurrent == '[') {
skipPair('[', ']');
} else if (*mCurrent == '{') {
skipPair('{', '}');
} else if (*mCurrent == cStart) {
skipPair(cStart, cEnd, failChars);
skipPair(cStart, cEnd);
} else if (*mCurrent == cEnd) {
mCurrent++; // skip over end
break;
@ -510,14 +634,81 @@ void CppTokenizer::skipPair(const QChar &cStart, const QChar cEnd, const QSet<QC
skipSingleQuote(); // don't do it inside AnsiString!
else
mCurrent++;
} else if (failChars.contains(*mCurrent)) {
break;
} else {
mCurrent++;
}
}
}
bool CppTokenizer::skipAngleBracketPair()
{
QChar* backup=mCurrent;
QVector<QChar> stack;
while (*mCurrent != '\0') {
switch((*mCurrent).unicode()) {
case '<':
case '(':
case '[':
stack.push_back(*mCurrent);
break;
case ')':
while (!stack.isEmpty() && stack.back()!='(') {
stack.pop_back();
}
//pop up '('
if (stack.isEmpty()) {
mCurrent=backup;
return false;
}
stack.pop_back();
break;
case ']':
while (!stack.isEmpty() && stack.back()!='[')
stack.pop_back();
//pop up '['
if (stack.isEmpty()) {
mCurrent=backup;
return false;
}
stack.pop_back();
break;
case '>':
if (stack.back()=='<')
stack.pop_back();
if (stack.isEmpty()) {
mCurrent++;
return true;
}
break;
case '{':
case '}':
case ';':
case '"':
case '\'':
mCurrent=backup;
return false;
case '-':
if (*(mCurrent+1)=='>') {
mCurrent=backup;
return false;
}
break;
case '.':
if (*(mCurrent+1)!='.') {
mCurrent=backup;
return false;
}
// skip
while (*(mCurrent+1)=='.')
mCurrent++;
break;
}
mCurrent++;
}
mCurrent=backup;
return false;
}
void CppTokenizer::skipRawString()
{
mCurrent++; //skip R
@ -566,17 +757,8 @@ void CppTokenizer::skipTemplateArgs()
{
if (*mCurrent != '<')
return;
QChar* start = mCurrent;
QSet<QChar> failSet;
failSet.insert('{');
failSet.insert('}');
failSet.insert(';');
skipPair('<', '>', failSet);
// if we failed, return to where we came from
if (start!=mCurrent && *(mCurrent - 1) != '>')
mCurrent = start;
skipPair('<', '>');
}
void CppTokenizer::skipToEOL()
@ -601,7 +783,7 @@ void CppTokenizer::skipToEOL()
void CppTokenizer::skipToNextToken()
{
while (isSpaceChar(*mCurrent) || isLineChar(*mCurrent))
advance();
mCurrent++;
}
bool CppTokenizer::isIdentChar(const QChar &ch)
@ -609,39 +791,29 @@ bool CppTokenizer::isIdentChar(const QChar &ch)
return ch=='_' || ch.isLetter() ;
}
int CppTokenizer::lambdasCount() const
{
return mLambdas.count();
}
int CppTokenizer::indexOfFirstLambda() const
{
return mLambdas.front();
}
void CppTokenizer::removeFirstLambda()
{
mLambdas.pop_front();
}
void CppTokenizer::advance()
{
switch(mCurrent->unicode()) {
case '\"': skipDoubleQuotes();
case '\"':
skipDoubleQuotes();
break;
case '\'': skipSingleQuote();
break;
case '/':
if (*(mCurrent + 1) == '=')
skipAssignment();
else
mCurrent++;
break;
case '=': {
if (mTokenList.size()>2
&& mTokenList[mTokenList.size()-2]->text == "using") {
addToken("=",mCurrentLine);
mCurrent++;
} else
skipAssignment();
break;
}
case '&':
case '*':
case '!':
case '|':
case '+':
case '-':
case '~':
if (*(mCurrent + 1) == '=')
skipAssignment();
else
mCurrent++;
case '\'':
skipSingleQuote();
break;
case '\\':
if (isLineChar(*(mCurrent + 1)))
@ -649,11 +821,14 @@ void CppTokenizer::advance()
else
mCurrent++;
break;
default:
if ((*mCurrent == 'R') && (*(mCurrent+1) == '"'))
case 'R':
if (*(mCurrent+1) == '"')
skipRawString();
else
mCurrent++;
break;
default:
mCurrent++;
}
}
@ -693,7 +868,7 @@ bool CppTokenizer::isLineChar(const QChar &ch)
bool CppTokenizer::isBlankChar(const QChar &ch)
{
return (ch<=32);
return (ch<=32) && (ch>0);
}
bool CppTokenizer::isOperatorChar(const QChar &ch)

View File

@ -22,10 +22,23 @@
class CppTokenizer
{
enum class TokenType {
Normal,
LeftBrace,
RightBrace,
LeftParenthesis,
RightParenthesis,
LeftBracket,
RightBracket,
Assignment,
LambdaCaptures
};
public:
struct Token {
QString text;
int line;
int matchIndex;
};
using PToken = std::shared_ptr<Token>;
using TokenList = QVector<PToken>;
@ -38,16 +51,19 @@ public:
PToken operator[](int i);
int tokenCount();
bool isIdentChar(const QChar& ch);
int lambdasCount() const;
int indexOfFirstLambda() const;
void removeFirstLambda();
private:
void addToken(const QString& sText, int iLine);
void addToken(const QString& sText, int iLine, TokenType tokenType);
void advance();
void countLines();
PToken getToken(int index);
QString getArguments();
QString getForInit();
QString getNextToken(
bool bSkipParenthesis = false,
TokenType *pTokenType,
bool bSkipArray = false,
bool bSkipBlock = false);
QString getNumber();
@ -65,7 +81,8 @@ private:
void simplifyArgs(QString& output);
void skipAssignment();
void skipDoubleQuotes();
void skipPair(const QChar& cStart, const QChar cEnd, const QSet<QChar>& failChars = QSet<QChar>());
void skipPair(const QChar& cStart, const QChar cEnd);
bool skipAngleBracketPair();
void skipRawString();
void skipSingleQuote();
void skipSplitLine();
@ -92,6 +109,10 @@ private:
int mCurrentLine;
QString mLastToken;
TokenList mTokenList;
QList<int> mLambdas;
QVector<int> mUnmatchedBraces; // stack of indices for unmatched '{'
QVector<int> mUnmatchedBrackets; // stack of indices for unmatched '['
QVector<int> mUnmatchedParenthesis;// stack of indices for unmatched '('
};
using PCppTokenizer = std::shared_ptr<CppTokenizer>;

View File

@ -25,7 +25,7 @@
QStringList CppDirectives;
QStringList JavadocTags;
QMap<QString,SkipType> CppKeywords;
QMap<QString,KeywordType> CppKeywords;
QSet<QString> CppControlKeyWords;
QSet<QString> CppTypeKeywords;
QSet<QString> CKeywords;
@ -55,107 +55,107 @@ void initParser()
CppSourceExts->insert("c++");
CppSourceExts->insert("cp");
// skip itself
CppKeywords.insert("and",SkipType::skItself);
CppKeywords.insert("and_eq",SkipType::skItself);
CppKeywords.insert("bitand",SkipType::skItself);
CppKeywords.insert("bitor",SkipType::skItself);
CppKeywords.insert("break",SkipType::skItself);
CppKeywords.insert("compl",SkipType::skItself);
CppKeywords.insert("constexpr",SkipType::skItself);
CppKeywords.insert("const_cast",SkipType::skItself);
CppKeywords.insert("continue",SkipType::skItself);
CppKeywords.insert("dynamic_cast",SkipType::skItself);
CppKeywords.insert("else",SkipType::skItself);
CppKeywords.insert("explicit",SkipType::skItself);
CppKeywords.insert("export",SkipType::skItself);
CppKeywords.insert("false",SkipType::skItself);
CppKeywords.insert("and",KeywordType::SkipItself);
CppKeywords.insert("and_eq",KeywordType::SkipItself);
CppKeywords.insert("bitand",KeywordType::SkipItself);
CppKeywords.insert("bitor",KeywordType::SkipItself);
CppKeywords.insert("break",KeywordType::SkipItself);
CppKeywords.insert("compl",KeywordType::SkipItself);
CppKeywords.insert("constexpr",KeywordType::SkipItself);
CppKeywords.insert("const_cast",KeywordType::SkipItself);
CppKeywords.insert("continue",KeywordType::SkipItself);
CppKeywords.insert("dynamic_cast",KeywordType::SkipItself);
CppKeywords.insert("else",KeywordType::SkipItself);
CppKeywords.insert("explicit",KeywordType::SkipItself);
CppKeywords.insert("export",KeywordType::SkipItself);
CppKeywords.insert("false",KeywordType::SkipItself);
//CppKeywords.insert("for",SkipType::skItself);
CppKeywords.insert("mutable",SkipType::skItself);
CppKeywords.insert("noexcept",SkipType::skItself);
CppKeywords.insert("not",SkipType::skItself);
CppKeywords.insert("not_eq",SkipType::skItself);
CppKeywords.insert("nullptr",SkipType::skItself);
CppKeywords.insert("or",SkipType::skItself);
CppKeywords.insert("or_eq",SkipType::skItself);
CppKeywords.insert("register",SkipType::skItself);
CppKeywords.insert("reinterpret_cast",SkipType::skItself);
CppKeywords.insert("static_assert",SkipType::skItself);
CppKeywords.insert("static_cast",SkipType::skItself);
CppKeywords.insert("template",SkipType::skItself);
CppKeywords.insert("mutable",KeywordType::SkipItself);
CppKeywords.insert("noexcept",KeywordType::SkipItself);
CppKeywords.insert("not",KeywordType::SkipItself);
CppKeywords.insert("not_eq",KeywordType::SkipItself);
CppKeywords.insert("nullptr",KeywordType::SkipItself);
CppKeywords.insert("or",KeywordType::SkipItself);
CppKeywords.insert("or_eq",KeywordType::SkipItself);
CppKeywords.insert("register",KeywordType::SkipItself);
CppKeywords.insert("reinterpret_cast",KeywordType::SkipItself);
CppKeywords.insert("static_cast",KeywordType::SkipItself);
CppKeywords.insert("template",KeywordType::SkipItself);
//CppKeywords.insert("this",SkipType::skItself);
CppKeywords.insert("thread_local",SkipType::skItself);
CppKeywords.insert("true",SkipType::skItself);
CppKeywords.insert("typename",SkipType::skItself);
CppKeywords.insert("virtual",SkipType::skItself);
CppKeywords.insert("volatile",SkipType::skItself);
CppKeywords.insert("xor",SkipType::skItself);
CppKeywords.insert("xor_eq",SkipType::skItself);
CppKeywords.insert("thread_local",KeywordType::SkipItself);
CppKeywords.insert("true",KeywordType::SkipItself);
CppKeywords.insert("typename",KeywordType::SkipItself);
CppKeywords.insert("virtual",KeywordType::SkipItself);
CppKeywords.insert("volatile",KeywordType::SkipItself);
CppKeywords.insert("xor",KeywordType::SkipItself);
CppKeywords.insert("xor_eq",KeywordType::SkipItself);
//CppKeywords.insert("catch",SkipType::skItself);
CppKeywords.insert("do",SkipType::skItself);
CppKeywords.insert("try",SkipType::skItself);
CppKeywords.insert("do",KeywordType::SkipItself);
CppKeywords.insert("try",KeywordType::SkipItself);
// Skip to ;
CppKeywords.insert("delete",SkipType::skToSemicolon);
CppKeywords.insert("delete[]",SkipType::skToSemicolon);
CppKeywords.insert("goto",SkipType::skToSemicolon);
CppKeywords.insert("new",SkipType::skToSemicolon);
CppKeywords.insert("return",SkipType::skToSemicolon);
CppKeywords.insert("throw",SkipType::skToSemicolon);
CppKeywords.insert("delete",KeywordType::SkipNextSemicolon);
CppKeywords.insert("delete[]",KeywordType::SkipNextSemicolon);
CppKeywords.insert("goto",KeywordType::SkipNextSemicolon);
CppKeywords.insert("new",KeywordType::SkipNextSemicolon);
CppKeywords.insert("return",KeywordType::SkipNextSemicolon);
CppKeywords.insert("throw",KeywordType::SkipNextSemicolon);
// CppKeywords.insert("using",SkipType::skToSemicolon); //won't use it
// Skip to :
CppKeywords.insert("case",SkipType::skToColon);
CppKeywords.insert("default",SkipType::skToColon);
CppKeywords.insert("case",KeywordType::SkipNextColon);
CppKeywords.insert("default",KeywordType::SkipNextColon);
// Skip to )
CppKeywords.insert("__attribute__",SkipType::skToRightParenthesis);
CppKeywords.insert("alignas",SkipType::skToRightParenthesis); // not right
CppKeywords.insert("alignof",SkipType::skToRightParenthesis); // not right
CppKeywords.insert("decltype",SkipType::skToRightParenthesis); // not right
CppKeywords.insert("if",SkipType::skToRightParenthesis);
CppKeywords.insert("sizeof",SkipType::skToRightParenthesis);
CppKeywords.insert("switch",SkipType::skToRightParenthesis);
CppKeywords.insert("typeid",SkipType::skToRightParenthesis);
CppKeywords.insert("while",SkipType::skToRightParenthesis);
CppKeywords.insert("__attribute__",KeywordType::SkipNextParenthesis);
CppKeywords.insert("__attribute",KeywordType::SkipNextParenthesis);
CppKeywords.insert("alignas",KeywordType::SkipNextParenthesis); // not right
CppKeywords.insert("alignof",KeywordType::SkipNextParenthesis); // not right
CppKeywords.insert("if",KeywordType::SkipNextParenthesis);
CppKeywords.insert("sizeof",KeywordType::SkipNextParenthesis);
CppKeywords.insert("switch",KeywordType::SkipNextParenthesis);
CppKeywords.insert("typeid",KeywordType::SkipNextParenthesis);
CppKeywords.insert("while",KeywordType::SkipNextParenthesis);
CppKeywords.insert("static_assert",KeywordType::SkipNextParenthesis);
// Skip to }
CppKeywords.insert("asm",SkipType::skToRightBrace);
//CppKeywords.insert("namespace",SkipType::skToLeftBrace); // won't process it
CppKeywords.insert("asm",KeywordType::MoveToRightBrace);
CppKeywords.insert("__asm",KeywordType::MoveToRightBrace);
// Skip to {
// wont handle
//Not supported yet
CppKeywords.insert("atomic_cancel",SkipType::skNone);
CppKeywords.insert("atomic_commit",SkipType::skNone);
CppKeywords.insert("atomic_noexcept",SkipType::skNone);
CppKeywords.insert("concept",SkipType::skNone);
CppKeywords.insert("consteval",SkipType::skNone);
CppKeywords.insert("constinit",SkipType::skNone);
CppKeywords.insert("co_wait",SkipType::skNone);
CppKeywords.insert("co_return",SkipType::skNone);
CppKeywords.insert("co_yield",SkipType::skNone);
CppKeywords.insert("reflexpr",SkipType::skNone);
CppKeywords.insert("requires",SkipType::skNone);
CppKeywords.insert("atomic_cancel",KeywordType::None);
CppKeywords.insert("atomic_commit",KeywordType::None);
CppKeywords.insert("atomic_noexcept",KeywordType::None);
CppKeywords.insert("concept",KeywordType::None);
CppKeywords.insert("consteval",KeywordType::None);
CppKeywords.insert("constinit",KeywordType::None);
CppKeywords.insert("co_wait",KeywordType::None);
CppKeywords.insert("co_return",KeywordType::None);
CppKeywords.insert("co_yield",KeywordType::None);
CppKeywords.insert("reflexpr",KeywordType::None);
CppKeywords.insert("requires",KeywordType::None);
// its a type
CppKeywords.insert("auto",SkipType::skNone);
CppKeywords.insert("bool",SkipType::skNone);
CppKeywords.insert("char",SkipType::skNone);
CppKeywords.insert("char8_t",SkipType::skNone);
CppKeywords.insert("char16_t",SkipType::skNone);
CppKeywords.insert("char32_t",SkipType::skNone);
CppKeywords.insert("double",SkipType::skNone);
CppKeywords.insert("float",SkipType::skNone);
CppKeywords.insert("int",SkipType::skNone);
CppKeywords.insert("long",SkipType::skNone);
CppKeywords.insert("short",SkipType::skNone);
CppKeywords.insert("signed",SkipType::skNone);
CppKeywords.insert("unsigned",SkipType::skNone);
CppKeywords.insert("void",SkipType::skNone);
CppKeywords.insert("wchar_t",SkipType::skNone);
CppKeywords.insert("auto",KeywordType::None);
CppKeywords.insert("bool",KeywordType::None);
CppKeywords.insert("char",KeywordType::None);
CppKeywords.insert("char8_t",KeywordType::None);
CppKeywords.insert("char16_t",KeywordType::None);
CppKeywords.insert("char32_t",KeywordType::None);
CppKeywords.insert("double",KeywordType::None);
CppKeywords.insert("float",KeywordType::None);
CppKeywords.insert("int",KeywordType::None);
CppKeywords.insert("long",KeywordType::None);
CppKeywords.insert("short",KeywordType::None);
CppKeywords.insert("signed",KeywordType::None);
CppKeywords.insert("unsigned",KeywordType::None);
CppKeywords.insert("void",KeywordType::None);
CppKeywords.insert("wchar_t",KeywordType::None);
// type keywords
CppTypeKeywords.insert("auto");
@ -177,33 +177,32 @@ void initParser()
CppTypeKeywords.insert("unsigned");
// it's part of type info
CppKeywords.insert("const",SkipType::skNone);
CppKeywords.insert("extern",SkipType::skNone);
CppKeywords.insert("inline",SkipType::skNone);
CppKeywords.insert("const",KeywordType::None);
CppKeywords.insert("extern",KeywordType::None);
// handled elsewhere
CppKeywords.insert("class",SkipType::skNone);
CppKeywords.insert("enum",SkipType::skNone);
CppKeywords.insert("friend",SkipType::skNone);
CppKeywords.insert("operator",SkipType::skNone);
CppKeywords.insert("private",SkipType::skNone);
CppKeywords.insert("protected",SkipType::skNone);
CppKeywords.insert("public",SkipType::skNone);
CppKeywords.insert("static",SkipType::skNone);
CppKeywords.insert("struct",SkipType::skNone);
CppKeywords.insert("typedef",SkipType::skNone);
CppKeywords.insert("union",SkipType::skNone);
// namespace
CppKeywords.insert("namespace",SkipType::skNone);
CppKeywords.insert("using",SkipType::skNone);
CppKeywords.insert("for",SkipType::skNone);
CppKeywords.insert("catch",SkipType::skNone);
CppKeywords.insert("class",KeywordType::None);
CppKeywords.insert("operator",KeywordType::None);
CppKeywords.insert("static",KeywordType::None);
CppKeywords.insert("struct",KeywordType::None);
CppKeywords.insert("union",KeywordType::None);
CppKeywords.insert("for",KeywordType::For);
CppKeywords.insert("catch",KeywordType::Catch);
CppKeywords.insert("private",KeywordType::Private);
CppKeywords.insert("public",KeywordType::Public);
CppKeywords.insert("enum",KeywordType::Enum);
CppKeywords.insert("namespace",KeywordType::Namespace);
CppKeywords.insert("inline",KeywordType::Inline);
CppKeywords.insert("typedef",KeywordType::Typedef);
CppKeywords.insert("using",KeywordType::Using);
CppKeywords.insert("protected",KeywordType::Protected);
CppKeywords.insert("friend",KeywordType::Friend);
CppKeywords.insert("decltype",KeywordType::DeclType); // not right
// nullptr is value
CppKeywords.insert("nullptr",SkipType::skNone);
CppKeywords.insert("nullptr",KeywordType::None);
//C Keywords
CKeywords.insert("auto");
@ -538,16 +537,16 @@ void CppScopes::clear()
MemberOperatorType getOperatorType(const QString &phrase, int index)
{
if (index>=phrase.length())
return MemberOperatorType::otOther;
return MemberOperatorType::Other;
if (phrase[index] == '.')
return MemberOperatorType::otDot;
return MemberOperatorType::Dot;
if (index+1>=phrase.length())
return MemberOperatorType::otOther;
return MemberOperatorType::Other;
if ((phrase[index] == '-') && (phrase[index+1] == '>'))
return MemberOperatorType::otArrow;
return MemberOperatorType::Arrow;
if ((phrase[index] == ':') && (phrase[index+1] == ':'))
return MemberOperatorType::otDColon;
return MemberOperatorType::otOther;
return MemberOperatorType::DColon;
return MemberOperatorType::Other;
}
bool isScopeTypeKind(StatementKind kind)
@ -648,11 +647,13 @@ StatementKind getKindOfStatement(const PStatement& statement)
if (statement->kind == StatementKind::skVariable) {
if (!statement->parentScope.lock()) {
return StatementKind::skGlobalVariable;
} else if (statement->scope == StatementScope::ssLocal) {
} else if (statement->scope == StatementScope::Local) {
return StatementKind::skLocalVariable;
} else {
return StatementKind::skVariable;
}
} else if (statement->kind == StatementKind::skParameter) {
return StatementKind::skLocalVariable;
}
return statement->kind;
}

View File

@ -56,17 +56,30 @@ using PDefine = std::shared_ptr<Define>;
using DefineMap = QHash<QString,PDefine>;
using PDefineMap = std::shared_ptr<DefineMap>;
enum class SkipType {
skItself, // skip itself
skToSemicolon, // skip to ;
skToColon, // skip to :
skToRightParenthesis, // skip to )
skToLeftBrace,// Skip to {
skToRightBrace, // skip to }
skNone // It's a keyword but don't process here
enum class KeywordType {
SkipItself, // skip itself
SkipNextSemicolon, // move to ; and skip it
SkipNextColon, // move to : and skip it
SkipNextParenthesis, // move to ) and skip it
MoveToLeftBrace,// move to {
MoveToRightBrace, // move to }
For, //for
Catch, //catch
Public, // public
Private,
Protected,
Friend,
Enum, //enum
Inline, // inline
Namespace, //namespace
Typedef, //typedef
Using, //using
DeclType, // decltype
None, // It's a keyword but don't process here
NotKeyword
};
//It will be used as hash key. DONT make it enum class!!!!!
enum StatementKind {
skUnknown,
skNamespace,
@ -94,23 +107,23 @@ enum StatementKind {
using StatementKindSet = QSet<StatementKind>;
enum class StatementScope {
ssGlobal,
ssLocal,
ssClassLocal
Global,
Local,
ClassLocal
};
enum class StatementClassScope {
scsNone,
scsPrivate,
scsProtected,
scsPublic
None,
Private,
Protected,
Public
};
enum class MemberOperatorType {
otArrow,
otDot,
otDColon,
otOther
Arrow,
Dot,
DColon,
Other
};
enum class EvalStatementKind {
@ -136,7 +149,7 @@ using StatementMap = QMultiMap<QString, PStatement>;
struct Statement {
// Statement();
// ~Statement();
std::weak_ptr<Statement> parentScope; // parent class/struct/namespace scope, don't use auto pointer to prevent circular reference
std::weak_ptr<Statement> parentScope; // parent class/struct/namespace scope, use weak pointer to prevent circular reference
QString type; // type "int"
QString command; // identifier/name of statement "foo"
QString args; // args "(int a,float b)"
@ -232,7 +245,7 @@ using PFileIncludes = std::shared_ptr<FileIncludes>;
extern QStringList CppDirectives;
extern QStringList JavadocTags;
extern QMap<QString,SkipType> CppKeywords;
extern QMap<QString,KeywordType> CppKeywords;
extern QSet<QString> CppControlKeyWords;
extern QSet<QString> CKeywords;
extern QSet<QString> CppTypeKeywords;

View File

@ -99,6 +99,7 @@ void ProjectFilesWidget::copyUnits()
unitCopy->setOverrideBuildCmd(unit->overrideBuildCmd());
unitCopy->setBuildCmd(unit->buildCmd());
unitCopy->setEncoding(unit->encoding());
unitCopy->setFileName(unit->fileName());
mUnits.append(unitCopy);
}
}

View File

@ -4716,6 +4716,14 @@
<source>Ctrl+Alt+Down</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Switch header/source</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Switch Header/Source</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>NewClassDialog</name>

View File

@ -127,7 +127,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../widgets/aboutdialog.cpp" line="41"/>
<source>Microsoft Visual C++</source>
<translation type="unfinished">Microsoft Visual C++</translation>
<translation>Microsoft Visual C++</translation>
</message>
<message>
<location filename="../widgets/aboutdialog.cpp" line="45"/>
@ -3920,11 +3920,11 @@ Are you really want to continue?</oldsource>
<message>
<location filename="../mainwindow.ui" line="918"/>
<location filename="../mainwindow.ui" line="2932"/>
<location filename="../mainwindow.cpp" line="5119"/>
<location filename="../mainwindow.cpp" line="5122"/>
<location filename="../mainwindow.cpp" line="5126"/>
<location filename="../mainwindow.cpp" line="5129"/>
<location filename="../mainwindow.cpp" line="7126"/>
<location filename="../mainwindow.cpp" line="5124"/>
<location filename="../mainwindow.cpp" line="5127"/>
<location filename="../mainwindow.cpp" line="5131"/>
<location filename="../mainwindow.cpp" line="5134"/>
<location filename="../mainwindow.cpp" line="7176"/>
<source>Issues</source>
<translation></translation>
</message>
@ -4362,7 +4362,7 @@ Are you really want to continue?</oldsource>
<message>
<location filename="../mainwindow.ui" line="773"/>
<location filename="../mainwindow.ui" line="776"/>
<location filename="../mainwindow.cpp" line="7507"/>
<location filename="../mainwindow.cpp" line="7557"/>
<source>New Problem Set</source>
<translation></translation>
</message>
@ -4381,14 +4381,14 @@ Are you really want to continue?</oldsource>
<message>
<location filename="../mainwindow.ui" line="815"/>
<location filename="../mainwindow.ui" line="818"/>
<location filename="../mainwindow.cpp" line="7549"/>
<location filename="../mainwindow.cpp" line="7599"/>
<source>Save Problem Set</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.ui" line="829"/>
<location filename="../mainwindow.ui" line="832"/>
<location filename="../mainwindow.cpp" line="7582"/>
<location filename="../mainwindow.cpp" line="7632"/>
<source>Load Problem Set</source>
<translation></translation>
</message>
@ -4524,7 +4524,6 @@ Are you really want to continue?</oldsource>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.ui" line="2027"/>
<location filename="../mainwindow.ui" line="2030"/>
<source>New Source File</source>
<translation></translation>
@ -4742,7 +4741,7 @@ Are you really want to continue?</oldsource>
</message>
<message>
<location filename="../mainwindow.ui" line="2598"/>
<location filename="../mainwindow.cpp" line="6029"/>
<location filename="../mainwindow.cpp" line="6034"/>
<source>Clear all breakpoints</source>
<translation></translation>
</message>
@ -4922,11 +4921,22 @@ Are you really want to continue?</oldsource>
<source>Ctrl+Alt+Down</source>
<translation>Ctrl+Alt+Down</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="3260"/>
<source>Switch header/source</source>
<translation>/</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="3263"/>
<source>Switch Header/Source</source>
<translation>/</translation>
</message>
<message>
<source>Save As Template...</source>
<translation type="vanished">...</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="2027"/>
<location filename="../mainwindow.cpp" line="2909"/>
<source>New File</source>
<translation></translation>
@ -4968,7 +4978,7 @@ Are you really want to continue?</oldsource>
</message>
<message>
<location filename="../mainwindow.ui" line="2761"/>
<location filename="../mainwindow.cpp" line="7069"/>
<location filename="../mainwindow.cpp" line="7119"/>
<source>Rename Symbol</source>
<translation></translation>
</message>
@ -4989,13 +4999,13 @@ Are you really want to continue?</oldsource>
</message>
<message>
<location filename="../mainwindow.ui" line="2781"/>
<location filename="../mainwindow.cpp" line="7279"/>
<location filename="../mainwindow.cpp" line="7329"/>
<source>Export As RTF</source>
<translation>RTF</translation>
</message>
<message>
<location filename="../mainwindow.ui" line="2786"/>
<location filename="../mainwindow.cpp" line="7301"/>
<location filename="../mainwindow.cpp" line="7351"/>
<source>Export As HTML</source>
<translation>HTML</translation>
</message>
@ -5369,22 +5379,22 @@ Are you really want to continue?</oldsource>
<message>
<location filename="../mainwindow.cpp" line="1927"/>
<location filename="../mainwindow.cpp" line="2101"/>
<location filename="../mainwindow.cpp" line="5163"/>
<location filename="../mainwindow.cpp" line="5170"/>
<location filename="../mainwindow.cpp" line="5168"/>
<location filename="../mainwindow.cpp" line="5175"/>
<source>Wrong Compiler Settings</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="1928"/>
<location filename="../mainwindow.cpp" line="2102"/>
<location filename="../mainwindow.cpp" line="5164"/>
<location filename="../mainwindow.cpp" line="5171"/>
<location filename="../mainwindow.cpp" line="5169"/>
<location filename="../mainwindow.cpp" line="5176"/>
<source>Compiler is set not to generate executable.</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="1929"/>
<location filename="../mainwindow.cpp" line="5165"/>
<location filename="../mainwindow.cpp" line="5170"/>
<source>We need the executabe to run problem case.</source>
<translation></translation>
</message>
@ -5452,7 +5462,7 @@ Are you really want to continue?</oldsource>
</message>
<message>
<location filename="../mainwindow.cpp" line="2103"/>
<location filename="../mainwindow.cpp" line="5172"/>
<location filename="../mainwindow.cpp" line="5177"/>
<source>Please correct this before start debugging</source>
<translation></translation>
</message>
@ -5510,22 +5520,22 @@ Are you really want to continue?</oldsource>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="8583"/>
<location filename="../mainwindow.cpp" line="8633"/>
<source>Go to Line</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="8583"/>
<location filename="../mainwindow.cpp" line="8633"/>
<source>Line</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="8605"/>
<location filename="../mainwindow.cpp" line="8655"/>
<source>Template Exists</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="8606"/>
<location filename="../mainwindow.cpp" line="8656"/>
<source>Template %1 already exists. Do you want to overwrite?</source>
<translation>%1</translation>
</message>
@ -5551,7 +5561,7 @@ Are you really want to continue?</oldsource>
</message>
<message>
<location filename="../mainwindow.cpp" line="318"/>
<location filename="../mainwindow.cpp" line="7516"/>
<location filename="../mainwindow.cpp" line="7566"/>
<source>Problem Set %1</source>
<translation>%1</translation>
</message>
@ -5625,15 +5635,15 @@ Are you really want to continue?</oldsource>
</message>
<message>
<location filename="../mainwindow.cpp" line="4041"/>
<location filename="../mainwindow.cpp" line="7365"/>
<location filename="../mainwindow.cpp" line="7407"/>
<location filename="../mainwindow.cpp" line="7415"/>
<location filename="../mainwindow.cpp" line="7457"/>
<source>Bookmark Description</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="4042"/>
<location filename="../mainwindow.cpp" line="7366"/>
<location filename="../mainwindow.cpp" line="7408"/>
<location filename="../mainwindow.cpp" line="7416"/>
<location filename="../mainwindow.cpp" line="7458"/>
<source>Description:</source>
<translation></translation>
</message>
@ -5779,7 +5789,7 @@ Are you really want to continue?</oldsource>
<location filename="../mainwindow.cpp" line="2921"/>
<location filename="../mainwindow.cpp" line="3937"/>
<location filename="../mainwindow.cpp" line="3943"/>
<location filename="../mainwindow.cpp" line="6754"/>
<location filename="../mainwindow.cpp" line="6759"/>
<source>Delete</source>
<translation></translation>
</message>
@ -5862,57 +5872,57 @@ Are you really want to continue?</oldsource>
<translation>%1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="4613"/>
<location filename="../mainwindow.cpp" line="4618"/>
<source>Save project</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="4614"/>
<location filename="../mainwindow.cpp" line="4619"/>
<source>The project &apos;%1&apos; has modifications.</source>
<translation>&apos;%1&apos;</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="4616"/>
<location filename="../mainwindow.cpp" line="7510"/>
<location filename="../mainwindow.cpp" line="4621"/>
<location filename="../mainwindow.cpp" line="7560"/>
<source>Do you want to save it?</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="4716"/>
<location filename="../mainwindow.cpp" line="4730"/>
<location filename="../mainwindow.cpp" line="4721"/>
<location filename="../mainwindow.cpp" line="4735"/>
<source>File Changed</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="4801"/>
<location filename="../mainwindow.cpp" line="4806"/>
<source>New Project File?</source>
<translation>?</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="4802"/>
<location filename="../mainwindow.cpp" line="4807"/>
<source>Do you want to add the new file to the project?</source>
<translation>?</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="4886"/>
<location filename="../mainwindow.cpp" line="4896"/>
<location filename="../mainwindow.cpp" line="7571"/>
<location filename="../mainwindow.cpp" line="4891"/>
<location filename="../mainwindow.cpp" line="4901"/>
<location filename="../mainwindow.cpp" line="7621"/>
<source>Save Error</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="5038"/>
<location filename="../mainwindow.cpp" line="5043"/>
<source>Change Project Compiler Set</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="5039"/>
<location filename="../mainwindow.cpp" line="5044"/>
<source>Change the project&apos;s compiler set will lose all custom compiler set options.</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="3673"/>
<location filename="../mainwindow.cpp" line="5041"/>
<location filename="../mainwindow.cpp" line="5046"/>
<source>Do you really want to do that?</source>
<translation></translation>
</message>
@ -5935,104 +5945,104 @@ Are you really want to continue?</oldsource>
<translation type="vanished">%1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="5897"/>
<location filename="../mainwindow.cpp" line="5902"/>
<source>Modify Watch</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="5898"/>
<location filename="../mainwindow.cpp" line="5903"/>
<source>Watch Expression</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6030"/>
<location filename="../mainwindow.cpp" line="6035"/>
<source>Do you really want to clear all breakpoints in this file?</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6228"/>
<location filename="../mainwindow.cpp" line="6233"/>
<source>New project</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6229"/>
<location filename="../mainwindow.cpp" line="6234"/>
<source>Close %1 and start new project?</source>
<translation>&apos;%1&apos;?</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6242"/>
<location filename="../mainwindow.cpp" line="6247"/>
<source>Folder not exist</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6243"/>
<location filename="../mainwindow.cpp" line="6248"/>
<source>Folder &apos;%1&apos; doesn&apos;t exist. Create it now?</source>
<translation>&apos;%1&apos;</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6250"/>
<location filename="../mainwindow.cpp" line="6255"/>
<source>Can&apos;t create folder</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6251"/>
<location filename="../mainwindow.cpp" line="6256"/>
<source>Failed to create folder &apos;%1&apos;.</source>
<translation>&apos;%1&apos;</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6266"/>
<location filename="../mainwindow.cpp" line="6271"/>
<source>Save new project as</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6755"/>
<location filename="../mainwindow.cpp" line="6760"/>
<source>Folder %1 is not empty.</source>
<translation>%1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6756"/>
<location filename="../mainwindow.cpp" line="6761"/>
<source>Do you really want to delete it?</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7430"/>
<location filename="../mainwindow.cpp" line="7480"/>
<source>Change working folder</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7431"/>
<location filename="../mainwindow.cpp" line="7481"/>
<source>File &apos;%1&apos; is not in the current working folder.</source>
<oldsource>File &apos;%1&apos; is not in the current working folder</oldsource>
<translation>&apos;%1&apos;</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7434"/>
<location filename="../mainwindow.cpp" line="7484"/>
<source>Do you want to change working folder to &apos;%1&apos;?</source>
<translation>&apos;%1&apos;?</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="8105"/>
<location filename="../mainwindow.cpp" line="8155"/>
<source>Can&apos;t Commit</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="8106"/>
<location filename="../mainwindow.cpp" line="8156"/>
<source>Git needs user info to commit.</source>
<translation>Git需要用信息进行提交</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="8374"/>
<location filename="../mainwindow.cpp" line="8424"/>
<source>Choose Input Data File</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="8376"/>
<location filename="../mainwindow.cpp" line="8431"/>
<location filename="../mainwindow.cpp" line="8426"/>
<location filename="../mainwindow.cpp" line="8481"/>
<source>All files (*.*)</source>
<translation> (*.*)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="8429"/>
<location filename="../mainwindow.cpp" line="8479"/>
<source>Choose Expected Output Data File</source>
<oldsource>Choose Expected Input Data File</oldsource>
<translation></translation>
@ -6044,59 +6054,59 @@ Are you really want to continue?</oldsource>
<message>
<location filename="../mainwindow.ui" line="2851"/>
<location filename="../mainwindow.ui" line="2854"/>
<location filename="../mainwindow.cpp" line="7486"/>
<location filename="../mainwindow.cpp" line="7536"/>
<source>Choose Working Folder</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7880"/>
<location filename="../mainwindow.cpp" line="7929"/>
<location filename="../mainwindow.cpp" line="7930"/>
<location filename="../mainwindow.cpp" line="7979"/>
<source>Header Exists</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7881"/>
<location filename="../mainwindow.cpp" line="7930"/>
<location filename="../mainwindow.cpp" line="7931"/>
<location filename="../mainwindow.cpp" line="7980"/>
<source>Header file &quot;%1&quot; already exists!</source>
<translation>&quot;%1&quot;</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7935"/>
<location filename="../mainwindow.cpp" line="7985"/>
<source>Source Exists</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7936"/>
<location filename="../mainwindow.cpp" line="7986"/>
<source>Source file &quot;%1&quot; already exists!</source>
<translation>&quot;%1&quot;</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="8084"/>
<location filename="../mainwindow.cpp" line="8134"/>
<source>Can&apos;t commit!</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="8085"/>
<location filename="../mainwindow.cpp" line="8135"/>
<source>The following files are in conflicting:</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="8090"/>
<location filename="../mainwindow.cpp" line="8140"/>
<source>Commit Message</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="8090"/>
<location filename="../mainwindow.cpp" line="8140"/>
<source>Commit Message:</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="8093"/>
<location filename="../mainwindow.cpp" line="8143"/>
<source>Commit Failed</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="8094"/>
<location filename="../mainwindow.cpp" line="8144"/>
<source>Commit message shouldn&apos;t be empty!</source>
<translation></translation>
</message>
@ -6105,22 +6115,22 @@ Are you really want to continue?</oldsource>
<translation type="vanished">Dev-C++ (*.dev)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6280"/>
<location filename="../mainwindow.cpp" line="6285"/>
<source>New project fail</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6281"/>
<location filename="../mainwindow.cpp" line="6286"/>
<source>Can&apos;t assign project template</source>
<translation>使</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6380"/>
<location filename="../mainwindow.cpp" line="6385"/>
<source>Remove file</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6381"/>
<location filename="../mainwindow.cpp" line="6386"/>
<source>Remove the file from disk?</source>
<translation></translation>
</message>
@ -6129,27 +6139,27 @@ Are you really want to continue?</oldsource>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6680"/>
<location filename="../mainwindow.cpp" line="6685"/>
<source>New Project File Name</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6681"/>
<location filename="../mainwindow.cpp" line="6686"/>
<source>File Name:</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6689"/>
<location filename="../mainwindow.cpp" line="6694"/>
<source>File Already Exists!</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6690"/>
<location filename="../mainwindow.cpp" line="6695"/>
<source>File &apos;%1&apos; already exists!</source>
<translation>&apos;%1&apos;</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6334"/>
<location filename="../mainwindow.cpp" line="6339"/>
<source>Add to project</source>
<translation></translation>
</message>
@ -6164,75 +6174,75 @@ Are you really want to continue?</oldsource>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="6268"/>
<location filename="../mainwindow.cpp" line="6273"/>
<source>Red Panda C++ project file (*.dev)</source>
<translation>C++(*.dev)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7042"/>
<location filename="../mainwindow.cpp" line="7092"/>
<source>Rename Error</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7043"/>
<location filename="../mainwindow.cpp" line="7093"/>
<source>Symbol &apos;%1&apos; is defined in system header.</source>
<translation>&apos;%1&apos;</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7070"/>
<location filename="../mainwindow.cpp" line="7120"/>
<source>New Name</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7217"/>
<location filename="../mainwindow.cpp" line="7229"/>
<location filename="../mainwindow.cpp" line="7267"/>
<location filename="../mainwindow.cpp" line="7279"/>
<source>Replace Error</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7218"/>
<location filename="../mainwindow.cpp" line="7268"/>
<source>Can&apos;t open file &apos;%1&apos; for replace!</source>
<translation>&apos;%1&apos;</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7230"/>
<location filename="../mainwindow.cpp" line="7280"/>
<source>Contents has changed since last search!</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7281"/>
<location filename="../mainwindow.cpp" line="7331"/>
<source>Rich Text Format Files (*.rtf)</source>
<translation>RTF格式文件 (*.rtf)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7303"/>
<location filename="../mainwindow.cpp" line="7353"/>
<source>HTML Files (*.html)</source>
<translation>HTML文件 (*.html)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7508"/>
<location filename="../mainwindow.cpp" line="7558"/>
<source>The current problem set is not empty.</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7526"/>
<location filename="../mainwindow.cpp" line="7576"/>
<source>Problem %1</source>
<translation>%1</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7556"/>
<location filename="../mainwindow.cpp" line="7584"/>
<location filename="../mainwindow.cpp" line="7606"/>
<location filename="../mainwindow.cpp" line="7634"/>
<source>Problem Set Files (*.pbs)</source>
<translation> (*.pbs)</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7590"/>
<location filename="../mainwindow.cpp" line="7640"/>
<source>Load Error</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="3755"/>
<location filename="../mainwindow.cpp" line="7604"/>
<location filename="../mainwindow.cpp" line="7654"/>
<source>Problem Case %1</source>
<translation>%1</translation>
</message>
@ -6245,13 +6255,13 @@ Are you really want to continue?</oldsource>
<location filename="../mainwindow.cpp" line="1359"/>
<location filename="../mainwindow.cpp" line="2576"/>
<location filename="../mainwindow.cpp" line="3025"/>
<location filename="../mainwindow.cpp" line="4723"/>
<location filename="../mainwindow.cpp" line="4841"/>
<location filename="../mainwindow.cpp" line="5005"/>
<location filename="../mainwindow.cpp" line="5017"/>
<location filename="../mainwindow.cpp" line="5459"/>
<location filename="../mainwindow.cpp" line="5471"/>
<location filename="../mainwindow.cpp" line="8514"/>
<location filename="../mainwindow.cpp" line="4728"/>
<location filename="../mainwindow.cpp" line="4846"/>
<location filename="../mainwindow.cpp" line="5010"/>
<location filename="../mainwindow.cpp" line="5022"/>
<location filename="../mainwindow.cpp" line="5464"/>
<location filename="../mainwindow.cpp" line="5476"/>
<location filename="../mainwindow.cpp" line="8564"/>
<source>Error</source>
<translation></translation>
</message>
@ -6278,79 +6288,79 @@ Are you really want to continue?</oldsource>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="4717"/>
<location filename="../mainwindow.cpp" line="4722"/>
<source>File &apos;%1&apos; was changed.</source>
<translation>&apos;%1&apos;</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="4717"/>
<location filename="../mainwindow.cpp" line="4722"/>
<source>Reload its content from disk?</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="4731"/>
<location filename="../mainwindow.cpp" line="4736"/>
<source>File &apos;%1&apos; was removed.</source>
<translation>&apos;%1&apos;</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="4731"/>
<location filename="../mainwindow.cpp" line="4736"/>
<source>Keep it open?</source>
<translation>C++</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="4834"/>
<location filename="../mainwindow.cpp" line="4839"/>
<source>Open</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="5230"/>
<location filename="../mainwindow.cpp" line="5235"/>
<source>Compile Failed</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="5236"/>
<location filename="../mainwindow.cpp" line="5241"/>
<source>Run Failed</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="3056"/>
<location filename="../mainwindow.cpp" line="5488"/>
<location filename="../mainwindow.cpp" line="5502"/>
<location filename="../mainwindow.cpp" line="8497"/>
<location filename="../mainwindow.cpp" line="5493"/>
<location filename="../mainwindow.cpp" line="5507"/>
<location filename="../mainwindow.cpp" line="8547"/>
<source>Confirm Convertion</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="3057"/>
<location filename="../mainwindow.cpp" line="5489"/>
<location filename="../mainwindow.cpp" line="5503"/>
<location filename="../mainwindow.cpp" line="8498"/>
<location filename="../mainwindow.cpp" line="5494"/>
<location filename="../mainwindow.cpp" line="5508"/>
<location filename="../mainwindow.cpp" line="8548"/>
<source>The editing file will be saved using %1 encoding. &lt;br /&gt;This operation can&apos;t be reverted. &lt;br /&gt;Are you sure to continue?</source>
<translation>使%1&lt;br /&gt;&lt;br /&gt;</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="5647"/>
<location filename="../mainwindow.cpp" line="5652"/>
<source>New Watch Expression</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="5648"/>
<location filename="../mainwindow.cpp" line="5653"/>
<source>Enter Watch Expression (it is recommended to use &apos;this-&gt;&apos; for class members):</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="5705"/>
<location filename="../mainwindow.cpp" line="5710"/>
<source>Parsing file %1 of %2: &quot;%3&quot;</source>
<translation>%1/%2&quot;%3&quot;</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="5727"/>
<location filename="../mainwindow.cpp" line="5733"/>
<location filename="../mainwindow.cpp" line="5732"/>
<location filename="../mainwindow.cpp" line="5738"/>
<source>Done parsing %1 files in %2 seconds</source>
<translation>%1,%2</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="5730"/>
<location filename="../mainwindow.cpp" line="5735"/>
<source>(%1 files per second)</source>
<translation>(%1</translation>
</message>
@ -8677,14 +8687,14 @@ Are you really want to continue?</oldsource>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="8522"/>
<location filename="../mainwindow.cpp" line="8572"/>
<location filename="../settingsdialog/settingsdialog.cpp" line="166"/>
<location filename="../settingsdialog/settingsdialog.cpp" line="246"/>
<source>Compiler Set</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="8523"/>
<location filename="../mainwindow.cpp" line="8573"/>
<location filename="../settingsdialog/settingsdialog.cpp" line="166"/>
<location filename="../settingsdialog/settingsdialog.cpp" line="169"/>
<source>Compiler</source>
@ -8696,7 +8706,7 @@ Are you really want to continue?</oldsource>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7497"/>
<location filename="../mainwindow.cpp" line="7547"/>
<location filename="../settingsdialog/settingsdialog.cpp" line="172"/>
<location filename="../settingsdialog/settingsdialog.cpp" line="205"/>
<location filename="../settingsdialog/settingsdialog.cpp" line="211"/>
@ -8772,15 +8782,15 @@ Are you really want to continue?</oldsource>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7498"/>
<location filename="../mainwindow.cpp" line="7827"/>
<location filename="../mainwindow.cpp" line="7548"/>
<location filename="../mainwindow.cpp" line="7877"/>
<location filename="../settingsdialog/settingsdialog.cpp" line="205"/>
<location filename="../settingsdialog/settingsdialog.cpp" line="208"/>
<source>Program Runner</source>
<translation></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="7826"/>
<location filename="../mainwindow.cpp" line="7876"/>
<location filename="../settingsdialog/settingsdialog.cpp" line="208"/>
<source>Problem Set</source>
<translation></translation>

View File

@ -4557,6 +4557,14 @@
<source>Ctrl+Alt+Down</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Switch header/source</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Switch Header/Source</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>NewClassDialog</name>

View File

@ -431,13 +431,13 @@ void BookmarkModel::sort(int column, Qt::SortOrder order)
case 0:
if (order == Qt::SortOrder::AscendingOrder) {
auto sorter=[](PBookmark b1,PBookmark b2) {
return QString::compare(b1->description,b2->description);
return b1->description < b2->description;
};
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
} else {
auto sorter=[](PBookmark b1,PBookmark b2) {
return QString::compare(b2->description,b1->description);
return b2->description<b1->description;
};
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
@ -446,13 +446,13 @@ void BookmarkModel::sort(int column, Qt::SortOrder order)
case 1:
if (order == Qt::SortOrder::AscendingOrder) {
auto sorter=[](PBookmark b1,PBookmark b2) {
return QString::compare(b1->filename,b2->filename);
return b1->filename<b2->filename;
};
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
} else {
auto sorter=[](PBookmark b1,PBookmark b2) {
return QString::compare(b2->filename,b1->filename);
return b2->filename<b1->filename;
};
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
@ -461,13 +461,13 @@ void BookmarkModel::sort(int column, Qt::SortOrder order)
case 2:
if (order == Qt::SortOrder::AscendingOrder) {
auto sorter=[](PBookmark b1,PBookmark b2) {
return b1->line-b2->line;
return b1->line<b2->line;
};
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
} else {
auto sorter=[](PBookmark b1,PBookmark b2) {
return b2->line-b1->line;
return b2->line<b1->line;
};
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);

View File

@ -338,7 +338,7 @@ void ClassBrowserModel::filterChildren(ClassBrowserNode *node, const StatementMa
if (statement == node->statement) // prevent infinite recursion
continue;
if (statement->scope == StatementScope::ssLocal)
if (statement->scope == StatementScope::Local)
continue;
if (pSettings->codeCompletion().hideSymbolsStartsWithTwoUnderLine()

View File

@ -278,11 +278,11 @@ static bool sortByScopeComparator(PStatement statement1,PStatement statement2){
if (statement1->inSystemHeader != statement2->inSystemHeader)
return !(statement1->inSystemHeader);
// Show local statements first
if (statement1->scope != StatementScope::ssGlobal
&& statement2->scope == StatementScope::ssGlobal ) {
if (statement1->scope != StatementScope::Global
&& statement2->scope == StatementScope::Global ) {
return true;
} else if (statement1->scope == StatementScope::ssGlobal
&& statement2->scope != StatementScope::ssGlobal ) {
} else if (statement1->scope == StatementScope::Global
&& statement2->scope != StatementScope::Global ) {
return false;
} else
return nameComparator(statement1,statement2);
@ -359,11 +359,11 @@ static bool sortByScopeWithUsageComparator(PStatement statement1,PStatement stat
if (statement1->inSystemHeader != statement2->inSystemHeader)
return !(statement1->inSystemHeader);
// Show local statements first
if (statement1->scope != StatementScope::ssGlobal
&& statement2->scope == StatementScope::ssGlobal ) {
if (statement1->scope != StatementScope::Global
&& statement2->scope == StatementScope::Global ) {
return true;
} else if (statement1->scope == StatementScope::ssGlobal
&& statement2->scope != StatementScope::ssGlobal ) {
} else if (statement1->scope == StatementScope::Global
&& statement2->scope != StatementScope::Global ) {
return false;
} else
return nameComparator(statement1,statement2);
@ -712,7 +712,7 @@ void CodeCompletionPopup::getCompletionFor(
if (children.isEmpty())
return;
foreach (const PStatement& childStatement, children) {
if ((childStatement->classScope==StatementClassScope::scsPublic)
if ((childStatement->classScope==StatementClassScope::Public)
&& !(
childStatement->kind == StatementKind::skConstructor
|| childStatement->kind == StatementKind::skDestructor)
@ -769,7 +769,7 @@ void CodeCompletionPopup::getCompletionFor(
|| childStatement->kind == StatementKind::skEnumClassType
|| childStatement->kind == StatementKind::skEnumType
)) {
if (childStatement->classScope == StatementClassScope::scsPublic)
if (childStatement->classScope == StatementClassScope::Public)
addStatement(childStatement,fileName,-1);
}
}

View File

@ -19,10 +19,12 @@
#include "../iconsmanager.h"
#include "../settings.h"
#include <QFileDialog>
#include <algorithm>
NewClassDialog::NewClassDialog(QWidget *parent) :
NewClassDialog::NewClassDialog(PCppParser parser, QWidget *parent) :
QDialog(parent),
ui(new Ui::NewClassDialog)
ui(new Ui::NewClassDialog),
mModel(parser)
{
setWindowFlag(Qt::WindowContextHelpButtonHint,false);
ui->setupUi(this);
@ -31,6 +33,7 @@ NewClassDialog::NewClassDialog(QWidget *parent) :
connect(pIconsManager,&IconsManager::actionIconsUpdated,
this, &NewClassDialog::onUpdateIcons);
ui->txtClassName->setFocus();
ui->cbBaseClass->setModel(&mModel);
}
NewClassDialog::~NewClassDialog()
@ -42,9 +45,9 @@ QString NewClassDialog::className() const
return ui->txtClassName->text();
}
QString NewClassDialog::baseClass() const
PStatement NewClassDialog::baseClass() const
{
return ui->cbBaseClass->currentText();
return mModel.getCandidate(ui->cbBaseClass->currentIndex());
}
QString NewClassDialog::headerName() const
@ -105,3 +108,86 @@ void NewClassDialog::on_txtClassName_textChanged(const QString &/* arg1 */)
ui->txtSourceName->setText(ui->txtClassName->text().toLower()+".cpp");
}
NewClassCandidatesModel::NewClassCandidatesModel(PCppParser parser):QAbstractListModel(),
mParser(parser)
{
fillClasses();
}
PStatement NewClassCandidatesModel::getCandidate(int row) const
{
if (row<0)
return PStatement();
if (row==0)
return PStatement();
return mCandidates[row-1];
}
void NewClassCandidatesModel::fillClasses()
{
if (!mParser->enabled())
return;
if (!mParser->freeze())
return;
foreach( const PStatement& s, mParser->statementList().childrenStatements()) {
if (s->kind==StatementKind::skClass
&& s->inProject
&& !s->command.startsWith("_")
&& !s->command.contains("<")
&& !mClassNames.contains(s->fullName)) {
if (getFileType(s->fileName)==FileType::CHeader
|| getFileType(s->fileName)==FileType::CppHeader) {
mCandidates.append(s);
mClassNames.insert(s->fullName);
}
} else if (s->kind == StatementKind::skNamespace
&& !s->command.startsWith("_")
&& !s->command.contains("<")) {
fillClassesInNamespace(s);
}
}
mParser->unFreeze();
std::sort(mCandidates.begin(),mCandidates.end(),[](const PStatement& s1, const PStatement& s2){
return s1->fullName<s2->fullName;
});
}
void NewClassCandidatesModel::fillClassesInNamespace(PStatement ns)
{
foreach( const PStatement& s, mParser->statementList().childrenStatements(ns)) {
if (s->kind==StatementKind::skClass
&& s->inProject
&& !s->command.startsWith("_")
&& !s->command.contains("<")
&& !mClassNames.contains(s->fullName)) {
if (getFileType(s->fileName)==FileType::CHeader
|| getFileType(s->fileName)==FileType::CppHeader) {
mCandidates.append(s);
mClassNames.insert(s->fullName);
}
} else if (s->kind == StatementKind::skNamespace
&& !s->command.startsWith("_")
&& !s->command.contains("<")) {
fillClassesInNamespace(s);
}
}
}
int NewClassCandidatesModel::rowCount(const QModelIndex &/*parent*/) const
{
return mCandidates.count()+1;
}
QVariant NewClassCandidatesModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role==Qt::DisplayRole) {
if (index.row()==0)
return "";
return mCandidates[index.row()-1]->fullName;
}
return QVariant();
}

View File

@ -18,21 +18,42 @@
#define NEWCLASSDIALOG_H
#include <QDialog>
#include "../parser/cppparser.h"
#include <QAbstractListModel>
namespace Ui {
class NewClassDialog;
}
class NewClassCandidatesModel: public QAbstractListModel {
Q_OBJECT
public:
explicit NewClassCandidatesModel(PCppParser parser);
PStatement getCandidate(int row) const;
private:
void fillClasses();
void fillClassesInNamespace(PStatement ns);
private:
PCppParser mParser;
QVector<PStatement> mCandidates;
QSet<QString> mClassNames;
// QAbstractItemModel interface
public:
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
};
class NewClassDialog : public QDialog
{
Q_OBJECT
public:
explicit NewClassDialog(QWidget *parent = nullptr);
explicit NewClassDialog(PCppParser parser, QWidget *parent = nullptr);
~NewClassDialog();
QString className() const;
QString baseClass() const;
PStatement baseClass() const;
QString headerName() const;
QString sourceName() const;
QString path() const;
@ -49,7 +70,8 @@ private slots:
private:
Ui::NewClassDialog *ui;
QList<PStatement> mClasses;
NewClassCandidatesModel mModel;
private:
void onUpdateIcons();

View File

@ -48,7 +48,11 @@
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QComboBox" name="cbBaseClass"/>
<widget class="QComboBox" name="cbBaseClass">
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item row="8" column="0" colspan="4">
<widget class="QWidget" name="widget" native="true">

View File

@ -33,7 +33,7 @@ RedPandaIDE.depends += redpanda-git-askpass
APP_NAME = RedPandaCPP
APP_VERSION = 2.1
APP_VERSION = 2.2
linux: {
isEmpty(PREFIX) {

View File

@ -6599,16 +6599,16 @@ bool SynEdit::modified() const
return mModified;
}
void SynEdit::setModified(bool Value)
void SynEdit::setModified(bool value)
{
if (Value) {
if (value) {
mLastModifyTime = QDateTime::currentDateTime();
emit statusChanged(StatusChange::scModified);
}
if (Value != mModified) {
mModified = Value;
if (value != mModified) {
mModified = value;
if (Value) {
if (value) {
mUndoList->clear();
mRedoList->clear();
} else {
@ -6649,6 +6649,7 @@ void SynEdit::setUndoLimit(int size)
void SynEdit::setUndoMemoryUsage(int size)
{
mUndoList->setMaxMemoryUsage(size*1024*1024);
// mUndoList->setMaxMemoryUsage(size*1024);
}
int SynEdit::charsInWindow() const

View File

@ -688,7 +688,7 @@ void Document::saveToFile(QFile &file, const QByteArray& encoding,
if (allAscii) {
realEncoding = ENCODING_ASCII;
} else if (encoding == ENCODING_AUTO_DETECT) {
if (codec->name().compare("System",Qt::CaseInsensitive)) {
if (codec->name().compare("System",Qt::CaseInsensitive)==0) {
realEncoding = pCharsetInfoManager->getDefaultSystemEncoding();
} else {
realEncoding = codec->name();
@ -989,9 +989,9 @@ PUndoItem UndoList::popItem()
// qDebug()<<"popped"<<item->changeNumber()<<item->changeText()<<(int)item->changeReason()<<mLastPoppedItemChangeNumber;
if (mLastPoppedItemChangeNumber!=item->changeNumber() && item->changeReason()!=ChangeReason::GroupBreak) {
mBlockCount--;
Q_ASSERT(mBlockCount>=0);
// qDebug()<<"pop"<<mBlockCount;
if (mBlockCount<0) {
qDebug()<<"block count calculation error";
mBlockCount=0;
}
}
@ -1059,13 +1059,22 @@ bool UndoList::fullUndoImposible() const
void UndoList::ensureMaxEntries()
{
if (mMaxUndoActions>0 && (mBlockCount > mMaxUndoActions || mMemoryUsage>mMaxMemoryUsage)){
if (mItems.isEmpty())
return;
// qDebug()<<QString("-- List Memory: %1 %2").arg(mMemoryUsage).arg(mMaxMemoryUsage);
if ((mMaxUndoActions >0 && mBlockCount > mMaxUndoActions)
|| (mMaxMemoryUsage>0 && mMemoryUsage>mMaxMemoryUsage)){
PUndoItem lastItem = mItems.back();
mFullUndoImposible = true;
while ((mBlockCount > mMaxUndoActions || mMemoryUsage>mMaxMemoryUsage)
while (((mMaxUndoActions >0 && mBlockCount > mMaxUndoActions)
|| (mMaxMemoryUsage>0 && mMemoryUsage>mMaxMemoryUsage))
&& !mItems.isEmpty()) {
//remove all undo item in block
PUndoItem item = mItems.front();
size_t changeNumber = item->changeNumber();
//we shouldn't drop the newest changes;
if (changeNumber == lastItem->changeNumber())
break;
while (mItems.count()>0) {
item = mItems.front();
if (item->changeNumber()!=changeNumber)
@ -1077,6 +1086,7 @@ void UndoList::ensureMaxEntries()
mBlockCount--;
}
}
// qDebug()<<QString("++ List Memory: %1").arg(mMemoryUsage);
}
SelectionMode UndoItem::changeSelMode() const
@ -1123,8 +1133,9 @@ UndoItem::UndoItem(ChangeReason reason, SelectionMode selMode,
foreach (const QString& s, text) {
length+=s.length();
}
mMemoryUsage -= length * sizeof(QChar) + text.length() * sizeof(QString)
mMemoryUsage = length * sizeof(QChar) + text.length() * sizeof(QString)
+ sizeof(UndoItem);
// qDebug()<<mMemoryUsage;
}
ChangeReason UndoItem::changeReason() const