helpwidget.cpp 27 KB
Newer Older
1 2
/****************************************************************************
**
3 4
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
5 6 7 8 9 10 11
**
** This file is part of Qt Creator.
**
** 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
12 13 14
** 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.
15
**
16 17 18 19 20 21 22
** 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.
23 24 25 26 27
**
****************************************************************************/

#include "helpwidget.h"

28
#include "bookmarkmanager.h"
29
#include "contentwindow.h"
30
#include "helpconstants.h"
31
#include "helpicons.h"
32 33
#include "helpplugin.h"
#include "helpviewer.h"
34
#include "indexwindow.h"
35
#include "localhelpmanager.h"
36
#include "openpagesmanager.h"
37
#include "searchwidget.h"
38
#include "topicchooser.h"
39 40 41

#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
42
#include <coreplugin/actionmanager/command.h>
43 44 45
#include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h>
#include <coreplugin/findplaceholder.h>
46 47
#include <coreplugin/minisplitter.h>
#include <coreplugin/sidebar.h>
48
#include <texteditor/texteditorconstants.h>
49
#include <utils/qtcassert.h>
50
#include <utils/styledbar.h>
51
#include <utils/utilsicons.h>
52

Sergey Belyashov's avatar
Sergey Belyashov committed
53
#include <QCoreApplication>
54
#include <QHBoxLayout>
55 56 57
#include <QHelpEngine>
#include <QHelpSearchEngine>
#include <QHelpSearchQuery>
58
#include <QMenu>
59 60 61
#include <QPrinter>
#include <QPrintDialog>
#include <QStackedWidget>
62 63
#include <QToolButton>

64 65
static const char kWindowSideBarSettingsKey[] = "Help/WindowSideBar";
static const char kModeSideBarSettingsKey[] = "Help/ModeSideBar";
66 67 68 69

