diff --git a/src/libs/cplusplus/BackwardsScanner.cpp b/src/libs/cplusplus/BackwardsScanner.cpp
index 70829a3d077d808c8104dac3a59505f206e153a6..7d1f812a11c94b320c171bd65b9bf3959fb9e990 100644
--- a/src/libs/cplusplus/BackwardsScanner.cpp
+++ b/src/libs/cplusplus/BackwardsScanner.cpp
@@ -119,7 +119,7 @@ QStringRef BackwardsScanner::textRef(int index) const
     return _text.midRef(firstToken.begin(), firstToken.length());
 }
 
-int BackwardsScanner::previousBlockState(const QTextBlock &block) const
+int BackwardsScanner::previousBlockState(const QTextBlock &block)
 {
     const QTextBlock prevBlock = block.previous();
 
diff --git a/src/libs/cplusplus/BackwardsScanner.h b/src/libs/cplusplus/BackwardsScanner.h
index 4f82ac28d4cb81674a146ed010f69719faf245da..8ab0685bb12aade01868e15a0f7aa8ef04efbe71 100644
--- a/src/libs/cplusplus/BackwardsScanner.h
+++ b/src/libs/cplusplus/BackwardsScanner.h
@@ -67,7 +67,7 @@ public:
     int startOfMatchingBrace(int index) const;
     int startOfBlock(int index) const;
 
-    int previousBlockState(const QTextBlock &block) const;
+    static int previousBlockState(const QTextBlock &block);
 
     int size() const;
 
diff --git a/src/libs/cplusplus/ExpressionUnderCursor.h b/src/libs/cplusplus/ExpressionUnderCursor.h
index c8dbbcdf6655aae3a0712acde52b6065a2ca8d1d..e7ef2f9912a462031e7d4ddda76de092796c9d57 100644
--- a/src/libs/cplusplus/ExpressionUnderCursor.h
+++ b/src/libs/cplusplus/ExpressionUnderCursor.h
@@ -56,7 +56,6 @@ public:
 private:
     int startOfExpression(BackwardsScanner &tk, int index);
     int startOfExpression_helper(BackwardsScanner &tk, int index);
-    int previousBlockState(const QTextBlock &block);
     bool isAccessToken(const SimpleToken &tk);
 
 private:
diff --git a/src/libs/cplusplus/ResolveExpression.cpp b/src/libs/cplusplus/ResolveExpression.cpp
index 0dc42ca9cca78a6c28545c284873dba3507d181d..1b19ed4d13b93ebe50d106dfb9b886354d82eae9 100644
--- a/src/libs/cplusplus/ResolveExpression.cpp
+++ b/src/libs/cplusplus/ResolveExpression.cpp
@@ -120,6 +120,25 @@ QList<Scope *> ResolveExpression::visibleScopes(const LookupItem &result) const
 
 bool ResolveExpression::visit(BinaryExpressionAST *ast)
 {
+    if (tokenKind(ast->binary_op_token) == T_COMMA && ast->right_expression && ast->right_expression->asQtMethod() != 0) {
+
+        if (ast->left_expression && ast->left_expression->asQtMethod() != 0)
+            thisObject();
+        else
+            accept(ast->left_expression);
+
+        QtMethodAST *qtMethod = ast->right_expression->asQtMethod();
+        if (DeclaratorAST *d = qtMethod->declarator) {
+            if (d->core_declarator) {
+                if (DeclaratorIdAST *declaratorId = d->core_declarator->asDeclaratorId())
+                    if (NameAST *nameAST = declaratorId->name)
+                        _results = resolveMemberExpression(_results, T_ARROW, nameAST->name);
+            }
+        }
+
+        return false;
+    }
+
     accept(ast->left_expression);
     return false;
 }
@@ -263,9 +282,15 @@ bool ResolveExpression::visit(BoolLiteralAST *)
 }
 
 bool ResolveExpression::visit(ThisExpressionAST *)
