/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Assistant of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "tracer.h"

#include "centralwidget.h"
#include "findwidget.h"
#include "helpenginewrapper.h"
#include "searchwidget.h"
#include "mainwindow.h"
#include "../shared/collectionconfiguration.h"

#if defined(QT_NO_WEBKIT)
#include "helpviewer_qtb.h"
#else
#include "helpviewer_qwv.h"
#endif // QT_NO_WEBKIT

#include <QtCore/QTimer>

#include <QtGui/QApplication>
#include <QtGui/QKeyEvent>
#include <QtGui/QLayout>
#include <QtGui/QMenu>
#include <QtGui/QPrinter>
#include <QtGui/QTabBar>
#include <QtGui/QTabWidget>
#include <QtGui/QTextBrowser>
#include <QtGui/QToolButton>
#include <QtGui/QPageSetupDialog>
#include <QtGui/QPrintDialog>
#include <QtGui/QPrintPreviewDialog>

#include <QtHelp/QHelpSearchEngine>

QT_BEGIN_NAMESPACE

namespace {
    HelpViewer* helpViewerFromTabPosition(const QTabWidget *widget,
        const QPoint &point)
    {
        TRACE_OBJ
        QTabBar *tabBar = qFindChild<QTabBar*>(widget);
        for (int i = 0; i < tabBar->count(); ++i) {
            if (tabBar->tabRect(i).contains(point))
                return qobject_cast<HelpViewer*>(widget->widget(i));
        }
        return 0;
    }
    CentralWidget *staticCentralWidget = 0;
}

// -- CentralWidget

CentralWidget::CentralWidget(MainWindow *parent)
    : QWidget(parent)
    , lastTabPage(0)
    , tabWidget(0)
    , findWidget(0)
    , printer(0)
    , usesDefaultCollection(parent->usesDefaultCollection())
    , m_searchWidget(0)
{
    TRACE_OBJ
    globalActionList.clear();
    staticCentralWidget = this;
    QVBoxLayout *vboxLayout = new QVBoxLayout(this);
    QString resourcePath = QLatin1String(":/trolltech/assistant/images/");

    vboxLayout->setMargin(0);
    tabWidget = new QTabWidget(this);
#ifndef Q_OS_MAC
    resourcePath.append(QLatin1String("win"));
#else
    resourcePath.append(QLatin1String("mac"));
    tabWidget->setDocumentMode(true);
#endif

    connect(tabWidget, SIGNAL(currentChanged(int)), this,
        SLOT(currentPageChanged(int)));

    QToolButton *newTabButton = new QToolButton(this);
    newTabButton->setAutoRaise(true);
    newTabButton->setToolTip(tr("Add new page"));
    newTabButton->setIcon(QIcon(resourcePath + QLatin1String("/addtab.png")));

    tabWidget->setCornerWidget(newTabButton, Qt::TopLeftCorner);
    connect(newTabButton, SIGNAL(clicked()), this, SLOT(newTab()));

    QToolButton *closeTabButton = new QToolButton(this);
    closeTabButton->setEnabled(false);
    closeTabButton->setAutoRaise(true);
    closeTabButton->setToolTip(tr("Close current page"));
    closeTabButton->setIcon(QIcon(resourcePath + QLatin1String("/closetab.png")));

    tabWidget->setCornerWidget(closeTabButton, Qt::TopRightCorner);
    connect(closeTabButton, SIGNAL(clicked()), this, SLOT(closeTab()));

    vboxLayout->addWidget(tabWidget);

    findWidget = new FindWidget(this);
    vboxLayout->addWidget(findWidget);
    findWidget->hide();

    connect(findWidget, SIGNAL(findNext()), this, SLOT(findNext()));
    connect(findWidget, SIGNAL(findPrevious()), this, SLOT(findPrevious()));
    connect(findWidget, SIGNAL(find(QString, bool)), this,
        SLOT(find(QString, bool)));
    connect(findWidget, SIGNAL(escapePressed()), this, SLOT(activateTab()));

    QTabBar *tabBar = qFindChild<QTabBar*>(tabWidget);
    if (tabBar) {
        tabBar->installEventFilter(this);
        tabBar->setContextMenuPolicy(Qt::CustomContextMenu);
        connect(tabBar, SIGNAL(customContextMenuRequested(QPoint)), this,
            SLOT(showTabBarContextMenu(QPoint)));
    }

#if defined(QT_NO_WEBKIT)
    QPalette p = palette();
    p.setColor(QPalette::Inactive, QPalette::Highlight,
        p.color(QPalette::Active, QPalette::Highlight));
    p.setColor(QPalette::Inactive, QPalette::HighlightedText,
        p.color(QPalette::Active, QPalette::HighlightedText));
    setPalette(p);
#endif
}

