Merge branch 'master' of github.com:royqh1979/RedPanda-CPP
This commit is contained in:
commit
d642ff3b74
16
NEWS.md
16
NEWS.md
|
@ -1,3 +1,19 @@
|
|||
Red Panda C++ Version 2.2
|
||||
|
||||
- enhancement: basic code completion support for C++ lambdas
|
||||
- enhancement: slightly reduce parsing time
|
||||
- fix: Wrong charset name returned when saving file
|
||||
- fix: 'using =' / 'namespace =' not correctly handled
|
||||
- fix: Pressing '*' at begin of line will crash app
|
||||
- enhancement: switch header/source in editor's context menu
|
||||
- enhancement: base class dropdown list in new class dialog now works
|
||||
- fix: Edting / show context menu when code analysis is turned on may crash app.
|
||||
- fix: Show context menu when edting non c/c++ file may crash app.
|
||||
- fix: Project Options Dialog's Files panel will crash app.
|
||||
- fix: Memory usage of undo system is not correctly calculated
|
||||
- fix: Set max undo memory usage to 0 don't really remove limit of undo
|
||||
- fix: Set max undo times to 0 don't really remove limit of undo
|
||||
|
||||
Red Panda C++ Version 2.1
|
||||
|
||||
- fix: editors that not in the editing panel shouldn't trigger switch breakpoint
|
||||
|
|
|
@ -6,7 +6,7 @@ Simplified Chinese Website: [https://royqh1979.gitee.io/redpandacpp/](https://ro
|
|||
English Website: [https://sourceforge.net/projects/redpanda-cpp](https://sourceforge.net/projects/redpanda-cpp)
|
||||
|
||||
New Features (Compared with Red Panda Dev-C++ 6):
|
||||
* Cross Platform (Windows/Linux)
|
||||
* Cross Platform (Windows/Linux/MacOS)
|
||||
* Problem Set (run and test program against predefined input / expected output data)
|
||||
* Competitve Companion support ( It's an chrome/firefox extension that can fetch problems from OJ websites)
|
||||
* Find symbol occurrences
|
||||
|
@ -36,5 +36,6 @@ Code Intellisense Improvements:
|
|||
* Support C++ 14 using type alias
|
||||
* Support C-Style enum variable definitions
|
||||
* Support MACRO with arguments
|
||||
* Support C++ lambdas
|
||||
|
||||
And many other improvements and bug fixes. See NEWS.md for full informantion.
|
|
@ -10,7 +10,7 @@ isEmpty(APP_NAME) {
|
|||
}
|
||||
|
||||
isEmpty(APP_VERSION) {
|
||||
APP_VERSION = 2.1
|
||||
APP_VERSION = 2.2
|
||||
}
|
||||
|
||||
macos: {
|
||||
|
|
|
@ -915,7 +915,7 @@ void Editor::onPreparePaintHighlightToken(int line, int aChar, const QString &to
|
|||
if (token.isEmpty())
|
||||
return;
|
||||
|
||||
if (mParser && mParser->enabled() && highlighter()) {
|
||||
if (mParser && highlighter()) {
|
||||
QString lineText = document()->getString(line-1);
|
||||
if (mParser->isIncludeLine(lineText)) {
|
||||
if (cursor() == Qt::PointingHandCursor) {
|
||||
|
@ -932,7 +932,7 @@ void Editor::onPreparePaintHighlightToken(int line, int aChar, const QString &to
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (attr == highlighter()->identifierAttribute()) {
|
||||
} else if (mParser->enabled() && attr == highlighter()->identifierAttribute()) {
|
||||
QSynedit::BufferCoord p{aChar,line};
|
||||
// BufferCoord pBeginPos,pEndPos;
|
||||
// QString s= getWordAtPosition(this,p, pBeginPos,pEndPos, WordPurpose::wpInformation);
|
||||
|
@ -1057,18 +1057,19 @@ bool Editor::event(QEvent *event)
|
|||
switch (reason) {
|
||||
case TipType::Preprocessor:
|
||||
// When hovering above a preprocessor line, determine if we want to show an include or a identifier hint
|
||||
if (mParser) {
|
||||
s = document()->getString(p.line - 1);
|
||||
isIncludeNextLine = mParser->isIncludeNextLine(s);
|
||||
if (!isIncludeNextLine)
|
||||
isIncludeLine = mParser->isIncludeLine(s);
|
||||
if (!isIncludeNextLine &&!isIncludeLine)
|
||||
s = wordAtRowCol(p);
|
||||
}
|
||||
break;
|
||||
case TipType::Identifier:
|
||||
if (pMainWindow->debugger()->executing() && !pMainWindow->debugger()->inferiorRunning())
|
||||
s = getWordAtPosition(this,p, pBeginPos,pEndPos, WordPurpose::wpEvaluation); // debugging
|
||||
else if (//devEditor.ParserHints and
|
||||
!mCompletionPopup->isVisible()
|
||||
else if (!mCompletionPopup->isVisible()
|
||||
&& !mHeaderCompletionPopup->isVisible()) {
|
||||
expression = getExpressionAtPosition(p);
|
||||
s = expression.join(""); // information during coding
|
||||
|
@ -1090,7 +1091,9 @@ bool Editor::event(QEvent *event)
|
|||
|
||||
s = s.trimmed();
|
||||
if ((s == mCurrentWord) && (mCurrentTipType == reason)) {
|
||||
if (qApp->queryKeyboardModifiers() == Qt::ControlModifier) {
|
||||
if (mParser
|
||||
&& mParser->enabled()
|
||||
&& qApp->queryKeyboardModifiers() == Qt::ControlModifier) {
|
||||
if (!hasFocus())
|
||||
activate();
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
|
@ -1148,7 +1151,9 @@ bool Editor::event(QEvent *event)
|
|||
if (!hint.isEmpty()) {
|
||||
// QApplication* app = dynamic_cast<QApplication *>(QApplication::instance());
|
||||
// if (app->keyboardModifiers().testFlag(Qt::ControlModifier)) {
|
||||
if (qApp->queryKeyboardModifiers() == Qt::ControlModifier) {
|
||||
if (mParser
|
||||
&& mParser->enabled()
|
||||
&& qApp->queryKeyboardModifiers() == Qt::ControlModifier) {
|
||||
if (!hasFocus())
|
||||
activate();
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
|
@ -1201,7 +1206,7 @@ void Editor::mouseReleaseEvent(QMouseEvent *event)
|
|||
&& (event->button() == Qt::LeftButton)) {
|
||||
|
||||
QSynedit::BufferCoord p;
|
||||
if (pointToCharLine(event->pos(),p)) {
|
||||
if (mParser && pointToCharLine(event->pos(),p)) {
|
||||
QString s = document()->getString(p.line - 1);
|
||||
if (mParser->isIncludeNextLine(s)) {
|
||||
QString filename = mParser->getHeaderFileName(mFilename,s, true);
|
||||
|
@ -1211,7 +1216,7 @@ void Editor::mouseReleaseEvent(QMouseEvent *event)
|
|||
QString filename = mParser->getHeaderFileName(mFilename,s);
|
||||
pMainWindow->openFile(filename);
|
||||
return;
|
||||
} else {
|
||||
} else if (mParser->enabled()) {
|
||||
gotoDefinition(p);
|
||||
return;
|
||||
}
|
||||
|
@ -2338,7 +2343,7 @@ bool Editor::handleBracketSkip()
|
|||
|
||||
bool Editor::handleMultilineCommentCompletion()
|
||||
{
|
||||
if ((caretX()-2 < lineText().length()) && (lineText()[caretX() - 2] == '/')) {
|
||||
if ((caretX()-2>=0) && (caretX()-2 < lineText().length()) && (lineText()[caretX() - 2] == '/')) {
|
||||
QString text=selText();
|
||||
beginUpdate();
|
||||
beginUndoBlock();
|
||||
|
@ -3457,7 +3462,7 @@ bool Editor::onCompletionInputMethod(QInputMethodEvent *event)
|
|||
Editor::TipType Editor::getTipType(QPoint point, QSynedit::BufferCoord& pos)
|
||||
{
|
||||
// Only allow in the text area...
|
||||
if (pointToCharLine(point, pos)) {
|
||||
if (pointToCharLine(point, pos) && highlighter()) {
|
||||
if (!pMainWindow->debugger()->executing()
|
||||
&& getSyntaxIssueAtPosition(pos)) {
|
||||
return TipType::Error;
|
||||
|
@ -3628,6 +3633,9 @@ void Editor::updateFunctionTip(bool showTip)
|
|||
if (!highlighter())
|
||||
return;
|
||||
|
||||
if (!mParser || !mParser->enabled())
|
||||
return;
|
||||
|
||||
bool isFunction = false;
|
||||
auto action = finally([&isFunction]{
|
||||
if (!isFunction)
|
||||
|
|
|
@ -296,18 +296,18 @@ QPixmap IconsManager::getPixmapForStatement(PStatement statement)
|
|||
case StatementKind::skFunction:
|
||||
case StatementKind::skConstructor:
|
||||
case StatementKind::skDestructor:
|
||||
if (statement->scope == StatementScope::ssGlobal)
|
||||
if (statement->scope == StatementScope::Global)
|
||||
return *(pIconsManager->getPixmap(IconsManager::PARSER_GLOBAL_METHOD));
|
||||
if (statement->isInherited) {
|
||||
if (statement->classScope == StatementClassScope::scsProtected) {
|
||||
if (statement->classScope == StatementClassScope::Protected) {
|
||||
return *(pIconsManager->getPixmap(IconsManager::PARSER_INHERITED_PROTECTED_METHOD));
|
||||
} else if (statement->classScope == StatementClassScope::scsPublic) {
|
||||
} else if (statement->classScope == StatementClassScope::Public) {
|
||||
return *(pIconsManager->getPixmap(IconsManager::PARSER_INHERITED_METHOD));
|
||||
}
|
||||
} else {
|
||||
if (statement->classScope == StatementClassScope::scsProtected) {
|
||||
if (statement->classScope == StatementClassScope::Protected) {
|
||||
return *(pIconsManager->getPixmap(IconsManager::PARSER_PROTECTED_METHOD));
|
||||
} else if (statement->classScope == StatementClassScope::scsPublic) {
|
||||
} else if (statement->classScope == StatementClassScope::Public) {
|
||||
return *(pIconsManager->getPixmap(IconsManager::PARSER_PUBLIC_METHOD));
|
||||
} else {
|
||||
return *(pIconsManager->getPixmap(IconsManager::PARSER_PRIVATE_METHOD));
|
||||
|
@ -320,15 +320,15 @@ QPixmap IconsManager::getPixmapForStatement(PStatement statement)
|
|||
return *(pIconsManager->getPixmap(IconsManager::PARSER_LOCAL_VAR));
|
||||
case StatementKind::skVariable:
|
||||
if (statement->isInherited) {
|
||||
if (statement->classScope == StatementClassScope::scsProtected) {
|
||||
if (statement->classScope == StatementClassScope::Protected) {
|
||||
return *(pIconsManager->getPixmap(IconsManager::PARSER_INHERITED_PROTECTD_VAR));
|
||||
} else if (statement->classScope == StatementClassScope::scsPublic) {
|
||||
} else if (statement->classScope == StatementClassScope::Public) {
|
||||
return *(pIconsManager->getPixmap(IconsManager::PARSER_INHERITED_VAR));
|
||||
}
|
||||
} else {
|
||||
if (statement->classScope == StatementClassScope::scsProtected) {
|
||||
if (statement->classScope == StatementClassScope::Protected) {
|
||||
return *(pIconsManager->getPixmap(IconsManager::PARSER_PROTECTED_VAR));
|
||||
} else if (statement->classScope == StatementClassScope::scsPublic) {
|
||||
} else if (statement->classScope == StatementClassScope::Public) {
|
||||
return *(pIconsManager->getPixmap(IconsManager::PARSER_PUBLIC_VAR));
|
||||
} else {
|
||||
return *(pIconsManager->getPixmap(IconsManager::PARSER_PRIVATE_VAR));
|
||||
|
|
|
@ -4416,13 +4416,20 @@ void MainWindow::onEditorContextMenu(const QPoint& pos)
|
|||
int line;
|
||||
if (editor->getPositionOfMouse(p)) {
|
||||
line=p.line;
|
||||
if (!switchHeaderSourceTarget(editor).isEmpty()) {
|
||||
|
||||
menu.addAction(ui->actionSwitchHeaderSource);
|
||||
menu.addSeparator();
|
||||
}
|
||||
//mouse on editing area
|
||||
menu.addAction(ui->actionCompile_Run);
|
||||
menu.addAction(ui->actionDebug);
|
||||
if (editor->parser() && editor->parser()->enabled()) {
|
||||
menu.addSeparator();
|
||||
menu.addAction(ui->actionGoto_Declaration);
|
||||
menu.addAction(ui->actionGoto_Definition);
|
||||
menu.addAction(ui->actionFind_references);
|
||||
}
|
||||
|
||||
menu.addSeparator();
|
||||
menu.addAction(ui->actionOpen_Containing_Folder);
|
||||
|
@ -4449,9 +4456,11 @@ void MainWindow::onEditorContextMenu(const QPoint& pos)
|
|||
menu.addAction(ui->actionFile_Properties);
|
||||
|
||||
//these actions needs parser
|
||||
if (editor->parser() && editor->parser()->enabled()) {
|
||||
ui->actionGoto_Declaration->setEnabled(!editor->parser()->parsing());
|
||||
ui->actionGoto_Definition->setEnabled(!editor->parser()->parsing());
|
||||
ui->actionFind_references->setEnabled(!editor->parser()->parsing());
|
||||
}
|
||||
} else {
|
||||
//mouse on gutter
|
||||
|
||||
|
@ -6781,6 +6790,51 @@ void MainWindow::reparseNonProjectEditors()
|
|||
}
|
||||
}
|
||||
|
||||
QString MainWindow::switchHeaderSourceTarget(Editor *editor)
|
||||
{
|
||||
QString filename=editor->filename();
|
||||
if (getFileType(filename)==FileType::CHeader
|
||||
|| getFileType(filename)==FileType::CppHeader) {
|
||||
QStringList lst;
|
||||
lst.push_back("c");
|
||||
lst.push_back("cc");
|
||||
lst.push_back("cpp");
|
||||
lst.push_back("cxx");
|
||||
lst.push_back("C");
|
||||
lst.push_back("CC");
|
||||
foreach(const QString& suffix,lst) {
|
||||
QString newFile=changeFileExt(filename,suffix);
|
||||
if (fileExists(newFile)) {
|
||||
return newFile;
|
||||
}
|
||||
}
|
||||
} else if (getFileType(filename)==FileType::CSource) {
|
||||
QStringList lst;
|
||||
lst.push_back("h");
|
||||
foreach(const QString& suffix,lst) {
|
||||
QString newFile=changeFileExt(filename,suffix);
|
||||
if (fileExists(newFile)) {
|
||||
return newFile;
|
||||
}
|
||||
}
|
||||
} else if (getFileType(filename)==FileType::CppSource) {
|
||||
QStringList lst;
|
||||
lst.push_back("h");
|
||||
lst.push_back("hpp");
|
||||
lst.push_back("hxx");
|
||||
lst.push_back("HH");
|
||||
lst.push_back("H");
|
||||
|
||||
foreach(const QString& suffix,lst) {
|
||||
QString newFile=changeFileExt(filename,suffix);
|
||||
if (fileExists(newFile)) {
|
||||
return newFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void MainWindow::onProjectViewNodeRenamed()
|
||||
{
|
||||
updateProjectView();
|
||||
|
@ -7913,7 +7967,7 @@ void MainWindow::on_actionNew_Class_triggered()
|
|||
{
|
||||
if (!mProject)
|
||||
return;
|
||||
NewClassDialog dialog;
|
||||
NewClassDialog dialog(mProject->cppParser());
|
||||
dialog.setPath(mProject->folder());
|
||||
if (dialog.exec()==QDialog::Accepted) {
|
||||
QDir dir(dialog.path());
|
||||
|
@ -7947,6 +8001,13 @@ void MainWindow::on_actionNew_Class_triggered()
|
|||
header.append(QString("#ifndef %1").arg(header_macro));
|
||||
header.append(QString("#define %1").arg(header_macro));
|
||||
header.append("");
|
||||
if (dialog.baseClass()) {
|
||||
header.append(QString("#include \"%1\"").arg(extractRelativePath(mProject->directory(),
|
||||
dialog.baseClass()->fileName)));
|
||||
header.append("");
|
||||
header.append(QString("class %1 : public %2 {").arg(dialog.className(),
|
||||
dialog.baseClass()->fullName));
|
||||
} else
|
||||
header.append(QString("class %1 {").arg(dialog.className()));
|
||||
header.append("public:");
|
||||
header.append("");
|
||||
|
@ -8655,3 +8716,13 @@ void MainWindow::on_actionGoto_block_end_triggered()
|
|||
editor->gotoBlockEnd();
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_actionSwitchHeaderSource_triggered()
|
||||
{
|
||||
Editor *editor=mEditorList->getEditor();
|
||||
QString file=switchHeaderSourceTarget(editor);
|
||||
if (!file.isEmpty()) {
|
||||
openFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -290,6 +290,7 @@ private:
|
|||
void setProjectViewCurrentUnit(std::shared_ptr<ProjectUnit> unit);
|
||||
|
||||
void reparseNonProjectEditors();
|
||||
QString switchHeaderSourceTarget(Editor *editor);
|
||||
|
||||
private slots:
|
||||
void onProjectViewNodeRenamed();
|
||||
|
@ -732,6 +733,8 @@ private slots:
|
|||
|
||||
void on_actionGoto_block_end_triggered();
|
||||
|
||||
void on_actionSwitchHeaderSource_triggered();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
EditorList *mEditorList;
|
||||
|
|
|
@ -3255,6 +3255,14 @@
|
|||
<string>Ctrl+Alt+Down</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSwitchHeaderSource">
|
||||
<property name="text">
|
||||
<string>Switch header/source</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Switch Header/Source</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -160,6 +160,7 @@ private:
|
|||
const QString& aType, // "Type" is already in use
|
||||
const QString& command,
|
||||
const QString& args,
|
||||
const QString& noNameArgs,
|
||||
const QString& value,
|
||||
int line,
|
||||
StatementKind kind,
|
||||
|
@ -173,6 +174,21 @@ private:
|
|||
const QString &aType, // "Type" is already in use
|
||||
const QString &command,
|
||||
const QString &args,
|
||||
const QString &noNameArgs,
|
||||
const QString& value,
|
||||
int line,
|
||||
StatementKind kind,
|
||||
const StatementScope& scope,
|
||||
const StatementClassScope& classScope,
|
||||
bool isDefinition,
|
||||
bool isStatic);
|
||||
PStatement addStatement(
|
||||
const PStatement& parent,
|
||||
const QString &fileName,
|
||||
const QString &aType, // "Type" is already in use
|
||||
const QString &command,
|
||||
int argStart,
|
||||
int argEnd,
|
||||
const QString& value,
|
||||
int line,
|
||||
StatementKind kind,
|
||||
|
@ -182,32 +198,30 @@ private:
|
|||
bool isStatic);
|
||||
void setInheritance(int index, const PStatement& classStatement, bool isStruct);
|
||||
bool isCurrentScope(const QString& command);
|
||||
void addSoloScopeLevel(PStatement& statement, int line, bool shouldResetBlock = true); // adds new solo level
|
||||
void addSoloScopeLevel(PStatement& statement, int line, bool shouldResetBlock=false); // adds new solo level
|
||||
void removeScopeLevel(int line); // removes level
|
||||
int skipBraces(int startAt);
|
||||
int skipBracket(int startAt);
|
||||
|
||||
int indexOfMatchingBrace(int startAt) {
|
||||
return mTokenizer[startAt]->matchIndex;
|
||||
}
|
||||
|
||||
void internalClear();
|
||||
|
||||
QStringList sortFilesByIncludeRelations(const QSet<QString> &files);
|
||||
|
||||
bool checkForCatchBlock();
|
||||
bool checkForEnum();
|
||||
bool checkForForBlock();
|
||||
bool checkForKeyword();
|
||||
bool checkForMethod(QString &sType, QString &sName, QString &sArgs,
|
||||
bool &isStatic, bool &isFriend); // caching of results
|
||||
bool checkForNamespace();
|
||||
bool checkForKeyword(KeywordType &keywordType);
|
||||
bool checkForMethod(QString &sType, QString &sName, int &argStartIndex,
|
||||
int &argEndIndex, bool &isStatic, bool &isFriend); // caching of results
|
||||
bool checkForNamespace(KeywordType keywordType);
|
||||
bool checkForPreprocessor();
|
||||
bool checkForScope();
|
||||
void checkForSkipStatement();
|
||||
bool checkForStructs();
|
||||
bool checkForTypedef();
|
||||
// bool checkForLambda();
|
||||
bool checkForScope(KeywordType keywordType);
|
||||
bool checkForStructs(KeywordType keywordType);
|
||||
bool checkForTypedefEnum();
|
||||
bool checkForTypedefStruct();
|
||||
bool checkForUsing();
|
||||
bool checkForVar();
|
||||
QString expandMacroType(const QString& name);
|
||||
bool checkForUsing(KeywordType keywordType);
|
||||
|
||||
void checkAndHandleMethodOrVar(KeywordType keywordType);
|
||||
|
||||
void fillListOfFunctions(const QString& fileName, int line,
|
||||
const PStatement& statement,
|
||||
|
@ -308,10 +322,23 @@ private:
|
|||
void doSkipInExpression(const QStringList& expression, int&pos, const QString& startSymbol, const QString& endSymbol);
|
||||
|
||||
bool isIdentifier(const QString& token) const {
|
||||
return (!token.isEmpty() && isLetterChar(token.front())
|
||||
return (!token.isEmpty() && isIdentChar(token.front())
|
||||
&& !token.contains('\"'));
|
||||
}
|
||||
|
||||
bool isIdentifierOrPointer(const QString& term) const {
|
||||
switch(term[0].unicode()) {
|
||||
case '*':
|
||||
return true;
|
||||
case '\"':
|
||||
case '\'':
|
||||
return false;
|
||||
default:
|
||||
return isIdentChar(term[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool isIntegerLiteral(const QString& token) const {
|
||||
if (token.isEmpty())
|
||||
return false;
|
||||
|
@ -335,6 +362,24 @@ private:
|
|||
return false;
|
||||
return (token.startsWith('\''));
|
||||
}
|
||||
|
||||
bool isKeyword(const QString& token) const {
|
||||
return mCppKeywords.contains(token);
|
||||
}
|
||||
|
||||
bool tokenIsIdentifier(const QString& token) const {
|
||||
//token won't be empty
|
||||
return isIdentChar(token[0]);
|
||||
}
|
||||
|
||||
bool tokenIsTypeOrNonKeyword(const QString& token) const {
|
||||
return tokenIsIdentifier(token) &&
|
||||
(mCppTypeKeywords.contains(token)
|
||||
|| !mCppKeywords.contains(token)
|
||||
|| token=="const");
|
||||
|
||||
}
|
||||
|
||||
PStatement doParseEvalTypeInfo(
|
||||
const QString& fileName,
|
||||
const PStatement& scope,
|
||||
|
@ -343,7 +388,8 @@ private:
|
|||
int& pointerLevel);
|
||||
|
||||
int getBracketEnd(const QString& s, int startAt);
|
||||
StatementClassScope getClassScope(int index);
|
||||
StatementClassScope getClassScope(const QString& text);
|
||||
StatementClassScope getClassScope(KeywordType keywordType);
|
||||
int getCurrentBlockBeginSkip();
|
||||
int getCurrentBlockEndSkip();
|
||||
int getCurrentInlineNamespaceEndSkip();
|
||||
|
@ -370,23 +416,25 @@ private:
|
|||
PStatement getTypeDef(const PStatement& statement,
|
||||
const QString& fileName, const QString& aType);
|
||||
void handleCatchBlock();
|
||||
void handleEnum();
|
||||
void handleEnum(bool isTypedef);
|
||||
void handleForBlock();
|
||||
void handleKeyword();
|
||||
void handleKeyword(KeywordType skipType);
|
||||
void handleLambda(int index, int endIndex);
|
||||
void handleMethod(
|
||||
StatementKind functionKind,
|
||||
const QString& sType,
|
||||
const QString& sName,
|
||||
const QString& sArgs,
|
||||
int argStart,
|
||||
bool isStatic,
|
||||
bool isFriend);
|
||||
void handleNamespace();
|
||||
void handleNamespace(KeywordType skipType);
|
||||
void handleOtherTypedefs();
|
||||
void handlePreprocessor();
|
||||
void handleScope();
|
||||
void handleScope(KeywordType keywordType);
|
||||
bool handleStatement();
|
||||
void handleStructs(bool isTypedef = false);
|
||||
void handleUsing();
|
||||
void handleVar();
|
||||
void handleVar(const QString& typePrefix,bool isExtern,bool isStatic);
|
||||
void internalParse(const QString& fileName);
|
||||
// function FindMacroDefine(const Command: AnsiString): PStatement;
|
||||
void inheritClassStatement(
|
||||
|
@ -410,11 +458,12 @@ private:
|
|||
// }
|
||||
void scanMethodArgs(
|
||||
const PStatement& functionStatement,
|
||||
const QString& argStr);
|
||||
int argStart);
|
||||
QString splitPhrase(const QString& phrase, QString& sClazz,
|
||||
QString& sOperator, QString &sMember);
|
||||
QString removeTemplateParams(const QString& phrase);
|
||||
|
||||
QString removeArgNames(const QString& args);
|
||||
bool splitLastMember(const QString& token, QString& lastMember, QString& remaining);
|
||||
|
||||
bool isSpaceChar(const QChar& ch) const {
|
||||
return ch==' ' || ch =='\t';
|
||||
|
@ -427,7 +476,14 @@ private:
|
|||
|| ch == '&';
|
||||
}
|
||||
|
||||
bool isLetterChar(const QChar& ch) const {
|
||||
bool isIdentifier(const QChar& ch) const {
|
||||
return ch.isLetter()
|
||||
|| ch == '_'
|
||||
|| ch == '~'
|
||||
;
|
||||
}
|
||||
|
||||
bool isIdentChar(const QChar& ch) const {
|
||||
return ch.isLetter()
|
||||
|| ch == '_';
|
||||
}
|
||||
|
@ -436,6 +492,24 @@ private:
|
|||
return (ch>='0' && ch<='9');
|
||||
}
|
||||
|
||||
bool isInvalidFunctionArgsSuffixChar(const QChar& ch) const {
|
||||
|
||||
// &&
|
||||
switch(ch.unicode()){
|
||||
case '.':
|
||||
case '-':
|
||||
case '+':
|
||||
case '/':
|
||||
case '%':
|
||||
case '*':
|
||||
case '|':
|
||||
case '?':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*'(', ';', ':', '{', '}', '#' */
|
||||
bool isSeperator(const QChar& ch) const {
|
||||
switch(ch.unicode()){
|
||||
|
@ -493,7 +567,7 @@ private:
|
|||
return ch=='\n' || ch=='\r';
|
||||
}
|
||||
|
||||
bool isNotFuncArgs(const QString& args);
|
||||
bool isNotFuncArgs(int startIndex);
|
||||
|
||||
/**
|
||||
* @brief Test if a statement is a class/struct/union/namespace/function
|
||||
|
@ -511,7 +585,20 @@ private:
|
|||
|
||||
void updateSerialId();
|
||||
|
||||
|
||||
int indexOfNextSemicolon(int index, int endIndex=-1);
|
||||
int indexOfNextSemicolonOrLeftBrace(int index);
|
||||
int indexOfNextColon(int index);
|
||||
int indexOfNextLeftBrace(int index);
|
||||
int indexPassParenthesis(int index);
|
||||
int indexPassBraces(int index);
|
||||
int skipAssignment(int index, int endIndex);
|
||||
void skipNextSemicolon(int index);
|
||||
int moveToNextBraceOrSkipNextSemicolon(int index, bool checkLambda, int endIndex=-1);
|
||||
void skipParenthesis(int index);
|
||||
QString mergeArgs(int startIndex, int endIndex);
|
||||
void parseCommandTypeAndArgs(QString& command,
|
||||
QString& typeSuffix,
|
||||
QString& args);
|
||||
private:
|
||||
int mParserId;
|
||||
ParserLanguage mLanguage;
|
||||
|
@ -528,9 +615,6 @@ private:
|
|||
QVector<PStatement> mCurrentScope;
|
||||
QVector<StatementClassScope> mCurrentClassScope;
|
||||
|
||||
// the start index in tokens to skip to ; when parsing typedef struct we need to skip
|
||||
// the names after the closing bracket because we have processed it
|
||||
QVector<int> mSkipList; // TList<Integer>
|
||||
StatementClassScope mClassScope;
|
||||
StatementModel mStatementList;
|
||||
//It's used in preprocessor, so we can't use fIncludeList instead
|
||||
|
@ -554,7 +638,7 @@ private:
|
|||
|
||||
QMutex mMutex;
|
||||
GetFileStreamCallBack mOnGetFileStream;
|
||||
QMap<QString,SkipType> mCppKeywords;
|
||||
QMap<QString,KeywordType> mCppKeywords;
|
||||
QSet<QString> mCppTypeKeywords;
|
||||
};
|
||||
using PCppParser = std::shared_ptr<CppParser>;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QDebug>
|
||||
|
||||
CppTokenizer::CppTokenizer()
|
||||
{
|
||||
|
@ -30,6 +31,10 @@ void CppTokenizer::clear()
|
|||
mBuffer.clear();
|
||||
mBufferStr.clear();
|
||||
mLastToken.clear();
|
||||
mUnmatchedBraces.clear();
|
||||
mUnmatchedBrackets.clear();
|
||||
mUnmatchedParenthesis.clear();
|
||||
mLambdas.clear();
|
||||
}
|
||||
|
||||
void CppTokenizer::tokenize(const QStringList &buffer)
|
||||
|
@ -48,16 +53,26 @@ void CppTokenizer::tokenize(const QStringList &buffer)
|
|||
mCurrent = mStart;
|
||||
mLineCount = mStart;
|
||||
QString s = "";
|
||||
bool bSkipBlocks = false;
|
||||
mCurrentLine = 1;
|
||||
|
||||
TokenType tokenType;
|
||||
while (true) {
|
||||
mLastToken = s;
|
||||
s = getNextToken(true, true, bSkipBlocks);
|
||||
s = getNextToken(&tokenType, true, false);
|
||||
simplify(s);
|
||||
if (s.isEmpty())
|
||||
break;
|
||||
else
|
||||
addToken(s,mCurrentLine);
|
||||
addToken(s,mCurrentLine,tokenType);
|
||||
}
|
||||
while (!mUnmatchedBraces.isEmpty()) {
|
||||
addToken("}",mCurrentLine,TokenType::RightBrace);
|
||||
}
|
||||
while (!mUnmatchedBrackets.isEmpty()) {
|
||||
addToken("]",mCurrentLine,TokenType::RightBracket);
|
||||
}
|
||||
while (!mUnmatchedParenthesis.isEmpty()) {
|
||||
addToken(")",mCurrentLine,TokenType::RightParenthesis);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,7 +83,7 @@ void CppTokenizer::dumpTokens(const QString &fileName)
|
|||
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||
QTextStream stream(&file);
|
||||
foreach (const PToken& token,mTokenList) {
|
||||
stream<<QString("%1,%2").arg(token->line).arg(token->text)
|
||||
stream<<QString("%1,%2,%3").arg(token->line).arg(token->text).arg(token->matchIndex)
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
|
||||
<<Qt::endl;
|
||||
#else
|
||||
|
@ -93,11 +108,59 @@ int CppTokenizer::tokenCount()
|
|||
return mTokenList.count();
|
||||
}
|
||||
|
||||
void CppTokenizer::addToken(const QString &sText, int iLine)
|
||||
void CppTokenizer::addToken(const QString &sText, int iLine, TokenType tokenType)
|
||||
{
|
||||
PToken token = std::make_shared<Token>();
|
||||
token->text = sText;
|
||||
token->line = iLine;
|
||||
#ifdef Q_DEBUG
|
||||
token->matchIndex = 1000000000;
|
||||
#endif
|
||||
switch(tokenType) {
|
||||
case TokenType::LeftBrace:
|
||||
token->matchIndex=-1;
|
||||
mUnmatchedBraces.push_back(mTokenList.count());
|
||||
break;
|
||||
case TokenType::RightBrace:
|
||||
if (mUnmatchedBraces.isEmpty()) {
|
||||
token->matchIndex=-1;
|
||||
} else {
|
||||
token->matchIndex = mUnmatchedBraces.last();
|
||||
mTokenList[token->matchIndex]->matchIndex=mTokenList.count();
|
||||
mUnmatchedBraces.pop_back();
|
||||
}
|
||||
break;
|
||||
case TokenType::LeftBracket:
|
||||
token->matchIndex=-1;
|
||||
mUnmatchedBrackets.push_back(mTokenList.count());
|
||||
break;
|
||||
case TokenType::RightBracket:
|
||||
if (mUnmatchedBrackets.isEmpty()) {
|
||||
token->matchIndex=-1;
|
||||
} else {
|
||||
token->matchIndex = mUnmatchedBrackets.last();
|
||||
mTokenList[token->matchIndex]->matchIndex=mTokenList.count();
|
||||
mUnmatchedBrackets.pop_back();
|
||||
}
|
||||
break;
|
||||
case TokenType::LeftParenthesis:
|
||||
token->matchIndex=-1;
|
||||
mUnmatchedParenthesis.push_back(mTokenList.count());
|
||||
break;
|
||||
case TokenType::RightParenthesis:
|
||||
if (mUnmatchedParenthesis.isEmpty()) {
|
||||
token->matchIndex=-1;
|
||||
} else {
|
||||
token->matchIndex = mUnmatchedParenthesis.last();
|
||||
mTokenList[token->matchIndex]->matchIndex=mTokenList.count();
|
||||
mUnmatchedParenthesis.pop_back();
|
||||
}
|
||||
break;
|
||||
case TokenType::LambdaCaptures:
|
||||
mLambdas.push_back(mTokenList.count());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mTokenList.append(token);
|
||||
}
|
||||
|
||||
|
@ -110,28 +173,6 @@ void CppTokenizer::countLines()
|
|||
}
|
||||
}
|
||||
|
||||
QString CppTokenizer::getArguments()
|
||||
{
|
||||
QChar* offset = mCurrent;
|
||||
skipPair('(', ')');
|
||||
QString result(offset,mCurrent-offset);
|
||||
simplifyArgs(result);
|
||||
if ((*mCurrent == '.') || ((*mCurrent == '-') && (*(mCurrent + 1) == '>'))) {
|
||||
// skip '.' and '->'
|
||||
while ( !( *mCurrent == 0
|
||||
|| *mCurrent == '('
|
||||
|| *mCurrent == ';'
|
||||
|| *mCurrent == '{'
|
||||
|| *mCurrent == '}'
|
||||
|| *mCurrent == ')'
|
||||
|| isLineChar(*mCurrent)
|
||||
|| isSpaceChar(*mCurrent)) )
|
||||
mCurrent++;
|
||||
}
|
||||
skipToNextToken();
|
||||
return result;
|
||||
}
|
||||
|
||||
QString CppTokenizer::getForInit()
|
||||
{
|
||||
QChar* startOffset = mCurrent;
|
||||
|
@ -139,12 +180,13 @@ QString CppTokenizer::getForInit()
|
|||
// Step into the init statement
|
||||
mCurrent++;
|
||||
|
||||
TokenType tokenType;
|
||||
// Process until ; or end of file
|
||||
while (true) {
|
||||
QString s = getNextToken(true, true, false);
|
||||
QString s = getNextToken(&tokenType, true, false);
|
||||
simplify(s);
|
||||
if (!s.isEmpty())
|
||||
addToken(s,mCurrentLine);
|
||||
addToken(s,mCurrentLine,tokenType);
|
||||
if ( (s == "") || (s == ";") || (s==":"))
|
||||
break;
|
||||
// : is used in for-each loop
|
||||
|
@ -156,10 +198,12 @@ QString CppTokenizer::getForInit()
|
|||
return "";
|
||||
}
|
||||
|
||||
QString CppTokenizer::getNextToken(bool /* bSkipParenthesis */, bool bSkipArray, bool bSkipBlock)
|
||||
QString CppTokenizer::getNextToken(TokenType *pTokenType, bool bSkipArray, bool bSkipBlock)
|
||||
{
|
||||
QString result;
|
||||
int backupIndex;
|
||||
bool done = false;
|
||||
*pTokenType=TokenType::Normal;
|
||||
while (true) {
|
||||
skipToNextToken();
|
||||
if (*mCurrent == 0)
|
||||
|
@ -179,13 +223,18 @@ QString CppTokenizer::getNextToken(bool /* bSkipParenthesis */, bool bSkipArray,
|
|||
countLines();
|
||||
result = getForInit();
|
||||
done = (result != "");
|
||||
} else if (isArguments()) {
|
||||
countLines();
|
||||
result = getArguments();
|
||||
done = (result != "");
|
||||
// } else if (isArguments()) {
|
||||
// countLines();
|
||||
// result = getArguments();
|
||||
// done = (result != "");
|
||||
} else if (isWord()) {
|
||||
countLines();
|
||||
result = getWord(false, bSkipArray, bSkipBlock);
|
||||
// if (result=="noexcept" || result == "throw") {
|
||||
// result="";
|
||||
// if (*mCurrent=='(')
|
||||
// skipPair('(',')');
|
||||
// }
|
||||
done = (result != "");
|
||||
} else if (isNumber()) {
|
||||
countLines();
|
||||
|
@ -196,49 +245,119 @@ QString CppTokenizer::getNextToken(bool /* bSkipParenthesis */, bool bSkipArray,
|
|||
case 0:
|
||||
done = true;
|
||||
break;
|
||||
case '/':
|
||||
advance();
|
||||
break;
|
||||
case ':':
|
||||
if (*(mCurrent + 1) == ':') {
|
||||
countLines();
|
||||
mCurrent+=2;
|
||||
result = "::";
|
||||
skipToNextToken();
|
||||
// Append next token to this one
|
||||
result = "::"+getWord(true, bSkipArray, bSkipBlock);
|
||||
if (isIdentChar(*mCurrent))
|
||||
result+=getWord(true, bSkipArray, bSkipBlock);
|
||||
done = true;
|
||||
} else {
|
||||
countLines();
|
||||
result = *mCurrent;
|
||||
advance();
|
||||
mCurrent++;
|
||||
done = true;
|
||||
}
|
||||
break;
|
||||
case '{':
|
||||
*pTokenType=TokenType::LeftBrace;
|
||||
countLines();
|
||||
result = *mCurrent;
|
||||
mCurrent++;
|
||||
done = true;
|
||||
break;
|
||||
case '}':
|
||||
*pTokenType=TokenType::RightBrace;
|
||||
countLines();
|
||||
result = *mCurrent;
|
||||
mCurrent++;
|
||||
done = true;
|
||||
break;
|
||||
case '(':
|
||||
*pTokenType=TokenType::LeftParenthesis;
|
||||
countLines();
|
||||
result = *mCurrent;
|
||||
mCurrent++;
|
||||
done = true;
|
||||
break;
|
||||
case '[':
|
||||
if (*(mCurrent+1)!='[') {
|
||||
*pTokenType=TokenType::LambdaCaptures;
|
||||
countLines();
|
||||
QChar* backup=mCurrent;
|
||||
skipPair('[',']');
|
||||
result = QString(backup,mCurrent-backup);
|
||||
done = true;
|
||||
} else {
|
||||
skipPair('[',']'); // attribute, skipit
|
||||
}
|
||||
break;
|
||||
case ')':
|
||||
*pTokenType=TokenType::RightParenthesis;
|
||||
countLines();
|
||||
result = *mCurrent;
|
||||
mCurrent++;
|
||||
done = true;
|
||||
break;
|
||||
case ';':
|
||||
case ',': //just return the brace or the ';'
|
||||
countLines();
|
||||
result = *mCurrent;
|
||||
advance();
|
||||
mCurrent++;
|
||||
done = true;
|
||||
break;
|
||||
case '>': // keep stream operators
|
||||
if (*(mCurrent + 1) == '>') {
|
||||
countLines();
|
||||
result = ">>";
|
||||
advance();
|
||||
mCurrent+=2;
|
||||
done = true;
|
||||
} else
|
||||
advance();
|
||||
mCurrent+=1;
|
||||
break;
|
||||
case '<':
|
||||
if (*(mCurrent + 1) == '<') {
|
||||
countLines();
|
||||
result = "<<";
|
||||
advance();
|
||||
mCurrent+=2;
|
||||
done = true;
|
||||
} else
|
||||
advance();
|
||||
mCurrent+=1;
|
||||
break;
|
||||
case '=': {
|
||||
if (*(mCurrent+1)=='=') {
|
||||
// skip '=='
|
||||
skipAssignment();
|
||||
} else {
|
||||
countLines();
|
||||
mCurrent+=1;
|
||||
result = "=";
|
||||
done = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '!':
|
||||
if (*(mCurrent+1)=='=') {
|
||||
skipAssignment();
|
||||
} else
|
||||
mCurrent++;
|
||||
break;
|
||||
case '/':
|
||||
case '%':
|
||||
case '&':
|
||||
case '*':
|
||||
case '|':
|
||||
case '+':
|
||||
case '-':
|
||||
case '~':
|
||||
if (*(mCurrent + 1) == '=') {
|
||||
skipAssignment();
|
||||
} else
|
||||
mCurrent++;
|
||||
break;
|
||||
default:
|
||||
advance();
|
||||
|
@ -256,7 +375,8 @@ QString CppTokenizer::getNumber()
|
|||
|
||||
if (isDigitChar(*mCurrent)) {
|
||||
while (isDigitChar(*mCurrent) || isHexChar(*mCurrent)) {
|
||||
advance();
|
||||
mCurrent++;
|
||||
//advance();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,10 +441,11 @@ QString CppTokenizer::getWord(bool bSkipParenthesis, bool bSkipArray, bool bSkip
|
|||
|
||||
// Skip template contents, but keep template variable types
|
||||
if (*mCurrent == '<') {
|
||||
offset = mCurrent; //we don't skip
|
||||
skipTemplateArgs();
|
||||
offset = mCurrent;
|
||||
|
||||
if (!bFoundTemplate) {
|
||||
if (bFoundTemplate) {
|
||||
skipTemplateArgs();
|
||||
} else if (skipAngleBracketPair()){
|
||||
result += QString(offset, mCurrent-offset);
|
||||
skipToNextToken();
|
||||
}
|
||||
|
@ -355,12 +476,15 @@ QString CppTokenizer::getWord(bool bSkipParenthesis, bool bSkipArray, bool bSkip
|
|||
if (result != "using") {
|
||||
result+=QString(mCurrent,2);
|
||||
mCurrent+=2;
|
||||
skipToNextToken();
|
||||
if (isIdentChar(*mCurrent)) {
|
||||
// Append next token to this one
|
||||
QString s = getWord(bSkipParenthesis, bSkipArray, bSkipBlock);
|
||||
result += s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -480,18 +604,18 @@ void CppTokenizer::skipDoubleQuotes()
|
|||
}
|
||||
}
|
||||
|
||||
void CppTokenizer::skipPair(const QChar &cStart, const QChar cEnd, const QSet<QChar>& failChars)
|
||||
void CppTokenizer::skipPair(const QChar &cStart, const QChar cEnd)
|
||||
{
|
||||
mCurrent++;
|
||||
while (*mCurrent != 0) {
|
||||
if ((*mCurrent == '(') && !failChars.contains('(')) {
|
||||
skipPair('(', ')', failChars);
|
||||
} else if ((*mCurrent == '[') && !failChars.contains('[')) {
|
||||
skipPair('[', ']', failChars);
|
||||
} else if ((*mCurrent == '{') && !failChars.contains('{')) {
|
||||
skipPair('{', '}', failChars);
|
||||
if (*mCurrent == '(') {
|
||||
skipPair('(', ')');
|
||||
} else if (*mCurrent == '[') {
|
||||
skipPair('[', ']');
|
||||
} else if (*mCurrent == '{') {
|
||||
skipPair('{', '}');
|
||||
} else if (*mCurrent == cStart) {
|
||||
skipPair(cStart, cEnd, failChars);
|
||||
skipPair(cStart, cEnd);
|
||||
} else if (*mCurrent == cEnd) {
|
||||
mCurrent++; // skip over end
|
||||
break;
|
||||
|
@ -510,14 +634,81 @@ void CppTokenizer::skipPair(const QChar &cStart, const QChar cEnd, const QSet<QC
|
|||
skipSingleQuote(); // don't do it inside AnsiString!
|
||||
else
|
||||
mCurrent++;
|
||||
} else if (failChars.contains(*mCurrent)) {
|
||||
break;
|
||||
} else {
|
||||
mCurrent++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CppTokenizer::skipAngleBracketPair()
|
||||
{
|
||||
QChar* backup=mCurrent;
|
||||
QVector<QChar> stack;
|
||||
while (*mCurrent != '\0') {
|
||||
switch((*mCurrent).unicode()) {
|
||||
case '<':
|
||||
case '(':
|
||||
case '[':
|
||||
stack.push_back(*mCurrent);
|
||||
break;
|
||||
case ')':
|
||||
while (!stack.isEmpty() && stack.back()!='(') {
|
||||
stack.pop_back();
|
||||
}
|
||||
//pop up '('
|
||||
if (stack.isEmpty()) {
|
||||
mCurrent=backup;
|
||||
return false;
|
||||
}
|
||||
stack.pop_back();
|
||||
break;
|
||||
case ']':
|
||||
while (!stack.isEmpty() && stack.back()!='[')
|
||||
stack.pop_back();
|
||||
//pop up '['
|
||||
if (stack.isEmpty()) {
|
||||
mCurrent=backup;
|
||||
return false;
|
||||
}
|
||||
stack.pop_back();
|
||||
break;
|
||||
case '>':
|
||||
if (stack.back()=='<')
|
||||
stack.pop_back();
|
||||
if (stack.isEmpty()) {
|
||||
mCurrent++;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case '{':
|
||||
case '}':
|
||||
case ';':
|
||||
case '"':
|
||||
case '\'':
|
||||
mCurrent=backup;
|
||||
return false;
|
||||
case '-':
|
||||
if (*(mCurrent+1)=='>') {
|
||||
mCurrent=backup;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '.':
|
||||
if (*(mCurrent+1)!='.') {
|
||||
mCurrent=backup;
|
||||
return false;
|
||||
}
|
||||
// skip
|
||||
while (*(mCurrent+1)=='.')
|
||||
mCurrent++;
|
||||
break;
|
||||
}
|
||||
mCurrent++;
|
||||
}
|
||||
mCurrent=backup;
|
||||
return false;
|
||||
}
|
||||
|
||||
void CppTokenizer::skipRawString()
|
||||
{
|
||||
mCurrent++; //skip R
|
||||
|
@ -566,17 +757,8 @@ void CppTokenizer::skipTemplateArgs()
|
|||
{
|
||||
if (*mCurrent != '<')
|
||||
return;
|
||||
QChar* start = mCurrent;
|
||||
|
||||
QSet<QChar> failSet;
|
||||
failSet.insert('{');
|
||||
failSet.insert('}');
|
||||
failSet.insert(';');
|
||||
skipPair('<', '>', failSet);
|
||||
|
||||
// if we failed, return to where we came from
|
||||
if (start!=mCurrent && *(mCurrent - 1) != '>')
|
||||
mCurrent = start;
|
||||
skipPair('<', '>');
|
||||
}
|
||||
|
||||
void CppTokenizer::skipToEOL()
|
||||
|
@ -601,7 +783,7 @@ void CppTokenizer::skipToEOL()
|
|||
void CppTokenizer::skipToNextToken()
|
||||
{
|
||||
while (isSpaceChar(*mCurrent) || isLineChar(*mCurrent))
|
||||
advance();
|
||||
mCurrent++;
|
||||
}
|
||||
|
||||
bool CppTokenizer::isIdentChar(const QChar &ch)
|
||||
|
@ -609,39 +791,29 @@ bool CppTokenizer::isIdentChar(const QChar &ch)
|
|||
return ch=='_' || ch.isLetter() ;
|
||||
}
|
||||
|
||||
int CppTokenizer::lambdasCount() const
|
||||
{
|
||||
return mLambdas.count();
|
||||
}
|
||||
|
||||
int CppTokenizer::indexOfFirstLambda() const
|
||||
{
|
||||
return mLambdas.front();
|
||||
}
|
||||
|
||||
void CppTokenizer::removeFirstLambda()
|
||||
{
|
||||
mLambdas.pop_front();
|
||||
}
|
||||
|
||||
void CppTokenizer::advance()
|
||||
{
|
||||
switch(mCurrent->unicode()) {
|
||||
case '\"': skipDoubleQuotes();
|
||||
case '\"':
|
||||
skipDoubleQuotes();
|
||||
break;
|
||||
case '\'': skipSingleQuote();
|
||||
break;
|
||||
case '/':
|
||||
if (*(mCurrent + 1) == '=')
|
||||
skipAssignment();
|
||||
else
|
||||
mCurrent++;
|
||||
break;
|
||||
case '=': {
|
||||
if (mTokenList.size()>2
|
||||
&& mTokenList[mTokenList.size()-2]->text == "using") {
|
||||
addToken("=",mCurrentLine);
|
||||
mCurrent++;
|
||||
} else
|
||||
skipAssignment();
|
||||
break;
|
||||
}
|
||||
case '&':
|
||||
case '*':
|
||||
case '!':
|
||||
case '|':
|
||||
case '+':
|
||||
case '-':
|
||||
case '~':
|
||||
if (*(mCurrent + 1) == '=')
|
||||
skipAssignment();
|
||||
else
|
||||
mCurrent++;
|
||||
case '\'':
|
||||
skipSingleQuote();
|
||||
break;
|
||||
case '\\':
|
||||
if (isLineChar(*(mCurrent + 1)))
|
||||
|
@ -649,11 +821,14 @@ void CppTokenizer::advance()
|
|||
else
|
||||
mCurrent++;
|
||||
break;
|
||||
default:
|
||||
if ((*mCurrent == 'R') && (*(mCurrent+1) == '"'))
|
||||
case 'R':
|
||||
if (*(mCurrent+1) == '"')
|
||||
skipRawString();
|
||||
else
|
||||
mCurrent++;
|
||||
break;
|
||||
default:
|
||||
mCurrent++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -693,7 +868,7 @@ bool CppTokenizer::isLineChar(const QChar &ch)
|
|||
|
||||
bool CppTokenizer::isBlankChar(const QChar &ch)
|
||||
{
|
||||
return (ch<=32);
|
||||
return (ch<=32) && (ch>0);
|
||||
}
|
||||
|
||||
bool CppTokenizer::isOperatorChar(const QChar &ch)
|
||||
|
|
|
@ -22,10 +22,23 @@
|
|||
|
||||
class CppTokenizer
|
||||
{
|
||||
enum class TokenType {
|
||||
Normal,
|
||||
LeftBrace,
|
||||
RightBrace,
|
||||
LeftParenthesis,
|
||||
RightParenthesis,
|
||||
LeftBracket,
|
||||
RightBracket,
|
||||
Assignment,
|
||||
LambdaCaptures
|
||||
};
|
||||
|
||||
public:
|
||||
struct Token {
|
||||
QString text;
|
||||
int line;
|
||||
int matchIndex;
|
||||
};
|
||||
using PToken = std::shared_ptr<Token>;
|
||||
using TokenList = QVector<PToken>;
|
||||
|
@ -38,16 +51,19 @@ public:
|
|||
PToken operator[](int i);
|
||||
int tokenCount();
|
||||
bool isIdentChar(const QChar& ch);
|
||||
int lambdasCount() const;
|
||||
int indexOfFirstLambda() const;
|
||||
void removeFirstLambda();
|
||||
|
||||
private:
|
||||
void addToken(const QString& sText, int iLine);
|
||||
void addToken(const QString& sText, int iLine, TokenType tokenType);
|
||||
void advance();
|
||||
void countLines();
|
||||
PToken getToken(int index);
|
||||
|
||||
QString getArguments();
|
||||
QString getForInit();
|
||||
QString getNextToken(
|
||||
bool bSkipParenthesis = false,
|
||||
TokenType *pTokenType,
|
||||
bool bSkipArray = false,
|
||||
bool bSkipBlock = false);
|
||||
QString getNumber();
|
||||
|
@ -65,7 +81,8 @@ private:
|
|||
void simplifyArgs(QString& output);
|
||||
void skipAssignment();
|
||||
void skipDoubleQuotes();
|
||||
void skipPair(const QChar& cStart, const QChar cEnd, const QSet<QChar>& failChars = QSet<QChar>());
|
||||
void skipPair(const QChar& cStart, const QChar cEnd);
|
||||
bool skipAngleBracketPair();
|
||||
void skipRawString();
|
||||
void skipSingleQuote();
|
||||
void skipSplitLine();
|
||||
|
@ -92,6 +109,10 @@ private:
|
|||
int mCurrentLine;
|
||||
QString mLastToken;
|
||||
TokenList mTokenList;
|
||||
QList<int> mLambdas;
|
||||
QVector<int> mUnmatchedBraces; // stack of indices for unmatched '{'
|
||||
QVector<int> mUnmatchedBrackets; // stack of indices for unmatched '['
|
||||
QVector<int> mUnmatchedParenthesis;// stack of indices for unmatched '('
|
||||
};
|
||||
|
||||
using PCppTokenizer = std::shared_ptr<CppTokenizer>;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
QStringList CppDirectives;
|
||||
QStringList JavadocTags;
|
||||
QMap<QString,SkipType> CppKeywords;
|
||||
QMap<QString,KeywordType> CppKeywords;
|
||||
QSet<QString> CppControlKeyWords;
|
||||
QSet<QString> CppTypeKeywords;
|
||||
QSet<QString> CKeywords;
|
||||
|
@ -55,107 +55,107 @@ void initParser()
|
|||
CppSourceExts->insert("c++");
|
||||
CppSourceExts->insert("cp");
|
||||
// skip itself
|
||||
CppKeywords.insert("and",SkipType::skItself);
|
||||
CppKeywords.insert("and_eq",SkipType::skItself);
|
||||
CppKeywords.insert("bitand",SkipType::skItself);
|
||||
CppKeywords.insert("bitor",SkipType::skItself);
|
||||
CppKeywords.insert("break",SkipType::skItself);
|
||||
CppKeywords.insert("compl",SkipType::skItself);
|
||||
CppKeywords.insert("constexpr",SkipType::skItself);
|
||||
CppKeywords.insert("const_cast",SkipType::skItself);
|
||||
CppKeywords.insert("continue",SkipType::skItself);
|
||||
CppKeywords.insert("dynamic_cast",SkipType::skItself);
|
||||
CppKeywords.insert("else",SkipType::skItself);
|
||||
CppKeywords.insert("explicit",SkipType::skItself);
|
||||
CppKeywords.insert("export",SkipType::skItself);
|
||||
CppKeywords.insert("false",SkipType::skItself);
|
||||
CppKeywords.insert("and",KeywordType::SkipItself);
|
||||
CppKeywords.insert("and_eq",KeywordType::SkipItself);
|
||||
CppKeywords.insert("bitand",KeywordType::SkipItself);
|
||||
CppKeywords.insert("bitor",KeywordType::SkipItself);
|
||||
CppKeywords.insert("break",KeywordType::SkipItself);
|
||||
CppKeywords.insert("compl",KeywordType::SkipItself);
|
||||
CppKeywords.insert("constexpr",KeywordType::SkipItself);
|
||||
CppKeywords.insert("const_cast",KeywordType::SkipItself);
|
||||
CppKeywords.insert("continue",KeywordType::SkipItself);
|
||||
CppKeywords.insert("dynamic_cast",KeywordType::SkipItself);
|
||||
CppKeywords.insert("else",KeywordType::SkipItself);
|
||||
CppKeywords.insert("explicit",KeywordType::SkipItself);
|
||||
CppKeywords.insert("export",KeywordType::SkipItself);
|
||||
CppKeywords.insert("false",KeywordType::SkipItself);
|
||||
//CppKeywords.insert("for",SkipType::skItself);
|
||||
CppKeywords.insert("mutable",SkipType::skItself);
|
||||
CppKeywords.insert("noexcept",SkipType::skItself);
|
||||
CppKeywords.insert("not",SkipType::skItself);
|
||||
CppKeywords.insert("not_eq",SkipType::skItself);
|
||||
CppKeywords.insert("nullptr",SkipType::skItself);
|
||||
CppKeywords.insert("or",SkipType::skItself);
|
||||
CppKeywords.insert("or_eq",SkipType::skItself);
|
||||
CppKeywords.insert("register",SkipType::skItself);
|
||||
CppKeywords.insert("reinterpret_cast",SkipType::skItself);
|
||||
CppKeywords.insert("static_assert",SkipType::skItself);
|
||||
CppKeywords.insert("static_cast",SkipType::skItself);
|
||||
CppKeywords.insert("template",SkipType::skItself);
|
||||
CppKeywords.insert("mutable",KeywordType::SkipItself);
|
||||
CppKeywords.insert("noexcept",KeywordType::SkipItself);
|
||||
CppKeywords.insert("not",KeywordType::SkipItself);
|
||||
CppKeywords.insert("not_eq",KeywordType::SkipItself);
|
||||
CppKeywords.insert("nullptr",KeywordType::SkipItself);
|
||||
CppKeywords.insert("or",KeywordType::SkipItself);
|
||||
CppKeywords.insert("or_eq",KeywordType::SkipItself);
|
||||
CppKeywords.insert("register",KeywordType::SkipItself);
|
||||
CppKeywords.insert("reinterpret_cast",KeywordType::SkipItself);
|
||||
CppKeywords.insert("static_cast",KeywordType::SkipItself);
|
||||
CppKeywords.insert("template",KeywordType::SkipItself);
|
||||
//CppKeywords.insert("this",SkipType::skItself);
|
||||
CppKeywords.insert("thread_local",SkipType::skItself);
|
||||
CppKeywords.insert("true",SkipType::skItself);
|
||||
CppKeywords.insert("typename",SkipType::skItself);
|
||||
CppKeywords.insert("virtual",SkipType::skItself);
|
||||
CppKeywords.insert("volatile",SkipType::skItself);
|
||||
CppKeywords.insert("xor",SkipType::skItself);
|
||||
CppKeywords.insert("xor_eq",SkipType::skItself);
|
||||
CppKeywords.insert("thread_local",KeywordType::SkipItself);
|
||||
CppKeywords.insert("true",KeywordType::SkipItself);
|
||||
CppKeywords.insert("typename",KeywordType::SkipItself);
|
||||
CppKeywords.insert("virtual",KeywordType::SkipItself);
|
||||
CppKeywords.insert("volatile",KeywordType::SkipItself);
|
||||
CppKeywords.insert("xor",KeywordType::SkipItself);
|
||||
CppKeywords.insert("xor_eq",KeywordType::SkipItself);
|
||||
|
||||
|
||||
//CppKeywords.insert("catch",SkipType::skItself);
|
||||
CppKeywords.insert("do",SkipType::skItself);
|
||||
CppKeywords.insert("try",SkipType::skItself);
|
||||
CppKeywords.insert("do",KeywordType::SkipItself);
|
||||
CppKeywords.insert("try",KeywordType::SkipItself);
|
||||
|
||||
// Skip to ;
|
||||
CppKeywords.insert("delete",SkipType::skToSemicolon);
|
||||
CppKeywords.insert("delete[]",SkipType::skToSemicolon);
|
||||
CppKeywords.insert("goto",SkipType::skToSemicolon);
|
||||
CppKeywords.insert("new",SkipType::skToSemicolon);
|
||||
CppKeywords.insert("return",SkipType::skToSemicolon);
|
||||
CppKeywords.insert("throw",SkipType::skToSemicolon);
|
||||
CppKeywords.insert("delete",KeywordType::SkipNextSemicolon);
|
||||
CppKeywords.insert("delete[]",KeywordType::SkipNextSemicolon);
|
||||
CppKeywords.insert("goto",KeywordType::SkipNextSemicolon);
|
||||
CppKeywords.insert("new",KeywordType::SkipNextSemicolon);
|
||||
CppKeywords.insert("return",KeywordType::SkipNextSemicolon);
|
||||
CppKeywords.insert("throw",KeywordType::SkipNextSemicolon);
|
||||
// CppKeywords.insert("using",SkipType::skToSemicolon); //won't use it
|
||||
|
||||
// Skip to :
|
||||
CppKeywords.insert("case",SkipType::skToColon);
|
||||
CppKeywords.insert("default",SkipType::skToColon);
|
||||
CppKeywords.insert("case",KeywordType::SkipNextColon);
|
||||
CppKeywords.insert("default",KeywordType::SkipNextColon);
|
||||
|
||||
// Skip to )
|
||||
CppKeywords.insert("__attribute__",SkipType::skToRightParenthesis);
|
||||
CppKeywords.insert("alignas",SkipType::skToRightParenthesis); // not right
|
||||
CppKeywords.insert("alignof",SkipType::skToRightParenthesis); // not right
|
||||
CppKeywords.insert("decltype",SkipType::skToRightParenthesis); // not right
|
||||
CppKeywords.insert("if",SkipType::skToRightParenthesis);
|
||||
CppKeywords.insert("sizeof",SkipType::skToRightParenthesis);
|
||||
CppKeywords.insert("switch",SkipType::skToRightParenthesis);
|
||||
CppKeywords.insert("typeid",SkipType::skToRightParenthesis);
|
||||
CppKeywords.insert("while",SkipType::skToRightParenthesis);
|
||||
CppKeywords.insert("__attribute__",KeywordType::SkipNextParenthesis);
|
||||
CppKeywords.insert("__attribute",KeywordType::SkipNextParenthesis);
|
||||
CppKeywords.insert("alignas",KeywordType::SkipNextParenthesis); // not right
|
||||
CppKeywords.insert("alignof",KeywordType::SkipNextParenthesis); // not right
|
||||
CppKeywords.insert("if",KeywordType::SkipNextParenthesis);
|
||||
CppKeywords.insert("sizeof",KeywordType::SkipNextParenthesis);
|
||||
CppKeywords.insert("switch",KeywordType::SkipNextParenthesis);
|
||||
CppKeywords.insert("typeid",KeywordType::SkipNextParenthesis);
|
||||
CppKeywords.insert("while",KeywordType::SkipNextParenthesis);
|
||||
CppKeywords.insert("static_assert",KeywordType::SkipNextParenthesis);
|
||||
|
||||
// Skip to }
|
||||
CppKeywords.insert("asm",SkipType::skToRightBrace);
|
||||
//CppKeywords.insert("namespace",SkipType::skToLeftBrace); // won't process it
|
||||
CppKeywords.insert("asm",KeywordType::MoveToRightBrace);
|
||||
CppKeywords.insert("__asm",KeywordType::MoveToRightBrace);
|
||||
// Skip to {
|
||||
|
||||
// wont handle
|
||||
|
||||
//Not supported yet
|
||||
CppKeywords.insert("atomic_cancel",SkipType::skNone);
|
||||
CppKeywords.insert("atomic_commit",SkipType::skNone);
|
||||
CppKeywords.insert("atomic_noexcept",SkipType::skNone);
|
||||
CppKeywords.insert("concept",SkipType::skNone);
|
||||
CppKeywords.insert("consteval",SkipType::skNone);
|
||||
CppKeywords.insert("constinit",SkipType::skNone);
|
||||
CppKeywords.insert("co_wait",SkipType::skNone);
|
||||
CppKeywords.insert("co_return",SkipType::skNone);
|
||||
CppKeywords.insert("co_yield",SkipType::skNone);
|
||||
CppKeywords.insert("reflexpr",SkipType::skNone);
|
||||
CppKeywords.insert("requires",SkipType::skNone);
|
||||
CppKeywords.insert("atomic_cancel",KeywordType::None);
|
||||
CppKeywords.insert("atomic_commit",KeywordType::None);
|
||||
CppKeywords.insert("atomic_noexcept",KeywordType::None);
|
||||
CppKeywords.insert("concept",KeywordType::None);
|
||||
CppKeywords.insert("consteval",KeywordType::None);
|
||||
CppKeywords.insert("constinit",KeywordType::None);
|
||||
CppKeywords.insert("co_wait",KeywordType::None);
|
||||
CppKeywords.insert("co_return",KeywordType::None);
|
||||
CppKeywords.insert("co_yield",KeywordType::None);
|
||||
CppKeywords.insert("reflexpr",KeywordType::None);
|
||||
CppKeywords.insert("requires",KeywordType::None);
|
||||
|
||||
// its a type
|
||||
CppKeywords.insert("auto",SkipType::skNone);
|
||||
CppKeywords.insert("bool",SkipType::skNone);
|
||||
CppKeywords.insert("char",SkipType::skNone);
|
||||
CppKeywords.insert("char8_t",SkipType::skNone);
|
||||
CppKeywords.insert("char16_t",SkipType::skNone);
|
||||
CppKeywords.insert("char32_t",SkipType::skNone);
|
||||
CppKeywords.insert("double",SkipType::skNone);
|
||||
CppKeywords.insert("float",SkipType::skNone);
|
||||
CppKeywords.insert("int",SkipType::skNone);
|
||||
CppKeywords.insert("long",SkipType::skNone);
|
||||
CppKeywords.insert("short",SkipType::skNone);
|
||||
CppKeywords.insert("signed",SkipType::skNone);
|
||||
CppKeywords.insert("unsigned",SkipType::skNone);
|
||||
CppKeywords.insert("void",SkipType::skNone);
|
||||
CppKeywords.insert("wchar_t",SkipType::skNone);
|
||||
CppKeywords.insert("auto",KeywordType::None);
|
||||
CppKeywords.insert("bool",KeywordType::None);
|
||||
CppKeywords.insert("char",KeywordType::None);
|
||||
CppKeywords.insert("char8_t",KeywordType::None);
|
||||
CppKeywords.insert("char16_t",KeywordType::None);
|
||||
CppKeywords.insert("char32_t",KeywordType::None);
|
||||
CppKeywords.insert("double",KeywordType::None);
|
||||
CppKeywords.insert("float",KeywordType::None);
|
||||
CppKeywords.insert("int",KeywordType::None);
|
||||
CppKeywords.insert("long",KeywordType::None);
|
||||
CppKeywords.insert("short",KeywordType::None);
|
||||
CppKeywords.insert("signed",KeywordType::None);
|
||||
CppKeywords.insert("unsigned",KeywordType::None);
|
||||
CppKeywords.insert("void",KeywordType::None);
|
||||
CppKeywords.insert("wchar_t",KeywordType::None);
|
||||
|
||||
// type keywords
|
||||
CppTypeKeywords.insert("auto");
|
||||
|
@ -177,33 +177,32 @@ void initParser()
|
|||
CppTypeKeywords.insert("unsigned");
|
||||
|
||||
// it's part of type info
|
||||
CppKeywords.insert("const",SkipType::skNone);
|
||||
CppKeywords.insert("extern",SkipType::skNone);
|
||||
CppKeywords.insert("inline",SkipType::skNone);
|
||||
CppKeywords.insert("const",KeywordType::None);
|
||||
CppKeywords.insert("extern",KeywordType::None);
|
||||
|
||||
// handled elsewhere
|
||||
CppKeywords.insert("class",SkipType::skNone);
|
||||
CppKeywords.insert("enum",SkipType::skNone);
|
||||
CppKeywords.insert("friend",SkipType::skNone);
|
||||
CppKeywords.insert("operator",SkipType::skNone);
|
||||
CppKeywords.insert("private",SkipType::skNone);
|
||||
CppKeywords.insert("protected",SkipType::skNone);
|
||||
CppKeywords.insert("public",SkipType::skNone);
|
||||
CppKeywords.insert("static",SkipType::skNone);
|
||||
CppKeywords.insert("struct",SkipType::skNone);
|
||||
CppKeywords.insert("typedef",SkipType::skNone);
|
||||
CppKeywords.insert("union",SkipType::skNone);
|
||||
// namespace
|
||||
CppKeywords.insert("namespace",SkipType::skNone);
|
||||
CppKeywords.insert("using",SkipType::skNone);
|
||||
|
||||
CppKeywords.insert("for",SkipType::skNone);
|
||||
CppKeywords.insert("catch",SkipType::skNone);
|
||||
CppKeywords.insert("class",KeywordType::None);
|
||||
CppKeywords.insert("operator",KeywordType::None);
|
||||
CppKeywords.insert("static",KeywordType::None);
|
||||
CppKeywords.insert("struct",KeywordType::None);
|
||||
CppKeywords.insert("union",KeywordType::None);
|
||||
|
||||
CppKeywords.insert("for",KeywordType::For);
|
||||
CppKeywords.insert("catch",KeywordType::Catch);
|
||||
CppKeywords.insert("private",KeywordType::Private);
|
||||
CppKeywords.insert("public",KeywordType::Public);
|
||||
CppKeywords.insert("enum",KeywordType::Enum);
|
||||
CppKeywords.insert("namespace",KeywordType::Namespace);
|
||||
CppKeywords.insert("inline",KeywordType::Inline);
|
||||
CppKeywords.insert("typedef",KeywordType::Typedef);
|
||||
CppKeywords.insert("using",KeywordType::Using);
|
||||
CppKeywords.insert("protected",KeywordType::Protected);
|
||||
CppKeywords.insert("friend",KeywordType::Friend);
|
||||
CppKeywords.insert("decltype",KeywordType::DeclType); // not right
|
||||
|
||||
|
||||
// nullptr is value
|
||||
CppKeywords.insert("nullptr",SkipType::skNone);
|
||||
CppKeywords.insert("nullptr",KeywordType::None);
|
||||
|
||||
//C Keywords
|
||||
CKeywords.insert("auto");
|
||||
|
@ -538,16 +537,16 @@ void CppScopes::clear()
|
|||
MemberOperatorType getOperatorType(const QString &phrase, int index)
|
||||
{
|
||||
if (index>=phrase.length())
|
||||
return MemberOperatorType::otOther;
|
||||
return MemberOperatorType::Other;
|
||||
if (phrase[index] == '.')
|
||||
return MemberOperatorType::otDot;
|
||||
return MemberOperatorType::Dot;
|
||||
if (index+1>=phrase.length())
|
||||
return MemberOperatorType::otOther;
|
||||
return MemberOperatorType::Other;
|
||||
if ((phrase[index] == '-') && (phrase[index+1] == '>'))
|
||||
return MemberOperatorType::otArrow;
|
||||
return MemberOperatorType::Arrow;
|
||||
if ((phrase[index] == ':') && (phrase[index+1] == ':'))
|
||||
return MemberOperatorType::otDColon;
|
||||
return MemberOperatorType::otOther;
|
||||
return MemberOperatorType::DColon;
|
||||
return MemberOperatorType::Other;
|
||||
}
|
||||
|
||||
bool isScopeTypeKind(StatementKind kind)
|
||||
|
@ -648,11 +647,13 @@ StatementKind getKindOfStatement(const PStatement& statement)
|
|||
if (statement->kind == StatementKind::skVariable) {
|
||||
if (!statement->parentScope.lock()) {
|
||||
return StatementKind::skGlobalVariable;
|
||||
} else if (statement->scope == StatementScope::ssLocal) {
|
||||
} else if (statement->scope == StatementScope::Local) {
|
||||
return StatementKind::skLocalVariable;
|
||||
} else {
|
||||
return StatementKind::skVariable;
|
||||
}
|
||||
} else if (statement->kind == StatementKind::skParameter) {
|
||||
return StatementKind::skLocalVariable;
|
||||
}
|
||||
return statement->kind;
|
||||
}
|
||||
|
|
|
@ -56,17 +56,30 @@ using PDefine = std::shared_ptr<Define>;
|
|||
using DefineMap = QHash<QString,PDefine>;
|
||||
using PDefineMap = std::shared_ptr<DefineMap>;
|
||||
|
||||
enum class SkipType {
|
||||
skItself, // skip itself
|
||||
skToSemicolon, // skip to ;
|
||||
skToColon, // skip to :
|
||||
skToRightParenthesis, // skip to )
|
||||
skToLeftBrace,// Skip to {
|
||||
skToRightBrace, // skip to }
|
||||
skNone // It's a keyword but don't process here
|
||||
enum class KeywordType {
|
||||
SkipItself, // skip itself
|
||||
SkipNextSemicolon, // move to ; and skip it
|
||||
SkipNextColon, // move to : and skip it
|
||||
SkipNextParenthesis, // move to ) and skip it
|
||||
MoveToLeftBrace,// move to {
|
||||
MoveToRightBrace, // move to }
|
||||
For, //for
|
||||
Catch, //catch
|
||||
Public, // public
|
||||
Private,
|
||||
Protected,
|
||||
Friend,
|
||||
Enum, //enum
|
||||
Inline, // inline
|
||||
Namespace, //namespace
|
||||
Typedef, //typedef
|
||||
Using, //using
|
||||
DeclType, // decltype
|
||||
None, // It's a keyword but don't process here
|
||||
NotKeyword
|
||||
};
|
||||
|
||||
|
||||
//It will be used as hash key. DONT make it enum class!!!!!
|
||||
enum StatementKind {
|
||||
skUnknown,
|
||||
skNamespace,
|
||||
|
@ -94,23 +107,23 @@ enum StatementKind {
|
|||
using StatementKindSet = QSet<StatementKind>;
|
||||
|
||||
enum class StatementScope {
|
||||
ssGlobal,
|
||||
ssLocal,
|
||||
ssClassLocal
|
||||
Global,
|
||||
Local,
|
||||
ClassLocal
|
||||
};
|
||||
|
||||
enum class StatementClassScope {
|
||||
scsNone,
|
||||
scsPrivate,
|
||||
scsProtected,
|
||||
scsPublic
|
||||
None,
|
||||
Private,
|
||||
Protected,
|
||||
Public
|
||||
};
|
||||
|
||||
enum class MemberOperatorType {
|
||||
otArrow,
|
||||
otDot,
|
||||
otDColon,
|
||||
otOther
|
||||
Arrow,
|
||||
Dot,
|
||||
DColon,
|
||||
Other
|
||||
};
|
||||
|
||||
enum class EvalStatementKind {
|
||||
|
@ -136,7 +149,7 @@ using StatementMap = QMultiMap<QString, PStatement>;
|
|||
struct Statement {
|
||||
// Statement();
|
||||
// ~Statement();
|
||||
std::weak_ptr<Statement> parentScope; // parent class/struct/namespace scope, don't use auto pointer to prevent circular reference
|
||||
std::weak_ptr<Statement> parentScope; // parent class/struct/namespace scope, use weak pointer to prevent circular reference
|
||||
QString type; // type "int"
|
||||
QString command; // identifier/name of statement "foo"
|
||||
QString args; // args "(int a,float b)"
|
||||
|
@ -232,7 +245,7 @@ using PFileIncludes = std::shared_ptr<FileIncludes>;
|
|||
|
||||
extern QStringList CppDirectives;
|
||||
extern QStringList JavadocTags;
|
||||
extern QMap<QString,SkipType> CppKeywords;
|
||||
extern QMap<QString,KeywordType> CppKeywords;
|
||||
extern QSet<QString> CppControlKeyWords;
|
||||
extern QSet<QString> CKeywords;
|
||||
extern QSet<QString> CppTypeKeywords;
|
||||
|
|
|
@ -99,6 +99,7 @@ void ProjectFilesWidget::copyUnits()
|
|||
unitCopy->setOverrideBuildCmd(unit->overrideBuildCmd());
|
||||
unitCopy->setBuildCmd(unit->buildCmd());
|
||||
unitCopy->setEncoding(unit->encoding());
|
||||
unitCopy->setFileName(unit->fileName());
|
||||
mUnits.append(unitCopy);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4716,6 +4716,14 @@
|
|||
<source>Ctrl+Alt+Down</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Switch header/source</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Switch Header/Source</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>NewClassDialog</name>
|
||||
|
|
|
@ -127,7 +127,7 @@ p, li { white-space: pre-wrap; }
|
|||
<message>
|
||||
<location filename="../widgets/aboutdialog.cpp" line="41"/>
|
||||
<source>Microsoft Visual C++</source>
|
||||
<translation type="unfinished">Microsoft Visual C++</translation>
|
||||
<translation>Microsoft Visual C++</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../widgets/aboutdialog.cpp" line="45"/>
|
||||
|
@ -3920,11 +3920,11 @@ Are you really want to continue?</oldsource>
|
|||
<message>
|
||||
<location filename="../mainwindow.ui" line="918"/>
|
||||
<location filename="../mainwindow.ui" line="2932"/>
|
||||
<location filename="../mainwindow.cpp" line="5119"/>
|
||||
<location filename="../mainwindow.cpp" line="5122"/>
|
||||
<location filename="../mainwindow.cpp" line="5126"/>
|
||||
<location filename="../mainwindow.cpp" line="5129"/>
|
||||
<location filename="../mainwindow.cpp" line="7126"/>
|
||||
<location filename="../mainwindow.cpp" line="5124"/>
|
||||
<location filename="../mainwindow.cpp" line="5127"/>
|
||||
<location filename="../mainwindow.cpp" line="5131"/>
|
||||
<location filename="../mainwindow.cpp" line="5134"/>
|
||||
<location filename="../mainwindow.cpp" line="7176"/>
|
||||
<source>Issues</source>
|
||||
<translation>编译器</translation>
|
||||
</message>
|
||||
|
@ -4362,7 +4362,7 @@ Are you really want to continue?</oldsource>
|
|||
<message>
|
||||
<location filename="../mainwindow.ui" line="773"/>
|
||||
<location filename="../mainwindow.ui" line="776"/>
|
||||
<location filename="../mainwindow.cpp" line="7507"/>
|
||||
<location filename="../mainwindow.cpp" line="7557"/>
|
||||
<source>New Problem Set</source>
|
||||
<translation>新建试题集</translation>
|
||||
</message>
|
||||
|
@ -4381,14 +4381,14 @@ Are you really want to continue?</oldsource>
|
|||
<message>
|
||||
<location filename="../mainwindow.ui" line="815"/>
|
||||
<location filename="../mainwindow.ui" line="818"/>
|
||||
<location filename="../mainwindow.cpp" line="7549"/>
|
||||
<location filename="../mainwindow.cpp" line="7599"/>
|
||||
<source>Save Problem Set</source>
|
||||
<translation>保存试题集</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="829"/>
|
||||
<location filename="../mainwindow.ui" line="832"/>
|
||||
<location filename="../mainwindow.cpp" line="7582"/>
|
||||
<location filename="../mainwindow.cpp" line="7632"/>
|
||||
<source>Load Problem Set</source>
|
||||
<translation>载入试题集</translation>
|
||||
</message>
|
||||
|
@ -4524,7 +4524,6 @@ Are you really want to continue?</oldsource>
|
|||
<translation>忽略空格</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="2027"/>
|
||||
<location filename="../mainwindow.ui" line="2030"/>
|
||||
<source>New Source File</source>
|
||||
<translation>新建源代码文件</translation>
|
||||
|
@ -4742,7 +4741,7 @@ Are you really want to continue?</oldsource>
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="2598"/>
|
||||
<location filename="../mainwindow.cpp" line="6029"/>
|
||||
<location filename="../mainwindow.cpp" line="6034"/>
|
||||
<source>Clear all breakpoints</source>
|
||||
<translation>删除所有断点</translation>
|
||||
</message>
|
||||
|
@ -4922,11 +4921,22 @@ Are you really want to continue?</oldsource>
|
|||
<source>Ctrl+Alt+Down</source>
|
||||
<translation>Ctrl+Alt+Down</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="3260"/>
|
||||
<source>Switch header/source</source>
|
||||
<translation>切换头文件/源文件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="3263"/>
|
||||
<source>Switch Header/Source</source>
|
||||
<translation>切换头文件/源文件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save As Template...</source>
|
||||
<translation type="vanished">保存为模板...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="2027"/>
|
||||
<location filename="../mainwindow.cpp" line="2909"/>
|
||||
<source>New File</source>
|
||||
<translation>新建文件</translation>
|
||||
|
@ -4968,7 +4978,7 @@ Are you really want to continue?</oldsource>
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="2761"/>
|
||||
<location filename="../mainwindow.cpp" line="7069"/>
|
||||
<location filename="../mainwindow.cpp" line="7119"/>
|
||||
<source>Rename Symbol</source>
|
||||
<translation>重命名符号</translation>
|
||||
</message>
|
||||
|
@ -4989,13 +4999,13 @@ Are you really want to continue?</oldsource>
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="2781"/>
|
||||
<location filename="../mainwindow.cpp" line="7279"/>
|
||||
<location filename="../mainwindow.cpp" line="7329"/>
|
||||
<source>Export As RTF</source>
|
||||
<translation>导出为RTF</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.ui" line="2786"/>
|
||||
<location filename="../mainwindow.cpp" line="7301"/>
|
||||
<location filename="../mainwindow.cpp" line="7351"/>
|
||||
<source>Export As HTML</source>
|
||||
<translation>导出为HTML</translation>
|
||||
</message>
|
||||
|
@ -5369,22 +5379,22 @@ Are you really want to continue?</oldsource>
|
|||
<message>
|
||||
<location filename="../mainwindow.cpp" line="1927"/>
|
||||
<location filename="../mainwindow.cpp" line="2101"/>
|
||||
<location filename="../mainwindow.cpp" line="5163"/>
|
||||
<location filename="../mainwindow.cpp" line="5170"/>
|
||||
<location filename="../mainwindow.cpp" line="5168"/>
|
||||
<location filename="../mainwindow.cpp" line="5175"/>
|
||||
<source>Wrong Compiler Settings</source>
|
||||
<translation>错误的编译器设置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="1928"/>
|
||||
<location filename="../mainwindow.cpp" line="2102"/>
|
||||
<location filename="../mainwindow.cpp" line="5164"/>
|
||||
<location filename="../mainwindow.cpp" line="5171"/>
|
||||
<location filename="../mainwindow.cpp" line="5169"/>
|
||||
<location filename="../mainwindow.cpp" line="5176"/>
|
||||
<source>Compiler is set not to generate executable.</source>
|
||||
<translation>编译器被设置为不生成可执行文件。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="1929"/>
|
||||
<location filename="../mainwindow.cpp" line="5165"/>
|
||||
<location filename="../mainwindow.cpp" line="5170"/>
|
||||
<source>We need the executabe to run problem case.</source>
|
||||
<translation>我们需要可执行文件来运行试题案例。</translation>
|
||||
</message>
|
||||
|
@ -5452,7 +5462,7 @@ Are you really want to continue?</oldsource>
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="2103"/>
|
||||
<location filename="../mainwindow.cpp" line="5172"/>
|
||||
<location filename="../mainwindow.cpp" line="5177"/>
|
||||
<source>Please correct this before start debugging</source>
|
||||
<translation>请在调试前改正设置。</translation>
|
||||
</message>
|
||||
|
@ -5510,22 +5520,22 @@ Are you really want to continue?</oldsource>
|
|||
<translation>全部复制</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="8583"/>
|
||||
<location filename="../mainwindow.cpp" line="8633"/>
|
||||
<source>Go to Line</source>
|
||||
<translation>跳转到行</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="8583"/>
|
||||
<location filename="../mainwindow.cpp" line="8633"/>
|
||||
<source>Line</source>
|
||||
<translation>行</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="8605"/>
|
||||
<location filename="../mainwindow.cpp" line="8655"/>
|
||||
<source>Template Exists</source>
|
||||
<translation>模板已存在</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="8606"/>
|
||||
<location filename="../mainwindow.cpp" line="8656"/>
|
||||
<source>Template %1 already exists. Do you want to overwrite?</source>
|
||||
<translation>模板%1已存在。是否覆盖?</translation>
|
||||
</message>
|
||||
|
@ -5551,7 +5561,7 @@ Are you really want to continue?</oldsource>
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="318"/>
|
||||
<location filename="../mainwindow.cpp" line="7516"/>
|
||||
<location filename="../mainwindow.cpp" line="7566"/>
|
||||
<source>Problem Set %1</source>
|
||||
<translation>试题集%1</translation>
|
||||
</message>
|
||||
|
@ -5625,15 +5635,15 @@ Are you really want to continue?</oldsource>
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="4041"/>
|
||||
<location filename="../mainwindow.cpp" line="7365"/>
|
||||
<location filename="../mainwindow.cpp" line="7407"/>
|
||||
<location filename="../mainwindow.cpp" line="7415"/>
|
||||
<location filename="../mainwindow.cpp" line="7457"/>
|
||||
<source>Bookmark Description</source>
|
||||
<translation>书签描述</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="4042"/>
|
||||
<location filename="../mainwindow.cpp" line="7366"/>
|
||||
<location filename="../mainwindow.cpp" line="7408"/>
|
||||
<location filename="../mainwindow.cpp" line="7416"/>
|
||||
<location filename="../mainwindow.cpp" line="7458"/>
|
||||
<source>Description:</source>
|
||||
<translation>描述:</translation>
|
||||
</message>
|
||||
|
@ -5779,7 +5789,7 @@ Are you really want to continue?</oldsource>
|
|||
<location filename="../mainwindow.cpp" line="2921"/>
|
||||
<location filename="../mainwindow.cpp" line="3937"/>
|
||||
<location filename="../mainwindow.cpp" line="3943"/>
|
||||
<location filename="../mainwindow.cpp" line="6754"/>
|
||||
<location filename="../mainwindow.cpp" line="6759"/>
|
||||
<source>Delete</source>
|
||||
<translation>删除</translation>
|
||||
</message>
|
||||
|
@ -5862,57 +5872,57 @@ Are you really want to continue?</oldsource>
|
|||
<translation>你真的要删除%1个文件吗?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="4613"/>
|
||||
<location filename="../mainwindow.cpp" line="4618"/>
|
||||
<source>Save project</source>
|
||||
<translation>保存项目</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="4614"/>
|
||||
<location filename="../mainwindow.cpp" line="4619"/>
|
||||
<source>The project '%1' has modifications.</source>
|
||||
<translation>项目'%1'有改动。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="4616"/>
|
||||
<location filename="../mainwindow.cpp" line="7510"/>
|
||||
<location filename="../mainwindow.cpp" line="4621"/>
|
||||
<location filename="../mainwindow.cpp" line="7560"/>
|
||||
<source>Do you want to save it?</source>
|
||||
<translation>需要保存吗?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="4716"/>
|
||||
<location filename="../mainwindow.cpp" line="4730"/>
|
||||
<location filename="../mainwindow.cpp" line="4721"/>
|
||||
<location filename="../mainwindow.cpp" line="4735"/>
|
||||
<source>File Changed</source>
|
||||
<translation>文件已发生变化</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="4801"/>
|
||||
<location filename="../mainwindow.cpp" line="4806"/>
|
||||
<source>New Project File?</source>
|
||||
<translation>新建项目文件?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="4802"/>
|
||||
<location filename="../mainwindow.cpp" line="4807"/>
|
||||
<source>Do you want to add the new file to the project?</source>
|
||||
<translation>您是否要将新建的文件加入项目?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="4886"/>
|
||||
<location filename="../mainwindow.cpp" line="4896"/>
|
||||
<location filename="../mainwindow.cpp" line="7571"/>
|
||||
<location filename="../mainwindow.cpp" line="4891"/>
|
||||
<location filename="../mainwindow.cpp" line="4901"/>
|
||||
<location filename="../mainwindow.cpp" line="7621"/>
|
||||
<source>Save Error</source>
|
||||
<translation>保存失败</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="5038"/>
|
||||
<location filename="../mainwindow.cpp" line="5043"/>
|
||||
<source>Change Project Compiler Set</source>
|
||||
<translation>改变项目编译器配置集</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="5039"/>
|
||||
<location filename="../mainwindow.cpp" line="5044"/>
|
||||
<source>Change the project's compiler set will lose all custom compiler set options.</source>
|
||||
<translation>改变项目的编译器配置集会导致所有的自定义编译器选项被重置。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="3673"/>
|
||||
<location filename="../mainwindow.cpp" line="5041"/>
|
||||
<location filename="../mainwindow.cpp" line="5046"/>
|
||||
<source>Do you really want to do that?</source>
|
||||
<translation>你真的想要那么做吗?</translation>
|
||||
</message>
|
||||
|
@ -5935,104 +5945,104 @@ Are you really want to continue?</oldsource>
|
|||
<translation type="vanished">无标题%1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="5897"/>
|
||||
<location filename="../mainwindow.cpp" line="5902"/>
|
||||
<source>Modify Watch</source>
|
||||
<translation>修改监视表达式</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="5898"/>
|
||||
<location filename="../mainwindow.cpp" line="5903"/>
|
||||
<source>Watch Expression</source>
|
||||
<translation>监视表达式</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6030"/>
|
||||
<location filename="../mainwindow.cpp" line="6035"/>
|
||||
<source>Do you really want to clear all breakpoints in this file?</source>
|
||||
<translation>您真的要清除该文件的所有断点吗?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6228"/>
|
||||
<location filename="../mainwindow.cpp" line="6233"/>
|
||||
<source>New project</source>
|
||||
<translation>新建项目</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6229"/>
|
||||
<location filename="../mainwindow.cpp" line="6234"/>
|
||||
<source>Close %1 and start new project?</source>
|
||||
<translation>关闭'%1'以打开新项目?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6242"/>
|
||||
<location filename="../mainwindow.cpp" line="6247"/>
|
||||
<source>Folder not exist</source>
|
||||
<translation>文件夹不存在</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6243"/>
|
||||
<location filename="../mainwindow.cpp" line="6248"/>
|
||||
<source>Folder '%1' doesn't exist. Create it now?</source>
|
||||
<translation>文件夹'%1'不存在。是否创建?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6250"/>
|
||||
<location filename="../mainwindow.cpp" line="6255"/>
|
||||
<source>Can't create folder</source>
|
||||
<translation>无法创建文件夹</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6251"/>
|
||||
<location filename="../mainwindow.cpp" line="6256"/>
|
||||
<source>Failed to create folder '%1'.</source>
|
||||
<translation>创建文件夹'%1'失败。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6266"/>
|
||||
<location filename="../mainwindow.cpp" line="6271"/>
|
||||
<source>Save new project as</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6755"/>
|
||||
<location filename="../mainwindow.cpp" line="6760"/>
|
||||
<source>Folder %1 is not empty.</source>
|
||||
<translation>文件夹%1不是空的。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6756"/>
|
||||
<location filename="../mainwindow.cpp" line="6761"/>
|
||||
<source>Do you really want to delete it?</source>
|
||||
<translation>你真的要删除它吗?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7430"/>
|
||||
<location filename="../mainwindow.cpp" line="7480"/>
|
||||
<source>Change working folder</source>
|
||||
<translation>改变工作文件夹</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7431"/>
|
||||
<location filename="../mainwindow.cpp" line="7481"/>
|
||||
<source>File '%1' is not in the current working folder.</source>
|
||||
<oldsource>File '%1' is not in the current working folder</oldsource>
|
||||
<translation>文件'%1'不在当前工作文件夹中。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7434"/>
|
||||
<location filename="../mainwindow.cpp" line="7484"/>
|
||||
<source>Do you want to change working folder to '%1'?</source>
|
||||
<translation>是否将工作文件夹改设为'%1'?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="8105"/>
|
||||
<location filename="../mainwindow.cpp" line="8155"/>
|
||||
<source>Can't Commit</source>
|
||||
<translation>无法提交</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="8106"/>
|
||||
<location filename="../mainwindow.cpp" line="8156"/>
|
||||
<source>Git needs user info to commit.</source>
|
||||
<translation>Git需要用信息进行提交。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="8374"/>
|
||||
<location filename="../mainwindow.cpp" line="8424"/>
|
||||
<source>Choose Input Data File</source>
|
||||
<translation>选择输入数据文件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="8376"/>
|
||||
<location filename="../mainwindow.cpp" line="8431"/>
|
||||
<location filename="../mainwindow.cpp" line="8426"/>
|
||||
<location filename="../mainwindow.cpp" line="8481"/>
|
||||
<source>All files (*.*)</source>
|
||||
<translation>所有文件 (*.*)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="8429"/>
|
||||
<location filename="../mainwindow.cpp" line="8479"/>
|
||||
<source>Choose Expected Output Data File</source>
|
||||
<oldsource>Choose Expected Input Data File</oldsource>
|
||||
<translation>选择期望输出文件</translation>
|
||||
|
@ -6044,59 +6054,59 @@ Are you really want to continue?</oldsource>
|
|||
<message>
|
||||
<location filename="../mainwindow.ui" line="2851"/>
|
||||
<location filename="../mainwindow.ui" line="2854"/>
|
||||
<location filename="../mainwindow.cpp" line="7486"/>
|
||||
<location filename="../mainwindow.cpp" line="7536"/>
|
||||
<source>Choose Working Folder</source>
|
||||
<translation>选择工作文件夹</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7880"/>
|
||||
<location filename="../mainwindow.cpp" line="7929"/>
|
||||
<location filename="../mainwindow.cpp" line="7930"/>
|
||||
<location filename="../mainwindow.cpp" line="7979"/>
|
||||
<source>Header Exists</source>
|
||||
<translation>头文件已存在</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7881"/>
|
||||
<location filename="../mainwindow.cpp" line="7930"/>
|
||||
<location filename="../mainwindow.cpp" line="7931"/>
|
||||
<location filename="../mainwindow.cpp" line="7980"/>
|
||||
<source>Header file "%1" already exists!</source>
|
||||
<translation>头文件"%1"已存在!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7935"/>
|
||||
<location filename="../mainwindow.cpp" line="7985"/>
|
||||
<source>Source Exists</source>
|
||||
<translation>源文件已存在!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7936"/>
|
||||
<location filename="../mainwindow.cpp" line="7986"/>
|
||||
<source>Source file "%1" already exists!</source>
|
||||
<translation>源文件"%1"已存在!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="8084"/>
|
||||
<location filename="../mainwindow.cpp" line="8134"/>
|
||||
<source>Can't commit!</source>
|
||||
<translation>无法提交!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="8085"/>
|
||||
<location filename="../mainwindow.cpp" line="8135"/>
|
||||
<source>The following files are in conflicting:</source>
|
||||
<translation>下列文件处于冲突状态,请解决后重新添加和提交:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="8090"/>
|
||||
<location filename="../mainwindow.cpp" line="8140"/>
|
||||
<source>Commit Message</source>
|
||||
<translation>提交信息</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="8090"/>
|
||||
<location filename="../mainwindow.cpp" line="8140"/>
|
||||
<source>Commit Message:</source>
|
||||
<translation>提交信息:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="8093"/>
|
||||
<location filename="../mainwindow.cpp" line="8143"/>
|
||||
<source>Commit Failed</source>
|
||||
<translation>提交失败</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="8094"/>
|
||||
<location filename="../mainwindow.cpp" line="8144"/>
|
||||
<source>Commit message shouldn't be empty!</source>
|
||||
<translation>提交信息不能为空!</translation>
|
||||
</message>
|
||||
|
@ -6105,22 +6115,22 @@ Are you really want to continue?</oldsource>
|
|||
<translation type="vanished">小熊猫Dev-C++项目文件 (*.dev)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6280"/>
|
||||
<location filename="../mainwindow.cpp" line="6285"/>
|
||||
<source>New project fail</source>
|
||||
<translation>新建项目失败</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6281"/>
|
||||
<location filename="../mainwindow.cpp" line="6286"/>
|
||||
<source>Can't assign project template</source>
|
||||
<translation>无法使用模板创建项目</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6380"/>
|
||||
<location filename="../mainwindow.cpp" line="6385"/>
|
||||
<source>Remove file</source>
|
||||
<translation>删除文件</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6381"/>
|
||||
<location filename="../mainwindow.cpp" line="6386"/>
|
||||
<source>Remove the file from disk?</source>
|
||||
<translation>同时从硬盘上删除文件?</translation>
|
||||
</message>
|
||||
|
@ -6129,27 +6139,27 @@ Are you really want to continue?</oldsource>
|
|||
<translation type="vanished">无标题</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6680"/>
|
||||
<location filename="../mainwindow.cpp" line="6685"/>
|
||||
<source>New Project File Name</source>
|
||||
<translation>新的项目文件名</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6681"/>
|
||||
<location filename="../mainwindow.cpp" line="6686"/>
|
||||
<source>File Name:</source>
|
||||
<translation>文件名:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6689"/>
|
||||
<location filename="../mainwindow.cpp" line="6694"/>
|
||||
<source>File Already Exists!</source>
|
||||
<translation>文件已存在!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6690"/>
|
||||
<location filename="../mainwindow.cpp" line="6695"/>
|
||||
<source>File '%1' already exists!</source>
|
||||
<translation>文件'%1'已经存在!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6334"/>
|
||||
<location filename="../mainwindow.cpp" line="6339"/>
|
||||
<source>Add to project</source>
|
||||
<translation>添加到项目</translation>
|
||||
</message>
|
||||
|
@ -6164,75 +6174,75 @@ Are you really want to continue?</oldsource>
|
|||
<translation>本操作会删除此试题的所有案例。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="6268"/>
|
||||
<location filename="../mainwindow.cpp" line="6273"/>
|
||||
<source>Red Panda C++ project file (*.dev)</source>
|
||||
<translation>小熊猫C++项目文件(*.dev)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7042"/>
|
||||
<location filename="../mainwindow.cpp" line="7092"/>
|
||||
<source>Rename Error</source>
|
||||
<translation>重命名出错</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7043"/>
|
||||
<location filename="../mainwindow.cpp" line="7093"/>
|
||||
<source>Symbol '%1' is defined in system header.</source>
|
||||
<translation>符号'%1'在系统头文件中定义,无法修改。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7070"/>
|
||||
<location filename="../mainwindow.cpp" line="7120"/>
|
||||
<source>New Name</source>
|
||||
<translation>新名称</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7217"/>
|
||||
<location filename="../mainwindow.cpp" line="7229"/>
|
||||
<location filename="../mainwindow.cpp" line="7267"/>
|
||||
<location filename="../mainwindow.cpp" line="7279"/>
|
||||
<source>Replace Error</source>
|
||||
<translation>替换出错</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7218"/>
|
||||
<location filename="../mainwindow.cpp" line="7268"/>
|
||||
<source>Can't open file '%1' for replace!</source>
|
||||
<translation>无法打开文件'%1'进行替换!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7230"/>
|
||||
<location filename="../mainwindow.cpp" line="7280"/>
|
||||
<source>Contents has changed since last search!</source>
|
||||
<translation>内容和上次查找时不一致。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7281"/>
|
||||
<location filename="../mainwindow.cpp" line="7331"/>
|
||||
<source>Rich Text Format Files (*.rtf)</source>
|
||||
<translation>RTF格式文件 (*.rtf)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7303"/>
|
||||
<location filename="../mainwindow.cpp" line="7353"/>
|
||||
<source>HTML Files (*.html)</source>
|
||||
<translation>HTML文件 (*.html)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7508"/>
|
||||
<location filename="../mainwindow.cpp" line="7558"/>
|
||||
<source>The current problem set is not empty.</source>
|
||||
<translation>当前的试题集不是空的。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7526"/>
|
||||
<location filename="../mainwindow.cpp" line="7576"/>
|
||||
<source>Problem %1</source>
|
||||
<translation>试题%1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7556"/>
|
||||
<location filename="../mainwindow.cpp" line="7584"/>
|
||||
<location filename="../mainwindow.cpp" line="7606"/>
|
||||
<location filename="../mainwindow.cpp" line="7634"/>
|
||||
<source>Problem Set Files (*.pbs)</source>
|
||||
<translation>试题集文件 (*.pbs)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7590"/>
|
||||
<location filename="../mainwindow.cpp" line="7640"/>
|
||||
<source>Load Error</source>
|
||||
<translation>载入失败</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="3755"/>
|
||||
<location filename="../mainwindow.cpp" line="7604"/>
|
||||
<location filename="../mainwindow.cpp" line="7654"/>
|
||||
<source>Problem Case %1</source>
|
||||
<translation>试题案例%1</translation>
|
||||
</message>
|
||||
|
@ -6245,13 +6255,13 @@ Are you really want to continue?</oldsource>
|
|||
<location filename="../mainwindow.cpp" line="1359"/>
|
||||
<location filename="../mainwindow.cpp" line="2576"/>
|
||||
<location filename="../mainwindow.cpp" line="3025"/>
|
||||
<location filename="../mainwindow.cpp" line="4723"/>
|
||||
<location filename="../mainwindow.cpp" line="4841"/>
|
||||
<location filename="../mainwindow.cpp" line="5005"/>
|
||||
<location filename="../mainwindow.cpp" line="5017"/>
|
||||
<location filename="../mainwindow.cpp" line="5459"/>
|
||||
<location filename="../mainwindow.cpp" line="5471"/>
|
||||
<location filename="../mainwindow.cpp" line="8514"/>
|
||||
<location filename="../mainwindow.cpp" line="4728"/>
|
||||
<location filename="../mainwindow.cpp" line="4846"/>
|
||||
<location filename="../mainwindow.cpp" line="5010"/>
|
||||
<location filename="../mainwindow.cpp" line="5022"/>
|
||||
<location filename="../mainwindow.cpp" line="5464"/>
|
||||
<location filename="../mainwindow.cpp" line="5476"/>
|
||||
<location filename="../mainwindow.cpp" line="8564"/>
|
||||
<source>Error</source>
|
||||
<translation>错误</translation>
|
||||
</message>
|
||||
|
@ -6278,79 +6288,79 @@ Are you really want to continue?</oldsource>
|
|||
<translation>版本控制</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="4717"/>
|
||||
<location filename="../mainwindow.cpp" line="4722"/>
|
||||
<source>File '%1' was changed.</source>
|
||||
<translation>磁盘文件'%1'已被修改。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="4717"/>
|
||||
<location filename="../mainwindow.cpp" line="4722"/>
|
||||
<source>Reload its content from disk?</source>
|
||||
<translation>是否重新读取它的内容?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="4731"/>
|
||||
<location filename="../mainwindow.cpp" line="4736"/>
|
||||
<source>File '%1' was removed.</source>
|
||||
<translation>磁盘文件'%1'已被删除。</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="4731"/>
|
||||
<location filename="../mainwindow.cpp" line="4736"/>
|
||||
<source>Keep it open?</source>
|
||||
<translation>是否保持它在小熊猫C++中打开的编辑窗口?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="4834"/>
|
||||
<location filename="../mainwindow.cpp" line="4839"/>
|
||||
<source>Open</source>
|
||||
<translation>打开</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="5230"/>
|
||||
<location filename="../mainwindow.cpp" line="5235"/>
|
||||
<source>Compile Failed</source>
|
||||
<translation>编译失败</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="5236"/>
|
||||
<location filename="../mainwindow.cpp" line="5241"/>
|
||||
<source>Run Failed</source>
|
||||
<translation>运行失败</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="3056"/>
|
||||
<location filename="../mainwindow.cpp" line="5488"/>
|
||||
<location filename="../mainwindow.cpp" line="5502"/>
|
||||
<location filename="../mainwindow.cpp" line="8497"/>
|
||||
<location filename="../mainwindow.cpp" line="5493"/>
|
||||
<location filename="../mainwindow.cpp" line="5507"/>
|
||||
<location filename="../mainwindow.cpp" line="8547"/>
|
||||
<source>Confirm Convertion</source>
|
||||
<translation>确认转换</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="3057"/>
|
||||
<location filename="../mainwindow.cpp" line="5489"/>
|
||||
<location filename="../mainwindow.cpp" line="5503"/>
|
||||
<location filename="../mainwindow.cpp" line="8498"/>
|
||||
<location filename="../mainwindow.cpp" line="5494"/>
|
||||
<location filename="../mainwindow.cpp" line="5508"/>
|
||||
<location filename="../mainwindow.cpp" line="8548"/>
|
||||
<source>The editing file will be saved using %1 encoding. <br />This operation can't be reverted. <br />Are you sure to continue?</source>
|
||||
<translation>当前编辑器中的文件将会使用%1编码保存。<br />这项操作无法被撤回。<br />你确定要继续吗?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="5647"/>
|
||||
<location filename="../mainwindow.cpp" line="5652"/>
|
||||
<source>New Watch Expression</source>
|
||||
<translation>新监视表达式</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="5648"/>
|
||||
<location filename="../mainwindow.cpp" line="5653"/>
|
||||
<source>Enter Watch Expression (it is recommended to use 'this->' for class members):</source>
|
||||
<translation>输入监视表达式</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="5705"/>
|
||||
<location filename="../mainwindow.cpp" line="5710"/>
|
||||
<source>Parsing file %1 of %2: "%3"</source>
|
||||
<translation>(%1/%2)正在解析文件"%3"</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="5727"/>
|
||||
<location filename="../mainwindow.cpp" line="5733"/>
|
||||
<location filename="../mainwindow.cpp" line="5732"/>
|
||||
<location filename="../mainwindow.cpp" line="5738"/>
|
||||
<source>Done parsing %1 files in %2 seconds</source>
|
||||
<translation>完成%1个文件的解析,用时%2秒</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="5730"/>
|
||||
<location filename="../mainwindow.cpp" line="5735"/>
|
||||
<source>(%1 files per second)</source>
|
||||
<translation>(每秒%1个文件)</translation>
|
||||
</message>
|
||||
|
@ -8677,14 +8687,14 @@ Are you really want to continue?</oldsource>
|
|||
<translation>性能</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="8522"/>
|
||||
<location filename="../mainwindow.cpp" line="8572"/>
|
||||
<location filename="../settingsdialog/settingsdialog.cpp" line="166"/>
|
||||
<location filename="../settingsdialog/settingsdialog.cpp" line="246"/>
|
||||
<source>Compiler Set</source>
|
||||
<translation>编译器配置集</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="8523"/>
|
||||
<location filename="../mainwindow.cpp" line="8573"/>
|
||||
<location filename="../settingsdialog/settingsdialog.cpp" line="166"/>
|
||||
<location filename="../settingsdialog/settingsdialog.cpp" line="169"/>
|
||||
<source>Compiler</source>
|
||||
|
@ -8696,7 +8706,7 @@ Are you really want to continue?</oldsource>
|
|||
<translation>自动链接</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7497"/>
|
||||
<location filename="../mainwindow.cpp" line="7547"/>
|
||||
<location filename="../settingsdialog/settingsdialog.cpp" line="172"/>
|
||||
<location filename="../settingsdialog/settingsdialog.cpp" line="205"/>
|
||||
<location filename="../settingsdialog/settingsdialog.cpp" line="211"/>
|
||||
|
@ -8772,15 +8782,15 @@ Are you really want to continue?</oldsource>
|
|||
<translation>杂项</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7498"/>
|
||||
<location filename="../mainwindow.cpp" line="7827"/>
|
||||
<location filename="../mainwindow.cpp" line="7548"/>
|
||||
<location filename="../mainwindow.cpp" line="7877"/>
|
||||
<location filename="../settingsdialog/settingsdialog.cpp" line="205"/>
|
||||
<location filename="../settingsdialog/settingsdialog.cpp" line="208"/>
|
||||
<source>Program Runner</source>
|
||||
<translation>程序运行</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="7826"/>
|
||||
<location filename="../mainwindow.cpp" line="7876"/>
|
||||
<location filename="../settingsdialog/settingsdialog.cpp" line="208"/>
|
||||
<source>Problem Set</source>
|
||||
<translation>试题集</translation>
|
||||
|
|
|
@ -4557,6 +4557,14 @@
|
|||
<source>Ctrl+Alt+Down</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Switch header/source</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Switch Header/Source</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>NewClassDialog</name>
|
||||
|
|
|
@ -431,13 +431,13 @@ void BookmarkModel::sort(int column, Qt::SortOrder order)
|
|||
case 0:
|
||||
if (order == Qt::SortOrder::AscendingOrder) {
|
||||
auto sorter=[](PBookmark b1,PBookmark b2) {
|
||||
return QString::compare(b1->description,b2->description);
|
||||
return b1->description < b2->description;
|
||||
};
|
||||
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
|
||||
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
|
||||
} else {
|
||||
auto sorter=[](PBookmark b1,PBookmark b2) {
|
||||
return QString::compare(b2->description,b1->description);
|
||||
return b2->description<b1->description;
|
||||
};
|
||||
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
|
||||
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
|
||||
|
@ -446,13 +446,13 @@ void BookmarkModel::sort(int column, Qt::SortOrder order)
|
|||
case 1:
|
||||
if (order == Qt::SortOrder::AscendingOrder) {
|
||||
auto sorter=[](PBookmark b1,PBookmark b2) {
|
||||
return QString::compare(b1->filename,b2->filename);
|
||||
return b1->filename<b2->filename;
|
||||
};
|
||||
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
|
||||
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
|
||||
} else {
|
||||
auto sorter=[](PBookmark b1,PBookmark b2) {
|
||||
return QString::compare(b2->filename,b1->filename);
|
||||
return b2->filename<b1->filename;
|
||||
};
|
||||
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
|
||||
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
|
||||
|
@ -461,13 +461,13 @@ void BookmarkModel::sort(int column, Qt::SortOrder order)
|
|||
case 2:
|
||||
if (order == Qt::SortOrder::AscendingOrder) {
|
||||
auto sorter=[](PBookmark b1,PBookmark b2) {
|
||||
return b1->line-b2->line;
|
||||
return b1->line<b2->line;
|
||||
};
|
||||
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
|
||||
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
|
||||
} else {
|
||||
auto sorter=[](PBookmark b1,PBookmark b2) {
|
||||
return b2->line-b1->line;
|
||||
return b2->line<b1->line;
|
||||
};
|
||||
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
|
||||
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
|
||||
|
|
|
@ -338,7 +338,7 @@ void ClassBrowserModel::filterChildren(ClassBrowserNode *node, const StatementMa
|
|||
if (statement == node->statement) // prevent infinite recursion
|
||||
continue;
|
||||
|
||||
if (statement->scope == StatementScope::ssLocal)
|
||||
if (statement->scope == StatementScope::Local)
|
||||
continue;
|
||||
|
||||
if (pSettings->codeCompletion().hideSymbolsStartsWithTwoUnderLine()
|
||||
|
|
|
@ -278,11 +278,11 @@ static bool sortByScopeComparator(PStatement statement1,PStatement statement2){
|
|||
if (statement1->inSystemHeader != statement2->inSystemHeader)
|
||||
return !(statement1->inSystemHeader);
|
||||
// Show local statements first
|
||||
if (statement1->scope != StatementScope::ssGlobal
|
||||
&& statement2->scope == StatementScope::ssGlobal ) {
|
||||
if (statement1->scope != StatementScope::Global
|
||||
&& statement2->scope == StatementScope::Global ) {
|
||||
return true;
|
||||
} else if (statement1->scope == StatementScope::ssGlobal
|
||||
&& statement2->scope != StatementScope::ssGlobal ) {
|
||||
} else if (statement1->scope == StatementScope::Global
|
||||
&& statement2->scope != StatementScope::Global ) {
|
||||
return false;
|
||||
} else
|
||||
return nameComparator(statement1,statement2);
|
||||
|
@ -359,11 +359,11 @@ static bool sortByScopeWithUsageComparator(PStatement statement1,PStatement stat
|
|||
if (statement1->inSystemHeader != statement2->inSystemHeader)
|
||||
return !(statement1->inSystemHeader);
|
||||
// Show local statements first
|
||||
if (statement1->scope != StatementScope::ssGlobal
|
||||
&& statement2->scope == StatementScope::ssGlobal ) {
|
||||
if (statement1->scope != StatementScope::Global
|
||||
&& statement2->scope == StatementScope::Global ) {
|
||||
return true;
|
||||
} else if (statement1->scope == StatementScope::ssGlobal
|
||||
&& statement2->scope != StatementScope::ssGlobal ) {
|
||||
} else if (statement1->scope == StatementScope::Global
|
||||
&& statement2->scope != StatementScope::Global ) {
|
||||
return false;
|
||||
} else
|
||||
return nameComparator(statement1,statement2);
|
||||
|
@ -712,7 +712,7 @@ void CodeCompletionPopup::getCompletionFor(
|
|||
if (children.isEmpty())
|
||||
return;
|
||||
foreach (const PStatement& childStatement, children) {
|
||||
if ((childStatement->classScope==StatementClassScope::scsPublic)
|
||||
if ((childStatement->classScope==StatementClassScope::Public)
|
||||
&& !(
|
||||
childStatement->kind == StatementKind::skConstructor
|
||||
|| childStatement->kind == StatementKind::skDestructor)
|
||||
|
@ -769,7 +769,7 @@ void CodeCompletionPopup::getCompletionFor(
|
|||
|| childStatement->kind == StatementKind::skEnumClassType
|
||||
|| childStatement->kind == StatementKind::skEnumType
|
||||
)) {
|
||||
if (childStatement->classScope == StatementClassScope::scsPublic)
|
||||
if (childStatement->classScope == StatementClassScope::Public)
|
||||
addStatement(childStatement,fileName,-1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,10 +19,12 @@
|
|||
#include "../iconsmanager.h"
|
||||
#include "../settings.h"
|
||||
#include <QFileDialog>
|
||||
#include <algorithm>
|
||||
|
||||
NewClassDialog::NewClassDialog(QWidget *parent) :
|
||||
NewClassDialog::NewClassDialog(PCppParser parser, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::NewClassDialog)
|
||||
ui(new Ui::NewClassDialog),
|
||||
mModel(parser)
|
||||
{
|
||||
setWindowFlag(Qt::WindowContextHelpButtonHint,false);
|
||||
ui->setupUi(this);
|
||||
|
@ -31,6 +33,7 @@ NewClassDialog::NewClassDialog(QWidget *parent) :
|
|||
connect(pIconsManager,&IconsManager::actionIconsUpdated,
|
||||
this, &NewClassDialog::onUpdateIcons);
|
||||
ui->txtClassName->setFocus();
|
||||
ui->cbBaseClass->setModel(&mModel);
|
||||
}
|
||||
|
||||
NewClassDialog::~NewClassDialog()
|
||||
|
@ -42,9 +45,9 @@ QString NewClassDialog::className() const
|
|||
return ui->txtClassName->text();
|
||||
}
|
||||
|
||||
QString NewClassDialog::baseClass() const
|
||||
PStatement NewClassDialog::baseClass() const
|
||||
{
|
||||
return ui->cbBaseClass->currentText();
|
||||
return mModel.getCandidate(ui->cbBaseClass->currentIndex());
|
||||
}
|
||||
|
||||
QString NewClassDialog::headerName() const
|
||||
|
@ -105,3 +108,86 @@ void NewClassDialog::on_txtClassName_textChanged(const QString &/* arg1 */)
|
|||
ui->txtSourceName->setText(ui->txtClassName->text().toLower()+".cpp");
|
||||
}
|
||||
|
||||
NewClassCandidatesModel::NewClassCandidatesModel(PCppParser parser):QAbstractListModel(),
|
||||
mParser(parser)
|
||||
{
|
||||
fillClasses();
|
||||
}
|
||||
|
||||
PStatement NewClassCandidatesModel::getCandidate(int row) const
|
||||
{
|
||||
if (row<0)
|
||||
return PStatement();
|
||||
if (row==0)
|
||||
return PStatement();
|
||||
return mCandidates[row-1];
|
||||
}
|
||||
|
||||
|
||||
void NewClassCandidatesModel::fillClasses()
|
||||
{
|
||||
if (!mParser->enabled())
|
||||
return;
|
||||
if (!mParser->freeze())
|
||||
return;
|
||||
foreach( const PStatement& s, mParser->statementList().childrenStatements()) {
|
||||
if (s->kind==StatementKind::skClass
|
||||
&& s->inProject
|
||||
&& !s->command.startsWith("_")
|
||||
&& !s->command.contains("<")
|
||||
&& !mClassNames.contains(s->fullName)) {
|
||||
if (getFileType(s->fileName)==FileType::CHeader
|
||||
|| getFileType(s->fileName)==FileType::CppHeader) {
|
||||
mCandidates.append(s);
|
||||
mClassNames.insert(s->fullName);
|
||||
}
|
||||
} else if (s->kind == StatementKind::skNamespace
|
||||
&& !s->command.startsWith("_")
|
||||
&& !s->command.contains("<")) {
|
||||
fillClassesInNamespace(s);
|
||||
}
|
||||
}
|
||||
mParser->unFreeze();
|
||||
std::sort(mCandidates.begin(),mCandidates.end(),[](const PStatement& s1, const PStatement& s2){
|
||||
return s1->fullName<s2->fullName;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void NewClassCandidatesModel::fillClassesInNamespace(PStatement ns)
|
||||
{
|
||||
foreach( const PStatement& s, mParser->statementList().childrenStatements(ns)) {
|
||||
if (s->kind==StatementKind::skClass
|
||||
&& s->inProject
|
||||
&& !s->command.startsWith("_")
|
||||
&& !s->command.contains("<")
|
||||
&& !mClassNames.contains(s->fullName)) {
|
||||
if (getFileType(s->fileName)==FileType::CHeader
|
||||
|| getFileType(s->fileName)==FileType::CppHeader) {
|
||||
mCandidates.append(s);
|
||||
mClassNames.insert(s->fullName);
|
||||
}
|
||||
} else if (s->kind == StatementKind::skNamespace
|
||||
&& !s->command.startsWith("_")
|
||||
&& !s->command.contains("<")) {
|
||||
fillClassesInNamespace(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int NewClassCandidatesModel::rowCount(const QModelIndex &/*parent*/) const
|
||||
{
|
||||
return mCandidates.count()+1;
|
||||
}
|
||||
|
||||
QVariant NewClassCandidatesModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
if (role==Qt::DisplayRole) {
|
||||
if (index.row()==0)
|
||||
return "";
|
||||
return mCandidates[index.row()-1]->fullName;
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
|
|
@ -18,21 +18,42 @@
|
|||
#define NEWCLASSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "../parser/cppparser.h"
|
||||
#include <QAbstractListModel>
|
||||
|
||||
namespace Ui {
|
||||
class NewClassDialog;
|
||||
}
|
||||
|
||||
class NewClassCandidatesModel: public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit NewClassCandidatesModel(PCppParser parser);
|
||||
PStatement getCandidate(int row) const;
|
||||
private:
|
||||
void fillClasses();
|
||||
void fillClassesInNamespace(PStatement ns);
|
||||
private:
|
||||
PCppParser mParser;
|
||||
QVector<PStatement> mCandidates;
|
||||
QSet<QString> mClassNames;
|
||||
|
||||
// QAbstractItemModel interface
|
||||
public:
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
};
|
||||
|
||||
class NewClassDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit NewClassDialog(QWidget *parent = nullptr);
|
||||
explicit NewClassDialog(PCppParser parser, QWidget *parent = nullptr);
|
||||
~NewClassDialog();
|
||||
|
||||
QString className() const;
|
||||
QString baseClass() const;
|
||||
PStatement baseClass() const;
|
||||
QString headerName() const;
|
||||
QString sourceName() const;
|
||||
QString path() const;
|
||||
|
@ -49,7 +70,8 @@ private slots:
|
|||
|
||||
private:
|
||||
Ui::NewClassDialog *ui;
|
||||
|
||||
QList<PStatement> mClasses;
|
||||
NewClassCandidatesModel mModel;
|
||||
private:
|
||||
void onUpdateIcons();
|
||||
|
||||
|
|
|
@ -48,7 +48,11 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" colspan="2">
|
||||
<widget class="QComboBox" name="cbBaseClass"/>
|
||||
<widget class="QComboBox" name="cbBaseClass">
|
||||
<property name="editable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="4">
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
|
|
|
@ -33,7 +33,7 @@ RedPandaIDE.depends += redpanda-git-askpass
|
|||
|
||||
APP_NAME = RedPandaCPP
|
||||
|
||||
APP_VERSION = 2.1
|
||||
APP_VERSION = 2.2
|
||||
|
||||
linux: {
|
||||
isEmpty(PREFIX) {
|
||||
|
|
|
@ -6599,16 +6599,16 @@ bool SynEdit::modified() const
|
|||
return mModified;
|
||||
}
|
||||
|
||||
void SynEdit::setModified(bool Value)
|
||||
void SynEdit::setModified(bool value)
|
||||
{
|
||||
if (Value) {
|
||||
if (value) {
|
||||
mLastModifyTime = QDateTime::currentDateTime();
|
||||
emit statusChanged(StatusChange::scModified);
|
||||
}
|
||||
if (Value != mModified) {
|
||||
mModified = Value;
|
||||
if (value != mModified) {
|
||||
mModified = value;
|
||||
|
||||
if (Value) {
|
||||
if (value) {
|
||||
mUndoList->clear();
|
||||
mRedoList->clear();
|
||||
} else {
|
||||
|
@ -6649,6 +6649,7 @@ void SynEdit::setUndoLimit(int size)
|
|||
void SynEdit::setUndoMemoryUsage(int size)
|
||||
{
|
||||
mUndoList->setMaxMemoryUsage(size*1024*1024);
|
||||
// mUndoList->setMaxMemoryUsage(size*1024);
|
||||
}
|
||||
|
||||
int SynEdit::charsInWindow() const
|
||||
|
|
|
@ -688,7 +688,7 @@ void Document::saveToFile(QFile &file, const QByteArray& encoding,
|
|||
if (allAscii) {
|
||||
realEncoding = ENCODING_ASCII;
|
||||
} else if (encoding == ENCODING_AUTO_DETECT) {
|
||||
if (codec->name().compare("System",Qt::CaseInsensitive)) {
|
||||
if (codec->name().compare("System",Qt::CaseInsensitive)==0) {
|
||||
realEncoding = pCharsetInfoManager->getDefaultSystemEncoding();
|
||||
} else {
|
||||
realEncoding = codec->name();
|
||||
|
@ -989,9 +989,9 @@ PUndoItem UndoList::popItem()
|
|||
// qDebug()<<"popped"<<item->changeNumber()<<item->changeText()<<(int)item->changeReason()<<mLastPoppedItemChangeNumber;
|
||||
if (mLastPoppedItemChangeNumber!=item->changeNumber() && item->changeReason()!=ChangeReason::GroupBreak) {
|
||||
mBlockCount--;
|
||||
Q_ASSERT(mBlockCount>=0);
|
||||
// qDebug()<<"pop"<<mBlockCount;
|
||||
if (mBlockCount<0) {
|
||||
qDebug()<<"block count calculation error";
|
||||
mBlockCount=0;
|
||||
}
|
||||
}
|
||||
|
@ -1059,13 +1059,22 @@ bool UndoList::fullUndoImposible() const
|
|||
|
||||
void UndoList::ensureMaxEntries()
|
||||
{
|
||||
if (mMaxUndoActions>0 && (mBlockCount > mMaxUndoActions || mMemoryUsage>mMaxMemoryUsage)){
|
||||
if (mItems.isEmpty())
|
||||
return;
|
||||
// qDebug()<<QString("-- List Memory: %1 %2").arg(mMemoryUsage).arg(mMaxMemoryUsage);
|
||||
if ((mMaxUndoActions >0 && mBlockCount > mMaxUndoActions)
|
||||
|| (mMaxMemoryUsage>0 && mMemoryUsage>mMaxMemoryUsage)){
|
||||
PUndoItem lastItem = mItems.back();
|
||||
mFullUndoImposible = true;
|
||||
while ((mBlockCount > mMaxUndoActions || mMemoryUsage>mMaxMemoryUsage)
|
||||
while (((mMaxUndoActions >0 && mBlockCount > mMaxUndoActions)
|
||||
|| (mMaxMemoryUsage>0 && mMemoryUsage>mMaxMemoryUsage))
|
||||
&& !mItems.isEmpty()) {
|
||||
//remove all undo item in block
|
||||
PUndoItem item = mItems.front();
|
||||
size_t changeNumber = item->changeNumber();
|
||||
//we shouldn't drop the newest changes;
|
||||
if (changeNumber == lastItem->changeNumber())
|
||||
break;
|
||||
while (mItems.count()>0) {
|
||||
item = mItems.front();
|
||||
if (item->changeNumber()!=changeNumber)
|
||||
|
@ -1077,6 +1086,7 @@ void UndoList::ensureMaxEntries()
|
|||
mBlockCount--;
|
||||
}
|
||||
}
|
||||
// qDebug()<<QString("++ List Memory: %1").arg(mMemoryUsage);
|
||||
}
|
||||
|
||||
SelectionMode UndoItem::changeSelMode() const
|
||||
|
@ -1123,8 +1133,9 @@ UndoItem::UndoItem(ChangeReason reason, SelectionMode selMode,
|
|||
foreach (const QString& s, text) {
|
||||
length+=s.length();
|
||||
}
|
||||
mMemoryUsage -= length * sizeof(QChar) + text.length() * sizeof(QString)
|
||||
mMemoryUsage = length * sizeof(QChar) + text.length() * sizeof(QString)
|
||||
+ sizeof(UndoItem);
|
||||
// qDebug()<<mMemoryUsage;
|
||||
}
|
||||
|
||||
ChangeReason UndoItem::changeReason() const
|
||||
|
|
Loading…
Reference in New Issue