1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include "centralwidget.h"
36 #include "helpviewer.h"
37 #include "localhelpmanager.h"
38 #include "topicchooser.h"
40 #include <QtCore/QEvent>
41 #include <QtCore/QTimer>
43 #include <QtGui/QKeyEvent>
44 #include <QtGui/QLayout>
45 #include <QtGui/QPageSetupDialog>
46 #include <QtGui/QPrinter>
47 #include <QtGui/QPrintDialog>
48 #include <QtGui/QPrintPreviewDialog>
49 #include <QtGui/QStackedWidget>
51 #include <QtHelp/QHelpEngine>
52 #include <QtHelp/QHelpSearchEngine>
54 using namespace Help::Internal;
56 CentralWidget *gStaticCentralWidget = 0;
60 CentralWidget::CentralWidget(QWidget *parent)
65 Q_ASSERT(!gStaticCentralWidget);
66 gStaticCentralWidget = this;
68 QVBoxLayout *vboxLayout = new QVBoxLayout(this);
69 vboxLayout->setMargin(0);
70 m_stackedWidget = new QStackedWidget(this);
71 vboxLayout->addWidget(m_stackedWidget);
74 CentralWidget::~CentralWidget()
82 for (int i = 0; i < m_stackedWidget->count(); ++i) {
83 const HelpViewer * const viewer = viewerAt(i);
84 const QUrl &source = viewer->source();
85 if (source.isValid()) {
86 currentPages += source.toString() + QLatin1Char('|');
87 zoomFactors += QString::number(viewer->scale()) + QLatin1Char('|');
91 QHelpEngineCore *engine = &LocalHelpManager::helpEngine();
92 engine->setCustomValue(QLatin1String("LastShownPages"), currentPages);
93 engine->setCustomValue(QLatin1String("LastShownPagesZoom"), zoomFactors);
94 engine->setCustomValue(QLatin1String("LastTabPage"), currentIndex());
97 CentralWidget *CentralWidget::instance()
99 Q_ASSERT(gStaticCentralWidget);
100 return gStaticCentralWidget;
103 bool CentralWidget::hasSelection() const
105 if (HelpViewer* viewer = currentHelpViewer())
106 return !viewer->selectedText().isEmpty();
110 bool CentralWidget::isForwardAvailable() const
112 const HelpViewer* viewer = currentHelpViewer();
114 return viewer->isForwardAvailable();
119 bool CentralWidget::isBackwardAvailable() const
121 const HelpViewer* viewer = currentHelpViewer();
123 return viewer->isBackwardAvailable();
128 HelpViewer* CentralWidget::viewerAt(int index) const
130 return qobject_cast<HelpViewer*> (m_stackedWidget->widget(index));
133 HelpViewer* CentralWidget::currentHelpViewer() const
135 return qobject_cast<HelpViewer*> (m_stackedWidget->currentWidget());
138 void CentralWidget::addPage(HelpViewer *page, bool fromSearch)
140 page->installEventFilter(this);
141 page->setFocus(Qt::OtherFocusReason);
142 connectSignals(page);
143 m_stackedWidget->addWidget(page);
145 connect(currentHelpViewer(), SIGNAL(loadFinished(bool)), this,
146 SLOT(highlightSearchTerms()));
150 void CentralWidget::removePage(int index)
152 const bool currentChanged = (index == currentIndex());
153 m_stackedWidget->removeWidget(m_stackedWidget->widget(index));
155 emit currentViewerChanged();
158 int CentralWidget::currentIndex() const
160 return m_stackedWidget->currentIndex();
163 void CentralWidget::setCurrentPage(HelpViewer *page)
165 m_stackedWidget->setCurrentWidget(page);
166 emit currentViewerChanged();
169 bool CentralWidget::find(const QString &txt, Find::FindFlags flags,
172 return currentHelpViewer()->findText(txt, flags, incremental, false);
177 void CentralWidget::copy()
179 if (HelpViewer* viewer = currentHelpViewer())
183 void CentralWidget::home()
185 if (HelpViewer* viewer = currentHelpViewer())
189 void CentralWidget::zoomIn()
191 HelpViewer* viewer = currentHelpViewer();
196 void CentralWidget::zoomOut()
198 HelpViewer* viewer = currentHelpViewer();
203 void CentralWidget::resetZoom()
205 HelpViewer* viewer = currentHelpViewer();
207 viewer->resetScale();
210 void CentralWidget::forward()
212 if (HelpViewer* viewer = currentHelpViewer())
216 void CentralWidget::nextPage()
218 m_stackedWidget->setCurrentIndex((m_stackedWidget->currentIndex() + 1)
219 % m_stackedWidget->count());
222 void CentralWidget::backward()
224 if (HelpViewer* viewer = currentHelpViewer())
228 void CentralWidget::previousPage()
230 m_stackedWidget->setCurrentIndex((m_stackedWidget->currentIndex() - 1)
231 % m_stackedWidget->count());
234 void CentralWidget::print()
236 #ifndef QT_NO_PRINTER
237 if (HelpViewer* viewer = currentHelpViewer()) {
240 QPrintDialog dlg(printer, this);
241 dlg.setWindowTitle(tr("Print Document"));
242 if (!viewer->selectedText().isEmpty())
243 dlg.addEnabledOption(QAbstractPrintDialog::PrintSelection);
244 dlg.addEnabledOption(QAbstractPrintDialog::PrintPageRange);
245 dlg.addEnabledOption(QAbstractPrintDialog::PrintCollateCopies);
247 if (dlg.exec() == QDialog::Accepted)
248 viewer->print(printer);
253 void CentralWidget::pageSetup()
255 #ifndef QT_NO_PRINTER
257 QPageSetupDialog dlg(printer);
262 void CentralWidget::printPreview()
264 #ifndef QT_NO_PRINTER
266 QPrintPreviewDialog preview(printer, this);
267 connect(&preview, SIGNAL(paintRequested(QPrinter*)),
268 SLOT(printPreview(QPrinter*)));
273 void CentralWidget::setSource(const QUrl &url)
275 if (HelpViewer* viewer = currentHelpViewer()) {
276 viewer->setSource(url);
277 viewer->setFocus(Qt::OtherFocusReason);
281 void CentralWidget::setSourceFromSearch(const QUrl &url)
283 if (HelpViewer* viewer = currentHelpViewer()) {
284 connect(viewer, SIGNAL(loadFinished(bool)), this,
285 SLOT(highlightSearchTerms()));
286 viewer->setSource(url);
287 viewer->setFocus(Qt::OtherFocusReason);
291 void CentralWidget::showTopicChooser(const QMap<QString, QUrl> &links,
292 const QString &keyword)
294 TopicChooser tc(this, keyword, links);
295 if (tc.exec() == QDialog::Accepted)
296 setSource(tc.link());
301 void CentralWidget::focusInEvent(QFocusEvent * /* event */)
303 // If we have a current help viewer then this is the 'focus proxy',
304 // otherwise it's the central widget. This is needed, so an embedding
305 // program can just set the focus to the central widget and it does
306 // The Right Thing(TM)
307 QObject *receiver = m_stackedWidget;
308 if (HelpViewer *viewer = currentHelpViewer())
310 QTimer::singleShot(1, receiver, SLOT(setFocus()));
315 void CentralWidget::highlightSearchTerms()
317 if (HelpViewer *viewer = currentHelpViewer()) {
318 QHelpSearchEngine *searchEngine =
319 LocalHelpManager::helpEngine().searchEngine();
320 QList<QHelpSearchQuery> queryList = searchEngine->query();
323 foreach (const QHelpSearchQuery &query, queryList) {
324 switch (query.fieldName) {
326 case QHelpSearchQuery::ALL: {
327 case QHelpSearchQuery::PHRASE:
328 case QHelpSearchQuery::DEFAULT:
329 case QHelpSearchQuery::ATLEAST:
330 foreach (QString term, query.wordList)
331 terms.append(term.remove(QLatin1String("\"")));
336 foreach (const QString& term, terms)
337 viewer->findText(term, 0, false, true);
338 disconnect(viewer, SIGNAL(loadFinished(bool)), this,
339 SLOT(highlightSearchTerms()));
343 void CentralWidget::printPreview(QPrinter *p)
345 #ifndef QT_NO_PRINTER
346 HelpViewer *viewer = currentHelpViewer();
354 void CentralWidget::handleSourceChanged(const QUrl &url)
356 if (sender() == currentHelpViewer())
357 emit sourceChanged(url);
362 void CentralWidget::initPrinter()
364 #ifndef QT_NO_PRINTER
366 printer = new QPrinter(QPrinter::HighResolution);
370 void CentralWidget::connectSignals(HelpViewer *page)
372 connect(page, SIGNAL(sourceChanged(QUrl)), this, SLOT(handleSourceChanged(QUrl)));
373 connect(page, SIGNAL(forwardAvailable(bool)), this, SIGNAL(forwardAvailable(bool)));
374 connect(page, SIGNAL(backwardAvailable(bool)), this, SIGNAL(backwardAvailable(bool)));
375 connect(page, SIGNAL(printRequested()), this, SLOT(print()));
376 connect(page, SIGNAL(openFindToolBar()), this, SIGNAL(openFindToolBar()));
379 bool CentralWidget::eventFilter(QObject *object, QEvent *e)
381 if (e->type() != QEvent::KeyPress)
382 return QWidget::eventFilter(object, e);
384 HelpViewer *viewer = currentHelpViewer();
385 QKeyEvent *keyEvent = static_cast<QKeyEvent*> (e);
386 if (viewer == object && keyEvent->key() == Qt::Key_Backspace) {
387 if (viewer->isBackwardAvailable()) {
388 #if !defined(QT_NO_WEBKIT)
389 // this helps in case there is an html <input> field
390 if (!viewer->hasFocus())
395 return QWidget::eventFilter(object, e);