CentralWidget::~CentralWidget()
{
    TRACE_OBJ
#ifndef QT_NO_PRINTER
    delete printer;
#endif

    QStringList zoomFactors;
    QStringList currentPages;
    bool searchAttached = m_searchWidget->isAttached();

    int i = searchAttached ? 1 : 0;
    for (; i < tabWidget->count(); ++i) {
        HelpViewer *viewer = qobject_cast<HelpViewer*>(tabWidget->widget(i));
        if (viewer && viewer->source().isValid()) {
            currentPages << viewer->source().toString();
            zoomFactors << QString::number(viewer->scale());
        }
    }

    HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
    helpEngine.setLastTabPage(tabWidget->currentIndex());
    helpEngine.setLastShownPages(currentPages);
    helpEngine.setSearchWasAttached(searchAttached);
    helpEngine.setLastZoomFactors(zoomFactors);
}

CentralWidget *CentralWidget::instance()
{
    TRACE_OBJ
    return staticCentralWidget;
}

void CentralWidget::newTab()
{
    TRACE_OBJ
    HelpViewer *viewer = currentHelpViewer();
#if !defined(QT_NO_WEBKIT)
    if (viewer && viewer->hasLoadFinished())
#else
    if (viewer)
#endif
        setSourceInNewTab(viewer->source());
}

void CentralWidget::zoomIn()
{
    TRACE_OBJ
    HelpViewer *viewer = currentHelpViewer();
    if (viewer)
        viewer->scaleUp();

    if (tabWidget->currentWidget() == m_searchWidget)
        m_searchWidget->zoomIn();
}

void CentralWidget::zoomOut()
{
    TRACE_OBJ
    HelpViewer *viewer = currentHelpViewer();
    if (viewer)
        viewer->scaleDown();

    if (tabWidget->currentWidget() == m_searchWidget)
        m_searchWidget->zoomOut();
}

void CentralWidget::nextPage()
{
    TRACE_OBJ
    int index = tabWidget->currentIndex() + 1;
    if (index >= tabWidget->count())
        index = 0;
    tabWidget->setCurrentIndex(index);
}

void CentralWidget::resetZoom()
{
    TRACE_OBJ
    if (HelpViewer *viewer = currentHelpViewer())
        viewer->resetScale();

    if (tabWidget->currentWidget() == m_searchWidget)
        m_searchWidget->resetZoom();
}

void CentralWidget::previousPage()
{
    TRACE_OBJ
    int index = tabWidget->currentIndex() -1;
    if (index < 0)
        index = tabWidget->count() -1;
    tabWidget->setCurrentIndex(index);
}

void CentralWidget::closeTab()
{
    TRACE_OBJ
    HelpViewer *viewer = currentHelpViewer();
    if (!viewer|| tabWidget->count() == 1)
        return;

    tabWidget->removeTab(tabWidget->indexOf(viewer));
    QTimer::singleShot(0, viewer, SLOT(deleteLater()));
}

void CentralWidget::setSource(const QUrl &url)
{
    TRACE_OBJ
    HelpViewer *viewer = currentHelpViewer();
    HelpViewer *lastViewer =
        qobject_cast<HelpViewer*>(tabWidget->widget(lastTabPage));

    if (!viewer && !lastViewer) {
        viewer = new HelpViewer(this);
        viewer->installEventFilter(this);
        lastTabPage = tabWidget->addTab(viewer, QString());
        tabWidget->setCurrentIndex(lastTabPage);
        connectSignals();
    } else {
        viewer = lastViewer;
    }

    viewer->setSource(url);
    currentPageChanged(lastTabPage);
    viewer->setFocus(Qt::OtherFocusReason);
    tabWidget->setCurrentIndex(lastTabPage);
    tabWidget->setTabText(lastTabPage, quoteTabTitle(viewer->documentTitle()));
}