namespace Help {
namespace Internal {

70 71 72 73 74 75 76 77
static void openUrlInWindow(const QUrl &url)
{
    HelpViewer *viewer = HelpPlugin::viewerForHelpViewerLocation(Core::HelpManager::ExternalHelpAlways);
    if (QTC_GUARD(viewer))
        viewer->setSource(url);
    Core::ICore::raiseWindow(viewer);
}

78 79 80 81 82
static bool isBookmarkable(const QUrl &url)
{
    return !url.isEmpty() && url != QUrl(Help::Constants::AboutBlank);
}

83 84
HelpWidget::HelpWidget(const Core::Context &context, WidgetStyle style, QWidget *parent) :
    QWidget(parent),
85
    m_style(style)
86
{
87 88 89 90 91 92 93 94 95 96
    m_viewerStack = new QStackedWidget;

    auto hLayout = new QHBoxLayout(this);
    hLayout->setMargin(0);
    hLayout->setSpacing(0);

    m_sideBarSplitter = new Core::MiniSplitter(this);
    m_sideBarSplitter->setOpaqueResize(false);
    hLayout->addWidget(m_sideBarSplitter);

97
    Utils::StyledBar *toolBar = new Utils::StyledBar();
98 99 100
    QHBoxLayout *layout = new QHBoxLayout(toolBar);
    layout->setSpacing(0);
    layout->setMargin(0);
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118

    auto rightSide = new QWidget(this);
    m_sideBarSplitter->insertWidget(1, rightSide);
    QVBoxLayout *vLayout = new QVBoxLayout(rightSide);
    vLayout->setMargin(0);
    vLayout->setSpacing(0);
    vLayout->addWidget(toolBar);
    vLayout->addWidget(m_viewerStack);
    Core::FindToolBarPlaceHolder *fth = new Core::FindToolBarPlaceHolder(this);
    vLayout->addWidget(fth);

    setFocusProxy(m_viewerStack);

    m_context = new Core::IContext(this);
    m_context->setContext(context);
    m_context->setWidget(m_sideBarSplitter);
    Core::ICore::addContextObject(m_context);

119
    Core::Command *cmd;
120 121 122 123 124 125 126 127
    QToolButton *button;

    if (style == ExternalWindow) {
        static int windowId = 0;
        Core::ICore::registerWindow(this,
                                    Core::Context(Core::Id("Help.Window.").withSuffix(++windowId)));
        setAttribute(Qt::WA_DeleteOnClose);
        setAttribute(Qt::WA_QuitOnClose, false); // don't prevent Qt Creator from closing
128 129
    }
    if (style != SideBarWidget) {
Ulf Hermann's avatar
Ulf Hermann committed
130
        m_toggleSideBarAction = new QAction(Utils::Icons::TOGGLE_SIDEBAR_TOOLBAR.icon(),
Sergey Belyashov's avatar
Sergey Belyashov committed
131 132
                                            QCoreApplication::translate("Core", Core::Constants::TR_SHOW_SIDEBAR),
                                            toolBar);
133 134 135 136 137 138
        m_toggleSideBarAction->setCheckable(true);
        m_toggleSideBarAction->setChecked(false);
        cmd = Core::ActionManager::registerAction(m_toggleSideBarAction,
                                                  Core::Constants::TOGGLE_SIDEBAR, context);
        connect(m_toggleSideBarAction, &QAction::toggled, m_toggleSideBarAction,
                [this](bool checked) {
Sergey Belyashov's avatar
Sergey Belyashov committed
139 140 141 142
                    m_toggleSideBarAction->setText(
                        QCoreApplication::translate("Core",
                                                    checked ? Core::Constants::TR_HIDE_SIDEBAR
                                                            : Core::Constants::TR_SHOW_SIDEBAR));
143 144
                });
        addSideBar();
145
        m_toggleSideBarAction->setChecked(m_sideBar->isVisibleTo(this));
146 147 148 149 150
        connect(m_toggleSideBarAction, &QAction::triggered, m_sideBar, &Core::SideBar::setVisible);
        connect(m_sideBar, &Core::SideBar::sideBarClosed, m_toggleSideBarAction, [this]() {
            m_toggleSideBarAction->setChecked(false);
        });
    }
151 152
    if (style == ExternalWindow)
        layout->addWidget(Core::Command::toolButtonWithAppendedShortcut(m_toggleSideBarAction, cmd));
153

154
    if (style != ModeWidget) {
155
        m_switchToHelp = new QAction(tr("Open in Help Mode"), toolBar);
156
        cmd = Core::ActionManager::registerAction(m_switchToHelp, Constants::CONTEXT_HELP, context);
Montel Laurent's avatar
Montel Laurent committed
157
        connect(m_switchToHelp, &QAction::triggered, this, &HelpWidget::helpModeButtonClicked);
158
        layout->addWidget(Core::Command::toolButtonWithAppendedShortcut(m_switchToHelp, cmd));
159
    }
160

161
    m_homeAction = new QAction(Icons::HOME_TOOLBAR.icon(), tr("Home"), this);
162 163
    cmd = Core::ActionManager::registerAction(m_homeAction, Constants::HELP_HOME, context);
    connect(m_homeAction, &QAction::triggered, this, &HelpWidget::goHome);
164
    layout->addWidget(Core::Command::toolButtonWithAppendedShortcut(m_homeAction, cmd));
165

166
    m_backAction = new QAction(Utils::Icons::PREV_TOOLBAR.icon(), tr("Back"), toolBar);
167
    connect(m_backAction, &QAction::triggered, this, &HelpWidget::backward);
168
    m_backMenu = new QMenu(toolBar);
Montel Laurent's avatar
Montel Laurent committed
169
    connect(m_backMenu, &QMenu::aboutToShow, this, &HelpWidget::updateBackMenu);
170 171 172
    m_backAction->setMenu(m_backMenu);
    cmd = Core::ActionManager::registerAction(m_backAction, Constants::HELP_PREVIOUS, context);
    cmd->setDefaultKeySequence(QKeySequence::Back);
173 174 175
    button = Core::Command::toolButtonWithAppendedShortcut(m_backAction, cmd);
    button->setPopupMode(QToolButton::DelayedPopup);
    layout->addWidget(button);
176

177
    m_forwardAction = new QAction(Utils::Icons::NEXT_TOOLBAR.icon(), tr("Forward"), toolBar);
178
    connect(m_forwardAction, &QAction::triggered, this, &HelpWidget::forward);
179
    m_forwardMenu = new QMenu(toolBar);
Montel Laurent's avatar
Montel Laurent committed
180
    connect(m_forwardMenu, &QMenu::aboutToShow, this, &HelpWidget::updateForwardMenu);
181 182 183
    m_forwardAction->setMenu(m_forwardMenu);
    cmd = Core::ActionManager::registerAction(m_forwardAction, Constants::HELP_NEXT, context);
    cmd->setDefaultKeySequence(QKeySequence::Forward);
184 185 186
    button = Core::Command::toolButtonWithAppendedShortcut(m_forwardAction, cmd);
    button->setPopupMode(QToolButton::DelayedPopup);
    layout->addWidget(button);
187

188
    m_addBookmarkAction = new QAction(Utils::Icons::BOOKMARK_TOOLBAR.icon(), tr("Add Bookmark"), this);
Eike Ziller's avatar
Eike Ziller committed
189
    cmd = Core::ActionManager::registerAction(m_addBookmarkAction, Constants::HELP_ADDBOOKMARK, context);
190 191 192
    cmd->setDefaultKeySequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+M") : tr("Ctrl+M")));
    connect(m_addBookmarkAction, &QAction::triggered, this, &HelpWidget::addBookmark);
    layout->addWidget(new Utils::StyledSeparator(toolBar));
193
    layout->addWidget(Core::Command::toolButtonWithAppendedShortcut(m_addBookmarkAction, cmd));
194

195 196 197
    if (style == ModeWidget) {
        layout->addWidget(new Utils::StyledSeparator(toolBar));
        layout->addWidget(OpenPagesManager::instance().openPagesComboBox(), 10);
198 199 200 201
    } else {
        layout->addWidget(new QLabel(), 10);
    }
    if (style != SideBarWidget) {
202 203 204
        m_filterComboBox = new QComboBox;
        m_filterComboBox->setMinimumContentsLength(15);
        m_filterComboBox->setModel(LocalHelpManager::filterModel());
205
        m_filterComboBox->setCurrentIndex(LocalHelpManager::filterIndex());
206 207 208 209 210 211 212
        layout->addWidget(m_filterComboBox);
        connect(m_filterComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
                LocalHelpManager::instance(), &LocalHelpManager::setFilterIndex);
        connect(LocalHelpManager::instance(), &LocalHelpManager::filterIndexChanged,
                m_filterComboBox, &QComboBox::setCurrentIndex);
    }

213 214
    layout->addStretch();

215 216 217
    m_printAction = new QAction(this);
    Core::ActionManager::registerAction(m_printAction, Core::Constants::PRINT, context);
    connect(m_printAction, &QAction::triggered, this, [this]() { print(currentViewer()); });
218

219
    m_copy = new QAction(this);
220
    Core::ActionManager::registerAction(m_copy, Core::Constants::COPY, context);
221
    connect(m_copy, &QAction::triggered, this, &HelpWidget::copy);
222 223

    Core::ActionContainer *advancedMenu = Core::ActionManager::actionContainer(Core::Constants::M_EDIT_ADVANCED);
Eike Ziller's avatar
Eike Ziller committed
224
    if (QTC_GUARD(advancedMenu)) {
225
        // reuse TextEditor constants to avoid a second pair of menu actions
226 227
        m_scaleUp = new QAction(tr("Increase Font Size"), this);
        cmd = Core::ActionManager::registerAction(m_scaleUp, TextEditor::Constants::INCREASE_FONT_SIZE,
228
                                                  context);
229
        connect(m_scaleUp, &QAction::triggered, this, &HelpWidget::scaleUp);
230 231
        advancedMenu->addAction(cmd, Core::Constants::G_EDIT_FONT);

232 233
        m_scaleDown = new QAction(tr("Decrease Font Size"), this);
        cmd = Core::ActionManager::registerAction(m_scaleDown, TextEditor::Constants::DECREASE_FONT_SIZE,
234
                                                  context);
235
        connect(m_scaleDown, &QAction::triggered, this, &HelpWidget::scaleDown);
236 237
        advancedMenu->addAction(cmd, Core::Constants::G_EDIT_FONT);

238 239
        m_resetScale = new QAction(tr("Reset Font Size"), this);
        cmd = Core::ActionManager::registerAction(m_resetScale, TextEditor::Constants::RESET_FONT_SIZE,
240
                                                  context);
241
        connect(m_resetScale, &QAction::triggered, this, &HelpWidget::resetScale);
242 243
        advancedMenu->addAction(cmd, Core::Constants::G_EDIT_FONT);
    }
244

245
    if (style != ExternalWindow) {
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
        auto openButton = new QToolButton;
        openButton->setIcon(Utils::Icons::SPLIT_HORIZONTAL_TOOLBAR.icon());
        openButton->setPopupMode(QToolButton::InstantPopup);
        openButton->setProperty("noArrow", true);
        layout->addWidget(openButton);
        QMenu *openMenu = new QMenu(openButton);
        if (m_switchToHelp)
            openMenu->addAction(m_switchToHelp);
        if (style == ModeWidget) {
            QAction *openPage = openMenu->addAction(tr("Open in New Page"));
            connect(openPage, &QAction::triggered, this, [this]() {
                if (HelpViewer *viewer = currentViewer())
                    OpenPagesManager::instance().createPage(viewer->source());
            });
        }
        QAction *openExternal = openMenu->addAction(tr("Open in Window"));
        connect(openExternal, &QAction::triggered, this, [this]() {
            if (HelpViewer *viewer = currentViewer()) {
                openUrlInWindow(viewer->source());
                if (m_style == SideBarWidget)
                    emit closeButtonClicked();
            }
        });
        openButton->setMenu(openMenu);

271 272 273
        const Utils::Icon &icon = style == ModeWidget ? Utils::Icons::CLOSE_TOOLBAR
                                                      : Utils::Icons::CLOSE_SPLIT_RIGHT;
        m_closeAction = new QAction(icon.icon(), QString(), toolBar);
Orgad Shaneh's avatar
Orgad Shaneh committed
274
        connect(m_closeAction, &QAction::triggered, this, &HelpWidget::closeButtonClicked);
275 276 277
        button = new QToolButton;
        button->setDefaultAction(m_closeAction);
        layout->addWidget(button);
278 279 280 281 282 283
    }

    if (style != ModeWidget) {
        HelpViewer *viewer = HelpPlugin::createHelpViewer(qreal(0.0));
        addViewer(viewer);
        setCurrentViewer(viewer);
284 285 286 287 288
    }
}

HelpWidget::~HelpWidget()
{
289
    if (m_sideBar) {
290
        m_sideBar->saveSettings(Core::ICore::settings(), sideBarSettingsKey());
291
        Core::ActionManager::unregisterAction(m_contentsAction, Constants::HELP_CONTENTS);
292
        Core::ActionManager::unregisterAction(m_indexAction, Constants::HELP_INDEX);
Eike Ziller's avatar
Eike Ziller committed
293
        Core::ActionManager::unregisterAction(m_bookmarkAction, Constants::HELP_BOOKMARKS);
294
        Core::ActionManager::unregisterAction(m_searchAction, Constants::HELP_SEARCH);
295 296
        if (m_openPagesAction)
            Core::ActionManager::unregisterAction(m_openPagesAction, Constants::HELP_OPENPAGES);
297
    }
298
    Core::ICore::removeContextObject(m_context);
299
    Core::ActionManager::unregisterAction(m_copy, Core::Constants::COPY);
300
    Core::ActionManager::unregisterAction(m_printAction, Core::Constants::PRINT);
301 302
    if (m_toggleSideBarAction)
        Core::ActionManager::unregisterAction(m_toggleSideBarAction, Core::Constants::TOGGLE_SIDEBAR);
303 304
    if (m_switchToHelp)
        Core::ActionManager::unregisterAction(m_switchToHelp, Constants::CONTEXT_HELP);
305
    Core::ActionManager::unregisterAction(m_homeAction, Constants::HELP_HOME);
306 307
    Core::ActionManager::unregisterAction(m_forwardAction, Constants::HELP_NEXT);
    Core::ActionManager::unregisterAction(m_backAction, Constants::HELP_PREVIOUS);
Eike Ziller's avatar
Eike Ziller committed
308
    Core::ActionManager::unregisterAction(m_addBookmarkAction, Constants::HELP_ADDBOOKMARK);
309 310 311 312 313 314
    if (m_scaleUp)
        Core::ActionManager::unregisterAction(m_scaleUp, TextEditor::Constants::INCREASE_FONT_SIZE);
    if (m_scaleDown)
        Core::ActionManager::unregisterAction(m_scaleDown, TextEditor::Constants::DECREASE_FONT_SIZE);
    if (m_resetScale)
        Core::ActionManager::unregisterAction(m_resetScale, TextEditor::Constants::RESET_FONT_SIZE);
315 316
}

317 318 319 320
void HelpWidget::addSideBar()
{
    QMap<QString, Core::Command *> shortcutMap;
    Core::Command *cmd;
321
    bool supportsNewPages = (m_style == ModeWidget);
322

323
    auto contentWindow = new ContentWindow;
324
    auto contentItem = new Core::SideBarItem(contentWindow, Constants::HELP_CONTENTS);
325
    contentWindow->setOpenInNewPageActionVisible(supportsNewPages);
326
    contentWindow->setWindowTitle(HelpPlugin::tr(Constants::SB_CONTENTS));
327 328
    connect(contentWindow, &ContentWindow::linkActivated,
            this, &HelpWidget::open);
Takumi ASAKI's avatar
Takumi ASAKI committed
329
    m_contentsAction = new QAction(HelpPlugin::tr(Constants::SB_CONTENTS), this);
330 331 332
    cmd = Core::ActionManager::registerAction(m_contentsAction, Constants::HELP_CONTENTS, m_context->context());
    cmd->setDefaultKeySequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+Shift+C")
                                                                  : tr("Ctrl+Shift+C")));
333
    shortcutMap.insert(Constants::HELP_CONTENTS, cmd);
334

335
    auto indexWindow = new IndexWindow();
336
    auto indexItem = new Core::SideBarItem(indexWindow, Constants::HELP_INDEX);
337
    indexWindow->setOpenInNewPageActionVisible(supportsNewPages);
338
    indexWindow->setWindowTitle(HelpPlugin::tr(Constants::SB_INDEX));
339 340 341 342
    connect(indexWindow, &IndexWindow::linkActivated,
            this, &HelpWidget::open);
    connect(indexWindow, &IndexWindow::linksActivated,
        this, &HelpWidget::showTopicChooser);
Takumi ASAKI's avatar
Takumi ASAKI committed
343
    m_indexAction = new QAction(HelpPlugin::tr(Constants::SB_INDEX), this);
344 345 346
    cmd = Core::ActionManager::registerAction(m_indexAction, Constants::HELP_INDEX, m_context->context());
    cmd->setDefaultKeySequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+I")
                                                                  : tr("Ctrl+Shift+I")));
