diff options
72 files changed, 1518 insertions, 813 deletions
diff --git a/demos/browser/networkaccessmanager.cpp b/demos/browser/networkaccessmanager.cpp index 9e717bb..34ba432 100644 --- a/demos/browser/networkaccessmanager.cpp +++ b/demos/browser/networkaccessmanager.cpp @@ -187,7 +187,7 @@ void NetworkAccessManager::proxyAuthenticationRequired(const QNetworkProxy &prox void NetworkAccessManager::sslErrors(QNetworkReply *reply, const QList<QSslError> &error) { // check if SSL certificate has been trusted already - QString replyHost = reply->url().host() + ":" + reply->url().port(); + QString replyHost = reply->url().host() + QString(":%1").arg(reply->url().port()); if(! sslTrustedHostList.contains(replyHost)) { BrowserMainWindow *mainWindow = BrowserApplication::instance()->mainWindow(); diff --git a/demos/embedded/lightmaps/lightmaps.cpp b/demos/embedded/lightmaps/lightmaps.cpp index dfbef06..8e64e73 100644 --- a/demos/embedded/lightmaps/lightmaps.cpp +++ b/demos/embedded/lightmaps/lightmaps.cpp @@ -45,6 +45,9 @@ #include <math.h> +#include "lightmaps.h" +#include "slippymap.h" + #ifndef M_PI #define M_PI 3.14159265358979323846 #endif @@ -59,552 +62,226 @@ // Hint: see above to find why I picked this one :) #define MAX_MAGNIFIER 229 -uint qHash(const QPoint& p) +LightMaps::LightMaps(QWidget *parent) + : QWidget(parent), pressed(false), snapped(false), zoomed(false), + invert(false) { - return p.x() * 17 ^ p.y(); + m_normalMap = new SlippyMap(this); + m_largeMap = new SlippyMap(this); + connect(m_normalMap, SIGNAL(updated(QRect)), SLOT(updateMap(QRect))); + connect(m_largeMap, SIGNAL(updated(QRect)), SLOT(update())); } -// tile size in pixels -const int tdim = 256; - -QPointF tileForCoordinate(qreal lat, qreal lng, int zoom) +void LightMaps::setCenter(qreal lat, qreal lng) { - qreal zn = static_cast<qreal>(1 << zoom); - qreal tx = (lng + 180.0) / 360.0; - qreal ty = (1.0 - log(tan(lat * M_PI / 180.0) + - 1.0 / cos(lat * M_PI / 180.0)) / M_PI) / 2.0; - return QPointF(tx * zn, ty * zn); + m_normalMap->latitude = lat; + m_normalMap->longitude = lng; + m_normalMap->invalidate(); + m_largeMap->latitude = lat; + m_largeMap->longitude = lng; + m_largeMap->invalidate(); } -qreal longitudeFromTile(qreal tx, int zoom) +void LightMaps::toggleNightMode() { - qreal zn = static_cast<qreal>(1 << zoom); - qreal lat = tx / zn * 360.0 - 180.0; - return lat; + invert = !invert; + update(); } -qreal latitudeFromTile(qreal ty, int zoom) +void LightMaps::updateMap(const QRect &r) { - qreal zn = static_cast<qreal>(1 << zoom); - qreal n = M_PI - 2 * M_PI * ty / zn; - qreal lng = 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n))); - return lng; + update(r); } -class SlippyMap: public QObject +void LightMaps::activateZoom() { - Q_OBJECT - -public: - int width; - int height; - int zoom; - qreal latitude; - qreal longitude; - - SlippyMap(QObject *parent = 0) - : QObject(parent) - , width(400) - , height(300) - , zoom(15) - , latitude(59.9138204) - , longitude(10.7387413) { - m_emptyTile = QPixmap(tdim, tdim); - m_emptyTile.fill(Qt::lightGray); - - QNetworkDiskCache *cache = new QNetworkDiskCache; - cache->setCacheDirectory(QDesktopServices::storageLocation - (QDesktopServices::CacheLocation)); - m_manager.setCache(cache); - connect(&m_manager, SIGNAL(finished(QNetworkReply*)), - this, SLOT(handleNetworkData(QNetworkReply*))); - } - - void invalidate() { - if (width <= 0 || height <= 0) - return; - - QPointF ct = tileForCoordinate(latitude, longitude, zoom); - qreal tx = ct.x(); - qreal ty = ct.y(); - - // top-left corner of the center tile - int xp = width / 2 - (tx - floor(tx)) * tdim; - int yp = height / 2 - (ty - floor(ty)) * tdim; - - // first tile vertical and horizontal - int xa = (xp + tdim - 1) / tdim; - int ya = (yp + tdim - 1) / tdim; - int xs = static_cast<int>(tx) - xa; - int ys = static_cast<int>(ty) - ya; - - // offset for top-left tile - m_offset = QPoint(xp - xa * tdim, yp - ya * tdim); - - // last tile vertical and horizontal - int xe = static_cast<int>(tx) + (width - xp - 1) / tdim; - int ye = static_cast<int>(ty) + (height - yp - 1) / tdim; - - // build a rect - m_tilesRect = QRect(xs, ys, xe - xs + 1, ye - ys + 1); - - if (m_url.isEmpty()) - download(); - - emit updated(QRect(0, 0, width, height)); - } - - void render(QPainter *p, const QRect &rect) { - for (int x = 0; x <= m_tilesRect.width(); ++x) - for (int y = 0; y <= m_tilesRect.height(); ++y) { - QPoint tp(x + m_tilesRect.left(), y + m_tilesRect.top()); - QRect box = tileRect(tp); - if (rect.intersects(box)) { - if (m_tilePixmaps.contains(tp)) - p->drawPixmap(box, m_tilePixmaps.value(tp)); - else - p->drawPixmap(box, m_emptyTile); - } - } - } - - void pan(const QPoint &delta) { - QPointF dx = QPointF(delta) / qreal(tdim); - QPointF center = tileForCoordinate(latitude, longitude, zoom) - dx; - latitude = latitudeFromTile(center.y(), zoom); - longitude = longitudeFromTile(center.x(), zoom); - invalidate(); - } - -private slots: - - void handleNetworkData(QNetworkReply *reply) { - QImage img; - QPoint tp = reply->request().attribute(QNetworkRequest::User).toPoint(); - QUrl url = reply->url(); - if (!reply->error()) - if (!img.load(reply, 0)) - img = QImage(); - reply->deleteLater(); - m_tilePixmaps[tp] = QPixmap::fromImage(img); - if (img.isNull()) - m_tilePixmaps[tp] = m_emptyTile; - emit updated(tileRect(tp)); - - // purge unused spaces - QRect bound = m_tilesRect.adjusted(-2, -2, 2, 2); - foreach(QPoint tp, m_tilePixmaps.keys()) - if (!bound.contains(tp)) - m_tilePixmaps.remove(tp); - - download(); - } - - void download() { - QPoint grab(0, 0); - for (int x = 0; x <= m_tilesRect.width(); ++x) - for (int y = 0; y <= m_tilesRect.height(); ++y) { - QPoint tp = m_tilesRect.topLeft() + QPoint(x, y); - if (!m_tilePixmaps.contains(tp)) { - grab = tp; - break; - } - } - if (grab == QPoint(0, 0)) { - m_url = QUrl(); - return; - } - - QString path = "http://tile.openstreetmap.org/%1/%2/%3.png"; - m_url = QUrl(path.arg(zoom).arg(grab.x()).arg(grab.y())); - QNetworkRequest request; - request.setUrl(m_url); - request.setRawHeader("User-Agent", "Nokia (Qt) Graphics Dojo 1.0"); - request.setAttribute(QNetworkRequest::User, QVariant(grab)); - m_manager.get(request); - } - -signals: - void updated(const QRect &rect); - -protected: - QRect tileRect(const QPoint &tp) { - QPoint t = tp - m_tilesRect.topLeft(); - int x = t.x() * tdim + m_offset.x(); - int y = t.y() * tdim + m_offset.y(); - return QRect(x, y, tdim, tdim); - } - -private: - QPoint m_offset; - QRect m_tilesRect; - QPixmap m_emptyTile; - QHash<QPoint, QPixmap> m_tilePixmaps; - QNetworkAccessManager m_manager; - QUrl m_url; -}; + zoomed = true; + tapTimer.stop(); + m_largeMap->zoom = m_normalMap->zoom + 1; + m_largeMap->width = m_normalMap->width * 2; + m_largeMap->height = m_normalMap->height * 2; + m_largeMap->latitude = m_normalMap->latitude; + m_largeMap->longitude = m_normalMap->longitude; + m_largeMap->invalidate(); + update(); +} -class LightMaps: public QWidget +void LightMaps::resizeEvent(QResizeEvent *) { - Q_OBJECT - -public: - LightMaps(QWidget *parent = 0) - : QWidget(parent) - , pressed(false) - , snapped(false) - , zoomed(false) - , invert(false) { - m_normalMap = new SlippyMap(this); - m_largeMap = new SlippyMap(this); - connect(m_normalMap, SIGNAL(updated(QRect)), SLOT(updateMap(QRect))); - connect(m_largeMap, SIGNAL(updated(QRect)), SLOT(update())); - } - - void setCenter(qreal lat, qreal lng) { - m_normalMap->latitude = lat; - m_normalMap->longitude = lng; - m_normalMap->invalidate(); - m_largeMap->invalidate(); - } - -public slots: - void toggleNightMode() { - invert = !invert; - update(); - } - -private slots: - void updateMap(const QRect &r) { - update(r); - } - -protected: - - void activateZoom() { - zoomed = true; - tapTimer.stop(); - m_largeMap->zoom = m_normalMap->zoom + 1; - m_largeMap->width = m_normalMap->width * 2; - m_largeMap->height = m_normalMap->height * 2; - m_largeMap->latitude = m_normalMap->latitude; - m_largeMap->longitude = m_normalMap->longitude; - m_largeMap->invalidate(); - update(); - } - - void resizeEvent(QResizeEvent *) { - m_normalMap->width = width(); - m_normalMap->height = height(); - m_normalMap->invalidate(); - m_largeMap->width = m_normalMap->width * 2; - m_largeMap->height = m_normalMap->height * 2; - m_largeMap->invalidate(); - } + m_normalMap->width = width(); + m_normalMap->height = height(); + m_normalMap->invalidate(); + m_largeMap->width = m_normalMap->width * 2; + m_largeMap->height = m_normalMap->height * 2; + m_largeMap->invalidate(); +} - void paintEvent(QPaintEvent *event) { - QPainter p; - p.begin(this); - m_normalMap->render(&p, event->rect()); - p.setPen(Qt::black); +void LightMaps::paintEvent(QPaintEvent *event) +{ + QPainter p; + p.begin(this); + m_normalMap->render(&p, event->rect()); + p.setPen(Qt::black); #if defined(Q_OS_SYMBIAN) - QFont font = p.font(); - font.setPixelSize(13); - p.setFont(font); + QFont font = p.font(); + font.setPixelSize(13); + p.setFont(font); #endif - p.drawText(rect(), Qt::AlignBottom | Qt::TextWordWrap, - "Map data CCBYSA 2009 OpenStreetMap.org contributors"); - p.end(); - - if (zoomed) { - int dim = qMin(width(), height()); - int magnifierSize = qMin(MAX_MAGNIFIER, dim * 2 / 3); - int radius = magnifierSize / 2; - int ring = radius - 15; - QSize box = QSize(magnifierSize, magnifierSize); - - // reupdate our mask - if (maskPixmap.size() != box) { - maskPixmap = QPixmap(box); - maskPixmap.fill(Qt::transparent); - - QRadialGradient g; - g.setCenter(radius, radius); - g.setFocalPoint(radius, radius); - g.setRadius(radius); - g.setColorAt(1.0, QColor(255, 255, 255, 0)); - g.setColorAt(0.5, QColor(128, 128, 128, 255)); - - QPainter mask(&maskPixmap); - mask.setRenderHint(QPainter::Antialiasing); - mask.setCompositionMode(QPainter::CompositionMode_Source); - mask.setBrush(g); - mask.setPen(Qt::NoPen); - mask.drawRect(maskPixmap.rect()); - mask.setBrush(QColor(Qt::transparent)); - mask.drawEllipse(g.center(), ring, ring); - mask.end(); - } - - QPoint center = dragPos - QPoint(0, radius); - center = center + QPoint(0, radius / 2); - QPoint corner = center - QPoint(radius, radius); - - QPoint xy = center * 2 - QPoint(radius, radius); + p.drawText(rect(), Qt::AlignBottom | Qt::TextWordWrap, + "Map data CCBYSA 2009 OpenStreetMap.org contributors"); + p.end(); + + if (zoomed) { + int dim = qMin(width(), height()); + int magnifierSize = qMin(MAX_MAGNIFIER, dim * 2 / 3); + int radius = magnifierSize / 2; + int ring = radius - 15; + QSize box = QSize(magnifierSize, magnifierSize); + + // reupdate our mask + if (maskPixmap.size() != box) { + maskPixmap = QPixmap(box); + maskPixmap.fill(Qt::transparent); + + QRadialGradient g; + g.setCenter(radius, radius); + g.setFocalPoint(radius, radius); + g.setRadius(radius); + g.setColorAt(1.0, QColor(255, 255, 255, 0)); + g.setColorAt(0.5, QColor(128, 128, 128, 255)); + + QPainter mask(&maskPixmap); + mask.setRenderHint(QPainter::Antialiasing); + mask.setCompositionMode(QPainter::CompositionMode_Source); + mask.setBrush(g); + mask.setPen(Qt::NoPen); + mask.drawRect(maskPixmap.rect()); + mask.setBrush(QColor(Qt::transparent)); + mask.drawEllipse(g.center(), ring, ring); + mask.end(); + } - // only set the dimension to the magnified portion - if (zoomPixmap.size() != box) { - zoomPixmap = QPixmap(box); - zoomPixmap.fill(Qt::lightGray); - } - if (true) { - QPainter p(&zoomPixmap); - p.translate(-xy); - m_largeMap->render(&p, QRect(xy, box)); - p.end(); - } + QPoint center = dragPos - QPoint(0, radius); + center = center + QPoint(0, radius / 2); + QPoint corner = center - QPoint(radius, radius); - QPainterPath clipPath; - clipPath.addEllipse(center, ring, ring); + QPoint xy = center * 2 - QPoint(radius, radius); - QPainter p(this); - p.setRenderHint(QPainter::Antialiasing); - p.setClipPath(clipPath); - p.drawPixmap(corner, zoomPixmap); - p.setClipping(false); - p.drawPixmap(corner, maskPixmap); - p.setPen(Qt::gray); - p.drawPath(clipPath); + // only set the dimension to the magnified portion + if (zoomPixmap.size() != box) { + zoomPixmap = QPixmap(box); + zoomPixmap.fill(Qt::lightGray); } - if (invert) { - QPainter p(this); - p.setCompositionMode(QPainter::CompositionMode_Difference); - p.fillRect(event->rect(), Qt::white); + if (true) { + QPainter p(&zoomPixmap); + p.translate(-xy); + m_largeMap->render(&p, QRect(xy, box)); p.end(); } - } - void timerEvent(QTimerEvent *) { - if (!zoomed) - activateZoom(); - update(); + QPainterPath clipPath; + clipPath.addEllipse(center, ring, ring); + + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + p.setClipPath(clipPath); + p.drawPixmap(corner, zoomPixmap); + p.setClipping(false); + p.drawPixmap(corner, maskPixmap); + p.setPen(Qt::gray); + p.drawPath(clipPath); } - - void mousePressEvent(QMouseEvent *event) { - if (event->buttons() != Qt::LeftButton) - return; - pressed = snapped = true; - pressPos = dragPos = event->pos(); - tapTimer.stop(); - tapTimer.start(HOLD_TIME, this); + if (invert) { + QPainter p(this); + p.setCompositionMode(QPainter::CompositionMode_Difference); + p.fillRect(event->rect(), Qt::white); + p.end(); } +} - void mouseMoveEvent(QMouseEvent *event) { - if (!event->buttons()) - return; - if (!zoomed) { - if (!pressed || !snapped) { - QPoint delta = event->pos() - pressPos; - pressPos = event->pos(); - m_normalMap->pan(delta); - return; - } else { - const int threshold = 10; - QPoint delta = event->pos() - pressPos; - if (snapped) { - snapped &= delta.x() < threshold; - snapped &= delta.y() < threshold; - snapped &= delta.x() > -threshold; - snapped &= delta.y() > -threshold; - } - if (!snapped) - tapTimer.stop(); - } - } else { - dragPos = event->pos(); - update(); - } - } +void LightMaps::timerEvent(QTimerEvent *) +{ + if (!zoomed) + activateZoom(); + update(); +} - void mouseReleaseEvent(QMouseEvent *) { - zoomed = false; - update(); - } +void LightMaps::mousePressEvent(QMouseEvent *event) +{ + if (event->buttons() != Qt::LeftButton) + return; + pressed = snapped = true; + pressPos = dragPos = event->pos(); + tapTimer.stop(); + tapTimer.start(HOLD_TIME, this); +} - void keyPressEvent(QKeyEvent *event) { - if (!zoomed) { - if (event->key() == Qt::Key_Left) - m_normalMap->pan(QPoint(20, 0)); - if (event->key() == Qt::Key_Right) - m_normalMap->pan(QPoint(-20, 0)); - if (event->key() == Qt::Key_Up) - m_normalMap->pan(QPoint(0, 20)); - if (event->key() == Qt::Key_Down) - m_normalMap->pan(QPoint(0, -20)); - if (event->key() == Qt::Key_Z || event->key() == Qt::Key_Select) { - dragPos = QPoint(width() / 2, height() / 2); - activateZoom(); - } +void LightMaps::mouseMoveEvent(QMouseEvent *event) +{ + if (!event->buttons()) + return; + if (!zoomed) { + if (!pressed || !snapped) { + QPoint delta = event->pos() - pressPos; + pressPos = event->pos(); + m_normalMap->pan(delta); + return; } else { - if (event->key() == Qt::Key_Z || event->key() == Qt::Key_Select) { - zoomed = false; - update(); - } - QPoint delta(0, 0); - if (event->key() == Qt::Key_Left) - delta = QPoint(-15, 0); - if (event->key() == Qt::Key_Right) - delta = QPoint(15, 0); - if (event->key() == Qt::Key_Up) - delta = QPoint(0, -15); - if (event->key() == Qt::Key_Down) - delta = QPoint(0, 15); - if (delta != QPoint(0, 0)) { - dragPos += delta; - update(); + const int threshold = 10; + QPoint delta = event->pos() - pressPos; + if (snapped) { + snapped &= delta.x() < threshold; + snapped &= delta.y() < threshold; + snapped &= delta.x() > -threshold; + snapped &= delta.y() > -threshold; } + if (!snapped) + tapTimer.stop(); } + } else { + dragPos = event->pos(); + update(); } +} -private: - SlippyMap *m_normalMap; - SlippyMap *m_largeMap; - bool pressed; - bool snapped; - QPoint pressPos; - QPoint dragPos; - QBasicTimer tapTimer; - bool zoomed; - QPixmap zoomPixmap; - QPixmap maskPixmap; - bool invert; -}; - -class MapZoom : public QMainWindow +void LightMaps::mouseReleaseEvent(QMouseEvent *) { - Q_OBJECT - -private: - LightMaps *map; - QNetworkSession *networkSession; - -public: - MapZoom(): QMainWindow(0) { - map = new LightMaps(this); - setCentralWidget(map); - map->setFocus(); - - QAction *osloAction = new QAction("&Oslo", this); - QAction *berlinAction = new QAction("&Berlin", this); - QAction *jakartaAction = new QAction("&Jakarta", this); - QAction *nightModeAction = new QAction("Night Mode", this); - nightModeAction->setCheckable(true); - nightModeAction->setChecked(false); - QAction *osmAction = new QAction("About OpenStreetMap", this); - connect(osloAction, SIGNAL(triggered()), SLOT(chooseOslo())); - connect(berlinAction, SIGNAL(triggered()), SLOT(chooseBerlin())); - connect(jakartaAction, SIGNAL(triggered()), SLOT(chooseJakarta())); - connect(nightModeAction, SIGNAL(triggered()), map, SLOT(toggleNightMode())); - connect(osmAction, SIGNAL(triggered()), SLOT(aboutOsm())); - -#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM) - menuBar()->addAction(osloAction); - menuBar()->addAction(berlinAction); - menuBar()->addAction(jakartaAction); - menuBar()->addAction(nightModeAction); - menuBar()->addAction(osmAction); -#else - QMenu *menu = menuBar()->addMenu("&Options"); - menu->addAction(osloAction); - menu->addAction(berlinAction); - menu->addAction(jakartaAction); - menu->addSeparator(); - menu->addAction(nightModeAction); - menu->addAction(osmAction); -#endif - - QNetworkConfigurationManager manager; - if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) { - // Get saved network configuration - QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); - settings.beginGroup(QLatin1String("QtNetwork")); - const QString id = - settings.value(QLatin1String("DefaultNetworkConfiguration")).toString(); - settings.endGroup(); - - // If the saved network configuration is not currently discovered use the system - // default - QNetworkConfiguration config = manager.configurationFromIdentifier(id); - if ((config.state() & QNetworkConfiguration::Discovered) != - QNetworkConfiguration::Discovered) { - config = manager.defaultConfiguration(); - } - - networkSession = new QNetworkSession(config, this); - connect(networkSession, SIGNAL(opened()), this, SLOT(sessionOpened())); + zoomed = false; + update(); +} - networkSession->open(); - } else { - networkSession = 0; +void LightMaps::keyPressEvent(QKeyEvent *event) +{ + if (!zoomed) { + if (event->key() == Qt::Key_Left) + m_normalMap->pan(QPoint(20, 0)); + if (event->key() == Qt::Key_Right) + m_normalMap->pan(QPoint(-20, 0)); + if (event->key() == Qt::Key_Up) + m_normalMap->pan(QPoint(0, 20)); + if (event->key() == Qt::Key_Down) + m_normalMap->pan(QPoint(0, -20)); + if (event->key() == Qt::Key_Z || event->key() == Qt::Key_Select) { + dragPos = QPoint(width() / 2, height() / 2); + activateZoom(); } - } - -private slots: - - void sessionOpened() { - // Save the used configuration - QNetworkConfiguration config = networkSession->configuration(); - QString id; - if (config.type() == QNetworkConfiguration::UserChoice) { - id = networkSession->sessionProperty( - QLatin1String("UserChoiceConfiguration")).toString(); - } else { - id = config.identifier(); + } else { + if (event->key() == Qt::Key_Z || event->key() == Qt::Key_Select) { + zoomed = false; + update(); + } + QPoint delta(0, 0); + if (event->key() == Qt::Key_Left) + delta = QPoint(-15, 0); + if (event->key() == Qt::Key_Right) + delta = QPoint(15, 0); + if (event->key() == Qt::Key_Up) + delta = QPoint(0, -15); + if (event->key() == Qt::Key_Down) + delta = QPoint(0, 15); + if (delta != QPoint(0, 0)) { + dragPos += delta; + update(); } - - QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); - settings.beginGroup(QLatin1String("QtNetwork")); - settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id); - settings.endGroup(); - } - - void chooseOslo() { - map->setCenter(59.9138204, 10.7387413); - } - - void chooseBerlin() { - map->setCenter(52.52958999943302, 13.383053541183472); - } - - void chooseJakarta() { - map->setCenter(-6.211544, 106.845172); - } - - void aboutOsm() { - QDesktopServices::openUrl(QUrl("http://www.openstreetmap.org")); } -}; - - -#include "lightmaps.moc" - -int main(int argc, char **argv) -{ -#if defined(Q_WS_X11) - QApplication::setGraphicsSystem("raster"); -#endif - - QApplication app(argc, argv); - app.setApplicationName("LightMaps"); - - MapZoom w; - w.setWindowTitle("OpenStreetMap"); -#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM) - w.showMaximized(); -#else - w.resize(600, 450); - w.show(); -#endif - - return app.exec(); } diff --git a/demos/embedded/lightmaps/lightmaps.h b/demos/embedded/lightmaps/lightmaps.h new file mode 100644 index 0000000..42a80c9 --- /dev/null +++ b/demos/embedded/lightmaps/lightmaps.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications 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 LIGHTMAPS_H +#define LIGHTMAPS_H + +#include <QBasicTimer> +#include <QWidget> + +class SlippyMap; + +class LightMaps: public QWidget +{ + Q_OBJECT + +public: + LightMaps(QWidget *parent = 0); + void setCenter(qreal lat, qreal lng); + +public slots: + void toggleNightMode(); + +protected: + void activateZoom(); + void resizeEvent(QResizeEvent *); + void paintEvent(QPaintEvent *event); + void timerEvent(QTimerEvent *); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *); + void keyPressEvent(QKeyEvent *event); + +private slots: + void updateMap(const QRect &r); + +private: + SlippyMap *m_normalMap; + SlippyMap *m_largeMap; + bool pressed; + bool snapped; + QPoint pressPos; + QPoint dragPos; + QBasicTimer tapTimer; + bool zoomed; + QPixmap zoomPixmap; + QPixmap maskPixmap; + bool invert; +}; + +#endif
\ No newline at end of file diff --git a/demos/embedded/lightmaps/lightmaps.pro b/demos/embedded/lightmaps/lightmaps.pro index 9d83721..cf1180b 100644 --- a/demos/embedded/lightmaps/lightmaps.pro +++ b/demos/embedded/lightmaps/lightmaps.pro @@ -1,5 +1,11 @@ TEMPLATE = app -SOURCES = lightmaps.cpp +HEADERS = lightmaps.h \ + mapzoom.h \ + slippymap.h +SOURCES = lightmaps.cpp \ + main.cpp \ + mapzoom.cpp \ + slippymap.cpp QT += network symbian { diff --git a/demos/embedded/lightmaps/main.cpp b/demos/embedded/lightmaps/main.cpp new file mode 100644 index 0000000..34d8d3d --- /dev/null +++ b/demos/embedded/lightmaps/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications 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 <QApplication> +#include "mapzoom.h" + +int main(int argc, char **argv) +{ +#if defined(Q_WS_X11) + QApplication::setGraphicsSystem("raster"); +#endif + + QApplication app(argc, argv); + app.setApplicationName("LightMaps"); + + MapZoom w; +#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM) + w.showMaximized(); +#else + w.resize(600, 450); + w.show(); +#endif + + return app.exec(); +} diff --git a/demos/embedded/lightmaps/mapzoom.cpp b/demos/embedded/lightmaps/mapzoom.cpp new file mode 100644 index 0000000..6cafc59 --- /dev/null +++ b/demos/embedded/lightmaps/mapzoom.cpp @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications 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 <QtGui> +#include <QtNetwork> +#include "lightmaps.h" +#include "mapzoom.h" + +MapZoom::MapZoom() + : QMainWindow(0) +{ + map = new LightMaps(this); + setCentralWidget(map); + map->setFocus(); + + QAction *osloAction = new QAction(tr("&Oslo"), this); + QAction *berlinAction = new QAction(tr("&Berlin"), this); + QAction *jakartaAction = new QAction(tr("&Jakarta"), this); + QAction *nightModeAction = new QAction(tr("Night Mode"), this); + nightModeAction->setCheckable(true); + nightModeAction->setChecked(false); + QAction *osmAction = new QAction(tr("About OpenStreetMap"), this); + connect(osloAction, SIGNAL(triggered()), SLOT(chooseOslo())); + connect(berlinAction, SIGNAL(triggered()), SLOT(chooseBerlin())); + connect(jakartaAction, SIGNAL(triggered()), SLOT(chooseJakarta())); + connect(nightModeAction, SIGNAL(triggered()), map, SLOT(toggleNightMode())); + connect(osmAction, SIGNAL(triggered()), SLOT(aboutOsm())); + +#if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM) + menuBar()->addAction(osloAction); + menuBar()->addAction(berlinAction); + menuBar()->addAction(jakartaAction); + menuBar()->addAction(nightModeAction); + menuBar()->addAction(osmAction); +#else + QMenu *menu = menuBar()->addMenu(tr("&Options")); + menu->addAction(osloAction); + menu->addAction(berlinAction); + menu->addAction(jakartaAction); + menu->addSeparator(); + menu->addAction(nightModeAction); + menu->addAction(osmAction); +#endif + + QNetworkConfigurationManager manager; + if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) { + // Get saved network configuration + QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); + settings.beginGroup(QLatin1String("QtNetwork")); + const QString id = + settings.value(QLatin1String("DefaultNetworkConfiguration")).toString(); + settings.endGroup(); + + // If the saved network configuration is not currently discovered use the system + // default + QNetworkConfiguration config = manager.configurationFromIdentifier(id); + if ((config.state() & QNetworkConfiguration::Discovered) != + QNetworkConfiguration::Discovered) { + config = manager.defaultConfiguration(); + } + + networkSession = new QNetworkSession(config, this); + connect(networkSession, SIGNAL(opened()), this, SLOT(sessionOpened())); + + networkSession->open(); + } else { + networkSession = 0; + } + + setWindowTitle(tr("Light Maps")); +} + +void MapZoom::sessionOpened() +{ + // Save the used configuration + QNetworkConfiguration config = networkSession->configuration(); + QString id; + if (config.type() == QNetworkConfiguration::UserChoice) { + id = networkSession->sessionProperty( + QLatin1String("UserChoiceConfiguration")).toString(); + } else { + id = config.identifier(); + } + + QSettings settings(QSettings::UserScope, QLatin1String("Trolltech")); + settings.beginGroup(QLatin1String("QtNetwork")); + settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id); + settings.endGroup(); +} + +void MapZoom::chooseOslo() +{ + map->setCenter(59.9138204, 10.7387413); +} + +void MapZoom::chooseBerlin() +{ + map->setCenter(52.52958999943302, 13.383053541183472); +} + +void MapZoom::chooseJakarta() +{ + map->setCenter(-6.211544, 106.845172); +} + +void MapZoom::aboutOsm() +{ + QDesktopServices::openUrl(QUrl("http://www.openstreetmap.org")); +} diff --git a/demos/embedded/lightmaps/mapzoom.h b/demos/embedded/lightmaps/mapzoom.h new file mode 100644 index 0000000..0b1ea8b --- /dev/null +++ b/demos/embedded/lightmaps/mapzoom.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications 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 MAPZOOM_H +#define MAPZOOM_H + +#include <QMainWindow> + +class QNetworkSession; +class LightMaps; + +class MapZoom : public QMainWindow +{ + Q_OBJECT + +public: + MapZoom(); + +private slots: + void sessionOpened(); + void chooseOslo(); + void chooseBerlin(); + void chooseJakarta(); + void aboutOsm(); + +private: + LightMaps *map; + QNetworkSession *networkSession; +}; + +#endif
\ No newline at end of file diff --git a/demos/embedded/lightmaps/slippymap.cpp b/demos/embedded/lightmaps/slippymap.cpp new file mode 100644 index 0000000..2c76f74 --- /dev/null +++ b/demos/embedded/lightmaps/slippymap.cpp @@ -0,0 +1,213 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications 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 <math.h> + +#include <QtGui> +#include <QtNetwork> +#include "slippymap.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +uint qHash(const QPoint& p) +{ + return p.x() * 17 ^ p.y(); +} + +// tile size in pixels +const int tdim = 256; + +QPointF tileForCoordinate(qreal lat, qreal lng, int zoom) +{ + qreal zn = static_cast<qreal>(1 << zoom); + qreal tx = (lng + 180.0) / 360.0; + qreal ty = (1.0 - log(tan(lat * M_PI / 180.0) + + 1.0 / cos(lat * M_PI / 180.0)) / M_PI) / 2.0; + return QPointF(tx * zn, ty * zn); +} + +qreal longitudeFromTile(qreal tx, int zoom) +{ + qreal zn = static_cast<qreal>(1 << zoom); + qreal lat = tx / zn * 360.0 - 180.0; + return lat; +} + +qreal latitudeFromTile(qreal ty, int zoom) +{ + qreal zn = static_cast<qreal>(1 << zoom); + qreal n = M_PI - 2 * M_PI * ty / zn; + qreal lng = 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n))); + return lng; +} + + +SlippyMap::SlippyMap(QObject *parent) + : QObject(parent), width(400), height(300), zoom(15), + latitude(59.9138204), longitude(10.7387413) +{ + m_emptyTile = QPixmap(tdim, tdim); + m_emptyTile.fill(Qt::lightGray); + + QNetworkDiskCache *cache = new QNetworkDiskCache; + cache->setCacheDirectory(QDesktopServices::storageLocation + (QDesktopServices::CacheLocation)); + m_manager.setCache(cache); + connect(&m_manager, SIGNAL(finished(QNetworkReply*)), + this, SLOT(handleNetworkData(QNetworkReply*))); +} + +void SlippyMap::invalidate() +{ + if (width <= 0 || height <= 0) + return; + + QPointF ct = tileForCoordinate(latitude, longitude, zoom); + qreal tx = ct.x(); + qreal ty = ct.y(); + + // top-left corner of the center tile + int xp = width / 2 - (tx - floor(tx)) * tdim; + int yp = height / 2 - (ty - floor(ty)) * tdim; + + // first tile vertical and horizontal + int xa = (xp + tdim - 1) / tdim; + int ya = (yp + tdim - 1) / tdim; + int xs = static_cast<int>(tx) - xa; + int ys = static_cast<int>(ty) - ya; + + // offset for top-left tile + m_offset = QPoint(xp - xa * tdim, yp - ya * tdim); + + // last tile vertical and horizontal + int xe = static_cast<int>(tx) + (width - xp - 1) / tdim; + int ye = static_cast<int>(ty) + (height - yp - 1) / tdim; + + // build a rect + m_tilesRect = QRect(xs, ys, xe - xs + 1, ye - ys + 1); + + if (m_url.isEmpty()) + download(); + + emit updated(QRect(0, 0, width, height)); +} + +void SlippyMap::render(QPainter *p, const QRect &rect) +{ + for (int x = 0; x <= m_tilesRect.width(); ++x) + for (int y = 0; y <= m_tilesRect.height(); ++y) { + QPoint tp(x + m_tilesRect.left(), y + m_tilesRect.top()); + QRect box = tileRect(tp); + if (rect.intersects(box)) { + if (m_tilePixmaps.contains(tp)) + p->drawPixmap(box, m_tilePixmaps.value(tp)); + else + p->drawPixmap(box, m_emptyTile); + } + } +} + +void SlippyMap::pan(const QPoint &delta) +{ + QPointF dx = QPointF(delta) / qreal(tdim); + QPointF center = tileForCoordinate(latitude, longitude, zoom) - dx; + latitude = latitudeFromTile(center.y(), zoom); + longitude = longitudeFromTile(center.x(), zoom); + invalidate(); +} + +void SlippyMap::handleNetworkData(QNetworkReply *reply) +{ + QImage img; + QPoint tp = reply->request().attribute(QNetworkRequest::User).toPoint(); + QUrl url = reply->url(); + if (!reply->error()) + if (!img.load(reply, 0)) + img = QImage(); + reply->deleteLater(); + m_tilePixmaps[tp] = QPixmap::fromImage(img); + if (img.isNull()) + m_tilePixmaps[tp] = m_emptyTile; + emit updated(tileRect(tp)); + + // purge unused spaces + QRect bound = m_tilesRect.adjusted(-2, -2, 2, 2); + foreach(QPoint tp, m_tilePixmaps.keys()) + if (!bound.contains(tp)) + m_tilePixmaps.remove(tp); + + download(); +} + +void SlippyMap::download() +{ + QPoint grab(0, 0); + for (int x = 0; x <= m_tilesRect.width(); ++x) + for (int y = 0; y <= m_tilesRect.height(); ++y) { + QPoint tp = m_tilesRect.topLeft() + QPoint(x, y); + if (!m_tilePixmaps.contains(tp)) { + grab = tp; + break; + } + } + if (grab == QPoint(0, 0)) { + m_url = QUrl(); + return; + } + + QString path = "http://tile.openstreetmap.org/%1/%2/%3.png"; + m_url = QUrl(path.arg(zoom).arg(grab.x()).arg(grab.y())); + QNetworkRequest request; + request.setUrl(m_url); + request.setRawHeader("User-Agent", "Nokia (Qt) Graphics Dojo 1.0"); + request.setAttribute(QNetworkRequest::User, QVariant(grab)); + m_manager.get(request); +} + +QRect SlippyMap::tileRect(const QPoint &tp) +{ + QPoint t = tp - m_tilesRect.topLeft(); + int x = t.x() * tdim + m_offset.x(); + int y = t.y() * tdim + m_offset.y(); + return QRect(x, y, tdim, tdim); +} diff --git a/demos/embedded/lightmaps/slippymap.h b/demos/embedded/lightmaps/slippymap.h new file mode 100644 index 0000000..ba43e40 --- /dev/null +++ b/demos/embedded/lightmaps/slippymap.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demonstration applications 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 SLIPPYMAP_H +#define SLIPPYMAP_H + +#include <QNetworkAccessManager> +#include <QPixmap> +#include <QUrl> + +class QNetworkReply; +class QPainter; + +class SlippyMap: public QObject +{ + Q_OBJECT + +public: + SlippyMap(QObject *parent = 0); + void invalidate(); + void render(QPainter *p, const QRect &rect); + void pan(const QPoint &delta); + + int width; + int height; + int zoom; + qreal latitude; + qreal longitude; + +signals: + void updated(const QRect &rect); + +private slots: + void handleNetworkData(QNetworkReply *reply); + void download(); + +protected: + QRect tileRect(const QPoint &tp); + +private: + QPoint m_offset; + QRect m_tilesRect; + QPixmap m_emptyTile; + QHash<QPoint, QPixmap> m_tilePixmaps; + QNetworkAccessManager m_manager; + QUrl m_url; +}; + +#endif
\ No newline at end of file diff --git a/doc/src/howtos/scalabilityintro.qdoc b/doc/src/howtos/scalabilityintro.qdoc index 5b4e58b..b1d9c19 100644 --- a/doc/src/howtos/scalabilityintro.qdoc +++ b/doc/src/howtos/scalabilityintro.qdoc @@ -198,11 +198,11 @@ \list \o \l{Item::anchors.top}{anchors} within an Item \o \l{Row} / \l{Column} / \l{Grid} - \o simple javascript expressions such as width: Math.round(parent.width / 3.0). + \o simple JavaScript expressions such as width: Math.round(parent.width / 3.0). \endlist These basic building blocks, along with the powerful evaluation - capabilities of javascript expressions within every QML binding, + capabilities of JavaScript expressions within every QML binding, are designed to allow the majority of the layout structure definition to be defined in a Device Profile independent way. @@ -214,14 +214,14 @@ container. By combining the features of the layout managers with simple - javascript expressions, a richer variety of designs can be + JavaScript expressions, a richer variety of designs can be expressed, without having to resort to additional layout measurement parameters or measurement values. Here are some things not to do with layouts: \list - \o Don't define complex javascript functions that are regularly + \o Don't define complex JavaScript functions that are regularly evaluated. This will cause poor performance, particularly during animated transitions. \o Don't define all of your layouts using x, y, width and @@ -275,7 +275,7 @@ by the top level orientation change), in the case of anchor layouts, AnchorAnimation elements can be used to control the transitions. In some cases, you can also use a NumberAnimation on - e.g. the width of an item. Remember to avoid complex javascript + e.g. the width of an item. Remember to avoid complex JavaScript calculations during each frame of animation. Using simple anchor definitions and anchor animations can help with this in the majority of cases. diff --git a/doc/src/tutorials/threads.qdoc b/doc/src/tutorials/threads.qdoc index 1d807a0..2d6a540 100644 --- a/doc/src/tutorials/threads.qdoc +++ b/doc/src/tutorials/threads.qdoc @@ -33,7 +33,7 @@ \title Threading Basics \brief An introduction to threads - \section1 What Are Threads + \section1 What Are Threads? Threads are about doing things in parallel, just like processes. So how do threads differ from processes? While you are making calculations on a diff --git a/examples/graphicsview/diagramscene/arrow.h b/examples/graphicsview/diagramscene/arrow.h index 070f74a..cc6ff97 100644 --- a/examples/graphicsview/diagramscene/arrow.h +++ b/examples/graphicsview/diagramscene/arrow.h @@ -74,8 +74,6 @@ public: DiagramItem *endItem() const { return myEndItem; } - -public slots: void updatePosition(); protected: diff --git a/mkspecs/linux-g++-maemo/qplatformdefs.h b/mkspecs/linux-g++-maemo/qplatformdefs.h index cf6d24e..0a0e122 100644 --- a/mkspecs/linux-g++-maemo/qplatformdefs.h +++ b/mkspecs/linux-g++-maemo/qplatformdefs.h @@ -43,3 +43,11 @@ #define QT_GUI_DOUBLE_CLICK_RADIUS 20 #define QT_GUI_DRAG_DISTANCE 16 + +#define QML_FLICK_OVERSHOOT 160 +#define QML_FLICK_SAMPLEBUFFER 6 +#define QML_FLICK_DISCARDSAMPLES 2 +#define QML_FLICK_DEFAULTMAXVELOCITY 2500 +#define QML_FLICK_DEFAULTDECELERATION 2000 +#define QML_FLICK_OVERSHOOTFRICTION 10 + diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 864d4a5..4d70744 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -525,7 +525,6 @@ public: #endif WA_X11DoNotAcceptFocus = 132, - WA_MacNoCocoaChildWindow = 133, // Add new attributes before this line WA_AttributeCount diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index c495d6f..22ad83b 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -925,14 +925,6 @@ the brushed metal style as supported by the windowing system. This attribute is only applicable to Mac OS X. - \value WA_MacNoCocoaChildWindow Indicates the widget should not be added - as a Cocoa child window of it's parent window. This will free the window - from being moved around together with the parent. However, this - will also allow it to stack/hide behind it's parent (if they are on - the same window level, e.g both windows are dialogs). This can cause problems if - both windows are modal, as the child can then block input to the parent - while hiding behind it. This attribute is only applicable to Mac OS X. - \omitvalue WA_MacMetalStyle \value WA_Mapped Indicates that the widget is mapped on screen. diff --git a/src/declarative/debugger/qdeclarativedebughelper.cpp b/src/declarative/debugger/qdeclarativedebughelper.cpp index 0478209..93f7423 100644 --- a/src/declarative/debugger/qdeclarativedebughelper.cpp +++ b/src/declarative/debugger/qdeclarativedebughelper.cpp @@ -65,10 +65,12 @@ void QDeclarativeDebugHelper::setAnimationSlowDownFactor(qreal factor) } void QDeclarativeDebugHelper::enableDebugging() { +#ifndef QDECLARATIVE_NO_DEBUG_PROTOCOL if (!QDeclarativeEnginePrivate::qml_debugging_enabled) { qWarning("Qml debugging is enabled. Only use this in a safe environment!"); } QDeclarativeEnginePrivate::qml_debugging_enabled = true; +#endif } QT_END_NAMESPACE diff --git a/src/declarative/debugger/qdeclarativedebugserver.cpp b/src/declarative/debugger/qdeclarativedebugserver.cpp index ea3d9a3..14e7187 100644 --- a/src/declarative/debugger/qdeclarativedebugserver.cpp +++ b/src/declarative/debugger/qdeclarativedebugserver.cpp @@ -159,8 +159,8 @@ QDeclarativeDebugServer *QDeclarativeDebugServer::instance() if (!commandLineTested) { commandLineTested = true; -#ifndef QDECLARATIVE_NO_DEBUG_PROTOCOL QApplicationPrivate *appD = static_cast<QApplicationPrivate*>(QObjectPrivate::get(qApp)); +#ifndef QDECLARATIVE_NO_DEBUG_PROTOCOL // ### remove port definition when protocol is changed int port = 0; bool block = false; @@ -204,6 +204,12 @@ QDeclarativeDebugServer *QDeclarativeDebugServer::instance() appD->qmljsDebugArgumentsString()).toAscii().constData()); } } +#else + if (!appD->qmljsDebugArgumentsString().isEmpty()) { + qWarning(QString::fromAscii("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". " + "QtDeclarative is not configured for debugging.").arg( + appD->qmljsDebugArgumentsString()).toAscii().constData()); + } #endif } diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 7e73a37..82ed18c 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -45,9 +45,40 @@ #include <QGraphicsSceneMouseEvent> #include <QPointer> #include <QTimer> +#include "qplatformdefs.h" QT_BEGIN_NAMESPACE +// The maximum number of pixels a flick can overshoot +#ifndef QML_FLICK_OVERSHOOT +#define QML_FLICK_OVERSHOOT 200 +#endif + +// The number of samples to use in calculating the velocity of a flick +#ifndef QML_FLICK_SAMPLEBUFFER +#define QML_FLICK_SAMPLEBUFFER 3 +#endif + +// The number of samples to discard when calculating the flick velocity. +// Touch panels often produce inaccurate results as the finger is lifted. +#ifndef QML_FLICK_DISCARDSAMPLES +#define QML_FLICK_DISCARDSAMPLES 1 +#endif + +// The default maximum velocity of a flick. +#ifndef QML_FLICK_DEFAULTMAXVELOCITY +#define QML_FLICK_DEFAULTMAXVELOCITY 2500 +#endif + +// The default deceleration of a flick. +#ifndef QML_FLICK_DEFAULTDECELERATION +#define QML_FLICK_DEFAULTDECELERATION 1750 +#endif + +// How much faster to decelerate when overshooting +#ifndef QML_FLICK_OVERSHOOTFRICTION +#define QML_FLICK_OVERSHOOTFRICTION 8 +#endif // FlickThreshold determines how far the "mouse" must have moved // before we perform a flick. @@ -141,8 +172,9 @@ QDeclarativeFlickablePrivate::QDeclarativeFlickablePrivate() , hMoved(false), vMoved(false) , movingHorizontally(false), movingVertically(false) , stealMouse(false), pressed(false), interactive(true), calcVelocity(false) - , deceleration(500), maxVelocity(2000), reportedVelocitySmoothing(100) - , delayedPressEvent(0), delayedPressTarget(0), pressDelay(0), fixupDuration(600) + , deceleration(QML_FLICK_DEFAULTDECELERATION) + , maxVelocity(QML_FLICK_DEFAULTMAXVELOCITY), reportedVelocitySmoothing(100) + , delayedPressEvent(0), delayedPressTarget(0), pressDelay(0), fixupDuration(400) , fixupMode(Normal), vTime(0), visibleArea(0) , flickableDirection(QDeclarativeFlickable::AutoFlickDirection) , boundsBehavior(QDeclarativeFlickable::DragAndOvershootBounds) @@ -176,19 +208,39 @@ void QDeclarativeFlickablePrivate::init() } /* - Returns the amount to overshoot by given a velocity. - Will be roughly in range 0 - size/4 + Returns the amount to overshoot by given a view size. + Will be up to the lesser of 1/3 of the view size or QML_FLICK_OVERSHOOT */ -qreal QDeclarativeFlickablePrivate::overShootDistance(qreal velocity, qreal size) +qreal QDeclarativeFlickablePrivate::overShootDistance(qreal size) { if (maxVelocity <= 0) return 0.0; - velocity = qAbs(velocity); - if (velocity > maxVelocity) - velocity = maxVelocity; - qreal dist = size / 4 * velocity / maxVelocity; - return dist; + return qMin(qreal(QML_FLICK_OVERSHOOT), size/3); +} + +void QDeclarativeFlickablePrivate::AxisData::addVelocitySample(qreal v, qreal maxVelocity) +{ + if (v > maxVelocity) + v = maxVelocity; + else if (v < -maxVelocity) + v = -maxVelocity; + velocityBuffer.append(v); + if (velocityBuffer.count() > QML_FLICK_SAMPLEBUFFER) + velocityBuffer.remove(0); +} + +void QDeclarativeFlickablePrivate::AxisData::updateVelocity() +{ + if (velocityBuffer.count() > QML_FLICK_DISCARDSAMPLES) { + velocity = 0; + int count = velocityBuffer.count()-QML_FLICK_DISCARDSAMPLES; + for (int i = 0; i < count; ++i) { + qreal v = velocityBuffer.at(i); + velocity += v; + } + velocity /= count; + } } void QDeclarativeFlickablePrivate::itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeom, const QRectF &oldGeom) @@ -220,15 +272,12 @@ void QDeclarativeFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal Q_Q(QDeclarativeFlickable); qreal maxDistance = -1; data.fixingUp = false; - bool overShoot = boundsBehavior == QDeclarativeFlickable::DragAndOvershootBounds; // -ve velocity means list is moving up if (velocity > 0) { - if (data.move.value() < minExtent) - maxDistance = qAbs(minExtent - data.move.value() + (overShoot?overShootDistance(velocity,vSize):0)); + maxDistance = qAbs(minExtent - data.move.value()); data.flickTarget = minExtent; } else { - if (data.move.value() > maxExtent) - maxDistance = qAbs(maxExtent - data.move.value()) + (overShoot?overShootDistance(velocity,vSize):0); + maxDistance = qAbs(maxExtent - data.move.value()); data.flickTarget = maxExtent; } if (maxDistance > 0) { @@ -240,7 +289,10 @@ void QDeclarativeFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal v = maxVelocity; } timeline.reset(data.move); - timeline.accel(data.move, v, deceleration, maxDistance); + if (boundsBehavior == QDeclarativeFlickable::DragAndOvershootBounds) + timeline.accel(data.move, v, deceleration); + else + timeline.accel(data.move, v, deceleration, maxDistance); timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this)); if (!flickingHorizontally && q->xflick()) { flickingHorizontally = true; @@ -327,6 +379,7 @@ void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal } } } + data.inOvershoot = false; fixupMode = Normal; vTime = timeline.time(); } @@ -706,16 +759,13 @@ void QDeclarativeFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEven q->setKeepMouseGrab(stealMouse); pressed = true; timeline.clear(); - hData.velocity = 0; - vData.velocity = 0; - hData.dragStartOffset = 0; - vData.dragStartOffset = 0; + hData.reset(); + vData.reset(); hData.dragMinBound = q->minXExtent(); vData.dragMinBound = q->minYExtent(); hData.dragMaxBound = q->maxXExtent(); vData.dragMaxBound = q->maxYExtent(); - hData.fixingUp = false; - vData.fixingUp = false; + fixupMode = Normal; lastPos = QPoint(); QDeclarativeItemPrivate::start(lastPosTime); pressPos = event->pos(); @@ -807,33 +857,33 @@ void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent if (stealMouse) q->setKeepMouseGrab(true); - if (!lastPos.isNull()) { - qreal elapsed = qreal(QDeclarativeItemPrivate::restart(lastPosTime)) / 1000.; - if (elapsed <= 0) - elapsed = 1; - if (q->yflick()) { - qreal diff = event->pos().y() - lastPos.y(); - // average to reduce the effect of spurious moves - vData.velocity += diff / elapsed; - vData.velocity /= 2; - } - - if (q->xflick()) { - qreal diff = event->pos().x() - lastPos.x(); - // average to reduce the effect of spurious moves - hData.velocity += diff / elapsed; - hData.velocity /= 2; - } + if (rejectY) { + vData.velocityBuffer.clear(); + vData.velocity = 0; + } + if (rejectX) { + hData.velocityBuffer.clear(); + hData.velocity = 0; } - - if (rejectY) vData.velocity = 0; - if (rejectX) hData.velocity = 0; if (hMoved || vMoved) { q->movementStarting(); q->viewportMoved(); } + if (!lastPos.isNull()) { + qreal elapsed = qreal(QDeclarativeItemPrivate::elapsed(lastPosTime)) / 1000.; + if (elapsed <= 0) + return; + QDeclarativeItemPrivate::restart(lastPosTime); + qreal dy = event->pos().y()-lastPos.y(); + if (q->yflick() && !rejectY) + vData.addVelocitySample(dy/elapsed, maxVelocity); + qreal dx = event->pos().x()-lastPos.x(); + if (q->xflick() && !rejectX) + hData.addVelocitySample(dx/elapsed, maxVelocity); + } + lastPos = event->pos(); } @@ -846,25 +896,33 @@ void QDeclarativeFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEv if (!lastPosTime.isValid()) return; - if (QDeclarativeItemPrivate::elapsed(lastPosTime) > 100) { - // if we drag then pause before release we should not cause a flick. + // if we drag then pause before release we should not cause a flick. + if (QDeclarativeItemPrivate::elapsed(lastPosTime) < 100) { + vData.updateVelocity(); + hData.updateVelocity(); + } else { hData.velocity = 0.0; vData.velocity = 0.0; } vTime = timeline.time(); - if (qAbs(vData.velocity) > MinimumFlickVelocity && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) - flickY(vData.velocity); + + qreal velocity = vData.velocity; + if (vData.atBeginning || vData.atEnd) + velocity /= 2; + if (qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) + flickY(velocity); else fixupY(); - if (qAbs(hData.velocity) > MinimumFlickVelocity && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) - flickX(hData.velocity); + velocity = hData.velocity; + if (hData.atBeginning || hData.atEnd) + velocity /= 2; + if (qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) + flickX(velocity); else fixupX(); - lastPosTime.invalidate(); - if (!timeline.isActive()) q->movementEnding(); } @@ -911,29 +969,41 @@ void QDeclarativeFlickable::wheelEvent(QGraphicsSceneWheelEvent *event) if (!d->interactive) { QDeclarativeItem::wheelEvent(event); } else if (yflick() && event->orientation() == Qt::Vertical) { - if (event->delta() > 0) - d->vData.velocity = qMax(event->delta() - d->vData.smoothVelocity.value(), qreal(250.0)); - else - d->vData.velocity = qMin(event->delta() - d->vData.smoothVelocity.value(), qreal(-250.0)); - d->flickingVertically = false; - d->flickY(d->vData.velocity); - if (d->flickingVertically) { - d->vMoved = true; - movementStarting(); + bool valid = false; + if (event->delta() > 0 && contentY() > -minYExtent()) { + d->vData.velocity = qMax(event->delta()*2 - d->vData.smoothVelocity.value(), qreal(d->maxVelocity/4)); + valid = true; + } else if (event->delta() < 0 && contentY() < -maxYExtent()) { + d->vData.velocity = qMin(event->delta()*2 - d->vData.smoothVelocity.value(), qreal(-d->maxVelocity/4)); + valid = true; + } + if (valid) { + d->flickingVertically = false; + d->flickY(d->vData.velocity); + if (d->flickingVertically) { + d->vMoved = true; + movementStarting(); + } + event->accept(); } - event->accept(); } else if (xflick() && event->orientation() == Qt::Horizontal) { - if (event->delta() > 0) - d->hData.velocity = qMax(event->delta() - d->hData.smoothVelocity.value(), qreal(250.0)); - else - d->hData.velocity = qMin(event->delta() - d->hData.smoothVelocity.value(), qreal(-250.0)); - d->flickingHorizontally = false; - d->flickX(d->hData.velocity); - if (d->flickingHorizontally) { - d->hMoved = true; - movementStarting(); + bool valid = false; + if (event->delta() > 0 && contentX() > -minXExtent()) { + d->hData.velocity = qMax(event->delta()*2 - d->hData.smoothVelocity.value(), qreal(d->maxVelocity/4)); + valid = true; + } else if (event->delta() < 0 && contentX() < -maxXExtent()) { + d->hData.velocity = qMin(event->delta()*2 - d->hData.smoothVelocity.value(), qreal(-d->maxVelocity/4)); + valid = true; + } + if (valid) { + d->flickingHorizontally = false; + d->flickX(d->hData.velocity); + if (d->flickingHorizontally) { + d->hMoved = true; + movementStarting(); + } + event->accept(); } - event->accept(); } else { QDeclarativeItem::wheelEvent(event); } @@ -1071,6 +1141,27 @@ void QDeclarativeFlickable::viewportMoved() } } + if (!d->vData.inOvershoot && !d->vData.fixingUp && d->flickingVertically + && (d->vData.move.value() > minYExtent() || d->vData.move.value() < maxYExtent()) + && qAbs(d->vData.smoothVelocity.value()) > 100) { + // Increase deceleration if we've passed a bound + d->vData.inOvershoot = true; + qreal maxDistance = d->overShootDistance(height()); + d->timeline.reset(d->vData.move); + d->timeline.accel(d->vData.move, -d->vData.smoothVelocity.value(), d->deceleration*QML_FLICK_OVERSHOOTFRICTION, maxDistance); + d->timeline.callback(QDeclarativeTimeLineCallback(&d->vData.move, d->fixupY_callback, d)); + } + if (!d->hData.inOvershoot && !d->hData.fixingUp && d->flickingHorizontally + && (d->hData.move.value() > minXExtent() || d->hData.move.value() < maxXExtent()) + && qAbs(d->hData.smoothVelocity.value()) > 100) { + // Increase deceleration if we've passed a bound + d->hData.inOvershoot = true; + qreal maxDistance = d->overShootDistance(width()); + d->timeline.reset(d->hData.move); + d->timeline.accel(d->hData.move, -d->hData.smoothVelocity.value(), d->deceleration*QML_FLICK_OVERSHOOTFRICTION, maxDistance); + d->timeline.callback(QDeclarativeTimeLineCallback(&d->hData.move, d->fixupX_callback, d)); + } + d->lastFlickablePosition = QPointF(d->hData.move.value(), d->vData.move.value()); d->vTime = d->timeline.time(); @@ -1524,7 +1615,7 @@ bool QDeclarativeFlickable::sceneEventFilter(QGraphicsItem *i, QEvent *e) \qmlproperty real Flickable::maximumFlickVelocity This property holds the maximum velocity that the user can flick the view in pixels/second. - The default is 2000 pixels/s + The default value is platform dependent. */ qreal QDeclarativeFlickable::maximumFlickVelocity() const { @@ -1545,7 +1636,7 @@ void QDeclarativeFlickable::setMaximumFlickVelocity(qreal v) \qmlproperty real Flickable::flickDeceleration This property holds the rate at which a flick will decelerate. - The default is 500. + The default value is platform dependent. */ qreal QDeclarativeFlickable::flickDeceleration() const { diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h index 38a5eb3..1117abb 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h @@ -94,9 +94,19 @@ public: struct AxisData { AxisData(QDeclarativeFlickablePrivate *fp, void (QDeclarativeFlickablePrivate::*func)(qreal)) : move(fp, func), viewSize(-1), smoothVelocity(fp), atEnd(false), atBeginning(true) - , fixingUp(false) + , fixingUp(false), inOvershoot(false) {} + void reset() { + velocityBuffer.clear(); + dragStartOffset = 0; + fixingUp = false; + inOvershoot = false; + } + + void addVelocitySample(qreal v, qreal maxVelocity); + void updateVelocity(); + QDeclarativeTimeLineValueProxy<QDeclarativeFlickablePrivate> move; qreal viewSize; qreal pressPos; @@ -106,9 +116,11 @@ public: qreal velocity; qreal flickTarget; QDeclarativeFlickablePrivate::Velocity smoothVelocity; + QPODVector<qreal,10> velocityBuffer; bool atEnd : 1; bool atBeginning : 1; bool fixingUp : 1; + bool inOvershoot : 1; }; void flickX(qreal velocity); @@ -129,7 +141,7 @@ public: void setRoundedViewportX(qreal x); void setRoundedViewportY(qreal y); - qreal overShootDistance(qreal velocity, qreal size); + qreal overShootDistance(qreal size); void itemGeometryChanged(QDeclarativeItem *, const QRectF &, const QRectF &); diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index b890c4f..cb1f6dc 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -1115,6 +1115,7 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m } else { QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent); } + data.inOvershoot = false; fixupMode = Normal; } @@ -1196,7 +1197,7 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m accel = v2 / (2.0f * qAbs(dist)); } else { data.flickTarget = velocity > 0 ? minExtent : maxExtent; - overshootDist = overShoot ? overShootDistance(v, vSize) : 0; + overshootDist = overShoot ? overShootDistance(vSize) : 0; } timeline.reset(data.move); timeline.accel(data.move, v, accel, maxDistance + overshootDist); diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp index a62d3d2..b776532 100644 --- a/src/declarative/graphicsitems/qdeclarativeimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp @@ -136,12 +136,10 @@ void QDeclarativeImagePrivate::setPixmap(const QPixmap &pixmap) Q_Q(QDeclarativeImage); pix.setPixmap(pixmap); - q->setImplicitWidth(pix.width()); - q->setImplicitHeight(pix.height()); + q->pixmapChange(); status = pix.isNull() ? QDeclarativeImageBase::Null : QDeclarativeImageBase::Ready; q->update(); - q->pixmapChange(); } /*! @@ -390,8 +388,11 @@ void QDeclarativeImage::updatePaintedGeometry() Q_D(QDeclarativeImage); if (d->fillMode == PreserveAspectFit) { - if (!d->pix.width() || !d->pix.height()) + if (!d->pix.width() || !d->pix.height()) { + setImplicitWidth(0); + setImplicitHeight(0); return; + } qreal w = widthValid() ? width() : d->pix.width(); qreal widthScale = w / qreal(d->pix.width()); qreal h = heightValid() ? height() : d->pix.height(); @@ -405,9 +406,13 @@ void QDeclarativeImage::updatePaintedGeometry() } if (widthValid() && !heightValid()) { setImplicitHeight(d->paintedHeight); + } else { + setImplicitHeight(d->pix.height()); } if (heightValid() && !widthValid()) { setImplicitWidth(d->paintedWidth); + } else { + setImplicitWidth(d->pix.width()); } } else if (d->fillMode == PreserveAspectCrop) { if (!d->pix.width() || !d->pix.height()) @@ -566,6 +571,13 @@ void QDeclarativeImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWi void QDeclarativeImage::pixmapChange() { + Q_D(QDeclarativeImage); + // PreserveAspectFit calculates the implicit size differently so we + // don't call our superclass pixmapChange(), since that would + // result in the implicit size being set incorrectly, then updated + // in updatePaintedGeometry() + if (d->fillMode != PreserveAspectFit) + QDeclarativeImageBase::pixmapChange(); updatePaintedGeometry(); } diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp index daebac4..81eac78 100644 --- a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp +++ b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp @@ -191,11 +191,9 @@ void QDeclarativeImageBase::load() d->pix.clear(this); d->status = Null; d->progress = 0.0; - setImplicitWidth(0); - setImplicitHeight(0); + pixmapChange(); emit progressChanged(d->progress); emit statusChanged(d->status); - pixmapChange(); update(); } else { QDeclarativePixmap::Options options; @@ -246,8 +244,7 @@ void QDeclarativeImageBase::requestFinished() d->progress = 1.0; - setImplicitWidth(d->pix.width()); - setImplicitHeight(d->pix.height()); + pixmapChange(); if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height()) emit sourceSizeChanged(); @@ -256,7 +253,7 @@ void QDeclarativeImageBase::requestFinished() emit statusChanged(d->status); if (d->progress != oldProgress) emit progressChanged(d->progress); - pixmapChange(); + update(); } @@ -279,6 +276,9 @@ void QDeclarativeImageBase::componentComplete() void QDeclarativeImageBase::pixmapChange() { + Q_D(QDeclarativeImageBase); + setImplicitWidth(d->pix.width()); + setImplicitHeight(d->pix.height()); } QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 6ae1ddc..f176916 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -1354,6 +1354,7 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m } else { QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent); } + data.inOvershoot = false; fixupMode = Normal; } @@ -1428,10 +1429,10 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m data.flickTarget = isRightToLeft() ? -data.flickTarget+size() : data.flickTarget; if (overShoot) { if (data.flickTarget >= minExtent) { - overshootDist = overShootDistance(v, vSize); + overshootDist = overShootDistance(vSize); data.flickTarget += overshootDist; } else if (data.flickTarget <= maxExtent) { - overshootDist = overShootDistance(v, vSize); + overshootDist = overShootDistance(vSize); data.flickTarget -= overshootDist; } } @@ -1451,10 +1452,10 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m } else if (overShoot) { data.flickTarget = data.move.value() - dist; if (data.flickTarget >= minExtent) { - overshootDist = overShootDistance(v, vSize); + overshootDist = overShootDistance(vSize); data.flickTarget += overshootDist; } else if (data.flickTarget <= maxExtent) { - overshootDist = overShootDistance(v, vSize); + overshootDist = overShootDistance(vSize); data.flickTarget -= overshootDist; } } @@ -2581,7 +2582,7 @@ void QDeclarativeListView::viewportMoved() d->inFlickCorrection = true; // Near an end and it seems that the extent has changed? // Recalculate the flick so that we don't end up in an odd position. - if (yflick()) { + if (yflick() && !d->vData.inOvershoot) { if (d->vData.velocity > 0) { const qreal minY = minYExtent(); if ((minY - d->vData.move.value() < height()/2 || d->vData.flickTarget - d->vData.move.value() < height()/2) @@ -2597,7 +2598,7 @@ void QDeclarativeListView::viewportMoved() } } - if (xflick()) { + if (xflick() && !d->hData.inOvershoot) { if (d->hData.velocity > 0) { const qreal minX = minXExtent(); if ((minX - d->hData.move.value() < width()/2 || d->hData.flickTarget - d->hData.move.value() < width()/2) diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index c284307..276f790 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -643,11 +643,11 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeComponentPrivate &dd, Q The \a properties argument is specified as a map of property-value items. For example, the code below creates an object with initial \c x and \c y values of 100 and 200, respectively: - \qml + \js var component = Qt.createComponent("Button.qml"); if (component.status == Component.Ready) component.createObject(parent, {"x": 100, "y": 100}); - \endqml + \endjs Dynamically created instances can be deleted with the \c destroy() method. See \l {Dynamic Object Management in QML} for more information. diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index a36a276..d51fdfe 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -421,7 +421,7 @@ \omitvalue ItemStopsFocusHandling \omit Same as ItemStopsClickFocusPropagation, but also suppresses focus-out. This flag allows you to completely take over focus handling. - This flag was introduced in Qt 4.7. + This flag was introduced in Qt 4.7. \endomit */ /*! diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 2c70ade..3b5290c 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -726,6 +726,8 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints) m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_EMAIL_ADDR_SPECIAL_CHARACTER_TABLE_DIALOG); } else if (needsCharMap) { m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG); + } else if ((hints & ImhFormattedNumbersOnly) || (hints & ImhDialableCharactersOnly)) { + m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG); } else { m_fepState->SetSpecialCharacterTableResourceId(0); } diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h index 6254061..406e6d4 100644 --- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h +++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h @@ -157,6 +157,20 @@ QT_END_NAMESPACE [NSApp terminate:sender]; } +- (void)setLevel:(NSInteger)windowLevel +{ + // Cocoa will upon activating/deactivating applications level modal + // windows up and down, regardsless of any explicit set window level. + // To ensure that modal stays-on-top dialogs actually stays on top after + // the application is activated (and therefore stacks in front of + // other stays-on-top windows), we need to add this little special-case override: + QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self]; + if (widget && widget->isModal() && (widget->windowFlags() & Qt::WindowStaysOnTopHint)) + [super setLevel:NSPopUpMenuWindowLevel]; + else + [super setLevel:windowLevel]; +} + - (void)sendEvent:(NSEvent *)event { if ([event type] == NSApplicationDefined) { diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index fd9deb5..ac35d42 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -598,10 +598,7 @@ void QWidget::setAutoFillBackground(bool enabled) \brief The QWidget class is the base class of all user interface objects. \ingroup basicwidgets - - \meta {technology} {User Interface} - \meta {platform} {all} - + The widget is the atom of the user interface: it receives mouse, keyboard and other events from the window system, and paints a representation of itself on the screen. Every widget is rectangular, and they are sorted in a diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 7105d23..aca1d53 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -2794,14 +2794,16 @@ void QWidgetPrivate::transferChildren() #ifdef QT_MAC_USE_COCOA void QWidgetPrivate::setSubWindowStacking(bool set) { + // After hitting too many unforeseen bugs trying to put Qt on top of the cocoa child + // window API, we have decided to revert this behaviour as much as we can. We + // therefore now only allow child windows to exist for children of modal dialogs. + static bool use_behaviour_qt473 = !qgetenv("QT_MAC_USE_CHILDWINDOWS").isEmpty(); + // This will set/remove a visual relationship between parent and child on screen. // The reason for doing this is to ensure that a child always stacks infront of - // its parent (expecially if both windows are modal, and the child blocks input to - // the parent while at the same time hiding behind it). Unfortunatly is turns out - // that [NSWindow addChildWindow] has + // its parent. Unfortunatly is turns out that [NSWindow addChildWindow] has // several unwanted side-effects, one of them being the moving of a child when - // moving the parent, which we choose to accept (if this is unacceptable, consider - // using Qt::WA_MacNoCocoaChildWindow). A way tougher side-effect is + // moving the parent, which we choose to accept. A way tougher side-effect is // that Cocoa will hide the parent if you hide the child. And in the case of // a tool window, since it will normally hide when you deactivate the // application, Cocoa will hide the parent upon deactivate as well. The result often @@ -2824,14 +2826,15 @@ void QWidgetPrivate::setSubWindowStacking(bool set) if (QWidget *parent = q->parentWidget()) { if (NSWindow *pwin = [qt_mac_nativeview_for(parent) window]) { if (set) { - if (!q->testAttribute(Qt::WA_MacNoCocoaChildWindow)) { - Qt::WindowType ptype = parent->window()->windowType(); - if ([pwin isVisible] && (ptype == Qt::Window || ptype == Qt::Dialog) && ![qwin parentWindow]) { - NSInteger level = [qwin level]; - [pwin addChildWindow:qwin ordered:NSWindowAbove]; - if ([qwin level] < level) - [qwin setLevel:level]; - } + Qt::WindowType ptype = parent->window()->windowType(); + if ([pwin isVisible] + && (ptype == Qt::Window || ptype == Qt::Dialog) + && ![qwin parentWindow] + && (!use_behaviour_qt473 && parent->windowModality() == Qt::ApplicationModal)) { + NSInteger level = [qwin level]; + [pwin addChildWindow:qwin ordered:NSWindowAbove]; + if ([qwin level] < level) + [qwin setLevel:level]; } } else { [pwin removeChildWindow:qwin]; @@ -2839,14 +2842,16 @@ void QWidgetPrivate::setSubWindowStacking(bool set) } } + // Only set-up child windows for q if q is modal: + if (set && !use_behaviour_qt473 && q->windowModality() != Qt::ApplicationModal) + return; + QObjectList widgets = q->children(); for (int i=0; i<widgets.size(); ++i) { QWidget *child = qobject_cast<QWidget *>(widgets.at(i)); if (child && child->isWindow()) { if (NSWindow *cwin = [qt_mac_nativeview_for(child) window]) { if (set) { - if (child->testAttribute(Qt::WA_MacNoCocoaChildWindow)) - continue; Qt::WindowType ctype = child->window()->windowType(); if ([cwin isVisible] && (ctype == Qt::Window || ctype == Qt::Dialog) && ![cwin parentWindow]) { NSInteger level = [cwin level]; diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index 00b103d..debca37 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -327,10 +327,8 @@ void qt_blend_argb32_on_rgb16_neon(uchar *destPixels, int dbpl, blend_8_pixels_argb32_on_rgb16_neon(dstBuffer, srcBuffer, const_alpha); - for (int j = 0; j < tail; ++j) { + for (int j = 0; j < tail; ++j) dst[i + j] = dstBuffer[j]; - src[i + j] = srcBuffer[j]; - } } dst = (quint16 *)(((uchar *) dst) + dbpl); diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index c1ae3f9..4b087e9 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -398,7 +398,7 @@ void QComboBoxPrivateContainer::leaveEvent(QEvent *) #ifdef Q_WS_MAC QStyleOptionComboBox opt = comboStyleOption(); if (combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo)) - view->setCurrentIndex(QModelIndex()); + view->clearSelection(); #endif } @@ -671,8 +671,8 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e) if (vector.manhattanLength() > 9 && blockMouseReleaseTimer.isActive()) blockMouseReleaseTimer.stop(); QModelIndex indexUnderMouse = view->indexAt(m->pos()); - if (indexUnderMouse.isValid() && indexUnderMouse != view->currentIndex() - && !QComboBoxDelegate::isSeparator(indexUnderMouse)) { + if (indexUnderMouse.isValid() + && !QComboBoxDelegate::isSeparator(indexUnderMouse)) { view->setCurrentIndex(indexUnderMouse); } } diff --git a/src/opengl/qpixmapdata_poolgl.cpp b/src/opengl/qpixmapdata_poolgl.cpp index 44d9c84..95152dd 100644 --- a/src/opengl/qpixmapdata_poolgl.cpp +++ b/src/opengl/qpixmapdata_poolgl.cpp @@ -64,19 +64,6 @@ QT_BEGIN_NAMESPACE Q_OPENGL_EXPORT extern QGLWidget* qt_gl_share_widget(); -/*! - \class QGLFramebufferObjectPool - \since 4.6 - - \brief The QGLFramebufferObject class provides a pool of framebuffer - objects for offscreen rendering purposes. - - When requesting an FBO of a given size and format, an FBO of the same - format and a size at least as big as the requested size will be returned. - - \internal -*/ - static inline int areaDiff(const QSize &size, const QGLFramebufferObject *fbo) { return qAbs(size.width() * size.height() - fbo->width() * fbo->height()); diff --git a/src/s60installs/qt.iby b/src/s60installs/qt.iby index 3a094a3..d6b36e0 100644 --- a/src/s60installs/qt.iby +++ b/src/s60installs/qt.iby @@ -39,11 +39,8 @@ file=ABI_DIR\BUILD_DIR\qtwcodecs.dll SHARED_LIB_DIR\qtwcodecs.dll file=ABI_DIR\BUILD_DIR\qsvgicon.dll SHARED_LIB_DIR\qsvgicon.dll // Phonon MMF backend -// This is commented out by default, as normally Helix backend will be used. -// If the Helix backend is present, it will override MMF backend, so make sure to remove it from -// image creation in addition to uncommenting the following lines if you want to use MMF backend. -//file=ABI_DIR\BUILD_DIR\phonon_mmf.dll SHARED_LIB_DIR\phonon_mmf.dll -//data=\epoc32\data\z\resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin +file=ABI_DIR\BUILD_DIR\phonon_mmf.dll SHARED_LIB_DIR\phonon_mmf.dll +data=\epoc32\data\z\resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin resource\qt\plugins\phonon_backend\phonon_mmf.qtplugin // graphicssystems file=ABI_DIR\BUILD_DIR\qvggraphicssystem.dll SHARED_LIB_DIR\qvggraphicssystem.dll diff --git a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp index d499edf..4fa1cb3 100644 --- a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp +++ b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp @@ -110,7 +110,7 @@ void tst_qdeclarativeflickable::create() QCOMPARE(obj->isInteractive(), true); QCOMPARE(obj->boundsBehavior(), QDeclarativeFlickable::DragAndOvershootBounds); QCOMPARE(obj->pressDelay(), 0); - QCOMPARE(obj->maximumFlickVelocity(), 2000.); + QCOMPARE(obj->maximumFlickVelocity(), 2500.); delete obj; } diff --git a/tests/auto/declarative/qdeclarativeimage/data/aspectratio.qml b/tests/auto/declarative/qdeclarativeimage/data/aspectratio.qml index 739299d..cd092bc 100644 --- a/tests/auto/declarative/qdeclarativeimage/data/aspectratio.qml +++ b/tests/auto/declarative/qdeclarativeimage/data/aspectratio.qml @@ -1,6 +1,10 @@ import QtQuick 1.0 Image { + property int widthChange: 0 + property int heightChange: 0 source: "heart.png" fillMode: Image.PreserveAspectFit; + onWidthChanged: widthChange += 1 + onHeightChanged: heightChange += 1 } diff --git a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp index c5a3d14..87e3347 100644 --- a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp +++ b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp @@ -248,14 +248,22 @@ void tst_qdeclarativeimage::preserveAspectRatio() canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/aspectratio.qml")); QDeclarativeImage *image = qobject_cast<QDeclarativeImage*>(canvas->rootObject()); QVERIFY(image != 0); + QCOMPARE(image->property("widthChange").toInt(), 1); + QCOMPARE(image->property("heightChange").toInt(), 1); image->setWidth(80.0); + QCOMPARE(image->property("widthChange").toInt(), 2); + QCOMPARE(image->property("heightChange").toInt(), 2); QCOMPARE(image->width(), 80.); QCOMPARE(image->height(), 80.); canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/aspectratio.qml")); image = qobject_cast<QDeclarativeImage*>(canvas->rootObject()); - image->setHeight(60.0); QVERIFY(image != 0); + QCOMPARE(image->property("widthChange").toInt(), 1); + QCOMPARE(image->property("heightChange").toInt(), 1); + image->setHeight(60.0); + QCOMPARE(image->property("widthChange").toInt(), 2); + QCOMPARE(image->property("heightChange").toInt(), 2); QCOMPARE(image->height(), 60.); QCOMPARE(image->width(), 60.); delete canvas; diff --git a/tests/auto/macnativeevents/tst_macnativeevents.cpp b/tests/auto/macnativeevents/tst_macnativeevents.cpp index ac7298c..731fe0a 100644 --- a/tests/auto/macnativeevents/tst_macnativeevents.cpp +++ b/tests/auto/macnativeevents/tst_macnativeevents.cpp @@ -68,7 +68,7 @@ private slots: void testMouseEnter(); void testChildDialogInFrontOfModalParent(); #ifdef QT_MAC_USE_COCOA - void testChildWindowInFrontOfParentWindow(); +// void testChildWindowInFrontOfParentWindow(); // void testChildToolWindowInFrontOfChildNormalWindow(); void testChildWindowInFrontOfStaysOnTopParentWindow(); #endif @@ -314,6 +314,11 @@ void tst_MacNativeEvents::testChildDialogInFrontOfModalParent() } #ifdef QT_MAC_USE_COCOA +#if 0 +// This test is disabled as of Qt-4.7.4 because we cannot do it +// unless we use the Cocoa sub window API. But using that opens up +// a world of side effects that we cannot live with. So we rather +// not support child-on-top-of-parent instead. void tst_MacNativeEvents::testChildWindowInFrontOfParentWindow() { // Test that a child window always stacks in front of its parent window. @@ -338,6 +343,7 @@ void tst_MacNativeEvents::testChildWindowInFrontOfParentWindow() QTest::qWait(100); QVERIFY(!child.isVisible()); } +#endif /* This test can be enabled once setStackingOrder has been fixed in qwidget_mac.mm void tst_MacNativeEvents::testChildToolWindowInFrontOfChildNormalWindow() diff --git a/tools/qdoc3/config.cpp b/tools/qdoc3/config.cpp index 267a09c..838f6ac 100644 --- a/tools/qdoc3/config.cpp +++ b/tools/qdoc3/config.cpp @@ -338,7 +338,7 @@ QSet<QString> Config::subVars(const QString& var) const { QSet<QString> result; QString varDot = var + QLatin1Char('.'); - QMap<QString, QString>::ConstIterator v = stringValueMap.begin(); + QStringMultiMap::ConstIterator v = stringValueMap.begin(); while (v != stringValueMap.end()) { if (v.key().startsWith(varDot)) { QString subVar = v.key().mid(varDot.length()); @@ -357,10 +357,10 @@ QSet<QString> Config::subVars(const QString& var) const with the matching keys (stripped of the prefix \a var and mapped to their values. The pairs are inserted into \a t */ -void Config::subVarsAndValues(const QString& var, QStringMap& t) const +void Config::subVarsAndValues(const QString& var, QStringMultiMap& t) const { QString varDot = var + QLatin1Char('.'); - QMap<QString, QString>::ConstIterator v = stringValueMap.begin(); + QStringMultiMap::ConstIterator v = stringValueMap.begin(); while (v != stringValueMap.end()) { if (v.key().startsWith(varDot)) { QString subVar = v.key().mid(varDot.length()); diff --git a/tools/qdoc3/config.h b/tools/qdoc3/config.h index 767acb1..8e19ed2 100644 --- a/tools/qdoc3/config.h +++ b/tools/qdoc3/config.h @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE -typedef QMap<QString,QString> QStringMap; +typedef QMultiMap<QString, QString> QStringMultiMap; class Config { @@ -76,7 +76,7 @@ class Config QRegExp getRegExp(const QString& var) const; QList<QRegExp> getRegExpList(const QString& var) const; QSet<QString> subVars(const QString& var) const; - void subVarsAndValues(const QString& var, QStringMap& t) const; + void subVarsAndValues(const QString& var, QStringMultiMap& t) const; QStringList getAllFiles(const QString& filesVar, const QString& dirsVar, const QSet<QString> &excludedDirs = QSet<QString>()); diff --git a/tools/qdoc3/declarativeparser/qdeclarativejsast.cpp b/tools/qdoc3/declarativeparser/qdeclarativejsast.cpp index afb399a..e59ffd7 100644 --- a/tools/qdoc3/declarativeparser/qdeclarativejsast.cpp +++ b/tools/qdoc3/declarativeparser/qdeclarativejsast.cpp @@ -39,9 +39,9 @@ ** ****************************************************************************/ -#include "private/qdeclarativejsast_p.h" +#include "qdeclarativejsast_p.h" -#include "private/qdeclarativejsastvisitor_p.h" +#include "qdeclarativejsastvisitor_p.h" QT_QML_BEGIN_NAMESPACE diff --git a/tools/qdoc3/declarativeparser/qdeclarativejsast_p.h b/tools/qdoc3/declarativeparser/qdeclarativejsast_p.h index 956d6e7..cd41187 100644 --- a/tools/qdoc3/declarativeparser/qdeclarativejsast_p.h +++ b/tools/qdoc3/declarativeparser/qdeclarativejsast_p.h @@ -53,8 +53,8 @@ // We mean it. // -#include "private/qdeclarativejsastvisitor_p.h" -#include "private/qdeclarativejsglobal_p.h" +#include "qdeclarativejsastvisitor_p.h" +#include "qdeclarativejsglobal_p.h" #include <QtCore/QString> diff --git a/tools/qdoc3/declarativeparser/qdeclarativejsastfwd_p.h b/tools/qdoc3/declarativeparser/qdeclarativejsastfwd_p.h index 8a20ab2..8344d54 100644 --- a/tools/qdoc3/declarativeparser/qdeclarativejsastfwd_p.h +++ b/tools/qdoc3/declarativeparser/qdeclarativejsastfwd_p.h @@ -42,7 +42,7 @@ #ifndef QDECLARATIVEJSAST_FWD_P_H #define QDECLARATIVEJSAST_FWD_P_H -#include "private/qdeclarativejsglobal_p.h" +#include "qdeclarativejsglobal_p.h" #include <QtCore/qglobal.h> diff --git a/tools/qdoc3/declarativeparser/qdeclarativejsastvisitor.cpp b/tools/qdoc3/declarativeparser/qdeclarativejsastvisitor.cpp index 8df755a..b4eecc1 100644 --- a/tools/qdoc3/declarativeparser/qdeclarativejsastvisitor.cpp +++ b/tools/qdoc3/declarativeparser/qdeclarativejsastvisitor.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include "private/qdeclarativejsastvisitor_p.h" +#include "qdeclarativejsastvisitor_p.h" QT_QML_BEGIN_NAMESPACE diff --git a/tools/qdoc3/declarativeparser/qdeclarativejsastvisitor_p.h b/tools/qdoc3/declarativeparser/qdeclarativejsastvisitor_p.h index 519b8c8..6ef7c81 100644 --- a/tools/qdoc3/declarativeparser/qdeclarativejsastvisitor_p.h +++ b/tools/qdoc3/declarativeparser/qdeclarativejsastvisitor_p.h @@ -53,8 +53,8 @@ // We mean it. // -#include "private/qdeclarativejsastfwd_p.h" -#include "private/qdeclarativejsglobal_p.h" +#include "qdeclarativejsastfwd_p.h" +#include "qdeclarativejsglobal_p.h" QT_QML_BEGIN_NAMESPACE diff --git a/tools/qdoc3/declarativeparser/qdeclarativejsengine_p.cpp b/tools/qdoc3/declarativeparser/qdeclarativejsengine_p.cpp index ec9271a..4d135c2 100644 --- a/tools/qdoc3/declarativeparser/qdeclarativejsengine_p.cpp +++ b/tools/qdoc3/declarativeparser/qdeclarativejsengine_p.cpp @@ -39,10 +39,10 @@ ** ****************************************************************************/ -#include "private/qdeclarativejsengine_p.h" +#include "qdeclarativejsengine_p.h" -#include "private/qdeclarativejsglobal_p.h" -#include "private/qdeclarativejsnodepool_p.h" +#include "qdeclarativejsglobal_p.h" +#include "qdeclarativejsnodepool_p.h" #include <qnumeric.h> #include <QHash> diff --git a/tools/qdoc3/declarativeparser/qdeclarativejsengine_p.h b/tools/qdoc3/declarativeparser/qdeclarativejsengine_p.h index 6c18b50..c6126ea 100644 --- a/tools/qdoc3/declarativeparser/qdeclarativejsengine_p.h +++ b/tools/qdoc3/declarativeparser/qdeclarativejsengine_p.h @@ -53,8 +53,8 @@ // We mean it. // -#include "private/qdeclarativejsglobal_p.h" -#include "private/qdeclarativejsastfwd_p.h" +#include "qdeclarativejsglobal_p.h" +#include "qdeclarativejsastfwd_p.h" #include <QString> #include <QSet> diff --git a/tools/qdoc3/declarativeparser/qdeclarativejslexer.cpp b/tools/qdoc3/declarativeparser/qdeclarativejslexer.cpp index 4dfef45..f5fb791 100644 --- a/tools/qdoc3/declarativeparser/qdeclarativejslexer.cpp +++ b/tools/qdoc3/declarativeparser/qdeclarativejslexer.cpp @@ -43,11 +43,11 @@ #include <config.h> #endif -#include "private/qdeclarativejslexer_p.h" +#include "qdeclarativejslexer_p.h" -#include "private/qdeclarativejsglobal_p.h" -#include "private/qdeclarativejsengine_p.h" -#include "private/qdeclarativejsgrammar_p.h" +#include "qdeclarativejsglobal_p.h" +#include "qdeclarativejsengine_p.h" +#include "qdeclarativejsgrammar_p.h" #include <QtCore/qcoreapplication.h> diff --git a/tools/qdoc3/declarativeparser/qdeclarativejslexer_p.h b/tools/qdoc3/declarativeparser/qdeclarativejslexer_p.h index e41337d..8febb54 100644 --- a/tools/qdoc3/declarativeparser/qdeclarativejslexer_p.h +++ b/tools/qdoc3/declarativeparser/qdeclarativejslexer_p.h @@ -53,7 +53,7 @@ // We mean it. // -#include "private/qdeclarativejsglobal_p.h" +#include "qdeclarativejsglobal_p.h" #include <QtCore/QString> diff --git a/tools/qdoc3/declarativeparser/qdeclarativejsmemorypool_p.h b/tools/qdoc3/declarativeparser/qdeclarativejsmemorypool_p.h index 7eea975..ebf75d1 100644 --- a/tools/qdoc3/declarativeparser/qdeclarativejsmemorypool_p.h +++ b/tools/qdoc3/declarativeparser/qdeclarativejsmemorypool_p.h @@ -53,7 +53,7 @@ // We mean it. // -#include "private/qdeclarativejsglobal_p.h" +#include "qdeclarativejsglobal_p.h" #include <QtCore/qglobal.h> #include <QtCore/qshareddata.h> diff --git a/tools/qdoc3/declarativeparser/qdeclarativejsnodepool_p.h b/tools/qdoc3/declarativeparser/qdeclarativejsnodepool_p.h index fde4897..ca3841c 100644 --- a/tools/qdoc3/declarativeparser/qdeclarativejsnodepool_p.h +++ b/tools/qdoc3/declarativeparser/qdeclarativejsnodepool_p.h @@ -53,8 +53,8 @@ // We mean it. // -#include "private/qdeclarativejsglobal_p.h" -#include "private/qdeclarativejsmemorypool_p.h" +#include "qdeclarativejsglobal_p.h" +#include "qdeclarativejsmemorypool_p.h" #include <QtCore/QHash> #include <QtCore/QString> diff --git a/tools/qdoc3/declarativeparser/qdeclarativejsparser.cpp b/tools/qdoc3/declarativeparser/qdeclarativejsparser.cpp index 9a93fa1..118dcc6 100644 --- a/tools/qdoc3/declarativeparser/qdeclarativejsparser.cpp +++ b/tools/qdoc3/declarativeparser/qdeclarativejsparser.cpp @@ -44,14 +44,14 @@ #include <string.h> -#include "private/qdeclarativejsengine_p.h" -#include "private/qdeclarativejslexer_p.h" -#include "private/qdeclarativejsast_p.h" -#include "private/qdeclarativejsnodepool_p.h" +#include "qdeclarativejsengine_p.h" +#include "qdeclarativejslexer_p.h" +#include "qdeclarativejsast_p.h" +#include "qdeclarativejsnodepool_p.h" -#include "private/qdeclarativejsparser_p.h" +#include "qdeclarativejsparser_p.h" #include <QVarLengthArray> // diff --git a/tools/qdoc3/declarativeparser/qdeclarativejsparser_p.h b/tools/qdoc3/declarativeparser/qdeclarativejsparser_p.h index ad46bff..5eec1a4 100644 --- a/tools/qdoc3/declarativeparser/qdeclarativejsparser_p.h +++ b/tools/qdoc3/declarativeparser/qdeclarativejsparser_p.h @@ -59,10 +59,10 @@ #ifndef QDECLARATIVEJSPARSER_P_H #define QDECLARATIVEJSPARSER_P_H -#include "private/qdeclarativejsglobal_p.h" -#include "private/qdeclarativejsgrammar_p.h" -#include "private/qdeclarativejsast_p.h" -#include "private/qdeclarativejsengine_p.h" +#include "qdeclarativejsglobal_p.h" +#include "qdeclarativejsgrammar_p.h" +#include "qdeclarativejsast_p.h" +#include "qdeclarativejsengine_p.h" #include <QtCore/QList> #include <QtCore/QString> diff --git a/tools/qdoc3/ditaxmlgenerator.cpp b/tools/qdoc3/ditaxmlgenerator.cpp index 4b4f776..1bc4992 100644 --- a/tools/qdoc3/ditaxmlgenerator.cpp +++ b/tools/qdoc3/ditaxmlgenerator.cpp @@ -5566,24 +5566,12 @@ void DitaXmlGenerator::writeDitaMap() \note If \a t is found in the metadata map, it is erased. i.e. Once you call this function for a particular \a t, you consume \a t. - - At the moment, it doesn't chaeck to see if there is a - default value for the tag. But it will eventually. */ bool DitaXmlGenerator::writeMetadataElement(const InnerNode* inner, DitaXmlGenerator::DitaTag t, bool force) { - QString s; - QStringMap& metaTagMap = const_cast<QStringMap&>(inner->doc().metaTagMap()); - QStringMap::iterator i = metaTagMap.find(ditaTags[t]); - if (i == metaTagMap.end()) { - s = metadataDefault(t); - } - else { - s = i.value(); - metaTagMap.erase(i); - } + QString s = getMetadataElement(inner,t); if (s.isEmpty() && !force) return false; writeStartTag(t); @@ -5593,6 +5581,34 @@ bool DitaXmlGenerator::writeMetadataElement(const InnerNode* inner, return true; } + +/*! + Looks up the tag name for \a t in the map of metadata + values for the current topic in \a inner. If one or more + value sfor the tag are found, the elements are written. + Otherwise nothing is written. + + Returns true or false depending on whether it writes + at least one element using the tag \a t. + + \note If \a t is found in the metadata map, it is erased. + i.e. Once you call this function for a particular \a t, + you consume \a t. + */ +bool DitaXmlGenerator::writeMetadataElements(const InnerNode* inner, + DitaXmlGenerator::DitaTag t) +{ + QStringList s = getMetadataElements(inner,t); + if (s.isEmpty()) + return false; + for (int i=0; i<s.size(); ++i) { + writeStartTag(t); + xmlWriter().writeCharacters(s[i]); + writeEndTag(); + } + return true; +} + /*! Looks up the tag name for \a t in the map of metadata values for the current topic in \a inner. If a value @@ -5604,16 +5620,29 @@ bool DitaXmlGenerator::writeMetadataElement(const InnerNode* inner, */ QString DitaXmlGenerator::getMetadataElement(const InnerNode* inner, DitaXmlGenerator::DitaTag t) { - QString s; - QStringMap& metaTagMap = const_cast<QStringMap&>(inner->doc().metaTagMap()); - QStringMap::iterator i = metaTagMap.find(ditaTags[t]); - if (i != metaTagMap.end()) { - s = i.value(); - metaTagMap.erase(i); - } - else { + QString s = Generator::getMetadataElement(inner, ditaTags[t]); + if (s.isEmpty()) s = metadataDefault(t); - } + return s; +} + +/*! + Looks up the tag name for \a t in the map of metadata + values for the current topic in \a inner. If values + for the tag are found, they are returned in a string + list. + + \note If \a t is found in the metadata map, all the + pairs having the key \a t are erased. i.e. Once you + all this function for a particular \a t, you consume + \a t. + */ +QStringList DitaXmlGenerator::getMetadataElements(const InnerNode* inner, + DitaXmlGenerator::DitaTag t) +{ + QStringList s = Generator::getMetadataElements(inner,ditaTags[t]); + if (s.isEmpty()) + s.append(metadataDefault(t)); return s; } @@ -5671,7 +5700,7 @@ DitaXmlGenerator::writeProlog(const InnerNode* inner, CodeMarker* marker) if (!inner) return; writeStartTag(DT_prolog); - writeMetadataElement(inner,DT_author); + writeMetadataElements(inner,DT_author); writeMetadataElement(inner,DT_publisher); QString s = getMetadataElement(inner,DT_copyryear); QString t = getMetadataElement(inner,DT_copyrholder); @@ -5690,11 +5719,13 @@ DitaXmlGenerator::writeProlog(const InnerNode* inner, CodeMarker* marker) xmlWriter().writeAttribute("view",s); writeEndTag(); // </permissions> writeStartTag(DT_metadata); - s = getMetadataElement(inner,DT_audience); - if (!s.isEmpty()) { - writeStartTag(DT_audience); - xmlWriter().writeAttribute("type",s); - writeEndTag(); // </audience> + QStringList sl = getMetadataElements(inner,DT_audience); + if (!sl.isEmpty()) { + for (int i=0; i<sl.size(); ++i) { + writeStartTag(DT_audience); + xmlWriter().writeAttribute("type",sl[i]); + writeEndTag(); // </audience> + } } if (!writeMetadataElement(inner,DT_category,false)) { writeStartTag(DT_category); @@ -5755,7 +5786,7 @@ DitaXmlGenerator::writeProlog(const InnerNode* inner, CodeMarker* marker) } writeEndTag(); // </prodinfo> } - const QStringMap& metaTagMap = inner->doc().metaTagMap(); + const QStringMultiMap& metaTagMap = inner->doc().metaTagMap(); QMapIterator<QString, QString> i(metaTagMap); while (i.hasNext()) { i.next(); diff --git a/tools/qdoc3/ditaxmlgenerator.h b/tools/qdoc3/ditaxmlgenerator.h index c7400bb..ffca234 100644 --- a/tools/qdoc3/ditaxmlgenerator.h +++ b/tools/qdoc3/ditaxmlgenerator.h @@ -319,7 +319,9 @@ class DitaXmlGenerator : public PageGenerator bool writeMetadataElement(const InnerNode* inner, DitaXmlGenerator::DitaTag t, bool force=true); + bool writeMetadataElements(const InnerNode* inner, DitaXmlGenerator::DitaTag t); QString getMetadataElement(const InnerNode* inner, DitaXmlGenerator::DitaTag t); + QStringList getMetadataElements(const InnerNode* inner, DitaXmlGenerator::DitaTag t); private: enum SubTitleSize { SmallSubTitle, LargeSubTitle }; @@ -516,7 +518,7 @@ class DitaXmlGenerator : public PageGenerator static QString ditaTags[]; QStack<QXmlStreamWriter*> xmlWriterStack; QStack<DitaTag> tagStack; - QStringMap metadataDefaults; + QStringMultiMap metadataDefaults; }; #define DITAXMLGENERATOR_ADDRESS "address" diff --git a/tools/qdoc3/doc.cpp b/tools/qdoc3/doc.cpp index 945b765..2239f43 100644 --- a/tools/qdoc3/doc.cpp +++ b/tools/qdoc3/doc.cpp @@ -63,6 +63,7 @@ Q_GLOBAL_STATIC(QSet<QString>, null_Set_QString) Q_GLOBAL_STATIC(QStringList, null_QStringList) Q_GLOBAL_STATIC(QList<Text>, null_QList_Text) Q_GLOBAL_STATIC(QStringMap, null_QStringMap) +Q_GLOBAL_STATIC(QStringMultiMap, null_QStringMultiMap) struct Macro { @@ -228,7 +229,7 @@ class DocPrivateExtra QList<int> tableOfContentsLevels; QList<Atom*> keywords; QList<Atom*> targets; - QStringMap metaMap; + QStringMultiMap metaMap; DocPrivateExtra() : granularity(Doc::Part) { } @@ -360,7 +361,7 @@ class DocParser void checkExpiry(const QString& date); void insertBaseName(const QString &baseName); void insertTarget(const QString& target, bool keyword); - void include(const QString& fileName); + void include(const QString& fileName, const QString& identifier); void startFormat(const QString& format, int cmd); bool openCommand(int cmd); bool closeCommand(int endCmd); @@ -804,7 +805,11 @@ void DocParser::parse(const QString& source, append(Atom::ImageText, getRestOfLine()); break; case CMD_INCLUDE: - include(getArgument()); + { + QString fileName = getArgument(); + QString identifier = getRestOfLine(); + include(fileName, identifier); + } break; case CMD_INLINEIMAGE: enterPara(); @@ -1578,7 +1583,7 @@ void DocParser::insertTarget(const QString &target, bool keyword) } } -void DocParser::include(const QString& fileName) +void DocParser::include(const QString& fileName, const QString& identifier) { if (location().depth() > 16) location().fatal(tr("Too many nested '\\%1's") @@ -1592,12 +1597,12 @@ void DocParser::include(const QString& fileName) fileName, userFriendlyFilePath); if (filePath.isEmpty()) { - location().warning(tr("Cannot find leaf file '%1'").arg(fileName)); + location().warning(tr("Cannot find qdoc include file '%1'").arg(fileName)); } else { QFile inFile(filePath); if (!inFile.open(QFile::ReadOnly)) { - location().warning(tr("Cannot open leaf file '%1'") + location().warning(tr("Cannot open qdoc include file '%1'") .arg(userFriendlyFilePath)); } else { @@ -1607,9 +1612,56 @@ void DocParser::include(const QString& fileName) QString includedStuff = inStream.readAll(); inFile.close(); - in.insert(pos, includedStuff); - len = in.length(); - openedInputs.push(pos + includedStuff.length()); + if (identifier.isEmpty()) { + in.insert(pos, includedStuff); + len = in.length(); + openedInputs.push(pos + includedStuff.length()); + } + else { + QStringList lineBuffer = includedStuff.split(QLatin1Char('\n')); + int i = 0; + int startLine = -1; + while (i < lineBuffer.size()) { + if (lineBuffer[i].startsWith("//!")) { + if (lineBuffer[i].contains(identifier)) { + startLine = i+1; + break; + } + } + ++i; + } + if (startLine < 0) { + location().warning(tr("Cannot find '%1' in '%2'") + .arg(identifier) + .arg(userFriendlyFilePath)); + return; + + } + QString result; + i = startLine; + do { + if (lineBuffer[i].startsWith("//!")) { + if (i<lineBuffer.size()) { + if (lineBuffer[i].contains(identifier)) { + break; + } + } + } + else + result += lineBuffer[i] + "\n"; + ++i; + } while (i < lineBuffer.size()); + if (result.isEmpty()) { + location().warning(tr("Empty qdoc snippet '%1' in '%2'") + .arg(identifier) + .arg(userFriendlyFilePath)); + } + else { + in.insert(pos, result); + len = in.length(); + openedInputs.push(pos + result.length()); + } + } } } } @@ -2909,9 +2961,9 @@ const QList<Atom *> &Doc::targets() const return priv->extra->targets; } -const QStringMap &Doc::metaTagMap() const +const QStringMultiMap &Doc::metaTagMap() const { - return priv && priv->extra ? priv->extra->metaMap : *null_QStringMap(); + return priv && priv->extra ? priv->extra->metaMap : *null_QStringMultiMap(); } void Doc::initialize(const Config& config) diff --git a/tools/qdoc3/doc.h b/tools/qdoc3/doc.h index ea832b1..e043b3a 100644 --- a/tools/qdoc3/doc.h +++ b/tools/qdoc3/doc.h @@ -64,7 +64,6 @@ class FakeNode; typedef QMap<QString, QStringList> QCommandMap; typedef QMap<QString, QString> QStringMap; -typedef QStringMap::const_iterator QStringMapEntry; typedef QMultiMap<QString, QString> QStringMultiMap; class Doc @@ -118,7 +117,7 @@ class Doc const QList<int> &tableOfContentsLevels() const; const QList<Atom *> &keywords() const; const QList<Atom *> &targets() const; - const QStringMap &metaTagMap() const; + const QStringMultiMap &metaTagMap() const; static void initialize( const Config &config ); static void terminate(); diff --git a/tools/qdoc3/doc/qdoc-manual.qdoc b/tools/qdoc3/doc/qdoc-manual.qdoc index 49dd819..0e4055b 100644 --- a/tools/qdoc3/doc/qdoc-manual.qdoc +++ b/tools/qdoc3/doc/qdoc-manual.qdoc @@ -259,6 +259,7 @@ \o \l {12-0-qdoc-commands-miscellaneous.html#if-command} {\\if} \o \l {09-qdoc-commands-includingimages.html#image-command} {\\image} \o \l {12-0-qdoc-commands-miscellaneous.html#include-command} {\\include} + \o \l {12-0-qdoc-commands-miscellaneous.html#include-command} {\\input} \o \l {09-qdoc-commands-includingimages.html#inlineimage-command} {\\inlineimage} \o \l {08-qdoc-commands-creatinglinks.html#keyword-command} {\\keyword} \o \l {08-qdoc-commands-creatinglinks.html#l-command} {\\l} @@ -1437,9 +1438,6 @@ application up and running. \endquotation - \warning If you use the \l {Compatibility Issues} - {compat.qdocconf} file this command is called \\include. - See also \l {quotefromfile-command} {\\quotefromfile} and \l {code-command} {\\code}. @@ -3965,24 +3963,28 @@ \target include-command \section1 \\include - The \\include command expands to the contents of the - file specified by the command's argument. - - \warning This is preliminary functionality. For more information, - see the \l - {26-qdoc-commands-compatibility.html#include-versus-input} - {compatibility} section. - - The command takes a file name as an argument, and is useful when - some piece of the documentation is used repeatedly: Move the - repetetive text into a separate file, and use the \\include - command whenever you want to insert the separate documentation. - - The contents of such a file should follow QDoc syntax, excluding - the enclosing \c{/}\c{*!} ... \c{*}\c{/} marks. To ensure that - QDoc won't attempt to read the file as a stand-alone piece of - documentation, we recommend that you use the \c .qdocinc - extension. + The \\include command sends all or part of the file specified by + its first argument to the QDoc input stream to be processed as a + qdoc comment snippet. This command is often assigned the alias, + \e {input}, in the QDoc configuration file, e.g. \e {alias.include + = input}. + + The command is useful when some snippet of commands and text is to + be used in multiple places in the documentation. In that case, + move the snippet into a separate file and use the \\include + command wherever you want to insert the snippet into the + documentation. To prevent QDoc from reading the file as a + stand-alone page of documentation, we recommend that you use the + \c .qdocinc extension for these \e {include} files. + + The command can have either one or two arguments. The first + argument is always a file name. The contents of the file must be + QDoc input, i.e. a sequence of QDoc commands and text, but without + the enclosing qdoc comment \c{/}\c{*!} ... \c{*}\c{/} delimeters. + If you want to include the entire named file, don't use the second + argument. If you want to include only part of the file, see the + \l{2-argument-form}{two argument form} below. Here is an example + of the one argument form: \code / *! @@ -3995,7 +3997,9 @@ * / \endcode - QDoc renders this as: + Here are links to the \c .qdocinc files used above: + \l{signalandslots.qdocinc}, \l{objectmodel.qdocinc}, + \l{layoutmanagement.qdocinc}. QDoc renders this page as: \quotation \raw HTML @@ -4007,8 +4011,40 @@ \input examples/layoutmanagement.qdocinc \endquotation - Here is the actual \c .qdocinc files: \l signalandslots.qdocinc, - \l objectmodel.qdocinc, \l layoutmanagement.qdocinc + \target 2-argument-form} + \section2 \\include filename snippet-identifier + + It is kind of a pain to make a separate \c .qdocinc file for every + QDoc include snippet you want to use in multiple places in the + documentation, especially given that you probably have to put the + copyright/license notice in every one of these files. So if you + have lots of these include snippets, you can put them all in a + single file if you want, and surround each one with: + \code + //! [snippet-id1] + + QDoc commands and text... + + //! [snippet-id1] + + //! [snippet-id2] + + More QDoc commands and text... + + //! [snippet-id2] + \endcode + + Then you can use the two-argument form of the command: + + \code + \input examples/signalandslots.qdocinc snippet-id2 + \input examples/objectmodel.qdocinc another-snippet-id + \endcode + + It works as expected. The sequence of QDoc commands and text found + between the two tags with the same name as the second argument is + sent to the QDoc input stream. You can even nest these snippets, + although it's not clear why you would want to do that. \target meta-command \section1 \\meta diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index b4768db..f05c030 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -549,7 +549,10 @@ void Generator::generateAlsoList(const Node *node, CodeMarker *marker) if (!alsoList.isEmpty()) { Text text; - text << Atom::ParaLeft << "See also "; + text << Atom::ParaLeft + << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD) + << "See also " + << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD); for (int i = 0; i < alsoList.size(); ++i) text << alsoList.at(i) << separator(i, alsoList.size()); @@ -559,6 +562,28 @@ void Generator::generateAlsoList(const Node *node, CodeMarker *marker) } } +/*! + Generate a list of maintainers in the output + */ +void Generator::generateMaintainerList(const InnerNode* node, CodeMarker* marker) +{ + QStringList sl = getMetadataElements(node,"maintainer"); + + if (!sl.isEmpty()) { + Text text; + text << Atom::ParaLeft + << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD) + << "Maintained by: " + << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD); + + for (int i = 0; i < sl.size(); ++i) + text << sl.at(i) << separator(i, sl.size()); + + text << Atom::ParaRight; + generateText(text, node, marker); + } +} + void Generator::generateInherits(const ClassNode *classe, CodeMarker *marker) { QList<RelatedClass>::ConstIterator r; @@ -566,7 +591,10 @@ void Generator::generateInherits(const ClassNode *classe, CodeMarker *marker) if (!classe->baseClasses().isEmpty()) { Text text; - text << Atom::ParaLeft << "Inherits "; + text << Atom::ParaLeft + << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD) + << "Inherits: " + << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD); r = classe->baseClasses().begin(); index = 0; @@ -604,7 +632,10 @@ void Generator::generateInheritedBy(const ClassNode *classe, { if (!classe->derivedClasses().isEmpty()) { Text text; - text << Atom::ParaLeft << "Inherited by "; + text << Atom::ParaLeft + << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD) + << "Inherited by: " + << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD); appendSortedNames(text, classe, classe->derivedClasses(), marker); text << Atom::ParaRight; @@ -1275,4 +1306,44 @@ QString Generator::outputPrefix(const QString &nodeType) return outputPrefixes[nodeType]; } +/*! + Looks up the tag \a t in the map of metadata values for the + current topic in \a inner. If a value for the tag is found, + the value is returned. + + \note If \a t is found in the metadata map, it is erased. + i.e. Once you call this function for a particular \a t, + you consume \a t. + */ +QString Generator::getMetadataElement(const InnerNode* inner, const QString& t) +{ + QString s; + QStringMultiMap& metaTagMap = const_cast<QStringMultiMap&>(inner->doc().metaTagMap()); + QStringMultiMap::iterator i = metaTagMap.find(t); + if (i != metaTagMap.end()) { + s = i.value(); + metaTagMap.erase(i); + } + return s; +} + +/*! + Looks up the tag \a t in the map of metadata values for the + current topic in \a inner. If values for the tag are found, + they are returned in a string list. + + \note If \a t is found in the metadata map, all the pairs + having the key \a t are erased. i.e. Once you call this + function for a particular \a t, you consume \a t. + */ +QStringList Generator::getMetadataElements(const InnerNode* inner, const QString& t) +{ + QStringList s; + QStringMultiMap& metaTagMap = const_cast<QStringMultiMap&>(inner->doc().metaTagMap()); + s = metaTagMap.values(t); + if (!s.isEmpty()) + metaTagMap.remove(t); + return s; +} + QT_END_NAMESPACE diff --git a/tools/qdoc3/generator.h b/tools/qdoc3/generator.h index 4482313..8fd5370 100644 --- a/tools/qdoc3/generator.h +++ b/tools/qdoc3/generator.h @@ -106,6 +106,7 @@ class Generator #endif virtual void generateBody(const Node *node, CodeMarker *marker); virtual void generateAlsoList(const Node *node, CodeMarker *marker); + virtual void generateMaintainerList(const InnerNode* node, CodeMarker* marker); virtual void generateInherits(const ClassNode *classe, CodeMarker *marker); virtual void generateInheritedBy(const ClassNode *classe, @@ -141,7 +142,6 @@ class Generator void unknownAtom(const Atom *atom); QMap<QString, QString> &formattingLeftMap(); QMap<QString, QString> &formattingRightMap(); - QMap<QString, QStringList> editionModuleMap; QMap<QString, QStringList> editionGroupMap; @@ -150,6 +150,9 @@ class Generator static void supplementAlsoList(const Node *node, QList<Text> &alsoList); static QString outputPrefix(const QString &nodeType); + QString getMetadataElement(const InnerNode* inner, const QString& t); + QStringList getMetadataElements(const InnerNode* inner, const QString& t); + private: void generateReimplementedFrom(const FunctionNode *func, CodeMarker *marker); diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index d1d1561..114db26 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -1327,6 +1327,7 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner, generateBody(inner, marker); out() << "</div>\n"; // QTBUG-9504 generateAlsoList(inner, marker); + generateMaintainerList(inner, marker); generateExtractionMark(inner, EndMark); } @@ -1605,7 +1606,10 @@ void HtmlGenerator::generateBreadCrumbs(const QString &title, const ClassNode *cn = static_cast<const ClassNode *>(node); QString name = node->moduleName(); breadcrumbs << Atom(Atom::ListItemLeft) - << Atom(Atom::AutoLink, QLatin1String("Modules")) + << Atom(Atom::Link, QLatin1String("All Modules")) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << Atom(Atom::String, QLatin1String("Modules")) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) << Atom(Atom::ListItemRight); if (!name.isEmpty()) breadcrumbs << Atom(Atom::ListItemLeft) @@ -1620,7 +1624,10 @@ void HtmlGenerator::generateBreadCrumbs(const QString &title, const FakeNode* fn = static_cast<const FakeNode*>(node); if (node->subType() == Node::Module) { breadcrumbs << Atom(Atom::ListItemLeft) - << Atom(Atom::AutoLink, QLatin1String("Modules")) + << Atom(Atom::Link, QLatin1String("All Modules")) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << Atom(Atom::String, QLatin1String("Modules")) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) << Atom(Atom::ListItemRight); QString name = node->name(); if (!name.isEmpty()) @@ -1630,9 +1637,7 @@ void HtmlGenerator::generateBreadCrumbs(const QString &title, } else if (node->subType() == Node::Group) { if (fn->name() == QString("modules")) - breadcrumbs << Atom(Atom::ListItemLeft) - << Atom(Atom::AutoLink, QLatin1String("Modules")) - << Atom(Atom::ListItemRight); + breadcrumbs << Atom(Atom::String, QLatin1String("Modules")); else breadcrumbs << Atom(Atom::ListItemLeft) << Atom(Atom::String, protectEnc(title)) @@ -1641,7 +1646,10 @@ void HtmlGenerator::generateBreadCrumbs(const QString &title, else if (node->subType() == Node::Page) { if (fn->name() == QString("qdeclarativeexamples.html")) { breadcrumbs << Atom(Atom::ListItemLeft) - << Atom(Atom::AutoLink, QLatin1String("Examples")) + << Atom(Atom::Link, QLatin1String("Qt Examples")) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << Atom(Atom::String, QLatin1String("Examples")) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) << Atom(Atom::ListItemRight); breadcrumbs << Atom(Atom::ListItemLeft) << Atom(Atom::AutoLink, QLatin1String("QML Examples & Demos")) @@ -1649,16 +1657,17 @@ void HtmlGenerator::generateBreadCrumbs(const QString &title, } else if (fn->name().startsWith("examples-")) { breadcrumbs << Atom(Atom::ListItemLeft) - << Atom(Atom::AutoLink, QLatin1String("Examples")) + << Atom(Atom::Link, QLatin1String("Qt Examples")) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << Atom(Atom::String, QLatin1String("Examples")) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) << Atom(Atom::ListItemRight); breadcrumbs << Atom(Atom::ListItemLeft) << Atom(Atom::String, protectEnc(title)) << Atom(Atom::ListItemRight); } else if (fn->name() == QString("namespaces.html")) - breadcrumbs << Atom(Atom::ListItemLeft) - << Atom(Atom::AutoLink, QLatin1String("Namespaces")) - << Atom(Atom::ListItemRight); + breadcrumbs << Atom(Atom::String, QLatin1String("Namespaces")); else breadcrumbs << Atom(Atom::ListItemLeft) << Atom(Atom::String, protectEnc(title)) @@ -1674,7 +1683,10 @@ void HtmlGenerator::generateBreadCrumbs(const QString &title, } else if (node->subType() == Node::Example) { breadcrumbs << Atom(Atom::ListItemLeft) - << Atom(Atom::AutoLink, QLatin1String("Examples")) + << Atom(Atom::Link, QLatin1String("Qt Examples")) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << Atom(Atom::String, QLatin1String("Examples")) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) << Atom(Atom::ListItemRight); QStringList sl = fn->name().split('/'); if (sl.contains("declarative")) @@ -1692,7 +1704,10 @@ void HtmlGenerator::generateBreadCrumbs(const QString &title, } else if (node->type() == Node::Namespace) { breadcrumbs << Atom(Atom::ListItemLeft) - << Atom(Atom::AutoLink, QLatin1String("Namespaces")) + << Atom(Atom::Link, QLatin1String("All Namespaces")) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << Atom(Atom::String, QLatin1String("Namespaces")) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) << Atom(Atom::ListItemRight); breadcrumbs << Atom(Atom::ListItemLeft) << Atom(Atom::String, protectEnc(title)) diff --git a/tools/qdoc3/jscodemarker.cpp b/tools/qdoc3/jscodemarker.cpp index 5a513f7..cbf040f 100644 --- a/tools/qdoc3/jscodemarker.cpp +++ b/tools/qdoc3/jscodemarker.cpp @@ -43,11 +43,11 @@ jscodemarker.cpp */ -#include "private/qdeclarativejsast_p.h" -#include "private/qdeclarativejsengine_p.h" -#include "private/qdeclarativejslexer_p.h" -#include "private/qdeclarativejsnodepool_p.h" -#include "private/qdeclarativejsparser_p.h" +#include "declarativeparser/qdeclarativejsast_p.h" +#include "declarativeparser/qdeclarativejsengine_p.h" +#include "declarativeparser/qdeclarativejslexer_p.h" +#include "declarativeparser/qdeclarativejsnodepool_p.h" +#include "declarativeparser/qdeclarativejsparser_p.h" #include "atom.h" #include "node.h" diff --git a/tools/qdoc3/qmlcodemarker.cpp b/tools/qdoc3/qmlcodemarker.cpp index a7dc5a0..ccca7b5 100644 --- a/tools/qdoc3/qmlcodemarker.cpp +++ b/tools/qdoc3/qmlcodemarker.cpp @@ -43,12 +43,12 @@ qmlcodemarker.cpp */ -#include "private/qdeclarativejsast_p.h" -#include "private/qdeclarativejsastfwd_p.h" -#include "private/qdeclarativejsengine_p.h" -#include "private/qdeclarativejslexer_p.h" -#include "private/qdeclarativejsnodepool_p.h" -#include "private/qdeclarativejsparser_p.h" +#include "declarativeparser/qdeclarativejsast_p.h" +#include "declarativeparser/qdeclarativejsastfwd_p.h" +#include "declarativeparser/qdeclarativejsengine_p.h" +#include "declarativeparser/qdeclarativejslexer_p.h" +#include "declarativeparser/qdeclarativejsnodepool_p.h" +#include "declarativeparser/qdeclarativejsparser_p.h" #include "atom.h" #include "node.h" diff --git a/tools/qdoc3/qmlcodemarker.h b/tools/qdoc3/qmlcodemarker.h index d693456..aab3455 100644 --- a/tools/qdoc3/qmlcodemarker.h +++ b/tools/qdoc3/qmlcodemarker.h @@ -46,7 +46,7 @@ #ifndef QMLCODEMARKER_H #define QMLCODEMARKER_H -#include "private/qdeclarativejsastfwd_p.h" +#include "declarativeparser/qdeclarativejsastfwd_p.h" #include "cppcodemarker.h" QT_BEGIN_NAMESPACE diff --git a/tools/qdoc3/qmlcodeparser.cpp b/tools/qdoc3/qmlcodeparser.cpp index 93a3ff9..45ca96f 100644 --- a/tools/qdoc3/qmlcodeparser.cpp +++ b/tools/qdoc3/qmlcodeparser.cpp @@ -43,9 +43,9 @@ qmlcodeparser.cpp */ -#include "private/qdeclarativejsast_p.h" -#include "private/qdeclarativejsastvisitor_p.h" -#include "private/qdeclarativejsnodepool_p.h" +#include "declarativeparser/qdeclarativejsast_p.h" +#include "declarativeparser/qdeclarativejsastvisitor_p.h" +#include "declarativeparser/qdeclarativejsnodepool_p.h" #include "qmlcodeparser.h" #include "node.h" diff --git a/tools/qdoc3/qmlcodeparser.h b/tools/qdoc3/qmlcodeparser.h index e5cc0dd..667cf5e 100644 --- a/tools/qdoc3/qmlcodeparser.h +++ b/tools/qdoc3/qmlcodeparser.h @@ -47,9 +47,9 @@ #define QMLCODEPARSER_H #include <QSet> -#include "private/qdeclarativejsengine_p.h" -#include "private/qdeclarativejslexer_p.h" -#include "private/qdeclarativejsparser_p.h" +#include "declarativeparser/qdeclarativejsengine_p.h" +#include "declarativeparser/qdeclarativejslexer_p.h" +#include "declarativeparser/qdeclarativejsparser_p.h" #include "codeparser.h" #include "location.h" diff --git a/tools/qdoc3/qmlmarkupvisitor.cpp b/tools/qdoc3/qmlmarkupvisitor.cpp index 7acac48..d88694b 100644 --- a/tools/qdoc3/qmlmarkupvisitor.cpp +++ b/tools/qdoc3/qmlmarkupvisitor.cpp @@ -41,9 +41,9 @@ #include <QStringList> #include <QtGlobal> -#include "private/qdeclarativejsast_p.h" -#include "private/qdeclarativejsastfwd_p.h" -#include "private/qdeclarativejsengine_p.h" +#include "declarativeparser/qdeclarativejsast_p.h" +#include "declarativeparser/qdeclarativejsastfwd_p.h" +#include "declarativeparser/qdeclarativejsengine_p.h" #include "qmlmarkupvisitor.h" diff --git a/tools/qdoc3/qmlmarkupvisitor.h b/tools/qdoc3/qmlmarkupvisitor.h index 709a858..97e392f 100644 --- a/tools/qdoc3/qmlmarkupvisitor.h +++ b/tools/qdoc3/qmlmarkupvisitor.h @@ -43,7 +43,7 @@ #define QMLVISITOR_H #include <QString> -#include "private/qdeclarativejsastvisitor_p.h" +#include "declarativeparser/qdeclarativejsastvisitor_p.h" #include "node.h" #include "tree.h" diff --git a/tools/qdoc3/qmlvisitor.cpp b/tools/qdoc3/qmlvisitor.cpp index 9295624..fc65093 100644 --- a/tools/qdoc3/qmlvisitor.cpp +++ b/tools/qdoc3/qmlvisitor.cpp @@ -42,9 +42,9 @@ #include <QFileInfo> #include <QStringList> #include <QtGlobal> -#include "private/qdeclarativejsast_p.h" -#include "private/qdeclarativejsastfwd_p.h" -#include "private/qdeclarativejsengine_p.h" +#include "declarativeparser/qdeclarativejsast_p.h" +#include "declarativeparser/qdeclarativejsastfwd_p.h" +#include "declarativeparser/qdeclarativejsengine_p.h" #include "node.h" #include "qmlvisitor.h" diff --git a/tools/qdoc3/qmlvisitor.h b/tools/qdoc3/qmlvisitor.h index 9da2c72..4771f9e 100644 --- a/tools/qdoc3/qmlvisitor.h +++ b/tools/qdoc3/qmlvisitor.h @@ -43,7 +43,7 @@ #define QMLVISITOR_H #include <QString> -#include "private/qdeclarativejsastvisitor_p.h" +#include "declarativeparser/qdeclarativejsastvisitor_p.h" #include "node.h" #include "tree.h" diff --git a/tools/qdoc3/quoter.cpp b/tools/qdoc3/quoter.cpp index dadf67c..d9210e3 100644 --- a/tools/qdoc3/quoter.cpp +++ b/tools/qdoc3/quoter.cpp @@ -41,6 +41,7 @@ #include <qfileinfo.h> #include <qregexp.h> +#include <qdebug.h> #include "quoter.h" @@ -65,7 +66,7 @@ static void replaceMultipleNewlines(QString &s) } // This is equivalent to line.split( QRegExp("\n(?!\n|$)") ) but much faster -static QStringList splitLines(const QString &line) +QStringList Quoter::splitLines(const QString &line) { QStringList result; int i = line.size(); diff --git a/tools/qdoc3/quoter.h b/tools/qdoc3/quoter.h index 6a59ab4..ee515b2 100644 --- a/tools/qdoc3/quoter.h +++ b/tools/qdoc3/quoter.h @@ -69,6 +69,8 @@ public: const QString& pattern ); QString quoteSnippet(const Location &docLocation, const QString &identifier); + static QStringList splitLines(const QString &line); + private: QString getLine(int unindent = 0); void failedAtEnd( const Location& docLocation, const QString& command ); diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index 6ca6bfb..b2c7f4f 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -51,6 +51,7 @@ #include <QMessageBox> #include <QAtomicInt> #include "qdeclarativetester.h" +#include <private/qdeclarativedebughelper_p.h> QT_USE_NAMESPACE @@ -538,6 +539,8 @@ int main(int argc, char ** argv) QApplication::setGraphicsSystem("raster"); #endif + QDeclarativeDebugHelper::enableDebugging(); + Application app(argc, argv); app.setApplicationName("QtQmlViewer"); app.setOrganizationName("Nokia"); |