diff --git a/language/duchain/navigation/useswidget.h b/language/duchain/navigation/useswidget.h --- a/language/duchain/navigation/useswidget.h +++ b/language/duchain/navigation/useswidget.h @@ -48,6 +48,10 @@ OneUseWidget(IndexedDeclaration declaration, IndexedString document, KTextEditor::Range range, const CodeRepresentation& code); ~OneUseWidget() override; + void setHighlighted(bool highlight); + bool isHighlighted() const; + void activateLink(); + private: void mousePressEvent(QMouseEvent * event) override; void resizeEvent ( QResizeEvent * event ) override; @@ -60,6 +64,7 @@ QLabel* m_label; QLabel* m_icon; QHBoxLayout* m_layout; + bool m_isHighlighted = false; }; diff --git a/language/duchain/navigation/useswidget.cpp b/language/duchain/navigation/useswidget.cpp --- a/language/duchain/navigation/useswidget.cpp +++ b/language/duchain/navigation/useswidget.cpp @@ -44,6 +44,18 @@ using namespace KDevelop; +namespace { + +QString backgroundColor(bool isHighlighted) +{ + if (isHighlighted) { + return QColor(251, 150, 242).name(); + } else { + return QColor(251, 250, 150).name(); + } +} + +} const int tooltipContextSize = 2; //How many lines around the use are shown in the tooltip @@ -92,11 +104,10 @@ //TODO: share code with context browser // mixing (255, 255, 0, 100) with white yields this: - const QColor background(251, 250, 150); const QColor foreground(0, 0, 0); return "" + line.left(range.start().column()).toHtmlEscaped() - + "" + + "" + line.mid(range.start().column(), range.end().column() - range.start().column()).toHtmlEscaped() + "" + line.mid(range.end().column(), line.length() - range.end().column()).toHtmlEscaped() + ""; } @@ -154,10 +165,35 @@ m_layout->setAlignment(Qt::AlignLeft); } +void OneUseWidget::setHighlighted(bool highlight) +{ + if (highlight == m_isHighlighted) { + return; + } + + if (highlight) { + m_label->setText(m_label->text().replace("background-color:" + backgroundColor(false), "background-color:" + backgroundColor(true))); + m_isHighlighted = true; + } else { + m_label->setText(m_label->text().replace("background-color:" + backgroundColor(true), "background-color:" + backgroundColor(false))); + m_isHighlighted = false; + } +} + +bool KDevelop::OneUseWidget::isHighlighted() const +{ + return m_isHighlighted; +} + +void OneUseWidget::activateLink() +{ + ICore::self()->documentController()->openDocument(m_document.toUrl(), m_range->range().start()); +} + void OneUseWidget::mousePressEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton && !event->modifiers()) { - ICore::self()->documentController()->openDocument(m_document.toUrl(), m_range->range().start()); + activateLink(); event->accept(); } } diff --git a/plugins/contextbrowser/contextbrowserview.h b/plugins/contextbrowser/contextbrowserview.h --- a/plugins/contextbrowser/contextbrowserview.h +++ b/plugins/contextbrowser/contextbrowserview.h @@ -29,6 +29,7 @@ #include #include #include +#include class ContextBrowserPlugin; class QVBoxLayout; @@ -42,8 +43,9 @@ class IDocument; } -class ContextBrowserView : public QWidget { +class ContextBrowserView : public QWidget, public KDevelop::IToolViewActionListener { Q_OBJECT + Q_INTERFACES(KDevelop::IToolViewActionListener) public: ContextBrowserView( ContextBrowserPlugin*, QWidget* parent ); ~ContextBrowserView() override; @@ -82,6 +84,8 @@ void updateLockIcon(bool); void declarationMenu(); void navigationContextChanged(bool wasInitial, bool isInitial); + void selectNextItem() override; + void selectPreviousItem() override; private: void showEvent(QShowEvent* event) override; diff --git a/plugins/contextbrowser/contextbrowserview.cpp b/plugins/contextbrowser/contextbrowserview.cpp --- a/plugins/contextbrowser/contextbrowserview.cpp +++ b/plugins/contextbrowser/contextbrowserview.cpp @@ -57,6 +57,81 @@ using namespace KDevelop; +namespace { + +enum Direction +{ + NextUse, + PreviousUse +}; + +void selectUse(ContextBrowserView* view, Direction direction) +{ + auto abstractNaviWidget = dynamic_cast(view->navigationWidget()); + + if (!abstractNaviWidget) { + return; + } + + auto usesWidget = dynamic_cast(abstractNaviWidget->context()->widget()); + if (!usesWidget) { + return; + } + + OneUseWidget* first = nullptr, *previous = nullptr, *current = nullptr; + for (auto item : usesWidget->items()) { + auto topContext = dynamic_cast(item); + if (!topContext) { + continue; + } + for (auto item : topContext->items()) { + auto navigationList = dynamic_cast(item); + if (!navigationList) { + continue; + } + for (auto item : navigationList->items()) { + auto use = dynamic_cast(item); + if (!use) { + continue; + } + if (!first) { + first = use; + } + current = use; + if (direction == PreviousUse && current->isHighlighted() && previous) { + previous->setHighlighted(true); + previous->activateLink(); + current->setHighlighted(false); + return; + } + if (direction == NextUse && previous && previous->isHighlighted()) { + current->setHighlighted(true); + current->activateLink(); + previous->setHighlighted(false); + return; + } + previous = current; + } + } + } + if (direction == NextUse && first) { + first->setHighlighted(true); + first->activateLink(); + if (current && current->isHighlighted()) + current->setHighlighted(false); + return; + } + if (direction == PreviousUse && current) { + current->setHighlighted(true); + current->activateLink(); + if (first && first->isHighlighted()) { + first->setHighlighted(false); + } + } +} + +} + QWidget* ContextBrowserView::createWidget(KDevelop::DUContext* context) { m_context = IndexedDUContext(context); if(m_context.data()) { @@ -241,6 +316,16 @@ } } +void ContextBrowserView::selectNextItem() +{ + selectUse(this, NextUse); +} + +void ContextBrowserView::selectPreviousItem() +{ + selectUse(this, PreviousUse); +} + void ContextBrowserView::setDeclaration(KDevelop::Declaration* decl, KDevelop::TopDUContext* topContext, bool force) { m_lastUsedTopContext = IndexedTopDUContext(topContext);