void CentralWidget::setupWidget()
{
    TRACE_OBJ
    HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
    int option = helpEngine.startOption();
    if (option != ShowLastPages) {
        QString homePage;
        if (option == ShowHomePage)
            homePage = helpEngine.homePage();
        else if (option == ShowBlankPage)
            homePage = QLatin1String("about:blank");
        setSource(homePage);
    } else {
        setLastShownPages();
    }
}

void CentralWidget::setLastShownPages()
{
    TRACE_OBJ
    HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
    const QStringList &lastShownPageList = helpEngine.lastShownPages();
    const int pageCount = lastShownPageList.count();
    if (pageCount == 0) {
        if (usesDefaultCollection)
            setSource(QUrl(QLatin1String("help")));
        else
            setSource(QUrl(QLatin1String("about:blank")));
        return;
    }
    QStringList zoomFactors = helpEngine.lastZoomFactors();
    while (zoomFactors.count() < pageCount)
        zoomFactors.append(CollectionConfiguration::DefaultZoomFactor);

    const bool searchIsAttached = m_searchWidget->isAttached();
    const bool searchWasAttached = helpEngine.searchWasAttached();
    int tabToShow = helpEngine.lastTabPage();
    if (searchWasAttached && !searchIsAttached && tabToShow != 0)
        --tabToShow;
    else if (!searchWasAttached && searchIsAttached)
        ++tabToShow;

    for (int curTab = 0; curTab < pageCount; ++curTab) {
        const QString &curFile = lastShownPageList.at(curTab);
        if (helpEngine.findFile(curFile).isValid()
            || curFile == QLatin1String("about:blank")) {
            setSourceInNewTab(curFile, zoomFactors.at(curTab).toFloat());
        } else if (curTab + searchIsAttached <= tabToShow)
            --tabToShow;
    }

    tabWidget->setCurrentIndex(tabToShow);
}

bool CentralWidget::hasSelection() const
{
    TRACE_OBJ
    const HelpViewer *viewer = currentHelpViewer();
    return viewer ? viewer->hasSelection() : false;
}

QUrl CentralWidget::currentSource() const
{
    TRACE_OBJ
    const HelpViewer *viewer = currentHelpViewer();
    if (viewer)
        return viewer->source();

    return QUrl();
}

QString CentralWidget::currentTitle() const
{
    TRACE_OBJ
    const HelpViewer *viewer = currentHelpViewer();
    if (viewer)
        return viewer->documentTitle();

    return QString();
}

void CentralWidget::copySelection()
{
    TRACE_OBJ
    HelpViewer *viewer = currentHelpViewer();
    if (viewer)
        viewer->copy();
}

void CentralWidget::showTextSearch()
{
    TRACE_OBJ
    findWidget->show();
}

void CentralWidget::initPrinter()
{
    TRACE_OBJ
#ifndef QT_NO_PRINTER
    if (!printer)
        printer = new QPrinter(QPrinter::HighResolution);
#endif
}

void CentralWidget::print()
{
    TRACE_OBJ
#ifndef QT_NO_PRINTER
    HelpViewer *viewer = currentHelpViewer();
    if (!viewer)
        return;

    initPrinter();

    QPrintDialog dlg(printer, this);
#if defined(QT_NO_WEBKIT)
    if (viewer->textCursor().hasSelection())
        dlg.addEnabledOption(QAbstractPrintDialog::PrintSelection);
#endif
    dlg.addEnabledOption(QAbstractPrintDialog::PrintPageRange);
    dlg.addEnabledOption(QAbstractPrintDialog::PrintCollateCopies);
    dlg.setWindowTitle(tr("Print Document"));
    if (dlg.exec() == QDialog::Accepted) {
        viewer->print(printer);
    }
#endif
}

