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
43 QT_BEGIN_NAMESPACE
44
ContentWindow()45 ContentWindow::ContentWindow()
46 : m_contentWidget(HelpEngineWrapper::instance().contentWidget())
47 , m_expandDepth(-2)
48 {
49 TRACE_OBJ
50 m_contentWidget->viewport()->installEventFilter(this);
51 m_contentWidget->setContextMenuPolicy(Qt::CustomContextMenu);
52
53 QVBoxLayout *layout = new QVBoxLayout(this);
54 layout->setContentsMargins(4, 4, 4, 4);
55 layout->addWidget(m_contentWidget);
56
57 connect(m_contentWidget, &QWidget::customContextMenuRequested,
58 this, &ContentWindow::showContextMenu);
59 connect(m_contentWidget, &QHelpContentWidget::linkActivated,
60 this, &ContentWindow::linkActivated);
61
62 QHelpContentModel *contentModel =
63 qobject_cast<QHelpContentModel*>(m_contentWidget->model());
64 connect(contentModel, &QHelpContentModel::contentsCreated,
65 this, &ContentWindow::expandTOC);
66 }
67
~ContentWindow()68 ContentWindow::~ContentWindow()
69 {
70 TRACE_OBJ
71 }
72
syncToContent(const QUrl & url)73 bool ContentWindow::syncToContent(const QUrl& url)
74 {
75 TRACE_OBJ
76 QModelIndex idx = m_contentWidget->indexOf(url);
77 if (!idx.isValid())
78 return false;
79 m_contentWidget->setCurrentIndex(idx);
80 return true;
81 }
82
expandTOC()83 void ContentWindow::expandTOC()
84 {
85 TRACE_OBJ
86 Q_ASSERT(m_expandDepth >= -2);
87 if (m_expandDepth > -2) {
88 expandToDepth(m_expandDepth);
89 m_expandDepth = -2;
90 }
91 }
92
expandToDepth(int depth)93 void 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 - 1);
104 }
105
focusInEvent(QFocusEvent * e)106 void ContentWindow::focusInEvent(QFocusEvent *e)
107 {
108 TRACE_OBJ
109 if (e->reason() != Qt::MouseFocusReason)
110 m_contentWidget->setFocus();
111 }
112
keyPressEvent(QKeyEvent * e)113 void ContentWindow::keyPressEvent(QKeyEvent *e)
114 {
115 TRACE_OBJ
116 if (e->key() == Qt::Key_Escape)
117 emit escapePressed();
118 }
119
eventFilter(QObject * o,QEvent * e)120 bool 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(me->pos());
127 if (!index.isValid())
128 return QWidget::eventFilter(o, 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*>(m_contentWidget->model());
137 if (contentModel) {
138 QHelpContentItem *itm = contentModel->contentItemAt(index);
139 if (itm && HelpViewer::canOpenPage(itm->url().path()))
140 OpenPagesManager::instance()->createPage(itm->url());
141 }
142 } else if (button == Qt::LeftButton) {
143 itemClicked(index);
144 }
145 }
146 }
147 return QWidget::eventFilter(o, e);
148 }
149
150
showContextMenu(const QPoint & pos)151 void ContentWindow::showContextMenu(const QPoint &pos)
152 {
153 TRACE_OBJ
154 if (!m_contentWidget->indexAt(pos).isValid())
155 return;
156
157 QHelpContentModel *contentModel =
158 qobject_cast<QHelpContentModel*>(m_contentWidget->model());
159 QHelpContentItem *itm =
160 contentModel->contentItemAt(m_contentWidget->currentIndex());
161
162 QMenu menu;
163 QAction *curTab = menu.addAction(tr("Open Link"));
164 QAction *newTab = menu.addAction(tr("Open Link in New Tab"));
165 if (!HelpViewer::canOpenPage(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(itm->url());
173 else if (newTab == action)
174 OpenPagesManager::instance()->createPage(itm->url());
175 }
176
itemClicked(const QModelIndex & index)177 void ContentWindow::itemClicked(const QModelIndex &index)
178 {
179 TRACE_OBJ
180 QHelpContentModel *contentModel =
181 qobject_cast<QHelpContentModel*>(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(url);
188 }
189 }
190 }
191
192 QT_END_NAMESPACE
193