1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
31 **************************************************************************/
33 #include "centralwidget.h"
35 #include "helpviewer.h"
36 #include "localhelpmanager.h"
37 #include "topicchooser.h"
39 #include <QtCore/QEvent>
40 #include <QtCore/QTimer>
42 #include <QtGui/QKeyEvent>
43 #include <QtGui/QLayout>
44 #include <QtGui/QPageSetupDialog>
45 #include <QtGui/QPrinter>
46 #include <QtGui/QPrintDialog>
47 #include <QtGui/QPrintPreviewDialog>
48 #include <QtGui/QStackedWidget>
50 #include <QtHelp/QHelpEngine>
51 #include <QtHelp/QHelpSearchEngine>
53 using namespace Help::Internal;
55 CentralWidget *gStaticCentralWidget = 0;
59 CentralWidget::CentralWidget(QWidget *parent)
64 Q_ASSERT(!gStaticCentralWidget);
65 gStaticCentralWidget = this;
67 QVBoxLayout *vboxLayout = new QVBoxLayout(this);
68 vboxLayout->setMargin(0);
69 m_stackedWidget = new QStackedWidget(this);
70 vboxLayout->addWidget(m_stackedWidget);
73 CentralWidget::~CentralWidget()
81 for (int i = 0; i < m_stackedWidget->count(); ++i) {
82 const HelpViewer * const viewer = viewerAt(i);
83 const QUrl &source = viewer->source();
84 if (source.isValid()) {
85 currentPages += source.toString() + QLatin1Char('|');
86 zoomFactors += QString::number(viewer->scale()) + QLatin1Char('|');
90 QHelpEngineCore *engine = &LocalHelpManager::helpEngine();
91 engine->setCustomValue(QLatin1String("LastShownPages"), currentPages);
92 engine->setCustomValue(QLatin1String("LastShownPagesZoom"), zoomFactors);
93 engine->setCustomValue(QLatin1String("LastTabPage"), currentIndex());
96 CentralWidget *CentralWidget::instance()
98 Q_ASSERT(gStaticCentralWidget);
99 return gStaticCentralWidget;
102 bool CentralWidget::hasSelection() const
104 if (HelpViewer* viewer = currentHelpViewer())
105 return !viewer->selectedText().isEmpty();
109 bool CentralWidget::isForwardAvailable() const
111 const HelpViewer* viewer = currentHelpViewer();
113 return viewer->isForwardAvailable();
118 bool CentralWidget::isBackwardAvailable() const
120 const HelpViewer* viewer = currentHelpViewer();
122 return viewer->isBackwardAvailable();
127 HelpViewer* CentralWidget::viewerAt(int index) const
129 return qobject_cast<HelpViewer*> (m_stackedWidget->widget(index));
132 HelpViewer* CentralWidget::currentHelpViewer() const
134 return qobject_cast<HelpViewer*> (m_stackedWidget->currentWidget());
137 void CentralWidget::addPage(HelpViewer *page, bool fromSearch)
139 page->installEventFilter(this);
140 page->setFocus(Qt::OtherFocusReason);
141 connectSignals(page);
142 m_stackedWidget->addWidget(page);
144 connect(currentHelpViewer(), SIGNAL(loadFinished(bool)), this,
145 SLOT(highlightSearchTerms()));
149 void CentralWidget::removePage(int index)
151 const bool currentChanged = (index == currentIndex());
152 m_stackedWidget->removeWidget(m_stackedWidget->widget(index));
154 emit currentViewerChanged();
157 int CentralWidget::currentIndex() const
159 return m_stackedWidget->currentIndex();
162 void CentralWidget::setCurrentPage(HelpViewer *page)
164 m_stackedWidget->setCurrentWidget(page);
165 emit currentViewerChanged();
168 bool CentralWidget::find(const QString &txt, Find::FindFlags flags,
169 bool incremental, bool *wrapped)
171 return currentHelpViewer()->findText(txt, flags, incremental, false, wrapped);
176 void CentralWidget::copy()
178 if (HelpViewer* viewer = currentHelpViewer())
182 void CentralWidget::home()
184 if (HelpViewer* viewer = currentHelpViewer())
188 void CentralWidget::zoomIn()
190 HelpViewer* viewer = currentHelpViewer();
195 void CentralWidget::zoomOut()
197 HelpViewer* viewer = currentHelpViewer();
202 void CentralWidget::resetZoom()
204 HelpViewer* viewer = currentHelpViewer();
206 viewer->resetScale();
209 void CentralWidget::forward()
211 if (HelpViewer* viewer = currentHelpViewer())
215 void CentralWidget::nextPage()
217 m_stackedWidget->setCurrentIndex((m_stackedWidget->currentIndex() + 1)
218 % m_stackedWidget->count());
221 void CentralWidget::backward()
223 if (HelpViewer* viewer = currentHelpViewer())
227 void CentralWidget::previousPage()
229 m_stackedWidget->setCurrentIndex((m_stackedWidget->currentIndex() - 1)
230 % m_stackedWidget->count());
233 void CentralWidget::print()
235 #ifndef QT_NO_PRINTER
236 if (HelpViewer* viewer = currentHelpViewer()) {
239 QPrintDialog dlg(printer, this);
240 dlg.setWindowTitle(tr("Print Document"));
241 if (!viewer->selectedText().isEmpty())
242 dlg.addEnabledOption(QAbstractPrintDialog::PrintSelection);
243 dlg.addEnabledOption(QAbstractPrintDialog::PrintPageRange);
244 dlg.addEnabledOption(QAbstractPrintDialog::PrintCollateCopies);
246 if (dlg.exec() == QDialog::Accepted)
247 viewer->print(printer);
252 void CentralWidget::pageSetup()
254 #ifndef QT_NO_PRINTER
256 QPageSetupDialog dlg(printer);
261 void CentralWidget::printPreview()
263 #ifndef QT_NO_PRINTER
265 QPrintPreviewDialog preview(printer, this);
266 connect(&preview, SIGNAL(paintRequested(QPrinter*)),
267 SLOT(printPreview(QPrinter*)));
272 void CentralWidget::setSource(const QUrl &url)
274 if (HelpViewer* viewer = currentHelpViewer()) {
275 viewer->setSource(url);
276 viewer->setFocus(Qt::OtherFocusReason);
280 void CentralWidget::setSourceFromSearch(const QUrl &url)
282 if (HelpViewer* viewer = currentHelpViewer()) {
283 connect(viewer, SIGNAL(loadFinished(bool)), this,
284 SLOT(highlightSearchTerms()));
285 viewer->setSource(url);
286 viewer->setFocus(Qt::OtherFocusReason);
290 void CentralWidget::showTopicChooser(const QMap<QString, QUrl> &links,
291 const QString &keyword)
293 TopicChooser tc(this, keyword, links);
294 if (tc.exec() == QDialog::Accepted)
295 setSource(tc.link());
300 void CentralWidget::focusInEvent(QFocusEvent * /* event */)
302 // If we have a current help viewer then this is the 'focus proxy',
303 // otherwise it's the central widget. This is needed, so an embedding
304 // program can just set the focus to the central widget and it does
305 // The Right Thing(TM)
306 QObject *receiver = m_stackedWidget;
307 if (HelpViewer *viewer = currentHelpViewer())
309 QTimer::singleShot(1, receiver, SLOT(setFocus()));
314 void CentralWidget::highlightSearchTerms()
316 if (HelpViewer *viewer = currentHelpViewer()) {
317 QHelpSearchEngine *searchEngine =
318 LocalHelpManager::helpEngine().searchEngine();
319 QList<QHelpSearchQuery> queryList = searchEngine->query();
322 foreach (const QHelpSearchQuery &query, queryList) {
323 switch (query.fieldName) {
325 case QHelpSearchQuery::ALL: {
326 case QHelpSearchQuery::PHRASE:
327 case QHelpSearchQuery::DEFAULT:
328 case QHelpSearchQuery::ATLEAST:
329 foreach (QString term, query.wordList)
330 terms.append(term.remove(QLatin1String("\"")));
335 foreach (const QString& term, terms)
336 viewer->findText(term, 0, false, true);
337 disconnect(viewer, SIGNAL(loadFinished(bool)), this,
338 SLOT(highlightSearchTerms()));
342 void CentralWidget::printPreview(QPrinter *p)
344 #ifndef QT_NO_PRINTER
345 HelpViewer *viewer = currentHelpViewer();
353 void CentralWidget::handleSourceChanged(const QUrl &url)
355 if (sender() == currentHelpViewer())
356 emit sourceChanged(url);
361 void CentralWidget::initPrinter()
363 #ifndef QT_NO_PRINTER
365 printer = new QPrinter(QPrinter::HighResolution);
369 void CentralWidget::connectSignals(HelpViewer *page)
371 connect(page, SIGNAL(sourceChanged(QUrl)), this, SLOT(handleSourceChanged(QUrl)));
372 connect(page, SIGNAL(forwardAvailable(bool)), this, SIGNAL(forwardAvailable(bool)));
373 connect(page, SIGNAL(backwardAvailable(bool)), this, SIGNAL(backwardAvailable(bool)));
374 connect(page, SIGNAL(printRequested()), this, SLOT(print()));
375 connect(page, SIGNAL(openFindToolBar()), this, SIGNAL(openFindToolBar()));
378 bool CentralWidget::eventFilter(QObject *object, QEvent *e)
380 if (e->type() != QEvent::KeyPress)
381 return QWidget::eventFilter(object, e);
383 HelpViewer *viewer = currentHelpViewer();
384 QKeyEvent *keyEvent = static_cast<QKeyEvent*> (e);
385 if (viewer == object && keyEvent->key() == Qt::Key_Backspace) {
386 if (viewer->isBackwardAvailable()) {
387 #if !defined(QT_NO_WEBKIT)
388 // this helps in case there is an html <input> field
389 if (!viewer->hasFocus())
394 return QWidget::eventFilter(object, e);