Initial import

This commit is contained in:
con
2008-12-02 12:01:29 +01:00
commit 05c35356ab
1675 changed files with 229938 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
<plugin name="Help" version="0.9.1" compatVersion="0.9.1">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2008 Nokia Corporation</copyright>
<license>Nokia Technology Preview License Agreement</license>
<description>Help system.</description>
<url>http://www.trolltech.com/</url>
<dependencyList>
<dependency name="Core" version="0.9.1"/>
<dependency name="Find" version="0.9.1"/>
<dependency name="QuickOpen" version="0.9.1"/>
</dependencyList>
</plugin>

View File

@@ -0,0 +1,687 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "centralwidget.h"
#include "helpviewer.h"
#include "topicchooser.h"
#include <QtCore/QDir>
#include <QtCore/QEvent>
#include <QtCore/QTimer>
#include <QtGui/QMenu>
#include <QtGui/QLabel>
#include <QtGui/QLayout>
#include <QtGui/QPrinter>
#include <QtGui/QLineEdit>
#include <QtGui/QCheckBox>
#include <QtGui/QTabBar>
#include <QtGui/QTabWidget>
#include <QtGui/QToolButton>
#include <QtGui/QMouseEvent>
#include <QtGui/QFocusEvent>
#include <QtGui/QMainWindow>
#include <QtGui/QSpacerItem>
#include <QtGui/QTextCursor>
#include <QtGui/QPrintDialog>
#include <QtGui/QApplication>
#include <QtGui/QTextDocumentFragment>
#include <QtGui/QPrintPreviewDialog>
#include <QtGui/QPageSetupDialog>
#include <QtHelp/QHelpEngine>
using namespace Help::Internal;
namespace {
HelpViewer* helpViewerFromTabPosition(const QTabWidget *widget, const QPoint &point)
{
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(QHelpEngine *engine, QWidget *parent)
: QWidget(parent)
, findBar(0)
, tabWidget(0)
, helpEngine(engine)
, printer(0)
{
lastTabPage = 0;
globalActionList.clear();
collectionFile = helpEngine->collectionFile();
QString system = QLatin1String("win");
#ifdef Q_OS_MAC
system = QLatin1String("mac");
#endif
tabWidget = new QTabWidget;
tabWidget->setDocumentMode(true);
tabWidget->setMovable(true);
connect(tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int)));
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(QString::fromUtf8(":/trolltech/assistant/images/%1/addtab.png").arg(system)));
tabWidget->setCornerWidget(newTabButton, Qt::TopLeftCorner);
connect(newTabButton, SIGNAL(clicked()), this, SLOT(newTab()));
QVBoxLayout *vboxLayout = new QVBoxLayout(this);
vboxLayout->setMargin(0);
vboxLayout->addWidget(tabWidget);
QTabBar *tabBar = qFindChild<QTabBar*>(tabWidget);
if (tabBar) {
tabBar->installEventFilter(this);
tabBar->setContextMenuPolicy(Qt::CustomContextMenu);
connect(tabBar, SIGNAL(customContextMenuRequested(const QPoint&)),
this, SLOT(showTabBarContextMenu(const QPoint&)));
}
staticCentralWidget = this;
}
CentralWidget::~CentralWidget()
{
QDir dir;
QString currentPages;
QHelpEngineCore engine(collectionFile, 0);
if (engine.setupData()) {
for (int i = 0; i < tabWidget->count(); ++i) {
HelpViewer *viewer = qobject_cast<HelpViewer*>(tabWidget->widget(i));
if (viewer && viewer->source().isValid())
currentPages.append(viewer->source().toString()).append(QLatin1Char('|'));
}
engine.setCustomValue(QLatin1String("LastTabPage"), lastTabPage);
engine.setCustomValue(QLatin1String("LastShownPages"), currentPages);
}
}
CentralWidget *CentralWidget::instance()
{
return staticCentralWidget;
}
void CentralWidget::newTab()
{
HelpViewer* viewer = currentHelpViewer();
if (viewer)
setSourceInNewTab(viewer->source());
}
void CentralWidget::zoomIn()
{
HelpViewer* viewer = currentHelpViewer();
if (viewer)
viewer->zoomIn();
}
void CentralWidget::zoomOut()
{
HelpViewer* viewer = currentHelpViewer();
if (viewer)
viewer->zoomOut();
}
void CentralWidget::nextPage()
{
if (tabWidget->currentIndex() < tabWidget->count() -1)
tabWidget->setCurrentIndex(tabWidget->currentIndex() +1);
else
tabWidget->setCurrentIndex(0);
}
void CentralWidget::resetZoom()
{
HelpViewer* viewer = currentHelpViewer();
if (viewer)
viewer->resetZoom();
}
void CentralWidget::previousPage()
{
int index = tabWidget->currentIndex() -1;
if (index >= 0)
tabWidget->setCurrentIndex(index);
else
tabWidget->setCurrentIndex(tabWidget->count() -1);
}
void CentralWidget::closeTab()
{
closeTab(tabWidget->currentIndex());
}
void CentralWidget::closeTab(int index)
{
HelpViewer* viewer = helpViewerAtIndex(index);
if (!viewer || tabWidget->count() == 1)
return;
tabWidget->removeTab(index);
QTimer::singleShot(0, viewer, SLOT(deleteLater()));
}
void CentralWidget::setSource(const QUrl &url)
{
HelpViewer* viewer = currentHelpViewer();
HelpViewer* lastViewer = qobject_cast<HelpViewer*>(tabWidget->widget(lastTabPage));
if (!viewer && !lastViewer) {
viewer = new HelpViewer(helpEngine, this);
viewer->installEventFilter(this);
lastTabPage = tabWidget->addTab(viewer, QString());
tabWidget->setCurrentIndex(lastTabPage);
connectSignals();
qApp->processEvents();
} else
viewer = lastViewer;
viewer->setSource(url);
currentPageChanged(lastTabPage);
viewer->setFocus(Qt::OtherFocusReason);
tabWidget->setCurrentIndex(lastTabPage);
tabWidget->setTabText(lastTabPage, quoteTabTitle(viewer->documentTitle()));
}
void CentralWidget::setLastShownPages()
{
const QStringList lastShownPageList = helpEngine->customValue(QLatin1String("LastShownPages")).
toString().split(QLatin1Char('|'), QString::SkipEmptyParts);
if (!lastShownPageList.isEmpty()) {
foreach (const QString page, lastShownPageList)
setSourceInNewTab(page);
tabWidget->setCurrentIndex(helpEngine->customValue(QLatin1String("LastTabPage"), 0).toInt());
} else {
QUrl url = helpEngine->findFile(QUrl("qthelp://com.trolltech.qt.440/qdoc/index.html"));
if (url.isValid())
setSource(url);
else
setSource(QUrl("qthelp://com.trolltech.qt.440/qdoc/index.html"));
}
updateBrowserFont();
}
bool CentralWidget::hasSelection() const
{
const HelpViewer* viewer = currentHelpViewer();
return viewer ? viewer->hasSelection() : false;
}
QUrl CentralWidget::currentSource() const
{
const HelpViewer* viewer = currentHelpViewer();
if (viewer)
return viewer->source();
return QUrl();
}
QString CentralWidget::currentTitle() const
{
const HelpViewer* viewer = currentHelpViewer();
if (viewer)
return viewer->documentTitle();
return QString();
}
void CentralWidget::copySelection()
{
HelpViewer* viewer = currentHelpViewer();
if (viewer)
viewer->copy();
}
void CentralWidget::initPrinter()
{
#ifndef QT_NO_PRINTER
if (!printer)
printer = new QPrinter(QPrinter::HighResolution);
#endif
}
void CentralWidget::print()
{
#ifndef QT_NO_PRINTER
HelpViewer* viewer = currentHelpViewer();
if (!viewer)
return;
initPrinter();
QPrintDialog *dlg = new QPrintDialog(printer, this);
#if !defined(USE_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);
}
delete dlg;
#endif
}
void CentralWidget::printPreview()
{
#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)
{
#ifndef QT_NO_PRINTER
HelpViewer *viewer = currentHelpViewer();
if (viewer)
viewer->print(p);
#endif
}
void CentralWidget::pageSetup()
{
#ifndef QT_NO_PRINTER
initPrinter();
QPageSetupDialog dlg(printer);
dlg.exec();
#endif
}
bool CentralWidget::isHomeAvailable() const
{
return currentHelpViewer() ? true : false;
}
void CentralWidget::home()
{
HelpViewer* viewer = currentHelpViewer();
if (viewer)
viewer->home();
}
bool CentralWidget::isForwardAvailable() const
{
const HelpViewer* viewer = currentHelpViewer();
if (viewer)
return viewer->isForwardAvailable();
return false;
}
void CentralWidget::forward()
{
HelpViewer* viewer = currentHelpViewer();
if (viewer)
viewer->forward();
}
bool CentralWidget::isBackwardAvailable() const
{
const HelpViewer* viewer = currentHelpViewer();
if (viewer)
return viewer->isBackwardAvailable();
return false;
}
void CentralWidget::backward()
{
HelpViewer* viewer = currentHelpViewer();
if (viewer)
viewer->backward();
}
QList<QAction*> CentralWidget::globalActions() const
{
return globalActionList;
}
void CentralWidget::setGlobalActions(const QList<QAction*> &actions)
{
globalActionList = actions;
}
void CentralWidget::setSourceInNewTab(const QUrl &url)
{
HelpViewer* viewer = new HelpViewer(helpEngine, this);
viewer->installEventFilter(this);
viewer->setSource(url);
viewer->setFocus(Qt::OtherFocusReason);
tabWidget->setCurrentIndex(tabWidget->addTab(viewer, viewer->documentTitle()));
QFont font = qApp->font();
if (helpEngine->customValue(QLatin1String("useBrowserFont")).toBool())
font = qVariantValue<QFont>(helpEngine->customValue(QLatin1String("browserFont")));
viewer->setFont(font);
connectSignals();
}
HelpViewer *CentralWidget::newEmptyTab()
{
HelpViewer* viewer = new HelpViewer(helpEngine, this);
viewer->installEventFilter(this);
viewer->setFocus(Qt::OtherFocusReason);
#if !defined(USE_WEBKIT)
viewer->setDocumentTitle(tr("unknown"));
#endif
tabWidget->setCurrentIndex(tabWidget->addTab(viewer, tr("unknown")));
connectSignals();
return viewer;
}
void CentralWidget::connectSignals()
{
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(const QUrl&)), this, SIGNAL(sourceChanged(const QUrl&)));
connect(viewer, SIGNAL(highlighted(const QString&)), this, SIGNAL(highlighted(const QString&)));
connect(viewer, SIGNAL(sourceChanged(const QUrl&)), this, SLOT(setTabTitle(const QUrl&)));
}
}
HelpViewer *CentralWidget::helpViewerAtIndex(int index) const
{
return qobject_cast<HelpViewer*>(tabWidget->widget(index));
}
HelpViewer *CentralWidget::currentHelpViewer() const
{
return qobject_cast<HelpViewer*>(tabWidget->currentWidget());
}
void CentralWidget::activateTab(bool onlyHelpViewer)
{
if (currentHelpViewer()) {
currentHelpViewer()->setFocus();
} else {
int idx = 0;
if (onlyHelpViewer)
idx = lastTabPage;
tabWidget->setCurrentIndex(idx);
tabWidget->currentWidget()->setFocus();
}
}
void CentralWidget::setTabTitle(const QUrl& url)
{
int tab = lastTabPage;
HelpViewer* viewer = currentHelpViewer();
#if defined(USE_WEBKIT)
if (!viewer || viewer->source() != url) {
QTabBar *tabBar = qFindChild<QTabBar*>(tabWidget);
for (tab = 0; tab < tabBar->count(); ++tab) {
viewer = qobject_cast<HelpViewer*>(tabWidget->widget(tab));
if (viewer && viewer->source() == url)
break;
}
}
#endif
if (viewer) {
tabWidget->setTabText(tab,
quoteTabTitle(viewer->documentTitle().trimmed()));
}
}
void CentralWidget::currentPageChanged(int index)
{
const HelpViewer *viewer = currentHelpViewer();
if (viewer || tabWidget->count() == 1)
lastTabPage = index;
bool enabled = false;
if (viewer)
enabled = tabWidget->count() > 1;
tabWidget->setTabsClosable(enabled);
tabWidget->cornerWidget(Qt::TopLeftCorner)->setEnabled(true);
emit currentViewerChanged();
}
void CentralWidget::showTabBarContextMenu(const QPoint &point)
{
HelpViewer* viewer = helpViewerFromTabPosition(tabWidget, point);
if (!viewer)
return;
QTabBar *tabBar = qFindChild<QTabBar*>(tabWidget);
QMenu menu(QLatin1String(""), tabBar);
QAction *new_page = menu.addAction(tr("Add New Page"));
QAction *close_page = menu.addAction(tr("Close This Page"));
QAction *close_pages = menu.addAction(tr("Close Other Pages"));
menu.addSeparator();
QAction *newBookmark = menu.addAction(tr("Add Bookmark for this Page..."));
if (tabBar->count() == 1) {
close_page->setEnabled(false);
close_pages->setEnabled(false);
}
QAction *picked_action = menu.exec(tabBar->mapToGlobal(point));
if (!picked_action)
return;
if (picked_action == new_page)
setSourceInNewTab(viewer->source());
if (picked_action == close_page) {
tabWidget->removeTab(tabWidget->indexOf(viewer));
QTimer::singleShot(0, viewer, SLOT(deleteLater()));
}
if (picked_action == close_pages) {
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 (picked_action == newBookmark)
emit addNewBookmark(viewer->documentTitle(), viewer->source().toString());
}
// if we have a current help viewer then this is the 'focus proxy', otherwise
// it's the tab widget itself
// this is needed, so an embedding program can just set the focus to the central widget
// and it does TheRightThing
void CentralWidget::focusInEvent(QFocusEvent * /* event */)
{
if (currentHelpViewer())
QTimer::singleShot(1, currentHelpViewer(), SLOT(setFocus()));
else
QTimer::singleShot(1, tabWidget, SLOT(setFocus()));
}
bool CentralWidget::eventFilter(QObject *object, QEvent *e)
{
if (currentHelpViewer() == object && e->type() == QEvent::KeyPress){
QKeyEvent *ke = static_cast<QKeyEvent*>(e);
if (ke->key() == Qt::Key_Backspace) {
HelpViewer *viewer = currentHelpViewer();
if (viewer && viewer->isBackwardAvailable())
viewer->backward();
return true;
}
}
QTabBar *tabBar = qobject_cast<QTabBar*>(object);
bool mousRel = e->type() == QEvent::MouseButtonRelease;
bool dblClick = e->type() == QEvent::MouseButtonDblClick;
if (tabBar && (mousRel || dblClick)) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(e);
HelpViewer *viewer = helpViewerFromTabPosition(tabWidget, mouseEvent->pos());
if (tabWidget->count() <= 1)
return QWidget::eventFilter(object, e);
if (viewer && (mouseEvent->button() == Qt::MidButton || dblClick)) {
tabWidget->removeTab(tabWidget->indexOf(viewer));
QTimer::singleShot(0, viewer, SLOT(deleteLater()));
currentPageChanged(tabWidget->currentIndex());
return true;
}
}
return QWidget::eventFilter(object, e);
}
void CentralWidget::updateBrowserFont()
{
QFont font = qApp->font();
if (helpEngine->customValue(QLatin1String("useBrowserFont")).toBool())
font = qVariantValue<QFont>(helpEngine->customValue(QLatin1String("browserFont")));
QWidget* widget = 0;
for (int i = 0; i < tabWidget->count(); ++i) {
widget = tabWidget->widget(i);
if (widget->font() != font)
widget->setFont(font);
}
}
bool CentralWidget::find(const QString &txt, QTextDocument::FindFlags findFlags, bool incremental)
{
HelpViewer* viewer = currentHelpViewer();
#if defined(USE_WEBKIT)
Q_UNUSED(incremental);
if (viewer) {
QWebPage::FindFlags options = QWebPage::FindWrapsAroundDocument;
if (findFlags & QTextDocument::FindBackward)
options |= QWebPage::FindBackward;
if (findFlags & QTextDocument::FindCaseSensitively)
options |= QWebPage::FindCaseSensitively;
return viewer->findText(txt, options);
}
return false;
#else
QTextCursor cursor;
QTextDocument *doc = 0;
QTextBrowser *browser = 0;
if (viewer) {
doc = viewer->document();
cursor = viewer->textCursor();
browser = qobject_cast<QTextBrowser*>(viewer);
}
/*
if (tabWidget->currentWidget() == m_searchWidget) {
QTextBrowser* browser = qFindChild<QTextBrowser*>(m_searchWidget);
if (browser) {
doc = browser->document();
cursor = browser->textCursor();
}
}
*/
if (!browser || !doc || cursor.isNull())
return false;
if (incremental)
cursor.setPosition(cursor.selectionStart());
QTextCursor found = doc->find(txt, cursor, findFlags);
if (found.isNull()) {
if ((findFlags&QTextDocument::FindBackward) == 0)
cursor.movePosition(QTextCursor::Start);
else
cursor.movePosition(QTextCursor::End);
found = doc->find(txt, cursor, findFlags);
if (found.isNull()) {
return false;
}
}
if (!found.isNull()) {
viewer->setTextCursor(found);
}
return true;
#endif
}
void CentralWidget::showTopicChooser(const QMap<QString, QUrl> &links,
const QString &keyword)
{
TopicChooser tc(this, keyword, links);
if (tc.exec() == QDialog::Accepted)
setSource(tc.link());
}
void CentralWidget::copy()
{
HelpViewer* viewer = currentHelpViewer();
if (viewer)
viewer->copy();
}
QString CentralWidget::quoteTabTitle(const QString &title) const
{
QString s = title;
return s.replace(QLatin1Char('&'), QLatin1String("&&"));
}