347
    shortcutMap.insert(Constants::HELP_INDEX, cmd);
348

Eike Ziller's avatar
Eike Ziller committed
349
    auto bookmarkWidget = new BookmarkWidget(&LocalHelpManager::bookmarkManager());
350
    bookmarkWidget->setWindowTitle(HelpPlugin::tr(Constants::SB_BOOKMARKS));
351
    bookmarkWidget->setOpenInNewPageActionVisible(supportsNewPages);
352
    auto bookmarkItem = new Core::SideBarItem(bookmarkWidget, Constants::HELP_BOOKMARKS);
Eike Ziller's avatar
Eike Ziller committed
353 354 355 356
    connect(bookmarkWidget, &BookmarkWidget::linkActivated, this, &HelpWidget::setSource);
    m_bookmarkAction = new QAction(tr("Activate Help Bookmarks View"), this);
    cmd = Core::ActionManager::registerAction(m_bookmarkAction, Constants::HELP_BOOKMARKS,
                                              m_context->context());
357
    cmd->setDefaultKeySequence(QKeySequence(Core::UseMacShortcuts ? tr("Alt+Meta+M")
Eike Ziller's avatar
Eike Ziller committed
358
                                                                  : tr("Ctrl+Shift+B")));
359
    shortcutMap.insert(Constants::HELP_BOOKMARKS, cmd);
