2012-10-02 09:12:39 +02:00
|
|
|
/****************************************************************************
|
2011-02-18 10:36:52 +01:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2011-02-18 10:36:52 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** This file is part of Qt Creator.
|
2011-02-18 10:36:52 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** Commercial License Usage
|
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
2016-01-15 14:57:40 +01:00
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
2011-02-18 10:36:52 +01:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** GNU General Public License Usage
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
|
** General Public License version 3 as published by the Free Software
|
|
|
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
|
|
|
** included in the packaging of this file. Please review the following
|
|
|
|
|
** information to ensure the GNU General Public License requirements will
|
|
|
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
2011-02-18 10:36:52 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
****************************************************************************/
|
2011-02-18 10:36:52 +01:00
|
|
|
|
2010-07-08 11:15:26 +02:00
|
|
|
#include "outlinefactory.h"
|
2010-07-30 22:16:59 +02:00
|
|
|
#include <coreplugin/coreconstants.h>
|
2010-07-14 16:46:54 +02:00
|
|
|
#include <coreplugin/icore.h>
|
2010-07-08 11:15:26 +02:00
|
|
|
#include <coreplugin/editormanager/editormanager.h>
|
2015-12-13 01:18:33 +02:00
|
|
|
#include <coreplugin/editormanager/ieditor.h>
|
2011-01-24 12:29:48 +01:00
|
|
|
|
2016-08-03 17:55:54 +02:00
|
|
|
#include <utils/utilsicons.h>
|
2019-07-16 12:29:20 +02:00
|
|
|
#include <utils/qtcassert.h>
|
2016-08-03 17:55:54 +02:00
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QToolButton>
|
|
|
|
|
#include <QLabel>
|
|
|
|
|
#include <QStackedWidget>
|
2011-01-24 12:29:48 +01:00
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QDebug>
|
2010-07-08 11:15:26 +02:00
|
|
|
|
|
|
|
|
namespace TextEditor {
|
2017-12-08 17:20:48 +01:00
|
|
|
|
|
|
|
|
static QList<IOutlineWidgetFactory *> g_outlineWidgetFactories;
|
2019-07-16 12:29:20 +02:00
|
|
|
static QPointer<Internal::OutlineFactory> g_outlineFactory;
|
2017-12-08 17:20:48 +01:00
|
|
|
|
|
|
|
|
IOutlineWidgetFactory::IOutlineWidgetFactory()
|
|
|
|
|
{
|
|
|
|
|
g_outlineWidgetFactories.append(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IOutlineWidgetFactory::~IOutlineWidgetFactory()
|
|
|
|
|
{
|
|
|
|
|
g_outlineWidgetFactories.removeOne(this);
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-16 12:29:20 +02:00
|
|
|
void IOutlineWidgetFactory::updateOutline()
|
|
|
|
|
{
|
|
|
|
|
if (QTC_GUARD(!g_outlineFactory.isNull()))
|
|
|
|
|
emit g_outlineFactory->updateOutline();
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-08 11:15:26 +02:00
|
|
|
namespace Internal {
|
|
|
|
|
|
|
|
|
|
OutlineWidgetStack::OutlineWidgetStack(OutlineFactory *factory) :
|
|
|
|
|
QStackedWidget(),
|
|
|
|
|
m_factory(factory),
|
2014-12-09 11:12:17 +01:00
|
|
|
m_syncWithEditor(true)
|
2010-07-08 11:15:26 +02:00
|
|
|
{
|
|
|
|
|
QLabel *label = new QLabel(tr("No outline available"), this);
|
|
|
|
|
label->setAlignment(Qt::AlignCenter);
|
2010-07-13 14:15:54 +02:00
|
|
|
|
|
|
|
|
// set background to be white
|
|
|
|
|
label->setAutoFillBackground(true);
|
|
|
|
|
label->setBackgroundRole(QPalette::Base);
|
|
|
|
|
|
2010-07-08 11:15:26 +02:00
|
|
|
addWidget(label);
|
|
|
|
|
|
|
|
|
|
m_toggleSync = new QToolButton;
|
2018-01-07 21:39:39 +01:00
|
|
|
m_toggleSync->setIcon(Utils::Icons::LINK_TOOLBAR.icon());
|
2010-07-08 11:15:26 +02:00
|
|
|
m_toggleSync->setCheckable(true);
|
|
|
|
|
m_toggleSync->setChecked(true);
|
|
|
|
|
m_toggleSync->setToolTip(tr("Synchronize with Editor"));
|
2015-12-13 01:18:33 +02:00
|
|
|
connect(m_toggleSync, &QAbstractButton::clicked,
|
|
|
|
|
this, &OutlineWidgetStack::toggleCursorSynchronization);
|
2010-07-08 11:15:26 +02:00
|
|
|
|
2017-08-31 19:09:28 +02:00
|
|
|
m_filterButton = new QToolButton(this);
|
|
|
|
|
// The ToolButton needs a parent because updateFilterMenu() sets
|
|
|
|
|
// it visible. That would open a top-level window if the button
|
|
|
|
|
// did not have a parent in that moment.
|
|
|
|
|
|
2016-08-03 17:55:54 +02:00
|
|
|
m_filterButton->setIcon(Utils::Icons::FILTER.icon());
|
2010-07-14 16:46:54 +02:00
|
|
|
m_filterButton->setToolTip(tr("Filter tree"));
|
|
|
|
|
m_filterButton->setPopupMode(QToolButton::InstantPopup);
|
2012-02-01 21:39:05 +01:00
|
|
|
m_filterButton->setProperty("noArrow", true);
|
2010-07-14 16:46:54 +02:00
|
|
|
m_filterMenu = new QMenu(m_filterButton);
|
|
|
|
|
m_filterButton->setMenu(m_filterMenu);
|
|
|
|
|
|
2015-12-13 01:18:33 +02:00
|
|
|
connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged,
|
2019-07-16 12:29:20 +02:00
|
|
|
this, &OutlineWidgetStack::updateEditor);
|
|
|
|
|
connect(factory, &OutlineFactory::updateOutline,
|
2015-12-13 01:18:33 +02:00
|
|
|
this, &OutlineWidgetStack::updateCurrentEditor);
|
2019-07-16 12:29:20 +02:00
|
|
|
updateCurrentEditor();
|
2010-07-08 11:15:26 +02:00
|
|
|
}
|
|
|
|
|
|
2018-11-25 18:52:41 +01:00
|
|
|
OutlineWidgetStack::~OutlineWidgetStack() = default;
|
2010-07-08 11:15:26 +02:00
|
|
|
|
|
|
|
|
QToolButton *OutlineWidgetStack::toggleSyncButton()
|
|
|
|
|
{
|
|
|
|
|
return m_toggleSync;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-14 16:46:54 +02:00
|
|
|
QToolButton *OutlineWidgetStack::filterButton()
|
|
|
|
|
{
|
|
|
|
|
return m_filterButton;
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-17 18:31:56 +03:00
|
|
|
void OutlineWidgetStack::saveSettings(QSettings *settings, int position)
|
2010-07-16 11:04:20 +02:00
|
|
|
{
|
2016-09-17 18:31:56 +03:00
|
|
|
const QString baseKey = QStringLiteral("Outline.%1.").arg(position);
|
|
|
|
|
settings->setValue(baseKey + QLatin1String("SyncWithEditor"), toggleSyncButton()->isChecked());
|
|
|
|
|
for (auto iter = m_widgetSettings.constBegin(); iter != m_widgetSettings.constEnd(); ++iter)
|
|
|
|
|
settings->setValue(baseKey + iter.key(), iter.value());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OutlineWidgetStack::restoreSettings(QSettings *settings, int position)
|
|
|
|
|
{
|
|
|
|
|
const QString baseKey = QStringLiteral("Outline.%1.").arg(position);
|
2014-12-09 11:12:17 +01:00
|
|
|
|
|
|
|
|
bool syncWithEditor = true;
|
|
|
|
|
m_widgetSettings.clear();
|
2016-09-17 18:31:56 +03:00
|
|
|
foreach (const QString &longKey, settings->allKeys()) {
|
|
|
|
|
if (!longKey.startsWith(baseKey))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
const QString key = longKey.mid(baseKey.length());
|
|
|
|
|
|
2014-12-09 11:12:17 +01:00
|
|
|
if (key == QLatin1String("SyncWithEditor")) {
|
2016-09-17 18:31:56 +03:00
|
|
|
syncWithEditor = settings->value(longKey).toBool();
|
2014-12-09 11:12:17 +01:00
|
|
|
continue;
|
|
|
|
|
}
|
2016-09-17 18:31:56 +03:00
|
|
|
m_widgetSettings.insert(key, settings->value(longKey));
|
2014-12-09 11:12:17 +01:00
|
|
|
}
|
2010-07-16 11:04:20 +02:00
|
|
|
|
2014-12-09 11:12:17 +01:00
|
|
|
toggleSyncButton()->setChecked(syncWithEditor);
|
2018-09-20 01:16:01 +03:00
|
|
|
if (auto outlineWidget = qobject_cast<IOutlineWidget*>(currentWidget()))
|
2014-12-09 11:12:17 +01:00
|
|
|
outlineWidget->restoreSettings(m_widgetSettings);
|
2010-07-16 11:04:20 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-08 11:15:26 +02:00
|
|
|
bool OutlineWidgetStack::isCursorSynchronized() const
|
|
|
|
|
{
|
|
|
|
|
return m_syncWithEditor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OutlineWidgetStack::toggleCursorSynchronization()
|
|
|
|
|
{
|
|
|
|
|
m_syncWithEditor = !m_syncWithEditor;
|
2018-09-20 01:16:01 +03:00
|
|
|
if (auto outlineWidget = qobject_cast<IOutlineWidget*>(currentWidget()))
|
2010-07-08 11:15:26 +02:00
|
|
|
outlineWidget->setCursorSynchronization(m_syncWithEditor);
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-14 16:46:54 +02:00
|
|
|
void OutlineWidgetStack::updateFilterMenu()
|
|
|
|
|
{
|
|
|
|
|
m_filterMenu->clear();
|
2018-09-20 01:16:01 +03:00
|
|
|
if (auto outlineWidget = qobject_cast<IOutlineWidget*>(currentWidget())) {
|
2010-07-14 16:46:54 +02:00
|
|
|
foreach (QAction *filterAction, outlineWidget->filterMenuActions()) {
|
|
|
|
|
m_filterMenu->addAction(filterAction);
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-06-25 17:47:39 -04:00
|
|
|
m_filterButton->setVisible(!m_filterMenu->actions().isEmpty());
|
2010-07-14 16:46:54 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-16 12:29:20 +02:00
|
|
|
void OutlineWidgetStack::updateCurrentEditor()
|
|
|
|
|
{
|
|
|
|
|
updateEditor(Core::EditorManager::currentEditor());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OutlineWidgetStack::updateEditor(Core::IEditor *editor)
|
2010-07-08 11:15:26 +02:00
|
|
|
{
|
2018-09-20 01:16:01 +03:00
|
|
|
IOutlineWidget *newWidget = nullptr;
|
2010-07-08 11:15:26 +02:00
|
|
|
|
|
|
|
|
if (editor) {
|
2018-11-25 18:52:41 +01:00
|
|
|
for (IOutlineWidgetFactory *widgetFactory : qAsConst(g_outlineWidgetFactories)) {
|
2010-07-08 11:15:26 +02:00
|
|
|
if (widgetFactory->supportsEditor(editor)) {
|
|
|
|
|
newWidget = widgetFactory->createWidget(editor);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (newWidget != currentWidget()) {
|
|
|
|
|
// delete old widget
|
2018-09-20 01:16:01 +03:00
|
|
|
if (auto outlineWidget = qobject_cast<IOutlineWidget*>(currentWidget())) {
|
2014-12-09 11:12:17 +01:00
|
|
|
QVariantMap widgetSettings = outlineWidget->settings();
|
|
|
|
|
for (auto iter = widgetSettings.constBegin(); iter != widgetSettings.constEnd(); ++iter)
|
|
|
|
|
m_widgetSettings.insert(iter.key(), iter.value());
|
2010-07-08 11:15:26 +02:00
|
|
|
removeWidget(outlineWidget);
|
|
|
|
|
delete outlineWidget;
|
|
|
|
|
}
|
|
|
|
|
if (newWidget) {
|
2014-12-09 11:12:17 +01:00
|
|
|
newWidget->restoreSettings(m_widgetSettings);
|
2010-07-08 11:15:26 +02:00
|
|
|
newWidget->setCursorSynchronization(m_syncWithEditor);
|
|
|
|
|
addWidget(newWidget);
|
|
|
|
|
setCurrentWidget(newWidget);
|
2014-04-09 17:04:50 +02:00
|
|
|
setFocusProxy(newWidget);
|
2010-07-08 11:15:26 +02:00
|
|
|
}
|
2010-07-22 13:02:47 +02:00
|
|
|
|
|
|
|
|
updateFilterMenu();
|
2010-07-08 11:15:26 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-24 11:15:32 +02:00
|
|
|
OutlineFactory::OutlineFactory()
|
|
|
|
|
{
|
2019-07-16 12:29:20 +02:00
|
|
|
QTC_CHECK(g_outlineFactory.isNull());
|
|
|
|
|
g_outlineFactory = this;
|
2014-06-24 11:15:32 +02:00
|
|
|
setDisplayName(tr("Outline"));
|
|
|
|
|
setId("Outline");
|
|
|
|
|
setPriority(600);
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-08 11:15:26 +02:00
|
|
|
Core::NavigationView OutlineFactory::createWidget()
|
|
|
|
|
{
|
|
|
|
|
Core::NavigationView n;
|
2018-09-20 01:16:01 +03:00
|
|
|
auto placeHolder = new OutlineWidgetStack(this);
|
2010-07-08 11:15:26 +02:00
|
|
|
n.widget = placeHolder;
|
2010-07-14 16:46:54 +02:00
|
|
|
n.dockToolBarWidgets.append(placeHolder->filterButton());
|
2010-07-22 12:58:19 +02:00
|
|
|
n.dockToolBarWidgets.append(placeHolder->toggleSyncButton());
|
2010-07-08 11:15:26 +02:00
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-17 18:31:56 +03:00
|
|
|
void OutlineFactory::saveSettings(QSettings *settings, int position, QWidget *widget)
|
2010-07-16 08:18:56 +02:00
|
|
|
{
|
2018-09-20 01:16:01 +03:00
|
|
|
auto widgetStack = qobject_cast<OutlineWidgetStack *>(widget);
|
2010-07-16 08:18:56 +02:00
|
|
|
Q_ASSERT(widgetStack);
|
2016-09-17 18:31:56 +03:00
|
|
|
widgetStack->saveSettings(settings, position);
|
2010-07-16 08:18:56 +02:00
|
|
|
}
|
|
|
|
|
|
2016-09-17 18:31:56 +03:00
|
|
|
void OutlineFactory::restoreSettings(QSettings *settings, int position, QWidget *widget)
|
2010-07-16 08:18:56 +02:00
|
|
|
{
|
2018-09-20 01:16:01 +03:00
|
|
|
auto widgetStack = qobject_cast<OutlineWidgetStack *>(widget);
|
2010-07-16 08:18:56 +02:00
|
|
|
Q_ASSERT(widgetStack);
|
2016-09-17 18:31:56 +03:00
|
|
|
widgetStack->restoreSettings(settings, position);
|
2010-07-16 08:18:56 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-08 11:15:26 +02:00
|
|
|
} // namespace Internal
|
|
|
|
|
} // namespace TextEditor
|