View File

@@ -0,0 +1,157 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef CENTRALWIDGET_H
#define CENTRALWIDGET_H
#include <QtCore/QUrl>
#include <QtCore/QPoint>
#include <QtCore/QObject>
#include <QtGui/QWidget>
#include <QtGui/QTextDocument>
QT_BEGIN_NAMESPACE
class QEvent;
class QLabel;
class QAction;
class QCheckBox;
class QLineEdit;
class QToolButton;
class QTabWidget;
class QHelpEngine;
class QFocusEvent;
class CentralWidget;
class HelpViewer;
QT_END_NAMESPACE
namespace Help {
namespace Internal {
class PrintHelper;
}
}
QT_BEGIN_NAMESPACE
class CentralWidget : public QWidget
{
Q_OBJECT
public:
CentralWidget(QHelpEngine *engine, QWidget *parent = 0);
~CentralWidget();
bool hasSelection() const;
QUrl currentSource() const;
QString currentTitle() const;
bool isHomeAvailable() const;
bool isForwardAvailable() const;
bool isBackwardAvailable() const;
QList<QAction*> globalActions() const;
void setGlobalActions(const QList<QAction*> &actions);
HelpViewer *currentHelpViewer() const;
void activateTab(bool onlyHelpViewer = false);
bool find(const QString &txt, QTextDocument::FindFlags findFlags, bool incremental);
void setLastShownPages();
static CentralWidget *instance();
public slots:
void zoomIn();
void zoomOut();
void nextPage();
void resetZoom();
void previousPage();
void copySelection();
void print();
void pageSetup();
void printPreview();
void updateBrowserFont();
void setSource(const QUrl &url);
void setSourceInNewTab(const QUrl &url);
HelpViewer *newEmptyTab();
void home();
void forward();
void backward();
void showTopicChooser(const QMap<QString, QUrl> &links,
const QString &keyword);
void copy();
protected:
void focusInEvent(QFocusEvent *event);
signals:
void currentViewerChanged();
void copyAvailable(bool yes);
void sourceChanged(const QUrl &url);
void highlighted(const QString &link);
void forwardAvailable(bool available);
void backwardAvailable(bool available);
void addNewBookmark(const QString &title, const QString &url);
private slots:
void newTab();
void closeTab();
void closeTab(int index);
void setTabTitle(const QUrl& url);
void currentPageChanged(int index);
void showTabBarContextMenu(const QPoint &point);
void printPreview(QPrinter *printer);
private:
void connectSignals();
bool eventFilter(QObject *object, QEvent *e);
void initPrinter();
HelpViewer *helpViewerAtIndex(int index) const;
QString quoteTabTitle(const QString &title) const;
private:
int lastTabPage;
QString collectionFile;
QList<QAction*> globalActionList;
QWidget *findBar;
QTabWidget* tabWidget;
QHelpEngine *helpEngine;
QPrinter *printer;
};
QT_END_NAMESPACE
//} // namespace Internal
//} // namespace Help
#endif // CENTRALWIDGET_H

View File

@@ -0,0 +1,180 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include <QtCore/QDebug>
#include <QtCore/QStack>
#include <QtGui/QFocusEvent>
#include <QtGui/QKeyEvent>
#include "contentstoolwindow.h"
#include "helpengine.h"
using namespace Help::Internal;
ContentsToolWidget::ContentsToolWidget()
{
wasInitialized = false;
setRootIsDecorated(true);
setItemHidden(headerItem(), true);
setUniformRowHeights(true);
setColumnCount(1);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setWindowTitle(tr("Contents"));
setWindowIcon(QIcon(":/help/images/book.png"));
}
void ContentsToolWidget::focusInEvent(QFocusEvent *e)
{
if (wasInitialized) {
if (e && e->reason() != Qt::MouseFocusReason
&& !currentItem() && topLevelItemCount())
setCurrentItem(topLevelItem(0));
return;
}
wasInitialized = true;
setCursor(QCursor(Qt::WaitCursor));
emit buildRequested();
}
void ContentsToolWidget::showEvent(QShowEvent *)
{
if (wasInitialized)
return;
wasInitialized = true;
setCursor(QCursor(Qt::WaitCursor));
emit buildRequested();
}
void ContentsToolWidget::keyPressEvent(QKeyEvent *e)
{
if (e && e->key() == Qt::Key_Escape) {
emit escapePressed();
e->accept();
return;
}
QTreeWidget::keyPressEvent(e);
}
enum
{
LinkRole = Qt::UserRole + 1000
};
ContentsToolWindow::ContentsToolWindow(const QList<int> &context, HelpEngine *help)
{
m_widget = new ContentsToolWidget;
helpEngine = help;
connect(helpEngine, SIGNAL(contentsInitialized()), this, SLOT(contentsDone()));
connect(m_widget, SIGNAL(buildRequested()), helpEngine, SLOT(buildContents()));
m_context = context;
m_context << 0;
connect(m_widget, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(indexRequested()));
connect(m_widget, SIGNAL(escapePressed()), this, SIGNAL(escapePressed()));
}
ContentsToolWindow::~ContentsToolWindow()
{
delete m_widget;
}
const QList<int> &ContentsToolWindow::context() const
{
return m_context;
}
QWidget *ContentsToolWindow::widget()
{
return m_widget;
}
void ContentsToolWindow::contentsDone()
{
m_widget->setCursor(QCursor(Qt::WaitCursor));
QList<QPair<QString, ContentList> > contentList = helpEngine->contents();
for(QList<QPair<QString, ContentList> >::Iterator it = contentList.begin(); it != contentList.end(); ++it) {
QTreeWidgetItem *newEntry;
QTreeWidgetItem *contentEntry;
QStack<QTreeWidgetItem*> stack;
stack.clear();
int depth = 0;
bool root = false;
QTreeWidgetItem *lastItem[64];
for(int j = 0; j < 64; ++j)
lastItem[j] = 0;
ContentList lst = (*it).second;
for (ContentList::ConstIterator it = lst.begin(); it != lst.end(); ++it) {
ContentItem item = *it;
if (item.depth == 0) {
newEntry = new QTreeWidgetItem(m_widget, 0);
newEntry->setIcon(0, QIcon(QString::fromUtf8(":/help/images/book.png")));
newEntry->setText(0, item.title);
newEntry->setData(0, LinkRole, item.reference);
stack.push(newEntry);
depth = 1;
root = true;
}
else{
if((item.depth > depth) && root) {
depth = item.depth;
stack.push(contentEntry);
}
if(item.depth == depth) {
contentEntry = new QTreeWidgetItem(stack.top(), lastItem[ depth ]);
lastItem[ depth ] = contentEntry;
contentEntry->setText(0, item.title);
contentEntry->setData(0, LinkRole, item.reference);
}
else if(item.depth < depth) {
stack.pop();
depth--;
item = *(--it);
}
}
}
}
m_widget->setCursor(QCursor(Qt::ArrowCursor));
}
void ContentsToolWindow::indexRequested()
{
QTreeWidgetItem *itm = m_widget->currentItem();
if (!itm)
return;
emit showLinkRequested(itm->data(0, LinkRole).toString(), false);
}

View File

@@ -0,0 +1,102 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef CONTENTSTOOLWINDOW_H
#define CONTENTSTOOLWINDOW_H
#include <QtGui/QTreeWidget>
#include <coreplugin/iview.h>
namespace Help {
namespace Internal {
class HelpEngine;
class ContentsToolWindow;
class ContentsToolWidget : public QTreeWidget
{
Q_OBJECT
public:
ContentsToolWidget();
signals:
void buildRequested();
void escapePressed();
private:
friend class ContentsToolWindow;
void showEvent(QShowEvent *e);
void focusInEvent(QFocusEvent *e);
void keyPressEvent(QKeyEvent *e);
bool wasInitialized;
};
class ContentsToolWindow : public Core::IView
{
Q_OBJECT
public:
ContentsToolWindow(const QList<int> &context, HelpEngine *help);
~ContentsToolWindow();
const QList<int> &context() const;
QWidget *widget();
QList<QWidget*> dockToolBarWidgets() const { return QList<QWidget*>(); }
const char *uniqueViewName() const { return "Help.ContentsToolWindow"; }
const char *globalMenuGroup() const { return "Help.Group"; }
inline QKeySequence defaultShortcut() const { return QKeySequence(); }
Qt::DockWidgetArea defaultArea() const { return Qt::RightDockWidgetArea; }
IView::ViewPosition defaultPosition() const { return IView::First; }
signals:
void showLinkRequested(const QString &link, bool newWindow);
void escapePressed();
private slots:
void contentsDone();
void indexRequested();
private:
HelpEngine *helpEngine;
QList<int> m_context;
ContentsToolWidget *m_widget;
};
} //namespace Internal
} //namespace Help
#endif

View File