+{
+    thisObject();
+    return false;
+}
+
+void ResolveExpression::thisObject()
 {
     if (! _context.symbol())
-        return false;
+        return;
 
     Scope *scope = _context.symbol()->scope();
     for (; scope; scope = scope->enclosingScope()) {
@@ -290,7 +315,6 @@ bool ResolveExpression::visit(ThisExpressionAST *)
             }
         }
     }
-    return false;
 }
 
 bool ResolveExpression::visit(CompoundExpressionAST *ast)
diff --git a/src/libs/cplusplus/ResolveExpression.h b/src/libs/cplusplus/ResolveExpression.h
index 39290ffa24bd97cd1198c02d5018563ff645de7e..eba5b29f91034dcd62ca23411ac9fc5aada9a0b4 100644
--- a/src/libs/cplusplus/ResolveExpression.h
+++ b/src/libs/cplusplus/ResolveExpression.h
@@ -63,6 +63,7 @@ public:
 protected:
     QList<LookupItem> switchResults(const QList<LookupItem> &symbols);
 
+    void thisObject();
     void addResult(const FullySpecifiedType &ty, Symbol *symbol = 0);
     void addResult(const LookupItem &result);
     void addResults(const QList<LookupItem> &results);
diff --git a/src/libs/cplusplus/TokenUnderCursor.cpp b/src/libs/cplusplus/TokenUnderCursor.cpp
index cf0468cab2f924f340fbd96a0f9325ad974f077b..5cbcdfc7a229d0108357cf97c88c68acc473a456 100644
--- a/src/libs/cplusplus/TokenUnderCursor.cpp
+++ b/src/libs/cplusplus/TokenUnderCursor.cpp
@@ -28,6 +28,7 @@
 **************************************************************************/
 
 #include "TokenUnderCursor.h"
+#include "BackwardsScanner.h"
 #include <Token.h>
 
 #include <QTextCursor>