void CentralWidget::printPreview()
{
    TRACE_OBJ
#ifndef QT_NO_PRINTER
    initPrinter();
    QPrintPreviewDialog preview(printer, this);
    connect(&preview, SIGNAL(paintRequested(QPrinter*)),
        SLOT(printPreview(QPrinter*)));
    preview.exec();
#endif
}

void CentralWidget::printPreview(QPrinter *p)
{
    TRACE_OBJ
#ifndef QT_NO_PRINTER
    HelpViewer *viewer = currentHelpViewer();
    if (viewer)
        viewer->print(p);
#endif
}

void CentralWidget::pageSetup()
{
    TRACE_OBJ
#ifndef QT_NO_PRINTER
    initPrinter();
    QPageSetupDialog dlg(printer);
    dlg.exec();
#endif
}

bool CentralWidget::isHomeAvailable() const
{
    TRACE_OBJ
    return currentHelpViewer() ? true : false;
}

void CentralWidget::home()
{
    TRACE_OBJ
    HelpViewer *viewer = currentHelpViewer();
    if (viewer)
        viewer->home();
}

bool CentralWidget::isForwardAvailable() const
{
    TRACE_OBJ
    const HelpViewer *viewer = currentHelpViewer();
    if (viewer)
        return viewer->isForwardAvailable();

    return false;
}

void CentralWidget::forward()
{
    TRACE_OBJ
    HelpViewer *viewer = currentHelpViewer();
    if (viewer)
        viewer->forward();
}

bool CentralWidget::isBackwardAvailable() const
{
    TRACE_OBJ
    const HelpViewer *viewer = currentHelpViewer();
    if (viewer)
        return viewer->isBackwardAvailable();

    return false;
}

void CentralWidget::backward()
{
    TRACE_OBJ
    HelpViewer *viewer = currentHelpViewer();
    if (viewer)
        viewer->backward();
}


QList<QAction*> CentralWidget::globalActions() const
{
    TRACE_OBJ
    return globalActionList;
}

void CentralWidget::setGlobalActions(const QList<QAction*> &actions)
{
    TRACE_OBJ
    globalActionList = actions;
}

void CentralWidget::setSourceInNewTab(const QUrl &url, qreal zoom)
{
    TRACE_OBJ
    if (HelpViewer *viewer = currentHelpViewer()) {
        if (viewer->launchWithExternalApp(url))
            return;
    }

    HelpViewer *viewer = new HelpViewer(this, zoom);
    viewer->installEventFilter(this);
    viewer->setSource(url);
    viewer->setFocus(Qt::OtherFocusReason);
    tabWidget->setCurrentIndex(tabWidget->addTab(viewer,
        quoteTabTitle(viewer->documentTitle())));
    connectSignals();
}

HelpViewer *CentralWidget::newEmptyTab()
{
    TRACE_OBJ
    HelpViewer *viewer = new HelpViewer(this);
    viewer->installEventFilter(this);
    viewer->setFocus(Qt::OtherFocusReason);
#if defined(QT_NO_WEBKIT)
    viewer->setDocumentTitle(tr("unknown"));
#endif
    tabWidget->setCurrentIndex(tabWidget->addTab(viewer, tr("unknown")));

    connectSignals();
    return viewer;
}

void CentralWidget::connectSignals()
{
    TRACE_OBJ
    const HelpViewer *viewer = currentHelpViewer();
    if (viewer) {
        connect(viewer, SIGNAL(copyAvailable(bool)), this,
            SIGNAL(copyAvailable(bool)));
        connect(viewer, SIGNAL(forwardAvailable(bool)), this,
            SIGNAL(forwardAvailable(bool)));
        connect(viewer, SIGNAL(backwardAvailable(bool)), this,
            SIGNAL(backwardAvailable(bool)));
        connect(viewer, SIGNAL(sourceChanged(QUrl)), this,
            SIGNAL(sourceChanged(QUrl)));
        connect(viewer, SIGNAL(highlighted(QString)), this,
            SIGNAL(highlighted(QString)));
        connect(viewer, SIGNAL(sourceChanged(QUrl)), this,
            SLOT(setTabTitle(QUrl)));
        connect(viewer, SIGNAL(printRequested()), this, SLOT(print()));
    }
}