@@ -0,0 +1,143 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "docsettingspage.h"
#include <QtGui/QFileDialog>
#include <QtGui/QMessageBox>
#include <QtHelp/QHelpEngine>
using namespace Help::Internal;
DocSettingsPage::DocSettingsPage(QHelpEngine *helpEngine)
: m_helpEngine(helpEngine),
m_registeredDocs(false)
{
}
QString DocSettingsPage::name() const
{
return "Documentation";
}
QString DocSettingsPage::category() const
{
return "Help";
}
QString DocSettingsPage::trCategory() const
{
return tr("Help");
}
QWidget *DocSettingsPage::createPage(QWidget *parent)
{
QWidget *w = new QWidget(parent);
m_ui.setupUi(w);
connect(m_ui.addButton, SIGNAL(clicked()),
this, SLOT(addDocumentation()));
connect(m_ui.removeButton, SIGNAL(clicked()),
this, SLOT(removeDocumentation()));
m_ui.docsListWidget->addItems(m_helpEngine->registeredDocumentations());
m_registeredDocs = false;
m_removeDocs.clear();
return w;
}
void DocSettingsPage::addDocumentation()
{
QStringList files = QFileDialog::getOpenFileNames(m_ui.addButton->parentWidget(),
tr("Add Documentation"),
QString(), tr("Qt Help Files (*.qch)"));
if (files.isEmpty())
return;
foreach (const QString &file, files) {
QString nsName = QHelpEngineCore::namespaceName(file);
if (nsName.isEmpty()) {
QMessageBox::warning(m_ui.addButton->parentWidget(),
tr("Add Documentation"),
tr("The file %1 is not a valid Qt Help file!")
.arg(file));
continue;
}
m_helpEngine->registerDocumentation(file);
m_ui.docsListWidget->addItem(nsName);
}
m_registeredDocs = true;
emit documentationAdded();
}
void DocSettingsPage::removeDocumentation()
{
QListWidgetItem *item = m_ui.docsListWidget->currentItem();
if (!item)
return;
m_removeDocs.append(item->text());
int row = m_ui.docsListWidget->currentRow();
m_ui.docsListWidget->takeItem(row);
if (row > 0)
--row;
if (m_ui.docsListWidget->count())
m_ui.docsListWidget->setCurrentRow(row);
delete item;
}
void DocSettingsPage::finished(bool accepted)
{
if (!accepted)
return;
emit dialogAccepted();
}
bool DocSettingsPage::applyChanges()
{
QStringList::const_iterator it = m_removeDocs.constBegin();
while (it != m_removeDocs.constEnd()) {
if (!m_helpEngine->unregisterDocumentation((*it))) {
QMessageBox::warning(m_ui.addButton->parentWidget(),
tr("Documentation"),
tr("Cannot unregister documentation file %1!")
.arg((*it)));
}
++it;
}
return m_registeredDocs || m_removeDocs.count();
}

View File

@@ -0,0 +1,81 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef DOCSETTINGSPAGE_H
#define DOCSETTINGSPAGE_H
#include <QtGui/QWidget>
#include <coreplugin/dialogs/ioptionspage.h>
#include "ui_docsettingspage.h"
QT_FORWARD_DECLARE_CLASS(QHelpEngine)
namespace Help {
namespace Internal {
class DocSettingsPage : public Core::IOptionsPage
{
Q_OBJECT
public:
DocSettingsPage(QHelpEngine *helpEngine);
QString name() const;
QString category() const;
QString trCategory() const;
QWidget *createPage(QWidget *parent);
void finished(bool accepted);
bool applyChanges();
signals:
void documentationAdded();
void dialogAccepted();
private slots:
void addDocumentation();
void removeDocumentation();
private:
QHelpEngine *m_helpEngine;
bool m_registeredDocs;
QStringList m_removeDocs;
Ui::DocSettingsPage m_ui;
};
} // namespace Help
} // namespace Internal
#endif // DOCSETTINGSPAGE_H

View File

@@ -0,0 +1,77 @@
<ui version="4.0" >
<class>DocSettingsPage</class>
<widget class="QWidget" name="DocSettingsPage" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>364</width>
<height>240</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<item>
<widget class="QLabel" name="label" >
<property name="text" >
<string>Registered Documentation:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="_3" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin" >
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="docsListWidget" />
</item>
<item>
<layout class="QVBoxLayout" name="_4" >
<property name="spacing" >
<number>6</number>
</property>
<property name="margin" >
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="addButton" >
<property name="text" >
<string>Add...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeButton" >
<property name="text" >
<string>Remove</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,220 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "filtersettingspage.h"
#include "filternamedialog.h"
#include <QtGui/QFileDialog>
#include <QtGui/QMessageBox>
#include <QtHelp/QHelpEngine>
using namespace Help::Internal;
FilterSettingsPage::FilterSettingsPage(QHelpEngine *helpEngine)
{
m_helpEngine = helpEngine;
}
QString FilterSettingsPage::name() const
{
return "Filters";
}
QString FilterSettingsPage::category() const
{
return "Help";
}
QString FilterSettingsPage::trCategory() const
{
return tr("Help");
}
QWidget *FilterSettingsPage::createPage(QWidget *parent)
{
m_currentPage = new QWidget(parent);
m_ui.setupUi(m_currentPage);
m_ui.attributeWidget->header()->hide();
m_ui.attributeWidget->setRootIsDecorated(false);
connect(m_ui.attributeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)),
this, SLOT(updateFilterMap()));
connect(m_ui.filterWidget,
SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
this, SLOT(updateAttributes(QListWidgetItem*)));
connect(m_ui.filterAddButton, SIGNAL(clicked()),
this, SLOT(addFilter()));
connect(m_ui.filterRemoveButton, SIGNAL(clicked()),
this, SLOT(removeFilter()));
updateFilterPage();
return m_currentPage;
}
void FilterSettingsPage::updateFilterPage()
{
if (!m_helpEngine)
return;
m_ui.filterWidget->clear();
m_ui.attributeWidget->clear();
QHelpEngineCore help(m_helpEngine->collectionFile(), 0);
help.setupData();
m_filterMapBackup.clear();
const QStringList filters = help.customFilters();
foreach (const QString filter, filters) {
QStringList atts = help.filterAttributes(filter);
m_filterMapBackup.insert(filter, atts);
if (!m_filterMap.contains(filter))
m_filterMap.insert(filter, atts);
}
m_ui.filterWidget->addItems(m_filterMap.keys());
foreach (const QString a, help.filterAttributes())
new QTreeWidgetItem(m_ui.attributeWidget, QStringList() << a);
if (m_filterMap.keys().count())
m_ui.filterWidget->setCurrentRow(0);
}
void FilterSettingsPage::updateAttributes(QListWidgetItem *item)
{
QStringList checkedList;
if (item)
checkedList = m_filterMap.value(item->text());
QTreeWidgetItem *itm;
for (int i=0; i<m_ui.attributeWidget->topLevelItemCount(); ++i) {
itm = m_ui.attributeWidget->topLevelItem(i);
if (checkedList.contains(itm->text(0)))
itm->setCheckState(0, Qt::Checked);
else
itm->setCheckState(0, Qt::Unchecked);
}
}
void FilterSettingsPage::updateFilterMap()
{
if (!m_ui.filterWidget->currentItem())
return;
QString filter = m_ui.filterWidget->currentItem()->text();
if (!m_filterMap.contains(filter))
return;
QStringList newAtts;
QTreeWidgetItem *itm = 0;
for (int i=0; i<m_ui.attributeWidget->topLevelItemCount(); ++i) {
itm = m_ui.attributeWidget->topLevelItem(i);
if (itm->checkState(0) == Qt::Checked)
newAtts.append(itm->text(0));
}
m_filterMap[filter] = newAtts;
}
void FilterSettingsPage::addFilter()
{
FilterNameDialog dia(m_currentPage);
if (dia.exec() == QDialog::Rejected)
return;
QString filterName = dia.filterName();
if (!m_filterMap.contains(filterName)) {
m_filterMap.insert(filterName, QStringList());
m_ui.filterWidget->addItem(filterName);
}
QList<QListWidgetItem*> lst = m_ui.filterWidget
->findItems(filterName, Qt::MatchCaseSensitive);
m_ui.filterWidget->setCurrentItem(lst.first());
}
void FilterSettingsPage::removeFilter()
{
QListWidgetItem *item = m_ui.filterWidget
->takeItem(m_ui.filterWidget->currentRow());
if (!item)
return;
m_filterMap.remove(item->text());
m_removedFilters.append(item->text());
delete item;
if (m_ui.filterWidget->count())
m_ui.filterWidget->setCurrentRow(0);
}
void FilterSettingsPage::finished(bool)
{
}
bool FilterSettingsPage::applyChanges()
{
bool changed = false;
if (m_filterMap.count() != m_filterMapBackup.count()) {
changed = true;
} else {
QMapIterator<QString, QStringList> it(m_filterMapBackup);
while (it.hasNext() && !changed) {
it.next();
if (!m_filterMap.contains(it.key())) {
changed = true;
} else {
QStringList a = it.value();
QStringList b = m_filterMap.value(it.key());
if (a.count() != b.count()) {
changed = true;
} else {
QStringList::const_iterator i(a.constBegin());
while (i != a.constEnd()) {
if (!b.contains(*i)) {
changed = true;
break;
}
++i;
}
}
}
}
}
if (changed) {
foreach (QString filter, m_removedFilters)
m_helpEngine->removeCustomFilter(filter);
QMapIterator<QString, QStringList> it(m_filterMap);
while (it.hasNext()) {
it.next();
m_helpEngine->addCustomFilter(it.key(), it.value());
}
return true;
}
return false;
}

View File

@@ -0,0 +1,82 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef FILTERSETTINGSPAGE_H
#define FILTERSETTINGSPAGE_H
#include <QtGui/QWidget>
#include <coreplugin/dialogs/ioptionspage.h>
#include "ui_filtersettingspage.h"
QT_FORWARD_DECLARE_CLASS(QHelpEngine)
namespace Help {
namespace Internal {
class FilterSettingsPage : public Core::IOptionsPage
{
Q_OBJECT
public:
FilterSettingsPage(QHelpEngine *helpEngine);
QString name() const;
QString category() const;
QString trCategory() const;
QWidget *createPage(QWidget *parent);
void finished(bool accepted);
bool applyChanges();
private slots:
void updateAttributes(QListWidgetItem *item);
void updateFilterMap();
void updateFilterPage();
void addFilter();
void removeFilter();
private:
QHelpEngine *m_helpEngine;
Ui::FilterSettingsPage m_ui;
QMap<QString, QStringList> m_filterMapBackup;
QMap<QString, QStringList> m_filterMap;
QStringList m_removedFilters;
QWidget *m_currentPage;
};
} // namespace Help
} // namespace Internal
#endif // DOCSETTINGSPAGE_H

View File

@@ -0,0 +1,72 @@
<ui version="4.0" >
<class>FilterSettingsPage</class>
<widget class="QWidget" name="FilterSettingsPage" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout" >
<item row="0" column="0" colspan="2" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>Filter:</string>
</property>
</widget>
</item>
<item row="0" column="2" >
<widget class="QLabel" name="label_2" >
<property name="frameShape" >
<enum>QFrame::NoFrame</enum>
</property>
<property name="text" >
<string>Attributes:</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2" >
<widget class="QListWidget" name="filterWidget" />
</item>
<item rowspan="2" row="1" column="2" >
<widget class="QTreeWidget" name="attributeWidget" >
<property name="showDropIndicator" stdset="0" >
<bool>false</bool>
</property>
<property name="rootIsDecorated" >
<bool>false</bool>
</property>
<property name="uniformRowHeights" >
<bool>true</bool>
</property>
<column>
<property name="text" >
<string>1</string>
</property>
</column>
</widget>
</item>
<item row="2" column="0" >
<widget class="QPushButton" name="filterAddButton" >
<property name="text" >
<string>Add</string>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QPushButton" name="filterRemoveButton" >
<property name="text" >
<string>Remove</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,3 @@
include(help_dependencies.pri)
LIBS *= -l$$qtLibraryTarget(Help)

36
src/plugins/help/help.pro Normal file
View File

@@ -0,0 +1,36 @@
TEMPLATE = lib
TARGET = Help
include(../../qworkbenchplugin.pri)
include(../../plugins/coreplugin/coreplugin.pri)
include(../../plugins/find/find.pri)
include(../../plugins/quickopen/quickopen.pri)
QT += network
CONFIG += help
DEFINES += QT_CLUCENE_SUPPORT \
HELP_LIBRARY
HEADERS += helpplugin.h \
docsettingspage.h \
filtersettingspage.h \
helpmode.h \
centralwidget.h \
searchwidget.h \
helpfindsupport.h \
help_global.h \
helpindexfilter.h \
indexwindow.h
SOURCES += helpplugin.cpp \
docsettingspage.cpp \
filtersettingspage.cpp \
helpmode.cpp \
centralwidget.cpp \
searchwidget.cpp \
helpfindsupport.cpp \
helpindexfilter.cpp
FORMS += docsettingspage.ui \
filtersettingspage.ui
RESOURCES += help.qrc
include(../../../shared/help/help.pri)
contains(QT_CONFIG, webkit) {
DEFINES += USE_WEBKIT
QT += webkit
}

16
src/plugins/help/help.qrc Normal file
View File