Eike Ziller's avatar
Eike Ziller committed
360

361 362 363 364 365 366 367
    auto searchItem = new SearchSideBarItem;
    connect(searchItem, &SearchSideBarItem::linkActivated, this, &HelpWidget::openFromSearch);
    m_searchAction = new QAction(tr("Activate Help Search View"), this);
    cmd = Core::ActionManager::registerAction(m_searchAction, Constants::HELP_SEARCH,
                                              m_context->context());
    cmd->setDefaultKeySequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+/")
                                                                  : tr("Ctrl+Shift+/")));
368
    shortcutMap.insert(Constants::HELP_SEARCH, cmd);
369

370 371 372
    Core::SideBarItem *openPagesItem = 0;
    if (m_style == ModeWidget) {
        QWidget *openPagesWidget = OpenPagesManager::instance().openPagesWidget();
373
        openPagesWidget->setWindowTitle(HelpPlugin::tr(Constants::SB_OPENPAGES));
374
        openPagesItem = new Core::SideBarItem(openPagesWidget, Constants::HELP_OPENPAGES);
375 376 377 378 379
        m_openPagesAction = new QAction(tr("Activate Open Help Pages View"), this);
        cmd = Core::ActionManager::registerAction(m_openPagesAction, Constants::HELP_OPENPAGES,
                                                  m_context->context());
        cmd->setDefaultKeySequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+O")
                                                                      : tr("Ctrl+Shift+O")));