HelpViewer* CentralWidget::viewerAt(int index) const
{
    TRACE_OBJ
    return qobject_cast<HelpViewer*>(tabWidget->widget(index));
}

HelpViewer* CentralWidget::currentHelpViewer() const
{
    TRACE_OBJ
    return qobject_cast<HelpViewer*>(tabWidget->currentWidget());
}

void CentralWidget::activateTab(bool onlyHelpViewer)
{
    TRACE_OBJ
    if (currentHelpViewer()) {
        currentHelpViewer()->setFocus();
    } else {
        int idx = 0;
        if (onlyHelpViewer)
            idx = lastTabPage;
        tabWidget->setCurrentIndex(idx);
        tabWidget->currentWidget()->setFocus();
    }
}

void CentralWidget::setTabTitle(const QUrl &url)
{
    TRACE_OBJ
    Q_UNUSED(url)
#if !defined(QT_NO_WEBKIT)
    QTabBar *tabBar = qFindChild<QTabBar*>(tabWidget);
    for (int tab = 0; tab < tabBar->count(); ++tab) {
        HelpViewer *viewer = qobject_cast<HelpViewer*>(tabWidget->widget(tab));
        if (viewer) {
            tabWidget->setTabText(tab,
                quoteTabTitle(viewer->documentTitle().trimmed()));
        }
    }
#else
    HelpViewer *viewer = currentHelpViewer();
    if (viewer) {
        tabWidget->setTabText(lastTabPage,
            quoteTabTitle(viewer->documentTitle().trimmed()));
    }
#endif
}

void CentralWidget::currentPageChanged(int index)
{
    TRACE_OBJ
    const HelpViewer *viewer = currentHelpViewer();
    if (viewer)
        lastTabPage = index;

    QWidget *widget = tabWidget->cornerWidget(Qt::TopRightCorner);
    widget->setEnabled(viewer && enableTabCloseAction());

    widget = tabWidget->cornerWidget(Qt::TopLeftCorner);
    widget->setEnabled(viewer ? true : false);

    emit currentViewerChanged();
}

void CentralWidget::showTabBarContextMenu(const QPoint &point)
{
    TRACE_OBJ
    HelpViewer *viewer = helpViewerFromTabPosition(tabWidget, point);
    if (!viewer)
        return;

    QTabBar *tabBar = qFindChild<QTabBar*>(tabWidget);

    QMenu menu(QLatin1String(""), tabBar);
    QAction *newPage = menu.addAction(tr("Add New Page"));

    bool enableAction = enableTabCloseAction();
    QAction *closePage = menu.addAction(tr("Close This Page"));
    closePage->setEnabled(enableAction);

    QAction *closePages = menu.addAction(tr("Close Other Pages"));
    closePages->setEnabled(enableAction);

    menu.addSeparator();

    QAction *newBookmark = menu.addAction(tr("Add Bookmark for this Page..."));
    const QString &url = viewer->source().toString();
    if (url.isEmpty() || url == QLatin1String("about:blank"))
        newBookmark->setEnabled(false);

    QAction *pickedAction = menu.exec(tabBar->mapToGlobal(point));
    if (pickedAction == newPage)
        setSourceInNewTab(viewer->source());

    if (pickedAction == closePage) {
        tabWidget->removeTab(tabWidget->indexOf(viewer));
        QTimer::singleShot(0, viewer, SLOT(deleteLater()));
    }

    if (pickedAction == closePages) {
        int currentPage = tabWidget->indexOf(viewer);
        for (int i = tabBar->count() -1; i >= 0; --i) {
            viewer = qobject_cast<HelpViewer*>(tabWidget->widget(i));
            if (i != currentPage && viewer) {
                tabWidget->removeTab(i);
                QTimer::singleShot(0, viewer, SLOT(deleteLater()));

                if (i < currentPage)
                    --currentPage;
            }
        }
    }

    if (pickedAction == newBookmark)
        emit addBookmark(viewer->documentTitle(), viewer->source().toString());
}