@@ -0,0 +1,16 @@
<RCC>
<qresource prefix="/help" >
<file>images/find.png</file>
<file>images/book.png</file>
<file>images/previous.png</file>
<file>images/next.png</file>
<file>images/home.png</file>
<file>images/bookmark.png</file>
</qresource>
<qresource prefix="/trolltech/assistant" >
<file>images/mac/addtab.png</file>
<file>images/mac/closetab.png</file>
<file>images/win/addtab.png</file>
<file>images/win/closetab.png</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,57 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
/****************************************************************************
**
** Copyright (C) 1992-$THISYEAR$ Trolltech AS. All rights reserved.
**
** This file is part of the $MODULE$ of the Qt Toolkit.
**
** $LICENSE$
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#ifndef HELP_GLOBAL_H
#define HELP_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(HELP_LIBRARY)
# define HELP_EXPORT Q_DECL_EXPORT
#else
# define HELP_EXPORT Q_DECL_IMPORT
#endif
#endif // HELP_GLOBAL_H

View File

@@ -0,0 +1,606 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QDateTime>
#include <QtCore/QCoreApplication>
#include "helpengine.h"
#include "config.h"
using namespace Help::Internal;
static bool verifyDirectory(const QString &str)
{
QFileInfo dirInfo(str);
if (!dirInfo.exists())
return QDir().mkdir(str);
if (!dirInfo.isDir()) {
qWarning("'%s' exists but is not a directory", str.toLatin1().constData());
return false;
}
return true;
}
struct IndexKeyword {
IndexKeyword(const QString &kw, const QString &l)
: keyword(kw), link(l) {}
IndexKeyword() : keyword(QString()), link(QString()) {}
bool operator<(const IndexKeyword &ik) const {
return keyword.toLower() < ik.keyword.toLower();
}
bool operator<=(const IndexKeyword &ik) const {
return keyword.toLower() <= ik.keyword.toLower();
}
bool operator>(const IndexKeyword &ik) const {
return keyword.toLower() > ik.keyword.toLower();
}
Q_DUMMY_COMPARISON_OPERATOR(IndexKeyword)
QString keyword;
QString link;
};
QDataStream &operator>>(QDataStream &s, IndexKeyword &ik)
{
s >> ik.keyword;
s >> ik.link;
return s;
}
QDataStream &operator<<(QDataStream &s, const IndexKeyword &ik)
{
s << ik.keyword;
s << ik.link;
return s;
}
/**
* Compare in a human-preferred alphanumeric way,
* e.g. 'Qt tutorial 2' will be less than 'Qt tutorial 11'.
*/
bool caseInsensitiveLessThan(const QString &as, const QString &bs)
{
const QChar *a = as.unicode();
const QChar *b = bs.unicode();
int result = 0;
while (result == 0)
{
ushort aa = a->unicode();
ushort bb = b->unicode();
if (aa == 0 || bb == 0) {
result = aa - bb;
break;
}
else if (a->isDigit() && b->isDigit())
{
const QChar *a_begin = a;
const QChar *b_begin = b;
bool loop = true;
do {
if (a->isDigit()) ++a;
else if (b->isDigit()) ++b;
else loop = false;
} while (loop);
// optimization: comparing the length of the two numbers is more efficient than constructing two qstrings.
result = (a - a_begin) - (b - b_begin);
if (result == 0) {
QString astr(a_begin, a - a_begin);
QString bstr(b_begin, b - b_begin);
long la = astr.toLong();
long lb = bstr.toLong();
result = la - lb;
}
} else {
aa = QChar(aa).toLower().unicode();
bb = QChar(bb).toLower().unicode();
result = aa - bb;
++a;
++b;
}
}
return result < 0 ? true : false;
}
/**
* \a real is kinda a hack for the smart search, need a way to match a regexp to an item
* How would you say the best match for Q.*Wiget is QWidget?
*/
QModelIndex IndexListModel::filter(const QString &s, const QString &real)
{
QStringList list;
int goodMatch = -1;
int perfectMatch = -1;
if (s.isEmpty())
perfectMatch = 0;
const QRegExp regExp(s);
QMultiMap<QString, QString>::iterator it = contents.begin();
QString lastKey;
for (; it != contents.end(); ++it) {
if (it.key() == lastKey)
continue;
lastKey = it.key();
const QString key = it.key();
if (key.contains(regExp) || key.contains(s, Qt::CaseInsensitive)) {
list.append(key);
//qDebug() << regExp << regExp.indexIn(s) << s << key << regExp.matchedLength();
if (perfectMatch == -1 && (key.startsWith(real, Qt::CaseInsensitive))) {
if (goodMatch == -1)
goodMatch = list.count() - 1;
if (s.length() == key.length())
perfectMatch = list.count() - 1;
} else if (perfectMatch > -1 && s == key) {
perfectMatch = list.count() - 1;
}
}
}
int bestMatch = perfectMatch;
if (bestMatch == -1)
bestMatch = goodMatch;
bestMatch = qMax(0, bestMatch);
// sort the new list
QString match;
if (bestMatch >= 0 && list.count() > bestMatch)
match = list[bestMatch];
qSort(list.begin(), list.end(), caseInsensitiveLessThan);
setStringList(list);
for (int i = 0; i < list.size(); ++i) {
if (list.at(i) == match){
bestMatch = i;
break;
}
}
return index(bestMatch, 0, QModelIndex());
}
HelpEngine::HelpEngine(QObject *parent, const QString &defaultQtVersionPath)
: QObject(parent)
{
titleMapThread = new TitleMapThread(this);
connect(titleMapThread, SIGNAL(errorOccured(const QString&)),
this, SIGNAL(errorOccured(const QString&)));
connect(titleMapThread, SIGNAL(finished()), this, SLOT(titleMapFinished()));
indexThread = new IndexThread(this);
connect(indexThread, SIGNAL(errorOccured(const QString&)),
this, SIGNAL(errorOccured(const QString&)));
connect(indexThread, SIGNAL(finished()), this, SLOT(indexFinished()));
indexModel = new IndexListModel(this);
Config::loadConfig(defaultQtVersionPath);
cacheFilesPath = QDir::homePath() + QLatin1String("/.assistant");
}
HelpEngine::~HelpEngine()
{
Config::configuration()->save();
}
void HelpEngine::init()
{
}
QString HelpEngine::cacheFilePath() const
{
return cacheFilesPath;
}
IndexListModel *HelpEngine::indices()
{
return indexModel;
}
void HelpEngine::buildContents()
{
contentsOnly = true;
if (!titleMapThread->isRunning()) {
titleMapThread->start(QThread::NormalPriority);
}
}
void HelpEngine::buildIndex()
{
if (!titleMapThread->isRunning()) {
contentsOnly = false;
titleMapThread->start(QThread::NormalPriority);
}
if (!indexThread->isRunning())
indexThread->start(QThread::NormalPriority);
}
void HelpEngine::titleMapFinished()
{
contentList = titleMapThread->contents();
titleMap = titleMapThread->documentTitleMap();
if (contentsOnly) {
contentsOnly = false;
emit contentsInitialized();
}
}
void HelpEngine::indexFinished()
{
indexModel = indexThread->model();
emit indexInitialized();
}
void HelpEngine::removeOldCacheFiles(bool onlyFulltextSearchIndex)
{
if (!verifyDirectory(cacheFilesPath)) {
qWarning("Failed to created assistant directory");
return;
}
QString pname = QLatin1String(".") + Config::configuration()->profileName();
QStringList fileList;
fileList << QLatin1String("indexdb40.dict")
<< QLatin1String("indexdb40.doc");
if (!onlyFulltextSearchIndex)
fileList << QLatin1String("indexdb40") << QLatin1String("contentdb40");
QStringList::iterator it = fileList.begin();
for (; it != fileList.end(); ++it) {
if (QFile::exists(cacheFilesPath + QDir::separator() + *it + pname)) {
QFile f(cacheFilesPath + QDir::separator() + *it + pname);
f.remove();
}
}
}
quint32 HelpEngine::getFileAges()
{
QStringList addDocuFiles = Config::configuration()->docFiles();
QStringList::const_iterator i = addDocuFiles.begin();
quint32 fileAges = 0;
for(; i != addDocuFiles.end(); ++i) {
QFileInfo fi(*i);
if (fi.exists())
fileAges += fi.lastModified().toTime_t();
}
return fileAges;
}
QString HelpEngine::removeAnchorFromLink(const QString &link)
{
int i = link.length();
int j = link.lastIndexOf('/');
int l = link.lastIndexOf(QDir::separator());
if (l > j)
j = l;
if (j > -1) {
QString fileName = link.mid(j+1);
int k = fileName.lastIndexOf('#');
if (k > -1)
i = j + k + 1;
}
return link.left(i);
}
QString HelpEngine::titleOfLink(const QString &link)
{
QString s = HelpEngine::removeAnchorFromLink(link);
s = titleMap[s];
if (s.isEmpty())
return link;
return s;
}
QString HelpEngine::home() const
{
QString link = Config::configuration()->homePage();
if (!link.startsWith(QLatin1String("file:")))
link.prepend("file:");
return link;
}
TitleMapThread::TitleMapThread(HelpEngine *he)
: QThread(he)
{
engine = he;
done = false;
}
TitleMapThread::~TitleMapThread()
{
}
void TitleMapThread::run()
{
if (done) {
engine->mutex.lock();
engine->titleMapDoneCondition.wakeAll();
engine->mutex.unlock();
return;
}
bool needRebuild = false;
if (Config::configuration()->profileName() == QLatin1String("default")) {
const QStringList docuFiles = Config::configuration()->docFiles();
for(QStringList::ConstIterator it = docuFiles.begin(); it != docuFiles.end(); it++) {
if (!QFile::exists(*it)) {
Config::configuration()->saveProfile(Profile::createDefaultProfile());
Config::configuration()->loadDefaultProfile();
needRebuild = true;
break;
}
}
}
if (Config::configuration()->docRebuild() || needRebuild) {
engine->removeOldCacheFiles();
Config::configuration()->setDocRebuild(false);
Config::configuration()->save();
}
if (contentList.isEmpty())
getAllContents();
titleMap.clear();
for(QList<QPair<QString, ContentList> >::Iterator it = contentList.begin(); it != contentList.end(); ++it) {
ContentList lst = (*it).second;
foreach (ContentItem item, lst) {
titleMap[item.reference] = item.title.trimmed();
}
}
done = true;
engine->mutex.lock();
engine->titleMapDoneCondition.wakeAll();
engine->mutex.unlock();
}
void TitleMapThread::getAllContents()
{
QFile contentFile(engine->cacheFilePath() + QDir::separator() + QLatin1String("contentdb40.")
+ Config::configuration()->profileName());
contentList.clear();
if (!contentFile.open(QFile::ReadOnly)) {
buildContentDict();
return;
}
QDataStream ds(&contentFile);
quint32 fileAges;
ds >> fileAges;
if (fileAges != engine->getFileAges()) {
contentFile.close();
engine->removeOldCacheFiles(true);
buildContentDict();
return;
}
QString key;
QList<ContentItem> lst;
while (!ds.atEnd()) {
ds >> key;
ds >> lst;
contentList += qMakePair(key, QList<ContentItem>(lst));
}
contentFile.close();
}
void TitleMapThread::buildContentDict()
{
QStringList docuFiles = Config::configuration()->docFiles();
quint32 fileAges = 0;
for(QStringList::iterator it = docuFiles.begin(); it != docuFiles.end(); it++) {
QFile file(*it);
if (!file.exists()) {
#ifdef _SHOW_ERRORS_
emit errorOccured(tr("Documentation file %1 does not exist!\n"
"Skipping file.").arg(QFileInfo(file).absoluteFilePath()));
#endif
continue;
}
fileAges += QFileInfo(file).lastModified().toTime_t();
DocuParser *handler = DocuParser::createParser(*it);
if(!handler) {
#ifdef _SHOW_ERRORS_
emit errorOccured(tr("Documentation file %1 is not compatible!\n"
"Skipping file.").arg(QFileInfo(file).absoluteFilePath()));
#endif
continue;
}
bool ok = handler->parse(&file);
file.close();
if(ok) {
contentList += qMakePair(*it, QList<ContentItem>(handler->getContentItems()));
delete handler;
} else {
#ifdef _SHOW_ERRORS_
QString msg = QString::fromLatin1("In file %1:\n%2")
.arg(QFileInfo(file).absoluteFilePath())
.arg(handler->errorProtocol());
emit errorOccured(msg);
#endif
continue;
}
}
QFile contentOut(engine->cacheFilePath() + QDir::separator() + QLatin1String("contentdb40.")
+ Config::configuration()->profileName());
if (contentOut.open(QFile::WriteOnly)) {
QDataStream s(&contentOut);
s << fileAges;
for(QList<QPair<QString, ContentList> >::Iterator it = contentList.begin(); it != contentList.end(); ++it) {
s << *it;
}
contentOut.close();
}
}
IndexThread::IndexThread(HelpEngine *he)
: QThread(he)
{
engine = he;
indexModel = new IndexListModel(this);
indexDone = false;
}
void IndexThread::run()
{
if (indexDone)
return;
engine->mutex.lock();
if (engine->titleMapThread->isRunning())
engine->titleMapDoneCondition.wait(&(engine->mutex));
engine->mutex.unlock();
keywordDocuments.clear();
QList<IndexKeyword> lst;
QFile indexFile(engine->cacheFilePath() + QDir::separator() + QLatin1String("indexdb40.") +
Config::configuration()->profileName());
if (!indexFile.open(QFile::ReadOnly)) {
buildKeywordDB();
if (!indexFile.open(QFile::ReadOnly)) {
#ifdef _SHOW_ERRORS_
emit errorOccured(tr("Failed to load keyword index file!"));
#endif
return;
}
}
QDataStream ds(&indexFile);
quint32 fileAges;
ds >> fileAges;
if (fileAges != engine->getFileAges()) {
indexFile.close();
buildKeywordDB();
if (!indexFile.open(QFile::ReadOnly)) {
#ifdef _SHOW_ERRORS_
emit errorOccured(tr("Cannot open the index file %1")
.arg(QFileInfo(indexFile).absoluteFilePath()));
#endif
return;
}
ds.setDevice(&indexFile);
ds >> fileAges;
}
ds >> lst;
indexFile.close();
for (int i=0; i<lst.count(); ++i) {
const IndexKeyword &idx = lst.at(i);
indexModel->addLink(idx.keyword, idx.link);
keywordDocuments << HelpEngine::removeAnchorFromLink(idx.link);
}
indexModel->publish();
indexDone = true;
}
void IndexThread::buildKeywordDB()
{
QStringList addDocuFiles = Config::configuration()->docFiles();
QStringList::iterator i = addDocuFiles.begin();
int steps = 0;
for(; i != addDocuFiles.end(); i++)
steps += QFileInfo(*i).size();
QList<IndexKeyword> lst;
quint32 fileAges = 0;
for(i = addDocuFiles.begin(); i != addDocuFiles.end(); i++){
QFile file(*i);
if (!file.exists()) {
#ifdef _SHOW_ERRORS_
emit errorOccured(tr("Documentation file %1 does not exist!\n"
"Skipping file.").arg(QFileInfo(file).absoluteFilePath()));
#endif
continue;
}
fileAges += QFileInfo(file).lastModified().toTime_t();
DocuParser *handler = DocuParser::createParser(*i);
bool ok = handler->parse(&file);
file.close();
if(!ok){
#ifdef _SHOW_ERRORS_
QString msg = QString::fromLatin1("In file %1:\n%2")
.arg(QFileInfo(file).absoluteFilePath())
.arg(handler->errorProtocol());
emit errorOccured(msg);
#endif
delete handler;
continue;
}
QList<IndexItem*> indLst = handler->getIndexItems();
foreach (IndexItem *indItem, indLst) {
QFileInfo fi(indItem->reference);
lst.append(IndexKeyword(indItem->keyword, indItem->reference));
}
delete handler;
}
if (!lst.isEmpty())
qSort(lst);
QFile indexout(engine->cacheFilePath() + QDir::separator() + QLatin1String("indexdb40.")
+ Config::configuration()->profileName());
if (verifyDirectory(engine->cacheFilePath()) && indexout.open(QFile::WriteOnly)) {
QDataStream s(&indexout);
s << fileAges;
s << lst;
indexout.close();
}
}

