diff --git a/src/plugins/genericprojectmanager/genericprojectnodes.cpp b/src/plugins/genericprojectmanager/genericprojectnodes.cpp index d9e4d3155c9e3b4a3b8424e16ee85192594adb63..c40b8e42fc818c9079d9304b6b31e362ff123aea 100644 --- a/src/plugins/genericprojectmanager/genericprojectnodes.cpp +++ b/src/plugins/genericprojectmanager/genericprojectnodes.cpp @@ -95,7 +95,7 @@ void GenericProjectNode::refresh() QFileInfo fileInfo(absoluteFileName); const QString absoluteFilePath = fileInfo.path(); - QString baseDir(QFileInfo(path()).absolutePath()); + QString baseDir = QFileInfo(path()).absolutePath(); if (! absoluteFilePath.startsWith(baseDir)) continue; // `file' is not part of the project. diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp index 9f3780d9a95f0bbda8073a9c0ed833af3b7c229c..3a8b84d4c5bbc740757e5d30b67b335cc8f76bb4 100644 --- a/src/plugins/projectexplorer/taskwindow.cpp +++ b/src/plugins/projectexplorer/taskwindow.cpp @@ -46,6 +46,7 @@ #include <QtGui/QListView> #include <QtGui/QPainter> #include <QtCore/QAbstractItemModel> +#include <QtGui/QSortFilterProxyModel> #include <QtGui/QApplication> #include <QtGui/QClipboard> #include <QtGui/QFont> @@ -93,6 +94,32 @@ private: QIcon m_unspecifiedIcon; }; +class ProjectExplorer::Internal::TaskFilterModel : public QSortFilterProxyModel +{ +public: + TaskFilterModel(TaskModel *sourceModel, QObject *parent = 0); + + TaskModel *taskModel() const; + + bool filterIncludesUnknowns() const { return m_includeUnknowns; } + void setFilterIncludesUnknowns(bool b) { m_includeUnknowns = b; invalidateFilter(); } + + bool filterIncludesWarnings() const { return m_includeWarnings; } + void setFilterIncludesWarnings(bool b) { m_includeWarnings = b; invalidateFilter(); } + + bool filterIncludesErrors() const { return m_includeErrors; } + void setFilterIncludesErrors(bool b) { m_includeErrors = b; invalidateFilter(); } + +protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; + +private: + // These correspond to ProjectExplorer::BuildParserInterface::PatternType. + bool m_includeUnknowns; + bool m_includeWarnings; + bool m_includeErrors; +}; + //// // TaskView //// @@ -241,18 +268,71 @@ void TaskModel::setFileNotFound(const QModelIndex &idx, bool b) } } +///// +// TaskFilterModel +///// + +TaskFilterModel::TaskFilterModel(TaskModel *sourceModel, QObject *parent) + : QSortFilterProxyModel(parent) +{ + setSourceModel(sourceModel); + setDynamicSortFilter(true); + m_includeUnknowns = m_includeWarnings = m_includeErrors = true; +} + +TaskModel *TaskFilterModel::taskModel() const +{ + return static_cast<TaskModel*>(sourceModel()); +} + +bool TaskFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); + ProjectExplorer::BuildParserInterface::PatternType type = ProjectExplorer::BuildParserInterface::PatternType(index.data(TaskModel::Type).toInt()); + switch (type) { + case ProjectExplorer::BuildParserInterface::Unknown: + return m_includeUnknowns; + + case ProjectExplorer::BuildParserInterface::Warning: + return m_includeWarnings; + + case ProjectExplorer::BuildParserInterface::Error: + return m_includeErrors; + } + + // Not one of the three supported types -- shouldn't happen, but we'll let it slide. + return true; +} + ///// // TaskWindow ///// +static QToolButton *createFilterButton(ProjectExplorer::BuildParserInterface::PatternType type, + const QString &toolTip, TaskModel *model, + QObject *receiver, const char *slot) +{ + QToolButton *button = new QToolButton; + button->setIcon(model->iconFor(type)); + button->setProperty("type", "dockbutton"); + button->setToolTip(toolTip); + button->setCheckable(true); + button->setChecked(true); + button->setAutoRaise(true); + button->setEnabled(true); + QObject::connect(button, SIGNAL(toggled(bool)), receiver, slot); + return button; +} + TaskWindow::TaskWindow() { Core::ICore *core = Core::ICore::instance(); m_model = new TaskModel; + m_filter = new TaskFilterModel(m_model); m_listview = new TaskView; - m_listview->setModel(m_model); + m_listview->setModel(m_filter); m_listview->setFrameStyle(QFrame::NoFrame); m_listview->setWindowTitle(tr("Build Issues")); m_listview->setSelectionMode(QAbstractItemView::SingleSelection); @@ -280,6 +360,10 @@ TaskWindow::TaskWindow() connect(m_copyAction, SIGNAL(triggered()), SLOT(copy())); + m_filterWarningsButton = createFilterButton(ProjectExplorer::BuildParserInterface::Warning, + tr("Show Warnings"), m_model, + this, SLOT(setShowWarnings(bool))); + m_errorCount = 0; m_currentTask = -1; } @@ -287,13 +371,15 @@ TaskWindow::TaskWindow() TaskWindow::~TaskWindow() { Core::ICore::instance()->removeContextObject(m_taskWindowContext); + delete m_filterWarningsButton; delete m_listview; + delete m_filter; delete m_model; } QList<QWidget*> TaskWindow::toolBarWidgets() const { - return QList<QWidget*>(); + return QList<QWidget*>() << m_filterWarningsButton; } QWidget *TaskWindow::outputWidget(QWidget *) @@ -366,6 +452,12 @@ void TaskWindow::copy() QApplication::clipboard()->setText(file + ':' + line + ": " + type + description); } +void TaskWindow::setShowWarnings(bool show) +{ + m_filter->setFilterIncludesWarnings(show); + m_filter->setFilterIncludesUnknowns(show); // "Unknowns" are often associated with warnings +} + int TaskWindow::numberOfTasks() const { return m_model->rowCount(QModelIndex()); @@ -388,41 +480,41 @@ bool TaskWindow::hasFocus() bool TaskWindow::canFocus() { - return m_model->rowCount(); + return m_filter->rowCount(); } void TaskWindow::setFocus() { - if (m_model->rowCount()) { + if (m_filter->rowCount()) { m_listview->setFocus(); if (m_listview->currentIndex() == QModelIndex()) { - m_listview->setCurrentIndex(m_model->index(0,0, QModelIndex())); + m_listview->setCurrentIndex(m_filter->index(0,0, QModelIndex())); } } } bool TaskWindow::canNext() { - return m_model->rowCount(); + return m_filter->rowCount(); } bool TaskWindow::canPrevious() { - return m_model->rowCount(); + return m_filter->rowCount(); } void TaskWindow::goToNext() { - if (!m_model->rowCount()) + if (!m_filter->rowCount()) return; QModelIndex currentIndex = m_listview->currentIndex(); if (currentIndex.isValid()) { int row = currentIndex.row() + 1; - if (row == m_model->rowCount()) + if (row == m_filter->rowCount()) row = 0; - currentIndex = m_model->index(row, 0); + currentIndex = m_filter->index(row, 0); } else { - currentIndex = m_model->index(0, 0); + currentIndex = m_filter->index(0, 0); } m_listview->setCurrentIndex(currentIndex); showTaskInFile(currentIndex); @@ -430,16 +522,16 @@ void TaskWindow::goToNext() void TaskWindow::goToPrev() { - if (!m_model->rowCount()) + if (!m_filter->rowCount()) return; QModelIndex currentIndex = m_listview->currentIndex(); if (currentIndex.isValid()) { int row = currentIndex.row() -1; if (row < 0) - row = m_model->rowCount() - 1; - currentIndex = m_model->index(row, 0); + row = m_filter->rowCount() - 1; + currentIndex = m_filter->index(row, 0); } else { - currentIndex = m_model->index(m_model->rowCount()-1, 0); + currentIndex = m_filter->index(m_filter->rowCount()-1, 0); } m_listview->setCurrentIndex(currentIndex); showTaskInFile(currentIndex); @@ -475,7 +567,7 @@ QSize TaskDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelInd QSize s; s.setWidth(option.rect.width()); const QAbstractItemView * view = qobject_cast<const QAbstractItemView *>(opt.widget); - TaskModel *model = static_cast<TaskModel *>(view->model()); + TaskModel *model = static_cast<TaskFilterModel *>(view->model())->taskModel(); int width = opt.rect.width() - model->sizeOfFile() - model->sizeOfLineNumber() - 12 - 22; if (view->selectionModel()->currentIndex() == index) { QString description = index.data(TaskModel::Description).toString(); @@ -544,7 +636,7 @@ void TaskDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, painter->setPen(textColor); - TaskModel *model = static_cast<TaskModel *>(view->model()); + TaskModel *model = static_cast<TaskFilterModel *>(view->model())->taskModel(); ProjectExplorer::BuildParserInterface::PatternType type = ProjectExplorer::BuildParserInterface::PatternType(index.data(TaskModel::Type).toInt()); QIcon icon = model->iconFor(type); painter->drawPixmap(2, opt.rect.top() + 2, icon.pixmap(16, 16)); diff --git a/src/plugins/projectexplorer/taskwindow.h b/src/plugins/projectexplorer/taskwindow.h index 7d4500677663c8ac674302f9682fa0a80be25b91..809b7efe82e8d060c6ac6814acc2c598dcd54f36 100644 --- a/src/plugins/projectexplorer/taskwindow.h +++ b/src/plugins/projectexplorer/taskwindow.h @@ -44,6 +44,7 @@ namespace ProjectExplorer { namespace Internal { class TaskModel; +class TaskFilterModel; class TaskView; class TaskWindowContext; @@ -85,6 +86,7 @@ signals: private slots: void showTaskInFile(const QModelIndex &index); void copy(); + void setShowWarnings(bool); private: int sizeHintForColumn(int column) const; @@ -93,9 +95,11 @@ private: int m_currentTask; TaskModel *m_model; + TaskFilterModel *m_filter; TaskView *m_listview; TaskWindowContext *m_taskWindowContext; QAction *m_copyAction; + QToolButton *m_filterWarningsButton; }; class TaskView : public QListView diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp index 6a72e3b90a7c29df9ec79aaf07e882b92496517a..946ecf5cb532da95de2f39468717827c5a9c39f6 100644 --- a/src/shared/cplusplus/AST.cpp +++ b/src/shared/cplusplus/AST.cpp @@ -2104,4 +2104,55 @@ unsigned ObjCMessageArgumentAST::lastToken() const return parameter_key_identifier + 1; } +unsigned ObjCProtocolExpressionAST::firstToken() const +{ + return protocol_token; +} + +unsigned ObjCProtocolExpressionAST::lastToken() const +{ + if (rparen_token) + return rparen_token + 1; + + if (identifier_token) + return identifier_token + 1; + + if (lparen_token) + return lparen_token + 1; + + return protocol_token + 1; +} + +unsigned ObjCTypeNameAST::firstToken() const +{ + return lparen_token; +} + +unsigned ObjCTypeNameAST::lastToken() const +{ + if (rparen_token) + return rparen_token + 1; + + if (type_id) + return type_id->lastToken(); + + if (type_qualifier) + return type_qualifier + 1; + + return lparen_token + 1; +} + +unsigned ObjCEncodeExpressionAST::firstToken() const +{ + return encode_token; +} + +unsigned ObjCEncodeExpressionAST::lastToken() const +{ + if (type_name) + return type_name->lastToken(); + + return encode_token + 1; +} + CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h index 393126c9d47bfb4044b00d4ebea856430b3ee583..290a84324ba041a75f4fbfdbaef4403f7d33bf99 100644 --- a/src/shared/cplusplus/AST.h +++ b/src/shared/cplusplus/AST.h @@ -2653,6 +2653,67 @@ protected: virtual void accept0(ASTVisitor *visitor); }; +class CPLUSPLUS_EXPORT ObjCProtocolExpressionAST: public ExpressionAST +{ +public: + unsigned protocol_token; + unsigned lparen_token; + unsigned identifier_token; + unsigned rparen_token; + +public: + virtual ObjCProtocolExpressionAST *asObjCProtocolExpression() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCProtocolExpressionAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + +class CPLUSPLUS_EXPORT ObjCTypeNameAST: public AST +{ +public: + unsigned lparen_token; + unsigned type_qualifier; + ExpressionAST *type_id; + unsigned rparen_token; + +public: + virtual ObjCTypeNameAST *asObjCTypeName() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCTypeNameAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + +class CPLUSPLUS_EXPORT ObjCEncodeExpressionAST: public ExpressionAST +{ +public: + unsigned encode_token; + ObjCTypeNameAST *type_name; + +public: + virtual ObjCEncodeExpressionAST *asObjCEncodeExpression() + { return this; } + + virtual unsigned firstToken() const; + virtual unsigned lastToken() const; + + virtual ObjCEncodeExpressionAST *clone(MemoryPool *pool) const; + +protected: + virtual void accept0(ASTVisitor *visitor); +}; + CPLUSPLUS_END_NAMESPACE CPLUSPLUS_END_HEADER diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp index 5065cfdd230d7f80546a220bdffaf859d1c12a60..abc89510a5d15c820515908d19c72d58e3ee27b3 100644 --- a/src/shared/cplusplus/ASTClone.cpp +++ b/src/shared/cplusplus/ASTClone.cpp @@ -1311,4 +1311,32 @@ ObjCMessageArgumentAST *ObjCMessageArgumentAST::clone(MemoryPool *pool) const return ast; } +ObjCProtocolExpressionAST *ObjCProtocolExpressionAST::clone(MemoryPool *pool) const +{ + ObjCProtocolExpressionAST *ast = new (pool) ObjCProtocolExpressionAST; + ast->protocol_token = protocol_token; + ast->lparen_token = lparen_token; + ast->identifier_token = identifier_token; + ast->rparen_token = rparen_token; + return ast; +} + +ObjCTypeNameAST *ObjCTypeNameAST::clone(MemoryPool *pool) const +{ + ObjCTypeNameAST *ast = new (pool) ObjCTypeNameAST; + ast->lparen_token = lparen_token; + ast->type_qualifier = type_qualifier; + if (type_id) ast->type_id = type_id->clone(pool); + ast->rparen_token = rparen_token; + return ast; +} + +ObjCEncodeExpressionAST *ObjCEncodeExpressionAST::clone(MemoryPool *pool) const +{ + ObjCEncodeExpressionAST *ast = new (pool) ObjCEncodeExpressionAST; + ast->encode_token = encode_token; + if (type_name) ast->type_name = type_name->clone(pool); + return ast; +} + CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp index 0f2052127d8068c4a03984ba19f5f5034e0c5cc3..02f1218afee847a7f39aa30d02e29a92d09ec39b 100644 --- a/src/shared/cplusplus/ASTVisit.cpp +++ b/src/shared/cplusplus/ASTVisit.cpp @@ -1234,4 +1234,35 @@ void ObjCMessageArgumentAST::accept0(ASTVisitor *visitor) visitor->endVisit(this); } +void ObjCProtocolExpressionAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + // visit ObjCProtocolExpressionAST + // visit ExpressionAST + } + visitor->endVisit(this); +} + +void ObjCTypeNameAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + // visit ObjCTypeNameAST + if (type_id) + accept(type_id, visitor); + // visit AST + } + visitor->endVisit(this); +} + +void ObjCEncodeExpressionAST::accept0(ASTVisitor *visitor) +{ + if (visitor->visit(this)) { + // visit ObjCEncodeExpressionAST + if (type_name) + accept(type_name, visitor); + // visit ExpressionAST + } + visitor->endVisit(this); +} + CPLUSPLUS_END_NAMESPACE diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h index 4b0672cbc1d9ba519a65f56e8610cdcd0df44910..130c6662622698a8976a36b50abef95ddb1fc324 100644 --- a/src/shared/cplusplus/ASTVisitor.h +++ b/src/shared/cplusplus/ASTVisitor.h @@ -206,6 +206,9 @@ public: virtual bool visit(ObjCMessageExpressionAST *) { return true; } virtual bool visit(ObjCMessageArgumentListAST *) { return true; } virtual bool visit(ObjCMessageArgumentAST *) { return true; } + virtual bool visit(ObjCProtocolExpressionAST *) { return true; } + virtual bool visit(ObjCTypeNameAST *) { return true; } + virtual bool visit(ObjCEncodeExpressionAST *) { return true; } virtual bool visit(DeclarationListAST *) { return true; } virtual void endVisit(DeclarationListAST *) { } @@ -323,6 +326,9 @@ public: virtual void endVisit(ObjCMessageExpressionAST *) { } virtual void endVisit(ObjCMessageArgumentListAST *) { } virtual void endVisit(ObjCMessageArgumentAST *) { } + virtual void endVisit(ObjCProtocolExpressionAST *) { } + virtual void endVisit(ObjCTypeNameAST *) { } + virtual void endVisit(ObjCEncodeExpressionAST *) { } private: Control *_control; diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h index e12393df6a88b580e6c7387082796b135e0a1e1f..f25e293282e9b528655a997c5912099cc57d7ca8 100644 --- a/src/shared/cplusplus/ASTfwd.h +++ b/src/shared/cplusplus/ASTfwd.h @@ -179,6 +179,9 @@ class ObjCProtocolRefsAST; class ObjCMessageExpressionAST; class ObjCMessageArgumentListAST; class ObjCMessageArgumentAST; +class ObjCProtocolExpressionAST; +class ObjCTypeNameAST; +class ObjCEncodeExpressionAST; CPLUSPLUS_END_NAMESPACE CPLUSPLUS_END_HEADER diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index ba705f9551bc2765f7ca873bb5e7d5ab68b60123..571ceaa074a8dc3b9b73cf36bdaee784eed2c4a9 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -2839,26 +2839,29 @@ bool Parser::parseObjCStringLiteral(ExpressionAST *&node) return true; } -bool Parser::parseObjCEncodeExpression(ExpressionAST *&) +bool Parser::parseObjCEncodeExpression(ExpressionAST *&node) { if (LA() != T_AT_ENCODE) return false; - /*unsigned encode_token = */ consumeToken(); - parseObjCTypeName(); + ObjCEncodeExpressionAST *ast = new (_pool) ObjCEncodeExpressionAST; + ast->encode_token = consumeToken(); + parseObjCTypeName(ast->type_name); + node = ast; return true; } -bool Parser::parseObjCProtocolExpression(ExpressionAST *&) +bool Parser::parseObjCProtocolExpression(ExpressionAST *&node) { if (LA() != T_AT_PROTOCOL) return false; - /*unsigned protocol_token = */ consumeToken(); - unsigned lparen_token = 0, identifier_token = 0, rparen_token = 0; - match(T_LPAREN, &lparen_token); - match(T_IDENTIFIER, &identifier_token); - match(T_RPAREN, &rparen_token); + ObjCProtocolExpressionAST *ast = new (_pool) ObjCProtocolExpressionAST; + ast->protocol_token = consumeToken(); + match(T_LPAREN, &(ast->lparen_token)); + match(T_IDENTIFIER, &(ast->identifier_token)); + match(T_RPAREN, &(ast->rparen_token)); + node = ast; return true; } @@ -4348,7 +4351,8 @@ bool Parser::parseObjCMethodPrototype() /*unsigned method_type_token = */ consumeToken(); - parseObjCTypeName(); + ObjCTypeNameAST *type_name = 0; + parseObjCTypeName(type_name); unsigned selector_token = 0; @@ -4407,17 +4411,17 @@ bool Parser::parseObjCPropertyAttribute() // objc-type-name ::= T_LPAREN objc-type-qualifiers-opt type-id T_RPAREN // -bool Parser::parseObjCTypeName() +bool Parser::parseObjCTypeName(ObjCTypeNameAST *&node) { if (LA() != T_LPAREN) return false; - unsigned lparen_token = 0, rparen_token = 0; - match(T_LPAREN, &lparen_token); - parseObjCTypeQualifiers(); - ExpressionAST *type_id = 0; - parseTypeId(type_id); - match(T_RPAREN, &rparen_token); + ObjCTypeNameAST *ast = new (_pool) ObjCTypeNameAST; + match(T_LPAREN, &(ast->lparen_token)); + parseObjCTypeQualifiers(ast->type_qualifier); + parseTypeId(ast->type_id); + match(T_RPAREN, &(ast->rparen_token)); + node = ast; return true; } @@ -4445,7 +4449,8 @@ bool Parser::parseObjCKeywordDeclaration() unsigned colon_token = 0; match(T_COLON, &colon_token); - parseObjCTypeName(); + ObjCTypeNameAST *type_name = 0; + parseObjCTypeName(type_name); SpecifierAST *attributes = 0, **attr = &attributes; while (parseAttributeSpecifier(*attr)) @@ -4457,7 +4462,7 @@ bool Parser::parseObjCKeywordDeclaration() return true; } -bool Parser::parseObjCTypeQualifiers() +bool Parser::parseObjCTypeQualifiers(unsigned &type_qualifier) { if (LA() != T_IDENTIFIER) return false; @@ -4466,7 +4471,7 @@ bool Parser::parseObjCTypeQualifiers() const int k = classifyObjectiveCTypeQualifiers(id->chars(), id->size()); if (k == Token_identifier) return false; - consumeToken(); + type_qualifier = consumeToken(); return true; } diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h index c81312d94f9dbeae842198f787b1a9fd3273ccd1..2de07f1bea8088ed44f83755502b483f5593ef4d 100644 --- a/src/shared/cplusplus/Parser.h +++ b/src/shared/cplusplus/Parser.h @@ -240,10 +240,10 @@ public: bool parseObjCImplementation(DeclarationAST *&node); bool parseObjCMethodPrototype(); bool parseObjCPropertyAttribute(); - bool parseObjCTypeName(); + bool parseObjCTypeName(ObjCTypeNameAST *&node); bool parseObjCSelector(unsigned &selector_token); bool parseObjCKeywordDeclaration(); - bool parseObjCTypeQualifiers(); + bool parseObjCTypeQualifiers(unsigned &type_qualifier); bool parseObjCEnd(DeclarationAST *&node); bool lookAtObjCSelector() const;