380
        shortcutMap.insert(Constants::HELP_OPENPAGES, cmd);
381 382
    }

383
    QList<Core::SideBarItem *> itemList;
384
    itemList << contentItem << indexItem << bookmarkItem << searchItem;
385 386
    if (openPagesItem)
         itemList << openPagesItem;
387
    m_sideBar = new Core::SideBar(itemList,
388 389
                                  QList<Core::SideBarItem *>() << contentItem
                                  << (openPagesItem ? openPagesItem : indexItem));
390 391 392 393 394
    m_sideBar->setShortcutMap(shortcutMap);
    m_sideBar->setCloseWhenEmpty(true);
    m_sideBarSplitter->insertWidget(0, m_sideBar);
    m_sideBarSplitter->setStretchFactor(0, 0);
    m_sideBarSplitter->setStretchFactor(1, 1);
395 396
    if (m_style != ModeWidget)
        m_sideBar->setVisible(false);
397
    m_sideBar->resize(250, size().height());
398
    m_sideBar->readSettings(Core::ICore::settings(), sideBarSettingsKey());
399 400
    m_sideBarSplitter->setSizes(QList<int>() << m_sideBar->size().width() << 300);

401
    connect(m_contentsAction, &QAction::triggered, m_sideBar, [this]() {
402
        m_sideBar->activateItem(Constants::HELP_CONTENTS);
403
    });
