diff --git a/plugins/contextbrowser/contextbrowserview.cpp b/plugins/contextbrowser/contextbrowserview.cpp index a39a71cdf9..142f1dfda8 100644 --- a/plugins/contextbrowser/contextbrowserview.cpp +++ b/plugins/contextbrowser/contextbrowserview.cpp @@ -1,315 +1,311 @@ /* * This file is part of KDevelop * * Copyright 2008 David Nolden * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "contextbrowserview.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "contextbrowser.h" #include "debug.h" #include #include #include #include "browsemanager.h" #include #include #include #include #include #include using namespace KDevelop; QWidget* ContextBrowserView::createWidget(KDevelop::DUContext* context) { m_context = IndexedDUContext(context); if(m_context.data()) { return m_context.data()->createNavigationWidget(nullptr, nullptr, {}, {}, AbstractNavigationWidget::EmbeddableWidget); } return 0; } KDevelop::IndexedDeclaration ContextBrowserView::declaration() const { return m_declaration; } QWidget* ContextBrowserView::createWidget(Declaration* decl, TopDUContext* topContext) { m_declaration = IndexedDeclaration(decl); return decl->context()->createNavigationWidget(decl, topContext, {}, {}, AbstractNavigationWidget::EmbeddableWidget); } void ContextBrowserView::resetWidget() { if (m_navigationWidget) { delete m_navigationWidget; m_navigationWidget = 0; } } void ContextBrowserView::declarationMenu() { DUChainReadLocker lock(DUChain::lock()); AbstractNavigationWidget* navigationWidget = dynamic_cast(m_navigationWidget.data()); if(navigationWidget) { AbstractDeclarationNavigationContext* navigationContext = dynamic_cast(navigationWidget->context().data()); if(navigationContext && navigationContext->declaration().data()) { KDevelop::DeclarationContext* c = new KDevelop::DeclarationContext(navigationContext->declaration().data()); lock.unlock(); QMenu menu; QList extensions = ICore::self()->pluginController()->queryPluginsForContextMenuExtensions( c ); ContextMenuExtension::populateMenu(&menu, extensions); menu.exec(QCursor::pos()); } } } void ContextBrowserView::updateLockIcon(bool checked) { - m_lockButton->setIcon(QIcon::fromTheme(checked ? QStringLiteral("document-encrypt") : QStringLiteral("document-decrypt"))); + m_lockAction->setIcon(QIcon::fromTheme(checked ? QStringLiteral("document-encrypt") : QStringLiteral("document-decrypt"))); } ContextBrowserView::ContextBrowserView( ContextBrowserPlugin* plugin, QWidget* parent ) : QWidget(parent), m_plugin(plugin), m_navigationWidget(new QTextBrowser()), m_autoLocked(false) { setWindowIcon( QIcon::fromTheme(QStringLiteral("code-context"), windowIcon()) ); m_allowLockedUpdate = false; - m_buttons = new QHBoxLayout; - m_buttons->addStretch(); - m_declarationMenuButton = new QToolButton(); - m_declarationMenuButton->setIcon(QIcon::fromTheme(QStringLiteral("code-class"))); - m_declarationMenuButton->setToolTip(i18n("Declaration menu")); - connect(m_declarationMenuButton, &QToolButton::clicked, this, &ContextBrowserView::declarationMenu); - m_buttons->addWidget(m_declarationMenuButton); - m_lockButton = new QToolButton(); - m_lockButton->setCheckable(true); - m_lockButton->setChecked(false); - m_lockButton->setToolTip(i18n("Lock current view")); - updateLockIcon(m_lockButton->isChecked()); - connect(m_lockButton, &QToolButton::toggled, this, &ContextBrowserView::updateLockIcon); - m_buttons->addWidget(m_lockButton); + m_declarationMenuAction = new QAction(QIcon::fromTheme(QStringLiteral("code-class")), QString(), this); + m_declarationMenuAction->setToolTip(i18n("Declaration menu")); + connect(m_declarationMenuAction, &QAction::triggered, this, &ContextBrowserView::declarationMenu); + addAction(m_declarationMenuAction); + m_lockAction = new QAction(this); + m_lockAction->setCheckable(true); + m_lockAction->setChecked(false); + m_lockAction->setToolTip(i18n("Lock current view")); + addAction(m_lockAction); + updateLockIcon(m_lockAction->isChecked()); + connect(m_lockAction, &QAction::triggered, this, &ContextBrowserView::updateLockIcon); m_layout = new QVBoxLayout; m_layout->setSpacing(0); m_layout->setMargin(0); - m_layout->addLayout(m_buttons); m_layout->addWidget(m_navigationWidget); //m_layout->addStretch(); setLayout(m_layout); m_plugin->registerToolView(this); } ContextBrowserView::~ContextBrowserView() { m_plugin->unRegisterToolView(this); } void ContextBrowserView::focusInEvent(QFocusEvent* event) { //Indicate that we have focus qCDebug(PLUGIN_CONTEXTBROWSER) << "got focus"; // parentWidget()->setBackgroundRole(QPalette::ToolTipBase); /* m_layout->removeItem(m_buttons);*/ return QWidget::focusInEvent(event); } void ContextBrowserView::focusOutEvent(QFocusEvent* event) { qCDebug(PLUGIN_CONTEXTBROWSER) << "lost focus"; // parentWidget()->setBackgroundRole(QPalette::Background); /* m_layout->insertLayout(0, m_buttons); for(int a = 0; a < m_buttons->count(); ++a) { QWidgetItem* item = dynamic_cast(m_buttons->itemAt(a)); }*/ QWidget::focusOutEvent(event); } bool ContextBrowserView::event(QEvent* event) { QKeyEvent* keyEvent = dynamic_cast(event); if(hasFocus() && keyEvent) { AbstractNavigationWidget* navigationWidget = dynamic_cast(m_navigationWidget.data()); if(navigationWidget && event->type() == QEvent::KeyPress) { int key = keyEvent->key(); if(key == Qt::Key_Left) navigationWidget->previous(); if(key == Qt::Key_Right) navigationWidget->next(); if(key == Qt::Key_Up) navigationWidget->up(); if(key == Qt::Key_Down) navigationWidget->down(); if(key == Qt::Key_Return || key == Qt::Key_Enter) navigationWidget->accept(); if(key == Qt::Key_L) - m_lockButton->toggle(); + m_lockAction->toggle(); } } return QWidget::event(event); } void ContextBrowserView::showEvent(QShowEvent* event) { DUChainReadLocker lock(DUChain::lock(), 200); if (!lock.locked()) { QWidget::showEvent(event); return; } TopDUContext* top = m_lastUsedTopContext.data(); if(top && m_navigationWidgetDeclaration.isValid() && m_navigationWidgetDeclaration.getDeclaration(top)) { if(top) { //Update the navigation-widget Declaration* decl = m_navigationWidgetDeclaration.getDeclaration(top); setDeclaration(decl, top, true); } } QWidget::showEvent(event); } bool ContextBrowserView::isLocked() const { bool isLocked; if (m_allowLockedUpdate) { isLocked = false; } else { - isLocked = m_lockButton->isChecked(); + isLocked = m_lockAction->isChecked(); } return isLocked; } void ContextBrowserView::updateMainWidget(QWidget* widget) { if (widget) { setUpdatesEnabled(false); qCDebug(PLUGIN_CONTEXTBROWSER) << ""; resetWidget(); m_navigationWidget = widget; m_layout->insertWidget(1, widget, 1); m_allowLockedUpdate = false; setUpdatesEnabled(true); if (widget->metaObject()->indexOfSignal(QMetaObject::normalizedSignature("contextChanged(bool,bool)")) != -1) { connect(widget, SIGNAL(contextChanged(bool,bool)), this, SLOT(navigationContextChanged(bool,bool))); } } } void ContextBrowserView::navigationContextChanged(bool wasInitial, bool isInitial) { - if(wasInitial && !isInitial && !m_lockButton->isChecked()) + if(wasInitial && !isInitial && !m_lockAction->isChecked()) { m_autoLocked = true; - m_lockButton->setChecked(true); + m_lockAction->setChecked(true); }else if(!wasInitial && isInitial && m_autoLocked) { m_autoLocked = false; - m_lockButton->setChecked(false); + m_lockAction->setChecked(false); }else if(isInitial) { m_autoLocked = false; } } void ContextBrowserView::setDeclaration(KDevelop::Declaration* decl, KDevelop::TopDUContext* topContext, bool force) { m_lastUsedTopContext = IndexedTopDUContext(topContext); if(isLocked() && (!m_navigationWidget.data() || !isVisible())) { // Automatically remove the locked state if the view is not visible or the widget was deleted, // because the locked state has side-effects on other navigation functionality. m_autoLocked = false; - m_lockButton->setChecked(false); + m_lockAction->setChecked(false); } if(m_navigationWidgetDeclaration == decl->id() && !force) return; m_navigationWidgetDeclaration = decl->id(); if (!isLocked() && (isVisible() || force)) { // NO-OP if toolview is hidden, for performance reasons QWidget* w = createWidget(decl, topContext); updateMainWidget(w); } } KDevelop::IndexedDeclaration ContextBrowserView::lockedDeclaration() const { - if(m_lockButton->isChecked()) + if(m_lockAction->isChecked()) return declaration(); else return KDevelop::IndexedDeclaration(); } void ContextBrowserView::allowLockedUpdate() { m_allowLockedUpdate = true; } void ContextBrowserView::setNavigationWidget(QWidget* widget) { updateMainWidget(widget); } void ContextBrowserView::setContext(KDevelop::DUContext* context) { if(!context) return; m_lastUsedTopContext = IndexedTopDUContext(context->topContext()); if(context->owner()) { if(context->owner()->id() == m_navigationWidgetDeclaration) return; m_navigationWidgetDeclaration = context->owner()->id(); }else{ m_navigationWidgetDeclaration = DeclarationId(); } if (!isLocked() && isVisible()) { // NO-OP if toolview is hidden, for performance reasons QWidget* w = createWidget(context); updateMainWidget(w); } } void ContextBrowserView::setSpecialNavigationWidget(QWidget* widget) { if (!isLocked() && isVisible()) { Q_ASSERT(widget); updateMainWidget(widget); } else if(widget) { widget->deleteLater(); } } diff --git a/plugins/contextbrowser/contextbrowserview.h b/plugins/contextbrowser/contextbrowserview.h index 03a57c2870..dcb76daca0 100644 --- a/plugins/contextbrowser/contextbrowserview.h +++ b/plugins/contextbrowser/contextbrowserview.h @@ -1,114 +1,114 @@ /* * This file is part of KDevelop * * Copyright 2008 David Nolden * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEVPLATFORM_PLUGIN_CONTEXTBROWSERVIEW_H #define KDEVPLATFORM_PLUGIN_CONTEXTBROWSERVIEW_H #include #include #include #include #include #include class ContextBrowserPlugin; class QVBoxLayout; class QHBoxLayout; -class QToolButton; +class QAction; class QCheckBox; class QMenu; class KComboBox; namespace KDevelop { class IDocument; } class ContextBrowserView : public QWidget { Q_OBJECT public: ContextBrowserView( ContextBrowserPlugin*, QWidget* parent ); ~ContextBrowserView() override; //duchain must be locked void setContext(KDevelop::DUContext* context); void setDeclaration(KDevelop::Declaration* decl, KDevelop::TopDUContext* topContext, bool force = false); void setSpecialNavigationWidget(QWidget*); void updateMainWidget(QWidget*); /** Allows a single update of the view even if in locked state. * This is needed to browse while the locked button is checked. */ void allowLockedUpdate(); ///Returns the currently locked declaration, or invalid of none is locked atm. KDevelop::IndexedDeclaration lockedDeclaration() const; void setNavigationWidget(QWidget* widget); QWidget* navigationWidget() { return m_navigationWidget; } //duchain must be locked QWidget* createWidget(KDevelop::DUContext* context); //duchain must be locked QWidget* createWidget(KDevelop::Declaration* decl, KDevelop::TopDUContext* topContext); KDevelop::IndexedDeclaration declaration() const; ///Returns whether the view is currently locked bool isLocked() const; private Q_SLOTS: void updateLockIcon(bool); void declarationMenu(); void navigationContextChanged(bool wasInitial, bool isInitial); private: void showEvent(QShowEvent* event) override; bool event(QEvent* event) override; void focusInEvent(QFocusEvent* event) override; void focusOutEvent(QFocusEvent* event) override; void resetWidget(); private: KDevelop::IndexedDeclaration m_declaration; ContextBrowserPlugin* m_plugin; QVBoxLayout* m_layout; - QToolButton* m_lockButton; - QToolButton* m_declarationMenuButton; + QAction* m_lockAction; + QAction* m_declarationMenuAction; QHBoxLayout* m_buttons; QPointer m_navigationWidget; KDevelop::DeclarationId m_navigationWidgetDeclaration; bool m_allowLockedUpdate; KDevelop::IndexedTopDUContext m_lastUsedTopContext; KDevelop::IndexedDUContext m_context; // Whether the lock-button was activated automatically due to user navigation bool m_autoLocked; }; #endif