@@ -52,7 +53,7 @@ SimpleToken TokenUnderCursor::operator()(const QTextCursor &cursor, QTextBlock *
     int column = cursor.position() - cursor.block().position();
 
     _text = block.text();
-    _tokens = tokenize(_text, previousBlockState(block));
+    _tokens = tokenize(_text, BackwardsScanner::previousBlockState(block));
     for (int index = _tokens.size() - 1; index != -1; --index) {
         const SimpleToken &tk = _tokens.at(index);
         if (tk.position() < column) {
@@ -64,15 +65,3 @@ SimpleToken TokenUnderCursor::operator()(const QTextCursor &cursor, QTextBlock *
 
     return SimpleToken();
 }
-
-int TokenUnderCursor::previousBlockState(const QTextBlock &block) const
-{
-    const QTextBlock prevBlock = block.previous();
-    if (prevBlock.isValid()) {
-        int state = prevBlock.userState();
-
-        if (state != -1)
-            return state;
-    }
-    return 0;
-}
diff --git a/src/libs/cplusplus/TokenUnderCursor.h b/src/libs/cplusplus/TokenUnderCursor.h
index 319467d330b7c32bcdcb417ed747cddc18ccafca..af1da311ec132cce7f8757b92c5d8c3ea0e7c5db 100644
--- a/src/libs/cplusplus/TokenUnderCursor.h
+++ b/src/libs/cplusplus/TokenUnderCursor.h
@@ -52,8 +52,6 @@ public:
     { return _tokens; }
 
 private:
-    int previousBlockState(const QTextBlock &block) const;
-
     QList<SimpleToken> _tokens;
     QString _text;
 };
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index 37772f4b8cae5b4a89fdfdbb5655423a31d5f42b..438da7697c702ed97ae6b686b95ac1a14710f505 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -1347,40 +1347,96 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
             tc.movePosition(QTextCursor::Right);
     }
 
-    static TokenUnderCursor tokenUnderCursor;
-
-    QTextBlock block;
-    const SimpleToken tk = tokenUnderCursor(tc, &block);
-
-    const int beginOfToken = block.position() + tk.begin();
-    const int endOfToken = block.position() + tk.end();
-
-    // Handle include directives
-    if (tk.is(T_STRING_LITERAL) || tk.is(T_ANGLE_STRING_LITERAL)) {
-        const unsigned lineno = cursor.blockNumber() + 1;
-        foreach (const Document::Include &incl, doc->includes()) {
-            if (incl.line() == lineno && incl.resolved()) {
-                link.fileName = incl.fileName();
-                link.begin = beginOfToken + 1;
-                link.end = endOfToken - 1;
-                return link;
+
+    int beginOfToken = 0;
+    int endOfToken = 0;
+
+    SimpleLexer tokenize;
+    tokenize.setQtMocRunEnabled(true);
+    const QString blockText = cursor.block().text();
+    const QList<SimpleToken> tokens = tokenize(blockText, BackwardsScanner::previousBlockState(cursor.block()));
+
+    bool recognizedQtMethod = false;
+
+    for (int i = 0; i < tokens.size(); ++i) {
+        const SimpleToken &tk = tokens.at(i);
+
+        if (column >= tk.begin() && column <= tk.end()) {
+            if (i >= 2 && tokens.at(i).is(T_IDENTIFIER) && tokens.at(i - 1).is(T_LPAREN)
+                && (tokens.at(i - 2).is(T_SIGNAL) || tokens.at(i - 2).is(T_SLOT))) {
+
+                // token[i] == T_IDENTIFIER
+                // token[i + 1] == T_LPAREN
+                // token[.....] == ....
+                // token[i + n] == T_RPAREN
+
+                if (i + 1 < tokens.size() && tokens.at(i + 1).is(T_LPAREN)) {
+                    // skip matched parenthesis
+                    int j = i - 1;
+                    int depth = 0;
+
+                    for (; j < tokens.size(); ++j) {
+                        if (tokens.at(j).is(T_LPAREN))
+                            ++depth;
+
+                        else if (tokens.at(j).is(T_RPAREN)) {
+                            if (! --depth)
+                                break;
+                        }
+                    }
+
+                    if (j < tokens.size()) {
+                        QTextBlock block = cursor.block();
+
+                        beginOfToken = block.position() + tokens.at(i).begin();
+                        endOfToken = block.position() + tokens.at(i).end();
+
+                        tc.setPosition(block.position() + tokens.at(j).end());
+                        recognizedQtMethod = true;
+                    }
+                }
             }
+            break;
         }
     }
 
-    if (tk.isNot(T_IDENTIFIER))
-        return link;
+    if (! recognizedQtMethod) {
+        static TokenUnderCursor tokenUnderCursor;
+
+        QTextBlock block;
+        const SimpleToken tk = tokenUnderCursor(tc, &block);
+
+        beginOfToken = block.position() + tk.begin();
+        endOfToken = block.position() + tk.end();
+
+        // Handle include directives
+        if (tk.is(T_STRING_LITERAL) || tk.is(T_ANGLE_STRING_LITERAL)) {
+            const unsigned lineno = cursor.blockNumber() + 1;
+            foreach (const Document::Include &incl, doc->includes()) {
+                if (incl.line() == lineno && incl.resolved()) {
+                    link.fileName = incl.fileName();
+                    link.begin = beginOfToken + 1;
+                    link.end = endOfToken - 1;
+                    return link;
+                }
+            }
+        }
+
+        if (tk.isNot(T_IDENTIFIER))
+            return link;
+
+        tc.setPosition(endOfToken);
+    }
 
     // Find the last symbol up to the cursor position
     Symbol *lastSymbol = doc->findSymbolAt(line, column);
     if (!lastSymbol)
         return link;
 
-    tc.setPosition(endOfToken);
-
     // Evaluate the type of the expression under the cursor
     ExpressionUnderCursor expressionUnderCursor;
     const QString expression = expressionUnderCursor(tc);
+
     TypeOfExpression typeOfExpression;
     typeOfExpression.setSnapshot(snapshot);
     QList<LookupItem> resolvedSymbols =