Eike Ziller's avatar
Eike Ziller committed
404
    connect(m_indexAction, &QAction::triggered, m_sideBar, [this]() {
405
        m_sideBar->activateItem(Constants::HELP_INDEX);
406
    });
Eike Ziller's avatar
Eike Ziller committed
407
    connect(m_bookmarkAction, &QAction::triggered, m_sideBar, [this]() {
408
        m_sideBar->activateItem(Constants::HELP_BOOKMARKS);
Eike Ziller's avatar
Eike Ziller committed
409
    });
410
    connect(m_searchAction, &QAction::triggered, m_sideBar, [this]() {
411
        m_sideBar->activateItem(Constants::HELP_SEARCH);
412
    });
413 414
    if (m_openPagesAction) {
        connect(m_openPagesAction, &QAction::triggered, m_sideBar, [this]() {
415
            m_sideBar->activateItem(Constants::HELP_OPENPAGES);
416 417 418 419 420 421 422 423
        });
    }
}

QString HelpWidget::sideBarSettingsKey() const
{
    switch (m_style) {
    case ModeWidget:
424
        return QString(kModeSideBarSettingsKey);
425
    case ExternalWindow:
426
        return QString(kWindowSideBarSettingsKey);
427 428 429 430 431
    case SideBarWidget:
        QTC_CHECK(false);
        break;
    }
    return QString();
432 433
}

434 435
HelpViewer *HelpWidget::currentViewer() const
{
436 437 438 439 440 441 442 443
    return qobject_cast<HelpViewer *>(m_viewerStack->currentWidget());
}

