diff options
417 files changed, 9030 insertions, 3271 deletions
@@ -1,14 +1,14 @@ INSTALLING Qt Source Package Version %VERSION%. For full installation instructions for each supported platform, please -see http://qt.nokia.com/doc/%VERSION%/installation.html, the file +see http://qt.nokia.com/doc/%SHORTVERSION%/installation.html, the file doc/html/installation.html in this package, or follow one of the following links: -Embedded Linux: http://qt.nokia.com/doc/%VERSION%/qt-embedded-install.html -Mac OS X: http://qt.nokia.com/doc/%VERSION%/install-mac.html -Windows: http://qt.nokia.com/doc/%VERSION%/install-win.html -Windows CE: http://qt.nokia.com/doc/%VERSION%/install-wince.html -X11 Platforms: http://qt.nokia.com/doc/%VERSION%/install-x11.html -Symbian Platform: http://qt.nokia.com/doc/%VERSION%/install-symbian.html +Embedded Linux: http://qt.nokia.com/doc/%SHORTVERSION%/qt-embedded-install.html +Mac OS X: http://qt.nokia.com/doc/%SHORTVERSION%/install-mac.html +Windows: http://qt.nokia.com/doc/%SHORTVERSION%/install-win.html +Windows CE: http://qt.nokia.com/doc/%SHORTVERSION%/install-wince.html +X11 Platforms: http://qt.nokia.com/doc/%SHORTVERSION%/install-x11.html +Symbian Platform: http://qt.nokia.com/doc/%SHORTVERSION%/install-symbian.html diff --git a/config.tests/mac/crc/main.cpp b/config.tests/mac/crc/main.cpp index 894f88b..700a4cd 100644 --- a/config.tests/mac/crc/main.cpp +++ b/config.tests/mac/crc/main.cpp @@ -71,7 +71,7 @@ private: for(int iCodes = 0; iCodes <= 0xFF; iCodes++) { ulTable[iCodes] = Reflect(iCodes, 8) << 24; for(int iPos = 0; iPos < 8; iPos++) { - ulTable[iCodes] = (ulTable[iCodes] << 1) + ulTable[iCodes] = ((ulTable[iCodes] << 1) & 0xffffffff) ^ ((ulTable[iCodes] & (1 << 31)) ? ulPolynomial : 0); } @@ -84,7 +84,7 @@ private: // Swap bit 0 for bit 7, bit 1 For bit 6, etc.... for(int iPos = 1; iPos < (cChar + 1); iPos++) { if(ulReflect & 1) { - ulValue |= (1 << (cChar - iPos)); + ulValue |= (1ul << (cChar - iPos)); } ulReflect >>= 1; } @@ -131,7 +131,7 @@ compilerSupportsFlag() cat >conftest.cpp <<EOF int main() { return 0; } EOF - "$TEST_COMPILER" "$@" -o /dev/null conftest.cpp + "$TEST_COMPILER" "$@" -o conftest.o conftest.cpp ret=$? rm -f conftest.cpp conftest.o return $ret @@ -3663,7 +3663,7 @@ Qt/X11 only: -no-opengl ......... Do not support OpenGL. + -opengl <api> ...... Enable OpenGL support. With no parameter, this will auto-detect the "best" - OpenGL API to use. If desktop OpenGL is avaliable, it + OpenGL API to use. If desktop OpenGL is available, it will be used. Use desktop, es1, es1cl or es2 for <api> to force the use of the Desktop (OpenGL 1.x or 2.x), OpenGL ES 1.x Common profile, 1.x Common Lite profile diff --git a/demos/qmediaplayer/mediaplayer.cpp b/demos/qmediaplayer/mediaplayer.cpp index 4021352..8f6848f 100644 --- a/demos/qmediaplayer/mediaplayer.cpp +++ b/demos/qmediaplayer/mediaplayer.cpp @@ -47,109 +47,114 @@ #include "ui_settings.h" -class MediaVideoWidget : public Phonon::VideoWidget +MediaVideoWidget::MediaVideoWidget(MediaPlayer *player, QWidget *parent) : + Phonon::VideoWidget(parent), m_player(player), m_action(this) +{ + m_action.setCheckable(true); + m_action.setChecked(false); + m_action.setShortcut(QKeySequence( Qt::AltModifier + Qt::Key_Return)); + m_action.setShortcutContext(Qt::WindowShortcut); + connect(&m_action, SIGNAL(toggled(bool)), SLOT(setFullScreen(bool))); + addAction(&m_action); + setAcceptDrops(true); +} + +void MediaVideoWidget::setFullScreen(bool enabled) { -public: - MediaVideoWidget(MediaPlayer *player, QWidget *parent = 0) : - Phonon::VideoWidget(parent), m_player(player), m_action(this) - { - m_action.setCheckable(true); - m_action.setChecked(false); - m_action.setShortcut(QKeySequence( Qt::AltModifier + Qt::Key_Return)); - m_action.setShortcutContext(Qt::WindowShortcut); - connect(&m_action, SIGNAL(toggled(bool)), SLOT(setFullScreen(bool))); - addAction(&m_action); - setAcceptDrops(true); - } + Phonon::VideoWidget::setFullScreen(enabled); + emit fullScreenChanged(enabled); +} -protected: - void mouseDoubleClickEvent(QMouseEvent *e) - { - Phonon::VideoWidget::mouseDoubleClickEvent(e); - setFullScreen(!isFullScreen()); - } +void MediaVideoWidget::mouseDoubleClickEvent(QMouseEvent *e) +{ + Phonon::VideoWidget::mouseDoubleClickEvent(e); + setFullScreen(!isFullScreen()); +} - void keyPressEvent(QKeyEvent *e) - { - if (e->key() == Qt::Key_Space && !e->modifiers()) { +void MediaVideoWidget::keyPressEvent(QKeyEvent *e) +{ + if(!e->modifiers()) { + // On non-QWERTY Symbian key-based devices, there is no space key. + // The zero key typically is marked with a space character. + if (e->key() == Qt::Key_Space || e->key() == Qt::Key_0) { m_player->playPause(); e->accept(); return; - } else if (e->key() == Qt::Key_Escape && !e->modifiers()) { + } + + // On Symbian devices, there is no key which maps to Qt::Key_Escape + // On devices which lack a backspace key (i.e. non-QWERTY devices), + // the 'C' key maps to Qt::Key_Backspace + else if (e->key() == Qt::Key_Escape || e->key() == Qt::Key_Backspace) { setFullScreen(false); e->accept(); return; } - Phonon::VideoWidget::keyPressEvent(e); } + Phonon::VideoWidget::keyPressEvent(e); +} - bool event(QEvent *e) +bool MediaVideoWidget::event(QEvent *e) +{ + switch(e->type()) { - switch(e->type()) - { - case QEvent::Close: - //we just ignore the cose events on the video widget - //this prevents ALT+F4 from having an effect in fullscreen mode - e->ignore(); - return true; - case QEvent::MouseMove: + case QEvent::Close: + //we just ignore the cose events on the video widget + //this prevents ALT+F4 from having an effect in fullscreen mode + e->ignore(); + return true; + case QEvent::MouseMove: #ifndef QT_NO_CURSOR - unsetCursor(); + unsetCursor(); #endif - //fall through - case QEvent::WindowStateChange: - { - //we just update the state of the checkbox, in case it wasn't already - m_action.setChecked(windowState() & Qt::WindowFullScreen); - const Qt::WindowFlags flags = m_player->windowFlags(); - if (windowState() & Qt::WindowFullScreen) { - m_timer.start(1000, this); - } else { - m_timer.stop(); + //fall through + case QEvent::WindowStateChange: + { + //we just update the state of the checkbox, in case it wasn't already + m_action.setChecked(windowState() & Qt::WindowFullScreen); + const Qt::WindowFlags flags = m_player->windowFlags(); + if (windowState() & Qt::WindowFullScreen) { + m_timer.start(1000, this); + } else { + m_timer.stop(); #ifndef QT_NO_CURSOR - unsetCursor(); + unsetCursor(); #endif - } } - break; - default: - break; } - - return Phonon::VideoWidget::event(e); + break; + default: + break; } - void timerEvent(QTimerEvent *e) - { - if (e->timerId() == m_timer.timerId()) { - //let's store the cursor shape + return Phonon::VideoWidget::event(e); +} + +void MediaVideoWidget::timerEvent(QTimerEvent *e) +{ + if (e->timerId() == m_timer.timerId()) { + //let's store the cursor shape #ifndef QT_NO_CURSOR - setCursor(Qt::BlankCursor); + setCursor(Qt::BlankCursor); #endif - } - Phonon::VideoWidget::timerEvent(e); - } - - void dropEvent(QDropEvent *e) - { - m_player->handleDrop(e); } + Phonon::VideoWidget::timerEvent(e); +} - void dragEnterEvent(QDragEnterEvent *e) { - if (e->mimeData()->hasUrls()) - e->acceptProposedAction(); - } +void MediaVideoWidget::dropEvent(QDropEvent *e) +{ + m_player->handleDrop(e); +} -private: - MediaPlayer *m_player; - QBasicTimer m_timer; - QAction m_action; -}; +void MediaVideoWidget::dragEnterEvent(QDragEnterEvent *e) { + if (e->mimeData()->hasUrls()) + e->acceptProposedAction(); +} MediaPlayer::MediaPlayer(const QString &filePath, const bool hasSmallScreen) : - playButton(0), nextEffect(0), settingsDialog(0), ui(0), + playButton(0), nextEffect(0), settingsDialog(0), ui(0), m_AudioOutput(Phonon::VideoCategory), m_videoWidget(new MediaVideoWidget(this)), m_hasSmallScreen(hasSmallScreen) @@ -266,6 +271,9 @@ MediaPlayer::MediaPlayer(const QString &filePath, fileMenu = new QMenu(this); QAction *openFileAction = fileMenu->addAction(tr("Open &File...")); QAction *openUrlAction = fileMenu->addAction(tr("Open &Location...")); + QAction *const openLinkAction = fileMenu->addAction(tr("Open &RAM File...")); + + connect(openLinkAction, SIGNAL(triggered(bool)), this, SLOT(openRamFile())); fileMenu->addSeparator(); QMenu *aspectMenu = fileMenu->addMenu(tr("&Aspect ratio")); @@ -297,24 +305,32 @@ MediaPlayer::MediaPlayer(const QString &filePath, QAction *scaleActionCrop = scaleMenu->addAction(tr("Scale and crop")); scaleActionCrop->setCheckable(true); scaleGroup->addAction(scaleActionCrop); - - fileMenu->addSeparator(); + + m_fullScreenAction = fileMenu->addAction(tr("Full screen video")); + m_fullScreenAction->setCheckable(true); + m_fullScreenAction->setEnabled(false); // enabled by hasVideoChanged + bool b = connect(m_fullScreenAction, SIGNAL(toggled(bool)), m_videoWidget, SLOT(setFullScreen(bool))); + Q_ASSERT(b); + b = connect(m_videoWidget, SIGNAL(fullScreenChanged(bool)), m_fullScreenAction, SLOT(setChecked(bool))); + Q_ASSERT(b); + + fileMenu->addSeparator(); QAction *settingsAction = fileMenu->addAction(tr("&Settings...")); - + // Setup signal connections: connect(rewindButton, SIGNAL(clicked()), this, SLOT(rewind())); //connect(openButton, SIGNAL(clicked()), this, SLOT(openFile())); openButton->setMenu(fileMenu); - + connect(playButton, SIGNAL(clicked()), this, SLOT(playPause())); connect(forwardButton, SIGNAL(clicked()), this, SLOT(forward())); //connect(openButton, SIGNAL(clicked()), this, SLOT(openFile())); connect(settingsAction, SIGNAL(triggered(bool)), this, SLOT(showSettingsDialog())); connect(openUrlAction, SIGNAL(triggered(bool)), this, SLOT(openUrl())); connect(openFileAction, SIGNAL(triggered(bool)), this, SLOT(openFile())); - - connect(m_videoWidget, SIGNAL(customContextMenuRequested(QPoint)), SLOT(showContextMenu(QPoint))); - connect(this, SIGNAL(customContextMenuRequested(QPoint)), SLOT(showContextMenu(QPoint))); + + connect(m_videoWidget, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(showContextMenu(const QPoint &))); + connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(showContextMenu(const QPoint &))); connect(&m_MediaObject, SIGNAL(metaDataChanged()), this, SLOT(updateInfo())); connect(&m_MediaObject, SIGNAL(totalTimeChanged(qint64)), this, SLOT(updateTime())); connect(&m_MediaObject, SIGNAL(tick(qint64)), this, SLOT(updateTime())); @@ -363,12 +379,12 @@ void MediaPlayer::stateChanged(Phonon::State newstate, Phonon::State oldstate) } QMessageBox::warning(this, "Phonon Mediaplayer", m_MediaObject.errorString(), QMessageBox::Close); break; - case Phonon::PausedState: - case Phonon::StoppedState: - playButton->setIcon(playIcon); + case Phonon::StoppedState: m_videoWidget->setFullScreen(false); - + // Fall through + case Phonon::PausedState: + playButton->setIcon(playIcon); if (m_MediaObject.currentSource().type() != Phonon::MediaSource::Invalid){ playButton->setEnabled(true); rewindButton->setEnabled(true); @@ -471,7 +487,7 @@ void MediaPlayer::effectChanged() void MediaPlayer::showSettingsDialog() { - playPauseForDialog(); + const bool hasPausedForDialog = playPauseForDialog(); if (!settingsDialog) initSettingsDialog(); @@ -519,7 +535,8 @@ void MediaPlayer::showSettingsDialog() ui->audioEffectsCombo->setCurrentIndex(currentEffect); } - playPauseForDialog(); + if (hasPausedForDialog) + m_MediaObject.play(); } void MediaPlayer::initVideoWindow() @@ -656,24 +673,29 @@ void MediaPlayer::setFile(const QString &fileName) m_MediaObject.play(); } -void MediaPlayer::playPauseForDialog() +bool MediaPlayer::playPauseForDialog() { - // If we're running on a small screen, we want to pause the video - // when popping up dialogs. - if (m_hasSmallScreen && - (Phonon::PlayingState == m_MediaObject.state() || - Phonon::PausedState == m_MediaObject.state())) - playPause(); + // If we're running on a small screen, we want to pause the video when + // popping up dialogs. We neither want to tamper with the state if the + // user has paused. + if (m_hasSmallScreen && m_MediaObject.hasVideo()) { + if (Phonon::PlayingState == m_MediaObject.state()) { + m_MediaObject.pause(); + return true; + } + } + return false; } void MediaPlayer::openFile() { - playPauseForDialog(); + const bool hasPausedForDialog = playPauseForDialog(); QStringList fileNames = QFileDialog::getOpenFileNames(this, QString(), QDesktopServices::storageLocation(QDesktopServices::MusicLocation)); - playPauseForDialog(); + if (hasPausedForDialog) + m_MediaObject.play(); m_MediaObject.clearQueue(); if (fileNames.size() > 0) { @@ -835,6 +857,51 @@ void MediaPlayer::openUrl() } } +/*! + \since 4.6 + */ +void MediaPlayer::openRamFile() +{ + QSettings settings; + settings.beginGroup(QLatin1String("BrowserMainWindow")); + + const QStringList fileNameList(QFileDialog::getOpenFileNames(this, + QString(), + settings.value("openRamFile").toString(), + QLatin1String("RAM files (*.ram)"))); + + if (fileNameList.isEmpty()) + return; + + QFile linkFile; + QList<QUrl> list; + QByteArray sourceURL; + for (int i = 0; i < fileNameList.count(); i++ ) { + linkFile.setFileName(fileNameList[i]); + if (linkFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + while (!linkFile.atEnd()) { + sourceURL = linkFile.readLine().trimmed(); + if (!sourceURL.isEmpty()) { + const QUrl url(QUrl::fromEncoded(sourceURL)); + if (url.isValid()) + list.append(url); + } + } + linkFile.close(); + } + } + + if (!list.isEmpty()) { + m_MediaObject.setCurrentSource(Phonon::MediaSource(list[0])); + m_MediaObject.play(); + for (int i = 1; i < list.count(); i++) + m_MediaObject.enqueue(Phonon::MediaSource(list[i])); + } + + forwardButton->setEnabled(!m_MediaObject.queue().isEmpty()); + settings.setValue("openRamFile", fileNameList[0]); +} + void MediaPlayer::finished() { } @@ -868,4 +935,5 @@ void MediaPlayer::hasVideoChanged(bool bHasVideo) { info->setVisible(!bHasVideo); m_videoWindow.setVisible(bHasVideo); + m_fullScreenAction->setEnabled(bHasVideo); } diff --git a/demos/qmediaplayer/mediaplayer.h b/demos/qmediaplayer/mediaplayer.h index a1c3d92..14ed4ac 100644 --- a/demos/qmediaplayer/mediaplayer.h +++ b/demos/qmediaplayer/mediaplayer.h @@ -47,6 +47,8 @@ #include <QtCore/QTimerEvent> #include <QtGui/QShowEvent> #include <QtGui/QIcon> +#include <QtCore/QBasicTimer> +#include <QtGui/QAction> #include <Phonon/AudioOutput> #include <Phonon/BackendCapabilities> @@ -67,6 +69,36 @@ class QMenu; class Ui_settings; QT_END_NAMESPACE +class MediaPlayer; + +class MediaVideoWidget : public Phonon::VideoWidget +{ + Q_OBJECT + +public: + MediaVideoWidget(MediaPlayer *player, QWidget *parent = 0); + +public slots: + // Over-riding non-virtual Phonon::VideoWidget slot + void setFullScreen(bool); + +signals: + void fullScreenChanged(bool); + +protected: + void mouseDoubleClickEvent(QMouseEvent *e); + void keyPressEvent(QKeyEvent *e); + bool event(QEvent *e); + void timerEvent(QTimerEvent *e); + void dropEvent(QDropEvent *e); + void dragEnterEvent(QDragEnterEvent *e); + +private: + MediaPlayer *m_player; + QBasicTimer m_timer; + QAction m_action; +}; + class MediaPlayer : public QWidget { @@ -74,7 +106,7 @@ class MediaPlayer : public: MediaPlayer(const QString &, const bool hasSmallScreen); - + void dragEnterEvent(QDragEnterEvent *e); void dragMoveEvent(QDragMoveEvent *e); void dropEvent(QDropEvent *e); @@ -82,7 +114,7 @@ public: void setFile(const QString &text); void initVideoWindow(); void initSettingsDialog(); - + public slots: void openFile(); void rewind(); @@ -104,14 +136,15 @@ private slots: void stateChanged(Phonon::State newstate, Phonon::State oldstate); void effectChanged(); void showSettingsDialog(); - void showContextMenu(const QPoint &); + void showContextMenu(const QPoint& point); void bufferStatus(int percent); void openUrl(); + void openRamFile(); void configureEffect(); void hasVideoChanged(bool); private: - void playPauseForDialog(); + bool playPauseForDialog(); QIcon playIcon; QIcon pauseIcon; @@ -130,11 +163,12 @@ private: Phonon::Effect *nextEffect; QDialog *settingsDialog; Ui_settings *ui; - + QAction *m_fullScreenAction; + QWidget m_videoWindow; Phonon::MediaObject m_MediaObject; Phonon::AudioOutput m_AudioOutput; - Phonon::VideoWidget *m_videoWidget; + MediaVideoWidget *m_videoWidget; Phonon::Path m_audioOutputPath; const bool m_hasSmallScreen; }; diff --git a/demos/qmediaplayer/qmediaplayer.pro b/demos/qmediaplayer/qmediaplayer.pro index 2f15c28..9407a81 100644 --- a/demos/qmediaplayer/qmediaplayer.pro +++ b/demos/qmediaplayer/qmediaplayer.pro @@ -32,4 +32,6 @@ symbian { DEPLOYMENT += addFiles include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) + + TARGET.CAPABILITY="NetworkServices" } diff --git a/demos/qmediaplayer/settings.ui b/demos/qmediaplayer/settings.ui index d2cedd4..03bd70e 100644 --- a/demos/qmediaplayer/settings.ui +++ b/demos/qmediaplayer/settings.ui @@ -1,283 +1,314 @@ -<ui version="4.0" > +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> <class>settings</class> - <widget class="QDialog" name="settings" > - <property name="geometry" > + <widget class="QDialog" name="settings"> + <property name="geometry"> <rect> <x>0</x> <y>0</y> - <width>360</width> - <height>362</height> + <width>175</width> + <height>397</height> </rect> </property> - <property name="windowTitle" > + <property name="windowTitle"> <string>Settings</string> </property> - <layout class="QVBoxLayout" name="verticalLayout_2" > + <layout class="QVBoxLayout" name="verticalLayout_2"> <item> - <widget class="QGroupBox" name="groupBox" > - <property name="title" > + <widget class="QGroupBox" name="groupBox"> + <property name="title"> <string>Video options:</string> </property> - <property name="flat" > + <property name="flat"> <bool>true</bool> </property> - <layout class="QGridLayout" name="gridLayout" > - <item row="0" column="0" > - <widget class="QLabel" name="label_9" > - <property name="text" > + <layout class="QGridLayout" name="gridLayout"> + <item row="5" column="2"> + <widget class="QComboBox" name="scalemodeCombo"> + <property name="sizeAdjustPolicy"> + <enum>QComboBox::AdjustToContentsOnFirstShow</enum> + </property> + <item> + <property name="text"> + <string>Fit in view</string> + </property> + </item> + <item> + <property name="text"> + <string>Scale and crop</string> + </property> + </item> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_9"> + <property name="text"> <string>Contrast:</string> </property> </widget> </item> - <item row="0" column="1" colspan="2" > - <widget class="QSlider" name="contrastSlider" > - <property name="minimum" > + <item row="0" column="1" colspan="2"> + <widget class="QSlider" name="contrastSlider"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="minimum"> <number>-8</number> </property> - <property name="maximum" > + <property name="maximum"> <number>8</number> </property> - <property name="orientation" > + <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="tickPosition" > + <property name="tickPosition"> <enum>QSlider::TicksBelow</enum> </property> - <property name="tickInterval" > + <property name="tickInterval"> <number>4</number> </property> </widget> </item> - <item row="1" column="0" > - <widget class="QLabel" name="label_8" > - <property name="text" > + <item row="1" column="0"> + <widget class="QLabel" name="label_8"> + <property name="text"> <string>Brightness:</string> </property> </widget> </item> - <item row="1" column="1" colspan="2" > - <widget class="QSlider" name="brightnessSlider" > - <property name="minimum" > + <item row="1" column="1" colspan="2"> + <widget class="QSlider" name="brightnessSlider"> + <property name="minimum"> <number>-8</number> </property> - <property name="maximum" > + <property name="maximum"> <number>8</number> </property> - <property name="orientation" > + <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="tickPosition" > + <property name="tickPosition"> <enum>QSlider::TicksBelow</enum> </property> - <property name="tickInterval" > + <property name="tickInterval"> <number>4</number> </property> </widget> </item> - <item row="2" column="0" > - <widget class="QLabel" name="label_7" > - <property name="text" > + <item row="2" column="0"> + <widget class="QLabel" name="label_7"> + <property name="text"> <string>Saturation:</string> </property> </widget> </item> - <item row="2" column="1" colspan="2" > - <widget class="QSlider" name="saturationSlider" > - <property name="minimum" > + <item row="2" column="1" colspan="2"> + <widget class="QSlider" name="saturationSlider"> + <property name="minimum"> <number>-8</number> </property> - <property name="maximum" > + <property name="maximum"> <number>8</number> </property> - <property name="orientation" > + <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="tickPosition" > + <property name="tickPosition"> <enum>QSlider::TicksBelow</enum> </property> - <property name="tickInterval" > + <property name="tickInterval"> <number>4</number> </property> </widget> </item> - <item row="3" column="0" > - <widget class="QLabel" name="label_2" > - <property name="text" > + <item row="3" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> <string>Hue:</string> </property> </widget> </item> - <item row="3" column="1" colspan="2" > - <widget class="QSlider" name="hueSlider" > - <property name="minimum" > + <item row="3" column="1" colspan="2"> + <widget class="QSlider" name="hueSlider"> + <property name="minimum"> <number>-8</number> </property> - <property name="maximum" > + <property name="maximum"> <number>8</number> </property> - <property name="orientation" > + <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="tickPosition" > + <property name="tickPosition"> <enum>QSlider::TicksBelow</enum> </property> - <property name="tickInterval" > + <property name="tickInterval"> <number>4</number> </property> </widget> </item> - <item row="4" column="0" colspan="2" > - <widget class="QLabel" name="label_10" > - <property name="text" > + <item row="4" column="0" colspan="2"> + <widget class="QLabel" name="label_10"> + <property name="text"> <string>Aspect ratio:</string> </property> </widget> </item> - <item row="4" column="2" > - <widget class="QComboBox" name="aspectCombo" > - <property name="minimumSize" > - <size> - <width>180</width> - <height>0</height> - </size> + <item row="4" column="2"> + <widget class="QComboBox" name="aspectCombo"> + <property name="sizeAdjustPolicy"> + <enum>QComboBox::AdjustToContentsOnFirstShow</enum> </property> <item> - <property name="text" > + <property name="text"> <string>Auto</string> </property> </item> <item> - <property name="text" > + <property name="text"> <string>Stretch</string> </property> </item> <item> - <property name="text" > + <property name="text"> <string>4/3</string> </property> </item> <item> - <property name="text" > + <property name="text"> <string>16/9</string> </property> </item> </widget> </item> - <item row="5" column="0" colspan="2" > - <widget class="QLabel" name="label_11" > - <property name="text" > + <item row="5" column="0" colspan="2"> + <widget class="QLabel" name="label_11"> + <property name="text"> <string>Scale Mode:</string> </property> </widget> </item> - <item row="5" column="2" > - <widget class="QComboBox" name="scalemodeCombo" > - <property name="minimumSize" > - <size> - <width>180</width> - <height>0</height> - </size> - </property> - <item> - <property name="text" > - <string>Fit in view</string> - </property> - </item> - <item> - <property name="text" > - <string>Scale and crop</string> - </property> - </item> - </widget> - </item> </layout> + <zorder>scalemodeCombo</zorder> + <zorder>label_9</zorder> + <zorder>contrastSlider</zorder> + <zorder>label_8</zorder> + <zorder>brightnessSlider</zorder> + <zorder>label_7</zorder> + <zorder>saturationSlider</zorder> + <zorder>label_2</zorder> + <zorder>hueSlider</zorder> + <zorder>label_10</zorder> + <zorder>aspectCombo</zorder> + <zorder>label_11</zorder> </widget> </item> <item> - <widget class="QGroupBox" name="groupBox_2" > - <property name="title" > + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> <string>Audio options:</string> </property> - <property name="flat" > + <property name="flat"> <bool>true</bool> </property> - <layout class="QVBoxLayout" name="verticalLayout" > + <layout class="QVBoxLayout" name="verticalLayout"> <item> - <layout class="QHBoxLayout" > + <layout class="QHBoxLayout"> <item> - <widget class="QLabel" name="label" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Preferred" hsizetype="Maximum" > + <widget class="QLabel" name="label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="minimumSize" > + <property name="minimumSize"> <size> - <width>90</width> + <width>10</width> <height>0</height> </size> </property> - <property name="text" > + <property name="text"> <string>Audio device:</string> </property> - <property name="alignment" > + <property name="alignment"> <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> </property> </widget> </item> <item> - <widget class="QComboBox" name="deviceCombo" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Minimum" > + <widget class="QComboBox" name="deviceCombo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> + <property name="minimumSize"> + <size> + <width>10</width> + <height>0</height> + </size> + </property> + <property name="sizeAdjustPolicy"> + <enum>QComboBox::AdjustToMinimumContentsLength</enum> + </property> </widget> </item> </layout> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout" > + <layout class="QHBoxLayout" name="horizontalLayout"> <item> - <widget class="QLabel" name="label_6" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Preferred" hsizetype="Maximum" > + <widget class="QLabel" name="label_6"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="minimumSize" > + <property name="minimumSize"> <size> - <width>90</width> + <width>10</width> <height>0</height> </size> </property> - <property name="text" > + <property name="text"> <string>Audio effect:</string> </property> - <property name="alignment" > + <property name="alignment"> <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> </property> </widget> </item> <item> - <widget class="QComboBox" name="audioEffectsCombo" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Maximum" hsizetype="Minimum" > + <widget class="QComboBox" name="audioEffectsCombo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> + <property name="minimumSize"> + <size> + <width>10</width> + <height>0</height> + </size> + </property> + <property name="sizeAdjustPolicy"> + <enum>QComboBox::AdjustToMinimumContentsLength</enum> + </property> </widget> </item> <item> - <widget class="QToolButton" name="effectButton" > - <property name="enabled" > + <widget class="QToolButton" name="effectButton"> + <property name="enabled"> <bool>false</bool> </property> - <property name="text" > + <property name="text"> <string>Setup</string> </property> </widget> @@ -285,123 +316,123 @@ </layout> </item> <item> - <layout class="QHBoxLayout" > + <layout class="QHBoxLayout"> <item> - <widget class="QLabel" name="crossFadeLabel" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Preferred" hsizetype="Maximum" > + <widget class="QLabel" name="crossFadeLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="minimumSize" > + <property name="minimumSize"> <size> - <width>90</width> + <width>10</width> <height>0</height> </size> </property> - <property name="text" > + <property name="text"> <string>Cross fade:</string> </property> - <property name="alignment" > + <property name="alignment"> <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> </property> </widget> </item> <item> - <layout class="QVBoxLayout" > + <layout class="QVBoxLayout"> <item> - <widget class="QSlider" name="crossFadeSlider" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Minimum" > + <widget class="QSlider" name="crossFadeSlider"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="minimum" > + <property name="minimum"> <number>-20</number> </property> - <property name="maximum" > + <property name="maximum"> <number>20</number> </property> - <property name="singleStep" > + <property name="singleStep"> <number>1</number> </property> - <property name="pageStep" > + <property name="pageStep"> <number>2</number> </property> - <property name="value" > + <property name="value"> <number>0</number> </property> - <property name="orientation" > + <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="tickPosition" > + <property name="tickPosition"> <enum>QSlider::TicksBelow</enum> </property> </widget> </item> <item> - <layout class="QHBoxLayout" > + <layout class="QHBoxLayout"> <item> - <widget class="QLabel" name="crossFadeLabel1" > - <property name="font" > + <widget class="QLabel" name="crossFadeLabel1"> + <property name="font"> <font> <pointsize>9</pointsize> </font> </property> - <property name="text" > + <property name="text"> <string>-10 Sec</string> </property> </widget> </item> <item> <spacer> - <property name="orientation" > + <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="sizeHint" stdset="0" > + <property name="sizeHint" stdset="0"> <size> - <width>40</width> + <width>0</width> <height>20</height> </size> </property> </spacer> </item> <item> - <widget class="QLabel" name="crossFadeLabel2" > - <property name="font" > + <widget class="QLabel" name="crossFadeLabel2"> + <property name="font"> <font> <pointsize>9</pointsize> </font> </property> - <property name="text" > + <property name="text"> <string>0</string> </property> </widget> </item> <item> <spacer> - <property name="orientation" > + <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="sizeHint" stdset="0" > + <property name="sizeHint" stdset="0"> <size> - <width>40</width> + <width>0</width> <height>20</height> </size> </property> </spacer> </item> <item> - <widget class="QLabel" name="crossFadeLabel3" > - <property name="font" > + <widget class="QLabel" name="crossFadeLabel3"> + <property name="font"> <font> <pointsize>9</pointsize> </font> </property> - <property name="text" > - <string>10 Sec</string> + <property name="text"> + <string>10 Sec </string> </property> </widget> </item> @@ -415,11 +446,11 @@ </widget> </item> <item> - <widget class="QDialogButtonBox" name="buttonBox" > - <property name="orientation" > + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="standardButtons" > + <property name="standardButtons"> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> </property> </widget> @@ -434,11 +465,11 @@ <receiver>settings</receiver> <slot>accept()</slot> <hints> - <hint type="sourcelabel" > + <hint type="sourcelabel"> <x>248</x> <y>254</y> </hint> - <hint type="destinationlabel" > + <hint type="destinationlabel"> <x>157</x> <y>274</y> </hint> @@ -450,11 +481,11 @@ <receiver>settings</receiver> <slot>reject()</slot> <hints> - <hint type="sourcelabel" > + <hint type="sourcelabel"> <x>316</x> <y>260</y> </hint> - <hint type="destinationlabel" > + <hint type="destinationlabel"> <x>286</x> <y>274</y> </hint> diff --git a/dist/README b/dist/README index 529d2bd..e7dfb19 100644 --- a/dist/README +++ b/dist/README @@ -52,7 +52,7 @@ documentation is available at http://qt.nokia.com/doc/. SUPPORTED PLATFORMS For a complete list of supported platforms, see -http://qt.nokia.com/doc/%VERSION%/supported-platforms.html. +http://qt.nokia.com/doc/%SHORTVERSION%/supported-platforms.html. COMMERCIAL EDITIONS @@ -65,7 +65,7 @@ the QtCore, QtGui (except QGraphicsView), QtTest, QtDBus and Qt3Support modules. For a full listing of the contents of each module, please refer to -http://qt.nokia.com/doc/%VERSION%/modules.html +http://qt.nokia.com/doc/%SHORTVERSION%/modules.html HOW TO REPORT A BUG diff --git a/dist/changes-4.6.0 b/dist/changes-4.6.0 index 887c96f..3e7d33b 100644 --- a/dist/changes-4.6.0 +++ b/dist/changes-4.6.0 @@ -91,9 +91,14 @@ Optimizations QtCore ------ + - QAbstractItemModel + * [MR#972] Added API to move items + * [MR#1072] Added function beginResetModel() / endResetModel() + - QByteArray * New overloads for QByteArray::insert() and QByteArray::prepend(). + * [MR#1286] Added value_type typedef for STL compatibility - QEventDispatcherGlib (internal class) * Fix a regression introduced in 4.5.3 that would cause timers to not @@ -195,6 +200,8 @@ QtGui - QAbstractItemView * [256502] Fixes selectionModel::hasSelection return value after model::reset. + * [MR#1426] Fixes some issues with Shift-selection + * [MR#1668] New QAbstractItemView::setDefaultDropAction - QApplication * [QTBUG-739] Removed internal widgets from QApplication::topLevelWidgets(). @@ -317,6 +324,7 @@ QtGui - QListView * [243335] Fixed the visualRect to return correct values when the widget is not yet shown. + * [MR#666] Fixed selection with Shift-Arrow/Shift-Click in QListView's IconMode - QMainWindow * [226060] Adding actions to a toolbar would always make the next toolbar @@ -422,6 +430,9 @@ QtGui * [240325] Even with wrap mode set to Qt::TextWordWrap, the layout would sometimes break outside word boundaries when floating objects affected the width available to the text. + * [MR#681] Added support for roman numbering for lists + * [MR#1753] Fixed escaping HTML attributes QTextDocument::toHtml() + - QTextLayout * [QTBUG-4468] Count tabs as multiple characters when applying a fixed @@ -443,6 +454,7 @@ QtGui - QTreeWidget * [253109] Shows the widget when calling setItemWidget. + * [MR#1393] Use stable sorting. - QWidget * Added inputMethodHints property. @@ -612,7 +624,7 @@ QtWebKit - QWebElement * New class; introduced to implement DOM like operations on a web page. - + - QWebFrame * New properties for an URL and a focus management. * New signals delivering current loading status. @@ -860,17 +872,17 @@ Qt for Embedded Linux - Phonon on Windows * Now much more reliable when reading a file through a QIODevice. - * If Video Mixing Renderer 9 is not available, falls back to software + * If Video Mixing Renderer 9 is not available, falls back to software rendering. * Fixed a flicker issue when switching source with a transition time of 0 - - - [QTBUG-3620] Fixed bug on X11 that caused bitmap fonts to become so small - it was unreadable when printed or presented in a print preview widget. - - - [QTBUG-4445] Fixed bug on Windows that caused problems when printing - text where several characters were represented by a single glyph, e.g. + + - [QTBUG-3620] Fixed bug on X11 that caused bitmap fonts to become so small + it was unreadable when printed or presented in a print preview widget. + + - [QTBUG-4445] Fixed bug on Windows that caused problems when printing + text where several characters were represented by a single glyph, e.g. a double 't' with the Calibri font. - + - EGL and OpenGL/ES * Protect the use of version-specific EGL symbols with #ifdef's. * Make sure an EGL context is current when resolving GL extensions. diff --git a/dist/changes-4.6.1 b/dist/changes-4.6.1 new file mode 100644 index 0000000..5efa0e2 --- /dev/null +++ b/dist/changes-4.6.1 @@ -0,0 +1,164 @@ +Qt 4.6.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 4.6.0. For more details, +refer to the online documentation included in this distribution. The +documentation is also available online: + + http://qt.nokia.com/doc/4.6 + +The Qt version 4.6 series is binary compatible with the 4.5.x series. +Applications compiled for 4.5 will continue to run with 4.6. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker, the (now obsolete) Task +Tracker, or the Merge Request queue of the public source repository. + +Qt Bug Tracker: http://bugreports.qt.nokia.com +Task Tracker: http://qt.nokia.com/developer/task-tracker +Merge Request: http://qt.gitorious.org + +**************************************************************************** +* General * +**************************************************************************** + +New features +------------ + + - SomeClass, SomeOtherClass + * New classes for foo, bar and baz + +Optimizations +------------- + + - Optimized foo in QSomeClass + * See list of Important Behavior Changes below + + +**************************************************************************** +* Library * +**************************************************************************** + +QtCore +------ + + - foo + * bar + +QtGui +----- + + - QPixmap + * load() and loadFromData() can now support compressed GL textures + in the DDS, ETC1, PVRTC2, and PVRTC4 formats if the OpenGL graphics + system is active and the appropriate extensions are present in the + GL implementation. + +QtDBus +------ + + - foo + * bar + +QtNetwork +--------- + + - foo + * bar + +QtOpenGL +-------- + + - QGLContext + * bindTexture(QString) now supports DDS, ETC1, PVRTC2, and PVRTC4 + compressed textures if the appropriate extensions are present + in the GL implementation. + +QtScript +-------- + + - foo + * bar + +QtSql +----- + + - foo + * bar + +QtXml +----- + + - foo + * bar + +Qt Plugins +---------- + + - foo + * bar + +Third party components +---------------------- + + - Updated foo to version 2.3.9. + + - Updated bar to the latest version from baz.org. + + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + +Qt for Unix (X11 and Mac OS X) +------------------------------ + + - + +Qt for Linux/X11 +---------------- + + - + +Qt for Windows +-------------- + + - + +Qt for Mac OS X +--------------- + + - + +Qt for Embedded Linux +--------------------- + + - + +DirectFB +-------- + + - + +Qt for Windows CE +----------------- + + - + +**************************************************************************** +* Tools * +**************************************************************************** + + - Designer + * foo + + - qdoc3 + * bar + + - Linguist + * baz + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - + diff --git a/doc/doc.pri b/doc/doc.pri index d4fdcd8..463c447 100644 --- a/doc/doc.pri +++ b/doc/doc.pri @@ -34,12 +34,9 @@ win32-g++:isEmpty(QMAKE_SH) { QT_DOCUMENTATION = $$replace(QT_DOCUMENTATION, "/", "\\\\") } - -!wince*:!cross_compile:SUBDIRS += tools/qdoc3 - # Build rules: adp_docs.commands = ($$QDOC $$ADP_DOCS_QDOCCONF_FILE) -adp_docs.depends += sub-tools-qdoc3 +adp_docs.depends += sub-tools # qdoc3 qch_docs.commands = $$QT_DOCUMENTATION qch_docs.depends += sub-tools diff --git a/doc/src/demos/anomaly.qdoc b/doc/src/demos/anomaly.qdoc new file mode 100644 index 0000000..a2ea677 --- /dev/null +++ b/doc/src/demos/anomaly.qdoc @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example demos/embedded/anomaly + \title Anomaly Demonstration + + \image anomaly-demo.png +*/ diff --git a/doc/src/demos/desktopservices.qdoc b/doc/src/demos/desktopservices.qdoc new file mode 100644 index 0000000..2eed37b --- /dev/null +++ b/doc/src/demos/desktopservices.qdoc @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example demos/embedded/desktopservices + \title Embedded Desktop Services Demonstration + + \image embeddeddesktopservices-demo.png +*/ diff --git a/doc/src/demos/digiflip.qdoc b/doc/src/demos/digiflip.qdoc new file mode 100644 index 0000000..553b11b --- /dev/null +++ b/doc/src/demos/digiflip.qdoc @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example demos/embedded/digiflip + \title Digiflip Demonstration +*/ diff --git a/doc/src/demos/embeddedsvgviewer.qdoc b/doc/src/demos/embeddedsvgviewer.qdoc new file mode 100644 index 0000000..c09b4f0 --- /dev/null +++ b/doc/src/demos/embeddedsvgviewer.qdoc @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example demos/embedded/embeddedsvgviewer + \title Embedded SVG Viewer Demonstration + + \image embeddedsvgviewer-demo.png +*/ diff --git a/doc/src/demos/flickable.qdoc b/doc/src/demos/flickable.qdoc new file mode 100644 index 0000000..03ccc48 --- /dev/null +++ b/doc/src/demos/flickable.qdoc @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example demos/embedded/flickable + \title Flickable List Demonstration + + \image flickable-demo.png +*/ diff --git a/doc/src/demos/flightinfo.qdoc b/doc/src/demos/flightinfo.qdoc new file mode 100644 index 0000000..efe658a --- /dev/null +++ b/doc/src/demos/flightinfo.qdoc @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example demos/embedded/flightinfo + \title Flight Info Demonstration + + \image flightinfo-demo.png +*/ diff --git a/doc/src/demos/fluidlauncher.qdoc b/doc/src/demos/fluidlauncher.qdoc new file mode 100644 index 0000000..20012a4 --- /dev/null +++ b/doc/src/demos/fluidlauncher.qdoc @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example demos/embedded/fluidlauncher + \title Fluid Launcher Demonstration + + \image fluidlauncher-demo.png +*/ diff --git a/doc/src/demos/lightmaps.qdoc b/doc/src/demos/lightmaps.qdoc new file mode 100644 index 0000000..04fde15 --- /dev/null +++ b/doc/src/demos/lightmaps.qdoc @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example demos/embedded/lightmaps + \title Light Maps Demonstration + + \image lightmaps-demo.png +*/ diff --git a/doc/src/demos/raycasting.qdoc b/doc/src/demos/raycasting.qdoc new file mode 100644 index 0000000..36c61f0 --- /dev/null +++ b/doc/src/demos/raycasting.qdoc @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example demos/embedded/raycasting + \title Ray Casting Demonstration + + \image raycasting-demo.png +*/ diff --git a/doc/src/demos/styledemo.qdoc b/doc/src/demos/styledemo.qdoc new file mode 100644 index 0000000..44745c9 --- /dev/null +++ b/doc/src/demos/styledemo.qdoc @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example demos/embedded/styledemo + \title Embedded Styles Demonstration + + \image styledemo-demo.png +*/ diff --git a/doc/src/demos/weatherinfo.qdoc b/doc/src/demos/weatherinfo.qdoc new file mode 100644 index 0000000..54b2734 --- /dev/null +++ b/doc/src/demos/weatherinfo.qdoc @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example demos/embedded/weatherinfo + \title Weather Info Demonstration + + \image weatherinfo-demo.png +*/ diff --git a/doc/src/examples/blurpicker.qdoc b/doc/src/examples/blurpicker.qdoc new file mode 100644 index 0000000..93c12bf --- /dev/null +++ b/doc/src/examples/blurpicker.qdoc @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example effects/blurpicker + \title Blur Picker Effect Example + + \image blurpickereffect-example.png +*/ diff --git a/doc/src/examples/fademessage.qdoc b/doc/src/examples/fademessage.qdoc new file mode 100644 index 0000000..ecea095 --- /dev/null +++ b/doc/src/examples/fademessage.qdoc @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example effects/fademessage + \title Fade Message Effect Example + + \image fademessageeffect-example.png +*/ diff --git a/doc/src/examples/fingerpaint.qdoc b/doc/src/examples/fingerpaint.qdoc new file mode 100644 index 0000000..9c55dac --- /dev/null +++ b/doc/src/examples/fingerpaint.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example multitouch/fingerpaint + \title Finger Paint Example + + The Finger Paint example shows the use of multi-touch with a custom widget + to create a simple painting application. + + \image multitouch-fingerpaint.png +*/ diff --git a/doc/src/examples/helloscript.qdoc b/doc/src/examples/helloscript.qdoc index 7142d8b..243b10f 100644 --- a/doc/src/examples/helloscript.qdoc +++ b/doc/src/examples/helloscript.qdoc @@ -69,7 +69,7 @@ The contents of the script file are read. - \snippet examples/script/helloscript/helloscript.qs 0 + \snippet examples/script/helloscript/helloscript.js 0 The script sets the \c text (note that the qTr() function is used to allow for translation) and \c styleSheet properties of the button, and calls the @@ -105,7 +105,7 @@ To generate the translation file, run \c lupdate as follows: \code - lupdate helloscript.qs -ts helloscript_la.ts + lupdate helloscript.js -ts helloscript_la.ts \endcode You should now have a file \c helloscript_la.ts in the current @@ -115,7 +115,7 @@ linguist helloscript_la.ts \endcode - You should now see the text "helloscript.qs" in the top left pane. + You should now see the text "helloscript.js" in the top left pane. Double-click it, then click on "Hello world!" and enter "Orbis, te saluto!" in the \gui Translation pane (the middle right of the window). Don't forget the exclamation mark! diff --git a/doc/src/examples/lighting.qdoc b/doc/src/examples/lighting.qdoc new file mode 100644 index 0000000..8e9d1c2 --- /dev/null +++ b/doc/src/examples/lighting.qdoc @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example effects/lighting + \title Lighting Effect Example + + \image lightingeffect-example.png +*/ diff --git a/doc/src/examples/multitouch-dials.qdoc b/doc/src/examples/multitouch-dials.qdoc new file mode 100644 index 0000000..52e964c --- /dev/null +++ b/doc/src/examples/multitouch-dials.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example multitouch/dials + \title Multi-Touch Dials Example + + The Multi-Touch Dials example shows how to apply multi-touch to a set of + standard Qt widgets. + + \image multitouch-dials-example.png +*/ diff --git a/doc/src/examples/multitouch-knobs.qdoc b/doc/src/examples/multitouch-knobs.qdoc new file mode 100644 index 0000000..d0c537c --- /dev/null +++ b/doc/src/examples/multitouch-knobs.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example multitouch/knobs + \title Multi-Touch Knobs Example + + The Multi-Touch Knobs example shows how to create custom controls that + accept multi-touch input. + + \image multitouch-knobs-example.png +*/ diff --git a/doc/src/examples/openvg-star.qdoc b/doc/src/examples/openvg-star.qdoc new file mode 100644 index 0000000..7c78e12 --- /dev/null +++ b/doc/src/examples/openvg-star.qdoc @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example openvg/star + \title OpenVG Star Example + + The OpenVG Star example demonstrates the use of Qt's OpenVG integration. +*/ diff --git a/doc/src/examples/pinchzoom.qdoc b/doc/src/examples/pinchzoom.qdoc new file mode 100644 index 0000000..ff8c811 --- /dev/null +++ b/doc/src/examples/pinchzoom.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/*! + \example multitouch/pinchzoom + \title Pinch Zoom Example + + The Pinch Zoom example shows how to use low-level multi-touch information + to recognize a gesture. + + \image multitouch-pinchzoom.png +*/ diff --git a/doc/src/examples/tablet.qdoc b/doc/src/examples/tablet.qdoc index 3c3ced9..b0548d4 100644 --- a/doc/src/examples/tablet.qdoc +++ b/doc/src/examples/tablet.qdoc @@ -79,7 +79,7 @@ the examples menus and connect their slots and signals. \o The \c TabletCanvas class inherits QWidget and receives tablet events. It uses the events to paint on a - QImage, which it draws onto itself. + offscreen pixmap, which it draws onto itself. \o The \c TabletApplication class inherits QApplication. This class handles tablet events that are not sent to \c tabletEvent(). We will look at this later. @@ -214,16 +214,16 @@ alphaChannelType, \c colorSturationType, and \c penWidthType, which we provide access functions for. - We draw on a QImage with \c myPen and \c myBrush using \c + We draw on a QPixmap with \c myPen and \c myBrush using \c myColor. The \c saveImage() and \c loadImage() saves and loads - the QImage to disk. The image is drawn on the widget in \c + the QPixmap to disk. The pixmap is drawn on the widget in \c paintEvent(). The \c pointerType and \c deviceType keeps the type of pointer, which is either a pen or an eraser, and device currently used on the tablet, which is either a stylus or an airbrush. The interpretation of events from the tablet is done in \c - tabletEvent(); \c paintImage(), \c updateBrush(), and \c + tabletEvent(); \c paintPixmap(), \c updateBrush(), and \c brushPattern() are helper functions used by \c tabletEvent(). @@ -234,20 +234,20 @@ \snippet examples/widgets/tablet/tabletcanvas.cpp 0 In the constructor we initialize our class variables. We need - to draw the background of our image, as the default is gray. + to draw the background of our pixmap, as the default is gray. Here is the implementation of \c saveImage(): \snippet examples/widgets/tablet/tabletcanvas.cpp 1 - QImage implements functionality to save itself to disk, so we - simply call \l{QImage::}{save()}. + QPixmap implements functionality to save itself to disk, so we + simply call \l{QPixmap::}{save()}. Here is the implementation of \c loadImage(): \snippet examples/widgets/tablet/tabletcanvas.cpp 2 - We simply call \l{QImage::}{load()}, which loads the image in \a + We simply call \l{QPixmap::}{load()}, which loads the image in \a file. Here is the implementation of \c tabletEvent(): @@ -259,7 +259,7 @@ is pressed down on, leaves, or moves on the tablet. We set the \c deviceDown to true when a device is pressed down on the tablet; we then know when we should draw when we receive move events. We - have implemented the \c updateBrush() and \c paintImage() helper + have implemented the \c updateBrush() and \c paintPixmap() helper functions to update \c myBrush and \c myPen after the state of \c alphaChannelType, \c colorSaturationType, and \c lineWidthType. @@ -267,13 +267,13 @@ \snippet examples/widgets/tablet/tabletcanvas.cpp 4 - We simply draw the image to the top left of the widget. + We simply draw the pixmap to the top left of the widget. - Here is the implementation of \c paintImage(): + Here is the implementation of \c paintPixmap(): \snippet examples/widgets/tablet/tabletcanvas.cpp 5 - In this function we draw on the image based on the movement of the + In this function we draw on the pixmap based on the movement of the device. If the device used on the tablet is a stylus we want to draw a line between the positions of the stylus recorded in \c polyLine. We also assume that this is a reasonable handling of any unknown device, @@ -334,7 +334,7 @@ We finally check wether the pointer is the stylus or the eraser. If it is the eraser, we set the color to the background color of - the image an let the pressure decide the pen width, else we set + the pixmap an let the pressure decide the pen width, else we set the colors we have set up previously in the function. diff --git a/doc/src/external-resources.qdoc b/doc/src/external-resources.qdoc index f965869..cd99505 100644 --- a/doc/src/external-resources.qdoc +++ b/doc/src/external-resources.qdoc @@ -417,3 +417,8 @@ \externalpage http://www.w3.org/TR/REC-CSS2/selector.html#q1 \title Standard CSS2 selector */ + +/*! + \externalpage http://www.w3.org/XML/Schema + \title XML Schema +*/ diff --git a/doc/src/getting-started/demos.qdoc b/doc/src/getting-started/demos.qdoc index 8f2829a..524f27c 100644 --- a/doc/src/getting-started/demos.qdoc +++ b/doc/src/getting-started/demos.qdoc @@ -163,4 +163,31 @@ \note The Phonon demos are currently not available for the MinGW platform. + \section1 Animation + + \list + \o \l{demos/sub-attaq}{Sub-Attaq} demonstrates the features of the + \l{The Animation Framework}{animation framework} and + \l{The State Machine Framework}{state machine framework} in the production of + a simple game. + \endlist + + \section1 Embedded Platforms + + \list + \o \l{demos/embedded/anomaly}{Anomaly} is a small screen browser with kinetic scrolling. + \o \l{demos/embedded/desktopservices}{Embedded Desktop Services} shows how to open + documents using the applications associated with their file types. + \o \l{demos/embedded/digiflip}{Digiflip} is a digital watch with transition effects. + \o \l{demos/embedded/embeddedsvgviewer}{Embedded SVG Viewer} shows how to display SVG + drawings on embedded devices. + \o \l{demos/embedded/flickable}{Flickable List} shows how to display a list with kinetic scrolling. + \o \l{demos/embedded/flightinfo}{Flight Info} fetches information about aircraft flights from the Web. + \o \l{demos/embedded/fluidlauncher}{Fluid Launcher} demo application launcher for embedded screens + \o \l{demos/embedded/lightmaps}{Light Maps} demonstrates OpenStreetMap integration with WebKit. + \o \l{demos/embedded/raycasting}{Ray Casting} demonstrates the use of ray casting with the + \l{The Graphics View Framework}{Graphics View} framework. + \o \l{demos/embedded/styledemo}{Embedded Styles} demonstrates the use of styles. + \o \l{demos/embedded/weatherinfo}{Weather Info} fetches weather information from the Web. + \endlist */ diff --git a/doc/src/getting-started/examples.qdoc b/doc/src/getting-started/examples.qdoc index e951804..f0a6799 100644 --- a/doc/src/getting-started/examples.qdoc +++ b/doc/src/getting-started/examples.qdoc @@ -206,7 +206,7 @@ \o \row - \o{2,1} \l{OpenGL Examples}{\bold OpenGL} + \o{2,1} \l{OpenGL Examples}{\bold{OpenGL}}\bold{ and }\l{OpenVG Examples}{\bold{OpenVG}}\bold{ Examples} \o{2,1} \l{Multimedia Examples}{\bold{Multimedia Framework}} \row \o \image opengl-examples.png OpenGL @@ -215,6 +215,9 @@ platforms, giving developers the opportunity to display hardware accelerated 3D graphics alongside a more conventional user interface. + Qt provides support for integration with OpenVG implementations on + platforms with suitable drivers. + \o \image phonon-examples.png \o Qt provides low-level audio support on linux,windows and mac platforms by default and @@ -299,37 +302,47 @@ to build highly animated, high-performance GUIs. \row + \o{2,1} \l{Multi-Touch Examples}{\bold{Multi-Touch Framework}} \o{2,1} \l{Gestures Examples}{\bold{Gestures}} - \o{2,1} \l{D-Bus Examples}{\bold{D-Bus}} + \row + \o \image multitouch-examples.png + \o + Support for multi-touch input makes it possible for developers to create + extensible and intuitive user interfaces. + \o \image gestures-examples.png \o Applications can be written to respond to gestures as a natural input method. These examples show how to enable support for standard and custom gestures in applications. - \o \image dbus-examples.png D-Bus - \o - D-Bus is an inter-process communication protocol for Unix/Linux systems. - These examples demonstrate how to write application that communicate with - each other. \row + \o{2,1} \l{D-Bus Examples}{\bold{D-Bus}} \o{2,1} \l{Qt for Embedded Linux Examples}{\bold{Qt for Embedded Linux}} - \o{2,1} \l{ActiveQt Examples}{\bold ActiveQt} + \row \o \image qt-embedded-examples.png \o Systems with limited resources, specialized hardware, and small screens require special attention. - \o \image activeqt-examples.png ActiveQt + \o \image dbus-examples.png D-Bus \o - These examples demonstrate how to write ActiveX controls and control servers - with Qt, and how to use ActiveX controls and COM objects in a Qt application. + D-Bus is an inter-process communication protocol for Unix/Linux systems. + These examples demonstrate how to write application that communicate with + each other. \row + \o{2,1} \l{ActiveQt Examples}{\bold ActiveQt} \o{2,1} \l{Qt Quarterly}{\bold{Qt Quarterly}} + \row + \o \image activeqt-examples.png ActiveQt + \o + These examples demonstrate how to write ActiveX controls and control servers + with Qt, and how to use ActiveX controls and COM objects in a Qt application. + \o \image qq-thumbnail.png QtQuarterly \o One more valuable source for examples and explanations of Qt @@ -777,7 +790,7 @@ \previouspage Inter-Process Communication Examples \contentspage Qt Examples - \nextpage Multimedia Examples + \nextpage OpenVG Examples \image opengl-examples.png @@ -806,6 +819,27 @@ */ /*! + \page examples-openvg.html + \title OpenVG Examples + + \previouspage OpenGL Examples + \contentspage Qt Examples + \nextpage Multimedia Examples + + \image openvg-examples.png + + Qt provides support for integration with OpenVG implementations on + platforms with suitable drivers. + + These examples demonstrate the basic techniques used to take advantage of + OpenVG in Qt applications. + + \list + \o \l{openvg/star}{OpenVG Star} + \endlist +*/ + +/*! \page examples-multimedia.html \title Multimedia Examples @@ -1096,7 +1130,7 @@ \previouspage State Machine Examples \contentspage Qt Examples - \nextpage Gestures Examples + \nextpage Multi-Touch Examples \image animation-examples.png Animation @@ -1113,10 +1147,29 @@ */ /*! + \page examples-multitouch.html + \title Multi-Touch Examples + + \previouspage Animation Framework Examples + \contentspage Qt Examples + \nextpage Gestures Examples + + Support for multi-touch input makes it possible for developers to create + extensible and intuitive user interfaces. + + \list + \o \l{multitouch/dials}{Multi-Touch Dials} + \o \l{multitouch/fingerpaint}{Finger Paint} + \o \l{multitouch/knobs}{Multi-Touch Knobs} + \o \l{multitouch/pinchzoom}{Pinch Zoom} + \endlist +*/ + +/*! \page examples-gestures.html \title Gestures Examples - \previouspage Animation Framework Examples + \previouspage Multi-Touch Examples \contentspage Qt Examples \nextpage D-Bus Examples diff --git a/doc/src/getting-started/installation.qdoc b/doc/src/getting-started/installation.qdoc index 1a5cd99..b052c3c 100644 --- a/doc/src/getting-started/installation.qdoc +++ b/doc/src/getting-started/installation.qdoc @@ -66,12 +66,12 @@ in the \l{Qt for X11 Requirements} document. For the open source version you do not need a license file. \o Unpack the archive if you have not done so already. For example, - if you have the \c{qt-x11-opensource-desktop-%VERSION%.tar.gz} + if you have the \c{qt-everywhere-opensource-src-%VERSION%.tar.gz} package, type the following commands at a command line prompt: \snippet doc/src/snippets/code/doc_src_installation.qdoc 0 - This creates the directory \c{/tmp/qt-x11-opensource-desktop-%VERSION%} + This creates the directory \c{/tmp/qt-everywhere-opensource-src-%VERSION%} containing the files from the archive. We only support the GNU version of the tar archiving utility. Note that on some systems it is called gtar. @@ -299,12 +299,12 @@ The following instructions describe how to install Qt from the source package. For the open source version you do not need a license file. \o Unpack the archive if you have not done so already. For example, - if you have the \c{qt-mac-opensource-desktop-%VERSION%.tar.gz} + if you have the \c{qt-everywhere-opensource-src-%VERSION%.tar.gz} package, type the following commands at a command line prompt: \snippet doc/src/snippets/code/doc_src_installation.qdoc 11 - This creates the directory \c{/tmp/qt-mac-opensource-desktop-%VERSION%} + This creates the directory \c{/tmp/qt-everywhere-opensource-src-%VERSION%} containing the files from the archive. \o Building @@ -423,7 +423,7 @@ in the \l{Qt for Windows CE Requirements} document. "Control Panel->System->Advanced->Environment variables" and for older versions by editing \c{c:\autoexec.bat}. - Make sure the enviroment variables for your compiler are set. + Make sure the enviroment variables for your compiler are set. Visual Studio includes \c{vcvars32.bat} for that purpose - or simply use the "Visual Studio Command Prompt" from the Start menu. @@ -530,7 +530,7 @@ in the \l{Qt for the Symbian platform Requirements} document. \snippet doc/src/snippets/code/doc_src_installation.qdoc 25 - To run the demos on the emulator simply navigate to the directory of the demo + To run the demos on the emulator simply navigate to the directory of the demo you want to see and run: \snippet doc/src/snippets/code/doc_src_installation.qdoc 27 @@ -554,7 +554,7 @@ Symbian platform, in the \l{Qt for the Symbian platform Requirements} document. \note \bold {This document describes how to install and configure Qt for -the Symbian platform from scratch. +the Symbian platform from scratch. If you are using pre-built binaries, follow the instructions given in the \l{Installing Qt on the Symbian platform from a Binary Package} document.} @@ -599,6 +599,13 @@ If you are using pre-built binaries, follow the instructions given in the emulator. This is done by locating the Carbide.c++ submenu on the Start menu, and choosing "Configure environment for WINSCW command line". + If you are planning to use abld (the default build system that comes with the S60 SDK) + to build Qt, you will also need to set the following environment variable: + + \snippet doc/src/snippets/code/doc_src_installation.qdoc 33 + + This is not necessary for other applications, only when building Qt. + \o Configure Qt To configure Qt for the Symbian platform, do: @@ -609,7 +616,7 @@ If you are using pre-built binaries, follow the instructions given in the \snippet doc/src/snippets/code/doc_src_installation.qdoc 31 to build the tools using MinGW, and the libraries using SBSv2. - SBSv2 also known as a (\l{http://developer.symbian.org/wiki/index.php/Introduction_to_RAPTOR} {Raptor}) + SBSv2 (also known as \l{http://developer.symbian.org/wiki/index.php/Introduction_to_RAPTOR} {Raptor}) is a next-generation Symbian build system. SBSv2 is not officially supported by any of the S60 SDKs currently available from Forum Nokia. @@ -634,8 +641,8 @@ If you are using pre-built binaries, follow the instructions given in the \snippet doc/src/snippets/code/doc_src_installation.qdoc 29 - \note You will need to supply certificate that allows installation - of binaries with "All -Tcb" capability to your device. + \note You will need to supply certificate that allows installation + of binaries with "All -Tcb" capability to your device. Similarly, install fluidlauncher to the device: @@ -644,7 +651,7 @@ If you are using pre-built binaries, follow the instructions given in the This will create a self-signed \c fluidlauncher_armv5_urel.sis and install it to your device. - To run the demos on the emulator simply navigate to the directory of the demo + To run the demos on the emulator simply navigate to the directory of the demo you want to see and run: \snippet doc/src/snippets/code/doc_src_installation.qdoc 27 @@ -704,6 +711,10 @@ If you are using pre-built binaries, follow the instructions given in the \l{http://www.microsoft.com/downloads/details.aspx?FamilyId=BB4A75AB-E2D4-4C96-B39D-37BAF6B5B1DC&displaylang=en}{here} to avoid runtime conflicts. + If you are using a source code package of Qt, you must first install Perl so + that the syncqt script invoked by configure can be executed. You can download + this \l{http://www.activestate/downloads/}{here}. + To build Qt with Phonon on Windows, you require: \list @@ -820,7 +831,7 @@ If you are using pre-built binaries, follow the instructions given in the when building Qt from its source code. On Debian-based GNU/Linux systems, for example, we recommend that you install the following development packages: - + \list \o libfontconfig1-dev \o libfreetype6-dev @@ -843,7 +854,7 @@ If you are using pre-built binaries, follow the instructions given in the The configure script will autodetect if OpenGL headers and libraries are installed on your system, and if so, it will include the QtOpenGL module in the Qt library. - + If your OpenGL headers or libraries are placed in a non-standard directory, you may need to change the \c QMAKE_INCDIR_OPENGL and/or \c QMAKE_LIBDIR_OPENGL in the config file for your system. @@ -947,7 +958,7 @@ If you are using pre-built binaries, follow the instructions given in the \table \header \o{1,2} Architecture \o{1,2} Compiler \o{2,1} QtCore \o{2,1} QtGui \o{2,1} QtNetwork \o{2,1} QtWebKit - \header \o Minimal \o Normal \o Minimal \o Normal \o Minimal \o Normal \o Minimal \o Normal + \header \o Minimal \o Normal \o Minimal \o Normal \o Minimal \o Normal \o Minimal \o Normal \row \o linux-x86-g++ \o GCC 4.2.4 \o 1.7M \o 2.7M \o 3.3M \o 9.9M \o 653K \o 1.1M \o N/A \o 17M \row \o linux-arm-g++ \o GCC 4.1.1 \o 1.9M \o 3.2M \o 4.1M \o 11M \o 507K \o 1.0M \o N/A \o 17M \row \o linux-mips-g++ (MIPS32) @@ -977,7 +988,7 @@ If you are using pre-built binaries, follow the instructions given in the Qt for the Symbian platform requires the following software installed on your development PC: \list - \o \l{http://www.forum.nokia.com/main/resources/tools_and_sdks/carbide_cpp/}{Carbide.c++ v2.0.0 or higher} + \o \l{http://www.forum.nokia.com/main/resources/tools_and_sdks/carbide_cpp/}{Carbide.c++ v2.0.0 or higher} \list \o \bold{Note:} It may be necessary to update the Carbide compiler. See \l{http://pepper.troll.no/s60prereleases/patches/}{here} for instructions how to check your @@ -999,7 +1010,7 @@ If you are using pre-built binaries, follow the instructions given in the \o \bold{Note:} This is not required if you are using pre-built binary package. \endlist \o Building Qt libraries requires \l{http://www.arm.com/products/DevTools/RVCT.html}{RVCT} 2.2 [build 686] or later, - which is not available free of charge. + which is not available free of charge. \endlist Running Qt on real device requires the following packages to be installed on your device. diff --git a/doc/src/getting-started/known-issues.qdoc b/doc/src/getting-started/known-issues.qdoc index b8c2192..7ae6d34 100644 --- a/doc/src/getting-started/known-issues.qdoc +++ b/doc/src/getting-started/known-issues.qdoc @@ -45,16 +45,14 @@ \ingroup platform-specific \brief A summary of known issues in Qt %VERSION% at the time of release. - This page documents known problems with the packaging and installation in - Qt %VERSION%, as well as issues with third party software that we have - not been able to work around. For a list of such issues in previous Qt - versions refer to this page in the respective documentation. + An up-to-date list of known issues with Qt %VERSION% can be found via the + \l{http://bugreports.qt.nokia.com/}{Qt Bug Tracker}. For a list list of known bugs in Qt %VERSION%, see the \l{Task Tracker} on the Qt website. An overview of known issues may also be found at: - \l{http://qt.gitorious.org/qt/pages/Qt460BetaKnownIssues} + \l{http://qt.gitorious.org/qt/pages/Qt460KnownIssues} {Known Issues Wiki}. \section1 Installation Issues @@ -134,6 +132,18 @@ currently calls winId() on widgets, which causes whole widget hierarchies to use native window handles. This slows down resizing. + \o Compile errors with Intel C++ Compiler.\br + There seems to be a bug in the Intel compiler with respect to + over-agressive inlining of code. + The problem will manifest itself during the link phase of QtGui where + it fails with the error that it cannot find QObjectData::~QObjectData(). + See \l{http://bugreports.qt.nokia.com/browse/QTBUG-5145} for updates on this + bug. + Also, due to some bugs in WebKit, the QtScript and QtWebKit modules + will not compile. + See \l{http://bugreports.qt.nokia.com/browse/QTBUG-6297} for a + workaround for QtScript. + \endlist \section2 Mac OS X diff --git a/doc/src/images/anomaly-demo.png b/doc/src/images/anomaly-demo.png Binary files differnew file mode 100644 index 0000000..a26e705 --- /dev/null +++ b/doc/src/images/anomaly-demo.png diff --git a/doc/src/images/blurpickereffect-example.png b/doc/src/images/blurpickereffect-example.png Binary files differnew file mode 100644 index 0000000..8894338 --- /dev/null +++ b/doc/src/images/blurpickereffect-example.png diff --git a/doc/src/images/embeddeddesktopservices-demo.png b/doc/src/images/embeddeddesktopservices-demo.png Binary files differnew file mode 100644 index 0000000..c1408c1 --- /dev/null +++ b/doc/src/images/embeddeddesktopservices-demo.png diff --git a/doc/src/images/embeddedsvgviewer-demo.png b/doc/src/images/embeddedsvgviewer-demo.png Binary files differnew file mode 100644 index 0000000..0b806d6 --- /dev/null +++ b/doc/src/images/embeddedsvgviewer-demo.png diff --git a/doc/src/images/fademessageeffect-example-faded.png b/doc/src/images/fademessageeffect-example-faded.png Binary files differnew file mode 100644 index 0000000..ea66d2c --- /dev/null +++ b/doc/src/images/fademessageeffect-example-faded.png diff --git a/doc/src/images/fademessageeffect-example.png b/doc/src/images/fademessageeffect-example.png Binary files differnew file mode 100644 index 0000000..823c851 --- /dev/null +++ b/doc/src/images/fademessageeffect-example.png diff --git a/doc/src/images/flickable-demo.png b/doc/src/images/flickable-demo.png Binary files differnew file mode 100644 index 0000000..98f3a69 --- /dev/null +++ b/doc/src/images/flickable-demo.png diff --git a/doc/src/images/flightinfo-demo.png b/doc/src/images/flightinfo-demo.png Binary files differnew file mode 100644 index 0000000..4e9a4b2 --- /dev/null +++ b/doc/src/images/flightinfo-demo.png diff --git a/doc/src/images/fluidlauncher-demo.png b/doc/src/images/fluidlauncher-demo.png Binary files differnew file mode 100644 index 0000000..1720890 --- /dev/null +++ b/doc/src/images/fluidlauncher-demo.png diff --git a/doc/src/images/lightingeffect-example.png b/doc/src/images/lightingeffect-example.png Binary files differnew file mode 100644 index 0000000..d9dc990 --- /dev/null +++ b/doc/src/images/lightingeffect-example.png diff --git a/doc/src/images/lightmaps-demo.png b/doc/src/images/lightmaps-demo.png Binary files differnew file mode 100644 index 0000000..f066f93 --- /dev/null +++ b/doc/src/images/lightmaps-demo.png diff --git a/doc/src/images/multitouch-dials-example.png b/doc/src/images/multitouch-dials-example.png Binary files differnew file mode 100644 index 0000000..60e1776 --- /dev/null +++ b/doc/src/images/multitouch-dials-example.png diff --git a/doc/src/images/multitouch-examples.png b/doc/src/images/multitouch-examples.png Binary files differnew file mode 100644 index 0000000..b053cf3 --- /dev/null +++ b/doc/src/images/multitouch-examples.png diff --git a/doc/src/images/multitouch-knobs-example.png b/doc/src/images/multitouch-knobs-example.png Binary files differnew file mode 100644 index 0000000..1cbd90d --- /dev/null +++ b/doc/src/images/multitouch-knobs-example.png diff --git a/doc/src/images/multitouch-pinchzoom-example.png b/doc/src/images/multitouch-pinchzoom-example.png Binary files differnew file mode 100644 index 0000000..1079fb2 --- /dev/null +++ b/doc/src/images/multitouch-pinchzoom-example.png diff --git a/doc/src/images/raycasting-demo.png b/doc/src/images/raycasting-demo.png Binary files differnew file mode 100644 index 0000000..53c5253 --- /dev/null +++ b/doc/src/images/raycasting-demo.png diff --git a/doc/src/images/styledemo-demo.png b/doc/src/images/styledemo-demo.png Binary files differnew file mode 100644 index 0000000..8e4ec90 --- /dev/null +++ b/doc/src/images/styledemo-demo.png diff --git a/doc/src/images/weatherinfo-demo.png b/doc/src/images/weatherinfo-demo.png Binary files differnew file mode 100644 index 0000000..3183aa4 --- /dev/null +++ b/doc/src/images/weatherinfo-demo.png diff --git a/doc/src/legal/3rdparty.qdoc b/doc/src/legal/3rdparty.qdoc index 974b2c4..f1c1847 100644 --- a/doc/src/legal/3rdparty.qdoc +++ b/doc/src/legal/3rdparty.qdoc @@ -114,6 +114,35 @@ FreeType-2, it has been modified in various other ways.} -- quoted from \c src/3rdparty/harfbuzz/README. + \hr + + Copyright (C) 2004,2007 Red Hat, Inc.\br + Copyright (C) 1998-2004 David Turner and Werner Lemberg\br + Copyright (C) 2006 Behdad Esfahbod\br + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + + This is part of HarfBuzz, an OpenType Layout engine library. + + Permission is hereby granted, without written agreement and without + license or royalty fees, to use, copy, modify, and distribute this + software and its documentation for any purpose, provided that the + above copyright notice and the following two paragraphs appear in + all copies of this software. + + IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. + + THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + + \hr + See \c src/3rdparty/harfbuzz/COPYING.FTL and src/3rdparty/harfbuzz/COPYING.GPL for license details. @@ -257,7 +286,9 @@ \hr Copyright (c) 1996-1997 Sam Leffler\br - Copyright (c) 1996 Pixar + Copyright (c) 1996 Pixar\br + Copyright (c) 1991-1997 Silicon Graphics, Inc.\br + Copyright (C) 2004, Andrey Kiselev <dron@ak4719.spb.edu> Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided @@ -280,6 +311,27 @@ \hr + Copyright (c) 1985, 1986 The Regents of the University of California.\br + All rights reserved. + + This code is derived from software contributed to Berkeley by + James A. Woods, derived from original work by Spencer Thomas + and Joseph Orost. + + Redistribution and use in source and binary forms are permitted + provided that the above copyright notice and this paragraph are + duplicated in all such forms and that any documentation, + advertising materials, and other materials related to such + distribution and use acknowledge that the software was developed + by the University of California, Berkeley. The name of the + University may not be used to endorse or promote products derived + from this software without specific prior written permission. + THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + \hr + See \c src/3rdparty/libtiff/COPYRIGHT for license details. \section1 Wintab API (\c wintab) @@ -297,4 +349,24 @@ src/3rdparty/zlib/README. See \c src/3rdparty/zlib/README for license details. + + \section1 JavaScriptCore + + \hr + + Copyright (c) 1991, 2000, 2001 by Lucent Technologies.\br + Copyright (C) 2002, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + + Permission to use, copy, modify, and distribute this software for any + purpose without fee is hereby granted, provided that this entire notice + is included in all copies of any software which is or includes a copy + or modification of this software and in all copies of the supporting + documentation for such software. + + THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY + REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + + See \c src/3rdparty/webkit/JavaScriptCore/wtf/dtoa.cpp for license details. */ diff --git a/doc/src/legal/licenses.qdoc b/doc/src/legal/licenses.qdoc index 11a84d2..3f24fc5 100644 --- a/doc/src/legal/licenses.qdoc +++ b/doc/src/legal/licenses.qdoc @@ -269,6 +269,467 @@ \list \o examples/webkit/fancybrowser/jquery.min.js \endlist + + \hr + + Copyright (C) Research In Motion Limited 2009. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met:\br + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer.\br + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution.\br + * Neither the name of Research In Motion Limited nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY Research In Motion Limited ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL Research In Motion Limited BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + \list + \o src/corelib/io/qurl.cpp + \endlist + + \hr + + Copyright (c) 2007-2008, Apple, Inc.\br + Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>\br + Copyright (C) 2009 Google Inc. All rights reserved.\br + Copyright (C) 2008, 2009 Paul Pedriana <ppedriana@ea.com>. All rights reserved.\br + Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)\br + Copyright (C) 2009 Jian Li <jianli@chromium.org>\br + Copyright (C) 2007 Staikos Computing Services Inc.\br + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)\br + Copyright (C) 2008 Nuanti Ltd.\br + Copyright (C) 2007 David Smith (catfish.man@gmail.com)\br + Copyright (C) 2008 Tony Chang <idealisms@gmail.com>\br + Copyright (C) 2007 Graham Dennis (graham.dennis@gmail.com) + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of Apple, Inc. nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + \list + \o Parts of WebKit used by the QtWebKit module + \endlist + + \hr + + Copyright (C) 1999 Serika Kurusugawa, All rights reserved.\br + Copyright (C) 1999-2000 Mizi Research Inc. All rights reserved.\br + Copyright (C) 2004, 2005 Daniel M. Duley\br + Copyright (C) 2000 Ming-Che Chuang\br + Copyright (C) 2001, 2002 James Su, Turbolinux Inc.\br + Copyright (C) 2002 WU Yi, HancomLinux Inc.\br + Copyright (C) 2001, 2002 Anthony Fok, ThizLinux Laboratory Ltd.\br + Copyright (c) 2000 Hans Petter Bieker. All rights reserved.\br + Copyright (C) 2001, 2002 ThizLinux Laboratory Ltd.\br + Copyright (C) 2001, 2002 Turbolinux, Inc. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + \list + \o Parts of the codecs implemented by Qt + \endlist + + \hr + + Copyright (c) 1992, 1993\br + The Regents of the University of California. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this software + must display the following acknowledgment: + This product includes software developed by the University of + California, Berkeley and its contributors. + 4. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + \list + \o src/corelib/tools/qlocale.cpp + \endlist + + \hr + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,\br + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer.\br + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution.\br + * Neither the name of the author nor the names of contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + \list + \o Parts of WebKit used by the QtWebKit module + \endlist + + \hr + + Copyright (C) 2005, 2007, 2008 by George Williams + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + \list + \o Parts of the FreeType library + \endlist + + \hr + + Copyright (C) 2006 Apple Computer, Inc. All rights reserved.\br + Copyright (C) 2007 Eric Seidel <eric@webkit.org>\br + Copyright (C) 2008 Kelvin W Sherlock (ksherlock@gmail.com)\br + Copyright (C) 2008 Alp Toker <alp@atoker.com>\br + Copyright (C) 2009 University of Szeged\br + Copyright (C) 2007 Alexey Proskuryakov (ap@nypop.com)\br + Copyright (C) 2009 Daniel Bates (dbates@intudata.com)\br + Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>\br + Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com\br + Copyright (C) 2007 Holger Hans Peter Freyther\br + Copyright (C) 2008 Collabora Ltd. All rights reserved.\br + Copyright (C) 2006 Dirk Mueller <mueller@kde.org>\br + Copyright (C) 2006 Zack Rusin <zack@kde.org>\br + Copyright (C) 2006 George Staikos <staikos@kde.org>\br + Copyright (C) 2006 Simon Hausmann <hausmann@kde.org>\br + Copyright (C) 2006 Rob Buis <buis@kde.org>\br + Copyright (C) 2008 Julien Chaffraix <jchaffraix@webkit.org>\br + Copyright (C) 2007 Henry Mason (hmason@mac.com)\br + Copyright (C) 1999 Lars Knoll (knoll@kde.org)\br + Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)\br + Copyright (c) 2009 The Android Open Source Project\br + Copyright (C) 2008 Dirk Schulze <krit@webkit.org>\br + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)\br + Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>\br + Copyright (C) 2009 280 North Inc. All Rights Reserved.\br + Copyright (C) 2009 Joseph Pecoraro\br + Copyright (C) 2008 Anthony Ricaud (rik24d@gmail.com)\br + Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>\br + Copyright (C) 2008 Christian Dywan <christian@imendio.com>\br + Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com \br + Copyright (C) 2009 Holger Hans Peter Freyther\br + Copyright (C) 2008 Google Inc. All rights reserved.\br + Copyright (C) 2006 Friedemann Kleint <fkleint@trolltech.com>\br + Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>\br + Copyright (C) 2008 Collin Jackson <collinj@webkit.org>\br + Copyright (C) 2007 Staikos Computing Services Inc. <info@staikos.net>\br + Copyright (C) 2008 Kevin Ollivier <kevino@theolliviers.com> All Rights Reserved.\br + Copyright (C) 2005 Frerich Raabe <raabe@kde.org>\br + Copyright (C) 2005 Maksim Orlovich <maksim@kde.org>\br + Copyright (C) 2005, 2006 Kimmo Kinnunen <kimmo.t.kinnunen@nokia.com>.\br + Copyright (C) 2007-2009 Torch Mobile, Inc. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer.\br + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + \list + \o Parts of WebKit used by the QtWebKit module + \endlist + + \hr + + Copyright (C) 2009 University of Szeged\br + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer.\br + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + \list + \o Parts of WebKit used by the QtWebKit module + \endlist + + \hr + + Copyright (C) 2002 Michael Ringgaard. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer.\br + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution.\br + 3. Neither the name of the project nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + \list + \o src/3rdparty/ce-compat/ce_time.c + \endlist + + \hr + + Copyright (c) 1997-2005 University of Cambridge. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the name of Apple + Inc. nor the names of their contributors may be used to endorse or + promote products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + \list + \o Parts of WebKit used by the QtWebKit module + \endlist + + \hr + + Originally written by Philip Hazel\br + Copyright (c) 1997-2006 University of Cambridge\br + Copyright (C) 2007 Eric Seidel <eric@webkit.org>\br + Copyright (C) 2002, 2004, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + + -----------------------------------------------------------------------------\br + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + \list + \o Parts of WebKit used by the QtWebKit module + \endlist + + \hr + + Copyright (C) 2006 Apple Computer, Inc. All rights reserved.\br + Copyright (C) 2008 Google Inc. All rights reserved.\br + Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer.\br + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution.\br + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + \list + \o Parts of WebKit used by the QtWebKit module + \endlist */ /*! diff --git a/doc/src/modules.qdoc b/doc/src/modules.qdoc index 94cab58..3058b84 100644 --- a/doc/src/modules.qdoc +++ b/doc/src/modules.qdoc @@ -503,7 +503,7 @@ \ingroup modules \brief The QtXmlPatterns module provides support for XPath, - XQuery, XSLT and XML schema-validation. + XQuery, XSLT and XML Schema validation. To include the definitions of the module's classes, use the following directive: diff --git a/doc/src/platforms/compiler-notes.qdoc b/doc/src/platforms/compiler-notes.qdoc index 0ae32c3..8f1202d 100644 --- a/doc/src/platforms/compiler-notes.qdoc +++ b/doc/src/platforms/compiler-notes.qdoc @@ -196,7 +196,7 @@ \list \o Windows - Intel(R) C++ Compiler for 32-bit applications, - Version 8.1 Build 20050309Z Package ID: W_CC_PC_8.1.026 + Version 9.1.040. \o Altix - Intel(R) C++ Itanium(R) Compiler for Itanium(R)-based applications Version 8.1 Build 20050406 Package ID: l_cc_pc_8.1.030 \endlist diff --git a/doc/src/platforms/platform-notes.qdoc b/doc/src/platforms/platform-notes.qdoc index 68015a6..85b9ff8 100644 --- a/doc/src/platforms/platform-notes.qdoc +++ b/doc/src/platforms/platform-notes.qdoc @@ -515,11 +515,8 @@ In addition, there exists a backend for the Helix framework. However, due to it not shipping with Qt, its availability depends on the Symbian platform in use. If available, it is loaded in preference over the MMF - plugin. The Helix plugin requires Symbian signed capabilities. If the - application does not have those capabilities, the MMF plugin, if present on - the device, will be loaded instead. The capabilities the Helix backend - requires are AllFiles, DiskAdmin and MultimediaDD. - + plugin. If the Helix plugin fails to load, the MMF plugin, if present on + the device, will be loaded instead. */ /*! diff --git a/doc/src/platforms/supported-platforms.qdoc b/doc/src/platforms/supported-platforms.qdoc index be098bc..d0334f5 100644 --- a/doc/src/platforms/supported-platforms.qdoc +++ b/doc/src/platforms/supported-platforms.qdoc @@ -170,6 +170,6 @@ \o Drop support for Visual Studio 2003 \o Drop support for HP-UX on PA-RISC \o Drop support for Windows Mobile 5 - \o Drop support for OpenGL ES Common Lite + \o Drop support for OpenGL ES Common Lite 1.0 \endlist */ diff --git a/doc/src/snippets/code/doc_src_installation.qdoc b/doc/src/snippets/code/doc_src_installation.qdoc index 3563a64..c810706 100644 --- a/doc/src/snippets/code/doc_src_installation.qdoc +++ b/doc/src/snippets/code/doc_src_installation.qdoc @@ -41,13 +41,13 @@ //! [0] cd /tmp -gunzip qt-x11-opensource-desktop-%VERSION%.tar.gz # uncompress the archive -tar xvf qt-x11-opensource-desktop-%VERSION%.tar # unpack it +gunzip qt-everywhere-opensource-src-%VERSION%.tar.gz # uncompress the archive +tar xvf qt-everywhere-opensource-src-%VERSION%.tar # unpack it //! [0] //! [1] -cd /tmp/qt-x11-opensource-desktop-%VERSION% +cd /tmp/qt-everywhere-opensource-src-%VERSION% ./configure //! [1] @@ -102,13 +102,13 @@ nmake //! [11] cd /tmp -gunzip qt-mac-opensource-desktop-%VERSION%.tar.gz # uncompress the archive -tar xvf qt-mac-opensource-desktop-%VERSION%.tar # unpack it +gunzip qt-everywhere-opensource-src-%VERSION%.tar.gz # uncompress the archive +tar xvf qt-everywhere-opensource-src-%VERSION%.tar # unpack it //! [11] //! [12] -cd /tmp/qt-mac-opensource-desktop-%VERSION% +cd /tmp/qt-everywhere-opensource-src-%VERSION% ./configure //! [12] @@ -201,7 +201,7 @@ make sis QT_SIS_OPTIONS=-i QT_SIS_CERTIFICATE=<certificate file> QT_SIS_KEY=<cer //! [29] //! [30] -cd embedded\fluidlauncher +cd demos\embedded\fluidlauncher make sis QT_SIS_OPTIONS=-i //! [30] @@ -216,3 +216,7 @@ bldmake bldfiles abld build winscw udeb abld build gcce urel //! [32] + +//! [33] +SYMBIANBUILD_DEPENDENCYOFF=1 +//! [33] diff --git a/doc/src/snippets/code/src_corelib_kernel_qvariant.cpp b/doc/src/snippets/code/src_corelib_kernel_qvariant.cpp index 6b9923c..41a9cb3 100644 --- a/doc/src/snippets/code/src_corelib_kernel_qvariant.cpp +++ b/doc/src/snippets/code/src_corelib_kernel_qvariant.cpp @@ -65,7 +65,6 @@ QVariant x, y(QString()), z(QString("")); x.convert(QVariant::Int); // x.isNull() == true // y.isNull() == true, z.isNull() == false -// y.isEmpty() == true, z.isEmpty() == true //! [1] diff --git a/examples/dialogs/standarddialogs/dialog.cpp b/examples/dialogs/standarddialogs/dialog.cpp index 6e06190..270fdd0 100644 --- a/examples/dialogs/standarddialogs/dialog.cpp +++ b/examples/dialogs/standarddialogs/dialog.cpp @@ -124,7 +124,7 @@ Dialog::Dialog(QWidget *parent) errorLabel = new QLabel; errorLabel->setFrameStyle(frameStyle); QPushButton *errorButton = - new QPushButton(tr("QErrorMessage::show&M&essage()")); + new QPushButton(tr("QErrorMessage::showM&essage()")); connect(integerButton, SIGNAL(clicked()), this, SLOT(setInteger())); connect(doubleButton, SIGNAL(clicked()), this, SLOT(setDouble())); diff --git a/examples/graphicsview/anchorlayout/main.cpp b/examples/graphicsview/anchorlayout/main.cpp index f898d1d..389bc9e 100644 --- a/examples/graphicsview/anchorlayout/main.cpp +++ b/examples/graphicsview/anchorlayout/main.cpp @@ -122,8 +122,8 @@ int main(int argc, char **argv) scene.addItem(w); scene.setBackgroundBrush(Qt::darkGreen); - QGraphicsView *view = new QGraphicsView(&scene); - view->show(); + QGraphicsView view(&scene); + view.show(); return app.exec(); } diff --git a/examples/itemviews/frozencolumn/freezetablewidget.cpp b/examples/itemviews/frozencolumn/freezetablewidget.cpp index ee50ae1..72dc2a1 100644 --- a/examples/itemviews/frozencolumn/freezetablewidget.cpp +++ b/examples/itemviews/frozencolumn/freezetablewidget.cpp @@ -84,7 +84,8 @@ void FreezeTableWidget::init() //! [init part2] frozenTableView->setStyleSheet("QTableView { border: none;" - "background-color: #8EDE21;}"); //for demo purposes + "background-color: #8EDE21;" + "selection-background-color: #999}"); //for demo purposes frozenTableView->setSelectionModel(selectionModel()); for(int col=1; col<model()->columnCount(); col++) frozenTableView->setColumnHidden(col, true); @@ -146,6 +147,12 @@ QModelIndex FreezeTableWidget::moveCursor(CursorAction cursorAction, } //! [navigate] +void FreezeTableWidget::scrollTo (const QModelIndex & index, ScrollHint hint){ + if(index.column()>0) + QTableView::scrollTo(index, hint); +} + + //! [geometry] void FreezeTableWidget::updateFrozenTableGeometry() diff --git a/examples/itemviews/frozencolumn/freezetablewidget.h b/examples/itemviews/frozencolumn/freezetablewidget.h index 403890f..d236d40 100644 --- a/examples/itemviews/frozencolumn/freezetablewidget.h +++ b/examples/itemviews/frozencolumn/freezetablewidget.h @@ -56,6 +56,7 @@ public: protected: virtual void resizeEvent(QResizeEvent *event); virtual QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers); + void scrollTo (const QModelIndex & index, ScrollHint hint = EnsureVisible); private: QTableView *frozenTableView; diff --git a/examples/itemviews/frozencolumn/grades.txt b/examples/itemviews/frozencolumn/grades.txt index 4b55b473..e1c6fcc 100644 --- a/examples/itemviews/frozencolumn/grades.txt +++ b/examples/itemviews/frozencolumn/grades.txt @@ -32,4 +32,5 @@ 9a+ , , 5.15a , , , XI+ , , , , 12a 9b , , 5.15b , , , , , , , 12b -# Wikipedia contributors. Grade (climbing). Wikipedia, The Free Encyclopedia. May 15, 2009, 20:42 UTC. Available at: http://en.wikipedia.org/w/index.php?title=Grade_(climbing)&oldid=290165724. Accessed May 28, 2009. +# Wikipedia contributors. Grade (climbing). Wikipedia, The Free Encyclopedia. May 15, 2009, 20:42 UTC. +# Available at: http://en.wikipedia.org/w/index.php?title=Grade_(climbing)&oldid=290165724. Accessed May 28, 2009. diff --git a/examples/network/broadcastreceiver/receiver.cpp b/examples/network/broadcastreceiver/receiver.cpp index 0a5922b..7889a05 100644 --- a/examples/network/broadcastreceiver/receiver.cpp +++ b/examples/network/broadcastreceiver/receiver.cpp @@ -52,7 +52,7 @@ Receiver::Receiver(QWidget *parent) //! [0] udpSocket = new QUdpSocket(this); - udpSocket->bind(45454); + udpSocket->bind(45454, QUdpSocket::ShareAddress); //! [0] //! [1] diff --git a/examples/script/helloscript/helloscript.qs b/examples/script/helloscript/helloscript.js index 6d8e87c..6d8e87c 100644 --- a/examples/script/helloscript/helloscript.qs +++ b/examples/script/helloscript/helloscript.js diff --git a/examples/script/helloscript/helloscript.qrc b/examples/script/helloscript/helloscript.qrc index dc93461..c52fa15 100644 --- a/examples/script/helloscript/helloscript.qrc +++ b/examples/script/helloscript/helloscript.qrc @@ -1,5 +1,5 @@ <RCC> <qresource prefix="/" > - <file>helloscript.qs</file> + <file>helloscript.js</file> </qresource> </RCC> diff --git a/examples/script/helloscript/main.cpp b/examples/script/helloscript/main.cpp index bc9a65e..55d63bf 100644 --- a/examples/script/helloscript/main.cpp +++ b/examples/script/helloscript/main.cpp @@ -68,7 +68,7 @@ int main(int argc, char *argv[]) //! [2] //! [3] - QString fileName(":/helloscript.qs"); + QString fileName(":/helloscript.js"); QFile scriptFile(fileName); scriptFile.open(QIODevice::ReadOnly); QTextStream stream(&scriptFile); diff --git a/examples/script/qsdbg/example.qs b/examples/script/qsdbg/example.js index 47c1363..47c1363 100644 --- a/examples/script/qsdbg/example.qs +++ b/examples/script/qsdbg/example.js diff --git a/examples/script/qsdbg/main.cpp b/examples/script/qsdbg/main.cpp index 526de0c..2a86c3d 100644 --- a/examples/script/qsdbg/main.cpp +++ b/examples/script/qsdbg/main.cpp @@ -39,14 +39,17 @@ ** ****************************************************************************/ +#include <QtCore/QCoreApplication> #include <QtScript> #include "scriptdebugger.h" int main(int argc, char **argv) { + QCoreApplication app(argc, argv); + if (argc < 2) { - fprintf(stderr, "*** you must specify a script file to evaluate (try example.qs)\n"); + fprintf(stderr, "*** you must specify a script file to evaluate (try example.js)\n"); return(-1); } diff --git a/examples/webkit/domtraversal/window.h b/examples/webkit/domtraversal/window.h index 5988df9..2795976 100644 --- a/examples/webkit/domtraversal/window.h +++ b/examples/webkit/domtraversal/window.h @@ -46,7 +46,9 @@ #include <QUrl> #include <QWebElement> +QT_BEGIN_NAMESPACE class QTreeWidgetItem; +QT_END_NAMESPACE //! [Window class definition] #include "ui_window.h" diff --git a/examples/widgets/scribble/scribblearea.cpp b/examples/widgets/scribble/scribblearea.cpp index 6c9d8aa..2bc2a69 100644 --- a/examples/widgets/scribble/scribblearea.cpp +++ b/examples/widgets/scribble/scribblearea.cpp @@ -139,11 +139,12 @@ void ScribbleArea::mouseReleaseEvent(QMouseEvent *event) } //! [12] //! [13] -void ScribbleArea::paintEvent(QPaintEvent * /* event */) +void ScribbleArea::paintEvent(QPaintEvent *event) //! [13] //! [14] { QPainter painter(this); - painter.drawImage(QPoint(0, 0), image); + QRect dirtyRect = event->rect(); + painter.drawImage(dirtyRect, image, dirtyRect); } //! [14] diff --git a/examples/widgets/softkeys/softkeys.cpp b/examples/widgets/softkeys/softkeys.cpp index 69b4941..d1586a5 100644 --- a/examples/widgets/softkeys/softkeys.cpp +++ b/examples/widgets/softkeys/softkeys.cpp @@ -66,11 +66,11 @@ MainWindow::MainWindow(QWidget *parent) infoLabel = new QLabel(tr(""), this); infoLabel->setContextMenuPolicy(Qt::NoContextMenu); - toggleButton = new QPushButton(tr("Custom softkeys"), this); + toggleButton = new QPushButton(tr("Custom"), this); toggleButton->setContextMenuPolicy(Qt::NoContextMenu); toggleButton->setCheckable(true); - pushButton = new QPushButton(tr("Open File Dialog"), this); + pushButton = new QPushButton(tr("File Dialog"), this); pushButton->setContextMenuPolicy(Qt::NoContextMenu); QComboBox* comboBox = new QComboBox(this); @@ -81,12 +81,12 @@ MainWindow::MainWindow(QWidget *parent) << QApplication::translate("MainWindow", "Selection3", 0, QApplication::UnicodeUTF8) ); - layout = new QVBoxLayout; - layout->addWidget(textEditor); - layout->addWidget(infoLabel); - layout->addWidget(toggleButton); - layout->addWidget(pushButton); - layout->addWidget(comboBox); + layout = new QGridLayout; + layout->addWidget(textEditor, 0, 0, 1, 2); + layout->addWidget(infoLabel, 1, 0, 1, 2); + layout->addWidget(toggleButton, 2, 0); + layout->addWidget(pushButton, 2, 1); + layout->addWidget(comboBox, 3, 0, 1, 2); central->setLayout(layout); fileMenu = menuBar()->addMenu(tr("&File")); diff --git a/examples/widgets/softkeys/softkeys.h b/examples/widgets/softkeys/softkeys.h index 178ae64..1372fa4 100644 --- a/examples/widgets/softkeys/softkeys.h +++ b/examples/widgets/softkeys/softkeys.h @@ -61,7 +61,7 @@ public: MainWindow(QWidget *parent = 0); ~MainWindow(); private: - QVBoxLayout *layout; + QGridLayout *layout; QWidget *central; QTextEdit* textEditor; QLabel *infoLabel; diff --git a/examples/widgets/stylesheet/mainwindow.ui b/examples/widgets/stylesheet/mainwindow.ui index 740d37b..2b232df 100644 --- a/examples/widgets/stylesheet/mainwindow.ui +++ b/examples/widgets/stylesheet/mainwindow.ui @@ -41,7 +41,7 @@ <string>Please read the LICENSE file before checking</string> </property> <property name="text" > - <string>I &accept the terms and &conditions</string> + <string>I accept the terms and &conditions</string> </property> </widget> </item> diff --git a/examples/widgets/tablet/tabletcanvas.cpp b/examples/widgets/tablet/tabletcanvas.cpp index 130498b..20b0d1e 100644 --- a/examples/widgets/tablet/tabletcanvas.cpp +++ b/examples/widgets/tablet/tabletcanvas.cpp @@ -50,7 +50,7 @@ TabletCanvas::TabletCanvas() resize(500, 500); myBrush = QBrush(); myPen = QPen(); - initImage(); + initPixmap(); setAutoFillBackground(true); deviceDown = false; myColor = Qt::red; @@ -60,29 +60,29 @@ TabletCanvas::TabletCanvas() lineWidthType = LineWidthPressure; } -void TabletCanvas::initImage() +void TabletCanvas::initPixmap() { - QImage newImage = QImage(width(), height(), QImage::Format_ARGB32); - QPainter painter(&newImage); - painter.fillRect(0, 0, newImage.width(), newImage.height(), Qt::white); - if (!image.isNull()) - painter.drawImage(0, 0, image); + QPixmap newPixmap = QPixmap(width(), height()); + newPixmap.fill(Qt::white); + QPainter painter(&newPixmap); + if (!pixmap.isNull()) + painter.drawPixmap(0, 0, pixmap); painter.end(); - image = newImage; + pixmap = newPixmap; } //! [0] //! [1] bool TabletCanvas::saveImage(const QString &file) { - return image.save(file); + return pixmap.save(file); } //! [1] //! [2] bool TabletCanvas::loadImage(const QString &file) { - bool success = image.load(file); + bool success = pixmap.load(file); if (success) { update(); @@ -114,8 +114,8 @@ void TabletCanvas::tabletEvent(QTabletEvent *event) if (deviceDown) { updateBrush(event); - QPainter painter(&image); - paintImage(painter, event); + QPainter painter(&pixmap); + paintPixmap(painter, event); } break; default: @@ -129,12 +129,12 @@ void TabletCanvas::tabletEvent(QTabletEvent *event) void TabletCanvas::paintEvent(QPaintEvent *) { QPainter painter(this); - painter.drawImage(QPoint(0, 0), image); + painter.drawPixmap(0, 0, pixmap); } //! [4] //! [5] -void TabletCanvas::paintImage(QPainter &painter, QTabletEvent *event) +void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event) { QPoint brushAdjust(10, 10); @@ -271,6 +271,6 @@ void TabletCanvas::updateBrush(QTabletEvent *event) void TabletCanvas::resizeEvent(QResizeEvent *) { - initImage(); + initPixmap(); polyLine[0] = polyLine[1] = polyLine[2] = QPoint(); } diff --git a/examples/widgets/tablet/tabletcanvas.h b/examples/widgets/tablet/tabletcanvas.h index 02b8794..5a2fb1d 100644 --- a/examples/widgets/tablet/tabletcanvas.h +++ b/examples/widgets/tablet/tabletcanvas.h @@ -43,7 +43,7 @@ #define TABLETCANVAS_H #include <QWidget> -#include <QImage> +#include <QPixmap> #include <QPoint> #include <QTabletEvent> #include <QColor> @@ -92,8 +92,8 @@ protected: void resizeEvent(QResizeEvent *event); private: - void initImage(); - void paintImage(QPainter &painter, QTabletEvent *event); + void initPixmap(); + void paintPixmap(QPainter &painter, QTabletEvent *event); Qt::BrushStyle brushPattern(qreal value); void updateBrush(QTabletEvent *event); @@ -104,7 +104,7 @@ private: QTabletEvent::TabletDevice myTabletDevice; QColor myColor; - QImage image; + QPixmap pixmap; QBrush myBrush; QPen myPen; bool deviceDown; diff --git a/examples/xml/saxbookmarks/mainwindow.cpp b/examples/xml/saxbookmarks/mainwindow.cpp index 49cb468..ff3cf11 100644 --- a/examples/xml/saxbookmarks/mainwindow.cpp +++ b/examples/xml/saxbookmarks/mainwindow.cpp @@ -67,8 +67,11 @@ MainWindow::MainWindow() void MainWindow::open() { #if defined(Q_OS_SYMBIAN) - // Always look for bookmarks on the same drive where the application is installed to. - QString bookmarksFolder = QCoreApplication::applicationFilePath().left(1); + // Look for bookmarks on the same drive where the application is installed to, + // if drive is not read only. QDesktopServices::DataLocation does this check, + // and returns writable drive. + QString bookmarksFolder = + QDesktopServices::storageLocation(QDesktopServices::DataLocation).left(1); bookmarksFolder.append(":/Data/qt/saxbookmarks"); QDir::setCurrent(bookmarksFolder); #endif diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index 79bac42..0f06b92 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -7,7 +7,7 @@ CONFIG += qt warn_on release incremental QT += core gui QMAKE_INCREMENTAL_STYLE = sublib -DEFINES += UNICODE QT_KEYPAD_NAVIGATION QT_SOFTKEYS_ENABLED +DEFINES += UNICODE QT_KEYPAD_NAVIGATION QT_SOFTKEYS_ENABLED QT_USE_MATH_H_FLOATS QMAKE_COMPILER_DEFINES += SYMBIAN QMAKE_EXT_OBJ = .o diff --git a/mkspecs/linux-g++-gles2-experimental/qmake.conf b/mkspecs/linux-g++-gles2-experimental/qmake.conf deleted file mode 100644 index 9c28d17..0000000 --- a/mkspecs/linux-g++-gles2-experimental/qmake.conf +++ /dev/null @@ -1,22 +0,0 @@ -# -# Experimental qmake configuration for GLES2 -# - -MAKEFILE_GENERATOR = UNIX -TEMPLATE = app -CONFIG += qt warn_on release incremental link_prl -QT += core gui -QMAKE_INCREMENTAL_STYLE = sublib - -include(../common/g++.conf) - -QMAKE_LFLAGS += -Wl,-rpath-link=/usr/lib - -include(../common/linux.conf) - -QMAKE_LIBS_EGL = -lEGL -QMAKE_LIBS_OPENGL = -lGLESv2 -QMAKE_LIBS_OPENGL_QT = -lGLESv2 -lEGL - - -load(qt_config) diff --git a/mkspecs/linux-g++-gles2-experimental/qplatformdefs.h b/mkspecs/linux-g++-gles2-experimental/qplatformdefs.h deleted file mode 100644 index ecfbc73..0000000 --- a/mkspecs/linux-g++-gles2-experimental/qplatformdefs.h +++ /dev/null @@ -1,166 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the qmake spec 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 QPLATFORMDEFS_H -#define QPLATFORMDEFS_H - -// Get Qt defines/settings - -#include "qglobal.h" - -// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs - -// 1) need to reset default environment if _BSD_SOURCE is defined -// 2) need to specify POSIX thread interfaces explicitly in glibc 2.0 -// 3) it seems older glibc need this to include the X/Open stuff -#ifndef _GNU_SOURCE -# define _GNU_SOURCE -#endif - -#include <unistd.h> - - -// We are hot - unistd.h should have turned on the specific APIs we requested - -#include <features.h> -#include <pthread.h> -#include <dirent.h> -#include <fcntl.h> -#include <grp.h> -#include <pwd.h> -#include <signal.h> -#include <dlfcn.h> - -#include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/ipc.h> -#include <sys/time.h> -#include <sys/shm.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <netinet/in.h> -#ifndef QT_NO_IPV6IFNAME -#include <net/if.h> -#endif - -#ifdef QT_LARGEFILE_SUPPORT -#define QT_STATBUF struct stat64 -#define QT_STATBUF4TSTAT struct stat64 -#define QT_STAT ::stat64 -#define QT_FSTAT ::fstat64 -#define QT_LSTAT ::lstat64 -#define QT_OPEN ::open64 -#define QT_TRUNCATE ::truncate64 -#define QT_FTRUNCATE ::ftruncate64 -#define QT_LSEEK ::lseek64 -#else -#define QT_STATBUF struct stat -#define QT_STATBUF4TSTAT struct stat -#define QT_STAT ::stat -#define QT_FSTAT ::fstat -#define QT_LSTAT ::lstat -#define QT_OPEN ::open -#define QT_TRUNCATE ::truncate -#define QT_FTRUNCATE ::ftruncate -#define QT_LSEEK ::lseek -#endif - -#ifdef QT_LARGEFILE_SUPPORT -#define QT_FOPEN ::fopen64 -#define QT_FSEEK ::fseeko64 -#define QT_FTELL ::ftello64 -#define QT_FGETPOS ::fgetpos64 -#define QT_FSETPOS ::fsetpos64 -#define QT_MMAP ::mmap64 -#define QT_FPOS_T fpos64_t -#define QT_OFF_T off64_t -#else -#define QT_FOPEN ::fopen -#define QT_FSEEK ::fseek -#define QT_FTELL ::ftell -#define QT_FGETPOS ::fgetpos -#define QT_FSETPOS ::fsetpos -#define QT_MMAP ::mmap -#define QT_FPOS_T fpos_t -#define QT_OFF_T long -#endif - -#define QT_STAT_REG S_IFREG -#define QT_STAT_DIR S_IFDIR -#define QT_STAT_MASK S_IFMT -#define QT_STAT_LNK S_IFLNK -#define QT_SOCKET_CONNECT ::connect -#define QT_SOCKET_BIND ::bind -#define QT_FILENO fileno -#define QT_CLOSE ::close -#define QT_READ ::read -#define QT_WRITE ::write -#define QT_ACCESS ::access -#define QT_GETCWD ::getcwd -#define QT_CHDIR ::chdir -#define QT_MKDIR ::mkdir -#define QT_RMDIR ::rmdir -#define QT_OPEN_LARGEFILE O_LARGEFILE -#define QT_OPEN_RDONLY O_RDONLY -#define QT_OPEN_WRONLY O_WRONLY -#define QT_OPEN_RDWR O_RDWR -#define QT_OPEN_CREAT O_CREAT -#define QT_OPEN_TRUNC O_TRUNC -#define QT_OPEN_APPEND O_APPEND - -#define QT_SIGNAL_RETTYPE void -#define QT_SIGNAL_ARGS int -#define QT_SIGNAL_IGNORE SIG_IGN - -#if defined(__GLIBC__) && (__GLIBC__ >= 2) -#define QT_SOCKLEN_T socklen_t -#else -#define QT_SOCKLEN_T int -#endif - -#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500) -#define QT_SNPRINTF ::snprintf -#define QT_VSNPRINTF ::vsnprintf -#endif - - -#endif // QPLATFORMDEFS_H diff --git a/mkspecs/unsupported/linux-host-g++/qmake.conf b/mkspecs/unsupported/linux-host-g++/qmake.conf new file mode 100644 index 0000000..237477c --- /dev/null +++ b/mkspecs/unsupported/linux-host-g++/qmake.conf @@ -0,0 +1,138 @@ +# +# QMake configuration for Scratchbox's host-gcc compiler. +# +# This mkspec can be used as the platform mkspec when building +# Qt in scratchbox. If used as such, qmake and similar host +# tools will be compiled for the host architecture (E.g. x86) +# and thus not run in the emulator. This results in a +# significant improvement in build times. +# +# Note: The mkspec copied & pasted parts from common/gcc.conf +# and common/linux.conf as setBootstrapVariable in +# configure has a bug which stops re-assignments working +# for QMake variables (I.e. "QMAKE_foo = bar" is broken). + +MAKEFILE_GENERATOR = UNIX +TEMPLATE = app +CONFIG += qt warn_on release incremental link_prl +QT += core gui +QMAKE_INCREMENTAL_STYLE = sublib + +# +# qmake configuration for common gcc +# + +QMAKE_CC = host-gcc +QMAKE_CFLAGS += -pipe +QMAKE_CFLAGS_DEPS += -M +QMAKE_CFLAGS_WARN_ON += -Wall -W +QMAKE_CFLAGS_WARN_OFF += -w +QMAKE_CFLAGS_RELEASE += -O2 +QMAKE_CFLAGS_DEBUG += -g +QMAKE_CFLAGS_SHLIB += -fPIC +QMAKE_CFLAGS_STATIC_LIB += -fPIC +QMAKE_CFLAGS_YACC += -Wno-unused -Wno-parentheses +QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden +QMAKE_CFLAGS_PRECOMPILE += -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} +QMAKE_CFLAGS_USE_PRECOMPILE += -include ${QMAKE_PCH_OUTPUT_BASE} + +QMAKE_CXX = host-g++ +QMAKE_CXXFLAGS += $$QMAKE_CFLAGS +QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS +QMAKE_CXXFLAGS_WARN_ON += $$QMAKE_CFLAGS_WARN_ON +QMAKE_CXXFLAGS_WARN_OFF += $$QMAKE_CFLAGS_WARN_OFF +QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE +QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG +QMAKE_CXXFLAGS_SHLIB += $$QMAKE_CFLAGS_SHLIB +QMAKE_CXXFLAGS_STATIC_LIB += $$QMAKE_CFLAGS_STATIC_LIB +QMAKE_CXXFLAGS_YACC += $$QMAKE_CFLAGS_YACC +QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden +QMAKE_CXXFLAGS_PRECOMPILE += -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} +QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE + +QMAKE_LINK = host-g++ +QMAKE_LINK_SHLIB = host-g++ +QMAKE_LINK_C = host-gcc +QMAKE_LINK_C_SHLIB = host-gcc +QMAKE_LFLAGS += +QMAKE_LFLAGS_RELEASE += -Wl,-O1 +QMAKE_LFLAGS_DEBUG += +QMAKE_LFLAGS_APP += +QMAKE_LFLAGS_SHLIB += -shared +QMAKE_LFLAGS_PLUGIN += $$QMAKE_LFLAGS_SHLIB +QMAKE_LFLAGS_SONAME += -Wl,-soname, +QMAKE_LFLAGS_THREAD += +QMAKE_LFLAGS_NOUNDEF += -Wl,--no-undefined +QMAKE_RPATH = -Wl,-rpath, + +QMAKE_PCH_OUTPUT_EXT = .gch + +# -Bsymbolic-functions (ld) support +QMAKE_LFLAGS_BSYMBOLIC_FUNC = -Wl,-Bsymbolic-functions +QMAKE_LFLAGS_DYNAMIC_LIST = -Wl,--dynamic-list, + +# +# qmake configuration for common linux +# + +QMAKE_CFLAGS_THREAD += -D_REENTRANT +QMAKE_CXXFLAGS_THREAD += $$QMAKE_CFLAGS_THREAD + +QMAKE_INCDIR = +QMAKE_LIBDIR = +QMAKE_INCDIR_X11 = /usr/X11R6/include +QMAKE_LIBDIR_X11 = /usr/X11R6/lib +QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] +QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] +QMAKE_INCDIR_OPENGL = /usr/X11R6/include +QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib +QMAKE_INCDIR_OPENGL_ES1 = $$QMAKE_INCDIR_OPENGL +QMAKE_LIBDIR_OPENGL_ES1 = $$QMAKE_LIBDIR_OPENGL +QMAKE_INCDIR_OPENGL_ES1CL = $$QMAKE_INCDIR_OPENGL +QMAKE_LIBDIR_OPENGL_ES1CL = $$QMAKE_LIBDIR_OPENGL +QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_INCDIR_OPENGL +QMAKE_LIBDIR_OPENGL_ES2 = $$QMAKE_LIBDIR_OPENGL +QMAKE_INCDIR_EGL = +QMAKE_LIBDIR_EGL = +QMAKE_INCDIR_OPENVG = +QMAKE_LIBDIR_OPENVG = + +QMAKE_LIBS = +QMAKE_LIBS_DYNLOAD = -ldl +QMAKE_LIBS_X11 = -lXext -lX11 -lm +QMAKE_LIBS_X11SM = -lSM -lICE +QMAKE_LIBS_NIS = -lnsl +QMAKE_LIBS_EGL = -lEGL +QMAKE_LIBS_OPENGL = -lGLU -lGL +QMAKE_LIBS_OPENGL_QT = -lGL +QMAKE_LIBS_OPENGL_ES1 = -lGLES_CM +QMAKE_LIBS_OPENGL_ES1CL = -lGLES_CL +QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 +QMAKE_LIBS_OPENVG = -lOpenVG +QMAKE_LIBS_THREAD = -lpthread + +QMAKE_MOC = $$[QT_INSTALL_BINS]/moc +QMAKE_UIC = $$[QT_INSTALL_BINS]/uic + +QMAKE_AR = host-ar cqs +QMAKE_OBJCOPY = host-objcopy +QMAKE_RANLIB = + +QMAKE_TAR = tar -cf +QMAKE_GZIP = gzip -9f + +QMAKE_COPY = cp -f +QMAKE_COPY_FILE = $(COPY) +QMAKE_COPY_DIR = $(COPY) -r +QMAKE_MOVE = mv -f +QMAKE_DEL_FILE = rm -f +QMAKE_DEL_DIR = rmdir +QMAKE_STRIP = host-strip +QMAKE_STRIPFLAGS_LIB += --strip-unneeded +QMAKE_CHK_DIR_EXISTS = test -d +QMAKE_MKDIR = mkdir -p +QMAKE_INSTALL_FILE = install -m 644 -p +QMAKE_INSTALL_PROGRAM = install -m 755 -p + +include(../common/unix.conf) +load(qt_config) diff --git a/mkspecs/unsupported/linux-host-g++/qplatformdefs.h b/mkspecs/unsupported/linux-host-g++/qplatformdefs.h new file mode 100644 index 0000000..60e0f5e --- /dev/null +++ b/mkspecs/unsupported/linux-host-g++/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake spec 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 "../../linux-g++/qplatformdefs.h" diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index afaf338..8379ed9 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -77,6 +77,15 @@ #define MMP_LINKEROPTION_CW "LINKEROPTION CW" #define MMP_LINKEROPTION_ARMCC "LINKEROPTION ARMCC" #define MMP_LINKEROPTION_GCCE "LINKEROPTION GCCE" +#define MMP_CAPABILITY "CAPABILITY" +#define MMP_EPOCALLOWDLLDATA "EPOCALLOWDLLDATA" +#define MMP_EPOCHEAPSIZE "EPOCHEAPSIZE" +#define MMP_EPOCSTACKSIZE "EPOCSTACKSIZE" +#define MMP_UID "UID" +#define MMP_VENDORID "VENDORID" +#define MMP_VERSION "VERSION" +#define MMP_START_RESOURCE "START RESOURCE" +#define MMP_END_RESOURCE "END" #define SIS_TARGET "sis" #define OK_SIS_TARGET "ok_sis" @@ -155,7 +164,7 @@ void SymbianMakefileGenerator::writeHeader(QTextStream &t) { t << "// ============================================================================" << endl; t << "// * Makefile for building: " << escapeFilePath(var("TARGET")) << endl; - t << "// * Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: "; + t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; t << "// * This file is generated by qmake and should not be modified by the" << endl; t << "// * user." << endl; @@ -444,7 +453,7 @@ void SymbianMakefileGenerator::writeCustomDefFile() QTextStream t(&ft); t << "; ==============================================================================" << endl; - t << "; Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: "; + t << "; Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; t << "; This file is generated by qmake and should not be modified by the" << endl; t << "; user." << endl; @@ -646,30 +655,76 @@ void SymbianMakefileGenerator::initMmpVariables() // Check MMP_RULES for singleton keywords that are overridden QStringList overridableMmpKeywords; + QStringList restrictableMmpKeywords; + QStringList restrictedMmpKeywords; + bool inResourceBlock = false; + overridableMmpKeywords << QLatin1String(MMP_TARGETTYPE); + restrictableMmpKeywords << QLatin1String(MMP_TARGET) << QLatin1String(MMP_SECUREID) + << QLatin1String(MMP_OPTION_CW) << QLatin1String(MMP_OPTION_ARMCC) + << QLatin1String(MMP_OPTION_GCCE) << QLatin1String(MMP_LINKEROPTION_CW) + << QLatin1String(MMP_LINKEROPTION_ARMCC) << QLatin1String(MMP_LINKEROPTION_GCCE) + << QLatin1String(MMP_CAPABILITY) << QLatin1String(MMP_EPOCALLOWDLLDATA) + << QLatin1String(MMP_EPOCHEAPSIZE) << QLatin1String(MMP_EPOCSTACKSIZE) + << QLatin1String(MMP_UID) << QLatin1String(MMP_VENDORID) + << QLatin1String(MMP_VERSION); foreach (QString item, project->values("MMP_RULES")) { if (project->values(item).isEmpty()) { - checkOverridability(overridableMmpKeywords, item); + handleMmpRulesOverrides(item, inResourceBlock, restrictedMmpKeywords, + restrictableMmpKeywords, overridableMmpKeywords); } else { foreach (QString itemRow, project->values(item)) { - checkOverridability(overridableMmpKeywords, itemRow); + handleMmpRulesOverrides(itemRow, inResourceBlock, restrictedMmpKeywords, + restrictableMmpKeywords, overridableMmpKeywords); } } } + + if (restrictedMmpKeywords.size()) { + fprintf(stderr, "Warning: Restricted statements detected in MMP_RULES:\n" + " (%s)\n" + " Use corresponding qmake variable(s) instead.\n", + qPrintable(restrictedMmpKeywords.join(", "))); + } } -void SymbianMakefileGenerator::checkOverridability(QStringList &overridableKeywords, QString &checkString) +void SymbianMakefileGenerator::handleMmpRulesOverrides(QString &checkString, + bool &inResourceBlock, + QStringList &restrictedMmpKeywords, + const QStringList &restrictableMmpKeywords, + const QStringList &overridableMmpKeywords) { - // Check if checkString contains overridable keyword and - // add the keyword to overridden keywords list if so. QString simplifiedString = checkString.simplified(); - foreach (QString item, overridableKeywords) { - if (simplifiedString.startsWith(item)) - appendIfnotExist(overriddenMmpKeywords, item); + + if (!inResourceBlock && simplifiedString.startsWith(MMP_START_RESOURCE, Qt::CaseInsensitive)) + inResourceBlock = true; + else if (inResourceBlock && simplifiedString.startsWith(MMP_END_RESOURCE, Qt::CaseInsensitive)) + inResourceBlock = false; + + // Allow restricted and overridable items in RESOURCE blocks as those do not actually + // override anything. + if (!inResourceBlock) { + appendKeywordIfMatchFound(overriddenMmpKeywords, overridableMmpKeywords, simplifiedString); + appendKeywordIfMatchFound(restrictedMmpKeywords, restrictableMmpKeywords, simplifiedString); + } +} + +void SymbianMakefileGenerator::appendKeywordIfMatchFound(QStringList &list, + const QStringList &keywordList, + QString &checkString) +{ + // Check if checkString starts with any supplied keyword and + // add the found keyword to list if it does. + foreach (QString item, keywordList) { + if (checkString.startsWith(QString(item).append(" "), Qt::CaseInsensitive) + || checkString.compare(item, Qt::CaseInsensitive) == 0) { + appendIfnotExist(list, item); + } } } + bool SymbianMakefileGenerator::removeDuplicatedStrings(QStringList &stringList) { QStringList tmpStringList; @@ -690,7 +745,7 @@ bool SymbianMakefileGenerator::removeDuplicatedStrings(QStringList &stringList) void SymbianMakefileGenerator::writeMmpFileHeader(QTextStream &t) { t << "// ==============================================================================" << endl; - t << "// Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: "; + t << "// Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; t << "// This file is generated by qmake and should not be modified by the" << endl; t << "// user." << endl; @@ -775,7 +830,7 @@ void SymbianMakefileGenerator::writeMmpFileMacrosPart(QTextStream& t) void SymbianMakefileGenerator::addMacro(QTextStream& t, const QString& value) { - t << "MACRO" << "\t\t" << value << endl; + t << "MACRO\t\t" << value << endl; } @@ -784,28 +839,28 @@ void SymbianMakefileGenerator::writeMmpFileTargetPart(QTextStream& t) bool skipTargetType = overriddenMmpKeywords.contains(MMP_TARGETTYPE); if (targetType == TypeExe) { - t << MMP_TARGET << "\t\t" << fixedTarget << ".exe" << endl; + t << MMP_TARGET "\t\t" << fixedTarget << ".exe" << endl; if (!skipTargetType) { if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive)) - t << MMP_TARGETTYPE << "\t\t" << "STDEXE" << endl; + t << MMP_TARGETTYPE "\t\tSTDEXE" << endl; else - t << MMP_TARGETTYPE << "\t\t" << "EXE" << endl; + t << MMP_TARGETTYPE "\t\tEXE" << endl; } } else if (targetType == TypeDll || targetType == TypePlugin) { - t << MMP_TARGET << "\t\t" << fixedTarget << ".dll" << endl; + t << MMP_TARGET "\t\t" << fixedTarget << ".dll" << endl; if (!skipTargetType) { if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive)) - t << MMP_TARGETTYPE << "\t\t" << "STDDLL" << endl; + t << MMP_TARGETTYPE "\t\tSTDDLL" << endl; else - t << MMP_TARGETTYPE << "\t\t" << "DLL" << endl; + t << MMP_TARGETTYPE "\t\tDLL" << endl; } } else if (targetType == TypeLib) { - t << MMP_TARGET << "\t\t" << fixedTarget << ".lib" << endl; + t << MMP_TARGET "\t\t" << fixedTarget << ".lib" << endl; if (!skipTargetType) { if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive)) - t << MMP_TARGETTYPE << "\t\t" << "STDLIB" << endl; + t << MMP_TARGETTYPE "\t\tSTDLIB" << endl; else - t << MMP_TARGETTYPE << "\t\t" << "LIB" << endl; + t << MMP_TARGETTYPE "\t\tLIB" << endl; } } else { fprintf(stderr, "Error: Unexpected targettype (%d) in SymbianMakefileGenerator::writeMmpFileTargetPart\n", targetType); @@ -813,30 +868,30 @@ void SymbianMakefileGenerator::writeMmpFileTargetPart(QTextStream& t) t << endl; - t << "UID" << "\t\t" << uid2 << " " << uid3 << endl; + t << MMP_UID "\t\t" << uid2 << " " << uid3 << endl; if (0 != project->values("TARGET.SID").size()) { - t << MMP_SECUREID << "\t\t" << project->values("TARGET.SID").join(" ") << endl; + t << MMP_SECUREID "\t\t" << project->values("TARGET.SID").join(" ") << endl; } else { if (0 == uid3.size()) - t << MMP_SECUREID << "\t\t" << "0" << endl; + t << MMP_SECUREID "\t\t0" << endl; else - t << MMP_SECUREID << "\t\t" << uid3 << endl; + t << MMP_SECUREID "\t\t" << uid3 << endl; } // default value used from mkspecs is 0 if (0 != project->values("TARGET.VID").size()) { - t << "VENDORID" << "\t\t" << project->values("TARGET.VID").join(" ") << endl; + t << MMP_VENDORID "\t\t" << project->values("TARGET.VID").join(" ") << endl; } t << endl; if (0 != project->first("TARGET.EPOCSTACKSIZE").size()) - t << "EPOCSTACKSIZE" << "\t\t" << project->first("TARGET.EPOCSTACKSIZE") << endl; + t << MMP_EPOCSTACKSIZE "\t\t" << project->first("TARGET.EPOCSTACKSIZE") << endl; if (0 != project->values("TARGET.EPOCHEAPSIZE").size()) - t << "EPOCHEAPSIZE" << "\t\t" << project->values("TARGET.EPOCHEAPSIZE").join(" ") << endl; + t << MMP_EPOCHEAPSIZE "\t\t" << project->values("TARGET.EPOCHEAPSIZE").join(" ") << endl; if (0 != project->values("TARGET.EPOCALLOWDLLDATA").size()) - t << "EPOCALLOWDLLDATA" << endl; + t << MMP_EPOCALLOWDLLDATA << endl; if (targetType == TypePlugin && !project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive)) { // Use custom def file for Qt plugins @@ -865,20 +920,20 @@ void SymbianMakefileGenerator::writeMmpFileResourcePart(QTextStream& t, QStringL t << lang << " "; // no endl } t << endl; - t << "START RESOURCE\t\t" << locTarget << endl; + t << MMP_START_RESOURCE "\t\t" << locTarget << endl; t << "HEADER" << endl; t << "TARGETPATH\t\t\t" RESOURCE_DIRECTORY_MMP << endl; - t << "END" << endl << endl; + t << MMP_END_RESOURCE << endl << endl; QString regTarget = fixedTarget; regTarget.append("_reg.rss"); t << "SOURCEPATH\t\t\t." << endl; - t << "START RESOURCE\t\t" << regTarget << endl; + t << MMP_START_RESOURCE "\t\t" << regTarget << endl; if (isForSymbianSbsv2()) t << "DEPENDS " << fixedTarget << ".rsg" << endl; t << "TARGETPATH\t\t" REGISTRATION_RESOURCE_DIRECTORY_HW << endl; - t << "END" << endl << endl; + t << MMP_END_RESOURCE << endl << endl; } } @@ -890,7 +945,7 @@ void SymbianMakefileGenerator::writeMmpFileSystemIncludePart(QTextStream& t) QStringList values = it.value(); for (int i = 0; i < values.size(); ++i) { QString handledPath = values.at(i); - t << "SYSTEMINCLUDE" << "\t\t" << fixPathForMmp(handledPath, current) << endl; + t << "SYSTEMINCLUDE\t\t" << fixPathForMmp(handledPath, current) << endl; } } @@ -946,14 +1001,14 @@ void SymbianMakefileGenerator::writeMmpFileCapabilityPart(QTextStream& t) { if (0 != project->first("TARGET.CAPABILITY").size()) { QStringList &capabilities = project->values("TARGET.CAPABILITY"); - t << "CAPABILITY" << "\t\t"; + t << MMP_CAPABILITY "\t\t"; for (int i = 0; i < capabilities.size(); ++i) { QString cap = capabilities.at(i); t << cap << " "; } } else { - t << "CAPABILITY" << "\t\t" << "None"; + t << MMP_CAPABILITY "\t\tNone"; } t << endl << endl; } @@ -1048,21 +1103,21 @@ void SymbianMakefileGenerator::writeMmpFileCompilerOptionPart(QTextStream& t) if (!gccelink.isEmpty() && gccelink[gccelink.size()-1] == ' ') gccelink.chop(1); - if (!cw.isEmpty() && !overriddenMmpKeywords.contains(MMP_OPTION_CW)) + if (!cw.isEmpty()) t << MMP_OPTION_CW " " << cw << endl; - if (!armcc.isEmpty() && !overriddenMmpKeywords.contains(MMP_OPTION_ARMCC)) + if (!armcc.isEmpty()) t << MMP_OPTION_ARMCC " " << armcc << endl; - if (!gcce.isEmpty() && !overriddenMmpKeywords.contains(MMP_OPTION_GCCE)) + if (!gcce.isEmpty()) t << MMP_OPTION_GCCE " " << gcce << endl; - if (!cwlink.isEmpty() && !overriddenMmpKeywords.contains(MMP_LINKEROPTION_CW)) + if (!cwlink.isEmpty()) t << MMP_LINKEROPTION_CW " " << cwlink << endl; - if (!armlink.isEmpty() && !overriddenMmpKeywords.contains(MMP_LINKEROPTION_ARMCC)) + if (!armlink.isEmpty()) t << MMP_LINKEROPTION_ARMCC " " << armlink << endl; - if (!gccelink.isEmpty() && !overriddenMmpKeywords.contains(MMP_LINKEROPTION_GCCE)) + if (!gccelink.isEmpty()) t << MMP_LINKEROPTION_GCCE " " << gccelink << endl; - t << endl; + t << endl; } void SymbianMakefileGenerator::writeMmpFileBinaryVersionPart(QTextStream& t) @@ -1098,7 +1153,7 @@ void SymbianMakefileGenerator::writeMmpFileBinaryVersionPart(QTextStream& t) mmpVersion = "10.0"; // Default binary version for symbian is 10.0 } - t << "VERSION " << mmpVersion << endl; + t << MMP_VERSION " " << mmpVersion << endl; } void SymbianMakefileGenerator::writeMmpFileRulesPart(QTextStream& t) @@ -1265,7 +1320,7 @@ void SymbianMakefileGenerator::writeRegRssFile(QStringList &userItems) generatedFiles << ft.fileName(); QTextStream t(&ft); t << "// ============================================================================" << endl; - t << "// * Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: "; + t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; t << "// * This file is generated by qmake and should not be modified by the" << endl; t << "// * user." << endl; @@ -1274,8 +1329,7 @@ void SymbianMakefileGenerator::writeRegRssFile(QStringList &userItems) t << "#include <" << fixedTarget << ".rsg>" << endl; t << "#include <appinfo.rh>" << endl; t << endl; - //t << "#include <data_caging_paths.hrh>" << "\n" << endl; - t << "UID2 " << "KUidAppRegistrationResourceFile" << endl; + t << "UID2 KUidAppRegistrationResourceFile" << endl; t << "UID3 " << uid3 << endl << endl; t << "RESOURCE APP_REGISTRATION_INFO" << endl; t << "\t{" << endl; @@ -1300,7 +1354,7 @@ void SymbianMakefileGenerator::writeRssFile(QString &numberOfIcons, QString &ico generatedFiles << ft.fileName(); QTextStream t(&ft); t << "// ============================================================================" << endl; - t << "// * Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: "; + t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; t << "// * This file is generated by qmake and should not be modified by the" << endl; t << "// * user." << endl; @@ -1346,7 +1400,7 @@ void SymbianMakefileGenerator::writeLocFile(QStringList &symbianLangCodes) generatedFiles << ft.fileName(); QTextStream t(&ft); t << "// ============================================================================" << endl; - t << "// * Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: "; + t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; t << "// * This file is generated by qmake and should not be modified by the" << endl; t << "// * user." << endl; diff --git a/qmake/generators/symbian/symmake.h b/qmake/generators/symbian/symmake.h index 2e78c46..1a20e64 100644 --- a/qmake/generators/symbian/symmake.h +++ b/qmake/generators/symbian/symmake.h @@ -96,7 +96,14 @@ protected: QString generateUID3(); void initMmpVariables(); - void checkOverridability(QStringList &overridableKeywords, QString &checkString); + void handleMmpRulesOverrides(QString &checkString, + bool &inResourceBlock, + QStringList &restrictedMmpKeywords, + const QStringList &restrictableMmpKeywords, + const QStringList &overridableMmpKeywords); + void appendKeywordIfMatchFound(QStringList &list, + const QStringList &keywordList, + QString &checkString); void writeHeader(QTextStream &t); void writeBldInfContent(QTextStream& t, bool addDeploymentExtension, const QString &iconFile); diff --git a/qmake/generators/symbian/symmake_sbsv2.cpp b/qmake/generators/symbian/symmake_sbsv2.cpp index 4fd5833..c7eae64 100644 --- a/qmake/generators/symbian/symmake_sbsv2.cpp +++ b/qmake/generators/symbian/symmake_sbsv2.cpp @@ -376,7 +376,10 @@ void SymbianSbsv2MakefileGenerator::writeBldInfExtensionRulesPart(QTextStream& t t << "START EXTENSION s60/mifconv" << endl; QFileInfo iconInfo = fileInfo(icon); - QString iconPath = iconInfo.path(); + + QFileInfo bldinf(project->values("MAKEFILE").first()); + QString iconPath = bldinf.dir().relativeFilePath(iconInfo.path()); + QString iconFile = iconInfo.baseName(); QFileInfo iconTargetInfo = fileInfo(iconTargetFile); diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index faa6415..44a461e 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -88,7 +88,7 @@ UnixMakefileGenerator::init() if(project->isEmpty("QMAKE_LIBTOOL")) project->values("QMAKE_LIBTOOL").append("libtool --silent"); if(project->isEmpty("QMAKE_SYMBOLIC_LINK")) - project->values("QMAKE_SYMBOLIC_LINK").append("ln -sf"); + project->values("QMAKE_SYMBOLIC_LINK").append("ln -f -s"); /* this should probably not be here, but I'm using it to wrap the .t files */ if(project->first("TEMPLATE") == "app") diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp index f3ec8e1..bfb03ab 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp +++ b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp @@ -975,7 +975,7 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc) face->glyphs_substituted = false; face->buffer = 0; - HB_Error error; + HB_Error error = HB_Err_Ok; HB_Stream stream; HB_Stream gdefStream; diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri index 28328e7..a6fb2f8 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri +++ b/src/3rdparty/javascriptcore/JavaScriptCore/JavaScriptCore.pri @@ -39,10 +39,12 @@ win32-* { contains(JAVASCRIPTCORE_JIT,yes) { DEFINES+=ENABLE_JIT=1 DEFINES+=ENABLE_YARR_JIT=1 + DEFINES+=ENABLE_YARR=1 } contains(JAVASCRIPTCORE_JIT,no) { DEFINES+=ENABLE_JIT=0 DEFINES+=ENABLE_YARR_JIT=0 + DEFINES+=ENABLE_YARR=0 } # In debug mode JIT disabled until crash fixed diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp index 073b35a..b098728 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp @@ -561,6 +561,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" asm volatile ( ".globl " SYMBOL_STRING(ctiTrampoline) "\n" +HIDE_SYMBOL(ctiTrampoline) "\n" SYMBOL_STRING(ctiTrampoline) ":" "\n" "stmdb sp!, {r1-r3}" "\n" "stmdb sp!, {r4-r8, lr}" "\n" @@ -584,6 +585,7 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n" asm volatile ( ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n" +HIDE_SYMBOL(ctiVMThrowTrampoline) "\n" SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" "mov r0, sp" "\n" "mov lr, r6" "\n" @@ -593,6 +595,7 @@ SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n" // Both has the same return sequence ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n" +HIDE_SYMBOL(ctiOpThrowNotCaught) "\n" SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "add sp, sp, #32" "\n" "ldmia sp!, {r4-r8, lr}" "\n" diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h index 43975ff..c2b8c02 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.h @@ -246,6 +246,10 @@ namespace JSC { MacroAssemblerCodePtr m_ctiNativeCallThunk; }; +#if COMPILER(GCC) +#pragma GCC visibility push(hidden) +#endif + extern "C" { EncodedJSValue JIT_STUB cti_op_add(STUB_ARGS_DECLARATION); EncodedJSValue JIT_STUB cti_op_bitand(STUB_ARGS_DECLARATION); @@ -363,6 +367,10 @@ extern "C" { void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS_DECLARATION); } // extern "C" +#if COMPILER(GCC) +#pragma GCC visibility pop +#endif + } // namespace JSC #endif // ENABLE(JIT) diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h index 56659a8..c03e8a7 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/TypeTraits.h @@ -155,7 +155,7 @@ namespace WTF { typedef IntegralConstant<bool, true> true_type; typedef IntegralConstant<bool, false> false_type; -#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER) // VC8 (VS2005) and later have built-in compiler support for HasTrivialConstructor / HasTrivialDestructor, // but for some unexplained reason it doesn't work on built-in types. template <typename T> struct HasTrivialConstructor : public IntegralConstant<bool, __has_trivial_constructor(T)>{ }; diff --git a/src/3rdparty/javascriptcore/WebKit.pri b/src/3rdparty/javascriptcore/WebKit.pri index 8291f30..16f89bf 100644 --- a/src/3rdparty/javascriptcore/WebKit.pri +++ b/src/3rdparty/javascriptcore/WebKit.pri @@ -11,7 +11,7 @@ isEmpty(OUTPUT_DIR) { DEFINES += BUILDING_QT__=1 building-libs { - win32-msvc*: INCLUDEPATH += $$PWD/JavaScriptCore/os-win32 + win32-msvc*|win32-icc: INCLUDEPATH += $$PWD/JavaScriptCore/os-win32 } else { CONFIG(QTDIR_build) { QT += webkit diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index 2059fbe..b6f53ae 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -50,6 +50,8 @@ MMF::VideoPlayer::VideoPlayer() , m_window(0) , m_totalTime(0) , m_pendingChanges(false) + , m_dsaActive(false) + , m_dsaWasActive(false) { construct(); } @@ -61,6 +63,7 @@ MMF::VideoPlayer::VideoPlayer(const AbstractPlayer& player) , m_window(0) , m_totalTime(0) , m_pendingChanges(false) + , m_dsaActive(false) { construct(); } @@ -86,6 +89,9 @@ void MMF::VideoPlayer::construct() )) ); + // CVideoPlayerUtility::NewL starts DSA + m_dsaActive = true; + if (KErrNone != err) changeState(ErrorState); @@ -315,8 +321,7 @@ void MMF::VideoPlayer::getVideoWindow() m_videoOutput->dump(); initVideoOutput(); - m_window = m_videoOutput->videoWindow(); - updateVideoRect(); + videoWindowChanged(); } else // Top-level window m_window = QApplication::activeWindow()->effectiveWinId()->DrawableWindow(); @@ -349,6 +354,18 @@ void MMF::VideoPlayer::initVideoOutput() Q_ASSERT(connected); connected = connect( + m_videoOutput, SIGNAL(beginVideoWindowNativePaint()), + this, SLOT(suspendDirectScreenAccess()) + ); + Q_ASSERT(connected); + + connected = connect( + m_videoOutput, SIGNAL(endVideoWindowNativePaint()), + this, SLOT(resumeDirectScreenAccess()) + ); + Q_ASSERT(connected); + + connected = connect( m_videoOutput, SIGNAL(aspectRatioChanged()), this, SLOT(aspectRatioChanged()) ); @@ -370,12 +387,48 @@ void MMF::VideoPlayer::videoWindowChanged() TRACE_ENTRY("state %d", state()); m_window = m_videoOutput->videoWindow(); - updateVideoRect(); TRACE_EXIT_0(); } +void MMF::VideoPlayer::suspendDirectScreenAccess() +{ + m_dsaWasActive = stopDirectScreenAccess(); +} + +void MMF::VideoPlayer::resumeDirectScreenAccess() +{ + if(m_dsaWasActive) { + startDirectScreenAccess(); + m_dsaWasActive = false; + } +} + +void MMF::VideoPlayer::startDirectScreenAccess() +{ + if(!m_dsaActive) { + TRAPD(err, m_player->StartDirectScreenAccessL()); + if(KErrNone == err) + m_dsaActive = true; + else + setError(NormalError); + } +} + +bool MMF::VideoPlayer::stopDirectScreenAccess() +{ + const bool dsaWasActive = m_dsaActive; + if(m_dsaActive) { + TRAPD(err, m_player->StopDirectScreenAccessL()); + if(KErrNone == err) + m_dsaActive = false; + else + setError(NormalError); + } + return dsaWasActive; +} + // Helper function for aspect ratio / scale mode handling QSize scaleToAspect(const QSize& srcRect, int aspectWidth, int aspectHeight) { @@ -393,7 +446,18 @@ QSize scaleToAspect(const QSize& srcRect, int aspectWidth, int aspectHeight) void MMF::VideoPlayer::updateVideoRect() { QRect videoRect; - const QRect windowRect = m_videoOutput->videoWindowRect(); + QRect windowRect = m_videoOutput->videoWindowRect(); + + // Clip to physical window size + // This is due to a defect in the layout when running on S60 3.2, which + // results in the rectangle of the video widget extending outside the + // screen in certain circumstances. These include the initial startup + // of the mediaplayer demo in portrait mode. When this rectangle is + // passed to the CVideoPlayerUtility, no video is rendered. + const TSize screenSize = m_screenDevice.SizeInPixels(); + const QRect screenRect(0, 0, screenSize.iWidth, screenSize.iHeight); + windowRect = windowRect.intersected(screenRect); + const QSize windowSize = windowRect.size(); // Calculate size of smallest rect which contains video frame size @@ -553,6 +617,7 @@ void MMF::VideoPlayer::applyVideoWindowChange() TRACE("SetDisplayWindowL err %d", err); setError(NormalError); } else { + m_dsaActive = true; TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, antialias)); if(KErrNone != err) { TRACE("SetScaleFactorL (2) err %d", err); diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.h b/src/3rdparty/phonon/mmf/mmf_videoplayer.h index 599bb88..abb1da8 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.h +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.h @@ -72,6 +72,8 @@ public Q_SLOTS: void videoWindowChanged(); void aspectRatioChanged(); void scaleModeChanged(); + void suspendDirectScreenAccess(); + void resumeDirectScreenAccess(); private: void construct(); @@ -89,6 +91,9 @@ private: void applyPendingChanges(); void applyVideoWindowChange(); + void startDirectScreenAccess(); + bool stopDirectScreenAccess(); + // AbstractMediaPlayer virtual int numberOfMetaDataEntries() const; virtual QPair<QString, QString> metaDataEntry(int index) const; @@ -111,6 +116,8 @@ private: qint64 m_totalTime; bool m_pendingChanges; + bool m_dsaActive; + bool m_dsaWasActive; }; diff --git a/src/3rdparty/phonon/mmf/objectdump_symbian.cpp b/src/3rdparty/phonon/mmf/objectdump_symbian.cpp index 2efebdb..edad537 100644 --- a/src/3rdparty/phonon/mmf/objectdump_symbian.cpp +++ b/src/3rdparty/phonon/mmf/objectdump_symbian.cpp @@ -46,7 +46,7 @@ QList<QByteArray> QAnnotatorWidget::annotation(const QObject& object) stream << "widget (Symbian): "; stream << "activated " << extra->activated << ' '; - stream << "disableBlit " << extra->disableBlit << ' '; + stream << "nativePaintMode " << extra->nativePaintMode << ' '; stream.flush(); result.append(array); diff --git a/src/3rdparty/phonon/mmf/videooutput.cpp b/src/3rdparty/phonon/mmf/videooutput.cpp index ddf30de..119dcb1 100644 --- a/src/3rdparty/phonon/mmf/videooutput.cpp +++ b/src/3rdparty/phonon/mmf/videooutput.cpp @@ -34,6 +34,8 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include <coecntrl.h> +#include <coemain.h> // for CCoeEnv + QT_BEGIN_NAMESPACE using namespace Phonon; @@ -72,12 +74,8 @@ MMF::VideoOutput::VideoOutput setAttribute(Qt::WA_NoSystemBackground, true); setAutoFillBackground(false); - // Causes QSymbianControl::Draw not to BitBlt this widget's region of the - // backing store. Since the backing store is (by default) a 16MU bitmap, - // blitting it results in this widget's screen region in the final - // framebuffer having opaque alpha values. This in turn causes the video - // to be invisible when running on the target device. - qt_widget_private(this)->extraData()->disableBlit = true; + qt_widget_private(this)->extraData()->nativePaintMode = QWExtra::ZeroFill; + qt_widget_private(this)->extraData()->receiveNativePaintEvents = true; getVideoWindowRect(); registerForAncestorMoved(); @@ -288,5 +286,18 @@ void MMF::VideoOutput::dump() const #endif } +void MMF::VideoOutput::beginNativePaintEvent(const QRect& /*controlRect*/) +{ + emit beginVideoWindowNativePaint(); +} + +void MMF::VideoOutput::endNativePaintEvent(const QRect& /*controlRect*/) +{ + // Ensure that draw ops are executed into the WSERV output framebuffer + CCoeEnv::Static()->WsSession().Flush(); + + emit endVideoWindowNativePaint(); +} + QT_END_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/videooutput.h b/src/3rdparty/phonon/mmf/videooutput.h index 6dfe69d..2788401 100644 --- a/src/3rdparty/phonon/mmf/videooutput.h +++ b/src/3rdparty/phonon/mmf/videooutput.h @@ -63,10 +63,16 @@ public: // Debugging output void dump() const; +public Q_SLOTS: + void beginNativePaintEvent(const QRect& /*controlRect*/); + void endNativePaintEvent(const QRect& /*controlRect*/); + Q_SIGNALS: void videoWindowChanged(); void aspectRatioChanged(); void scaleModeChanged(); + void beginVideoWindowNativePaint(); + void endVideoWindowNativePaint(); protected: // Override QWidget functions diff --git a/src/3rdparty/webkit/ChangeLog b/src/3rdparty/webkit/ChangeLog index 26dbaf7..1e89d1e 100644 --- a/src/3rdparty/webkit/ChangeLog +++ b/src/3rdparty/webkit/ChangeLog @@ -1,3 +1,13 @@ +2009-11-30 Jan-Arve Sæther <jan-arve.saether@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix compilation with win32-icc + + Include os-win32 for stdint.h since MS does not ship that in their PSDK. + + * WebKit.pri: + 2009-10-30 Adam Barth <abarth@webkit.org> Reviewed by Mark Rowe. diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog index 304f9ef..d7d2d57 100644 --- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog @@ -1,3 +1,56 @@ +2009-11-30 Jan-Arve Sæther <jan-arve.saether@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix compilation with win32-icc + + The Intel compiler does not support the __has_trivial_constructor type + trait. The Intel Compiler can report itself as _MSC_VER >= 1400. The + reason for that is that the Intel Compiler depends on the Microsoft + Platform SDK, and in order to try to be "fully" MS compatible it will + "pretend" to be the same MS compiler as was shipped with the MS PSDK. + (Thus, compiling with win32-icc with VC8 SDK will make the source code + "think" the compiler at hand supports this type trait). + + * wtf/TypeTraits.h: + +2009-11-28 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Eric Seidel. + + Apply workaround for the limitation of VirtualFree with MEM_RELEASE to all ports running on Windows + https://bugs.webkit.org/show_bug.cgi?id=31943 + + * runtime/MarkStack.h: + (JSC::MarkStack::MarkStackArray::shrinkAllocation): + +2009-11-18 Gabor Loki <loki@inf.u-szeged.hu> + + Reviewed by Darin Adler. + + Fix the clobber list of cacheFlush for ARM and Thumb2 on Linux + https://bugs.webkit.org/show_bug.cgi?id=31631 + + * jit/ExecutableAllocator.h: + (JSC::ExecutableAllocator::cacheFlush): + +2009-11-23 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Symbian] Fix lastIndexOf() for Symbian + https://bugs.webkit.org/show_bug.cgi?id=31773 + + Symbian soft floating point library has problems with operators + comparing NaN to numbers. Without a workaround lastIndexOf() + function does not work. + + Patch developed by David Leong. + + * runtime/StringPrototype.cpp: + (JSC::stringProtoFuncLastIndexOf):Add an extra test + to check for NaN for Symbian. + 2009-11-18 Harald Fernengel <harald.fernengel@nokia.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h index 5c43eeb..9ca62c8 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h +++ b/src/3rdparty/webkit/JavaScriptCore/jit/ExecutableAllocator.h @@ -203,7 +203,7 @@ public: "pop {r7}\n" : : "r" (code), "r" (reinterpret_cast<char*>(code) + size) - : "r0", "r1"); + : "r0", "r1", "r2"); } #elif PLATFORM(SYMBIAN) static void cacheFlush(void* code, size_t size) @@ -224,7 +224,7 @@ public: "pop {r7}\n" : : "r" (code), "r" (reinterpret_cast<char*>(code) + size) - : "r0", "r1"); + : "r0", "r1", "r2"); } #else #error "The cacheFlush support is missing on this platform." diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h b/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h index ea09f54..a114ae0 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/MarkStack.h @@ -153,7 +153,7 @@ namespace JSC { ASSERT(0 == (size % MarkStack::pageSize())); if (size == m_allocated) return; -#if PLATFORM(WIN) || PLATFORM(SYMBIAN) +#if PLATFORM(WIN_OS) || PLATFORM(SYMBIAN) // We cannot release a part of a region with VirtualFree. To get around this, // we'll release the entire region and reallocate the size that we want. releaseStack(m_data, m_allocated); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp index a0713b8..a0cc9f1 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/StringPrototype.cpp @@ -469,6 +469,11 @@ JSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSV dpos = 0; else if (!(dpos <= len)) // true for NaN dpos = len; +#if PLATFORM(SYMBIAN) + // Work around for broken NaN compare operator + else if (isnan(dpos)) + dpos = len; +#endif return jsNumber(exec, s.rfind(u2, static_cast<int>(dpos))); } diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/TypeTraits.h b/src/3rdparty/webkit/JavaScriptCore/wtf/TypeTraits.h index 6ce6a3e..9e75e7a 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/TypeTraits.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/TypeTraits.h @@ -155,7 +155,7 @@ namespace WTF { typedef IntegralConstant<bool, true> true_type; typedef IntegralConstant<bool, false> false_type; -#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER) // VC8 (VS2005) and later have built-in compiler support for HasTrivialConstructor / HasTrivialDestructor, // but for some unexplained reason it doesn't work on built-in types. template <typename T> struct HasTrivialConstructor : public IntegralConstant<bool, __has_trivial_constructor(T)>{ }; diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index f40dda4..62acbdf 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - 7bdf90f753d25fb1b5628b0980827df11110ad5a + 9de63cde0ac8aa08e207d4ffce2846df1a44a364 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 6daf411..4f6146f 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,53 @@ +2009-11-23 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Wrong runtime instance objects of wrapped QObjects may be used if + the wrapped object died before the gc removed the instance. + + https://bugs.webkit.org/show_bug.cgi?id=31681 + + Before using a cached instance, verify that its wrapped QObject is + still alive. + + * bridge/qt/qt_instance.cpp: + (JSC::Bindings::QtInstance::getQtInstance): + * bridge/qt/qt_instance.h: + (JSC::Bindings::QtInstance::hashKey): + +2009-11-25 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix crash of QtWebKit on any page with Flash when compiled with MinGW. + + Fix inline assembly, don't dereference the function pointer twice. + + * plugins/win/PluginViewWin.cpp: + (WebCore::PluginView::hookedBeginPaint): + (WebCore::PluginView::hookedEndPaint): + +2009-11-22 Jakub Wieczorek <faw217@gmail.com> + + Reviewed by Adam Barth. + + [Qt] Remove the Referer header when redirecting to a non-secure site + https://bugs.webkit.org/show_bug.cgi?id=31785 + + This makes Qt pass two tests introduced in r50226. + + * platform/network/qt/QNetworkReplyHandler.cpp: + (WebCore::QNetworkReplyHandler::sendResponseIfNeeded): + +2009-11-19 Olivier Goffart <ogoffart@trolltech.com> + + Reviewed by Simon Hausmann. + + [Qt] Normalize signal and slot signatures. + + * platform/graphics/qt/MediaPlayerPrivatePhonon.cpp: + (WebCore::MediaPlayerPrivate::MediaPlayerPrivate): + 2009-11-18 Benjamin Poulain <benjamin.poulain@nokia.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp index 0546014..ec362ec 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp @@ -111,10 +111,17 @@ PassRefPtr<QtInstance> QtInstance::getQtInstance(QObject* o, PassRefPtr<RootObje { JSLock lock(SilenceAssertionsOnly); - foreach(QtInstance* instance, cachedInstances.values(o)) { - if (instance->rootObject() == rootObject) - return instance; - } + foreach(QtInstance* instance, cachedInstances.values(o)) + if (instance->rootObject() == rootObject) { + // The garbage collector removes instances, but it may happen that the wrapped + // QObject dies before the gc kicks in. To handle that case we have to do an additional + // check if to see if the instance's wrapped object is still alive. If it isn't, then + // we have to create a new wrapper. + if (!instance->getObject()) + cachedInstances.remove(instance->hashKey()); + else + return instance; + } RefPtr<QtInstance> ret = QtInstance::create(o, rootObject, ownership); cachedInstances.insert(o, ret.get()); diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h index 00aaa5b..0afc6c7 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h @@ -59,6 +59,7 @@ public: JSValue booleanValue() const; QObject* getObject() const { return m_object; } + QObject* hashKey() const { return m_hashkey; } static PassRefPtr<QtInstance> getQtInstance(QObject*, PassRefPtr<RootObject>, QScriptEngine::ValueOwnership ownership); diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp index 2f4722f..1ac80f6 100644 --- a/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp +++ b/src/3rdparty/webkit/WebCore/platform/network/qt/QNetworkReplyHandler.cpp @@ -325,6 +325,10 @@ void QNetworkReplyHandler::sendResponseIfNeeded() newRequest.setHTTPMethod("GET"); } + // Should not set Referer after a redirect from a secure resource to non-secure one. + if (!newRequest.url().protocolIs("https") && protocolIs(newRequest.httpReferrer(), "https")) + newRequest.clearHTTPReferrer(); + client->willSendRequest(m_resourceHandle, newRequest, response); m_redirected = true; m_request = newRequest.toNetworkRequest(m_resourceHandle->getInternal()->m_frame); diff --git a/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp b/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp index 5ccce0e..b313afb 100644 --- a/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/win/PluginViewWin.cpp @@ -145,7 +145,7 @@ HDC WINAPI PluginView::hookedBeginPaint(HWND hWnd, PAINTSTRUCT* lpPaint) "push %3\n" "call *%4\n" : "=a" (result) - : "a" (beginPaintSysCall), "g" (lpPaint), "g" (hWnd), "m" (*beginPaint) + : "a" (beginPaintSysCall), "g" (lpPaint), "g" (hWnd), "m" (beginPaint) : "memory" ); return result; @@ -175,7 +175,7 @@ BOOL WINAPI PluginView::hookedEndPaint(HWND hWnd, const PAINTSTRUCT* lpPaint) "push %3\n" "call *%4\n" : "=a" (result) - : "a" (endPaintSysCall), "g" (lpPaint), "g" (hWnd), "m" (*endPaint) + : "a" (endPaintSysCall), "g" (lpPaint), "g" (hWnd), "m" (endPaint) ); return result; #elif defined (_M_IX86) diff --git a/src/3rdparty/webkit/WebKit.pri b/src/3rdparty/webkit/WebKit.pri index 10291b4..5188662 100644 --- a/src/3rdparty/webkit/WebKit.pri +++ b/src/3rdparty/webkit/WebKit.pri @@ -11,7 +11,7 @@ isEmpty(OUTPUT_DIR) { DEFINES += BUILDING_QT__=1 building-libs { - win32-msvc*: INCLUDEPATH += $$PWD/JavaScriptCore/os-win32 + win32-msvc*|win32-icc: INCLUDEPATH += $$PWD/JavaScriptCore/os-win32 } else { CONFIG(QTDIR_build) { QT += webkit diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.cpp index 8922150..441bec7 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebelement.cpp @@ -99,6 +99,14 @@ public: It is possible to replace the contents of child elements using setPlainText() and setInnerXml(). To replace the element itself and its contents, use setOuterXml(). + + \section1 Examples + + The \l{DOM Traversal Example} shows one way to traverse documents in a running + example. + + The \l{Simple Selector Example} can be used to experiment with the searching + features of this class and provides sample code you can start working with. */ /*! @@ -195,8 +203,7 @@ bool QWebElement::isNull() const \a selectorQuery. If there are no matching elements, an empty list is returned. - \l{http://www.w3.org/TR/REC-CSS2/selector.html#q1}{Standard CSS2 selector} - syntax is used for the query. + \l{Standard CSS2 selector} syntax is used for the query. \note This search is performed recursively. @@ -211,8 +218,7 @@ QWebElementCollection QWebElement::findAll(const QString &selectorQuery) const Returns the first child element that matches the given CSS selector \a selectorQuery. - \l{http://www.w3.org/TR/REC-CSS2/selector.html#q1}{Standard CSS2 selector} - syntax is used for the query. + \l{Standard CSS2 selector} syntax is used for the query. \note This search is performed recursively. diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp index aedf95a..1bdc3ed 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp @@ -864,7 +864,12 @@ void QWebPagePrivate::mouseReleaseEvent(QGraphicsSceneMouseEvent* ev) void QWebPagePrivate::handleSoftwareInputPanel(Qt::MouseButton button) { #if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + Frame* frame = page->focusController()->focusedFrame(); + if (!frame) + return; + if (client && client->inputMethodEnabled() + && frame->document()->focusedNode() && button == Qt::LeftButton && qApp->autoSipEnabled()) { QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel( client->ownerWidget()->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel)); diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index 457e9c2..2f0bf17 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,66 @@ +2009-11-28 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] SoftwareInputPanelRequest event sent when clicking in newly loaded page + + https://bugs.webkit.org/show_bug.cgi?id=31401 + + Don't set the event unless there is a focused node we can use + for editing afterwards. + + * Api/qwebpage.cpp: + (QWebPagePrivate::handleSoftwareInputPanel): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::inputMethods): + +2009-11-23 David Boddie <dboddie@trolltech.com> + + Reviewed by Simon Hausmann. + + Updated the QWebElement documentation with links to examples and + external resources. + Fixed the project file for the webelement snippet and tidied up the + markers used for quoting the code. + + * Api/qwebelement.cpp: + * docs/webkitsnippets/webelement/main.cpp: + (findAll): + * docs/webkitsnippets/webelement/webelement.pro: + +2009-11-23 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Wrong runtime instance objects of wrapped QObjects may be used if + the wrapped object died before the gc removed the instance. + + https://bugs.webkit.org/show_bug.cgi?id=31681 + + Added a unit-test to verify that wrapping a QObject with the + same identity as a previously but now dead object works. + + * tests/qwebframe/tst_qwebframe.cpp: + +2009-11-19 Olivier Goffart <ogoffart@trolltech.com> + + Reviewed by Simon Hausmann. + + [Qt] Normalize signal and slot signatures. + + * Api/qgraphicswebview.cpp: + (QGraphicsWebView::setPage): + * Api/qwebview.cpp: + (QWebView::setPage): + * WebCoreSupport/FrameLoaderClientQt.cpp: + (WebCore::FrameLoaderClientQt::setFrame): + * docs/webkitsnippets/qtwebkit_qwebinspector_snippet.cpp: + (wrapInFunction): + * tests/qwebframe/tst_qwebframe.cpp: + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::modified): + (tst_QWebPage::database): + 2009-11-18 Paul Olav Tvete <paul.tvete@nokia.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/main.cpp b/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/main.cpp index d437a6f..2707ffb 100644 --- a/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/main.cpp +++ b/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/main.cpp @@ -22,7 +22,6 @@ #include <qwebview.h> #include <qwebframe.h> #include <qwebelement.h> -#include <qdebug.h> static QWebFrame *frame; @@ -53,9 +52,10 @@ static void findAll() </p> */ +//! [FindAll intro] QList<QWebElement> allSpans = document.findAll("span"); QList<QWebElement> introSpans = document.findAll("p.intro span"); -//! [FindAll] +//! [FindAll intro] //! [FindAll] } int main(int argc, char *argv[]) diff --git a/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/webelement.pro b/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/webelement.pro index f9b403b..8ca4b59 100644 --- a/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/webelement.pro +++ b/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/webelement/webelement.pro @@ -1,5 +1,8 @@ TEMPLATE = app CONFIG -= app_bundle +CONFIG(QTDIR_build) { + QT += webkit +} SOURCES = main.cpp include(../../../../../WebKit.pri) QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp index d88d905..8cc7953 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp @@ -605,6 +605,7 @@ private slots: void render(); void scrollPosition(); void evaluateWillCauseRepaint(); + void qObjectWrapperWithSameIdentity(); private: QString evalJS(const QString&s) { @@ -2785,6 +2786,43 @@ void tst_QWebFrame::evaluateWillCauseRepaint() QTest::qWait(2000); } +class TestFactory : public QObject +{ + Q_OBJECT +public: + TestFactory() + : obj(0), counter(0) + {} + + Q_INVOKABLE QObject* getNewObject() + { + delete obj; + obj = new QObject(this); + obj->setObjectName(QLatin1String("test") + QString::number(++counter)); + return obj; + + } + + QObject* obj; + int counter; +}; + +void tst_QWebFrame::qObjectWrapperWithSameIdentity() +{ + m_view->setHtml("<script>function triggerBug() { document.getElementById('span1').innerText = test.getNewObject().objectName; }</script>" + "<body><span id='span1'>test</span></body>"); + + QWebFrame* mainFrame = m_view->page()->mainFrame(); + QCOMPARE(mainFrame->toPlainText(), QString("test")); + + mainFrame->addToJavaScriptWindowObject("test", new TestFactory, QScriptEngine::ScriptOwnership); + + mainFrame->evaluateJavaScript("triggerBug();"); + QCOMPARE(mainFrame->toPlainText(), QString("test1")); + + mainFrame->evaluateJavaScript("triggerBug();"); + QCOMPARE(mainFrame->toPlainText(), QString("test2")); +} QTEST_MAIN(tst_QWebFrame) #include "tst_qwebframe.moc" diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index 32002e7..ee1969d 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -1487,6 +1487,21 @@ void tst_QWebPage::inputMethods() QVERIFY(!(inputMethodHints(view) & Qt::ImhHiddenText)); #endif + page->mainFrame()->setHtml("<html><body><p>nothing to input here"); + viewEventSpy.clear(); + + QWebElement para = page->mainFrame()->findFirstElement("p"); + { + QMouseEvent evpres(QEvent::MouseButtonPress, para.geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + page->event(&evpres); + QMouseEvent evrel(QEvent::MouseButtonRelease, para.geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + page->event(&evrel); + } + +#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0) + QVERIFY(!viewEventSpy.contains(QEvent::RequestSoftwareInputPanel)); +#endif + delete container; } diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index ef4989b..299585a 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -229,7 +229,10 @@ void QUnifiedTimer::restartAnimationTimer() void QUnifiedTimer::timerEvent(QTimerEvent *event) { - if (event->timerId() == startStopAnimationTimer.timerId()) { + //in the case of consistent timing we make sure the orders in which events come is always the same + //for that purpose we do as if the startstoptimer would always fire before the animation timer + if ((consistentTiming && startStopAnimationTimer.isActive()) || + event->timerId() == startStopAnimationTimer.timerId()) { startStopAnimationTimer.stop(); //we transfer the waiting animations into the "really running" state @@ -247,7 +250,9 @@ void QUnifiedTimer::timerEvent(QTimerEvent *event) time.start(); } } - } else if (event->timerId() == animationTimer.timerId()) { + } + + if (event->timerId() == animationTimer.timerId()) { // update current time on all top level animations updateAnimationsTime(); restartAnimationTimer(); diff --git a/src/corelib/codecs/qiconvcodec.cpp b/src/corelib/codecs/qiconvcodec.cpp index 8c4cc82..0fb78d5 100644 --- a/src/corelib/codecs/qiconvcodec.cpp +++ b/src/corelib/codecs/qiconvcodec.cpp @@ -378,7 +378,7 @@ QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt } int invalidCount = 0; - do { + while (inBytesLeft != 0) { if (iconv(state->cd, inBytesPtr, &inBytesLeft, &outBytes, &outBytesLeft) == (size_t) -1) { if (errno == EINVAL && convState) { // buffer ends in a surrogate @@ -418,7 +418,7 @@ QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt } } } - } while (inBytesLeft != 0); + } // reset to initial state iconv(state->cd, 0, &inBytesLeft, 0, &outBytesLeft); diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 2e9f839..6623e0c 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -44,11 +44,11 @@ #include <stddef.h> -#define QT_VERSION_STR "4.6.0" +#define QT_VERSION_STR "4.6.1" /* QT_VERSION is (major << 16) + (minor << 8) + patch. */ -#define QT_VERSION 0x040600 +#define QT_VERSION 0x040601 /* can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) */ diff --git a/src/corelib/io/qfilesystemwatcher_dnotify.cpp b/src/corelib/io/qfilesystemwatcher_dnotify.cpp index 17ac9c6..c70232c 100644 --- a/src/corelib/io/qfilesystemwatcher_dnotify.cpp +++ b/src/corelib/io/qfilesystemwatcher_dnotify.cpp @@ -269,8 +269,11 @@ QStringList QDnotifyFileSystemWatcherEngine::addPaths(const QStringList &paths, } } - fd = ::dirfd(d); - int parentFd = parent?::dirfd(parent):0; + fd = qt_safe_dup(::dirfd(d)); + int parentFd = parent ? qt_safe_dup(::dirfd(parent)) : 0; + + ::closedir(d); + if(parent) ::closedir(parent); Q_ASSERT(fd); if(::fcntl(fd, F_SETSIG, SIGIO) || @@ -279,10 +282,6 @@ QStringList QDnotifyFileSystemWatcherEngine::addPaths(const QStringList &paths, (parent && ::fcntl(parentFd, F_SETSIG, SIGIO)) || (parent && ::fcntl(parentFd, F_NOTIFY, DN_DELETE | DN_RENAME | DN_MULTISHOT))) { - - ::closedir(d); - if(parent) ::closedir(parent); - continue; // Could not set appropriate flags } diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 3cf9b7e..37b0ea1 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -55,6 +55,7 @@ #include "private/qcore_unix_p.h" #endif #include <stdio.h> +#include <stdlib.h> QT_BEGIN_NAMESPACE @@ -137,6 +138,21 @@ QString QFSFileEnginePrivate::canonicalized(const QString &path) if (path.isEmpty()) return path; + // FIXME let's see if this stuff works, then we might be able to remove some of the other code. +#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) + if (path.size() == 1 && path.at(0) == QLatin1Char('/')) + return path; +#endif + // Mac OS X 10.5.x doesn't support the realpath(X,0) extenstion we use here. +#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) || defined(Q_OS_SYMBIAN) + char *ret = realpath(path.toLocal8Bit().constData(), (char*)0); + if (ret) { + QString canonicalPath = QDir::cleanPath(QString::fromLocal8Bit(ret)); + free(ret); + return canonicalPath; + } +#endif + QFileInfo fi; const QChar slash(QLatin1Char('/')); QString tmpPath = path; diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 87f0737..41a6a1b 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE #define Q_USE_DEPRECATED_MAP_API 1 #endif -class QFSFileEnginePrivate : public QAbstractFileEnginePrivate +class Q_AUTOTEST_EXPORT QFSFileEnginePrivate : public QAbstractFileEnginePrivate { Q_DECLARE_PUBLIC(QFSFileEngine) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 35737b3..71414ce 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -191,12 +191,16 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) return false; } - QT_STATBUF statBuf; - if (QT_FSTAT(fd, &statBuf) != -1) { - if ((statBuf.st_mode & S_IFMT) == S_IFDIR) { - q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); - QT_CLOSE(fd); - return false; + if (!(openMode & QIODevice::WriteOnly)) { + // we don't need this check if we tried to open for writing because then + // we had received EISDIR anyway. + QT_STATBUF statBuf; + if (QT_FSTAT(fd, &statBuf) != -1) { + if ((statBuf.st_mode & S_IFMT) == S_IFDIR) { + q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); + QT_CLOSE(fd); + return false; + } } } @@ -230,12 +234,16 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) return false; } - QT_STATBUF statBuf; - if (QT_FSTAT(fileno(fh), &statBuf) != -1) { - if ((statBuf.st_mode & S_IFMT) == S_IFDIR) { - q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); - fclose(fh); - return false; + if (!(openMode & QIODevice::WriteOnly)) { + // we don't need this check if we tried to open for writing because then + // we had received EISDIR anyway. + QT_STATBUF statBuf; + if (QT_FSTAT(fileno(fh), &statBuf) != -1) { + if ((statBuf.st_mode & S_IFMT) == S_IFDIR) { + q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); + fclose(fh); + return false; + } } } @@ -1245,7 +1253,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla } if (offset < 0 || offset != qint64(QT_OFF_T(offset)) - || size < 0 || size > qint64(size_t(-1))) { + || size < 0 || quint64(size) > quint64(size_t(-1))) { q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL))); return 0; } diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp index 10a61ca..9335085 100644 --- a/src/corelib/kernel/qabstractitemmodel.cpp +++ b/src/corelib/kernel/qabstractitemmodel.cpp @@ -2546,9 +2546,9 @@ bool QAbstractItemModel::beginMoveRows(const QModelIndex &sourceParent, int sour int destinationLast = destinationChild + (sourceLast - sourceFirst); d->changes.push(QAbstractItemModelPrivate::Change(destinationParent, destinationChild, destinationLast)); - d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Vertical); emit rowsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild); emit layoutAboutToBeChanged(); + d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Vertical); return true; } diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index b3497b9..c305341 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -336,6 +336,7 @@ public: // internal window handle used for socketnotifiers/timers/etc HWND internalHwnd; + HHOOK getMessageHook; // for controlling when to send posted events QAtomicInt serialNumber; @@ -363,7 +364,7 @@ public: }; QEventDispatcherWin32Private::QEventDispatcherWin32Private() - : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), serialNumber(0), lastSerialNumber(0), wakeUps(0) + : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), getMessageHook(0), serialNumber(0), lastSerialNumber(0), wakeUps(0) { resolveTimerAPI(); } @@ -471,37 +472,11 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) } return 0; } else if (message == WM_TIMER) { - if (wp == SendPostedEventsTimerId) { - KillTimer(d->internalHwnd, wp); - int localSerialNumber = d->serialNumber; - (void) d->wakeUps.fetchAndStoreRelease(0); - if (localSerialNumber != d->lastSerialNumber) { - PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0); - } - } else { - Q_ASSERT(d != 0); - d->sendTimerEvent(wp); - } + Q_ASSERT(d != 0); + d->sendTimerEvent(wp); return 0; } else if (message == WM_QT_SENDPOSTEDEVENTS) { int localSerialNumber = d->serialNumber; - - if (GetQueueStatus(QS_INPUT | QS_RAWINPUT | QS_TIMER) != 0) { - // delay the next pass of sendPostedEvents() until we get the special - // WM_TIMER, which allows all pending Windows messages to be processed - if (SetTimer(d->internalHwnd, SendPostedEventsTimerId, 0, 0) == 0) { - // failed to start the timer, oops, clear wakeUps in an attempt to keep things running - qErrnoWarning("Qt: INTERNAL ERROR: failed to start sendPostedEvents() timer"); - d->wakeUps.fetchAndStoreRelease(0); - } else { - // SetTimer() succeeded, nothing to do now - ; - } - } else { - // nothing pending in the queue, let sendPostedEvents go through - d->wakeUps.fetchAndStoreRelease(0); - } - if (localSerialNumber != d->lastSerialNumber) { d->lastSerialNumber = localSerialNumber; QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); @@ -512,6 +487,35 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) return DefWindowProc(hwnd, message, wp, lp); } +LRESULT CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp) +{ + if (wp == PM_REMOVE) { + QEventDispatcherWin32 *q = qobject_cast<QEventDispatcherWin32 *>(QAbstractEventDispatcher::instance()); + Q_ASSERT(q != 0); + if (q) { + QEventDispatcherWin32Private *d = q->d_func(); + int localSerialNumber = d->serialNumber; + if (HIWORD(GetQueueStatus(QS_INPUT | QS_RAWINPUT | QS_TIMER)) == 0) { + // no more input or timer events in the message queue, we can allow posted events to be + // sent now + (void) d->wakeUps.fetchAndStoreRelease(0); + MSG *msg = (MSG *) lp; + if (localSerialNumber != d->lastSerialNumber + // if this message IS the one that triggers sendPostedEvents(), no need to post it again + && msg->hwnd != d->internalHwnd + && msg->message != WM_QT_SENDPOSTEDEVENTS) { + PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0); + } + } + } + } +#ifdef Q_OS_WINCE + return 0; +#else + return CallNextHookEx(0, code, wp, lp); +#endif +} + static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher) { // make sure that multiple Qt's can coexist in the same process @@ -636,6 +640,14 @@ void QEventDispatcherWin32::createInternalHwnd() return; d->internalHwnd = qt_create_internal_window(this); +#ifndef Q_OS_WINCE + // setup GetMessage hook needed to drive our posted events + d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId()); + if (!d->getMessageHook) { + qFatal("Qt: INTERNALL ERROR: failed to install GetMessage hook"); + } +#endif + // register all socket notifiers QList<int> sockets = (d->sn_read.keys().toSet() + d->sn_write.keys().toSet() @@ -725,7 +737,12 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) } } if (haveMessage) { - if (msg.message == WM_QT_SENDPOSTEDEVENTS) { +#ifdef Q_OS_WINCE + // WinCE doesn't support hooks at all, so we have to call this by hand :( + (void) qt_GetMessageHook(0, PM_REMOVE, (LPARAM) &msg); +#endif + + if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) { if (seenWM_QT_SENDPOSTEDEVENTS) { needWM_QT_SENDPOSTEDEVENTS = true; continue; @@ -1058,6 +1075,12 @@ void QEventDispatcherWin32::closingDown() d->unregisterTimer(d->timerVec.at(i), true); d->timerVec.clear(); d->timerDict.clear(); + +#ifndef Q_OS_WINCE + if (d->getMessageHook) + UnhookWindowsHookEx(d->getMessageHook); + d->getMessageHook = 0; +#endif } bool QEventDispatcherWin32::event(QEvent *e) diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index a5ef4d4..7f0e87d 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -102,6 +102,7 @@ public: private: friend LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); + friend LRESULT CALLBACK qt_GetMessageHook(int, WPARAM, LPARAM); }; QT_END_NAMESPACE diff --git a/src/corelib/kernel/qmath.h b/src/corelib/kernel/qmath.h index a9e4378..820f424 100644 --- a/src/corelib/kernel/qmath.h +++ b/src/corelib/kernel/qmath.h @@ -76,6 +76,16 @@ inline int qFloor(qreal v) return int(floor(v)); } +inline qreal qFabs(qreal v) +{ +#ifdef QT_USE_MATH_H_FLOATS + if(sizeof(qreal) == sizeof(float)) + return fabsf(float(v)); + else +#endif + return fabs(v); +} + inline qreal qSin(qreal v) { #ifdef QT_USE_MATH_H_FLOATS @@ -96,6 +106,16 @@ inline qreal qCos(qreal v) return cos(v); } +inline qreal qTan(qreal v) +{ +#ifdef QT_USE_MATH_H_FLOATS + if (sizeof(qreal) == sizeof(float)) + return tanf(float(v)); + else +#endif + return tan(v); +} + inline qreal qAcos(qreal v) { #ifdef QT_USE_MATH_H_FLOATS @@ -106,6 +126,36 @@ inline qreal qAcos(qreal v) return acos(v); } +inline qreal qAsin(qreal v) +{ +#ifdef QT_USE_MATH_H_FLOATS + if (sizeof(qreal) == sizeof(float)) + return asinf(float(v)); + else +#endif + return asin(v); +} + +inline qreal qAtan(qreal v) +{ +#ifdef QT_USE_MATH_H_FLOATS + if(sizeof(qreal) == sizeof(float)) + return atanf(float(v)); + else +#endif + return atan(v); +} + +inline qreal qAtan2(qreal x, qreal y) +{ +#ifdef QT_USE_MATH_H_FLOATS + if(sizeof(qreal) == sizeof(float)) + return atan2f(float(x), float(y)); + else +#endif + return atan2(x, y); +} + inline qreal qSqrt(qreal v) { #ifdef QT_USE_MATH_H_FLOATS @@ -126,6 +176,13 @@ inline qreal qLn(qreal v) return log(v); } +inline qreal qExp(qreal v) +{ + // only one signature + // exists, exp(double) + return exp(v); +} + inline qreal qPow(qreal x, qreal y) { #ifdef QT_USE_MATH_H_FLOATS diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 1260d47..30cd011 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -145,8 +145,7 @@ QObjectPrivate::QObjectPrivate(int version) receiveChildEvents = true; postedEvents = 0; extraData = 0; - for (uint i = 0; i < (sizeof connectedSignals / sizeof connectedSignals[0]); ++i) - connectedSignals[i] = 0; + connectedSignals = 0; inEventHandler = false; inThreadChangeEvent = false; deleteWatch = 0; @@ -2925,13 +2924,9 @@ bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index, QObjectPrivate *const sender_d = QObjectPrivate::get(s); if (signal_index < 0) { - for (uint i = 0; i < (sizeof sender_d->connectedSignals - / sizeof sender_d->connectedSignals[0] ); ++i) - sender_d->connectedSignals[i] = ~0u; - } else if (signal_index < (int)sizeof sender_d->connectedSignals * 8) { - uint n = (signal_index / (8 * sizeof sender_d->connectedSignals[0])); - sender_d->connectedSignals[n] |= (1 << (signal_index - n * 8 - * sizeof sender_d->connectedSignals[0])); + sender_d->connectedSignals = ~ulong(0); + } else if (signal_index < (int)sizeof(sender_d->connectedSignals) * 8) { + sender_d->connectedSignals |= ulong(1) << signal_index; } return true; @@ -3189,15 +3184,9 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign computeOffsets(m, &signalOffset, &methodOffset); int signal_index = signalOffset + local_signal_index; - if (signal_index < (int)sizeof(sender->d_func()->connectedSignals) * 8 - && !qt_signal_spy_callback_set.signal_begin_callback - && !qt_signal_spy_callback_set.signal_end_callback) { - uint n = (signal_index / (8 * sizeof sender->d_func()->connectedSignals[0])); - uint m = 1 << (signal_index - n * 8 * sizeof sender->d_func()->connectedSignals[0]); - if ((sender->d_func()->connectedSignals[n] & m) == 0) - // nothing connected to these signals, and no spy - return; - } + + if (!sender->d_func()->isSignalConnected(signal_index)) + return; // nothing connected to these signals, and no spy if (sender->d_func()->blockSig) return; @@ -3358,28 +3347,6 @@ int QObjectPrivate::signalIndex(const char *signalName) const return relative_index + signalOffset; } -/*! \internal - - Returns true if the signal with index \a signal_index from object \a sender is connected. - Signals with indices above a certain range are always considered connected (see connectedSignals - in QObjectPrivate). If a signal spy is installed, all signals are considered connected. - - \a signal_index must be the index returned by QObjectPrivate::signalIndex; -*/ -bool QObjectPrivate::isSignalConnected(int signal_index) const -{ - if (signal_index < (int)sizeof(connectedSignals) * 8 - && !qt_signal_spy_callback_set.signal_begin_callback - && !qt_signal_spy_callback_set.signal_end_callback) { - uint n = (signal_index / (8 * sizeof connectedSignals[0])); - uint m = 1 << (signal_index - n * 8 * sizeof connectedSignals[0]); - if ((connectedSignals[n] & m) == 0) - // nothing connected to these signals, and no spy - return false; - } - return true; -} - /***************************************************************************** Properties *****************************************************************************/ diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 340498f..1a178e2 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -91,7 +91,11 @@ template<typename T> inline QList<T> qFindChildren(const QObject *, const QRegEx # endif #endif -class QObjectData { +class +#if defined(__INTEL_COMPILER) && defined(Q_OS_WIN) +Q_CORE_EXPORT +#endif +QObjectData { public: virtual ~QObjectData() = 0; QObject *q_ptr; diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index f087407..f899c78 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -172,7 +172,7 @@ public: } int signalIndex(const char *signalName) const; - bool isSignalConnected(int signalIdx) const; + inline bool isSignalConnected(int signalIdx) const; public: QString objectName; @@ -183,7 +183,7 @@ public: Connection *senders; // linked list of connections connected to this object Sender *currentSender; // object currently activating the object - mutable quint32 connectedSignals[2]; // 64-bit, so doesn't cause padding on 64-bit platforms + mutable ulong connectedSignals; #ifdef QT3_SUPPORT QList<QObject *> pendingChildInsertedEvents; @@ -205,6 +205,23 @@ public: int *deleteWatch; }; +/*! \internal + + Returns true if the signal with index \a signal_index from object \a sender is connected. + Signals with indices above a certain range are always considered connected (see connectedSignals + in QObjectPrivate). If a signal spy is installed, all signals are considered connected. + + \a signal_index must be the index returned by QObjectPrivate::signalIndex; +*/ +inline bool QObjectPrivate::isSignalConnected(int signal_index) const +{ + return signal_index >= (int)sizeof(connectedSignals) * 8 + || qt_signal_spy_callback_set.signal_begin_callback + || qt_signal_spy_callback_set.signal_end_callback + || (connectedSignals & (ulong(1) << signal_index)); +} + + inline void q_guard_addGuard(QGuard<QObject> *g) { QObjectPrivate *p = QObjectPrivate::get(g->o); diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 6496876..ea0254b 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -744,7 +744,7 @@ bool QLibraryPrivate::isPlugin(QSettings *settings) pluginState = IsNotAPlugin; // be pessimistic - if ((qt_version > QT_VERSION) || ((QT_VERSION & 0xff0000) > (qt_version & 0xff0000))) { + if ((qt_version & 0x00ff00) > (QT_VERSION & 0x00ff00) || (qt_version & 0xff0000) != (QT_VERSION & 0xff0000)) { if (qt_debug_component()) { qWarning("In %s:\n" " Plugin uses incompatible Qt library (%d.%d.%d) [%s]", diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h index 7b86ee0..5017dbd 100644 --- a/src/corelib/thread/qbasicatomic.h +++ b/src/corelib/thread/qbasicatomic.h @@ -137,7 +137,12 @@ public: #if defined(QT_ARCH_WINDOWS) || defined(QT_ARCH_WINDOWSCE) union { T * volatile _q_value; - long volatile _q_value_integral; +# if !defined(Q_OS_WINCE) && !defined(__i386__) && !defined(_M_IX86) + qint64 +# else + long +# endif + volatile _q_value_integral; }; #else T * volatile _q_value; diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 1918229..2de03dc 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -69,18 +69,18 @@ inline uint qHash(int key) { return uint(key); } inline uint qHash(ulong key) { if (sizeof(ulong) > sizeof(uint)) { - return uint((key >> (8 * sizeof(uint) - 1)) ^ key); + return uint(((key >> (8 * sizeof(uint) - 1)) ^ key) & (~0U)); } else { - return uint(key); + return uint(key & (~0U)); } } inline uint qHash(long key) { return qHash(ulong(key)); } inline uint qHash(quint64 key) { if (sizeof(quint64) > sizeof(uint)) { - return uint((key >> (8 * sizeof(uint) - 1)) ^ key); + return uint(((key >> (8 * sizeof(uint) - 1)) ^ key) & (~0U)); } else { - return uint(key); + return uint(key & (~0U)); } } inline uint qHash(qint64 key) { return qHash(quint64(key)); } diff --git a/src/corelib/tools/qtimeline.cpp b/src/corelib/tools/qtimeline.cpp index cd3483d..ce49e3f 100644 --- a/src/corelib/tools/qtimeline.cpp +++ b/src/corelib/tools/qtimeline.cpp @@ -125,7 +125,7 @@ void QTimeLinePrivate::setCurrentTime(int msecs) #ifdef QTIMELINE_DEBUG qDebug() << "QTimeLinePrivate::setCurrentTime: frameForTime" << currentTime << currentFrame; #endif - if (lastValue != q->currentValue()) + if (!qFuzzyCompare(lastValue, q->currentValue())) emit q->valueChanged(q->currentValue()); if (lastFrame != currentFrame) { const int transitionframe = (direction == QTimeLine::Forward ? endFrame : startFrame); diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index f0de98d..e00cf3f 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -219,7 +219,7 @@ public: inline const_iterator &operator--() { i--; return *this; } inline const_iterator operator--(int) { T *n = i; i--; return n; } inline const_iterator &operator+=(int j) { i+=j; return *this; } - inline const_iterator &operator-=(int j) { i+=j; return *this; } + inline const_iterator &operator-=(int j) { i-=j; return *this; } inline const_iterator operator+(int j) const { return const_iterator(i+j); } inline const_iterator operator-(int j) const { return const_iterator(i-j); } inline int operator-(const_iterator j) const { return i - j.i; } @@ -324,7 +324,7 @@ void QVector<T>::detach_helper() { realloc(d->size, d->alloc); } template <typename T> void QVector<T>::reserve(int asize) -{ if (asize > d->alloc || d->ref != 1) realloc(d->size, asize); d->capacity = 1; } +{ if (asize > d->alloc) realloc(d->size, asize); if (d->ref == 1) d->capacity = 1; } template <typename T> void QVector<T>::resize(int asize) { realloc(asize, (asize > d->alloc || (!d->capacity && asize < d->size && asize < (d->alloc >> 1))) ? @@ -441,6 +441,7 @@ void QVector<T>::free(Data *x) template <typename T> void QVector<T>::realloc(int asize, int aalloc) { + Q_ASSERT(asize <= aalloc); T *pOld; T *pNew; union { QVectorData *d; Data *p; } x; @@ -496,7 +497,8 @@ void QVector<T>::realloc(int asize, int aalloc) pOld = p->array + x.d->size; pNew = x.p->array + x.d->size; // copy objects from the old array into the new array - while (x.d->size < qMin(asize, d->size)) { + const int toMove = qMin(asize, d->size); + while (x.d->size < toMove) { new (pNew++) T(*pOld++); x.d->size++; } diff --git a/src/corelib/xml/qxmlstream.g b/src/corelib/xml/qxmlstream.g index 22ba33d..9921d41 100644 --- a/src/corelib/xml/qxmlstream.g +++ b/src/corelib/xml/qxmlstream.g @@ -915,6 +915,7 @@ markup ::= markup_start markup_list RBRACK; markup_list ::= markup_decl | space | pereference; markup_list ::= markup_list markup_decl | markup_list space | markup_list pereference; +markup_list ::=; markup_decl ::= element_decl | attlist_decl | entity_decl | entity_done | notation_decl | processing_instruction | comment; diff --git a/src/corelib/xml/qxmlstream_p.h b/src/corelib/xml/qxmlstream_p.h index 253f8bd..5eea065 100644 --- a/src/corelib/xml/qxmlstream_p.h +++ b/src/corelib/xml/qxmlstream_p.h @@ -121,7 +121,7 @@ public: XML = 54, ACCEPT_STATE = 416, - RULE_COUNT = 269, + RULE_COUNT = 270, STATE_COUNT = 427, TERMINAL_COUNT = 57, NON_TERMINAL_COUNT = 84, @@ -172,105 +172,105 @@ const char *const QXmlStreamReader_Table::spell [] = { const short QXmlStreamReader_Table::lhs [] = { 57, 57, 59, 59, 59, 59, 59, 59, 59, 59, 67, 68, 64, 72, 72, 72, 75, 66, 66, 66, - 66, 79, 78, 80, 80, 80, 80, 80, 80, 81, - 81, 81, 81, 81, 81, 81, 87, 83, 88, 88, - 88, 88, 91, 92, 93, 93, 93, 93, 94, 94, - 96, 96, 96, 97, 97, 98, 98, 99, 99, 100, - 100, 89, 89, 95, 90, 101, 101, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 104, 105, 105, - 105, 105, 107, 108, 109, 109, 84, 84, 110, 110, - 112, 112, 85, 85, 85, 65, 65, 76, 114, 63, - 115, 116, 86, 86, 86, 117, 117, 117, 117, 117, + 66, 79, 78, 80, 80, 80, 80, 80, 80, 80, + 81, 81, 81, 81, 81, 81, 81, 87, 83, 88, + 88, 88, 88, 91, 92, 93, 93, 93, 93, 94, + 94, 96, 96, 96, 97, 97, 98, 98, 99, 99, + 100, 100, 89, 89, 95, 90, 101, 101, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, 104, 105, + 105, 105, 105, 107, 108, 109, 109, 84, 84, 110, + 110, 112, 112, 85, 85, 85, 65, 65, 76, 114, + 63, 115, 116, 86, 86, 86, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 118, 118, - 119, 119, 119, 119, 119, 119, 119, 119, 122, 70, - 70, 70, 70, 123, 124, 123, 124, 123, 124, 123, - 124, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 118, + 118, 119, 119, 119, 119, 119, 119, 119, 119, 122, + 70, 70, 70, 70, 123, 124, 123, 124, 123, 124, + 123, 124, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 125, 73, 113, 113, 113, 113, 127, - 128, 127, 128, 127, 128, 127, 128, 129, 129, 129, + 126, 126, 126, 126, 125, 73, 113, 113, 113, 113, + 127, 128, 127, 128, 127, 128, 127, 128, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, - 129, 129, 106, 106, 106, 106, 131, 132, 131, 132, - 131, 131, 132, 132, 133, 133, 133, 133, 135, 71, - 71, 71, 136, 136, 137, 62, 60, 61, 138, 121, - 82, 130, 134, 120, 139, 139, 139, 139, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 74, 69, - 69, 77, 111, 102, 102, 102, 102, 102, 140}; + 129, 129, 129, 106, 106, 106, 106, 131, 132, 131, + 132, 131, 131, 132, 132, 133, 133, 133, 133, 135, + 71, 71, 71, 136, 136, 137, 62, 60, 61, 138, + 121, 82, 130, 134, 120, 139, 139, 139, 139, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 74, + 69, 69, 77, 111, 102, 102, 102, 102, 102, 140}; const short QXmlStreamReader_Table::rhs [] = { 2, 1, 4, 2, 2, 2, 2, 2, 2, 0, 1, 1, 9, 2, 4, 0, 4, 4, 6, 6, - 4, 1, 3, 1, 1, 1, 2, 2, 2, 1, - 1, 1, 1, 1, 1, 1, 4, 4, 1, 1, - 1, 1, 1, 2, 1, 1, 1, 0, 2, 2, - 2, 6, 6, 1, 5, 1, 5, 3, 5, 0, - 1, 6, 8, 4, 2, 1, 5, 1, 1, 1, - 1, 1, 1, 1, 1, 6, 7, 1, 2, 2, - 1, 4, 3, 3, 1, 2, 5, 6, 4, 6, - 3, 5, 5, 3, 4, 4, 5, 2, 3, 2, - 2, 4, 5, 5, 7, 1, 1, 1, 1, 1, + 4, 1, 3, 1, 1, 1, 2, 2, 2, 0, + 1, 1, 1, 1, 1, 1, 1, 4, 4, 1, + 1, 1, 1, 1, 2, 1, 1, 1, 0, 2, + 2, 2, 6, 6, 1, 5, 1, 5, 3, 5, + 0, 1, 6, 8, 4, 2, 1, 5, 1, 1, + 1, 1, 1, 1, 1, 1, 6, 7, 1, 2, + 2, 1, 4, 3, 3, 1, 2, 5, 6, 4, + 6, 3, 5, 5, 3, 4, 4, 5, 2, 3, + 2, 2, 4, 5, 5, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, - 2, 3, 3, 2, 2, 2, 2, 1, 1, 1, + 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, + 2, 2, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 2, 3, 3, 2, - 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 3, 3, + 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 2, 3, 3, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 5, 0, - 1, 3, 1, 3, 2, 4, 3, 5, 1, 3, - 3, 3, 3, 4, 1, 1, 2, 2, 2, 4, - 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2}; + 1, 1, 1, 2, 2, 3, 3, 2, 2, 2, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 5, + 0, 1, 3, 1, 3, 2, 4, 3, 5, 1, + 3, 3, 3, 3, 4, 1, 1, 2, 2, 2, + 4, 2, 2, 2, 2, 2, 2, 2, 0, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 2}; const short QXmlStreamReader_Table::action_default [] = { - 10, 258, 0, 2, 1, 0, 124, 116, 118, 119, - 126, 128, 122, 11, 113, 107, 0, 108, 127, 110, - 114, 112, 120, 123, 125, 106, 109, 111, 117, 115, - 130, 121, 239, 12, 253, 135, 249, 252, 0, 129, - 139, 256, 16, 251, 137, 136, 0, 255, 138, 258, - 230, 257, 254, 0, 0, 263, 0, 246, 245, 0, - 248, 247, 244, 240, 98, 262, 0, 235, 0, 0, - 259, 96, 97, 100, 0, 131, 133, 132, 134, 0, - 0, 260, 0, 0, 175, 0, 172, 164, 166, 167, - 141, 153, 170, 161, 155, 156, 152, 158, 162, 160, - 168, 171, 151, 154, 157, 159, 165, 163, 173, 169, - 149, 174, 0, 143, 147, 145, 150, 140, 148, 0, - 146, 142, 144, 0, 15, 14, 261, 0, 22, 21, - 260, 0, 0, 20, 0, 0, 31, 36, 30, 0, - 32, 260, 0, 33, 0, 24, 0, 34, 0, 26, - 35, 25, 0, 241, 40, 39, 260, 42, 48, 260, - 41, 0, 43, 260, 48, 260, 0, 260, 0, 48, - 0, 47, 45, 46, 50, 51, 260, 260, 0, 56, - 260, 53, 260, 0, 57, 0, 54, 260, 52, 260, - 0, 55, 64, 0, 260, 60, 260, 0, 58, 61, - 62, 0, 260, 0, 0, 59, 63, 44, 49, 65, - 0, 38, 0, 0, 260, 0, 93, 94, 0, 0, - 0, 0, 260, 0, 209, 200, 202, 204, 177, 189, - 207, 198, 192, 190, 193, 188, 195, 197, 205, 208, - 187, 191, 194, 196, 201, 199, 203, 206, 210, 212, - 211, 185, 0, 0, 242, 179, 183, 181, 0, 0, - 92, 186, 176, 184, 0, 182, 178, 180, 91, 0, - 95, 0, 0, 0, 0, 0, 260, 85, 260, 0, - 261, 0, 86, 0, 88, 68, 73, 72, 69, 70, - 71, 260, 74, 75, 0, 0, 0, 268, 267, 265, - 266, 264, 66, 260, 0, 260, 0, 0, 67, 76, - 260, 0, 260, 0, 0, 77, 0, 78, 0, 81, - 84, 0, 0, 214, 224, 223, 0, 226, 228, 227, - 225, 0, 243, 216, 220, 218, 222, 213, 221, 0, - 219, 215, 217, 0, 80, 79, 0, 82, 0, 83, - 87, 99, 0, 37, 0, 0, 0, 0, 90, 89, - 0, 102, 23, 27, 29, 28, 0, 0, 260, 261, - 0, 260, 0, 105, 104, 260, 0, 103, 101, 0, - 0, 18, 260, 17, 0, 19, 0, 0, 250, 0, - 260, 0, 238, 0, 231, 237, 0, 236, 233, 260, - 260, 261, 232, 234, 0, 260, 0, 229, 260, 0, - 260, 0, 230, 0, 0, 13, 269, 9, 5, 8, - 4, 0, 7, 258, 6, 0, 3}; + 10, 259, 0, 2, 1, 0, 125, 117, 119, 120, + 127, 129, 123, 11, 114, 108, 0, 109, 128, 111, + 115, 113, 121, 124, 126, 107, 110, 112, 118, 116, + 131, 122, 240, 12, 254, 136, 250, 253, 0, 130, + 140, 257, 16, 252, 138, 137, 0, 256, 139, 259, + 231, 258, 255, 0, 0, 264, 0, 247, 246, 0, + 249, 248, 245, 241, 99, 263, 0, 236, 0, 0, + 260, 97, 98, 101, 0, 132, 134, 133, 135, 0, + 0, 261, 0, 0, 176, 0, 173, 165, 167, 168, + 142, 154, 171, 162, 156, 157, 153, 159, 163, 161, + 169, 172, 152, 155, 158, 160, 166, 164, 174, 170, + 150, 175, 0, 144, 148, 146, 151, 141, 149, 0, + 147, 143, 145, 0, 15, 14, 262, 0, 22, 21, + 261, 30, 0, 20, 0, 0, 32, 37, 31, 0, + 33, 261, 0, 34, 0, 24, 0, 35, 0, 26, + 36, 25, 0, 242, 41, 40, 261, 43, 49, 261, + 42, 0, 44, 261, 49, 261, 0, 261, 0, 49, + 0, 48, 46, 47, 51, 52, 261, 261, 0, 57, + 261, 54, 261, 0, 58, 0, 55, 261, 53, 261, + 0, 56, 65, 0, 261, 61, 261, 0, 59, 62, + 63, 0, 261, 0, 0, 60, 64, 45, 50, 66, + 0, 39, 0, 0, 261, 0, 94, 95, 0, 0, + 0, 0, 261, 0, 210, 201, 203, 205, 178, 190, + 208, 199, 193, 191, 194, 189, 196, 198, 206, 209, + 188, 192, 195, 197, 202, 200, 204, 207, 211, 213, + 212, 186, 0, 0, 243, 180, 184, 182, 0, 0, + 93, 187, 177, 185, 0, 183, 179, 181, 92, 0, + 96, 0, 0, 0, 0, 0, 261, 86, 261, 0, + 262, 0, 87, 0, 89, 69, 74, 73, 70, 71, + 72, 261, 75, 76, 0, 0, 0, 269, 268, 266, + 267, 265, 67, 261, 0, 261, 0, 0, 68, 77, + 261, 0, 261, 0, 0, 78, 0, 79, 0, 82, + 85, 0, 0, 215, 225, 224, 0, 227, 229, 228, + 226, 0, 244, 217, 221, 219, 223, 214, 222, 0, + 220, 216, 218, 0, 81, 80, 0, 83, 0, 84, + 88, 100, 0, 38, 0, 0, 0, 0, 91, 90, + 0, 103, 23, 27, 29, 28, 0, 0, 261, 262, + 0, 261, 0, 106, 105, 261, 0, 104, 102, 0, + 0, 18, 261, 17, 0, 19, 0, 0, 251, 0, + 261, 0, 239, 0, 232, 238, 0, 237, 234, 261, + 261, 262, 233, 235, 0, 261, 0, 230, 261, 0, + 261, 0, 231, 0, 0, 13, 270, 9, 5, 8, + 4, 0, 7, 259, 6, 0, 3}; const short QXmlStreamReader_Table::goto_default [] = { 2, 4, 3, 49, 388, 43, 37, 52, 47, 41, @@ -736,8 +736,8 @@ public: } }; -class QXmlStreamEntityResolver; +class QXmlStreamEntityResolver; #ifndef QT_NO_XMLSTREAMREADER class QXmlStreamReaderPrivate : public QXmlStreamReader_Table, public QXmlStreamPrivateTagStack{ QXmlStreamReader *q_ptr; @@ -1355,44 +1355,44 @@ bool QXmlStreamReaderPrivate::parse() scanDtd = false; break; - case 36: + case 37: if (!scanString(spell[EMPTY], EMPTY, false) && !scanString(spell[ANY], ANY, false) && atEnd) { - resume(36); + resume(37); return false; } break; - case 42: + case 43: if (!scanString(spell[PCDATA], PCDATA, false) && atEnd) { - resume(42); + resume(43); return false; } break; - case 67: { + case 68: { lastAttributeIsCData = true; } break; - case 77: + case 78: if (!scanAfterDefaultDecl() && atEnd) { - resume(77); + resume(78); return false; } break; - case 82: + case 83: sym(1) = sym(2); lastAttributeValue.clear(); lastAttributeIsCData = false; if (!scanAttType() && atEnd) { - resume(82); + resume(83); return false; } break; - case 83: { + case 84: { DtdAttribute &dtdAttribute = dtdAttributes.push(); dtdAttribute.tagName.clear(); dtdAttribute.isCDATA = lastAttributeIsCData; @@ -1413,7 +1413,7 @@ bool QXmlStreamReaderPrivate::parse() } } break; - case 87: { + case 88: { if (referenceToUnparsedEntityDetected && !standalone) break; int n = dtdAttributes.size(); @@ -1433,9 +1433,9 @@ bool QXmlStreamReaderPrivate::parse() } } break; - case 88: { + case 89: { if (!scanPublicOrSystem() && atEnd) { - resume(88); + resume(89); return false; } EntityDeclaration &entityDeclaration = entityDeclarations.push(); @@ -1443,9 +1443,9 @@ bool QXmlStreamReaderPrivate::parse() entityDeclaration.name = symString(3); } break; - case 89: { + case 90: { if (!scanPublicOrSystem() && atEnd) { - resume(89); + resume(90); return false; } EntityDeclaration &entityDeclaration = entityDeclarations.push(); @@ -1454,9 +1454,9 @@ bool QXmlStreamReaderPrivate::parse() entityDeclaration.parameter = true; } break; - case 90: { + case 91: { if (!scanNData() && atEnd) { - resume(90); + resume(91); return false; } EntityDeclaration &entityDeclaration = entityDeclarations.top(); @@ -1464,9 +1464,9 @@ bool QXmlStreamReaderPrivate::parse() entityDeclaration.external = true; } break; - case 91: { + case 92: { if (!scanNData() && atEnd) { - resume(91); + resume(92); return false; } EntityDeclaration &entityDeclaration = entityDeclarations.top(); @@ -1475,7 +1475,7 @@ bool QXmlStreamReaderPrivate::parse() entityDeclaration.external = true; } break; - case 92: { + case 93: { EntityDeclaration &entityDeclaration = entityDeclarations.top(); entityDeclaration.notationName = symString(3); if (entityDeclaration.parameter) @@ -1483,8 +1483,8 @@ bool QXmlStreamReaderPrivate::parse() } //fall through - case 93: - case 94: { + case 94: + case 95: { if (referenceToUnparsedEntityDetected && !standalone) { entityDeclarations.pop(); break; @@ -1502,7 +1502,7 @@ bool QXmlStreamReaderPrivate::parse() } } break; - case 95: { + case 96: { setType(QXmlStreamReader::ProcessingInstruction); int pos = sym(4).pos + sym(4).len; processingInstructionTarget = symString(3); @@ -1515,39 +1515,39 @@ bool QXmlStreamReaderPrivate::parse() else if(!QXmlUtils::isNCName(piTarget)) raiseWellFormedError(QXmlStream::tr("%1 is an invalid processing instruction name.").arg(piTarget)); } else if (type != QXmlStreamReader::Invalid){ - resume(95); + resume(96); return false; } } break; - case 96: + case 97: setType(QXmlStreamReader::ProcessingInstruction); processingInstructionTarget = symString(3); if (!processingInstructionTarget.toString().compare(QLatin1String("xml"), Qt::CaseInsensitive)) raiseWellFormedError(QXmlStream::tr("Invalid processing instruction name.")); break; - case 97: + case 98: if (!scanAfterLangleBang() && atEnd) { - resume(97); + resume(98); return false; } break; - case 98: + case 99: if (!scanUntil("--")) { - resume(98); + resume(99); return false; } break; - case 99: { + case 100: { setType(QXmlStreamReader::Comment); int pos = sym(1).pos + 4; text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3); } break; - case 100: { + case 101: { setType(QXmlStreamReader::Characters); isCDATA = true; isWhitespace = false; @@ -1555,131 +1555,131 @@ bool QXmlStreamReaderPrivate::parse() if (scanUntil("]]>", -1)) { text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3); } else { - resume(100); + resume(101); return false; } } break; - case 101: { + case 102: { if (!scanPublicOrSystem() && atEnd) { - resume(101); + resume(102); return false; } NotationDeclaration ¬ationDeclaration = notationDeclarations.push(); notationDeclaration.name = symString(3); } break; - case 102: { + case 103: { NotationDeclaration ¬ationDeclaration = notationDeclarations.top(); notationDeclaration.systemId = symString(3); notationDeclaration.publicId.clear(); } break; - case 103: { + case 104: { NotationDeclaration ¬ationDeclaration = notationDeclarations.top(); notationDeclaration.systemId.clear(); checkPublicLiteral((notationDeclaration.publicId = symString(3))); } break; - case 104: { + case 105: { NotationDeclaration ¬ationDeclaration = notationDeclarations.top(); checkPublicLiteral((notationDeclaration.publicId = symString(3))); notationDeclaration.systemId = symString(5); } break; - case 128: + case 129: isWhitespace = false; // fall through - case 129: + case 130: sym(1).len += fastScanContentCharList(); if (atEnd && !inParseEntity) { - resume(129); + resume(130); return false; } break; - case 138: + case 139: if (!textBuffer.isEmpty()) { setType(QXmlStreamReader::Characters); text = &textBuffer; } break; - case 139: case 140: + case 141: clearSym(); break; - case 141: case 142: + case 143: sym(1) = sym(2); break; - case 143: case 144: case 145: case 146: + case 147: sym(1).len += sym(2).len; break; - case 172: + case 173: if (normalizeLiterals) textBuffer.data()[textBuffer.size()-1] = QLatin1Char(' '); break; - case 173: + case 174: sym(1).len += fastScanLiteralContent(); if (atEnd) { - resume(173); + resume(174); return false; } break; - case 174: { + case 175: { if (!QXmlUtils::isPublicID(symString(1).toString())) { raiseWellFormedError(QXmlStream::tr("%1 is an invalid PUBLIC identifier.").arg(symString(1).toString())); - resume(174); + resume(175); return false; } } break; - case 175: case 176: + case 177: clearSym(); break; - case 177: case 178: + case 179: sym(1) = sym(2); break; - case 179: case 180: case 181: case 182: + case 183: sym(1).len += sym(2).len; break; - case 212: case 213: + case 214: clearSym(); break; - case 214: case 215: + case 216: sym(1) = sym(2); lastAttributeValue = symString(1); break; - case 216: case 217: case 218: case 219: + case 220: sym(1).len += sym(2).len; break; - case 228: { + case 229: { QStringRef prefix = symPrefix(1); if (prefix.isEmpty() && symString(1) == QLatin1String("xmlns") && namespaceProcessing) { NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push(); @@ -1749,7 +1749,7 @@ bool QXmlStreamReaderPrivate::parse() } } break; - case 234: { + case 235: { normalizeLiterals = true; Tag &tag = tagStack_push(); prefix = tag.namespaceDeclaration.prefix = addToStringStorage(symPrefix(2)); @@ -1759,11 +1759,11 @@ bool QXmlStreamReaderPrivate::parse() raiseWellFormedError(QXmlStream::tr("Invalid XML name.")); } break; - case 235: + case 236: isEmptyElement = true; // fall through - case 236: + case 237: setType(QXmlStreamReader::StartElement); resolveTag(); if (tagStack.size() == 1 && hasSeenTag && !inParseEntity) @@ -1771,7 +1771,7 @@ bool QXmlStreamReaderPrivate::parse() hasSeenTag = true; break; - case 237: { + case 238: { setType(QXmlStreamReader::EndElement); Tag &tag = tagStack_pop(); @@ -1782,7 +1782,7 @@ bool QXmlStreamReaderPrivate::parse() raiseWellFormedError(QXmlStream::tr("Opening and ending tag mismatch.")); } break; - case 238: + case 239: if (entitiesMustBeDeclared()) { raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(unresolvedEntity)); break; @@ -1791,7 +1791,7 @@ bool QXmlStreamReaderPrivate::parse() name = &unresolvedEntity; break; - case 239: { + case 240: { sym(1).len += sym(2).len + 1; QString reference = symString(2).toString(); if (entityHash.contains(reference)) { @@ -1830,7 +1830,7 @@ bool QXmlStreamReaderPrivate::parse() } break; - case 240: { + case 241: { sym(1).len += sym(2).len + 1; QString reference = symString(2).toString(); if (parameterEntityHash.contains(reference)) { @@ -1849,11 +1849,11 @@ bool QXmlStreamReaderPrivate::parse() } } break; - case 241: + case 242: sym(1).len += sym(2).len + 1; break; - case 242: { + case 243: { sym(1).len += sym(2).len + 1; QString reference = symString(2).toString(); if (entityHash.contains(reference)) { @@ -1889,7 +1889,7 @@ bool QXmlStreamReaderPrivate::parse() } } break; - case 243: { + case 244: { if (uint s = resolveCharRef(3)) { if (s >= 0xffff) putStringLiteral(QString::fromUcs4(&s, 1)); @@ -1903,43 +1903,43 @@ bool QXmlStreamReaderPrivate::parse() } } break; - case 246: case 247: + case 248: sym(1).len += sym(2).len; break; - case 258: + case 259: sym(1).len += fastScanSpace(); if (atEnd) { - resume(258); + resume(259); return false; } break; - case 261: { + case 262: { sym(1).len += fastScanName(&sym(1).prefix); if (atEnd) { - resume(261); + resume(262); return false; } } break; - case 262: + case 263: sym(1).len += fastScanName(); if (atEnd) { - resume(262); + resume(263); return false; } break; - case 263: case 264: case 265: case 266: case 267: + case 268: sym(1).len += fastScanNMTOKEN(); if (atEnd) { - resume(267); + resume(268); return false; } @@ -1958,7 +1958,8 @@ bool QXmlStreamReaderPrivate::parse() } return false; } +#endif //QT_NO_XMLSTREAMREADER.xml + -#endif //QT_NO_XMLSTREAMREADER #endif // QXMLSTREAM_P_H diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index d3aff6d..d7088ff 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -1005,9 +1005,6 @@ void QDBusConnectionPrivate::setBusService(const QDBusConnection &connection) busService = new QDBusConnectionInterface(connection, this); ref.deref(); // busService has increased the refcounting to us // avoid cyclic refcounting -// if (mode != PeerMode) - QObject::connect(busService, SIGNAL(serviceOwnerChanged(QString,QString,QString)), - this, SIGNAL(serviceOwnerChanged(QString,QString,QString))); QObject::connect(this, SIGNAL(callWithCallbackFailed(QDBusError,QDBusMessage)), busService, SIGNAL(callWithCallbackFailed(QDBusError,QDBusMessage)), diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 830dac3..b65e101 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -199,9 +199,6 @@ public: QDBusMetaObject *findMetaObject(const QString &service, const QString &path, const QString &interface, QDBusError &error); - void registerService(const QString &serviceName); - void unregisterService(const QString &serviceName); - void postEventToThread(int action, QObject *target, QEvent *event); inline void serverConnection(const QDBusConnection &connection) @@ -238,6 +235,8 @@ public slots: void objectDestroyed(QObject *o); void relaySignal(QObject *obj, const QMetaObject *, int signalId, const QVariantList &args); void _q_serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner); + void registerService(const QString &serviceName); + void unregisterService(const QString &serviceName); signals: void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner); diff --git a/src/dbus/qdbusconnectioninterface.cpp b/src/dbus/qdbusconnectioninterface.cpp index 3b38432..0f9a67f 100644 --- a/src/dbus/qdbusconnectioninterface.cpp +++ b/src/dbus/qdbusconnectioninterface.cpp @@ -337,6 +337,11 @@ void QDBusConnectionInterface::connectNotify(const char *signalName) QDBusAbstractInterface::connectNotify(SIGNAL(NameLost(QString))); else if (qstrcmp(signalName, SIGNAL(serviceOwnerChanged(QString,QString,QString))) == 0) { + static bool warningPrinted = false; + if (!warningPrinted) { + qWarning("Connecting to deprecated signal QDBusConnectionInterface::serviceOwnerChanged(QString,QString,QString)"); + warningPrinted = true; + } QDBusAbstractInterface::connectNotify(SIGNAL(NameOwnerChanged(QString,QString,QString))); } } @@ -389,6 +394,12 @@ void QDBusConnectionInterface::disconnectNotify(const char *signalName) empty string, it means the name \a name has just been created; if \a newOwner is empty, the name \a name has no current owner and is no longer available. + + \note connecting to this signal will make the application listen for and + receive every single service ownership change on the bus. Depending on + how many services are running, this make the application be activated to + receive more signals than it needs. To avoid this problem, use the + QDBusServiceWatcher class, which can listen for specific changes. */ /*! diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 870ddd0..40febc4 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -948,9 +948,6 @@ QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p) rootNode.flags = 0; watchedServiceNames[QLatin1String(DBUS_SERVICE_DBUS)] = 1; - - connect(this, SIGNAL(serviceOwnerChanged(QString,QString,QString)), - this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); } QDBusConnectionPrivate::~QDBusConnectionPrivate() @@ -1180,11 +1177,7 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in void QDBusConnectionPrivate::_q_serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner) { - if (oldOwner == baseService) - unregisterService(name); - if (newOwner == baseService) - registerService(name); - + Q_UNUSED(oldOwner); QDBusWriteLocker locker(UpdateSignalHookOwnerAction, this); QMutableHashIterator<QString, SignalHook> it(signalHooks); it.toFront(); @@ -1655,9 +1648,16 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError baseService = QString::fromUtf8(service); } else { - qWarning("QDBusConnectionPrivate::SetConnection: Unable to get base service"); + qWarning("QDBusConnectionPrivate::setConnection: Unable to get base service"); } + QString busService = QLatin1String(DBUS_SERVICE_DBUS); + connectSignal(busService, QString(), QString(), QString(), QLatin1String("NameAcquired"), QStringList(), QString(), + this, SLOT(registerService(QString))); + connectSignal(busService, QString(), QString(), QString(), QLatin1String("NameLost"), QStringList(), QString(), + this, SLOT(unregisterService(QString))); + + q_dbus_connection_add_filter(connection, qDBusSignalFilter, this, 0); //qDebug("base service: %s", service); diff --git a/src/dbus/qdbusservicewatcher.cpp b/src/dbus/qdbusservicewatcher.cpp index 1557b47..4328558 100644 --- a/src/dbus/qdbusservicewatcher.cpp +++ b/src/dbus/qdbusservicewatcher.cpp @@ -50,7 +50,6 @@ QT_BEGIN_NAMESPACE Q_GLOBAL_STATIC_WITH_ARGS(QString, busService, (QLatin1String(DBUS_SERVICE_DBUS))) -Q_GLOBAL_STATIC_WITH_ARGS(QString, busPath, (QLatin1String(DBUS_PATH_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString, busInterface, (QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString, signalName, (QLatin1String("NameOwnerChanged"))) @@ -127,7 +126,7 @@ QStringList QDBusServiceWatcherPrivate::matchArgsForService(const QString &servi void QDBusServiceWatcherPrivate::addService(const QString &service) { QStringList matchArgs = matchArgsForService(service); - connection.connect(*busService(), *busPath(), *busInterface(), *signalName(), + connection.connect(*busService(), QString(), *busInterface(), *signalName(), matchArgs, QString(), q_func(), SLOT(_q_serviceOwnerChanged(QString,QString,QString))); } @@ -135,7 +134,7 @@ void QDBusServiceWatcherPrivate::addService(const QString &service) void QDBusServiceWatcherPrivate::removeService(const QString &service) { QStringList matchArgs = matchArgsForService(service); - connection.disconnect(*busService(), *busPath(), *busInterface(), *signalName(), + connection.disconnect(*busService(), QString(), *busInterface(), *signalName(), matchArgs, QString(), q_func(), SLOT(_q_serviceOwnerChanged(QString,QString,QString))); } diff --git a/src/gui/dialogs/dialogs.pri b/src/gui/dialogs/dialogs.pri index b9fad41..63f64a2 100644 --- a/src/gui/dialogs/dialogs.pri +++ b/src/gui/dialogs/dialogs.pri @@ -28,13 +28,27 @@ HEADERS += \ dialogs/qprintpreviewdialog.h !embedded:mac { - OBJECTIVE_SOURCES += dialogs/qcolordialog_mac.mm \ - dialogs/qfiledialog_mac.mm \ + OBJECTIVE_SOURCES += dialogs/qfiledialog_mac.mm \ dialogs/qfontdialog_mac.mm \ dialogs/qnspanelproxy_mac.mm \ dialogs/qpagesetupdialog_mac.mm \ dialogs/qprintdialog_mac.mm + +# Compile qcolordialog_mac.mm with exception support, disregarding the -no-exceptions +# configure option. (qcolordialog_mac needs to catch exceptions thrown by cocoa) + EXCEPTION_SOURCES = dialogs/qcolordialog_mac.mm + exceptions_compiler.commands = $$QMAKE_CXX -c + exceptions_compiler.commands += $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} + exceptions_compiler.commands += -fexceptions + exceptions_compiler.dependency_type = TYPE_C + exceptions_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} + exceptions_compiler.input = EXCEPTION_SOURCES + exceptions_compiler.variable_out = OBJECTS + exceptions_compiler.name = compiling[exceptopns] ${QMAKE_FILE_IN} + silent:exceptions_compiler.commands = @echo compiling[exceptopns] ${QMAKE_FILE_IN} && $$exceptions_compiler.commands + QMAKE_EXTRA_COMPILERS += exceptions_compiler } + win32 { HEADERS += dialogs/qwizard_win_p.h SOURCES += dialogs/qdialogsbinarycompat_win.cpp \ diff --git a/src/gui/dialogs/qcolordialog_mac.mm b/src/gui/dialogs/qcolordialog_mac.mm index 5f074c0..53d2e1e 100644 --- a/src/gui/dialogs/qcolordialog_mac.mm +++ b/src/gui/dialogs/qcolordialog_mac.mm @@ -336,7 +336,6 @@ QT_USE_NAMESPACE } } - QAbstractEventDispatcher::instance()->interrupt(); if (mResultCode == NSCancelButton) mPriv->colorDialog()->reject(); else diff --git a/src/gui/dialogs/qfiledialog_win.cpp b/src/gui/dialogs/qfiledialog_win.cpp index d8ae73e..0116319 100644 --- a/src/gui/dialogs/qfiledialog_win.cpp +++ b/src/gui/dialogs/qfiledialog_win.cpp @@ -534,7 +534,7 @@ QStringList qt_win_CID_get_open_file_names(const QFileDialogArgs &args, modal_widget.setParent(args.parent, Qt::Window); QApplicationPrivate::enterModal(&modal_widget); // Multiple selection is allowed only in IFileOpenDialog. - IFileOpenDialog *pfd; + IFileOpenDialog *pfd = 0; HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, @@ -607,6 +607,8 @@ QStringList qt_win_CID_get_open_file_names(const QFileDialogArgs &args, } } } + if (pfd) + pfd->Release(); return result; } diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm index 5b0983b..0c467cd 100644 --- a/src/gui/dialogs/qfontdialog_mac.mm +++ b/src/gui/dialogs/qfontdialog_mac.mm @@ -625,10 +625,11 @@ void QFontDialogPrivate::setFont(void *delegate, const QFont &font) } NSFontManager *mgr = [NSFontManager sharedFontManager]; - nsFont = [mgr fontWithFamily:qt_mac_QStringToNSString(font.family()) + QFontInfo fontInfo(font); + nsFont = [mgr fontWithFamily:qt_mac_QStringToNSString(fontInfo.family()) traits:mask weight:weight - size:QFontInfo(font).pointSize()]; + size:fontInfo.pointSize()]; } [mgr setSelectedFont:nsFont isMultiple:NO]; diff --git a/src/gui/dialogs/qprogressdialog.cpp b/src/gui/dialogs/qprogressdialog.cpp index f5024bb..98b15e9 100644 --- a/src/gui/dialogs/qprogressdialog.cpp +++ b/src/gui/dialogs/qprogressdialog.cpp @@ -424,10 +424,6 @@ void QProgressDialog::setCancelButton(QPushButton *cancelButton) { Q_D(QProgressDialog); delete d->cancel; -#ifdef QT_SOFTKEYS_ENABLED - delete d->cancelAction; - d->cancelAction = 0; -#endif d->cancel = cancelButton; if (cancelButton) { if (cancelButton->parentWidget() == this) { diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index c0e4890..6ee4bfc 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -236,6 +236,18 @@ bool QEglContext::makeCurrent(EGLSurface surface) currentSurface = surface; setCurrentContext(apiType, this); + // Force the right API to be bound before making the context current. + // The EGL implementation should be able to figure this out from ctx, + // but some systems require the API to be explicitly set anyway. +#ifdef EGL_OPENGL_ES_API + if (apiType == QEgl::OpenGL) + eglBindAPI(EGL_OPENGL_ES_API); +#endif +#ifdef EGL_OPENVG_API + if (apiType == QEgl::OpenVG) + eglBindAPI(EGL_OPENVG_API); +#endif + bool ok = eglMakeCurrent(dpy, surface, surface, ctx); if (!ok) qWarning() << "QEglContext::makeCurrent():" << errorString(eglGetError()); @@ -417,7 +429,10 @@ QString QEglContext::extensions() bool QEglContext::hasExtension(const char* extensionName) { - return extensions().contains(QLatin1String(extensionName)); + QList<QByteArray> extensions = + QByteArray(reinterpret_cast<const char *> + (eglQueryString(QEglContext::defaultDisplay(0), EGL_EXTENSIONS))).split(' '); + return extensions.contains(extensionName); } QEglContext *QEglContext::currentContext(QEgl::API api) diff --git a/src/gui/egl/qeglproperties.cpp b/src/gui/egl/qeglproperties.cpp index 2d37edb..4d4410a 100644 --- a/src/gui/egl/qeglproperties.cpp +++ b/src/gui/egl/qeglproperties.cpp @@ -229,6 +229,15 @@ void QEglProperties::setRenderableType(QEgl::API api) // reductions in complexity are possible. bool QEglProperties::reduceConfiguration() { + // EGL chooses configs with the highest color depth over + // those with smaller (but faster) lower color depths. One + // way around this is to set EGL_BUFFER_SIZE to 16, which + // trumps the others. Of course, there may not be a 16-bit + // config avaliable, so it's the first restraint we remove. + if (value(EGL_BUFFER_SIZE) == 16) { + removeValue(EGL_BUFFER_SIZE); + return true; + } if (removeValue(EGL_SAMPLE_BUFFERS)) { removeValue(EGL_SAMPLES); return true; diff --git a/src/gui/graphicsview/qgraph_p.h b/src/gui/graphicsview/qgraph_p.h index 0a2bf27..076b8fa 100644 --- a/src/gui/graphicsview/qgraph_p.h +++ b/src/gui/graphicsview/qgraph_p.h @@ -236,11 +236,13 @@ public: EdgeData *data = edgeData(v, v1); bool forward = data->from == v; if (forward) { - edges += QString::fromAscii("\"%1\"->\"%2\" [label=\"[%3,%4,%5]\" dir=both color=\"#000000:#a0a0a0\"] \n") + edges += QString::fromAscii("\"%1\"->\"%2\" [label=\"[%3,%4,%5,%6,%7]\" color=\"#000000\"] \n") .arg(v->toString()) .arg(v1->toString()) .arg(data->minSize) + .arg(data->minPrefSize) .arg(data->prefSize) + .arg(data->maxPrefSize) .arg(data->maxSize) ; } diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp index 7e5929e..6718a28 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp @@ -158,7 +158,7 @@ QGraphicsAnchor::~QGraphicsAnchor() \property QGraphicsAnchor::sizePolicy \brief the size policy for the QGraphicsAnchor. - By setting the size policy on an anchor you can configure how the item can resize itself + By setting the size policy on an anchor you can configure how the anchor can resize itself from its preferred spacing. For instance, if the anchor has the size policy QSizePolicy::Minimum, the spacing is the minimum size of the anchor. However, its size can grow up to the anchors maximum size. If the default size policy is QSizePolicy::Fixed, @@ -247,7 +247,7 @@ QGraphicsAnchorLayout::~QGraphicsAnchorLayout() /*! Creates an anchor between the edge \a firstEdge of item \a firstItem and the edge \a secondEdge - of item \a secondItem. The magnitude of the anchor is picked up from the style. Anchors + of item \a secondItem. The spacing of the anchor is picked up from the style. Anchors between a layout edge and an item edge will have a size of 0. If there is already an anchor between the edges, the the new anchor will replace the old one. @@ -370,12 +370,6 @@ void QGraphicsAnchorLayout::setHorizontalSpacing(qreal spacing) { Q_D(QGraphicsAnchorLayout); - // ### We don't support negative spacing yet - if (spacing < 0) { - spacing = 0; - qWarning() << "QGraphicsAnchorLayout does not support negative spacing."; - } - d->spacings[0] = spacing; invalidate(); } @@ -389,12 +383,6 @@ void QGraphicsAnchorLayout::setVerticalSpacing(qreal spacing) { Q_D(QGraphicsAnchorLayout); - // ### We don't support negative spacing yet - if (spacing < 0) { - spacing = 0; - qWarning() << "QGraphicsAnchorLayout does not support negative spacing."; - } - d->spacings[1] = spacing; invalidate(); } @@ -405,7 +393,8 @@ void QGraphicsAnchorLayout::setVerticalSpacing(qreal spacing) If an item is anchored with no spacing associated with the anchor, it will use the default spacing. - Currently QGraphicsAnchorLayout does not support negative default spacings. + QGraphicsAnchorLayout does not support negative spacings. Setting a negative value will unset the + previous spacing and make the layout use the spacing provided by the current widget style. \sa setHorizontalSpacing(), setVerticalSpacing() */ @@ -413,14 +402,6 @@ void QGraphicsAnchorLayout::setSpacing(qreal spacing) { Q_D(QGraphicsAnchorLayout); - // ### Currently we do not support negative anchors inside the graph. - // To avoid those being created by a negative spacing, we must - // make this test. - if (spacing < 0) { - spacing = 0; - qWarning() << "QGraphicsAnchorLayout does not support negative spacing."; - } - d->spacings[0] = d->spacings[1] = spacing; invalidate(); } diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index fb67278..03ed63d 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -49,20 +49,34 @@ #endif #include "qgraphicsanchorlayout_p.h" + #ifndef QT_NO_GRAPHICSVIEW QT_BEGIN_NAMESPACE +// To ensure that all variables inside the simplex solver are non-negative, +// we limit the size of anchors in the interval [-limit, limit]. Then before +// sending them to the simplex solver we add "limit" as an offset, so that +// they are actually calculated in the interval [0, 2 * limit] +// To avoid numerical errors in platforms where we use single precision, +// we use a tighter limit for the variables range. +const qreal g_offset = (sizeof(qreal) == sizeof(double)) ? QWIDGETSIZE_MAX : QWIDGETSIZE_MAX / 32; QGraphicsAnchorPrivate::QGraphicsAnchorPrivate(int version) : QObjectPrivate(version), layoutPrivate(0), data(0), sizePolicy(QSizePolicy::Fixed), preferredSize(0), - hasSize(true), reversed(false) + hasSize(true) { } QGraphicsAnchorPrivate::~QGraphicsAnchorPrivate() { - layoutPrivate->removeAnchor(data->from, data->to); + if (data) { + // The QGraphicsAnchor was already deleted at this moment. We must clean + // the dangling pointer to avoid double deletion in the AnchorData dtor. + data->graphicsAnchor = 0; + + layoutPrivate->removeAnchor(data->from, data->to); + } } void QGraphicsAnchorPrivate::setSizePolicy(QSizePolicy::Policy policy) @@ -80,27 +94,12 @@ void QGraphicsAnchorPrivate::setSpacing(qreal value) return; } - const qreal rawValue = reversed ? -preferredSize : preferredSize; - if (hasSize && (rawValue == value)) + if (hasSize && (preferredSize == value)) return; // The anchor has an user-defined size hasSize = true; - - // The simplex solver cannot handle negative sizes. To workaround that, - // if value is less than zero, we reverse the anchor and set the absolute - // value; - if (value >= 0) { - preferredSize = value; - if (reversed) - qSwap(data->from, data->to); - reversed = false; - } else { - preferredSize = -value; - if (!reversed) - qSwap(data->from, data->to); - reversed = true; - } + preferredSize = value; layoutPrivate->q_func()->invalidate(); } @@ -114,9 +113,6 @@ void QGraphicsAnchorPrivate::unsetSpacing() // Return to standard direction hasSize = false; - if (reversed) - qSwap(data->from, data->to); - reversed = false; layoutPrivate->q_func()->invalidate(); } @@ -128,14 +124,14 @@ qreal QGraphicsAnchorPrivate::spacing() const return 0; } - return reversed ? -preferredSize : preferredSize; + return preferredSize; } -static void internalSizeHints(QSizePolicy::Policy policy, - qreal minSizeHint, qreal prefSizeHint, qreal maxSizeHint, - qreal *minSize, qreal *prefSize, - qreal *maxSize) +static void applySizePolicy(QSizePolicy::Policy policy, + qreal minSizeHint, qreal prefSizeHint, qreal maxSizeHint, + qreal *minSize, qreal *prefSize, + qreal *maxSize) { // minSize, prefSize and maxSize are initialized // with item's preferred Size: this is QSizePolicy::Fixed. @@ -167,6 +163,18 @@ static void internalSizeHints(QSizePolicy::Policy policy, *prefSize = prefSizeHint; } +AnchorData::~AnchorData() +{ + if (graphicsAnchor) { + // Remove reference to ourself to avoid double removal in + // QGraphicsAnchorPrivate dtor. + graphicsAnchor->d_func()->data = 0; + + delete graphicsAnchor; + } +} + + void AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo) { QSizePolicy::Policy policy; @@ -182,6 +190,9 @@ void AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo) maxSize = QWIDGETSIZE_MAX; if (isCenterAnchor) maxSize /= 2; + + minPrefSize = prefSize; + maxPrefSize = maxSize; return; } else { if (orientation == QGraphicsAnchorLayoutPrivate::Horizontal) { @@ -206,14 +217,18 @@ void AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo) // It is a user-created anchor, fetch size information from the associated QGraphicsAnchor Q_ASSERT(graphicsAnchor); QGraphicsAnchorPrivate *anchorPrivate = graphicsAnchor->d_func(); + + // Policy, min and max sizes are straightforward policy = anchorPrivate->sizePolicy; minSizeHint = 0; + maxSizeHint = QWIDGETSIZE_MAX; + + // Preferred Size if (anchorPrivate->hasSize) { - // One can only configure the preferred size of a normal anchor. Their minimum and - // maximum "size hints" are always 0 and QWIDGETSIZE_MAX, correspondingly. However, - // their effective size hints might be narrowed down due to their size policies. + // Anchor has user-defined size prefSizeHint = anchorPrivate->preferredSize; } else { + // Fetch size information from style const Qt::Orientation orient = Qt::Orientation(QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge) + 1); qreal s = styleInfo->defaultSpacing(orient); if (s < 0) { @@ -229,10 +244,14 @@ void AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo) } prefSizeHint = s; } - maxSizeHint = QWIDGETSIZE_MAX; } - internalSizeHints(policy, minSizeHint, prefSizeHint, maxSizeHint, - &minSize, &prefSize, &maxSize); + + // Fill minSize, prefSize and maxSize based on policy and sizeHints + applySizePolicy(policy, minSizeHint, prefSizeHint, maxSizeHint, + &minSize, &prefSize, &maxSize); + + minPrefSize = prefSize; + maxPrefSize = maxSize; // Set the anchor effective sizes to preferred. // @@ -252,13 +271,7 @@ void ParallelAnchorData::updateChildrenSizes() firstEdge->sizeAtPreferred = sizeAtPreferred; firstEdge->sizeAtMaximum = sizeAtMaximum; - // We have the convention that the first children will define the direction of the - // pararell group. So we can check whether the second edge is "forward" in relation - // to the group if it have the same direction as the first edge. Note that we don't - // use 'this->from' because it might be changed by vertex simplification. - const bool secondForward = (firstEdge->from == secondEdge->from); - - if (secondForward) { + if (secondForward()) { secondEdge->sizeAtMinimum = sizeAtMinimum; secondEdge->sizeAtPreferred = sizeAtPreferred; secondEdge->sizeAtMaximum = sizeAtMaximum; @@ -272,21 +285,40 @@ void ParallelAnchorData::updateChildrenSizes() secondEdge->updateChildrenSizes(); } -bool ParallelAnchorData::calculateSizeHints() -{ - // Note that parallel groups can lead to unfeasibility, so during calculation, we can - // find out one unfeasibility. Because of that this method return boolean. This can't - // happen in sequential, so there the method is void. +/* + \internal - // Account for parallel anchors where the second edge is backwards. - // We rely on the fact that a forward anchor of sizes min, pref, max is equivalent - // to a backwards anchor of size (-max, -pref, -min) + Initialize the parallel anchor size hints using the sizeHint information from + its children. - // Also see comments in updateChildrenSizes(). - const bool secondForward = (firstEdge->from == secondEdge->from); - const qreal secondMin = secondForward ? secondEdge->minSize : -secondEdge->maxSize; - const qreal secondPref = secondForward ? secondEdge->prefSize : -secondEdge->prefSize; - const qreal secondMax = secondForward ? secondEdge->maxSize : -secondEdge->minSize; + Note that parallel groups can lead to unfeasibility, so during calculation, we can + find out one unfeasibility. Because of that this method return boolean. This can't + happen in sequential, so there the method is void. + */ +bool ParallelAnchorData::calculateSizeHints() +{ + // Normalize second child sizes. + // A negative anchor of sizes min, minPref, pref, maxPref and max, is equivalent + // to a forward anchor of sizes -max, -maxPref, -pref, -minPref, -min + qreal secondMin; + qreal secondMinPref; + qreal secondPref; + qreal secondMaxPref; + qreal secondMax; + + if (secondForward()) { + secondMin = secondEdge->minSize; + secondMinPref = secondEdge->minPrefSize; + secondPref = secondEdge->prefSize; + secondMaxPref = secondEdge->maxPrefSize; + secondMax = secondEdge->maxSize; + } else { + secondMin = -secondEdge->maxSize; + secondMinPref = -secondEdge->maxPrefSize; + secondPref = -secondEdge->prefSize; + secondMaxPref = -secondEdge->minPrefSize; + secondMax = -secondEdge->minSize; + } minSize = qMax(firstEdge->minSize, secondMin); maxSize = qMin(firstEdge->maxSize, secondMax); @@ -298,23 +330,72 @@ bool ParallelAnchorData::calculateSizeHints() return false; } - // The equivalent preferred Size of a parallel anchor is calculated as to - // reduce the deviation from the original preferred sizes _and_ to avoid shrinking - // items below their preferred sizes, unless strictly needed. - - // ### This logic only holds if all anchors in the layout are "well-behaved" in the - // following terms: + // Preferred size calculation + // The calculation of preferred size is done as follows: + // + // 1) Check whether one of the child anchors is the layout structural anchor + // If so, we can simply copy the preferred information from the other child, + // after bounding it to our minimum and maximum sizes. + // If not, then we proceed with the actual calculations. + // + // 2) The whole algorithm for preferred size calculation is based on the fact + // that, if a given anchor cannot remain at its preferred size, it'd rather + // grow than shrink. // - // - There are no negative-sized anchors - // - All sequential anchors are composed of children in the same direction as the - // sequential anchor itself + // What happens though is that while this affirmative is true for simple + // anchors, it may not be true for sequential anchors that have one or more + // reversed anchors inside it. That happens because when a sequential anchor + // grows, any reversed anchors inside it may be required to shrink, something + // we try to avoid, as said above. // - // With these assumptions we can grow a child knowing that no hidden items will - // have to shrink as the result of that. - // If any of these does not hold, we have a situation where the ParallelAnchor - // does not have enough information to calculate its equivalent prefSize. - prefSize = qMax(firstEdge->prefSize, secondPref); - prefSize = qMin(prefSize, maxSize); + // To overcome this, besides their actual preferred size "prefSize", each anchor + // exports what we call "minPrefSize" and "maxPrefSize". These two values define + // a surrounding interval where, if required to move, the anchor would rather + // remain inside. + // + // For standard anchors, this area simply represents the region between + // prefSize and maxSize, which makes sense since our first affirmation. + // For composed anchors, these values are calculated as to reduce the global + // "damage", that is, to reduce the total deviation and the total amount of + // anchors that had to shrink. + + if (firstEdge->isLayoutAnchor) { + prefSize = qBound(minSize, secondPref, maxSize); + minPrefSize = qBound(minSize, secondMinPref, maxSize); + maxPrefSize = qBound(minSize, secondMaxPref, maxSize); + } else if (secondEdge->isLayoutAnchor) { + prefSize = qBound(minSize, firstEdge->prefSize, maxSize); + minPrefSize = qBound(minSize, firstEdge->minPrefSize, maxSize); + maxPrefSize = qBound(minSize, firstEdge->maxPrefSize, maxSize); + } else { + // Calculate the intersection between the "preferred" regions of each child + const qreal lowerBoundary = + qBound(minSize, qMax(firstEdge->minPrefSize, secondMinPref), maxSize); + const qreal upperBoundary = + qBound(minSize, qMin(firstEdge->maxPrefSize, secondMaxPref), maxSize); + const qreal prefMean = + qBound(minSize, (firstEdge->prefSize + secondPref) / 2, maxSize); + + if (lowerBoundary < upperBoundary) { + // If there is an intersection between the two regions, this intersection + // will be used as the preferred region of the parallel anchor itself. + // The preferred size will be the bounded average between the two preferred + // sizes. + prefSize = qBound(lowerBoundary, prefMean, upperBoundary); + minPrefSize = lowerBoundary; + maxPrefSize = upperBoundary; + } else { + // If there is no intersection, we have to attribute "damage" to at least + // one of the children. The minimum total damage is achieved in points + // inside the region that extends from (1) the upper boundary of the lower + // region to (2) the lower boundary of the upper region. + // Then, we expose this region as _our_ preferred region and once again, + // use the bounded average as our preferred size. + prefSize = qBound(upperBoundary, prefMean, lowerBoundary); + minPrefSize = upperBoundary; + maxPrefSize = lowerBoundary; + } + } // See comment in AnchorData::refreshSizeHints() about sizeAt* values sizeAtMinimum = prefSize; @@ -332,19 +413,28 @@ bool ParallelAnchorData::calculateSizeHints() 1 is at Maximum */ static QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> getFactor(qreal value, qreal min, - qreal pref, qreal max) + qreal minPref, qreal pref, + qreal maxPref, qreal max) { QGraphicsAnchorLayoutPrivate::Interval interval; qreal lower; qreal upper; - if (value < pref) { - interval = QGraphicsAnchorLayoutPrivate::MinToPreferred; + if (value < minPref) { + interval = QGraphicsAnchorLayoutPrivate::MinimumToMinPreferred; lower = min; + upper = minPref; + } else if (value < pref) { + interval = QGraphicsAnchorLayoutPrivate::MinPreferredToPreferred; + lower = minPref; upper = pref; - } else { - interval = QGraphicsAnchorLayoutPrivate::PreferredToMax; + } else if (value < maxPref) { + interval = QGraphicsAnchorLayoutPrivate::PreferredToMaxPreferred; lower = pref; + upper = maxPref; + } else { + interval = QGraphicsAnchorLayoutPrivate::MaxPreferredToMaximum; + lower = maxPref; upper = max; } @@ -359,19 +449,26 @@ static QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> getFactor(qreal valu } static qreal interpolate(const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> &factor, - qreal min, qreal pref, - qreal max) + qreal min, qreal minPref, qreal pref, qreal maxPref, qreal max) { qreal lower; qreal upper; switch (factor.first) { - case QGraphicsAnchorLayoutPrivate::MinToPreferred: + case QGraphicsAnchorLayoutPrivate::MinimumToMinPreferred: lower = min; + upper = minPref; + break; + case QGraphicsAnchorLayoutPrivate::MinPreferredToPreferred: + lower = minPref; upper = pref; break; - case QGraphicsAnchorLayoutPrivate::PreferredToMax: + case QGraphicsAnchorLayoutPrivate::PreferredToMaxPreferred: lower = pref; + upper = maxPref; + break; + case QGraphicsAnchorLayoutPrivate::MaxPreferredToMaximum: + lower = maxPref; upper = max; break; } @@ -381,34 +478,43 @@ static qreal interpolate(const QPair<QGraphicsAnchorLayoutPrivate::Interval, qre void SequentialAnchorData::updateChildrenSizes() { - // ### REMOVE ME - // ### check whether we are guarantee to get those or we need to warn stuff at this - // point. - Q_ASSERT(sizeAtMinimum > minSize || qAbs(sizeAtMinimum - minSize) < 0.00000001); - Q_ASSERT(sizeAtPreferred > minSize || qAbs(sizeAtPreferred - minSize) < 0.00000001); - Q_ASSERT(sizeAtMaximum > minSize || qAbs(sizeAtMaximum - minSize) < 0.00000001); - - // These may be false if this anchor was in parallel with the layout stucture - // Q_ASSERT(sizeAtMinimum < maxSize || qAbs(sizeAtMinimum - maxSize) < 0.00000001); - // Q_ASSERT(sizeAtPreferred < maxSize || qAbs(sizeAtPreferred - maxSize) < 0.00000001); - // Q_ASSERT(sizeAtMaximum < maxSize || qAbs(sizeAtMaximum - maxSize) < 0.00000001); - // Band here refers if the value is in the Minimum To Preferred // band (the lower band) or the Preferred To Maximum (the upper band). const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> minFactor = - getFactor(sizeAtMinimum, minSize, prefSize, maxSize); + getFactor(sizeAtMinimum, minSize, minPrefSize, prefSize, maxPrefSize, maxSize); const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> prefFactor = - getFactor(sizeAtPreferred, minSize, prefSize, maxSize); + getFactor(sizeAtPreferred, minSize, minPrefSize, prefSize, maxPrefSize, maxSize); const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> maxFactor = - getFactor(sizeAtMaximum, minSize, prefSize, maxSize); + getFactor(sizeAtMaximum, minSize, minPrefSize, prefSize, maxPrefSize, maxSize); + + // XXX This is not safe if Vertex simplification takes place after the sequential + // anchor is created. In that case, "prev" will be a group-vertex, different from + // "from" or "to", that _contains_ one of them. + AnchorVertex *prev = from; for (int i = 0; i < m_edges.count(); ++i) { AnchorData *e = m_edges.at(i); - e->sizeAtMinimum = interpolate(minFactor, e->minSize, e->prefSize, e->maxSize); - e->sizeAtPreferred = interpolate(prefFactor, e->minSize, e->prefSize, e->maxSize); - e->sizeAtMaximum = interpolate(maxFactor, e->minSize, e->prefSize, e->maxSize); + const bool edgeIsForward = (e->from == prev); + if (edgeIsForward) { + e->sizeAtMinimum = interpolate(minFactor, e->minSize, e->minPrefSize, + e->prefSize, e->maxPrefSize, e->maxSize); + e->sizeAtPreferred = interpolate(prefFactor, e->minSize, e->minPrefSize, + e->prefSize, e->maxPrefSize, e->maxSize); + e->sizeAtMaximum = interpolate(maxFactor, e->minSize, e->minPrefSize, + e->prefSize, e->maxPrefSize, e->maxSize); + prev = e->to; + } else { + Q_ASSERT(prev == e->to); + e->sizeAtMinimum = interpolate(minFactor, e->maxSize, e->maxPrefSize, + e->prefSize, e->minPrefSize, e->minSize); + e->sizeAtPreferred = interpolate(prefFactor, e->maxSize, e->maxPrefSize, + e->prefSize, e->minPrefSize, e->minSize); + e->sizeAtMaximum = interpolate(maxFactor, e->maxSize, e->maxPrefSize, + e->prefSize, e->minPrefSize, e->minSize); + prev = e->from; + } e->updateChildrenSizes(); } @@ -419,12 +525,31 @@ void SequentialAnchorData::calculateSizeHints() minSize = 0; prefSize = 0; maxSize = 0; + minPrefSize = 0; + maxPrefSize = 0; + + AnchorVertex *prev = from; for (int i = 0; i < m_edges.count(); ++i) { AnchorData *edge = m_edges.at(i); - minSize += edge->minSize; - prefSize += edge->prefSize; - maxSize += edge->maxSize; + + const bool edgeIsForward = (edge->from == prev); + if (edgeIsForward) { + minSize += edge->minSize; + prefSize += edge->prefSize; + maxSize += edge->maxSize; + minPrefSize += edge->minPrefSize; + maxPrefSize += edge->maxPrefSize; + prev = edge->to; + } else { + Q_ASSERT(prev == edge->to); + minSize -= edge->maxSize; + prefSize -= edge->prefSize; + maxSize -= edge->minSize; + minPrefSize -= edge->maxPrefSize; + maxPrefSize -= edge->minPrefSize; + prev = edge->from; + } } // See comment in AnchorData::refreshSizeHints() about sizeAt* values @@ -588,16 +713,25 @@ AnchorData *QGraphicsAnchorLayoutPrivate::addAnchorMaybeParallel(AnchorData *new AnchorData *child = children[i]; QList<QSimplexConstraint *> *childConstraints = childrenConstraints[i]; + // We need to fix the second child constraints if the parallel group will have the + // opposite direction of the second child anchor. For the point of view of external + // entities, this anchor was reversed. So if at some point we say that the parallel + // has a value of 20, this mean that the second child (when reversed) will be + // assigned -20. + const bool needsReverse = i == 1 && !parallel->secondForward(); + if (!child->isCenterAnchor) continue; parallel->isCenterAnchor = true; - for (int i = 0; i < constraints.count(); ++i) { - QSimplexConstraint *c = constraints[i]; + for (int j = 0; j < constraints.count(); ++j) { + QSimplexConstraint *c = constraints[j]; if (c->variables.contains(child)) { childConstraints->append(c); qreal v = c->variables.take(child); + if (needsReverse) + v *= -1; c->variables.insert(parallel, v); } } @@ -628,24 +762,10 @@ static AnchorData *createSequence(Graph<AnchorVertex, AnchorData> *graph, const QVector<AnchorVertex*> &vertices, AnchorVertex *after) { - AnchorData *data = graph->edgeData(before, vertices.first()); - Q_ASSERT(data); - - const bool forward = (before == data->from); - QVector<AnchorVertex *> orderedVertices; - - if (forward) { - orderedVertices = vertices; - } else { - qSwap(before, after); - for (int i = vertices.count() - 1; i >= 0; --i) - orderedVertices.append(vertices.at(i)); - } - #if defined(QT_DEBUG) && 0 QString strVertices; - for (int i = 0; i < orderedVertices.count(); ++i) { - strVertices += QString::fromAscii("%1 - ").arg(orderedVertices.at(i)->toString()); + for (int i = 0; i < vertices.count(); ++i) { + strVertices += QString::fromAscii("%1 - ").arg(vertices.at(i)->toString()); } QString strPath = QString::fromAscii("%1 - %2%3").arg(before->toString(), strVertices, after->toString()); qDebug("simplifying [%s] to [%s - %s]", qPrintable(strPath), qPrintable(before->toString()), qPrintable(after->toString())); @@ -654,15 +774,22 @@ static AnchorData *createSequence(Graph<AnchorVertex, AnchorData> *graph, AnchorVertex *prev = before; QVector<AnchorData *> edges; - for (int i = 0; i <= orderedVertices.count(); ++i) { - AnchorVertex *next = (i < orderedVertices.count()) ? orderedVertices.at(i) : after; + // Take from the graph, the edges that will be simplificated + for (int i = 0; i < vertices.count(); ++i) { + AnchorVertex *next = vertices.at(i); AnchorData *ad = graph->takeEdge(prev, next); Q_ASSERT(ad); edges.append(ad); prev = next; } - SequentialAnchorData *sequence = new SequentialAnchorData(orderedVertices, edges); + // Take the last edge (not covered in the loop above) + AnchorData *ad = graph->takeEdge(vertices.last(), after); + Q_ASSERT(ad); + edges.append(ad); + + // Create sequence + SequentialAnchorData *sequence = new SequentialAnchorData(vertices, edges); sequence->from = before; sequence->to = after; @@ -922,7 +1049,6 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP QStack<QPair<AnchorVertex *, AnchorVertex *> > stack; stack.push(qMakePair(static_cast<AnchorVertex *>(0), layoutFirstVertex[orientation])); QVector<AnchorVertex*> candidates; - bool candidatesForward = true; // Walk depth-first, in the stack we store start of the candidate sequence (beforeSequence) // and the vertex to be visited. @@ -938,9 +1064,8 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP // A vertex can trigger an end of sequence if // (a) it is a layout vertex, we don't simplify away the layout vertices; // (b) it does not have exactly 2 adjacents; - // (c) it will change the direction of the sequence; - // (d) its next adjacent is already visited (a cycle in the graph); - // (e) the next anchor is a center anchor. + // (c) its next adjacent is already visited (a cycle in the graph). + // (d) the next anchor is a center anchor. const QList<AnchorVertex *> &adjacents = g.adjacentVertices(v); const bool isLayoutVertex = v->m_item == q; @@ -955,19 +1080,10 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP endOfSequence = isLayoutVertex || adjacents.count() != 2; if (!endOfSequence) { - // If this is the first vertice, determine what is the direction to use for this - // sequence. - if (candidates.isEmpty()) { - const AnchorData *data = g.edgeData(beforeSequence, v); - Q_ASSERT(data); - candidatesForward = (beforeSequence == data->from); - } - // This is a tricky part. We peek at the next vertex to find out whether // - // - the edge from this vertex to the next vertex has the same direction; - // - we already visited the next vertex; - // - the next anchor is a center. + // - we already visited the next vertex (c); + // - the next anchor is a center (d). // // Those are needed to identify the remaining end of sequence cases. Note that unlike // (a) and (b), we preempt the end of sequence by looking into the next vertex. @@ -985,22 +1101,17 @@ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutP const AnchorData *data = g.edgeData(v, after); Q_ASSERT(data); - const bool willChangeDirection = (candidatesForward != (v == data->from)); const bool cycleFound = visited.contains(after); - // Now cases (c), (d) and (e)... - endOfSequence = willChangeDirection || cycleFound || data->isCenterAnchor; + // Now cases (c) and (d)... + endOfSequence = cycleFound || data->isCenterAnchor; - if (endOfSequence) { - if (!willChangeDirection) { - // If the direction will not change, we can add the current vertex to the - // candidates list and we know that 'after' can be used as afterSequence. - candidates.append(v); - afterSequence = after; - } - } else { + if (!endOfSequence) { // If it's not an end of sequence, then the vertex didn't trigger neither of the - // previously four cases, so it can be added to the candidates list. + // previously three cases, so it can be added to the candidates list. + candidates.append(v); + } else if (cycleFound && (beforeSequence != after)) { + afterSequence = after; candidates.append(v); } } @@ -1143,9 +1254,15 @@ void QGraphicsAnchorLayoutPrivate::restoreSimplifiedConstraints(ParallelAnchorDa c->variables.insert(parallel->firstEdge, v); } + // When restoring, we might have to revert constraints back. See comments on + // addAnchorMaybeParallel(). + const bool needsReverse = !parallel->secondForward(); + for (int i = 0; i < parallel->m_secondConstraints.count(); ++i) { QSimplexConstraint *c = parallel->m_secondConstraints.at(i); qreal v = c->variables[parallel]; + if (needsReverse) + v *= -1; c->variables.remove(parallel); c->variables.insert(parallel->secondEdge, v); } @@ -1187,7 +1304,22 @@ void QGraphicsAnchorLayoutPrivate::restoreVertices(Orientation orientation) Graph<AnchorVertex, AnchorData> &g = graph[orientation]; QList<AnchorVertexPair *> &toRestore = simplifiedVertices[orientation]; - // We will restore the vertices in the inverse order of creation, this way we ensure that + // Since we keep a list of parallel anchors and vertices that were created during vertex + // simplification, we can now iterate on those lists instead of traversing the graph + // recursively. + + // First, restore the constraints changed when we created parallel anchors. Note that this + // works at this point because the constraints doesn't depend on vertex information and at + // this point it's always safe to identify whether the second child is forward or backwards. + // In the next step, we'll change the anchors vertices so that would not be possible anymore. + QList<AnchorData *> ¶llelAnchors = anchorsFromSimplifiedVertices[orientation]; + + for (int i = parallelAnchors.count() - 1; i >= 0; --i) { + ParallelAnchorData *parallel = static_cast<ParallelAnchorData *>(parallelAnchors.at(i)); + restoreSimplifiedConstraints(parallel); + } + + // Then, we will restore the vertices in the inverse order of creation, this way we ensure that // the vertex being restored was not wrapped by another simplification. for (int i = toRestore.count() - 1; i >= 0; --i) { AnchorVertexPair *pair = toRestore.at(i); @@ -1231,20 +1363,9 @@ void QGraphicsAnchorLayoutPrivate::restoreVertices(Orientation orientation) delete pair; } - toRestore.clear(); - - // The restoration process for vertex simplification also restored the effect of the - // parallel anchors created during vertex simplification, so we just need to restore - // the constraints in case of parallels that contain center anchors. For the same - // reason as above, order matters here. - QList<AnchorData *> ¶llelAnchors = anchorsFromSimplifiedVertices[orientation]; - - for (int i = parallelAnchors.count() - 1; i >= 0; --i) { - ParallelAnchorData *parallel = static_cast<ParallelAnchorData *>(parallelAnchors.at(i)); - restoreSimplifiedConstraints(parallel); - delete parallel; - } + qDeleteAll(parallelAnchors); parallelAnchors.clear(); + toRestore.clear(); } QGraphicsAnchorLayoutPrivate::Orientation @@ -1272,7 +1393,6 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges() addAnchor_helper(layout, Qt::AnchorLeft, layout, Qt::AnchorRight, data); data->maxSize = QWIDGETSIZE_MAX; - data->skipInPreferred = 1; // Save a reference to layout vertices layoutFirstVertex[Horizontal] = internalVertex(layout, Qt::AnchorLeft); @@ -1284,7 +1404,6 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges() addAnchor_helper(layout, Qt::AnchorTop, layout, Qt::AnchorBottom, data); data->maxSize = QWIDGETSIZE_MAX; - data->skipInPreferred = 1; // Save a reference to layout vertices layoutFirstVertex[Vertical] = internalVertex(layout, Qt::AnchorTop); @@ -1654,6 +1773,10 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::getAnchor(QGraphicsLayoutItem *fi QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge) { + // Do not expose internal anchors + if (firstItem == secondItem) + return 0; + const Orientation orientation = edgeOrientation(firstEdge); AnchorVertex *v1 = internalVertex(firstItem, firstEdge); AnchorVertex *v2 = internalVertex(secondItem, secondEdge); @@ -1661,8 +1784,16 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::getAnchor(QGraphicsLayoutItem *fi QGraphicsAnchor *graphicsAnchor = 0; AnchorData *data = graph[orientation].edgeData(v1, v2); - if (data) - graphicsAnchor = acquireGraphicsAnchor(data); + if (data) { + // We could use "acquireGraphicsAnchor" here, but to avoid a regression where + // an internal anchor was wrongly exposed, I want to ensure no new + // QGraphicsAnchor instances are created by this call. + // This assumption must hold because anchors are either user-created (and already + // have their public object created), or they are internal (and must not reach + // this point). + Q_ASSERT(data->graphicsAnchor); + graphicsAnchor = data->graphicsAnchor; + } return graphicsAnchor; } @@ -1677,12 +1808,16 @@ void QGraphicsAnchorLayoutPrivate::removeAnchor(AnchorVertex *firstVertex, { Q_Q(QGraphicsAnchorLayout); - // Actually delete the anchor - removeAnchor_helper(firstVertex, secondVertex); - + // Save references to items while it's safe to assume the vertices exist QGraphicsLayoutItem *firstItem = firstVertex->m_item; QGraphicsLayoutItem *secondItem = secondVertex->m_item; + // Delete the anchor (may trigger deletion of center vertices) + removeAnchor_helper(firstVertex, secondVertex); + + // Ensure no dangling pointer is left behind + firstVertex = secondVertex = 0; + // Checking if the item stays in the layout or not bool keepFirstItem = false; bool keepSecondItem = false; @@ -2049,6 +2184,25 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( /*! \internal + Shift all the constraints by a certain amount. This allows us to deal with negative values in + the linear program if they are bounded by a certain limit. Functions should be careful to + call it again with a negative amount, to shift the constraints back. +*/ +static void shiftConstraints(const QList<QSimplexConstraint *> &constraints, qreal amount) +{ + for (int i = 0; i < constraints.count(); ++i) { + QSimplexConstraint *c = constraints.at(i); + qreal multiplier = 0; + foreach (qreal v, c->variables.values()) { + multiplier += v; + } + c->constant += multiplier * amount; + } +} + +/*! + \internal + Calculate the sizes for all anchors which are part of the trunk. This works on top of a (possibly) simplified graph. */ @@ -2069,12 +2223,14 @@ bool QGraphicsAnchorLayoutPrivate::calculateTrunk(Orientation orientation, const QList<QSimplexConstraint *> sizeHintConstraints = constraintsFromSizeHints(variables); QList<QSimplexConstraint *> allConstraints = constraints + sizeHintConstraints; + shiftConstraints(allConstraints, g_offset); + // Solve min and max size hints qreal min, max; feasible = solveMinMax(allConstraints, path, &min, &max); if (feasible) { - solvePreferred(allConstraints, variables); + solvePreferred(constraints, variables); // Calculate and set the preferred size for the layout, // from the edge sizes that were calculated above. @@ -2092,6 +2248,7 @@ bool QGraphicsAnchorLayoutPrivate::calculateTrunk(Orientation orientation, const } qDeleteAll(sizeHintConstraints); + shiftConstraints(constraints, -g_offset); } else { // No Simplex is necessary because the path was simplified all the way to a single @@ -2122,8 +2279,8 @@ bool QGraphicsAnchorLayoutPrivate::calculateTrunk(Orientation orientation, const bool QGraphicsAnchorLayoutPrivate::calculateNonTrunk(const QList<QSimplexConstraint *> &constraints, const QList<AnchorData *> &variables) { - QList<QSimplexConstraint *> sizeHintConstraints = constraintsFromSizeHints(variables); - bool feasible = solvePreferred(constraints + sizeHintConstraints, variables); + shiftConstraints(constraints, g_offset); + bool feasible = solvePreferred(constraints, variables); if (feasible) { // Propagate size at preferred to other sizes. Semi-floats always will be @@ -2136,7 +2293,7 @@ bool QGraphicsAnchorLayoutPrivate::calculateNonTrunk(const QList<QSimplexConstra } } - qDeleteAll(sizeHintConstraints); + shiftConstraints(constraints, -g_offset); return feasible; } @@ -2271,13 +2428,21 @@ QList<QSimplexConstraint *> QGraphicsAnchorLayoutPrivate::constraintsFromSizeHin layoutEdge = graph[orient].edgeData(layoutFirstVertex[orient], layoutCentralVertex[orient]); } else { layoutEdge = graph[orient].edgeData(layoutFirstVertex[orient], layoutLastVertex[orient]); + } - // If maxSize is less then "infinite", that means there are other anchors - // grouped together with this one. We can't ignore its maximum value so we - // set back the variable to NULL to prevent the continue condition from being - // satisfied in the loop below. - if (layoutEdge->maxSize < QWIDGETSIZE_MAX) - layoutEdge = 0; + // If maxSize is less then "infinite", that means there are other anchors + // grouped together with this one. We can't ignore its maximum value so we + // set back the variable to NULL to prevent the continue condition from being + // satisfied in the loop below. + const qreal expectedMax = layoutCentralVertex[orient] ? QWIDGETSIZE_MAX / 2 : QWIDGETSIZE_MAX; + qreal actualMax; + if (layoutEdge->from == layoutFirstVertex[orient]) { + actualMax = layoutEdge->maxSize; + } else { + actualMax = -layoutEdge->minSize; + } + if (actualMax != expectedMax) { + layoutEdge = 0; } // For each variable, create constraints based on size hints @@ -2292,17 +2457,23 @@ QList<QSimplexConstraint *> QGraphicsAnchorLayoutPrivate::constraintsFromSizeHin if (ad->dependency == AnchorData::Slave) continue; - if ((ad->minSize == ad->maxSize) || qFuzzyCompare(ad->minSize, ad->maxSize)) { + // To use negative variables inside simplex, we shift them so the minimum negative value is + // mapped to zero before solving. To make sure that it works, we need to guarantee that the + // variables are all inside a certain boundary. + qreal boundedMin = qBound(-g_offset, ad->minSize, g_offset); + qreal boundedMax = qBound(-g_offset, ad->maxSize, g_offset); + + if ((boundedMin == boundedMax) || qFuzzyCompare(boundedMin, boundedMax)) { QSimplexConstraint *c = new QSimplexConstraint; c->variables.insert(ad, 1.0); - c->constant = ad->minSize; + c->constant = boundedMin; c->ratio = QSimplexConstraint::Equal; anchorConstraints += c; unboundedProblem = false; } else { QSimplexConstraint *c = new QSimplexConstraint; c->variables.insert(ad, 1.0); - c->constant = ad->minSize; + c->constant = boundedMin; c->ratio = QSimplexConstraint::MoreOrEqual; anchorConstraints += c; @@ -2314,7 +2485,7 @@ QList<QSimplexConstraint *> QGraphicsAnchorLayoutPrivate::constraintsFromSizeHin c = new QSimplexConstraint; c->variables.insert(ad, 1.0); - c->constant = ad->maxSize; + c->constant = boundedMax; c->ratio = QSimplexConstraint::LessOrEqual; anchorConstraints += c; unboundedProblem = false; @@ -2325,7 +2496,8 @@ QList<QSimplexConstraint *> QGraphicsAnchorLayoutPrivate::constraintsFromSizeHin if (unboundedProblem) { QSimplexConstraint *c = new QSimplexConstraint; c->variables.insert(layoutEdge, 1.0); - c->constant = QWIDGETSIZE_MAX; + // The maximum size that the layout can take + c->constant = g_offset; c->ratio = QSimplexConstraint::LessOrEqual; anchorConstraints += c; } @@ -2591,6 +2763,8 @@ void QGraphicsAnchorLayoutPrivate::setupEdgesInterpolation( result = getFactor(current, sizeHints[orientation][Qt::MinimumSize], sizeHints[orientation][Qt::PreferredSize], + sizeHints[orientation][Qt::PreferredSize], + sizeHints[orientation][Qt::PreferredSize], sizeHints[orientation][Qt::MaximumSize]); interpolationInterval[orientation] = result.first; @@ -2619,6 +2793,7 @@ void QGraphicsAnchorLayoutPrivate::interpolateEdge(AnchorVertex *base, AnchorDat interpolationProgress[orientation]); qreal edgeDistance = interpolate(factor, edge->sizeAtMinimum, edge->sizeAtPreferred, + edge->sizeAtPreferred, edge->sizeAtPreferred, edge->sizeAtMaximum); Q_ASSERT(edge->from == base || edge->to == base); @@ -2646,34 +2821,46 @@ bool QGraphicsAnchorLayoutPrivate::solveMinMax(const QList<QSimplexConstraint *> for (iter = path.negatives.constBegin(); iter != path.negatives.constEnd(); ++iter) objective.variables.insert(*iter, -1.0); + const qreal objectiveOffset = (path.positives.count() - path.negatives.count()) * g_offset; simplex.setObjective(&objective); // Calculate minimum values - *min = simplex.solveMin(); + *min = simplex.solveMin() - objectiveOffset; // Save sizeAtMinimum results QList<AnchorData *> variables = getVariables(constraints); for (int i = 0; i < variables.size(); ++i) { AnchorData *ad = static_cast<AnchorData *>(variables.at(i)); - ad->sizeAtMinimum = ad->result; - Q_ASSERT(ad->sizeAtMinimum >= ad->minSize || - qAbs(ad->sizeAtMinimum - ad->minSize) < 0.00000001); + ad->sizeAtMinimum = ad->result - g_offset; } // Calculate maximum values - *max = simplex.solveMax(); + *max = simplex.solveMax() - objectiveOffset; // Save sizeAtMaximum results for (int i = 0; i < variables.size(); ++i) { AnchorData *ad = static_cast<AnchorData *>(variables.at(i)); - ad->sizeAtMaximum = ad->result; - // Q_ASSERT(ad->sizeAtMaximum <= ad->maxSize || - // qAbs(ad->sizeAtMaximum - ad->maxSize) < 0.00000001); + ad->sizeAtMaximum = ad->result - g_offset; } } return feasible; } +enum slackType { Grower = -1, Shrinker = 1 }; +static QPair<QSimplexVariable *, QSimplexConstraint *> createSlack(QSimplexConstraint *sizeConstraint, + qreal interval, slackType type) +{ + QSimplexVariable *slack = new QSimplexVariable; + sizeConstraint->variables.insert(slack, type); + + QSimplexConstraint *limit = new QSimplexConstraint; + limit->variables.insert(slack, 1.0); + limit->ratio = QSimplexConstraint::LessOrEqual; + limit->constant = interval; + + return qMakePair(slack, limit); +} + bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint *> &constraints, const QList<AnchorData *> &variables) { @@ -2684,7 +2871,8 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint // Fill the objective coefficients for this variable. In the // end the objective function will be // - // z = n * (A_shrink + B_shrink + ...) + (A_grower + B_grower + ...) + // z = n * (A_shrinker_hard + A_grower_hard + B_shrinker_hard + B_grower_hard + ...) + + // (A_shrinker_soft + A_grower_soft + B_shrinker_soft + B_grower_soft + ...) // // where n is the number of variables that have // slacks. Note that here we use the number of variables @@ -2696,29 +2884,67 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint // and we now fill the values for the slack constraints (one per variable), // which have this form (the constant A_pref was set when creating the slacks): // - // A + A_shrinker - A_grower = A_pref + // A + A_shrinker_hard + A_shrinker_soft - A_grower_hard - A_grower_soft = A_pref // for (int i = 0; i < variables.size(); ++i) { AnchorData *ad = variables.at(i); - if (ad->skipInPreferred) + + // The layout original structure anchors are not relevant in preferred size calculation + if (ad->isLayoutAnchor) continue; - QSimplexVariable *grower = new QSimplexVariable; - QSimplexVariable *shrinker = new QSimplexVariable; - QSimplexConstraint *c = new QSimplexConstraint; - c->variables.insert(ad, 1.0); - c->variables.insert(shrinker, 1.0); - c->variables.insert(grower, -1.0); - c->constant = ad->prefSize; + // By default, all variables are equal to their preferred size. If they have room to + // grow or shrink, such flexibility will be added by the additional variables below. + QSimplexConstraint *sizeConstraint = new QSimplexConstraint; + preferredConstraints += sizeConstraint; + sizeConstraint->variables.insert(ad, 1.0); + sizeConstraint->constant = ad->prefSize + g_offset; + + // Can easily shrink + QPair<QSimplexVariable *, QSimplexConstraint *> slack; + const qreal softShrinkInterval = ad->prefSize - ad->minPrefSize; + if (softShrinkInterval) { + slack = createSlack(sizeConstraint, softShrinkInterval, Shrinker); + preferredVariables += slack.first; + preferredConstraints += slack.second; + + // Add to objective with ratio == 1 (soft) + objective.variables.insert(slack.first, 1.0); + } - preferredConstraints += c; - preferredVariables += grower; - preferredVariables += shrinker; + // Can easily grow + const qreal softGrowInterval = ad->maxPrefSize - ad->prefSize; + if (softGrowInterval) { + slack = createSlack(sizeConstraint, softGrowInterval, Grower); + preferredVariables += slack.first; + preferredConstraints += slack.second; - objective.variables.insert(grower, 1.0); - objective.variables.insert(shrinker, variables.size()); - } + // Add to objective with ratio == 1 (soft) + objective.variables.insert(slack.first, 1.0); + } + + // Can shrink if really necessary + const qreal hardShrinkInterval = ad->minPrefSize - ad->minSize; + if (hardShrinkInterval) { + slack = createSlack(sizeConstraint, hardShrinkInterval, Shrinker); + preferredVariables += slack.first; + preferredConstraints += slack.second; + + // Add to objective with ratio == N (hard) + objective.variables.insert(slack.first, variables.size()); + } + // Can grow if really necessary + const qreal hardGrowInterval = ad->maxSize - ad->maxPrefSize; + if (hardGrowInterval) { + slack = createSlack(sizeConstraint, hardGrowInterval, Grower); + preferredVariables += slack.first; + preferredConstraints += slack.second; + + // Add to objective with ratio == N (hard) + objective.variables.insert(slack.first, variables.size()); + } + } QSimplex *simplex = new QSimplex; bool feasible = simplex->setConstraints(constraints + preferredConstraints); @@ -2731,7 +2957,7 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint // Save sizeAtPreferred results for (int i = 0; i < variables.size(); ++i) { AnchorData *ad = variables.at(i); - ad->sizeAtPreferred = ad->result; + ad->sizeAtPreferred = ad->result - g_offset; } // Make sure we delete the simplex solver -before- we delete the diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 2b365fb..3be9d41 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -123,18 +123,17 @@ struct AnchorData : public QSimplexVariable { AnchorData() : QSimplexVariable(), from(0), to(0), minSize(0), prefSize(0), maxSize(0), + minPrefSize(0), maxPrefSize(0), sizeAtMinimum(0), sizeAtPreferred(0), - sizeAtMaximum(0), item(0), - graphicsAnchor(0), skipInPreferred(0), + sizeAtMaximum(0), item(0), graphicsAnchor(0), type(Normal), isLayoutAnchor(false), isCenterAnchor(false), orientation(0), dependency(Independent) {} + virtual ~AnchorData(); virtual void updateChildrenSizes() {} void refreshSizeHints(const QLayoutStyleInfo *styleInfo = 0); - virtual ~AnchorData() {} - #ifdef QT_DEBUG void dump(int indent = 2); inline QString toString() const; @@ -155,6 +154,9 @@ struct AnchorData : public QSimplexVariable { qreal prefSize; qreal maxSize; + qreal minPrefSize; + qreal maxPrefSize; + // Calculated sizes // These attributes define which sizes should that anchor be in when the // layout is at its minimum, preferred or maximum sizes. Values are @@ -169,7 +171,6 @@ struct AnchorData : public QSimplexVariable { QGraphicsLayoutItem *item; QGraphicsAnchor *graphicsAnchor; - uint skipInPreferred : 1; uint type : 2; // either Normal, Sequential or Parallel uint isLayoutAnchor : 1; // if this anchor is an internal layout anchor uint isCenterAnchor : 1; @@ -215,7 +216,8 @@ struct ParallelAnchorData : public AnchorData Q_ASSERT(((first->from == second->from) && (first->to == second->to)) || ((first->from == second->to) && (first->to == second->from))); - // We arbitrarily choose the direction of the first child as "our" direction + // Our convention will be that the parallel group anchor will have the same + // direction as the first anchor. from = first->from; to = first->to; #ifdef QT_DEBUG @@ -226,6 +228,13 @@ struct ParallelAnchorData : public AnchorData virtual void updateChildrenSizes(); bool calculateSizeHints(); + bool secondForward() const { + // We have the convention that the first children will define the direction of the + // pararell group. Note that we can't rely on 'this->from' or 'this->to' because they + // might be changed by vertex simplification. + return firstEdge->from == secondEdge->from; + } + AnchorData* firstEdge; AnchorData* secondEdge; @@ -345,7 +354,6 @@ public: qreal preferredSize; uint hasSize : 1; // if false, get size from style. - uint reversed : 1; // if true, the anchor was inverted to keep its value positive }; @@ -367,8 +375,10 @@ public: // // Interval represents which interpolation interval are we operating in. enum Interval { - MinToPreferred = 0, - PreferredToMax + MinimumToMinPreferred = 0, + MinPreferredToPreferred, + PreferredToMaxPreferred, + MaxPreferredToMaximum }; // Several structures internal to the layout are duplicated to handle diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 710048e..90cc132 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -52,7 +52,7 @@ painting implementation and item interaction through its event handlers. QGraphicsItem is part of \l{The Graphics View Framework} - \img graphicsview-items.png + \image graphicsview-items.png For convenience, Qt provides a set of standard graphics items for the most common shapes. These are: @@ -378,14 +378,14 @@ it's parent if it's z-value is negative. This flag enables setZValue() to toggle ItemStacksBehindParent. - \value ItemIsPanel. The item is a panel. A panel provides activation and + \value ItemIsPanel The item is a panel. A panel provides activation and contained focus handling. Only one panel can be active at a time (see QGraphicsItem::isActive()). When no panel is active, QGraphicsScene activates all non-panel items. Window items (i.e., QGraphicsItem::isWindow() returns true) are panels. This flag was introduced in Qt 4.6. - \omitvalue ItemIsFocusScope Internal only (for now). + \omitvalue ItemIsFocusScope \omit Internal only (for now). \endomit \value ItemSendsScenePositionChanges The item enables itemChange() notifications for ItemScenePositionHasChanged. For performance reasons, @@ -755,7 +755,6 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch case QGraphicsItem::ItemClipsChildrenToShape: flag = AncestorClipsChildren; enabled = flags & QGraphicsItem::ItemClipsChildrenToShape; - invalidateCachedClipPathRecursively(/*childrenOnly=*/true); break; case QGraphicsItem::ItemIgnoresTransformations: flag = AncestorIgnoresTransformations; @@ -1104,9 +1103,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) parent->itemChange(QGraphicsItem::ItemChildAddedChange, thisPointerVariant); if (scene) { if (!implicitUpdate) - scene->d_func()->markDirty(q_ptr, QRect(), - /*invalidateChildren=*/false, - /*maybeDirtyClipPath=*/true); + scene->d_func()->markDirty(q_ptr); // Re-enable scene pos notifications for new ancestors if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) @@ -1147,11 +1144,8 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) setEnabledHelper(true, /* explicit = */ false); // If the item is being deleted, the whole scene will be updated. - if (scene) { - scene->d_func()->markDirty(q_ptr, QRect(), - /*invalidateChildren=*/false, - /*maybeDirtyClipPath=*/true); - } + if (scene) + scene->d_func()->markDirty(q_ptr); } } @@ -1347,8 +1341,8 @@ QGraphicsItem::~QGraphicsItem() } if (!d_ptr->children.isEmpty()) { - QList<QGraphicsItem *> oldChildren = d_ptr->children; - qDeleteAll(oldChildren); + while (!d_ptr->children.isEmpty()) + delete d_ptr->children.first(); Q_ASSERT(d_ptr->children.isEmpty()); } @@ -1732,9 +1726,6 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) d_ptr->updateAncestorFlag(ItemClipsChildrenToShape); } - if ((flags & ItemClipsToShape) != (oldFlags & ItemClipsToShape)) - d_ptr->invalidateCachedClipPath(); - if ((flags & ItemIgnoresTransformations) != (oldFlags & ItemIgnoresTransformations)) { // Item children clipping changes. Propagate the ancestor flag to // all children. @@ -1777,9 +1768,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) else d_ptr->scene->d_func()->unregisterScenePosItem(this); } - d_ptr->scene->d_func()->markDirty(this, QRectF(), - /*invalidateChildren=*/true, - /*maybeDirtyClipPath*/true); + d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true); } // Notify change. @@ -2127,12 +2116,8 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo QGraphicsItemCache *c = (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData)); if (c) c->purge(); - if (scene) { - scene->d_func()->markDirty(q_ptr, QRectF(), - /*invalidateChildren=*/false, - /*maybeDirtyClipPath=*/false, - /*force=*/true); - } + if (scene) + scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true); } // Certain properties are dropped as an item becomes invisible. @@ -2542,7 +2527,6 @@ void QGraphicsItem::setOpacity(qreal opacity) #endif //QT_NO_GRAPHICSEFFECT d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true, - /*maybeDirtyClipPath=*/false, /*force=*/false, /*ignoreOpacity=*/true); } @@ -2570,6 +2554,8 @@ QGraphicsEffect *QGraphicsItem::graphicsEffect() const If \a effect is the installed on a different item, setGraphicsEffect() will remove the effect from the item and install it on this item. + QGraphicsItem takes ownership of \a effect. + \note This function will apply the effect on itself and all its children. \since 4.6 @@ -2579,29 +2565,19 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect) if (d_ptr->graphicsEffect == effect) return; - if (d_ptr->graphicsEffect && effect) { + if (d_ptr->graphicsEffect) { delete d_ptr->graphicsEffect; d_ptr->graphicsEffect = 0; } - if (!effect) { - // Unset current effect. - QGraphicsEffectPrivate *oldEffectPrivate = d_ptr->graphicsEffect->d_func(); - d_ptr->graphicsEffect = 0; - if (oldEffectPrivate) { - oldEffectPrivate->setGraphicsEffectSource(0); // deletes the current source. - if (d_ptr->scene) // Update the views directly. - d_ptr->scene->d_func()->markDirty(this, QRectF(), false, false, false, false, true); - } - } else { + if (effect) { // Set new effect. QGraphicsEffectSourcePrivate *sourced = new QGraphicsItemEffectSourcePrivate(this); QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced); d_ptr->graphicsEffect = effect; effect->d_func()->setGraphicsEffectSource(source); + prepareGeometryChange(); } - - prepareGeometryChange(); } #endif //QT_NO_GRAPHICSEFFECT @@ -3399,7 +3375,6 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos) { Q_Q(QGraphicsItem); inSetPosHelper = 1; - updateCachedClipPathFromSetPosHelper(pos); if (scene) q->prepareGeometryChange(); QPointF oldPos = this->pos; @@ -4535,22 +4510,12 @@ bool QGraphicsItem::isClipped() const QPainterPath QGraphicsItem::clipPath() const { Q_D(const QGraphicsItem); - if (!d->dirtyClipPath) - return d->emptyClipPath ? QPainterPath() : d->cachedClipPath; - - if (!isClipped()) { - d_ptr->setCachedClipPath(QPainterPath()); - return d->cachedClipPath; - } + if (!isClipped()) + return QPainterPath(); const QRectF thisBoundingRect(boundingRect()); - if (thisBoundingRect.isEmpty()) { - if (d_ptr->flags & ItemClipsChildrenToShape) - d_ptr->setEmptyCachedClipPathRecursively(); - else - d_ptr->setEmptyCachedClipPath(); + if (thisBoundingRect.isEmpty()) return QPainterPath(); - } QPainterPath clip; // Start with the item's bounding rect. @@ -4561,40 +4526,18 @@ QPainterPath QGraphicsItem::clipPath() const const QGraphicsItem *lastParent = this; // Intersect any in-between clips starting at the top and moving downwards. - bool foundValidClipPath = false; while ((parent = parent->d_ptr->parent)) { if (parent->d_ptr->flags & ItemClipsChildrenToShape) { // Map clip to the current parent and intersect with its shape/clipPath clip = lastParent->itemTransform(parent).map(clip); - if ((foundValidClipPath = !parent->d_ptr->dirtyClipPath && parent->isClipped())) { - if (parent->d_ptr->emptyClipPath) { - if (d_ptr->flags & ItemClipsChildrenToShape) - d_ptr->setEmptyCachedClipPathRecursively(); - else - d_ptr->setEmptyCachedClipPath(); - return QPainterPath(); - } - clip = clip.intersected(parent->d_ptr->cachedClipPath); - if (!(parent->d_ptr->flags & ItemClipsToShape)) - clip = clip.intersected(parent->shape()); - } else { - clip = clip.intersected(parent->shape()); - } - - if (clip.isEmpty()) { - if (d_ptr->flags & ItemClipsChildrenToShape) - d_ptr->setEmptyCachedClipPathRecursively(); - else - d_ptr->setEmptyCachedClipPath(); + clip = clip.intersected(parent->shape()); + if (clip.isEmpty()) return clip; - } lastParent = parent; } - if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) - || foundValidClipPath) { + if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) break; - } } if (lastParent != this) { @@ -4607,7 +4550,6 @@ QPainterPath QGraphicsItem::clipPath() const if (d->flags & ItemClipsToShape) clip = clip.intersected(shape()); - d_ptr->setCachedClipPath(clip); return clip; } @@ -5026,15 +4968,14 @@ void QGraphicsItem::setBoundingRegionGranularity(qreal granularity) \internal Returns true if we can discard an update request; otherwise false. */ -bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreClipping, bool ignoreVisibleBit, - bool ignoreDirtyBit, bool ignoreOpacity) const +bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreVisibleBit, bool ignoreDirtyBit, + bool ignoreOpacity) const { // No scene, or if the scene is updating everything, means we have nothing // to do. The only exception is if the scene tracks the growing scene rect. return !scene || (!visible && !ignoreVisibleBit && !this->ignoreVisible) || (!ignoreDirtyBit && fullUpdatePending) - || (!ignoreClipping && (childrenClippedToShape() && isClippedAway())) || (!ignoreOpacity && !this->ignoreOpacity && childrenCombineOpacity() && isFullyTransparent()); } @@ -5169,109 +5110,6 @@ void QGraphicsItemPrivate::removeExtraItemCache() unsetExtra(ExtraCacheData); } -void QGraphicsItemPrivate::setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect) -{ - setEmptyCachedClipPath(); - - const bool checkRect = !emptyIfOutsideThisRect.isNull() - && !(flags & QGraphicsItem::ItemClipsChildrenToShape); - for (int i = 0; i < children.size(); ++i) { - if (!checkRect) { - children.at(i)->d_ptr->setEmptyCachedClipPathRecursively(); - continue; - } - - QGraphicsItem *child = children.at(i); - const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect); - if (rect.intersects(child->boundingRect())) - child->d_ptr->invalidateCachedClipPathRecursively(false, rect); - else - child->d_ptr->setEmptyCachedClipPathRecursively(rect); - } -} - -void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool childrenOnly, const QRectF &emptyIfOutsideThisRect) -{ - if (!childrenOnly) - invalidateCachedClipPath(); - - const bool checkRect = !emptyIfOutsideThisRect.isNull(); - for (int i = 0; i < children.size(); ++i) { - if (!checkRect) { - children.at(i)->d_ptr->invalidateCachedClipPathRecursively(false); - continue; - } - - QGraphicsItem *child = children.at(i); - const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect); - if (rect.intersects(child->boundingRect())) - child->d_ptr->invalidateCachedClipPathRecursively(false, rect); - else - child->d_ptr->setEmptyCachedClipPathRecursively(rect); - } -} - -void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(const QPointF &newPos) -{ - Q_ASSERT(inSetPosHelper); - - if (inDestructor || !(ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) - return; // Not clipped by any ancestor. - - // Find closest clip ancestor and transform. - Q_Q(QGraphicsItem); - // COMBINE - QTransform thisToParentTransform = QTransform::fromTranslate(newPos.x(), newPos.y()); - if (transformData) - thisToParentTransform = transformData->computedFullTransform(&thisToParentTransform); - QGraphicsItem *clipParent = parent; - while (clipParent && !clipParent->d_ptr->inDestructor && !(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)) { - thisToParentTransform *= clipParent->d_ptr->transformToParent(); - clipParent = clipParent->d_ptr->parent; - } - - // Ensure no parents are currently being deleted. This can only - // happen if the item is moved by a dying ancestor. - QGraphicsItem *p = clipParent; - while (p) { - if (p->d_ptr->inDestructor) - return; - p = p->d_ptr->parent; - } - - // From here everything is calculated in clip parent's coordinates. - const QRectF parentBoundingRect(clipParent->boundingRect()); - const QRectF thisBoundingRect(thisToParentTransform.mapRect(q->boundingRect())); - - if (!parentBoundingRect.intersects(thisBoundingRect)) { - // Item is moved outside the clip parent's bounding rect, - // i.e. it is fully clipped and the clip path is empty. - if (flags & QGraphicsItem::ItemClipsChildrenToShape) - setEmptyCachedClipPathRecursively(); - else - setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentBoundingRect)); - return; - } - - const QPainterPath parentClip(clipParent->isClipped() ? clipParent->clipPath() : clipParent->shape()); - if (parentClip.contains(thisBoundingRect)) - return; // Item is inside the clip parent's shape. No update required. - - const QRectF parentClipRect(parentClip.controlPointRect()); - if (!parentClipRect.intersects(thisBoundingRect)) { - // Item is moved outside the clip parent's shape, - // i.e. it is fully clipped and the clip path is empty. - if (flags & QGraphicsItem::ItemClipsChildrenToShape) - setEmptyCachedClipPathRecursively(); - else - setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentClipRect)); - } else { - // Item is partially inside the clip parent's shape, - // i.e. the cached clip path must be invalidated. - invalidateCachedClipPathRecursively(false, thisToParentTransform.inverted().mapRect(parentClipRect)); - } -} - // Traverses all the ancestors up to the top-level and updates the pointer to // always point to the top-most item that has a dirty scene transform. // It then backtracks to the top-most dirty item and start calculating the @@ -7288,9 +7126,7 @@ void QGraphicsItem::prepareGeometryChange() QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); scenePrivate->index->prepareBoundingRectChange(this); - scenePrivate->markDirty(this, QRectF(), - /*invalidateChildren=*/true, - /*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper); + scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true); // For compatibility reasons, we have to update the item's old geometry // if someone is connected to the changed signal or the scene has no views. @@ -7313,16 +7149,6 @@ void QGraphicsItem::prepareGeometryChange() // ### Only do this if the parent's effect applies to the entire subtree. parent->d_ptr->notifyBoundingRectChanged = 1; } - - if (d_ptr->inSetPosHelper) - return; - - if (d_ptr->flags & ItemClipsChildrenToShape - || d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { - d_ptr->invalidateCachedClipPathRecursively(); - } else { - d_ptr->invalidateCachedClipPath(); - } } /*! @@ -7468,13 +7294,6 @@ void QGraphicsObject::ungrabGesture(Qt::GestureType gesture) */ /*! - \property QGraphicsObject::id - \brief the id of of the item - - \sa QObject::objectName(), QObject::setObjectName() -*/ - -/*! \property QGraphicsObject::opacity \brief the opacity of the item @@ -9604,9 +9423,11 @@ void QGraphicsTextItem::setDefaultTextColor(const QColor &col) { QTextControl *c = dd->textControl(); QPalette pal = c->palette(); + QColor old = pal.color(QPalette::Text); pal.setColor(QPalette::Text, col); c->setPalette(pal); - update(); + if (old != col) + update(); } /*! @@ -9874,7 +9695,7 @@ void QGraphicsTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) } QWidget *widget = event->widget(); - if (widget) { + if (widget && (dd->control->textInteractionFlags() & Qt::TextEditable) && boundingRect().contains(event->pos())) { qt_widget_private(widget)->handleSoftwareInputPanel(event->button(), dd->clickCausedFocus); } dd->clickCausedFocus = 0; diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 8bbe9f1..8818a0b 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -537,7 +537,6 @@ class Q_GUI_EXPORT QGraphicsObject : public QObject, public QGraphicsItem { Q_OBJECT Q_PROPERTY(QGraphicsObject * parent READ parentObject WRITE setParentItem NOTIFY parentChanged DESIGNABLE false) - Q_PROPERTY(QString id READ objectName WRITE setObjectName) Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged FINAL) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 75c8246..8f9fe54 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -152,8 +152,6 @@ public: dirty(0), dirtyChildren(0), localCollisionHack(0), - dirtyClipPath(1), - emptyClipPath(0), inSetPosHelper(0), needSortChildren(1), // ### can be 0 by default? allChildrenDirty(0), @@ -221,7 +219,7 @@ public: void appendGraphicsTransform(QGraphicsTransform *t); void setVisibleHelper(bool newVisible, bool explicitly, bool update = true); void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true); - bool discardUpdateRequest(bool ignoreClipping = false, bool ignoreVisibleBit = false, + bool discardUpdateRequest(bool ignoreVisibleBit = false, bool ignoreDirtyBit = false, bool ignoreOpacity = false) const; int depth() const; #ifndef QT_NO_GRAPHICSEFFECT @@ -307,26 +305,6 @@ public: QGraphicsItemCache *extraItemCache() const; void removeExtraItemCache(); - inline void setCachedClipPath(const QPainterPath &path) - { - cachedClipPath = path; - dirtyClipPath = 0; - emptyClipPath = 0; - } - - inline void setEmptyCachedClipPath() - { - emptyClipPath = 1; - dirtyClipPath = 0; - } - - void setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect = QRectF()); - - inline void invalidateCachedClipPath() - { /*static int count = 0 ;qWarning("%i", ++count);*/ dirtyClipPath = 1; emptyClipPath = 0; } - - void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF()); - void updateCachedClipPathFromSetPosHelper(const QPointF &newPos); void ensureSceneTransformRecursive(QGraphicsItem **topMostDirtyItem); inline void ensureSceneTransform() { @@ -409,17 +387,12 @@ public: return true; } - inline bool isClippedAway() const - { return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); } - inline bool childrenClippedToShape() const { return (flags & QGraphicsItem::ItemClipsChildrenToShape) || children.isEmpty(); } inline bool isInvisible() const { - return !visible - || (childrenClippedToShape() && isClippedAway()) - || (childrenCombineOpacity() && isFullyTransparent()); + return !visible || (childrenCombineOpacity() && isFullyTransparent()); } void setFocusHelper(Qt::FocusReason focusReason, bool climb); @@ -435,7 +408,6 @@ public: inline void sendScenePosChange(); virtual void siblingOrderChange(); - QPainterPath cachedClipPath; QRectF childrenBoundingRect; QRectF needsRepaint; QMap<QWidget *, QRect> paintedViewBoundingRects; @@ -480,8 +452,6 @@ public: quint32 dirty : 1; quint32 dirtyChildren : 1; quint32 localCollisionHack : 1; - quint32 dirtyClipPath : 1; - quint32 emptyClipPath : 1; quint32 inSetPosHelper : 1; quint32 needSortChildren : 1; quint32 allChildrenDirty : 1; @@ -592,7 +562,10 @@ public: {} inline void detach() - { item->setGraphicsEffect(0); } + { + item->d_ptr->graphicsEffect = 0; + item->prepareGeometryChange(); + } inline const QGraphicsItem *graphicsItem() const { return item; } diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 10d251d..27ebb79 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -555,7 +555,8 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) // Clear focus on the item to remove any reference in the focusWidget chain. item->clearFocus(); - markDirty(item, QRectF(), false, false, false, false, /*removingItemFromScene=*/true); + markDirty(item, QRectF(), /*invalidateChildren=*/false, /*force=*/false, + /*ignoreOpacity=*/false, /*removingItemFromScene=*/true); if (item->d_ptr->inDestructor) { // The item is actually in its destructor, we call the special method in the index. @@ -4232,7 +4233,6 @@ static void _q_paintIntoCache(QPixmap *pix, QGraphicsItem *item, const QRegion & if (!subPix.isNull()) { // Blit the subpixmap into the main pixmap. pixmapPainter.begin(pix); - pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source); pixmapPainter.setClipRegion(pixmapExposed); pixmapPainter.drawPixmap(br.topLeft(), subPix); pixmapPainter.end(); @@ -4759,15 +4759,13 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q } void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, bool invalidateChildren, - bool maybeDirtyClipPath, bool force, bool ignoreOpacity, - bool removingItemFromScene) + bool force, bool ignoreOpacity, bool removingItemFromScene) { Q_ASSERT(item); if (updateAll) return; - if (item->d_ptr->discardUpdateRequest(/*ignoreClipping=*/maybeDirtyClipPath, - /*ignoreVisibleBit=*/force, + if (item->d_ptr->discardUpdateRequest(/*ignoreVisibleBit=*/force, /*ignoreDirtyBit=*/removingItemFromScene || invalidateChildren, /*ignoreOpacity=*/ignoreOpacity)) { if (item->d_ptr->dirty) { diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index fdec466..69e4d5b 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -78,7 +78,7 @@ class QGraphicsSceneIndex; class QGraphicsView; class QGraphicsWidget; -class QGraphicsScenePrivate : public QObjectPrivate +class Q_AUTOTEST_EXPORT QGraphicsScenePrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QGraphicsScene) public: @@ -222,8 +222,7 @@ public: QRegion *, QWidget *, qreal, const QTransform *const, bool, bool); void markDirty(QGraphicsItem *item, const QRectF &rect = QRectF(), bool invalidateChildren = false, - bool maybeDirtyClipPath = false, bool force = false, bool ignoreOpacity = false, - bool removingItemFromScene = false); + bool force = false, bool ignoreOpacity = false, bool removingItemFromScene = false); void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false, qreal parentOpacity = qreal(1.0)); @@ -266,6 +265,7 @@ public: { if (needSortTopLevelItems) { qSort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf); + topLevelSequentialOrdering = false; needSortTopLevelItems = false; } } diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h index 762cad1..cd161ad 100644 --- a/src/gui/graphicsview/qgraphicsview_p.h +++ b/src/gui/graphicsview/qgraphicsview_p.h @@ -172,10 +172,17 @@ public: inline void dispatchPendingUpdateRequests() { +#ifndef Q_WS_MAC + // QWidget::update() works slightly different on the Mac; it's not part of + // our backing store so it needs special threatment. if (qt_widget_private(viewport)->paintOnScreen()) QCoreApplication::sendPostedEvents(viewport, QEvent::UpdateRequest); else QCoreApplication::sendPostedEvents(viewport->window(), QEvent::UpdateRequest); +#else + QCoreApplication::processEvents(QEventLoop::AllEvents | QEventLoop::ExcludeSocketNotifiers + | QEventLoop::ExcludeUserInputEvents); +#endif } bool updateRect(const QRect &rect); diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index d9c65bb..fe569f4 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -385,8 +385,6 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) QSizeF oldSize = size(); QGraphicsLayoutItem::setGeometry(newGeom); - wd->invalidateCachedClipPathRecursively(); - // Send resize event bool resized = newGeom.size() != oldSize; if (resized) { @@ -1303,7 +1301,8 @@ bool QGraphicsWidget::event(QEvent *event) case QEvent::Polish: polishEvent(); d->polished = true; - d->updateFont(d->font); + if (!d->font.isCopyOf(QApplication::font())) + d->updateFont(d->font); break; case QEvent::WindowActivate: case QEvent::WindowDeactivate: diff --git a/src/gui/graphicsview/qsimplex_p.h b/src/gui/graphicsview/qsimplex_p.h index a5816d1..2004471 100644 --- a/src/gui/graphicsview/qsimplex_p.h +++ b/src/gui/graphicsview/qsimplex_p.h @@ -107,7 +107,7 @@ struct QSimplexConstraint Q_ASSERT(constant > 0 || qFuzzyCompare(1, 1 + constant)); - if ((leftHandSide == constant) || qAbs(leftHandSide - constant) < 0.00000001) + if ((leftHandSide == constant) || qAbs(leftHandSide - constant) < 0.0000001) return true; switch (ratio) { diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp index 15af7a2..ad9bdd0 100644 --- a/src/gui/image/qiconloader.cpp +++ b/src/gui/image/qiconloader.cpp @@ -249,21 +249,19 @@ QThemeIconEntries QIconLoader::findIconHelper(const QString &themeName, const QIconDirInfo &dirInfo = subDirs.at(i); QString subdir = dirInfo.path; QDir currentDir(contentDir + subdir); - - if (dirInfo.type == QIconDirInfo::Scalable && m_supportsSvg && - currentDir.exists(iconName + svgext)) { - ScalableEntry *iconEntry = new ScalableEntry; - iconEntry->dir = dirInfo; - iconEntry->filename = currentDir.filePath(iconName + svgext); - entries.append(iconEntry); - - } else if (currentDir.exists(iconName + pngext)) { + if (currentDir.exists(iconName + pngext)) { PixmapEntry *iconEntry = new PixmapEntry; iconEntry->dir = dirInfo; iconEntry->filename = currentDir.filePath(iconName + pngext); // Notice we ensure that pixmap entries allways come before // scalable to preserve search order afterwards entries.prepend(iconEntry); + } else if (m_supportsSvg && + currentDir.exists(iconName + svgext)) { + ScalableEntry *iconEntry = new ScalableEntry; + iconEntry->dir = dirInfo; + iconEntry->filename = currentDir.filePath(iconName + svgext); + entries.append(iconEntry); } } @@ -444,10 +442,8 @@ QIconLoaderEngineEntry *QIconLoaderEngine::entryForSize(const QSize &size) /* * Returns the actual icon size. For scalable svg's this is equivalent - * to the requested size. Otherwise the closest match is returned. - * - * todo: the spec is a bit fuzzy in this area, but we should probably - * allow scaling down pixmap icons as well. + * to the requested size. Otherwise the closest match is returned but + * we can never return a bigger size than the requested size. * */ QSize QIconLoaderEngine::actualSize(const QSize &size, QIcon::Mode mode, @@ -460,8 +456,10 @@ QSize QIconLoaderEngine::actualSize(const QSize &size, QIcon::Mode mode, const QIconDirInfo &dir = entry->dir; if (dir.type == QIconDirInfo::Scalable) return size; - else - return QSize(dir.size, dir.size); + else { + int result = qMin<int>(dir.size, qMin(size.width(), size.height())); + return QSize(result, result); + } } return QIconEngineV2::actualSize(size, mode, state); } diff --git a/src/gui/image/qimagepixmapcleanuphooks.cpp b/src/gui/image/qimagepixmapcleanuphooks.cpp index 35322e9..2aa61b8 100644 --- a/src/gui/image/qimagepixmapcleanuphooks.cpp +++ b/src/gui/image/qimagepixmapcleanuphooks.cpp @@ -55,20 +55,11 @@ Q_GUI_EXPORT _qt_pixmap_cleanup_hook_64 qt_pixmap_cleanup_hook_64 = 0; Q_GUI_EXPORT _qt_image_cleanup_hook qt_image_cleanup_hook = 0; Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64 = 0; - -QImagePixmapCleanupHooks* qt_image_and_pixmap_cleanup_hooks = 0; - - -QImagePixmapCleanupHooks::QImagePixmapCleanupHooks() -{ - qt_image_and_pixmap_cleanup_hooks = this; -} +Q_GLOBAL_STATIC(QImagePixmapCleanupHooks, qt_image_and_pixmap_cleanup_hooks) QImagePixmapCleanupHooks *QImagePixmapCleanupHooks::instance() { - if (!qt_image_and_pixmap_cleanup_hooks) - qt_image_and_pixmap_cleanup_hooks = new QImagePixmapCleanupHooks; - return qt_image_and_pixmap_cleanup_hooks; + return qt_image_and_pixmap_cleanup_hooks(); } void QImagePixmapCleanupHooks::addPixmapModificationHook(_qt_pixmap_cleanup_hook_pm hook) @@ -102,12 +93,11 @@ void QImagePixmapCleanupHooks::removeImageHook(_qt_image_cleanup_hook_64 hook) imageHooks.removeAll(hook); } - void QImagePixmapCleanupHooks::executePixmapModificationHooks(QPixmap* pm) { - Q_ASSERT(qt_image_and_pixmap_cleanup_hooks); - for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks->pixmapModificationHooks.count(); ++i) - qt_image_and_pixmap_cleanup_hooks->pixmapModificationHooks[i](pm); + QImagePixmapCleanupHooks *h = qt_image_and_pixmap_cleanup_hooks(); + for (int i = 0; i < h->pixmapModificationHooks.count(); ++i) + h->pixmapModificationHooks[i](pm); if (qt_pixmap_cleanup_hook_64) qt_pixmap_cleanup_hook_64(pm->cacheKey()); @@ -115,9 +105,9 @@ void QImagePixmapCleanupHooks::executePixmapModificationHooks(QPixmap* pm) void QImagePixmapCleanupHooks::executePixmapDestructionHooks(QPixmap* pm) { - Q_ASSERT(qt_image_and_pixmap_cleanup_hooks); - for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks->pixmapDestructionHooks.count(); ++i) - qt_image_and_pixmap_cleanup_hooks->pixmapDestructionHooks[i](pm); + QImagePixmapCleanupHooks *h = qt_image_and_pixmap_cleanup_hooks(); + for (int i = 0; i < h->pixmapDestructionHooks.count(); ++i) + h->pixmapDestructionHooks[i](pm); if (qt_pixmap_cleanup_hook_64) qt_pixmap_cleanup_hook_64(pm->cacheKey()); @@ -125,9 +115,8 @@ void QImagePixmapCleanupHooks::executePixmapDestructionHooks(QPixmap* pm) void QImagePixmapCleanupHooks::executeImageHooks(qint64 key) { - Q_ASSERT(qt_image_and_pixmap_cleanup_hooks); - for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks->imageHooks.count(); ++i) - qt_image_and_pixmap_cleanup_hooks->imageHooks[i](key); + for (int i = 0; i < qt_image_and_pixmap_cleanup_hooks()->imageHooks.count(); ++i) + qt_image_and_pixmap_cleanup_hooks()->imageHooks[i](key); if (qt_image_cleanup_hook_64) qt_image_cleanup_hook_64(key); diff --git a/src/gui/image/qimagepixmapcleanuphooks_p.h b/src/gui/image/qimagepixmapcleanuphooks_p.h index 9e490d7..dfc5f28 100644 --- a/src/gui/image/qimagepixmapcleanuphooks_p.h +++ b/src/gui/image/qimagepixmapcleanuphooks_p.h @@ -61,13 +61,10 @@ typedef void (*_qt_image_cleanup_hook_64)(qint64); typedef void (*_qt_pixmap_cleanup_hook_pm)(QPixmap*); class QImagePixmapCleanupHooks; -extern QImagePixmapCleanupHooks* qt_image_and_pixmap_cleanup_hooks; class Q_GUI_EXPORT QImagePixmapCleanupHooks { public: - QImagePixmapCleanupHooks(); - static QImagePixmapCleanupHooks *instance(); static void enableCleanupHooks(const QImage &image); diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 985a20b..617cfe5 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1165,7 +1165,7 @@ QPixmap QPixmap::grabWidget(QWidget * widget, const QRect &rect) Qt::HANDLE QPixmap::handle() const { #if defined(Q_WS_X11) - if (data->classId() == QPixmapData::X11Class) + if (data && data->classId() == QPixmapData::X11Class) return static_cast<const QX11PixmapData*>(data.constData())->handle(); #endif return 0; @@ -1216,7 +1216,7 @@ QPixmap::QPixmap(const QImage& image) if (!qt_pixmap_thread_test()) return; - if (data->pixelType() == QPixmapData::BitmapType) + if (data && data->pixelType() == QPixmapData::BitmapType) *this = QBitmap::fromImage(image); else *this = fromImage(image); diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index bdff5e7..a295d66 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -437,6 +437,10 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints) void QCoeFepInputContext::applyFormat(QList<QInputMethodEvent::Attribute> *attributes) { TCharFormat cFormat; + QColor styleTextColor = QApplication::palette("QLineEdit").text().color(); + TLogicalRgb tontColor(TRgb(styleTextColor.red(), styleTextColor.green(), styleTextColor.blue(), styleTextColor.alpha())); + cFormat.iFontPresentation.iTextColor = tontColor; + TInt numChars = 0; TInt charPos = 0; int oldSize = attributes->size(); diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index c691fe2..de6e6cb 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -96,6 +96,7 @@ QAbstractItemViewPrivate::QAbstractItemViewPrivate() autoScrollMargin(16), autoScrollCount(0), shouldScrollToCurrentOnShow(false), + shouldClearStatusTip(false), alternatingColors(false), textElideMode(Qt::ElideRight), verticalScrollMode(QAbstractItemView::ScrollPerItem), @@ -161,14 +162,15 @@ void QAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index emit q->entered(index); #ifndef QT_NO_STATUSTIP QString statustip = model->data(index, Qt::StatusTipRole).toString(); - if (parent && !statustip.isEmpty()) { + if (parent && (shouldClearStatusTip || !statustip.isEmpty())) { QStatusTipEvent tip(statustip); QApplication::sendEvent(parent, &tip); + shouldClearStatusTip = !statustip.isEmpty(); } #endif } else { #ifndef QT_NO_STATUSTIP - if (parent) { + if (parent && shouldClearStatusTip) { QString emptyString; QStatusTipEvent tip( emptyString ); QApplication::sendEvent(parent, &tip); @@ -1559,6 +1561,14 @@ bool QAbstractItemView::viewportEvent(QEvent *event) d->viewportEnteredNeeded = true; break; case QEvent::Leave: + #ifndef QT_NO_STATUSTIP + if (d->shouldClearStatusTip && d->parent) { + QString empty; + QStatusTipEvent tip(empty); + QApplication::sendEvent(d->parent, &tip); + d->shouldClearStatusTip = false; + } + #endif d->enteredIndex = QModelIndex(); break; case QEvent::ToolTip: @@ -1615,7 +1625,7 @@ void QAbstractItemView::mousePressEvent(QMouseEvent *event) QPoint offset = d->offset(); if ((command & QItemSelectionModel::Current) == 0) d->pressedPosition = pos + offset; - else if (!indexAt(d->pressedPosition).isValid()) + else if (!indexAt(d->pressedPosition - offset).isValid()) d->pressedPosition = visualRect(currentIndex()).center() + offset; if (edit(index, NoEditTriggers, event)) @@ -2185,7 +2195,7 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) // note that we don't check if the new current index is enabled because moveCursor() makes sure it is if (command & QItemSelectionModel::Current) { d->selectionModel->setCurrentIndex(newCurrent, QItemSelectionModel::NoUpdate); - if (!indexAt(d->pressedPosition).isValid()) + if (!indexAt(d->pressedPosition - d->offset()).isValid()) d->pressedPosition = visualRect(oldCurrent).center() + d->offset(); QRect rect(d->pressedPosition - d->offset(), visualRect(newCurrent).center()); setSelection(rect, command); @@ -2542,7 +2552,9 @@ void QAbstractItemView::verticalScrollbarValueChanged(int value) Q_D(QAbstractItemView); if (verticalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) d->model->fetchMore(d->root); - d->checkMouseMove(viewport()->mapFromGlobal(QCursor::pos())); + QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos()); + if (viewport()->rect().contains(posInVp)) + d->checkMouseMove(posInVp); } /*! @@ -2553,7 +2565,9 @@ void QAbstractItemView::horizontalScrollbarValueChanged(int value) Q_D(QAbstractItemView); if (horizontalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) d->model->fetchMore(d->root); - d->checkMouseMove(viewport()->mapFromGlobal(QCursor::pos())); + QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos()); + if (viewport()->rect().contains(posInVp)) + d->checkMouseMove(posInVp); } /*! diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index f1ba874..0b5cfbe 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -396,6 +396,7 @@ public: int autoScrollMargin; int autoScrollCount; bool shouldScrollToCurrentOnShow; //used to know if we should scroll to current on show event + bool shouldClearStatusTip; //if there is a statustip currently shown that need to be cleared when leaving. bool alternatingColors; diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index 5df8481..6f0fba6 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -1913,7 +1913,6 @@ void QHeaderView::initializeSections(int start, int end) Q_ASSERT(start >= 0); Q_ASSERT(end >= 0); - d->executePostedLayout(); d->invalidateCachedSizeHint(); if (end + 1 < d->sectionCount) { @@ -1939,11 +1938,25 @@ void QHeaderView::initializeSections(int start, int end) d->sectionCount = end + 1; if (!d->logicalIndices.isEmpty()) { - d->logicalIndices.resize(d->sectionCount); - d->visualIndices.resize(d->sectionCount); - for (int i = start; i < d->sectionCount; ++i){ - d->logicalIndices[i] = i; - d->visualIndices[i] = i; + if (oldCount <= d->sectionCount) { + d->logicalIndices.resize(d->sectionCount); + d->visualIndices.resize(d->sectionCount); + for (int i = oldCount; i < d->sectionCount; ++i) { + d->logicalIndices[i] = i; + d->visualIndices[i] = i; + } + } else { + int j = 0; + for (int i = 0; i < oldCount; ++i) { + int v = d->logicalIndices.at(i); + if (v < d->sectionCount) { + d->logicalIndices[j] = v; + d->visualIndices[v] = j; + j++; + } + } + d->logicalIndices.resize(d->sectionCount); + d->visualIndices.resize(d->sectionCount); } } diff --git a/src/gui/itemviews/qlistwidget.cpp b/src/gui/itemviews/qlistwidget.cpp index 5dd1d76..929d688 100644 --- a/src/gui/itemviews/qlistwidget.cpp +++ b/src/gui/itemviews/qlistwidget.cpp @@ -176,7 +176,8 @@ void QListModel::move(int srcRow, int dstRow) || dstRow < 0 || dstRow >= items.count()) return; - beginMoveRows(QModelIndex(), srcRow, srcRow, QModelIndex(), dstRow); + if (!beginMoveRows(QModelIndex(), srcRow, srcRow, QModelIndex(), dstRow)) + return; if (srcRow < dstRow) --dstRow; items.move(srcRow, dstRow); diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index f1ae3d2..fc82f30 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -1153,6 +1153,8 @@ void QSortFilterProxyModelPrivate::_q_sourceAboutToBeReset() { Q_Q(QSortFilterProxyModel); q->beginResetModel(); + invalidatePersistentIndexes(); + clear_mapping(); } void QSortFilterProxyModelPrivate::_q_sourceReset() @@ -1470,6 +1472,8 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) { Q_D(QSortFilterProxyModel); + beginResetModel(); + disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(_q_sourceDataChanged(QModelIndex,QModelIndex))); @@ -1551,7 +1555,7 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) connect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset())); d->clear_mapping(); - reset(); + endResetModel(); if (d->update_source_sort_column() && d->dynamic_sortfilter) d->sort(); } diff --git a/src/gui/itemviews/qtreewidget.cpp b/src/gui/itemviews/qtreewidget.cpp index c133ae4..948ca79 100644 --- a/src/gui/itemviews/qtreewidget.cpp +++ b/src/gui/itemviews/qtreewidget.cpp @@ -1580,7 +1580,7 @@ void QTreeWidgetItem::setChildIndicatorPolicy(QTreeWidgetItem::ChildIndicatorPol if (!view) return; - view->viewport()->update( view->d_func()->itemDecorationRect(view->d_func()->index(this))); + view->scheduleDelayedItemsLayout(); } /*! diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 7d0e5c7..f2bd288 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -206,7 +206,8 @@ embedded { qcocoaapplication_mac_p.h \ qcocoaapplicationdelegate_mac_p.h \ qmacgesturerecognizer_mac_p.h \ - qmultitouch_mac_p.h + qmultitouch_mac_p.h \ + qcocoasharedwindowmethods_mac_p.h OBJECTIVE_SOURCES += \ kernel/qcursor_mac.mm \ diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 4764a2d..9f4cd0c 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -933,7 +933,8 @@ void QApplicationPrivate::initialize() QApplicationPrivate::wheel_scroll_lines = 3; #endif - initializeMultitouch(); + if (qt_is_gui_used) + initializeMultitouch(); } /*! diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index 84da56e..688e51f 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -1687,7 +1687,10 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event UInt32 mac_buttons = 0; GetEventParameter(event, kEventParamMouseChord, typeUInt32, 0, sizeof(mac_buttons), 0, &mac_buttons); - buttons = qt_mac_get_buttons(mac_buttons); + if (ekind != kEventMouseWheelMoved) + buttons = qt_mac_get_buttons(mac_buttons); + else + buttons = QApplication::mouseButtons(); } int wheel_deltaX = 0; @@ -2449,7 +2452,7 @@ OSStatus QApplicationPrivate::globalAppleEventProcessor(const AppleEvent *ae, Ap switch(aeID) { case kAEQuitApplication: { extern bool qt_mac_quit_menu_item_enabled; // qmenu_mac.cpp - if(!QApplicationPrivate::modalState() && qt_mac_quit_menu_item_enabled) { + if (qt_mac_quit_menu_item_enabled) { QCloseEvent ev; QApplication::sendSpontaneousEvent(app, &ev); if(ev.isAccepted()) { diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 85b6d00..ab57c32 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -133,36 +133,46 @@ private: TTimeIntervalMicroSeconds iDuration; }; +static QS60Beep* qt_S60Beep = 0; + QS60Beep::~QS60Beep() { + if (iToneUtil) { + switch (iState) { + case EBeepPlaying: + iToneUtil->CancelPlay(); + break; + case EBeepNotPrepared: + iToneUtil->CancelPrepare(); + break; + } + } delete iToneUtil; } QS60Beep* QS60Beep::NewL(TInt aFrequency, TTimeIntervalMicroSeconds aDuration) { - QS60Beep* self=new (ELeave) QS60Beep(); + QS60Beep* self = new (ELeave) QS60Beep(); CleanupStack::PushL(self); self->ConstructL(aFrequency, aDuration); CleanupStack::Pop(); return self; -}; +} void QS60Beep::ConstructL(TInt aFrequency, TTimeIntervalMicroSeconds aDuration) { - iToneUtil=CMdaAudioToneUtility::NewL(*this); - iState=EBeepNotPrepared; - iFrequency=aFrequency; - iDuration=aDuration; - iToneUtil->PrepareToPlayTone(iFrequency,iDuration); + iToneUtil = CMdaAudioToneUtility::NewL(*this); + iState = EBeepNotPrepared; + iFrequency = aFrequency; + iDuration = aDuration; + iToneUtil->PrepareToPlayTone(iFrequency, iDuration); } void QS60Beep::Play() { - if (iState != EBeepNotPrepared) { - if (iState == EBeepPlaying) { - iToneUtil->CancelPlay(); - iState = EBeepPrepared; - } + if (iState == EBeepPlaying) { + iToneUtil->CancelPlay(); + iState = EBeepPrepared; } iToneUtil->Play(); @@ -173,13 +183,14 @@ void QS60Beep::MatoPrepareComplete(TInt aError) { if (aError == KErrNone) { iState = EBeepPrepared; + Play(); } } void QS60Beep::MatoPlayComplete(TInt aError) { Q_UNUSED(aError); - iState=EBeepPrepared; + iState = EBeepPrepared; } @@ -812,6 +823,12 @@ void QSymbianControl::Draw(const TRect& controlRect) const if (!engine) return; + const bool sendNativePaintEvents = qwidget->d_func()->extraData()->receiveNativePaintEvents; + if (sendNativePaintEvents) { + const QRect r = qt_TRect2QRect(controlRect); + QMetaObject::invokeMethod(qwidget, "beginNativePaintEvent", Qt::DirectConnection, Q_ARG(QRect, r)); + } + // Map source rectangle into coordinates of the backing store. const QPoint controlBase(controlRect.iTl.iX, controlRect.iTl.iY); const QPoint backingStoreBase = qwidget->mapTo(qwidget->window(), controlBase); @@ -822,14 +839,48 @@ void QSymbianControl::Draw(const TRect& controlRect) const CFbsBitmap *bitmap = s60Surface->symbianBitmap(); CWindowGc &gc = SystemGc(); - if(!qwidget->d_func()->extraData()->disableBlit) { + switch(qwidget->d_func()->extraData()->nativePaintMode) { + case QWExtra::Disable: + // Do nothing + break; + + case QWExtra::Blit: if (qwidget->d_func()->isOpaque) gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); gc.BitBlt(controlRect.iTl, bitmap, backingStoreRect); + break; + + case QWExtra::ZeroFill: + if (Window().DisplayMode() == EColor16MA) { + gc.SetBrushStyle(CGraphicsContext::ESolidBrush); + gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); + gc.SetBrushColor(TRgb::Color16MA(0)); + gc.Clear(controlRect); + } else { + gc.SetBrushColor(TRgb(0x000000)); + gc.Clear(controlRect); + }; + break; + + default: + Q_ASSERT(false); } } else { surface->flush(qwidget, QRegion(qt_TRect2QRect(backingStoreRect)), QPoint()); } + + if (sendNativePaintEvents) { + const QRect r = qt_TRect2QRect(controlRect); + // The draw ops aren't actually sent to WSERV until the graphics + // context is deactivated, which happens in the function calling + // this one. We therefore delay the delivery of endNativePaintEvent, + // to ensure that drawing has completed by the time the widget + // receives the event. Note that, if the widget needs to ensure + // that the draw ops have actually been executed into the output + // framebuffer, a call to RWsSession::Flush is required in the + // endNativePaintEvent implementation. + QMetaObject::invokeMethod(qwidget, "endNativePaintEvent", Qt::QueuedConnection, Q_ARG(QRect, r)); + } } void QSymbianControl::SizeChanged() @@ -908,6 +959,8 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */) } QApplication::setActiveWindow(qwidget->window()); + qwidget->d_func()->setWindowIcon_sys(true); + qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle()); #ifdef Q_WS_S60 // If widget is fullscreen, hide status pane and button container // otherwise show them. @@ -945,7 +998,10 @@ void QSymbianControl::HandleResourceChange(int resourceType) TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect(); SetExtent(r.iTl, r.Size()); } - qwidget->d_func()->setWindowIcon_sys(true); + if (IsFocused() && IsVisible()) { + qwidget->d_func()->setWindowIcon_sys(true); + qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle()); + } break; case KUidValueCoeFontChangeEvent: // font change event @@ -1221,6 +1277,10 @@ void qt_init(QApplicationPrivate * /* priv */, int) *****************************************************************************/ void qt_cleanup() { + if(qt_S60Beep) { + delete qt_S60Beep; + qt_S60Beep = 0; + } QFontCache::cleanup(); // Has to happen now, since QFontEngineS60 has FBS handles // S60 structure and window server session are freed in eventdispatcher destructor as they are needed there @@ -1462,14 +1522,13 @@ void QApplication::setCursorFlashTime(int msecs) void QApplication::beep() { - TInt frequency=440; - TTimeIntervalMicroSeconds duration(500000); - QS60Beep* beep=NULL; - TRAPD(err, beep=QS60Beep::NewL(frequency, duration)); - if (!err) - beep->Play(); - delete beep; - beep=NULL; + if (!qt_S60Beep) { + TInt frequency = 880; + TTimeIntervalMicroSeconds duration(500000); + TRAP_IGNORE(qt_S60Beep=QS60Beep::NewL(frequency, duration)); + } + if (qt_S60Beep) + qt_S60Beep->Play(); } /*! diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 05e75a2..b677228 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -243,8 +243,12 @@ static PtrWTGet ptrWTGet = 0; static PACKET localPacketBuf[QT_TABLET_NPACKETQSIZE]; // our own tablet packet queue. HCTX qt_tablet_context; // the hardware context for the tablet (like a window handle) bool qt_tablet_tilt_support; -static void tabletInit(UINT wActiveCsr, HCTX hTab); + +#ifndef QT_NO_TABLETEVENT +static void tabletInit(const quint64 uniqueId, const UINT csr_type, HCTX hTab); +static void tabletUpdateCursor(QTabletDeviceData &tdd, const UINT currentCursor); static void initWinTabFunctions(); // resolve the WINTAB api functions +#endif // QT_NO_TABLETEVENT #ifndef QT_NO_ACCESSIBILITY @@ -256,7 +260,7 @@ extern QWidget* qt_get_tablet_widget(); extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); extern QRegion qt_dirtyRegion(QWidget *); -typedef QHash<UINT, QTabletDeviceData> QTabletCursorInfo; +typedef QHash<quint64, QTabletDeviceData> QTabletCursorInfo; Q_GLOBAL_STATIC(QTabletCursorInfo, tCursorInfo) QTabletDeviceData currentTabletPointer; @@ -791,7 +795,9 @@ void qt_init(QApplicationPrivate *priv, int) if (QApplication::desktopSettingsAware()) qt_set_windows_resources(); +#ifndef QT_NO_TABLETEVENT initWinTabFunctions(); +#endif // QT_NO_TABLETEVENT QApplicationPrivate::inputContext = new QWinInputContext(0); // Read the initial cleartype settings... @@ -2325,25 +2331,43 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam } break; case WT_PROXIMITY: - if (ptrWTPacketsGet) { - bool enteredProximity = LOWORD(lParam) != 0; - PACKET proximityBuffer[QT_TABLET_NPACKETQSIZE]; - int totalPacks = ptrWTPacketsGet(qt_tablet_context, QT_TABLET_NPACKETQSIZE, proximityBuffer); - if (totalPacks > 0 && enteredProximity) { - uint currentCursor = proximityBuffer[0].pkCursor; - if (!tCursorInfo()->contains(currentCursor)) - tabletInit(currentCursor, qt_tablet_context); - currentTabletPointer = tCursorInfo()->value(currentCursor); + + #ifndef QT_NO_TABLETEVENT + if (ptrWTPacketsGet && ptrWTInfo) { + const bool enteredProximity = LOWORD(lParam) != 0; + PACKET proximityBuffer[1]; // we are only interested in the first packet in this case + const int totalPacks = ptrWTPacketsGet(qt_tablet_context, 1, proximityBuffer); + if (totalPacks > 0) { + const UINT currentCursor = proximityBuffer[0].pkCursor; + + UINT csr_physid; + ptrWTInfo(WTI_CURSORS + currentCursor, CSR_PHYSID, &csr_physid); + UINT csr_type; + ptrWTInfo(WTI_CURSORS + currentCursor, CSR_TYPE, &csr_type); + const UINT deviceIdMask = 0xFF6; // device type mask && device color mask + quint64 uniqueId = (csr_type & deviceIdMask); + uniqueId = (uniqueId << 32) | csr_physid; + + // initialising and updating the cursor should be done in response to + // WT_CSRCHANGE. We do it in WT_PROXIMITY because some wintab never send + // the event WT_CSRCHANGE even if asked with CXO_CSRMESSAGES + const QTabletCursorInfo *const globalCursorInfo = tCursorInfo(); + if (!globalCursorInfo->contains(uniqueId)) + tabletInit(uniqueId, csr_type, qt_tablet_context); + + currentTabletPointer = globalCursorInfo->value(uniqueId); + tabletUpdateCursor(currentTabletPointer, currentCursor); } qt_tabletChokeMouse = false; -#ifndef QT_NO_TABLETEVENT + QTabletEvent tabletProximity(enteredProximity ? QEvent::TabletEnterProximity : QEvent::TabletLeaveProximity, QPoint(), QPoint(), QPointF(), currentTabletPointer.currentDevice, currentTabletPointer.currentPointerType, 0, 0, 0, 0, 0, 0, 0, currentTabletPointer.llId); QApplication::sendEvent(qApp, &tabletProximity); -#endif // QT_NO_TABLETEVENT } + #endif // QT_NO_TABLETEVENT + break; #ifdef Q_WS_WINCE_WM case WM_SETFOCUS: { @@ -3317,63 +3341,57 @@ bool QETWidget::translateWheelEvent(const MSG &msg) // the following is adapted from the wintab syspress example (public domain) /* -------------------------------------------------------------------------- */ -static void tabletInit(UINT wActiveCsr, HCTX hTab) +// Initialize the "static" information of a cursor device (pen, airbrush, etc). +// The QTabletDeviceData is initialized with the data that do not change in time +// (number of button, type of device, etc) but do not initialize the variable data +// (e.g.: pen or eraser) +#ifndef QT_NO_TABLETEVENT + +static void tabletInit(const quint64 uniqueId, const UINT csr_type, HCTX hTab) { + Q_ASSERT(ptrWTInfo); + Q_ASSERT(ptrWTGet); + + Q_ASSERT(!tCursorInfo()->contains(uniqueId)); + /* browse WinTab's many info items to discover pressure handling. */ - if (ptrWTInfo && ptrWTGet) { - AXIS np; - LOGCONTEXT lc; - BYTE wPrsBtn; - BYTE logBtns[32]; - UINT size; - - /* discover the LOGICAL button generated by the pressure channel. */ - /* get the PHYSICAL button from the cursor category and run it */ - /* through that cursor's button map (usually the identity map). */ - wPrsBtn = (BYTE)-1; - ptrWTInfo(WTI_CURSORS + wActiveCsr, CSR_NPBUTTON, &wPrsBtn); - size = ptrWTInfo(WTI_CURSORS + wActiveCsr, CSR_BUTTONMAP, &logBtns); - if ((UINT)wPrsBtn < size) - wPrsBtn = logBtns[wPrsBtn]; - - /* get the current context for its device variable. */ - ptrWTGet(hTab, &lc); - - /* get the size of the pressure axis. */ - QTabletDeviceData tdd; - ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_NPRESSURE, &np); - tdd.minPressure = int(np.axMin); - tdd.maxPressure = int(np.axMax); - - ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_TPRESSURE, &np); - tdd.minTanPressure = int(np.axMin); - tdd.maxTanPressure = int(np.axMax); - - LOGCONTEXT lcMine; - - /* get default region */ - ptrWTInfo(WTI_DEFCONTEXT, 0, &lcMine); - - tdd.minX = 0; - tdd.maxX = int(lcMine.lcInExtX) - int(lcMine.lcInOrgX); - - tdd.minY = 0; - tdd.maxY = int(lcMine.lcInExtY) - int(lcMine.lcInOrgY); - - tdd.minZ = 0; - tdd.maxZ = int(lcMine.lcInExtZ) - int(lcMine.lcInOrgZ); - - int csr_type, - csr_physid; - ptrWTInfo(WTI_CURSORS + wActiveCsr, CSR_TYPE, &csr_type); - ptrWTInfo(WTI_CURSORS + wActiveCsr, CSR_PHYSID, &csr_physid); - tdd.llId = csr_type & 0x0F06; - tdd.llId = (tdd.llId << 24) | csr_physid; -#ifndef QT_NO_TABLETEVENT - if (((csr_type & 0x0006) == 0x0002) && ((csr_type & 0x0F06) != 0x0902)) { - tdd.currentDevice = QTabletEvent::Stylus; - } else { - switch (csr_type & 0x0F06) { + AXIS np; + LOGCONTEXT lc; + + /* get the current context for its device variable. */ + ptrWTGet(hTab, &lc); + + /* get the size of the pressure axis. */ + QTabletDeviceData tdd; + tdd.llId = uniqueId; + + ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_NPRESSURE, &np); + tdd.minPressure = int(np.axMin); + tdd.maxPressure = int(np.axMax); + + ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_TPRESSURE, &np); + tdd.minTanPressure = int(np.axMin); + tdd.maxTanPressure = int(np.axMax); + + LOGCONTEXT lcMine; + + /* get default region */ + ptrWTInfo(WTI_DEFCONTEXT, 0, &lcMine); + + tdd.minX = 0; + tdd.maxX = int(lcMine.lcInExtX) - int(lcMine.lcInOrgX); + + tdd.minY = 0; + tdd.maxY = int(lcMine.lcInExtY) - int(lcMine.lcInOrgY); + + tdd.minZ = 0; + tdd.maxZ = int(lcMine.lcInExtZ) - int(lcMine.lcInOrgZ); + + const uint cursorTypeBitMask = 0x0F06; // bitmask to find the specific cursor type (see Wacom FAQ) + if (((csr_type & 0x0006) == 0x0002) && ((csr_type & cursorTypeBitMask) != 0x0902)) { + tdd.currentDevice = QTabletEvent::Stylus; + } else { + switch (csr_type & cursorTypeBitMask) { case 0x0802: tdd.currentDevice = QTabletEvent::Stylus; break; @@ -3391,26 +3409,34 @@ static void tabletInit(UINT wActiveCsr, HCTX hTab) break; default: tdd.currentDevice = QTabletEvent::NoDevice; - } - } - - switch (wActiveCsr % 3) { - case 2: - tdd.currentPointerType = QTabletEvent::Eraser; - break; - case 1: - tdd.currentPointerType = QTabletEvent::Pen; - break; - case 0: - tdd.currentPointerType = QTabletEvent::Cursor; - break; - default: - tdd.currentPointerType = QTabletEvent::UnknownPointer; } + } + tCursorInfo()->insert(uniqueId, tdd); +} #endif // QT_NO_TABLETEVENT - tCursorInfo()->insert(wActiveCsr, tdd); + +// Update the "dynamic" informations of a cursor device (pen, airbrush, etc). +// The dynamic information is the information of QTabletDeviceData that can change +// in time (eraser or pen if a device is turned around). +#ifndef QT_NO_TABLETEVENT + +static void tabletUpdateCursor(QTabletDeviceData &tdd, const UINT currentCursor) +{ + switch (currentCursor % 3) { // %3 for dual track + case 0: + tdd.currentPointerType = QTabletEvent::Cursor; + break; + case 1: + tdd.currentPointerType = QTabletEvent::Pen; + break; + case 2: + tdd.currentPointerType = QTabletEvent::Eraser; + break; + default: + tdd.currentPointerType = QTabletEvent::UnknownPointer; } } +#endif // QT_NO_TABLETEVENT bool QETWidget::translateTabletEvent(const MSG &msg, PACKET *localPacketBuf, int numPackets) @@ -3546,6 +3572,10 @@ bool QETWidget::translateTabletEvent(const MSG &msg, PACKET *localPacketBuf, } extern bool qt_is_gui_used; + + +#ifndef QT_NO_TABLETEVENT + static void initWinTabFunctions() { #if defined(Q_OS_WINCE) @@ -3564,6 +3594,7 @@ static void initWinTabFunctions() } #endif // Q_OS_WINCE } +#endif // QT_NO_TABLETEVENT // diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm index 37dcc67..304e5d3 100644 --- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm +++ b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm @@ -178,6 +178,9 @@ static void cleanupCocoaApplicationDelegate() return [[qtMenuLoader retain] autorelease]; } +// This function will only be called when NSApp is actually running. Before +// that, the kAEQuitApplication apple event will be sendt to +// QApplicationPrivate::globalAppleEventProcessor in qapplication_mac.mm - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { Q_UNUSED(sender); diff --git a/src/gui/kernel/qcocoamenuloader_mac.mm b/src/gui/kernel/qcocoamenuloader_mac.mm index 9ab077f..990571d 100644 --- a/src/gui/kernel/qcocoamenuloader_mac.mm +++ b/src/gui/kernel/qcocoamenuloader_mac.mm @@ -76,9 +76,14 @@ QT_USE_NAMESPACE - (void)ensureAppMenuInMenu:(NSMenu *)menu { + // The application menu is the menu in the menu bar that contains the + // 'Quit' item. When changing menu bar (e.g when swithing between + // windows with different menu bars), we never recreate this menu, but + // instead pull it out the current menu bar and place into the new one: NSMenu *mainMenu = [NSApp mainMenu]; if ([NSApp mainMenu] == menu) - return; // nothing to do! + return; // nothing to do (menu is the current menu bar)! + #ifndef QT_NAMESPACE Q_ASSERT(mainMenu); #endif diff --git a/src/gui/kernel/qcocoapanel_mac.mm b/src/gui/kernel/qcocoapanel_mac.mm index a26d775..9154284 100644 --- a/src/gui/kernel/qcocoapanel_mac.mm +++ b/src/gui/kernel/qcocoapanel_mac.mm @@ -50,152 +50,16 @@ #include <QtGui/QWidget> QT_FORWARD_DECLARE_CLASS(QWidget); -QT_BEGIN_NAMESPACE -extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm -QT_END_NAMESPACE QT_USE_NAMESPACE - -@interface NSWindow (QtCoverForHackWithCategory) -+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask; -@end - - @implementation QT_MANGLE_NAMESPACE(QCocoaPanel) -- (BOOL)canBecomeKeyWindow -{ - QWidget *widget = [self QT_MANGLE_NAMESPACE(qt_qwidget)]; - - bool isToolTip = (widget->windowType() == Qt::ToolTip); - bool isPopup = (widget->windowType() == Qt::Popup); - return !(isPopup || isToolTip); -} - /*********************************************************************** - BEGIN Copy and Paste between QCocoaWindow and QCocoaPanel + Copy and Paste between QCocoaWindow and QCocoaPanel This is a bit unfortunate, but thanks to the dynamic dispatch we have to duplicate this code or resort to really silly forwarding methods **************************************************************************/ - -/* - The methods keyDown, keyUp, and flagsChanged... These really shouldn't ever - get hit. We automatically say we can be first responder if we are a window. - So, the handling should get handled by the view. This is here more as a - last resort (i.e., this is code that can potentially be removed). - */ - -- (void)toggleToolbarShown:(id)sender -{ - macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]); - [super toggleToolbarShown:sender]; -} - -- (void)keyDown:(NSEvent *)theEvent -{ - bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); - if (!keyOK) - [super keyDown:theEvent]; -} - -- (void)keyUp:(NSEvent *)theEvent -{ - bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); - if (!keyOK) - [super keyUp:theEvent]; -} - -- (void)flagsChanged:(NSEvent *)theEvent -{ - qt_dispatchModifiersChanged(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); - [super flagsChanged:theEvent]; -} - - -- (void)tabletProximity:(NSEvent *)tabletEvent -{ - qt_dispatchTabletProximityEvent(tabletEvent); -} - -- (void)sendEvent:(NSEvent *)event -{ - QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self]; - - // Cocoa can hold onto the window after we've disavowed its knowledge. So, - // if we get sent an event afterwards just have it go through the super's - // version and don't do any stuff with Qt. - if (!widget) { - [super sendEvent:event]; - return; - } - [self retain]; - QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(qt_mac_nativeview_for(widget)); - Qt::MouseButton mouseButton = cocoaButton2QtButton([event buttonNumber]); - - // sometimes need to redirect mouse events to the popup. - QWidget *popup = qAppInstance()->activePopupWidget(); - if (popup && popup != widget) { - switch([event type]) - { - case NSLeftMouseDown: - qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton); - // Don't call super here. This prevents us from getting the mouseUp event, - // which we need to send even if the mouseDown event was not accepted. - // (this is standard Qt behavior.) - break; - case NSRightMouseDown: - case NSOtherMouseDown: - if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton)) - [super sendEvent:event]; - break; - case NSLeftMouseUp: - case NSRightMouseUp: - case NSOtherMouseUp: - if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonRelease, mouseButton)) - [super sendEvent:event]; - break; - case NSMouseMoved: - qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, Qt::NoButton); - break; - case NSLeftMouseDragged: - case NSRightMouseDragged: - case NSOtherMouseDragged: - [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->view = view; - [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->theEvent = event; - if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, mouseButton)) - [super sendEvent:event]; - break; - default: - [super sendEvent:event]; - break; - } - } else { - [super sendEvent:event]; - } - qt_mac_dispatchNCMouseMessage(self, event, [self QT_MANGLE_NAMESPACE(qt_qwidget)], leftButtonIsRightButton); - - - [self release]; -} - -- (BOOL)makeFirstResponder:(NSResponder *)responder -{ - // For some reason Cocoa wants to flip the first responder - // when Qt doesn't want to, sorry, but "No" :-) - if (responder == nil && qApp->focusWidget()) - return NO; - return [super makeFirstResponder:responder]; -} - -/*********************************************************************** - END Copy and Paste between QCocoaWindow and QCocoaPanel -***********************************************************************/ -+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask -{ - if (styleMask & QtMacCustomizeWindow) - return [QT_MANGLE_NAMESPACE(QCocoaWindowCustomThemeFrame) class]; - return [super frameViewClassForStyleMask:styleMask]; -} +#include "qcocoasharedwindowmethods_mac_p.h" @end #endif diff --git a/src/gui/kernel/qcocoapanel_mac_p.h b/src/gui/kernel/qcocoapanel_mac_p.h index d95cd93..69dca1e 100644 --- a/src/gui/kernel/qcocoapanel_mac_p.h +++ b/src/gui/kernel/qcocoapanel_mac_p.h @@ -54,12 +54,10 @@ #ifdef QT_MAC_USE_COCOA #import <Cocoa/Cocoa.h> - @interface QT_MANGLE_NAMESPACE(QCocoaPanel) : NSPanel { bool leftButtonIsRightButton; } + (Class)frameViewClassForStyleMask:(NSUInteger)styleMask; - @end #endif diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h new file mode 100644 index 0000000..f347240 --- /dev/null +++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h @@ -0,0 +1,187 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module 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$ +** +****************************************************************************/ + +/**************************************************************************** + NB: This is not a header file, dispite the file name suffix. This file is + included directly into the source code of qcocoawindow_mac.mm and + qcocoapanel_mac.mm to avoid manually doing copy and paste of the exact + same code needed at both places. This solution makes it more difficult + to e.g fix a bug in qcocoawindow_mac.mm, but forget to do the same in + qcocoapanel_mac.mm. + The reason we need to do copy and paste in the first place, rather than + resolve to method overriding, is that QCocoaPanel needs to inherit from + NSPanel, while QCocoaWindow needs to inherit NSWindow rather than NSPanel). +****************************************************************************/ + +QT_BEGIN_NAMESPACE +extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm +extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp +QT_END_NAMESPACE + +- (BOOL)canBecomeKeyWindow +{ + QWidget *widget = [self QT_MANGLE_NAMESPACE(qt_qwidget)]; + + bool isToolTip = (widget->windowType() == Qt::ToolTip); + bool isPopup = (widget->windowType() == Qt::Popup); + return !(isPopup || isToolTip); +} + +- (void)toggleToolbarShown:(id)sender +{ + macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]); + [super toggleToolbarShown:sender]; +} + +/* + The methods keyDown, keyUp, and flagsChanged... These really shouldn't ever + get hit. We automatically say we can be first responder if we are a window. + So, the handling should get handled by the view. This is here more as a + last resort (i.e., this is code that can potentially be removed). + */ +- (void)keyDown:(NSEvent *)theEvent +{ + bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); + if (!keyOK) + [super keyDown:theEvent]; +} + +- (void)keyUp:(NSEvent *)theEvent +{ + bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); + if (!keyOK) + [super keyUp:theEvent]; +} + +- (void)flagsChanged:(NSEvent *)theEvent +{ + qt_dispatchModifiersChanged(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); + [super flagsChanged:theEvent]; +} + + +- (void)tabletProximity:(NSEvent *)tabletEvent +{ + qt_dispatchTabletProximityEvent(tabletEvent); +} + +- (void)sendEvent:(NSEvent *)event +{ + QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self]; + + // Cocoa can hold onto the window after we've disavowed its knowledge. So, + // if we get sent an event afterwards just have it go through the super's + // version and don't do any stuff with Qt. + if (!widget) { + [super sendEvent:event]; + return; + } + + [self retain]; + QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(qt_mac_nativeview_for(widget)); + Qt::MouseButton mouseButton = cocoaButton2QtButton([event buttonNumber]); + + bool handled = false; + // sometimes need to redirect mouse events to the popup. + QWidget *popup = qAppInstance()->activePopupWidget(); + if (popup) { + switch([event type]) + { + case NSLeftMouseDown: + if (!qt_button_down) + qt_button_down = widget; + handled = qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton); + // Don't call super here. This prevents us from getting the mouseUp event, + // which we need to send even if the mouseDown event was not accepted. + // (this is standard Qt behavior.) + break; + case NSRightMouseDown: + case NSOtherMouseDown: + if (!qt_button_down) + qt_button_down = widget; + handled = qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton); + break; + case NSLeftMouseUp: + case NSRightMouseUp: + case NSOtherMouseUp: + handled = qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonRelease, mouseButton); + qt_button_down = 0; + break; + case NSMouseMoved: + handled = qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, Qt::NoButton); + break; + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: + [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->view = view; + [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->theEvent = event; + handled = qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, mouseButton); + break; + default: + [super sendEvent:event]; + break; + } + } else { + [super sendEvent:event]; + } + + if (!handled) + qt_mac_dispatchNCMouseMessage(self, event, [self QT_MANGLE_NAMESPACE(qt_qwidget)], leftButtonIsRightButton); + + [self release]; +} + +- (BOOL)makeFirstResponder:(NSResponder *)responder +{ + // For some reason Cocoa wants to flip the first responder + // when Qt doesn't want to, sorry, but "No" :-) + if (responder == nil && qApp->focusWidget()) + return NO; + return [super makeFirstResponder:responder]; +} + ++ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask +{ + if (styleMask & QtMacCustomizeWindow) + return [QT_MANGLE_NAMESPACE(QCocoaWindowCustomThemeFrame) class]; + return [super frameViewClassForStyleMask:styleMask]; +} + diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 72eedad..ddd8ca6 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -64,12 +64,16 @@ #include <qdebug.h> -@interface NSEvent (DeviceDelta) +@interface NSEvent (Qt_Compile_Leopard_DeviceDelta) - (CGFloat)deviceDeltaX; - (CGFloat)deviceDeltaY; - (CGFloat)deviceDeltaZ; @end +@interface NSEvent (Qt_Compile_Leopard_Gestures) + - (CGFloat)magnification; +@end + QT_BEGIN_NAMESPACE Q_GLOBAL_STATIC(DnDParams, qMacDnDParams); @@ -79,6 +83,7 @@ extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); // qapplication.cpp extern OSViewRef qt_mac_nativeview_for(const QWidget *w); // qwidget_mac.mm extern const QStringList& qEnabledDraggedTypes(); // qmime_mac.cpp extern QPointer<QWidget> qt_mouseover; //qapplication_mac.mm +extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum) { @@ -691,6 +696,9 @@ extern "C" { - (void)mouseDown:(NSEvent *)theEvent { + if (!qt_button_down) + qt_button_down = qwidget; + qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, Qt::LeftButton); // Don't call super here. This prevents us from getting the mouseUp event, // which we need to send even if the mouseDown event was not accepted. @@ -700,75 +708,62 @@ extern "C" { - (void)mouseUp:(NSEvent *)theEvent { - bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, Qt::LeftButton); + qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, Qt::LeftButton); - if (!mouseOK) - [super mouseUp:theEvent]; + qt_button_down = 0; } - (void)rightMouseDown:(NSEvent *)theEvent { - bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, Qt::RightButton); + if (!qt_button_down) + qt_button_down = qwidget; - if (!mouseOK) - [super rightMouseDown:theEvent]; + qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, Qt::RightButton); } - (void)rightMouseUp:(NSEvent *)theEvent { - bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, Qt::RightButton); + qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, Qt::RightButton); - if (!mouseOK) - [super rightMouseUp:theEvent]; + qt_button_down = 0; } - (void)otherMouseDown:(NSEvent *)theEvent { - Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]); - bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, mouseButton); + if (!qt_button_down) + qt_button_down = qwidget; - if (!mouseOK) - [super otherMouseDown:theEvent]; + Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]); + qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, mouseButton); } - (void)otherMouseUp:(NSEvent *)theEvent { Qt::MouseButton mouseButton = cocoaButton2QtButton([theEvent buttonNumber]); - bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, mouseButton); - - if (!mouseOK) - [super otherMouseUp:theEvent]; + qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonRelease, mouseButton); + qt_button_down = 0; } - (void)mouseDragged:(NSEvent *)theEvent { qMacDnDParams()->view = self; qMacDnDParams()->theEvent = theEvent; - bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton); - - if (!mouseOK) - [super mouseDragged:theEvent]; + qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton); } - (void)rightMouseDragged:(NSEvent *)theEvent { qMacDnDParams()->view = self; qMacDnDParams()->theEvent = theEvent; - bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton); - - if (!mouseOK) - [super rightMouseDragged:theEvent]; + qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton); } - (void)otherMouseDragged:(NSEvent *)theEvent { qMacDnDParams()->view = self; qMacDnDParams()->theEvent = theEvent; - bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton); - - if (!mouseOK) - [super otherMouseDragged:theEvent]; + qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseMove, Qt::NoButton); } - (void)scrollWheel:(NSEvent *)theEvent @@ -782,12 +777,19 @@ extern "C" { NSPoint windowPoint = [theEvent locationInWindow]; NSPoint globalPoint = [[theEvent window] convertBaseToScreen:windowPoint]; NSPoint localPoint = [self convertPoint:windowPoint fromView:nil]; - QPoint qlocal = QPoint(localPoint.x, localPoint.y); - QPoint qglobal = QPoint(globalPoint.x, globalPoint.y); - Qt::MouseButton buttons = cocoaButton2QtButton([theEvent buttonNumber]); + QPoint qlocal = QPoint(localPoint.x, flipYCoordinate(localPoint.y)); + QPoint qglobal = QPoint(globalPoint.x, flipYCoordinate(globalPoint.y)); + Qt::MouseButtons buttons = QApplication::mouseButtons(); bool wheelOK = false; Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]); QWidget *widgetToGetMouse = qwidget; + // if popup is open it should get wheel events if the cursor is over the popup, + // otherwise the event should be ignored. + if (QWidget *popup = qAppInstance()->activePopupWidget()) { + if (!popup->geometry().contains(qglobal)) + return; + } + int deltaX = 0; int deltaY = 0; int deltaZ = 0; @@ -893,6 +895,7 @@ extern "C" { bool all = qwidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents); qt_translateRawTouchEvent(qwidget, QTouchEvent::TouchPad, QCocoaTouch::getCurrentTouchPointList(event, all)); } +#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 - (void)magnifyWithEvent:(NSEvent *)event; { @@ -963,7 +966,6 @@ extern "C" { qNGEvent.position = flipPoint(p).toPoint(); qt_sendSpontaneousEvent(qwidget, &qNGEvent); } -#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 - (void)frameDidChange:(NSNotification *)note { @@ -1447,6 +1449,9 @@ Qt::DropAction QDragManager::drag(QDrag *o) pasteboard:pboard source:dndParams.view slideBack:YES]; + // reset the implicit grab widget when drag ends because we will not + // receive the mouse release event when DND is active. + qt_button_down = 0; [dndParams.view release]; [image release]; dragPrivate()->executed_action = Qt::IgnoreAction; diff --git a/src/gui/kernel/qcocoawindow_mac.mm b/src/gui/kernel/qcocoawindow_mac.mm index 263f0ac..a9aa373 100644 --- a/src/gui/kernel/qcocoawindow_mac.mm +++ b/src/gui/kernel/qcocoawindow_mac.mm @@ -50,15 +50,8 @@ #include <QtGui/QWidget> QT_FORWARD_DECLARE_CLASS(QWidget); -QT_BEGIN_NAMESPACE -extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm -QT_END_NAMESPACE QT_USE_NAMESPACE -@interface NSWindow (QtCoverForHackWithCategory) -+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask; -@end - @implementation NSWindow (QT_MANGLE_NAMESPACE(QWidgetIntegration)) - (id)QT_MANGLE_NAMESPACE(qt_initWithQWidget):(QWidget*)widget contentRect:(NSRect)rect styleMask:(NSUInteger)mask; @@ -83,138 +76,12 @@ QT_USE_NAMESPACE @implementation QT_MANGLE_NAMESPACE(QCocoaWindow) -- (BOOL)canBecomeKeyWindow -{ - return YES; -} - /*********************************************************************** - BEGIN Copy and Paste between QCocoaWindow and QCocoaPanel + Copy and Paste between QCocoaWindow and QCocoaPanel This is a bit unfortunate, but thanks to the dynamic dispatch we have to duplicate this code or resort to really silly forwarding methods **************************************************************************/ - -/* - The methods keyDown, keyUp, and flagsChanged... These really shouldn't ever - get hit. We automatically say we can be first responder if we are a window. - So, the handling should get handled by the view. This is here more as a - last resort (i.e., this is code that can potentially be removed). - */ - -- (void)toggleToolbarShown:(id)sender -{ - macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]); - [super toggleToolbarShown:sender]; -} - -- (void)keyDown:(NSEvent *)theEvent -{ - bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); - if (!keyOK) - [super keyDown:theEvent]; -} - -- (void)keyUp:(NSEvent *)theEvent -{ - bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); - if (!keyOK) - [super keyUp:theEvent]; -} - -- (void)flagsChanged:(NSEvent *)theEvent -{ - qt_dispatchModifiersChanged(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); - [super flagsChanged:theEvent]; -} - - -- (void)tabletProximity:(NSEvent *)tabletEvent -{ - qt_dispatchTabletProximityEvent(tabletEvent); -} - -- (void)sendEvent:(NSEvent *)event -{ - QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self]; - - // Cocoa can hold onto the window after we've disavowed its knowledge. So, - // if we get sent an event afterwards just have it go through the super's - // version and don't do any stuff with Qt. - if (!widget) { - [super sendEvent:event]; - return; - } - - [self retain]; - QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(qt_mac_nativeview_for(widget)); - Qt::MouseButton mouseButton = cocoaButton2QtButton([event buttonNumber]); - // sometimes need to redirect mouse events to the popup. - QWidget *popup = qAppInstance()->activePopupWidget(); - if (popup && popup != widget) { - switch([event type]) - { - case NSLeftMouseDown: - qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton); - // Don't call super here. This prevents us from getting the mouseUp event, - // which we need to send even if the mouseDown event was not accepted. - // (this is standard Qt behavior.) - break; - case NSRightMouseDown: - case NSOtherMouseDown: - if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonPress, mouseButton)) - [super sendEvent:event]; - break; - case NSLeftMouseUp: - case NSRightMouseUp: - case NSOtherMouseUp: - if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseButtonRelease, mouseButton)) - [super sendEvent:event]; - break; - case NSMouseMoved: - qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, Qt::NoButton); - break; - case NSLeftMouseDragged: - case NSRightMouseDragged: - case NSOtherMouseDragged: - [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->view = view; - [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->theEvent = event; - if (!qt_mac_handleMouseEvent(view, event, QEvent::MouseMove, mouseButton)) - [super sendEvent:event]; - break; - default: - [super sendEvent:event]; - break; - } - } else { - [super sendEvent:event]; - } - qt_mac_dispatchNCMouseMessage(self, event, [self QT_MANGLE_NAMESPACE(qt_qwidget)], leftButtonIsRightButton); - - - [self release]; -} - - -- (BOOL)makeFirstResponder:(NSResponder *)responder -{ - // For some reason Cocoa wants to flip the first responder - // when Qt doesn't want to, sorry, but "No" :-) - if (responder == nil && qApp->focusWidget()) - return NO; - return [super makeFirstResponder:responder]; -} - -/*********************************************************************** - END Copy and Paste between QCocoaWindow and QCocoaPanel -***********************************************************************/ - -+ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask -{ - if (styleMask & QtMacCustomizeWindow) - return [QT_MANGLE_NAMESPACE(QCocoaWindowCustomThemeFrame) class]; - return [super frameViewClassForStyleMask:styleMask]; -} +#include "qcocoasharedwindowmethods_mac_p.h" @end - #endif diff --git a/src/gui/kernel/qcocoawindow_mac_p.h b/src/gui/kernel/qcocoawindow_mac_p.h index a688d96..91c5d4e 100644 --- a/src/gui/kernel/qcocoawindow_mac_p.h +++ b/src/gui/kernel/qcocoawindow_mac_p.h @@ -50,13 +50,18 @@ // We mean it. // -#include "qmacdefines_mac.h" #ifdef QT_MAC_USE_COCOA +#include "qmacdefines_mac.h" #import <Cocoa/Cocoa.h> enum { QtMacCustomizeWindow = 1 << 21 }; // This will one day be run over by QT_FORWARD_DECLARE_CLASS(QWidget); +QT_FORWARD_DECLARE_CLASS(QStringList); + +@interface NSWindow (QtCoverForHackWithCategory) ++ (Class)frameViewClassForStyleMask:(NSUInteger)styleMask; +@end @interface NSWindow (QT_MANGLE_NAMESPACE(QWidgetIntegration)) - (id)QT_MANGLE_NAMESPACE(qt_initWithQWidget):(QWidget *)widget contentRect:(NSRect)rect styleMask:(NSUInteger)mask; @@ -70,3 +75,4 @@ QT_FORWARD_DECLARE_CLASS(QWidget); + (Class)frameViewClassForStyleMask:(NSUInteger)styleMask; @end #endif + diff --git a/src/gui/kernel/qcocoawindowdelegate_mac.mm b/src/gui/kernel/qcocoawindowdelegate_mac.mm index 9fb674e..8a22a65 100644 --- a/src/gui/kernel/qcocoawindowdelegate_mac.mm +++ b/src/gui/kernel/qcocoawindowdelegate_mac.mm @@ -324,8 +324,13 @@ static void cleanupCocoaWindowDelegate() NSRect frameToReturn = defaultFrame; QWidget *qwidget = m_windowHash->value(window); QSizeF size = qwidget->maximumSize(); - frameToReturn.size.width = qMin<CGFloat>(frameToReturn.size.width, size.width()); - frameToReturn.size.height = qMin<CGFloat>(frameToReturn.size.height, size.height()); + NSRect windowFrameRect = [window frame]; + NSRect viewFrameRect = [[window contentView] frame]; + // consider additional size required for titlebar & frame + frameToReturn.size.width = qMin<CGFloat>(frameToReturn.size.width, + size.width()+(windowFrameRect.size.width - viewFrameRect.size.width)); + frameToReturn.size.height = qMin<CGFloat>(frameToReturn.size.height, + size.height()+(windowFrameRect.size.height - viewFrameRect.size.height)); return frameToReturn; } diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm index 427f0b0..e0eebfd 100644 --- a/src/gui/kernel/qeventdispatcher_mac.mm +++ b/src/gui/kernel/qeventdispatcher_mac.mm @@ -572,7 +572,7 @@ bool QEventDispatcherMac::processEvents(QEventLoop::ProcessEventsFlags flags) while (!d->interrupt && [NSApp runModalSession:session] == NSRunContinuesResponse) qt_mac_waitForMoreModalSessionEvents(); if (!d->interrupt && session == d->currentModalSessionCached) { - // Someone called e.g. [NSApp stopModal:] from outside the event + // INVARIANT: Someone called e.g. [NSApp stopModal:] from outside the event // dispatcher (e.g to stop a native dialog). But that call wrongly stopped // 'session' as well. As a result, we need to restart all internal sessions: d->temporarilyStopAllModalSessions(); @@ -596,7 +596,13 @@ bool QEventDispatcherMac::processEvents(QEventLoop::ProcessEventsFlags flags) if (NSModalSession session = d->currentModalSession()) { if (flags & QEventLoop::WaitForMoreEvents) qt_mac_waitForMoreModalSessionEvents(); - [NSApp runModalSession:session]; + NSInteger status = [NSApp runModalSession:session]; + if (status != NSRunContinuesResponse && session == d->currentModalSessionCached) { + // INVARIANT: Someone called e.g. [NSApp stopModal:] from outside the event + // dispatcher (e.g to stop a native dialog). But that call wrongly stopped + // 'session' as well. As a result, we need to restart all internal sessions: + d->temporarilyStopAllModalSessions(); + } retVal = true; break; } else { diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index e3af683..2361dd0 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -282,8 +282,8 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni \row \i SelectPreviousPage \i Shift+PgUp \i Shift+PgUp \i Shift+PgUp \i Shift+PgUp \i Shift+PgUp \row \i SelectStartOfLine \i Shift+Home \i Ctrl+Shift+Left \i Shift+Home \i Shift+Home \i Shift+Home \row \i SelectEndOfLine \i Shift+End \i Ctrl+Shift+Right \i Shift+End \i Shift+End \i Shift+End - \row \i SelectStartOfBlock \i (none) \i Alt+Shift+Up \i (none) \i (none) \i (none) - \row \i SelectEndOfBlock \i (none) \i Alt+Shift+Down \i (none) \i (none) \i (none) + \row \i SelectStartOfBlock \i (none) \i Alt+Shift+Up, Meta+Shift+A \i (none) \i (none) \i (none) + \row \i SelectEndOfBlock \i (none) \i Alt+Shift+Down, Meta+Shift+E \i (none) \i (none) \i (none) \row \i SelectStartOfDocument\i Ctrl+Shift+Home \i Ctrl+Shift+Up, Shift+Home \i Ctrl+Shift+Home\i Ctrl+Shift+Home \i Ctrl+Shift+Home \row \i SelectEndOfDocument \i Ctrl+Shift+End \i Ctrl+Shift+Down, Shift+End \i Ctrl+Shift+End \i Ctrl+Shift+End \i Ctrl+Shift+End \row \i DeleteStartOfWord \i Ctrl+Backspace \i Alt+Backspace \i Ctrl+Backspace \i Ctrl+Backspace \i (none) @@ -732,6 +732,8 @@ const QKeyBinding QKeySequencePrivate::keyBindings[] = { {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_Down, QApplicationPrivate::KB_Mac}, {QKeySequence::MoveToPreviousPage, 0, Qt::META | Qt::Key_PageUp, QApplicationPrivate::KB_Mac}, {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_PageDown, QApplicationPrivate::KB_Mac}, + {QKeySequence::SelectStartOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_A, QApplicationPrivate::KB_Mac}, + {QKeySequence::SelectEndOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_E, QApplicationPrivate::KB_Mac}, {QKeySequence::SelectStartOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Left, QApplicationPrivate::KB_Mac}, {QKeySequence::SelectEndOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Right, QApplicationPrivate::KB_Mac} }; diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp index 775d773..0e98f39 100644 --- a/src/gui/kernel/qsoftkeymanager.cpp +++ b/src/gui/kernel/qsoftkeymanager.cpp @@ -190,7 +190,7 @@ bool QSoftKeyManager::event(QEvent *e) } QWidget *parent = source->parentWidget(); - if (parent && softKeys.isEmpty()) + if (parent && softKeys.isEmpty() && !source->isWindow()) source = parent; else break; @@ -246,15 +246,22 @@ void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &softkeys) break; } - int command = (softKeyAction->objectName().contains("_q_menuSoftKeyAction")) + int command = (softKeyAction->objectName().contains(QLatin1String("_q_menuSoftKeyAction"))) ? EAknSoftkeyOptions : s60CommandStart + index; + // _q_menuSoftKeyAction action is set to "invisible" and all invisible actions are by default + // disabled. However we never want to dim options softkey, even it is set to "invisible" + bool dimmed = (command == EAknSoftkeyOptions) ? false : !softKeyAction->isEnabled(); + if (position != -1) { const int underlineShortCut = QApplication::style()->styleHint(QStyle::SH_UnderlineShortcut); QString iconText = softKeyAction->iconText(); TPtrC text = qt_QString2TPtrC( underlineShortCut ? softKeyAction->text() : iconText); - QT_TRAP_THROWING(nativeContainer->SetCommandL(position, command, text)); + QT_TRAP_THROWING( + nativeContainer->SetCommandL(position, command, text); + nativeContainer->DimCommand(command, dimmed); + ); } } diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index c0fb8aa..ef680a4 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -139,6 +139,7 @@ void QMacWindowFader::performFade() extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); // qapplication.cpp; extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm extern QWidget * mac_mouse_grabber; +extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds) { @@ -748,7 +749,11 @@ void qt_mac_dispatchNCMouseMessage(void * /* NSWindow* */eventWindow, void * /* NSRect frameRect = [window frame]; if (fakeNCEvents || NSMouseInRect(globalPoint, frameRect, NO)) { NSRect contentRect = [window contentRectForFrameRect:frameRect]; - if (fakeNCEvents || !NSMouseInRect(globalPoint, contentRect, NO)) { + qglobalPoint = QPoint(flipPoint(globalPoint).toPoint()); + QWidget *w = widgetToGetEvent->childAt(widgetToGetEvent->mapFromGlobal(qglobalPoint)); + // check that the mouse pointer is on the non-client area and + // there are not widgets in it. + if (fakeNCEvents || (!NSMouseInRect(globalPoint, contentRect, NO) && !w)) { qglobalPoint = QPoint(flipPoint(globalPoint).toPoint()); qlocalPoint = widgetToGetEvent->mapFromGlobal(qglobalPoint); processThisEvent = true; @@ -759,8 +764,11 @@ void qt_mac_dispatchNCMouseMessage(void * /* NSWindow* */eventWindow, void * /* // This is not an NC area mouse message. if (!processThisEvent) return; + // If the window is frame less, generate fake mouse events instead. (floating QToolBar) - if (fakeNCEvents && (widgetToGetEvent->window()->windowFlags() & Qt::FramelessWindowHint)) + // or if someone already got an explicit or implicit grab + if (mac_mouse_grabber || qt_button_down || + (fakeNCEvents && (widgetToGetEvent->window()->windowFlags() & Qt::FramelessWindowHint))) fakeMouseEvents = true; Qt::MouseButton button; @@ -838,8 +846,15 @@ void qt_mac_dispatchNCMouseMessage(void * /* NSWindow* */eventWindow, void * /* leftButtonIsRightButton = false; } } + QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, button, keyMods); qt_sendSpontaneousEvent(widgetToGetEvent, &qme); + + // We don't need to set the implicit grab widget here because we won't + // reach this point if then event type is Press over a Qt widget. + // However we might need to unset it if the event is Release. + if (eventType == QEvent::MouseButtonRelease) + qt_button_down = 0; #endif } @@ -873,15 +888,12 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev // Find the widget that *should* get the event (e.g., maybe it was a pop-up, // they always get the mouse event). QWidget *qwidget = [theView qt_qwidget]; - QWidget *widgetToGetMouse = qwidget; + QWidget *widgetToGetMouse = 0; + NSView *tmpView = 0; QWidget *popup = qAppInstance()->activePopupWidget(); - NSView *tmpView = theView; - if (mac_mouse_grabber && mac_mouse_grabber != widgetToGetMouse) { - widgetToGetMouse = mac_mouse_grabber; - tmpView = qt_mac_nativeview_for(widgetToGetMouse); - } + QPoint qglobalPoint(flipPoint(globalPoint).toPoint()); - if (popup && popup != qwidget->window()) { + if (popup) { widgetToGetMouse = popup; tmpView = qt_mac_nativeview_for(popup); windowPoint = [[tmpView window] convertScreenToBase:globalPoint]; @@ -899,7 +911,17 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev widgetToGetMouse = [static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(tmpView) qt_qwidget]; } + } else { + extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp + QPoint pos; + widgetToGetMouse = QApplicationPrivate::pickMouseReceiver(qwidget, qglobalPoint, + pos, eventType, + button, qt_button_down, 0); + if (widgetToGetMouse) + tmpView = qt_mac_nativeview_for(widgetToGetMouse); } + if (!widgetToGetMouse) + return false; NSPoint localPoint = [tmpView convertPoint:windowPoint fromView:nil]; QPoint qlocalPoint(localPoint.x, localPoint.y); @@ -945,14 +967,13 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev break; } [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->localPoint = localPoint; - QPoint qglobalPoint(flipPoint(globalPoint).toPoint()); QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, buttons, keyMods); qt_sendSpontaneousEvent(widgetToGetMouse, &qme); if (eventType == QEvent::MouseButtonPress && button == Qt::RightButton) { QContextMenuEvent qcme(QContextMenuEvent::Mouse, qlocalPoint, qglobalPoint, keyMods); qt_sendSpontaneousEvent(widgetToGetMouse, &qcme); } - return qme.isAccepted(); + return true; #endif } diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index fbb9115..e551a1d 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -366,7 +366,8 @@ bool QWidget::hasEditFocus() const normally; otherwise, Qt::Key_Up and Qt::Key_Down are used to change focus. - This feature is only available in Qt for Embedded Linux. + This feature is only available in Qt for Embedded Linux and Qt + for Symbian. \sa hasEditFocus(), QApplication::keypadNavigationEnabled() */ @@ -4605,7 +4606,7 @@ void QWidgetPrivate::updateFont(const QFont &font) if (!q->parentWidget() && extra && extra->proxyWidget) { QGraphicsProxyWidget *p = extra->proxyWidget; inheritedFontResolveMask = p->d_func()->inheritedFontResolveMask | p->font().resolve(); - } else + } else #endif //QT_NO_GRAPHICSVIEW if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) { inheritedFontResolveMask = 0; @@ -5045,6 +5046,8 @@ QGraphicsEffect *QWidget::graphicsEffect() const If \a effect is the installed on a different widget, setGraphicsEffect() will remove the effect from the widget and install it on this widget. + QWidget takes ownership of \a effect. + \note This function will apply the effect on itself and all its children. \since 4.6 @@ -5058,28 +5061,22 @@ void QWidget::setGraphicsEffect(QGraphicsEffect *effect) if (d->graphicsEffect == effect) return; - if (d->graphicsEffect && effect) { + if (d->graphicsEffect) { + d->invalidateBuffer(rect()); delete d->graphicsEffect; d->graphicsEffect = 0; } - if (!effect) { - // Unset current effect. - QGraphicsEffectPrivate *oldEffectPrivate = d->graphicsEffect->d_func(); - d->graphicsEffect = 0; - if (oldEffectPrivate) { - oldEffectPrivate->setGraphicsEffectSource(0); // deletes the current source. - } - } else { + if (effect) { // Set new effect. QGraphicsEffectSourcePrivate *sourced = new QWidgetEffectSourcePrivate(this); QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced); d->graphicsEffect = effect; effect->d_func()->setGraphicsEffectSource(source); + update(); } d->updateIsOpaque(); - update(); } #endif //QT_NO_GRAPHICSEFFECT @@ -6045,6 +6042,11 @@ bool QWidget::hasFocus() const (Nothing happens if the focus in and focus out widgets are the same.) + \note On embedded platforms, setFocus() will not cause an input panel + to be opened by the input method. If you want this to happen, you + have to send a QEvent::RequestSoftwareInputPanel event to the + widget yourself. + setFocus() gives focus to a widget regardless of its focus policy, but does not clear any keyboard grab (see grabKeyboard()). @@ -6057,7 +6059,7 @@ bool QWidget::hasFocus() const \sa hasFocus(), clearFocus(), focusInEvent(), focusOutEvent(), setFocusPolicy(), focusWidget(), QApplication::focusWidget(), grabKeyboard(), - grabMouse(), {Keyboard Focus} + grabMouse(), {Keyboard Focus}, QEvent::RequestSoftwareInputPanel */ void QWidget::setFocus(Qt::FocusReason reason) @@ -8374,9 +8376,10 @@ bool QWidget::event(QEvent *event) case QEvent::TouchUpdate: case QEvent::TouchEnd: { +#ifndef Q_WS_MAC QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event); const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().first(); - if (touchPoint.isPrimary()) + if (touchPoint.isPrimary() || touchEvent->deviceType() == QTouchEvent::TouchPad) break; // fake a mouse event! @@ -8405,6 +8408,7 @@ bool QWidget::event(QEvent *event) Qt::LeftButton, touchEvent->modifiers()); (void) QApplication::sendEvent(this, &mouseEvent); +#endif // Q_WS_MAC break; } case QEvent::Gesture: @@ -9897,13 +9901,13 @@ void QWidget::scroll(int dx, int dy) Q_D(QWidget); #ifndef QT_NO_GRAPHICSVIEW if (QGraphicsProxyWidget *proxy = QWidgetPrivate::nearestGraphicsProxyWidget(this)) { - // Graphics View maintains its own dirty region as a list of rects; - // until we can connect item updates directly to the view, we must - // separately add a translated dirty region. - if (!d->dirty.isEmpty()) { - foreach (const QRect &rect, (d->dirty.translated(dx, dy)).rects()) - proxy->update(rect); - } + // Graphics View maintains its own dirty region as a list of rects; + // until we can connect item updates directly to the view, we must + // separately add a translated dirty region. + if (!d->dirty.isEmpty()) { + foreach (const QRect &rect, (d->dirty.translated(dx, dy)).rects()) + proxy->update(rect); + } proxy->scroll(dx, dy, proxy->subWidgetRect(this)); return; } @@ -9932,13 +9936,13 @@ void QWidget::scroll(int dx, int dy, const QRect &r) Q_D(QWidget); #ifndef QT_NO_GRAPHICSVIEW if (QGraphicsProxyWidget *proxy = QWidgetPrivate::nearestGraphicsProxyWidget(this)) { - // Graphics View maintains its own dirty region as a list of rects; - // until we can connect item updates directly to the view, we must - // separately add a translated dirty region. - if (!d->dirty.isEmpty()) { - foreach (const QRect &rect, (d->dirty.translated(dx, dy) & r).rects()) - proxy->update(rect); - } + // Graphics View maintains its own dirty region as a list of rects; + // until we can connect item updates directly to the view, we must + // separately add a translated dirty region. + if (!d->dirty.isEmpty()) { + foreach (const QRect &rect, (d->dirty.translated(dx, dy) & r).rects()) + proxy->update(rect); + } proxy->scroll(dx, dy, r.translated(proxy->subWidgetRect(this).topLeft().toPoint())); return; } diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h index 5ba1d23..0824db3 100644 --- a/src/gui/kernel/qwidget.h +++ b/src/gui/kernel/qwidget.h @@ -744,6 +744,7 @@ private: friend struct QWidgetExceptionCleaner; friend class QGestureManager; friend class QWinNativePanGestureRecognizer; + friend class QWidgetEffectSourcePrivate; #ifdef Q_WS_MAC friend class QCoreGraphicsPaintEnginePrivate; diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 71f0077..7dc4d85 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -725,6 +725,23 @@ static OSWindowRef qt_mac_create_window(QWidget *, WindowClass wclass, WindowAtt return window; } +#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 +/* We build the release package against the 10.4 SDK. + So, to enable gestures for applications running on + 10.6+, we define the missing constants here: */ +enum { + kEventClassGesture = 'gest', + kEventGestureStarted = 1, + kEventGestureEnded = 2, + kEventGestureMagnify = 4, + kEventGestureSwipe = 5, + kEventGestureRotate = 6, + kEventParamRotationAmount = 'rota', + kEventParamSwipeDirection = 'swip', + kEventParamMagnificationAmount = 'magn' +}; +#endif + // window events static EventTypeSpec window_events[] = { { kEventClassWindow, kEventWindowClose }, @@ -741,13 +758,11 @@ static EventTypeSpec window_events[] = { { kEventClassWindow, kEventWindowGetRegion }, { kEventClassWindow, kEventWindowGetClickModality }, { kEventClassWindow, kEventWindowTransitionCompleted }, -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 { kEventClassGesture, kEventGestureStarted }, { kEventClassGesture, kEventGestureEnded }, { kEventClassGesture, kEventGestureMagnify }, { kEventClassGesture, kEventGestureSwipe }, { kEventClassGesture, kEventGestureRotate }, -#endif { kEventClassMouse, kEventMouseDown } }; static EventHandlerUPP mac_win_eventUPP = 0; @@ -1036,7 +1051,6 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event, handled_event = false; break; } -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 case kEventClassGesture: { // First, find the widget that was under // the mouse when the gesture happened: @@ -1064,7 +1078,7 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event, break; case kEventGestureRotate: { CGFloat amount; - if (GetEventParameter(event, kEventParamRotationAmount, typeCGFloat, 0, + if (GetEventParameter(event, kEventParamRotationAmount, 'cgfl', 0, sizeof(amount), 0, &amount) != noErr) { handled_event = false; break; @@ -1091,7 +1105,7 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event, break; } case kEventGestureMagnify: { CGFloat amount; - if (GetEventParameter(event, kEventParamMagnificationAmount, typeCGFloat, 0, + if (GetEventParameter(event, kEventParamMagnificationAmount, 'cgfl', 0, sizeof(amount), 0, &amount) != noErr) { handled_event = false; break; @@ -1103,7 +1117,6 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event, QApplication::sendSpontaneousEvent(widget, &qNGEvent); break; } -#endif // gestures default: handled_event = false; @@ -2604,8 +2617,6 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows) releaseMouse(); if(mac_keyboard_grabber == this) releaseKeyboard(); - if(acceptDrops()) - setAcceptDrops(false); if(testAttribute(Qt::WA_ShowModal)) // just be sure we leave modal QApplicationPrivate::leaveModal(this); @@ -3643,6 +3654,16 @@ void QWidgetPrivate::setFocus_sys() } } +NSComparisonResult compareViews2Raise(id view1, id view2, void *context) +{ + id topView = reinterpret_cast<id>(context); + if (view1 == topView) + return NSOrderedDescending; + if (view2 == topView) + return NSOrderedAscending; + return NSOrderedSame; +} + void QWidgetPrivate::raise_sys() { Q_Q(QWidget); @@ -3650,7 +3671,6 @@ void QWidgetPrivate::raise_sys() return; #if QT_MAC_USE_COCOA - QMacCocoaAutoReleasePool pool; if (isRealWindow()) { // Calling orderFront shows the window on Cocoa too. if (!q->testAttribute(Qt::WA_DontShowOnScreen) && q->isVisible()) { @@ -3662,16 +3682,9 @@ void QWidgetPrivate::raise_sys() SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly); } } else { - // Cocoa doesn't really have an idea of Z-ordering, but you can - // fake it by changing the order of it. But beware, removing an - // NSView will also remove it as the first responder. So we re-set - // the first responder just in case: NSView *view = qt_mac_nativeview_for(q); NSView *parentView = [view superview]; - NSResponder *firstResponder = [[view window] firstResponder]; - [view removeFromSuperview]; - [parentView addSubview:view]; - [[view window] makeFirstResponder:firstResponder]; + [parentView sortSubviewsUsingFunction:compareViews2Raise context:reinterpret_cast<void *>(view)]; } #else if(q->isWindow()) { @@ -3689,47 +3702,29 @@ void QWidgetPrivate::raise_sys() #endif } +NSComparisonResult compareViews2Lower(id view1, id view2, void *context) +{ + id topView = reinterpret_cast<id>(context); + if (view1 == topView) + return NSOrderedAscending; + if (view2 == topView) + return NSOrderedDescending; + return NSOrderedSame; +} + void QWidgetPrivate::lower_sys() { Q_Q(QWidget); if((q->windowType() == Qt::Desktop)) return; #ifdef QT_MAC_USE_COCOA - QMacCocoaAutoReleasePool pool; if (isRealWindow()) { OSWindowRef window = qt_mac_window_for(q); [window orderBack:window]; } else { - // Cocoa doesn't really have an idea of Z-ordering, but you can - // fake it by changing the order of it. In this case - // we put the item at the beginning of the list, but that means - // we must re-insert everything since we cannot modify the list directly. - NSView *myview = qt_mac_nativeview_for(q); - NSView *parentView = [myview superview]; - NSArray *tmpViews = [parentView subviews]; - NSMutableArray *subviews = [[NSMutableArray alloc] initWithCapacity:[tmpViews count]]; - [subviews addObjectsFromArray:tmpViews]; - NSResponder *firstResponder = [[myview window] firstResponder]; - // Implicit assumption that myViewIndex is included in subviews, that's why I'm not checking - // myViewIndex. - NSUInteger index = 0; - NSUInteger myViewIndex = 0; - bool foundMyView = false; - for (NSView *subview in subviews) { - [subview removeFromSuperview]; - if (subview == myview) { - foundMyView = true; - myViewIndex = index; - } - ++index; - } - [parentView addSubview:myview]; - if (foundMyView) - [subviews removeObjectAtIndex:myViewIndex]; - for (NSView *subview in subviews) - [parentView addSubview:subview]; - [subviews release]; - [[myview window] makeFirstResponder:firstResponder]; + NSView *view = qt_mac_nativeview_for(q); + NSView *parentView = [view superview]; + [parentView sortSubviewsUsingFunction:compareViews2Lower context:reinterpret_cast<void *>(view)]; } #else if(q->isWindow()) { @@ -3742,6 +3737,16 @@ void QWidgetPrivate::lower_sys() #endif } +NSComparisonResult compareViews2StackUnder(id view1, id view2, void *context) +{ + const QHash<NSView *, int> &viewOrder = *reinterpret_cast<QHash<NSView *, int> *>(context); + if (viewOrder[view1] < viewOrder[view2]) + return NSOrderedAscending; + if (viewOrder[view1] > viewOrder[view2]) + return NSOrderedDescending; + return NSOrderedSame; +} + void QWidgetPrivate::stackUnder_sys(QWidget *w) { // stackUnder @@ -3750,37 +3755,23 @@ void QWidgetPrivate::stackUnder_sys(QWidget *w) return; #ifdef QT_MAC_USE_COCOA // Do the same trick as lower_sys() and put this widget before the widget passed in. - QMacCocoaAutoReleasePool pool; - NSView *myview = qt_mac_nativeview_for(q); + NSView *myView = qt_mac_nativeview_for(q); NSView *wView = qt_mac_nativeview_for(w); - NSView *parentView = [myview superview]; - NSArray *tmpViews = [parentView subviews]; - NSMutableArray *subviews = [[NSMutableArray alloc] initWithCapacity:[tmpViews count]]; - [subviews addObjectsFromArray:tmpViews]; - // Implicit assumption that myViewIndex and wViewIndex is included in subviews, - // that's why I'm not checking myViewIndex. - NSUInteger index = 0; - NSUInteger myViewIndex = 0; - NSUInteger wViewIndex = 0; - for (NSView *subview in subviews) { - [subview removeFromSuperview]; - if (subview == myview) - myViewIndex = index; - else if (subview == wView) - wViewIndex = index; - ++index; - } - index = 0; + QHash<NSView *, int> viewOrder; + NSView *parentView = [myView superview]; + NSArray *subviews = [parentView subviews]; + NSUInteger index = 1; + // make a hash of view->zorderindex and make sure z-value is always odd, + // so that when we modify the order we create a new (even) z-value which + // will not interfere with others. for (NSView *subview in subviews) { - if (index == myViewIndex) - continue; - if (index == wViewIndex) - [parentView addSubview:myview]; - [parentView addSubview:subview]; + viewOrder.insert(subview, index * 2); ++index; } - [subviews release]; + viewOrder[myView] = viewOrder[wView] - 1; + + [parentView sortSubviewsUsingFunction:compareViews2StackUnder context:reinterpret_cast<void *>(&viewOrder)]; #else QWidget *p = q->parentWidget(); if(!p || p != w->parentWidget()) diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 66efcb5..5d73951 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -230,12 +230,42 @@ struct QWExtra { #elif defined(Q_OS_SYMBIAN) // <----------------------------------------------------- Symbian uint activated : 1; // RWindowBase::Activated has been called - // If set, QSymbianControl::Draw does not blit this widget - // This is to allow, for use cases such as video, widgets which, from the Qt point - // of view, are just placeholders in the scene. For these widgets, any necessary - // drawing to the UI framebuffer is done by the relevant Symbian subsystem. For - // video rendering, this would be an MMF controller, or MDF post-processor. - uint disableBlit : 1; + /** + * Defines the behaviour of QSymbianControl::Draw. + */ + enum NativePaintMode { + /** + * Normal drawing mode: blits the required region of the backing store + * via WSERV. + */ + Blit, + + /** + * Disable drawing for this widget. + */ + Disable, + + /** + * Paint zeros into the WSERV framebuffer, using BitGDI APIs. For windows + * with an EColor16MU display mode, zero is written only into the R, G and B + * channels of the pixel. + */ + ZeroFill, + + Default = Blit + }; + + NativePaintMode nativePaintMode : 2; + + /** + * If this bit is set, each native widget receives the signals from the + * Symbian control immediately before and immediately after draw ops are + * sent to the window server for this control: + * void beginNativePaintEvent(const QRect &paintRect); + * void endNativePaintEvent(const QRect &paintRect); + */ + uint receiveNativePaintEvents : 1; + #endif }; @@ -793,7 +823,7 @@ public: {} inline void detach() - { m_widget->setGraphicsEffect(0); } + { m_widget->d_func()->graphicsEffect = 0; } inline const QGraphicsItem *graphicsItem() const { return 0; } diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index b1c37d3..37614c7 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -488,12 +488,6 @@ void QWidgetPrivate::show_sys() if(q->isWindow()) id->setFocusSafely(true); - - // Force setting of the icon after window is made visible, - // this is needed even WA_SetWindowIcon is not set, as in that case we need - // to reset to the application level window icon - if(q->isWindow()) - setWindowIcon_sys(true); } invalidateBuffer(q->rect()); @@ -887,7 +881,8 @@ void QWidgetPrivate::deleteTLSysExtra() void QWidgetPrivate::createSysExtra() { extra->activated = 0; - extra->disableBlit = 0; + extra->nativePaintMode = QWExtra::Default; + extra->receiveNativePaintEvents = 0; } void QWidgetPrivate::deleteSysExtra() @@ -1180,18 +1175,6 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows) if (id->IsFocused()) // Avoid unnecessry calls to FocusChanged() id->setFocusSafely(false); id->ControlEnv()->AppUi()->RemoveFromStack(id); - - // Hack to activate window under destroyed one. With this activation - // the next visible window will get keyboard focus - WId wid = CEikonEnv::Static()->AppUi()->TopFocusedControl(); - if (wid) { - QWidget *widget = QWidget::find(wid); - QApplication::setActiveWindow(widget); - if (widget) { - // Reset global window title for focusing window - widget->d_func()->setWindowTitle_sys(widget->windowTitle()); - } - } } } diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 8226797..1b8f413 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -949,6 +949,8 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) return; QWidgetBackingStore *wbs = x->backingStore; + if (!wbs) + return; static int accelEnv = -1; if (accelEnv == -1) { diff --git a/src/gui/painting/qpaintdevice.qdoc b/src/gui/painting/qpaintdevice.qdoc index ac1c3de..e923e90 100644 --- a/src/gui/painting/qpaintdevice.qdoc +++ b/src/gui/painting/qpaintdevice.qdoc @@ -82,7 +82,7 @@ horizontal and vertical resolution of the device in dots per inch. The physicalDpiX() and physicalDpiY() functions also return the resolution of the device in dots per inch, but note that if - the logical and vertical resolution differ, the corresponding + the logical and physical resolution differ, the corresponding QPaintEngine must handle the mapping. Finally, the colorCount() function returns the number of different colors available for the paint device. diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 3f33319..4a72434 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3240,7 +3240,8 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte drawCached = false; // don't try to cache huge fonts - if (ti.fontEngine->fontDef.pixelSize * qSqrt(s->matrix.determinant()) >= 64) + const qreal pixelSize = ti.fontEngine->fontDef.pixelSize; + if (pixelSize * pixelSize * qAbs(s->matrix.determinant()) >= 64 * 64) drawCached = false; // ### Remove the TestFontEngine and Box engine crap, in these diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 7d1c109..9a0e319 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -56,6 +56,20 @@ QT_BEGIN_NAMESPACE * class QVectorPath * */ +QVectorPath::~QVectorPath() +{ + if (m_hints & ShouldUseCacheHint) { + CacheEntry *e = m_cache; + while (e) { + if (e->data) + e->cleanup(e->engine, e->data); + CacheEntry *n = e->next; + delete e; + e = n; + } + } +} + QRectF QVectorPath::controlPointRect() const { @@ -94,7 +108,7 @@ QRectF QVectorPath::controlPointRect() const QVectorPath::CacheEntry *QVectorPath::addCacheData(QPaintEngineEx *engine, void *data, - qvectorpath_cache_cleanup cleanup) { + qvectorpath_cache_cleanup cleanup) const{ Q_ASSERT(!lookupCacheData(engine)); if ((m_hints & IsCachedHint) == 0) { m_cache = 0; diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 48629d1..66bf4f7 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -284,7 +284,7 @@ bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev) // Update matrix. if (q->d_ptr->state->WxF) { - q->d_ptr->state->redirectionMatrix *= q->d_ptr->state->worldMatrix; + q->d_ptr->state->redirectionMatrix = q->d_ptr->state->matrix; q->d_ptr->state->redirectionMatrix.translate(-offset.x(), -offset.y()); q->d_ptr->state->worldMatrix = QTransform(); q->d_ptr->state->WxF = false; @@ -5886,7 +5886,12 @@ void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption Draws the text item \a ti at position \a p. */ -/*! \internal +/*! + \fn void QPainter::drawTextItem(const QPointF &p, const QTextItem &ti) + + \internal + \since 4.1 + Draws the text item \a ti at position \a p. This method ignores the painters background mode and @@ -5899,34 +5904,57 @@ void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption ignored aswell. You'll need to pass in the correct flags to get underlining and strikeout. */ -static QPainterPath generateWavyPath(qreal minWidth, qreal maxRadius, QPaintDevice *device) + +static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen) { - extern int qt_defaultDpi(); + const qreal radiusBase = qMax(qreal(1), maxRadius); + + QString key = QLatin1String("WaveUnderline-"); + key += pen.color().name(); + key += QLatin1Char('-'); + key += QString::number(radiusBase); + + QPixmap pixmap; + if (QPixmapCache::find(key, pixmap)) + return pixmap; + + const qreal halfPeriod = qMax(qreal(2), qreal(radiusBase * 1.61803399)); // the golden ratio + const int width = qCeil(100 / (2 * halfPeriod)) * (2 * halfPeriod); + const int radius = qFloor(radiusBase); + QPainterPath path; - bool up = true; - const qreal radius = qMax(qreal(.5), qMin(qreal(1.25 * device->logicalDpiY() / qt_defaultDpi()), maxRadius)); - qreal xs, ys; - int i = 0; - path.moveTo(0, radius); - do { - xs = i*(2*radius); - ys = 0; + qreal xs = 0; + qreal ys = radius; - qreal remaining = minWidth - xs; - qreal angle = 180; + while (xs < width) { + xs += halfPeriod; + ys = -ys; + path.quadTo(xs - halfPeriod / 2, ys, xs, 0); + } - // cut-off at the last arc segment - if (remaining < 2 * radius) - angle = 180 * remaining / (2 * radius); + pixmap = QPixmap(width, radius * 2); + pixmap.fill(Qt::transparent); + { + QPen wavePen = pen; + wavePen.setCapStyle(Qt::SquareCap); + + // This is to protect against making the line too fat, as happens on Mac OS X + // due to it having a rather thick width for the regular underline. + const qreal maxPenWidth = .8 * radius; + if (wavePen.widthF() > maxPenWidth) + wavePen.setWidth(maxPenWidth); - path.arcTo(xs, ys, 2*radius, 2*radius, 180, up ? angle : -angle); + QPainter imgPainter(&pixmap); + imgPainter.setPen(wavePen); + imgPainter.setRenderHint(QPainter::Antialiasing); + imgPainter.translate(0, radius); + imgPainter.drawPath(path); + } - up = !up; - ++i; - } while (xs + 2*radius < minWidth); + QPixmapCache::insert(key, pixmap); - return path; + return pixmap; } static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QTextItemInt &ti) @@ -5947,9 +5975,11 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const pen.setCapStyle(Qt::FlatCap); QLineF line(pos.x(), pos.y(), pos.x() + ti.width.toReal(), pos.y()); + + const qreal underlineOffset = fe->underlinePosition().toReal(); // deliberately ceil the offset to avoid the underline coming too close to // the text above it. - const qreal underlinePos = pos.y() + qCeil(fe->underlinePosition().toReal()); + const qreal underlinePos = pos.y() + qCeil(underlineOffset); if (underlineStyle == QTextCharFormat::SpellCheckUnderline) { underlineStyle = QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle)); @@ -5957,16 +5987,18 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const if (underlineStyle == QTextCharFormat::WaveUnderline) { painter->save(); - painter->setRenderHint(QPainter::Antialiasing); - painter->translate(pos.x(), underlinePos); + painter->translate(0, pos.y() + 1); QColor uc = ti.charFormat.underlineColor(); if (uc.isValid()) - painter->setPen(uc); + pen.setColor(uc); - painter->drawPath(generateWavyPath(ti.width.toReal(), - fe->underlinePosition().toReal(), - painter->device())); + // Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms + const QPixmap wave = generateWavyPixmap(qMax(underlineOffset, pen.widthF()), pen); + const int descent = (int) ti.descent.toReal(); + + painter->setBrushOrigin(painter->brushOrigin().x(), 0); + painter->fillRect(pos.x(), 0, qCeil(ti.width.toReal()), qMin(wave.height(), descent), wave); painter->restore(); } else if (underlineStyle != QTextCharFormat::NoUnderline) { QLineF underLine(line.x1(), underlinePos, line.x2(), underlinePos); @@ -6001,10 +6033,6 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const painter->setBrush(oldBrush); } -/*! - \internal - \since 4.1 -*/ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti) { #ifdef QT_DEBUG_DRAW @@ -7602,7 +7630,7 @@ start_lengthVariant: // in the paint engines when drawing on floating point offsets const qreal scale = painter->transform().m22(); if (scale != 0) - yoff = qRound(yoff * scale) / scale; + yoff = -qRound(-yoff * scale) / scale; } } } diff --git a/src/gui/painting/qprintengine_pdf.cpp b/src/gui/painting/qprintengine_pdf.cpp index 4cccc91..3d82edf 100644 --- a/src/gui/painting/qprintengine_pdf.cpp +++ b/src/gui/painting/qprintengine_pdf.cpp @@ -206,7 +206,7 @@ void QPdfEngine::drawImage(const QRectF &rectangle, const QImage &image, const Q QRect sourceRect = sr.toRect(); QImage im = sourceRect != image.rect() ? image.copy(sourceRect) : image; bool bitmap = true; - const int object = d->addImage(image, &bitmap, im.cacheKey()); + const int object = d->addImage(im, &bitmap, im.cacheKey()); if (object < 0) return; diff --git a/src/gui/painting/qvectorpath_p.h b/src/gui/painting/qvectorpath_p.h index ec27970..5eaddf4 100644 --- a/src/gui/painting/qvectorpath_p.h +++ b/src/gui/painting/qvectorpath_p.h @@ -68,7 +68,7 @@ QT_MODULE(Gui) class QPaintEngineEx; -typedef void (*qvectorpath_cache_cleanup)(void *data); +typedef void (*qvectorpath_cache_cleanup)(QPaintEngineEx *engine, void *data); struct QRealRect { qreal x1, y1, x2, y2; @@ -118,6 +118,8 @@ public: { } + ~QVectorPath(); + QRectF controlPointRect() const; inline Hint shape() const { return (Hint) (m_hints & ShapeMask); } @@ -128,6 +130,7 @@ public: inline bool hasImplicitClose() const { return m_hints & ImplicitClose; } inline bool hasWindingFill() const { return m_hints & WindingFill; } + inline void makeCacheable() const { m_hints |= ShouldUseCacheHint; m_cache = 0; } inline uint hints() const { return m_hints; } inline const QPainterPath::ElementType *elements() const { return m_elements; } @@ -146,9 +149,9 @@ public: CacheEntry *next; }; - CacheEntry *addCacheData(QPaintEngineEx *engine, void *data, qvectorpath_cache_cleanup cleanup); + CacheEntry *addCacheData(QPaintEngineEx *engine, void *data, qvectorpath_cache_cleanup cleanup) const; inline CacheEntry *lookupCacheData(QPaintEngineEx *engine) const { - Q_ASSERT(m_hints & IsCachedHint); + Q_ASSERT(m_hints & ShouldUseCacheHint); CacheEntry *e = m_cache; while (e) { if (e->engine == engine) @@ -162,14 +165,14 @@ public: private: Q_DISABLE_COPY(QVectorPath) - CacheEntry *m_cache; - const QPainterPath::ElementType *m_elements; const qreal *m_points; const int m_count; mutable uint m_hints; mutable QRealRect m_cp_rect; + + mutable CacheEntry *m_cache; }; Q_GUI_EXPORT const QVectorPath &qtVectorPathForPath(const QPainterPath &path); diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index 4c9541b..5028e5f 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -770,8 +770,6 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::Highlight)); else if (vopt->features & QStyleOptionViewItemV2::Alternate) p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::AlternateBase)); - else if (!(vopt->state & QStyle::State_Enabled)) - p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::Base)); } break; case PE_PanelItemViewItem: diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 5566cc6..e10bb41 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -645,6 +645,15 @@ int QGtkStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidg return buttonsHaveIcons; } + case SH_UnderlineShortcut: { + gboolean underlineShortcut = true; + if (!d->gtk_check_version(2, 12, 0)) { + GtkSettings *settings = d->gtk_settings_get_default(); + g_object_get(settings, "gtk-enable-mnemonics", &underlineShortcut, NULL); + } + return underlineShortcut; + } + default: return QCleanlooksStyle::styleHint(hint, option, widget, returnData); } @@ -1368,7 +1377,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom else { gtkCachedPainter.paintFlatBox(gtkEntry, "entry_bg", contentRect, option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE, - GTK_SHADOW_NONE, style, entryPath + QString::number(focus)); + GTK_SHADOW_NONE, gtkCombo->style, entryPath + QString::number(focus)); } gtkCachedPainter.paintShadow(gtkEntry, comboBox->editable ? "entry" : "frame", frameRect, frameState, @@ -3366,12 +3375,28 @@ QIcon QGtkStyle::standardIconImplementation(StandardPixmap standardIcon, /*! \reimp */ QRect QGtkStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const { + Q_D(const QGtkStyle); + QRect r = QCleanlooksStyle::subElementRect(element, option, widget); switch (element) { case SE_ProgressBarLabel: case SE_ProgressBarContents: case SE_ProgressBarGroove: return option->rect; + case SE_PushButtonContents: + if (!d->gtk_check_version(2, 10, 0)) { + GtkWidget *gtkButton = d->gtkWidget(QLS("GtkButton")); + GtkBorder *border = 0; + d->gtk_widget_style_get(gtkButton, "inner-border", &border, NULL); + if (border) { + r = option->rect.adjusted(border->left, border->top, -border->right, -border->bottom); + d->gtk_border_free(border); + } else { + r = option->rect.adjusted(1, 1, -1, -1); + } + r = visualRect(option->direction, option->rect, r); + } + break; default: break; } diff --git a/src/gui/styles/qgtkstyle_p.cpp b/src/gui/styles/qgtkstyle_p.cpp index 5f4ebae..a644a5b 100644 --- a/src/gui/styles/qgtkstyle_p.cpp +++ b/src/gui/styles/qgtkstyle_p.cpp @@ -158,6 +158,7 @@ Ptr_gtk_window_get_type QGtkStylePrivate::gtk_window_get_type = 0; Ptr_gtk_widget_get_type QGtkStylePrivate::gtk_widget_get_type = 0; Ptr_gtk_rc_get_style_by_paths QGtkStylePrivate::gtk_rc_get_style_by_paths = 0; Ptr_gtk_check_version QGtkStylePrivate::gtk_check_version = 0; +Ptr_gtk_border_free QGtkStylePrivate::gtk_border_free = 0; Ptr_pango_font_description_get_size QGtkStylePrivate::pango_font_description_get_size = 0; Ptr_pango_font_description_get_weight QGtkStylePrivate::pango_font_description_get_weight = 0; @@ -202,8 +203,12 @@ Ptr_gnome_vfs_init QGtkStylePrivate::gnome_vfs_init = 0; typedef int (*x11ErrorHandler)(Display*, XErrorEvent*); +QT_END_NAMESPACE + Q_DECLARE_METATYPE(QGtkStylePrivate*); +QT_BEGIN_NAMESPACE + static void gtkStyleSetCallback(GtkWidget*) { qRegisterMetaType<QGtkStylePrivate *>(); @@ -412,6 +417,7 @@ void QGtkStylePrivate::resolveGtk() const gtk_widget_get_type =(Ptr_gtk_widget_get_type)libgtk.resolve("gtk_widget_get_type"); gtk_rc_get_style_by_paths =(Ptr_gtk_rc_get_style_by_paths)libgtk.resolve("gtk_rc_get_style_by_paths"); gtk_check_version =(Ptr_gtk_check_version)libgtk.resolve("gtk_check_version"); + gtk_border_free =(Ptr_gtk_border_free)libgtk.resolve("gtk_border_free"); pango_font_description_get_size = (Ptr_pango_font_description_get_size)libgtk.resolve("pango_font_description_get_size"); pango_font_description_get_weight = (Ptr_pango_font_description_get_weight)libgtk.resolve("pango_font_description_get_weight"); pango_font_description_get_family = (Ptr_pango_font_description_get_family)libgtk.resolve("pango_font_description_get_family"); diff --git a/src/gui/styles/qgtkstyle_p.h b/src/gui/styles/qgtkstyle_p.h index f6ab8a3..c27308f 100644 --- a/src/gui/styles/qgtkstyle_p.h +++ b/src/gui/styles/qgtkstyle_p.h @@ -176,6 +176,7 @@ typedef GtkWidget* (*Ptr_gtk_file_chooser_dialog_new)(const gchar *title, typedef void (*Ptr_gtk_file_chooser_set_current_name) (GtkFileChooser *, const gchar *); typedef gboolean (*Ptr_gtk_file_chooser_set_filename) (GtkFileChooser *chooser, const gchar *name); typedef gint (*Ptr_gtk_dialog_run) (GtkDialog*); +typedef void (*Ptr_gtk_border_free)(GtkBorder *); typedef guchar* (*Ptr_gdk_pixbuf_get_pixels) (const GdkPixbuf *pixbuf); typedef int (*Ptr_gdk_pixbuf_get_width) (const GdkPixbuf *pixbuf); @@ -371,6 +372,7 @@ public: static Ptr_gtk_widget_get_type gtk_widget_get_type; static Ptr_gtk_rc_get_style_by_paths gtk_rc_get_style_by_paths; static Ptr_gtk_check_version gtk_check_version; + static Ptr_gtk_border_free gtk_border_free; static Ptr_pango_font_description_get_size pango_font_description_get_size; static Ptr_pango_font_description_get_weight pango_font_description_get_weight; diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm index 38c3feb..4075cf7 100644 --- a/src/gui/styles/qmacstyle_mac.mm +++ b/src/gui/styles/qmacstyle_mac.mm @@ -2155,9 +2155,9 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW wdi.titleWidth = tb->rect.width(); QCFType<HIShapeRef> region; HIRect hirect = qt_hirectForQRect(tb->rect); - if (hirect.size.width == -1) + if (hirect.size.width <= 0) hirect.size.width = 100; - if (hirect.size.height == -1) + if (hirect.size.height <= 0) hirect.size.height = 30; HIThemeGetWindowShape(&hirect, &wdi, kWindowTitleBarRgn, ®ion); @@ -4843,9 +4843,11 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex uint sc = SC_TitleBarMinButton; ThemeTitleBarWidget tbw = kThemeWidgetCollapseBox; bool active = titlebar->state & State_Active; - int border = 2; - titleBarRect.origin.x += border; - titleBarRect.origin.y -= border; + if (qMacVersion() < QSysInfo::MV_10_6) { + int border = 2; + titleBarRect.origin.x += border; + titleBarRect.origin.y -= border; + } while (sc <= SC_TitleBarCloseButton) { if (sc & titlebar->subControls) { diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index b5c0d4f..be4f15a 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -144,7 +144,7 @@ const struct QS60StylePrivate::frameElementCenter QS60StylePrivate::m_frameEleme {SE_ToolBarButtonPressed, QS60StyleEnums::SP_QsnFrSctrlButtonCenterPressed}, {SE_PanelBackground, QS60StyleEnums::SP_QsnFrSetOptCenter}, {SE_ButtonInactive, QS60StyleEnums::SP_QsnFrButtonCenterInactive}, - {SE_Editor, QS60StyleEnums::SP_QsnFrNotepadCenter}, + {SE_Editor, QS60StyleEnums::SP_QsnFrInputCenter}, }; static const int frameElementsCount = @@ -454,14 +454,6 @@ void QS60StylePrivate::setThemePalette(QApplication *app) const Q_UNUSED(app) QPalette widgetPalette = QPalette(Qt::white); setThemePalette(&widgetPalette); - QApplication::setPalette(widgetPalette); //calling QApplication::setPalette clears palette hash - setThemePaletteHash(&widgetPalette); - storeThemePalette(&widgetPalette); -} - -void QS60StylePrivate::setThemePalette(QStyleOption *option) const -{ - setThemePalette(&option->palette); } QPalette* QS60StylePrivate::themePalette() @@ -638,16 +630,16 @@ void QS60StylePrivate::setThemePalette(QWidget *widget) const { if(!widget) return; - QPalette widgetPalette = QApplication::palette(widget); //header view and its viewport need to be set 100% transparent button color, since drawing code will //draw transparent theme graphics to table column and row headers. if (qobject_cast<QHeaderView *>(widget)){ + QPalette widgetPalette = QApplication::palette(widget); widgetPalette.setColor(QPalette::Active, QPalette::ButtonText, s60Color(QS60StyleEnums::CL_QsnTextColors, 23, 0)); QHeaderView* header = qobject_cast<QHeaderView *>(widget); widgetPalette.setColor(QPalette::Button, Qt::transparent ); - if ( header->viewport() ) + if (header->viewport()) header->viewport()->setPalette(widgetPalette); QApplication::setPalette(widgetPalette, "QHeaderView"); } @@ -662,7 +654,7 @@ void QS60StylePrivate::setThemePalette(QPalette *palette) const palette->setColor(QPalette::WindowText, s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0)); palette->setColor(QPalette::ButtonText, - s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0)); + s60Color(QS60StyleEnums::CL_QsnTextColors, 20, 0)); palette->setColor(QPalette::Text, s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0)); palette->setColor(QPalette::ToolTipText, @@ -690,6 +682,10 @@ void QS60StylePrivate::setThemePalette(QPalette *palette) const palette->setColor(QPalette::Midlight, palette->color(QPalette::Button).lighter(125)); palette->setColor(QPalette::Mid, palette->color(QPalette::Button).darker(150)); palette->setColor(QPalette::Shadow, Qt::black); + + QApplication::setPalette(*palette); //calling QApplication::setPalette clears palette hash + setThemePaletteHash(palette); + storeThemePalette(palette); } void QS60StylePrivate::deleteThemePalette() @@ -757,13 +753,15 @@ void QS60StylePrivate::setThemePaletteHash(QPalette *palette) const QApplication::setPalette(widgetPalette, "QTableView"); widgetPalette = *palette; + widgetPalette.setColor(QPalette::Text, + s60Color(QS60StyleEnums::CL_QsnTextColors, 27, 0)); widgetPalette.setColor(QPalette::HighlightedText, s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0)); QApplication::setPalette(widgetPalette, "QLineEdit"); widgetPalette = *palette; widgetPalette.setColor(QPalette::Text, - s60Color(QS60StyleEnums::CL_QsnTextColors, 34, 0)); + s60Color(QS60StyleEnums::CL_QsnTextColors, 27, 0)); widgetPalette.setColor(QPalette::HighlightedText, s60Color(QS60StyleEnums::CL_QsnTextColors, 24, 0)); QApplication::setPalette(widgetPalette, "QTextEdit"); @@ -810,7 +808,7 @@ QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlag case QS60StyleEnums::SP_QgnGrafTabActiveL: //Returned QSize for tabs must not be square, but narrow rectangle with width:height //ratio of 1:2 for horizontal tab bars (and 2:1 for vertical ones). - result.setWidth(10); + result.setWidth(result.height()>>1); break; case QS60StyleEnums::SP_QgnIndiSliderEdit: result.scale(pixelMetric(QStyle::PM_SliderLength), @@ -868,7 +866,7 @@ QSize QS60StylePrivate::partSize(QS60StyleEnums::SkinParts part, SkinElementFlag return result; } -bool QS60StylePrivate::canDrawThemeBackground(const QBrush &backgroundBrush) +bool QS60StylePrivate::canDrawThemeBackground(const QBrush &backgroundBrush) { //If brush is not changed from style's default values, draw theme graphics. return (backgroundBrush.color() == Qt::transparent || @@ -1786,7 +1784,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, if (qobject_cast<const QAbstractButton *>(widget)) { //Make cornerButton slightly smaller so that it is not on top of table border graphic. QStyleOptionHeader subopt = *header; - const int borderTweak = + const int borderTweak = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth)>>1; if (subopt.direction == Qt::LeftToRight) subopt.rect.adjust(borderTweak, borderTweak, 0, -borderTweak); @@ -1879,7 +1877,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, adjustableFlags = (adjustableFlags | QS60StylePrivate::SF_PointWest); } else { const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); - if (option->direction == Qt::LeftToRight) + if (option->direction == Qt::LeftToRight) headerRect.adjust(-2*frameWidth, 0, 0, 0); else headerRect.adjust(0, 0, 2*frameWidth, 0); @@ -2025,7 +2023,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti buttonRect.setHeight((int)(buttonRect.height() * scaler)); // move the rect up for half of the new height-gain const int newY = (buttonRect.bottomRight().y() - option->rect.bottomRight().y()) >> 1 ; - buttonRect.adjust(0,-newY,0,-newY); + buttonRect.adjust(0, -newY, -1, -newY); painter->save(); QColor themeColor = d->s60Color(QS60StyleEnums::CL_QsnTextColors, 6, option); @@ -2347,10 +2345,10 @@ int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w int retValue = -1; switch (sh) { case SH_Table_GridLineColor: - retValue = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors,2,0).rgb(); + retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors,2,0).rgba()); break; case SH_GroupBox_TextLabelColor: - retValue = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors,6,0).rgb(); + retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors,6,0).rgba()); break; case SH_ScrollBar_ScrollWhenPointerLeavesControl: retValue = true; @@ -2406,10 +2404,9 @@ int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w retValue = QFormLayout::WrapLongRows; break; default: + retValue = QCommonStyle::styleHint(sh, opt, widget, hret); break; } - if (retValue == -1) - retValue = QCommonStyle::styleHint(sh, opt, widget, hret); return retValue; } @@ -2594,7 +2591,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple const int indicatorRect = pixelMetric(PM_MenuButtonIndicator) + 2*pixelMetric(PM_ButtonMargin); const int border = pixelMetric(PM_ButtonMargin) + pixelMetric(PM_DefaultFrameWidth); ret = toolButton->rect; - const bool popup = (toolButton->features & + const bool popup = (toolButton->features & (QStyleOptionToolButton::MenuButtonPopup | QStyleOptionToolButton::PopupDelay)) == QStyleOptionToolButton::MenuButtonPopup; switch (scontrol) { diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index ea86bb2..5ab2308 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -271,15 +271,6 @@ public: SP_QsnFrButtonSideLInactive, SP_QsnFrButtonSideRInactive, SP_QsnFrButtonCenterInactive, - SP_QsnFrNotepadCornerTl, - SP_QsnFrNotepadCornerTr, - SP_QsnFrNotepadCornerBl, - SP_QsnFrNotepadCornerBr, - SP_QsnFrNotepadSideT, - SP_QsnFrNotepadSideB, - SP_QsnFrNotepadSideL, - SP_QsnFrNotepadSideR, - SP_QsnFrNotepadCenter }; enum ColorLists { @@ -418,8 +409,6 @@ public: //set theme palette for application void setThemePalette(QApplication *application) const; - //set theme palette for style option - void setThemePalette(QStyleOption *option) const; //access to theme palette static QPalette* themePalette(); diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index a8dbf8d..48b8fad 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -1324,9 +1324,9 @@ QS60Style::QS60Style() void QS60StylePrivate::handleDynamicLayoutVariantSwitch() { clearCaches(QS60StylePrivate::CC_LayoutChange); + setBackgroundTexture(qApp); setActiveLayout(); refreshUI(); - setBackgroundTexture(qApp); foreach (QWidget *widget, QApplication::allWidgets()) widget->ensurePolished(); } diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp index 30f2f35..0a59d6d 100644 --- a/src/gui/styles/qwindowsstyle.cpp +++ b/src/gui/styles/qwindowsstyle.cpp @@ -213,10 +213,12 @@ bool QWindowsStyle::eventFilter(QObject *o, QEvent *e) case QEvent::StyleChange: case QEvent::Show: if (QProgressBar *bar = qobject_cast<QProgressBar *>(o)) { - d->bars << bar; - if (d->bars.size() == 1) { - Q_ASSERT(d->animationFps> 0); - d->animateTimer = startTimer(1000 / d->animationFps); + if (!d->bars.contains(bar)) { + d->bars << bar; + if (d->bars.size() == 1) { + Q_ASSERT(d->animationFps> 0); + d->animateTimer = startTimer(1000 / d->animationFps); + } } } break; diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp index fe7f5d7..50be342 100644 --- a/src/gui/styles/qwindowsxpstyle.cpp +++ b/src/gui/styles/qwindowsxpstyle.cpp @@ -623,8 +623,7 @@ void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData) painter->save(); - QMatrix m = painter->matrix(); - bool complexXForm = m.m11() != 1.0 || m.m22() != 1.0 || m.m12() != 0.0 || m.m21() != 0.0; + bool complexXForm = painter->deviceTransform().type() > QTransform::TxTranslate; bool translucentToplevel = false; QPaintDevice *pdev = painter->device(); @@ -3780,12 +3779,19 @@ int QWindowsXPStyle::styleHint(StyleHint hint, const QStyleOption *option, const QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(returnData); const QStyleOptionTitleBar *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(option); if (mask && titlebar) { + // Note certain themes will not return the whole window frame but only the titlebar part when + // queried This function needs to return the entire window mask, hence we will only fetch the mask for the + // titlebar itself and add the remaining part of the window rect at the bottom. + int tbHeight = proxy()->pixelMetric(PM_TitleBarHeight, option, widget); + QRect titleBarRect = option->rect; + titleBarRect.setHeight(tbHeight); XPThemeData themeData; if (titlebar->titleBarState & Qt::WindowMinimized) { - themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_MINCAPTION, CS_ACTIVE, option->rect); + themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_MINCAPTION, CS_ACTIVE, titleBarRect); } else - themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_CAPTION, CS_ACTIVE, option->rect); - mask->region = d->region(themeData); + themeData = XPThemeData(widget, 0, QLatin1String("WINDOW"), WP_CAPTION, CS_ACTIVE, titleBarRect); + mask->region = d->region(themeData) + + QRect(0, tbHeight, option->rect.width(), option->rect.height() - tbHeight); } } break; diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp index 808dca6..bf8af92 100644 --- a/src/gui/text/qfontdatabase_s60.cpp +++ b/src/gui/text/qfontdatabase_s60.cpp @@ -51,6 +51,9 @@ #include <private/qcore_symbian_p.h> #if defined(QT_NO_FREETYPE) #include <OPENFONT.H> +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include <graphics/openfontrasterizer.h> // COpenFontRasterizer has moved to a new header file +#endif // SYMBIAN_ENABLE_SPLIT_HEADERS #endif QT_BEGIN_NAMESPACE diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 21b9cca..27fc3c1 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1370,8 +1370,8 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len, for (int i = 0; i < len; ++i) { bool surrogate = (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && i < len-1 && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000); - if (glyphs->glyphs[glyph_pos] == 0) { + if (glyphs->glyphs[glyph_pos] == 0 && str[i].category() != QChar::Separator_Line) { QGlyphLayoutInstance tmp = glyphs->instance(glyph_pos); for (int x = 1; x < engines.size(); ++x) { QFontEngine *engine = engines.at(x); diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp index 6c367ab..7ec8e31 100644 --- a/src/gui/text/qfontengine_win.cpp +++ b/src/gui/text/qfontengine_win.cpp @@ -485,61 +485,80 @@ glyph_metrics_t QFontEngineWin::boundingBox(const QGlyphLayout &glyphs) return glyph_metrics_t(0, -tm.tmAscent, w, tm.tmHeight, w, 0); } +#ifndef Q_WS_WINCE +bool QFontEngineWin::getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const +{ + Q_ASSERT(metrics != 0); + + HDC hdc = shared_dc(); + + GLYPHMETRICS gm; + DWORD res = 0; + MAT2 mat; + mat.eM11.value = mat.eM22.value = 1; + mat.eM11.fract = mat.eM22.fract = 0; + mat.eM21.value = mat.eM12.value = 0; + mat.eM21.fract = mat.eM12.fract = 0; + + if (t.type() > QTransform::TxTranslate) { + // We need to set the transform using the HDC's world + // matrix rather than using the MAT2 above, because the + // results provided when transforming via MAT2 does not + // match the glyphs that are drawn using a WorldTransform + XFORM xform; + xform.eM11 = t.m11(); + xform.eM12 = t.m12(); + xform.eM21 = t.m21(); + xform.eM22 = t.m22(); + xform.eDx = 0; + xform.eDy = 0; + SetGraphicsMode(hdc, GM_ADVANCED); + SetWorldTransform(hdc, &xform); + } + + uint format = GGO_METRICS; + if (ttf) + format |= GGO_GLYPH_INDEX; + res = GetGlyphOutline(hdc, glyph, format, &gm, 0, 0, &mat); + + if (t.type() > QTransform::TxTranslate) { + XFORM xform; + xform.eM11 = xform.eM22 = 1; + xform.eM12 = xform.eM21 = xform.eDx = xform.eDy = 0; + SetWorldTransform(hdc, &xform); + SetGraphicsMode(hdc, GM_COMPATIBLE); + } + + if (res != GDI_ERROR) { + *metrics = glyph_metrics_t(gm.gmptGlyphOrigin.x, -gm.gmptGlyphOrigin.y, + (int)gm.gmBlackBoxX, (int)gm.gmBlackBoxY, gm.gmCellIncX, gm.gmCellIncY); + return true; + } else { + return false; + } +} +#endif glyph_metrics_t QFontEngineWin::boundingBox(glyph_t glyph, const QTransform &t) { #ifndef Q_WS_WINCE - GLYPHMETRICS gm; - HDC hdc = shared_dc(); SelectObject(hdc, hfont); - if (!ttf) { + + glyph_metrics_t glyphMetrics; + bool success = getOutlineMetrics(glyph, t, &glyphMetrics); + + if (!ttf && !success) { + // Bitmap fonts wchar_t ch = glyph; ABCFLOAT abc; GetCharABCWidthsFloat(hdc, ch, ch, &abc); int width = qRound(abc.abcfB); - return glyph_metrics_t(0, -tm.tmAscent, width, tm.tmHeight, width, 0).transformed(t); - } else { - DWORD res = 0; - MAT2 mat; - mat.eM11.value = mat.eM22.value = 1; - mat.eM11.fract = mat.eM22.fract = 0; - mat.eM21.value = mat.eM12.value = 0; - mat.eM21.fract = mat.eM12.fract = 0; - - if (t.type() > QTransform::TxTranslate) { - // We need to set the transform using the HDC's world - // matrix rather than using the MAT2 above, because the - // results provided when transforming via MAT2 does not - // match the glyphs that are drawn using a WorldTransform - XFORM xform; - xform.eM11 = t.m11(); - xform.eM12 = t.m12(); - xform.eM21 = t.m21(); - xform.eM22 = t.m22(); - xform.eDx = 0; - xform.eDy = 0; - SetGraphicsMode(hdc, GM_ADVANCED); - SetWorldTransform(hdc, &xform); - } - - res = GetGlyphOutline(hdc, glyph, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, 0, &mat); - - if (t.type() > QTransform::TxTranslate) { - XFORM xform; - xform.eM11 = xform.eM22 = 1; - xform.eM12 = xform.eM21 = xform.eDx = xform.eDy = 0; - SetWorldTransform(hdc, &xform); - SetGraphicsMode(hdc, GM_COMPATIBLE); - } - - if (res != GDI_ERROR) { - return glyph_metrics_t(gm.gmptGlyphOrigin.x, -gm.gmptGlyphOrigin.y, - (int)gm.gmBlackBoxX, (int)gm.gmBlackBoxY, gm.gmCellIncX, gm.gmCellIncY); - } + return glyph_metrics_t(QFixed::fromReal(abc.abcfA), -tm.tmAscent, width, tm.tmHeight, width, 0).transformed(t); } - return glyph_metrics_t(); + + return glyphMetrics; #else HDC hdc = shared_dc(); HGDIOBJ oldFont = SelectObject(hdc, hfont); @@ -1135,7 +1154,7 @@ QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin { ExtTextOut(hdc, -gx + margin, -gy + margin, options, 0, (LPCWSTR) &glyph, 1, 0); } - + SelectObject(hdc, old_font); return ni; } diff --git a/src/gui/text/qfontengine_win_p.h b/src/gui/text/qfontengine_win_p.h index 9c4b0a9..bab71c9 100644 --- a/src/gui/text/qfontengine_win_p.h +++ b/src/gui/text/qfontengine_win_p.h @@ -109,6 +109,10 @@ public: int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs, bool mirrored) const; void getCMap(); +#ifndef Q_WS_WINCE + bool getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const; +#endif + QString _name; HFONT hfont; LOGFONT logfont; diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index be79773..f96f66b 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -1849,8 +1849,8 @@ void QTextControlPrivate::inputMethodEvent(QInputMethodEvent *e) || e->preeditString() != cursor.block().layout()->preeditAreaText() || e->replacementLength() > 0; + cursor.beginEditBlock(); if (isGettingInput) { - cursor.beginEditBlock(); cursor.removeSelectedText(); } @@ -1876,7 +1876,8 @@ void QTextControlPrivate::inputMethodEvent(QInputMethodEvent *e) QTextBlock block = cursor.block(); QTextLayout *layout = block.layout(); - layout->setPreeditArea(cursor.position() - block.position(), e->preeditString()); + if (isGettingInput) + layout->setPreeditArea(cursor.position() - block.position(), e->preeditString()); QList<QTextLayout::FormatRange> overrides; preeditCursor = e->preeditString().length(); hideCursor = false; @@ -1897,9 +1898,7 @@ void QTextControlPrivate::inputMethodEvent(QInputMethodEvent *e) } } layout->setAdditionalFormats(overrides); - - if (isGettingInput) - cursor.endEditBlock(); + cursor.endEditBlock(); } QVariant QTextControl::inputMethodQuery(Qt::InputMethodQuery property) const diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 048325c..523dd18 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -1767,6 +1767,12 @@ void QTextDocument::print(QPrinter *printer) const fromPage = qMax(1, fromPage); toPage = qMin(doc->pageCount(), toPage); + if (toPage < fromPage) { + // if the user entered a page range outside the actual number + // of printable pages, just return + return; + } + if (printer->pageOrder() == QPrinter::LastPageFirst) { int tmp = fromPage; fromPage = toPage; diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index 18e1ffc..b015198 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -870,6 +870,7 @@ int QTextDocumentPrivate::undoRedo(bool undo) undoEnabled = false; beginEditBlock(); + int editPos = -1; while (1) { if (undo) --undoState; @@ -881,11 +882,13 @@ int QTextDocumentPrivate::undoRedo(bool undo) remove(c.pos, c.length, (QTextUndoCommand::Operation)c.operation); PMDEBUG(" erase: from %d, length %d", c.pos, c.length); c.command = QTextUndoCommand::Removed; + editPos = c.pos; break; case QTextUndoCommand::Removed: PMDEBUG(" insert: format %d (from %d, length %d, strpos=%d)", c.format, c.pos, c.length, c.strPos); insert_string(c.pos, c.strPos, c.length, c.format, (QTextUndoCommand::Operation)c.operation); c.command = QTextUndoCommand::Inserted; + editPos = c.pos + c.length; break; case QTextUndoCommand::BlockInserted: case QTextUndoCommand::BlockAdded: @@ -895,6 +898,7 @@ int QTextDocumentPrivate::undoRedo(bool undo) c.command = QTextUndoCommand::BlockRemoved; else c.command = QTextUndoCommand::BlockDeleted; + editPos = c.pos; break; case QTextUndoCommand::BlockRemoved: case QTextUndoCommand::BlockDeleted: @@ -905,6 +909,7 @@ int QTextDocumentPrivate::undoRedo(bool undo) c.command = QTextUndoCommand::BlockInserted; else c.command = QTextUndoCommand::BlockAdded; + editPos = c.pos + 1; break; case QTextUndoCommand::CharFormatChanged: { resetBlockRevision = -1; // ## TODO @@ -915,6 +920,7 @@ int QTextDocumentPrivate::undoRedo(bool undo) int oldFormat = it.value()->format; setCharFormat(c.pos, c.length, formats.charFormat(c.format)); c.format = oldFormat; + editPos = c.pos + c.length; break; } case QTextUndoCommand::BlockFormatChanged: { @@ -937,6 +943,7 @@ int QTextDocumentPrivate::undoRedo(bool undo) group->blockFormatChanged(it); } documentChange(it.position(), it.length()); + editPos = -1; break; } case QTextUndoCommand::GroupFormatChange: { @@ -946,6 +953,7 @@ int QTextDocumentPrivate::undoRedo(bool undo) int oldFormat = formats.objectFormatIndex(c.objectIndex); changeObjectFormat(object, c.format); c.format = oldFormat; + editPos = -1; break; } case QTextUndoCommand::Custom: @@ -954,6 +962,7 @@ int QTextDocumentPrivate::undoRedo(bool undo) c.custom->undo(); else c.custom->redo(); + editPos = -1; break; default: Q_ASSERT(false); @@ -979,8 +988,7 @@ int QTextDocumentPrivate::undoRedo(bool undo) break; } undoEnabled = true; - int editPos = -1; - if (docChangeFrom >= 0) { + if (editPos < 0 && docChangeFrom >= 0) { editPos = qMin(docChangeFrom + docChangeLength, length() - 1); } endEditBlock(); diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp index 9b7e8de..1bd4dd6 100644 --- a/src/gui/text/qtextodfwriter.cpp +++ b/src/gui/text/qtextodfwriter.cpp @@ -447,18 +447,19 @@ void QTextOdfWriter::writeBlockFormat(QXmlStreamWriter &writer, QTextBlockFormat writer.writeStartElement(styleNS, QString::fromLatin1("paragraph-properties")); if (format.hasProperty(QTextFormat::BlockAlignment)) { + const Qt::Alignment alignment = format.alignment() & Qt::AlignHorizontal_Mask; QString value; - if (format.alignment() == Qt::AlignLeading) + if (alignment == Qt::AlignLeading) value = QString::fromLatin1("start"); - else if (format.alignment() == Qt::AlignTrailing) + else if (alignment == Qt::AlignTrailing) value = QString::fromLatin1("end"); - else if (format.alignment() == (Qt::AlignLeft | Qt::AlignAbsolute)) + else if (alignment == (Qt::AlignLeft | Qt::AlignAbsolute)) value = QString::fromLatin1("left"); - else if (format.alignment() == (Qt::AlignRight | Qt::AlignAbsolute)) + else if (alignment == (Qt::AlignRight | Qt::AlignAbsolute)) value = QString::fromLatin1("right"); - else if (format.alignment() == Qt::AlignHCenter) + else if (alignment == Qt::AlignHCenter) value = QString::fromLatin1("center"); - else if (format.alignment() == Qt::AlignJustify) + else if (alignment == Qt::AlignJustify) value = QString::fromLatin1("justify"); else qWarning() << "QTextOdfWriter: unsupported paragraph alignment; " << format.alignment(); diff --git a/src/gui/util/qdesktopservices_s60.cpp b/src/gui/util/qdesktopservices_s60.cpp index 1890d56..c6932de 100644 --- a/src/gui/util/qdesktopservices_s60.cpp +++ b/src/gui/util/qdesktopservices_s60.cpp @@ -41,7 +41,7 @@ // This flag changes the implementation to use S60 CDcoumentHandler // instead of apparch when opening the files -#undef USE_DOCUMENTHANDLER +#define USE_DOCUMENTHANDLER #include <qcoreapplication.h> #include <qdir.h> @@ -58,12 +58,14 @@ #include <rsendasmessage.h> // RSendAsMessage #ifdef Q_WS_S60 -# include <pathinfo.h> // PathInfo +# include <pathinfo.h> // PathInfo # ifdef USE_DOCUMENTHANDLER -# include <documenthandler.h> // CDocumentHandler +# include <documenthandler.h> // CDocumentHandler +# include <aknserverapp.h> # endif -#elif defined(USE_DOCUMENTHANDLER) -# error CDocumentHandler requires support for S60 +#else +# warning CDocumentHandler requires support for S60 +# undef USE_DOCUMENTHANDLER // Fallback to RApaLsSession based implementation #endif QT_BEGIN_NAMESPACE @@ -95,6 +97,42 @@ private: R* mPtr; }; +#ifdef USE_DOCUMENTHANDLER +class QS60DocumentHandler : public MAknServerAppExitObserver +{ +public: + QS60DocumentHandler() :docHandler(0) {} + + ~QS60DocumentHandler() { + delete docHandler; + } + + CDocumentHandler& documentHandler() { + // In case user calls openUrl twice subsequently, before the first embedded app is closed + // we use the same CDocumentHandler instance. Using same instance makes sure the first + // launched embedded app is closed and latter one gets embedded to our app. + // Using different instance would help only theoretically since user cannot interact with + // several embedded apps at the same time. + if(!docHandler) { + QT_TRAP_THROWING(docHandler = CDocumentHandler::NewL()); + docHandler->SetExitObserver(this); + } + return *docHandler; + } + +private: // From MAknServerAppExitObserver + void HandleServerAppExit(TInt /*aReason*/) { + delete docHandler; + docHandler = 0; + } + +private: + CDocumentHandler* docHandler; +}; +Q_GLOBAL_STATIC(QS60DocumentHandler, qt_s60_documenthandler); +#endif + + static void handleMailtoSchemeLX(const QUrl &url) { // this function has many intermingled leaves and throws. Qt and Symbian objects do not have @@ -264,21 +302,9 @@ static void openDocumentL(const TDesC& aUrl) CleanupStack::PopAndDestroy(); // appArcSession #else // This is an alternative way to launch app associated to MIME type - // CDocumentHandler would support opening apps in embedded mode, - // but our Qt application window group seems to always get switched on top of embedded one - // -> Cannot use menus etc of embedded app -> used - - CDocumentHandler* docHandler = CDocumentHandler::NewLC(); + // CDocumentHandler also supports opening apps in embedded mode. TDataType temp; - //Standalone file opening fails for some file-types at least in S60 3.1 emulator - //For example .txt file fails with KErrAlreadyInUse and music files with KERN-EXEC 0 - //Workaround is to use OpenFileEmbeddedL - //docHandler->OpenFileL(aUrl, temp); - - // Opening file with CDocumentHandler will leave if file does not exist - // Leave is trapped in openDocument and false returned to user. - docHandler->OpenFileEmbeddedL(aUrl, temp); - CleanupStack::PopAndDestroy(docHandler); + qt_s60_documenthandler()->documentHandler().OpenFileEmbeddedL(aUrl, temp); #endif } @@ -349,7 +375,7 @@ QString QDesktopServices::storageLocation(StandardLocation type) case DesktopLocation: qWarning("No desktop concept in Symbian OS"); // But lets still use some feasible default - path.Append(writableDataRoot()); + path.Append(writableDataRoot()); break; case DocumentsLocation: path.Append(writableDataRoot()); @@ -380,7 +406,7 @@ QString QDesktopServices::storageLocation(StandardLocation type) #endif break; case TempLocation: - return QDir::tempPath(); + return QDir::tempPath(); break; case HomeLocation: path.Append(writableDataRoot()); @@ -394,10 +420,10 @@ QString QDesktopServices::storageLocation(StandardLocation type) CEikonEnv::Static()->FsSession().PrivatePath(path); path.Insert(0, writableExeDrive().Name()); path.Append(KCacheSubDir); - break; + break; default: // Lets use feasible default - path.Append(writableDataRoot()); + path.Append(writableDataRoot()); break; } diff --git a/src/gui/util/qsystemtrayicon.cpp b/src/gui/util/qsystemtrayicon.cpp index c6ea00f..6f2b501 100644 --- a/src/gui/util/qsystemtrayicon.cpp +++ b/src/gui/util/qsystemtrayicon.cpp @@ -380,6 +380,9 @@ bool QSystemTrayIcon::supportsMessages() On Windows, the \a millisecondsTimeoutHint is usually ignored by the system when the application has focus. + On Mac OS X, the Growl notification system must be installed for this function to + display messages. + \sa show() supportsMessages() */ void QSystemTrayIcon::showMessage(const QString& title, const QString& msg, diff --git a/src/gui/util/qsystemtrayicon_mac.mm b/src/gui/util/qsystemtrayicon_mac.mm index b74ca85..93295a7 100644 --- a/src/gui/util/qsystemtrayicon_mac.mm +++ b/src/gui/util/qsystemtrayicon_mac.mm @@ -314,8 +314,22 @@ QT_END_NAMESPACE { Q_UNUSED(notification); down = NO; + + if( ![self icon]->icon().isNull() ) { +#ifndef QT_MAC_USE_COCOA + const short scale = GetMBarHeight()-4; +#else + CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; + const short scale = hgt - 4; +#endif + NSImage *nsimage = static_cast<NSImage *>(qt_mac_create_nsimage([self icon]->icon().pixmap(QSize(scale, scale)))); + [self setImage: nsimage]; + [nsimage release]; + } + if([self icon]->contextMenu()) [self icon]->contextMenu()->hide(); + [self setNeedsDisplay:YES]; } @@ -327,6 +341,20 @@ QT_END_NAMESPACE [self icon]->contextMenu()->hide(); [self setNeedsDisplay:YES]; +#ifndef QT_MAC_USE_COCOA + const short scale = GetMBarHeight()-4; +#else + CGFloat hgt = [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; + const short scale = hgt - 4; +#endif + + if( down && ![self icon]->icon().isNull() ) { + NSImage *nsaltimage = static_cast<NSImage *>(qt_mac_create_nsimage([self icon]->icon().pixmap(QSize(scale, scale), QIcon::Selected))); + [self setImage: nsaltimage]; + [nsaltimage release]; + } + + if (down) [parent triggerSelector:self]; else if ((clickCount%2)) diff --git a/src/gui/widgets/qabstractbutton.cpp b/src/gui/widgets/qabstractbutton.cpp index cb46791..8834373 100644 --- a/src/gui/widgets/qabstractbutton.cpp +++ b/src/gui/widgets/qabstractbutton.cpp @@ -165,7 +165,7 @@ QAbstractButtonPrivate::QAbstractButtonPrivate(QSizePolicy::ControlType type) shortcutId(0), #endif checkable(false), checked(false), autoRepeat(false), autoExclusive(false), - down(false), blockRefresh(false), + down(false), blockRefresh(false), pressed(false), #ifndef QT_NO_BUTTONGROUP group(0), #endif @@ -1090,6 +1090,7 @@ void QAbstractButton::mousePressEvent(QMouseEvent *e) } if (hitButton(e->pos())) { setDown(true); + d->pressed = true; repaint(); //flush paint event before invoking potentially expensive operation QApplication::flush(); d->emitPressed(); @@ -1103,6 +1104,8 @@ void QAbstractButton::mousePressEvent(QMouseEvent *e) void QAbstractButton::mouseReleaseEvent(QMouseEvent *e) { Q_D(QAbstractButton); + d->pressed = false; + if (e->button() != Qt::LeftButton) { e->ignore(); return; @@ -1127,7 +1130,7 @@ void QAbstractButton::mouseReleaseEvent(QMouseEvent *e) void QAbstractButton::mouseMoveEvent(QMouseEvent *e) { Q_D(QAbstractButton); - if (!(e->buttons() & Qt::LeftButton)) { + if (!(e->buttons() & Qt::LeftButton) || !d->pressed) { e->ignore(); return; } diff --git a/src/gui/widgets/qabstractbutton_p.h b/src/gui/widgets/qabstractbutton_p.h index be7c022..d86163b 100644 --- a/src/gui/widgets/qabstractbutton_p.h +++ b/src/gui/widgets/qabstractbutton_p.h @@ -77,6 +77,7 @@ public: uint autoExclusive :1; uint down :1; uint blockRefresh :1; + uint pressed : 1; #ifndef QT_NO_BUTTONGROUP QButtonGroup* group; diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index 35639b7..3cf4e94 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -294,7 +294,9 @@ void QAbstractScrollAreaPrivate::init() q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); layoutChildren(); +#ifndef Q_WS_MAC viewport->grabGesture(Qt::PanGesture); +#endif } #ifdef Q_WS_WIN @@ -543,7 +545,9 @@ void QAbstractScrollArea::setViewport(QWidget *widget) d->viewport->setParent(this); d->viewport->setFocusProxy(this); d->viewport->installEventFilter(d->viewportFilter.data()); +#ifndef Q_WS_MAC d->viewport->grabGesture(Qt::PanGesture); +#endif d->layoutChildren(); if (isVisible()) d->viewport->show(); diff --git a/src/gui/widgets/qdialogbuttonbox.cpp b/src/gui/widgets/qdialogbuttonbox.cpp index 2ee5751..f2ef941 100644 --- a/src/gui/widgets/qdialogbuttonbox.cpp +++ b/src/gui/widgets/qdialogbuttonbox.cpp @@ -46,6 +46,7 @@ #include <QtGui/qdialog.h> #include <QtGui/qapplication.h> #include <QtGui/private/qwidget_p.h> +#include <QtGui/qaction.h> #include "qdialogbuttonbox.h" @@ -259,6 +260,31 @@ static const int layouts[2][5][14] = } }; +class QDialogButtonEnabledProxy : public QObject +{ +public: + QDialogButtonEnabledProxy(QObject *parent, QWidget *src, QAction *trg) : QObject(parent), source(src), target(trg) + { + source->installEventFilter(this); + target->setEnabled(source->isEnabled()); + } + ~QDialogButtonEnabledProxy() + { + source->removeEventFilter(this); + } + bool eventFilter(QObject *object, QEvent *event) + { + if (object == source && event->type() == QEvent::EnabledChange) { + target->setEnabled(source->isEnabled()); + } + return false; + }; +private: + QWidget *source; + QAction *target; +}; + + class QDialogButtonBoxPrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QDialogButtonBox) @@ -548,7 +574,9 @@ void QDialogButtonBoxPrivate::addButton(QAbstractButton *button, QDialogButtonBo QObject::connect(button, SIGNAL(destroyed()), q, SLOT(_q_handleButtonDestroyed())); buttonLists[role].append(button); #ifdef QT_SOFTKEYS_ENABLED - softKeyActions.insert(button, createSoftKey(button, role)); + QAction *action = createSoftKey(button, role); + softKeyActions.insert(button, action); + new QDialogButtonEnabledProxy(action, button, action); #endif if (doLayout) layoutButtons(); @@ -1215,6 +1243,30 @@ bool QDialogButtonBox::event(QEvent *event) }else if (event->type() == QEvent::LanguageChange) { d->retranslateStrings(); } +#ifdef QT_SOFTKEYS_ENABLED + else if (event->type() == QEvent::ParentChange) { + QWidget *dialog = 0; + QWidget *p = this; + while (p && !p->isWindow()) { + p = p->parentWidget(); + if ((dialog = qobject_cast<QDialog *>(p))) + break; + } + + // If the parent changes, then move the softkeys + for (QHash<QAbstractButton *, QAction *>::const_iterator it = d->softKeyActions.constBegin(); + it != d->softKeyActions.constEnd(); ++it) { + QAction *current = it.value(); + QList<QWidget *> widgets = current->associatedWidgets(); + foreach (QWidget *w, widgets) + w->removeAction(current); + if (dialog) + dialog->addAction(current); + else + addAction(current); + } + } +#endif return QWidget::event(event); } diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index 07914b2..0a26a77 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -1167,7 +1167,8 @@ bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWid QDockAreaLayoutInfo *subinfo = item.subinfo; QLayoutItem *widgetItem = item.widgetItem; - QRect r = subinfo == 0 ? dockedGeometry(widgetItem->widget()) : subinfo->rect; + QPlaceHolderItem *placeHolderItem = item.placeHolderItem; + QRect r = subinfo == 0 ? widgetItem ? dockedGeometry(widgetItem->widget()) : placeHolderItem->topLevelRect : subinfo->rect; Qt::Orientation opposite = o == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal; #ifdef QT_NO_TABBAR @@ -1176,13 +1177,15 @@ bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWid QDockAreaLayoutInfo *new_info = new QDockAreaLayoutInfo(sep, dockPos, opposite, tabBarShape, mainWindow); + //item become a new top-level item.subinfo = new_info; item.widgetItem = 0; + item.placeHolderItem = 0; QDockAreaLayoutItem new_item = widgetItem == 0 ? QDockAreaLayoutItem(subinfo) - : QDockAreaLayoutItem(widgetItem); + : widgetItem ? QDockAreaLayoutItem(widgetItem) : QDockAreaLayoutItem(placeHolderItem); new_item.size = pick(opposite, r.size()); new_item.pos = pick(opposite, r.topLeft()); new_info->item_list.append(new_item); diff --git a/src/gui/widgets/qfontcombobox.cpp b/src/gui/widgets/qfontcombobox.cpp index d601f81..b976b94 100644 --- a/src/gui/widgets/qfontcombobox.cpp +++ b/src/gui/widgets/qfontcombobox.cpp @@ -269,9 +269,8 @@ void QFontComboBoxPrivate::_q_updateModel() void QFontComboBoxPrivate::_q_currentChanged(const QString &text) { Q_Q(QFontComboBox); - QFont newFont(text); - if (currentFont.family() != newFont.family()) { - currentFont = newFont; + if (currentFont.family() != text) { + currentFont.setFamily(text); emit q->currentFontChanged(currentFont); } } diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index 300a2ea..117c550 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -138,7 +138,12 @@ void QLineControl::copy(QClipboard::Mode mode) const */ void QLineControl::paste() { - insert(QApplication::clipboard()->text(QClipboard::Clipboard)); + QString clip = QApplication::clipboard()->text(QClipboard::Clipboard); + if (!clip.isEmpty() || hasSelectedText()) { + separate(); //make it a separate undo/redo command + insert(clip); + separate(); + } } #endif // !QT_NO_CLIPBOARD @@ -1581,16 +1586,16 @@ void QLineControl::processKeyEvent(QKeyEvent* event) } } #endif //QT_NO_CLIPBOARD - else if (event == QKeySequence::MoveToStartOfLine) { + else if (event == QKeySequence::MoveToStartOfLine || event == QKeySequence::MoveToStartOfBlock) { home(0); } - else if (event == QKeySequence::MoveToEndOfLine) { + else if (event == QKeySequence::MoveToEndOfLine || event == QKeySequence::MoveToEndOfBlock) { end(0); } - else if (event == QKeySequence::SelectStartOfLine) { + else if (event == QKeySequence::SelectStartOfLine || event == QKeySequence::SelectStartOfBlock) { home(1); } - else if (event == QKeySequence::SelectEndOfLine) { + else if (event == QKeySequence::SelectEndOfLine || event == QKeySequence::SelectEndOfBlock) { end(1); } else if (event == QKeySequence::MoveToNextChar) { @@ -1666,6 +1671,7 @@ void QLineControl::processKeyEvent(QKeyEvent* event) } #endif // QT_NO_SHORTCUT else { + bool handled = false; #ifdef Q_WS_MAC if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down) { Qt::KeyboardModifiers myModifiers = (event->modifiers() & ~Qt::KeypadModifier); @@ -1683,6 +1689,7 @@ void QLineControl::processKeyEvent(QKeyEvent* event) event->key() == Qt::Key_Up ? home(0) : end(0); } } + handled = true; } #endif if (event->modifiers() & Qt::ControlModifier) { @@ -1715,7 +1722,8 @@ void QLineControl::processKeyEvent(QKeyEvent* event) break; #endif default: - unknown = true; + if (!handled) + unknown = true; } } else { // ### check for *no* modifier switch (event->key()) { @@ -1748,7 +1756,8 @@ void QLineControl::processKeyEvent(QKeyEvent* event) #endif default: - unknown = true; + if (!handled) + unknown = true; } } } diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 3800224..2c1acdb 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -383,6 +383,38 @@ void QLineEdit::setText(const QString& text) d->control->setText(text); } +// ### Qt 4.7: remove this #if guard +#if (QT_VERSION >= 0x407000) || defined(Q_WS_MAEMO_5) +/*! + \since 4.7 + + \property QLineEdit::placeholderText + \brief the line edit's placeholder text + + Setting this property makes the line edit display a grayed-out + placeholder text as long as the text() is empty and the widget doesn't + have focus. + + By default, this property contains an empty string. + + \sa text() +*/ +QString QLineEdit::placeholderText() const +{ + Q_D(const QLineEdit); + return d->placeholderText; +} + +void QLineEdit::setPlaceholderText(const QString& placeholderText) +{ + Q_D(QLineEdit); + if (d->placeholderText != placeholderText) { + d->placeholderText = placeholderText; + if (!hasFocus()) + update(); + } +} +#endif /*! \property QLineEdit::displayText @@ -1411,6 +1443,8 @@ bool QLineEdit::event(QEvent * e) QTimer::singleShot(0, this, SLOT(_q_handleWindowActivate())); }else if(e->type() == QEvent::ShortcutOverride){ d->control->processEvent(e); + } else if (e->type() == QEvent::KeyRelease) { + d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime()); } #ifdef QT_KEYPAD_NAVIGATION @@ -1515,7 +1549,7 @@ void QLineEdit::mouseReleaseEvent(QMouseEvent* e) } #endif - if (!isReadOnly()) + if (!isReadOnly() && rect().contains(e->pos())) d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus); d->clickCausedFocus = 0; } @@ -1615,6 +1649,8 @@ void QLineEdit::keyPressEvent(QKeyEvent *event) } #endif d->control->processKeyEvent(event); + if (event->isAccepted()) + d->control->setCursorBlinkPeriod(0); } /*! @@ -1825,6 +1861,18 @@ void QLineEdit::paintEvent(QPaintEvent *) } QRect lineRect(r.x() + d->horizontalMargin, d->vscroll, r.width() - 2*d->horizontalMargin, fm.height()); + if (d->control->text().isEmpty()) { + if (!hasFocus() && !d->placeholderText.isEmpty()) { + QColor col = pal.text().color(); + col.setAlpha(128); + QPen oldpen = p.pen(); + p.setPen(col); + p.drawText(lineRect, va, d->placeholderText); + p.setPen(oldpen); + return; + } + } + int cix = qRound(d->control->cursorToX()); // horizontal scrolling. d->hscroll is the left indent from the beginning diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h index ac918c7..594e488 100644 --- a/src/gui/widgets/qlineedit.h +++ b/src/gui/widgets/qlineedit.h @@ -83,6 +83,10 @@ class Q_GUI_EXPORT QLineEdit : public QWidget Q_PROPERTY(bool undoAvailable READ isUndoAvailable) Q_PROPERTY(bool redoAvailable READ isRedoAvailable) Q_PROPERTY(bool acceptableInput READ hasAcceptableInput) +// ### Qt 4.7: remove this #if guard +#if (QT_VERSION >= 0x407000) || defined(Q_WS_MAEMO_5) + Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText) +#endif public: explicit QLineEdit(QWidget* parent=0); @@ -98,6 +102,12 @@ public: QString displayText() const; +// ### Qt 4.7: remove this #if guard +#if (QT_VERSION >= 0x407000) || defined(Q_WS_MAEMO_5) + QString placeholderText() const; + void setPlaceholderText(const QString &); +#endif + int maxLength() const; void setMaxLength(int); diff --git a/src/gui/widgets/qlineedit_p.cpp b/src/gui/widgets/qlineedit_p.cpp index d03c003..4437fef 100644 --- a/src/gui/widgets/qlineedit_p.cpp +++ b/src/gui/widgets/qlineedit_p.cpp @@ -103,12 +103,12 @@ void QLineEditPrivate::_q_handleWindowActivate() void QLineEditPrivate::_q_textEdited(const QString &text) { Q_Q(QLineEdit); + emit q->textEdited(text); #ifndef QT_NO_COMPLETER - if (control->completer() && - control->completer()->completionMode() != QCompleter::InlineCompletion) + if (control->completer() + && control->completer()->completionMode() != QCompleter::InlineCompletion) control->complete(-1); // update the popup on cut/paste/del #endif - emit q->textEdited(text); } void QLineEditPrivate::_q_cursorPositionChanged(int from, int to) diff --git a/src/gui/widgets/qlineedit_p.h b/src/gui/widgets/qlineedit_p.h index 244d2be..dc648e8 100644 --- a/src/gui/widgets/qlineedit_p.h +++ b/src/gui/widgets/qlineedit_p.h @@ -142,6 +142,8 @@ public: int topTextMargin; int rightTextMargin; int bottomTextMargin; + + QString placeholderText; }; #endif // QT_NO_LINEEDIT diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 501e62f..557acfb 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -120,6 +120,7 @@ void QMainWindowPrivate::init() #ifdef QT_SOFTKEYS_ENABLED menuBarAction = QSoftKeyManager::createAction(QSoftKeyManager::MenuSoftKey, q); menuBarAction->setObjectName(QLatin1String("_q_menuSoftKeyAction")); + menuBarAction->setVisible(false); #endif } diff --git a/src/gui/widgets/qmdiarea.cpp b/src/gui/widgets/qmdiarea.cpp index b3288c3..f3dbe34 100644 --- a/src/gui/widgets/qmdiarea.cpp +++ b/src/gui/widgets/qmdiarea.cpp @@ -1947,8 +1947,10 @@ QMdiSubWindow *QMdiArea::addSubWindow(QWidget *widget, Qt::WindowFlags windowFla /*! Removes \a widget from the MDI area. The \a widget must be either a QMdiSubWindow or a widget that is the internal widget of - a subwindow. Note that the subwindow is not deleted by QMdiArea - and that its parent is set to 0. + a subwindow. Note \a widget is never actually deleted by QMdiArea. + If a QMdiSubWindow is passed in its parent is set to 0 and it is + removed, but if an internal widget is passed in the child widget + is set to 0 but the QMdiSubWindow is not removed. \sa addSubWindow() */ diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 761a060..ec9683d 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -65,6 +65,8 @@ #include "qmenubar_p.h" #include "qwidgetaction.h" #include "qtoolbutton.h" +#include "qpushbutton.h" +#include <private/qpushbutton_p.h> #include <private/qaction_p.h> #include <private/qsoftkeymanager_p.h> #ifdef QT3_SUPPORT @@ -229,7 +231,7 @@ void QMenuPrivate::updateActionRects() const Q_Q(const QMenu); if (!itemsDirty) return; - + q->ensurePolished(); //let's reinitialize the buffer @@ -292,7 +294,7 @@ void QMenuPrivate::updateActionRects() const if (!action->isVisible() || (collapsibleSeparators && previousWasSeparator && action->isSeparator())) continue; // we continue, this action will get an empty QRect - + previousWasSeparator = action->isSeparator(); //let the style modify the above size.. @@ -417,12 +419,7 @@ void QMenuPrivate::hideUpToMenuBar() hideMenu(m, fadeMenus); if (!fadeMenus) // Mac doesn't clear the action until after hidden. m->d_func()->setCurrentAction(0); - } else { -#ifndef QT_NO_TOOLBUTTON - if (qobject_cast<QToolButton*>(caused) == 0) -#endif - qWarning("QMenu: Internal error"); - caused = 0; + } else { caused = 0; } } #if defined(Q_WS_MAC) @@ -1139,7 +1136,7 @@ void QMenuPrivate::_q_actionTriggered() //we check the parent hierarchy QList< QPointer<QWidget> > list; for(QWidget *widget = q->parentWidget(); widget; ) { - if (qobject_cast<QMenu*>(widget) + if (qobject_cast<QMenu*>(widget) #ifndef QT_NO_MENUBAR || qobject_cast<QMenuBar*>(widget) #endif @@ -1306,7 +1303,7 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) the addAction(), addActions() and insertAction() functions. An action is represented vertically and rendered by QStyle. In addition, actions can have a text label, an optional icon drawn on the very left side, - and shortcut key sequence such as "Ctrl+X". + and shortcut key sequence such as "Ctrl+X". The existing actions held by a menu can be found with actions(). @@ -1825,8 +1822,15 @@ void QMenu::popup(const QPoint &p, QAction *atAction) ensurePolished(); // Get the right font emit aboutToShow(); + const bool actionListChanged = d->itemsDirty; d->updateActionRects(); - QPoint pos = p; + QPoint pos; + QPushButton *causedButton = qobject_cast<QPushButton*>(d->causedPopup.widget); + if (actionListChanged && causedButton) + pos = QPushButtonPrivate::get(causedButton)->adjustedMenuPosition(); + else + pos = p; + QSize size = sizeHint(); QRect screen; #ifndef QT_NO_GRAPHICSVIEW @@ -1906,9 +1910,9 @@ void QMenu::popup(const QPoint &p, QAction *atAction) pos.setX(qMax(p.x()-size.width(), screen.right()-desktopFrame-size.width()+1)); } else { if (pos.x()+size.width()-1 > screen.right()-desktopFrame) - pos.setX(qMin(p.x()+size.width(), screen.right()-desktopFrame-size.width()+1)); + pos.setX(screen.right()-desktopFrame-size.width()+1); if (pos.x() < screen.left()+desktopFrame) - pos.setX(qMax(p.x(), screen.left() + desktopFrame)); + pos.setX(screen.left() + desktopFrame); } if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) { if(snapToMouse) @@ -2302,22 +2306,9 @@ void QMenu::mouseReleaseEvent(QMouseEvent *e) if (action->menu()) action->menu()->d_func()->setFirstActionActive(); else { -#if defined(Q_WS_WIN) && !defined(QT_NO_MENUBAR) +#if defined(Q_WS_WIN) //On Windows only context menus can be activated with the right button - bool isContextMenu = true; - const QWidget *cause = d->causedPopup.widget; - while (cause) { - //if the popup was caused by either QMenuBar or a QToolButton, it is not a context menu - if (qobject_cast<const QMenuBar *>(cause) || qobject_cast<const QToolButton *>(cause)) { - isContextMenu = false; - break; - } else if (const QMenu *menu = qobject_cast<const QMenu *>(cause)) { - cause = menu->d_func()->causedPopup.widget; - } else { - break; - } - } - if (e->button() == Qt::LeftButton || isContextMenu) + if (e->button() == Qt::LeftButton || d->topCausedWidget() == 0) #endif d->activateAction(action, QAction::Trigger); } diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm index 9510cc6..30bbd31 100644 --- a/src/gui/widgets/qmenu_mac.mm +++ b/src/gui/widgets/qmenu_mac.mm @@ -763,7 +763,9 @@ QMacMenuAction::~QMacMenuAction() { #ifdef QT_MAC_USE_COCOA [menu release]; - if (action) { + // Update the menu item if this action still owns it. For some items + // (like 'Quit') ownership will be transferred between all menu bars... + if (action && action.data() == reinterpret_cast<QAction *>([menuItem tag])) { QAction::MenuRole role = action->menuRole(); // Check if the item is owned by Qt, and should be hidden to keep it from causing // problems. Do it for everything but the quit menu item since that should always @@ -774,8 +776,8 @@ QMacMenuAction::~QMacMenuAction() && menuItem != [getMenuLoader() quitMenuItem]) { [menuItem setHidden:YES]; } + [menuItem setTag:nil]; } - [menuItem setTag:nil]; [menuItem release]; #endif } diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h index 5757885..93017f5 100644 --- a/src/gui/widgets/qmenu_p.h +++ b/src/gui/widgets/qmenu_p.h @@ -182,6 +182,7 @@ public: } void init(); + static QMenuPrivate *get(QMenu *m) { return m->d_func(); } int scrollerHeight() const; //item calculations diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index 377b39a..599f15b 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -1489,7 +1489,8 @@ bool QMenuBar::event(QEvent *e) break; case QEvent::ShortcutOverride: { QKeyEvent *kev = static_cast<QKeyEvent*>(e); - if (kev->key() == Qt::Key_Escape) { + //we only filter out escape if there is a current action + if (kev->key() == Qt::Key_Escape && d->currentAction) { e->accept(); return true; } diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index c7759e8..89fe7b8 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -1802,6 +1802,9 @@ void QPlainTextEdit::paintEvent(QPaintEvent *e) QTextBlock block = firstVisibleBlock(); qreal maximumWidth = document()->documentLayout()->documentSize().width(); + // Set a brush origin so that the WaveUnderline knows where the wave started + painter.setBrushOrigin(offset); + // keep right margin clean from full-width selection int maxX = offset.x() + qMax((qreal)viewportRect.width(), maximumWidth) - document()->documentMargin(); @@ -1966,7 +1969,7 @@ void QPlainTextEdit::mouseReleaseEvent(QMouseEvent *e) d->ensureCursorVisible(); } - if (!isReadOnly()) + if (!isReadOnly() && rect().contains(e->pos())) d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus); d->clickCausedFocus = 0; } diff --git a/src/gui/widgets/qpushbutton.cpp b/src/gui/widgets/qpushbutton.cpp index eb34336..849bc43 100644 --- a/src/gui/widgets/qpushbutton.cpp +++ b/src/gui/widgets/qpushbutton.cpp @@ -63,6 +63,7 @@ #include "qaccessible.h" #endif +#include "private/qmenu_p.h" #include "private/qpushbutton_p.h" QT_BEGIN_NAMESPACE @@ -575,12 +576,33 @@ void QPushButtonPrivate::_q_popupPressed() return; menu->setNoReplayFor(q); + + QPoint menuPos = adjustedMenuPosition(); + + QPointer<QPushButton> guard(q); + QMenuPrivate::get(menu)->causedPopup.widget = guard; + + //Because of a delay in menu effects, we must keep track of the + //menu visibility to avoid flicker on button release + menuOpen = true; + menu->exec(menuPos); + if (guard) { + menuOpen = false; + q->setDown(false); + } +} + +QPoint QPushButtonPrivate::adjustedMenuPosition() +{ + Q_Q(QPushButton); + bool horizontal = true; #if !defined(QT_NO_TOOLBAR) QToolBar *tb = qobject_cast<QToolBar*>(parent); if (tb && tb->orientation() == Qt::Vertical) horizontal = false; #endif + QWidgetItem item(q); QRect rect = item.geometry(); rect.setRect(rect.x() - q->x(), rect.y() - q->y(), rect.width(), rect.height()); @@ -603,17 +625,10 @@ void QPushButtonPrivate::_q_popupPressed() else x -= menuSize.width(); } - QPointer<QPushButton> guard(q); - //Because of a delay in menu effects, we must keep track of the - //menu visibility to avoid flicker on button release - menuOpen = true; - menu->exec(QPoint(x, y)); - if (guard) { - menuOpen = false; - q->setDown(false); - } + return QPoint(x,y); } + #endif // QT_NO_MENU void QPushButtonPrivate::resetLayoutItemMargins() diff --git a/src/gui/widgets/qpushbutton_p.h b/src/gui/widgets/qpushbutton_p.h index f448027..2510e05 100644 --- a/src/gui/widgets/qpushbutton_p.h +++ b/src/gui/widgets/qpushbutton_p.h @@ -68,6 +68,10 @@ public: defaultButton(false), flat(false), menuOpen(false), lastAutoDefault(false) {} inline void init() { resetLayoutItemMargins(); } + static QPushButtonPrivate* get(QPushButton *b) { return b->d_func(); } +#ifndef QT_NO_MENU + QPoint adjustedMenuPosition(); +#endif void resetLayoutItemMargins(); void _q_popupPressed(); QDialog *dialogParent() const; diff --git a/src/gui/widgets/qspinbox.cpp b/src/gui/widgets/qspinbox.cpp index 9eb07ac..50b225c 100644 --- a/src/gui/widgets/qspinbox.cpp +++ b/src/gui/widgets/qspinbox.cpp @@ -65,14 +65,13 @@ class QSpinBoxPrivate : public QAbstractSpinBoxPrivate { Q_DECLARE_PUBLIC(QSpinBox) public: - QSpinBoxPrivate(QWidget *parent = 0); + QSpinBoxPrivate(); void emitSignals(EmitPolicy ep, const QVariant &); virtual QVariant valueFromText(const QString &n) const; virtual QString textFromValue(const QVariant &n) const; QVariant validateAndInterpret(QString &input, int &pos, QValidator::State &state) const; - QChar thousand; inline void init() { Q_Q(QSpinBox); @@ -85,7 +84,7 @@ class QDoubleSpinBoxPrivate : public QAbstractSpinBoxPrivate { Q_DECLARE_PUBLIC(QDoubleSpinBox) public: - QDoubleSpinBoxPrivate(QWidget *parent = 0); + QDoubleSpinBoxPrivate(); void emitSignals(EmitPolicy ep, const QVariant &); virtual QVariant valueFromText(const QString &n) const; @@ -95,7 +94,6 @@ public: double round(double input) const; // variables int decimals; - QChar delimiter, thousand; inline void init() { Q_Q(QDoubleSpinBox); @@ -201,7 +199,7 @@ public: */ QSpinBox::QSpinBox(QWidget *parent) - : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent) + : QAbstractSpinBox(*new QSpinBoxPrivate, parent) { Q_D(QSpinBox); d->init(); @@ -213,7 +211,7 @@ QSpinBox::QSpinBox(QWidget *parent) argument and then use setObjectName() instead. */ QSpinBox::QSpinBox(QWidget *parent, const char *name) - : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent) + : QAbstractSpinBox(*new QSpinBoxPrivate, parent) { Q_D(QSpinBox); setObjectName(QString::fromAscii(name)); @@ -225,7 +223,7 @@ QSpinBox::QSpinBox(QWidget *parent, const char *name) argument and then use setObjectName() instead. */ QSpinBox::QSpinBox(int minimum, int maximum, int step, QWidget *parent, const char *name) - : QAbstractSpinBox(*new QSpinBoxPrivate(parent), parent) + : QAbstractSpinBox(*new QSpinBoxPrivate, parent) { Q_D(QSpinBox); d->minimum = QVariant(qMin<int>(minimum, maximum)); @@ -464,10 +462,9 @@ void QSpinBox::setRange(int minimum, int maximum) QString QSpinBox::textFromValue(int value) const { - Q_D(const QSpinBox); QString str = locale().toString(value); if (qAbs(value) >= 1000 || value == INT_MIN) { - str.remove(d->thousand); + str.remove(locale().groupSeparator()); } return str; @@ -516,9 +513,7 @@ QValidator::State QSpinBox::validate(QString &text, int &pos) const */ void QSpinBox::fixup(QString &input) const { - Q_D(const QSpinBox); - - input.remove(d->thousand); + input.remove(locale().groupSeparator()); } @@ -600,7 +595,7 @@ void QSpinBox::fixup(QString &input) const \sa setMinimum(), setMaximum(), setSingleStep() */ QDoubleSpinBox::QDoubleSpinBox(QWidget *parent) - : QAbstractSpinBox(*new QDoubleSpinBoxPrivate(parent), parent) + : QAbstractSpinBox(*new QDoubleSpinBoxPrivate, parent) { Q_D(QDoubleSpinBox); d->init(); @@ -875,7 +870,7 @@ QString QDoubleSpinBox::textFromValue(double value) const Q_D(const QDoubleSpinBox); QString str = locale().toString(value, 'f', d->decimals); if (qAbs(value) >= 1000.0) { - str.remove(d->thousand); + str.remove(locale().groupSeparator()); } return str; } @@ -920,9 +915,7 @@ QValidator::State QDoubleSpinBox::validate(QString &text, int &pos) const */ void QDoubleSpinBox::fixup(QString &input) const { - Q_D(const QDoubleSpinBox); - - input.remove(d->thousand); + input.remove(locale().groupSeparator()); } // --- QSpinBoxPrivate --- @@ -932,18 +925,13 @@ void QDoubleSpinBox::fixup(QString &input) const Constructs a QSpinBoxPrivate object */ -QSpinBoxPrivate::QSpinBoxPrivate(QWidget *parent) +QSpinBoxPrivate::QSpinBoxPrivate() { minimum = QVariant((int)0); maximum = QVariant((int)99); value = minimum; singleStep = QVariant((int)1); type = QVariant::Int; - const QString str = (parent ? parent->locale() : QLocale()).toString(4567); - if (str.size() == 5) { - thousand = QChar(str.at(1)); - } - } /*! @@ -1019,20 +1007,17 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, state = QValidator::Invalid; // special-case -0 will be interpreted as 0 and thus not be invalid with a range from 0-100 } else { bool ok = false; - bool removedThousand = false; num = locale.toInt(copy, &ok, 10); - if (!ok && copy.contains(thousand) && (max >= 1000 || min <= -1000)) { - const int s = copy.size(); - copy.remove(thousand); - pos = qMax(0, pos - (s - copy.size())); - removedThousand = true; - num = locale.toInt(copy, &ok, 10); + if (!ok && copy.contains(locale.groupSeparator()) && (max >= 1000 || min <= -1000)) { + QString copy2 = copy; + copy2.remove(locale.groupSeparator()); + num = locale.toInt(copy2, &ok, 10); } QSBDEBUG() << __FILE__ << __LINE__<< "num is set to" << num; if (!ok) { state = QValidator::Invalid; } else if (num >= min && num <= max) { - state = removedThousand ? QValidator::Intermediate : QValidator::Acceptable; + state = QValidator::Acceptable; } else if (max == min) { state = QValidator::Invalid; } else { @@ -1064,7 +1049,7 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, Constructs a QSpinBoxPrivate object */ -QDoubleSpinBoxPrivate::QDoubleSpinBoxPrivate(QWidget *parent) +QDoubleSpinBoxPrivate::QDoubleSpinBoxPrivate() { minimum = QVariant(0.0); maximum = QVariant(99.99); @@ -1072,15 +1057,6 @@ QDoubleSpinBoxPrivate::QDoubleSpinBoxPrivate(QWidget *parent) singleStep = QVariant(1.0); decimals = 2; type = QVariant::Double; - const QString str = (parent ? parent->locale() : QLocale()).toString(4567.1); - if (str.size() == 6) { - delimiter = str.at(4); - thousand = QChar((ushort)0); - } else if (str.size() == 7) { - thousand = str.at(1); - delimiter = str.at(5); - } - Q_ASSERT(!delimiter.isNull()); } /*! @@ -1155,7 +1131,7 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, state = max != min ? QValidator::Intermediate : QValidator::Invalid; goto end; case 1: - if (copy.at(0) == delimiter + if (copy.at(0) == locale.decimalPoint() || (plus && copy.at(0) == QLatin1Char('+')) || (minus && copy.at(0) == QLatin1Char('-'))) { state = QValidator::Intermediate; @@ -1163,7 +1139,7 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, } break; case 2: - if (copy.at(1) == delimiter + if (copy.at(1) == locale.decimalPoint() && ((plus && copy.at(0) == QLatin1Char('+')) || (minus && copy.at(0) == QLatin1Char('-')))) { state = QValidator::Intermediate; goto end; @@ -1172,14 +1148,14 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, default: break; } - if (copy.at(0) == thousand) { + if (copy.at(0) == locale.groupSeparator()) { QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; state = QValidator::Invalid; goto end; } else if (len > 1) { - const int dec = copy.indexOf(delimiter); + const int dec = copy.indexOf(locale.decimalPoint()); if (dec != -1) { - if (dec + 1 < copy.size() && copy.at(dec + 1) == delimiter && pos == dec + 1) { + if (dec + 1 < copy.size() && copy.at(dec + 1) == locale.decimalPoint() && pos == dec + 1) { copy.remove(dec + 1, 1); // typing a delimiter when you are on the delimiter } // should be treated as typing right arrow @@ -1189,7 +1165,7 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, goto end; } for (int i=dec + 1; i<copy.size(); ++i) { - if (copy.at(i).isSpace() || copy.at(i) == thousand) { + if (copy.at(i).isSpace() || copy.at(i) == locale.groupSeparator()) { QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; state = QValidator::Invalid; goto end; @@ -1198,12 +1174,12 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, } else { const QChar &last = copy.at(len - 1); const QChar &secondLast = copy.at(len - 2); - if ((last == thousand || last.isSpace()) - && (secondLast == thousand || secondLast.isSpace())) { + if ((last == locale.groupSeparator() || last.isSpace()) + && (secondLast == locale.groupSeparator() || secondLast.isSpace())) { state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; goto end; - } else if (last.isSpace() && (!thousand.isSpace() || secondLast.isSpace())) { + } else if (last.isSpace() && (!locale.groupSeparator().isSpace() || secondLast.isSpace())) { state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; goto end; @@ -1215,11 +1191,10 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, bool ok = false; num = locale.toDouble(copy, &ok); QSBDEBUG() << __FILE__ << __LINE__ << locale << copy << num << ok; - bool notAcceptable = false; if (!ok) { - if (thousand.isPrint()) { - if (max < 1000 && min > -1000 && copy.contains(thousand)) { + if (locale.groupSeparator().isPrint()) { + if (max < 1000 && min > -1000 && copy.contains(locale.groupSeparator())) { state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; goto end; @@ -1227,27 +1202,23 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, const int len = copy.size(); for (int i=0; i<len- 1; ++i) { - if (copy.at(i) == thousand && copy.at(i + 1) == thousand) { + if (copy.at(i) == locale.groupSeparator() && copy.at(i + 1) == locale.groupSeparator()) { QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; state = QValidator::Invalid; goto end; } } - const int s = copy.size(); - copy.remove(thousand); - pos = qMax(0, pos - (s - copy.size())); - - - num = locale.toDouble(copy, &ok); - QSBDEBUG() << thousand << num << copy << ok; + QString copy2 = copy; + copy2.remove(locale.groupSeparator()); + num = locale.toDouble(copy2, &ok); + QSBDEBUG() << locale.groupSeparator() << num << copy2 << ok; if (!ok) { state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; goto end; } - notAcceptable = true; } } @@ -1255,9 +1226,8 @@ QVariant QDoubleSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; } else if (num >= min && num <= max) { - state = notAcceptable ? QValidator::Intermediate : QValidator::Acceptable; - QSBDEBUG() << __FILE__ << __LINE__<< "state is set to " - << (state == QValidator::Intermediate ? "Intermediate" : "Acceptable"); + state = QValidator::Acceptable; + QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Acceptable"; } else if (max == min) { // when max and min is the same the only non-Invalid input is max (or min) state = QValidator::Invalid; QSBDEBUG() << __FILE__ << __LINE__<< "state is set to Invalid"; diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index 1c49ef0..1bc0bf1 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -1578,7 +1578,7 @@ void QTextEdit::mouseReleaseEvent(QMouseEvent *e) d->autoScrollTimer.stop(); ensureCursorVisible(); } - if (!isReadOnly()) + if (!isReadOnly() && rect().contains(e->pos())) d->handleSoftwareInputPanel(e->button(), d->clickCausedFocus); d->clickCausedFocus = 0; } diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp index 58a3d28..c0ca015 100644 --- a/src/gui/widgets/qtoolbar.cpp +++ b/src/gui/widgets/qtoolbar.cpp @@ -396,10 +396,10 @@ bool QToolBarPrivate::mouseMoveEvent(QMouseEvent *event) void QToolBarPrivate::unplug(const QRect &_r) { Q_Q(QToolBar); - layout->setExpanded(false); QRect r = _r; r.moveTopLeft(q->mapToGlobal(QPoint(0, 0))); setWindowState(true, true, r); + layout->setExpanded(false); } void QToolBarPrivate::plug(const QRect &r) diff --git a/src/gui/widgets/qtoolbararealayout.cpp b/src/gui/widgets/qtoolbararealayout.cpp index b7e985c..b83026b 100644 --- a/src/gui/widgets/qtoolbararealayout.cpp +++ b/src/gui/widgets/qtoolbararealayout.cpp @@ -598,16 +598,21 @@ int QToolBarAreaLayoutInfo::distance(const QPoint &pos) const { switch (dockPos) { case QInternal::LeftDock: - return pos.x() - rect.right(); + if (pos.y() < rect.bottom()) + return pos.x() - rect.right(); case QInternal::RightDock: - return rect.left() - pos.x(); + if (pos.y() < rect.bottom()) + return rect.left() - pos.x(); case QInternal::TopDock: - return pos.y() - rect.bottom(); + if (pos.x() < rect.right()) + return pos.y() - rect.bottom(); case QInternal::BottomDock: - return rect.top() - pos.y(); + if (pos.x() < rect.right()) + return rect.top() - pos.y(); default: - return -1; + break; } + return -1; } /****************************************************************************** @@ -1296,6 +1301,8 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar* QList<QToolBar*> toolBars = _toolBars; int lines; stream >> lines; + if (!testing) + testing = mainWindow->unifiedTitleAndToolBarOnMac(); for (int j = 0; j < lines; ++j) { int pos; @@ -1306,6 +1313,7 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar* stream >> cnt; QToolBarAreaLayoutInfo &dock = docks[pos]; + const bool applyingLayout = !testing && !(pos == QInternal::TopDock && mainWindow->unifiedTitleAndToolBarOnMac()); QToolBarAreaLayoutLine line(dock.o); for (int k = 0; k < cnt; ++k) { @@ -1346,7 +1354,7 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar* continue; } - if (!testing) { + if (applyingLayout) { item.widgetItem = new QWidgetItemV2(toolBar); toolBar->setOrientation(floating ? ((shown & 2) ? Qt::Vertical : Qt::Horizontal) : dock.o); toolBar->setVisible(shown & 1); @@ -1357,7 +1365,7 @@ bool QToolBarAreaLayout::restoreState(QDataStream &stream, const QList<QToolBar* } } - if (!testing) { + if (applyingLayout) { dock.lines.append(line); } } diff --git a/src/gui/widgets/qtoolbarlayout.cpp b/src/gui/widgets/qtoolbarlayout.cpp index 0afe5d8..93429e4 100644 --- a/src/gui/widgets/qtoolbarlayout.cpp +++ b/src/gui/widgets/qtoolbarlayout.cpp @@ -654,6 +654,7 @@ void QToolBarLayout::setExpanded(bool exp) if (!tb) return; if (QMainWindow *win = qobject_cast<QMainWindow*>(tb->parentWidget())) { + animating = !tb->isWindow() && win->isAnimated(); QMainWindowLayout *layout = qobject_cast<QMainWindowLayout*>(win->layout()); if (expanded) { tb->raise(); @@ -664,7 +665,7 @@ void QToolBarLayout::setExpanded(bool exp) layoutActions(rect.size()); } } - layout->layoutState.toolBarAreaLayout.apply(win->isAnimated()); + layout->layoutState.toolBarAreaLayout.apply(animating); } } diff --git a/src/network/access/qnetworkcookiejar.cpp b/src/network/access/qnetworkcookiejar.cpp index 19f7217..f826115 100644 --- a/src/network/access/qnetworkcookiejar.cpp +++ b/src/network/access/qnetworkcookiejar.cpp @@ -192,9 +192,10 @@ bool QNetworkCookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieLis // validate the cookie & set the defaults if unset if (cookie.path().isEmpty()) cookie.setPath(defaultPath); - else if (!isParentPath(pathAndFileName, cookie.path())) - continue; // not accepted - + // don't do path checking. See http://bugreports.qt.nokia.com/browse/QTBUG-5815 +// else if (!isParentPath(pathAndFileName, cookie.path())) { +// continue; // not accepted +// } if (cookie.domain().isEmpty()) { cookie.setDomain(defaultDomain); } else { diff --git a/src/network/kernel/qnetworkproxy_win.cpp b/src/network/kernel/qnetworkproxy_win.cpp index 6f92424..0e2dd2b 100644 --- a/src/network/kernel/qnetworkproxy_win.cpp +++ b/src/network/kernel/qnetworkproxy_win.cpp @@ -291,7 +291,10 @@ void QWindowsSystemProxy::init() GlobalFree(ieProxyConfig.lpszAutoConfigUrl); } if (ieProxyConfig.lpszProxy) { - proxyServerList << QString::fromWCharArray(ieProxyConfig.lpszProxy); + // http://msdn.microsoft.com/en-us/library/aa384250%28VS.85%29.aspx speaks only about a "proxy URL", + // not multiple URLs. However we tested this and it can return multiple URLs. So we use splitSpaceSemicolon + // on it. + proxyServerList = splitSpaceSemicolon(QString::fromWCharArray(ieProxyConfig.lpszProxy)); GlobalFree(ieProxyConfig.lpszProxy); } if (ieProxyConfig.lpszProxyBypass) { diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp index 1fe3999..ee1a797 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE void QGL2PEXVertexArray::clear() { vertexArray.reset(); - vertexArrayStops.clear(); + vertexArrayStops.reset(); boundingRectDirty = true; } @@ -101,7 +101,7 @@ void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseSc boundingRectDirty = false; } - if (!outline) + if (!outline && !path.isConvex()) addCentroid(path, 0); int lastMoveTo = vertexArray.size(); @@ -120,15 +120,14 @@ void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseSc // qDebug("QVectorPath has element types"); for (int i=1; i<path.elementCount(); ++i) { - const QPainterPath::ElementType elementType = elements[i]; - switch (elementType) { + switch (elements[i]) { case QPainterPath::MoveToElement: if (!outline) addClosingLine(lastMoveTo); // qDebug("element[%d] is a MoveToElement", i); - vertexArrayStops.append(vertexArray.size()); + vertexArrayStops.add(vertexArray.size()); if (!outline) { - addCentroid(path, i); + if (!path.isConvex()) addCentroid(path, i); lastMoveTo = vertexArray.size(); } lineToArray(points[i].x(), points[i].y()); // Add the moveTo as a new vertex @@ -137,11 +136,22 @@ void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseSc // qDebug("element[%d] is a LineToElement", i); lineToArray(points[i].x(), points[i].y()); break; - case QPainterPath::CurveToElement: -// qDebug("element[%d] is a CurveToElement", i); - curveToArray(points[i], points[i+1], points[i+2], curveInverseScale); - i+=2; - break; + case QPainterPath::CurveToElement: { + QBezier b = QBezier::fromPoints(*(((const QPointF *) points) + i - 1), + points[i], + points[i+1], + points[i+2]); + QRectF bounds = b.bounds(); + // threshold based on same algorithm as in qtriangulatingstroker.cpp + int threshold = qMin<float>(64, qMax(bounds.width(), bounds.height()) * 3.14f / (curveInverseScale * 6)); + if (threshold < 3) threshold = 3; + qreal one_over_threshold_minus_1 = 1.f / (threshold - 1); + for (int t=0; t<threshold; ++t) { + QPointF pt = b.pointAt(t * one_over_threshold_minus_1); + lineToArray(pt.x(), pt.y()); + } + i += 2; + break; } default: break; } @@ -150,7 +160,7 @@ void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseSc if (!outline) addClosingLine(lastMoveTo); - vertexArrayStops.append(vertexArray.size()); + vertexArrayStops.add(vertexArray.size()); } void QGL2PEXVertexArray::lineToArray(const GLfloat x, const GLfloat y) @@ -167,35 +177,4 @@ void QGL2PEXVertexArray::lineToArray(const GLfloat x, const GLfloat y) minY = y; } -void QGL2PEXVertexArray::curveToArray(const QGLPoint &cp1, const QGLPoint &cp2, const QGLPoint &ep, GLfloat inverseScale) -{ - qreal inverseScaleHalf = inverseScale / 2; - - QBezier beziers[32]; - beziers[0] = QBezier::fromPoints(vertexArray.last(), cp1, cp2, ep); - QBezier *b = beziers; - while (b >= beziers) { - // check if we can pop the top bezier curve from the stack - qreal l = qAbs(b->x4 - b->x1) + qAbs(b->y4 - b->y1); - qreal d; - if (l > inverseScale) { - d = qAbs( (b->x4 - b->x1)*(b->y1 - b->y2) - (b->y4 - b->y1)*(b->x1 - b->x2) ) - + qAbs( (b->x4 - b->x1)*(b->y1 - b->y3) - (b->y4 - b->y1)*(b->x1 - b->x3) ); - d /= l; - } else { - d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) + - qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3); - } - if (d < inverseScaleHalf || b == beziers + 31) { - // good enough, we pop it off and add the endpoint - lineToArray(b->x4, b->y4); - --b; - } else { - // split, second half of the polygon goes lower into the stack - b->split(b+1, b); - ++b; - } - } -} - QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h index 719904f..98eaa91 100644 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h +++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h @@ -108,23 +108,23 @@ public: void clear(); QGLPoint* data() {return vertexArray.data();} - QVector<int>& stops() {return vertexArrayStops;} + int *stops() const { return vertexArrayStops.data(); } + int stopCount() const { return vertexArrayStops.size(); } QGLRect boundingRect() const; + int vertexCount() const { return vertexArray.size(); } + void lineToArray(const GLfloat x, const GLfloat y); private: QDataBuffer<QGLPoint> vertexArray; - QVector<int> vertexArrayStops; + QDataBuffer<int> vertexArrayStops; GLfloat maxX; GLfloat maxY; GLfloat minX; GLfloat minY; bool boundingRectDirty; - - inline void curveToArray(const QGLPoint &cp1, const QGLPoint &cp2, const QGLPoint &ep, GLfloat inverseScale); - void addClosingLine(int index); void addCentroid(const QVectorPath &path, int subPathIndex); }; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 823f919..3fce384 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -62,6 +62,8 @@ and use the correct program when we really need it. */ +// #define QT_OPENGL_CACHE_AS_VBOS + #include "qpaintengineex_opengl2_p.h" #include <string.h> //for memcpy @@ -344,6 +346,13 @@ extern QImage qt_imageForBrush(int brushStyle, bool invert); QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate() { delete shaderManager; + + while (pathCaches.size()) { + QVectorPath::CacheEntry *e = *(pathCaches.constBegin()); + e->cleanup(e->engine, e->data); + e->data = 0; + e->engine = 0; + } } void QGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id) @@ -846,6 +855,30 @@ void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode) mode = newMode; } +struct QGL2PEVectorPathCache +{ +#ifdef QT_OPENGL_CACHE_AS_VBOS + GLuint vbo; +#else + float *vertices; +#endif + int vertexCount; + GLenum primitiveType; + qreal iscale; +}; + +void qopengl2paintengine_cleanup_vectorpath(QPaintEngineEx *engine, void *data) +{ + QGL2PEVectorPathCache *c = (QGL2PEVectorPathCache *) data; +#ifdef QT_OPENGL_CACHE_AS_VBOS + QGL2PaintEngineExPrivate *d = QGL2PaintEngineExPrivate::getData((QGL2PaintEngineEx *) engine); + d->unusedVBOSToClean << c->vbo; +#else + qFree(c->vertices); +#endif + delete c; +} + // Assumes everything is configured for the brush you want to use void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) { @@ -863,10 +896,74 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) prepareForDraw(currentBrush->isOpaque()); composite(rect); } else if (path.isConvex()) { - vertexCoordinateArray.clear(); - vertexCoordinateArray.addPath(path, inverseScale, false); - prepareForDraw(currentBrush->isOpaque()); - drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN); + + if (path.isCacheable()) { + QVectorPath::CacheEntry *data = path.lookupCacheData(q); + QGL2PEVectorPathCache *cache; + + if (data) { + cache = (QGL2PEVectorPathCache *) data->data; + // Check if scale factor is exceeded for curved paths and generate curves if so... + if (path.isCurved()) { + qreal scaleFactor = cache->iscale / inverseScale; + if (scaleFactor < 0.5 || scaleFactor > 2.0) { +#ifdef QT_OPENGL_CACHE_AS_VBOS + glDeleteBuffers(1, &cache->vbo); + cache->vbo = 0; +#else + qFree(cache->vertices); +#endif + cache->vertexCount = 0; + } + } + } else { + cache = new QGL2PEVectorPathCache; + cache->vertexCount = 0; + data = const_cast<QVectorPath &>(path).addCacheData(q, cache, qopengl2paintengine_cleanup_vectorpath); + } + + // Flatten the path at the current scale factor and fill it into the cache struct. + if (!cache->vertexCount) { + vertexCoordinateArray.clear(); + vertexCoordinateArray.addPath(path, inverseScale, false); + int vertexCount = vertexCoordinateArray.vertexCount(); + int floatSizeInBytes = vertexCount * 2 * sizeof(float); + cache->vertexCount = vertexCount; + cache->primitiveType = GL_TRIANGLE_FAN; + cache->iscale = inverseScale; +#ifdef QT_OPENGL_CACHE_AS_VBOS + glGenBuffers(1, &cache->vbo); + glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); + glBufferData(GL_ARRAY_BUFFER, floatSizeInBytes, vertexCoordinateArray.data(), GL_STATIC_DRAW); +#else + cache->vertices = (float *) qMalloc(floatSizeInBytes); + memcpy(cache->vertices, vertexCoordinateArray.data(), floatSizeInBytes); +#endif + } + + prepareForDraw(currentBrush->isOpaque()); + glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); +#ifdef QT_OPENGL_CACHE_AS_VBOS + glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); + glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, false, 0, 0); +#else + glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, false, 0, cache->vertices); +#endif + glDrawArrays(cache->primitiveType, 0, cache->vertexCount); + + } else { + // printf(" - Marking path as cachable...\n"); + // Tag it for later so that if the same path is drawn twice, it is assumed to be static and thus cachable + // ### Remove before release... + static bool do_vectorpath_cache = qgetenv("QT_OPENGL_NO_PATH_CACHE").isEmpty(); + if (do_vectorpath_cache) + path.makeCacheable(); + vertexCoordinateArray.clear(); + vertexCoordinateArray.addPath(path, inverseScale, false); + prepareForDraw(currentBrush->isOpaque()); + drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN); + } + } else { // The path is too complicated & needs the stencil technique vertexCoordinateArray.clear(); @@ -908,7 +1005,8 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data, int count, - const QVector<int> *stops, + int *stops, + int stopCount, const QGLRect &bounds, StencilFillMode mode) { @@ -966,7 +1064,7 @@ void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data, // Dec. for back-facing "holes" glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_DECR_WRAP); glStencilMask(~GL_STENCIL_HIGH_BIT); - drawVertexArrays(data, stops, GL_TRIANGLE_FAN); + drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN); if (q->state()->clipTestEnabled) { // Clear high bit of stencil outside of path @@ -978,7 +1076,7 @@ void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data, } else if (mode == OddEvenFillMode) { glStencilMask(GL_STENCIL_HIGH_BIT); glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit - drawVertexArrays(data, stops, GL_TRIANGLE_FAN); + drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN); } else { // TriStripStrokeFillMode Q_ASSERT(count && !stops); // tristrips generated directly, so no vertexArray or stops @@ -1137,7 +1235,7 @@ void QGL2PaintEngineExPrivate::composite(const QGLRect& boundingRect) } // Draws the vertex array as a set of <vertexArrayStops.size()> triangle fans. -void QGL2PaintEngineExPrivate::drawVertexArrays(const float *data, const QVector<int> *stops, +void QGL2PaintEngineExPrivate::drawVertexArrays(const float *data, int *stops, int stopCount, GLenum primitive) { // Now setup the pointer to the vertex array: @@ -1145,7 +1243,8 @@ void QGL2PaintEngineExPrivate::drawVertexArrays(const float *data, const QVector glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, data); int previousStop = 0; - foreach(int stop, *stops) { + for (int i=0; i<stopCount; ++i) { + int stop = stops[i]; /* qDebug("Drawing triangle fan for vertecies %d -> %d:", previousStop, stop-1); for (int i=previousStop; i<stop; ++i) @@ -1304,7 +1403,7 @@ void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) QRectF bounds = path.controlPointRect().adjusted(-extra, -extra, extra, extra); d->fillStencilWithVertexArray(d->stroker.vertices(), d->stroker.vertexCount() / 2, - 0, bounds, QGL2PaintEngineExPrivate::TriStripStrokeFillMode); + 0, 0, bounds, QGL2PaintEngineExPrivate::TriStripStrokeFillMode); glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); @@ -1452,7 +1551,8 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem drawCached = false; // don't try to cache huge fonts - if (ti.fontEngine->fontDef.pixelSize * qSqrt(s->matrix.determinant()) >= 64) + const qreal pixelSize = ti.fontEngine->fontDef.pixelSize; + if (pixelSize * pixelSize * qAbs(s->matrix.determinant()) >= 64 * 64) drawCached = false; QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0 @@ -1753,7 +1853,8 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->device->beginPaint(); #if !defined(QT_OPENGL_ES_2) - bool success = qt_resolve_version_2_0_functions(d->ctx); + bool success = qt_resolve_version_2_0_functions(d->ctx) + && qt_resolve_buffer_extensions(d->ctx); Q_ASSERT(success); Q_UNUSED(success); #endif @@ -1773,13 +1874,10 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->glyphCacheType = QFontEngineGlyphCache::Raster_A8; #if !defined(QT_OPENGL_ES_2) - if (!d->device->format().alpha() #if defined(Q_WS_WIN) - && qt_cleartype_enabled + if (qt_cleartype_enabled) #endif - ) { d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask; - } #endif #if defined(QT_OPENGL_ES_2) @@ -1817,6 +1915,13 @@ bool QGL2PaintEngineEx::end() delete d->shaderManager; d->shaderManager = 0; +#ifdef QT_OPENGL_CACHE_AS_VBOS + if (!d->unusedVBOSToClean.isEmpty()) { + glDeleteBuffers(d->unusedVBOSToClean.size(), d->unusedVBOSToClean.constData()); + d->unusedVBOSToClean.clear(); + } +#endif + return false; } diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 9720723..0084476 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -195,18 +195,18 @@ public: void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern = false); void drawCachedGlyphs(const QPointF &p, QFontEngineGlyphCache::Type glyphType, const QTextItemInt &ti); - void drawVertexArrays(const float *data, const QVector<int> *stops, GLenum primitive); + void drawVertexArrays(const float *data, int *stops, int stopCount, GLenum primitive); void drawVertexArrays(QGL2PEXVertexArray &vertexArray, GLenum primitive) { - drawVertexArrays((const float *) vertexArray.data(), &vertexArray.stops(), primitive); + drawVertexArrays((const float *) vertexArray.data(), vertexArray.stops(), vertexArray.stopCount(), primitive); } // ^ draws whatever is in the vertex array void composite(const QGLRect& boundingRect); // ^ Composites the bounding rect onto dest buffer - void fillStencilWithVertexArray(const float *data, int count, const QVector<int> *stops, const QGLRect &bounds, StencilFillMode mode); + void fillStencilWithVertexArray(const float *data, int count, int *stops, int stopCount, const QGLRect &bounds, StencilFillMode mode); void fillStencilWithVertexArray(QGL2PEXVertexArray& vertexArray, bool useWindingFill) { - fillStencilWithVertexArray((const float *) vertexArray.data(), 0, &vertexArray.stops(), + fillStencilWithVertexArray((const float *) vertexArray.data(), 0, vertexArray.stops(), vertexArray.stopCount(), vertexArray.boundingRect(), useWindingFill ? WindingFillMode : OddEvenFillMode); } @@ -221,6 +221,7 @@ public: void restoreDepthRangeForRenderText(); static QGLEngineShaderManager* shaderManagerForEngine(QGL2PaintEngineEx *engine) { return engine->d_func()->shaderManager; } + static QGL2PaintEngineExPrivate *getData(QGL2PaintEngineEx *engine) { return engine->d_func(); } QGL2PaintEngineEx* q; QGLPaintDevice* device; @@ -294,6 +295,9 @@ public: QScopedPointer<QPixmapFilter> fastBlurFilter; QScopedPointer<QPixmapFilter> dropShadowFilter; QScopedPointer<QPixmapFilter> fastDropShadowFilter; + + QSet<QVectorPath::CacheEntry *> pathCaches; + QVector<GLuint> unusedVBOSToClean; }; QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp index 1478b09..6082f49 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp @@ -209,6 +209,65 @@ void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen) } } +void QTriangulatingStroker::moveTo(const qreal *pts) +{ + m_cx = pts[0]; + m_cy = pts[1]; + + float x2 = pts[2]; + float y2 = pts[3]; + normalVector(m_cx, m_cy, x2, y2, &m_nvx, &m_nvy); + + + // To acheive jumps we insert zero-area tringles. This is done by + // adding two identical points in both the end of previous strip + // and beginning of next strip + bool invisibleJump = m_vertices.size(); + + switch (m_cap_style) { + case Qt::FlatCap: + if (invisibleJump) { + m_vertices.add(m_cx + m_nvx); + m_vertices.add(m_cy + m_nvy); + } + break; + case Qt::SquareCap: { + float sx = m_cx - m_nvy; + float sy = m_cy + m_nvx; + if (invisibleJump) { + m_vertices.add(sx + m_nvx); + m_vertices.add(sy + m_nvy); + } + emitLineSegment(sx, sy, m_nvx, m_nvy); + break; } + case Qt::RoundCap: { + QVarLengthArray<float> points; + arcPoints(m_cx, m_cy, m_cx + m_nvx, m_cy + m_nvy, m_cx - m_nvx, m_cy - m_nvy, points); + m_vertices.resize(m_vertices.size() + points.size() + 2 * int(invisibleJump)); + int count = m_vertices.size(); + int front = 0; + int end = points.size() / 2; + while (front != end) { + m_vertices.at(--count) = points[2 * end - 1]; + m_vertices.at(--count) = points[2 * end - 2]; + --end; + if (front == end) + break; + m_vertices.at(--count) = points[2 * front + 1]; + m_vertices.at(--count) = points[2 * front + 0]; + ++front; + } + + if (invisibleJump) { + m_vertices.at(count - 1) = m_vertices.at(count + 1); + m_vertices.at(count - 2) = m_vertices.at(count + 0); + } + break; } + default: break; // ssssh gcc... + } + emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); +} + void QTriangulatingStroker::cubicTo(const qreal *pts) { const QPointF *p = (const QPointF *) pts; @@ -246,6 +305,152 @@ void QTriangulatingStroker::cubicTo(const qreal *pts) m_nvy = vy; } +void QTriangulatingStroker::join(const qreal *pts) +{ + // Creates a join to the next segment (m_cx, m_cy) -> (pts[0], pts[1]) + normalVector(m_cx, m_cy, pts[0], pts[1], &m_nvx, &m_nvy); + + switch (m_join_style) { + case Qt::BevelJoin: + break; + case Qt::SvgMiterJoin: + case Qt::MiterJoin: { + // Find out on which side the join should be. + int count = m_vertices.size(); + float prevNvx = m_vertices.at(count - 2) - m_cx; + float prevNvy = m_vertices.at(count - 1) - m_cy; + float xprod = prevNvx * m_nvy - prevNvy * m_nvx; + float px, py, qx, qy; + + // If the segments are parallel, use bevel join. + if (qFuzzyIsNull(xprod)) + break; + + // Find the corners of the previous and next segment to join. + if (xprod < 0) { + px = m_vertices.at(count - 2); + py = m_vertices.at(count - 1); + qx = m_cx - m_nvx; + qy = m_cy - m_nvy; + } else { + px = m_vertices.at(count - 4); + py = m_vertices.at(count - 3); + qx = m_cx + m_nvx; + qy = m_cy + m_nvy; + } + + // Find intersection point. + float pu = px * prevNvx + py * prevNvy; + float qv = qx * m_nvx + qy * m_nvy; + float ix = (m_nvy * pu - prevNvy * qv) / xprod; + float iy = (prevNvx * qv - m_nvx * pu) / xprod; + + // Check that the distance to the intersection point is less than the miter limit. + if ((ix - px) * (ix - px) + (iy - py) * (iy - py) <= m_miter_limit * m_miter_limit) { + m_vertices.add(ix); + m_vertices.add(iy); + m_vertices.add(ix); + m_vertices.add(iy); + } + // else + // Do a plain bevel join if the miter limit is exceeded or if + // the lines are parallel. This is not what the raster + // engine's stroker does, but it is both faster and similar to + // what some other graphics API's do. + + break; } + case Qt::RoundJoin: { + QVarLengthArray<float> points; + int count = m_vertices.size(); + float prevNvx = m_vertices.at(count - 2) - m_cx; + float prevNvy = m_vertices.at(count - 1) - m_cy; + if (m_nvx * prevNvy - m_nvy * prevNvx < 0) { + arcPoints(0, 0, m_nvx, m_nvy, -prevNvx, -prevNvy, points); + for (int i = points.size() / 2; i > 0; --i) + emitLineSegment(m_cx, m_cy, points[2 * i - 2], points[2 * i - 1]); + } else { + arcPoints(0, 0, -prevNvx, -prevNvy, m_nvx, m_nvy, points); + for (int i = 0; i < points.size() / 2; ++i) + emitLineSegment(m_cx, m_cy, points[2 * i + 0], points[2 * i + 1]); + } + break; } + default: break; // gcc warn-- + } + + emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); +} + +void QTriangulatingStroker::endCap(const qreal *) +{ + switch (m_cap_style) { + case Qt::FlatCap: + break; + case Qt::SquareCap: + emitLineSegment(m_cx + m_nvy, m_cy - m_nvx, m_nvx, m_nvy); + break; + case Qt::RoundCap: { + QVarLengthArray<float> points; + int count = m_vertices.size(); + arcPoints(m_cx, m_cy, m_vertices.at(count - 2), m_vertices.at(count - 1), m_vertices.at(count - 4), m_vertices.at(count - 3), points); + int front = 0; + int end = points.size() / 2; + while (front != end) { + m_vertices.add(points[2 * end - 2]); + m_vertices.add(points[2 * end - 1]); + --end; + if (front == end) + break; + m_vertices.add(points[2 * front + 0]); + m_vertices.add(points[2 * front + 1]); + ++front; + } + break; } + default: break; // to shut gcc up... + } +} + +void QTriangulatingStroker::arcPoints(float cx, float cy, float fromX, float fromY, float toX, float toY, QVarLengthArray<float> &points) +{ + float dx1 = fromX - cx; + float dy1 = fromY - cy; + float dx2 = toX - cx; + float dy2 = toY - cy; + + // while more than 180 degrees left: + while (dx1 * dy2 - dx2 * dy1 < 0) { + float tmpx = dx1 * m_cos_theta - dy1 * m_sin_theta; + float tmpy = dx1 * m_sin_theta + dy1 * m_cos_theta; + dx1 = tmpx; + dy1 = tmpy; + points.append(cx + dx1); + points.append(cy + dy1); + } + + // while more than 90 degrees left: + while (dx1 * dx2 + dy1 * dy2 < 0) { + float tmpx = dx1 * m_cos_theta - dy1 * m_sin_theta; + float tmpy = dx1 * m_sin_theta + dy1 * m_cos_theta; + dx1 = tmpx; + dy1 = tmpy; + points.append(cx + dx1); + points.append(cy + dy1); + } + + // while more than 0 degrees left: + while (dx1 * dy2 - dx2 * dy1 > 0) { + float tmpx = dx1 * m_cos_theta - dy1 * m_sin_theta; + float tmpy = dx1 * m_sin_theta + dy1 * m_cos_theta; + dx1 = tmpx; + dy1 = tmpy; + points.append(cx + dx1); + points.append(cy + dy1); + } + + // remove last point which was rotated beyond [toX, toY]. + if (!points.isEmpty()) + points.resize(points.size() - 2); +} + static void qdashprocessor_moveTo(qreal x, qreal y, void *data) { ((QDashedStrokeProcessor *) data)->addElement(QPainterPath::MoveToElement, x, y); diff --git a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h index a0117d5..2dba0ce 100644 --- a/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h +++ b/src/opengl/gl2paintengineex/qtriangulatingstroker_p.h @@ -43,6 +43,7 @@ #define QTRIANGULATINGSTROKER_P_H #include <private/qdatabuffer_p.h> +#include <qvarlengtharray.h> #include <private/qvectorpath_p.h> #include <private/qbezier_p.h> #include <private/qnumeric_p.h> @@ -62,13 +63,13 @@ public: private: inline void emitLineSegment(float x, float y, float nx, float ny); - inline void moveTo(const qreal *pts); + void moveTo(const qreal *pts); inline void lineTo(const qreal *pts); void cubicTo(const qreal *pts); - inline void join(const qreal *pts); + void join(const qreal *pts); inline void normalVector(float x1, float y1, float x2, float y2, float *nx, float *ny); - inline void endCap(const qreal *pts); - inline void arc(float x, float y); + void endCap(const qreal *pts); + void arcPoints(float cx, float cy, float fromX, float fromY, float toX, float toY, QVarLengthArray<float> &points); void endCapOrJoinClosed(const qreal *start, const qreal *cur, bool implicitClose, bool endsAtStart); @@ -116,10 +117,6 @@ private: qreal m_inv_scale; }; - - - - inline void QTriangulatingStroker::normalVector(float x1, float y1, float x2, float y2, float *nx, float *ny) { @@ -139,8 +136,6 @@ inline void QTriangulatingStroker::normalVector(float x1, float y1, float x2, fl *ny = dx * pw; } - - inline void QTriangulatingStroker::emitLineSegment(float x, float y, float vx, float vy) { m_vertices.add(x + vx); @@ -149,103 +144,6 @@ inline void QTriangulatingStroker::emitLineSegment(float x, float y, float vx, f m_vertices.add(y - vy); } - - -// We draw a full circle for any round join or round cap which is a -// bit of overkill... -inline void QTriangulatingStroker::arc(float x, float y) -{ - float dx = m_width; - float dy = 0; - for (int i=0; i<=m_roundness; ++i) { - float tmpx = dx * m_cos_theta - dy * m_sin_theta; - float tmpy = dx * m_sin_theta + dy * m_cos_theta; - dx = tmpx; - dy = tmpy; - emitLineSegment(x, y, dx, dy); - } -} - - - -inline void QTriangulatingStroker::endCap(const qreal *pts) -{ - switch (m_cap_style) { - case Qt::FlatCap: - break; - case Qt::SquareCap: { - float dx = m_cx - *(pts - 2); - float dy = m_cy - *(pts - 1); - - float len = m_width / sqrt(dx * dx + dy * dy); - dx = dx * len; - dy = dy * len; - - emitLineSegment(m_cx + dx, m_cy + dy, m_nvx, m_nvy); - break; } - case Qt::RoundCap: - arc(m_cx, m_cy); - break; - default: break; // to shut gcc up... - } -} - - -void QTriangulatingStroker::moveTo(const qreal *pts) -{ - m_cx = pts[0]; - m_cy = pts[1]; - - float x2 = pts[2]; - float y2 = pts[3]; - normalVector(m_cx, m_cy, x2, y2, &m_nvx, &m_nvy); - - - // To acheive jumps we insert zero-area tringles. This is done by - // adding two identical points in both the end of previous strip - // and beginning of next strip - bool invisibleJump = m_vertices.size(); - - switch (m_cap_style) { - case Qt::FlatCap: - if (invisibleJump) { - m_vertices.add(m_cx + m_nvx); - m_vertices.add(m_cy + m_nvy); - } - break; - case Qt::SquareCap: { - float dx = x2 - m_cx; - float dy = y2 - m_cy; - float len = m_width / sqrt(dx * dx + dy * dy); - dx = dx * len; - dy = dy * len; - float sx = m_cx - dx; - float sy = m_cy - dy; - if (invisibleJump) { - m_vertices.add(sx + m_nvx); - m_vertices.add(sy + m_nvy); - } - emitLineSegment(sx, sy, m_nvx, m_nvy); - break; } - case Qt::RoundCap: - if (invisibleJump) { - m_vertices.add(m_cx + m_nvx); - m_vertices.add(m_cy + m_nvy); - } - - // This emitLineSegment is not needed for the arc, but we need - // to start where we put the invisibleJump vertex, otherwise - // we'll have visible triangles between subpaths. - emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); - arc(m_cx, m_cy); - break; - default: break; // ssssh gcc... - } - emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); -} - - - void QTriangulatingStroker::lineTo(const qreal *pts) { emitLineSegment(pts[0], pts[1], m_nvx, m_nvy); @@ -253,52 +151,6 @@ void QTriangulatingStroker::lineTo(const qreal *pts) m_cy = pts[1]; } - - -void QTriangulatingStroker::join(const qreal *pts) -{ - // Creates a join to the next segment (m_cx, m_cy) -> (pts[0], pts[1]) - normalVector(m_cx, m_cy, pts[0], pts[1], &m_nvx, &m_nvy); - - switch (m_join_style) { - case Qt::BevelJoin: - break; - case Qt::MiterJoin: { - int p1 = m_vertices.size() - 6; - int p2 = m_vertices.size() - 2; - QLineF line(m_vertices.at(p1), m_vertices.at(p1+1), - m_vertices.at(p2), m_vertices.at(p2+1)); - QLineF nextLine(m_cx - m_nvx, m_cy - m_nvy, - pts[0] - m_nvx, pts[1] - m_nvy); - - QPointF isect; - if (line.intersect(nextLine, &isect) != QLineF::NoIntersection - && QLineF(line.p2(), isect).length() <= m_miter_limit) { - // The intersection point mirrored over the m_cx, m_cy point - m_vertices.add(m_cx - (isect.x() - m_cx)); - m_vertices.add(m_cy - (isect.y() - m_cy)); - - // The intersection point - m_vertices.add(isect.x()); - m_vertices.add(isect.y()); - } - // else - // Do a plain bevel join if the miter limit is exceeded or if - // the lines are parallel. This is not what the raster - // engine's stroker does, but it is both faster and similar to - // what some other graphics API's do. - - break; } - case Qt::RoundJoin: - arc(m_cx, m_cy); - break; - - default: break; // gcc warn-- - } - - emitLineSegment(m_cx, m_cy, m_nvx, m_nvy); -} - QT_END_NAMESPACE #endif diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index d5ca218..1bd1b91 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -127,18 +127,6 @@ Q_GLOBAL_STATIC(QGLDefaultOverlayFormat, defaultOverlayFormatInstance) QGLExtensions::Extensions QGLExtensions::glExtensions = 0; bool QGLExtensions::nvidiaFboNeedsFinish = false; -#ifndef APIENTRY -# define APIENTRY -#endif -typedef void (APIENTRY *pfn_glCompressedTexImage2DARB) (GLenum, GLint, GLenum, GLsizei, - GLsizei, GLint, GLsizei, const GLvoid *); -static pfn_glCompressedTexImage2DARB qt_glCompressedTexImage2DARB = 0; - - -#ifndef APIENTRY -#define APIENTRY -#endif - Q_GLOBAL_STATIC(QGLSignalProxy, theSignalProxy) QGLSignalProxy *QGLSignalProxy::instance() { @@ -185,12 +173,12 @@ public: #else // We can't do this in the constructor for this object because it // needs to be called *before* the QApplication constructor. - // Also check for the FragmentProgram extension in conjunction with + // Also check for the FragmentShader extension in conjunction with // the 2.0 version flag, to cover the case where we export the display // from an old GL 1.1 server to a GL 2.x client. In that case we can't // use GL 2.0. if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) - && (QGLExtensions::glExtensions & QGLExtensions::FragmentProgram) + && (QGLExtensions::glExtensions & QGLExtensions::FragmentShader) && qgetenv("QT_GL_USE_OPENGL1ENGINE").isEmpty()) engineType = QPaintEngine::OpenGL2; else @@ -1495,6 +1483,7 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format) version_flags_cached = false; version_flags = QGLFormat::OpenGL_Version_None; current_fbo = 0; + default_fbo = 0; active_engine = 0; } @@ -1886,118 +1875,42 @@ void QGLContextPrivate::cleanup() { } -typedef QHash<QString, GLuint> QGLDDSCache; -Q_GLOBAL_STATIC(QGLDDSCache, qgl_dds_cache) - /*! \overload - Reads the DirectDrawSurface (DDS) compressed file \a fileName and - generates a 2D GL texture from it. + Reads the compressed texture file \a fileName and generates a 2D GL + texture from it. - Only the DXT1, DXT3 and DXT5 DDS formats are supported. + This function can load DirectDrawSurface (DDS) textures in the + DXT1, DXT3 and DXT5 DDS formats if the \c GL_ARB_texture_compression + and \c GL_EXT_texture_compression_s3tc extensions are supported. - Note that this will only work if the implementation supports the - \c GL_ARB_texture_compression and \c GL_EXT_texture_compression_s3tc - extensions. + Since 4.6.1, textures in the ETC1 format can be loaded if the + \c GL_OES_compressed_ETC1_RGB8_texture extension is supported + and the ETC1 texture has been encapsulated in the PVR container format. + Also, textures in the PVRTC2 and PVRTC4 formats can be loaded + if the \c GL_IMG_texture_compression_pvrtc extension is supported. \sa deleteTexture() */ GLuint QGLContext::bindTexture(const QString &fileName) { - if (!qt_glCompressedTexImage2DARB) { - qWarning("QGLContext::bindTexture(): The GL implementation does not support texture" - "compression extensions."); - return 0; - } - - QGLDDSCache::const_iterator it = qgl_dds_cache()->constFind(fileName); - if (it != qgl_dds_cache()->constEnd()) { + Q_D(QGLContext); + QGLDDSCache *dds_cache = &(d->group->m_dds_cache); + QGLDDSCache::const_iterator it = dds_cache->constFind(fileName); + if (it != dds_cache->constEnd()) { glBindTexture(GL_TEXTURE_2D, it.value()); return it.value(); } - QFile f(fileName); - f.open(QIODevice::ReadOnly); - - char tag[4]; - f.read(&tag[0], 4); - if (strncmp(tag,"DDS ", 4) != 0) { - qWarning("QGLContext::bindTexture(): not a DDS image file."); - return 0; - } - - DDSFormat ddsHeader; - f.read((char *) &ddsHeader, sizeof(DDSFormat)); - - if (!ddsHeader.dwLinearSize) { - qWarning("QGLContext::bindTexture() DDS image size is not valid."); - return 0; - } - - int factor = 4; - int bufferSize = 0; - int blockSize = 16; - GLenum format; - - switch(ddsHeader.ddsPixelFormat.dwFourCC) { - case FOURCC_DXT1: - format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - factor = 2; - blockSize = 8; - break; - case FOURCC_DXT3: - format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - break; - case FOURCC_DXT5: - format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - break; - default: - qWarning("QGLContext::bindTexture() DDS image format not supported."); + QGLTexture texture(this); + QSize size = texture.bindCompressedTexture(fileName); + if (!size.isValid()) return 0; - } - - if (ddsHeader.dwMipMapCount > 1) - bufferSize = ddsHeader.dwLinearSize * factor; - else - bufferSize = ddsHeader.dwLinearSize; - GLubyte *pixels = (GLubyte *) malloc(bufferSize*sizeof(GLubyte)); - f.seek(ddsHeader.dwSize + 4); - f.read((char *) pixels, bufferSize); - f.close(); - - GLuint tx_id; - glGenTextures(1, &tx_id); - glBindTexture(GL_TEXTURE_2D, tx_id); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - int size; - int offset = 0; - int w = ddsHeader.dwWidth; - int h = ddsHeader.dwHeight; - - // load mip-maps - for(int i = 0; i < (int) ddsHeader.dwMipMapCount; ++i) { - if (w == 0) w = 1; - if (h == 0) h = 1; - - size = ((w+3)/4) * ((h+3)/4) * blockSize; - qt_glCompressedTexImage2DARB(GL_TEXTURE_2D, i, format, w, h, 0, - size, pixels + offset); - offset += size; - - // half size for each mip-map level - w = w/2; - h = h/2; - } - - free(pixels); - - qgl_dds_cache()->insert(fileName, tx_id); - return tx_id; + dds_cache->insert(fileName, texture.id); + return texture.id; } static inline QRgb qt_gl_convertToGLFormatHelper(QRgb src_pixel, GLenum texture_format) @@ -2277,13 +2190,21 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G #ifdef QGL_BIND_TEXTURE_DEBUG printf(" - flipping bits over y (%d ms)\n", time.elapsed()); #endif - int ipl = img.bytesPerLine() / 4; - int h = img.height(); - for (int y=0; y<h/2; ++y) { - int *a = (int *) img.scanLine(y); - int *b = (int *) img.scanLine(h - y - 1); - for (int x=0; x<ipl; ++x) - qSwap(a[x], b[x]); + if (img.isDetached()) { + int ipl = img.bytesPerLine() / 4; + int h = img.height(); + for (int y=0; y<h/2; ++y) { + int *a = (int *) img.scanLine(y); + int *b = (int *) img.scanLine(h - y - 1); + for (int x=0; x<ipl; ++x) + qSwap(a[x], b[x]); + } + } else { + // Create a new image and copy across. If we use the + // above in-place code then a full copy of the image is + // made before the lines are swapped, which processes the + // data twice. This version should only do it once. + img = img.mirrored(); } } @@ -2313,6 +2234,14 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G } } } +#ifdef QT_OPENGL_ES + // OpenGL/ES requires that the internal and external formats be identical. + // This is typically used to convert GL_RGBA into GL_BGRA. + // Also, we need to use GL_UNSIGNED_BYTE when the format is GL_BGRA. + internalFormat = externalFormat; + if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV) + pixel_type = GL_UNSIGNED_BYTE; +#endif #ifdef QGL_BIND_TEXTURE_DEBUG printf(" - uploading, image.format=%d, externalFormat=0x%x, internalFormat=0x%x, pixel_type=0x%x\n", img.format(), externalFormat, internalFormat, pixel_type); @@ -2584,17 +2513,20 @@ GLuint QGLContext::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, Q */ void QGLContext::deleteTexture(GLuint id) { + Q_D(QGLContext); + if (QGLTextureCache::instance()->remove(this, id)) return; // check the DDS cache if the texture wasn't found in the pixmap/image // cache - QList<QString> ddsKeys = qgl_dds_cache()->keys(); + QGLDDSCache *dds_cache = &(d->group->m_dds_cache); + QList<QString> ddsKeys = dds_cache->keys(); for (int i = 0; i < ddsKeys.size(); ++i) { - GLuint texture = qgl_dds_cache()->value(ddsKeys.at(i)); + GLuint texture = dds_cache->value(ddsKeys.at(i)); if (id == texture) { glDeleteTextures(1, &texture); - qgl_dds_cache()->remove(ddsKeys.at(i)); + dds_cache->remove(ddsKeys.at(i)); return; } } @@ -4162,7 +4094,7 @@ void QGLWidget::qglColor(const QColor& c) const const QGLContext *ctx = QGLContext::currentContext(); if (ctx) { if (ctx->format().rgba()) - glColor4ub(c.red(), c.green(), c.blue(), c.alpha()); + glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF()); else if (!d->cmap.isEmpty()) { // QGLColormap in use? int i = d->cmap.find(c.rgb()); if (i < 0) @@ -4898,10 +4830,18 @@ void QGLExtensions::init_extensions() glExtensions |= SampleBuffers; if (extensions.contains("GL_SGIS_generate_mipmap")) glExtensions |= GenerateMipmap; - if (extensions.contains("GL_EXT_texture_compression_s3tc")) + if (extensions.contains("GL_ARB_texture_compression")) glExtensions |= TextureCompression; + if (extensions.contains("GL_EXT_texture_compression_s3tc")) + glExtensions |= DDSTextureCompression; + if (extensions.contains("GL_OES_compressed_ETC1_RGB8_texture")) + glExtensions |= ETC1TextureCompression; + if (extensions.contains("GL_IMG_texture_compression_pvrtc")) + glExtensions |= PVRTCTextureCompression; if (extensions.contains("GL_ARB_fragment_program")) glExtensions |= FragmentProgram; + if (extensions.contains("GL_ARB_fragment_shader")) + glExtensions |= FragmentShader; if (extensions.contains("GL_ARB_texture_mirrored_repeat")) glExtensions |= MirroredRepeat; if (extensions.contains("GL_EXT_framebuffer_object")) @@ -4919,6 +4859,7 @@ void QGLExtensions::init_extensions() #if defined(QT_OPENGL_ES_2) glExtensions |= FramebufferObject; glExtensions |= GenerateMipmap; + glExtensions |= FragmentShader; #endif #if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL) if (extensions.contains("GL_OES_framebuffer_object")) @@ -4942,12 +4883,6 @@ void QGLExtensions::init_extensions() if (extensions.contains("GL_EXT_bgra")) glExtensions |= BGRATextureFormat; - - - QGLContext cx(QGLFormat::defaultFormat()); - if (glExtensions & TextureCompression) { - qt_glCompressedTexImage2DARB = (pfn_glCompressedTexImage2DARB) cx.getProcAddress(QLatin1String("glCompressedTexImage2DARB")); - } } /* @@ -5103,4 +5038,340 @@ void QGLSharedResourceGuard::setContext(const QGLContext *context) } } +QSize QGLTexture::bindCompressedTexture + (const QString& fileName, const char *format) +{ + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly)) + return QSize(); + QByteArray contents = file.readAll(); + file.close(); + return bindCompressedTexture + (contents.constData(), contents.size(), format); +} + +// PVR header format for container files that store textures compressed +// with the ETC1, PVRTC2, and PVRTC4 encodings. Format information from the +// PowerVR SDK at http://www.imgtec.com/powervr/insider/powervr-sdk.asp +// "PVRTexTool Reference Manual, version 1.11f". +struct PvrHeader +{ + quint32 headerSize; + quint32 height; + quint32 width; + quint32 mipMapCount; + quint32 flags; + quint32 dataSize; + quint32 bitsPerPixel; + quint32 redMask; + quint32 greenMask; + quint32 blueMask; + quint32 alphaMask; + quint32 magic; + quint32 surfaceCount; +}; + +#define PVR_MAGIC 0x21525650 // "PVR!" in little-endian + +#define PVR_FORMAT_MASK 0x000000FF +#define PVR_FORMAT_PVRTC2 0x00000018 +#define PVR_FORMAT_PVRTC4 0x00000019 +#define PVR_FORMAT_ETC1 0x00000036 + +#define PVR_HAS_MIPMAPS 0x00000100 +#define PVR_TWIDDLED 0x00000200 +#define PVR_NORMAL_MAP 0x00000400 +#define PVR_BORDER_ADDED 0x00000800 +#define PVR_CUBE_MAP 0x00001000 +#define PVR_FALSE_COLOR_MIPMAPS 0x00002000 +#define PVR_VOLUME_TEXTURE 0x00004000 +#define PVR_ALPHA_IN_TEXTURE 0x00008000 +#define PVR_VERTICAL_FLIP 0x00010000 + +#ifndef GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG +#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 +#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 +#endif + +#ifndef GL_ETC1_RGB8_OES +#define GL_ETC1_RGB8_OES 0x8D64 +#endif + +bool QGLTexture::canBindCompressedTexture + (const char *buf, int len, const char *format, bool *hasAlpha) +{ + if (QSysInfo::ByteOrder != QSysInfo::LittleEndian) { + // Compressed texture loading only supported on little-endian + // systems such as x86 and ARM at the moment. + return false; + } + if (!format) { + // Auto-detect the format from the header. + if (len >= 4 && !qstrncmp(buf, "DDS ", 4)) { + *hasAlpha = true; + return true; + } else if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4)) { + const PvrHeader *pvrHeader = + reinterpret_cast<const PvrHeader *>(buf); + *hasAlpha = (pvrHeader->alphaMask != 0); + return true; + } + } else { + // Validate the format against the header. + if (!qstricmp(format, "DDS")) { + if (len >= 4 && !qstrncmp(buf, "DDS ", 4)) { + *hasAlpha = true; + return true; + } + } else if (!qstricmp(format, "PVR") || !qstricmp(format, "ETC1")) { + if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4)) { + const PvrHeader *pvrHeader = + reinterpret_cast<const PvrHeader *>(buf); + *hasAlpha = (pvrHeader->alphaMask != 0); + return true; + } + } + } + return false; +} + +#define ctx QGLContext::currentContext() + +QSize QGLTexture::bindCompressedTexture + (const char *buf, int len, const char *format) +{ + if (QSysInfo::ByteOrder != QSysInfo::LittleEndian) { + // Compressed texture loading only supported on little-endian + // systems such as x86 and ARM at the moment. + return QSize(); + } +#if !defined(QT_OPENGL_ES) + if (!glCompressedTexImage2D) { + if (!(QGLExtensions::glExtensions & QGLExtensions::TextureCompression)) { + qWarning("QGLContext::bindTexture(): The GL implementation does " + "not support texture compression extensions."); + return QSize(); + } + glCompressedTexImage2D = (_glCompressedTexImage2DARB) ctx->getProcAddress(QLatin1String("glCompressedTexImage2DARB")); + if (!glCompressedTexImage2D) { + qWarning("QGLContext::bindTexture(): could not resolve " + "glCompressedTexImage2DARB."); + return QSize(); + } + } +#endif + if (!format) { + // Auto-detect the format from the header. + if (len >= 4 && !qstrncmp(buf, "DDS ", 4)) + return bindCompressedTextureDDS(buf, len); + else if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4)) + return bindCompressedTexturePVR(buf, len); + } else { + // Validate the format against the header. + if (!qstricmp(format, "DDS")) { + if (len >= 4 && !qstrncmp(buf, "DDS ", 4)) + return bindCompressedTextureDDS(buf, len); + } else if (!qstricmp(format, "PVR") || !qstricmp(format, "ETC1")) { + if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4)) + return bindCompressedTexturePVR(buf, len); + } + } + return QSize(); +} + +QSize QGLTexture::bindCompressedTextureDDS(const char *buf, int len) +{ + // We only support 2D texture loading at present. + if (target != GL_TEXTURE_2D) + return QSize(); + + // Bail out if the necessary extension is not present. + if (!(QGLExtensions::glExtensions & QGLExtensions::DDSTextureCompression)) { + qWarning("QGLContext::bindTexture(): DDS texture compression is not supported."); + return QSize(); + } + + const DDSFormat *ddsHeader = reinterpret_cast<const DDSFormat *>(buf + 4); + if (!ddsHeader->dwLinearSize) { + qWarning("QGLContext::bindTexture(): DDS image size is not valid."); + return QSize(); + } + + int blockSize = 16; + GLenum format; + + switch(ddsHeader->ddsPixelFormat.dwFourCC) { + case FOURCC_DXT1: + format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + blockSize = 8; + break; + case FOURCC_DXT3: + format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + break; + case FOURCC_DXT5: + format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + break; + default: + qWarning("QGLContext::bindTexture(): DDS image format not supported."); + return QSize(); + } + + const GLubyte *pixels = + reinterpret_cast<const GLubyte *>(buf + ddsHeader->dwSize + 4); + + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_2D, id); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + int size; + int offset = 0; + int available = len - int(ddsHeader->dwSize + 4); + int w = ddsHeader->dwWidth; + int h = ddsHeader->dwHeight; + + // load mip-maps + for(int i = 0; i < (int) ddsHeader->dwMipMapCount; ++i) { + if (w == 0) w = 1; + if (h == 0) h = 1; + + size = ((w+3)/4) * ((h+3)/4) * blockSize; + if (size > available) + break; + glCompressedTexImage2D(GL_TEXTURE_2D, i, format, w, h, 0, + size, pixels + offset); + offset += size; + available -= size; + + // half size for each mip-map level + w = w/2; + h = h/2; + } + + // DDS images are not inverted. + options &= ~QGLContext::InvertedYBindOption; + + return QSize(ddsHeader->dwWidth, ddsHeader->dwHeight); +} + +QSize QGLTexture::bindCompressedTexturePVR(const char *buf, int len) +{ + // We only support 2D texture loading at present. Cube maps later. + if (target != GL_TEXTURE_2D) + return QSize(); + + // Determine which texture format we will be loading. + const PvrHeader *pvrHeader = reinterpret_cast<const PvrHeader *>(buf); + GLenum textureFormat; + quint32 minWidth, minHeight; + switch (pvrHeader->flags & PVR_FORMAT_MASK) { + case PVR_FORMAT_PVRTC2: + if (pvrHeader->alphaMask) + textureFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + else + textureFormat = GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG; + minWidth = 16; + minHeight = 8; + break; + + case PVR_FORMAT_PVRTC4: + if (pvrHeader->alphaMask) + textureFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + else + textureFormat = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; + minWidth = 8; + minHeight = 8; + break; + + case PVR_FORMAT_ETC1: + textureFormat = GL_ETC1_RGB8_OES; + minWidth = 4; + minHeight = 4; + break; + + default: + qWarning("QGLContext::bindTexture(): PVR image format 0x%x not supported.", int(pvrHeader->flags & PVR_FORMAT_MASK)); + return QSize(); + } + + // Bail out if the necessary extension is not present. + if (textureFormat == GL_ETC1_RGB8_OES) { + if (!(QGLExtensions::glExtensions & + QGLExtensions::ETC1TextureCompression)) { + qWarning("QGLContext::bindTexture(): ETC1 texture compression is not supported."); + return QSize(); + } + } else { + if (!(QGLExtensions::glExtensions & + QGLExtensions::PVRTCTextureCompression)) { + qWarning("QGLContext::bindTexture(): PVRTC texture compression is not supported."); + return QSize(); + } + } + + // Boundary check on the buffer size. + quint32 bufferSize = pvrHeader->headerSize + pvrHeader->dataSize; + if (bufferSize > quint32(len)) { + qWarning("QGLContext::bindTexture(): PVR image size is not valid."); + return QSize(); + } + + // Create the texture. + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_2D, id); + if (pvrHeader->mipMapCount) { + if ((options & QGLContext::LinearFilteringBindOption) != 0) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + } else { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + } + } else if ((options & QGLContext::LinearFilteringBindOption) != 0) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } else { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + + // Load the compressed mipmap levels. + const GLubyte *buffer = + reinterpret_cast<const GLubyte *>(buf + pvrHeader->headerSize); + bufferSize = pvrHeader->dataSize; + quint32 level = 0; + quint32 width = pvrHeader->width; + quint32 height = pvrHeader->height; + while (bufferSize > 0 && level < pvrHeader->mipMapCount) { + quint32 size = + (qMax(width, minWidth) * qMax(height, minHeight) * + pvrHeader->bitsPerPixel) / 8; + if (size > bufferSize) + break; + glCompressedTexImage2D(GL_TEXTURE_2D, GLint(level), textureFormat, + GLsizei(width), GLsizei(height), 0, + GLsizei(size), buffer); + width /= 2; + height /= 2; + buffer += size; + ++level; + } + + // Restore the default pixel alignment for later texture uploads. + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + + // Set the invert flag for the texture. + if ((pvrHeader->flags & PVR_VERTICAL_FLIP) != 0) + options |= QGLContext::InvertedYBindOption; + else + options &= ~QGLContext::InvertedYBindOption; + + return QSize(pvrHeader->width, pvrHeader->height); +} + +#undef ctx + QT_END_NAMESPACE diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 8e472e5..179d69a 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -222,6 +222,8 @@ public: class QGLContextResource; class QGLSharedResourceGuard; +typedef QHash<QString, GLuint> QGLDDSCache; + // QGLContextPrivate has the responsibility of creating context groups. // QGLContextPrivate and QGLShareRegister will both maintain the reference counter and destroy // context groups when needed. @@ -246,6 +248,7 @@ private: QHash<QGLContextResource *, void *> m_resources; QGLSharedResourceGuard *m_guards; // double-linked list of active guards. QAtomicInt m_refs; + QGLDDSCache m_dds_cache; void cleanupResources(const QGLContext *ctx); @@ -328,6 +331,7 @@ public: GLint max_texture_size; GLuint current_fbo; + GLuint default_fbo; QPaintEngine *active_engine; static inline QGLContextGroup *contextGroup(const QGLContext *ctx) { return ctx->d_ptr->group; } @@ -376,7 +380,11 @@ public: PixelBufferObject = 0x00000800, FramebufferBlit = 0x00001000, NPOTTextures = 0x00002000, - BGRATextureFormat = 0x00004000 + BGRATextureFormat = 0x00004000, + DDSTextureCompression = 0x00008000, + ETC1TextureCompression = 0x00010000, + PVRTCTextureCompression = 0x00020000, + FragmentShader = 0x00040000 }; Q_DECLARE_FLAGS(Extensions, Extension) @@ -481,6 +489,14 @@ public: QPixmapData* boundPixmap; #endif + bool canBindCompressedTexture + (const char *buf, int len, const char *format, bool *hasAlpha); + QSize bindCompressedTexture + (const QString& fileName, const char *format = 0); + QSize bindCompressedTexture + (const char *buf, int len, const char *format = 0); + QSize bindCompressedTextureDDS(const char *buf, int len); + QSize bindCompressedTexturePVR(const char *buf, int len); }; class QGLTextureCache { @@ -517,7 +533,8 @@ bool qt_gl_preferGL2Engine(); inline GLenum qt_gl_preferredTextureFormat() { - return QSysInfo::ByteOrder == QSysInfo::BigEndian ? GL_RGBA : GL_BGRA; + return (QGLExtensions::glExtensions & QGLExtensions::BGRATextureFormat) && QSysInfo::ByteOrder == QSysInfo::LittleEndian + ? GL_BGRA : GL_RGBA; } inline GLenum qt_gl_preferredTextureTarget() diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index b51c239..a868e83 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -63,6 +63,7 @@ void qt_egl_add_platform_config(QEglProperties& props, QPaintDevice *device) props.setPixelFormat(static_cast<QImage *>(device)->format()); } +// Chooses the EGL config and creates the EGL context bool QGLContext::chooseContext(const QGLContext* shareContext) { Q_D(QGLContext); @@ -73,56 +74,74 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) int devType = device()->devType(); // Get the display and initialize it. - d->eglContext = new QEglContext(); - d->eglContext->setApi(QEgl::OpenGL); - if (!d->eglContext->openDisplay(device())) { - delete d->eglContext; - d->eglContext = 0; - return false; - } + if (d->eglContext == 0) { + d->eglContext = new QEglContext(); + d->eglContext->setApi(QEgl::OpenGL); + if (!d->eglContext->openDisplay(device())) { + delete d->eglContext; + d->eglContext = 0; + return false; + } - // Construct the configuration we need for this surface. - QEglProperties configProps; - qt_egl_set_format(configProps, devType, d->glFormat); - qt_egl_add_platform_config(configProps, device()); - configProps.setRenderableType(QEgl::OpenGL); - - QEgl::PixelFormatMatch matchType = QEgl::BestPixelFormat; - if (device()->depth() == 16) { - configProps.setValue(EGL_RED_SIZE, 5); - configProps.setValue(EGL_GREEN_SIZE, 6); - configProps.setValue(EGL_BLUE_SIZE, 5); - configProps.setValue(EGL_ALPHA_SIZE, 0); - matchType = QEgl::ExactPixelFormat; - } - configProps.setRenderableType(QEgl::OpenGL); + // Construct the configuration we need for this surface. + QEglProperties configProps; + qt_egl_set_format(configProps, devType, d->glFormat); + qt_egl_add_platform_config(configProps, device()); + configProps.setRenderableType(QEgl::OpenGL); + +#if We_have_an_EGL_library_which_bothers_to_check_EGL_BUFFER_SIZE + if (device()->depth() == 16 && configProps.value(EGL_ALPHA_SIZE) <= 0) { + qDebug("Setting EGL_BUFFER_SIZE to 16"); + configProps.setValue(EGL_BUFFER_SIZE, 16); + configProps.setValue(EGL_ALPHA_SIZE, 0); + } - // Search for a matching configuration, reducing the complexity - // each time until we get something that matches. - if (!d->eglContext->chooseConfig(configProps, matchType)) { - delete d->eglContext; - d->eglContext = 0; - return false; - } + if (!d->eglContext->chooseConfig(configProps, QEgl::BestPixelFormat)) { + delete d->eglContext; + d->eglContext = 0; + return false; + } +#else + QEgl::PixelFormatMatch matchType = QEgl::BestPixelFormat; + if ((device()->depth() == 16) && configProps.value(EGL_ALPHA_SIZE) == 0) { + configProps.setValue(EGL_RED_SIZE, 5); + configProps.setValue(EGL_GREEN_SIZE, 6); + configProps.setValue(EGL_BLUE_SIZE, 5); + configProps.setValue(EGL_ALPHA_SIZE, 0); + matchType = QEgl::ExactPixelFormat; + } - // Inform the higher layers about the actual format properties. - qt_egl_update_format(*(d->eglContext), d->glFormat); + // Search for a matching configuration, reducing the complexity + // each time until we get something that matches. + if (!d->eglContext->chooseConfig(configProps, matchType)) { + delete d->eglContext; + d->eglContext = 0; + return false; + } +#endif - // Create a new context for the configuration. - if (!d->eglContext->createContext - (shareContext ? shareContext->d_func()->eglContext : 0)) { - delete d->eglContext; - d->eglContext = 0; - return false; - } - d->sharing = d->eglContext->isSharing(); - if (d->sharing && shareContext) - const_cast<QGLContext *>(shareContext)->d_func()->sharing = true; +// qDebug("QGLContext::chooseContext() - using EGL config %d:", d->eglContext->config()); +// qDebug() << QEglProperties(d->eglContext->config()).toString(); + + // Create a new context for the configuration. + if (!d->eglContext->createContext + (shareContext ? shareContext->d_func()->eglContext : 0)) { + delete d->eglContext; + d->eglContext = 0; + return false; + } + d->sharing = d->eglContext->isSharing(); + if (d->sharing && shareContext) + const_cast<QGLContext *>(shareContext)->d_func()->sharing = true; #if defined(EGL_VERSION_1_1) - if (d->glFormat.swapInterval() != -1 && devType == QInternal::Widget) - eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval()); + if (d->glFormat.swapInterval() != -1 && devType == QInternal::Widget) + eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval()); #endif + } + + // Inform the higher layers about the actual format properties. + qt_egl_update_format(*(d->eglContext), d->glFormat); return true; } @@ -160,6 +179,9 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf memset(&vi, 0, sizeof(XVisualInfo)); + EGLint eglConfigColorSize; + eglGetConfigAttrib(display, config, EGL_BUFFER_SIZE, &eglConfigColorSize); + // Check to see if EGL is suggesting an appropriate visual id: EGLint nativeVisualId; eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &nativeVisualId); @@ -189,8 +211,12 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf } else #endif { -// qDebug("Using opaque X Visual ID (%d) provided by EGL", (int)vi.visualid); - vi = *chosenVisualInfo; + if (eglConfigColorSize == chosenVisualInfo->depth) { +// qDebug("Using opaque X Visual ID (%d) provided by EGL", (int)vi.visualid); + vi = *chosenVisualInfo; + } else + qWarning("Warning: EGL suggested using X visual ID %d (%d bpp) for config %d (%d bpp), but the depths do not match!", + nativeVisualId, chosenVisualInfo->depth, (int)config, eglConfigColorSize); } XFree(chosenVisualInfo); } @@ -300,6 +326,8 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool createFailed = false; if (!d->glcx->isValid()) { + // Create the QGLContext here, which in turn chooses the EGL config + // and creates the EGL context: if (!d->glcx->create(shareContext ? shareContext : oldcx)) createFailed = true; } diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h index 3510765..62e216c 100644 --- a/src/opengl/qglextensions_p.h +++ b/src/opengl/qglextensions_p.h @@ -184,6 +184,10 @@ typedef void (APIENTRY *_glBlitFramebufferEXT) (int srcX0, int srcY0, int srcX1, typedef void (APIENTRY *_glRenderbufferStorageMultisampleEXT) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +// ARB_texture_compression +typedef void (APIENTRY *_glCompressedTexImage2DARB) (GLenum, GLint, GLenum, GLsizei, + GLsizei, GLint, GLsizei, const GLvoid *); + QT_BEGIN_NAMESPACE struct QGLExtensionFuncs @@ -289,6 +293,11 @@ struct QGLExtensionFuncs #endif qt_glMapBufferARB = 0; qt_glUnmapBufferARB = 0; + +#if !defined(QT_OPENGL_ES) + // Texture compression + qt_glCompressedTexImage2DARB = 0; +#endif } @@ -397,6 +406,10 @@ struct QGLExtensionFuncs _glMapBufferARB qt_glMapBufferARB; _glUnmapBufferARB qt_glUnmapBufferARB; +#if !defined(QT_OPENGL_ES) + // Texture compression + _glCompressedTexImage2DARB qt_glCompressedTexImage2DARB; +#endif }; @@ -732,6 +745,10 @@ struct QGLExtensionFuncs #define glClearDepth glClearDepthf #endif +#if !defined(QT_OPENGL_ES) +#define glCompressedTexImage2D QGLContextPrivate::extensionFuncs(ctx).qt_glCompressedTexImage2DARB +#endif + extern bool qt_resolve_framebufferobject_extensions(QGLContext *ctx); bool qt_resolve_buffer_extensions(QGLContext *ctx); diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index d79283e..d0297c9 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -899,8 +899,8 @@ bool QGLFramebufferObject::release() #endif if (current) { - current->d_ptr->current_fbo = 0; - glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); + current->d_ptr->current_fbo = current->d_ptr->default_fbo; + glBindFramebuffer(GL_FRAMEBUFFER_EXT, current->d_ptr->default_fbo); } return true; diff --git a/src/opengl/qglpaintdevice.cpp b/src/opengl/qglpaintdevice.cpp index 2867de5..bcd90a5 100644 --- a/src/opengl/qglpaintdevice.cpp +++ b/src/opengl/qglpaintdevice.cpp @@ -89,6 +89,12 @@ void QGLPaintDevice::beginPaint() ctx->d_ptr->current_fbo = m_thisFBO; glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_thisFBO); } + + // Set the default fbo for the context to m_thisFBO so that + // if some raw GL code between beginNativePainting() and + // endNativePainting() calls QGLFramebufferObject::release(), + // painting will revert to the window surface's fbo. + ctx->d_ptr->default_fbo = m_thisFBO; } void QGLPaintDevice::ensureActiveTarget() @@ -101,6 +107,8 @@ void QGLPaintDevice::ensureActiveTarget() ctx->d_ptr->current_fbo = m_thisFBO; glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_thisFBO); } + + ctx->d_ptr->default_fbo = m_thisFBO; } void QGLPaintDevice::endPaint() @@ -111,6 +119,8 @@ void QGLPaintDevice::endPaint() ctx->d_ptr->current_fbo = m_previousFBO; glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_previousFBO); } + + ctx->d_ptr->default_fbo = 0; } QGLFormat QGLPaintDevice::format() const diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 8ab17a0..ed7fdff 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -110,11 +110,7 @@ static bool DEBUG_TEMP_FLAG; static inline void qt_glColor4ubv(unsigned char *col) { -#ifdef QT_OPENGL_ES - glColor4f(col[0]/255.0, col[1]/255.0, col[2]/255.0, col[3]/255.0); -#else - glColor4ubv(col); -#endif + glColor4f(col[0]/255.0f, col[1]/255.0f, col[2]/255.0f, col[3]/255.0f); } struct QT_PointF { diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index fb55097..0299cea 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -53,6 +53,8 @@ #include <private/qpaintengineex_opengl2_p.h> #include <qdesktopwidget.h> +#include <qfile.h> +#include <qimagereader.h> QT_BEGIN_NAMESPACE @@ -321,25 +323,47 @@ void QGLPixmapData::ensureCreated() const QGLShareContextScope ctx(qt_gl_share_widget()->context()); m_ctx = ctx; - const GLenum format = qt_gl_preferredTextureFormat(); + const GLenum internal_format = m_hasAlpha ? GL_RGBA : GL_RGB; +#ifdef QT_OPENGL_ES_2 + const GLenum external_format = internal_format; +#else + const GLenum external_format = qt_gl_preferredTextureFormat(); +#endif const GLenum target = GL_TEXTURE_2D; if (!m_texture.id) { glGenTextures(1, &m_texture.id); glBindTexture(target, m_texture.id); - GLenum format = m_hasAlpha ? GL_RGBA : GL_RGB; - glTexImage2D(target, 0, format, w, h, 0, - GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexImage2D(target, 0, internal_format, w, h, 0, external_format, GL_UNSIGNED_BYTE, 0); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } if (!m_source.isNull()) { - const QImage tx = ctx->d_func()->convertToGLFormat(m_source, true, format); + if (external_format == GL_RGB) { + QImage tx = m_source.convertToFormat(QImage::Format_RGB32); + + QVector<uchar> pixelData(w * h * 3); + uchar *p = &pixelData[0]; + QRgb *src = (QRgb *)tx.bits(); + + for (int i = 0; i < w * h; ++i) { + *p++ = qRed(*src); + *p++ = qGreen(*src); + *p++ = qBlue(*src); + ++src; + } - glBindTexture(target, m_texture.id); - glTexSubImage2D(target, 0, 0, 0, w, h, format, - GL_UNSIGNED_BYTE, tx.bits()); + glBindTexture(target, m_texture.id); + glTexSubImage2D(target, 0, 0, 0, w, h, external_format, + GL_UNSIGNED_BYTE, &pixelData[0]); + } else { + const QImage tx = ctx->d_func()->convertToGLFormat(m_source, true, external_format); + + glBindTexture(target, m_texture.id); + glTexSubImage2D(target, 0, 0, 0, w, h, external_format, + GL_UNSIGNED_BYTE, tx.bits()); + } if (useFramebufferObjects()) m_source = QImage(); @@ -385,6 +409,61 @@ void QGLPixmapData::fromImage(const QImage &image, } } +bool QGLPixmapData::fromFile(const QString &filename, const char *format, + Qt::ImageConversionFlags flags) +{ + if (pixelType() == QPixmapData::BitmapType) + return QPixmapData::fromFile(filename, format, flags); + QFile file(filename); + if (!file.open(QIODevice::ReadOnly)) + return false; + QByteArray data = file.peek(64); + bool alpha; + if (m_texture.canBindCompressedTexture + (data.constData(), data.size(), format, &alpha)) { + resize(0, 0); + data = file.readAll(); + file.close(); + QSize size = m_texture.bindCompressedTexture + (data.constData(), data.size(), format); + if (!size.isEmpty()) { + w = size.width(); + h = size.height(); + is_null = false; + d = 32; + m_hasAlpha = alpha; + m_source = QImage(); + m_dirty = isValid(); + return true; + } + return false; + } + fromImage(QImageReader(&file, format).read(), flags); + return !isNull(); +} + +bool QGLPixmapData::fromData(const uchar *buffer, uint len, const char *format, + Qt::ImageConversionFlags flags) +{ + bool alpha; + const char *buf = reinterpret_cast<const char *>(buffer); + if (m_texture.canBindCompressedTexture(buf, int(len), format, &alpha)) { + resize(0, 0); + QSize size = m_texture.bindCompressedTexture(buf, int(len), format); + if (!size.isEmpty()) { + w = size.width(); + h = size.height(); + is_null = false; + d = 32; + m_hasAlpha = alpha; + m_source = QImage(); + m_dirty = isValid(); + return true; + } + } + return QPixmapData::fromData(buffer, len, format, flags); +} + bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect) { Q_UNUSED(dx); diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h index 8a13e03..007c52a 100644 --- a/src/opengl/qpixmapdata_gl_p.h +++ b/src/opengl/qpixmapdata_gl_p.h @@ -106,6 +106,10 @@ public: // Re-implemented from QPixmapData: void resize(int width, int height); void fromImage(const QImage &image, Qt::ImageConversionFlags flags); + bool fromFile(const QString &filename, const char *format, + Qt::ImageConversionFlags flags); + bool fromData(const uchar *buffer, uint len, const char *format, + Qt::ImageConversionFlags flags); void copy(const QPixmapData *data, const QRect &rect); bool scroll(int dx, int dy, const QRect &rect); void fill(const QColor &color); diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index e353f5d..7194f9d 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -493,7 +493,6 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & } #endif d_ptr->paintedRegion = QRegion(); - context()->swapBuffers(); } else { glFlush(); @@ -688,11 +687,13 @@ void QGLWindowSurface::updateGeometry() { d_ptr->size = rect.size(); if (d_ptr->ctx) { +#ifndef QT_OPENGL_ES_2 if (d_ptr->destructive_swap_buffers) { glBindTexture(target, d_ptr->tex_id); glTexImage2D(target, 0, GL_RGBA, rect.width(), rect.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); glBindTexture(target, 0); } +#endif return; } @@ -756,11 +757,7 @@ void QGLWindowSurface::updateGeometry() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); -#ifndef QT_OPENGL_ES glOrtho(0, d_ptr->pb->width(), d_ptr->pb->height(), 0, -999999, 999999); -#else - glOrthof(0, d_ptr->pb->width(), d_ptr->pb->height(), 0, -999999, 999999); -#endif d_ptr->pb->d_ptr->qctx->d_func()->internal_context = true; return; @@ -774,6 +771,7 @@ void QGLWindowSurface::updateGeometry() { ctx->makeCurrent(); +#ifndef QT_OPENGL_ES_2 if (d_ptr->destructive_swap_buffers) { glGenTextures(1, &d_ptr->tex_id); glBindTexture(target, d_ptr->tex_id); @@ -783,6 +781,7 @@ void QGLWindowSurface::updateGeometry() { glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindTexture(target, 0); } +#endif qDebug() << "QGLWindowSurface: Using plain widget as window surface" << this;; d_ptr->ctx = ctx; diff --git a/src/openvg/openvg.pro b/src/openvg/openvg.pro index bf224b4..8927c4c 100644 --- a/src/openvg/openvg.pro +++ b/src/openvg/openvg.pro @@ -34,6 +34,7 @@ contains(QT_CONFIG, egl) { include(../qbase.pri) unix:QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui +symbian:TARGET.UID3 = 0x2001E62F !isEmpty(QMAKE_INCDIR_OPENVG): INCLUDEPATH += $$QMAKE_INCDIR_OPENVG !isEmpty(QMAKE_LIBDIR_OPENVG): LIBS_PRIVATE += -L$$QMAKE_LIBDIR_OPENVG diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index fda4b10..6b829dd 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -1570,12 +1570,6 @@ void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) d->dirty |= QPaintEngine::DirtyClipRegion; - // If we have a non-simple transform, then use path-based clipping. - if (op != Qt::NoClip && !clipTransformIsSimple(d->transform)) { - QPaintEngineEx::clip(rect, op); - return; - } - switch (op) { case Qt::NoClip: { @@ -1612,12 +1606,6 @@ void QVGPaintEngine::clip(const QRegion ®ion, Qt::ClipOperation op) d->dirty |= QPaintEngine::DirtyClipRegion; - // If we have a non-simple transform, then use path-based clipping. - if (op != Qt::NoClip && !clipTransformIsSimple(d->transform)) { - QPaintEngineEx::clip(region, op); - return; - } - switch (op) { case Qt::NoClip: { @@ -3459,14 +3447,11 @@ void QVGCompositionHelper::endCompositing() } void QVGCompositionHelper::blitWindow - (QVGEGLWindowSurfacePrivate *surface, const QRect& rect, - const QPoint& topLeft, int opacity) + (VGImage image, const QSize& imageSize, + const QRect& rect, const QPoint& topLeft, int opacity) { - // Get the VGImage that is acting as a back buffer for the window. - VGImage image = surface->surfaceImage(); if (image == VG_INVALID_HANDLE) return; - QSize imageSize = surface->surfaceSize(); // Determine which sub rectangle of the window to draw. QRect sr = rect.translated(-topLeft); diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index 19c90ed..5d5fcbf 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -65,12 +65,21 @@ QVGPixmapData::QVGPixmapData(PixelType type) recreate = true; #if !defined(QT_NO_EGL) context = 0; + qt_vg_register_pixmap(this); #endif setSerialNumber(++qt_vg_pixmap_serial); } QVGPixmapData::~QVGPixmapData() { + destroyImageAndContext(); +#if !defined(QT_NO_EGL) + qt_vg_unregister_pixmap(this); +#endif +} + +void QVGPixmapData::destroyImageAndContext() +{ if (vgImage != VG_INVALID_HANDLE) { // We need to have a context current to destroy the image. #if !defined(QT_NO_EGL) @@ -93,11 +102,16 @@ QVGPixmapData::~QVGPixmapData() if (vgImageOpacity != VG_INVALID_HANDLE) vgDestroyImage(vgImageOpacity); #endif + vgImage = VG_INVALID_HANDLE; + vgImageOpacity = VG_INVALID_HANDLE; } #if !defined(QT_NO_EGL) - if (context) - qt_vg_destroy_context(context); + if (context) { + qt_vg_destroy_context(context, QInternal::Pixmap); + context = 0; + } #endif + recreate = true; } QPixmapData *QVGPixmapData::createCompatiblePixmapData() const @@ -217,7 +231,7 @@ VGImage QVGPixmapData::toVGImage() #if !defined(QT_NO_EGL) // Increase the reference count on the shared context. if (!context) - context = qt_vg_create_context(0); + context = qt_vg_create_context(0, QInternal::Pixmap); #endif if (recreate && prevSize != QSize(w, h)) { @@ -286,6 +300,17 @@ VGImage QVGPixmapData::toVGImage(qreal opacity) #endif } +void QVGPixmapData::hibernate() +{ + // If the image was imported (e.g, from an SgImage under Symbian), + // then we cannot copy it back to main memory for storage. + if (vgImage != VG_INVALID_HANDLE && source.isNull()) + return; + + forceToImage(); + destroyImageAndContext(); +} + extern int qt_defaultDpiX(); extern int qt_defaultDpiY(); @@ -376,7 +401,7 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) // when "0" used as argument then // default display, context are used if (!context) - context = qt_vg_create_context(0); + context = qt_vg_create_context(0, QInternal::Pixmap); if (vgImage != VG_INVALID_HANDLE) { vgDestroyImage(vgImage); diff --git a/src/openvg/qpixmapdata_vg_p.h b/src/openvg/qpixmapdata_vg_p.h index fe19f35..c0bb098 100644 --- a/src/openvg/qpixmapdata_vg_p.h +++ b/src/openvg/qpixmapdata_vg_p.h @@ -55,8 +55,6 @@ #include <QtGui/private/qpixmap_raster_p.h> #include <private/qvg_p.h> -#if !defined(QT_NO_EGL) -#endif #if defined(Q_OS_SYMBIAN) class RSGImage; @@ -66,6 +64,15 @@ QT_BEGIN_NAMESPACE class QEglContext; +#if !defined(QT_NO_EGL) +class QVGPixmapData; +class QVGSharedContext; + +void qt_vg_register_pixmap(QVGPixmapData *pd); +void qt_vg_unregister_pixmap(QVGPixmapData *pd); +void qt_vg_hibernate_pixmaps(QVGSharedContext *context); +#endif + class Q_OPENVG_EXPORT QVGPixmapData : public QPixmapData { public: @@ -94,6 +101,14 @@ public: // Return the VGImage form for a specific opacity setting. virtual VGImage toVGImage(qreal opacity); + // Release the VG resources associated with this pixmap and copy + // the pixmap's contents out of the GPU back into main memory. + // The VG resource will be automatically recreated the next time + // toVGImage() is called. Does nothing if the pixmap cannot be + // hibernated for some reason (e.g. VGImage is shared with another + // process via a SgImage). + virtual void hibernate(); + QSize size() const { return QSize(w, h); } #if defined(Q_OS_SYMBIAN) @@ -108,6 +123,16 @@ protected: void cleanup(); #endif +#if !defined(QT_NO_EGL) +private: + QVGPixmapData *next; + QVGPixmapData *prev; + + friend void qt_vg_register_pixmap(QVGPixmapData *pd); + friend void qt_vg_unregister_pixmap(QVGPixmapData *pd); + friend void qt_vg_hibernate_pixmaps(QVGSharedContext *context); +#endif + protected: QSize prevSize; VGImage vgImage; @@ -121,6 +146,8 @@ protected: void forceToImage(); QImage::Format sourceFormat() const; + + void destroyImageAndContext(); }; QT_END_NAMESPACE diff --git a/src/openvg/qvg_p.h b/src/openvg/qvg_p.h index 04e2bab..3577013 100644 --- a/src/openvg/qvg_p.h +++ b/src/openvg/qvg_p.h @@ -71,11 +71,17 @@ class QEglContext; // Create an EGL context, but don't bind it to a surface. If single-context // mode is enabled, this will return the previously-created context. -Q_OPENVG_EXPORT QEglContext *qt_vg_create_context(QPaintDevice *device); +// "devType" indicates the type of device using the context, usually +// QInternal::Widget or QInternal::Pixmap. +Q_OPENVG_EXPORT QEglContext *qt_vg_create_context + (QPaintDevice *device, int devType); // Destroy an EGL context that was created by qt_vg_create_context(). // If single-context mode is enabled, this will decrease the reference count. -Q_OPENVG_EXPORT void qt_vg_destroy_context(QEglContext *context); +// "devType" indicates the type of device destroying the context, usually +// QInternal::Widget or QInternal::Pixmap. +Q_OPENVG_EXPORT void qt_vg_destroy_context + (QEglContext *context, int devType); // Return the shared pbuffer surface that can be made current to // destroy VGImage objects when there is no other surface available. diff --git a/src/openvg/qvgcompositionhelper_p.h b/src/openvg/qvgcompositionhelper_p.h index 3afe31e..ed24e73 100644 --- a/src/openvg/qvgcompositionhelper_p.h +++ b/src/openvg/qvgcompositionhelper_p.h @@ -71,8 +71,8 @@ public: void startCompositing(const QSize& screenSize); void endCompositing(); - void blitWindow(QVGEGLWindowSurfacePrivate *surface, const QRect& rect, - const QPoint& topLeft, int opacity); + void blitWindow(VGImage image, const QSize& imageSize, + const QRect& rect, const QPoint& topLeft, int opacity); void fillBackground(const QRegion& region, const QBrush& brush); void drawCursorPixmap(const QPixmap& pixmap, const QPoint& offset); void setScissor(const QRegion& region); diff --git a/src/openvg/qwindowsurface_vgegl.cpp b/src/openvg/qwindowsurface_vgegl.cpp index 29d82c8..1571083 100644 --- a/src/openvg/qwindowsurface_vgegl.cpp +++ b/src/openvg/qwindowsurface_vgegl.cpp @@ -111,15 +111,19 @@ public: QEglContext *context; int refCount; + int widgetRefCount; QVGPaintEngine *engine; EGLSurface surface; + QVGPixmapData *firstPixmap; }; QVGSharedContext::QVGSharedContext() : context(0) , refCount(0) + , widgetRefCount(0) , engine(0) , surface(EGL_NO_SURFACE) + , firstPixmap(0) { } @@ -154,6 +158,28 @@ void qt_vg_destroy_paint_engine(QVGPaintEngine *engine) Q_UNUSED(engine); } +void qt_vg_register_pixmap(QVGPixmapData *pd) +{ + QVGSharedContext *shared = sharedContext(); + pd->next = shared->firstPixmap; + pd->prev = 0; + if (shared->firstPixmap) + shared->firstPixmap->prev = pd; + shared->firstPixmap = pd; +} + +void qt_vg_unregister_pixmap(QVGPixmapData *pd) +{ + if (pd->next) + pd->next->prev = pd->prev; + if (pd->prev) { + pd->prev->next = pd->next; + } else { + QVGSharedContext *shared = sharedContext(); + shared->firstPixmap = pd->next; + } +} + #else QVGPaintEngine *qt_vg_create_paint_engine(void) @@ -166,6 +192,16 @@ void qt_vg_destroy_paint_engine(QVGPaintEngine *engine) delete engine; } +void qt_vg_register_pixmap(QVGPixmapData *pd) +{ + Q_UNUSED(pd); +} + +void qt_vg_unregister_pixmap(QVGPixmapData *pd) +{ + Q_UNUSED(pd); +} + #endif #ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT @@ -200,6 +236,42 @@ static QEglContext *createContext(QPaintDevice *device) else eglSwapInterval(context->display(), 1); +#ifdef EGL_RENDERABLE_TYPE + // Has the user specified an explicit EGL configuration to use? + QByteArray configId = qgetenv("QT_VG_EGL_CONFIG"); + if (!configId.isEmpty()) { + EGLint cfgId = configId.toInt(); + EGLint properties[] = { + EGL_CONFIG_ID, cfgId, + EGL_NONE + }; + EGLint matching = 0; + EGLConfig cfg; + if (eglChooseConfig + (context->display(), properties, &cfg, 1, &matching) && + matching > 0) { + // Check that the selected configuration actually supports OpenVG + // and then create the context with it. + EGLint id = 0; + EGLint type = 0; + eglGetConfigAttrib + (context->display(), cfg, EGL_CONFIG_ID, &id); + eglGetConfigAttrib + (context->display(), cfg, EGL_RENDERABLE_TYPE, &type); + if (cfgId == id && (type & EGL_OPENVG_BIT) != 0) { + context->setConfig(cfg); + if (!context->createContext()) { + delete context; + return 0; + } + return context; + } else { + qWarning("QT_VG_EGL_CONFIG: %d is not a valid OpenVG configuration", int(cfgId)); + } + } + } +#endif + // Choose an appropriate configuration for rendering into the device. QEglProperties configProps; configProps.setPaintDeviceFormat(device); @@ -211,19 +283,19 @@ static QEglContext *createContext(QPaintDevice *device) configProps.setValue(EGL_ALPHA_MASK_SIZE, 1); #endif #ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT - configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT | + configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT); configProps.setRenderableType(QEgl::OpenVG); if (!context->chooseConfig(configProps)) { // Try again without the "pre" bit. - configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT); + configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT); if (!context->chooseConfig(configProps)) { delete context; return 0; } } #else - configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT); + configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT); configProps.setRenderableType(QEgl::OpenVG); if (!context->chooseConfig(configProps)) { delete context; @@ -242,9 +314,11 @@ static QEglContext *createContext(QPaintDevice *device) #if !defined(QVG_NO_SINGLE_CONTEXT) -QEglContext *qt_vg_create_context(QPaintDevice *device) +QEglContext *qt_vg_create_context(QPaintDevice *device, int devType) { QVGSharedContext *shared = sharedContext(); + if (devType == QInternal::Widget) + ++(shared->widgetRefCount); if (shared->context) { ++(shared->refCount); return shared->context; @@ -255,23 +329,65 @@ QEglContext *qt_vg_create_context(QPaintDevice *device) } } -void qt_vg_destroy_context(QEglContext *context) +static void qt_vg_destroy_shared_context(QVGSharedContext *shared) +{ + shared->context->makeCurrent(qt_vg_shared_surface()); + delete shared->engine; + shared->engine = 0; + shared->context->doneCurrent(); + if (shared->surface != EGL_NO_SURFACE) { + eglDestroySurface(shared->context->display(), shared->surface); + shared->surface = EGL_NO_SURFACE; + } + delete shared->context; + shared->context = 0; +} + +void qt_vg_hibernate_pixmaps(QVGSharedContext *shared) +{ + // Artificially increase the reference count to prevent the + // context from being destroyed until after we have finished + // the hibernation process. + ++(shared->refCount); + + // We need a context current to hibernate the VGImage objects. + shared->context->makeCurrent(qt_vg_shared_surface()); + + // Scan all QVGPixmapData objects in the system and hibernate them. + QVGPixmapData *pd = shared->firstPixmap; + while (pd != 0) { + pd->hibernate(); + pd = pd->next; + } + + // Don't need the current context any more. + shared->context->lazyDoneCurrent(); + + // Decrease the reference count and destroy the context if necessary. + if (--(shared->refCount) <= 0) + qt_vg_destroy_shared_context(shared); +} + +void qt_vg_destroy_context(QEglContext *context, int devType) { QVGSharedContext *shared = sharedContext(); if (shared->context != context) { // This is not the shared context. Shouldn't happen! delete context; - } else if (--(shared->refCount) <= 0) { - shared->context->makeCurrent(qt_vg_shared_surface()); - delete shared->engine; - shared->engine = 0; - shared->context->doneCurrent(); - if (shared->surface != EGL_NO_SURFACE) { - eglDestroySurface(shared->context->display(), shared->surface); - shared->surface = EGL_NO_SURFACE; - } - delete shared->context; - shared->context = 0; + return; + } + if (devType == QInternal::Widget) + --(shared->widgetRefCount); + if (--(shared->refCount) <= 0) { + qt_vg_destroy_shared_context(shared); + } else if (shared->widgetRefCount <= 0 && devType == QInternal::Widget) { + // All of the widget window surfaces have been destroyed + // but we still have VG pixmaps active. Ask them to hibernate + // to free up GPU resources until a widget is shown again. + // This may eventually cause the EGLContext to be destroyed + // because nothing in the system needs a context, which will + // free up even more GPU resources. + qt_vg_hibernate_pixmaps(shared); } } @@ -302,13 +418,15 @@ EGLSurface qt_vg_shared_surface(void) #else -QEglContext *qt_vg_create_context(QPaintDevice *device) +QEglContext *qt_vg_create_context(QPaintDevice *device, int devType) { + Q_UNUSED(devType); return createContext(device); } -void qt_vg_destroy_context(QEglContext *context) +void qt_vg_destroy_context(QEglContext *context, int devType) { + Q_UNUSED(devType); delete context; } @@ -398,7 +516,7 @@ QVGEGLWindowSurfaceVGImage::~QVGEGLWindowSurfaceVGImage() } if (windowSurface != EGL_NO_SURFACE) context->destroySurface(windowSurface); - qt_vg_destroy_context(context); + qt_vg_destroy_context(context, QInternal::Widget); } } @@ -417,7 +535,7 @@ QEglContext *QVGEGLWindowSurfaceVGImage::ensureContext(QWidget *widget) if (!context) { // Create a new EGL context. We create the surface in beginPaint(). size = newSize; - context = qt_vg_create_context(widget); + context = qt_vg_create_context(widget, QInternal::Widget); if (!context) return 0; isPaintingActive = false; @@ -512,7 +630,7 @@ QVGEGLWindowSurfaceDirect::~QVGEGLWindowSurfaceDirect() if (context) { if (windowSurface != EGL_NO_SURFACE) context->destroySurface(windowSurface); - qt_vg_destroy_context(context); + qt_vg_destroy_context(context, QInternal::Widget); } } @@ -551,7 +669,7 @@ QEglContext *QVGEGLWindowSurfaceDirect::ensureContext(QWidget *widget) qt_vg_destroy_paint_engine(engine); engine = 0; context->destroySurface(windowSurface); - qt_vg_destroy_context(context); + qt_vg_destroy_context(context, QInternal::Widget); context = 0; windowSurface = EGL_NO_SURFACE; } @@ -560,7 +678,7 @@ QEglContext *QVGEGLWindowSurfaceDirect::ensureContext(QWidget *widget) if (!context) { // Create a new EGL context and bind it to the widget surface. size = newSize; - context = qt_vg_create_context(widget); + context = qt_vg_create_context(widget, QInternal::Widget); if (!context) return 0; // We want a direct to window rendering surface if possible. @@ -577,7 +695,7 @@ QEglContext *QVGEGLWindowSurfaceDirect::ensureContext(QWidget *widget) #endif EGLSurface surface = context->createSurface(widget, &surfaceProps); if (surface == EGL_NO_SURFACE) { - qt_vg_destroy_context(context); + qt_vg_destroy_context(context, QInternal::Widget); context = 0; return 0; } diff --git a/src/plugins/qpluginbase.pri b/src/plugins/qpluginbase.pri index a3abc98..b66f8f9 100644 --- a/src/plugins/qpluginbase.pri +++ b/src/plugins/qpluginbase.pri @@ -1,6 +1,6 @@ TEMPLATE = lib isEmpty(QT_MAJOR_VERSION) { - VERSION=4.6.0 + VERSION=4.6.1 } else { VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION} } diff --git a/src/plugins/sqldrivers/sqldrivers.pro b/src/plugins/sqldrivers/sqldrivers.pro index 2bd5f2c..83d71e4 100644 --- a/src/plugins/sqldrivers/sqldrivers.pro +++ b/src/plugins/sqldrivers/sqldrivers.pro @@ -10,6 +10,4 @@ contains(sql-plugins, sqlite) : SUBDIRS += sqlite contains(sql-plugins, sqlite2) : SUBDIRS += sqlite2 contains(sql-plugins, ibase) : SUBDIRS += ibase -contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { - symbian:contains(CONFIG, system-sqlite): SUBDIRS += sqlite_symbian - } +symbian:contains(CONFIG, system-sqlite): SUBDIRS += sqlite_symbian diff --git a/src/qbase.pri b/src/qbase.pri index 0aae24d..d1a2a75 100644 --- a/src/qbase.pri +++ b/src/qbase.pri @@ -4,7 +4,7 @@ INCLUDEPATH *= $$QMAKE_INCDIR_QT/$$TARGET #just for today to have some compat isEmpty(QT_ARCH):!isEmpty(ARCH):QT_ARCH=$$ARCH #another compat that will rot for change #215700 TEMPLATE = lib isEmpty(QT_MAJOR_VERSION) { - VERSION=4.6.0 + VERSION=4.6.1 } else { VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION} } diff --git a/src/qt3support/other/q3process_unix.cpp b/src/qt3support/other/q3process_unix.cpp index 955b65f..32a68e0 100644 --- a/src/qt3support/other/q3process_unix.cpp +++ b/src/qt3support/other/q3process_unix.cpp @@ -249,7 +249,7 @@ int qnx6SocketPairReplacement (int socketFD[2]) { if (errno != EINPROGRESS) { BAILOUT }; // Accept connection - socketFD[0] = accept(tmpSocket, (struct sockaddr *)NULL, (size_t *)NULL); + socketFD[0] = accept(tmpSocket, (struct sockaddr *)NULL, (QT_SOCKLEN_T *)NULL); if(socketFD[0] == -1) { BAILOUT }; // We're done diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index 166b6fe..60df1f5 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -271,7 +271,7 @@ EXPORTS ??0QImageIOHandler@@IAE@AAVQImageIOHandlerPrivate@@@Z @ 270 NONAME ; QImageIOHandler::QImageIOHandler(class QImageIOHandlerPrivate &) ??0QImageIOHandler@@QAE@XZ @ 271 NONAME ; QImageIOHandler::QImageIOHandler(void) ??0QImageIOPlugin@@QAE@PAVQObject@@@Z @ 272 NONAME ; QImageIOPlugin::QImageIOPlugin(class QObject *) - ??0QImagePixmapCleanupHooks@@QAE@XZ @ 273 NONAME ; QImagePixmapCleanupHooks::QImagePixmapCleanupHooks(void) + ??0QImagePixmapCleanupHooks@@QAE@XZ @ 273 NONAME ABSENT ; QImagePixmapCleanupHooks::QImagePixmapCleanupHooks(void) ??0QImageReader@@QAE@ABVQString@@ABVQByteArray@@@Z @ 274 NONAME ; QImageReader::QImageReader(class QString const &, class QByteArray const &) ??0QImageReader@@QAE@PAVQIODevice@@ABVQByteArray@@@Z @ 275 NONAME ; QImageReader::QImageReader(class QIODevice *, class QByteArray const &) ??0QImageReader@@QAE@XZ @ 276 NONAME ; QImageReader::QImageReader(void) @@ -2021,7 +2021,7 @@ EXPORTS ?addButton@QMessageBox@@QAEPAVQPushButton@@ABVQString@@W4ButtonRole@1@@Z @ 2020 NONAME ; class QPushButton * QMessageBox::addButton(class QString const &, enum QMessageBox::ButtonRole) ?addButton@QMessageBox@@QAEPAVQPushButton@@W4StandardButton@1@@Z @ 2021 NONAME ; class QPushButton * QMessageBox::addButton(enum QMessageBox::StandardButton) ?addButton@QMessageBox@@QAEXPAVQAbstractButton@@W4ButtonRole@1@@Z @ 2022 NONAME ; void QMessageBox::addButton(class QAbstractButton *, enum QMessageBox::ButtonRole) - ?addCacheData@QVectorPath@@QAEPAUCacheEntry@1@PAVQPaintEngineEx@@PAXP6AX1@Z@Z @ 2023 NONAME ; struct QVectorPath::CacheEntry * QVectorPath::addCacheData(class QPaintEngineEx *, void *, void (*)(void *)) + ?addCacheData@QVectorPath@@QAEPAUCacheEntry@1@PAVQPaintEngineEx@@PAXP6AX1@Z@Z @ 2023 NONAME ABSENT ; struct QVectorPath::CacheEntry * QVectorPath::addCacheData(class QPaintEngineEx *, void *, void (*)(void *)) ?addChild@QGraphicsItemPrivate@@QAEXPAVQGraphicsItem@@@Z @ 2024 NONAME ; void QGraphicsItemPrivate::addChild(class QGraphicsItem *) ?addChild@QTreeWidgetItem@@QAEXPAV1@@Z @ 2025 NONAME ; void QTreeWidgetItem::addChild(class QTreeWidgetItem *) ?addChildLayout@QLayout@@IAEXPAV1@@Z @ 2026 NONAME ; void QLayout::addChildLayout(class QLayout *) @@ -3724,7 +3724,7 @@ EXPORTS ?directory@QFileDialog@@QBE?AVQDir@@XZ @ 3723 NONAME ; class QDir QFileDialog::directory(void) const ?directoryEntered@QFileDialog@@IAEXABVQString@@@Z @ 3724 NONAME ; void QFileDialog::directoryEntered(class QString const &) ?dirtyRegionOffset@QAbstractItemView@@IBE?AVQPoint@@XZ @ 3725 NONAME ; class QPoint QAbstractItemView::dirtyRegionOffset(void) const - ?discardUpdateRequest@QGraphicsItemPrivate@@QBE_N_N000@Z @ 3726 NONAME ; bool QGraphicsItemPrivate::discardUpdateRequest(bool, bool, bool, bool) const + ?discardUpdateRequest@QGraphicsItemPrivate@@QBE_N_N000@Z @ 3726 NONAME ABSENT ; bool QGraphicsItemPrivate::discardUpdateRequest(bool, bool, bool, bool) const ?disconnectFromModel@QProxyModel@@IBEXPBVQAbstractItemModel@@@Z @ 3727 NONAME ; void QProxyModel::disconnectFromModel(class QAbstractItemModel const *) const ?dispatchEnterLeave@QApplicationPrivate@@SAXPAVQWidget@@0@Z @ 3728 NONAME ; void QApplicationPrivate::dispatchEnterLeave(class QWidget *, class QWidget *) ?display@QLCDNumber@@QAEXABVQString@@@Z @ 3729 NONAME ; void QLCDNumber::display(class QString const &) @@ -5522,8 +5522,8 @@ EXPORTS ?invalidateBuffer@QWidgetPrivate@@QAEXABVQRect@@@Z @ 5521 NONAME ; void QWidgetPrivate::invalidateBuffer(class QRect const &) ?invalidateBuffer@QWidgetPrivate@@QAEXABVQRegion@@@Z @ 5522 NONAME ; void QWidgetPrivate::invalidateBuffer(class QRegion const &) ?invalidateBuffer_resizeHelper@QWidgetPrivate@@QAEXABVQPoint@@ABVQSize@@@Z @ 5523 NONAME ; void QWidgetPrivate::invalidateBuffer_resizeHelper(class QPoint const &, class QSize const &) - ?invalidateCachedClipPath@QGraphicsItemPrivate@@QAEXXZ @ 5524 NONAME ; void QGraphicsItemPrivate::invalidateCachedClipPath(void) - ?invalidateCachedClipPathRecursively@QGraphicsItemPrivate@@QAEX_NABVQRectF@@@Z @ 5525 NONAME ; void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool, class QRectF const &) + ?invalidateCachedClipPath@QGraphicsItemPrivate@@QAEXXZ @ 5524 NONAME ABSENT ; void QGraphicsItemPrivate::invalidateCachedClipPath(void) + ?invalidateCachedClipPathRecursively@QGraphicsItemPrivate@@QAEX_NABVQRectF@@@Z @ 5525 NONAME ABSENT ; void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool, class QRectF const &) ?invalidateChildrenSceneTransform@QGraphicsItemPrivate@@QAEXXZ @ 5526 NONAME ; void QGraphicsItemPrivate::invalidateChildrenSceneTransform(void) ?invalidateDepthRecursively@QGraphicsItemPrivate@@QAEXXZ @ 5527 NONAME ; void QGraphicsItemPrivate::invalidateDepthRecursively(void) ?invalidateFilter@QSortFilterProxyModel@@IAEXXZ @ 5528 NONAME ; void QSortFilterProxyModel::invalidateFilter(void) @@ -5589,7 +5589,7 @@ EXPORTS ?isClickable@QHeaderView@@QBE_NXZ @ 5588 NONAME ; bool QHeaderView::isClickable(void) const ?isClipEnabled@QPaintEngineState@@QBE_NXZ @ 5589 NONAME ; bool QPaintEngineState::isClipEnabled(void) const ?isClipped@QGraphicsItem@@QBE_NXZ @ 5590 NONAME ; bool QGraphicsItem::isClipped(void) const - ?isClippedAway@QGraphicsItemPrivate@@QBE_NXZ @ 5591 NONAME ; bool QGraphicsItemPrivate::isClippedAway(void) const + ?isClippedAway@QGraphicsItemPrivate@@QBE_NXZ @ 5591 NONAME ABSENT ; bool QGraphicsItemPrivate::isClippedAway(void) const ?isClosed@QPolygonF@@QBE_NXZ @ 5592 NONAME ; bool QPolygonF::isClosed(void) const ?isCollapsible@QSplitter@@QBE_NH@Z @ 5593 NONAME ; bool QSplitter::isCollapsible(int) const ?isColumnHidden@QTableView@@QBE_NH@Z @ 5594 NONAME ; bool QTableView::isColumnHidden(int) const @@ -8586,7 +8586,7 @@ EXPORTS ?setCacheMode@QGraphicsItem@@QAEXW4CacheMode@1@ABVQSize@@@Z @ 8585 NONAME ; void QGraphicsItem::setCacheMode(enum QGraphicsItem::CacheMode, class QSize const &) ?setCacheMode@QGraphicsView@@QAEXV?$QFlags@W4CacheModeFlag@QGraphicsView@@@@@Z @ 8586 NONAME ; void QGraphicsView::setCacheMode(class QFlags<enum QGraphicsView::CacheModeFlag>) ?setCacheMode@QMovie@@QAEXW4CacheMode@1@@Z @ 8587 NONAME ; void QMovie::setCacheMode(enum QMovie::CacheMode) - ?setCachedClipPath@QGraphicsItemPrivate@@QAEXABVQPainterPath@@@Z @ 8588 NONAME ; void QGraphicsItemPrivate::setCachedClipPath(class QPainterPath const &) + ?setCachedClipPath@QGraphicsItemPrivate@@QAEXABVQPainterPath@@@Z @ 8588 NONAME ABSENT ; void QGraphicsItemPrivate::setCachedClipPath(class QPainterPath const &) ?setCalendarPopup@QDateTimeEdit@@QAEX_N@Z @ 8589 NONAME ; void QDateTimeEdit::setCalendarPopup(bool) ?setCalendarWidget@QDateTimeEdit@@QAEXPAVQCalendarWidget@@@Z @ 8590 NONAME ; void QDateTimeEdit::setCalendarWidget(class QCalendarWidget *) ?setCancelButton@QProgressDialog@@QAEXPAVQPushButton@@@Z @ 8591 NONAME ; void QProgressDialog::setCancelButton(class QPushButton *) @@ -8901,8 +8901,8 @@ EXPORTS ?setElementPositionAt@QPainterPath@@QAEXHMM@Z @ 8900 NONAME ; void QPainterPath::setElementPositionAt(int, float, float) ?setElideMode@QTabBar@@QAEXW4TextElideMode@Qt@@@Z @ 8901 NONAME ; void QTabBar::setElideMode(enum Qt::TextElideMode) ?setElideMode@QTabWidget@@QAEXW4TextElideMode@Qt@@@Z @ 8902 NONAME ; void QTabWidget::setElideMode(enum Qt::TextElideMode) - ?setEmptyCachedClipPath@QGraphicsItemPrivate@@QAEXXZ @ 8903 NONAME ; void QGraphicsItemPrivate::setEmptyCachedClipPath(void) - ?setEmptyCachedClipPathRecursively@QGraphicsItemPrivate@@QAEXABVQRectF@@@Z @ 8904 NONAME ; void QGraphicsItemPrivate::setEmptyCachedClipPathRecursively(class QRectF const &) + ?setEmptyCachedClipPath@QGraphicsItemPrivate@@QAEXXZ @ 8903 NONAME ABSENT ; void QGraphicsItemPrivate::setEmptyCachedClipPath(void) + ?setEmptyCachedClipPathRecursively@QGraphicsItemPrivate@@QAEXABVQRectF@@@Z @ 8904 NONAME ABSENT ; void QGraphicsItemPrivate::setEmptyCachedClipPathRecursively(class QRectF const &) ?setEmptyLabel@QUndoView@@QAEXABVQString@@@Z @ 8905 NONAME ; void QUndoView::setEmptyLabel(class QString const &) ?setEnabled@QAction@@QAEX_N@Z @ 8906 NONAME ; void QAction::setEnabled(bool) ?setEnabled@QActionGroup@@QAEX_N@Z @ 8907 NONAME ; void QActionGroup::setEnabled(bool) @@ -11919,7 +11919,7 @@ EXPORTS ?updateBlock@QAbstractTextDocumentLayout@@IAEXABVQTextBlock@@@Z @ 11918 NONAME ; void QAbstractTextDocumentLayout::updateBlock(class QTextBlock const &) ?updateBoundingRect@QGraphicsEffect@@IAEXXZ @ 11919 NONAME ; void QGraphicsEffect::updateBoundingRect(void) ?updateCacheIfNecessary@QWidgetItemV2@@ABEXXZ @ 11920 NONAME ; void QWidgetItemV2::updateCacheIfNecessary(void) const - ?updateCachedClipPathFromSetPosHelper@QGraphicsItemPrivate@@QAEXABVQPointF@@@Z @ 11921 NONAME ; void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(class QPointF const &) + ?updateCachedClipPathFromSetPosHelper@QGraphicsItemPrivate@@QAEXABVQPointF@@@Z @ 11921 NONAME ABSENT ; void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(class QPointF const &) ?updateCell@QCalendarWidget@@IAEXABVQDate@@@Z @ 11922 NONAME ; void QCalendarWidget::updateCell(class QDate const &) ?updateCells@QCalendarWidget@@IAEXXZ @ 11923 NONAME ; void QCalendarWidget::updateCells(void) ?updateDisplayText@QLineControl@@AAEXXZ @ 11924 NONAME ; void QLineControl::updateDisplayText(void) @@ -12517,4 +12517,9 @@ EXPORTS ?effectiveFocusWidget@QWidgetPrivate@@QAEPAVQWidget@@XZ @ 12516 NONAME ; class QWidget * QWidgetPrivate::effectiveFocusWidget(void) ?ignoreUnusedNavigationEvents@QTextControl@@QBE_NXZ @ 12517 NONAME ; bool QTextControl::ignoreUnusedNavigationEvents(void) const ?setIgnoreUnusedNavigationEvents@QTextControl@@QAEX_N@Z @ 12518 NONAME ; void QTextControl::setIgnoreUnusedNavigationEvents(bool) + ?discardUpdateRequest@QGraphicsItemPrivate@@QBE_N_N00@Z @ 12519 NONAME ; bool QGraphicsItemPrivate::discardUpdateRequest(bool, bool, bool) const + ??1QImagePixmapCleanupHooks@@QAE@XZ @ 12520 NONAME ; QImagePixmapCleanupHooks::~QImagePixmapCleanupHooks(void) + ?addCacheData@QVectorPath@@QBEPAUCacheEntry@1@PAVQPaintEngineEx@@PAXP6AX01@Z@Z @ 12521 NONAME ; struct QVectorPath::CacheEntry * QVectorPath::addCacheData(class QPaintEngineEx *, void *, void (*)(class QPaintEngineEx *, void *)) const + ?makeCacheable@QVectorPath@@QBEXXZ @ 12522 NONAME ; void QVectorPath::makeCacheable(void) const + ??1QVectorPath@@QAE@XZ @ 12523 NONAME ; QVectorPath::~QVectorPath(void) diff --git a/src/s60installs/bwins/QtOpenVGu.def b/src/s60installs/bwins/QtOpenVGu.def new file mode 100644 index 0000000..88e724f --- /dev/null +++ b/src/s60installs/bwins/QtOpenVGu.def @@ -0,0 +1,142 @@ +EXPORTS + ?size@QVGPixmapData@@QBE?AVQSize@@XZ @ 1 NONAME ; class QSize QVGPixmapData::size(void) const + ?toVGImage@QVGPixmapData@@UAEKM@Z @ 2 NONAME ; unsigned long QVGPixmapData::toVGImage(float) + ?drawEllipse@QVGPaintEngine@@UAEXABVQRect@@@Z @ 3 NONAME ; void QVGPaintEngine::drawEllipse(class QRect const &) + ?setState@QVGPaintEngine@@UAEXPAVQPainterState@@@Z @ 4 NONAME ; void QVGPaintEngine::setState(class QPainterState *) + ?penChanged@QVGPaintEngine@@UAEXXZ @ 5 NONAME ; void QVGPaintEngine::penChanged(void) + ?defaultClipRegion@QVGPaintEngine@@AAE?AVQRegion@@XZ @ 6 NONAME ; class QRegion QVGPaintEngine::defaultClipRegion(void) + ??0QVGEGLWindowSurfaceVGImage@@QAE@PAVQWindowSurface@@@Z @ 7 NONAME ; QVGEGLWindowSurfaceVGImage::QVGEGLWindowSurfaceVGImage(class QWindowSurface *) + ?paintEngine@QVGPixmapData@@UBEPAVQPaintEngine@@XZ @ 8 NONAME ; class QPaintEngine * QVGPixmapData::paintEngine(void) const + ?drawRoundedRect@QVGPaintEngine@@UAEXABVQRectF@@MMW4SizeMode@Qt@@@Z @ 9 NONAME ; void QVGPaintEngine::drawRoundedRect(class QRectF const &, float, float, enum Qt::SizeMode) + ?qt_vg_image_to_vg_format@@YA?AW4VGImageFormat@@W4Format@QImage@@@Z @ 10 NONAME ; enum VGImageFormat qt_vg_image_to_vg_format(enum QImage::Format) + ?surfaceImage@QVGEGLWindowSurfacePrivate@@UBEKXZ @ 11 NONAME ; unsigned long QVGEGLWindowSurfacePrivate::surfaceImage(void) const + ?state@QVGPaintEngine@@QBEPBVQVGPainterState@@XZ @ 12 NONAME ; class QVGPainterState const * QVGPaintEngine::state(void) const + ??_EQVGEGLWindowSurfaceDirect@@UAE@I@Z @ 13 NONAME ; QVGEGLWindowSurfaceDirect::~QVGEGLWindowSurfaceDirect(unsigned int) + ?updateScissor@QVGPaintEngine@@AAEXXZ @ 14 NONAME ; void QVGPaintEngine::updateScissor(void) + ??_EQVGCompositionHelper@@UAE@I@Z @ 15 NONAME ; QVGCompositionHelper::~QVGCompositionHelper(unsigned int) + ?fill@QVGPixmapData@@UAEXABVQColor@@@Z @ 16 NONAME ; void QVGPixmapData::fill(class QColor const &) + ?toImage@QVGPixmapData@@UBE?AVQImage@@XZ @ 17 NONAME ; class QImage QVGPixmapData::toImage(void) const + ?renderHintsChanged@QVGPaintEngine@@UAEXXZ @ 18 NONAME ; void QVGPaintEngine::renderHintsChanged(void) + ?clearRect@QVGPaintEngine@@AAE_NABVQRectF@@ABVQColor@@@Z @ 19 NONAME ; bool QVGPaintEngine::clearRect(class QRectF const &, class QColor const &) + ??1QVGEGLWindowSurfaceVGImage@@UAE@XZ @ 20 NONAME ; QVGEGLWindowSurfaceVGImage::~QVGEGLWindowSurfaceVGImage(void) + ?state@QVGPaintEngine@@QAEPAVQVGPainterState@@XZ @ 21 NONAME ; class QVGPainterState * QVGPaintEngine::state(void) + ??0QVGPaintEngine@@IAE@AAVQVGPaintEnginePrivate@@@Z @ 22 NONAME ; QVGPaintEngine::QVGPaintEngine(class QVGPaintEnginePrivate &) + ?blitWindow@QVGCompositionHelper@@QAEXKABVQSize@@ABVQRect@@ABVQPoint@@H@Z @ 23 NONAME ; void QVGCompositionHelper::blitWindow(unsigned long, class QSize const &, class QRect const &, class QPoint const &, int) + ?ensureContext@QVGEGLWindowSurfaceVGImage@@UAEPAVQEglContext@@PAVQWidget@@@Z @ 24 NONAME ; class QEglContext * QVGEGLWindowSurfaceVGImage::ensureContext(class QWidget *) + ??0QVGCompositionHelper@@QAE@XZ @ 25 NONAME ; QVGCompositionHelper::QVGCompositionHelper(void) + ?sourceFormat@QVGPixmapData@@IBE?AW4Format@QImage@@XZ @ 26 NONAME ; enum QImage::Format QVGPixmapData::sourceFormat(void) const + ?beginNativePainting@QVGPaintEngine@@UAEXXZ @ 27 NONAME ; void QVGPaintEngine::beginNativePainting(void) + ?clipEnabledChanged@QVGPaintEngine@@UAEXXZ @ 28 NONAME ; void QVGPaintEngine::clipEnabledChanged(void) + ?metric@QVGPixmapData@@MBEHW4PaintDeviceMetric@QPaintDevice@@@Z @ 29 NONAME ; int QVGPixmapData::metric(enum QPaintDevice::PaintDeviceMetric) const + ?draw@QVGPaintEngine@@UAEXABVQVectorPath@@@Z @ 30 NONAME ; void QVGPaintEngine::draw(class QVectorPath const &) + ?drawRects@QVGPaintEngine@@UAEXPBVQRect@@H@Z @ 31 NONAME ; void QVGPaintEngine::drawRects(class QRect const *, int) + ??0QVGPixmapData@@QAE@W4PixelType@QPixmapData@@@Z @ 32 NONAME ; QVGPixmapData::QVGPixmapData(enum QPixmapData::PixelType) + ??0QVGWindowSurface@@QAE@PAVQWidget@@PAVQVGEGLWindowSurfacePrivate@@@Z @ 33 NONAME ; QVGWindowSurface::QVGWindowSurface(class QWidget *, class QVGEGLWindowSurfacePrivate *) + ?fillBackground@QVGCompositionHelper@@QAEXABVQRegion@@ABVQBrush@@@Z @ 34 NONAME ; void QVGCompositionHelper::fillBackground(class QRegion const &, class QBrush const &) + ?drawLines@QVGPaintEngine@@UAEXPBVQLine@@H@Z @ 35 NONAME ; void QVGPaintEngine::drawLines(class QLine const *, int) + ?ensureContext@QVGEGLWindowSurfaceDirect@@UAEPAVQEglContext@@PAVQWidget@@@Z @ 36 NONAME ; class QEglContext * QVGEGLWindowSurfaceDirect::ensureContext(class QWidget *) + ??0QVGPaintEngine@@QAE@XZ @ 37 NONAME ; QVGPaintEngine::QVGPaintEngine(void) + ?cleanup@QVGPixmapData@@IAEXXZ @ 38 NONAME ; void QVGPixmapData::cleanup(void) + ?drawPixmap@QVGPaintEngine@@UAEXABVQPointF@@ABVQPixmap@@@Z @ 39 NONAME ; void QVGPaintEngine::drawPixmap(class QPointF const &, class QPixmap const &) + ?drawImage@QVGPaintEngine@@UAEXABVQRectF@@ABVQImage@@0V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 40 NONAME ; void QVGPaintEngine::drawImage(class QRectF const &, class QImage const &, class QRectF const &, class QFlags<enum Qt::ImageConversionFlag>) + ?drawTiledPixmap@QVGPaintEngine@@UAEXABVQRectF@@ABVQPixmap@@ABVQPointF@@@Z @ 41 NONAME ; void QVGPaintEngine::drawTiledPixmap(class QRectF const &, class QPixmap const &, class QPointF const &) + ?drawEllipse@QVGPaintEngine@@UAEXABVQRectF@@@Z @ 42 NONAME ; void QVGPaintEngine::drawEllipse(class QRectF const &) + ?endCompositing@QVGCompositionHelper@@QAEXXZ @ 43 NONAME ; void QVGCompositionHelper::endCompositing(void) + ??_EQVGEGLWindowSurfaceVGImage@@UAE@I@Z @ 44 NONAME ; QVGEGLWindowSurfaceVGImage::~QVGEGLWindowSurfaceVGImage(unsigned int) + ?begin@QVGPaintEngine@@UAE_NPAVQPaintDevice@@@Z @ 45 NONAME ; bool QVGPaintEngine::begin(class QPaintDevice *) + ?fillRect@QVGPaintEngine@@UAEXABVQRectF@@ABVQBrush@@@Z @ 46 NONAME ; void QVGPaintEngine::fillRect(class QRectF const &, class QBrush const &) + ?paintEngine@QVGWindowSurface@@UBEPAVQPaintEngine@@XZ @ 47 NONAME ; class QPaintEngine * QVGWindowSurface::paintEngine(void) const + ??0QVGPainterState@@QAE@XZ @ 48 NONAME ; QVGPainterState::QVGPainterState(void) + ?d_func@QVGPaintEngine@@ABEPBVQVGPaintEnginePrivate@@XZ @ 49 NONAME ; class QVGPaintEnginePrivate const * QVGPaintEngine::d_func(void) const + ?qt_vg_create_context@@YAPAVQEglContext@@PAVQPaintDevice@@@Z @ 50 NONAME ; class QEglContext * qt_vg_create_context(class QPaintDevice *) + ?clip@QVGPaintEngine@@UAEXABVQRegion@@W4ClipOperation@Qt@@@Z @ 51 NONAME ; void QVGPaintEngine::clip(class QRegion const &, enum Qt::ClipOperation) + ?endNativePainting@QVGPaintEngine@@UAEXXZ @ 52 NONAME ; void QVGPaintEngine::endNativePainting(void) + ?brushChanged@QVGPaintEngine@@UAEXXZ @ 53 NONAME ; void QVGPaintEngine::brushChanged(void) + ?setGeometry@QVGWindowSurface@@UAEXABVQRect@@@Z @ 54 NONAME ; void QVGWindowSurface::setGeometry(class QRect const &) + ?createCompatiblePixmapData@QVGPixmapData@@UBEPAVQPixmapData@@XZ @ 55 NONAME ; class QPixmapData * QVGPixmapData::createCompatiblePixmapData(void) const + ?endPaint@QVGWindowSurface@@UAEXABVQRegion@@@Z @ 56 NONAME ; void QVGWindowSurface::endPaint(class QRegion const &) + ?resize@QVGPixmapData@@UAEXHH@Z @ 57 NONAME ; void QVGPixmapData::resize(int, int) + ?mainSurface@QVGEGLWindowSurfaceVGImage@@IBEHXZ @ 58 NONAME ; int QVGEGLWindowSurfaceVGImage::mainSurface(void) const + ??0QVGEGLWindowSurfaceDirect@@QAE@PAVQWindowSurface@@@Z @ 59 NONAME ; QVGEGLWindowSurfaceDirect::QVGEGLWindowSurfaceDirect(class QWindowSurface *) + ?clip@QVGPaintEngine@@UAEXABVQRect@@W4ClipOperation@Qt@@@Z @ 60 NONAME ; void QVGPaintEngine::clip(class QRect const &, enum Qt::ClipOperation) + ?fillRegion@QVGPaintEngine@@QAEXABVQRegion@@ABVQColor@@ABVQSize@@@Z @ 61 NONAME ; void QVGPaintEngine::fillRegion(class QRegion const &, class QColor const &, class QSize const &) + ?surfaceSize@QVGEGLWindowSurfaceDirect@@UBE?AVQSize@@XZ @ 62 NONAME ; class QSize QVGEGLWindowSurfaceDirect::surfaceSize(void) const + ?drawPoints@QVGPaintEngine@@UAEXPBVQPointF@@H@Z @ 63 NONAME ; void QVGPaintEngine::drawPoints(class QPointF const *, int) + ?paintEngine@QVGEGLWindowSurfacePrivate@@QAEPAVQVGPaintEngine@@XZ @ 64 NONAME ; class QVGPaintEngine * QVGEGLWindowSurfacePrivate::paintEngine(void) + ?stroke@QVGPaintEngine@@UAEXABVQVectorPath@@ABVQPen@@@Z @ 65 NONAME ; void QVGPaintEngine::stroke(class QVectorPath const &, class QPen const &) + ??0QVGPainterState@@QAE@AAV0@@Z @ 66 NONAME ; QVGPainterState::QVGPainterState(class QVGPainterState &) + ?startCompositing@QVGCompositionHelper@@QAEXABVQSize@@@Z @ 67 NONAME ; void QVGCompositionHelper::startCompositing(class QSize const &) + ??1QVGEGLWindowSurfacePrivate@@UAE@XZ @ 68 NONAME ; QVGEGLWindowSurfacePrivate::~QVGEGLWindowSurfacePrivate(void) + ?qt_vg_destroy_paint_engine@@YAXPAVQVGPaintEngine@@@Z @ 69 NONAME ; void qt_vg_destroy_paint_engine(class QVGPaintEngine *) + ?compositionModeChanged@QVGPaintEngine@@UAEXXZ @ 70 NONAME ; void QVGPaintEngine::compositionModeChanged(void) + ?type@QVGPaintEngine@@UBE?AW4Type@QPaintEngine@@XZ @ 71 NONAME ; enum QPaintEngine::Type QVGPaintEngine::type(void) const + ?fillRect@QVGPaintEngine@@UAEXABVQRectF@@ABVQColor@@@Z @ 72 NONAME ; void QVGPaintEngine::fillRect(class QRectF const &, class QColor const &) + ??0QVGEGLWindowSurfacePrivate@@QAE@PAVQWindowSurface@@@Z @ 73 NONAME ; QVGEGLWindowSurfacePrivate::QVGEGLWindowSurfacePrivate(class QWindowSurface *) + ?drawImage@QVGPaintEngine@@UAEXABVQPointF@@ABVQImage@@@Z @ 74 NONAME ; void QVGPaintEngine::drawImage(class QPointF const &, class QImage const &) + ?flush@QVGWindowSurface@@UAEXPAVQWidget@@ABVQRegion@@ABVQPoint@@@Z @ 75 NONAME ; void QVGWindowSurface::flush(class QWidget *, class QRegion const &, class QPoint const &) + ?isValid@QVGPixmapData@@QBE_NXZ @ 76 NONAME ; bool QVGPixmapData::isValid(void) const + ?beginPaint@QVGEGLWindowSurfaceVGImage@@UAEXPAVQWidget@@@Z @ 77 NONAME ; void QVGEGLWindowSurfaceVGImage::beginPaint(class QWidget *) + ?createState@QVGPaintEngine@@UBEPAVQPainterState@@PAV2@@Z @ 78 NONAME ; class QPainterState * QVGPaintEngine::createState(class QPainterState *) const + ?buffer@QVGPixmapData@@UAEPAVQImage@@XZ @ 79 NONAME ; class QImage * QVGPixmapData::buffer(void) + ?qt_vg_destroy_context@@YAXPAVQEglContext@@@Z @ 80 NONAME ; void qt_vg_destroy_context(class QEglContext *) + ?clip@QVGPaintEngine@@UAEXABVQVectorPath@@W4ClipOperation@Qt@@@Z @ 81 NONAME ; void QVGPaintEngine::clip(class QVectorPath const &, enum Qt::ClipOperation) + ?drawPolygon@QVGPaintEngine@@UAEXPBVQPoint@@HW4PolygonDrawMode@QPaintEngine@@@Z @ 82 NONAME ; void QVGPaintEngine::drawPolygon(class QPoint const *, int, enum QPaintEngine::PolygonDrawMode) + ?fromImage@QVGPixmapData@@UAEXABVQImage@@V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 83 NONAME ; void QVGPixmapData::fromImage(class QImage const &, class QFlags<enum Qt::ImageConversionFlag>) + ??1QVGPainterState@@UAE@XZ @ 84 NONAME ; QVGPainterState::~QVGPainterState(void) + ??1QVGPaintEngine@@UAE@XZ @ 85 NONAME ; QVGPaintEngine::~QVGPaintEngine(void) + ?hasAlphaChannel@QVGPixmapData@@UBE_NXZ @ 86 NONAME ; bool QVGPixmapData::hasAlphaChannel(void) const + ?endPaint@QVGEGLWindowSurfaceVGImage@@UAEXPAVQWidget@@ABVQRegion@@PAVQImage@@@Z @ 87 NONAME ; void QVGEGLWindowSurfaceVGImage::endPaint(class QWidget *, class QRegion const &, class QImage *) + ?beginPaint@QVGEGLWindowSurfaceDirect@@UAEXPAVQWidget@@@Z @ 88 NONAME ; void QVGEGLWindowSurfaceDirect::beginPaint(class QWidget *) + ?qt_vg_config_to_image_format@@YA?AW4Format@QImage@@PAVQEglContext@@@Z @ 89 NONAME ; enum QImage::Format qt_vg_config_to_image_format(class QEglContext *) + ?qt_vg_config_to_vg_format@@YA?AW4VGImageFormat@@PAVQEglContext@@@Z @ 90 NONAME ; enum VGImageFormat qt_vg_config_to_vg_format(class QEglContext *) + ?setScissor@QVGCompositionHelper@@QAEXABVQRegion@@@Z @ 91 NONAME ; void QVGCompositionHelper::setScissor(class QRegion const &) + ?drawPath@QVGPaintEngine@@UAEXABVQPainterPath@@@Z @ 92 NONAME ; void QVGPaintEngine::drawPath(class QPainterPath const &) + ?drawLines@QVGPaintEngine@@UAEXPBVQLineF@@H@Z @ 93 NONAME ; void QVGPaintEngine::drawLines(class QLineF const *, int) + ?toNativeType@QVGPixmapData@@UAEPAXW4NativeType@QPixmapData@@@Z @ 94 NONAME ; void * QVGPixmapData::toNativeType(enum QPixmapData::NativeType) + ??1QVGWindowSurface@@UAE@XZ @ 95 NONAME ; QVGWindowSurface::~QVGWindowSurface(void) + ?metric@QVGWindowSurface@@MBEHW4PaintDeviceMetric@QPaintDevice@@@Z @ 96 NONAME ; int QVGWindowSurface::metric(enum QPaintDevice::PaintDeviceMetric) const + ??1QVGPixmapData@@UAE@XZ @ 97 NONAME ; QVGPixmapData::~QVGPixmapData(void) + ??1QVGEGLWindowSurfaceDirect@@UAE@XZ @ 98 NONAME ; QVGEGLWindowSurfaceDirect::~QVGEGLWindowSurfaceDirect(void) + ??_EQVGPixmapData@@UAE@I@Z @ 99 NONAME ; QVGPixmapData::~QVGPixmapData(unsigned int) + ?restoreState@QVGPaintEngine@@AAEXV?$QFlags@W4DirtyFlag@QPaintEngine@@@@@Z @ 100 NONAME ; void QVGPaintEngine::restoreState(class QFlags<enum QPaintEngine::DirtyFlag>) + ??1QVGCompositionHelper@@UAE@XZ @ 101 NONAME ; QVGCompositionHelper::~QVGCompositionHelper(void) + ??0QVGWindowSurface@@QAE@PAVQWidget@@@Z @ 102 NONAME ; QVGWindowSurface::QVGWindowSurface(class QWidget *) + ?isDefaultClipRegion@QVGPaintEngine@@AAE_NABVQRegion@@@Z @ 103 NONAME ; bool QVGPaintEngine::isDefaultClipRegion(class QRegion const &) + ?transformChanged@QVGPaintEngine@@UAEXXZ @ 104 NONAME ; void QVGPaintEngine::transformChanged(void) + ?fromNativeType@QVGPixmapData@@UAEXPAXW4NativeType@QPixmapData@@@Z @ 105 NONAME ; void QVGPixmapData::fromNativeType(void *, enum QPixmapData::NativeType) + ?setAlphaChannel@QVGPixmapData@@UAEXABVQPixmap@@@Z @ 106 NONAME ; void QVGPixmapData::setAlphaChannel(class QPixmap const &) + ??_EQVGWindowSurface@@UAE@I@Z @ 107 NONAME ; QVGWindowSurface::~QVGWindowSurface(unsigned int) + ?qPixmapToVGImage@@YAKABVQPixmap@@@Z @ 108 NONAME ; unsigned long qPixmapToVGImage(class QPixmap const &) + ?opacityChanged@QVGPaintEngine@@UAEXXZ @ 109 NONAME ; void QVGPaintEngine::opacityChanged(void) + ?surfaceSize@QVGEGLWindowSurfaceVGImage@@UBE?AVQSize@@XZ @ 110 NONAME ; class QSize QVGEGLWindowSurfaceVGImage::surfaceSize(void) const + ?paintDevice@QVGWindowSurface@@UAEPAVQPaintDevice@@XZ @ 111 NONAME ; class QPaintDevice * QVGWindowSurface::paintDevice(void) + ?qt_vg_create_paint_engine@@YAPAVQVGPaintEngine@@XZ @ 112 NONAME ; class QVGPaintEngine * qt_vg_create_paint_engine(void) + ?drawPixmap@QVGPaintEngine@@UAEXABVQRectF@@ABVQPixmap@@0@Z @ 113 NONAME ; void QVGPaintEngine::drawPixmap(class QRectF const &, class QPixmap const &, class QRectF const &) + ?beginPaint@QVGWindowSurface@@UAEXABVQRegion@@@Z @ 114 NONAME ; void QVGWindowSurface::beginPaint(class QRegion const &) + ??_EQVGEGLWindowSurfacePrivate@@UAE@I@Z @ 115 NONAME ; QVGEGLWindowSurfacePrivate::~QVGEGLWindowSurfacePrivate(unsigned int) + ?endPaint@QVGEGLWindowSurfaceDirect@@UAEXPAVQWidget@@ABVQRegion@@PAVQImage@@@Z @ 116 NONAME ; void QVGEGLWindowSurfaceDirect::endPaint(class QWidget *, class QRegion const &, class QImage *) + ?scroll@QVGWindowSurface@@UAE_NABVQRegion@@HH@Z @ 117 NONAME ; bool QVGWindowSurface::scroll(class QRegion const &, int, int) + ?surfaceImage@QVGEGLWindowSurfaceVGImage@@UBEKXZ @ 118 NONAME ; unsigned long QVGEGLWindowSurfaceVGImage::surfaceImage(void) const + ?isDefaultClipRect@QVGPaintEngine@@AAE_NABVQRect@@@Z @ 119 NONAME ; bool QVGPaintEngine::isDefaultClipRect(class QRect const &) + ?windowSurfaceSize@QVGEGLWindowSurfacePrivate@@IBE?AVQSize@@PAVQWidget@@@Z @ 120 NONAME ; class QSize QVGEGLWindowSurfacePrivate::windowSurfaceSize(class QWidget *) const + ?pixmapFilter@QVGPaintEngine@@UAEPAVQPixmapFilter@@HPBV2@@Z @ 121 NONAME ; class QPixmapFilter * QVGPaintEngine::pixmapFilter(int, class QPixmapFilter const *) + ?destroyPaintEngine@QVGEGLWindowSurfacePrivate@@IAEXXZ @ 122 NONAME ; void QVGEGLWindowSurfacePrivate::destroyPaintEngine(void) + ?qt_vg_shared_surface@@YAHXZ @ 123 NONAME ; int qt_vg_shared_surface(void) + ?drawCursorPixmap@QVGCompositionHelper@@QAEXABVQPixmap@@ABVQPoint@@@Z @ 124 NONAME ; void QVGCompositionHelper::drawCursorPixmap(class QPixmap const &, class QPoint const &) + ?drawPixmaps@QVGPaintEngine@@UAEXPBUData@QDrawPixmaps@@HABVQPixmap@@V?$QFlags@W4DrawingHint@QDrawPixmaps@@@@@Z @ 125 NONAME ; void QVGPaintEngine::drawPixmaps(struct QDrawPixmaps::Data const *, int, class QPixmap const &, class QFlags<enum QDrawPixmaps::DrawingHint>) + ?drawPolygon@QVGPaintEngine@@UAEXPBVQPointF@@HW4PolygonDrawMode@QPaintEngine@@@Z @ 126 NONAME ; void QVGPaintEngine::drawPolygon(class QPointF const *, int, enum QPaintEngine::PolygonDrawMode) + ?toVGImage@QVGPixmapData@@UAEKXZ @ 127 NONAME ; unsigned long QVGPixmapData::toVGImage(void) + ?end@QVGPaintEngine@@UAE_NXZ @ 128 NONAME ; bool QVGPaintEngine::end(void) + ??_EQVGPainterState@@UAE@I@Z @ 129 NONAME ; QVGPainterState::~QVGPainterState(unsigned int) + ?drawRects@QVGPaintEngine@@UAEXPBVQRectF@@H@Z @ 130 NONAME ; void QVGPaintEngine::drawRects(class QRectF const *, int) + ?d_func@QVGPaintEngine@@AAEPAVQVGPaintEnginePrivate@@XZ @ 131 NONAME ; class QVGPaintEnginePrivate * QVGPaintEngine::d_func(void) + ?brushOriginChanged@QVGPaintEngine@@UAEXXZ @ 132 NONAME ; void QVGPaintEngine::brushOriginChanged(void) + ?drawTextItem@QVGPaintEngine@@UAEXABVQPointF@@ABVQTextItem@@@Z @ 133 NONAME ; void QVGPaintEngine::drawTextItem(class QPointF const &, class QTextItem const &) + ?clearScissor@QVGCompositionHelper@@QAEXXZ @ 134 NONAME ; void QVGCompositionHelper::clearScissor(void) + ?fill@QVGPaintEngine@@UAEXABVQVectorPath@@ABVQBrush@@@Z @ 135 NONAME ; void QVGPaintEngine::fill(class QVectorPath const &, class QBrush const &) + ?forceToImage@QVGPixmapData@@IAEXXZ @ 136 NONAME ; void QVGPixmapData::forceToImage(void) + ?drawPoints@QVGPaintEngine@@UAEXPBVQPoint@@H@Z @ 137 NONAME ; void QVGPaintEngine::drawPoints(class QPoint const *, int) + ??_EQVGPaintEngine@@UAE@I@Z @ 138 NONAME ; QVGPaintEngine::~QVGPaintEngine(unsigned int) + ?clip@QVGPaintEngine@@UAEXABVQPainterPath@@W4ClipOperation@Qt@@@Z @ 139 NONAME ; void QVGPaintEngine::clip(class QPainterPath const &, enum Qt::ClipOperation) + ?vgPrivate@QVGPaintEngine@@QAEPAVQVGPaintEnginePrivate@@XZ @ 140 NONAME ; class QVGPaintEnginePrivate * QVGPaintEngine::vgPrivate(void) + diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def index 6a4cdbd..89fa76f 100644 --- a/src/s60installs/eabi/QtCoreu.def +++ b/src/s60installs/eabi/QtCoreu.def @@ -2556,7 +2556,7 @@ EXPORTS _ZNK14QObjectPrivate10senderListEv @ 2555 NONAME _ZNK14QObjectPrivate11signalIndexEPKc @ 2556 NONAME _ZNK14QObjectPrivate12receiverListEPKc @ 2557 NONAME - _ZNK14QObjectPrivate17isSignalConnectedEi @ 2558 NONAME + _ZNK14QObjectPrivate17isSignalConnectedEi @ 2558 NONAME ABSENT _ZNK14QObjectPrivate8isSenderEPK7QObjectPKc @ 2559 NONAME _ZNK14QStringMatcher7indexInEPK5QCharii @ 2560 NONAME _ZNK14QStringMatcher7indexInERK7QStringi @ 2561 NONAME diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index 6c45a6e..429ca79 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -4680,9 +4680,9 @@ EXPORTS _ZN20QGraphicsItemPrivate28ensureSequentialSiblingIndexEv @ 4679 NONAME _ZN20QGraphicsItemPrivate29ensureSceneTransformRecursiveEPP13QGraphicsItem @ 4680 NONAME _ZN20QGraphicsItemPrivate30updateSceneTransformFromParentEv @ 4681 NONAME - _ZN20QGraphicsItemPrivate33setEmptyCachedClipPathRecursivelyERK6QRectF @ 4682 NONAME - _ZN20QGraphicsItemPrivate35invalidateCachedClipPathRecursivelyEbRK6QRectF @ 4683 NONAME - _ZN20QGraphicsItemPrivate36updateCachedClipPathFromSetPosHelperERK7QPointF @ 4684 NONAME + _ZN20QGraphicsItemPrivate33setEmptyCachedClipPathRecursivelyERK6QRectF @ 4682 NONAME ABSENT + _ZN20QGraphicsItemPrivate35invalidateCachedClipPathRecursivelyEbRK6QRectF @ 4683 NONAME ABSENT + _ZN20QGraphicsItemPrivate36updateCachedClipPathFromSetPosHelperERK7QPointF @ 4684 NONAME ABSENT _ZN20QGraphicsItemPrivate8addChildEP13QGraphicsItem @ 4685 NONAME _ZN20QGraphicsPolygonItem10setPolygonERK9QPolygonF @ 4686 NONAME _ZN20QGraphicsPolygonItem11setFillRuleEN2Qt8FillRuleE @ 4687 NONAME @@ -5221,8 +5221,8 @@ EXPORTS _ZN24QImagePixmapCleanupHooks17executeImageHooksEx @ 5220 NONAME _ZN24QImagePixmapCleanupHooks18executePixmapHooksEP7QPixmap @ 5221 NONAME ABSENT _ZN24QImagePixmapCleanupHooks8instanceEv @ 5222 NONAME - _ZN24QImagePixmapCleanupHooksC1Ev @ 5223 NONAME - _ZN24QImagePixmapCleanupHooksC2Ev @ 5224 NONAME + _ZN24QImagePixmapCleanupHooksC1Ev @ 5223 NONAME ABSENT + _ZN24QImagePixmapCleanupHooksC2Ev @ 5224 NONAME ABSENT _ZN24QPixmapConvolutionFilter11qt_metacallEN11QMetaObject4CallEiPPv @ 5225 NONAME _ZN24QPixmapConvolutionFilter11qt_metacastEPKc @ 5226 NONAME _ZN24QPixmapConvolutionFilter16staticMetaObjectE @ 5227 NONAME DATA 16 @@ -9388,7 +9388,7 @@ EXPORTS _ZNK20QGraphicsItemPrivate15initStyleOptionEP24QStyleOptionGraphicsItemRK10QTransformRK7QRegionb @ 9387 NONAME _ZNK20QGraphicsItemPrivate19genericMapFromSceneERK7QPointFPK7QWidget @ 9388 NONAME _ZNK20QGraphicsItemPrivate19maybeExtraItemCacheEv @ 9389 NONAME - _ZNK20QGraphicsItemPrivate20discardUpdateRequestEbbbb @ 9390 NONAME + _ZNK20QGraphicsItemPrivate20discardUpdateRequestEbbbb @ 9390 NONAME ABSENT _ZNK20QGraphicsItemPrivate21effectiveBoundingRectEv @ 9391 NONAME _ZNK20QGraphicsItemPrivate22inputMethodQueryHelperEN2Qt16InputMethodQueryE @ 9392 NONAME _ZNK20QGraphicsItemPrivate24combineTransformToParentEP10QTransformPKS0_ @ 9393 NONAME @@ -11571,7 +11571,7 @@ EXPORTS _ZN11QTapGesture19getStaticMetaObjectEv @ 11570 NONAME _ZN11QTapGestureC1EP7QObject @ 11571 NONAME _ZN11QTapGestureC2EP7QObject @ 11572 NONAME - _ZN11QVectorPath12addCacheDataEP14QPaintEngineExPvPFvS2_E @ 11573 NONAME + _ZN11QVectorPath12addCacheDataEP14QPaintEngineExPvPFvS2_E @ 11573 NONAME ABSENT _ZN12QApplication18symbianEventFilterEPK13QSymbianEvent @ 11574 NONAME _ZN12QApplication19symbianProcessEventEPK13QSymbianEvent @ 11575 NONAME _ZN13QGestureEvent11setAcceptedEN2Qt11GestureTypeEb @ 11576 NONAME @@ -11737,4 +11737,8 @@ EXPORTS _Zls6QDebugRKN12QStyleOption10OptionTypeE @ 11736 NONAME _ZN12QTextControl31setIgnoreUnusedNavigationEventsEb @ 11737 NONAME _ZNK12QTextControl28ignoreUnusedNavigationEventsEv @ 11738 NONAME + _ZN11QVectorPathD1Ev @ 11739 NONAME + _ZN11QVectorPathD2Ev @ 11740 NONAME + _ZNK11QVectorPath12addCacheDataEP14QPaintEngineExPvPFvS1_S2_E @ 11741 NONAME + _ZNK20QGraphicsItemPrivate20discardUpdateRequestEbbb @ 11742 NONAME diff --git a/src/s60installs/eabi/QtOpenVGu.def b/src/s60installs/eabi/QtOpenVGu.def index 776fc4b..8458983 100644 --- a/src/s60installs/eabi/QtOpenVGu.def +++ b/src/s60installs/eabi/QtOpenVGu.def @@ -99,7 +99,7 @@ EXPORTS _ZN16QVGWindowSurfaceD0Ev @ 98 NONAME _ZN16QVGWindowSurfaceD1Ev @ 99 NONAME _ZN16QVGWindowSurfaceD2Ev @ 100 NONAME - _ZN20QVGCompositionHelper10blitWindowEP26QVGEGLWindowSurfacePrivateRK5QRectRK6QPointi @ 101 NONAME + _ZN20QVGCompositionHelper10blitWindowEP26QVGEGLWindowSurfacePrivateRK5QRectRK6QPointi @ 101 NONAME ABSENT _ZN20QVGCompositionHelper10setScissorERK7QRegion @ 102 NONAME _ZN20QVGCompositionHelper12clearScissorEv @ 103 NONAME _ZN20QVGCompositionHelper14endCompositingEv @ 104 NONAME @@ -167,4 +167,6 @@ EXPORTS _ZThn8_N16QVGWindowSurfaceD1Ev @ 166 NONAME _ZThn8_NK16QVGWindowSurface11paintEngineEv @ 167 NONAME _ZThn8_NK16QVGWindowSurface6metricEN12QPaintDevice17PaintDeviceMetricE @ 168 NONAME + _ZN14QVGPaintEngine10fillRegionERK7QRegionRK6QColorRK5QSize @ 169 NONAME + _ZN20QVGCompositionHelper10blitWindowEmRK5QSizeRK5QRectRK6QPointi @ 170 NONAME diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index 2d9c489..37adfa9 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -90,7 +90,7 @@ symbian: { } contains(QT_CONFIG, phonon): { - qtlibraries.sources += Phonon.dll + qtlibraries.sources += phonon.dll } contains(QT_CONFIG, script): { diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index dc0e0d0..b6aa872 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -1101,16 +1101,6 @@ void QScriptEnginePrivate::mark(JSC::MarkStack& markStack) } } -#ifndef QT_NO_QOBJECT - { - QHash<QObject*, QScript::QObjectData*>::const_iterator it; - for (it = m_qobjectData.constBegin(); it != m_qobjectData.constEnd(); ++it) { - QScript::QObjectData *qdata = it.value(); - qdata->mark(markStack); - } - } -#endif - { QHash<int, QScriptTypeInfo*>::const_iterator it; for (it = m_typeInfos.constBegin(); it != m_typeInfos.constEnd(); ++it) { @@ -1134,6 +1124,17 @@ void QScriptEnginePrivate::mark(JSC::MarkStack& markStack) context = context->parentContext(); } } + +#ifndef QT_NO_QOBJECT + markStack.drain(); // make sure everything is marked before marking qobject data + { + QHash<QObject*, QScript::QObjectData*>::const_iterator it; + for (it = m_qobjectData.constBegin(); it != m_qobjectData.constEnd(); ++it) { + QScript::QObjectData *qdata = it.value(); + qdata->mark(markStack); + } + } +#endif } bool QScriptEnginePrivate::isCollecting() const diff --git a/src/script/api/qscriptengineagent.cpp b/src/script/api/qscriptengineagent.cpp index e7998b7..a2af514 100644 --- a/src/script/api/qscriptengineagent.cpp +++ b/src/script/api/qscriptengineagent.cpp @@ -154,7 +154,10 @@ void QScriptEngineAgentPrivate::exceptionCatch(const JSC::DebuggerCallFrame& fra void QScriptEngineAgentPrivate::atStatement(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno, int column) { QScript::UStringSourceProviderWithFeedback *source = engine->loadedScripts.value(sourceID); - Q_ASSERT(source != 0); + if (!source) { + // QTBUG-6108: We don't have the source for this script, so ignore. + return; + } column = source->columnNumberFromOffset(column); JSC::CallFrame *oldFrame = engine->currentFrame; int oldAgentLineNumber = engine->agentLineNumber; @@ -183,7 +186,10 @@ void QScriptEngineAgentPrivate::didReachBreakpoint(const JSC::DebuggerCallFrame& { if (q_ptr->supportsExtension(QScriptEngineAgent::DebuggerInvocationRequest)) { QScript::UStringSourceProviderWithFeedback *source = engine->loadedScripts.value(sourceID); - Q_ASSERT(source != 0); + if (!source) { + // QTBUG-6108: We don't have the source for this script, so ignore. + return; + } column = source->columnNumberFromOffset(column); JSC::CallFrame *oldFrame = engine->currentFrame; int oldAgentLineNumber = engine->agentLineNumber; diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp index 559fcd3..63ba9ec 100644 --- a/src/script/bridge/qscriptqobject.cpp +++ b/src/script/bridge/qscriptqobject.cpp @@ -83,22 +83,23 @@ struct QObjectConnection void mark(JSC::MarkStack& markStack) { - // ### need to find out if senderWrapper is marked if (senderWrapper) { - // see if the sender should be marked or not + // see if the sender should be marked or not; + // if the C++ object is owned by script, we don't want + // it to stay alive due to a script connection. Q_ASSERT(senderWrapper.inherits(&QScriptObject::info)); QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(senderWrapper)); - QScriptObjectDelegate *delegate = scriptObject->delegate(); - Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::QtObject)); - QObjectDelegate *inst = static_cast<QObjectDelegate*>(delegate); - if ((inst->ownership() == QScriptEngine::ScriptOwnership) - || ((inst->ownership() == QScriptEngine::AutoOwnership) - && inst->value() && !inst->value()->parent())) { - // #### don't mark if not marked otherwise - //senderWrapper = JSC::JSValue(); - markStack.append(senderWrapper); - } else { - markStack.append(senderWrapper); + if (!JSC::Heap::isCellMarked(scriptObject)) { + QScriptObjectDelegate *delegate = scriptObject->delegate(); + Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::QtObject)); + QObjectDelegate *inst = static_cast<QObjectDelegate*>(delegate); + if ((inst->ownership() == QScriptEngine::ScriptOwnership) + || ((inst->ownership() == QScriptEngine::AutoOwnership) + && inst->value() && !inst->value()->parent())) { + senderWrapper = JSC::JSValue(); + } else { + markStack.append(senderWrapper); + } } } if (receiver) diff --git a/src/script/script.pro b/src/script/script.pro index 008c556..771047a 100644 --- a/src/script/script.pro +++ b/src/script/script.pro @@ -1,7 +1,7 @@ TARGET = QtScript QPRO_PWD = $$PWD QT = core -DEFINES += JSC=QTJSC jscyyparse=qtjscyyparse jscyylex=qtjscyylex jscyyerror=qtjscyyerror +DEFINES += JSC=QTJSC jscyyparse=qtjscyyparse jscyylex=qtjscyylex jscyyerror=qtjscyyerror WTF=QTWTF DEFINES += QT_BUILD_SCRIPT_LIB DEFINES += QT_NO_USING_NAMESPACE DEFINES += QLALR_NO_QSCRIPTGRAMMAR_DEBUG_INFO diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp index 3f13405..5d039cf 100644 --- a/src/sql/drivers/db2/qsql_db2.cpp +++ b/src/sql/drivers/db2/qsql_db2.cpp @@ -1025,7 +1025,6 @@ QVariant QDB2Result::data(int field) break; case QVariant::Double: { - QString value=qGetStringData(d->hStmt, field, info.length() + 1, isNull); switch(numericalPrecisionPolicy()) { case QSql::LowPrecisionInt32: v = new QVariant(qGetIntData(d->hStmt, field, isNull)); diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index f368d1d..b74babc 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -509,15 +509,24 @@ bool QMYSQLResult::fetchNext() return false; if (d->preparedQuery) { #if MYSQL_VERSION_ID >= 40108 - if (mysql_stmt_fetch(d->stmt)) + int nRC = mysql_stmt_fetch(d->stmt); + if (nRC) { +#ifdef MYSQL_DATA_TRUNCATED + if (nRC == 1 || nRC == MYSQL_DATA_TRUNCATED) +#else + if (nRC == 1) +#endif // MYSQL_DATA_TRUNCATED + setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult", + "Unable to fetch data"), QSqlError::StatementError, d->stmt)); return false; + } #else return false; #endif } else { - d->row = mysql_fetch_row(d->result); - if (!d->row) - return false; + d->row = mysql_fetch_row(d->result); + if (!d->row) + return false; } setAt(at() + 1); return true; @@ -1365,7 +1374,6 @@ QStringList QMYSQLDriver::tables(QSql::TableType type) const QSqlIndex QMYSQLDriver::primaryIndex(const QString& tablename) const { QSqlIndex idx; - bool prepQ; if (!isOpen()) return idx; diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp index 17f2c92..f130087 100644 --- a/src/sql/drivers/oci/qsql_oci.cpp +++ b/src/sql/drivers/oci/qsql_oci.cpp @@ -2200,26 +2200,34 @@ bool QOCIDriver::rollbackTransaction() QStringList QOCIDriver::tables(QSql::TableType type) const { QStringList tl; + QStringList sysUsers = QStringList() << QLatin1String("MDSYS") + << QLatin1String("LBACSYS") + << QLatin1String("SYS") + << QLatin1String("SYSTEM") + << QLatin1String("WKSYS") + << QLatin1String("CTXSYS") + << QLatin1String("WMSYS"); + + QString user = d->user; + if ( isIdentifierEscaped(user, QSqlDriver::TableName)) + user = stripDelimiters(user, QSqlDriver::TableName); + else + user = user.toUpper(); + + if(sysUsers.contains(user)) + sysUsers.removeAll(user);; + if (!isOpen()) return tl; QSqlQuery t(createResult()); t.setForwardOnly(true); if (type & QSql::Tables) { - t.exec(QLatin1String("select owner, table_name from all_tables " - "where owner != 'MDSYS' " - "and owner != 'LBACSYS' " - "and owner != 'SYS' " - "and owner != 'SYSTEM' " - "and owner != 'WKSYS'" - "and owner != 'CTXSYS'" - "and owner != 'WMSYS'")); - - QString user = d->user; - if ( isIdentifierEscaped(user, QSqlDriver::TableName)) - user = stripDelimiters(user, QSqlDriver::TableName); - else - user = user.toUpper(); + QString query = QLatin1String("select owner, table_name from all_tables where "); + QStringList whereList; + foreach(const QString &sysUserName, sysUsers) + whereList << QLatin1String("owner != '") + sysUserName + QLatin1String("' "); + t.exec(query + whereList.join(QLatin1String(" and "))); while (t.next()) { if (t.value(0).toString().toUpper() != user.toUpper()) @@ -2229,30 +2237,21 @@ QStringList QOCIDriver::tables(QSql::TableType type) const } // list all table synonyms as well - t.exec(QLatin1String("select owner, synonym_name from all_synonyms " - "where owner != 'MDSYS' " - "and owner != 'LBACSYS' " - "and owner != 'SYS' " - "and owner != 'SYSTEM' " - "and owner != 'WKSYS'" - "and owner != 'CTXSYS'" - "and owner != 'WMSYS'")); + query = QLatin1String("select owner, synonym_name from all_synonyms where "); + t.exec(query + whereList.join(QLatin1String(" and "))); while (t.next()) { if (t.value(0).toString() != d->user) - tl.append(t.value(0).toString() + QLatin1String(".") + t.value(1).toString()); + tl.append(t.value(0).toString() + QLatin1Char('.') + t.value(1).toString()); else tl.append(t.value(1).toString()); } } if (type & QSql::Views) { - t.exec(QLatin1String("select owner, view_name from all_views " - "where owner != 'MDSYS' " - "and owner != 'LBACSYS' " - "and owner != 'SYS' " - "and owner != 'SYSTEM' " - "and owner != 'WKSYS'" - "and owner != 'CTXSYS'" - "and owner != 'WMSYS'")); + QString query = QLatin1String("select owner, view_name from all_views where "); + QStringList whereList; + foreach(const QString &sysUserName, sysUsers) + whereList << QLatin1String("owner != '") + sysUserName + QLatin1String("' "); + t.exec(query + whereList.join(QLatin1String(" and "))); while (t.next()) { if (t.value(0).toString().toUpper() != d->user.toUpper()) tl.append(t.value(0).toString() + QLatin1Char('.') + t.value(1).toString()); @@ -2265,6 +2264,28 @@ QStringList QOCIDriver::tables(QSql::TableType type) const while (t.next()) { tl.append(t.value(0).toString()); } + QString query = QLatin1String("select owner, table_name from all_tables where "); + QStringList whereList; + foreach(const QString &sysUserName, sysUsers) + whereList << QLatin1String("owner = '") + sysUserName + QLatin1String("' "); + t.exec(query + whereList.join(QLatin1String(" or "))); + + while (t.next()) { + if (t.value(0).toString().toUpper() != user.toUpper()) + tl.append(t.value(0).toString() + QLatin1Char('.') + t.value(1).toString()); + else + tl.append(t.value(1).toString()); + } + + // list all table synonyms as well + query = QLatin1String("select owner, synonym_name from all_synonyms where "); + t.exec(query + whereList.join(QLatin1String(" or "))); + while (t.next()) { + if (t.value(0).toString() != d->user) + tl.append(t.value(0).toString() + QLatin1String(".") + t.value(1).toString()); + else + tl.append(t.value(1).toString()); + } } return tl; } diff --git a/src/sql/models/qsqlrelationaltablemodel.cpp b/src/sql/models/qsqlrelationaltablemodel.cpp index 5f0a35d..aec54d6 100644 --- a/src/sql/models/qsqlrelationaltablemodel.cpp +++ b/src/sql/models/qsqlrelationaltablemodel.cpp @@ -563,7 +563,7 @@ QString QSqlRelationalTableModel::selectStatement() const // If there are duplicate field names they must be aliased if (fieldNames.value(fieldList[i]) > 1) { - QString relTableName = relation.tableName(); + QString relTableName = relation.tableName().section(QChar::fromLatin1('.'), -1, -1); if (d->db.driver()->isIdentifierEscaped(relTableName, QSqlDriver::TableName)) relTableName = d->db.driver()->stripDelimiters(relTableName, QSqlDriver::TableName); QString displayColumn = relation.displayColumn(); diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 722981c..0dbb90f 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -30,8 +30,7 @@ win32:DEFINES += QT_NODLL INCLUDEPATH += $$QT_BUILD_TREE/include \ $$QT_BUILD_TREE/include/QtCore \ - $$QT_BUILD_TREE/include/QtXml \ - $$QT_BUILD_TREE/src/corelib/global # qlibraryinfo.cpp includes qconfig.cpp + $$QT_BUILD_TREE/include/QtXml DEPENDPATH += $$INCLUDEPATH \ ../../corelib/global \ @@ -49,7 +48,6 @@ SOURCES += \ ../../corelib/codecs/qtsciicodec.cpp \ ../../corelib/codecs/qutfcodec.cpp \ ../../corelib/global/qglobal.cpp \ - ../../corelib/global/qlibraryinfo.cpp \ ../../corelib/global/qmalloc.cpp \ ../../corelib/global/qnumeric.cpp \ ../../corelib/io/qabstractfileengine.cpp \ @@ -65,7 +63,6 @@ SOURCES += \ ../../corelib/io/qtemporaryfile.cpp \ ../../corelib/io/qtextstream.cpp \ ../../corelib/io/qurl.cpp \ - ../../corelib/io/qsettings.cpp \ ../../corelib/kernel/qmetatype.cpp \ ../../corelib/kernel/qvariant.cpp \ ../../corelib/tools/qbitarray.cpp \ @@ -90,12 +87,11 @@ unix:SOURCES += ../../corelib/io/qfsfileengine_unix.cpp \ ../../corelib/io/qfsfileengine_iterator_unix.cpp win32:SOURCES += ../../corelib/io/qfsfileengine_win.cpp \ - ../../corelib/io/qfsfileengine_iterator_win.cpp \ - ../../corelib/io/qsettings_win.cpp + ../../corelib/io/qfsfileengine_iterator_win.cpp macx: { QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 #enables weak linking for 10.4 (exported) - SOURCES += ../../corelib/kernel/qcore_mac.cpp ../../corelib/io/qsettings_mac.cpp + SOURCES += ../../corelib/kernel/qcore_mac.cpp LIBS += -framework CoreServices } diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 1ed6586..8fcc0df 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -292,7 +292,8 @@ void Generator::generateCode() QList<QByteArray> extraList; for (int i = 0; i < cdef->propertyList.count(); ++i) { const PropertyDef &p = cdef->propertyList.at(i); - if (!isVariantType(p.type) && !metaTypes.contains(p.type)) { + if (!isVariantType(p.type) && !metaTypes.contains(p.type) && !p.type.contains('*') && + !p.type.contains('<') && !p.type.contains('>')) { int s = p.type.lastIndexOf("::"); if (s > 0) { QByteArray scope = p.type.left(s); diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp index 287cf11..ee92195 100644 --- a/src/xmlpatterns/api/qxmlschema.cpp +++ b/src/xmlpatterns/api/qxmlschema.cpp @@ -65,6 +65,11 @@ QT_BEGIN_NAMESPACE \snippet doc/src/snippets/qxmlschema/main.cpp 0 + \section1 XML Schema Version + + This class is used to represent schemas that conform to the \l{XML Schema} 1.0 + specification. + \sa QXmlSchemaValidator, {xmlpatterns/schema}{XML Schema Validation Example} */ diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp index 11e0417..682d34f 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.cpp +++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp @@ -71,6 +71,11 @@ QT_BEGIN_NAMESPACE \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 3 + \section1 XML Schema Version + + This class implements schema validation according to the \l{XML Schema} 1.0 + specification. + \sa QXmlSchema, {xmlpatterns/schema}{XML Schema Validation Example} */ diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index d5d72a7..92d29ae 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -148,7 +148,6 @@ SUBDIRS += \ qfontmetrics \ qftp \ qgetputenv \ - qgl \ qglobal \ qgraphicseffect \ qgraphicseffectsource \ @@ -458,7 +457,9 @@ SUBDIRS += \ rcc \ windowsmobile -!wince*:SUBDIRS += $$Q3SUBDIRS +contains(QT_CONFIG,opengl):SUBDIRS += qgl + +contains(QT_CONFIG,qt3support):!wince*:SUBDIRS += $$Q3SUBDIRS contains(QT_CONFIG, OdfWriter):SUBDIRS += qzip qtextodfwriter mac: { diff --git a/tests/auto/languagechange/tst_languagechange.cpp b/tests/auto/languagechange/tst_languagechange.cpp index 1319f15..449d34b 100644 --- a/tests/auto/languagechange/tst_languagechange.cpp +++ b/tests/auto/languagechange/tst_languagechange.cpp @@ -193,7 +193,7 @@ void tst_languageChange::retranslatability_data() #else << "QFileSystemModel::Type::All other platforms" #endif - << "QFileSystemModel::%1 KB" +// << "QFileSystemModel::%1 KB" << "QDialogButtonBox::Cancel" << "QDialogButtonBox::Open" << "QFileDialog::File &name:"); @@ -232,6 +232,7 @@ void tst_languageChange::retranslatability() QSKIP("The native file dialog is used on Mac OS", SkipSingle); #endif QFileDialog dlg; + dlg.setOption(QFileDialog::DontUseNativeDialog); QString tmpParentDir = QDir::tempPath() + "/languagechangetestdir"; QString tmpDir = tmpParentDir + "/finaldir"; QString fooName = tmpParentDir + "/foo"; diff --git a/tests/auto/linguist/lconvert/data/phrasebook.qph b/tests/auto/linguist/lconvert/data/phrasebook.qph new file mode 100644 index 0000000..847a53b --- /dev/null +++ b/tests/auto/linguist/lconvert/data/phrasebook.qph @@ -0,0 +1,21 @@ +<!DOCTYPE QPH> +<QPH language="de" sourcelanguage="en_US"> +<phrase> + <source>About</source> + <target>Info</target> +</phrase> +<phrase> + <source>adornment</source> + <target>Zubehör</target> +</phrase> +<phrase> + <source>barrel button</source> + <target>Pen-Knopf</target> + <definition>pen</definition> +</phrase> +<phrase> + <source>foo & bar</source> + <target>Foo & bar</target> + <definition><test>übergroß</definition> +</phrase> +</QPH> diff --git a/tests/auto/linguist/lconvert/tst_lconvert.cpp b/tests/auto/linguist/lconvert/tst_lconvert.cpp index 10098a4..cf8f5c3 100644 --- a/tests/auto/linguist/lconvert/tst_lconvert.cpp +++ b/tests/auto/linguist/lconvert/tst_lconvert.cpp @@ -213,6 +213,7 @@ void tst_lconvert::readverifies_data() QTest::newRow("relative locations") << "relative.ts" << "ts"; QTest::newRow("message ids") << "msgid.ts" << "ts"; QTest::newRow("length variants") << "variants.ts" << "ts"; + QTest::newRow("qph") << "phrasebook.qph" << "qph"; } void tst_lconvert::readverifies() diff --git a/tests/auto/mediaobject/dummy/dummy.pro b/tests/auto/mediaobject/dummy/dummy.pro index 9febde7..5417b50 100644 --- a/tests/auto/mediaobject/dummy/dummy.pro +++ b/tests/auto/mediaobject/dummy/dummy.pro @@ -1,7 +1,7 @@ TEMPLATE = lib isEmpty(QT_MAJOR_VERSION) { - VERSION=4.6.0 + VERSION=4.6.1 } else { VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION} } diff --git a/tests/auto/moc/namespaced-flags.h b/tests/auto/moc/namespaced-flags.h index d3f9548..b366447 100644 --- a/tests/auto/moc/namespaced-flags.h +++ b/tests/auto/moc/namespaced-flags.h @@ -62,13 +62,18 @@ namespace Foo { Q_OBJECT //Q_PROPERTY( Bar::Flags flags READ flags WRITE setFlags ) // triggers assertion Q_PROPERTY( Foo::Bar::Flags flags READ flags WRITE setFlags ) // fails to compile, or with the same assertion if moc fix is applied + Q_PROPERTY( QList<Foo::Bar::Flags> flagsList READ flagsList WRITE setFlagsList ) public: explicit Baz( QObject * parent=0 ) : QObject( parent ), mFlags() {} void setFlags( Bar::Flags f ) { mFlags = f; } Bar::Flags flags() const { return mFlags; } + + void setFlagsList( const QList<Bar::Flags> &f ) { mList = f; } + QList<Bar::Flags> flagsList() const { return mList; } private: Bar::Flags mFlags; + QList<Bar::Flags> mList; }; } diff --git a/tests/auto/moc/tst_moc.cpp b/tests/auto/moc/tst_moc.cpp index 69d6ca7..2316ba2 100644 --- a/tests/auto/moc/tst_moc.cpp +++ b/tests/auto/moc/tst_moc.cpp @@ -489,7 +489,6 @@ private slots: void constructors(); void typenameWithUnsigned(); void warnOnVirtualSignal(); - signals: void sigWithUnsignedArg(unsigned foo); void sigWithSignedArg(signed foo); @@ -817,6 +816,8 @@ void tst_Moc::structQObject() #include "namespaced-flags.h" +Q_DECLARE_METATYPE(QList<Foo::Bar::Flags>); + void tst_Moc::namespacedFlags() { Foo::Baz baz; @@ -829,6 +830,12 @@ void tst_Moc::namespacedFlags() QVERIFY(v.isValid()); QVERIFY(baz.setProperty("flags", v)); QVERIFY(baz.flags() == bar.flags()); + + QList<Foo::Bar::Flags> l; + l << baz.flags(); + QVariant v2 = baz.setProperty("flagsList", QVariant::fromValue(l)); + QCOMPARE(l, baz.flagsList()); + QCOMPARE(l, qvariant_cast<QList<Foo::Bar::Flags> >(baz.property("flagsList"))); } void tst_Moc::warnOnMultipleInheritance() diff --git a/tests/auto/networkselftest/tst_networkselftest.cpp b/tests/auto/networkselftest/tst_networkselftest.cpp index f13bcad..b9be5cb 100644 --- a/tests/auto/networkselftest/tst_networkselftest.cpp +++ b/tests/auto/networkselftest/tst_networkselftest.cpp @@ -156,7 +156,7 @@ static QString prettyByteArray(const QByteArray &array) return result; } -static bool doSocketRead(QTcpSocket *socket, int minBytesAvailable, int timeout = 2000) +static bool doSocketRead(QTcpSocket *socket, int minBytesAvailable, int timeout = 4000) { QTime timer; timer.start(); @@ -171,7 +171,7 @@ static bool doSocketRead(QTcpSocket *socket, int minBytesAvailable, int timeout } } -static bool doSocketFlush(QTcpSocket *socket, int timeout = 2000) +static bool doSocketFlush(QTcpSocket *socket, int timeout = 4000) { #ifndef QT_NO_OPENSSL QSslSocket *sslSocket = qobject_cast<QSslSocket *>(socket); diff --git a/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp b/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp index 413419d..3736813 100644 --- a/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp +++ b/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp @@ -112,6 +112,8 @@ private slots: void testMoveWithinOwnRange_data(); void testMoveWithinOwnRange(); + void testMoveThroughProxy(); + void testReset(); @@ -1112,6 +1114,25 @@ void tst_QAbstractItemModel::testMoveSameParentUp() } } +void tst_QAbstractItemModel::testMoveThroughProxy() +{ + QSortFilterProxyModel *proxy = new QSortFilterProxyModel(this); + proxy->setSourceModel(m_model); + + QList<QPersistentModelIndex> persistentList; + + persistentList.append(proxy->index(0, 0)); + persistentList.append(proxy->index(0, 0, proxy->mapFromSource(m_model->index(5, 0)))); + + ModelMoveCommand *moveCommand = new ModelMoveCommand(m_model, this); + moveCommand->setNumCols(4); + moveCommand->setAncestorRowNumbers(QList<int>() << 5); + moveCommand->setStartRow(0); + moveCommand->setEndRow(0); + moveCommand->setDestRow(0); + moveCommand->doCommand(); +} + void tst_QAbstractItemModel::testMoveToGrandParent_data() { QTest::addColumn<int>("startRow"); diff --git a/tests/auto/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/qabstractitemview/tst_qabstractitemview.cpp index db840f4..6479829 100644 --- a/tests/auto/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/qabstractitemview/tst_qabstractitemview.cpp @@ -46,6 +46,7 @@ #include <qstandarditemmodel.h> #include <qapplication.h> #include <qlistview.h> +#include <qlistwidget.h> #include <qtableview.h> #include <qtreeview.h> #include <qtreewidget.h> @@ -224,6 +225,7 @@ private slots: void shiftArrowSelectionAfterScrolling(); void shiftSelectionAfterRubberbandSelection(); void ctrlRubberbandSelection(); + void QTBUG6407_extendedSelection(); }; class MyAbstractItemDelegate : public QAbstractItemDelegate @@ -1433,5 +1435,45 @@ void tst_QAbstractItemView::ctrlRubberbandSelection() QVERIFY(selected.contains(index2)); } +void tst_QAbstractItemView::QTBUG6407_extendedSelection() +{ + QListWidget view; + view.setSelectionMode(QAbstractItemView::ExtendedSelection); + for(int i = 0; i < 50; ++i) + view.addItem(QString::number(i)); + + view.resize(200,200); + + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(static_cast<QWidget *>(&view), QApplication::activeWindow()); + + view.verticalScrollBar()->setValue(view.verticalScrollBar()->maximum()); + QTest::qWait(20); + + QModelIndex index49 = view.model()->index(49,0); + QPoint p = view.visualRect(index49).center(); + QVERIFY(view.viewport()->rect().contains(p)); + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, p); + QCOMPARE(view.currentIndex(), index49); + QCOMPARE(view.selectedItems().count(), 1); + + QModelIndex index47 = view.model()->index(47,0); + p = view.visualRect(index47).center(); + QVERIFY(view.viewport()->rect().contains(p)); + QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ShiftModifier, p); + QCOMPARE(view.currentIndex(), index47); + QCOMPARE(view.selectedItems().count(), 3); //49, 48, 47; + + QModelIndex index44 = view.model()->index(44,0); + p = view.visualRect(index44).center(); + QVERIFY(view.viewport()->rect().contains(p)); + QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ShiftModifier, p); + QCOMPARE(view.currentIndex(), index44); + QCOMPARE(view.selectedItems().count(), 6); //49 .. 44; + +} + QTEST_MAIN(tst_QAbstractItemView) #include "tst_qabstractitemview.moc" diff --git a/tests/auto/qcombobox/tst_qcombobox.cpp b/tests/auto/qcombobox/tst_qcombobox.cpp index af71961..bd5cd70 100644 --- a/tests/auto/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/qcombobox/tst_qcombobox.cpp @@ -2516,10 +2516,12 @@ void tst_QComboBox::task_QTBUG_1071_changingFocusEmitsActivated() layout.addWidget(&edit); w.show(); + QApplication::setActiveWindow(&w); QTest::qWaitForWindowShown(&w); cb.clearEditText(); cb.setFocus(); QApplication::processEvents(); + QTRY_VERIFY(cb.hasFocus()); QTest::keyClick(0, '1'); QCOMPARE(spy.count(), 0); edit.setFocus(); diff --git a/tests/auto/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/qdbusconnection/tst_qdbusconnection.cpp index bb034a3..c1976c0 100644 --- a/tests/auto/qdbusconnection/tst_qdbusconnection.cpp +++ b/tests/auto/qdbusconnection/tst_qdbusconnection.cpp @@ -96,6 +96,8 @@ private slots: void registerQObjectChildren(); void callSelf(); + void callSelfByAnotherName_data(); + void callSelfByAnotherName(); void multipleInterfacesInQObject(); void slotsWithLessParameters(); @@ -493,6 +495,70 @@ void tst_QDBusConnection::callSelf() QCOMPARE(reply.arguments().value(0).toInt(), 45); } +void tst_QDBusConnection::callSelfByAnotherName_data() +{ + QTest::addColumn<int>("registerMethod"); + QTest::newRow("connection") << 0; + QTest::newRow("connection-interface") << 1; + QTest::newRow("direct") << 2; +} + +void tst_QDBusConnection::callSelfByAnotherName() +{ + static int counter = 0; + QString sname = serviceName() + QString::number(counter++); + + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + TestObject testObject; + QVERIFY(con.registerObject("/test", &testObject, + QDBusConnection::ExportAllContents)); + con.connect("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameOwnerChanged", + QStringList() << sname << "", + QString(), &QTestEventLoop::instance(), SLOT(exitLoop())); + + // register the name + QFETCH(int, registerMethod); + switch (registerMethod) { + case 0: + QVERIFY(con.registerService(sname)); + break; + + case 1: + QVERIFY(con.interface()->registerService(sname).value() == QDBusConnectionInterface::ServiceRegistered); + break; + + case 2: { + // flag is DBUS_NAME_FLAG_DO_NOT_QUEUE = 0x04 + // reply is DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER = 1 + QDBusReply<uint> reply = con.interface()->call("RequestName", sname, 4u); + QVERIFY(reply.value() == 1); + } + } + + struct Deregisterer { + QDBusConnection con; + QString sname; + Deregisterer(const QDBusConnection &con, const QString &sname) : con(con), sname(sname) {} + ~Deregisterer() { con.interface()->unregisterService(sname); } + } deregisterer(con, sname); + + // give the connection a chance to find out that we're good to go + QTestEventLoop::instance().enterLoop(2); + con.disconnect("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameOwnerChanged", + QStringList() << sname << "", + QString(), &QTestEventLoop::instance(), SLOT(exitLoop())); + QVERIFY(!QTestEventLoop::instance().timeout()); + + // make the call + QDBusMessage msg = QDBusMessage::createMethodCall(sname, "/test", + QString(), "test0"); + QDBusMessage reply = con.call(msg, QDBus::Block, 1000); + + QVERIFY(reply.type() == QDBusMessage::ReplyMessage); +} + void tst_QDBusConnection::multipleInterfacesInQObject() { QDBusConnection con = QDBusConnection::sessionBus(); diff --git a/tests/auto/qdesktopservices/tst_qdesktopservices.cpp b/tests/auto/qdesktopservices/tst_qdesktopservices.cpp index 2d9e5dc..c105a97 100644 --- a/tests/auto/qdesktopservices/tst_qdesktopservices.cpp +++ b/tests/auto/qdesktopservices/tst_qdesktopservices.cpp @@ -70,6 +70,7 @@ private slots: void openMailtoUrl(); void openFileUrl_data(); void openFileUrl(); + void openMultipleFileUrls(); #endif void handlers(); void storageLocation_data(); @@ -197,6 +198,7 @@ void tst_qdesktopservices::openMailtoUrl() QFETCH(QUrl, url); QFETCH(bool, result); QCOMPARE(QDesktopServices::openUrl(url), result); + QTest::qWait(5000); } void tst_qdesktopservices::openFileUrl_data() @@ -239,7 +241,19 @@ void tst_qdesktopservices::openFileUrl() QFETCH(QUrl, url); QFETCH(bool, result); QCOMPARE(QDesktopServices::openUrl(url), result); - QTest::qWait(15000); + QTest::qWait(5000); +} + +void tst_qdesktopservices::openMultipleFileUrls() +{ +#ifndef RUN_MANUAL_TESTS + QSKIP("Test disabled -- only for manual purposes", SkipAll); +#endif + + QCOMPARE(QDesktopServices::openUrl(QUrl("file:///c:/data/images/image.bmp")), true); + QCOMPARE(QDesktopServices::openUrl(QUrl("file:///c:/data/images/image.png")), true); + QCOMPARE(QDesktopServices::openUrl(QUrl("file:///c:/data/others/noendofline.txt")), true); + QCOMPARE(QDesktopServices::openUrl(QUrl("file:///c:/data/installs/ErrRd.sisx")), true); } #endif diff --git a/tests/auto/qdialogbuttonbox/tst_qdialogbuttonbox.cpp b/tests/auto/qdialogbuttonbox/tst_qdialogbuttonbox.cpp index 936ebf7..2c49fc8 100644 --- a/tests/auto/qdialogbuttonbox/tst_qdialogbuttonbox.cpp +++ b/tests/auto/qdialogbuttonbox/tst_qdialogbuttonbox.cpp @@ -111,6 +111,9 @@ private slots: void testDefaultButton_data(); void testDefaultButton(); void testS60SoftKeys(); +#ifdef QT_SOFTKEYS_ENABLED + void testSoftKeyReparenting(); +#endif void task191642_default(); private: @@ -715,6 +718,17 @@ void tst_QDialogButtonBox::testDefaultButton_data() QTest::newRow("third accept explicit after add") << 0 << 2 << 2; } +static int softKeyCount(QWidget *widget) +{ + int softkeyCount = 0; + QList<QAction *> actions = widget->actions(); + foreach (QAction *action, actions) { + if (action->softKeyRole() != QAction::NoSoftKey) + softkeyCount++; + } + return softkeyCount; +} + void tst_QDialogButtonBox::testS60SoftKeys() { #ifdef Q_WS_S60 @@ -722,33 +736,47 @@ void tst_QDialogButtonBox::testS60SoftKeys() QDialogButtonBox buttonBox(&dialog); buttonBox.setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); dialog.show(); - - int softkeyCount = 0; - QList<QAction *> actions = dialog.actions(); - foreach (QAction *action, actions) { - if (action->softKeyRole() != QAction::NoSoftKey) - softkeyCount++; - } - QCOMPARE( softkeyCount, 2); + + QCOMPARE( softKeyCount(&dialog), 2); QDialog dialog2(0); QDialogButtonBox buttonBox2(&dialog2); buttonBox2.setStandardButtons(QDialogButtonBox::Cancel); dialog2.show(); - int softkeyCount2 = 0; - QList<QAction *> actions2 = dialog2.actions(); - foreach (QAction *action, actions2) { - if (action->softKeyRole() != QAction::NoSoftKey) - softkeyCount2++; - } - QCOMPARE( softkeyCount2, 1); - + QCOMPARE( softKeyCount(&dialog2), 1); + #else QSKIP("S60-specific test", SkipAll ); #endif } +#ifdef QT_SOFTKEYS_ENABLED +void tst_QDialogButtonBox::testSoftKeyReparenting() +{ + QDialog dialog; + QDialogButtonBox *buttonBox = new QDialogButtonBox; + buttonBox->addButton(QDialogButtonBox::Ok); + buttonBox->addButton(QDialogButtonBox::Cancel); + + QCOMPARE(softKeyCount(&dialog), 0); + QCOMPARE(softKeyCount(buttonBox), 2); + + // Were the softkeys re-parented correctly? + dialog.setLayout(new QVBoxLayout); + dialog.layout()->addWidget(buttonBox); + QCOMPARE(softKeyCount(&dialog), 2); + QCOMPARE(softKeyCount(buttonBox), 0); + + // Softkeys are only added to QDialog, not QWidget + QWidget *nested = new QWidget; + nested->setLayout(new QVBoxLayout); + nested->layout()->addWidget(buttonBox); + QCOMPARE(softKeyCount(nested), 0); + QCOMPARE(softKeyCount(buttonBox), 2); +} +#endif + void tst_QDialogButtonBox::testDefaultButton() { QFETCH(int, whenToSetDefault); diff --git a/tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp b/tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp index 3d2fa42..7f03153 100644 --- a/tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp +++ b/tests/auto/qdoublespinbox/tst_qdoublespinbox.cpp @@ -147,6 +147,8 @@ private slots: void task221221(); void task255471_decimalsValidation(); + void taskQTBUG_5008_textFromValueAndValidate(); + public slots: void valueChangedHelper(const QString &); void valueChangedHelper(double); @@ -682,7 +684,7 @@ void tst_QDoubleSpinBox::valueFromTextAndValidate_data() QTest::newRow("data10") << QString(" 1") << Acceptable << 0.0 << 100.0 << (int)QLocale::Norwegian << QString("1"); QTest::newRow("data11") << QString(" 1") << Acceptable << 0.0 << 100.0 << (int)QLocale::C << QString("1"); QTest::newRow("data12") << QString("1,") << Acceptable << 0.0 << 100.0 << (int)QLocale::Norwegian << QString(); - QTest::newRow("data13") << QString("1,") << Intermediate << 0.0 << 1000.0 << (int)QLocale::C << QString(); + QTest::newRow("data13") << QString("1,") << Acceptable << 0.0 << 1000.0 << (int)QLocale::C << QString(); QTest::newRow("data14") << QString("1, ") << Acceptable << 0.0 << 100.0 << (int)QLocale::Norwegian << QString("1,"); QTest::newRow("data15") << QString("1, ") << Invalid << 0.0 << 100.0 << (int)QLocale::C << QString(); QTest::newRow("data16") << QString("2") << Intermediate << 100.0 << 102.0 << (int)QLocale::C << QString(); @@ -717,8 +719,8 @@ void tst_QDoubleSpinBox::valueFromTextAndValidate_data() QTest::newRow("data45") << QString("200,2") << Invalid << 0.0 << 1000.0 << (int)QLocale::C << QString(); QTest::newRow("data46") << QString("200,2") << Acceptable << 0.0 << 1000.0 << (int)QLocale::German << QString(); QTest::newRow("data47") << QString("2.2") << Acceptable << 0.0 << 1000.0 << (int)QLocale::C << QString(); - QTest::newRow("data48") << QString("2.2") << Intermediate << 0.0 << 1000.0 << (int)QLocale::German << QString(); - QTest::newRow("data49") << QString("2.2,00") << Intermediate << 0.0 << 1000.0 << (int)QLocale::German << QString(); + QTest::newRow("data48") << QString("2.2") << Acceptable << 0.0 << 1000.0 << (int)QLocale::German << QString(); + QTest::newRow("data49") << QString("2.2,00") << Acceptable << 0.0 << 1000.0 << (int)QLocale::German << QString(); QTest::newRow("data50") << QString("2.2") << Acceptable << 0.0 << 1000.0 << (int)QLocale::C << QString(); QTest::newRow("data51") << QString("2.2,00") << Invalid << 0.0 << 1000.0 << (int)QLocale::C << QString(); QTest::newRow("data52") << QString("2..2,00") << Invalid << 0.0 << 1000.0 << (int)QLocale::German << QString(); @@ -1044,6 +1046,43 @@ void tst_QDoubleSpinBox::task255471_decimalsValidation() } } +void tst_QDoubleSpinBox::taskQTBUG_5008_textFromValueAndValidate() +{ + class DecoratedSpinBox : public QDoubleSpinBox + { + public: + DecoratedSpinBox() + { + setLocale(QLocale::French); + setMaximum(100000000); + setValue(1000); + } + + QLineEdit *lineEdit() const + { + return QDoubleSpinBox::lineEdit(); + } + + //we use the French delimiters here + QString textFromValue (double value) const + { + return locale().toString(value); + } + } spinbox; + spinbox.show(); + spinbox.activateWindow(); + spinbox.setFocus(); + QApplication::setActiveWindow(&spinbox); + QTest::qWaitForWindowShown(&spinbox); + QTRY_VERIFY(spinbox.hasFocus()); + QTRY_COMPARE(static_cast<QWidget *>(&spinbox), QApplication::activeWindow()); + QCOMPARE(spinbox.text(), spinbox.locale().toString(spinbox.value())); + spinbox.lineEdit()->setCursorPosition(2); //just after the first thousand separator + QTest::keyClick(0, Qt::Key_0); // let's insert a 0 + QCOMPARE(spinbox.value(), 10000.); + spinbox.clearFocus(); //make sure the value is correctly formatted + QCOMPARE(spinbox.text(), spinbox.locale().toString(spinbox.value())); +} QTEST_MAIN(tst_QDoubleSpinBox) #include "tst_qdoublespinbox.moc" diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index cf46ce1..7ee5665 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -2783,10 +2783,21 @@ void tst_QFile::mapOpenMode() void tst_QFile::openDirectory() { - QFile f1("resources"); + QFile f1(SRCDIR "resources"); + // it's a directory, it must exist + QVERIFY(f1.exists()); + + // ...but not be openable QVERIFY(!f1.open(QIODevice::ReadOnly)); f1.close(); QVERIFY(!f1.open(QIODevice::ReadOnly|QIODevice::Unbuffered)); + f1.close(); + QVERIFY(!f1.open(QIODevice::ReadWrite)); + f1.close(); + QVERIFY(!f1.open(QIODevice::WriteOnly)); + f1.close(); + QVERIFY(!f1.open(QIODevice::WriteOnly|QIODevice::Unbuffered)); + f1.close(); } void tst_QFile::openStandardStreams() diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 21edbcf..cd58fd6 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -513,6 +513,10 @@ void tst_QFileInfo::canonicalFilePath() QFileInfo info("/tmp/../../../../../../../../../../../../../../../../../"); info.canonicalFilePath(); + // This used to crash on Mac + QFileInfo dontCrash(QLatin1String("/")); + QCOMPARE(dontCrash.canonicalFilePath(), QLatin1String("/")); + #ifndef Q_OS_WIN // test symlinks QFile::remove("link.lnk"); diff --git a/tests/auto/qfontcombobox/tst_qfontcombobox.cpp b/tests/auto/qfontcombobox/tst_qfontcombobox.cpp index b974ecab..657be06 100644 --- a/tests/auto/qfontcombobox/tst_qfontcombobox.cpp +++ b/tests/auto/qfontcombobox/tst_qfontcombobox.cpp @@ -144,9 +144,11 @@ void tst_QFontComboBox::currentFont() QFont oldCurrentFont = box.currentFont(); box.setCurrentFont(currentFont); - QCOMPARE(box.currentFont(), currentFont); - QString boxFontFamily = QFontInfo(box.currentFont()).family(); QRegExp foundry(" \\[.*\\]"); + if (!box.currentFont().family().contains(foundry)) { + QCOMPARE(box.currentFont(), currentFont); + } + QString boxFontFamily = QFontInfo(box.currentFont()).family(); if (!currentFont.family().contains(foundry)) boxFontFamily.remove(foundry); QCOMPARE(boxFontFamily, currentFont.family()); diff --git a/tests/auto/qftp/tst_qftp.cpp b/tests/auto/qftp/tst_qftp.cpp index 1e7f424..27c2e13 100644 --- a/tests/auto/qftp/tst_qftp.cpp +++ b/tests/auto/qftp/tst_qftp.cpp @@ -618,7 +618,7 @@ void tst_QFtp::get() } addCommand( QFtp::Close, ftp->close() ); - QTestEventLoop::instance().enterLoop( 30 ); + QTestEventLoop::instance().enterLoop( 50 ); delete ftp; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -1020,7 +1020,7 @@ void tst_QFtp::renameInit( const QString &host, const QString &user, const QStri addCommand( QFtp::Put, ftp->put( QByteArray(), createFile ) ); addCommand( QFtp::Close, ftp->close() ); - QTestEventLoop::instance().enterLoop( 30 ); + QTestEventLoop::instance().enterLoop( 50 ); delete ftp; if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -1295,14 +1295,18 @@ void tst_QFtp::abort_data() // Qt/CE and Symbian test environment has to less memory for this test #if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) QByteArray bigData( 10*1024*1024, 0 ); +#else + QByteArray bigData( 1*1024*1024, 0 ); +#endif bigData.fill( 'B' ); - QTest::newRow( "put_fluke01" ) << QtNetworkSettings::serverName() << (uint)21 << QString("qtest/upload/abort_put") << bigData; -#endif } void tst_QFtp::abort() { + // In case you wonder where the abort() actually happens, look into + // tst_QFtp::dataTransferProgress + // QFETCH( QString, host ); QFETCH( uint, port ); QFETCH( QString, file ); @@ -1324,7 +1328,7 @@ void tst_QFtp::abort() addCommand( QFtp::Close, ftp->close() ); for(int time = 0; time <= uploadData.length() / 30000; time += 30) { - QTestEventLoop::instance().enterLoop( 30 ); + QTestEventLoop::instance().enterLoop( 50 ); if(ftp->currentCommand() == QFtp::None) break; } @@ -1404,7 +1408,7 @@ void tst_QFtp::bytesAvailable() if ( type != 0 ) addCommand( QFtp::Close, ftp->close() ); - QTestEventLoop::instance().enterLoop( 30 ); + QTestEventLoop::instance().enterLoop( 40 ); if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); @@ -1493,7 +1497,7 @@ void tst_QFtp::proxy() addCommand( QFtp::Cd, ftp->cd( dir ) ); addCommand( QFtp::List, ftp->list() ); - QTestEventLoop::instance().enterLoop( 30 ); + QTestEventLoop::instance().enterLoop( 50 ); delete ftp; if ( QTestEventLoop::instance().timeout() ) { @@ -1921,7 +1925,7 @@ bool tst_QFtp::fileExists( const QString &host, quint16 port, const QString &use delete ftp; if ( QTestEventLoop::instance().timeout() ) { // ### make this test work - qWarning("Network operation timed out"); + qWarning("tst_QFtp::fileExists: Network operation timed out"); return FALSE; } inFileDirExistsFunction = FALSE; @@ -1972,6 +1976,7 @@ bool tst_QFtp::dirExists( const QString &host, quint16 port, const QString &user if ( QTestEventLoop::instance().timeout() ) { // ### make this test work // QFAIL( "Network operation timed out" ); + qWarning("tst_QFtp::dirExists: Network operation timed out"); return FALSE; } inFileDirExistsFunction = FALSE; diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 2ad024f..6e78522 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -86,6 +86,10 @@ private slots: void parallelSimplificationOfCenter(); void simplificationVsRedundance(); void spacingPersistency(); + void snakeParallelWithLayout(); + void parallelToHalfLayout(); + void globalSpacing(); + void graphicsAnchorHandling(); }; class RectWidget : public QGraphicsWidget @@ -1193,7 +1197,7 @@ void tst_QGraphicsAnchorLayout::styleDefaults() QSizeF pref(20, 20); QSizeF max (50, 50); - /* + /* create this layout, where a,b have controlType QSizePolicy::RadioButton c,d have controlType QSizePolicy::PushButton: +-------+ @@ -1240,9 +1244,9 @@ void tst_QGraphicsAnchorLayout::styleDefaults() scene.addItem(window); window->show(); - QGraphicsView *view = new QGraphicsView(&scene); - view->resize(200, 200); - view->show(); + QGraphicsView view(&scene); + view.resize(200, 200); + view.show(); window->adjustSize(); QCOMPARE(a->geometry(), QRectF(0, 3, 20, 20)); //radio @@ -1261,10 +1265,13 @@ void tst_QGraphicsAnchorLayout::styleDefaults() window->setStyle(style); window->adjustSize(); QCOMPARE(a->geometry(), QRectF(0, 3, 20, 20)); - QCOMPARE(b->geometry(), QRectF(21, 25, 20, 20)); + QCOMPARE(b->geometry(), QRectF(21, 25, 20, 20)); QCOMPARE(c->geometry(), QRectF(42, 47, 20, 20)); QCOMPARE(d->geometry(), QRectF(63, 69, 20, 20)); QCOMPARE(l->geometry(), QRectF(0, 0, 89, 98)); + + window->setStyle(0); + delete style; } @@ -1773,7 +1780,8 @@ void tst_QGraphicsAnchorLayout::simplificationVsOrder() QGraphicsWidget *b = createItem(min, pref, max, "B"); QGraphicsWidget *c = createItem(min, pref, max, "C"); - QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + QGraphicsWidget frame; + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&frame); // Bulk anchors l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft); @@ -1798,7 +1806,6 @@ void tst_QGraphicsAnchorLayout::simplificationVsOrder() l->effectiveSizeHint(Qt::MinimumSize); if (hasSimplification) { - QEXPECT_FAIL("", "Sequential anchors cannot handle children of opposite directions", Continue); QCOMPARE(usedSimplex(l, Qt::Horizontal), false); QCOMPARE(usedSimplex(l, Qt::Vertical), false); } @@ -1843,7 +1850,8 @@ void tst_QGraphicsAnchorLayout::simplificationVsRedundance() QGraphicsWidget *b = createItem(min, pref, max, "B"); QGraphicsWidget *c = createItem(min, pref, max, "C"); - QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + QGraphicsWidget frame; + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&frame); l->addCornerAnchors(a, Qt::TopLeftCorner, l, Qt::TopLeftCorner); l->addCornerAnchors(a, Qt::BottomLeftCorner, l, Qt::BottomLeftCorner); @@ -1892,5 +1900,163 @@ void tst_QGraphicsAnchorLayout::spacingPersistency() QCOMPARE(anchor->spacing(), 30.0); } +/* + Test whether a correct preferred size is set when a "snake" sequence is in parallel with the + layout or half of the layout. The tricky thing here is that all items on the snake should + keep their preferred sizes. +*/ +void tst_QGraphicsAnchorLayout::snakeParallelWithLayout() +{ + QSizeF min(10, 20); + QSizeF pref(50, 20); + QSizeF max(100, 20); + + QGraphicsWidget *a = createItem(max, max, max, "A"); + QGraphicsWidget *b = createItem(min, pref, max, "B"); + QGraphicsWidget *c = createItem(max, max, max, "C"); + + QGraphicsWidget parent; + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&parent); + l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(0); + + // First we'll do the case in parallel with the entire layout... + l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft); + l->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorRight); + l->addAnchor(b, Qt::AnchorLeft, c, Qt::AnchorLeft); + l->addAnchor(c, Qt::AnchorRight, l, Qt::AnchorRight); + + l->addAnchor(l, Qt::AnchorTop, a, Qt::AnchorTop); + l->addAnchor(a, Qt::AnchorBottom, b, Qt::AnchorTop); + l->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop); + l->addAnchor(c, Qt::AnchorBottom, l, Qt::AnchorBottom); + + parent.resize(l->effectiveSizeHint(Qt::PreferredSize)); + + // Note that A and C are fixed in the maximum size + QCOMPARE(l->geometry(), QRectF(QPointF(0, 0), QSizeF(150, 60))); + QCOMPARE(a->geometry(), QRectF(QPointF(0, 0), max)); + QCOMPARE(b->geometry(), QRectF(QPointF(50, 20), pref)); + QCOMPARE(c->geometry(), QRectF(QPointF(50, 40), max)); + + // Then, we change the "snake" to be in parallel with half of the layout + delete l->anchor(c, Qt::AnchorRight, l, Qt::AnchorRight); + l->addAnchor(c, Qt::AnchorRight, l, Qt::AnchorHorizontalCenter); + + parent.resize(l->effectiveSizeHint(Qt::PreferredSize)); + + QCOMPARE(l->geometry(), QRectF(QPointF(0, 0), QSizeF(300, 60))); + QCOMPARE(a->geometry(), QRectF(QPointF(0, 0), max)); + QCOMPARE(b->geometry(), QRectF(QPointF(50, 20), pref)); + QCOMPARE(c->geometry(), QRectF(QPointF(50, 40), max)); +} + +/* + Avoid regression where the sizeHint constraints would not be + created for a parallel anchor that included the first layout half +*/ +void tst_QGraphicsAnchorLayout::parallelToHalfLayout() +{ + QGraphicsWidget *a = createItem(); + + QGraphicsWidget w; + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&w); + l->setContentsMargins(10, 10, 10, 10); + + l->addAnchors(l, a, Qt::Vertical); + + QGraphicsAnchor *anchor; + anchor = l->addAnchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft); + anchor->setSpacing(5); + anchor = l->addAnchor(l, Qt::AnchorHorizontalCenter, a, Qt::AnchorRight); + anchor->setSpacing(-5); + + const QSizeF minimumSizeHint = w.effectiveSizeHint(Qt::MinimumSize); + const QSizeF preferredSizeHint = w.effectiveSizeHint(Qt::PreferredSize); + const QSizeF maximumSizeHint = w.effectiveSizeHint(Qt::MaximumSize); + + const QSizeF overhead = QSizeF(10 + 5 + 5, 10) * 2; + + QCOMPARE(minimumSizeHint, QSizeF(200, 100) + overhead); + QCOMPARE(preferredSizeHint, QSizeF(300, 100) + overhead); + QCOMPARE(maximumSizeHint, QSizeF(400, 100) + overhead); +} + +void tst_QGraphicsAnchorLayout::globalSpacing() +{ + QGraphicsWidget *a = createItem(); + QGraphicsWidget *b = createItem(); + + QGraphicsWidget w; + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(&w); + + l->addCornerAnchors(l, Qt::TopLeftCorner, a, Qt::TopLeftCorner); + l->addCornerAnchors(a, Qt::BottomRightCorner, b, Qt::TopLeftCorner); + l->addCornerAnchors(b, Qt::BottomRightCorner, l, Qt::BottomRightCorner); + + w.resize(w.effectiveSizeHint(Qt::PreferredSize)); + qreal vSpacing = b->geometry().top() - a->geometry().bottom(); + qreal hSpacing = b->geometry().left() - a->geometry().right(); + + // Set spacings manually + l->setVerticalSpacing(vSpacing + 10); + l->setHorizontalSpacing(hSpacing + 5); + + w.resize(w.effectiveSizeHint(Qt::PreferredSize)); + qreal newVSpacing = b->geometry().top() - a->geometry().bottom(); + qreal newHSpacing = b->geometry().left() - a->geometry().right(); + + QCOMPARE(newVSpacing, vSpacing + 10); + QCOMPARE(newHSpacing, hSpacing + 5); + + // Set a negative spacing. This will unset the previous spacing and + // bring back the widget-defined spacing. + l->setSpacing(-1); + + w.resize(w.effectiveSizeHint(Qt::PreferredSize)); + newVSpacing = b->geometry().top() - a->geometry().bottom(); + newHSpacing = b->geometry().left() - a->geometry().right(); + + QCOMPARE(newVSpacing, vSpacing); + QCOMPARE(newHSpacing, hSpacing); +} + +void tst_QGraphicsAnchorLayout::graphicsAnchorHandling() +{ + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout(); + QGraphicsWidget *a = createItem(); + + l->addAnchors(l, a); + + QGraphicsAnchor *layoutAnchor = l->anchor(l, Qt::AnchorTop, l, Qt::AnchorBottom); + QGraphicsAnchor *itemAnchor = l->anchor(a, Qt::AnchorTop, a, Qt::AnchorBottom); + QGraphicsAnchor *invalidAnchor = l->anchor(a, Qt::AnchorTop, l, Qt::AnchorBottom); + + // Ensure none of these anchors are accessible. + QVERIFY(layoutAnchor == 0); + QVERIFY(itemAnchor == 0); + QVERIFY(invalidAnchor == 0); + + // Hook the anchors to a QObject + QObject object; + QGraphicsAnchor *userAnchor = l->anchor(l, Qt::AnchorTop, a, Qt::AnchorTop); + userAnchor->setParent(&object); + userAnchor = l->anchor(l, Qt::AnchorBottom, a, Qt::AnchorBottom); + userAnchor->setParent(&object); + userAnchor = l->anchor(l, Qt::AnchorRight, a, Qt::AnchorRight); + userAnchor->setParent(&object); + userAnchor = l->anchor(l, Qt::AnchorLeft, a, Qt::AnchorLeft); + userAnchor->setParent(&object); + + QCOMPARE(object.children().size(), 4); + + // Delete layout, this will cause all anchors to be deleted internally. + // We expect the public QGraphicsAnchor instances to be deleted too. + delete l; + QCOMPARE(object.children().size(), 0); + + delete a; +} + QTEST_MAIN(tst_QGraphicsAnchorLayout) #include "tst_qgraphicsanchorlayout.moc" diff --git a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp index baa1ba1..57dc90d 100644 --- a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp +++ b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp @@ -356,6 +356,8 @@ void tst_QGraphicsAnchorLayout1::testItemAt() QVERIFY( layout->itemAt(0) == widget2 ); + delete widget1; + widget->setLayout(layout); delete widget; } @@ -460,6 +462,12 @@ void tst_QGraphicsAnchorLayout1::testAddAndRemoveAnchor() QCOMPARE( layout->count(), 0 ); + delete widget1; + delete widget2; + delete widget3; + delete widget4; + delete widget5; + widget->setLayout(layout); delete widget; } @@ -1740,9 +1748,9 @@ void tst_QGraphicsAnchorLayout1::testBasicLayout() QRectF actual = truncate(widgets[item.index]->geometry()); QCOMPARE(actual, expected); - delete widgets[item.index]; } + qDeleteAll(widgets); delete widget; } @@ -2231,8 +2239,9 @@ void tst_QGraphicsAnchorLayout1::testRemoveCenterAnchor() const BasicLayoutTestResult item = result[i]; QCOMPARE(widgets[item.index]->geometry(), item.rect); - delete widgets[item.index]; } + + qDeleteAll(widgets); delete widget; } @@ -2360,7 +2369,7 @@ void tst_QGraphicsAnchorLayout1::testSingleSizePolicy() QFETCH(bool, valid); // create objects - QGraphicsWidget *widget = new QGraphicsWidget; + QGraphicsWidget widget; TheAnchorLayout *layout = new TheAnchorLayout; TestWidget *childWidget = new TestWidget; @@ -2370,11 +2379,11 @@ void tst_QGraphicsAnchorLayout1::testSingleSizePolicy() layout->setAnchor( layout, Qt::AnchorTop, childWidget, Qt::AnchorTop, 10 ); layout->setAnchor( childWidget, Qt::AnchorBottom, layout, Qt::AnchorBottom, 10 ); - widget->setLayout( layout ); + widget.setLayout( layout ); // set test case specific: policy and size childWidget->setSizePolicy( policy ); - widget->setGeometry( QRectF( QPoint(0,0), size ) ); + widget.setGeometry( QRectF( QPoint(0,0), size ) ); QCOMPARE( layout->isValid() , valid ); @@ -2516,7 +2525,7 @@ void tst_QGraphicsAnchorLayout1::testDoubleSizePolicy() QFETCH(qreal, width2); // create objects - QGraphicsWidget *widget = new QGraphicsWidget; + QGraphicsWidget widget; TheAnchorLayout *layout = new TheAnchorLayout; TestWidget *childWidget1 = new TestWidget; TestWidget *childWidget2 = new TestWidget; @@ -2526,13 +2535,13 @@ void tst_QGraphicsAnchorLayout1::testDoubleSizePolicy() layout->setAnchor( childWidget1, Qt::AnchorRight, childWidget2, Qt::AnchorLeft, 10 ); layout->setAnchor( childWidget2, Qt::AnchorRight, layout, Qt::AnchorRight, 10 ); - widget->setLayout( layout ); + widget.setLayout( layout ); // set test case specific: policy childWidget1->setSizePolicy( policy1 ); childWidget2->setSizePolicy( policy2 ); - widget->setGeometry( QRectF( QPoint(0,0), QSize( 100,100 ) ) ); + widget.setGeometry( QRectF( QPoint(0,0), QSize( 100,100 ) ) ); // check results: if ( width1 == -1.0f ) { @@ -2649,7 +2658,7 @@ void tst_QGraphicsAnchorLayout1::testSizeDistribution() QFETCH(qreal, width2); // create objects - QGraphicsWidget *widget = new QGraphicsWidget; + QGraphicsWidget widget; TheAnchorLayout *layout = new TheAnchorLayout; TestWidget *childWidget1 = new TestWidget; TestWidget *childWidget2 = new TestWidget; @@ -2659,7 +2668,7 @@ void tst_QGraphicsAnchorLayout1::testSizeDistribution() layout->setAnchor( childWidget1, Qt::AnchorRight, childWidget2, Qt::AnchorLeft, 10 ); layout->setAnchor( childWidget2, Qt::AnchorRight, layout, Qt::AnchorRight, 10 ); - widget->setLayout( layout ); + widget.setLayout( layout ); // set test case specific: size hints childWidget1->setMinimumWidth( sizeHints1.value( Qt::MinimumSize ) ); @@ -2670,7 +2679,7 @@ void tst_QGraphicsAnchorLayout1::testSizeDistribution() childWidget2->setPreferredWidth( sizeHints2.value( Qt::PreferredSize ) ); childWidget2->setMaximumWidth( sizeHints2.value( Qt::MaximumSize ) ); - widget->setGeometry( QRectF( QPoint(0,0), QSize( 100,100 ) ) ); + widget.setGeometry( QRectF( QPoint(0,0), QSize( 100,100 ) ) ); // check results: if ( width1 == -1.0f ) { diff --git a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp index d216924..259df4d 100644 --- a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp +++ b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp @@ -196,8 +196,8 @@ void tst_QGraphicsEffect::source() // Uninstall effect on QGraphicsItem. effect->reset(); item->setGraphicsEffect(0); - QVERIFY(!effect->source()); - QVERIFY(effect->m_sourceChangedFlags & QGraphicsEffect::SourceDetached); + QVERIFY(!effect); + effect = new CustomEffect; // The item takes ownership and should delete the effect when destroyed. item->setGraphicsEffect(effect); @@ -249,10 +249,10 @@ void tst_QGraphicsEffect::boundingRect() QCOMPARE(effect->boundingRect(), effect->boundingRectFor(itemRect)); // Uninstall effect on QGraphicsItem. + QPointer<CustomEffect> ptr = effect; item->setGraphicsEffect(0); - QCOMPARE(effect->boundingRect(), QRectF()); + QVERIFY(!ptr); - delete effect; delete item; } @@ -343,11 +343,11 @@ void tst_QGraphicsEffect::draw() QCOMPARE(item->numRepaints, 0); // Make sure uninstalling an effect triggers a repaint. + QPointer<CustomEffect> ptr = effect; item->setGraphicsEffect(0); + QVERIFY(!ptr); QTest::qWait(50); - QCOMPARE(effect->numRepaints, 0); QCOMPARE(item->numRepaints, 1); - delete effect; } void tst_QGraphicsEffect::opacity() diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index db80db6..6266933 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -7962,6 +7962,22 @@ void tst_QGraphicsItem::setGraphicsEffect() delete item; QVERIFY(!blurEffect); delete anotherItem; + + // Ensure the effect is uninstalled when deleting it + item = new QGraphicsRectItem(0, 0, 10, 10); + blurEffect = new QGraphicsBlurEffect; + item->setGraphicsEffect(blurEffect); + delete blurEffect; + QVERIFY(!item->graphicsEffect()); + + // Ensure the existing effect is uninstalled and deleted when setting a null effect + blurEffect = new QGraphicsBlurEffect; + item->setGraphicsEffect(blurEffect); + item->setGraphicsEffect(0); + QVERIFY(!item->graphicsEffect()); + QVERIFY(!blurEffect); + + delete item; } void tst_QGraphicsItem::panel() @@ -9759,16 +9775,16 @@ void tst_QGraphicsItem::QTBUG_5418_textItemSetDefaultColor() { struct Item : public QGraphicsTextItem { - bool painted; + int painted; void paint(QPainter *painter, const QStyleOptionGraphicsItem *opt, QWidget *wid) { - painted = true; + painted++; QGraphicsTextItem::paint(painter, opt, wid); } }; Item *i = new Item; - i->painted = false; + i->painted = 0; i->setPlainText("I AM A TROLL"); QGraphicsScene scene; @@ -9780,11 +9796,11 @@ void tst_QGraphicsItem::QTBUG_5418_textItemSetDefaultColor() QTRY_VERIFY(i->painted); QApplication::processEvents(); - i->painted = false; + i->painted = 0; QColor col(Qt::red); i->setDefaultTextColor(col); QApplication::processEvents(); - QTRY_VERIFY(i->painted); //check that changing the color force an update + QTRY_COMPARE(i->painted, 1); //check that changing the color force an update i->painted = false; QImage image(400, 200, QImage::Format_RGB32); @@ -9792,7 +9808,7 @@ void tst_QGraphicsItem::QTBUG_5418_textItemSetDefaultColor() QPainter painter(&image); scene.render(&painter); painter.end(); - QVERIFY(i->painted); + QCOMPARE(i->painted, 1); int numRedPixel = 0; QRgb rgb = col.rgb(); @@ -9810,6 +9826,11 @@ void tst_QGraphicsItem::QTBUG_5418_textItemSetDefaultColor() } } QCOMPARE(numRedPixel, -1); //color not found, FAIL! + + i->painted = 0; + i->setDefaultTextColor(col); + QApplication::processEvents(); + QCOMPARE(i->painted, 0); //same color as before should not trigger an update (QTBUG-6242) } QTEST_MAIN(tst_QGraphicsItem) diff --git a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index 36ee22c..42d5268 100644 --- a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -181,6 +181,7 @@ private slots: void updateAndDelete(); void inputMethod(); void clickFocus(); + void windowFrameMargins(); }; // Subclass that exposes the protected functions. @@ -3506,6 +3507,29 @@ void tst_QGraphicsProxyWidget::clickFocus() QVERIFY(!proxy->widget()->hasFocus()); } +void tst_QGraphicsProxyWidget::windowFrameMargins() +{ + // Make sure the top margin is non-zero when passing Qt::Window. + QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(0, Qt::Window); + + qreal left, top, right, bottom; + proxy->getWindowFrameMargins(&left, &top, &right, &bottom); + QVERIFY(top > 0); + + proxy->setWidget(new QPushButton("testtest")); + proxy->getWindowFrameMargins(&left, &top, &right, &bottom); + QVERIFY(top > 0); + + QGraphicsScene scene; + scene.addItem(proxy); + proxy->getWindowFrameMargins(&left, &top, &right, &bottom); + QVERIFY(top > 0); + + proxy->unsetWindowFrameMargins(); + proxy->getWindowFrameMargins(&left, &top, &right, &bottom); + QVERIFY(top > 0); +} + QTEST_MAIN(tst_QGraphicsProxyWidget) #include "tst_qgraphicsproxywidget.moc" diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index 20d9eb8..c5e57f7 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -46,6 +46,8 @@ #endif #include <QtGui> +#include <private/qgraphicsscene_p.h> +#include <private/qgraphicssceneindex_p.h> #include <math.h> #include "../../shared/util.h" @@ -269,6 +271,7 @@ private slots: void initialFocus(); void polishItems(); void isActive(); + void siblingIndexAlwaysValid(); // task specific tests below me void task139710_bspTreeCrash(); @@ -277,6 +280,7 @@ private slots: void task160653_selectionChanged(); void task250680_childClip(); void taskQTBUG_5904_crashWithDeviceCoordinateCache(); + void taskQT657_paintIntoCacheWithTransparentParts(); }; void tst_QGraphicsScene::initTestCase() @@ -1459,6 +1463,7 @@ void tst_QGraphicsScene::focusItemLostFocus() class ClearTestItem : public QGraphicsRectItem { public: + ClearTestItem(QGraphicsItem *parent = 0) : QGraphicsRectItem(parent) {} ~ClearTestItem() { qDeleteAll(items); } QList<QGraphicsItem *> items; }; @@ -1483,6 +1488,11 @@ void tst_QGraphicsScene::clear() scene.addItem(secondItem); QCOMPARE(scene.items().at(0), firstItem); QCOMPARE(scene.items().at(1), secondItem); + + ClearTestItem *thirdItem = new ClearTestItem(firstItem); + QGraphicsItem *forthItem = new QGraphicsRectItem(firstItem); + thirdItem->items += forthItem; + // must not crash even if firstItem deletes secondItem scene.clear(); QVERIFY(scene.items().isEmpty()); @@ -4181,6 +4191,71 @@ void tst_QGraphicsScene::isActive() } +void tst_QGraphicsScene::siblingIndexAlwaysValid() +{ + QGraphicsScene scene; + + QGraphicsWidget *parent = new QGraphicsWidget; + parent->setZValue(350); + parent->setGeometry(0, 0, 100, 100); + QGraphicsWidget *parent2 = new QGraphicsWidget; + parent2->setGeometry(10, 10, 50, 50); + QGraphicsWidget *child = new QGraphicsWidget(parent2); + child->setGeometry(15, 15, 25, 25); + child->setZValue(150); + //Both are top level + scene.addItem(parent); + scene.addItem(parent2); + + //Then we make the child a top level + child->setParentItem(0); + + //This is trigerred by a repaint... + QGraphicsScenePrivate::get(&scene)->index->estimateTopLevelItems(QRectF(), Qt::AscendingOrder); + + delete child; + + //If there are in the list that's bad, we crash... + QVERIFY(!QGraphicsScenePrivate::get(&scene)->topLevelItems.contains(static_cast<QGraphicsItem *>(child))); + + //Other case + QGraphicsScene scene2; + // works with bsp tree index + scene2.setItemIndexMethod(QGraphicsScene::NoIndex); + + QGraphicsView view2(&scene2); + + // first add the blue rect + QGraphicsRectItem* const item1 = new QGraphicsRectItem(QRect( 10, 10, 10, 10 )); + item1->setPen(QColor(Qt::blue)); + item1->setBrush(Qt::blue); + scene2.addItem(item1); + + // then add the red rect + QGraphicsRectItem* const item2 = new QGraphicsRectItem(5, 5, 10, 10); + item2->setPen(QColor(Qt::red)); + item2->setBrush(Qt::red); + scene2.addItem(item2); + + // now the blue one is visible on top of the red one -> swap them (important for the bug) + item1->setZValue(1.0); + item2->setZValue(0.0); + + view2.show(); + + // handle events as a real life app would do + QApplication::processEvents(); + + // now delete the red rect + delete item2; + + // handle events as a real life app would do + QApplication::processEvents(); + + //We should not crash + +} + void tst_QGraphicsScene::taskQTBUG_5904_crashWithDeviceCoordinateCache() { QGraphicsScene scene; @@ -4196,5 +4271,43 @@ void tst_QGraphicsScene::taskQTBUG_5904_crashWithDeviceCoordinateCache() // No crash, then it passed! } +void tst_QGraphicsScene::taskQT657_paintIntoCacheWithTransparentParts() +{ + QWidget *w = new QWidget(); + w->setPalette(Qt::blue); + w->setGeometry(0, 0, 50, 50); + + QGraphicsScene *scene = new QGraphicsScene(); + QGraphicsView *view = new QGraphicsView(scene); + + QGraphicsProxyWidget *proxy = scene->addWidget(w); + proxy->setCacheMode(QGraphicsItem::DeviceCoordinateCache); + proxy->rotate(15); + + view->show(); + QTest::qWaitForWindowShown(view); + w->update(10,10,10,10); + QTest::qWait(50); + + QPixmap pix; + QGraphicsItemPrivate* itemp = QGraphicsItemPrivate::get(proxy); + QPixmapCache::Key key = itemp->extraItemCache()->deviceData.value(view->viewport()).key; + QVERIFY(QPixmapCache::find(key, &pix)); + + QTransform t = proxy->sceneTransform(); + // Map from scene coordinates to pixmap coordinates. + // X origin in the pixmap is the most-left point + // of the item's boundingRect in the scene. + qreal adjust = t.mapRect(proxy->boundingRect().toRect()).left(); + QRect rect = t.mapRect(QRect(10, 10, 10, 10)).adjusted(-adjust, 0, -adjust + 1, 1); + QPixmap subpix = pix.copy(rect); + + QImage im = subpix.toImage(); + for(int i = 0; i < im.width(); i++) { + for(int j = 0; j < im.height(); j++) + QCOMPARE(qAlpha(im.pixel(i, j)), 255); + } +} + QTEST_MAIN(tst_QGraphicsScene) #include "tst_qgraphicsscene.moc" diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index 3b98c2f..3303df5 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -106,6 +106,7 @@ private slots: void font_data(); void font(); void fontPropagation(); + void fontChangedEvent(); void fontPropagationWidgetItemWidget(); void fontPropagationSceneChange(); void geometry_data(); @@ -673,6 +674,40 @@ void tst_QGraphicsWidget::fontPropagation() QCOMPARE(child2->font().pointSize(), 43); } +void tst_QGraphicsWidget::fontChangedEvent() +{ + QGraphicsWidget *root = new QGraphicsWidget; + QGraphicsScene scene; + scene.addItem(root); + + // Check that only the application fonts apply. + QFont appFont = QApplication::font(); + QCOMPARE(scene.font(), appFont); + QCOMPARE(root->font(), appFont); + + EventSpy rootSpyFont(root, QEvent::FontChange); + EventSpy rootSpyPolish(root, QEvent::Polish); + QCOMPARE(rootSpyFont.count(), 0); + QApplication::processEvents(); //The polish event is sent + QCOMPARE(rootSpyPolish.count(), 1); + QApplication::processEvents(); //Process events to see if we get the font change event + //The font is still the same so no fontChangeEvent + QCOMPARE(rootSpyFont.count(), 0); + + QFont font; + font.setPointSize(43); + root->setFont(font); + QApplication::processEvents(); //Process events to get the font change event + //The font changed + QCOMPARE(rootSpyFont.count(), 1); + + //then roll back to the default one. + root->setFont(appFont); + QApplication::processEvents(); //Process events to get the font change event + //The font changed + QCOMPARE(rootSpyFont.count(), 2); +} + void tst_QGraphicsWidget::fontPropagationWidgetItemWidget() { QGraphicsWidget *widget = new QGraphicsWidget; diff --git a/tests/auto/qheaderview/tst_qheaderview.cpp b/tests/auto/qheaderview/tst_qheaderview.cpp index c13e829..a8e7461 100644 --- a/tests/auto/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/qheaderview/tst_qheaderview.cpp @@ -43,6 +43,7 @@ #include <QtTest/QtTest> #include <QStandardItemModel> #include <QStringListModel> +#include <QSortFilterProxyModel> #include <qabstractitemmodel.h> #include <qapplication.h> @@ -188,6 +189,7 @@ private slots: void task236450_hidden_data(); void task236450_hidden(); void task248050_hideRow(); + void QTBUG6058_reset(); protected: QHeaderView *view; @@ -1947,5 +1949,49 @@ void tst_QHeaderView::task248050_hideRow() } +//returns 0 if everything is fine. +static int checkHeaderViewOrder(QHeaderView *view, const QVector<int> &expected) +{ + if (view->count() != expected.count()) + return 1; + + for (int i = 0; i < expected.count(); i++) { + if (view->logicalIndex(i) != expected.at(i)) + return i + 10; + if (view->visualIndex(expected.at(i)) != i) + return i + 100; + } + return 0; +} + + +void tst_QHeaderView::QTBUG6058_reset() +{ + QStringListModel model1( QStringList() << "0" << "1" << "2" << "3" << "4" << "5" ); + QStringListModel model2( QStringList() << "a" << "b" << "c" ); + QSortFilterProxyModel proxy; + + QHeaderView view(Qt::Vertical); + view.setModel(&proxy); + view.show(); + QTest::qWait(20); + + proxy.setSourceModel(&model1); + QApplication::processEvents(); + view.swapSections(0,2); + view.swapSections(1,4); + QApplication::processEvents(); + QCOMPARE(checkHeaderViewOrder(&view, QVector<int>() << 2 << 4 << 0 << 3 << 1 << 5) , 0); + + proxy.setSourceModel(&model2); + QApplication::processEvents(); + QCOMPARE(checkHeaderViewOrder(&view, QVector<int>() << 2 << 0 << 1 ) , 0); + + proxy.setSourceModel(&model1); + QApplication::processEvents(); + QCOMPARE(checkHeaderViewOrder(&view, QVector<int>() << 2 << 0 << 1 << 3 << 4 << 5 ) , 0); +} + + QTEST_MAIN(tst_QHeaderView) #include "tst_qheaderview.moc" diff --git a/tests/auto/qhttp/tst_qhttp.cpp b/tests/auto/qhttp/tst_qhttp.cpp index 0ea0d15..b4b6ceb 100644 --- a/tests/auto/qhttp/tst_qhttp.cpp +++ b/tests/auto/qhttp/tst_qhttp.cpp @@ -363,7 +363,7 @@ void tst_QHttp::get() } addRequest( QHttpRequestHeader(), getId ); - QTestEventLoop::instance().enterLoop( 30 ); + QTestEventLoop::instance().enterLoop( 50 ); if ( QTestEventLoop::instance().timeout() ) QFAIL( "Network operation timed out" ); diff --git a/tests/auto/qlibrary/lib/lib.pro b/tests/auto/qlibrary/lib/lib.pro index 25a50b5..6d80881 100644 --- a/tests/auto/qlibrary/lib/lib.pro +++ b/tests/auto/qlibrary/lib/lib.pro @@ -10,20 +10,6 @@ wince*: DEFINES += WIN32_MSVC win32-msvc: DEFINES += WIN32_MSVC win32-borland: DEFINES += WIN32_BORLAND -# Force a copy of the library to have an extension that is non-standard. -# We want to test if we can load a shared library with *any* filename... - -# For windows test if we can load a filename with multiple dots. -win32: { - QMAKE_POST_LINK = copy /Y $(DESTDIR_TARGET) ..\mylib.dl2 && \ - copy /Y $(DESTDIR_TARGET) ..\system.trolltech.test.mylib.dll && \ - copy /Y $(DESTDIR_TARGET) ..\mylib_noextension -} -unix:!symbian: { - QMAKE_POST_LINK = cp -f $(DESTDIR)$(TARGET) ../libmylib.so2 && \ - cp -f $(DESTDIR)$(TARGET) ../system.trolltech.test.mylib.so -} - #no special install rule for the library used by test INSTALLS = diff --git a/tests/auto/qlibrary/lib2/lib2.pro b/tests/auto/qlibrary/lib2/lib2.pro index fc00af8..da30a2d 100644 --- a/tests/auto/qlibrary/lib2/lib2.pro +++ b/tests/auto/qlibrary/lib2/lib2.pro @@ -14,15 +14,19 @@ win32-borland: DEFINES += WIN32_BORLAND # Force a copy of the library to have an extension that is non-standard. # We want to test if we can load a shared library with *any* filename... -# For windows test if we can load a filename with multiple dots. -win32: { - QMAKE_POST_LINK = copy /Y ..\mylib2.dll ..\mylib.dl2 && \ - copy /Y ..\mylib2.dll ..\system.trolltech.test.mylib.dll -} - -unix:!symbian: { - QMAKE_POST_LINK = cp -f $(DESTDIR)$(TARGET) ../libmylib.so2 && \ - cp -f $(DESTDIR)$(TARGET) ../system.trolltech.test.mylib.so +!symbian { + win32 { + src = $(DESTDIR_TARGET) + files = mylib.dl2 system.trolltech.test.mylib.dll + } else { + src = $(DESTDIR)$(TARGET) + files = libmylib.so2 system.trolltech.test.mylib.so + } + for(file, files) { + QMAKE_POST_LINK += $(COPY) $$src ..$$QMAKE_DIR_SEP$$file && + CLEAN_FILES += ../$$file + } + QMAKE_POST_LINK = $$member(QMAKE_POST_LINK, 0, -2) } symbian-abld: { diff --git a/tests/auto/qlibrary/tst_qlibrary.cpp b/tests/auto/qlibrary/tst_qlibrary.cpp index ca6db9a..c7f52bc 100644 --- a/tests/auto/qlibrary/tst_qlibrary.cpp +++ b/tests/auto/qlibrary/tst_qlibrary.cpp @@ -218,22 +218,22 @@ void tst_QLibrary::load_data() #else QString currDir = QDir::currentPath(); #endif - QTest::newRow( "ok00" ) << currDir + "/mylib" << (bool)true; - QTest::newRow( "notexist" ) << currDir + "/nolib" << (bool)false; - QTest::newRow( "badlibrary" ) << currDir + "/qlibrary.pro" << (bool)false; + QTest::newRow( "ok00" ) << currDir + "/mylib" << true; + QTest::newRow( "notexist" ) << currDir + "/nolib" << false; + QTest::newRow( "badlibrary" ) << currDir + "/qlibrary.pro" << false; #ifdef Q_OS_MAC - QTest::newRow("ok (libmylib ver. 1)") << currDir + "/libmylib" <<(bool)true; + QTest::newRow("ok (libmylib ver. 1)") << currDir + "/libmylib" <<true; #endif # if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) - QTest::newRow( "ok01 (with suffix)" ) << currDir + "/mylib.dll" << (bool)true; - QTest::newRow( "ok02 (with non-standard suffix)" ) << currDir + "/mylib.dl2" << (bool)true; - QTest::newRow( "ok03 (with many dots)" ) << currDir + "/system.trolltech.test.mylib.dll" << (bool)true; + QTest::newRow( "ok01 (with suffix)" ) << currDir + "/mylib.dll" << true; + QTest::newRow( "ok02 (with non-standard suffix)" ) << currDir + "/mylib.dl2" << true; + QTest::newRow( "ok03 (with many dots)" ) << currDir + "/system.trolltech.test.mylib.dll" << true; # elif defined Q_OS_UNIX - QTest::newRow( "ok01 (with suffix)" ) << currDir + "/libmylib" SUFFIX << (bool)true; - QTest::newRow( "ok02 (with non-standard suffix)" ) << currDir + "/libmylib.so2" << (bool)true; - QTest::newRow( "ok03 (with non-standard suffix)" ) << currDir + "/system.trolltech.test.mylib.so" << (bool)true; + QTest::newRow( "ok01 (with suffix)" ) << currDir + "/libmylib" SUFFIX << true; + QTest::newRow( "ok02 (with non-standard suffix)" ) << currDir + "/libmylib.so2" << true; + QTest::newRow( "ok03 (with many dots)" ) << currDir + "/system.trolltech.test.mylib.so" << true; # endif // Q_OS_UNIX } @@ -262,12 +262,12 @@ void tst_QLibrary::unload_data() QString currDir = QDir::currentPath(); #endif - QTest::newRow( "mylib" ) << currDir + "/mylib" << (bool)TRUE; + QTest::newRow( "mylib" ) << currDir + "/mylib" << true; #ifdef Q_WS_MAC if (QSysInfo::MacintoshVersion <= QSysInfo::MV_10_3) QEXPECT_FAIL("mylib", "dlcompat cannot unload libraries", Continue); #endif - QTest::newRow( "ok01" ) << currDir + "/nolib" << (bool)FALSE; + QTest::newRow( "ok01" ) << currDir + "/nolib" << false; } void tst_QLibrary::unload() @@ -312,9 +312,9 @@ void tst_QLibrary::resolve_data() QString currDir = QDir::currentPath(); #endif - QTest::newRow( "ok00" ) << currDir + "/mylib" << QString("mylibversion") << (bool)TRUE; - QTest::newRow( "bad00" ) << currDir + "/mylib" << QString("nosym") << (bool)FALSE; - QTest::newRow( "bad01" ) << currDir + "/nolib" << QString("nosym") << (bool)FALSE; + QTest::newRow( "ok00" ) << currDir + "/mylib" << QString("mylibversion") << true; + QTest::newRow( "bad00" ) << currDir + "/mylib" << QString("nosym") << false; + QTest::newRow( "bad01" ) << currDir + "/nolib" << QString("nosym") << false; } void tst_QLibrary::resolve() @@ -479,9 +479,9 @@ void tst_QLibrary::loadHints_data() #if defined(Q_OS_AIX) if (QFile::exists("/usr/lib/libGL.a") || QFile::exists("/usr/X11R6/lib/libGL.a")) { # if QT_POINTER_SIZE == 4 - QTest::newRow( "ok03 (Archive member)" ) << "libGL.a(shr.o)" << int(QLibrary::LoadArchiveMemberHint) << (bool)TRUE; + QTest::newRow( "ok03 (Archive member)" ) << "libGL.a(shr.o)" << int(QLibrary::LoadArchiveMemberHint) << true; # else - QTest::newRow( "ok03 (Archive member)" ) << "libGL.a(shr_64.o)" << int(QLibrary::LoadArchiveMemberHint) << (bool)TRUE; + QTest::newRow( "ok03 (Archive member)" ) << "libGL.a(shr_64.o)" << int(QLibrary::LoadArchiveMemberHint) << true; #endif } #endif @@ -494,13 +494,13 @@ void tst_QLibrary::loadHints_data() lh |= QLibrary::ResolveAllSymbolsHint; # if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN) - QTest::newRow( "ok01 (with suffix)" ) << currDir + "/mylib.dll" << int(lh) << (bool)TRUE; - QTest::newRow( "ok02 (with non-standard suffix)" ) << currDir + "/mylib.dl2" << int(lh) << (bool)TRUE; - QTest::newRow( "ok03 (with many dots)" ) << currDir + "/system.trolltech.test.mylib.dll" << int(lh) << (bool)TRUE; + QTest::newRow( "ok01 (with suffix)" ) << currDir + "/mylib.dll" << int(lh) << true; + QTest::newRow( "ok02 (with non-standard suffix)" ) << currDir + "/mylib.dl2" << int(lh) << true; + QTest::newRow( "ok03 (with many dots)" ) << currDir + "/system.trolltech.test.mylib.dll" << int(lh) << true; # elif defined Q_OS_UNIX - QTest::newRow( "ok01 (with suffix)" ) << currDir + "/libmylib" SUFFIX << int(lh) << (bool)TRUE; - QTest::newRow( "ok02 (with non-standard suffix)" ) << currDir + "/libmylib.so2" << int(lh) << (bool)TRUE; - QTest::newRow( "ok03 (with many dots)" ) << currDir + "/system.trolltech.test.mylib.so" << int(lh) << (bool)TRUE; + QTest::newRow( "ok01 (with suffix)" ) << currDir + "/libmylib" SUFFIX << int(lh) << true; + QTest::newRow( "ok02 (with non-standard suffix)" ) << currDir + "/libmylib.so2" << int(lh) << true; + QTest::newRow( "ok03 (with many dots)" ) << currDir + "/system.trolltech.test.mylib.so" << int(lh) << true; # endif // Q_OS_UNIX } @@ -535,10 +535,10 @@ void tst_QLibrary::fileName_data() << sys_qualifiedLibraryName(QLatin1String("mylib")); #ifdef Q_WS_WIN #ifndef Q_OS_WINCE - QTest::newRow( "ok02" ) << "user32" + QTest::newRow( "ok03" ) << "user32" << "USER32.dll"; #else - QTest::newRow( "ok02" ) << "coredll" + QTest::newRow( "ok03" ) << "coredll" << "coredll.dll"; #endif #endif diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp index b4dfbba..fa2b9bd 100644 --- a/tests/auto/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/qlineedit/tst_qlineedit.cpp @@ -51,6 +51,10 @@ #include "qcompleter.h" #include "qstandarditemmodel.h" +#ifndef QT_NO_CLIPBOARD +#include "qclipboard.h" +#endif + #ifdef Q_WS_MAC #include <Carbon/Carbon.h> // For the random function. #include <cstdlib> // For the random function. @@ -157,6 +161,10 @@ private slots: void undo_keypressevents_data(); void undo_keypressevents(); +#ifndef QT_NO_CLIPBOARD + void QTBUG5786_undoPaste(); +#endif + void clear(); void text_data(); @@ -261,6 +269,8 @@ private slots: void task241436_passwordEchoOnEditRestoreEchoMode(); void task248948_redoRemovedSelection(); void taskQTBUG_4401_enterKeyClearsPassword(); + void taskQTBUG_4679_moveToStartEndOfBlock(); + void taskQTBUG_4679_selectToStartEndOfBlock(); protected slots: #ifdef QT3_SUPPORT @@ -1406,6 +1416,50 @@ void tst_QLineEdit::undo_keypressevents() QVERIFY(testWidget->text().isEmpty()); } +#ifndef QT_NO_CLIPBOARD +static bool nativeClipboardWorking() +{ +#ifdef Q_WS_MAC + PasteboardRef pasteboard; + OSStatus status = PasteboardCreate(0, &pasteboard); + if (status == noErr) + CFRelease(pasteboard); + return status == noErr; +#endif + return true; +} + +void tst_QLineEdit::QTBUG5786_undoPaste() +{ + if (!nativeClipboardWorking()) + QSKIP("this machine doesn't support the clipboard", SkipAll); + QString initial("initial"); + QString string("test"); + QString additional("add"); + QApplication::clipboard()->setText(string); + QLineEdit edit(initial); + QCOMPARE(edit.text(), initial); + edit.paste(); + QCOMPARE(edit.text(), initial + string); + edit.paste(); + QCOMPARE(edit.text(), initial + string + string); + edit.insert(additional); + QCOMPARE(edit.text(), initial + string + string + additional); + edit.undo(); + QCOMPARE(edit.text(), initial + string + string); + edit.undo(); + QCOMPARE(edit.text(), initial + string); + edit.undo(); + QCOMPARE(edit.text(), initial); + edit.selectAll(); + QApplication::clipboard()->setText(QString()); + edit.paste(); + QVERIFY(edit.text().isEmpty()); + +} +#endif + + void tst_QLineEdit::clear() { // checking that clear of empty/nullstring doesn't add to undo history @@ -3308,6 +3362,7 @@ void tst_QLineEdit::task174640_editingFinished() QApplication::setActiveWindow(&mw); mw.activateWindow(); QTest::qWaitForWindowShown(&mw); + QTRY_COMPARE(&mw, QApplication::activeWindow()); QSignalSpy editingFinishedSpy(le1, SIGNAL(editingFinished())); @@ -3548,5 +3603,40 @@ void tst_QLineEdit::taskQTBUG_4401_enterKeyClearsPassword() QTRY_COMPARE(testWidget->text(), password); } +void tst_QLineEdit::taskQTBUG_4679_moveToStartEndOfBlock() +{ +#ifdef Q_OS_MAC + const QString text("there are no blocks for lineEdit"); + testWidget->setText(text); + testWidget->setCursorPosition(5); + QCOMPARE(testWidget->cursorPosition(), 5); + testWidget->setFocus(); + QTest::keyPress(testWidget, Qt::Key_A, Qt::MetaModifier); + QCOMPARE(testWidget->cursorPosition(), 0); + QTest::keyPress(testWidget, Qt::Key_E, Qt::MetaModifier); + QCOMPARE(testWidget->cursorPosition(), text.size()); +#endif // Q_OS_MAC +} + +void tst_QLineEdit::taskQTBUG_4679_selectToStartEndOfBlock() +{ +#ifdef Q_OS_MAC + const QString text("there are no blocks for lineEdit, select all"); + testWidget->setText(text); + testWidget->setCursorPosition(5); + QCOMPARE(testWidget->cursorPosition(), 5); + testWidget->setFocus(); + QTest::keyPress(testWidget, Qt::Key_A, Qt::MetaModifier | Qt::ShiftModifier); + QCOMPARE(testWidget->cursorPosition(), 0); + QVERIFY(testWidget->hasSelectedText()); + QCOMPARE(testWidget->selectedText(), text.mid(0, 5)); + + QTest::keyPress(testWidget, Qt::Key_E, Qt::MetaModifier | Qt::ShiftModifier); + QCOMPARE(testWidget->cursorPosition(), text.size()); + QVERIFY(testWidget->hasSelectedText()); + QCOMPARE(testWidget->selectedText(), text.mid(5)); +#endif // Q_OS_MAC +} + QTEST_MAIN(tst_QLineEdit) #include "tst_qlineedit.moc" diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp index 605b3e3..98001c8 100644 --- a/tests/auto/qlistview/tst_qlistview.cpp +++ b/tests/auto/qlistview/tst_qlistview.cpp @@ -586,7 +586,15 @@ void tst_QListView::indexAt() index = view.indexAt(QPoint(20,2 * sz.height())); QVERIFY(!index.isValid()); - + // Check when peeking out of the viewport bounds + index = view.indexAt(QPoint(view.viewport()->rect().width(), 0)); + QVERIFY(!index.isValid()); + index = view.indexAt(QPoint(-1, 0)); + QVERIFY(!index.isValid()); + index = view.indexAt(QPoint(20, view.viewport()->rect().height())); + QVERIFY(!index.isValid()); + index = view.indexAt(QPoint(20, -1)); + QVERIFY(!index.isValid()); model.rCount = 30; QListViewShowEventListener view2; @@ -1779,8 +1787,10 @@ void tst_QListView::task262152_setModelColumnNavigate() view.setModelColumn(1); view.show(); + QApplication::setActiveWindow(&view); QTest::qWaitForWindowShown(&view); - QTest::qWait(120); + QTest::qWait(30); + QTRY_COMPARE(static_cast<QWidget *>(&view), QApplication::activeWindow()); QTest::keyClick(&view, Qt::Key_Down); QTest::qWait(30); QTRY_COMPARE(view.currentIndex(), model.index(1,1)); @@ -1898,7 +1908,7 @@ void tst_QListView::taskQTBUG_5877_skippingItemInPageDownUp() QTest::qWaitForWindowShown(&vu); int itemHeight = vu.visualRect(model.index(0, 0)).height(); - int visibleRowCount = vu.height() / itemHeight; + int visibleRowCount = vu.viewport()->height() / itemHeight; int scrolledRowCount = visibleRowCount - 1; for (int i = 0; i < currentItemIndexes.size(); ++i) { diff --git a/tests/auto/qlistwidget/tst_qlistwidget.cpp b/tests/auto/qlistwidget/tst_qlistwidget.cpp index cb8f1e9..863c308 100644 --- a/tests/auto/qlistwidget/tst_qlistwidget.cpp +++ b/tests/auto/qlistwidget/tst_qlistwidget.cpp @@ -867,6 +867,7 @@ void tst_QListWidget::moveItemsPriv_data() QTest::newRow("Same place") << 5 << 2 << 2 << false; QTest::newRow("Up") << 5 << 4 << 2 << true; QTest::newRow("Down") << 5 << 2 << 4 << true; + QTest::newRow("QTBUG-6532 assert") << 5 << 0 << 1 << false; } void tst_QListWidget::moveItemsPriv() diff --git a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp index 5ead049..8cabadb 100644 --- a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp @@ -695,7 +695,7 @@ public: || socket.error() == QLocalSocket::ConnectionRefusedError) && tries < 1000); if (tries == 0 && socket.state() != QLocalSocket::ConnectedState) { - QVERIFY(socket.waitForConnected(3000)); + QVERIFY(socket.waitForConnected(7000)); QVERIFY(socket.state() == QLocalSocket::ConnectedState); } @@ -725,7 +725,7 @@ public: int done = clients; while (done > 0) { bool timedOut = true; - QVERIFY(server.waitForNewConnection(3000, &timedOut)); + QVERIFY(server.waitForNewConnection(7000, &timedOut)); QVERIFY(!timedOut); QLocalSocket *serverSocket = server.nextPendingConnection(); QVERIFY(serverSocket); diff --git a/tests/auto/qmenu/tst_qmenu.cpp b/tests/auto/qmenu/tst_qmenu.cpp index 7cdfe46..af10ad1 100644 --- a/tests/auto/qmenu/tst_qmenu.cpp +++ b/tests/auto/qmenu/tst_qmenu.cpp @@ -82,7 +82,7 @@ private slots: void keyboardNavigation_data(); void keyboardNavigation(); void focus(); - void overrideMenuAction(); + void overrideMenuAction(); void statusTip(); void widgetActionFocus(); void mouseActivation(); @@ -103,12 +103,14 @@ private slots: void task258920_mouseBorder(); void setFixedWidth(); void deleteActionInTriggered(); + void pushButtonPopulateOnAboutToShow(); protected slots: void onActivated(QAction*); void onHighlighted(QAction*); void onStatusMessageChanged(const QString &); void onStatusTipTimer(); void deleteAction(QAction *a) { delete a; } + void populateMenu(); private: void createActions(); QMenu *menus[2], *lastMenu; @@ -258,6 +260,15 @@ void tst_QMenu::onStatusMessageChanged(const QString &s) statustip=s; } +void tst_QMenu::populateMenu(){ + //just adds 3 dummy actions and a separator. + lastMenu->addAction("Foo"); + lastMenu->addAction("Bar"); + lastMenu->addAction("FooBar"); + lastMenu->addSeparator(); + +} + //actual tests void @@ -896,7 +907,29 @@ void tst_QMenu::deleteActionInTriggered() QVERIFY(!a); } +void tst_QMenu::pushButtonPopulateOnAboutToShow() +{ + QPushButton b("Test PushButton"); + b.setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); + lastMenu = new QMenu; + b.setMenu(lastMenu); + const int scrNumber = QApplication::desktop()->screenNumber(&b); + connect(lastMenu, SIGNAL(aboutToShow()), this, SLOT(populateMenu())); + b.show(); + const QRect screen = QApplication::desktop()->screenGeometry(scrNumber); + b.move(10, screen.bottom()-b.height()-5); + QTest::qWaitForWindowShown(&b); + QTimer::singleShot(300,lastMenu, SLOT(hide())); + QTest::mouseClick(&b, Qt::LeftButton, Qt::NoModifier, b.rect().center()); + QVERIFY(!lastMenu->geometry().intersects(b.geometry())); + + b.move(10, screen.bottom()-lastMenu->height()-5); + QTimer::singleShot(300,lastMenu, SLOT(hide())); + QTest::mouseClick(&b, Qt::LeftButton, Qt::NoModifier, b.rect().center()); + QVERIFY(!lastMenu->geometry().intersects(b.geometry())); + +} QTEST_MAIN(tst_QMenu) diff --git a/tests/auto/qmenubar/tst_qmenubar.cpp b/tests/auto/qmenubar/tst_qmenubar.cpp index 4291c3e..aa6caae 100644 --- a/tests/auto/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/qmenubar/tst_qmenubar.cpp @@ -167,7 +167,8 @@ private slots: void task223138_triggered(); void task256322_highlight(); void menubarSizeHint(); - + void taskQTBUG4965_escapeEaten(); + #if defined(QT3_SUPPORT) void indexBasedInsertion_data(); void indexBasedInsertion(); @@ -1359,7 +1360,7 @@ tst_QMenuBar::allowActiveAndDisabled() // disabled menu items are added QMenu fileMenu("&File"); - // Task 241043 : check that second menu is activated + // Task 241043 : check that second menu is activated // if all items are disabled QAction *act = fileMenu.addAction("Disabled"); act->setEnabled(false); @@ -1387,7 +1388,7 @@ tst_QMenuBar::allowActiveAndDisabled() QCOMPARE(mb->activeAction()->text(), fileMenu.title()); else QCOMPARE(mb->activeAction()->text(), fileMenu.title()); - + mb->hide(); #endif //Q_WS_MAC } @@ -1602,7 +1603,7 @@ void tst_QMenuBar::menubarSizeHint() virtual int pixelMetric(PixelMetric metric, const QStyleOption * option = 0, const QWidget * widget = 0 ) const { // I chose strange values (prime numbers to be more sure that the size of the menubar is correct) - switch (metric) + switch (metric) { case QStyle::PM_MenuBarItemSpacing: return 7; @@ -1620,7 +1621,7 @@ void tst_QMenuBar::menubarSizeHint() QMenuBar mb; mb.setNativeMenuBar(false); //we can't check the geometry of native menubars - + mb.setStyle(&style); //this is a list of arbitrary strings so that we check the geometry QStringList list = QStringList() << "trer" << "ezrfgtgvqd" << "sdgzgzerzerzer" << "eerzertz" << "er"; @@ -1664,6 +1665,30 @@ void tst_QMenuBar::menubarSizeHint() QCOMPARE(resSize, mb.sizeHint()); } +void tst_QMenuBar::taskQTBUG4965_escapeEaten() +{ +#ifdef Q_WS_MAC + QSKIP("On Mac, do not test the menubar with escape key", SkipAll); +#endif + QMenuBar menubar; + QMenu menu("menu1"); + QAction *first = menubar.addMenu(&menu); + menu.addAction("quit", &menubar, SLOT(close()), QKeySequence("ESC")); + menubar.show(); + QApplication::setActiveWindow(&menubar); + QTest::qWaitForWindowShown(&menubar); + menubar.setActiveAction(first); + QTRY_VERIFY(menu.isVisible()); + QCOMPARE(menubar.activeAction(), first); + QTest::keyClick(0, Qt::Key_Escape); + QVERIFY(!menu.isVisible()); + QTRY_VERIFY(menubar.hasFocus()); + QCOMPARE(menubar.activeAction(), first); + QTest::keyClick(0, Qt::Key_Escape); + QVERIFY(!menubar.activeAction()); + QTest::keyClick(0, Qt::Key_Escape); //now the action should be triggered + QTRY_VERIFY(!menubar.isVisible()); +} #if defined(QT3_SUPPORT) void tst_QMenuBar::indexBasedInsertion_data() diff --git a/tests/auto/qnetworkcookiejar/tst_qnetworkcookiejar.cpp b/tests/auto/qnetworkcookiejar/tst_qnetworkcookiejar.cpp index ff7e78e..b52c515 100644 --- a/tests/auto/qnetworkcookiejar/tst_qnetworkcookiejar.cpp +++ b/tests/auto/qnetworkcookiejar/tst_qnetworkcookiejar.cpp @@ -168,13 +168,16 @@ void tst_QNetworkCookieJar::setCookiesFromUrl_data() cookie.setDomain("something.completely.different"); QTest::newRow("security-domain-1") << preset << cookie << "http://www.foo.tld" << result << false; - cookie.setDomain("www.foo.tld"); + // we want the cookie to be accepted although the path does not match, see QTBUG-5815 + cookie.setDomain(".foo.tld"); cookie.setPath("/something"); - QTest::newRow("security-path-1") << preset << cookie << "http://www.foo.tld" << result << false; + result += cookie; + QTest::newRow("security-path-1") << preset << cookie << "http://www.foo.tld" << result << true; // setting the defaults: finalCookie = cookie; finalCookie.setPath("/something/"); + finalCookie.setDomain("www.foo.tld"); cookie.setPath(""); cookie.setDomain(""); result.clear(); @@ -285,6 +288,22 @@ void tst_QNetworkCookieJar::cookiesForUrl_data() QTest::newRow("exp-match-4") << allCookies << "http://qt.nokia.com/web" << result; QTest::newRow("exp-match-4") << allCookies << "http://qt.nokia.com/web/" << result; QTest::newRow("exp-match-6") << allCookies << "http://qt.nokia.com/web/content" << result; + + // path matching + allCookies.clear(); + QNetworkCookie anotherCookie; + anotherCookie.setName("a"); + anotherCookie.setPath("/web"); + anotherCookie.setDomain(".nokia.com"); + allCookies += anotherCookie; + result.clear(); + QTest::newRow("path-unmatch-1") << allCookies << "http://nokia.com/" << result; + QTest::newRow("path-unmatch-2") << allCookies << "http://nokia.com/something/else" << result; + result += anotherCookie; + QTest::newRow("path-match-1") << allCookies << "http://nokia.com/web" << result; + QTest::newRow("path-match-2") << allCookies << "http://nokia.com/web/" << result; + QTest::newRow("path-match-3") << allCookies << "http://nokia.com/web/content" << result; + } void tst_QNetworkCookieJar::cookiesForUrl() diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index bd83c47..6d43c1d 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -2212,7 +2212,7 @@ void tst_QNetworkReply::ioGetWithManyProxies() connect(&manager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)), SLOT(sslErrors(QNetworkReply*,QList<QSslError>))); #endif - QTestEventLoop::instance().enterLoop(10); + QTestEventLoop::instance().enterLoop(15); QVERIFY(!QTestEventLoop::instance().timeout()); manager.disconnect(SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), @@ -2622,7 +2622,7 @@ void tst_QNetworkReply::ioPostToHttpFromSocket() QSignalSpy authenticationRequiredSpy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); QSignalSpy proxyAuthenticationRequiredSpy(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); - QTestEventLoop::instance().enterLoop(6); + QTestEventLoop::instance().enterLoop(12); disconnect(&manager, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); disconnect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), @@ -3241,8 +3241,11 @@ void tst_QNetworkReply::receiveCookiesFromHttp_data() cookie = QNetworkCookie("a", "b"); cookie.setPath("/not/part-of-path"); header << cookie; + cookie.setDomain(QtNetworkSettings::serverName()); + jar << cookie; QTest::newRow("invalid-cookie-path") << "a=b; path=/not/part-of-path" << header << jar; + jar.clear(); cookie = QNetworkCookie("a", "b"); cookie.setDomain(".example.com"); header.clear(); diff --git a/tests/auto/qobject/tst_qobject.cpp b/tests/auto/qobject/tst_qobject.cpp index 5035139..67a9c46 100644 --- a/tests/auto/qobject/tst_qobject.cpp +++ b/tests/auto/qobject/tst_qobject.cpp @@ -60,6 +60,10 @@ #include <QProcess> #include "qobject.h" +#ifdef QT_BUILD_INTERNAL +#include <private/qobject_p.h> +#endif + #include <math.h> @@ -121,6 +125,7 @@ private slots: void interfaceIid(); void deleteQObjectWhenDeletingEvent(); void overloads(); + void isSignalConnected(); protected: }; @@ -3016,5 +3021,109 @@ void tst_QObject::overloads() QCOMPARE(obj2.o4_obj, qApp); //default arg of the slot } +class ManySignals : public QObject +{ Q_OBJECT + friend class tst_QObject; +signals: + void sig00(); void sig01(); void sig02(); void sig03(); void sig04(); + void sig05(); void sig06(); void sig07(); void sig08(); void sig09(); + void sig10(); void sig11(); void sig12(); void sig13(); void sig14(); + void sig15(); void sig16(); void sig17(); void sig18(); void sig19(); + void sig20(); void sig21(); void sig22(); void sig23(); void sig24(); + void sig25(); void sig26(); void sig27(); void sig28(); void sig29(); + void sig30(); void sig31(); void sig32(); void sig33(); void sig34(); + void sig35(); void sig36(); void sig37(); void sig38(); void sig39(); + void sig40(); void sig41(); void sig42(); void sig43(); void sig44(); + void sig45(); void sig46(); void sig47(); void sig48(); void sig49(); + void sig50(); void sig51(); void sig52(); void sig53(); void sig54(); + void sig55(); void sig56(); void sig57(); void sig58(); void sig59(); + void sig60(); void sig61(); void sig62(); void sig63(); void sig64(); + void sig65(); void sig66(); void sig67(); void sig68(); void sig69(); + +public slots: + void received() { rec++; } +public: + int rec; +}; + + +void tst_QObject::isSignalConnected() +{ + ManySignals o; + o.rec = 0; +#ifdef QT_BUILD_INTERNAL + QObjectPrivate *priv = QObjectPrivate::get(&o); + QVERIFY(!priv->isSignalConnected(priv->signalIndex("destroyed()"))); + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig00()"))); + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig05()"))); + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig15()"))); + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig29()"))); + if (sizeof(void *) >= 8) { //on 32bit isSignalConnected only works with the first 32 signals + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig60()"))); + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig61()"))); + } +#endif + + QObject::connect(&o, SIGNAL(sig00()), &o, SIGNAL(sig69())); + QObject::connect(&o, SIGNAL(sig34()), &o, SIGNAL(sig03())); + QObject::connect(&o, SIGNAL(sig69()), &o, SIGNAL(sig34())); + QObject::connect(&o, SIGNAL(sig03()), &o, SIGNAL(sig18())); + +#ifdef QT_BUILD_INTERNAL + QVERIFY(!priv->isSignalConnected(priv->signalIndex("destroyed()"))); + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig05()"))); + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig15()"))); + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig29()"))); + + QVERIFY(priv->isSignalConnected(priv->signalIndex("sig00()"))); + QVERIFY(priv->isSignalConnected(priv->signalIndex("sig03()"))); + QVERIFY(priv->isSignalConnected(priv->signalIndex("sig34()"))); + QVERIFY(priv->isSignalConnected(priv->signalIndex("sig69()"))); + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig18()"))); +#endif + + QObject::connect(&o, SIGNAL(sig18()), &o, SIGNAL(sig29())); + QObject::connect(&o, SIGNAL(sig29()), &o, SIGNAL(sig62())); + QObject::connect(&o, SIGNAL(sig62()), &o, SIGNAL(sig28())); + QObject::connect(&o, SIGNAL(sig28()), &o, SIGNAL(sig27())); + +#ifdef QT_BUILD_INTERNAL + QVERIFY(priv->isSignalConnected(priv->signalIndex("sig18()"))); + QVERIFY(priv->isSignalConnected(priv->signalIndex("sig62()"))); + QVERIFY(priv->isSignalConnected(priv->signalIndex("sig28()"))); + QVERIFY(priv->isSignalConnected(priv->signalIndex("sig69()"))); + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig27()"))); +#endif + + QCOMPARE(o.rec, 0); + emit o.sig01(); + emit o.sig34(); + QCOMPARE(o.rec, 0); + + QObject::connect(&o, SIGNAL(sig27()), &o, SLOT(received())); + +#ifdef QT_BUILD_INTERNAL + QVERIFY(priv->isSignalConnected(priv->signalIndex("sig00()"))); + QVERIFY(priv->isSignalConnected(priv->signalIndex("sig03()"))); + QVERIFY(priv->isSignalConnected(priv->signalIndex("sig34()"))); + QVERIFY(priv->isSignalConnected(priv->signalIndex("sig18()"))); + QVERIFY(priv->isSignalConnected(priv->signalIndex("sig62()"))); + QVERIFY(priv->isSignalConnected(priv->signalIndex("sig28()"))); + QVERIFY(priv->isSignalConnected(priv->signalIndex("sig69()"))); + QVERIFY(priv->isSignalConnected(priv->signalIndex("sig27()"))); + + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig04()"))); + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig21()"))); + QVERIFY(!priv->isSignalConnected(priv->signalIndex("sig25()"))); +#endif + + emit o.sig00(); + QCOMPARE(o.rec, 1); + emit o.sig69(); + QCOMPARE(o.rec, 2); + emit o.sig36(); + QCOMPARE(o.rec, 2); +} + QTEST_MAIN(tst_QObject) #include "tst_qobject.moc" diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index 8b71349..67d1972 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -41,7 +41,7 @@ #include <QtTest/QtTest> - +#include "../../shared/util.h" #include <qpainter.h> #include <qapplication.h> @@ -67,6 +67,11 @@ #include <qqueue.h> +#include <qgraphicsview.h> +#include <qgraphicsscene.h> +#include <qgraphicsproxywidget.h> +#include <qlayout.h> + #if defined(Q_OS_SYMBIAN) # define SRCDIR "." #endif @@ -244,6 +249,8 @@ private slots: void setPenColorOnImage(); void setPenColorOnPixmap(); + void QTBUG5939_attachPainterPrivate(); + private: void fillData(); void setPenColor(QPainter& p); @@ -4404,6 +4411,55 @@ void tst_QPainter::setPenColorOnPixmap() setPenColor(p); } +class TestProxy : public QGraphicsProxyWidget +{ +public: + TestProxy() : QGraphicsProxyWidget() {} + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + QGraphicsProxyWidget::paint(painter, option, widget); + deviceTransform = painter->deviceTransform(); + } + QTransform deviceTransform; +}; + +class TestWidget : public QWidget +{ +Q_OBJECT +public: + TestWidget() : QWidget(), painted(false) {} + void paintEvent(QPaintEvent *) + { + QPainter p(this); + deviceTransform = p.deviceTransform(); + worldTransform = p.worldTransform(); + painted = true; + } + QTransform deviceTransform; + QTransform worldTransform; + bool painted; +}; + +void tst_QPainter::QTBUG5939_attachPainterPrivate() +{ + QWidget *w = new QWidget(); + QGraphicsScene *scene = new QGraphicsScene(); + QGraphicsView *view = new QGraphicsView(scene, w); + view->move(50 ,50); + TestProxy *proxy = new TestProxy(); + TestWidget *widget = new TestWidget(); + proxy->setWidget(widget); + scene->addItem(proxy); + proxy->rotate(45); + w->resize(scene->sceneRect().size().toSize()); + + w->show(); + QTRY_VERIFY(widget->painted); + + QVERIFY(widget->worldTransform.isIdentity()); + QCOMPARE(widget->deviceTransform, proxy->deviceTransform); +} + QTEST_MAIN(tst_QPainter) #include "tst_qpainter.moc" diff --git a/tests/auto/qscriptable/tst_qscriptable.cpp b/tests/auto/qscriptable/tst_qscriptable.cpp index 90f1db8..c0945d8 100644 --- a/tests/auto/qscriptable/tst_qscriptable.cpp +++ b/tests/auto/qscriptable/tst_qscriptable.cpp @@ -332,7 +332,7 @@ void tst_QScriptable::thisObject() { QVERIFY(!m_scriptable.oofThisObject().isValid()); m_engine.evaluate("o.oof = 123"); - QEXPECT_FAIL("", "Setter doesn't get called when it's in the prototype", Continue); + QEXPECT_FAIL("", "QTBUG-5749: Setter doesn't get called when it's in the prototype", Continue); QVERIFY(m_scriptable.oofThisObject().strictlyEquals(m_engine.evaluate("o"))); } { diff --git a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp index a0af214..4ecd887 100644 --- a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp +++ b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp @@ -1114,7 +1114,7 @@ void tst_QScriptContext::calledAsConstructor() QVERIFY(!fun3.property("calledAsConstructor").toBool()); eng.evaluate("new test();"); if (qt_script_isJITEnabled()) - QEXPECT_FAIL("", "calledAsConstructor is not correctly set for JS functions when JIT is enabled", Continue); + QEXPECT_FAIL("", "QTBUG-6132: calledAsConstructor is not correctly set for JS functions when JIT is enabled", Continue); QVERIFY(fun3.property("calledAsConstructor").toBool()); } diff --git a/tests/auto/qscriptcontextinfo/tst_qscriptcontextinfo.cpp b/tests/auto/qscriptcontextinfo/tst_qscriptcontextinfo.cpp index fe69c07..09ef820 100644 --- a/tests/auto/qscriptcontextinfo/tst_qscriptcontextinfo.cpp +++ b/tests/auto/qscriptcontextinfo/tst_qscriptcontextinfo.cpp @@ -249,13 +249,13 @@ void tst_QScriptContextInfo::qtFunction() QCOMPARE(info.functionEndLineNumber(), -1); QCOMPARE(info.functionStartLineNumber(), -1); if (x == 0) - QEXPECT_FAIL("", "QScriptContextInfo doesn't pick the correct meta-index for overloaded slots", Continue); + QEXPECT_FAIL("", "QTBUG-6133: QScriptContextInfo doesn't pick the correct meta-index for overloaded slots", Continue); QCOMPARE(info.functionParameterNames().size(), pnames.size()); if (x == 0) - QEXPECT_FAIL("", "QScriptContextInfo doesn't pick the correct meta-index for overloaded slots", Continue); + QEXPECT_FAIL("", "QTBUG-6133: QScriptContextInfo doesn't pick the correct meta-index for overloaded slots", Continue); QCOMPARE(info.functionParameterNames(), pnames); if (x == 0) - QEXPECT_FAIL("", "QScriptContextInfo doesn't pick the correct meta-index for overloaded slots", Continue); + QEXPECT_FAIL("", "QTBUG-6133: QScriptContextInfo doesn't pick the correct meta-index for overloaded slots", Continue); QCOMPARE(info.functionMetaIndex(), metaObject()->indexOfMethod(sig)); } diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp index 8eaad78..2d629b7 100644 --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp @@ -154,6 +154,7 @@ private slots: void functionScopes(); void nativeFunctionScopes(); void evaluateProgram(); + void collectGarbageAfterConnect(); void qRegExpInport_data(); void qRegExpInport(); @@ -1148,7 +1149,7 @@ void tst_QScriptEngine::globalObjectProperties() QScriptValue::PropertyFlags flags = QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration; global.setProperty(name, val, flags); QVERIFY(global.property(name).equals(val)); - QEXPECT_FAIL("", "custom Global Object properties don't retain attributes", Continue); + QEXPECT_FAIL("", "QTBUG-6134: custom Global Object properties don't retain attributes", Continue); QCOMPARE(global.propertyFlags(name), flags); global.setProperty(name, QScriptValue()); QVERIFY(!global.property(name).isValid()); @@ -2033,7 +2034,7 @@ void tst_QScriptEngine::valueConversion() QScriptValue val = qScriptValueFromValue(&eng, in); QVERIFY(val.isRegExp()); QRegExp out = val.toRegExp(); - QEXPECT_FAIL("", "JSC-based back-end doesn't preserve QRegExp::patternSyntax (always uses RegExp2)", Continue); + QEXPECT_FAIL("", "QTBUG-6136: JSC-based back-end doesn't preserve QRegExp::patternSyntax (always uses RegExp2)", Continue); QCOMPARE(out.patternSyntax(), in.patternSyntax()); QCOMPARE(out.pattern(), in.pattern()); QCOMPARE(out.caseSensitivity(), in.caseSensitivity()); @@ -2050,7 +2051,7 @@ void tst_QScriptEngine::valueConversion() in.setMinimal(true); QScriptValue val = qScriptValueFromValue(&eng, in); QVERIFY(val.isRegExp()); - QEXPECT_FAIL("", "JSC-based back-end doesn't preserve QRegExp::minimal (always false)", Continue); + QEXPECT_FAIL("", "QTBUG-6136: JSC-based back-end doesn't preserve QRegExp::minimal (always false)", Continue); QCOMPARE(val.toRegExp().isMinimal(), in.isMinimal()); } } @@ -2505,7 +2506,7 @@ void tst_QScriptEngine::stacktrace() QVERIFY(eng.hasUncaughtException()); QVERIFY(result.isError()); - QEXPECT_FAIL("", "", Abort); + QEXPECT_FAIL("", "QTBUG-6139: uncaughtExceptionBacktrace() doesn't give the full backtrace", Abort); QCOMPARE(eng.uncaughtExceptionBacktrace(), backtrace); QVERIFY(eng.hasUncaughtException()); QVERIFY(result.strictlyEquals(eng.uncaughtException())); @@ -3045,7 +3046,7 @@ void tst_QScriptEngine::errorConstructors() eng.clearExceptions(); QVERIFY(ret.toString().startsWith(name)); if (x != 0) - QEXPECT_FAIL("", "JSC doesn't assign lineNumber when errors are not thrown", Continue); + QEXPECT_FAIL("", "QTBUG-6138: JSC doesn't assign lineNumber when errors are not thrown", Continue); QCOMPARE(ret.property("lineNumber").toInt32(), i+2); } } @@ -3063,14 +3064,19 @@ void tst_QScriptEngine::argumentsProperty() { { QScriptEngine eng; - QEXPECT_FAIL("", "", Continue); - QVERIFY(eng.evaluate("arguments").isUndefined()); + { + QScriptValue ret = eng.evaluate("arguments"); + QVERIFY(ret.isError()); + QCOMPARE(ret.toString(), QString::fromLatin1("ReferenceError: Can't find variable: arguments")); + } eng.evaluate("arguments = 10"); - QScriptValue ret = eng.evaluate("arguments"); - QVERIFY(ret.isNumber()); - QCOMPARE(ret.toInt32(), 10); - QEXPECT_FAIL("", "", Continue); - QVERIFY(!eng.evaluate("delete arguments").toBoolean()); + { + QScriptValue ret = eng.evaluate("arguments"); + QVERIFY(ret.isNumber()); + QCOMPARE(ret.toInt32(), 10); + } + QVERIFY(eng.evaluate("delete arguments").toBoolean()); + QVERIFY(!eng.globalObject().property("arguments").isValid()); } { QScriptEngine eng; @@ -3081,11 +3087,11 @@ void tst_QScriptEngine::argumentsProperty() } { QScriptEngine eng; + QVERIFY(!eng.globalObject().property("arguments").isValid()); QScriptValue ret = eng.evaluate("(function() { arguments = 456; return arguments; })()"); QVERIFY(ret.isNumber()); QCOMPARE(ret.toInt32(), 456); - QEXPECT_FAIL("", "", Continue); - QVERIFY(eng.evaluate("arguments").isUndefined()); + QVERIFY(!eng.globalObject().property("arguments").isValid()); } { @@ -4438,6 +4444,23 @@ void tst_QScriptEngine::evaluateProgram() } } +void tst_QScriptEngine::collectGarbageAfterConnect() +{ + // QTBUG-6366 + QScriptEngine engine; + QPointer<QWidget> widget = new QWidget; + engine.globalObject().setProperty( + "widget", engine.newQObject(widget, QScriptEngine::ScriptOwnership)); + QVERIFY(engine.evaluate("widget.customContextMenuRequested.connect(\n" + " function() { print('hello'); }\n" + ");") + .isUndefined()); + QVERIFY(widget != 0); + engine.evaluate("widget = null;"); + collectGarbage_helper(engine); + QVERIFY(widget == 0); +} + static QRegExp minimal(QRegExp r) { r.setMinimal(true); return r; } void tst_QScriptEngine::qRegExpInport_data() diff --git a/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp b/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp index 032c34b..1a02785 100644 --- a/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp +++ b/tests/auto/qscriptengineagent/tst_qscriptengineagent.cpp @@ -85,6 +85,7 @@ private slots: void functionEntryAndExit_native(); void functionEntryAndExit_native2(); void functionEntryAndExit_nativeThrowing(); + void functionEntryAndExit_builtin_data(); void functionEntryAndExit_builtin(); void functionEntryAndExit_objects(); void functionEntryAndExit_slots(); @@ -114,6 +115,7 @@ private slots: void evaluateProgram(); void evaluateProgram_SyntaxError(); void evaluateNullProgram(); + void QTBUG6108(); private: double m_testProperty; @@ -475,7 +477,7 @@ void tst_QScriptEngineAgent::scriptLoadAndUnload_eval() spy->clear(); eng.evaluate("eval('function foo() { print(123); }')"); - QEXPECT_FAIL("","Eval is threaded in different way that in old backend", Abort); + QEXPECT_FAIL("","QTBUG-6140 Eval is threaded in different way that in old backend", Abort); QCOMPARE(spy->count(), 3); QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); @@ -810,18 +812,42 @@ void tst_QScriptEngineAgent::functionEntryAndExit_nativeThrowing() delete spy; } +void tst_QScriptEngineAgent::functionEntryAndExit_builtin_data() +{ + QTest::addColumn<QString>("script"); + QTest::addColumn<QString>("result"); + + QTest::newRow("string native") << "'ciao'.toString()" << "ciao"; + QTest::newRow("string object") << "String('ciao').toString()" << "ciao"; + QTest::newRow("number native") << "(123).toString()" << "123"; + QTest::newRow("number object") << "Number(123).toString()" << "123"; + QTest::newRow("array native") << "['s','a'].toString()" << "s, a"; + QTest::newRow("array object") << "Array('s', 'a').toString()" << "s,a"; + QTest::newRow("boolean native") << "false.toString()" << "false"; + QTest::newRow("boolean object") << "Boolean(true).toString()" << "true"; + QTest::newRow("regexp native") << "/a/.toString()" << "/a/"; + QTest::newRow("regexp object") << "RegExp('a').toString()" << "/a/"; +} + /** check behaiviour of built-in function */ void tst_QScriptEngineAgent::functionEntryAndExit_builtin() { + QFETCH(QString, script); + QFETCH(QString, result); QScriptEngine eng; ScriptEngineSpy *spy = new ScriptEngineSpy(&eng, ~(ScriptEngineSpy::IgnoreFunctionEntry | ScriptEngineSpy::IgnoreFunctionExit)); { spy->clear(); - eng.evaluate("'ciao'.toString()"); - - if (qt_script_isJITEnabled()) - QEXPECT_FAIL("", "Some events are missing when JIT is enabled", Abort); + eng.evaluate(script); + + if (qt_script_isJITEnabled()) { + QEXPECT_FAIL("string native", "QTBUG-6187 Some events are missing when JIT is enabled", Abort); + QEXPECT_FAIL("number native", "QTBUG-6187 Some events are missing when JIT is enabled", Abort); + QEXPECT_FAIL("array native", "QTBUG-6187 Some events are missing when JIT is enabled", Abort); + QEXPECT_FAIL("boolean native", "QTBUG-6187 Some events are missing when JIT is enabled", Abort); + QEXPECT_FAIL("regexp native", "QTBUG-6187 Some events are missing when JIT is enabled", Abort); + } QCOMPARE(spy->count(), 4); // evaluate() entry @@ -834,14 +860,13 @@ void tst_QScriptEngineAgent::functionEntryAndExit_builtin() // built-in native function exit QCOMPARE(spy->at(2).type, ScriptEngineEvent::FunctionExit); QCOMPARE(spy->at(2).scriptId, qint64(-1)); - QVERIFY(spy->at(2).value.isString()); - QCOMPARE(spy->at(2).value.toString(), QString("ciao")); + QCOMPARE(spy->at(2).value.toString(), QString(result)); // evaluate() exit QCOMPARE(spy->at(3).type, ScriptEngineEvent::FunctionExit); QCOMPARE(spy->at(3).scriptId, spy->at(0).scriptId); QVERIFY(spy->at(3).value.isString()); - QCOMPARE(spy->at(3).value.toString(), QString("ciao")); + QCOMPARE(spy->at(3).value.toString(), QString(result)); } delete spy; } @@ -1160,16 +1185,16 @@ void tst_QScriptEngineAgent::positionChange_1() { spy->clear(); eng.evaluate(";"); - QEXPECT_FAIL("","JSC do not evaluate ';' to statemant",Continue); + QEXPECT_FAIL("","QTBUG-6142 JSC do not evaluate ';' to statemant",Continue); QCOMPARE(spy->count(), 1); if (spy->count()) { - QEXPECT_FAIL("","JSC do not evaluate ';' to statemant",Continue); + QEXPECT_FAIL("","QTBUG-6142 JSC do not evaluate ';' to statemant",Continue); QCOMPARE(spy->at(0).type, ScriptEngineEvent::PositionChange); - QEXPECT_FAIL("","JSC do not evaluate ';' to statemant",Continue); + QEXPECT_FAIL("","QTBUG-6142 JSC do not evaluate ';' to statemant",Continue); QVERIFY(spy->at(0).scriptId != -1); - QEXPECT_FAIL("","JSC do not evaluate ';' to statemant",Continue); + QEXPECT_FAIL("","QTBUG-6142 JSC do not evaluate ';' to statemant",Continue); QCOMPARE(spy->at(0).lineNumber, 1); - QEXPECT_FAIL("","JSC do not evaluate ';' to statemant",Continue); + QEXPECT_FAIL("","QTBUG-6142 JSC do not evaluate ';' to statemant",Continue); QCOMPARE(spy->at(0).columnNumber, 1); } } @@ -1551,7 +1576,7 @@ void tst_QScriptEngineAgent::positionChange_2() } { - QEXPECT_FAIL("","I believe the test is wrong. Expressions shouldn't call positionChange " + QEXPECT_FAIL("","QTBUG-6142 I believe the test is wrong. Expressions shouldn't call positionChange " "because statement '1+2' will call it at least twice, why debugger have to " "stop here so many times?", Abort); spy->clear(); @@ -2088,8 +2113,6 @@ void tst_QScriptEngineAgent::syntaxError() i = 2; QCOMPARE(spy->at(i).type, ScriptEngineEvent::ContextPush); - QEXPECT_FAIL("","The test is broken, contextPush event do not provide scriptId", Continue); - QVERIFY(spy->at(i).scriptId == -1); i = 3; QCOMPARE(spy->at(i).type, ScriptEngineEvent::FunctionEntry); QVERIFY(spy->at(i).scriptId == -1); @@ -2098,14 +2121,12 @@ void tst_QScriptEngineAgent::syntaxError() QVERIFY(spy->at(i).scriptId == -1); i = 5; QCOMPARE(spy->at(i).type, ScriptEngineEvent::ContextPop); - QEXPECT_FAIL("","The test is broken, contextPop event do not provide scriptId", Continue); - QVERIFY(spy->at(i).scriptId == -1); i = 6; QCOMPARE(spy->at(i).type, ScriptEngineEvent::ExceptionThrow); QCOMPARE(spy->at(i).scriptId, spy->at(0).scriptId); QVERIFY(!spy->at(i).hasExceptionHandler); QVERIFY(spy->at(i).value.isError()); - QEXPECT_FAIL("","There are other messages in JSC",Continue); + QEXPECT_FAIL("","QTBUG-6137 There are other messages in JSC",Continue); QCOMPARE(spy->at(i).value.toString(), QString("SyntaxError: Expected `}'")); QCOMPARE(spy->at(i).scriptId, spy->at(0).scriptId); i = 7; @@ -2138,7 +2159,7 @@ void tst_QScriptEngineAgent::extension_invoctaion() QCOMPARE(spy->at(1).lineNumber, lineNumber); QCOMPARE(spy->at(1).columnNumber, 1); - QEXPECT_FAIL("","In JSC Eval('debugger') returns undefined",Abort); + QEXPECT_FAIL("","QTBUG-6135 In JSC Eval('debugger') returns undefined",Abort); QVERIFY(ret.isString()); QCOMPARE(ret.toString(), QString::fromLatin1("extension(DebuggerInvocationRequest)")); } @@ -2306,5 +2327,32 @@ void tst_QScriptEngineAgent::evaluateNullProgram() QCOMPARE(spy->count(), 0); } +void tst_QScriptEngineAgent::QTBUG6108() +{ + QScriptEngine eng; + ScriptEngineSpy *spy = new ScriptEngineSpy(&eng); + eng.evaluate("eval('a = 1')"); + QCOMPARE(spy->count(), 5); + + QCOMPARE(spy->at(0).type, ScriptEngineEvent::ScriptLoad); + QVERIFY(spy->at(0).scriptId != -1); + + QCOMPARE(spy->at(1).type, ScriptEngineEvent::FunctionEntry); + QVERIFY(spy->at(1).scriptId != -1); + QCOMPARE(spy->at(1).scriptId, spy->at(0).scriptId); + + QCOMPARE(spy->at(2).type, ScriptEngineEvent::PositionChange); + QVERIFY(spy->at(2).scriptId != -1); + QCOMPARE(spy->at(2).scriptId, spy->at(0).scriptId); + QCOMPARE(spy->at(2).lineNumber, 1); + + QCOMPARE(spy->at(3).type, ScriptEngineEvent::FunctionExit); + QVERIFY(spy->at(3).scriptId != -1); + QCOMPARE(spy->at(3).scriptId, spy->at(0).scriptId); + + QCOMPARE(spy->at(4).type, ScriptEngineEvent::ScriptUnload); + QCOMPARE(spy->at(4).scriptId, spy->at(0).scriptId); +} + QTEST_MAIN(tst_QScriptEngineAgent) #include "tst_qscriptengineagent.moc" diff --git a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp index 44adf7e..a47cabb 100644 --- a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp +++ b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp @@ -1630,6 +1630,29 @@ void tst_QScriptExtQObject::connectAndDisconnect() m_myObject->emitMySignalWithVariantArg(123); QCOMPARE(m_engine->evaluate("gotSignal").toBoolean(), true); QCOMPARE(m_engine->evaluate("signalArgs.length").toNumber(), 1.0); + QCOMPARE(m_engine->evaluate("signalArgs[0]").toNumber(), 123.0); + QVERIFY(m_engine->evaluate("myObject.mySignalWithVariantArg.disconnect(myHandler)").isUndefined()); + + // signal with argument type that's unknown to the meta-type system + m_myObject->clearConnectedSignal(); + QVERIFY(m_engine->evaluate("myObject.mySignalWithScriptEngineArg.connect(myHandler)").isUndefined()); + QCOMPARE(m_myObject->connectedSignal().constData(), SIGNAL(mySignalWithScriptEngineArg(QScriptEngine*))); + m_engine->evaluate("gotSignal = false"); + QTest::ignoreMessage(QtWarningMsg, "QScriptEngine: Unable to handle unregistered datatype 'QScriptEngine*' when invoking handler of signal MyQObject::mySignalWithScriptEngineArg(QScriptEngine*)"); + m_myObject->emitMySignalWithScriptEngineArg(m_engine); + QCOMPARE(m_engine->evaluate("gotSignal").toBoolean(), true); + QCOMPARE(m_engine->evaluate("signalArgs.length").toNumber(), 1.0); + QVERIFY(m_engine->evaluate("signalArgs[0]").isUndefined()); + QVERIFY(m_engine->evaluate("myObject.mySignalWithScriptEngineArg.disconnect(myHandler)").isUndefined()); + + // signal with QVariant arg: argument conversion should work + m_myObject->clearConnectedSignal(); + QVERIFY(m_engine->evaluate("myObject.mySignalWithVariantArg.connect(myHandler)").isUndefined()); + QCOMPARE(m_myObject->connectedSignal().constData(), SIGNAL(mySignalWithVariantArg(QVariant))); + m_engine->evaluate("gotSignal = false"); + m_myObject->emitMySignalWithVariantArg(123); + QCOMPARE(m_engine->evaluate("gotSignal").toBoolean(), true); + QCOMPARE(m_engine->evaluate("signalArgs.length").toNumber(), 1.0); QVERIFY(m_engine->evaluate("signalArgs[0]").isNumber()); QCOMPARE(m_engine->evaluate("signalArgs[0]").toNumber(), 123.0); QVERIFY(m_engine->evaluate("myObject.mySignalWithVariantArg.disconnect(myHandler)").isUndefined()); diff --git a/tests/auto/qsharedmemory/qsystemlock/tst_qsystemlock.cpp b/tests/auto/qsharedmemory/qsystemlock/tst_qsystemlock.cpp index 35f05d1..518cdbf 100644 --- a/tests/auto/qsharedmemory/qsystemlock/tst_qsystemlock.cpp +++ b/tests/auto/qsharedmemory/qsystemlock/tst_qsystemlock.cpp @@ -202,9 +202,9 @@ void tst_QSystemLock::processes() QStringList scripts; for (int i = 0; i < readOnly; ++i) - scripts.append(QFileInfo(SRCDIR "lackey/scripts/ systemlock_read.js").absoluteFilePath() ); + scripts.append(QFileInfo(SRCDIR "/../lackey/scripts/systemlock_read.js").absoluteFilePath() ); for (int i = 0; i < readWrite; ++i) - scripts.append(QFileInfo(SRCDIR "lackey/scripts/systemlock_readwrite.js").absoluteFilePath()); + scripts.append(QFileInfo(SRCDIR "/../lackey/scripts/systemlock_readwrite.js").absoluteFilePath()); QList<QProcess*> consumers; unsigned int failedProcesses = 0; @@ -213,8 +213,8 @@ void tst_QSystemLock::processes() QStringList arguments = QStringList() << scripts.at(i); QProcess *p = new QProcess; p->setProcessChannelMode(QProcess::ForwardedChannels); - - p->start(QFileInfo(SRCDIR "lackey/lackey").absoluteFilePath(), arguments); + + p->start("../lackey/lackey", arguments); // test, if the process could be started. if (p->waitForStarted(2000)) diff --git a/tests/auto/qsharedmemory/tst_qsharedmemory.cpp b/tests/auto/qsharedmemory/tst_qsharedmemory.cpp index 4ab3b0b..f72b6f7 100644 --- a/tests/auto/qsharedmemory/tst_qsharedmemory.cpp +++ b/tests/auto/qsharedmemory/tst_qsharedmemory.cpp @@ -708,10 +708,7 @@ void tst_QSharedMemory::simpleThreadedProducerConsumer() void tst_QSharedMemory::simpleProcessProducerConsumer_data() { QTest::addColumn<int>("processes"); - int tries = 10; -#ifdef Q_OS_WIN - tries = 5; -#endif + int tries = 5; for (int i = 0; i < tries; ++i) { QTest::newRow("1 process") << 1; QTest::newRow("5 processes") << 5; @@ -737,7 +734,7 @@ void tst_QSharedMemory::simpleProcessProducerConsumer() #endif QProcess producer; producer.setProcessChannelMode(QProcess::ForwardedChannels); - producer.start( QFileInfo("./lackey/lackey.exe").absoluteFilePath(), arguments); + producer.start( "./lackey/lackey", arguments); producer.waitForStarted(); QVERIFY(producer.error() != QProcess::FailedToStart); diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index ed9206c..0cb08f9 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -73,6 +73,7 @@ private slots: void forwardDeclaration2(); void memoryManagement(); void downCast(); + void functionCallDownCast(); void upCast(); void qobjectWeakManagement(); void noSharedPointerFromWeakQObject(); @@ -503,6 +504,15 @@ void tst_QSharedPointer::downCast() QCOMPARE(DerivedData::derivedDestructorCounter, destructorCount + 1); } +void functionDataByValue(QSharedPointer<Data> p) { Q_UNUSED(p); }; +void functionDataByRef(const QSharedPointer<Data> &p) { Q_UNUSED(p); }; +void tst_QSharedPointer::functionCallDownCast() +{ + QSharedPointer<DerivedData> p(new DerivedData()); + functionDataByValue(p); + functionDataByRef(p); +} + void tst_QSharedPointer::upCast() { QSharedPointer<Data> baseptr = QSharedPointer<Data>(new DerivedData); diff --git a/tests/auto/qsoftkeymanager/tst_qsoftkeymanager.cpp b/tests/auto/qsoftkeymanager/tst_qsoftkeymanager.cpp index 87e0533..f923739 100644 --- a/tests/auto/qsoftkeymanager/tst_qsoftkeymanager.cpp +++ b/tests/auto/qsoftkeymanager/tst_qsoftkeymanager.cpp @@ -73,6 +73,7 @@ private slots: void updateSoftKeysCompressed(); void handleCommand(); void checkSoftkeyEnableStates(); + void noMergingOverWindowBoundary(); private: // utils inline void simulateSymbianCommand(int command) @@ -235,5 +236,66 @@ void tst_QSoftKeyManager::checkSoftkeyEnableStates() QCOMPARE(spy1.count(), 5); } +/* + This tests that the softkeys are not merged over window boundaries. I.e. dialogs + don't get softkeys of base widget by default - QTBUG-6163. +*/ +void tst_QSoftKeyManager::noMergingOverWindowBoundary() +{ + // Create base window against which the dialog softkeys will ve verified + QWidget base; + + QAction* baseLeft = new QAction(tr("BaseLeft"), &base); + baseLeft->setSoftKeyRole(QAction::PositiveSoftKey); + base.addAction(baseLeft); + + QAction* baseRight = new QAction(tr("BaseRight"), &base); + baseRight->setSoftKeyRole(QAction::NegativeSoftKey); + base.addAction(baseRight); + + base.showMaximized(); + QApplication::processEvents(); + + QSignalSpy baseLeftSpy(baseLeft, SIGNAL(triggered())); + QSignalSpy baseRightSpy(baseRight, SIGNAL(triggered())); + + //Verify that both base softkeys emit triggered signals + simulateSymbianCommand(s60CommandStart); + simulateSymbianCommand(s60CommandStart + 1); + + QCOMPARE(baseLeftSpy.count(), 1); + QCOMPARE(baseRightSpy.count(), 1); + baseLeftSpy.clear(); + baseRightSpy.clear(); + + // Verify that no softkey merging when using dialog without parent + QDialog dlg; + dlg.show(); + + QApplication::processEvents(); + + simulateSymbianCommand(s60CommandStart); + simulateSymbianCommand(s60CommandStart + 1); + + QCOMPARE(baseLeftSpy.count(), 0); + QCOMPARE(baseRightSpy.count(), 0); + + // Ensure base view has focus again + dlg.hide(); + base.showMaximized(); + + // Verify that no softkey merging when using dialog with parent + QDialog dlg2(&base); + dlg2.show(); + + QApplication::processEvents(); + + simulateSymbianCommand(s60CommandStart); + simulateSymbianCommand(s60CommandStart + 1); + + QCOMPARE(baseLeftSpy.count(), 0); + QCOMPARE(baseRightSpy.count(), 0); +} + QTEST_MAIN(tst_QSoftKeyManager) #include "tst_qsoftkeymanager.moc" diff --git a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index e99e9d6..b7839f7 100644 --- a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -135,6 +135,7 @@ private slots: void task251296_hiddenChildren(); void task252507_mapFromToSource(); void task255652_removeRowsRecursive(); + void taskQTBUG_6205_doubleProxySelectionSetSourceModel(); protected: void buildHierarchy(const QStringList &data, QAbstractItemModel *model); @@ -2815,5 +2816,41 @@ void tst_QSortFilterProxyModel::task255652_removeRowsRecursive() delete pItem11; } +void tst_QSortFilterProxyModel::taskQTBUG_6205_doubleProxySelectionSetSourceModel() +{ + QStandardItemModel *model1 = new QStandardItemModel; + QStandardItem *parentItem = model1->invisibleRootItem(); + for (int i = 0; i < 4; ++i) { + QStandardItem *item = new QStandardItem(QString("model1 item %0").arg(i)); + parentItem->appendRow(item); + parentItem = item; + } + + QStandardItemModel *model2 = new QStandardItemModel; + QStandardItem *parentItem2 = model2->invisibleRootItem(); + for (int i = 0; i < 4; ++i) { + QStandardItem *item = new QStandardItem(QString("model2 item %0").arg(i)); + parentItem2->appendRow(item); + parentItem2 = item; + } + + QSortFilterProxyModel *toggleProxy = new QSortFilterProxyModel; + toggleProxy->setSourceModel(model1); + + QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel; + proxyModel->setSourceModel(toggleProxy); + + QModelIndex mi = proxyModel->index(0, 0, proxyModel->index(0, 0, proxyModel->index(0, 0))); + QItemSelectionModel ism(proxyModel); + ism.select(mi, QItemSelectionModel::Select); + QModelIndexList mil = ism.selectedIndexes(); + QCOMPARE(mil.count(), 1); + QCOMPARE(mil.first(), mi); + + toggleProxy->setSourceModel(model2); + // No crash, it's good news! + QVERIFY(ism.selection().isEmpty()); +} + QTEST_MAIN(tst_QSortFilterProxyModel) #include "tst_qsortfilterproxymodel.moc" diff --git a/tests/auto/qspinbox/tst_qspinbox.cpp b/tests/auto/qspinbox/tst_qspinbox.cpp index 2389060..e5e63a0 100644 --- a/tests/auto/qspinbox/tst_qspinbox.cpp +++ b/tests/auto/qspinbox/tst_qspinbox.cpp @@ -146,6 +146,8 @@ private slots: void sizeHint(); + void taskQTBUG_5008_textFromValueAndValidate(); + public slots: void valueChangedHelper(const QString &); void valueChangedHelper(int); @@ -756,7 +758,7 @@ void tst_QSpinBox::editingFinished() box->activateWindow(); box->setFocus(); - QTRY_COMPARE(qApp->focusWidget(), box); + QTRY_COMPARE(qApp->focusWidget(), (QWidget *)box); QSignalSpy editingFinishedSpy1(box, SIGNAL(editingFinished())); QSignalSpy editingFinishedSpy2(box2, SIGNAL(editingFinished())); @@ -1004,5 +1006,45 @@ void tst_QSpinBox::sizeHint() delete widget; } +void tst_QSpinBox::taskQTBUG_5008_textFromValueAndValidate() +{ + class DecoratedSpinBox : public QSpinBox + { + public: + DecoratedSpinBox() + { + setLocale(QLocale::French); + setMaximum(100000000); + setValue(1000000); + } + + QLineEdit *lineEdit() const + { + return QSpinBox::lineEdit(); + } + + //we use the French delimiters here + QString textFromValue (int value) const + { + return locale().toString(value); + } + + } spinbox; + spinbox.show(); + spinbox.activateWindow(); + spinbox.setFocus(); + QApplication::setActiveWindow(&spinbox); + QTest::qWaitForWindowShown(&spinbox); + QTRY_VERIFY(spinbox.hasFocus()); + QTRY_COMPARE(static_cast<QWidget *>(&spinbox), QApplication::activeWindow()); + QCOMPARE(spinbox.text(), spinbox.locale().toString(spinbox.value())); + spinbox.lineEdit()->setCursorPosition(2); //just after the first thousand separator + QTest::keyClick(0, Qt::Key_0); // let's insert a 0 + QCOMPARE(spinbox.value(), 10000000); //it's been multiplied by 10 + spinbox.clearFocus(); //make sure the value is correctly formatted + QCOMPARE(spinbox.text(), spinbox.locale().toString(spinbox.value())); +} + + QTEST_MAIN(tst_QSpinBox) #include "tst_qspinbox.moc" diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index fe7c3ea..f840ca6 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -86,6 +86,8 @@ private slots: void open(); void tables_data() { generic_data(); } void tables(); + void oci_tables_data() { generic_data("QOCI"); } + void oci_tables(); void transaction_data() { generic_data(); } void transaction(); void eventNotification_data() { generic_data(); } @@ -380,6 +382,7 @@ void tst_QSqlDatabase::dropTestTables(QSqlDatabase db) if (db.driverName().startsWith("QOCI")) { q.exec("drop user "+qTableName("CREATOR")+" cascade"); q.exec("drop user "+qTableName("APPUSER")+" cascade"); + q.exec("DROP TABLE system."+qTableName("mypassword")); } } @@ -2481,5 +2484,18 @@ void tst_QSqlDatabase::mysql_savepointtest() QVERIFY_SQL(q, exec("savepoint foo")); } +void tst_QSqlDatabase::oci_tables() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + QSqlQuery q(db); + QString systemTableName("system."+qTableName("mypassword")); + QVERIFY_SQL(q, exec("CREATE TABLE "+systemTableName+"(name VARCHAR(20))")); + QVERIFY(!db.tables().contains(systemTableName.toUpper())); + qDebug() << db.tables(QSql::SystemTables); + QVERIFY(db.tables(QSql::SystemTables).contains(systemTableName.toUpper())); +} + QTEST_MAIN(tst_QSqlDatabase) #include "tst_qsqldatabase.moc" diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index 4264a70..a8908fd 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -199,6 +199,8 @@ private slots: void QTBUG_5251_data() { generic_data("QPSQL"); } void QTBUG_5251(); + void QTBUG_6421_data() { generic_data("QOCI"); } + void QTBUG_6421(); private: // returns all database connections @@ -302,7 +304,8 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) << qTableName( "more_results" ) << qTableName( "blobstest" ) << qTableName( "oraRowId" ) - << qTableName( "qtest_batch" ); + << qTableName( "qtest_batch" ) + << qTableName(QLatin1String("bug6421")).toUpper(); if ( db.driverName().startsWith("QPSQL") ) tablenames << qTableName("task_233829"); @@ -2935,5 +2938,28 @@ void tst_QSqlQuery::QTBUG_5251() } +void tst_QSqlQuery::QTBUG_6421() +{ + QFETCH( QString, dbName ); + QSqlDatabase db = QSqlDatabase::database( dbName ); + CHECK_DATABASE( db ); + + QSqlQuery q(db); + QString tableName=qTableName(QLatin1String("bug6421")).toUpper(); + + QVERIFY_SQL(q, exec("create table "+tableName+"(COL1 char(10), COL2 char(10), COL3 char(10))")); + QVERIFY_SQL(q, exec("create index INDEX1 on "+tableName+" (COL1 desc)")); + QVERIFY_SQL(q, exec("create index INDEX2 on "+tableName+" (COL2 desc)")); + QVERIFY_SQL(q, exec("create index INDEX3 on "+tableName+" (COL3 desc)")); + q.setForwardOnly(true); + QVERIFY_SQL(q, exec("select COLUMN_EXPRESSION from ALL_IND_EXPRESSIONS where TABLE_NAME='"+tableName+"'")); + QVERIFY_SQL(q, next()); + QCOMPARE(q.value(0).toString(), QLatin1String("\"COL1\"")); + QVERIFY_SQL(q, next()); + QCOMPARE(q.value(0).toString(), QLatin1String("\"COL2\"")); + QVERIFY_SQL(q, next()); + QCOMPARE(q.value(0).toString(), QLatin1String("\"COL3\"")); +} + QTEST_MAIN( tst_QSqlQuery ) #include "tst_qsqlquery.moc" diff --git a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp index 8c840cd..4ae5000 100644 --- a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp +++ b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp @@ -1212,10 +1212,11 @@ void tst_QSqlRelationalTableModel::psqlSchemaTest() QSqlQuery q(db); QVERIFY_SQL(q, exec("create schema "+qTableName("QTBUG_5373"))); QVERIFY_SQL(q, exec("create schema "+qTableName("QTBUG_5373_s2"))); - QVERIFY_SQL(q, exec("create table "+qTableName("QTBUG_5373")+"."+qTableName("user")+"(userid int primary key, relatingid int)")); - QVERIFY_SQL(q, exec("create table "+qTableName("QTBUG_5373_s2")+"."+qTableName("user2")+"(userid2 int primary key, username2 char(40))")); - model.setTable(qTableName("QTBUG_5373")+"."+qTableName("user")); - model.setRelation(1, QSqlRelation(qTableName("QTBUG_5373_s2")+"."+qTableName("user2"), "userid2", "username2")); + QVERIFY_SQL(q, exec("create table "+qTableName("QTBUG_5373")+"."+qTableName("document")+"(document_id int primary key, relatingid int, userid int)")); + QVERIFY_SQL(q, exec("create table "+qTableName("QTBUG_5373_s2")+"."+qTableName("user")+"(userid int primary key, username char(40))")); + model.setTable(qTableName("QTBUG_5373")+"."+qTableName("document")); + model.setRelation(1, QSqlRelation(qTableName("QTBUG_5373_s2")+"."+qTableName("user"), "userid", "username")); + model.setRelation(2, QSqlRelation(qTableName("QTBUG_5373_s2")+"."+qTableName("user"), "userid", "username")); QVERIFY_SQL(model, select()); } diff --git a/tests/auto/qstatusbar/tst_qstatusbar.cpp b/tests/auto/qstatusbar/tst_qstatusbar.cpp index 92d9185..03d8ca8 100644 --- a/tests/auto/qstatusbar/tst_qstatusbar.cpp +++ b/tests/auto/qstatusbar/tst_qstatusbar.cpp @@ -266,10 +266,15 @@ void tst_QStatusBar::QTBUG4334_hiddenOnMaximizedWindow() main.setStatusBar(&statusbar); main.showMaximized(); QTest::qWaitForWindowShown(&main); +#ifndef Q_WS_MAC QVERIFY(!statusbar.findChild<QSizeGrip*>()->isVisible()); +#endif main.showNormal(); QTest::qWaitForWindowShown(&main); QVERIFY(statusbar.findChild<QSizeGrip*>()->isVisible()); + main.showFullScreen(); + QTest::qWaitForWindowShown(&main); + QVERIFY(!statusbar.findChild<QSizeGrip*>()->isVisible()); } QTEST_MAIN(tst_QStatusBar) diff --git a/tests/auto/qtcpserver/tst_qtcpserver.cpp b/tests/auto/qtcpserver/tst_qtcpserver.cpp index 2540096..8b86111 100644 --- a/tests/auto/qtcpserver/tst_qtcpserver.cpp +++ b/tests/auto/qtcpserver/tst_qtcpserver.cpp @@ -523,7 +523,7 @@ void tst_QTcpServer::waitForConnectionTest() QTcpSocket findLocalIpSocket; findLocalIpSocket.connectToHost(QtNetworkSettings::serverName(), 143); - QVERIFY(findLocalIpSocket.waitForConnected(2000)); + QVERIFY(findLocalIpSocket.waitForConnected(5000)); QTcpServer server; bool timeout = false; diff --git a/tests/auto/qtextcursor/tst_qtextcursor.cpp b/tests/auto/qtextcursor/tst_qtextcursor.cpp index d910c8d..d0c2afd 100644 --- a/tests/auto/qtextcursor/tst_qtextcursor.cpp +++ b/tests/auto/qtextcursor/tst_qtextcursor.cpp @@ -149,6 +149,8 @@ private slots: void adjustCursorsOnInsert(); + void cursorPositionWithBlockUndoAndRedo(); + private: int blockCount(); @@ -1747,9 +1749,33 @@ void tst_QTextCursor::adjustCursorsOnInsert() QCOMPARE(selection.anchor(), posAfter); doc->undo(); +} +void tst_QTextCursor::cursorPositionWithBlockUndoAndRedo() +{ + cursor.insertText("AAAABBBBCCCCDDDD"); + cursor.beginEditBlock(); + cursor.setPosition(12); + int cursorPositionBefore = cursor.position(); + cursor.insertText("*"); + cursor.setPosition(8); + cursor.insertText("*"); + cursor.setPosition(4); + cursor.insertText("*"); + cursor.setPosition(0); + cursor.insertText("*"); + int cursorPositionAfter = cursor.position(); + cursor.endEditBlock(); + QVERIFY(doc->toPlainText() == "*AAAA*BBBB*CCCC*DDDD"); + QCOMPARE(12, cursorPositionBefore); + QCOMPARE(1, cursorPositionAfter); - + doc->undo(&cursor); + QVERIFY(doc->toPlainText() == "AAAABBBBCCCCDDDD"); + QCOMPARE(cursor.position(), cursorPositionBefore); + doc->redo(&cursor); + QVERIFY(doc->toPlainText() == "*AAAA*BBBB*CCCC*DDDD"); + QCOMPARE(cursor.position(), cursorPositionAfter); } QTEST_MAIN(tst_QTextCursor) diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp index fee030c..bebc4bd 100644 --- a/tests/auto/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/qtextedit/tst_qtextedit.cpp @@ -200,6 +200,7 @@ private slots: void pasteFromQt3RichText(); void noWrapBackgrounds(); void preserveCharFormatAfterUnchangingSetPosition(); + void twoSameInputMethodEvents(); private: void createSelection(); @@ -2183,5 +2184,23 @@ void tst_QTextEdit::preserveCharFormatAfterUnchangingSetPosition() QCOMPARE(edit.textColor(), color); } +// Regression test for QTBUG-4696 +void tst_QTextEdit::twoSameInputMethodEvents() +{ + ed->setText("testLine"); + ed->show(); + QList<QInputMethodEvent::Attribute> attributes; + attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, + ed->textCursor().position(), + 0, + QVariant())); + + QInputMethodEvent event("PreEditText", attributes); + QApplication::sendEvent(ed, &event); + QCOMPARE(ed->document()->firstBlock().layout()->lineCount(), 1); + QApplication::sendEvent(ed, &event); + QCOMPARE(ed->document()->firstBlock().layout()->lineCount(), 1); +} + QTEST_MAIN(tst_QTextEdit) #include "tst_qtextedit.moc" diff --git a/tests/auto/qtreewidget/tst_qtreewidget.cpp b/tests/auto/qtreewidget/tst_qtreewidget.cpp index 621072c..0c6df4f 100644 --- a/tests/auto/qtreewidget/tst_qtreewidget.cpp +++ b/tests/auto/qtreewidget/tst_qtreewidget.cpp @@ -168,6 +168,8 @@ private slots: void task239150_editorWidth(); void setTextUpdate(); void taskQTBUG2844_visualItemRect(); + void setChildIndicatorPolicy(); + public slots: void itemSelectionChanged(); @@ -3290,6 +3292,57 @@ void tst_QTreeWidget::taskQTBUG2844_visualItemRect() QCOMPARE(tree.visualItemRect(&item), rectCol0 | rectCol1); } +void tst_QTreeWidget::setChildIndicatorPolicy() +{ + QTreeWidget treeWidget; + treeWidget.setColumnCount(1); + + class MyItemDelegate : public QStyledItemDelegate + { + public: + MyItemDelegate() : numPaints(0), expectChildren(false) { } + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const + { + numPaints++; + QCOMPARE(!(option.state & QStyle::State_Children), !expectChildren); + QStyledItemDelegate::paint(painter, option, index); + } + mutable int numPaints; + bool expectChildren; + } delegate; + + treeWidget.setItemDelegate(&delegate); + treeWidget.show(); + + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList("Hello")); + treeWidget.insertTopLevelItem(0, item); + QTest::qWait(50); + QTRY_VERIFY(delegate.numPaints > 0); + + delegate.numPaints = 0; + delegate.expectChildren = true; + item->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator); + QApplication::processEvents(); + QTRY_COMPARE(delegate.numPaints, 1); + + delegate.numPaints = 0; + delegate.expectChildren = false; + item->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless); + QApplication::processEvents(); + QTRY_COMPARE(delegate.numPaints, 1); + + delegate.numPaints = 0; + delegate.expectChildren = true; + new QTreeWidgetItem(item); + QApplication::processEvents(); + QTRY_COMPARE(delegate.numPaints, 1); + + delegate.numPaints = 0; + delegate.expectChildren = false; + item->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicator); + QApplication::processEvents(); + QTRY_COMPARE(delegate.numPaints, 1); +} diff --git a/tests/auto/qudpsocket/tst_qudpsocket.cpp b/tests/auto/qudpsocket/tst_qudpsocket.cpp index 9418be0..160d74c 100644 --- a/tests/auto/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/qudpsocket/tst_qudpsocket.cpp @@ -295,8 +295,8 @@ void tst_QUdpSocket::loop() QCOMPARE(paul.writeDatagram(paulMessage.data(), paulMessage.length(), peterAddress, peter.localPort()), qint64(paulMessage.length())); - QVERIFY(peter.waitForReadyRead(5000)); - QVERIFY(paul.waitForReadyRead(5000)); + QVERIFY(peter.waitForReadyRead(9000)); + QVERIFY(paul.waitForReadyRead(9000)); char peterBuffer[16*1024]; char paulBuffer[16*1024]; if (success) { diff --git a/tests/auto/qvector/tst_qvector.cpp b/tests/auto/qvector/tst_qvector.cpp index 21c9270..f538f6a 100644 --- a/tests/auto/qvector/tst_qvector.cpp +++ b/tests/auto/qvector/tst_qvector.cpp @@ -56,6 +56,7 @@ public: private slots: void outOfMemory(); + void QTBUG6416_reserve(); }; int fooCtor; @@ -220,5 +221,18 @@ void tst_QVector::outOfMemory() } } +void tst_QVector::QTBUG6416_reserve() +{ + fooCtor = 0; + fooDtor = 0; + { + QVector<Foo> a; + a.resize(2); + QVector<Foo> b(a); + b.reserve(1); + } + QCOMPARE(fooCtor, fooDtor); +} + QTEST_APPLESS_MAIN(tst_QVector) #include "tst_qvector.moc" diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 1e3f5f8..3e14b56 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -391,6 +391,7 @@ private slots: #endif void focusProxyAndInputMethods(); + void scrollWithoutBackingStore(); private: bool ensureScreenSize(int width, int height); @@ -9548,6 +9549,22 @@ void tst_QWidget::setGraphicsEffect() delete widget; QVERIFY(!blurEffect); delete anotherWidget; + + // Ensure the effect is uninstalled when deleting it + widget = new QWidget; + blurEffect = new QGraphicsBlurEffect; + widget->setGraphicsEffect(blurEffect); + delete blurEffect; + QVERIFY(!widget->graphicsEffect()); + + // Ensure the existing effect is uninstalled and deleted when setting a null effect + blurEffect = new QGraphicsBlurEffect; + widget->setGraphicsEffect(blurEffect); + widget->setGraphicsEffect(0); + QVERIFY(!widget->graphicsEffect()); + QVERIFY(!blurEffect); + + delete widget; } void tst_QWidget::activateWindow() @@ -9703,5 +9720,42 @@ void tst_QWidget::focusProxyAndInputMethods() delete toplevel; } +class scrollWidgetWBS : public QWidget +{ +public: + void deleteBackingStore() + { + if (static_cast<QWidgetPrivate*>(d_ptr.data())->maybeBackingStore()) { + delete static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->backingStore; + static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->backingStore = 0; + } + } + void enableBackingStore() + { + if (!static_cast<QWidgetPrivate*>(d_ptr.data())->maybeBackingStore()) { + static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->backingStore = new QWidgetBackingStore(this); + static_cast<QWidgetPrivate*>(d_ptr.data())->invalidateBuffer(this->rect()); + repaint(); + } + } +}; + +void tst_QWidget::scrollWithoutBackingStore() +{ + scrollWidgetWBS scrollable; + scrollable.resize(100,100); + QLabel child(QString("@"),&scrollable); + child.resize(50,50); + scrollable.show(); + QTest::qWaitForWindowShown(&scrollable); + scrollable.scroll(50,50); + QCOMPARE(child.pos(),QPoint(50,50)); + scrollable.deleteBackingStore(); + scrollable.scroll(-25,-25); + QCOMPARE(child.pos(),QPoint(25,25)); + scrollable.enableBackingStore(); + QCOMPARE(child.pos(),QPoint(25,25)); +} + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc" diff --git a/tests/auto/qwidget_window/tst_qwidget_window.cpp b/tests/auto/qwidget_window/tst_qwidget_window.cpp index 13d1d2d..ec11ab3 100644 --- a/tests/auto/qwidget_window/tst_qwidget_window.cpp +++ b/tests/auto/qwidget_window/tst_qwidget_window.cpp @@ -52,6 +52,9 @@ #include <QX11Info> #endif // Q_WS_X11 +#include "../../shared/util.h" + + class tst_QWidget_window : public QWidget { Q_OBJECT @@ -150,7 +153,7 @@ void tst_QWidget_window::tst_show_resize_hide_show() class TestWidget : public QWidget { public: - int m_first, m_next; + int m_first, m_next; bool paintEventReceived; void reset(){ m_first = m_next = 0; paintEventReceived = false; } @@ -163,7 +166,7 @@ public: case QEvent::Show: if (m_first) m_next = event->type(); - else + else m_first = event->type(); break; case QEvent::Paint: @@ -173,7 +176,7 @@ public: break; } return QWidget::event(event); - } + } }; void tst_QWidget_window::tst_windowFilePathAndwindowTitle_data() @@ -289,7 +292,7 @@ void tst_QWidget_window::tst_showWithoutActivating() #else QWidget w; w.show(); - qt_x11_wait_for_window_manager(&w); + QTest::qWaitForWindowShown(&w); QApplication::processEvents(); QApplication::clipboard(); @@ -302,8 +305,11 @@ void tst_QWidget_window::tst_showWithoutActivating() Window window; int revertto; - XGetInputFocus(QX11Info::display(), &window, &revertto); - QCOMPARE(lineEdit->winId(), window); + QTRY_COMPARE(lineEdit->winId(), + (XGetInputFocus(QX11Info::display(), &window, &revertto), window) ); + // Note the use of the , before window because we want the XGetInputFocus to be re-executed + // in each iteration of the inside loop of the QTRY_COMPARE macro + #endif // Q_WS_X11 } @@ -315,11 +321,9 @@ void tst_QWidget_window::tst_paintEventOnSecondShow() w.reset(); w.show(); -#ifdef Q_WS_X11 - QTest::qWait(500); -#endif + QTest::qWaitForWindowShown(&w); QApplication::processEvents(); - QVERIFY(w.paintEventReceived); + QTRY_VERIFY(w.paintEventReceived); } QTEST_MAIN(tst_QWidget_window) diff --git a/tests/auto/qxmlstream/data/doctypeEmptyMarkupDecl.ref b/tests/auto/qxmlstream/data/doctypeEmptyMarkupDecl.ref new file mode 100644 index 0000000..ea85e32 --- /dev/null +++ b/tests/auto/qxmlstream/data/doctypeEmptyMarkupDecl.ref @@ -0,0 +1,7 @@ +StartDocument( ) +Comment( text=" Empty markup declaration in a doctype. " ) +DTD( text=" +<!DOCTYPE doc []>" dtdName="doc" ) +StartElement( name="doc" qualifiedName="doc" ) +EndElement( name="doc" qualifiedName="doc" ) +EndDocument( ) diff --git a/tests/auto/qxmlstream/data/doctypeEmptyMarkupDecl.xml b/tests/auto/qxmlstream/data/doctypeEmptyMarkupDecl.xml new file mode 100644 index 0000000..1c66c0c --- /dev/null +++ b/tests/auto/qxmlstream/data/doctypeEmptyMarkupDecl.xml @@ -0,0 +1,3 @@ +<!-- Empty markup declaration in a doctype. --> +<!DOCTYPE doc []> +<doc></doc> diff --git a/tests/auto/rcc/data/images.expected b/tests/auto/rcc/data/images.expected index 24d75b6..71be819 100644 --- a/tests/auto/rcc/data/images.expected +++ b/tests/auto/rcc/data/images.expected @@ -97,10 +97,10 @@ static const unsigned char qt_resource_struct[] = { QT_BEGIN_NAMESPACE -extern bool qRegisterResourceData +extern Q_CORE_EXPORT bool qRegisterResourceData (int, const unsigned char *, const unsigned char *, const unsigned char *); -extern bool qUnregisterResourceData +extern Q_CORE_EXPORT bool qUnregisterResourceData (int, const unsigned char *, const unsigned char *, const unsigned char *); QT_END_NAMESPACE diff --git a/tests/auto/selftests/expected_cmptest.txt b/tests/auto/selftests/expected_cmptest.txt index f70eba5..a941f21 100644 --- a/tests/auto/selftests/expected_cmptest.txt +++ b/tests/auto/selftests/expected_cmptest.txt @@ -1,5 +1,5 @@ ********* Start testing of tst_Cmptest ********* -Config: Using QTest library 4.6.0, Qt 4.6.0 +Config: Using QTest library 4.6.1, Qt 4.6.1 PASS : tst_Cmptest::initTestCase() PASS : tst_Cmptest::compare_boolfuncs() PASS : tst_Cmptest::compare_pointerfuncs() diff --git a/tests/auto/selftests/expected_crashes_3.txt b/tests/auto/selftests/expected_crashes_3.txt index 55cd0b4..692fddb 100644 --- a/tests/auto/selftests/expected_crashes_3.txt +++ b/tests/auto/selftests/expected_crashes_3.txt @@ -1,5 +1,5 @@ ********* Start testing of tst_Crashes ********* -Config: Using QTest library 4.6.0, Qt 4.6.0 +Config: Using QTest library 4.6.1, Qt 4.6.1 PASS : tst_Crashes::initTestCase() QFATAL : tst_Crashes::crash() Received signal 11 FAIL! : tst_Crashes::crash() Received a fatal error. diff --git a/tests/auto/selftests/expected_longstring.txt b/tests/auto/selftests/expected_longstring.txt index 4abdb23..5755c97 100644 --- a/tests/auto/selftests/expected_longstring.txt +++ b/tests/auto/selftests/expected_longstring.txt @@ -1,5 +1,5 @@ ********* Start testing of tst_LongString ********* -Config: Using QTest library 4.6.0, Qt 4.6.0 +Config: Using QTest library 4.6.1, Qt 4.6.1 PASS : tst_LongString::initTestCase() FAIL! : tst_LongString::failWithLongString() Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. diff --git a/tests/auto/selftests/expected_maxwarnings.txt b/tests/auto/selftests/expected_maxwarnings.txt index 8dae5f7..032a3e8 100644 --- a/tests/auto/selftests/expected_maxwarnings.txt +++ b/tests/auto/selftests/expected_maxwarnings.txt @@ -1,5 +1,5 @@ ********* Start testing of MaxWarnings ********* -Config: Using QTest library 4.6.0, Qt 4.6.0 +Config: Using QTest library 4.6.1, Qt 4.6.1 PASS : MaxWarnings::initTestCase() QWARN : MaxWarnings::warn() 0 QWARN : MaxWarnings::warn() 1 diff --git a/tests/auto/selftests/expected_skip.txt b/tests/auto/selftests/expected_skip.txt index 88c0426..e687759 100644 --- a/tests/auto/selftests/expected_skip.txt +++ b/tests/auto/selftests/expected_skip.txt @@ -1,5 +1,5 @@ ********* Start testing of tst_Skip ********* -Config: Using QTest library 4.6.0, Qt 4.6.0 +Config: Using QTest library 4.6.1, Qt 4.6.1 PASS : tst_Skip::initTestCase() SKIP : tst_Skip::test() skipping all Loc: [/home/rmcgover/depot/qt-git/mainline/tests/auto/selftests/skip/tst_skip.cpp(68)] diff --git a/tests/auto/selftests/expected_xunit.txt b/tests/auto/selftests/expected_xunit.txt index cb74491..d5cd531 100644 --- a/tests/auto/selftests/expected_xunit.txt +++ b/tests/auto/selftests/expected_xunit.txt @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="UTF-8" ?> <testsuite errors="5" failures="3" tests="9" name="tst_Xunit"> <properties> - <property value="4.6.0" name="QTestVersion"/> - <property value="4.6.0" name="QtVersion"/> + <property value="4.6.1" name="QTestVersion"/> + <property value="4.6.1" name="QtVersion"/> </properties> <testcase result="pass" name="initTestCase"/> <testcase result="pass" name="testFunc1"> diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro index a63fb41..9170039 100644 --- a/tests/benchmarks/benchmarks.pro +++ b/tests/benchmarks/benchmarks.pro @@ -3,6 +3,7 @@ SUBDIRS = containers-associative \ containers-sequential \ qanimation \ qbytearray \ + qfileinfo \ qfile_vs_qnetworkaccessmanager \ qpainter \ qtestlib-simple events \ diff --git a/tests/benchmarks/qdir/tst_qdir.cpp b/tests/benchmarks/qdir/tst_qdir.cpp index 2e4a28a..64c6ba1 100644 --- a/tests/benchmarks/qdir/tst_qdir.cpp +++ b/tests/benchmarks/qdir/tst_qdir.cpp @@ -68,7 +68,8 @@ public slots: void cleanupTestCase() { { QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); - + testdir.setSorting(QDir::Unsorted); + testdir.setFilter(QDir::AllEntries | QDir::System | QDir::Hidden); foreach (const QString &filename, testdir.entryList()) { testdir.remove(filename); } @@ -77,6 +78,8 @@ public slots: temp.rmdir(QLatin1String("test_speed")); } private slots: + void baseline() {} + void sizeSpeed() { QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); QBENCHMARK { @@ -87,6 +90,18 @@ private slots: } } } + void sizeSpeedIterator() { + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + QBENCHMARK { + QDirIterator dit(testdir.path(), QDir::Files); + while (dit.hasNext()) { + dit.fileInfo().isDir(); + dit.fileInfo().size(); + dit.next(); + } + } + } + void sizeSpeedWithoutFilter() { QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); QBENCHMARK { @@ -96,6 +111,18 @@ private slots: } } } + void sizeSpeedWithoutFilterIterator() { + QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); + QBENCHMARK { + QDirIterator dit(testdir.path()); + while (dit.hasNext()) { + dit.fileInfo().isDir(); + dit.fileInfo().size(); + dit.next(); + } + } + } + void sizeSpeedWithoutFileInfoList() { QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); testdir.setSorting(QDir::Unsorted); @@ -107,6 +134,7 @@ private slots: } } } + void iDontWantAnyStat() { QDir testdir(QDir::tempPath() + QLatin1String("/test_speed")); testdir.setSorting(QDir::Unsorted); @@ -118,8 +146,16 @@ private slots: } } } + void iDontWantAnyStatIterator() { + QBENCHMARK { + QDirIterator dit(QDir::tempPath() + QLatin1String("/test_speed")); + while (dit.hasNext()) { + dit.next(); + } + } + } - void testLowLevel() { + void sizeSpeedWithoutFilterLowLevel() { #ifdef Q_OS_WIN const wchar_t *dirpath = (wchar_t*)testdir.absolutePath().utf16(); wchar_t appendedPath[MAX_PATH]; diff --git a/tests/benchmarks/qfileinfo/main.cpp b/tests/benchmarks/qfileinfo/main.cpp new file mode 100644 index 0000000..711209c --- /dev/null +++ b/tests/benchmarks/qfileinfo/main.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite 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 <QDebug> +#include <qtest.h> +#include <QtTest/QtTest> +#include <QtCore/QCoreApplication> +#include <QtCore/QFileInfo> + +#include "private/qfsfileengine_p.h" + +class qfileinfo : public QObject +{ + Q_OBJECT +private slots: + void canonicalFileNamePerformance(); + + void initTestCase(); + void cleanupTestCase(); +public: + qfileinfo() : QObject() {}; +}; + +void qfileinfo::initTestCase() +{ +} + +void qfileinfo::cleanupTestCase() +{ +} + +void qfileinfo::canonicalFileNamePerformance() +{ + QString appPath = QCoreApplication::applicationFilePath(); + QFSFileEnginePrivate::canonicalized(appPath); // warmup + QFSFileEnginePrivate::canonicalized(appPath); // more warmup + QBENCHMARK { + for (int i = 0; i < 5000; i++) { + QFSFileEnginePrivate::canonicalized(appPath); + } + } +} + +QTEST_MAIN(qfileinfo) + +#include "main.moc" diff --git a/tests/benchmarks/qfileinfo/qfileinfo.pro b/tests/benchmarks/qfileinfo/qfileinfo.pro new file mode 100644 index 0000000..295cb50 --- /dev/null +++ b/tests/benchmarks/qfileinfo/qfileinfo.pro @@ -0,0 +1,12 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = qfileinfo +DEPENDPATH += . +INCLUDEPATH += . + +QT -= gui + +CONFIG += release + +# Input +SOURCES += main.cpp diff --git a/tests/manual/qwidget_zorder/main.cpp b/tests/manual/qwidget_zorder/main.cpp new file mode 100644 index 0000000..fe8e0a2 --- /dev/null +++ b/tests/manual/qwidget_zorder/main.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite module 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> + +class Widget : public QWidget +{ + Q_OBJECT +public: + Widget() + { + QWidget *stackWidget = new QWidget; + stackWidget->setFixedSize(400, 300); + button = new QPushButton("pushbutton", stackWidget); + plainTextEdit = new QPlainTextEdit(stackWidget); + plainTextEdit->setWordWrapMode(QTextOption::NoWrap); + QString s = "foo bar bar foo foo bar bar foo"; + for (int i = 0; i < 10; ++i) { + plainTextEdit->appendPlainText(s); + s.remove(1, 2); + } + calendar = new QCalendarWidget(stackWidget); + button->move(10, 10); + button->resize(100, 100); + plainTextEdit->move(30, 70); + plainTextEdit->resize(100, 100); + calendar->move(80, 40); + + QWidget *buttonOps = new QWidget; + QVBoxLayout *l = new QVBoxLayout(buttonOps); + QPushButton *lower = new QPushButton("button: lower"); + connect(lower, SIGNAL(clicked()), button, SLOT(lower())); + l->addWidget(lower); + QPushButton *raise = new QPushButton("button: raise"); + connect(raise, SIGNAL(clicked()), button, SLOT(raise())); + l->addWidget(raise); + + lower = new QPushButton("calendar: lower"); + connect(lower, SIGNAL(clicked()), calendar, SLOT(lower())); + l->addWidget(lower); + raise = new QPushButton("calendar: raise"); + connect(raise, SIGNAL(clicked()), calendar, SLOT(raise())); + l->addWidget(raise); + QPushButton *stackUnder = new QPushButton("calendar: stack under textedit"); + connect(stackUnder, SIGNAL(clicked()), this, SLOT(stackCalendarUnderTextEdit())); + l->addWidget(stackUnder); + + lower = new QPushButton("lower textedit"); + connect(lower, SIGNAL(clicked()), plainTextEdit, SLOT(lower())); + l->addWidget(lower); + raise = new QPushButton("raise textedit"); + connect(raise, SIGNAL(clicked()), plainTextEdit, SLOT(raise())); + l->addWidget(raise); + + QHBoxLayout *mainLayout = new QHBoxLayout(this); + mainLayout->addWidget(buttonOps); + mainLayout->addWidget(stackWidget); + } + +private Q_SLOTS: + void stackCalendarUnderTextEdit() + { + calendar->stackUnder(plainTextEdit); + } + +private: + QPushButton *button; + QPlainTextEdit *plainTextEdit; + QCalendarWidget *calendar; +}; + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + Widget w; + w.show(); + return app.exec(); +} + +#include "main.moc" diff --git a/tests/manual/qwidget_zorder/qwidget_zorder.pro b/tests/manual/qwidget_zorder/qwidget_zorder.pro new file mode 100644 index 0000000..5526f91 --- /dev/null +++ b/tests/manual/qwidget_zorder/qwidget_zorder.pro @@ -0,0 +1,6 @@ +TEMPLATE = app +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp diff --git a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp index ab32537..b9aedbe 100644 --- a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp +++ b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp @@ -578,6 +578,7 @@ void QHelpSearchIndexWriter::cancelIndexing() void QHelpSearchIndexWriter::updateIndex(const QString &collectionFile, const QString &indexFilesFolder, bool reindex) { + wait(); mutex.lock(); this->m_cancel = false; this->m_reindex = reindex; diff --git a/tools/assistant/lib/qhelpsearchindexwriter_default.cpp b/tools/assistant/lib/qhelpsearchindexwriter_default.cpp index 06deb85..60b9642 100644 --- a/tools/assistant/lib/qhelpsearchindexwriter_default.cpp +++ b/tools/assistant/lib/qhelpsearchindexwriter_default.cpp @@ -184,6 +184,7 @@ void QHelpSearchIndexWriter::updateIndex(const QString &collectionFile, const QString &indexFilesFolder, bool reindex) { + wait(); QMutexLocker lock(&mutex); this->m_cancel = false; diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp index 6f6875f..7488662 100644 --- a/tools/assistant/tools/assistant/centralwidget.cpp +++ b/tools/assistant/tools/assistant/centralwidget.cpp @@ -223,6 +223,7 @@ CentralWidget::CentralWidget(QHelpEngine *engine, MainWindow *parent) QString resourcePath = QLatin1String(":/trolltech/assistant/images/"); vboxLayout->setMargin(0); + tabWidget = new QTabWidget(this); #ifndef Q_OS_MAC resourcePath.append(QLatin1String("win")); #else @@ -230,7 +231,6 @@ CentralWidget::CentralWidget(QHelpEngine *engine, MainWindow *parent) tabWidget->setDocumentMode(true); #endif - tabWidget = new QTabWidget(this); connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(currentPageChanged(int))); diff --git a/tools/assistant/tools/assistant/doc/assistant.qdocconf b/tools/assistant/tools/assistant/doc/assistant.qdocconf index 161d34f..0a7ffe0 100644 --- a/tools/assistant/tools/assistant/doc/assistant.qdocconf +++ b/tools/assistant/tools/assistant/doc/assistant.qdocconf @@ -12,5 +12,5 @@ HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \ "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \ "<td width=\"30%\" align=\"left\">Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies)</td>\n" \ "<td width=\"40%\" align=\"center\">Trademarks</td>\n" \ - "<td width=\"30%\" align=\"right\"><div align=\"right\">Qt 4.6.0</div></td>\n" \ + "<td width=\"30%\" align=\"right\"><div align=\"right\">Qt 4.6.1</div></td>\n" \ "</tr></table></div></address>" diff --git a/tools/assistant/tools/assistant/indexwindow.cpp b/tools/assistant/tools/assistant/indexwindow.cpp index 6d35649..97828c1 100644 --- a/tools/assistant/tools/assistant/indexwindow.cpp +++ b/tools/assistant/tools/assistant/indexwindow.cpp @@ -112,18 +112,22 @@ bool IndexWindow::eventFilter(QObject *obj, QEvent *e) case Qt::Key_Up: idx = m_indexWidget->model()->index(idx.row()-1, idx.column(), idx.parent()); - if (idx.isValid()) + if (idx.isValid()) { m_indexWidget->setCurrentIndex(idx); + return true; + } break; case Qt::Key_Down: idx = m_indexWidget->model()->index(idx.row()+1, idx.column(), idx.parent()); - if (idx.isValid()) + if (idx.isValid()) { m_indexWidget->setCurrentIndex(idx); + return true; + } break; case Qt::Key_Escape: emit escapePressed(); - break; + return true; default: ; // stop complaining } } else if (obj == m_indexWidget && e->type() == QEvent::ContextMenu) { diff --git a/tools/designer/src/components/formeditor/formwindowmanager.cpp b/tools/designer/src/components/formeditor/formwindowmanager.cpp index 23d8580..246c56f 100644 --- a/tools/designer/src/components/formeditor/formwindowmanager.cpp +++ b/tools/designer/src/components/formeditor/formwindowmanager.cpp @@ -196,6 +196,7 @@ bool FormWindowManager::eventFilter(QObject *o, QEvent *e) case QEvent::HoverEnter: case QEvent::HoverLeave: case QEvent::HoverMove: + case QEvent::AcceptDropsChange: return false; default: break; diff --git a/tools/linguist/linguist/mainwindow.cpp b/tools/linguist/linguist/mainwindow.cpp index 5c3aaa1..383f5aa 100644 --- a/tools/linguist/linguist/mainwindow.cpp +++ b/tools/linguist/linguist/mainwindow.cpp @@ -305,8 +305,6 @@ MainWindow::MainWindow() m_contextView->setModel(m_sortedContextsModel); m_contextView->header()->setMovable(false); m_contextView->setColumnHidden(0, true); - m_contextView->header()->setResizeMode(1, QHeaderView::Stretch); - m_contextView->header()->setResizeMode(2, QHeaderView::ResizeToContents); m_contextView->header()->setStretchLastSection(false); m_contextDock->setWidget(m_contextView); @@ -335,8 +333,6 @@ MainWindow::MainWindow() m_messageView->setModel(m_sortedMessagesModel); m_messageView->header()->setMovable(false); m_messageView->setColumnHidden(0, true); - m_messageView->setColumnHidden(2, true); - // last visible column auto-stretches m_messagesDock->setWidget(m_messageView); @@ -443,6 +439,7 @@ MainWindow::MainWindow() statusBar()->addPermanentWidget(m_modifiedLabel); modelCountChanged(); + initViewHeaders(); resetSorting(); connect(m_dataModel, SIGNAL(modifiedChanged(bool)), @@ -509,6 +506,14 @@ MainWindow::~MainWindow() delete m_printer; } +void MainWindow::initViewHeaders() +{ + m_contextView->header()->setResizeMode(1, QHeaderView::Stretch); + m_contextView->header()->setResizeMode(2, QHeaderView::ResizeToContents); + m_messageView->setColumnHidden(2, true); + // last visible column auto-stretches +} + void MainWindow::modelCountChanged() { int mc = m_dataModel->modelCount(); @@ -740,6 +745,7 @@ bool MainWindow::closeAll() m_messageView->setUpdatesEnabled(false); m_dataModel->closeAll(); modelCountChanged(); + initViewHeaders(); recentFiles().closeGroup(); return true; } @@ -2348,6 +2354,17 @@ void MainWindow::updatePhraseDicts() m_phraseView->update(); } +static bool haveMnemonic(const QString &str) +{ + QString mnemonic = QKeySequence::mnemonic(str); + if (mnemonic == QLatin1String("Alt+Space")) { + // "Nobody" ever really uses these, and they are highly annoying + // because we get a lot of false positives. + return false; + } + return !mnemonic.isEmpty(); +} + void MainWindow::updateDanger(const MultiDataIndex &index, bool verbose) { MultiDataIndex curIdx = index; @@ -2379,10 +2396,10 @@ void MainWindow::updateDanger(const MultiDataIndex &index, bool verbose) } if (m_ui.actionAccelerators->isChecked()) { - bool sk = !QKeySequence::mnemonic(source).isEmpty(); + bool sk = haveMnemonic(source); bool tk = true; for (int i = 0; i < translations.count() && tk; ++i) { - tk &= !QKeySequence::mnemonic(translations[i]).isEmpty(); + tk &= haveMnemonic(translations[i]); } if (!sk && tk) { diff --git a/tools/linguist/linguist/mainwindow.h b/tools/linguist/linguist/mainwindow.h index 8b46893..dc711d8 100644 --- a/tools/linguist/linguist/mainwindow.h +++ b/tools/linguist/linguist/mainwindow.h @@ -179,6 +179,7 @@ private: bool prev(bool checkUnfinished); void updateStatistics(); + void initViewHeaders(); void modelCountChanged(); void setupMenuBar(); void setupToolBars(); diff --git a/tools/linguist/linguist/messagemodel.cpp b/tools/linguist/linguist/messagemodel.cpp index 024fd91..49cd382 100644 --- a/tools/linguist/linguist/messagemodel.cpp +++ b/tools/linguist/linguist/messagemodel.cpp @@ -786,16 +786,9 @@ void MultiDataModel::closeAll() m_numFinished = 0; m_numEditable = 0; m_numMessages = 0; - int delCol = m_dataModels.count(); - m_msgModel->beginRemoveColumns(QModelIndex(), 1, delCol); - for (int i = m_multiContextList.size(); --i >= 0;) { - m_msgModel->beginRemoveColumns(m_msgModel->createIndex(i, 0, 0), 1, delCol); - m_msgModel->endRemoveColumns(); - } qDeleteAll(m_dataModels); m_dataModels.clear(); m_multiContextList.clear(); - m_msgModel->endRemoveColumns(); m_msgModel->reset(); emit allModelsDeleted(); onModifiedChanged(); diff --git a/tools/linguist/linguist/translationsettingsdialog.cpp b/tools/linguist/linguist/translationsettingsdialog.cpp index 0d94c3a..562f14e 100644 --- a/tools/linguist/linguist/translationsettingsdialog.cpp +++ b/tools/linguist/linguist/translationsettingsdialog.cpp @@ -60,15 +60,7 @@ TranslationSettingsDialog::TranslationSettingsDialog(QWidget *parent) m_ui.srcCbLanguageList->model()->sort(0, Qt::AscendingOrder); m_ui.srcCbLanguageList->insertItem(0, QLatin1String("POSIX"), QVariant(QLocale::C)); - for (int i = QLocale::AnyCountry + 1; i < QLocale::LastCountry; ++i) { - QString country = QLocale::countryToString(QLocale::Country(i)); - m_ui.srcCbCountryList->addItem(country, QVariant(i)); - } - m_ui.srcCbCountryList->model()->sort(0, Qt::AscendingOrder); - m_ui.srcCbCountryList->insertItem(0, tr("Any Country"), QVariant(QLocale::AnyCountry)); - m_ui.tgtCbLanguageList->setModel(m_ui.srcCbLanguageList->model()); - m_ui.tgtCbCountryList->setModel(m_ui.srcCbCountryList->model()); } void TranslationSettingsDialog::setDataModel(DataModel *dataModel) @@ -87,6 +79,31 @@ void TranslationSettingsDialog::setPhraseBook(PhraseBook *phraseBook) setWindowTitle(tr("Settings for '%1' - Qt Linguist").arg(fn)); } +static void fillCountryCombo(const QVariant &lng, QComboBox *combo) +{ + combo->clear(); + QLocale::Language lang = QLocale::Language(lng.toInt()); + if (lang != QLocale::C) { + foreach (QLocale::Country cntr, QLocale::countriesForLanguage(lang)) { + QString country = QLocale::countryToString(cntr); + combo->addItem(country, QVariant(cntr)); + } + combo->model()->sort(0, Qt::AscendingOrder); + } + combo->insertItem(0, TranslationSettingsDialog::tr("Any Country"), QVariant(QLocale::AnyCountry)); + combo->setCurrentIndex(0); +} + +void TranslationSettingsDialog::on_srcCbLanguageList_currentIndexChanged(int idx) +{ + fillCountryCombo(m_ui.srcCbLanguageList->itemData(idx), m_ui.srcCbCountryList); +} + +void TranslationSettingsDialog::on_tgtCbLanguageList_currentIndexChanged(int idx) +{ + fillCountryCombo(m_ui.tgtCbLanguageList->itemData(idx), m_ui.tgtCbCountryList); +} + void TranslationSettingsDialog::on_buttonBox_accepted() { int itemindex = m_ui.tgtCbLanguageList->currentIndex(); diff --git a/tools/linguist/linguist/translationsettingsdialog.h b/tools/linguist/linguist/translationsettingsdialog.h index 2408add..7908cd7 100644 --- a/tools/linguist/linguist/translationsettingsdialog.h +++ b/tools/linguist/linguist/translationsettingsdialog.h @@ -66,6 +66,8 @@ private: private slots: void on_buttonBox_accepted(); + void on_srcCbLanguageList_currentIndexChanged(int idx); + void on_tgtCbLanguageList_currentIndexChanged(int idx); private: Ui::TranslationSettingsDialog m_ui; diff --git a/tools/linguist/lrelease/lrelease.pro b/tools/linguist/lrelease/lrelease.pro index e4c18ee..6beafa3 100644 --- a/tools/linguist/lrelease/lrelease.pro +++ b/tools/linguist/lrelease/lrelease.pro @@ -5,11 +5,18 @@ DESTDIR = ../../../bin DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII SOURCES += main.cpp +INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global # qlibraryinfo.cpp includes qconfig.cpp +SOURCES += \ + $$QT_SOURCE_TREE/src/corelib/global/qlibraryinfo.cpp \ + $$QT_SOURCE_TREE/src/corelib/io/qsettings.cpp +win32:SOURCES += $$QT_SOURCE_TREE/src/corelib/io/qsettings_win.cpp +macx:SOURCES += $$QT_SOURCE_TREE/src/corelib/io/qsettings_mac.cpp + include(../../../src/tools/bootstrap/bootstrap.pri) include(../shared/formats.pri) include(../shared/proparser.pri) -win32-msvc*:LIBS += advapi32.lib # for qsettings_win.cpp +win32:LIBS += -ladvapi32 # for qsettings_win.cpp target.path=$$[QT_INSTALL_BINS] INSTALLS += target diff --git a/tools/linguist/phrasebooks/french.qph b/tools/linguist/phrasebooks/french.qph index d710abd..9e1a580 100644 --- a/tools/linguist/phrasebooks/french.qph +++ b/tools/linguist/phrasebooks/french.qph @@ -1402,4 +1402,40 @@ <source>&Redo</source> <target>&Rétablir</target> </phrase> +<phrase> + <source>Edit</source> + <target>Éditer</target> +</phrase> +<phrase> + <source>PATH:</source> + <target>PATH :</target> +</phrase> +<phrase> + <source>Change:</source> + <target>Modification :</target> +</phrase> +<phrase> + <source>Edit...</source> + <target>Modifier...</target> +</phrase> +<phrase> + <source>&Username:</source> + <target>&Utilisateur :</target> +</phrase> +<phrase> + <source>Link</source> + <target>Lien</target> +</phrase> +<phrase> + <source>Paste:</source> + <target>Collage :</target> +</phrase> +<phrase> + <source>Label</source> + <target>Libellé</target> +</phrase> +<phrase> + <source>&Debug</source> + <target>&Déboguer</target> +</phrase> </QPH> diff --git a/tools/linguist/shared/qph.cpp b/tools/linguist/shared/qph.cpp index 788245c..32bdabb 100644 --- a/tools/linguist/shared/qph.cpp +++ b/tools/linguist/shared/qph.cpp @@ -81,14 +81,20 @@ bool QPHReader::read(Translator &translator) while (!atEnd()) { readNext(); if (isStartElement()) { - if (name() == QLatin1String("source")) + if (name() == QLatin1String("source")) { m_currentField = SourceField; - else if (name() == QLatin1String("target")) + } else if (name() == QLatin1String("target")) { m_currentField = TargetField; - else if (name() == QLatin1String("definition")) + } else if (name() == QLatin1String("definition")) { m_currentField = DefinitionField; - else + } else { m_currentField = NoField; + if (name() == QLatin1String("QPH")) { + QXmlStreamAttributes atts = attributes(); + translator.setLanguageCode(atts.value(QLatin1String("language")).toString()); + translator.setSourceLanguageCode(atts.value(QLatin1String("sourcelanguage")).toString()); + } + } } else if (isWhiteSpace()) { // ignore these } else if (isCharacters()) { @@ -104,7 +110,7 @@ bool QPHReader::read(Translator &translator) TranslatorMessage msg; msg.setSourceText(m_currentSource); msg.setTranslation(m_currentTarget); - msg.setTranslatorComment(m_currentDefinition); + msg.setComment(m_currentDefinition); translator.append(msg); m_currentSource.clear(); m_currentTarget.clear(); @@ -157,7 +163,14 @@ static bool saveQPH(const Translator &translator, QIODevice &dev, ConversionData { QTextStream t(&dev); t.setCodec(QTextCodec::codecForName("UTF-8")); - t << "<!DOCTYPE QPH>\n<QPH>\n"; + t << "<!DOCTYPE QPH>\n<QPH"; + QString languageCode = translator.languageCode(); + if (!languageCode.isEmpty() && languageCode != QLatin1String("C")) + t << " language=\"" << languageCode << "\""; + languageCode = translator.sourceLanguageCode(); + if (!languageCode.isEmpty() && languageCode != QLatin1String("C")) + t << " sourcelanguage=\"" << languageCode << "\""; + t << ">\n"; foreach (const TranslatorMessage &msg, translator.messages()) { t << "<phrase>\n"; t << " <source>" << protect(msg.sourceText()) << "</source>\n"; @@ -166,9 +179,8 @@ static bool saveQPH(const Translator &translator, QIODevice &dev, ConversionData QChar(Translator::TextVariantSeparator)); t << " <target>" << protect(str) << "</target>\n"; - if (!msg.context().isEmpty() || !msg.comment().isEmpty()) - t << " <definition>" << msg.context() << msg.comment() - << "</definition>\n"; + if (!msg.comment().isEmpty()) + t << " <definition>" << protect(msg.comment()) << "</definition>\n"; t << "</phrase>\n"; } t << "</QPH>\n"; diff --git a/tools/linguist/shared/translator.h b/tools/linguist/shared/translator.h index 353cf9d..fa447a3 100644 --- a/tools/linguist/shared/translator.h +++ b/tools/linguist/shared/translator.h @@ -55,10 +55,12 @@ QT_BEGIN_NAMESPACE #ifdef QT_BOOTSTRAPPED -struct QObject { +class QObject { +public: static QString tr(const char *sourceText, const char * = 0, int n = -1); }; -struct QCoreApplication : public QObject { +class QCoreApplication : public QObject { +public: enum Encoding { CodecForTr }; static QString translate(const char *, const char *sourceText, const char * = 0, Encoding = CodecForTr, int n = -1) diff --git a/tools/qdoc3/config.cpp b/tools/qdoc3/config.cpp index 0fc3606..1a4e46e 100644 --- a/tools/qdoc3/config.cpp +++ b/tools/qdoc3/config.cpp @@ -399,6 +399,13 @@ QStringList Config::getAllFiles(const QString &filesVar, } /*! + \a fileName is the path of the file to find. + + \a files and \a dirs are the lists where we must find the + components of \a fileName. + + \a location is used for obtaining the file and line numbers + for report qdoc errors. */ QString Config::findFile(const Location& location, const QStringList& files, @@ -527,6 +534,11 @@ QString Config::findFile(const Location& location, } /*! + Copies the \a sourceFilePath to the file name constructed by + concatenating \a targetDirPath and \a userFriendlySourceFilePath. + \a location is for identifying the file and line number where + a qdoc error occurred. The constructed output file name is + returned. */ QString Config::copyFile(const Location& location, const QString& sourceFilePath, diff --git a/tools/qdoc3/config.h b/tools/qdoc3/config.h index 725129a..33e5739 100644 --- a/tools/qdoc3/config.h +++ b/tools/qdoc3/config.h @@ -161,6 +161,7 @@ class Config #define CONFIG_VERSIONSYM "versionsym" #define CONFIG_FILEEXTENSIONS "fileextensions" +#define CONFIG_IMAGEEXTENSIONS "imageextensions" #ifdef QDOC_QML #define CONFIG_QMLONLY "qmlonly" diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index ce71e51..41a2456 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -197,8 +197,14 @@ CppCodeParser::CppCodeParser() */ CppCodeParser::~CppCodeParser() { + // nothing. } +/*! + The constructor initializes a map of special node types + for identifying important nodes. And it initializes + some filters for identifying certain kinds of files. + */ void CppCodeParser::initializeParser(const Config &config) { CodeParser::initializeParser(config); @@ -220,24 +226,46 @@ void CppCodeParser::initializeParser(const Config &config) exampleNameFilter = exampleFilePatterns.join(" "); else exampleNameFilter = "*.cpp *.h *.js *.xq *.svg *.xml *.ui"; + + QStringList exampleImagePatterns = config.getStringList( + CONFIG_EXAMPLES + Config::dot + CONFIG_IMAGEEXTENSIONS); + + if (!exampleImagePatterns.isEmpty()) + exampleImageFilter = exampleImagePatterns.join(" "); + else + exampleImageFilter = "*.png"; } +/*! + Clear the map of common node types and call + the same function in the base class. + */ void CppCodeParser::terminateParser() { nodeTypeMap.clear(); CodeParser::terminateParser(); } +/*! + Returns "Cpp". + */ QString CppCodeParser::language() { return "Cpp"; } +/*! + Returns a list of extensions for header files. + */ QString CppCodeParser::headerFileNameFilter() { return "*.ch *.h *.h++ *.hh *.hpp *.hxx"; } +/*! + Returns a list of extensions for source files, i.e. not + header files. + */ QString CppCodeParser::sourceFileNameFilter() { return "*.c++ *.cc *.cpp *.cxx"; @@ -299,6 +327,12 @@ void CppCodeParser::parseSourceFile(const Location& location, fclose(in); } +/*! + This is called after all the header files have been parsed. + I think the most important thing it does is resolve class + inheritance links in the tree. But it also initializes a + bunch of stuff. + */ void CppCodeParser::doneParsingHeaderFiles(Tree *tree) { tree->resolveInheritance(); @@ -345,6 +379,12 @@ void CppCodeParser::doneParsingHeaderFiles(Tree *tree) mutableAssociativeIteratorClasses.clear(); } +/*! + This is called after all the source files (i.e., not the + header files) have been parsed. It traverses the tree to + resolve property links, normalize overload signatures, and + do other housekeeping of the tree. + */ void CppCodeParser::doneParsingSourceFiles(Tree *tree) { tree->root()->makeUndocumentedChildrenInternal(); @@ -353,6 +393,13 @@ void CppCodeParser::doneParsingSourceFiles(Tree *tree) tree->resolveProperties(); } +/*! + This function searches the \a tree to find a FunctionNode + for a function with the signature \a synopsis. If the + \a relative node is provided, the search begins there. If + \a fuzzy is true, base classes are searched. The function + node is returned, if found. + */ const FunctionNode *CppCodeParser::findFunctionNode(const QString& synopsis, Tree *tree, Node *relative, @@ -2212,6 +2259,7 @@ void CppCodeParser::createExampleFileNodes(FakeNode *fake) exampleDirs, proFileName, userFriendlyFilePath); + if (fullPath.isEmpty()) { QString tmp = proFileName; proFileName = examplePath + "/" + "qbuild.pro"; @@ -2231,8 +2279,18 @@ void CppCodeParser::createExampleFileNodes(FakeNode *fake) int sizeOfBoringPartOfName = fullPath.size() - proFileName.size(); fullPath.truncate(fullPath.lastIndexOf('/')); - QStringList exampleFiles = Config::getFilesHere(fullPath, - exampleNameFilter); + QStringList exampleFiles = Config::getFilesHere(fullPath,exampleNameFilter); + QString imagesPath = fullPath + "/images"; + QStringList imageFiles = Config::getFilesHere(imagesPath,exampleImageFilter); + +#if 0 + qDebug() << "examplePath:" << examplePath; + qDebug() << " exampleFiles" << exampleFiles; + qDebug() << "imagesPath:" << imagesPath; + qDebug() << "fullPath:" << fullPath; + qDebug() << " imageFiles" << imageFiles; +#endif + if (!exampleFiles.isEmpty()) { // move main.cpp and to the end, if it exists QString mainCpp; @@ -2259,6 +2317,11 @@ void CppCodeParser::createExampleFileNodes(FakeNode *fake) (void) new FakeNode(fake, exampleFile.mid(sizeOfBoringPartOfName), Node::File); + foreach (const QString &imageFile, imageFiles) { + FakeNode* newFake = new FakeNode(fake, + imageFile.mid(sizeOfBoringPartOfName), + Node::Image); + } } QT_END_NAMESPACE diff --git a/tools/qdoc3/cppcodeparser.h b/tools/qdoc3/cppcodeparser.h index e2e9d55..fff5bd9 100644 --- a/tools/qdoc3/cppcodeparser.h +++ b/tools/qdoc3/cppcodeparser.h @@ -185,6 +185,7 @@ class CppCodeParser : public CodeParser static QStringList exampleFiles; static QStringList exampleDirs; QString exampleNameFilter; + QString exampleImageFilter; }; QT_END_NAMESPACE diff --git a/tools/qdoc3/documentation.pri b/tools/qdoc3/documentation.pri deleted file mode 100644 index d952183..0000000 --- a/tools/qdoc3/documentation.pri +++ /dev/null @@ -1,5 +0,0 @@ -# NOTE: THIS FILE IS SHARED BY qdoc3.pro AND projects.pro -# -# So while changing this file, please make sure to that your changes -# work in root qt soure dir with (n)make docs and for building with qdoc -# diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index f7569ce..9389268 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -138,14 +138,15 @@ void Generator::initialize(const Config &config) while (g != generators.end()) { if (outputFormats.contains((*g)->format())) { (*g)->initializeGenerator(config); - QStringList extraImages = config.getStringList(CONFIG_EXTRAIMAGES + - Config::dot + - (*g)->format()); + QStringList extraImages = + config.getStringList(CONFIG_EXTRAIMAGES+Config::dot+(*g)->format()); QStringList::ConstIterator e = extraImages.begin(); while (e != extraImages.end()) { QString userFriendlyFilePath; QString filePath = Config::findFile(config.lastLocation(), - imageFiles, imageDirs, *e, + imageFiles, + imageDirs, + *e, imgFileExts[(*g)->format()], userFriendlyFilePath); if (!filePath.isEmpty()) @@ -529,33 +530,80 @@ void Generator::generateInheritedBy(const ClassNode *classe, } } -void Generator::generateExampleFiles(const FakeNode *fake, CodeMarker *marker) +void Generator::generateFileList(const FakeNode* fake, + CodeMarker* marker, + Node::SubType subtype, + const QString& tag) { - if (fake->childNodes().isEmpty()) - return; - + int count = 0; + Text text; OpenedList openedList(OpenedList::Bullet); - Text text; - text << Atom::ParaLeft << "Files:" << Atom::ParaRight + text << Atom::ParaLeft << tag << Atom::ParaRight << Atom(Atom::ListLeft, openedList.styleString()); - foreach (const Node *child, fake->childNodes()) { - QString exampleFile = child->name(); - openedList.next(); - text << Atom(Atom::ListItemNumber, openedList.numberString()) - << Atom(Atom::ListItemLeft, openedList.styleString()) - << Atom::ParaLeft - << Atom(Atom::Link, exampleFile) - << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) - << exampleFile - << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) - << Atom::ParaRight - << Atom(Atom::ListItemRight, openedList.styleString()); + + foreach (const Node* child, fake->childNodes()) { + if (child->subType() == subtype) { + ++count; + QString file = child->name(); + + if (file == "network/qftp/images/dir.png") + qDebug() << "FILE:" << file; + + openedList.next(); + text << Atom(Atom::ListItemNumber, openedList.numberString()) + << Atom(Atom::ListItemLeft, openedList.styleString()) + << Atom::ParaLeft + << Atom(Atom::Link, file) + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) + << file + << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) + << Atom::ParaRight + << Atom(Atom::ListItemRight, openedList.styleString()); + } } text << Atom(Atom::ListRight, openedList.styleString()); - generateText(text, fake, marker); + if (count > 0) + generateText(text, fake, marker); } +void Generator::generateExampleFiles(const FakeNode *fake, CodeMarker *marker) +{ + if (fake->childNodes().isEmpty()) + return; + generateFileList(fake, marker, Node::File, QString("Files:")); + generateFileList(fake, marker, Node::Image, QString("Images:")); +} + +#if 0 + QList<Generator *>::ConstIterator g = generators.begin(); + while (g != generators.end()) { + if (outputFormats.contains((*g)->format())) { + (*g)->initializeGenerator(config); + QStringList extraImages = + config.getStringList(CONFIG_EXTRAIMAGES+Config::dot+(*g)->format()); + QStringList::ConstIterator e = extraImages.begin(); + while (e != extraImages.end()) { + QString userFriendlyFilePath; + QString filePath = Config::findFile(config.lastLocation(), + imageFiles, + imageDirs, + *e, + imgFileExts[(*g)->format()], + userFriendlyFilePath); + if (!filePath.isEmpty()) + Config::copyFile(config.lastLocation(), + filePath, + userFriendlyFilePath, + (*g)->outputDir() + + "/images"); + ++e; + } + } + ++g; + } +#endif + void Generator::generateModuleWarning(const ClassNode *classe, CodeMarker *marker) { diff --git a/tools/qdoc3/generator.h b/tools/qdoc3/generator.h index 0258534..7667789 100644 --- a/tools/qdoc3/generator.h +++ b/tools/qdoc3/generator.h @@ -119,6 +119,10 @@ class Generator CodeMarker *marker, bool generate, int& numGeneratedAtoms); + void generateFileList(const FakeNode* fake, + CodeMarker* marker, + Node::SubType subtype, + const QString& tag); void generateExampleFiles(const FakeNode *fake, CodeMarker *marker); void generateModuleWarning(const ClassNode *classe, CodeMarker *marker); diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp index 373002c..b855823 100644 --- a/tools/qdoc3/node.cpp +++ b/tools/qdoc3/node.cpp @@ -767,6 +767,9 @@ FakeNode::FakeNode(InnerNode *parent, const QString& name, SubType subtype) } /*! + Returns the fake node's full title, which is usually + just title(), but for some SubType values is different + from title() */ QString FakeNode::fullTitle() const { @@ -776,6 +779,12 @@ QString FakeNode::fullTitle() const else return title(); } + else if (sub == Image) { + if (title().isEmpty()) + return name().mid(name().lastIndexOf('/') + 1) + " Image File"; + else + return title(); + } else if (sub == HeaderFile) { if (title().isEmpty()) return name(); @@ -788,13 +797,14 @@ QString FakeNode::fullTitle() const } /*! + Returns the subtitle. */ QString FakeNode::subTitle() const { if (!stle.isEmpty()) return stle; - if (sub == File) { + if ((sub == File) || (sub == Image)) { if (title().isEmpty() && name().contains("/")) return name(); } diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h index dbdc174..223f528 100644 --- a/tools/qdoc3/node.h +++ b/tools/qdoc3/node.h @@ -89,6 +89,7 @@ class Node Example, HeaderFile, File, + Image, Group, Module, Page, diff --git a/tools/qdoc3/qdoc3.pro b/tools/qdoc3/qdoc3.pro index bacef3f..441bf39 100644 --- a/tools/qdoc3/qdoc3.pro +++ b/tools/qdoc3/qdoc3.pro @@ -105,3 +105,5 @@ SOURCES += apigenerator.cpp \ webxmlgenerator.cpp \ yyindent.cpp +target.path = $$[QT_INSTALL_BINS] +INSTALLS += target diff --git a/tools/qdoc3/test/assistant.qdocconf b/tools/qdoc3/test/assistant.qdocconf index 4ddc94a..adca7b4 100644 --- a/tools/qdoc3/test/assistant.qdocconf +++ b/tools/qdoc3/test/assistant.qdocconf @@ -17,7 +17,7 @@ qhp.Assistant.namespace = com.trolltech.assistant.460 qhp.Assistant.virtualFolder = qdoc qhp.Assistant.indexTitle = Qt Assistant Manual qhp.Assistant.extraFiles = classic.css images/qt-logo.png images/trolltech-logo.png -qhp.Assistant.filterAttributes = qt 4.6.0 tools assistant +qhp.Assistant.filterAttributes = qt 4.6.1 tools assistant qhp.Assistant.customFilters.Assistant.name = Qt Assistant Manual qhp.Assistant.customFilters.Assistant.filterAttributes = qt tools assistant qhp.Assistant.subprojects = manual examples diff --git a/tools/qdoc3/test/designer.qdocconf b/tools/qdoc3/test/designer.qdocconf index 9d8bd23..d30ade9 100644 --- a/tools/qdoc3/test/designer.qdocconf +++ b/tools/qdoc3/test/designer.qdocconf @@ -17,7 +17,7 @@ qhp.Designer.namespace = com.trolltech.designer.460 qhp.Designer.virtualFolder = qdoc qhp.Designer.indexTitle = Qt Designer Manual qhp.Designer.extraFiles = classic.css images/qt-logo.png images/trolltech-logo.png -qhp.Designer.filterAttributes = qt 4.6.0 tools designer +qhp.Designer.filterAttributes = qt 4.6.1 tools designer qhp.Designer.customFilters.Designer.name = Qt Designer Manual qhp.Designer.customFilters.Designer.filterAttributes = qt tools designer qhp.Designer.subprojects = manual examples diff --git a/tools/qdoc3/test/linguist.qdocconf b/tools/qdoc3/test/linguist.qdocconf index f433529..f06671b 100644 --- a/tools/qdoc3/test/linguist.qdocconf +++ b/tools/qdoc3/test/linguist.qdocconf @@ -17,7 +17,7 @@ qhp.Linguist.namespace = com.trolltech.linguist.460 qhp.Linguist.virtualFolder = qdoc qhp.Linguist.indexTitle = Qt Linguist Manual qhp.Linguist.extraFiles = classic.css images/qt-logo.png images/trolltech-logo.png -qhp.Linguist.filterAttributes = qt 4.6.0 tools linguist +qhp.Linguist.filterAttributes = qt 4.6.1 tools linguist qhp.Linguist.customFilters.Linguist.name = Qt Linguist Manual qhp.Linguist.customFilters.Linguist.filterAttributes = qt tools linguist qhp.Linguist.subprojects = manual examples diff --git a/tools/qdoc3/test/qmake.qdocconf b/tools/qdoc3/test/qmake.qdocconf index dcb3c9a..ad27d75 100644 --- a/tools/qdoc3/test/qmake.qdocconf +++ b/tools/qdoc3/test/qmake.qdocconf @@ -17,7 +17,7 @@ qhp.qmake.namespace = com.trolltech.qmake.460 qhp.qmake.virtualFolder = qdoc qhp.qmake.indexTitle = QMake Manual qhp.qmake.extraFiles = classic.css images/qt-logo.png images/trolltech-logo.png -qhp.qmake.filterAttributes = qt 4.6.0 tools qmake +qhp.qmake.filterAttributes = qt 4.6.1 tools qmake qhp.qmake.customFilters.qmake.name = qmake Manual qhp.qmake.customFilters.qmake.filterAttributes = qt tools qmake qhp.qmake.subprojects = manual diff --git a/tools/qdoc3/test/qt-build-docs.qdocconf b/tools/qdoc3/test/qt-build-docs.qdocconf index d1733e5..e9b9eb8 100644 --- a/tools/qdoc3/test/qt-build-docs.qdocconf +++ b/tools/qdoc3/test/qt-build-docs.qdocconf @@ -32,9 +32,9 @@ qhp.Qt.extraFiles = classic.css \ images/dynamiclayouts-example.png \ images/stylesheet-coffee-plastique.png -qhp.Qt.filterAttributes = qt 4.6.0 qtrefdoc -qhp.Qt.customFilters.Qt.name = Qt 4.6.0 -qhp.Qt.customFilters.Qt.filterAttributes = qt 4.6.0 +qhp.Qt.filterAttributes = qt 4.6.1 qtrefdoc +qhp.Qt.customFilters.Qt.name = Qt 4.6.1 +qhp.Qt.customFilters.Qt.filterAttributes = qt 4.6.1 qhp.Qt.subprojects = classes overviews examples qhp.Qt.subprojects.classes.title = Classes qhp.Qt.subprojects.classes.indexTitle = Qt's Classes @@ -97,6 +97,7 @@ excludedirs = $QT_SOURCE_TREE/src/3rdparty/clucene \ sources.fileextensions = "*.cpp *.qdoc *.mm" examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp" +examples.imageextensions = "*.png" exampledirs = $QT_SOURCE_TREE/doc/src \ $QT_SOURCE_TREE/examples \ diff --git a/tools/qdoc3/test/qt.qdocconf b/tools/qdoc3/test/qt.qdocconf index d70ef58..a99f73e 100644 --- a/tools/qdoc3/test/qt.qdocconf +++ b/tools/qdoc3/test/qt.qdocconf @@ -34,9 +34,9 @@ qhp.Qt.extraFiles = classic.css \ images/dynamiclayouts-example.png \ images/stylesheet-coffee-plastique.png -qhp.Qt.filterAttributes = qt 4.6.0 qtrefdoc -qhp.Qt.customFilters.Qt.name = Qt 4.6.0 -qhp.Qt.customFilters.Qt.filterAttributes = qt 4.6.0 +qhp.Qt.filterAttributes = qt 4.6.1 qtrefdoc +qhp.Qt.customFilters.Qt.name = Qt 4.6.1 +qhp.Qt.customFilters.Qt.filterAttributes = qt 4.6.1 qhp.Qt.subprojects = classes overviews examples qhp.Qt.subprojects.classes.title = Classes qhp.Qt.subprojects.classes.indexTitle = Qt's Classes @@ -100,6 +100,7 @@ excludedirs = $QTDIR/src/3rdparty/clucene \ sources.fileextensions = "*.cpp *.qdoc *.mm" examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp" +examples.imageextensions = "*.png" exampledirs = $QTDIR/doc/src \ $QTDIR/examples \ diff --git a/tools/tools.pro b/tools/tools.pro index 87ba3c9..4cff507 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -31,5 +31,7 @@ contains(QT_CONFIG, dbus):SUBDIRS += qdbus !wince*:contains(QT_CONFIG, xmlpatterns): SUBDIRS += xmlpatterns xmlpatternsvalidator embedded: SUBDIRS += makeqpf +!wince*:!cross_compile:SUBDIRS += qdoc3 + CONFIG+=ordered QTDIR_build:REQUIRES = "contains(QT_CONFIG, full-config)" diff --git a/tools/xmlpatterns/main.cpp b/tools/xmlpatterns/main.cpp index a930b70..604523b 100644 --- a/tools/xmlpatterns/main.cpp +++ b/tools/xmlpatterns/main.cpp @@ -80,14 +80,14 @@ QT_USE_NAMESPACE Represents the name and value found in "-param name=value". */ typedef QPair<QString, QString> Parameter; -Q_DECLARE_METATYPE(Parameter); +Q_DECLARE_METATYPE(Parameter) /*! \internal \since 4.4 For the -output switch. */ -Q_DECLARE_METATYPE(QIODevice *); +Q_DECLARE_METATYPE(QIODevice *) /*! \class PatternistApplicationParser diff --git a/translations/translations.pri b/translations/translations.pri index 5eb7328..7a24a4f 100644 --- a/translations/translations.pri +++ b/translations/translations.pri @@ -9,7 +9,7 @@ defineReplace(prependAll) { } LUPDATE = $$QT_BUILD_TREE/bin/lupdate -locations relative -no-ui-lines -win32:isEmpty(QMAKE_SH):LUPDATE ~= s|/|\\|g +LUPDATE ~= s,/,$$QMAKE_DIR_SEP, ###### Qt Libraries diff --git a/translations/translations.pro b/translations/translations.pro index 60f84e6..ef09dc3 100644 --- a/translations/translations.pro +++ b/translations/translations.pro @@ -1,7 +1,7 @@ TRANSLATIONS = $$files(*.ts) LRELEASE = $$QT_BUILD_TREE/bin/lrelease -win32:isEmpty(QMAKE_SH):LRELEASE ~= s|/|\\|g +LRELEASE ~= s,/,$$QMAKE_DIR_SEP, contains(TEMPLATE_PREFIX, vc):vcproj = 1 diff --git a/util/s60pixelmetrics/pixel_metrics.cpp b/util/s60pixelmetrics/pixel_metrics.cpp index 9507c67..9ba6c8b 100644 --- a/util/s60pixelmetrics/pixel_metrics.cpp +++ b/util/s60pixelmetrics/pixel_metrics.cpp @@ -812,13 +812,12 @@ TInt PixelMetrics::PixelMetricValue(QStyle::PixelMetric metric) value = PixelMetricMenuValue(metric, mainPaneRect); break; case QStyle::PM_ButtonIconSize: + { //lets use voice recorder icons as a base //Unfortunately S60 graphics don't separate button bevel graphics from the actual icon. //Se we have no means to query the margin from bevel border to "central icon" border. //So, we need to make a estimate... - const TInt varietyForButtons = !landscape ? 0 : 1; - TAknLayoutRect vRMainRect; vRMainRect.LayoutRect( mainPaneRect, AknLayoutScalable_Apps::main_vorec_pane() ); @@ -833,7 +832,7 @@ TInt PixelMetrics::PixelMetricValue(QStyle::PixelMetric metric) // 0.32 is the estimate how much the icon occupies of the button bevel area value = vRButtonCellGraphicsRect.Rect().Width() * 0.32; - + } break; case QStyle::PM_SmallIconSize: { |