1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Assistant of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include "contentwindow.h"
30
31#include "centralwidget.h"
32#include "helpenginewrapper.h"
33#include "helpviewer.h"
34#include "openpagesmanager.h"
35#include "tracer.h"
36
37#include <QtWidgets/QLayout>
38#include <QtGui/QFocusEvent>
39#include <QtWidgets/QMenu>
40
41#include <QtHelp/QHelpContentWidget>
42
43QT_BEGIN_NAMESPACE
44
45ContentWindow::ContentWindow()
46 : m_contentWidget(HelpEngineWrapper::instance().contentWidget())
47 , m_expandDepth(-2)
48{
49 TRACE_OBJ
50 m_contentWidget->viewport()->installEventFilter(filterObj: this);
51 m_contentWidget->setContextMenuPolicy(Qt::CustomContextMenu);
52
53 QVBoxLayout *layout = new QVBoxLayout(this);
54 layout->setContentsMargins(left: 4, top: 4, right: 4, bottom: 4);
55 layout->addWidget(m_contentWidget);
56
57 connect(sender: m_contentWidget, signal: &QWidget::customContextMenuRequested,
58 receiver: this, slot: &ContentWindow::showContextMenu);
59 connect(sender: m_contentWidget, signal: &QHelpContentWidget::linkActivated,
60 receiver: this, slot: &ContentWindow::linkActivated);
61
62 QHelpContentModel *contentModel =
63 qobject_cast<QHelpContentModel*>(object: m_contentWidget->model());
64 connect(sender: contentModel, signal: &QHelpContentModel::contentsCreated,
65 receiver: this, slot: &ContentWindow::expandTOC);
66}
67
68ContentWindow::~ContentWindow()
69{
70 TRACE_OBJ
71}
72
73bool ContentWindow::syncToContent(const QUrl& url)
74{
75 TRACE_OBJ
76 QModelIndex idx = m_contentWidget->indexOf(link: url);
77 if (!idx.isValid())
78 return false;
79 m_contentWidget->setCurrentIndex(idx);
80 return true;
81}
82
83void ContentWindow::expandTOC()
84{
85 TRACE_OBJ
86 Q_ASSERT(m_expandDepth >= -2);
87 if (m_expandDepth > -2) {
88 expandToDepth(depth: m_expandDepth);
89 m_expandDepth = -2;
90 }
91}
92
93void ContentWindow::expandToDepth(int depth)
94{
95 TRACE_OBJ
96 Q_ASSERT(depth >= -2);
97 m_expandDepth = depth;
98 if (depth == -1)
99 m_contentWidget->expandAll();
100 else if (depth == 0)
101 m_contentWidget->collapseAll();
102 else
103 m_contentWidget->expandToDepth(depth: depth - 1);
104}
105
106void ContentWindow::focusInEvent(QFocusEvent *e)
107{
108 TRACE_OBJ
109 if (e->reason() != Qt::MouseFocusReason)
110 m_contentWidget->setFocus();
111}
112
113void ContentWindow::keyPressEvent(QKeyEvent *e)
114{
115 TRACE_OBJ
116 if (e->key() == Qt::Key_Escape)
117 emit escapePressed();
118}
119
120bool ContentWindow::eventFilter(QObject *o, QEvent *e)
121{
122 TRACE_OBJ
123 if (m_contentWidget && o == m_contentWidget->viewport()
124 && e->type() == QEvent::MouseButtonRelease) {
125 QMouseEvent *me = static_cast<QMouseEvent*>(e);
126 const QModelIndex &index = m_contentWidget->indexAt(p: me->pos());
127 if (!index.isValid())
128 return QWidget::eventFilter(watched: o, event: e);
129
130 const Qt::MouseButtons button = me->button();
131 QItemSelectionModel *sm = m_contentWidget->selectionModel();
132 if (sm->isSelected(index)) {
133 if ((button == Qt::LeftButton && (me->modifiers() & Qt::ControlModifier))
134 || (button == Qt::MiddleButton)) {
135 QHelpContentModel *contentModel =
136 qobject_cast<QHelpContentModel*>(object: m_contentWidget->model());
137 if (contentModel) {
138 QHelpContentItem *itm = contentModel->contentItemAt(index);
139 if (itm && HelpViewer::canOpenPage(url: itm->url().path()))
140 OpenPagesManager::instance()->createPage(url: itm->url());
141 }
142 } else if (button == Qt::LeftButton) {
143 itemClicked(index);
144 }
145 }
146 }
147 return QWidget::eventFilter(watched: o, event: e);
148}
149
150
151void ContentWindow::showContextMenu(const QPoint &pos)
152{
153 TRACE_OBJ
154 if (!m_contentWidget->indexAt(p: pos).isValid())
155 return;
156
157 QHelpContentModel *contentModel =
158 qobject_cast<QHelpContentModel*>(object: m_contentWidget->model());
159 QHelpContentItem *itm =
160 contentModel->contentItemAt(index: m_contentWidget->currentIndex());
161
162 QMenu menu;
163 QAction *curTab = menu.addAction(text: tr(s: "Open Link"));
164 QAction *newTab = menu.addAction(text: tr(s: "Open Link in New Tab"));
165 if (!HelpViewer::canOpenPage(url: itm->url().path()))
166 newTab->setEnabled(false);
167
168 menu.move(m_contentWidget->mapToGlobal(pos));
169
170 QAction *action = menu.exec();
171 if (curTab == action)
172 emit linkActivated(link: itm->url());
173 else if (newTab == action)
174 OpenPagesManager::instance()->createPage(url: itm->url());
175}
176
177void ContentWindow::itemClicked(const QModelIndex &index)
178{
179 TRACE_OBJ
180 QHelpContentModel *contentModel =
181 qobject_cast<QHelpContentModel*>(object: m_contentWidget->model());
182
183 if (contentModel) {
184 if (QHelpContentItem *itm = contentModel->contentItemAt(index)) {
185 const QUrl &url = itm->url();
186 if (url != CentralWidget::instance()->currentSource())
187 emit linkActivated(link: url);
188 }
189 }
190}
191
192QT_END_NAMESPACE
193

source code of qttools/src/assistant/assistant/contentwindow.cpp