void HelpWidget::setCurrentViewer(HelpViewer *viewer)
{
    m_viewerStack->setCurrentWidget(viewer);
    m_backAction->setEnabled(viewer->isBackwardAvailable());
    m_forwardAction->setEnabled(viewer->isForwardAvailable());
444
    m_addBookmarkAction->setEnabled(isBookmarkable(viewer->source()));
445 446 447 448 449 450 451 452 453 454
    if (m_style == ExternalWindow)
        updateWindowTitle();
    emit sourceChanged(viewer->source());
}

int HelpWidget::currentIndex() const
{
    return m_viewerStack->currentIndex();
}

455
void HelpWidget::addViewer(HelpViewer *viewer)
456 457 458
{
    m_viewerStack->addWidget(viewer);
    viewer->setFocus(Qt::OtherFocusReason);
459 460
    viewer->setActionVisible(HelpViewer::Action::NewPage, m_style == ModeWidget);
    viewer->setActionVisible(HelpViewer::Action::ExternalWindow, m_style != ExternalWindow);
461
    connect(viewer, &HelpViewer::sourceChanged, this, [viewer, this](const QUrl &url) {
462 463
        if (currentViewer() == viewer) {
            m_addBookmarkAction->setEnabled(isBookmarkable(url));
464
            emit sourceChanged(url);
465
        }
466 467 468 469 470 471 472 473 474 475 476 477 478
    });
    connect(viewer, &HelpViewer::forwardAvailable, this, [viewer, this](bool available) {
        if (currentViewer() == viewer)
            m_forwardAction->setEnabled(available);
    });
    connect(viewer, &HelpViewer::backwardAvailable, this, [viewer, this](bool available) {
        if (currentViewer() == viewer)
            m_backAction->setEnabled(available);
    });
    connect(viewer, &HelpViewer::printRequested, this, [viewer, this]() {
        print(viewer);
    });
    if (m_style == ExternalWindow)
Montel Laurent's avatar
Montel Laurent committed
479
        connect(viewer, &HelpViewer::titleChanged, this, &HelpWidget::updateWindowTitle);
480

481
    connect(viewer, &HelpViewer::loadFinished, this, &HelpWidget::highlightSearchTerms);
482 483 484
    connect(viewer, &HelpViewer::newPageRequested, [](const QUrl &url) {
        OpenPagesManager::instance().createPage(url);
    });
485
    connect(viewer, &HelpViewer::externalPageRequested, this, &openUrlInWindow);
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511

    updateCloseButton();
}

void HelpWidget::removeViewerAt(int index)
{
    QWidget *viewerWidget = m_viewerStack->widget(index);
    QTC_ASSERT(viewerWidget, return);
    m_viewerStack->removeWidget(viewerWidget);
    // do not delete, that is done in the model
    // delete viewerWidget;
    if (m_viewerStack->currentWidget())
        setCurrentViewer(qobject_cast<HelpViewer *>(m_viewerStack->currentWidget()));
    updateCloseButton();
}

int HelpWidget::viewerCount() const
{
    return m_viewerStack->count();
}

HelpViewer *HelpWidget::viewerAt(int index) const
{
    return qobject_cast<HelpViewer *>(m_viewerStack->widget(index));
}

512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
void HelpWidget::open(const QUrl &url, bool newPage)
{
    if (newPage)
        OpenPagesManager::instance().createPage(url);
    else
        setSource(url);
}

void HelpWidget::showTopicChooser(const QMap<QString, QUrl> &links,
    const QString &keyword, bool newPage)
{
    TopicChooser tc(this, keyword, links);
    if (tc.exec() == QDialog::Accepted)
        open(tc.link(), newPage);
}

528 529 530 531 532 533
void HelpWidget::activateSideBarItem(const QString &id)
{
    QTC_ASSERT(m_sideBar, return);
    m_sideBar->activateItem(id);
}

534 535 536 537 538 539 540 541
void HelpWidget::setSource(const QUrl &url)
{
    HelpViewer* viewer = currentViewer();
    QTC_ASSERT(viewer, return);
    viewer->setSource(url);
    viewer->setFocus(Qt::OtherFocusReason);
}

542
void HelpWidget::openFromSearch(const QUrl &url, const QStringList &searchTerms, bool newPage)
543
{
544
    m_searchTerms = searchTerms;
545
    if (newPage)
546
        OpenPagesManager::instance().createPage(url);
547 548 549 550 551 552
    else {
        HelpViewer* viewer = currentViewer();
        QTC_ASSERT(viewer, return);
        viewer->setSource(url);
        viewer->setFocus(Qt::OtherFocusReason);
    }
553 554
}