View File

@@ -0,0 +1,182 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef HELPENGINE_H
#define HELPENGINE_H
#include <QtCore/QThread>
#include <QtCore/QPair>
#include <QtCore/QMap>
#include <QtCore/QWaitCondition>
#include <QtCore/QMutex>
#include <QtGui/QStringListModel>
#include "docuparser.h"
namespace Help {
namespace Internal {
class HelpEngine;
typedef QList<ContentItem> ContentList;
class IndexListModel: public QStringListModel
{
public:
IndexListModel(QObject *parent = 0)
: QStringListModel(parent) {}
void clear() { contents.clear(); setStringList(QStringList()); }
QString description(int index) const { return stringList().at(index); }
QStringList links(int index) const { return contents.values(stringList().at(index)); }
void addLink(const QString &description, const QString &link) { contents.insert(description, link); }
void publish() { filter(QString(), QString()); }
QModelIndex filter(const QString &s, const QString &real);
virtual Qt::ItemFlags flags(const QModelIndex &index) const
{ return QStringListModel::flags(index) & ~Qt::ItemIsEditable; }
private:
QMultiMap<QString, QString> contents;
};
class TitleMapThread : public QThread
{
Q_OBJECT
public:
TitleMapThread(HelpEngine *he);
~TitleMapThread();
void setup();
QList<QPair<QString, ContentList> > contents() const { return contentList; }
QMap<QString, QString> documentTitleMap() const { return titleMap; }
signals:
void errorOccured(const QString &errMsg);
protected:
void run();
private:
void getAllContents();
void buildContentDict();
QList<QPair<QString, ContentList> > contentList;
QMap<QString, QString> titleMap;
HelpEngine *engine;
bool done;
};
class IndexThread : public QThread
{
Q_OBJECT
public:
IndexThread(HelpEngine *he);
void setup();
IndexListModel *model() const { return indexModel; }
protected:
void run();
signals:
void errorOccured(const QString &errMsg);
private:
void buildKeywordDB();
HelpEngine *engine;
QStringList keywordDocuments;
IndexListModel *indexModel;
bool indexDone;
};
class HelpEngine : public QObject
{
Q_OBJECT
public:
HelpEngine(QObject *parent, const QString& defaultQtVersionPath);
~HelpEngine();
void init();
QList<QPair<QString, ContentList> > contents() const { return contentList; }
IndexListModel *indices();
QString titleOfLink(const QString &link);
static QString removeAnchorFromLink(const QString &link);
QString home() const;
signals:
void indexInitialized();
void contentsInitialized();
void errorOccured(const QString &errMsg);
public slots:
void buildContents();
void buildIndex();
private slots:
void titleMapFinished();
void indexFinished();
private:
friend class TitleMapThread;
friend class IndexThread;
void removeOldCacheFiles(bool onlyFulltextSearchIndex = false);
QString cacheFilePath() const;
quint32 getFileAges();
QList<QPair<QString, ContentList> > contentList;
QMap<QString, QString> titleMap;
QString cacheFilesPath;
IndexListModel *indexModel;
QWaitCondition titleMapDoneCondition;
QMutex mutex;
TitleMapThread *titleMapThread;
IndexThread *indexThread;
bool contentsOnly;
};
} //namespace Internal
} //namespace Help
#endif

View File

@@ -0,0 +1,78 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "helpfindsupport.h"
#include "helpviewer.h"
using namespace Help::Internal;
HelpFindSupport::HelpFindSupport(CentralWidget *centralWidget)
: m_centralWidget(centralWidget)
{
}
HelpFindSupport::~HelpFindSupport()
{
}
bool HelpFindSupport::isEnabled() const
{
return true;
}
QString HelpFindSupport::currentFindString() const
{
Q_ASSERT(m_centralWidget);
HelpViewer* viewer = m_centralWidget->currentHelpViewer();
if (!viewer)
return QString();
#if defined(USE_WEBKIT)
return viewer->selectedText();
#else
return viewer->textCursor().selectedText();
#endif
}
QString HelpFindSupport::completedFindString() const { return QString(); }
bool HelpFindSupport::findIncremental(const QString &txt, QTextDocument::FindFlags findFlags)
{
Q_ASSERT(m_centralWidget);
findFlags &= ~QTextDocument::FindBackward;
return m_centralWidget->find(txt, findFlags, true);
}
bool HelpFindSupport::findStep(const QString &txt, QTextDocument::FindFlags findFlags)
{
Q_ASSERT(m_centralWidget);
return m_centralWidget->find(txt, findFlags, false);
}

View File

@@ -0,0 +1,74 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef HELPFINDSUPPORT_H
#define HELPFINDSUPPORT_H
#include "centralwidget.h"
#include <find/ifindsupport.h>
namespace Help {
namespace Internal {
class HelpFindSupport : public Find::IFindSupport
{
Q_OBJECT
public:
HelpFindSupport(CentralWidget *centralWidget);
~HelpFindSupport();
bool isEnabled() const;
bool supportsReplace() const { return false; }
void resetIncrementalSearch() {}
void clearResults() {}
QString currentFindString() const;
QString completedFindString() const;
bool findIncremental(const QString &txt, QTextDocument::FindFlags findFlags);
bool findStep(const QString &txt, QTextDocument::FindFlags findFlags);
bool replaceStep(const QString &, const QString &,
QTextDocument::FindFlags ) { return false; }
int replaceAll(const QString &, const QString &,
QTextDocument::FindFlags ) { return 0; }
private:
bool find(const QString &ttf, QTextDocument::FindFlags findFlags, bool incremental);
CentralWidget *m_centralWidget;
};
} // namespace Internal
} // namespace Help
#endif // HELPFINDSUPPORT_H

View File

@@ -0,0 +1,114 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "helpindexfilter.h"
#include "helpplugin.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/modemanager.h>
#include <QtHelp/QHelpEngine>
#include <QtHelp/QHelpIndexModel>
using namespace QuickOpen;
using namespace Help;
using namespace Help::Internal;
Q_DECLARE_METATYPE(IQuickOpenFilter*);
HelpIndexFilter::HelpIndexFilter(HelpPlugin *plugin, QHelpEngine *helpEngine):
m_plugin(plugin),
m_helpEngine(helpEngine),
m_icon(QIcon()) // TODO: Put an icon next to the results
{
setIncludedByDefault(false);
setShortcutString("?");
connect(m_helpEngine->indexModel(), SIGNAL(indexCreated()),
this, SLOT(updateIndices()));
}
void HelpIndexFilter::updateIndices()
{
const QString currentFilter = m_plugin->indexFilter();
if (!currentFilter.isEmpty())
m_plugin->setIndexFilter(QString());
m_helpIndex = m_helpEngine->indexModel()->stringList();
if (!currentFilter.isEmpty())
m_plugin->setIndexFilter(currentFilter);
}
QString HelpIndexFilter::trName() const
{
return tr("Help index");
}
QString HelpIndexFilter::name() const
{
return QLatin1String("HelpIndexFilter");
}
IQuickOpenFilter::Priority HelpIndexFilter::priority() const
{
return Medium;
}
QList<FilterEntry> HelpIndexFilter::matchesFor(const QString &entry)
{
QList<FilterEntry> entries;
foreach (const QString &string, m_helpIndex) {
if (string.contains(entry, Qt::CaseInsensitive)) {
FilterEntry entry(this, string, QVariant(), m_icon);
entries.append(entry);
}
}
return entries;
}
void HelpIndexFilter::accept(FilterEntry selection) const
{
QMap<QString, QUrl> links = m_helpEngine->indexModel()->linksForKeyword(selection.displayName);
if (links.size() == 1) {
emit linkActivated(links.begin().value());
} else if (!links.isEmpty()) {
emit linksActivated(links, selection.displayName);
}
}
void HelpIndexFilter::refresh(QFutureInterface<void> &future)
{
Q_UNUSED(future);
// Nothing to refresh
}

View File

@@ -0,0 +1,82 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef HELPINDEXFILTER_H
#define HELPINDEXFILTER_H
#include <quickopen/iquickopenfilter.h>
#include <QtGui/QIcon>
QT_BEGIN_NAMESPACE
class QHelpEngine;
class QUrl;
QT_END_NAMESPACE
namespace Help {
namespace Internal {
class HelpPlugin;
class HelpIndexFilter : public QuickOpen::IQuickOpenFilter
{
Q_OBJECT
public:
HelpIndexFilter(HelpPlugin *plugin, QHelpEngine *helpEngine);
// IQuickOpenFilter
QString trName() const;
QString name() const;
Priority priority() const;
QList<QuickOpen::FilterEntry> matchesFor(const QString &entry);
void accept(QuickOpen::FilterEntry selection) const;
void refresh(QFutureInterface<void> &future);
signals:
void linkActivated(const QUrl &link) const;
void linksActivated(const QMap<QString, QUrl> &urls, const QString &keyword) const;
private slots:
void updateIndices();
private:
HelpPlugin *m_plugin;
QHelpEngine *m_helpEngine;
QStringList m_helpIndex;
QIcon m_icon;
};
} // namespace Internal
} // namespace Help
#endif // HELPINDEXFILTER_H

View File

@@ -0,0 +1,53 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "helpmode.h"
#include "helpplugin.h"
#include <QtCore/QLatin1String>
#include <QtGui/QWidget>
#include <coreplugin/findplaceholder.h>
using namespace Help;
using namespace Help::Internal;
HelpMode::HelpMode(QWidget *widget, QWidget *centralWidget, QObject *parent):
BaseMode(tr("Help"),
Constants::ID_MODE_HELP,
QIcon((QLatin1String(":/fancyactionbar/images/mode_Reference.png"))), Constants::P_MODE_HELP, widget, parent),
m_centralWidget(centralWidget)
{
m_centralWidget->layout()->setSpacing(0);
m_centralWidget->layout()->addWidget(new Core::FindToolBarPlaceHolder(this));
}

View File

@@ -0,0 +1,61 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef HELPMODE_H
#define HELPMODE_H
#include <QtCore/QObject>
#include <coreplugin/basemode.h>
QT_BEGIN_NAMESPACE
class QWidget;
QT_END_NAMESPACE
namespace Help {
namespace Internal {
class HelpMode : public Core::BaseMode
{
Q_OBJECT
public:
HelpMode(QWidget *widget, QWidget *centralWidget, QObject *parent = 0);
private:
QWidget *m_centralWidget;
};
} // namespace Internal
} // namespace Help
#endif // HELPMODE_H

View File

