diff --git plugins/contextbrowser/contextbrowser.cpp plugins/contextbrowser/contextbrowser.cpp index cdafb50a238fcd60fedfd39768b9737f4f23fd0f..d05107a36c04b24125edb35ea68ac3bcc4da19ae 100644 --- plugins/contextbrowser/contextbrowser.cpp +++ plugins/contextbrowser/contextbrowser.cpp @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include #include @@ -571,22 +573,10 @@ QWidget* ContextBrowserPlugin::navigationWidgetForPosition(KTextEditor::View* vi } TopDUContext* topContext = DUChainUtils::standardContextForUrl(view->document()->url()); + QVector problems; if (topContext) { // first pass: find problems under the cursor - const auto problems = findProblemsUnderCursor(topContext, position, itemRange); - if (!problems.isEmpty()) { - if (problems == m_currentToolTipProblems && m_currentToolTip) { - return nullptr; - } - - m_currentToolTipProblems = problems; - - auto widget = new AbstractNavigationWidget; - auto context = new ProblemNavigationContext(problems); - context->setTopContext(TopDUContextPointer(topContext)); - widget->setContext(NavigationContextPointer(context)); - return widget; - } + problems = findProblemsUnderCursor(topContext, position, itemRange); } const auto itemUnderCursor = DUChainUtils::itemUnderCursor(viewUrl, position); @@ -597,18 +587,61 @@ QWidget* ContextBrowserPlugin::navigationWidgetForPosition(KTextEditor::View* vi Q_ASSERT(alias); decl = alias->aliasedDeclaration().declaration(); } - if(decl) { - if(m_currentToolTipDeclaration == IndexedDeclaration(decl) && m_currentToolTip) + // Return nullptr if the correct contents are already shown. + if (m_currentToolTip && + problems == m_currentToolTipProblems && + (!decl || IndexedDeclaration(decl) == m_currentToolTipDeclaration)) { return nullptr; + } + // Remember current state. + m_currentToolTipProblems = problems; + if (decl) { m_currentToolTipDeclaration = IndexedDeclaration(decl); - itemRange = itemUnderCursor.range; - return decl->context()->createNavigationWidget(decl, DUChainUtils::standardContextForUrl(viewUrl)); + } + + AbstractNavigationWidget* problemWidget = nullptr; + if (!problems.isEmpty()) { + problemWidget = new AbstractNavigationWidget; + auto context = new ProblemNavigationContext(problems); + context->setTopContext(TopDUContextPointer(topContext)); + problemWidget->setContext(NavigationContextPointer(context)); + } + + QWidget* declWidget = nullptr; + if (decl) { + if (itemRange.isValid()) { + itemRange.expandToRange(itemUnderCursor.range); + } else { + itemRange = itemUnderCursor.range; + } + declWidget = decl->context()->createNavigationWidget(decl, DUChainUtils::standardContextForUrl(viewUrl)); + } + + if (problemWidget && declWidget) { + int maxHeight; + auto geom = QApplication::desktop()->availableGeometry(QCursor::pos()); + maxHeight = geom.height() / 3; + if (problemWidget->sizeHint().height() + declWidget->sizeHint().height() <= maxHeight) { + QWidget* combinedWidget = new QWidget(); + QVBoxLayout* layout = new QVBoxLayout(); + layout->setContentsMargins(2, 2, 2, 2); + layout->setSpacing(0); + layout->addWidget(problemWidget); + layout->addWidget(declWidget); + combinedWidget->setLayout(layout); + return combinedWidget; + } + } + if (declWidget) { + return declWidget; + } else if (problemWidget) { + return problemWidget; } if (topContext) { // second pass: find closest problem to the cursor - const auto problems = findProblemsCloseToCursor(topContext, position, view, itemRange); + problems = findProblemsCloseToCursor(topContext, position, view, itemRange); if (!problems.isEmpty()) { if (problems == m_currentToolTipProblems && m_currentToolTip) { return nullptr;