555 556 557 558 559
void HelpWidget::closeEvent(QCloseEvent *)
{
    emit aboutToClose();
}

560 561 562
void HelpWidget::updateBackMenu()
{
    m_backMenu->clear();
563 564
    QTC_ASSERT(currentViewer(), return);
    currentViewer()->addBackHistoryItems(m_backMenu);
565 566 567 568 569
}

void HelpWidget::updateForwardMenu()
{
    m_forwardMenu->clear();
570 571
    QTC_ASSERT(currentViewer(), return);
    currentViewer()->addForwardHistoryItems(m_forwardMenu);
572 573
}

574 575
void HelpWidget::updateWindowTitle()
{
576 577
    QTC_ASSERT(currentViewer(), return);
    const QString pageTitle = currentViewer()->title();
578 579 580 581 582 583
    if (pageTitle.isEmpty())
        setWindowTitle(tr("Help"));
    else
        setWindowTitle(tr("Help - %1").arg(pageTitle));
}

584
void HelpWidget::helpModeButtonClicked()
585
{
586 587
    QTC_ASSERT(currentViewer(), return);
    emit openHelpMode(currentViewer()->source());
588 589
    if (m_style == ExternalWindow)
        close();
590 591
}

592 593 594
void HelpWidget::updateCloseButton()
{
    if (m_style == ModeWidget) {
595
        const bool closeOnReturn = LocalHelpManager::returnOnClose();
596 597 598 599
        m_closeAction->setEnabled(closeOnReturn || m_viewerStack->count() > 1);
    }
}

600 601 602 603 604 605 606 607 608 609 610 611
void HelpWidget::goHome()
{
    if (HelpViewer *viewer = currentViewer())
        viewer->home();
}

void HelpWidget::addBookmark()
{
    HelpViewer *viewer = currentViewer();
    QTC_ASSERT(viewer, return);

    const QString &url = viewer->source().toString();
612
    if (!isBookmarkable(url))
613 614 615 616 617 618
        return;

    BookmarkManager *manager = &LocalHelpManager::bookmarkManager();
    manager->showBookmarkDialog(this, viewer->title(), url);
}

619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672
void HelpWidget::copy()
{
    QTC_ASSERT(currentViewer(), return);
    currentViewer()->copy();
}

void HelpWidget::forward()
{
    QTC_ASSERT(currentViewer(), return);
    currentViewer()->forward();
}

void HelpWidget::backward()
{
    QTC_ASSERT(currentViewer(), return);
    currentViewer()->backward();
}

void HelpWidget::scaleUp()
{
    QTC_ASSERT(currentViewer(), return);
    currentViewer()->scaleUp();
}

void HelpWidget::scaleDown()
{
    QTC_ASSERT(currentViewer(), return);
    currentViewer()->scaleDown();
}

void HelpWidget::resetScale()
{
    QTC_ASSERT(currentViewer(), return);
    currentViewer()->resetScale();
}

void HelpWidget::print(HelpViewer *viewer)
{
    QTC_ASSERT(viewer, return);
    if (!m_printer)
        m_printer = new QPrinter(QPrinter::HighResolution);
    QPrintDialog dlg(m_printer, this);
    dlg.setWindowTitle(tr("Print Documentation"));
    if (!viewer->selectedText().isEmpty())
        dlg.addEnabledOption(QAbstractPrintDialog::PrintSelection);
    dlg.addEnabledOption(QAbstractPrintDialog::PrintPageRange);
    dlg.addEnabledOption(QAbstractPrintDialog::PrintCollateCopies);

    if (dlg.exec() == QDialog::Accepted)
        viewer->print(m_printer);
}

void HelpWidget::highlightSearchTerms()
{
673 674 675 676 677 678 679
    if (m_searchTerms.isEmpty())
        return;
    HelpViewer *viewer = qobject_cast<HelpViewer *>(sender());
    QTC_ASSERT(viewer, return);
    foreach (const QString& term, m_searchTerms)
        viewer->findText(term, 0, false, true);
    m_searchTerms.clear();
680 681
}

682 683
} // Internal
} // Help