@@ -0,0 +1,684 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "helpplugin.h"
#include "docsettingspage.h"
#include "filtersettingspage.h"
#include "helpindexfilter.h"
#include "helpmode.h"
#include "helpviewer.h"
#include "contentwindow.h"
#include "indexwindow.h"
#include "bookmarkmanager.h"
#include "centralwidget.h"
#include "helpfindsupport.h"
#include "searchwidget.h"
#include <QtCore/QDebug>
#include <QtCore/qplugin.h>
#include <QtCore/QFileInfo>
#include <QtCore/QSettings>
#include <QtCore/QDir>
#include <QtCore/QResource>
#include <QtGui/QAction>
#include <QtGui/QShortcut>
#include <QtGui/QSplitter>
#include <QtGui/QStyle>
#include <QtGui/QToolBar>
#include <QtGui/QComboBox>
#include <QtHelp/QHelpEngine>
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/uniqueidmanager.h>
#include <coreplugin/actionmanager/actionmanagerinterface.h>
#include <coreplugin/minisplitter.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/rightpane.h>
#include <coreplugin/sidebar.h>
#include <coreplugin/welcomemode.h>
using namespace Help;
using namespace Help::Internal;
HelpManager::HelpManager(QHelpEngine *helpEngine)
: m_helpEngine(helpEngine)
{
}
void HelpManager::registerDocumentation(const QStringList &fileNames)
{
bool needsSetup = false;
{
QHelpEngineCore hc(m_helpEngine->collectionFile());
hc.setupData();
foreach (const QString &fileName, fileNames) {
if (!QFile::exists(fileName))
continue;
QString fileNamespace = QHelpEngineCore::namespaceName(fileName);
if (!fileNamespace.isEmpty() && !hc.registeredDocumentations().contains(fileNamespace)) {
if (hc.registerDocumentation(fileName))
needsSetup = true;
else
qDebug() << "error registering" << fileName << hc.error();
}
}
}
if (needsSetup)
qDebug() << m_helpEngine->setupData();
}
HelpPlugin::HelpPlugin() :
m_core(0),
m_helpEngine(0),
m_contextHelpEngine(0),
m_contentWidget(0),
m_indexWidget(0),
m_centralWidget(0),
m_helpViewerForSideBar(0),
m_mode(0),
m_shownLastPages(false),
m_contentItem(0),
m_indexItem(0),
m_searchItem(0),
m_bookmarkItem(0),
m_rightPaneSideBar(0)
{
}
HelpPlugin::~HelpPlugin()
{
}
bool HelpPlugin::initialize(const QStringList & /*arguments*/, QString *)
{
m_core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();
QList<int> globalcontext;
globalcontext << Core::Constants::C_GLOBAL_ID;
QList<int> modecontext;
modecontext << m_core->uniqueIDManager()->uniqueIdentifier(Constants::C_MODE_HELP);
// FIXME shouldn't the help engine create the directory if it doesn't exist?
QFileInfo fi(m_core->settings()->fileName());
QDir directory(fi.absolutePath());
if (!directory.exists())
directory.mkpath(directory.absolutePath());
m_helpEngine = new QHelpEngine(directory.absolutePath()
+ QLatin1String("/helpcollection.qhc"), this);
connect(m_helpEngine, SIGNAL(setupFinished()),
this, SLOT(updateFilterComboBox()));
addAutoReleasedObject(new HelpManager(m_helpEngine));
m_docSettingsPage = new DocSettingsPage(m_helpEngine);
addAutoReleasedObject(m_docSettingsPage);
m_filterSettingsPage = new FilterSettingsPage(m_helpEngine);
addAutoReleasedObject(m_filterSettingsPage);
connect(m_docSettingsPage, SIGNAL(documentationAdded()),
m_filterSettingsPage, SLOT(updateFilterPage()));
connect(m_docSettingsPage, SIGNAL(dialogAccepted()),
this, SLOT(checkForHelpChanges()));
m_contentWidget = new ContentWindow(m_helpEngine);
m_contentWidget->setWindowTitle(tr("Contents"));
m_indexWidget = new IndexWindow(m_helpEngine);
m_indexWidget->setWindowTitle(tr("Index"));
m_searchWidget = new SearchWidget(m_helpEngine->searchEngine());
m_searchWidget->setWindowTitle(tr("Search"));
m_bookmarkManager = new BookmarkManager(m_helpEngine);
m_bookmarkWidget = new BookmarkWidget(m_bookmarkManager, 0, false);
m_bookmarkWidget->setWindowTitle(tr("Bookmarks"));
connect(m_bookmarkWidget, SIGNAL(addBookmark()),
this, SLOT(addBookmark()));
Core::ActionManagerInterface *am = m_core->actionManager();
Core::ICommand *cmd;
// Add Home, Previous and Next actions (used in the toolbar)
QAction *homeAction = new QAction(QIcon(QLatin1String(":/help/images/home.png")), tr("Home"), this);
cmd = am->registerAction(homeAction, QLatin1String("Help.Home"), globalcontext);
QAction *previousAction = new QAction(QIcon(QLatin1String(":/help/images/previous.png")),
tr("Previous"), this);
cmd = am->registerAction(previousAction, QLatin1String("Help.Previous"), modecontext);
cmd->setDefaultKeySequence(QKeySequence(Qt::Key_Backspace));
QAction *nextAction = new QAction(QIcon(QLatin1String(":/help/images/next.png")), tr("Next"), this);
cmd = am->registerAction(nextAction, QLatin1String("Help.Next"), modecontext);
QAction *addBookmarkAction = new QAction(QIcon(QLatin1String(":/help/images/bookmark.png")),
tr("Add Bookmark"), this);
cmd = am->registerAction(addBookmarkAction, QLatin1String("Help.AddBookmark"), modecontext);
cmd->setDefaultKeySequence(QKeySequence(Qt::CTRL + Qt::Key_M));
// Add Index, Contents, and Context menu items and a separator to the Help menu
QAction *indexAction = new QAction(tr("Index"), this);
cmd = am->registerAction(indexAction, QLatin1String("Help.Index"), globalcontext);
am->actionContainer(Core::Constants::M_HELP)->addAction(cmd, Core::Constants::G_HELP_HELP);
QAction *contentsAction = new QAction(tr("Contents"), this);
cmd = am->registerAction(contentsAction, QLatin1String("Help.Contents"), globalcontext);
am->actionContainer(Core::Constants::M_HELP)->addAction(cmd, Core::Constants::G_HELP_HELP);
QAction *searchAction = new QAction(tr("Search"), this);
cmd = am->registerAction(searchAction, QLatin1String("Help.Search"), globalcontext);
am->actionContainer(Core::Constants::M_HELP)->addAction(cmd, Core::Constants::G_HELP_HELP);
QAction *contextAction = new QAction(tr("Context Help"), this);
cmd = am->registerAction(contextAction, QLatin1String("Help.Context"), globalcontext);
cmd->setDefaultKeySequence(QKeySequence(Qt::Key_F1));
am->actionContainer(Core::Constants::M_HELP)->addAction(cmd, Core::Constants::G_HELP_HELP);
#ifndef Q_OS_MAC
QAction *sep = new QAction(this);
sep->setSeparator(true);
cmd = am->registerAction(sep, QLatin1String("Help.Separator"), globalcontext);
am->actionContainer(Core::Constants::M_HELP)->addAction(cmd, Core::Constants::G_HELP_HELP);
#endif
m_centralWidget = new CentralWidget(m_helpEngine);
Aggregation::Aggregate *agg = new Aggregation::Aggregate;
agg->add(m_centralWidget);
agg->add(new HelpFindSupport(m_centralWidget));
QWidget *mainWidget = new QWidget;
QVBoxLayout *mainWidgetLayout = new QVBoxLayout(mainWidget);
mainWidgetLayout->setMargin(0);
mainWidgetLayout->setSpacing(0);
mainWidgetLayout->addWidget(createToolBar());
mainWidgetLayout->addWidget(m_centralWidget);
m_contentItem = new Core::SideBarItem(m_contentWidget);
m_indexItem = new Core::SideBarItem(m_indexWidget);
m_searchItem = new Core::SideBarItem(m_searchWidget);
m_bookmarkItem = new Core::SideBarItem(m_bookmarkWidget);
QList<Core::SideBarItem*> itemList;
itemList << m_contentItem << m_indexItem << m_searchItem << m_bookmarkItem;
m_sideBar = new Core::SideBar(itemList, QList<Core::SideBarItem*>() << m_indexItem);
QSplitter *splitter = new Core::MiniSplitter;
splitter->setOpaqueResize(false);
splitter->addWidget(m_sideBar);
splitter->addWidget(mainWidget);
splitter->setStretchFactor(0, 0);
splitter->setStretchFactor(1, 1);
splitter->setSizes(QList<int>() << 300 << 300);
m_mode = new HelpMode(splitter, m_centralWidget);
m_mode->setContext(QList<int>() << modecontext);
addAutoReleasedObject(m_mode);
QAction *printAction = new QAction(this);
am->registerAction(printAction, Core::Constants::PRINT, modecontext);
connect(printAction, SIGNAL(triggered()), m_centralWidget, SLOT(print()));
QAction *copyAction = new QAction(this);
cmd = am->registerAction(copyAction, Core::Constants::COPY, modecontext);
connect(copyAction, SIGNAL(triggered()), m_centralWidget, SLOT(copy()));
copyAction->setText(cmd->action()->text());
copyAction->setIcon(cmd->action()->icon());
QMap<QString, Core::ICommand*> shortcutMap;
QShortcut *shortcut = new QShortcut(splitter);
shortcut->setWhatsThis(tr("Activate Index in Help mode"));
cmd = am->registerShortcut(shortcut, QLatin1String("Help.IndexShortcut"), modecontext);
cmd->setDefaultKeySequence(QKeySequence(Qt::CTRL + Qt::Key_I));
connect(shortcut, SIGNAL(activated()), this, SLOT(activateIndex()));
shortcutMap.insert(m_indexWidget->windowTitle(), cmd);
shortcut = new QShortcut(splitter);
shortcut->setWhatsThis(tr("Activate Contents in Help mode"));
cmd = am->registerShortcut(shortcut, QLatin1String("Help.ContentsShortcut"), modecontext);
cmd->setDefaultKeySequence(QKeySequence(Qt::CTRL + Qt::Key_T));
connect(shortcut, SIGNAL(activated()), this, SLOT(activateContents()));
shortcutMap.insert(m_contentWidget->windowTitle(), cmd);
shortcut = new QShortcut(splitter);
shortcut->setWhatsThis(tr("Activate Search in Help mode"));
cmd = am->registerShortcut(shortcut, QLatin1String("Help.SearchShortcut"), modecontext);
cmd->setDefaultKeySequence(QKeySequence(Qt::CTRL + Qt::Key_S));
connect(shortcut, SIGNAL(activated()), this, SLOT(activateSearch()));
shortcutMap.insert(m_searchWidget->windowTitle(), cmd);
shortcutMap.insert(m_bookmarkWidget->windowTitle(), 0);
m_sideBar->setShortcutMap(shortcutMap);
connect(homeAction, SIGNAL(triggered()), m_centralWidget, SLOT(home()));
connect(previousAction, SIGNAL(triggered()), m_centralWidget, SLOT(backward()));
connect(nextAction, SIGNAL(triggered()), m_centralWidget, SLOT(forward()));
connect(addBookmarkAction, SIGNAL(triggered()), this, SLOT(addBookmark()));
connect(m_contentWidget, SIGNAL(linkActivated(const QUrl&)),
m_centralWidget, SLOT(setSource(const QUrl&)));
connect(m_indexWidget, SIGNAL(linkActivated(const QUrl&)),
m_centralWidget, SLOT(setSource(const QUrl&)));
connect(m_searchWidget, SIGNAL(requestShowLink(const QUrl&)),
m_centralWidget, SLOT(setSource(const QUrl&)));
connect(m_searchWidget, SIGNAL(requestShowLinkInNewTab(const QUrl&)),
m_centralWidget, SLOT(setSourceInNewTab(const QUrl&)));
connect(m_bookmarkWidget, SIGNAL(requestShowLink(const QUrl&)),
m_centralWidget, SLOT(setSource(const QUrl&)));
connect(m_centralWidget, SIGNAL(backwardAvailable(bool)),
previousAction, SLOT(setEnabled(bool)));
connect(m_centralWidget, SIGNAL(forwardAvailable(bool)),
nextAction, SLOT(setEnabled(bool)));
connect(m_centralWidget, SIGNAL(addNewBookmark(const QString&, const QString&)),
this, SLOT(addNewBookmark(const QString&, const QString&)));
QList<QAction*> actionList;
actionList << previousAction
<< nextAction
<< homeAction
#ifndef Q_OS_MAC
<< sep
#endif
<< copyAction;
m_centralWidget->setGlobalActions(actionList);
connect(contextAction, SIGNAL(triggered()), this, SLOT(activateContext()));
connect(indexAction, SIGNAL(triggered()), this, SLOT(activateIndex()));
connect(contentsAction, SIGNAL(triggered()), this, SLOT(activateContents()));
connect(searchAction, SIGNAL(triggered()), this, SLOT(activateSearch()));
connect(m_core->modeManager(), SIGNAL(currentModeChanged(Core::IMode*)),
this, SLOT(modeChanged(Core::IMode*)));
connect(m_contentWidget, SIGNAL(linkActivated(const QUrl&)),
m_centralWidget, SLOT(setSource(const QUrl&)));
connect(m_indexWidget, SIGNAL(linkActivated(const QUrl&)),
m_centralWidget, SLOT(setSource(const QUrl&)));
connect(m_indexWidget, SIGNAL(linksActivated(const QMap<QString, QUrl>&, const QString&)),
m_centralWidget, SLOT(showTopicChooser(const QMap<QString, QUrl>&, const QString&)));
HelpIndexFilter *helpIndexFilter = new HelpIndexFilter(this, m_helpEngine);
addAutoReleasedObject(helpIndexFilter);
connect(helpIndexFilter, SIGNAL(linkActivated(QUrl)),
this, SLOT(switchToHelpMode(QUrl)));
connect(helpIndexFilter, SIGNAL(linksActivated(const QMap<QString, QUrl>&, const QString&)),
this, SLOT(switchToHelpMode(const QMap<QString, QUrl>&, const QString&)));
previousAction->setEnabled(m_centralWidget->isBackwardAvailable());
nextAction->setEnabled(m_centralWidget->isForwardAvailable());
createRightPaneSideBar();
return true;
}
void HelpPlugin::createRightPaneSideBar()
{
QAction *switchToHelpMode = new QAction("Go to Help Mode", this);
m_rightPaneBackwardAction = new QAction(QIcon(QLatin1String(":/help/images/previous.png")), tr("Previous"), this);
m_rightPaneForwardAction = new QAction(QIcon(QLatin1String(":/help/images/next.png")), tr("Next"), this);
QToolBar *rightPaneToolBar = new QToolBar();
rightPaneToolBar->addAction(switchToHelpMode);
rightPaneToolBar->addAction(m_rightPaneBackwardAction);
rightPaneToolBar->addAction(m_rightPaneForwardAction);
connect(switchToHelpMode, SIGNAL(triggered()), this, SLOT(switchToHelpMode()));
connect(m_rightPaneBackwardAction, SIGNAL(triggered()), this, SLOT(rightPaneBackward()));
connect(m_rightPaneForwardAction, SIGNAL(triggered()), this, SLOT(rightPaneForward()));
QToolButton *closeButton = new QToolButton();
closeButton->setProperty("type", QLatin1String("dockbutton"));
closeButton->setIcon(QIcon(":/qworkbench/images/closebutton.png"));
// Dummy layout to align the close button to the right
QHBoxLayout *hboxLayout = new QHBoxLayout();
hboxLayout->setSpacing(0);
hboxLayout->setMargin(0);
hboxLayout->addStretch(5);
hboxLayout->addWidget(closeButton);
QWidget *w = new QWidget(rightPaneToolBar);
w->setLayout(hboxLayout);
rightPaneToolBar->addWidget(w);
connect(closeButton, SIGNAL(clicked()), this, SLOT(slotHideRightPane()));
QVBoxLayout *rightPaneLayout = new QVBoxLayout;
rightPaneLayout->setMargin(0);
rightPaneLayout->setSpacing(0);
rightPaneLayout->addWidget(rightPaneToolBar);
m_helpViewerForSideBar = new HelpViewer(m_helpEngine, 0);
rightPaneLayout->addWidget(m_helpViewerForSideBar);
m_rightPaneSideBar = new QWidget;
m_rightPaneSideBar->setLayout(rightPaneLayout);
m_rightPaneSideBar->setFocusProxy(m_helpViewerForSideBar);
addAutoReleasedObject(new Core::BaseRightPaneWidget(m_rightPaneSideBar));
}
void HelpPlugin::rightPaneBackward()
{
m_helpViewerForSideBar->backward();
}
void HelpPlugin::rightPaneForward()
{
m_helpViewerForSideBar->forward();
}
void HelpPlugin::switchToHelpMode()
{
switchToHelpMode(m_helpViewerForSideBar->source());
Core::RightPaneWidget::instance()->setShown(false);
}
void HelpPlugin::switchToHelpMode(const QUrl &source)
{
m_core->modeManager()->activateMode(QLatin1String(Constants::ID_MODE_HELP));
m_centralWidget->setSource(source);
m_centralWidget->setFocus();
}
void HelpPlugin::switchToHelpMode(const QMap<QString, QUrl> &urls, const QString &keyword)
{
m_core->modeManager()->activateMode(QLatin1String(Constants::ID_MODE_HELP));
m_centralWidget->showTopicChooser(urls, keyword);
}
void HelpPlugin::slotHideRightPane()
{
Core::RightPaneWidget::instance()->setShown(false);
}
void HelpPlugin::extensionsInitialized()
{
m_sideBar->readSettings(m_core->settings());
if (!m_helpEngine->setupData()) {
qWarning() << "Could not initialize help engine: " << m_helpEngine->error();
return;
}
bool needsSetup = false;
bool assistantInternalDocRegistered = false;
foreach (QString ns, m_helpEngine->registeredDocumentations()) {
if (ns == QString("com.nokia.qtcreator.%1%2")
.arg(IDE_VERSION_MAJOR).arg(IDE_VERSION_MINOR)) {
assistantInternalDocRegistered = true;
break;
}
}
if (!assistantInternalDocRegistered) {
QFileInfo fi(m_helpEngine->collectionFile());
const QString qchFileName =
QDir::cleanPath(QCoreApplication::applicationDirPath()
#if defined(Q_OS_MAC)
+ QLatin1String("/../Resources/doc/qtcreator.qch"));
#else
+ QLatin1String("/../doc/qtcreator.qch"));
#endif
QHelpEngineCore hc(fi.absoluteFilePath());
hc.setupData();
if (!hc.registerDocumentation(qchFileName))
qDebug() << hc.error();
needsSetup = true;
}
int i = m_helpEngine->customValue(
QLatin1String("UnfilteredFilterInserted")).toInt();
if (i != 1) {
{
QHelpEngineCore hc(m_helpEngine->collectionFile());
hc.setupData();
hc.addCustomFilter(tr("Unfiltered"), QStringList());
hc.setCustomValue(QLatin1String("UnfilteredFilterInserted"), 1);
}
m_helpEngine->blockSignals(true);
m_helpEngine->setCurrentFilter(tr("Unfiltered"));
m_helpEngine->blockSignals(false);
needsSetup = true;
}
if (needsSetup)
m_helpEngine->setupData();
updateFilterComboBox();
m_bookmarkManager->setupBookmarkModels();
if (Core::Internal::WelcomeMode *welcomeMode = qobject_cast<Core::Internal::WelcomeMode*>(m_core->modeManager()->mode(Core::Constants::MODE_WELCOME))) {
connect(welcomeMode, SIGNAL(requestHelp(QString)), this, SLOT(openGettingStarted()));
}
}
void HelpPlugin::shutdown()
{
m_sideBar->saveSettings(m_core->settings());
m_bookmarkManager->saveBookmarks();
delete m_bookmarkManager;
}
void HelpPlugin::setIndexFilter(const QString &filter)
{
m_indexWidget->setSearchLineEditText(filter);
}
QString HelpPlugin::indexFilter() const
{
return m_indexWidget->searchLineEditText();
}
void HelpPlugin::modeChanged(Core::IMode *mode)
{
if (mode == m_mode && !m_shownLastPages) {
m_shownLastPages = true;
qApp->processEvents();
qApp->setOverrideCursor(Qt::WaitCursor);
m_centralWidget->setLastShownPages();
qApp->restoreOverrideCursor();
}
}
void HelpPlugin::activateContext()
{
using namespace Core;
// case 1 sidebar shown and has focus, we show whatever we have in the
// sidebar in big
RightPanePlaceHolder* placeHolder = RightPanePlaceHolder::current();
if(placeHolder && Core::RightPaneWidget::instance()->hasFocus()) {
switchToHelpMode();
return;
}
bool useSideBar = false;
if (placeHolder && !Core::RightPaneWidget::instance()->hasFocus())
useSideBar = true;
// Find out what to show
HelpViewer *viewer = 0;
if (IContext *context = m_core->currentContextObject()) {
if (!m_contextHelpEngine) {
m_contextHelpEngine = new QHelpEngineCore(m_helpEngine->collectionFile(), this);
//m_contextHelpEngine->setAutoSaveFilter(false);
m_contextHelpEngine->setupData();
m_contextHelpEngine->setCurrentFilter(tr("Unfiltered"));
}
const QString &id = context->contextHelpId();
QMap<QString, QUrl> links = m_contextHelpEngine->linksForIdentifier(id);
if (!links.isEmpty()) {
if (useSideBar) {
Core::RightPaneWidget::instance()->setShown(true);
viewer = m_helpViewerForSideBar;
} else {
viewer = m_centralWidget->currentHelpViewer();
m_core->modeManager()->activateMode(QLatin1String(Constants::ID_MODE_HELP));
}
if (viewer) {
QUrl source = *links.begin();
if (viewer->source() != source)
viewer->setSource(source);
viewer->setFocus();
}
} else {
// No link found
if (useSideBar) {
Core::RightPaneWidget::instance()->setShown(true);
viewer = m_helpViewerForSideBar;
} else {
viewer = m_centralWidget->currentHelpViewer();
m_core->modeManager()->activateMode(QLatin1String(Constants::ID_MODE_HELP));
}
if (viewer) {
viewer->setHtml(tr("<title>No Documentation</title><br><br>"
"<center><b>%1</b><br><br>No documentation available.").
arg(id));
viewer->setSource(QUrl());
//activateIndex();
}
}
} else {
// No context object
if (useSideBar) {
Core::RightPaneWidget::instance()->setShown(true);
viewer = m_helpViewerForSideBar;
} else {
viewer = m_centralWidget->currentHelpViewer();
m_core->modeManager()->activateMode(QLatin1String(Constants::ID_MODE_HELP));
}
if (viewer) {
viewer->setSource(QUrl());
viewer->setHtml("<title>No Documentation</title><br><br><center>No"
" documentation available.");
//activateIndex();
}
}
}
void HelpPlugin::activateIndex()
{
m_core->modeManager()->activateMode(QLatin1String(Constants::ID_MODE_HELP));
m_sideBar->activateItem(m_indexItem);
}
void HelpPlugin::activateContents()
{
m_core->modeManager()->activateMode(QLatin1String(Constants::ID_MODE_HELP));
m_sideBar->activateItem(m_contentItem);
}
void HelpPlugin::activateSearch()
{
m_core->modeManager()->activateMode(QLatin1String(Constants::ID_MODE_HELP));
m_sideBar->activateItem(m_searchItem);
}
QToolBar *HelpPlugin::createToolBar()
{
QToolBar *toolWidget = new QToolBar;
Core::ActionManagerInterface *am = m_core->actionManager();
toolWidget->addAction(am->command(QLatin1String("Help.Home"))->action());
toolWidget->addAction(am->command(QLatin1String("Help.Previous"))->action());
toolWidget->addAction(am->command(QLatin1String("Help.Next"))->action());
toolWidget->addSeparator();
toolWidget->addAction(am->command(QLatin1String("Help.AddBookmark"))->action());
//int size = toolWidget->style()->pixelMetric(QStyle::PM_SmallIconSize);
//toolWidget->setIconSize(QSize(size, size));
toolWidget->setMovable(false);
toolWidget->addSeparator();
QWidget *w = new QWidget;
QHBoxLayout *layout = new QHBoxLayout(w);
layout->setMargin(0);
layout->addSpacing(10);
layout->addWidget(new QLabel(tr("Filtered by:")));
m_filterComboBox = new QComboBox;
m_filterComboBox->setMinimumContentsLength(20);
connect(m_filterComboBox, SIGNAL(activated(const QString&)),
this, SLOT(filterDocumentation(const QString&)));
layout->addWidget(m_filterComboBox);
toolWidget->addWidget(w);
return toolWidget;
}
void HelpPlugin::updateFilterComboBox()
{
QString curFilter = m_filterComboBox->currentText();
if (curFilter.isEmpty())
curFilter = m_helpEngine->currentFilter();
m_filterComboBox->clear();
m_filterComboBox->addItems(m_helpEngine->customFilters());
int idx = m_filterComboBox->findText(curFilter);
if (idx < 0)
idx = 0;
m_filterComboBox->setCurrentIndex(idx);
}
void HelpPlugin::checkForHelpChanges()
{
bool changed = m_docSettingsPage->applyChanges();
changed |= m_filterSettingsPage->applyChanges();
if (changed)
m_helpEngine->setupData();
}
void HelpPlugin::filterDocumentation(const QString &customFilter)
{
m_helpEngine->setCurrentFilter(customFilter);
}
void HelpPlugin::addBookmark()
{
addNewBookmark(m_centralWidget->currentTitle(), m_centralWidget->currentSource().toString());
}
void HelpPlugin::addNewBookmark(const QString &title, const QString &url)
{
if (url.isEmpty())
return;
m_bookmarkManager->showBookmarkDialog(m_centralWidget, title, url);
}
void HelpPlugin::openGettingStarted()
{
m_core->modeManager()->activateMode(QLatin1String(Constants::ID_MODE_HELP));
m_centralWidget->setSource(
QString("qthelp://com.nokia.qtcreator.%1%2/doc/index.html")
.arg(IDE_VERSION_MAJOR).arg(IDE_VERSION_MINOR));
}
Q_EXPORT_PLUGIN(HelpPlugin)

View File

@@ -0,0 +1,169 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef HELPPLUGIN_H
#define HELPPLUGIN_H
#include "help_global.h"
#include <extensionsystem/iplugin.h>
#include <QtCore/QMap>
QT_BEGIN_NAMESPACE
class QAction;
class QComboBox;
class QHelpEngineCore;
class QHelpEngine;
class QShortcut;
class QToolBar;
class QUrl;
class IndexWindow;
class ContentWindow;
class BookmarkManager;
class BookmarkWidget;
class CentralWidget;
class HelpViewer;
QT_END_NAMESPACE
namespace Core {
class ICore;
class IMode;
class SideBar;
class SideBarItem;
}
namespace Help {
namespace Constants {
const char * const HELPVIEWER_KIND = "Qt Help Viewer";
const char * const C_MODE_HELP = "Help Mode";
const int P_MODE_HELP = 70;
const char * const ID_MODE_HELP = "Help.HelpMode";
}
class HELP_EXPORT HelpManager : public QObject
{
Q_OBJECT
public:
HelpManager(QHelpEngine *helpEngine);
void registerDocumentation(const QStringList &fileNames);
private:
QHelpEngine *m_helpEngine;
};
namespace Internal {
class HelpMode;
class HelpPluginEditorFactory;
class DocSettingsPage;
class FilterSettingsPage;
class SearchWidget;
class HelpPlugin : public ExtensionSystem::IPlugin
{
Q_OBJECT
public:
HelpPlugin();
virtual ~HelpPlugin();
bool initialize(const QStringList &arguments, QString *error_message);
void extensionsInitialized();
void shutdown();
// Necessary to get the unfiltered list in the help index filter
void setIndexFilter(const QString &filter);
QString indexFilter() const;
private slots:
void modeChanged(Core::IMode *mode);
void activateContext();
void activateIndex();
void activateContents();
void activateSearch();
void checkForHelpChanges();
void updateFilterComboBox();
void filterDocumentation(const QString &customFilter);
void addBookmark();
void addNewBookmark(const QString &title, const QString &url);
void rightPaneBackward();
void rightPaneForward();
void switchToHelpMode();
void switchToHelpMode(const QUrl &source);
void switchToHelpMode(const QMap<QString, QUrl> &urls, const QString &keyword);
void slotHideRightPane();
void openGettingStarted();
private:
QToolBar *createToolBar();
void createRightPaneSideBar();
Core::ICore *m_core;
QHelpEngine *m_helpEngine;
QHelpEngineCore *m_contextHelpEngine;
ContentWindow *m_contentWidget;
IndexWindow *m_indexWidget;
BookmarkWidget *m_bookmarkWidget;
BookmarkManager *m_bookmarkManager;
SearchWidget *m_searchWidget;
CentralWidget *m_centralWidget;
HelpViewer *m_helpViewerForSideBar;
HelpMode *m_mode;
bool m_shownLastPages;
Core::SideBarItem *m_contentItem;
Core::SideBarItem *m_indexItem;
Core::SideBarItem *m_searchItem;
Core::SideBarItem *m_bookmarkItem;
DocSettingsPage *m_docSettingsPage;
FilterSettingsPage *m_filterSettingsPage;
QComboBox *m_filterComboBox;
Core::SideBar *m_sideBar;
QWidget *m_rightPaneSideBar;
QAction *m_rightPaneBackwardAction;
QAction *m_rightPaneForwardAction;
};
} // namespace Internal
} // namespace Help
#endif // HELPPLUGIN_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 908 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

View File

@@ -0,0 +1,215 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include <QtCore/QDebug>
#include <QtGui/QKeyEvent>
#include <QtGui/QFocusEvent>
#include <QtGui/QLayout>
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include <QtGui/QListView>
#include <QtGui/QApplication>
#include "indextoolwindow.h"
#include "helpengine.h"
#include "topicchooser.h"
using namespace Help::Internal;
IndexToolWidget::IndexToolWidget()
{
wasInitialized = false;
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setMargin(0);
QLabel *l = new QLabel(tr("Look for:"), this);
layout->addWidget(l);
findLineEdit = new QLineEdit(this);
findLineEdit->installEventFilter(this);
layout->addWidget(findLineEdit);
indicesView = new QListView(this);
indicesView->setLayoutMode(QListView::Batched);
indicesView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
layout->addWidget(indicesView);
setWindowTitle(tr("Index"));
setWindowIcon(QIcon(":/help/images/find.png"));
}
void IndexToolWidget::focusInEvent(QFocusEvent *e)
{
showEvent(0);
if (e && e->reason() != Qt::MouseFocusReason) {
findLineEdit->selectAll();
findLineEdit->setFocus();
}
}
void IndexToolWidget::showEvent(QShowEvent *)
{
if (!wasInitialized) {
wasInitialized = true;
setCursor(QCursor(Qt::WaitCursor));
emit buildRequested();
}
}
bool IndexToolWidget::eventFilter(QObject * o, QEvent * e)
{
if (o == findLineEdit && e->type() == QEvent::KeyPress) {
switch (static_cast<QKeyEvent*>(e)->key()) {
case Qt::Key_Up:
case Qt::Key_Down:
case Qt::Key_PageDown:
case Qt::Key_PageUp:
QApplication::sendEvent(indicesView, e);
break;
case Qt::Key_Escape:
emit escapePressed();
break;
default:
break;
}
}
return QWidget::eventFilter(o, e);
}
IndexToolWindow::IndexToolWindow(const QList<int> &context, HelpEngine *help)
{
m_context = context;
m_context << 0;
m_widget = new IndexToolWidget;
helpEngine = help;
connect(helpEngine, SIGNAL(indexInitialized()), this, SLOT(indexDone()));
model = 0;
connect(m_widget->findLineEdit, SIGNAL(textEdited(const QString&)),
this, SLOT(searchInIndex(const QString &)));
connect(m_widget->findLineEdit, SIGNAL(returnPressed()), this, SLOT(indexRequested()));
connect(m_widget, SIGNAL(buildRequested()), helpEngine, SLOT(buildIndex()));
connect(m_widget->indicesView, SIGNAL(activated(const QModelIndex&)),
this, SLOT(indexRequested()));
connect(m_widget, SIGNAL(escapePressed()), this, SIGNAL(escapePressed()));
}
IndexToolWindow::~IndexToolWindow()
{
delete m_widget;
}
const QList<int> &IndexToolWindow::context() const
{
return m_context;
}
QWidget *IndexToolWindow::widget()
{
return m_widget;
}
void IndexToolWindow::indexDone()
{
model = helpEngine->indices();
m_widget->indicesView->setModel(model);
m_widget->setCursor(QCursor(Qt::ArrowCursor));
}
void IndexToolWindow::searchInIndex(const QString &str)
{
if (!model)
return;
QRegExp atoz("[A-Z]");
int matches = str.count(atoz);
if (matches > 0 && !str.contains(".*"))
{
int start = 0;
QString newSearch;
for (; matches > 0; --matches) {
int match = str.indexOf(atoz, start+1);
if (match <= start)
continue;
newSearch += str.mid(start, match-start);
newSearch += ".*";
start = match;
}
newSearch += str.mid(start);
m_widget->indicesView->setCurrentIndex(model->filter(newSearch, str));
}
else
m_widget->indicesView->setCurrentIndex(model->filter(str, str));
}
void IndexToolWindow::indexRequested()
{
if (!model)
return;
int row = m_widget->indicesView->currentIndex().row();
if (row == -1 || row >= model->rowCount())
return;
QString description = model->description(row);
QStringList links = model->links(row);
bool blocked = m_widget->findLineEdit->blockSignals(true);
m_widget->findLineEdit->setText(description);
m_widget->findLineEdit->blockSignals(blocked);
if (links.count() == 1) {
emit showLinkRequested(links.first(), false);
} else {
qSort(links);
QStringList::Iterator it = links.begin();
QStringList linkList;
QStringList linkNames;
for (; it != links.end(); ++it) {
linkList << *it;
linkNames << helpEngine->titleOfLink(*it);
}
QString link = TopicChooser::getLink(m_widget, linkNames, linkList, description);
if (!link.isEmpty())
emit showLinkRequested(link, false);
}
model->publish();
m_widget->indicesView->setCurrentIndex(model->index(model->stringList().indexOf(description)));
m_widget->indicesView->scrollTo(m_widget->indicesView->currentIndex(), QAbstractItemView::PositionAtTop);
}

View File

@@ -0,0 +1,113 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef INDEXTOOLWINDOW_H
#define INDEXTOOLWINDOW_H
#include <QtCore/QModelIndex>
#include <QtGui/QWidget>
#include <coreplugin/iview.h>
class QListView;
class QLineEdit;
namespace Help {
namespace Internal {
class HelpEngine;
class IndexListModel;
class IndexToolWindow;
class IndexToolWidget : public QWidget
{
Q_OBJECT
public:
IndexToolWidget();
signals:
void buildRequested();
void escapePressed();
private:
friend class IndexToolWindow;
bool eventFilter(QObject * o, QEvent * e);
void showEvent(QShowEvent *e);
void focusInEvent(QFocusEvent *e);
bool wasInitialized;
QLineEdit *findLineEdit;
QListView *indicesView;
};
class IndexToolWindow : public Core::IView
{
Q_OBJECT
public:
IndexToolWindow(const QList<int> &context, HelpEngine *help);
~IndexToolWindow();
const QList<int> &context() const;
QWidget *widget();
QList<QWidget*> dockToolBarWidgets() const { return QList<QWidget*>(); }
const char *uniqueViewName() const { return "Help.IndexToolWindow"; }
const char *globalMenuGroup() const { return "Help.Group"; }
inline QKeySequence defaultShortcut() const { return QKeySequence(); }
Qt::DockWidgetArea defaultArea() const { return Qt::RightDockWidgetArea; }
IView::ViewPosition defaultPosition() const { return IView::Second; }
signals:
void showLinkRequested(const QString &link, bool newWindow);
void escapePressed();
private slots:
void indexDone();
void searchInIndex(const QString &str);
void indexRequested();
private:
HelpEngine *helpEngine;
IndexListModel *model;
QList<int> m_context;
IndexToolWidget *m_widget;
};
} // namespace Internal
} // namespace Help
#endif // INDEXTOOLWINDOW_H

View File

@@ -0,0 +1,82 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef INDEXWINDOW
#define INDEXWINDOW
#include <QtCore/QUrl>
#include <QtGui/QWidget>
#include <QtGui/QLineEdit>
QT_BEGIN_NAMESPACE
class QHelpIndexWidget;
class QHelpEngine;
class IndexWindow : public QWidget
{
Q_OBJECT
public:
IndexWindow(QHelpEngine *helpEngine, QWidget *parent = 0);
~IndexWindow();
void setSearchLineEditText(const QString &text);
QString searchLineEditText() const
{
return m_searchLineEdit->text();
}
signals:
void linkActivated(const QUrl &link);
void linksActivated(const QMap<QString, QUrl> &links,
const QString &keyword);
void escapePressed();
private slots:
void filterIndices(const QString &filter);
void enableSearchLineEdit();
void disableSearchLineEdit();
private:
bool eventFilter(QObject *obj, QEvent *e);
void focusInEvent(QFocusEvent *e);
QLineEdit *m_searchLineEdit;
QHelpIndexWidget *m_indexWidget;
QHelpEngine *m_helpEngine;
};
QT_END_NAMESPACE
#endif

View File

@@ -0,0 +1,213 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "searchwidget.h"
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtGui/QMenu>
#include <QtGui/QLayout>
#include <QtGui/QKeyEvent>
#include <QtGui/QClipboard>
#include <QtGui/QApplication>
#include <QtGui/QTextBrowser>
#include <QtHelp/QHelpSearchEngine>
#include <QtHelp/QHelpSearchQueryWidget>
#include <QtHelp/QHelpSearchResultWidget>
using namespace Help::Internal;
SearchWidget::SearchWidget(QHelpSearchEngine *engine, QWidget *parent)
: QWidget(parent)
, zoomCount(0)
, searchEngine(engine)
{
QVBoxLayout *vLayout = new QVBoxLayout(this);
resultWidget = searchEngine->resultWidget();
QHelpSearchQueryWidget *queryWidget = searchEngine->queryWidget();
vLayout->addWidget(queryWidget);
vLayout->addWidget(resultWidget);
setFocusProxy(queryWidget);
connect(queryWidget, SIGNAL(search()), this, SLOT(search()));
connect(resultWidget, SIGNAL(requestShowLink(const QUrl&)),
this, SIGNAL(requestShowLink(const QUrl&)));
connect(searchEngine, SIGNAL(searchingStarted()), this, SLOT(searchingStarted()));
connect(searchEngine, SIGNAL(searchingFinished(int)), this, SLOT(searchingFinished(int)));
}
SearchWidget::~SearchWidget()
{
// nothing todo
}
void SearchWidget::zoomIn()
{
#ifndef QT_CLUCENE_SUPPORT
return;
#endif
QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget);
if (browser && zoomCount != 10) {
zoomCount++;
browser->zoomIn();
}
}
void SearchWidget::zoomOut()
{
#ifndef QT_CLUCENE_SUPPORT
return;
#endif
QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget);
if (browser && zoomCount != -5) {
zoomCount--;
browser->zoomOut();
}
}
void SearchWidget::resetZoom()
{
#ifndef QT_CLUCENE_SUPPORT
return;
#endif
if (zoomCount == 0)
return;
QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget);
if (browser) {
browser->zoomOut(zoomCount);
zoomCount = 0;
}
}
void SearchWidget::search() const
{
QList<QHelpSearchQuery> query = searchEngine->queryWidget()->query();
searchEngine->search(query);
}
void SearchWidget::searchingStarted()
{
qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
}
void SearchWidget::searchingFinished(int hits)
{
Q_UNUSED(hits)
qApp->restoreOverrideCursor();
}
void SearchWidget::keyPressEvent(QKeyEvent *keyEvent)
{
if (keyEvent->key() == Qt::Key_Escape)
emit escapePressed();
}
void SearchWidget::contextMenuEvent(QContextMenuEvent *contextMenuEvent)
{
QMenu menu;
QPoint point = contextMenuEvent->globalPos();
#ifdef QT_CLUCENE_SUPPORT
QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget);
if (!browser)
return;
point = browser->mapFromGlobal(point);
if (!browser->rect().contains(point, true))
return;
QUrl link = browser->anchorAt(point);
QAction *copyAction = menu.addAction(tr("&Copy") +
QString(QLatin1String("\t") + QString(QKeySequence(Qt::CTRL | Qt::Key_C))));
copyAction->setEnabled(QTextCursor(browser->textCursor()).hasSelection());
QAction *copyAnchorAction = menu.addAction(tr("Copy &Link Location"));
copyAnchorAction->setEnabled(!link.isEmpty() && link.isValid());
QAction *newTabAction = menu.addAction(tr("Open Link in New Tab") +
QString(QLatin1String("\t") + QString(QKeySequence(Qt::CTRL))) +
QLatin1String("LMB"));
newTabAction->setEnabled(!link.isEmpty() && link.isValid());
menu.addSeparator();
QAction *selectAllAction = menu.addAction(tr("Select All") +
QString(QLatin1String("\t") + QString(QKeySequence(Qt::CTRL | Qt::Key_A))));
QAction *usedAction = menu.exec(mapToGlobal(contextMenuEvent->pos()));
if (usedAction == copyAction) {
QTextCursor cursor = browser->textCursor();
if (!cursor.isNull() && cursor.hasSelection()) {
QString selectedText = cursor.selectedText();
QMimeData *data = new QMimeData();
data->setText(selectedText);
QApplication::clipboard()->setMimeData(data);
}
}
else if (usedAction == copyAnchorAction) {
QApplication::clipboard()->setText(link.toString());
}
else if (usedAction == newTabAction) {
emit requestShowLinkInNewTab(link);
}
else if (usedAction == selectAllAction) {
browser->selectAll();
}
#else
point = resultWidget->mapFromGlobal(point);
QUrl link = resultWidget->linkAt(point);
if (link.isEmpty() || !link.isValid())
return;
QAction *curTab = menu.addAction(tr("Open Link"));
QAction *newTab = menu.addAction(tr("Open Link in New Tab"));
QAction *action = menu.exec(mapToGlobal(contextMenuEvent->pos()));
if (curTab == action)
emit requestShowLink(link);
else if (newTab == action)
emit requestShowLinkInNewTab(link);
#endif
}

View File

@@ -0,0 +1,88 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception version
** 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef SEARCHWIDGET_H
#define SEARCHWIDGET_H
#include <QtCore/QUrl>
#include <QtCore/QPoint>
#include <QtGui/QWidget>
QT_BEGIN_NAMESPACE
class QMouseEvent;
class QHelpSearchEngine;
class QHelpSearchResultWidget;
QT_END_NAMESPACE
namespace Help {
namespace Internal {
class SearchWidget : public QWidget
{
Q_OBJECT
public:
SearchWidget(QHelpSearchEngine *engine, QWidget *parent = 0);
~SearchWidget();
void zoomIn();
void zoomOut();
void resetZoom();
signals:
void requestShowLink(const QUrl &url);
void requestShowLinkInNewTab(const QUrl &url);
void escapePressed();
private slots:
void search() const;
void searchingStarted();
void searchingFinished(int hits);
private:
void keyPressEvent(QKeyEvent *keyEvent);
void contextMenuEvent(QContextMenuEvent *contextMenuEvent);
private:
int zoomCount;
QHelpSearchEngine *searchEngine;
QHelpSearchResultWidget *resultWidget;
};
} // namespace Internal
} // namespace Help
#endif // SEARCHWIDGET_H