bool CentralWidget::eventFilter(QObject *object, QEvent *e)
{
    TRACE_OBJ
    if (e->type() == QEvent::KeyPress) {
        QKeyEvent *ke = static_cast<QKeyEvent*>(e);
        switch (ke->key()) {
            default: {
                return QWidget::eventFilter(object, e);
            }   break;

            case Qt::Key_Backspace: {
                HelpViewer *viewer = currentHelpViewer();
                if (viewer == object) {
#if defined(QT_NO_WEBKIT)
                    if (viewer->isBackwardAvailable()) {
#else
                    if (viewer->isBackwardAvailable() && !viewer->hasFocus()) {
#endif
                        viewer->backward();
                        return true;
                    }
                }
            }   break;
        }
    }

    if (qobject_cast<QTabBar*>(object)) {
        const bool dblClick = e->type() == QEvent::MouseButtonDblClick;
        if ((e->type() == QEvent::MouseButtonRelease) || dblClick) {
            QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(e);
            HelpViewer *viewer = helpViewerFromTabPosition(tabWidget,
                mouseEvent->pos());
            if (viewer) {
                if ((mouseEvent->button() == Qt::MidButton) || dblClick) {
                    if (availableHelpViewer() > 1) {
                        tabWidget->removeTab(tabWidget->indexOf(viewer));
                        QTimer::singleShot(0, viewer, SLOT(deleteLater()));
                        currentPageChanged(tabWidget->currentIndex());
                        return true;
                    }
                }
            }
        }
    }

    return QWidget::eventFilter(object, e);
}

void CentralWidget::keyPressEvent(QKeyEvent *e)
{
    TRACE_OBJ
    const QString &text = e->text();
    if (text.startsWith(QLatin1Char('/'))) {
        if (!findWidget->isVisible()) {
            findWidget->showAndClear();
        } else {
            findWidget->show();
        }
    } else {
        QWidget::keyPressEvent(e);
    }
}

void CentralWidget::findNext()
{
    TRACE_OBJ
    find(findWidget->text(), true);
}

void CentralWidget::findPrevious()
{
    TRACE_OBJ
    find(findWidget->text(), false);
}

void CentralWidget::find(const QString &ttf, bool forward)
{
    TRACE_OBJ
    bool found = false;
#if defined(QT_NO_WEBKIT)
    found = findInTextBrowser(ttf, forward);
#else
    found = findInWebPage(ttf, forward);
#endif

    if (!found && ttf.isEmpty())
        found = true;   // the line edit is empty, no need to mark it red...

    if (!findWidget->isVisible())
        findWidget->show();
    findWidget->setPalette(found);
}

bool CentralWidget::findInWebPage(const QString &ttf, bool forward)
{
    TRACE_OBJ
#if !defined(QT_NO_WEBKIT)
    if (HelpViewer *viewer = currentHelpViewer()) {
        bool found = false;
        QWebPage::FindFlags options;
        if (!ttf.isEmpty()) {
            if (!forward)
                options |= QWebPage::FindBackward;

            if (findWidget->caseSensitive())
                options |= QWebPage::FindCaseSensitively;

            found = viewer->findText(ttf, options);
            findWidget->setTextWrappedVisible(false);

            if (!found) {
                options |= QWebPage::FindWrapsAroundDocument;
                found = viewer->findText(ttf, options);
                if (found)
                    findWidget->setTextWrappedVisible(true);
            }
        }
        // force highlighting of all other matches, also when empty (clear)
        options = QWebPage::HighlightAllOccurrences;
        if (findWidget->caseSensitive())
            options |= QWebPage::FindCaseSensitively;
        viewer->findText(QLatin1String(""), options);
        viewer->findText(ttf, options);
        return found;
    }

    // this needs to stay, case for active search results page
    return findInTextBrowser(ttf, forward);
#else
    Q_UNUSED(ttf);
    Q_UNUSED(forward);
#endif
    return false;
}

bool CentralWidget::findInTextBrowser(const QString &ttf, bool forward)
{
    TRACE_OBJ
    QTextBrowser *browser = qobject_cast<QTextBrowser*>(currentHelpViewer());
    if (tabWidget->currentWidget() == m_searchWidget)
        browser = qFindChild<QTextBrowser*>(m_searchWidget);

    if (!browser || ttf.isEmpty())
        return false;

    QTextDocument *doc = browser->document();
    QTextCursor cursor = browser->textCursor();

    if (!doc || cursor.isNull())
        return false;

    QTextDocument::FindFlags options;

    if (cursor.hasSelection()) {
        cursor.setPosition(forward ? cursor.position() : cursor.anchor(),
            QTextCursor::MoveAnchor);
    }

    if (!forward)
        options |= QTextDocument::FindBackward;

    if (findWidget->caseSensitive())
        options |= QTextDocument::FindCaseSensitively;

    findWidget->setTextWrappedVisible(false);

    bool found = true;
    QTextCursor newCursor = doc->find(ttf, cursor, options);
    if (newCursor.isNull()) {
        QTextCursor ac(doc);
        ac.movePosition(options & QTextDocument::FindBackward
            ? QTextCursor::End : QTextCursor::Start);
        newCursor = doc->find(ttf, ac, options);
        if (newCursor.isNull()) {
            found = false;
            newCursor = cursor;
        } else {
            findWidget->setTextWrappedVisible(true);
        }
    }
    browser->setTextCursor(newCursor);
    return found;
}

void CentralWidget::updateBrowserFont()
{
    TRACE_OBJ
    const bool searchAttached = searchWidgetAttached();
    if (searchAttached) {
        HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
        m_searchWidget->setFont(helpEngine.usesBrowserFont()
            ? helpEngine.browserFont() : qApp->font());
    }

    const int count = tabWidget->count();
    if (HelpViewer* viewer = viewerAt(count - 1)) {
        const QFont &font = viewer->viewerFont();
        for (int i = searchAttached ? 1 : 0; i < count; ++i)
            viewerAt(i)->setViewerFont(font);
    }
}

bool CentralWidget::searchWidgetAttached() const
{
    TRACE_OBJ
    return m_searchWidget && m_searchWidget->isAttached();
}

void CentralWidget::createSearchWidget(QHelpSearchEngine *searchEngine)
{
    TRACE_OBJ
    if (m_searchWidget)
        return;

    m_searchWidget = new SearchWidget(searchEngine, this);
    connect(m_searchWidget, SIGNAL(requestShowLink(QUrl)), this,
        SLOT(setSourceFromSearch(QUrl)));
    connect(m_searchWidget, SIGNAL(requestShowLinkInNewTab(QUrl)), this,
        SLOT(setSourceFromSearchInNewTab(QUrl)));

    HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
    m_searchWidget->setFont(!helpEngine.usesBrowserFont() ? qApp->font()
        : helpEngine.browserFont());
}

void CentralWidget::activateSearchWidget(bool updateLastTabPage)
{
    TRACE_OBJ
    if (!m_searchWidget)
        createSearchWidget(HelpEngineWrapper::instance().searchEngine());

    if (!m_searchWidget->isAttached()) {
        tabWidget->insertTab(0, m_searchWidget, tr("Search"));
        m_searchWidget->setAttached(true);

        if (updateLastTabPage)
            lastTabPage++;
    }

    tabWidget->setCurrentWidget(m_searchWidget);
    m_searchWidget->setFocus();
}

void CentralWidget::removeSearchWidget()
{
    TRACE_OBJ
    if (searchWidgetAttached()) {
        tabWidget->removeTab(0);
        m_searchWidget->setAttached(false);
    }
}

int CentralWidget::availableHelpViewer() const
{
    TRACE_OBJ
    int count = tabWidget->count();
    if (searchWidgetAttached())
        count--;
    return count;
}

bool CentralWidget::enableTabCloseAction() const
{
    TRACE_OBJ
    int minTabCount = 1;
    if (searchWidgetAttached())
        minTabCount = 2;

    return (tabWidget->count() > minTabCount);
}

QString CentralWidget::quoteTabTitle(const QString &title) const
{
    TRACE_OBJ
    QString s = title;
    return s.replace(QLatin1Char('&'), QLatin1String("&&"));
}

void
CentralWidget::setSourceFromSearch(const QUrl &url)
{
    TRACE_OBJ
    setSource(url);
#if defined(QT_NO_WEBKIT)
    highlightSearchTerms();
#else
    connect(currentHelpViewer(), SIGNAL(loadFinished(bool)), this,
        SLOT(highlightSearchTerms()));
#endif
}

void
CentralWidget::setSourceFromSearchInNewTab(const QUrl &url)
{
    TRACE_OBJ
    setSourceInNewTab(url);
#if defined(QT_NO_WEBKIT)
    highlightSearchTerms();
#else
    connect(currentHelpViewer(), SIGNAL(loadFinished(bool)), this,
        SLOT(highlightSearchTerms()));
#endif
}

void
CentralWidget::highlightSearchTerms()
{
    TRACE_OBJ
    HelpViewer *viewer = currentHelpViewer();
    if (!viewer)
        return;

    QHelpSearchEngine *searchEngine =
        HelpEngineWrapper::instance().searchEngine();
    QList<QHelpSearchQuery> queryList = searchEngine->query();

    QStringList terms;
    foreach (const QHelpSearchQuery &query, queryList) {
        switch (query.fieldName) {
            default: break;
            case QHelpSearchQuery::ALL: {
            case QHelpSearchQuery::PHRASE:
            case QHelpSearchQuery::DEFAULT:
            case QHelpSearchQuery::ATLEAST:
                foreach (QString term, query.wordList)
                    terms.append(term.remove(QLatin1Char('"')));
            }
        }
    }

#if defined(QT_NO_WEBKIT)
    viewer->viewport()->setUpdatesEnabled(false);

    QTextCharFormat marker;
    marker.setForeground(Qt::red);

    QTextCursor firstHit;

    QTextCursor c = viewer->textCursor();
    c.beginEditBlock();
    foreach (const QString& term, terms) {
        c.movePosition(QTextCursor::Start);
        viewer->setTextCursor(c);

        while (viewer->find(term, QTextDocument::FindWholeWords)) {
            QTextCursor hit = viewer->textCursor();
            if (firstHit.isNull() || hit.position() < firstHit.position())
                firstHit = hit;

            hit.mergeCharFormat(marker);
        }
    }

    if (firstHit.isNull()) {
        firstHit = viewer->textCursor();
        firstHit.movePosition(QTextCursor::Start);
    }
    firstHit.clearSelection();
    c.endEditBlock();
    viewer->setTextCursor(firstHit);

    viewer->viewport()->setUpdatesEnabled(true);
#else
    viewer->findText("", QWebPage::HighlightAllOccurrences);
         // clears existing selections
    foreach (const QString& term, terms)
        viewer->findText(term, QWebPage::HighlightAllOccurrences);

    disconnect(viewer, SIGNAL(loadFinished(bool)), this,
        SLOT(highlightSearchTerms()));
#endif
}


void CentralWidget::closeOrReloadTabs(const QList<int> &indices, bool tryReload)
{
    TRACE_OBJ
    QList<int> sortedIndices = indices;
    qSort(sortedIndices);
    for (int i = sortedIndices.count(); --i >= 0;) {
        const int tab = sortedIndices.at(i);
        bool close = true;
        if (tryReload) {
            HelpViewer *viewer =
                    qobject_cast<HelpViewer*>(tabWidget->widget(tab));
            if (HelpEngineWrapper::instance().findFile(viewer->source()).isValid()) {
                viewer->reload();
                close = false;
            }
        }
        if (close)
            closeTabAt(tab);
    }
    if (availableHelpViewer() == 0)
        setSource(QUrl(QLatin1String("about:blank")));
}

void CentralWidget::closeTabAt(int index)
{
    TRACE_OBJ
    HelpViewer *viewer = qobject_cast<HelpViewer*>(tabWidget->widget(index));
    tabWidget->removeTab(index);
    QTimer::singleShot(0, viewer, SLOT(deleteLater()));
}

QMap<int, QString> CentralWidget::currentSourceFileList() const
{
    TRACE_OBJ
    QMap<int, QString> sourceList;
    for (int i = 0; i < tabWidget->count(); ++i) {
        HelpViewer *viewer = qobject_cast<HelpViewer*>(tabWidget->widget(i));
        if (viewer && viewer->source().isValid())
            sourceList.insert(i, viewer->source().host());
    }
    return sourceList;
}

QT_END_NAMESPACE
