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 Red Panda C++ Version 2.1
- fix: editors that not in the editing panel shouldn't trigger switch breakpoint - 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) English Website: [https://sourceforge.net/projects/redpanda-cpp](https://sourceforge.net/projects/redpanda-cpp)
New Features (Compared with Red Panda Dev-C++ 6): 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) * 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) * Competitve Companion support ( It's an chrome/firefox extension that can fetch problems from OJ websites)
* Find symbol occurrences * Find symbol occurrences
@ -36,5 +36,6 @@ Code Intellisense Improvements:
* Support C++ 14 using type alias * Support C++ 14 using type alias
* Support C-Style enum variable definitions * Support C-Style enum variable definitions
* Support MACRO with arguments * Support MACRO with arguments
* Support C++ lambdas
And many other improvements and bug fixes. See NEWS.md for full informantion. 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) { isEmpty(APP_VERSION) {
APP_VERSION = 2.1 APP_VERSION = 2.2
} }
macos: { macos: {

View File

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

View File

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

View File

@ -4416,13 +4416,20 @@ void MainWindow::onEditorContextMenu(const QPoint& pos)
int line; int line;
if (editor->getPositionOfMouse(p)) { if (editor->getPositionOfMouse(p)) {
line=p.line; line=p.line;
if (!switchHeaderSourceTarget(editor).isEmpty()) {
menu.addAction(ui->actionSwitchHeaderSource);
menu.addSeparator();
}
//mouse on editing area //mouse on editing area
menu.addAction(ui->actionCompile_Run); menu.addAction(ui->actionCompile_Run);
menu.addAction(ui->actionDebug); menu.addAction(ui->actionDebug);
menu.addSeparator(); if (editor->parser() && editor->parser()->enabled()) {
menu.addAction(ui->actionGoto_Declaration); menu.addSeparator();
menu.addAction(ui->actionGoto_Definition); menu.addAction(ui->actionGoto_Declaration);
menu.addAction(ui->actionFind_references); menu.addAction(ui->actionGoto_Definition);
menu.addAction(ui->actionFind_references);
}
menu.addSeparator(); menu.addSeparator();
menu.addAction(ui->actionOpen_Containing_Folder); menu.addAction(ui->actionOpen_Containing_Folder);
@ -4449,9 +4456,11 @@ void MainWindow::onEditorContextMenu(const QPoint& pos)
menu.addAction(ui->actionFile_Properties); menu.addAction(ui->actionFile_Properties);
//these actions needs parser //these actions needs parser
ui->actionGoto_Declaration->setEnabled(!editor->parser()->parsing()); if (editor->parser() && editor->parser()->enabled()) {
ui->actionGoto_Definition->setEnabled(!editor->parser()->parsing()); ui->actionGoto_Declaration->setEnabled(!editor->parser()->parsing());
ui->actionFind_references->setEnabled(!editor->parser()->parsing()); ui->actionGoto_Definition->setEnabled(!editor->parser()->parsing());
ui->actionFind_references->setEnabled(!editor->parser()->parsing());
}
} else { } else {
//mouse on gutter //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() void MainWindow::onProjectViewNodeRenamed()
{ {
updateProjectView(); updateProjectView();
@ -7913,7 +7967,7 @@ void MainWindow::on_actionNew_Class_triggered()
{ {
if (!mProject) if (!mProject)
return; return;
NewClassDialog dialog; NewClassDialog dialog(mProject->cppParser());
dialog.setPath(mProject->folder()); dialog.setPath(mProject->folder());
if (dialog.exec()==QDialog::Accepted) { if (dialog.exec()==QDialog::Accepted) {
QDir dir(dialog.path()); QDir dir(dialog.path());
@ -7947,7 +8001,14 @@ void MainWindow::on_actionNew_Class_triggered()
header.append(QString("#ifndef %1").arg(header_macro)); header.append(QString("#ifndef %1").arg(header_macro));
header.append(QString("#define %1").arg(header_macro)); header.append(QString("#define %1").arg(header_macro));
header.append(""); header.append("");
header.append(QString("class %1 {").arg(dialog.className())); 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("public:");
header.append(""); header.append("");
header.append("private:"); header.append("private:");
@ -8642,7 +8703,7 @@ bool MainWindow::isClosingAll() const
void MainWindow::on_actionGoto_block_start_triggered() void MainWindow::on_actionGoto_block_start_triggered()
{ {
Editor* editor=mEditorList->getEditor(); Editor *editor=mEditorList->getEditor();
if (editor) if (editor)
editor->gotoBlockStart(); editor->gotoBlockStart();
} }
@ -8650,8 +8711,18 @@ void MainWindow::on_actionGoto_block_start_triggered()
void MainWindow::on_actionGoto_block_end_triggered() void MainWindow::on_actionGoto_block_end_triggered()
{ {
Editor* editor=mEditorList->getEditor(); Editor *editor=mEditorList->getEditor();
if (editor) if (editor)
editor->gotoBlockEnd(); 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 setProjectViewCurrentUnit(std::shared_ptr<ProjectUnit> unit);
void reparseNonProjectEditors(); void reparseNonProjectEditors();
QString switchHeaderSourceTarget(Editor *editor);
private slots: private slots:
void onProjectViewNodeRenamed(); void onProjectViewNodeRenamed();
@ -732,6 +733,8 @@ private slots:
void on_actionGoto_block_end_triggered(); void on_actionGoto_block_end_triggered();
void on_actionSwitchHeaderSource_triggered();
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
EditorList *mEditorList; EditorList *mEditorList;

View File

@ -3255,6 +3255,14 @@
<string>Ctrl+Alt+Down</string> <string>Ctrl+Alt+Down</string>
</property> </property>
</action> </action>
<action name="actionSwitchHeaderSource">
<property name="text">
<string>Switch header/source</string>
</property>
<property name="toolTip">
<string>Switch Header/Source</string>
</property>
</action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <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& aType, // "Type" is already in use
const QString& command, const QString& command,
const QString& args, const QString& args,
const QString& noNameArgs,
const QString& value, const QString& value,
int line, int line,
StatementKind kind, StatementKind kind,
@ -173,6 +174,21 @@ private:
const QString &aType, // "Type" is already in use const QString &aType, // "Type" is already in use
const QString &command, const QString &command,
const QString &args, 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, const QString& value,
int line, int line,
StatementKind kind, StatementKind kind,
@ -182,32 +198,30 @@ private:
bool isStatic); bool isStatic);
void setInheritance(int index, const PStatement& classStatement, bool isStruct); void setInheritance(int index, const PStatement& classStatement, bool isStruct);
bool isCurrentScope(const QString& command); 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 void removeScopeLevel(int line); // removes level
int skipBraces(int startAt);
int skipBracket(int startAt); int indexOfMatchingBrace(int startAt) {
return mTokenizer[startAt]->matchIndex;
}
void internalClear(); void internalClear();
QStringList sortFilesByIncludeRelations(const QSet<QString> &files); QStringList sortFilesByIncludeRelations(const QSet<QString> &files);
bool checkForCatchBlock(); bool checkForKeyword(KeywordType &keywordType);
bool checkForEnum(); bool checkForMethod(QString &sType, QString &sName, int &argStartIndex,
bool checkForForBlock(); int &argEndIndex, bool &isStatic, bool &isFriend); // caching of results
bool checkForKeyword(); bool checkForNamespace(KeywordType keywordType);
bool checkForMethod(QString &sType, QString &sName, QString &sArgs,
bool &isStatic, bool &isFriend); // caching of results
bool checkForNamespace();
bool checkForPreprocessor(); bool checkForPreprocessor();
bool checkForScope(); // bool checkForLambda();
void checkForSkipStatement(); bool checkForScope(KeywordType keywordType);
bool checkForStructs(); bool checkForStructs(KeywordType keywordType);
bool checkForTypedef();
bool checkForTypedefEnum(); bool checkForTypedefEnum();
bool checkForTypedefStruct(); bool checkForTypedefStruct();
bool checkForUsing(); bool checkForUsing(KeywordType keywordType);
bool checkForVar();
QString expandMacroType(const QString& name); void checkAndHandleMethodOrVar(KeywordType keywordType);
void fillListOfFunctions(const QString& fileName, int line, void fillListOfFunctions(const QString& fileName, int line,
const PStatement& statement, const PStatement& statement,
@ -308,10 +322,23 @@ private:
void doSkipInExpression(const QStringList& expression, int&pos, const QString& startSymbol, const QString& endSymbol); void doSkipInExpression(const QStringList& expression, int&pos, const QString& startSymbol, const QString& endSymbol);
bool isIdentifier(const QString& token) const { bool isIdentifier(const QString& token) const {
return (!token.isEmpty() && isLetterChar(token.front()) return (!token.isEmpty() && isIdentChar(token.front())
&& !token.contains('\"')); && !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 { bool isIntegerLiteral(const QString& token) const {
if (token.isEmpty()) if (token.isEmpty())
return false; return false;
@ -335,6 +362,24 @@ private:
return false; return false;
return (token.startsWith('\'')); 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( PStatement doParseEvalTypeInfo(
const QString& fileName, const QString& fileName,
const PStatement& scope, const PStatement& scope,
@ -343,7 +388,8 @@ private:
int& pointerLevel); int& pointerLevel);
int getBracketEnd(const QString& s, int startAt); int getBracketEnd(const QString& s, int startAt);
StatementClassScope getClassScope(int index); StatementClassScope getClassScope(const QString& text);
StatementClassScope getClassScope(KeywordType keywordType);
int getCurrentBlockBeginSkip(); int getCurrentBlockBeginSkip();
int getCurrentBlockEndSkip(); int getCurrentBlockEndSkip();
int getCurrentInlineNamespaceEndSkip(); int getCurrentInlineNamespaceEndSkip();
@ -370,23 +416,25 @@ private:
PStatement getTypeDef(const PStatement& statement, PStatement getTypeDef(const PStatement& statement,
const QString& fileName, const QString& aType); const QString& fileName, const QString& aType);
void handleCatchBlock(); void handleCatchBlock();
void handleEnum(); void handleEnum(bool isTypedef);
void handleForBlock(); void handleForBlock();
void handleKeyword(); void handleKeyword(KeywordType skipType);
void handleLambda(int index, int endIndex);
void handleMethod( void handleMethod(
StatementKind functionKind,
const QString& sType, const QString& sType,
const QString& sName, const QString& sName,
const QString& sArgs, int argStart,
bool isStatic, bool isStatic,
bool isFriend); bool isFriend);
void handleNamespace(); void handleNamespace(KeywordType skipType);
void handleOtherTypedefs(); void handleOtherTypedefs();
void handlePreprocessor(); void handlePreprocessor();
void handleScope(); void handleScope(KeywordType keywordType);
bool handleStatement(); bool handleStatement();
void handleStructs(bool isTypedef = false); void handleStructs(bool isTypedef = false);
void handleUsing(); void handleUsing();
void handleVar(); void handleVar(const QString& typePrefix,bool isExtern,bool isStatic);
void internalParse(const QString& fileName); void internalParse(const QString& fileName);
// function FindMacroDefine(const Command: AnsiString): PStatement; // function FindMacroDefine(const Command: AnsiString): PStatement;
void inheritClassStatement( void inheritClassStatement(
@ -410,11 +458,12 @@ private:
// } // }
void scanMethodArgs( void scanMethodArgs(
const PStatement& functionStatement, const PStatement& functionStatement,
const QString& argStr); int argStart);
QString splitPhrase(const QString& phrase, QString& sClazz, QString splitPhrase(const QString& phrase, QString& sClazz,
QString& sOperator, QString &sMember); 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 { bool isSpaceChar(const QChar& ch) const {
return ch==' ' || ch =='\t'; return ch==' ' || ch =='\t';
@ -427,7 +476,14 @@ private:
|| ch == '&'; || 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() return ch.isLetter()
|| ch == '_'; || ch == '_';
} }
@ -436,6 +492,24 @@ private:
return (ch>='0' && ch<='9'); 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 { bool isSeperator(const QChar& ch) const {
switch(ch.unicode()){ switch(ch.unicode()){
@ -493,7 +567,7 @@ private:
return ch=='\n' || ch=='\r'; 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 * @brief Test if a statement is a class/struct/union/namespace/function
@ -511,7 +585,20 @@ private:
void updateSerialId(); 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: private:
int mParserId; int mParserId;
ParserLanguage mLanguage; ParserLanguage mLanguage;
@ -528,9 +615,6 @@ private:
QVector<PStatement> mCurrentScope; QVector<PStatement> mCurrentScope;
QVector<StatementClassScope> mCurrentClassScope; 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; StatementClassScope mClassScope;
StatementModel mStatementList; StatementModel mStatementList;
//It's used in preprocessor, so we can't use fIncludeList instead //It's used in preprocessor, so we can't use fIncludeList instead
@ -554,7 +638,7 @@ private:
QMutex mMutex; QMutex mMutex;
GetFileStreamCallBack mOnGetFileStream; GetFileStreamCallBack mOnGetFileStream;
QMap<QString,SkipType> mCppKeywords; QMap<QString,KeywordType> mCppKeywords;
QSet<QString> mCppTypeKeywords; QSet<QString> mCppTypeKeywords;
}; };
using PCppParser = std::shared_ptr<CppParser>; using PCppParser = std::shared_ptr<CppParser>;

View File

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

View File

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

View File

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

View File

@ -56,17 +56,30 @@ using PDefine = std::shared_ptr<Define>;
using DefineMap = QHash<QString,PDefine>; using DefineMap = QHash<QString,PDefine>;
using PDefineMap = std::shared_ptr<DefineMap>; using PDefineMap = std::shared_ptr<DefineMap>;
enum class SkipType { enum class KeywordType {
skItself, // skip itself SkipItself, // skip itself
skToSemicolon, // skip to ; SkipNextSemicolon, // move to ; and skip it
skToColon, // skip to : SkipNextColon, // move to : and skip it
skToRightParenthesis, // skip to ) SkipNextParenthesis, // move to ) and skip it
skToLeftBrace,// Skip to { MoveToLeftBrace,// move to {
skToRightBrace, // skip to } MoveToRightBrace, // move to }
skNone // It's a keyword but don't process here 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 { enum StatementKind {
skUnknown, skUnknown,
skNamespace, skNamespace,
@ -94,23 +107,23 @@ enum StatementKind {
using StatementKindSet = QSet<StatementKind>; using StatementKindSet = QSet<StatementKind>;
enum class StatementScope { enum class StatementScope {
ssGlobal, Global,
ssLocal, Local,
ssClassLocal ClassLocal
}; };
enum class StatementClassScope { enum class StatementClassScope {
scsNone, None,
scsPrivate, Private,
scsProtected, Protected,
scsPublic Public
}; };
enum class MemberOperatorType { enum class MemberOperatorType {
otArrow, Arrow,
otDot, Dot,
otDColon, DColon,
otOther Other
}; };
enum class EvalStatementKind { enum class EvalStatementKind {
@ -136,7 +149,7 @@ using StatementMap = QMultiMap<QString, PStatement>;
struct Statement { struct Statement {
// Statement(); // 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 type; // type "int"
QString command; // identifier/name of statement "foo" QString command; // identifier/name of statement "foo"
QString args; // args "(int a,float b)" QString args; // args "(int a,float b)"
@ -232,7 +245,7 @@ using PFileIncludes = std::shared_ptr<FileIncludes>;
extern QStringList CppDirectives; extern QStringList CppDirectives;
extern QStringList JavadocTags; extern QStringList JavadocTags;
extern QMap<QString,SkipType> CppKeywords; extern QMap<QString,KeywordType> CppKeywords;
extern QSet<QString> CppControlKeyWords; extern QSet<QString> CppControlKeyWords;
extern QSet<QString> CKeywords; extern QSet<QString> CKeywords;
extern QSet<QString> CppTypeKeywords; extern QSet<QString> CppTypeKeywords;

View File

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

View File

@ -4716,6 +4716,14 @@
<source>Ctrl+Alt+Down</source> <source>Ctrl+Alt+Down</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </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>
<context> <context>
<name>NewClassDialog</name> <name>NewClassDialog</name>

View File

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

View File

@ -4557,6 +4557,14 @@
<source>Ctrl+Alt+Down</source> <source>Ctrl+Alt+Down</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </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>
<context> <context>
<name>NewClassDialog</name> <name>NewClassDialog</name>

View File

@ -431,13 +431,13 @@ void BookmarkModel::sort(int column, Qt::SortOrder order)
case 0: case 0:
if (order == Qt::SortOrder::AscendingOrder) { if (order == Qt::SortOrder::AscendingOrder) {
auto sorter=[](PBookmark b1,PBookmark b2) { 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(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter); std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
} else { } else {
auto sorter=[](PBookmark b1,PBookmark b2) { 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(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter); std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
@ -446,13 +446,13 @@ void BookmarkModel::sort(int column, Qt::SortOrder order)
case 1: case 1:
if (order == Qt::SortOrder::AscendingOrder) { if (order == Qt::SortOrder::AscendingOrder) {
auto sorter=[](PBookmark b1,PBookmark b2) { 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(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter); std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
} else { } else {
auto sorter=[](PBookmark b1,PBookmark b2) { 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(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter); std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
@ -461,13 +461,13 @@ void BookmarkModel::sort(int column, Qt::SortOrder order)
case 2: case 2:
if (order == Qt::SortOrder::AscendingOrder) { if (order == Qt::SortOrder::AscendingOrder) {
auto sorter=[](PBookmark b1,PBookmark b2) { 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(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter); std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
} else { } else {
auto sorter=[](PBookmark b1,PBookmark b2) { 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(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.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 if (statement == node->statement) // prevent infinite recursion
continue; continue;
if (statement->scope == StatementScope::ssLocal) if (statement->scope == StatementScope::Local)
continue; continue;
if (pSettings->codeCompletion().hideSymbolsStartsWithTwoUnderLine() if (pSettings->codeCompletion().hideSymbolsStartsWithTwoUnderLine()

View File

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

View File

@ -19,10 +19,12 @@
#include "../iconsmanager.h" #include "../iconsmanager.h"
#include "../settings.h" #include "../settings.h"
#include <QFileDialog> #include <QFileDialog>
#include <algorithm>
NewClassDialog::NewClassDialog(QWidget *parent) : NewClassDialog::NewClassDialog(PCppParser parser, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::NewClassDialog) ui(new Ui::NewClassDialog),
mModel(parser)
{ {
setWindowFlag(Qt::WindowContextHelpButtonHint,false); setWindowFlag(Qt::WindowContextHelpButtonHint,false);
ui->setupUi(this); ui->setupUi(this);
@ -31,6 +33,7 @@ NewClassDialog::NewClassDialog(QWidget *parent) :
connect(pIconsManager,&IconsManager::actionIconsUpdated, connect(pIconsManager,&IconsManager::actionIconsUpdated,
this, &NewClassDialog::onUpdateIcons); this, &NewClassDialog::onUpdateIcons);
ui->txtClassName->setFocus(); ui->txtClassName->setFocus();
ui->cbBaseClass->setModel(&mModel);
} }
NewClassDialog::~NewClassDialog() NewClassDialog::~NewClassDialog()
@ -42,9 +45,9 @@ QString NewClassDialog::className() const
return ui->txtClassName->text(); 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 QString NewClassDialog::headerName() const
@ -105,3 +108,86 @@ void NewClassDialog::on_txtClassName_textChanged(const QString &/* arg1 */)
ui->txtSourceName->setText(ui->txtClassName->text().toLower()+".cpp"); 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 #define NEWCLASSDIALOG_H
#include <QDialog> #include <QDialog>
#include "../parser/cppparser.h"
#include <QAbstractListModel>
namespace Ui { namespace Ui {
class NewClassDialog; 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 class NewClassDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit NewClassDialog(QWidget *parent = nullptr); explicit NewClassDialog(PCppParser parser, QWidget *parent = nullptr);
~NewClassDialog(); ~NewClassDialog();
QString className() const; QString className() const;
QString baseClass() const; PStatement baseClass() const;
QString headerName() const; QString headerName() const;
QString sourceName() const; QString sourceName() const;
QString path() const; QString path() const;
@ -49,7 +70,8 @@ private slots:
private: private:
Ui::NewClassDialog *ui; Ui::NewClassDialog *ui;
QList<PStatement> mClasses;
NewClassCandidatesModel mModel;
private: private:
void onUpdateIcons(); void onUpdateIcons();

View File

@ -48,7 +48,11 @@
</widget> </widget>
</item> </item>
<item row="1" column="2" colspan="2"> <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>
<item row="8" column="0" colspan="4"> <item row="8" column="0" colspan="4">
<widget class="QWidget" name="widget" native="true"> <widget class="QWidget" name="widget" native="true">

View File

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

View File

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

View File

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

View File

@ -208,7 +208,7 @@ void ASResource::buildAssignmentOperators(vector<const string*>* assignmentOpera
assignmentOperators->emplace_back(&AS_LS_LS_LS_ASSIGN); assignmentOperators->emplace_back(&AS_LS_LS_LS_ASSIGN);
assert(assignmentOperators->size() < elements); assert(assignmentOperators->size() < elements);
sort(assignmentOperators->begin(), assignmentOperators->end(), sortOnLength); sort(assignmentOperators->begin(), assignmentOperators->end(), sortOnLength);
} }
/** /**
@ -228,7 +228,7 @@ void ASResource::buildCastOperators(vector<const string*>* castOperators)
castOperators->emplace_back(&AS_STATIC_CAST); castOperators->emplace_back(&AS_STATIC_CAST);
assert(castOperators->size() < elements); assert(castOperators->size() < elements);
sort(castOperators->begin(), castOperators->end(), sortOnName); sort(castOperators->begin(), castOperators->end(), sortOnName);
} }
/** /**
@ -295,7 +295,7 @@ void ASResource::buildHeaders(vector<const string*>* headers, int fileType, bool
} }
assert(headers->size() < elements); assert(headers->size() < elements);
sort(headers->begin(), headers->end(), sortOnName); sort(headers->begin(), headers->end(), sortOnName);
} }
/** /**
@ -369,7 +369,7 @@ void ASResource::buildNonAssignmentOperators(vector<const string*>* nonAssignmen
nonAssignmentOperators->emplace_back(&AS_LAMBDA); nonAssignmentOperators->emplace_back(&AS_LAMBDA);
assert(nonAssignmentOperators->size() < elements); assert(nonAssignmentOperators->size() < elements);
sort(nonAssignmentOperators->begin(), nonAssignmentOperators->end(), sortOnLength); sort(nonAssignmentOperators->begin(), nonAssignmentOperators->end(), sortOnLength);
} }
/** /**
@ -425,7 +425,7 @@ void ASResource::buildNonParenHeaders(vector<const string*>* nonParenHeaders, in
} }
assert(nonParenHeaders->size() < elements); assert(nonParenHeaders->size() < elements);
sort(nonParenHeaders->begin(), nonParenHeaders->end(), sortOnName); sort(nonParenHeaders->begin(), nonParenHeaders->end(), sortOnName);
} }
/** /**
@ -489,7 +489,7 @@ void ASResource::buildOperators(vector<const string*>* operators, int fileType)
} }
assert(operators->size() < elements); assert(operators->size() < elements);
sort(operators->begin(), operators->end(), sortOnLength); sort(operators->begin(), operators->end(), sortOnLength);
} }
/** /**
@ -527,7 +527,7 @@ void ASResource::buildPreBlockStatements(vector<const string*>* preBlockStatemen
} }
assert(preBlockStatements->size() < elements); assert(preBlockStatements->size() < elements);
sort(preBlockStatements->begin(), preBlockStatements->end(), sortOnName); sort(preBlockStatements->begin(), preBlockStatements->end(), sortOnName);
} }
/** /**
@ -567,7 +567,7 @@ void ASResource::buildPreCommandHeaders(vector<const string*>* preCommandHeaders
} }
assert(preCommandHeaders->size() < elements); assert(preCommandHeaders->size() < elements);
sort(preCommandHeaders->begin(), preCommandHeaders->end(), sortOnName); sort(preCommandHeaders->begin(), preCommandHeaders->end(), sortOnName);
} }
/** /**
@ -604,7 +604,7 @@ void ASResource::buildPreDefinitionHeaders(vector<const string*>* preDefinitionH
} }
assert(preDefinitionHeaders->size() < elements); assert(preDefinitionHeaders->size() < elements);
sort(preDefinitionHeaders->begin(), preDefinitionHeaders->end(), sortOnName); sort(preDefinitionHeaders->begin(), preDefinitionHeaders->end(), sortOnName);
} }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *