diff options
47 files changed, 1364 insertions, 829 deletions
diff --git a/doc/src/development/assistant-manual.qdoc b/doc/src/development/assistant-manual.qdoc index 8de500e..3ecadc7 100644 --- a/doc/src/development/assistant-manual.qdoc +++ b/doc/src/development/assistant-manual.qdoc @@ -672,9 +672,6 @@ to make Assistant listen to your application, turn on its remote control functionality by passing the \c{-enableRemoteControl} command line option. - \warning The trailing '\0' must be appended separately to the QByteArray, - e.g., \c{QByteArray("command" + '\0')}. - The following example shows how this can be done: \snippet doc/src/snippets/code/doc_src_assistant-manual.qdoc 2 @@ -685,6 +682,9 @@ \snippet doc/src/snippets/code/doc_src_assistant-manual.qdoc 3 + Note that the trailing newline character is required to mark the end + of the input. + The following commands can be used to control \QA: \table diff --git a/doc/src/snippets/code/doc_src_assistant-manual.qdoc b/doc/src/snippets/code/doc_src_assistant-manual.qdoc index 24870b4..700d755 100644 --- a/doc/src/snippets/code/doc_src_assistant-manual.qdoc +++ b/doc/src/snippets/code/doc_src_assistant-manual.qdoc @@ -58,7 +58,7 @@ assistant -collectionFile file <cacheDirectory>mycompany/myapplication</cacheDirectory> <aboutMenuText> <text>About My Application</text> - <text language="de">Über meine Applikation...</text> + <text language="de">Ãœber meine Applikation...</text> </aboutMenuText> <aboutDialog> <file>about.txt</file> @@ -95,8 +95,7 @@ if (!process->waitForStarted()) //! [3] QByteArray ba; -ba.append("setSource qthelp://com.mycompany.1_0_0/doc/index.html"); -ba.append('\0'); +ba.append("setSource qthelp://com.mycompany.1_0_0/doc/index.html\n"); process->write(ba); //! [3] @@ -105,8 +104,7 @@ process->write(ba); QByteArray ba; ba.append("hide bookmarks;"); ba.append("hide index;"); -ba.append("setSource qthelp://com.mycompany.1_0_0/doc/index.html"); -ba.append('\0'); +ba.append("setSource qthelp://com.mycompany.1_0_0/doc/index.html\n"); process->write(ba); //! [4] diff --git a/examples/help/remotecontrol/remotecontrol.cpp b/examples/help/remotecontrol/remotecontrol.cpp index adb92d0..9dc166e 100644 --- a/examples/help/remotecontrol/remotecontrol.cpp +++ b/examples/help/remotecontrol/remotecontrol.cpp @@ -123,7 +123,7 @@ void RemoteControl::sendCommand(const QString &cmd) { if (process->state() != QProcess::Running) return; - process->write(cmd.toLocal8Bit() + '\0'); + process->write(cmd.toLocal8Bit() + '\n'); } void RemoteControl::on_indexButton_clicked() diff --git a/examples/help/simpletextviewer/assistant.cpp b/examples/help/simpletextviewer/assistant.cpp index ab20f3e..2807365 100644 --- a/examples/help/simpletextviewer/assistant.cpp +++ b/examples/help/simpletextviewer/assistant.cpp @@ -73,7 +73,7 @@ void Assistant::showDocumentation(const QString &page) QByteArray ba("SetSource "); ba.append("qthelp://com.trolltech.examples.simpletextviewer/doc/"); - proc->write(ba + page.toLocal8Bit() + '\0'); + proc->write(ba + page.toLocal8Bit() + '\n'); } //! [1] diff --git a/examples/webkit/fancybrowser/main.cpp b/examples/webkit/fancybrowser/main.cpp index 7f3c983..2245788 100644 --- a/examples/webkit/fancybrowser/main.cpp +++ b/examples/webkit/fancybrowser/main.cpp @@ -45,7 +45,12 @@ int main(int argc, char * argv[]) { QApplication app(argc, argv); - MainWindow *browser = new MainWindow; + QUrl url; + if (argc > 1) + url = QUrl(argv[1]); + else + url = QUrl("http://www.google.com/ncr"); + MainWindow *browser = new MainWindow(url); browser->show(); return app.exec(); } diff --git a/examples/webkit/fancybrowser/mainwindow.cpp b/examples/webkit/fancybrowser/mainwindow.cpp index 11fac91..234afba 100644 --- a/examples/webkit/fancybrowser/mainwindow.cpp +++ b/examples/webkit/fancybrowser/mainwindow.cpp @@ -45,7 +45,7 @@ //! [1] -MainWindow::MainWindow() +MainWindow::MainWindow(const QUrl& url) { progress = 0; @@ -60,7 +60,7 @@ MainWindow::MainWindow() //! [2] view = new QWebView(this); - view->load(QUrl("http://www.google.com/ncr")); + view->load(url); connect(view, SIGNAL(loadFinished(bool)), SLOT(adjustLocation())); connect(view, SIGNAL(titleChanged(const QString&)), SLOT(adjustTitle())); connect(view, SIGNAL(loadProgress(int)), SLOT(setProgress(int))); @@ -78,6 +78,11 @@ MainWindow::MainWindow() toolBar->addWidget(locationEdit); //! [2] + QMenu *viewMenu = menuBar()->addMenu(tr("&View")); + QAction* viewSourceAction = new QAction("Page Source", this); + connect(viewSourceAction, SIGNAL(triggered()), SLOT(viewSource())); + viewMenu->addAction(viewSourceAction); + //! [3] QMenu *effectMenu = menuBar()->addMenu(tr("&Effect")); effectMenu->addAction("Highlight all links", this, SLOT(highlightAllLinks())); @@ -100,6 +105,23 @@ MainWindow::MainWindow() } //! [3] +void MainWindow::viewSource() +{ + QNetworkAccessManager* accessManager = view->page()->networkAccessManager(); + QNetworkRequest request(view->url()); + QNetworkReply* reply = accessManager->get(request); + connect(reply, SIGNAL(finished()), this, SLOT(slotSourceDownloaded())); +} + +void MainWindow::slotSourceDownloaded() +{ + QNetworkReply* reply = qobject_cast<QNetworkReply*>(const_cast<QObject*>(sender())); + QTextEdit* textEdit = new QTextEdit(NULL); + textEdit->setAttribute(Qt::WA_DeleteOnClose); + textEdit->show(); + textEdit->setPlainText(reply->readAll()); +} + //! [4] void MainWindow::adjustLocation() { @@ -136,6 +158,8 @@ void MainWindow::finishLoading(bool) progress = 100; adjustTitle(); view->page()->mainFrame()->evaluateJavaScript(jQuery); + // Enable this to see the dump of the internal render tree + //qDebug() << view->page()->mainFrame()->renderTreeDump(); } //! [6] diff --git a/examples/webkit/fancybrowser/mainwindow.h b/examples/webkit/fancybrowser/mainwindow.h index 33fd8f5..be95614 100644 --- a/examples/webkit/fancybrowser/mainwindow.h +++ b/examples/webkit/fancybrowser/mainwindow.h @@ -52,7 +52,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(); + MainWindow(const QUrl& url); protected slots: @@ -62,6 +62,9 @@ protected slots: void setProgress(int p); void finishLoading(bool); + void viewSource(); + void slotSourceDownloaded(); + void highlightAllLinks(); void rotateImages(bool toggle); void removeGifImages(); diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp index 19e86a6..308e847 100644 --- a/src/corelib/io/qdatastream.cpp +++ b/src/corelib/io/qdatastream.cpp @@ -48,6 +48,7 @@ #include <stdio.h> #include <ctype.h> #include <stdlib.h> +#include "qendian.h" QT_BEGIN_NAMESPACE @@ -670,24 +671,12 @@ QDataStream &QDataStream::operator>>(qint16 &i) { i = 0; CHECK_STREAM_PRECOND(*this) - if (noswap) { - if (dev->read((char *)&i, 2) != 2) { - i = 0; - setStatus(ReadPastEnd); - } + if (dev->read((char *)&i, 2) != 2) { + i = 0; + setStatus(ReadPastEnd); } else { - union { - qint16 val1; - char val2[2]; - } x; - char *p = x.val2; - char b[2]; - if (dev->read(b, 2) == 2) { - *p++ = b[1]; - *p = b[0]; - i = x.val1; - } else { - setStatus(ReadPastEnd); + if (!noswap) { + i = qbswap(i); } } return *this; @@ -713,26 +702,12 @@ QDataStream &QDataStream::operator>>(qint32 &i) { i = 0; CHECK_STREAM_PRECOND(*this) - if (noswap) { - if (dev->read((char *)&i, 4) != 4) { - i = 0; - setStatus(ReadPastEnd); - } - } else { // swap bytes - union { - qint32 val1; - char val2[4]; - } x; - char *p = x.val2; - char b[4]; - if (dev->read(b, 4) == 4) { - *p++ = b[3]; - *p++ = b[2]; - *p++ = b[1]; - *p = b[0]; - i = x.val1; - } else { - setStatus(ReadPastEnd); + if (dev->read((char *)&i, 4) != 4) { + i = 0; + setStatus(ReadPastEnd); + } else { + if (!noswap) { + i = qbswap(i); } } return *this; @@ -761,31 +736,14 @@ QDataStream &QDataStream::operator>>(qint64 &i) quint32 i1, i2; *this >> i2 >> i1; i = ((quint64)i1 << 32) + i2; - } else if (noswap) { // no conversion needed + } else { if (dev->read((char *)&i, 8) != 8) { i = qint64(0); setStatus(ReadPastEnd); - } - } else { // swap bytes - union { - qint64 val1; - char val2[8]; - } x; - - char *p = x.val2; - char b[8]; - if (dev->read(b, 8) == 8) { - *p++ = b[7]; - *p++ = b[6]; - *p++ = b[5]; - *p++ = b[4]; - *p++ = b[3]; - *p++ = b[2]; - *p++ = b[1]; - *p = b[0]; - i = x.val1; } else { - setStatus(ReadPastEnd); + if (!noswap) { + i = qbswap(i); + } } } return *this; @@ -825,27 +783,17 @@ QDataStream &QDataStream::operator>>(float &f) f = 0.0f; CHECK_STREAM_PRECOND(*this) - if (noswap) { - if (dev->read((char *)&f, 4) != 4) { - f = 0.0f; - setStatus(ReadPastEnd); - } - } else { // swap bytes - union { - float val1; - char val2[4]; - } x; - - char *p = x.val2; - char b[4]; - if (dev->read(b, 4) == 4) { - *p++ = b[3]; - *p++ = b[2]; - *p++ = b[1]; - *p = b[0]; + if (dev->read((char *)&f, 4) != 4) { + f = 0.0f; + setStatus(ReadPastEnd); + } else { + if (!noswap) { + union { + float val1; + quint32 val2; + } x; + x.val2 = qbswap(*reinterpret_cast<quint32 *>(&f)); f = x.val1; - } else { - setStatus(ReadPastEnd); } } return *this; @@ -878,30 +826,17 @@ QDataStream &QDataStream::operator>>(double &f) f = 0.0; CHECK_STREAM_PRECOND(*this) #ifndef Q_DOUBLE_FORMAT - if (noswap) { - if (dev->read((char *)&f, 8) != 8) { - f = 0.0; - setStatus(ReadPastEnd); - } - } else { // swap bytes - union { - double val1; - char val2[8]; - } x; - char *p = x.val2; - char b[8]; - if (dev->read(b, 8) == 8) { - *p++ = b[7]; - *p++ = b[6]; - *p++ = b[5]; - *p++ = b[4]; - *p++ = b[3]; - *p++ = b[2]; - *p++ = b[1]; - *p = b[0]; + if (dev->read((char *)&f, 8) != 8) { + f = 0.0; + setStatus(ReadPastEnd); + } else { + if (!noswap) { + union { + double val1; + quint64 val2; + } x; + x.val2 = qbswap(*reinterpret_cast<quint64 *>(&f)); f = x.val1; - } else { - setStatus(ReadPastEnd); } } #else @@ -1073,20 +1008,10 @@ QDataStream &QDataStream::operator<<(qint8 i) QDataStream &QDataStream::operator<<(qint16 i) { CHECK_STREAM_PRECOND(*this) - if (noswap) { - dev->write((char *)&i, sizeof(qint16)); - } else { // swap bytes - union { - qint16 val1; - char val2[2]; - } x; - x.val1 = i; - char *p = x.val2; - char b[2]; - b[1] = *p++; - b[0] = *p; - dev->write(b, 2); + if (!noswap) { + i = qbswap(i); } + dev->write((char *)&i, sizeof(qint16)); return *this; } @@ -1100,22 +1025,10 @@ QDataStream &QDataStream::operator<<(qint16 i) QDataStream &QDataStream::operator<<(qint32 i) { CHECK_STREAM_PRECOND(*this) - if (noswap) { - dev->write((char *)&i, sizeof(qint32)); - } else { // swap bytes - union { - qint32 val1; - char val2[4]; - } x; - x.val1 = i; - char *p = x.val2; - char b[4]; - b[3] = *p++; - b[2] = *p++; - b[1] = *p++; - b[0] = *p; - dev->write(b, 4); + if (!noswap) { + i = qbswap(i); } + dev->write((char *)&i, sizeof(qint32)); return *this; } @@ -1141,25 +1054,11 @@ QDataStream &QDataStream::operator<<(qint64 i) quint32 i1 = i & 0xffffffff; quint32 i2 = i >> 32; *this << i2 << i1; - } else if (noswap) { // no conversion needed + } else { + if (!noswap) { + i = qbswap(i); + } dev->write((char *)&i, sizeof(qint64)); - } else { // swap bytes - union { - qint64 val1; - char val2[8]; - } x; - x.val1 = i; - char *p = x.val2; - char b[8]; - b[7] = *p++; - b[6] = *p++; - b[5] = *p++; - b[4] = *p++; - b[3] = *p++; - b[2] = *p++; - b[1] = *p++; - b[0] = *p; - dev->write(b, 8); } return *this; } @@ -1203,22 +1102,16 @@ QDataStream &QDataStream::operator<<(float f) CHECK_STREAM_PRECOND(*this) float g = f; // fixes float-on-stack problem - if (noswap) { // no conversion needed - dev->write((char *)&g, sizeof(float)); - } else { // swap bytes + if (!noswap) { union { float val1; - char val2[4]; + quint32 val2; } x; - x.val1 = f; - char *p = x.val2; - char b[4]; - b[3] = *p++; - b[2] = *p++; - b[1] = *p++; - b[0] = *p; - dev->write(b, 4); + x.val1 = g; + x.val2 = qbswap(x.val2); + g = x.val1; } + dev->write((char *)&g, sizeof(float)); return *this; } @@ -1242,26 +1135,16 @@ QDataStream &QDataStream::operator<<(double f) CHECK_STREAM_PRECOND(*this) #ifndef Q_DOUBLE_FORMAT - if (noswap) { - dev->write((char *)&f, sizeof(double)); - } else { + if (!noswap) { union { double val1; - char val2[8]; + quint64 val2; } x; x.val1 = f; - char *p = x.val2; - char b[8]; - b[7] = *p++; - b[6] = *p++; - b[5] = *p++; - b[4] = *p++; - b[3] = *p++; - b[2] = *p++; - b[1] = *p++; - b[0] = *p; - dev->write(b, 8); + x.val2 = qbswap(x.val2); + f = x.val1; } + dev->write((char *)&f, sizeof(double)); #else union { double val1; diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index f087407..425a1df 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -189,8 +189,8 @@ public: QList<QObject *> pendingChildInsertedEvents; #else // preserve binary compatibility with code compiled without Qt 3 support - // ### why? - QList<QObject *> unused; + // keeping the binary layout stable helps the Qt Creator debugger + void *unused; #endif QList<QPointer<QObject> > eventFilters; diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index f7321ef..4434fe7 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -55,6 +55,7 @@ #include "qtools_p.h" #include "qhash.h" #include "qdebug.h" +#include "qendian.h" #ifdef Q_OS_MAC #include <private/qcore_mac_p.h> @@ -7306,7 +7307,7 @@ QDataStream &operator>>(QDataStream &in, QString &str) != (QSysInfo::ByteOrder == QSysInfo::BigEndian)) { ushort *data = reinterpret_cast<ushort *>(str.data()); while (len--) { - *data = (*data >> 8) | (*data << 8); + *data = qbswap(*data); ++data; } } diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 985a20b..b085c09 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1076,6 +1076,9 @@ QPixmap QPixmap::grabWidget(QWidget * widget, const QRect &rect) if (widget->testAttribute(Qt::WA_PendingResizeEvent) || !widget->testAttribute(Qt::WA_WState_Created)) sendResizeEvents(widget); + widget->d_func()->prepareToRender(QRegion(), + QWidget::DrawWindowBackground | QWidget::DrawChildren | QWidget::IgnoreMask); + QRect r(rect); if (r.width() < 0) r.setWidth(widget->width() - rect.x()); @@ -1086,8 +1089,8 @@ QPixmap QPixmap::grabWidget(QWidget * widget, const QRect &rect) return QPixmap(); QPixmap res(r.size()); - widget->render(&res, QPoint(), r, - QWidget::DrawWindowBackground | QWidget::DrawChildren | QWidget::IgnoreMask); + widget->d_func()->render(&res, QPoint(), r, QWidget::DrawWindowBackground + | QWidget::DrawChildren | QWidget::IgnoreMask, true); return res; } diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 4aa358f..30cb9a7 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -4838,90 +4838,7 @@ void QWidget::unsetCursor() void QWidget::render(QPaintDevice *target, const QPoint &targetOffset, const QRegion &sourceRegion, RenderFlags renderFlags) { - Q_D(QWidget); - if (!target) { - qWarning("QWidget::render: null pointer to paint device"); - return; - } - - const bool inRenderWithPainter = d->extra && d->extra->inRenderWithPainter; - QRegion paintRegion = !inRenderWithPainter ? d->prepareToRender(sourceRegion, renderFlags) - : sourceRegion; - if (paintRegion.isEmpty()) - return; - -#ifndef Q_WS_MAC - QPainter *oldSharedPainter = inRenderWithPainter ? d->sharedPainter() : 0; - - // Use the target's shared painter if set (typically set when doing - // "other->render(widget);" in the widget's paintEvent. - if (target->devType() == QInternal::Widget) { - QWidgetPrivate *targetPrivate = static_cast<QWidget *>(target)->d_func(); - if (targetPrivate->extra && targetPrivate->extra->inRenderWithPainter) { - QPainter *targetPainter = targetPrivate->sharedPainter(); - if (targetPainter && targetPainter->isActive()) - d->setSharedPainter(targetPainter); - } - } -#endif - - // Use the target's redirected device if set and adjust offset and paint - // region accordingly. This is typically the case when people call render - // from the paintEvent. - QPoint offset = targetOffset; - offset -= paintRegion.boundingRect().topLeft(); - QPoint redirectionOffset; - QPaintDevice *redirected = 0; - - if (target->devType() == QInternal::Widget) - redirected = static_cast<QWidget *>(target)->d_func()->redirected(&redirectionOffset); - if (!redirected) - redirected = QPainter::redirected(target, &redirectionOffset); - - if (redirected) { - target = redirected; - offset -= redirectionOffset; - } - - if (!inRenderWithPainter) { // Clip handled by shared painter (in qpainter.cpp). - if (QPaintEngine *targetEngine = target->paintEngine()) { - const QRegion targetSystemClip = targetEngine->systemClip(); - if (!targetSystemClip.isEmpty()) - paintRegion &= targetSystemClip.translated(-offset); - } - } - - // Set backingstore flags. - int flags = QWidgetPrivate::DrawPaintOnScreen | QWidgetPrivate::DrawInvisible; - if (renderFlags & DrawWindowBackground) - flags |= QWidgetPrivate::DrawAsRoot; - - if (renderFlags & DrawChildren) - flags |= QWidgetPrivate::DrawRecursive; - else - flags |= QWidgetPrivate::DontSubtractOpaqueChildren; - -#ifdef Q_WS_QWS - flags |= QWidgetPrivate::DontSetCompositionMode; -#endif - - if (target->devType() == QInternal::Printer) { - QPainter p(target); - d->render_helper(&p, targetOffset, paintRegion, renderFlags); - return; - } - -#ifndef Q_WS_MAC - // Render via backingstore. - d->drawWidget(target, paintRegion, offset, flags, d->sharedPainter()); - - // Restore shared painter. - if (oldSharedPainter) - d->setSharedPainter(oldSharedPainter); -#else - // Render via backingstore (no shared painter). - d->drawWidget(target, paintRegion, offset, flags, 0); -#endif + d_func()->render(target, targetOffset, sourceRegion, renderFlags, false); } /*! @@ -5371,6 +5288,97 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP } } +void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset, + const QRegion &sourceRegion, QWidget::RenderFlags renderFlags, + bool readyToRender) +{ + Q_Q(QWidget); + if (!target) { + qWarning("QWidget::render: null pointer to paint device"); + return; + } + + const bool inRenderWithPainter = extra && extra->inRenderWithPainter; + QRegion paintRegion = !inRenderWithPainter && !readyToRender + ? prepareToRender(sourceRegion, renderFlags) + : sourceRegion; + if (paintRegion.isEmpty()) + return; + +#ifndef Q_WS_MAC + QPainter *oldSharedPainter = inRenderWithPainter ? sharedPainter() : 0; + + // Use the target's shared painter if set (typically set when doing + // "other->render(widget);" in the widget's paintEvent. + if (target->devType() == QInternal::Widget) { + QWidgetPrivate *targetPrivate = static_cast<QWidget *>(target)->d_func(); + if (targetPrivate->extra && targetPrivate->extra->inRenderWithPainter) { + QPainter *targetPainter = targetPrivate->sharedPainter(); + if (targetPainter && targetPainter->isActive()) + setSharedPainter(targetPainter); + } + } +#endif + + // Use the target's redirected device if set and adjust offset and paint + // region accordingly. This is typically the case when people call render + // from the paintEvent. + QPoint offset = targetOffset; + offset -= paintRegion.boundingRect().topLeft(); + QPoint redirectionOffset; + QPaintDevice *redirected = 0; + + if (target->devType() == QInternal::Widget) + redirected = static_cast<QWidget *>(target)->d_func()->redirected(&redirectionOffset); + if (!redirected) + redirected = QPainter::redirected(target, &redirectionOffset); + + if (redirected) { + target = redirected; + offset -= redirectionOffset; + } + + if (!inRenderWithPainter) { // Clip handled by shared painter (in qpainter.cpp). + if (QPaintEngine *targetEngine = target->paintEngine()) { + const QRegion targetSystemClip = targetEngine->systemClip(); + if (!targetSystemClip.isEmpty()) + paintRegion &= targetSystemClip.translated(-offset); + } + } + + // Set backingstore flags. + int flags = DrawPaintOnScreen | DrawInvisible; + if (renderFlags & QWidget::DrawWindowBackground) + flags |= DrawAsRoot; + + if (renderFlags & QWidget::DrawChildren) + flags |= DrawRecursive; + else + flags |= DontSubtractOpaqueChildren; + +#ifdef Q_WS_QWS + flags |= DontSetCompositionMode; +#endif + + if (target->devType() == QInternal::Printer) { + QPainter p(target); + render_helper(&p, targetOffset, paintRegion, renderFlags); + return; + } + +#ifndef Q_WS_MAC + // Render via backingstore. + drawWidget(target, paintRegion, offset, flags, sharedPainter()); + + // Restore shared painter. + if (oldSharedPainter) + setSharedPainter(oldSharedPainter); +#else + // Render via backingstore (no shared painter). + drawWidget(target, paintRegion, offset, flags, 0); +#endif +} + void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectList& siblings, int index, const QRegion &rgn, const QPoint &offset, int flags #ifdef Q_BACKINGSTORE_SUBSURFACES diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index eea929b..8e87c37 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -353,6 +353,8 @@ public: QRegion prepareToRender(const QRegion ®ion, QWidget::RenderFlags renderFlags); void render_helper(QPainter *painter, const QPoint &targetOffset, const QRegion &sourceRegion, QWidget::RenderFlags renderFlags); + void render(QPaintDevice *target, const QPoint &targetOffset, const QRegion &sourceRegion, + QWidget::RenderFlags renderFlags, bool readyToRender); void drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, int flags, QPainter *sharedPainter = 0, QWidgetBackingStore *backingStore = 0); diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index 4c9541b..fab3998 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -5664,10 +5664,16 @@ QIcon QCommonStyle::standardIconImplementation(StandardPixmap standardIcon, cons OSType iconType = 0; switch (standardIcon) { case QStyle::SP_MessageBoxQuestion: + iconType = kQuestionMarkIcon; + break; case QStyle::SP_MessageBoxInformation: + iconType = kAlertNoteIcon; + break; case QStyle::SP_MessageBoxWarning: + iconType = kAlertCautionIcon; + break; case QStyle::SP_MessageBoxCritical: - iconType = kGenericApplicationIcon; + iconType = kAlertStopIcon; break; case SP_DesktopIcon: iconType = kDesktopIcon; diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp index 9ab4057..0792cea 100644 --- a/src/network/access/qnetworkreply.cpp +++ b/src/network/access/qnetworkreply.cpp @@ -530,6 +530,12 @@ QByteArray QNetworkReply::rawHeader(const QByteArray &headerName) const return QByteArray(); } +const QList<QNetworkReply::RawHeaderPair>& QNetworkReply::rawHeaderPairs() const +{ + Q_D(const QNetworkReply); + return d->rawHeaders; +} + /*! Returns a list of headers fields that were sent by the remote server, in the order that they were sent. Duplicate headers are diff --git a/src/network/access/qnetworkreply.h b/src/network/access/qnetworkreply.h index c624810..82086c4 100644 --- a/src/network/access/qnetworkreply.h +++ b/src/network/access/qnetworkreply.h @@ -128,6 +128,9 @@ public: QList<QByteArray> rawHeaderList() const; QByteArray rawHeader(const QByteArray &headerName) const; + typedef QPair<QByteArray, QByteArray> RawHeaderPair; + const QList<RawHeaderPair>& rawHeaderPairs() const; + // attributes QVariant attribute(QNetworkRequest::Attribute code) const; diff --git a/tests/auto/networkdata/README b/tests/auto/networkdata/README new file mode 100644 index 0000000..e8748cc --- /dev/null +++ b/tests/auto/networkdata/README @@ -0,0 +1 @@ +This directory contains network test data diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index d7f042e..fcb59f9 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -47,6 +47,7 @@ #include <qmatrix.h> #include <qdesktopwidget.h> #include <qpaintengine.h> +#include <qtreewidget.h> #include <private/qpixmapdata_p.h> @@ -791,14 +792,32 @@ void tst_QPixmap::drawBitmap() void tst_QPixmap::grabWidget() { QWidget widget; - widget.setPalette(Qt::green); - widget.resize(128, 128); + QImage image(128, 128, QImage::Format_ARGB32_Premultiplied); + for (int row = 0; row < image.height(); ++row) { + QRgb *line = reinterpret_cast<QRgb *>(image.scanLine(row)); + for (int col = 0; col < image.width(); ++col) + line[col] = qRgb(rand() & 255, row, col); + } - QPixmap expected(64, 64); - expected.fill(Qt::green); + QPalette pal = widget.palette(); + pal.setBrush(QPalette::Window, QBrush(image)); + widget.setPalette(pal); + widget.resize(128, 128); + QPixmap expected = QPixmap::fromImage(QImage(image.scanLine(64) + 64 * 4, 64, 64, image.bytesPerLine(), image.format())); QPixmap actual = QPixmap::grabWidget(&widget, QRect(64, 64, 64, 64)); QVERIFY(lenientCompare(actual, expected)); + + actual = QPixmap::grabWidget(&widget, 64, 64); + QVERIFY(lenientCompare(actual, expected)); + + // Make sure a widget that is not yet shown is grabbed correctly. + QTreeWidget widget2; + actual = QPixmap::grabWidget(&widget2); + widget2.show(); + expected = QPixmap::grabWidget(&widget2); + + QVERIFY(lenientCompare(actual, expected)); } void tst_QPixmap::grabWindow() diff --git a/tools/assistant/lib/lib.pro b/tools/assistant/lib/lib.pro index 51933de..26d3456 100644 --- a/tools/assistant/lib/lib.pro +++ b/tools/assistant/lib/lib.pro @@ -23,7 +23,6 @@ unix:QMAKE_PKGCONFIG_REQUIRES += QtNetwork \ QtSql \ QtXml LIBS_PRIVATE += -l$$qclucene - RESOURCES += helpsystem.qrc SOURCES += qhelpenginecore.cpp \ qhelpengine.cpp \ @@ -41,6 +40,7 @@ SOURCES += qhelpenginecore.cpp \ qhelpsearchindexwriter_default.cpp \ qhelpsearchindexreader_default.cpp \ qhelpsearchindexreader.cpp \ + qclucenefieldnames.cpp \ qhelp_global.cpp # access to clucene @@ -63,7 +63,8 @@ HEADERS += qhelpenginecore.h \ qhelpsearchindex_default_p.h \ qhelpsearchindexwriter_default_p.h \ qhelpsearchindexreader_default_p.h \ - qhelpsearchindexreader_p.h + qhelpsearchindexreader_p.h \ + qclucenefieldnames_p.h # access to clucene HEADERS += qhelpsearchindexwriter_clucene_p.h \ diff --git a/tools/assistant/lib/qclucenefieldnames.cpp b/tools/assistant/lib/qclucenefieldnames.cpp new file mode 100644 index 0000000..84e3a1a --- /dev/null +++ b/tools/assistant/lib/qclucenefieldnames.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Assistant of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qclucenefieldnames_p.h" + +QT_BEGIN_NAMESPACE + +namespace qt { +namespace fulltextsearch { +namespace clucene { +const QString AttributeField(QLatin1String("attribute")); +const QString ContentField(QLatin1String("content")); +const QString NamespaceField(QLatin1String("namespace")); +const QString PathField(QLatin1String("path")); +const QString TitleField(QLatin1String("title")); +const QString TitleTokenizedField(QLatin1String("titleTokenized")); +} // namespace clucene +} // namespace fulltextsearch +} // namespace qt + +QT_END_NAMESPACE diff --git a/tools/assistant/lib/qclucenefieldnames_p.h b/tools/assistant/lib/qclucenefieldnames_p.h new file mode 100644 index 0000000..489832f --- /dev/null +++ b/tools/assistant/lib/qclucenefieldnames_p.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Assistant of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCLUCENEFIELDNAMES_P_H +#define QCLUCENEFIELDNAMES_P_H + +#include <QtCore/QtGlobal> +#include <QtCore/QString> + +QT_BEGIN_NAMESPACE + +namespace qt { +namespace fulltextsearch { +namespace clucene { + extern const QString AttributeField; + extern const QString ContentField; + extern const QString NamespaceField; + extern const QString PathField; + extern const QString TitleField; + extern const QString TitleTokenizedField; +} // namespace clucene +} // namespace fulltextsearch +} // namespace qt + +QT_END_NAMESPACE + +#endif // QCLUCENEFIELDNAMES_P_H diff --git a/tools/assistant/lib/qhelp_global.cpp b/tools/assistant/lib/qhelp_global.cpp index 980de27..aa9f0dd 100644 --- a/tools/assistant/lib/qhelp_global.cpp +++ b/tools/assistant/lib/qhelp_global.cpp @@ -86,17 +86,17 @@ QString QHelpGlobal::codecFromData(const QByteArray &data) QString QHelpGlobal::codecFromHtmlData(const QByteArray &data) { - QString content = QString::fromUtf8(data.constData(), data.size()); - int start = content.indexOf(QLatin1String("<meta"), 0, Qt::CaseInsensitive); + QString head = QString::fromUtf8(data.constData(), qMin(1000, data.size())); + int start = head.indexOf(QLatin1String("<meta"), 0, Qt::CaseInsensitive); if (start > 0) { int end; QRegExp r(QLatin1String("charset=([^\"\\s]+)")); while (start != -1) { - end = content.indexOf(QLatin1Char('>'), start) + 1; - const QString &meta = content.mid(start, end - start).toLower(); + end = head.indexOf(QLatin1Char('>'), start) + 1; + const QString &meta = head.mid(start, end - start).toLower(); if (r.indexIn(meta) != -1) return r.cap(1); - start = content.indexOf(QLatin1String("<meta"), end, + start = head.indexOf(QLatin1String("<meta"), end, Qt::CaseInsensitive); } } @@ -105,8 +105,8 @@ QString QHelpGlobal::codecFromHtmlData(const QByteArray &data) QString QHelpGlobal::codecFromXmlData(const QByteArray &data) { - QString content = QString::fromUtf8(data.constData(), data.size()); + QString head = QString::fromUtf8(data.constData(), qMin(1000, data.size())); const QRegExp encodingExp(QLatin1String("^\\s*<\\?xml version=" "\"\\d\\.\\d\" encoding=\"([^\"]+)\"\\?>.*")); - return encodingExp.exactMatch(content) ? encodingExp.cap(1) : QString(); + return encodingExp.exactMatch(head) ? encodingExp.cap(1) : QString(); } diff --git a/tools/assistant/lib/qhelpcollectionhandler.cpp b/tools/assistant/lib/qhelpcollectionhandler.cpp index 4aa7ab6..9092259 100644 --- a/tools/assistant/lib/qhelpcollectionhandler.cpp +++ b/tools/assistant/lib/qhelpcollectionhandler.cpp @@ -308,10 +308,8 @@ bool QHelpCollectionHandler::addCustomFilter(const QString &filterName, m_query.prepare(QLatin1String("SELECT Id FROM FilterNameTable WHERE Name=?")); m_query.bindValue(0, filterName); m_query.exec(); - while (m_query.next()) { + if (m_query.next()) nameId = m_query.value(0).toInt(); - break; - } m_query.exec(QLatin1String("SELECT Id, Name FROM FilterAttributeTable")); QStringList idsToInsert = attributes; diff --git a/tools/assistant/lib/qhelpenginecore.cpp b/tools/assistant/lib/qhelpenginecore.cpp index 140e99a..c83d12c 100644 --- a/tools/assistant/lib/qhelpenginecore.cpp +++ b/tools/assistant/lib/qhelpenginecore.cpp @@ -404,8 +404,9 @@ QStringList QHelpEngineCore::customFilters() const /*! Adds the new custom filter \a filterName. The filter attributes - are specified by \a attributes. The function returns false if - the filter can not be added, e.g. when the filter already exists. + are specified by \a attributes. If the filter already exists, + its attribute set is replaced. The function returns true if + the operation succeeded, otherwise it returns false. \sa customFilters(), removeCustomFilter() */ diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp index 954f41f..e180375 100644 --- a/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp +++ b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp @@ -39,16 +39,19 @@ ** ****************************************************************************/ -#include "qhelpenginecore.h" -#include "fulltextsearch/qsearchable_p.h" -#include "fulltextsearch/qqueryparser_p.h" #include "fulltextsearch/qindexreader_p.h" +#include "fulltextsearch/qqueryparser_p.h" +#include "fulltextsearch/qsearchable_p.h" +#include "qclucenefieldnames_p.h" +#include "qhelpenginecore.h" + #include "qhelpsearchindexreader_clucene_p.h" #include <QtCore/QDir> #include <QtCore/QSet> #include <QtCore/QString> #include <QtCore/QFileInfo> +#include <QtCore/QSharedPointer> #include <QtCore/QStringList> #include <QtCore/QTextStream> #include <QtCore/QMutexLocker> @@ -108,64 +111,88 @@ void QHelpSearchIndexReaderClucene::run() #if !defined(QT_NO_EXCEPTIONS) try { #endif - QCLuceneBooleanQuery booleanQuery; + QCLuceneBooleanQuery booleanQueryTitle; + QCLuceneBooleanQuery booleanQueryContent; QCLuceneStandardAnalyzer analyzer; - if (!buildQuery(booleanQuery, queryList, analyzer)) { + const QStringList& attribList = + engine.filterAttributes(engine.currentFilter()); + bool titleQueryIsValid = buildQuery(queryList, TitleTokenizedField, + attribList, booleanQueryTitle, analyzer); + bool contentQueryIsValid = buildQuery(queryList, ContentField, + attribList, booleanQueryContent, analyzer); + if (!titleQueryIsValid && !contentQueryIsValid) { emit searchingFinished(0); return; } - const QStringList attribList = engine.filterAttributes(engine.currentFilter()); - if (!attribList.isEmpty()) { - QCLuceneQuery* query = QCLuceneQueryParser::parse(QLatin1String("+") - + attribList.join(QLatin1String(" +")), QLatin1String("attribute"), analyzer); + QCLuceneIndexSearcher indexSearcher(indexPath); - if (!query) { + // QCLuceneHits object must be allocated on the heap, because + // there is no default constructor. + QSharedPointer<QCLuceneHits> titleHits; + QSharedPointer<QCLuceneHits> contentHits; + if (titleQueryIsValid) { + titleHits = QSharedPointer<QCLuceneHits>(new QCLuceneHits( + indexSearcher.search(booleanQueryTitle))); + } + if (contentQueryIsValid) { + contentHits = QSharedPointer<QCLuceneHits>(new QCLuceneHits( + indexSearcher.search(booleanQueryContent))); + } + bool boost = true; + if ((titleHits.isNull() || titleHits->length() == 0) + && (contentHits.isNull() || contentHits->length() == 0)) { + booleanQueryTitle = QCLuceneBooleanQuery(); + booleanQueryContent = QCLuceneBooleanQuery(); + titleQueryIsValid = + buildTryHarderQuery(queryList, TitleTokenizedField, + attribList, booleanQueryTitle, analyzer); + contentQueryIsValid = + buildTryHarderQuery(queryList, ContentField, attribList, + booleanQueryContent, analyzer); + if (!titleQueryIsValid && !contentQueryIsValid) { emit searchingFinished(0); return; } - booleanQuery.add(query, true, true, false); - } - - QCLuceneIndexSearcher indexSearcher(indexPath); - QCLuceneHits hits = indexSearcher.search(booleanQuery); - - bool boost = true; - QCLuceneBooleanQuery tryHarderQuery; - if (hits.length() == 0) { - if (buildTryHarderQuery(tryHarderQuery, queryList, analyzer)) { - if (!attribList.isEmpty()) { - QCLuceneQuery* query = QCLuceneQueryParser::parse(QLatin1String("+") - + attribList.join(QLatin1String(" +")), QLatin1String("attribute"), - analyzer); - tryHarderQuery.add(query, true, true, false); - } - hits = indexSearcher.search(tryHarderQuery); - boost = (hits.length() == 0); + if (titleQueryIsValid) { + titleHits = QSharedPointer<QCLuceneHits>(new QCLuceneHits( + indexSearcher.search(booleanQueryTitle))); + } + if (contentQueryIsValid) { + contentHits = QSharedPointer<QCLuceneHits>(new QCLuceneHits( + indexSearcher.search(booleanQueryContent))); } + boost = false; } + QList<QSharedPointer<QCLuceneHits> > cluceneHitsList; + if (!titleHits.isNull()) + cluceneHitsList.append(titleHits); + if (!contentHits.isNull()) + cluceneHitsList.append(contentHits); QSet<QString> pathSet; QCLuceneDocument document; const QStringList namespaceList = engine.registeredDocumentations(); - for (qint32 i = 0; i < hits.length(); i++) { - document = hits.document(i); - const QString path = document.get(QLatin1String("path")); - if (!pathSet.contains(path) && namespaceList.contains( - document.get(QLatin1String("namespace")), Qt::CaseInsensitive)) { - pathSet.insert(path); - hitList.append(qMakePair(path, document.get(QLatin1String("title")))); - } - document.clear(); + foreach (QSharedPointer<QCLuceneHits> hits, cluceneHitsList) { + for (qint32 i = 0; i < hits->length(); i++) { + document = hits->document(i); + const QString path = document.get(PathField); + if (!pathSet.contains(path) && namespaceList.contains( + document.get(NamespaceField), Qt::CaseInsensitive)) { + pathSet.insert(path); + hitList.append(qMakePair(path, document.get(TitleField))); + } + document.clear(); - mutex.lock(); - if (m_cancel) { + mutex.lock(); + if (m_cancel) { + mutex.unlock(); + emit searchingFinished(0); + return; + } mutex.unlock(); - emit searchingFinished(0); - return; } - mutex.unlock(); } indexSearcher.close(); @@ -185,144 +212,205 @@ void QHelpSearchIndexReaderClucene::run() } } -bool QHelpSearchIndexReaderClucene::defaultQuery(const QString &term, QCLuceneBooleanQuery &booleanQuery, - QCLuceneStandardAnalyzer &analyzer) +bool QHelpSearchIndexReaderClucene::buildQuery( + const QList<QHelpSearchQuery> &queries, const QString &fieldName, + const QStringList &filterAttributes, QCLuceneBooleanQuery &booleanQuery, + QCLuceneAnalyzer &analyzer) { - const QLatin1String c("content"); - const QLatin1String t("titleTokenized"); - - QCLuceneQuery *query = QCLuceneQueryParser::parse(term, c, analyzer); - QCLuceneQuery *query2 = QCLuceneQueryParser::parse(term, t, analyzer); - if (query && query2) { - booleanQuery.add(query, true, false, false); - booleanQuery.add(query2, true, false, false); - return true; + bool queryIsValid = false; + foreach (const QHelpSearchQuery &query, queries) { + if (fieldName != ContentField && isNegativeQuery(query)) { + queryIsValid = false; + break; + } + switch (query.fieldName) { + case QHelpSearchQuery::FUZZY: + if (addFuzzyQuery(query, fieldName, booleanQuery, analyzer)) + queryIsValid = true; + break; + case QHelpSearchQuery::WITHOUT: + if (fieldName != ContentField) + return false; + if (addWithoutQuery(query, fieldName, booleanQuery)) + queryIsValid = true; + break; + case QHelpSearchQuery::PHRASE: + if (addPhraseQuery(query, fieldName, booleanQuery)) + queryIsValid = true; + break; + case QHelpSearchQuery::ALL: + if (addAllQuery(query, fieldName, booleanQuery)) + queryIsValid = true; + break; + case QHelpSearchQuery::DEFAULT: + if (addDefaultQuery(query, fieldName, true, booleanQuery, analyzer)) + queryIsValid = true; + break; + case QHelpSearchQuery::ATLEAST: + if (addAtLeastQuery(query, fieldName, booleanQuery, analyzer)) + queryIsValid = true; + break; + default: + Q_ASSERT(!"Invalid field name"); + } } - return false; + if (queryIsValid && !filterAttributes.isEmpty()) { + queryIsValid = + addAttributesQuery(filterAttributes, booleanQuery, analyzer); + } + + return queryIsValid; } -bool QHelpSearchIndexReaderClucene::buildQuery(QCLuceneBooleanQuery &booleanQuery, - const QList<QHelpSearchQuery> &queryList, QCLuceneStandardAnalyzer &analyzer) +bool QHelpSearchIndexReaderClucene::buildTryHarderQuery( + const QList<QHelpSearchQuery> &queries, const QString &fieldName, + const QStringList &filterAttributes, QCLuceneBooleanQuery &booleanQuery, + QCLuceneAnalyzer &analyzer) { - foreach (const QHelpSearchQuery query, queryList) { - switch (query.fieldName) { - case QHelpSearchQuery::FUZZY: { - const QLatin1String fuzzy("~"); - foreach (const QString &term, query.wordList) { - if (term.isEmpty() - || !defaultQuery(term.toLower() + fuzzy, booleanQuery, analyzer)) { - return false; - } - } - } break; - - case QHelpSearchQuery::WITHOUT: { - QStringList stopWords = QCLuceneStopAnalyzer().englishStopWords(); - foreach (const QString &term, query.wordList) { - if (stopWords.contains(term, Qt::CaseInsensitive)) - continue; - - QCLuceneQuery *query = new QCLuceneTermQuery(QCLuceneTerm( - QLatin1String("content"), term.toLower())); - QCLuceneQuery *query2 = new QCLuceneTermQuery(QCLuceneTerm( - QLatin1String("titleTokenized"), term.toLower())); - - if (query && query2) { - booleanQuery.add(query, true, false, true); - booleanQuery.add(query2, true, false, true); - } else { - return false; - } - } - } break; - - case QHelpSearchQuery::PHRASE: { - const QString &term = query.wordList.at(0).toLower(); - if (term.contains(QLatin1Char(' '))) { - QStringList termList = term.split(QLatin1String(" ")); - QCLucenePhraseQuery *q = new QCLucenePhraseQuery(); - QStringList stopWords = QCLuceneStopAnalyzer().englishStopWords(); - foreach (const QString &term, termList) { - if (!stopWords.contains(term, Qt::CaseInsensitive)) - q->addTerm(QCLuceneTerm(QLatin1String("content"), term.toLower())); - } - booleanQuery.add(q, true, true, false); - } else { - QCLuceneQuery *query = new QCLuceneTermQuery(QCLuceneTerm( - QLatin1String("content"), term.toLower())); - QCLuceneQuery *query2 = new QCLuceneTermQuery(QCLuceneTerm( - QLatin1String("titleTokenized"), term.toLower())); - - if (query && query2) { - booleanQuery.add(query, true, true, false); - booleanQuery.add(query2, true, false, false); - } else { - return false; - } - } - } break; + if (queries.isEmpty()) + return false; + const QHelpSearchQuery &query = queries.front(); + if (query.fieldName != QHelpSearchQuery::DEFAULT) + return false; + if (isNegativeQuery(query)) + return false; + if (!addDefaultQuery(query, fieldName, false, booleanQuery, analyzer)) + return false; + if (filterAttributes.isEmpty()) + return true; + return addAttributesQuery(filterAttributes, booleanQuery, analyzer); +} - case QHelpSearchQuery::ALL: { - QStringList stopWords = QCLuceneStopAnalyzer().englishStopWords(); - foreach (const QString &term, query.wordList) { - if (stopWords.contains(term, Qt::CaseInsensitive)) - continue; +bool QHelpSearchIndexReaderClucene::isNegativeQuery(const QHelpSearchQuery &query) const +{ + const QString &search = query.wordList.join(" "); + return search.contains('!') || search.contains('-') + || search.contains(QLatin1String(" NOT ")); +} - QCLuceneQuery *query = new QCLuceneTermQuery(QCLuceneTerm( - QLatin1String("content"), term.toLower())); +bool QHelpSearchIndexReaderClucene::addFuzzyQuery(const QHelpSearchQuery &query, + const QString &fieldName, QCLuceneBooleanQuery &booleanQuery, + QCLuceneAnalyzer &analyzer) +{ + bool queryIsValid = false; + const QLatin1String fuzzy("~"); + foreach (const QString &term, query.wordList) { + if (!term.isEmpty()) { + QCLuceneQuery *lQuery = + QCLuceneQueryParser::parse(term + fuzzy, fieldName, analyzer); + if (lQuery != 0) { + booleanQuery.add(lQuery, true, false, false); + queryIsValid = true; + } + } + } + return queryIsValid; +} - if (query) { - booleanQuery.add(query, true, true, false); - } else { - return false; - } - } - } break; +bool QHelpSearchIndexReaderClucene::addWithoutQuery(const QHelpSearchQuery &query, + const QString &fieldName, QCLuceneBooleanQuery &booleanQuery) +{ + bool queryIsValid = false; + const QStringList &stopWords = QCLuceneStopAnalyzer().englishStopWords(); + foreach (const QString &term, query.wordList) { + if (stopWords.contains(term, Qt::CaseInsensitive)) + continue; + QCLuceneQuery *lQuery = new QCLuceneTermQuery(QCLuceneTerm( + fieldName, term.toLower())); + booleanQuery.add(lQuery, true, false, true); + queryIsValid = true; + } + return queryIsValid; +} - case QHelpSearchQuery::DEFAULT: { - foreach (const QString &term, query.wordList) { - QCLuceneQuery *query = QCLuceneQueryParser::parse(term.toLower(), - QLatin1String("content"), analyzer); +bool QHelpSearchIndexReaderClucene::addPhraseQuery(const QHelpSearchQuery &query, + const QString &fieldName, QCLuceneBooleanQuery &booleanQuery) +{ + bool queryIsValid = false; + const QString &term = query.wordList.at(0).toLower(); + if (term.contains(QLatin1Char(' '))) { + const QStringList termList = term.split(QLatin1String(" ")); + QCLucenePhraseQuery *q = new QCLucenePhraseQuery(); + const QStringList stopWords = QCLuceneStopAnalyzer().englishStopWords(); + foreach (const QString &term, termList) { + if (!stopWords.contains(term, Qt::CaseInsensitive)) + q->addTerm(QCLuceneTerm(fieldName, term.toLower())); + } + if (!q->getTerms().isEmpty()) { + booleanQuery.add(q, true, true, false); + queryIsValid = true; + } + } else { + QCLuceneQuery *lQuery = new QCLuceneTermQuery(QCLuceneTerm( + fieldName, term.toLower())); + booleanQuery.add(lQuery, true, true, false); + queryIsValid = true; + } + return queryIsValid; +} - if (query) - booleanQuery.add(query, true, true, false); - } - } break; +bool QHelpSearchIndexReaderClucene::addAllQuery(const QHelpSearchQuery &query, + const QString &fieldName, QCLuceneBooleanQuery &booleanQuery) +{ + bool queryIsValid = false; + const QStringList &stopWords = QCLuceneStopAnalyzer().englishStopWords(); + foreach (const QString &term, query.wordList) { + if (stopWords.contains(term, Qt::CaseInsensitive)) + continue; + QCLuceneQuery *lQuery = new QCLuceneTermQuery(QCLuceneTerm( + fieldName, term.toLower())); + booleanQuery.add(lQuery, true, true, false); + queryIsValid = true; + } + return queryIsValid; +} - case QHelpSearchQuery::ATLEAST: { - foreach (const QString &term, query.wordList) { - if (term.isEmpty() || !defaultQuery(term.toLower(), booleanQuery, analyzer)) - return false; - } - } +bool QHelpSearchIndexReaderClucene::addDefaultQuery(const QHelpSearchQuery &query, + const QString &fieldName, bool allTermsRequired, + QCLuceneBooleanQuery &booleanQuery, + QCLuceneAnalyzer &analyzer) +{ + bool queryIsValid = false; + foreach (const QString &term, query.wordList) { + QCLuceneQuery *lQuery = + QCLuceneQueryParser::parse(term.toLower(), fieldName, analyzer); + if (lQuery) { + booleanQuery.add(lQuery, true, allTermsRequired, false); + queryIsValid = true; } } - - return true; + return queryIsValid; } -bool QHelpSearchIndexReaderClucene::buildTryHarderQuery(QCLuceneBooleanQuery &booleanQuery, - const QList<QHelpSearchQuery> &queryList, QCLuceneStandardAnalyzer &analyzer) +bool QHelpSearchIndexReaderClucene::addAtLeastQuery( + const QHelpSearchQuery &query, const QString &fieldName, + QCLuceneBooleanQuery &booleanQuery, QCLuceneAnalyzer &analyzer) { - bool retVal = false; - foreach (const QHelpSearchQuery query, queryList) { - switch (query.fieldName) { - default: break; - case QHelpSearchQuery::DEFAULT: { - foreach (const QString &term, query.wordList) { - QCLuceneQuery *query = QCLuceneQueryParser::parse(term.toLower(), - QLatin1String("content"), analyzer); - - if (query) { - retVal = true; - booleanQuery.add(query, true, false, false); - } - } - } break; + bool queryIsValid = false; + foreach (const QString &term, query.wordList) { + if (!term.isEmpty()) { + QCLuceneQuery *lQuery = + QCLuceneQueryParser::parse(term, fieldName, analyzer); + if (lQuery) { + booleanQuery.add(lQuery, true, false, false); + queryIsValid = true; + } } } - return retVal; + return queryIsValid; +} + +bool QHelpSearchIndexReaderClucene::addAttributesQuery( + const QStringList &filterAttributes, QCLuceneBooleanQuery &booleanQuery, + QCLuceneAnalyzer &analyzer) +{ + QCLuceneQuery* lQuery = QCLuceneQueryParser::parse(QLatin1String("+") + + filterAttributes.join(QLatin1String(" +")), AttributeField, analyzer); + if (!lQuery) + return false; + booleanQuery.add(lQuery, true, true, false); + return true; } void QHelpSearchIndexReaderClucene::boostSearchHits(const QHelpEngineCore &engine, @@ -336,21 +424,22 @@ void QHelpSearchIndexReaderClucene::boostSearchHits(const QHelpEngineCore &engin QCLuceneStandardAnalyzer analyzer; QCLuceneQuery *parsedQuery = QCLuceneQueryParser::parse( - joinedQuery, QLatin1String("content"), analyzer); + joinedQuery, ContentField, analyzer); if (parsedQuery) { joinedQuery = parsedQuery->toString(); delete parsedQuery; } - int length = QString(QLatin1String("content:")).length(); - int index = joinedQuery.indexOf(QLatin1String("content:")); + const QString contentString(ContentField + QLatin1String(":")); + int length = contentString.length(); + int index = joinedQuery.indexOf(contentString); QString term; int nextIndex = 0; QStringList searchTerms; while (index != -1) { - nextIndex = joinedQuery.indexOf(QLatin1String("content:"), index + 1); + nextIndex = joinedQuery.indexOf(contentString, index + 1); term = joinedQuery.mid(index + length, nextIndex - (length + index)).simplified(); if (term.startsWith(QLatin1String("\"")) && term.endsWith(QLatin1String("\""))) { diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h index d7b539a..608668f 100644 --- a/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h +++ b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h @@ -53,16 +53,19 @@ // We mean it. // -#include "qhelpsearchindexreader_p.h" +#include <QtCore/QList> +#include <QtCore/QString> +#include <QtCore/QStringList> #include "fulltextsearch/qanalyzer_p.h" #include "fulltextsearch/qquery_p.h" +#include "qhelpsearchindexreader_p.h" QT_BEGIN_NAMESPACE namespace qt { - namespace fulltextsearch { - namespace clucene { +namespace fulltextsearch { +namespace clucene { class QHelpSearchIndexReaderClucene : public QHelpSearchIndexReader { @@ -74,18 +77,38 @@ public: private: void run(); - bool defaultQuery(const QString &term, QCLuceneBooleanQuery &booleanQuery, - QCLuceneStandardAnalyzer &analyzer); - bool buildQuery(QCLuceneBooleanQuery &booleanQuery, const QList<QHelpSearchQuery> &queryList, - QCLuceneStandardAnalyzer &analyzer); - bool buildTryHarderQuery(QCLuceneBooleanQuery &booleanQuery, - const QList<QHelpSearchQuery> &queryList, QCLuceneStandardAnalyzer &analyzer); void boostSearchHits(const QHelpEngineCore &engine, QList<QHelpSearchEngine::SearchHit> &hitList, const QList<QHelpSearchQuery> &queryList); + bool buildQuery(const QList<QHelpSearchQuery> &queries, + const QString &fieldName, + const QStringList &filterAttributes, + QCLuceneBooleanQuery &booleanQuery, + QCLuceneAnalyzer &analyzer); + bool buildTryHarderQuery(const QList<QHelpSearchQuery> &queries, + const QString &fieldName, + const QStringList &filterAttributes, + QCLuceneBooleanQuery &booleanQuery, + QCLuceneAnalyzer &analyzer); + bool addFuzzyQuery(const QHelpSearchQuery &query, const QString &fieldName, + QCLuceneBooleanQuery &booleanQuery, QCLuceneAnalyzer &analyzer); + bool addWithoutQuery(const QHelpSearchQuery &query, const QString &fieldName, + QCLuceneBooleanQuery &booleanQuery); + bool addPhraseQuery(const QHelpSearchQuery &query, const QString &fieldName, + QCLuceneBooleanQuery &booleanQuery); + bool addAllQuery(const QHelpSearchQuery &query, const QString &fieldName, + QCLuceneBooleanQuery &booleanQuery); + bool addDefaultQuery(const QHelpSearchQuery &query, const QString &fieldName, + bool allTermsRequired, QCLuceneBooleanQuery &booleanQuery, + QCLuceneAnalyzer &analyzer); + bool addAtLeastQuery(const QHelpSearchQuery &query, const QString &fieldName, + QCLuceneBooleanQuery &booleanQuery, QCLuceneAnalyzer &analyzer); + bool addAttributesQuery(const QStringList &filterAttributes, + QCLuceneBooleanQuery &booleanQuery, QCLuceneAnalyzer &analyzer); + bool isNegativeQuery(const QHelpSearchQuery &query) const; }; - } // namespace clucene - } // namespace fulltextsearch +} // namespace clucene +} // namespace fulltextsearch } // namespace qt QT_END_NAMESPACE diff --git a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp index ab32537..f23efa5 100644 --- a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp +++ b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "qclucenefieldnames_p.h" #include "qhelpenginecore.h" #include "qhelp_global.h" #include "fulltextsearch/qhits_p.h" @@ -407,17 +408,17 @@ public: QString parsedTitle = QHelpGlobal::documentTitle(data); if(!parsedData.isEmpty()) { - document->add(new QCLuceneField(QLatin1String("content"), + document->add(new QCLuceneField(ContentField, parsedData,QCLuceneField::INDEX_TOKENIZED)); - document->add(new QCLuceneField(QLatin1String("path"), fileName, + document->add(new QCLuceneField(PathField, fileName, QCLuceneField::STORE_YES | QCLuceneField::INDEX_UNTOKENIZED)); - document->add(new QCLuceneField(QLatin1String("title"), parsedTitle, + document->add(new QCLuceneField(TitleField, parsedTitle, QCLuceneField::STORE_YES | QCLuceneField::INDEX_UNTOKENIZED)); - document->add(new QCLuceneField(QLatin1String("titleTokenized"), parsedTitle, + document->add(new QCLuceneField(TitleTokenizedField, parsedTitle, QCLuceneField::STORE_YES | QCLuceneField::INDEX_TOKENIZED)); - document->add(new QCLuceneField(QLatin1String("namespace"), namespaceName, + document->add(new QCLuceneField(NamespaceField, namespaceName, QCLuceneField::STORE_YES | QCLuceneField::INDEX_UNTOKENIZED)); - document->add(new QCLuceneField(QLatin1String("attribute"), attributes, + document->add(new QCLuceneField(AttributeField, attributes, QCLuceneField::STORE_YES | QCLuceneField::INDEX_TOKENIZED)); return true; } @@ -712,9 +713,7 @@ void QHelpSearchIndexWriter::run() if (indexMap.contains(namespaceName)) { // make sure we really have content indexed for namespace - // NOTE: Extra variable just for GCC 3.3.5 - QLatin1String key("namespace"); - QCLuceneTermQuery query(QCLuceneTerm(key, namespaceName)); + QCLuceneTermQuery query(QCLuceneTerm(NamespaceField, namespaceName)); QCLuceneIndexSearcher indexSearcher(indexPath); QCLuceneHits hits = indexSearcher.search(query); if (hits.length() <= 0) @@ -857,8 +856,7 @@ void QHelpSearchIndexWriter::removeDocuments(const QString &indexPath, return; QCLuceneIndexReader reader = QCLuceneIndexReader::open(indexPath); - reader.deleteDocuments(QCLuceneTerm(QLatin1String("namespace"), - namespaceName)); + reader.deleteDocuments(QCLuceneTerm(NamespaceField, namespaceName)); reader.close(); } diff --git a/tools/assistant/lib/qhelpsearchquerywidget.cpp b/tools/assistant/lib/qhelpsearchquerywidget.cpp index f2f40ec..10d5470 100644 --- a/tools/assistant/lib/qhelpsearchquerywidget.cpp +++ b/tools/assistant/lib/qhelpsearchquerywidget.cpp @@ -120,33 +120,6 @@ private: // nothing todo } - QString escapeString(const QString &text) - { - QString retValue = text; - const QString escape(QLatin1String("\\")); - QStringList escapableCharsList; - escapableCharsList << QLatin1String("\\") << QLatin1String("+") - << QLatin1String("-") << QLatin1String("!") << QLatin1String("(") - << QLatin1String(")") << QLatin1String(":") << QLatin1String("^") - << QLatin1String("[") << QLatin1String("]") << QLatin1String("{") - << QLatin1String("}") << QLatin1String("~"); - - // make sure we won't end up with an empty string - foreach (const QString escapeChar, escapableCharsList) { - if (retValue.contains(escapeChar)) - retValue.replace(escapeChar, QLatin1String("")); - } - if (retValue.trimmed().isEmpty()) - return retValue; - - retValue = text; // now realy escape the string... - foreach (const QString escapeChar, escapableCharsList) { - if (retValue.contains(escapeChar)) - retValue.replace(escapeChar, escape + escapeChar); - } - return retValue; - } - QStringList buildTermList(const QString query) { bool s = false; @@ -295,14 +268,14 @@ private slots: #else if (defaultQuery->isEnabled()) { queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT, - buildTermList(escapeString(defaultQuery->text())))); + buildTermList(defaultQuery->text()))); } else { const QRegExp exp(QLatin1String("\\s+")); QStringList lst = similarQuery->text().split(exp, QString::SkipEmptyParts); if (!lst.isEmpty()) { QStringList fuzzy; foreach (const QString term, lst) - fuzzy += buildTermList(escapeString(term)); + fuzzy += buildTermList(term); queryList.append(QHelpSearchQuery(QHelpSearchQuery::FUZZY, fuzzy)); } @@ -310,13 +283,13 @@ private slots: if (!lst.isEmpty()) { QStringList without; foreach (const QString term, lst) - without.append(escapeString(term)); + without.append(term); queryList.append(QHelpSearchQuery(QHelpSearchQuery::WITHOUT, without)); } if (!exactQuery->text().isEmpty()) { QString phrase = exactQuery->text().remove(QLatin1Char('\"')); - phrase = escapeString(phrase.simplified()); + phrase = phrase.simplified(); queryList.append(QHelpSearchQuery(QHelpSearchQuery::PHRASE, QStringList(phrase))); } @@ -324,7 +297,7 @@ private slots: if (!lst.isEmpty()) { QStringList all; foreach (const QString term, lst) - all.append(escapeString(term)); + all.append(term); queryList.append(QHelpSearchQuery(QHelpSearchQuery::ALL, all)); } @@ -332,7 +305,7 @@ private slots: if (!lst.isEmpty()) { QStringList atLeast; foreach (const QString term, lst) - atLeast += buildTermList(escapeString(term)); + atLeast += buildTermList(term); queryList.append(QHelpSearchQuery(QHelpSearchQuery::ATLEAST, atLeast)); } } diff --git a/tools/assistant/tools/assistant/assistant.pro b/tools/assistant/tools/assistant/assistant.pro index 1a7e874..4b69060 100644 --- a/tools/assistant/tools/assistant/assistant.pro +++ b/tools/assistant/tools/assistant/assistant.pro @@ -36,7 +36,8 @@ HEADERS += helpviewer.h \ remotecontrol.h \ cmdlineparser.h \ aboutdialog.h \ - qtdocinstaller.h + qtdocinstaller.h \ + xbelsupport.h win32 { HEADERS += remotecontrol_win.h @@ -57,7 +58,8 @@ SOURCES += helpviewer.cpp \ remotecontrol.cpp \ cmdlineparser.cpp \ aboutdialog.cpp \ - qtdocinstaller.cpp + qtdocinstaller.cpp \ + xbelsupport.cpp FORMS += topicchooser.ui \ preferencesdialog.ui \ diff --git a/tools/assistant/tools/assistant/assistant.qch b/tools/assistant/tools/assistant/assistant.qch Binary files differindex 78fe9f3..e6d5299 100644 --- a/tools/assistant/tools/assistant/assistant.qch +++ b/tools/assistant/tools/assistant/assistant.qch diff --git a/tools/assistant/tools/assistant/assistant_images.qrc b/tools/assistant/tools/assistant/assistant_images.qrc index 58e03b5..34918c0 100644 --- a/tools/assistant/tools/assistant/assistant_images.qrc +++ b/tools/assistant/tools/assistant/assistant_images.qrc @@ -4,6 +4,7 @@ <file>images/assistant-128.png</file> <file>images/assistant.png</file> <file>images/wrap.png</file> + <file>images/bookmark.png</file> #mac <file>images/mac/addtab.png</file> <file>images/mac/book.png</file> diff --git a/tools/assistant/tools/assistant/bookmarkmanager.cpp b/tools/assistant/tools/assistant/bookmarkmanager.cpp index 511a56e..7c7029a 100644 --- a/tools/assistant/tools/assistant/bookmarkmanager.cpp +++ b/tools/assistant/tools/assistant/bookmarkmanager.cpp @@ -150,8 +150,8 @@ void BookmarkDialog::addNewFolder() const QString &name = index.data().toString(); ui.bookmarkFolders->setCurrentIndex(ui.bookmarkFolders->findText(name)); + renameFolder(index, newFolder); } - ui.treeView->setFocus(); } void BookmarkDialog::toolButtonClicked() @@ -243,14 +243,19 @@ void BookmarkDialog::customContextMenuRequested(const QPoint &point) if (index.isValid()) name = index.data().toString(); ui.bookmarkFolders->setCurrentIndex(ui.bookmarkFolders->findText(name)); + } else if (picked == renameItem) { + renameFolder(index, proxyIndex); } - else if (picked == renameItem) { - BookmarkModel *model = bookmarkManager->treeBookmarkModel(); - if (QStandardItem *item = model->itemFromIndex(proxyIndex)) { - item->setEditable(true); - ui.treeView->edit(index); - item->setEditable(false); - } +} + +void BookmarkDialog::renameFolder(const QModelIndex &index, + const QModelIndex &proxyIndex) +{ + const BookmarkModel * const model = bookmarkManager->treeBookmarkModel(); + if (QStandardItem *item = model->itemFromIndex(proxyIndex)) { + item->setEditable(true); + ui.treeView->edit(index); + item->setEditable(false); } } @@ -301,7 +306,7 @@ bool BookmarkDialog::eventFilter(QObject *object, QEvent *e) } -// #pragma mark -- BookmarkWidget +// BookmarkWidget BookmarkWidget::BookmarkWidget(BookmarkManager *manager, QWidget *parent, @@ -587,7 +592,7 @@ bool BookmarkWidget::eventFilter(QObject *object, QEvent *e) } -// #pragma mark -- BookmarkModel +// BookmarkModel BookmarkModel::BookmarkModel(int rows, int columns, QObject *parent) @@ -615,7 +620,7 @@ Qt::ItemFlags BookmarkModel::flags(const QModelIndex &index) const } -// #pragma mark -- BookmarkManager +// BookmarkManager BookmarkManager::BookmarkManager(QHelpEngineCore *_helpEngine) @@ -625,6 +630,7 @@ BookmarkManager::BookmarkManager(QHelpEngineCore *_helpEngine) , helpEngine(_helpEngine) { folderIcon = QApplication::style()->standardIcon(QStyle::SP_DirClosedIcon); + bookmarkIcon = QIcon(QLatin1String(":/trolltech/assistant/images/bookmark.png")); connect(treeModel, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(itemChanged(QStandardItem*))); @@ -734,6 +740,7 @@ void BookmarkManager::addNewBookmark(const QModelIndex &index, { QStandardItem *item = new QStandardItem(name); item->setEditable(false); + item->setIcon(bookmarkIcon); item->setData(false, Qt::UserRole + 11); item->setData(url, Qt::UserRole + 10); @@ -833,10 +840,12 @@ void BookmarkManager::setupBookmarkModels() } } - if (type == QLatin1String("Folder")) - item->setIcon(folderIcon); - else + if (type != QLatin1String("Folder")) { + item->setIcon(bookmarkIcon); listModel->appendRow(item->clone()); + } else { + item->setIcon(folderIcon); + } } } diff --git a/tools/assistant/tools/assistant/bookmarkmanager.h b/tools/assistant/tools/assistant/bookmarkmanager.h index aba7da0..c6be134 100644 --- a/tools/assistant/tools/assistant/bookmarkmanager.h +++ b/tools/assistant/tools/assistant/bookmarkmanager.h @@ -90,6 +90,7 @@ private slots: private: bool eventFilter(QObject *object, QEvent *e); + void renameFolder(const QModelIndex &index, const QModelIndex &proxyIndex); private: QString m_url; @@ -202,6 +203,7 @@ private: private: QString oldText; QIcon folderIcon; + QIcon bookmarkIcon; BookmarkModel *treeModel; BookmarkModel *listModel; diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp index 67d803d..1c62954 100644 --- a/tools/assistant/tools/assistant/centralwidget.cpp +++ b/tools/assistant/tools/assistant/centralwidget.cpp @@ -550,18 +550,17 @@ void CentralWidget::print() initPrinter(); - QPrintDialog *dlg = new QPrintDialog(printer, this); + QPrintDialog dlg(printer, this); #if defined(QT_NO_WEBKIT) if (viewer->textCursor().hasSelection()) - dlg->addEnabledOption(QAbstractPrintDialog::PrintSelection); + dlg.addEnabledOption(QAbstractPrintDialog::PrintSelection); #endif - dlg->addEnabledOption(QAbstractPrintDialog::PrintPageRange); - dlg->addEnabledOption(QAbstractPrintDialog::PrintCollateCopies); - dlg->setWindowTitle(tr("Print Document")); - if (dlg->exec() == QDialog::Accepted) { + dlg.addEnabledOption(QAbstractPrintDialog::PrintPageRange); + dlg.addEnabledOption(QAbstractPrintDialog::PrintCollateCopies); + dlg.setWindowTitle(tr("Print Document")); + if (dlg.exec() == QDialog::Accepted) { viewer->print(printer); } - delete dlg; #endif } @@ -1002,7 +1001,7 @@ void CentralWidget::updateBrowserFont() int i = searchAttached ? 1 : 0; getBrowserFontFor(tabWidget->widget(i), &font); - for (i; i < tabWidget->count(); ++i) + for (; i < tabWidget->count(); ++i) setBrowserFontFor(tabWidget->widget(i), font); } @@ -1143,6 +1142,17 @@ CentralWidget::highlightSearchTerms() #endif } + +void CentralWidget::closeTabs(const QList<int> &indices) +{ + QList<int> sortedIndices = indices; + qSort(sortedIndices); + for (int i = sortedIndices.count(); --i >= 0;) + closeTabAt(sortedIndices.at(i)); + if (availableHelpViewer() == 0) + setSource(QUrl(QLatin1String("about:blank"))); +} + void CentralWidget::closeTabAt(int index) { HelpViewer *viewer = qobject_cast<HelpViewer*>(tabWidget->widget(index)); diff --git a/tools/assistant/tools/assistant/centralwidget.h b/tools/assistant/tools/assistant/centralwidget.h index 8c186f0..c348abf 100644 --- a/tools/assistant/tools/assistant/centralwidget.h +++ b/tools/assistant/tools/assistant/centralwidget.h @@ -42,6 +42,7 @@ #ifndef CENTRALWIDGET_H #define CENTRALWIDGET_H +#include <QtCore/QList> #include <QtCore/QUrl> #include <QtCore/QPoint> #include <QtCore/QObject> @@ -134,6 +135,7 @@ public: int availableHelpViewer() const; bool enableTabCloseAction() const; + void closeTabs(const QList<int> &indices); void closeTabAt(int index); QMap<int, QString> currentSourceFileList() const; diff --git a/tools/assistant/tools/assistant/images/bookmark.png b/tools/assistant/tools/assistant/images/bookmark.png Binary files differnew file mode 100644 index 0000000..57e57e3 --- /dev/null +++ b/tools/assistant/tools/assistant/images/bookmark.png diff --git a/tools/assistant/tools/assistant/main.cpp b/tools/assistant/tools/assistant/main.cpp index 12bc5b1..2df7a6b 100644 --- a/tools/assistant/tools/assistant/main.cpp +++ b/tools/assistant/tools/assistant/main.cpp @@ -66,6 +66,8 @@ QT_USE_NAMESPACE Q_IMPORT_PLUGIN(qsqlite) #endif +namespace { + void updateLastPagesOnUnregister(QHelpEngineCore& helpEngine, const QString& nsName) { @@ -187,6 +189,8 @@ QString indexFilesFolder(const QString &collectionFile) return indexFilesFolder; } +} // Anonymous namespace. + int main(int argc, char *argv[]) { // First do a quick search for arguments that imply command-line mode. diff --git a/tools/assistant/tools/assistant/mainwindow.cpp b/tools/assistant/tools/assistant/mainwindow.cpp index 01c4f75..ac4e42b 100644 --- a/tools/assistant/tools/assistant/mainwindow.cpp +++ b/tools/assistant/tools/assistant/mainwindow.cpp @@ -52,6 +52,7 @@ #include "aboutdialog.h" #include "searchwidget.h" #include "qtdocinstaller.h" +#include "xbelsupport.h" #include <QtCore/QDir> #include <QtCore/QTimer> @@ -76,6 +77,7 @@ #include <QtGui/QProgressBar> #include <QtGui/QDesktopServices> #include <QtGui/QToolButton> +#include <QtGui/QFileDialog> #include <QtHelp/QHelpEngine> #include <QtHelp/QHelpSearchEngine> @@ -374,13 +376,17 @@ void MainWindow::checkInitState() void MainWindow::updateBookmarkMenu() { if (m_bookmarkManager) { + m_bookmarkMenu->removeAction(m_importBookmarkAction); + m_bookmarkMenu->removeAction(m_exportBookmarkAction); m_bookmarkMenu->removeAction(m_bookmarkMenuAction); - + m_bookmarkMenu->clear(); - + + m_bookmarkMenu->addAction(m_importBookmarkAction); + m_bookmarkMenu->addAction(m_exportBookmarkAction); m_bookmarkMenu->addAction(m_bookmarkMenuAction); m_bookmarkMenu->addSeparator(); - + m_bookmarkManager->fillBookmarkMenu(m_bookmarkMenu); } } @@ -437,8 +443,12 @@ void MainWindow::setupActions() m_closeTabAction->setShortcuts(QKeySequence::Close); QAction *tmp = menu->addAction(tr("&Quit"), this, SLOT(close())); - tmp->setShortcut(QKeySequence::Quit); tmp->setMenuRole(QAction::QuitRole); +#ifdef Q_OS_WIN + tmp->setShortcut(QKeySequence(tr("CTRL+Q"))); +#else + tmp->setShortcut(QKeySequence::Quit); +#endif menu = menuBar()->addMenu(tr("&Edit")); m_copyAction = menu->addAction(tr("&Copy selected Text"), m_centralWidget, @@ -529,6 +539,10 @@ void MainWindow::setupActions() << QKeySequence(Qt::CTRL + Qt::Key_PageUp)); m_bookmarkMenu = menuBar()->addMenu(tr("&Bookmarks")); + m_importBookmarkAction = m_bookmarkMenu->addAction(tr("Import..."), + this, SLOT(importBookmarks())); + m_exportBookmarkAction = m_bookmarkMenu->addAction(tr("Export..."), + this, SLOT(exportBookmarks())); m_bookmarkMenuAction = m_bookmarkMenu->addAction(tr("Add Bookmark..."), this, SLOT(addBookmark())); m_bookmarkMenuAction->setShortcut(tr("CTRL+D")); @@ -861,41 +875,84 @@ void MainWindow::showAboutDialog() aboutDia.exec(); } +void MainWindow::setContentsVisible(bool visible) +{ + if (visible) + showContents(); + else + hideContents(); +} + void MainWindow::showContents() { activateDockWidget(m_contentWindow); } +void MainWindow::hideContents() +{ + m_contentWindow->parentWidget()->hide(); +} + +void MainWindow::setIndexVisible(bool visible) +{ + if (visible) + showIndex(); + else + hideIndex(); +} + void MainWindow::showIndex() { activateDockWidget(m_indexWindow); } +void MainWindow::hideIndex() +{ + m_indexWindow->parentWidget()->hide(); +} + +void MainWindow::setBookmarksVisible(bool visible) +{ + if (visible) + showBookmarks(); + else + hideBookmarks(); +} + + void MainWindow::showBookmarks() { activateDockWidget(m_bookmarkWidget); } -void MainWindow::activateDockWidget(QWidget *w) +void MainWindow::hideBookmarks() { - w->parentWidget()->show(); - w->parentWidget()->raise(); - w->setFocus(); + m_bookmarkWidget->parentWidget()->hide(); } -void MainWindow::hideContents() +void MainWindow::setSearchVisible(bool visible) { - m_contentWindow->parentWidget()->hide(); + if (visible) + showSearch(); + else + hideSearch(); } -void MainWindow::hideIndex() +void MainWindow::showSearch() { - m_indexWindow->parentWidget()->hide(); + m_centralWidget->activateSearchWidget(); } -void MainWindow::hideBookmarks() +void MainWindow::hideSearch() { - m_bookmarkWidget->parentWidget()->hide(); + m_centralWidget->removeSearchWidget(); +} + +void MainWindow::activateDockWidget(QWidget *w) +{ + w->parentWidget()->show(); + w->parentWidget()->raise(); + w->setFocus(); } void MainWindow::setIndexString(const QString &str) @@ -916,21 +973,11 @@ void MainWindow::activateCurrentCentralWidgetTab() m_centralWidget->activateTab(); } -void MainWindow::showSearch() -{ - m_centralWidget->activateSearchWidget(); -} - void MainWindow::showSearchWidget() { m_centralWidget->activateSearchWidget(true); } -void MainWindow::hideSearch() -{ - m_centralWidget->removeSearchWidget(); -} - void MainWindow::updateApplicationFont() { QFont font = qApp->font(); @@ -1035,6 +1082,41 @@ QString MainWindow::defaultHelpCollectionFileName() arg(QLatin1String(QT_VERSION_STR)); } +void MainWindow::importBookmarks() +{ + const QString &fileName = QFileDialog::getOpenFileName(0, tr("Open File"), + QDir::currentPath(), tr("Files (*.xbel)")); + + if (fileName.isEmpty()) + return; + + QFile file(fileName); + if (file.open(QIODevice::ReadOnly)) { + XbelReader reader(m_bookmarkManager->treeBookmarkModel(), + m_bookmarkManager->listBookmarkModel()); + reader.readFromFile(&file); + } +} + +void MainWindow::exportBookmarks() +{ + QString fileName = QFileDialog::getSaveFileName(0, tr("Save File"), + "untitled.xbel", tr("Files (*.xbel)")); + + QLatin1String suffix(".xbel"); + if (!fileName.endsWith(suffix)) + fileName.append(suffix); + + QFile file(fileName); + if (file.open(QIODevice::WriteOnly)) { + XbelWriter writer(m_bookmarkManager->treeBookmarkModel()); + writer.writeToFile(&file); + } else { + QMessageBox::information(this, tr("Qt Assistant"), + tr("Unable to save bookmarks."), tr("OK")); + } +} + void MainWindow::currentFilterChanged(const QString &filter) { const int index = m_filterCombo->findText(filter); diff --git a/tools/assistant/tools/assistant/mainwindow.h b/tools/assistant/tools/assistant/mainwindow.h index 7559fe4..96daf99 100644 --- a/tools/assistant/tools/assistant/mainwindow.h +++ b/tools/assistant/tools/assistant/mainwindow.h @@ -76,10 +76,6 @@ public: static QString defaultHelpCollectionFileName(); public: - void hideContents(); - void hideIndex(); - void hideBookmarks(); - void hideSearch(); void setIndexString(const QString &str); void expandTOC(int depth); bool usesDefaultCollection() const; @@ -88,16 +84,20 @@ signals: void initDone(); public slots: - void showContents(); - void showIndex(); - void showBookmarks(); - void showSearch(); + void setContentsVisible(bool visible); + void setIndexVisible(bool visible); + void setBookmarksVisible(bool visible); + void setSearchVisible(bool visible); void showSearchWidget(); void syncContents(); void activateCurrentCentralWidgetTab(); void currentFilterChanged(const QString &filter); private slots: + void showContents(); + void showIndex(); + void showBookmarks(); + void showSearch(); void insertLastPages(); void addBookmark(); void gotoAddress(); @@ -123,6 +123,9 @@ private slots: void updateBookmarkMenu(); void showBookmark(QAction *action); + void importBookmarks(); + void exportBookmarks(); + private: bool initHelpDB(); void setupActions(); @@ -133,6 +136,10 @@ private: void setupAddressToolbar(); QMenu *toolBarMenu(); QWidget *setupBookmarkWidget(); + void hideContents(); + void hideIndex(); + void hideBookmarks(); + void hideSearch(); QHelpEngine *m_helpEngine; CentralWidget *m_centralWidget; @@ -163,6 +170,8 @@ private: QMenu *m_toolBarMenu; QMenu *m_bookmarkMenu; QAction *m_bookmarkMenuAction; + QAction *m_importBookmarkAction; + QAction *m_exportBookmarkAction; CmdLineParser *m_cmdLine; diff --git a/tools/assistant/tools/assistant/preferencesdialog.cpp b/tools/assistant/tools/assistant/preferencesdialog.cpp index d964015..2aa451e 100644 --- a/tools/assistant/tools/assistant/preferencesdialog.cpp +++ b/tools/assistant/tools/assistant/preferencesdialog.cpp @@ -378,12 +378,7 @@ void PreferencesDialog::applyChanges() } } - qSort(m_TabsToClose); - CentralWidget* widget = CentralWidget::instance(); - for (int i = m_TabsToClose.count(); --i >= 0;) - widget->closeTabAt(m_TabsToClose.at(i)); - if (widget->availableHelpViewer()== 0) - widget->setSource(QUrl(QLatin1String("about:blank"))); + CentralWidget::instance()->closeTabs(m_TabsToClose); if (m_unregDocs.count()) { foreach (const QString &doc, m_unregDocs) diff --git a/tools/assistant/tools/assistant/remotecontrol.cpp b/tools/assistant/tools/assistant/remotecontrol.cpp index 474a681..55780e1 100644 --- a/tools/assistant/tools/assistant/remotecontrol.cpp +++ b/tools/assistant/tools/assistant/remotecontrol.cpp @@ -44,6 +44,7 @@ #include "centralwidget.h" #include <QtCore/QFile> +#include <QtCore/QFileInfo> #include <QtCore/QThread> #include <QtCore/QTextStream> #include <QtCore/QSocketNotifier> @@ -97,9 +98,9 @@ void StdInListenerWin::run() #endif while (ok) { - ok = ReadFile(hStdinDup, chBuf, 4096, &dwRead, NULL); + ok = ReadFile(hStdinDup, chBuf, sizeof(chBuf), &dwRead, NULL); if (ok && dwRead != 0) - emit receivedCommand(QString::fromLocal8Bit(chBuf)); + emit receivedCommand(QString::fromLocal8Bit(chBuf, dwRead)); } } #endif @@ -147,113 +148,169 @@ void RemoteControl::handleCommandString(const QString &cmdString) { QStringList cmds = cmdString.split(QLatin1Char(';')); QStringList::const_iterator it = cmds.constBegin(); - QString cmdLine, cmd, arg; while (it != cmds.constEnd()) { - cmdLine = (*it).trimmed(); - cmd = cmdLine; - arg.clear(); - int i = cmdLine.indexOf(QLatin1Char(' ')); - if (i > 0) { - cmd = cmdLine.left(i); - arg = cmdLine.mid(i+1); - } - cmd = cmd.toLower(); + QString cmd, arg; + splitInputString(*it, cmd, arg); if (m_debug) QMessageBox::information(0, tr("Debugging Remote Control"), tr("Received Command: %1 %2").arg(cmd).arg(arg)); - if (cmd == QLatin1String("debug")) { - if (arg == QLatin1String("on")) - m_debug = true; - else - m_debug = false; - } else if (cmd == QLatin1String("show")) { - if (arg.toLower() == QLatin1String("contents")) { - m_mainWindow->showContents(); - } else if (arg.toLower() == QLatin1String("index")) { - m_mainWindow->showIndex(); - } else if (arg.toLower() == QLatin1String("bookmarks")) { - m_mainWindow->showBookmarks(); - } else if (arg.toLower() == QLatin1String("search")) { - m_mainWindow->showSearch(); - } - } else if (cmd == QLatin1String("hide")) { - if (arg.toLower() == QLatin1String("contents")) { - m_mainWindow->hideContents(); - } else if (arg.toLower() == QLatin1String("index")) { - m_mainWindow->hideIndex(); - } else if (arg.toLower() == QLatin1String("bookmarks")) { - m_mainWindow->hideBookmarks(); - } else if (arg.toLower() == QLatin1String("search")) { - m_mainWindow->hideSearch(); - } - } else if (cmd == QLatin1String("setsource")) { - QUrl url(arg); - if (url.isValid()) { - if (url.isRelative()) - url = CentralWidget::instance()->currentSource().resolved(url); - if (m_caching) { - clearCache(); - m_setSource = url; - } else { - CentralWidget::instance()->setSource(url); - } - } - } else if (cmd == QLatin1String("synccontents")) { - if (m_caching) - m_syncContents = true; - else - m_mainWindow->syncContents(); - } else if (cmd == QLatin1String("activatekeyword")) { - if (m_caching) { - clearCache(); - m_activateKeyword = arg; - } else { - m_mainWindow->setIndexString(arg); - if (!arg.isEmpty()) - m_helpEngine->indexWidget()->activateCurrentItem(); - } - } else if (cmd == QLatin1String("activateidentifier")) { - if (m_caching) { - clearCache(); - m_activateIdentifier = arg; - } else { - QMap<QString, QUrl> links = - m_helpEngine->linksForIdentifier(arg); - if (links.count()) - CentralWidget::instance()->setSource(links.constBegin().value()); - } - } else if (cmd == QLatin1String("expandtoc")) { - bool ok = false; - int depth = -1; - if (!arg.isEmpty()) - depth = arg.toInt(&ok); - if (!ok) - depth = -1; - - if (m_caching) - m_expandTOC = depth; - else - m_mainWindow->expandTOC(depth); - } else if (cmd == QLatin1String("setcurrentfilter")) { - if (!m_helpEngine->customFilters().contains(arg)) - return; - if (m_caching) { - clearCache(); - m_currentFilter = arg; - } else { - m_helpEngine->setCurrentFilter(arg); - } - } else { + if (cmd == QLatin1String("debug")) + handleDebugCommand(arg); + else if (cmd == QLatin1String("show")) + handleShowOrHideCommand(arg, true); + else if (cmd == QLatin1String("hide")) + handleShowOrHideCommand(arg, false); + else if (cmd == QLatin1String("setsource")) + handleSetSourceCommand(arg); + else if (cmd == QLatin1String("synccontents")) + handleSyncContentsCommand(); + else if (cmd == QLatin1String("activatekeyword")) + handleActivateKeywordCommand(arg); + else if (cmd == QLatin1String("activateidentifier")) + handleActivateIdentifierCommand(arg); + else if (cmd == QLatin1String("expandtoc")) + handleExpandTocCommand(arg); + else if (cmd == QLatin1String("setcurrentfilter")) + handleSetCurrentFilterCommand(arg); + else if (cmd == QLatin1String("register")) + handleRegisterCommand(arg); + else if (cmd == QLatin1String("unregister")) + handleUnregisterCommand(arg); + else return; - } + ++it; } m_mainWindow->raise(); m_mainWindow->activateWindow(); } +void RemoteControl::splitInputString(const QString &input, QString &cmd, + QString &arg) +{ + QString cmdLine = input.trimmed(); + int i = cmdLine.indexOf(QLatin1Char(' ')); + cmd = cmdLine.left(i); + arg = cmdLine.mid(i+1); + cmd = cmd.toLower(); +} + +void RemoteControl::handleDebugCommand(const QString &arg) +{ + m_debug = arg == QLatin1String("on"); +} + +void RemoteControl::handleShowOrHideCommand(const QString &arg, bool show) +{ + if (arg.toLower() == QLatin1String("contents")) + m_mainWindow->setContentsVisible(show); + else if (arg.toLower() == QLatin1String("index")) + m_mainWindow->setIndexVisible(show); + else if (arg.toLower() == QLatin1String("bookmarks")) + m_mainWindow->setBookmarksVisible(show); + else if (arg.toLower() == QLatin1String("search")) + m_mainWindow->setSearchVisible(show); +} + +void RemoteControl::handleSetSourceCommand(const QString &arg) +{ + QUrl url(arg); + if (url.isValid()) { + if (url.isRelative()) + url = CentralWidget::instance()->currentSource().resolved(url); + if (m_caching) { + clearCache(); + m_setSource = url; + } else { + CentralWidget::instance()->setSource(url); + } + } +} + +void RemoteControl::handleSyncContentsCommand() +{ + if (m_caching) + m_syncContents = true; + else + m_mainWindow->syncContents(); +} + +void RemoteControl::handleActivateKeywordCommand(const QString &arg) +{ + if (m_caching) { + clearCache(); + m_activateKeyword = arg; + } else { + m_mainWindow->setIndexString(arg); + if (!arg.isEmpty()) + m_helpEngine->indexWidget()->activateCurrentItem(); + } +} + +void RemoteControl::handleActivateIdentifierCommand(const QString &arg) +{ + if (m_caching) { + clearCache(); + m_activateIdentifier = arg; + } else { + const QMap<QString, QUrl> &links = + m_helpEngine->linksForIdentifier(arg); + if (!links.isEmpty()) + CentralWidget::instance()->setSource(links.constBegin().value()); + } +} + +void RemoteControl::handleExpandTocCommand(const QString &arg) +{ + bool ok = false; + int depth = -1; + if (!arg.isEmpty()) + depth = arg.toInt(&ok); + if (!ok) + depth = -1; + + if (m_caching) + m_expandTOC = depth; + else + m_mainWindow->expandTOC(depth); +} + +void RemoteControl::handleSetCurrentFilterCommand(const QString &arg) +{ + if (m_helpEngine->customFilters().contains(arg)) { + if (m_caching) { + clearCache(); + m_currentFilter = arg; + } else { + m_helpEngine->setCurrentFilter(arg); + } + } +} + +void RemoteControl::handleRegisterCommand(const QString &arg) +{ + const QString &absFileName = QFileInfo(arg).absoluteFilePath(); + if (m_helpEngine->registeredDocumentations(). + contains(QHelpEngineCore::namespaceName(absFileName))) + return; + m_helpEngine->registerDocumentation(absFileName); + m_helpEngine->setupData(); +} + +void RemoteControl::handleUnregisterCommand(const QString &arg) +{ + const QString &absFileName = QFileInfo(arg).absoluteFilePath(); + const QString &ns = QHelpEngineCore::namespaceName(absFileName); + if (m_helpEngine->registeredDocumentations().contains(ns)) { + CentralWidget* widget = CentralWidget::instance(); + widget->closeTabs(widget->currentSourceFileList().keys(ns)); + m_helpEngine->unregisterDocumentation(ns); + m_helpEngine->setupData(); + } +} + void RemoteControl::applyCache() { if (m_setSource.isValid()) { diff --git a/tools/assistant/tools/assistant/remotecontrol.h b/tools/assistant/tools/assistant/remotecontrol.h index 710712c..c1c3105 100644 --- a/tools/assistant/tools/assistant/remotecontrol.h +++ b/tools/assistant/tools/assistant/remotecontrol.h @@ -43,6 +43,7 @@ #define REMOTECONTROL_H #include <QtCore/QObject> +#include <QtCore/QString> #include <QtCore/QUrl> QT_BEGIN_NAMESPACE @@ -64,6 +65,17 @@ private slots: private: void clearCache(); + void splitInputString(const QString &input, QString &cmd, QString &arg); + void handleDebugCommand(const QString &arg); + void handleShowOrHideCommand(const QString &arg, bool show); + void handleSetSourceCommand(const QString &arg); + void handleSyncContentsCommand(); + void handleActivateKeywordCommand(const QString &arg); + void handleActivateIdentifierCommand(const QString &arg); + void handleExpandTocCommand(const QString &arg); + void handleSetCurrentFilterCommand(const QString &arg); + void handleRegisterCommand(const QString &arg); + void handleUnregisterCommand(const QString &arg); private: MainWindow *m_mainWindow; diff --git a/tools/assistant/tools/assistant/xbelsupport.cpp b/tools/assistant/tools/assistant/xbelsupport.cpp new file mode 100644 index 0000000..545be6c --- /dev/null +++ b/tools/assistant/tools/assistant/xbelsupport.cpp @@ -0,0 +1,234 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Assistant of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "xbelsupport.h" +#include "bookmarkmanager.h" + +#include <QtCore/QCoreApplication> + +struct Bookmark { + QString title; + QString url; + bool folded; +}; + +XbelWriter::XbelWriter(BookmarkModel *model) + : QXmlStreamWriter() + , treeModel(model) +{ + setAutoFormatting(true); +} + +void XbelWriter::writeToFile(QIODevice *device) +{ + setDevice(device); + + writeStartDocument(); + writeDTD(QLatin1String("<!DOCTYPE xbel>")); + writeStartElement(QLatin1String("xbel")); + writeAttribute(QLatin1String("version"), QLatin1String("1.0")); + + QStandardItem *root = treeModel->invisibleRootItem(); + for (int i = 0; i < root->rowCount(); ++i) + writeData(root->child(i)); + + writeEndDocument(); +} + +void XbelWriter::writeData(QStandardItem *child) +{ + Bookmark entry; + entry.title = child->data(Qt::DisplayRole).toString(); + entry.url = child->data(Qt::UserRole + 10).toString(); + + if (entry.url == QLatin1String("Folder")) { + writeStartElement(QLatin1String("folder")); + + entry.folded = !child->data(Qt::UserRole + 11).toBool(); + writeAttribute(QLatin1String("folded"), + entry.folded ? QLatin1String("yes") : QLatin1String("no")); + + writeTextElement(QLatin1String("title"), entry.title); + + for (int i = 0; i < child->rowCount(); ++i) + writeData(child->child(i)); + + writeEndElement(); + } else { + writeStartElement(QLatin1String("bookmark")); + writeAttribute(QLatin1String("href"), entry.url); + writeTextElement(QLatin1String("title"), entry.title); + writeEndElement(); + } +} + + +// XbelReader + + +XbelReader::XbelReader(BookmarkModel *tree, BookmarkModel *list) + : QXmlStreamReader() + , treeModel(tree) + , listModel(list) +{ + folderIcon = QApplication::style()->standardIcon(QStyle::SP_DirClosedIcon); + bookmarkIcon = QIcon(QLatin1String(":/trolltech/assistant/images/bookmark.png")); +} + +bool XbelReader::readFromFile(QIODevice *device) +{ + setDevice(device); + + while (!atEnd()) { + readNext(); + + if (isStartElement()) { + if (name() == QLatin1String("xbel") + && attributes().value(QLatin1String("version")) + == QLatin1String("1.0")) { + readXBEL(); + } else { + raiseError(QLatin1String("The file is not an XBEL version 1.0 file.")); + } + } + } + + return !error(); +} + +void XbelReader::readXBEL() +{ + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + if (name() == QLatin1String("folder")) + readFolder(0); + else if (name() == QLatin1String("bookmark")) + readBookmark(0); + else + readUnknownElement(); + } + } +} + +void XbelReader::readUnknownElement() +{ + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) + readUnknownElement(); + } +} + +void XbelReader::readFolder(QStandardItem *item) +{ + QStandardItem *folder = createChildItem(item); + folder->setIcon(folderIcon); + folder->setData(QLatin1String("Folder"), Qt::UserRole + 10); + + bool expanded = + (attributes().value(QLatin1String("folded")) != QLatin1String("no")); + folder->setData(expanded, Qt::UserRole + 11); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + if (name() == QLatin1String("title")) + folder->setText(readElementText()); + else if (name() == QLatin1String("folder")) + readFolder(folder); + else if (name() == QLatin1String("bookmark")) + readBookmark(folder); + else + readUnknownElement(); + } + } +} + +void XbelReader::readBookmark(QStandardItem *item) +{ + QStandardItem *bookmark = createChildItem(item); + bookmark->setIcon(bookmarkIcon); + bookmark->setText(QCoreApplication::tr("Unknown title")); + bookmark->setData(attributes().value(QLatin1String("href")).toString(), + Qt::UserRole + 10); + + while (!atEnd()) { + readNext(); + + if (isEndElement()) + break; + + if (isStartElement()) { + if (name() == QLatin1String("title")) + bookmark->setText(readElementText()); + else + readUnknownElement(); + } + } + + listModel->appendRow(bookmark->clone()); +} + +QStandardItem *XbelReader::createChildItem(QStandardItem *item) +{ + QStandardItem *childItem = new QStandardItem(); + childItem->setEditable(false); + + if (item) + item->appendRow(childItem); + else + treeModel->appendRow(childItem); + + return childItem; +} diff --git a/tools/assistant/tools/assistant/xbelsupport.h b/tools/assistant/tools/assistant/xbelsupport.h new file mode 100644 index 0000000..177b04b --- /dev/null +++ b/tools/assistant/tools/assistant/xbelsupport.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Assistant of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef XBELSUPPORT_H +#define XBELSUPPORT_H + +#include <QtGui/QIcon> +#include <QtXml/QXmlStreamReader> + +QT_FORWARD_DECLARE_CLASS(QIODevice) +QT_FORWARD_DECLARE_CLASS(QStandardItem) + +class BookmarkModel; + +class XbelWriter : public QXmlStreamWriter +{ +public: + XbelWriter(BookmarkModel *model); + void writeToFile(QIODevice *device); + +private: + void writeData(QStandardItem *item); + +private: + BookmarkModel *treeModel; +}; + +class XbelReader : public QXmlStreamReader +{ +public: + XbelReader(BookmarkModel *tree, BookmarkModel *list); + bool readFromFile(QIODevice *device); + +private: + void readXBEL(); + void readUnknownElement(); + void readFolder(QStandardItem *item); + void readBookmark(QStandardItem *item); + QStandardItem* createChildItem(QStandardItem *item); + +private: + QIcon folderIcon; + QIcon bookmarkIcon; + + BookmarkModel *treeModel; + BookmarkModel *listModel; +}; + +#endif // XBELSUPPORT_H diff --git a/tools/assistant/tools/qcollectiongenerator/main.cpp b/tools/assistant/tools/qcollectiongenerator/main.cpp index 18a59d1..a2df6ab 100644 --- a/tools/assistant/tools/qcollectiongenerator/main.cpp +++ b/tools/assistant/tools/qcollectiongenerator/main.cpp @@ -322,6 +322,14 @@ void CollectionConfigReader::readRegister() } } +namespace { + QString absoluteFileName(const QString &basePath, const QString &fileName) + { + return QFileInfo(fileName).isAbsolute() ? + fileName : basePath + QDir::separator() + fileName; + } +} + int main(int argc, char *argv[]) { QString error; @@ -403,13 +411,13 @@ int main(int argc, char *argv[]) while (it != config.filesToGenerate().constEnd()) { fprintf(stdout, "Generating help for %s...\n", qPrintable(it.key())); QHelpProjectData helpData; - if (!helpData.readData(basePath + QDir::separator() + it.key())) { + if (!helpData.readData(absoluteFileName(basePath, it.key()))) { fprintf(stderr, "%s\n", qPrintable(helpData.errorMessage())); return -1; } HelpGenerator helpGenerator; - if (!helpGenerator.generate(&helpData, basePath + QDir::separator() + it.value())) { + if (!helpGenerator.generate(&helpData, absoluteFileName(basePath, it.value()))) { fprintf(stderr, "%s\n", qPrintable(helpGenerator.error())); return -1; } @@ -433,7 +441,7 @@ int main(int argc, char *argv[]) } foreach (const QString &file, config.filesToRegister()) { - if (!helpEngine.registerDocumentation(basePath + QDir::separator() + file)) { + if (!helpEngine.registerDocumentation(absoluteFileName(basePath, file))) { fprintf(stderr, "%s\n", qPrintable(helpEngine.error())); return -1; } @@ -470,7 +478,7 @@ int main(int argc, char *argv[]) QDateTime::currentDateTime().toTime_t()); if (!config.applicationIcon().isEmpty()) { - QFile icon(basePath + QDir::separator() + config.applicationIcon()); + QFile icon(absoluteFileName(basePath, config.applicationIcon())); if (!icon.open(QIODevice::ReadOnly)) { fprintf(stderr, "Cannot open %s!\n", qPrintable(icon.fileName())); return -1; @@ -491,7 +499,7 @@ int main(int argc, char *argv[]) } if (!config.aboutIcon().isEmpty()) { - QFile icon(basePath + QDir::separator() + config.aboutIcon()); + QFile icon(absoluteFileName(basePath, config.aboutIcon())); if (!icon.open(QIODevice::ReadOnly)) { fprintf(stderr, "Cannot open %s!\n", qPrintable(icon.fileName())); return -1; @@ -512,7 +520,7 @@ int main(int argc, char *argv[]) while (it != config.aboutTextFiles().constEnd()) { s << it.key(); - QFileInfo fi(basePath + QDir::separator() + it.value()); + QFileInfo fi(absoluteFileName(basePath, it.value())); QFile f(fi.absoluteFilePath()); if (!f.open(QIODevice::ReadOnly)) { fprintf(stderr, "Cannot open %s!\n", qPrintable(f.fileName())); diff --git a/tools/qdoc3/test/qt-build-docs.qdocconf b/tools/qdoc3/test/qt-build-docs.qdocconf index 470ee30..76aac57 100644 --- a/tools/qdoc3/test/qt-build-docs.qdocconf +++ b/tools/qdoc3/test/qt-build-docs.qdocconf @@ -12,6 +12,7 @@ edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript QtScri QtWebKit QtXml QtXmlPatterns Qt3Support QtHelp \ QtDesigner QtAssistant QAxContainer Phonon \ QAxServer QtUiTools QtTest QtDBus + edition.DesktopLight.modules = QtCore QtDBus QtGui Qt3SupportLight QtTest edition.DesktopLight.groups = -graphicsview-api diff --git a/tools/qdoc3/test/qt-inc.qdocconf b/tools/qdoc3/test/qt-inc.qdocconf deleted file mode 100644 index 097db3f..0000000 --- a/tools/qdoc3/test/qt-inc.qdocconf +++ /dev/null @@ -1,149 +0,0 @@ -include(compat.qdocconf) -include(macros.qdocconf) - -project = Qt -description = Qt Reference Documentation -url = http://qt.nokia.com/doc/4.7 - -edition.Desktop = QtCore QtGui QtNetwork QtOpenGL QtSql QtSvg QtXml \ - QtScript QtDesigner Qt3Support QAxContainer QAxServer \ - QtUiTools QtTest QtDBus -edition.DesktopLight = QtCore QtGui Qt3SupportLight QtTest - -language = Cpp - -norecursion = true -sources.fileextensions = "*.cpp *.qdoc" -sourcedirs = $QDOC_CURRENT_DIR -headerdirs = $QDOC_CURRENT_DIR -exampledirs = $QTDIR/doc/src \ - $QTDIR/examples \ - $QTDIR \ - $QTDIR/qmake/examples \ - $QTDIR/src/3rdparty/webkit/WebKit/qt/docs -imagedirs = $QTDIR/doc/src/images \ - $QTDIR/examples -outputdir = $QTDIR/doc/html -indexdir = $QTDIR/doc/indexes -indexes = $QDOC_INPUT_INDEXES -outputindex = $QDOC_OUTPUT_INDEX -base = file:$QTDIR/doc/html -versionsym = QT_VERSION_STR -defines = Q_QDOC \ - QT_.*_SUPPORT \ - QT_.*_LIB \ - QT_COMPAT \ - QT_KEYPAD_NAVIGATION \ - QT3_SUPPORT \ - Q_WS_.* \ - Q_OS_.* \ - Q_BYTE_ORDER \ - __cplusplus - -codeindent = 1 -extraimages.HTML = qt-logo \ - trolltech-logo - -Cpp.ignoretokens = QAXFACTORY_EXPORT \ - QDESIGNER_COMPONENTS_LIBRARY \ - QDESIGNER_EXTENSION_LIBRARY \ - QDESIGNER_SDK_LIBRARY \ - QDESIGNER_SHARED_LIBRARY \ - QDESIGNER_UILIB_LIBRARY \ - QM_EXPORT_CANVAS \ - QM_EXPORT_DNS \ - QM_EXPORT_DOM \ - QM_EXPORT_FTP \ - QM_EXPORT_HTTP \ - QM_EXPORT_ICONVIEW \ - QM_EXPORT_NETWORK \ - QM_EXPORT_OPENGL \ - QM_EXPORT_SQL \ - QM_EXPORT_TABLE \ - QM_EXPORT_WORKSPACE \ - QM_EXPORT_XML \ - QT_ASCII_CAST_WARN \ - QT_BEGIN_HEADER \ - QT_DESIGNER_STATIC \ - QT_END_HEADER \ - QT_WIDGET_PLUGIN_EXPORT \ - Q_COMPAT_EXPORT \ - Q_CORE_EXPORT \ - Q_EXPLICIT \ - Q_EXPORT \ - Q_EXPORT_CODECS_CN \ - Q_EXPORT_CODECS_JP \ - Q_EXPORT_CODECS_KR \ - Q_EXPORT_PLUGIN \ - Q_GFX_INLINE \ - Q_GUI_EXPORT \ - Q_GUI_EXPORT_INLINE \ - Q_GUI_EXPORT_STYLE_CDE \ - Q_GUI_EXPORT_STYLE_COMPACT \ - Q_GUI_EXPORT_STYLE_MAC \ - Q_GUI_EXPORT_STYLE_MOTIF \ - Q_GUI_EXPORT_STYLE_MOTIFPLUS \ - Q_GUI_EXPORT_STYLE_PLATINUM \ - Q_GUI_EXPORT_STYLE_POCKETPC \ - Q_GUI_EXPORT_STYLE_SGI \ - Q_GUI_EXPORT_STYLE_WINDOWS \ - Q_GUI_EXPORT_STYLE_WINDOWSXP \ - Q_INLINE_TEMPLATE \ - Q_NETWORK_EXPORT \ - Q_OPENGL_EXPORT \ - Q_OUTOFLINE_TEMPLATE \ - Q_SQL_EXPORT \ - Q_SVG_EXPORT \ - Q_SCRIPT_EXPORT \ - Q_TESTLIB_EXPORT \ - Q_TYPENAME \ - Q_XML_EXPORT \ - QDBUS_EXPORT \ - Q_GADGET \ - QWEBKIT_EXPORT -Cpp.ignoredirectives = Q_DECLARE_HANDLE \ - Q_DECLARE_INTERFACE \ - Q_DECLARE_METATYPE \ - Q_DECLARE_OPERATORS_FOR_FLAGS \ - Q_DECLARE_PRIVATE \ - Q_DECLARE_PUBLIC \ - Q_DECLARE_SHARED \ - Q_DECLARE_TR_FUNCTIONS \ - Q_DECLARE_TYPEINFO \ - Q_DISABLE_COPY \ - Q_DUMMY_COMPARISON_OPERATOR \ - Q_ENUMS \ - Q_FLAGS \ - Q_INTERFACES \ - Q_OS_SYMBIAN \ - __attribute__ - -HTML.stylesheets = $QTDIR/util/qdoc3/test/classic.css -HTML.postheader = "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n" \ - "<tr>\n" \ - "<td align=\"left\" valign=\"top\" width=\"32\">" \ - "<a href=\"http://qt.nokia.com/\"><img src=\"images/qt-logo.png\" align=\"left\" width=\"32\" height=\"32\" border=\"0\" /></a>" \ - "</td>\n" \ - "<td width=\"1\"> </td>" \ - "<td class=\"postheader\" valign=\"center\">" \ - "<a href=\"index.html\">" \ - "<font color=\"#004faf\">Home</font></a> ·" \ - " <a href=\"classes.html\">" \ - "<font color=\"#004faf\">All Classes</font></a> ·" \ - " <a href=\"mainclasses.html\">" \ - "<font color=\"#004faf\">Main Classes</font></a> ·" \ - " <a href=\"groups.html\">" \ - "<font color=\"#004faf\">Grouped Classes</font></a> ·" \ - " <a href=\"modules.html\">" \ - "<font color=\"#004faf\">Modules</font></a> ·" \ - " <a href=\"functions.html\">" \ - "<font color=\"#004faf\">Functions</font></a>" \ - "</td>\n" \ - "<td align=\"right\" valign=\"top\" width=\"230\"><a href=\"http://qt.nokia.com\"><img src=\"images/trolltech-logo.png\" align=\"right\" width=\"203\" height=\"32\" border=\"0\" /></a></td></tr></table>" - -HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \ - "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \ - "<td width=\"30%\" align=\"left\">Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies)</td>\n" \ - "<td width=\"40%\" align=\"center\"><a href=\"trademarks.html\">Trademarks</a></td>\n" \ - "<td width=\"30%\" align=\"right\"><div align=\"right\">Qt \\version</div></td>\n" \ - "</tr></table></div></address>" |