summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/dialogs/qcolordialog_mac.mm36
-rw-r--r--src/gui/dialogs/qfiledialog.cpp46
-rw-r--r--src/gui/dialogs/qfiledialog_win.cpp7
-rw-r--r--src/gui/dialogs/qfilesystemmodel.cpp5
-rw-r--r--src/gui/dialogs/qfilesystemmodel_p.h16
-rw-r--r--src/gui/dialogs/qfontdialog_mac.mm4
-rw-r--r--src/gui/dialogs/qmessagebox.cpp17
-rw-r--r--src/gui/effects/qgraphicseffect.cpp26
-rw-r--r--src/gui/effects/qgraphicseffect_p.h11
-rw-r--r--src/gui/embedded/directfb.pri1
-rw-r--r--src/gui/embedded/qscreen_qws.cpp1
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp31
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp56
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h1
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp30
-rw-r--r--src/gui/graphicsview/qgridlayoutengine.cpp7
-rw-r--r--src/gui/image/qimage.cpp59
-rw-r--r--src/gui/image/qimage.h2
-rw-r--r--src/gui/image/qimagereader.cpp42
-rw-r--r--src/gui/image/qpixmap.cpp9
-rw-r--r--src/gui/image/qpixmap_raster.cpp2
-rw-r--r--src/gui/image/qpixmap_s60.cpp103
-rw-r--r--src/gui/image/qpixmap_s60_p.h6
-rw-r--r--src/gui/image/qpixmap_x11.cpp2
-rw-r--r--src/gui/image/qpixmapfilter.cpp364
-rw-r--r--src/gui/image/qpnghandler.cpp7
-rw-r--r--src/gui/image/qppmhandler.cpp2
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp3
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp28
-rw-r--r--src/gui/itemviews/qabstractitemview_p.h1
-rw-r--r--src/gui/itemviews/qsortfilterproxymodel.cpp34
-rw-r--r--src/gui/itemviews/qtableview.cpp14
-rw-r--r--src/gui/kernel/kernel.pri1
-rw-r--r--src/gui/kernel/qapplication.cpp54
-rw-r--r--src/gui/kernel/qapplication_s60.cpp170
-rw-r--r--src/gui/kernel/qboxlayout.cpp6
-rw-r--r--src/gui/kernel/qcocoasharedwindowmethods_mac_p.h41
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm11
-rw-r--r--src/gui/kernel/qevent.cpp8
-rw-r--r--src/gui/kernel/qeventdispatcher_mac.mm415
-rw-r--r--src/gui/kernel/qeventdispatcher_mac_p.h11
-rw-r--r--src/gui/kernel/qgesturemanager.cpp42
-rw-r--r--src/gui/kernel/qgesturemanager_p.h4
-rw-r--r--src/gui/kernel/qguieventdispatcher_glib.cpp2
-rw-r--r--src/gui/kernel/qt_s60_p.h14
-rw-r--r--src/gui/kernel/qwidget.cpp25
-rw-r--r--src/gui/kernel/qwidget_mac.mm60
-rw-r--r--src/gui/kernel/qwidget_x11.cpp2
-rw-r--r--src/gui/mac/qt_menu.nib/classes.nib16
-rw-r--r--src/gui/mac/qt_menu.nib/info.nib4
-rw-r--r--src/gui/mac/qt_menu.nib/keyedobjects.nibbin5567 -> 5560 bytes
-rw-r--r--src/gui/painting/painting.pri7
-rw-r--r--src/gui/painting/qbezier.cpp20
-rw-r--r--src/gui/painting/qblendfunctions.cpp2
-rw-r--r--src/gui/painting/qdrawhelper.cpp33
-rw-r--r--src/gui/painting/qdrawhelper_neon.cpp260
-rw-r--r--src/gui/painting/qdrawhelper_neon_p.h76
-rw-r--r--src/gui/painting/qemulationpaintengine.cpp30
-rw-r--r--src/gui/painting/qmemrotate.cpp21
-rw-r--r--src/gui/painting/qmemrotate_p.h2
-rw-r--r--src/gui/painting/qpainter.cpp2
-rw-r--r--src/gui/painting/qpathclipper.cpp2
-rw-r--r--src/gui/painting/qstroker.cpp4
-rw-r--r--src/gui/painting/qwindowsurface_s60.cpp8
-rw-r--r--src/gui/statemachine/qguistatemachine.cpp2
-rw-r--r--src/gui/styles/qcommonstyle.cpp2
-rw-r--r--src/gui/styles/qmacstyle_mac.mm12
-rw-r--r--src/gui/styles/qs60style.cpp330
-rw-r--r--src/gui/styles/qs60style_p.h11
-rw-r--r--src/gui/styles/qs60style_s60.cpp138
-rw-r--r--src/gui/styles/qs60style_simulated.cpp5
-rw-r--r--src/gui/styles/qstylehelper.cpp2
-rw-r--r--src/gui/styles/qstylesheetstyle.cpp6
-rw-r--r--src/gui/text/qfontdatabase.cpp14
-rw-r--r--src/gui/text/qfontdatabase_win.cpp1
-rw-r--r--src/gui/text/qfontengine_mac.mm8
-rw-r--r--src/gui/text/qtextcontrol.cpp6
-rw-r--r--src/gui/text/qtextcursor.cpp55
-rw-r--r--src/gui/text/qtextodfwriter.cpp13
-rw-r--r--src/gui/util/qdesktopservices_win.cpp14
-rw-r--r--src/gui/util/qsystemtrayicon_p.h1
-rw-r--r--src/gui/util/qsystemtrayicon_win.cpp21
-rw-r--r--src/gui/widgets/qabstractspinbox.cpp65
-rw-r--r--src/gui/widgets/qabstractspinbox_p.h3
-rw-r--r--src/gui/widgets/qcocoamenu_mac_p.h4
-rw-r--r--src/gui/widgets/qcombobox.cpp5
-rw-r--r--src/gui/widgets/qdial.cpp3
-rw-r--r--src/gui/widgets/qfocusframe.cpp91
-rw-r--r--src/gui/widgets/qlineedit.cpp6
-rw-r--r--src/gui/widgets/qlineedit.h1
-rw-r--r--src/gui/widgets/qlineedit_p.cpp20
-rw-r--r--src/gui/widgets/qlineedit_p.h2
-rw-r--r--src/gui/widgets/qmainwindow.h2
-rw-r--r--src/gui/widgets/qmainwindowlayout_mac.mm3
-rw-r--r--src/gui/widgets/qmdiarea.cpp16
-rw-r--r--src/gui/widgets/qmenu_mac.mm20
-rw-r--r--src/gui/widgets/qplaintextedit.cpp1
-rw-r--r--src/gui/widgets/qtextedit.cpp2
98 files changed, 2258 insertions, 953 deletions
diff --git a/src/gui/dialogs/qcolordialog_mac.mm b/src/gui/dialogs/qcolordialog_mac.mm
index 53d2e1e..a350be1 100644
--- a/src/gui/dialogs/qcolordialog_mac.mm
+++ b/src/gui/dialogs/qcolordialog_mac.mm
@@ -79,6 +79,7 @@ QT_USE_NAMESPACE
BOOL mHackedPanel;
NSInteger mResultCode;
BOOL mDialogIsExecuting;
+ BOOL mResultSet;
}
- (id)initWithColorPanel:(NSColorPanel *)panel
stolenContentView:(NSView *)stolenContentView
@@ -116,6 +117,7 @@ QT_USE_NAMESPACE
mHackedPanel = (okButton != 0);
mResultCode = NSCancelButton;
mDialogIsExecuting = false;
+ mResultSet = false;
if (mHackedPanel) {
[self relayout];
@@ -159,11 +161,13 @@ QT_USE_NAMESPACE
- (BOOL)windowShouldClose:(id)window
{
Q_UNUSED(window);
- if (mHackedPanel) {
- [self onCancelClicked];
- } else {
+ if (!mHackedPanel)
[self updateQtColor];
+ if (mDialogIsExecuting) {
[self finishOffWithCode:NSCancelButton];
+ } else {
+ mResultSet = true;
+ mPriv->colorDialog()->reject();
}
return true;
}
@@ -240,11 +244,12 @@ QT_USE_NAMESPACE
- (void)onCancelClicked
{
- Q_ASSERT(mHackedPanel);
- [[mStolenContentView window] close];
- delete mQtColor;
- mQtColor = new QColor();
- [self finishOffWithCode:NSCancelButton];
+ if (mHackedPanel) {
+ [[mStolenContentView window] close];
+ delete mQtColor;
+ mQtColor = new QColor();
+ [self finishOffWithCode:NSCancelButton];
+ }
}
- (void)updateQtColor
@@ -306,10 +311,16 @@ QT_USE_NAMESPACE
} else {
// Since we are not in a modal event loop, we can safely close
// down QColorDialog
- if (mResultCode == NSCancelButton)
- mPriv->colorDialog()->reject();
- else
- mPriv->colorDialog()->accept();
+ // Calling accept() or reject() can in turn call closeCocoaColorPanel.
+ // This check will prevent any such recursion.
+ if (!mResultSet) {
+ mResultSet = true;
+ if (mResultCode == NSCancelButton) {
+ mPriv->colorDialog()->reject();
+ } else {
+ mPriv->colorDialog()->accept();
+ }
+ }
}
}
@@ -336,6 +347,7 @@ QT_USE_NAMESPACE
}
}
+ QAbstractEventDispatcher::instance()->interrupt();
if (mResultCode == NSCancelButton)
mPriv->colorDialog()->reject();
else
diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp
index 45a410f..3c388de 100644
--- a/src/gui/dialogs/qfiledialog.cpp
+++ b/src/gui/dialogs/qfiledialog.cpp
@@ -669,6 +669,9 @@ void QFileDialog::setOptions(Options options)
}
if (changed & HideNameFilterDetails)
setNameFilters(d->nameFilters);
+
+ if (changed & ShowDirsOnly)
+ setFilter((options & ShowDirsOnly) ? filter() & ~QDir::Files : filter() | QDir::Files);
}
QFileDialog::Options QFileDialog::options() const
@@ -995,6 +998,24 @@ bool QFileDialog::isNameFilterDetailsVisible() const
}
+/*
+ Strip the filters by removing the details, e.g. (*.*).
+*/
+QStringList qt_strip_filters(const QStringList &filters)
+{
+ QStringList strippedFilters;
+ QRegExp r(QString::fromLatin1(qt_file_dialog_filter_reg_exp));
+ for (int i = 0; i < filters.count(); ++i) {
+ QString filterName;
+ int index = r.indexIn(filters[i]);
+ if (index >= 0)
+ filterName = r.cap(1);
+ strippedFilters.append(filterName.simplified());
+ }
+ return strippedFilters;
+}
+
+
/*!
\since 4.4
@@ -1021,20 +1042,11 @@ void QFileDialog::setNameFilters(const QStringList &filters)
if (cleanedFilters.isEmpty())
return;
- if (testOption(HideNameFilterDetails)) {
- QStringList strippedFilters;
- QRegExp r(QString::fromLatin1(qt_file_dialog_filter_reg_exp));
- for (int i = 0; i < cleanedFilters.count(); ++i) {
- QString filterName;
- int index = r.indexIn(cleanedFilters[i]);
- if (index >= 0)
- filterName = r.cap(1);
- strippedFilters.append(filterName.simplified());
- }
- d->qFileDialogUi->fileTypeCombo->addItems(strippedFilters);
- } else {
+ if (testOption(HideNameFilterDetails))
+ d->qFileDialogUi->fileTypeCombo->addItems(qt_strip_filters(cleanedFilters));
+ else
d->qFileDialogUi->fileTypeCombo->addItems(cleanedFilters);
- }
+
d->_q_useNameFilter(0);
}
@@ -1085,8 +1097,12 @@ void QFileDialog::selectNameFilter(const QString &filter)
d->selectNameFilter_sys(filter);
return;
}
-
- int i = d->qFileDialogUi->fileTypeCombo->findText(filter);
+ int i;
+ if (testOption(HideNameFilterDetails)) {
+ i = d->qFileDialogUi->fileTypeCombo->findText(qt_strip_filters(qt_make_filter_list(filter)).first());
+ } else {
+ i = d->qFileDialogUi->fileTypeCombo->findText(filter);
+ }
if (i >= 0) {
d->qFileDialogUi->fileTypeCombo->setCurrentIndex(i);
d->_q_useNameFilter(d->qFileDialogUi->fileTypeCombo->currentIndex());
diff --git a/src/gui/dialogs/qfiledialog_win.cpp b/src/gui/dialogs/qfiledialog_win.cpp
index c74f622..6128a8a 100644
--- a/src/gui/dialogs/qfiledialog_win.cpp
+++ b/src/gui/dialogs/qfiledialog_win.cpp
@@ -85,11 +85,6 @@ static const CLSID QT_CLSID_FileOpenDialog = {0xdc1c5a9c, 0xe88a, 0x4dde, {0xa5,
#endif
-// Don't remove the lines below!
-//
-// resolving the W methods manually is needed, because Windows 95 doesn't include
-// these methods in Shell32.lib (not even stubs!), so you'd get an unresolved symbol
-// when Qt calls getExistingDirectory(), etc.
typedef LPITEMIDLIST (WINAPI *PtrSHBrowseForFolder)(BROWSEINFO*);
static PtrSHBrowseForFolder ptrSHBrowseForFolder = 0;
typedef BOOL (WINAPI *PtrSHGetPathFromIDList)(LPITEMIDLIST,LPWSTR);
@@ -125,7 +120,7 @@ static void qt_win_resolve_libs()
ptrSHGetMalloc = (PtrSHGetMalloc) lib.resolve("SHGetMalloc");
#else
// CE stores them in a different lib and does not use unicode version
- HINSTANCE handle = LoadLibraryW(L"Ceshell");
+ HINSTANCE handle = LoadLibrary(L"Ceshell");
ptrSHBrowseForFolder = (PtrSHBrowseForFolder)GetProcAddress(handle, L"SHBrowseForFolder");
ptrSHGetPathFromIDList = (PtrSHGetPathFromIDList)GetProcAddress(handle, L"SHGetPathFromIDList");
ptrSHGetMalloc = (PtrSHGetMalloc)GetProcAddress(handle, L"SHGetMalloc");
diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/gui/dialogs/qfilesystemmodel.cpp
index 8e78503..6ec80a9 100644
--- a/src/gui/dialogs/qfilesystemmodel.cpp
+++ b/src/gui/dialogs/qfilesystemmodel.cpp
@@ -1223,8 +1223,7 @@ bool QFileSystemModel::dropMimeData(const QMimeData *data, Qt::DropAction action
case Qt::MoveAction:
for (; it != urls.constEnd(); ++it) {
QString path = (*it).toLocalFile();
- success = QFile::copy(path, to + QFileInfo(path).fileName())
- && QFile::remove(path) && success;
+ success = QFile::rename(path, to + QFileInfo(path).fileName()) && success;
}
break;
default:
@@ -1779,7 +1778,7 @@ void QFileSystemModelPrivate::_q_fileSystemChanged(const QString &path, const QL
node->fileName = fileName;
}
- if (info.size() == -1) {
+ if (info.size() == -1 && !info.isSymLink()) {
removeNode(parentNode, fileName);
continue;
}
diff --git a/src/gui/dialogs/qfilesystemmodel_p.h b/src/gui/dialogs/qfilesystemmodel_p.h
index 175159f..68e19dc 100644
--- a/src/gui/dialogs/qfilesystemmodel_p.h
+++ b/src/gui/dialogs/qfilesystemmodel_p.h
@@ -238,15 +238,15 @@ public:
void sortChildren(int column, const QModelIndex &parent);
inline int translateVisibleLocation(QFileSystemNode *parent, int row) const {
- if (sortOrder == Qt::AscendingOrder)
- return row;
- if (parent->dirtyChildrenIndex == -1 || row < parent->dirtyChildrenIndex)
- if (parent->dirtyChildrenIndex != -1)
- return parent->dirtyChildrenIndex - row - 1;
- else
+ if (sortOrder != Qt::AscendingOrder) {
+ if (parent->dirtyChildrenIndex == -1)
return parent->visibleChildren.count() - row - 1;
- else
- return row;
+
+ if (row < parent->dirtyChildrenIndex)
+ return parent->dirtyChildrenIndex - row - 1;
+ }
+
+ return row;
}
inline static QString myComputer() {
diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm
index 0c467cd..31bab2b 100644
--- a/src/gui/dialogs/qfontdialog_mac.mm
+++ b/src/gui/dialogs/qfontdialog_mac.mm
@@ -394,7 +394,9 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
}
[mFontPanel setDelegate:nil];
[[NSFontManager sharedFontManager] setDelegate:nil];
+#ifdef QT_MAC_USE_COCOA
[[NSFontManager sharedFontManager] setTarget:nil];
+#endif
}
@end
@@ -518,7 +520,9 @@ void *QFontDialogPrivate::openCocoaFontPanel(const QFont &initial,
extraHeight:dialogExtraHeight];
[ourPanel setDelegate:delegate];
[[NSFontManager sharedFontManager] setDelegate:delegate];
+#ifdef QT_MAC_USE_COCOA
[[NSFontManager sharedFontManager] setTarget:delegate];
+#endif
setFont(delegate, initial);
// hack to get correct initial layout
diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp
index a318c43..8ec8d1c 100644
--- a/src/gui/dialogs/qmessagebox.cpp
+++ b/src/gui/dialogs/qmessagebox.cpp
@@ -188,6 +188,9 @@ public:
bool autoAddOkButton;
QAbstractButton *detectedEscapeButton;
QLabel *informativeLabel;
+#ifdef Q_OS_SYMBIAN
+ QTextEdit *textEdit;
+#endif
QPointer<QObject> receiverToDisconnectOnClose;
QByteArray memberToDisconnectOnClose;
QByteArray signalToDisconnectOnClose;
@@ -2459,10 +2462,24 @@ void QMessageBox::setInformativeText(const QString &text)
#endif
label->setWordWrap(true);
QGridLayout *grid = static_cast<QGridLayout *>(layout());
+#ifdef Q_OS_SYMBIAN
+ label->hide();
+ QTextEdit *textEdit = new QTextEdit(this);
+ textEdit->setReadOnly(true);
+ grid->addWidget(textEdit, 1, 1, 1, 1);
+ d->textEdit = textEdit;
+#else
grid->addWidget(label, 1, 1, 1, 1);
+#endif
d->informativeLabel = label;
}
d->informativeLabel->setText(text);
+
+#ifdef Q_OS_SYMBIAN
+ //We need to put the informative label inside textEdit to enable scrolling of long texts.
+ d->textEdit->setText(d->informativeLabel->text());
+#endif
+
d->updateSize();
}
diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp
index d6cabaa..a523bab 100644
--- a/src/gui/effects/qgraphicseffect.cpp
+++ b/src/gui/effects/qgraphicseffect.cpp
@@ -313,7 +313,10 @@ QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offse
// Shortcut, no cache for childless pixmap items...
const QGraphicsItem *item = graphicsItem();
if (system == Qt::LogicalCoordinates && mode == QGraphicsEffect::NoPad && item && isPixmap()) {
- return ((QGraphicsPixmapItem *) item)->pixmap();
+ const QGraphicsPixmapItem *pixmapItem = static_cast<const QGraphicsPixmapItem *>(item);
+ if (offset)
+ *offset = pixmapItem->offset().toPoint();
+ return pixmapItem->pixmap();
}
if (system == Qt::DeviceCoordinates && item
@@ -371,10 +374,14 @@ QGraphicsEffectSourcePrivate::~QGraphicsEffectSourcePrivate()
invalidateCache();
}
-void QGraphicsEffectSourcePrivate::invalidateCache(bool effectRectChanged) const
+void QGraphicsEffectSourcePrivate::invalidateCache(InvalidateReason reason) const
{
- if (effectRectChanged && m_cachedMode != QGraphicsEffect::PadToEffectiveBoundingRect)
+ if (m_cachedMode != QGraphicsEffect::PadToEffectiveBoundingRect
+ && (reason == EffectRectChanged
+ || reason == TransformChanged
+ && m_cachedSystem == Qt::LogicalCoordinates))
return;
+
QPixmapCache::remove(m_cacheKey);
}
@@ -520,7 +527,7 @@ void QGraphicsEffect::updateBoundingRect()
Q_D(QGraphicsEffect);
if (d->source) {
d->source->d_func()->effectBoundingRectChanged();
- d->source->d_func()->invalidateCache(true);
+ d->source->d_func()->invalidateCache(QGraphicsEffectSourcePrivate::EffectRectChanged);
}
}
@@ -837,22 +844,19 @@ QRectF QGraphicsBlurEffect::boundingRectFor(const QRectF &rect) const
void QGraphicsBlurEffect::draw(QPainter *painter)
{
Q_D(QGraphicsBlurEffect);
- if (d->filter->radius() <= 0) {
+ if (d->filter->radius() < 1) {
drawSource(painter);
return;
}
PixmapPadMode mode = PadToEffectiveBoundingRect;
if (painter->paintEngine()->type() == QPaintEngine::OpenGL2)
- mode = PadToTransparentBorder;
+ mode = NoPad;
// Draw pixmap in device coordinates to avoid pixmap scaling.
QPoint offset;
- const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, mode);
- QTransform restoreTransform = painter->worldTransform();
- painter->setWorldTransform(QTransform());
+ QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, mode);
d->filter->draw(painter, offset, pixmap);
- painter->setWorldTransform(restoreTransform);
}
/*!
@@ -1033,7 +1037,7 @@ void QGraphicsDropShadowEffect::draw(QPainter *painter)
PixmapPadMode mode = PadToEffectiveBoundingRect;
if (painter->paintEngine()->type() == QPaintEngine::OpenGL2)
- mode = PadToTransparentBorder;
+ mode = NoPad;
// Draw pixmap in device coordinates to avoid pixmap scaling.
QPoint offset;
diff --git a/src/gui/effects/qgraphicseffect_p.h b/src/gui/effects/qgraphicseffect_p.h
index 0011eef..cab7a48 100644
--- a/src/gui/effects/qgraphicseffect_p.h
+++ b/src/gui/effects/qgraphicseffect_p.h
@@ -108,6 +108,13 @@ public:
, m_cachedMode(QGraphicsEffect::PadToTransparentBorder)
{}
+ enum InvalidateReason
+ {
+ TransformChanged,
+ EffectRectChanged,
+ SourceChanged
+ };
+
virtual ~QGraphicsEffectSourcePrivate();
virtual void detach() = 0;
virtual QRectF boundingRect(Qt::CoordinateSystem system) const = 0;
@@ -121,7 +128,9 @@ public:
virtual QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset = 0,
QGraphicsEffect::PixmapPadMode mode = QGraphicsEffect::PadToTransparentBorder) const = 0;
virtual void effectBoundingRectChanged() = 0;
- void invalidateCache(bool effectRectChanged = false) const;
+
+ void invalidateCache(InvalidateReason reason = SourceChanged) const;
+ Qt::CoordinateSystem currentCachedSystem() const { return m_cachedSystem; }
friend class QGraphicsScenePrivate;
friend class QGraphicsItem;
diff --git a/src/gui/embedded/directfb.pri b/src/gui/embedded/directfb.pri
index 84253b5..bd1d947 100644
--- a/src/gui/embedded/directfb.pri
+++ b/src/gui/embedded/directfb.pri
@@ -14,6 +14,7 @@
#DEFINES += QT_NO_DIRECTFB_KEYBOARD
#DEFINES += QT_DIRECTFB_TIMING
#DEFINES += QT_NO_DIRECTFB_OPAQUE_DETECTION
+#DEFINES += QT_NO_DIRECTFB_STRETCHBLIT
#DIRECTFB_DRAWINGOPERATIONS=DRAW_RECTS|DRAW_LINES|DRAW_IMAGE|DRAW_PIXMAP|DRAW_TILED_PIXMAP|STROKE_PATH|DRAW_PATH|DRAW_POINTS|DRAW_ELLIPSE|DRAW_POLYGON|DRAW_TEXT|FILL_PATH|FILL_RECT|DRAW_COLORSPANS|DRAW_ROUNDED_RECT
#DEFINES += \"QT_DIRECTFB_WARN_ON_RASTERFALLBACKS=$$DIRECTFB_DRAWINGOPERATIONS\"
#DEFINES += \"QT_DIRECTFB_DISABLE_RASTERFALLBACKS=$$DIRECTFB_DRAWINGOPERATIONS\"
diff --git a/src/gui/embedded/qscreen_qws.cpp b/src/gui/embedded/qscreen_qws.cpp
index ae5570f..07bb258 100644
--- a/src/gui/embedded/qscreen_qws.cpp
+++ b/src/gui/embedded/qscreen_qws.cpp
@@ -3150,6 +3150,7 @@ int QScreen::subScreenIndexAt(const QPoint &p) const
#if 0
#ifdef QT_LOADABLE_MODULES
+#include <dlfcn.h>
// ### needs update after driver init changes
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index d955f16..726d571 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -2181,7 +2181,7 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
}
// Enable subfocus
- if (newVisible) {
+ if (scene && newVisible) {
QGraphicsItem *p = parent;
bool done = false;
while (p) {
@@ -7177,9 +7177,16 @@ void QGraphicsItem::prepareGeometryChange()
QGraphicsItem *parent = this;
while ((parent = parent->d_ptr->parent)) {
- parent->d_ptr->dirtyChildrenBoundingRect = 1;
+ QGraphicsItemPrivate *parentp = parent->d_ptr.data();
+ parentp->dirtyChildrenBoundingRect = 1;
// ### Only do this if the parent's effect applies to the entire subtree.
- parent->d_ptr->notifyBoundingRectChanged = 1;
+ parentp->notifyBoundingRectChanged = 1;
+#ifndef QT_NO_GRAPHICSEFFECT
+ if (parentp->scene && parentp->graphicsEffect) {
+ parentp->notifyInvalidated = 1;
+ static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()->source->d_func())->invalidateCache();
+ }
+#endif
}
}
@@ -10717,7 +10724,6 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP
qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
return QPixmap();
}
-
if (!item->d_ptr->scene)
return QPixmap();
QGraphicsScenePrivate *scened = item->d_ptr->scene->d_func();
@@ -10725,9 +10731,11 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP
const QRectF sourceRect = boundingRect(system);
QRectF effectRectF;
+ bool unpadded = false;
if (mode == QGraphicsEffect::PadToEffectiveBoundingRect) {
if (info) {
effectRectF = item->graphicsEffect()->boundingRectFor(boundingRect(Qt::DeviceCoordinates));
+ unpadded = (effectRectF.size() == sourceRect.size());
if (info && system == Qt::LogicalCoordinates)
effectRectF = info->painter->worldTransform().inverted().mapRect(effectRectF);
} else {
@@ -10739,6 +10747,7 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP
effectRectF = sourceRect.adjusted(-1.5, -1.5, 1.5, 1.5);
} else {
effectRectF = sourceRect;
+ unpadded = true;
}
QRect effectRect = effectRectF.toAlignedRect();
@@ -10746,6 +10755,14 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP
if (offset)
*offset = effectRect.topLeft();
+ bool untransformed = !deviceCoordinates
+ || info->painter->worldTransform().type() <= QTransform::TxTranslate;
+ if (untransformed && unpadded && isPixmap()) {
+ if (offset)
+ *offset = boundingRect(system).topLeft().toPoint();
+ return static_cast<QGraphicsPixmapItem *>(item)->pixmap();
+ }
+
if (deviceCoordinates) {
// Clip to viewport rect.
int left, top, right, bottom;
@@ -10773,12 +10790,6 @@ QPixmap QGraphicsItemEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QP
if (effectRect.isEmpty())
return QPixmap();
- if (system == Qt::LogicalCoordinates
- && effectRect.size() == sourceRect.size()
- && isPixmap()) {
- return static_cast<QGraphicsPixmapItem *>(item)->pixmap();
- }
-
QPixmap pixmap(effectRect.size());
pixmap.fill(Qt::transparent);
QPainter pixmapPainter(&pixmap);
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index b1c1ea0..1fc5a2e 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -292,6 +292,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
processDirtyItemsEmitted(false),
selectionChanging(0),
needSortTopLevelItems(true),
+ unpolishedItemsModified(true),
holesInTopLevelSiblingIndex(false),
topLevelSequentialOrdering(true),
scenePosDescendantsUpdatePending(false),
@@ -428,12 +429,12 @@ void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item)
*/
void QGraphicsScenePrivate::_q_polishItems()
{
- QSet<QGraphicsItem *>::Iterator it;
+ QSet<QGraphicsItem *>::Iterator it = unpolishedItems.begin();
const QVariant booleanTrueVariant(true);
while (!unpolishedItems.isEmpty()) {
- it = unpolishedItems.begin();
QGraphicsItem *item = *it;
- unpolishedItems.erase(it);
+ it = unpolishedItems.erase(it);
+ unpolishedItemsModified = false;
if (!item->d_ptr->explicitlyHidden) {
item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant);
item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant);
@@ -442,6 +443,8 @@ void QGraphicsScenePrivate::_q_polishItems()
QEvent event(QEvent::Polish);
QApplication::sendEvent((QGraphicsWidget *)item, &event);
}
+ if (unpolishedItemsModified)
+ it = unpolishedItems.begin();
}
}
@@ -636,6 +639,7 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
hoverItems.removeAll(item);
cachedItemsUnderMouse.removeAll(item);
unpolishedItems.remove(item);
+ unpolishedItemsModified = true;
resetDirtyItem(item);
//We remove all references of item from the sceneEventFilter arrays
@@ -1561,7 +1565,10 @@ QGraphicsScene::QGraphicsScene(qreal x, qreal y, qreal width, qreal height, QObj
}
/*!
- Destroys the QGraphicsScene object.
+ Removes and deletes all items from the scene object
+ before destroying the scene object. The scene object
+ is removed from the application's global scene list,
+ and it is removed from all associated views.
*/
QGraphicsScene::~QGraphicsScene()
{
@@ -2443,23 +2450,26 @@ void QGraphicsScene::destroyItemGroup(QGraphicsItemGroup *group)
}
/*!
- Adds or moves the item \a item and all its childen to the scene.
+ Adds or moves the \a item and all its childen to this scene.
+ This scene takes ownership of the \a item.
If the item is visible (i.e., QGraphicsItem::isVisible() returns
true), QGraphicsScene will emit changed() once control goes back
to the event loop.
- If the item is already in a different scene, it will first be removed from
- its old scene, and then added to this scene as a top-level.
+ If the item is already in a different scene, it will first be
+ removed from its old scene, and then added to this scene as a
+ top-level.
- QGraphicsScene will send ItemSceneChange notifications to \a item while
- it is added to the scene. If item does not currently belong to a scene, only one
- notification is sent. If it does belong to scene already (i.e., it is
- moved to this scene), QGraphicsScene will send an addition notification as
- the item is removed from its previous scene.
+ QGraphicsScene will send ItemSceneChange notifications to \a item
+ while it is added to the scene. If item does not currently belong
+ to a scene, only one notification is sent. If it does belong to
+ scene already (i.e., it is moved to this scene), QGraphicsScene
+ will send an addition notification as the item is removed from its
+ previous scene.
- If the item is a panel, the scene is active, and there is no active panel
- in the scene, then the item will be activated.
+ If the item is a panel, the scene is active, and there is no
+ active panel in the scene, then the item will be activated.
\sa removeItem(), addEllipse(), addLine(), addPath(), addPixmap(),
addRect(), addText(), addWidget(), {QGraphicsItem#Sorting}{Sorting}
@@ -2571,9 +2581,10 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
item->d_ptr->resolveFont(d->font.resolve());
item->d_ptr->resolvePalette(d->palette.resolve());
- if (d->unpolishedItems.isEmpty())
- QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection);
- d->unpolishedItems.insert(item);
+ if (d->unpolishedItems.isEmpty())
+ QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection);
+ d->unpolishedItems.insert(item);
+ d->unpolishedItemsModified = true;
// Reenable selectionChanged() for individual items
--d->selectionChanging;
@@ -4673,10 +4684,13 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
painter->setWorldTransform(*transformPtr);
painter->setOpacity(opacity);
- if (sourced->lastEffectTransform != painter->worldTransform()) {
+ if (sourced->currentCachedSystem() != Qt::LogicalCoordinates
+ && sourced->lastEffectTransform != painter->worldTransform())
+ {
sourced->lastEffectTransform = painter->worldTransform();
- sourced->invalidateCache();
+ sourced->invalidateCache(QGraphicsEffectSourcePrivate::TransformChanged);
}
+
item->d_ptr->graphicsEffect->draw(painter);
painter->setWorldTransform(restoreTransform);
sourced->info = 0;
@@ -5088,6 +5102,10 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool
\snippet doc/src/snippets/graphicssceneadditemsnippet.cpp 0
+ \obsolete Since Qt 4.6, this function is not called anymore unless
+ the QGraphicsView::IndirectPainting flag is given as an Optimization
+ flag.
+
\sa drawBackground(), drawForeground()
*/
void QGraphicsScene::drawItems(QPainter *painter,
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 69e4d5b..f6ec0aa 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -111,6 +111,7 @@ public:
QSet<QGraphicsItem *> unpolishedItems;
QList<QGraphicsItem *> topLevelItems;
bool needSortTopLevelItems;
+ bool unpolishedItemsModified;
bool holesInTopLevelSiblingIndex;
bool topLevelSequentialOrdering;
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index ffe64aa..c8f2c7c 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -217,7 +217,9 @@ static const int QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS = 503; // largest prime <
common side effect is that items that do draw with antialiasing can leave
painting traces behind on the scene as they are moved.
- \omitvalue IndirectPainting
+ \value IndirectPainting Since Qt 4.6, restore the old painting algorithm
+ that calls QGraphicsView::drawItems() and QGraphicsScene::drawItems().
+ To be used only for compatibility with old code.
*/
/*!
@@ -1208,6 +1210,11 @@ void QGraphicsView::setTransformationAnchor(ViewportAnchor anchor)
{
Q_D(QGraphicsView);
d->transformationAnchor = anchor;
+
+ // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse
+ // in order to have up-to-date information for centering the view.
+ if (d->transformationAnchor == AnchorUnderMouse)
+ d->viewport->setMouseTracking(true);
}
/*!
@@ -1235,6 +1242,11 @@ void QGraphicsView::setResizeAnchor(ViewportAnchor anchor)
{
Q_D(QGraphicsView);
d->resizeAnchor = anchor;
+
+ // Ensure mouse tracking is enabled in the case we are using AnchorUnderMouse
+ // in order to have up-to-date information for centering the view.
+ if (d->resizeAnchor == AnchorUnderMouse)
+ d->viewport->setMouseTracking(true);
}
/*!
@@ -2597,9 +2609,12 @@ void QGraphicsView::setupViewport(QWidget *widget)
}
// We are only interested in mouse tracking if items
- // accept hover events or use non-default cursors.
- if (d->scene && (!d->scene->d_func()->allItemsIgnoreHoverEvents
- || !d->scene->d_func()->allItemsUseDefaultCursor)) {
+ // accept hover events or use non-default cursors or if
+ // AnchorUnderMouse is used as transformation or resize anchor.
+ if ((d->scene && (!d->scene->d_func()->allItemsIgnoreHoverEvents
+ || !d->scene->d_func()->allItemsUseDefaultCursor))
+ || d->transformationAnchor == AnchorUnderMouse
+ || d->resizeAnchor == AnchorUnderMouse) {
widget->setMouseTracking(true);
}
@@ -3352,7 +3367,8 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
#define X11 qt_x11Data
#endif
backgroundPainter.setCompositionMode(QPainter::CompositionMode_Source);
- drawBackground(&backgroundPainter, exposedSceneRect);
+ QRectF backgroundExposedSceneRect = mapToScene(d->backgroundPixmapExposed.boundingRect()).boundingRect();
+ drawBackground(&backgroundPainter, backgroundExposedSceneRect);
d->backgroundPixmapExposed = QRegion();
}
@@ -3602,6 +3618,10 @@ void QGraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
The default implementation calls the scene's drawItems() function.
+ \obsolete Since Qt 4.6, this function is not called anymore unless
+ the QGraphicsView::IndirectPainting flag is given as an Optimization
+ flag.
+
\sa drawForeground(), drawBackground(), QGraphicsScene::drawItems()
*/
void QGraphicsView::drawItems(QPainter *painter, int numItems,
diff --git a/src/gui/graphicsview/qgridlayoutengine.cpp b/src/gui/graphicsview/qgridlayoutengine.cpp
index f61360a..1fece7a 100644
--- a/src/gui/graphicsview/qgridlayoutengine.cpp
+++ b/src/gui/graphicsview/qgridlayoutengine.cpp
@@ -51,6 +51,7 @@
#include "qvarlengtharray.h"
#include <QtDebug>
+#include <QtCore/qmath.h>
QT_BEGIN_NAMESPACE
@@ -70,7 +71,7 @@ static void insertOrRemoveItems(QVector<T> &items, int index, int delta)
static qreal growthFactorBelowPreferredSize(qreal desired, qreal sumAvailable, qreal sumDesired)
{
Q_ASSERT(sumDesired != 0.0);
- return desired * ::pow(sumAvailable / sumDesired, desired / sumDesired);
+ return desired * qPow(sumAvailable / sumDesired, desired / sumDesired);
}
static qreal fixedDescent(qreal descent, qreal ascent, qreal targetSize)
@@ -181,9 +182,9 @@ void QGridLayoutRowData::distributeMultiCells()
QVarLengthArray<qreal> newSizes(span);
for (int j = 0; j < NSizes; ++j) {
- qreal extra = compare(totalBox, box, j);
+ qreal extra = compare(box, totalBox, j);
if (extra > 0.0) {
- calculateGeometries(start, end, totalBox.q_sizes(j), dummy.data(), newSizes.data(),
+ calculateGeometries(start, end, box.q_sizes(j), dummy.data(), newSizes.data(),
0, totalBox);
for (int k = 0; k < span; ++k)
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index ec8dd88..d857547 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -696,7 +696,9 @@ bool QImageData::checkForAlphaPixels() const
/*!
\enum QImage::Format
- The following image formats are available in all versions of Qt:
+ The following image formats are available in Qt. Values greater
+ than QImage::Format_RGB16 were added in Qt 4.4. See the notes
+ after the table.
\value Format_Invalid The image is invalid.
\value Format_Mono The image is stored using 1-bit per pixel. Bytes are
@@ -705,17 +707,12 @@ bool QImageData::checkForAlphaPixels() const
packed with the less significant bit (LSB) first.
\value Format_Indexed8 The image is stored using 8-bit indexes
- into a colormap. \warning Drawing into a
- QImage with Indexed8 format is not
- supported.
+ into a colormap.
\value Format_RGB32 The image is stored using a 32-bit RGB format (0xffRRGGBB).
\value Format_ARGB32 The image is stored using a 32-bit ARGB
- format (0xAARRGGBB). \warning Do not
- render into ARGB32 images using
- QPainter. Format_ARGB32_Premultiplied is
- significantly faster.
+ format (0xAARRGGBB).
\value Format_ARGB32_Premultiplied The image is stored using a premultiplied 32-bit
ARGB format (0xAARRGGBB), i.e. the red,
@@ -744,6 +741,12 @@ bool QImageData::checkForAlphaPixels() const
\value Format_ARGB4444_Premultiplied The image is stored using a
premultiplied 16-bit ARGB format (4-4-4-4).
+ \note Drawing into a QImage with QImage::Format_Indexed8 is not
+ supported.
+
+ \note Do not render into ARGB32 images using QPainter. Using
+ QImage::Format_ARGB32_Premultiplied is significantly faster.
+
\sa format(), convertToFormat()
*/
@@ -1832,7 +1835,7 @@ void QImage::setColor(int i, QRgb c)
qAlpha() to access the pixels.
\sa bytesPerLine(), bits(), {QImage#Pixel Manipulation}{Pixel
- Manipulation}
+ Manipulation}, constScanLine()
*/
uchar *QImage::scanLine(int i)
{
@@ -1862,6 +1865,28 @@ const uchar *QImage::scanLine(int i) const
/*!
+ Returns a pointer to the pixel data at the scanline with index \a
+ i. The first scanline is at index 0.
+
+ The scanline data is aligned on a 32-bit boundary.
+
+ Note that QImage uses \l{Implicit Data Sharing} {implicit data
+ sharing}, but this function does \e not perform a deep copy of the
+ shared pixel data, because the returned data is const.
+
+ \sa scanLine(), constBits()
+ \since 4.7
+*/
+const uchar *QImage::constScanLine(int i) const
+{
+ if (!d)
+ return 0;
+
+ Q_ASSERT(i >= 0 && i < height());
+ return d->data + i * d->bytes_per_line;
+}
+
+/*!
Returns a pointer to the first pixel data. This is equivalent to
scanLine(0).
@@ -1870,7 +1895,7 @@ const uchar *QImage::scanLine(int i) const
data, thus ensuring that this QImage is the only one using the
current return value.
- \sa scanLine(), byteCount()
+ \sa scanLine(), byteCount(), constBits()
*/
uchar *QImage::bits()
{
@@ -1898,6 +1923,20 @@ const uchar *QImage::bits() const
}
+/*!
+ Returns a pointer to the first pixel data.
+
+ Note that QImage uses \l{Implicit Data Sharing} {implicit data
+ sharing}, but this function does \e not perform a deep copy of the
+ shared pixel data, because the returned data is const.
+
+ \sa bits(), constScanLine()
+ \since 4.7
+*/
+const uchar *QImage::constBits() const
+{
+ return d ? d->data : 0;
+}
/*!
\fn void QImage::reset()
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index ce7f450..4e74c0e 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -182,6 +182,7 @@ public:
uchar *bits();
const uchar *bits() const;
+ const uchar *constBits() const;
#ifdef QT_DEPRECATED
QT_DEPRECATED int numBytes() const;
#endif
@@ -189,6 +190,7 @@ public:
uchar *scanLine(int);
const uchar *scanLine(int) const;
+ const uchar *constScanLine(int) const;
int bytesPerLine() const;
bool valid(int x, int y) const;
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 074f3eb..7580446 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -471,7 +471,6 @@ QImageReaderPrivate::QImageReaderPrivate(QImageReader *qq)
handler = 0;
quality = -1;
imageReaderError = QImageReader::UnknownError;
- errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Unknown error"));
q = qq;
}
@@ -1214,11 +1213,12 @@ bool QImageReader::jumpToImage(int imageNumber)
}
/*!
- For image formats that support animation, this function returns
- the number of times the animation should loop. Otherwise, it
- returns -1.
+ For image formats that support animation, this function returns the number
+ of times the animation should loop. If this function returns -1, it can
+ either mean the animation should loop forever, or that an error occurred.
+ If an error occurred, canRead() will return false.
- \sa supportsAnimation(), QImageIOHandler::loopCount()
+ \sa supportsAnimation(), QImageIOHandler::loopCount(), canRead()
*/
int QImageReader::loopCount() const
{
@@ -1228,13 +1228,13 @@ int QImageReader::loopCount() const
}
/*!
- For image formats that support animation, this function returns
- the total number of images in the animation.
+ For image formats that support animation, this function returns the total
+ number of images in the animation. If the format does not support
+ animation, 0 is returned.
- Certain animation formats do not support this feature, in which
- case 0 is returned.
+ This function returns -1 if an error occurred.
- \sa supportsAnimation(), QImageIOHandler::imageCount()
+ \sa supportsAnimation(), QImageIOHandler::imageCount(), canRead()
*/
int QImageReader::imageCount() const
{
@@ -1244,11 +1244,13 @@ int QImageReader::imageCount() const
}
/*!
- For image formats that support animation, this function returns
- the number of milliseconds to wait until displaying the next frame
- in the animation. Otherwise, 0 is returned.
+ For image formats that support animation, this function returns the number
+ of milliseconds to wait until displaying the next frame in the animation.
+ If the image format doesn't support animation, 0 is returned.
+
+ This function returns -1 if an error occurred.
- \sa supportsAnimation(), QImageIOHandler::nextImageDelay()
+ \sa supportsAnimation(), QImageIOHandler::nextImageDelay(), canRead()
*/
int QImageReader::nextImageDelay() const
{
@@ -1258,11 +1260,13 @@ int QImageReader::nextImageDelay() const
}
/*!
- For image formats that support animation, this function returns
- the sequence number of the current frame. Otherwise, -1 is
- returned.
+ For image formats that support animation, this function returns the
+ sequence number of the current frame. If the image format doesn't support
+ animation, 0 is returned.
+
+ This function returns -1 if an error occurred.
- \sa supportsAnimation(), QImageIOHandler::currentImageNumber()
+ \sa supportsAnimation(), QImageIOHandler::currentImageNumber(), canRead()
*/
int QImageReader::currentImageNumber() const
{
@@ -1302,6 +1306,8 @@ QImageReader::ImageReaderError QImageReader::error() const
*/
QString QImageReader::errorString() const
{
+ if (d->errorString.isEmpty())
+ return QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Unknown error"));
return d->errorString;
}
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 406dc0b..30eb788 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -831,14 +831,13 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers
if (QPixmapCache::find(key, *this))
return true;
- if (!data)
- data = QPixmapData::create(0, 0, QPixmapData::PixmapType);
-
- if (data->fromFile(fileName, format, flags)) {
+ QPixmapData *tmp = QPixmapData::create(0, 0, QPixmapData::PixmapType);
+ if (tmp->fromFile(fileName, format, flags)) {
+ data = tmp;
QPixmapCache::insert(key, *this);
return true;
}
-
+ delete tmp;
return false;
}
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index 1b01e6f..3c1d7e9 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -375,7 +375,7 @@ int QRasterPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
case QPaintDevice::PdmWidthMM:
return qRound(d->width * 25.4 / qt_defaultDpiX());
case QPaintDevice::PdmHeightMM:
- return qRound(d->width * 25.4 / qt_defaultDpiY());
+ return qRound(d->height * 25.4 / qt_defaultDpiY());
case QPaintDevice::PdmNumColors:
return d->colortable.size();
case QPaintDevice::PdmDepth:
diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp
index dc33ade..8194db5 100644
--- a/src/gui/image/qpixmap_s60.cpp
+++ b/src/gui/image/qpixmap_s60.cpp
@@ -235,7 +235,7 @@ static CFbsBitmap* uncompress(CFbsBitmap* bitmap)
QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
bitmapGc->Activate(bitmapDevice);
- bitmapGc->DrawBitmap(TPoint(), bitmap);
+ bitmapGc->BitBlt(TPoint(), bitmap);
delete bitmapGc;
delete bitmapDevice;
@@ -346,8 +346,6 @@ QPixmap QPixmap::fromSymbianCFbsBitmap(CFbsBitmap *bitmap)
QS60PixmapData::QS60PixmapData(PixelType type) : QRasterPixmapData(type),
symbianBitmapDataAccess(new QSymbianBitmapDataAccess),
cfbsBitmap(0),
- bitmapDevice(0),
- bitmapGc(0),
pengine(0),
bytes(0),
formatLocked(false)
@@ -385,8 +383,6 @@ void QS60PixmapData::resize(int width, int height)
if(cfbsBitmap->SizeInPixels() != newSize) {
cfbsBitmap->Resize(TSize(width, height));
- bitmapDevice->Resize(TSize(width, height));
- bitmapGc->Resized();
if(pengine) {
delete pengine;
pengine = 0;
@@ -397,21 +393,10 @@ void QS60PixmapData::resize(int width, int height)
}
}
-bool QS60PixmapData::initSymbianBitmapContext()
-{
- QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(cfbsBitmap));
- QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
- bitmapGc->Activate(bitmapDevice);
-
- return true;
-}
-
void QS60PixmapData::release()
{
if (cfbsBitmap) {
QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
- delete bitmapGc;
- delete bitmapDevice;
delete cfbsBitmap;
lock.relock();
}
@@ -419,8 +404,6 @@ void QS60PixmapData::release()
delete pengine;
image = QImage();
cfbsBitmap = 0;
- bitmapGc = 0;
- bitmapDevice = 0;
pengine = 0;
bytes = 0;
}
@@ -428,42 +411,52 @@ void QS60PixmapData::release()
/*!
* Takes ownership of bitmap. Used by window surface
*/
-void QS60PixmapData::fromSymbianBitmap(CFbsBitmap* bitmap)
+void QS60PixmapData::fromSymbianBitmap(CFbsBitmap* bitmap, bool lockFormat)
{
- cfbsBitmap = bitmap;
- formatLocked = true;
+ Q_ASSERT(bitmap);
- if(!initSymbianBitmapContext()) {
- qWarning("Could not create CBitmapContext");
- release();
- return;
- }
+ release();
+
+ cfbsBitmap = bitmap;
+ formatLocked = lockFormat;
- setSerialNumber(cfbsBitmap->Handle());
+ setSerialNumber(cfbsBitmap->Handle());
- UPDATE_BUFFER();
+ UPDATE_BUFFER();
- // Create default palette if needed
- if (cfbsBitmap->DisplayMode() == EGray2) {
- image.setColorCount(2);
- image.setColor(0, QColor(Qt::color0).rgba());
- image.setColor(1, QColor(Qt::color1).rgba());
+ // Create default palette if needed
+ if (cfbsBitmap->DisplayMode() == EGray2) {
+ image.setColorCount(2);
+ image.setColor(0, QColor(Qt::color0).rgba());
+ image.setColor(1, QColor(Qt::color1).rgba());
//Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
//So invert mono bitmaps so that masks work correctly.
image.invertPixels();
- } else if (cfbsBitmap->DisplayMode() == EGray256) {
- for (int i=0; i < 256; ++i)
- image.setColor(i, qRgb(i, i, i));
- }else if (cfbsBitmap->DisplayMode() == EColor256) {
- const TColor256Util *palette = TColor256Util::Default();
- for (int i=0; i < 256; ++i)
- image.setColor(i, (QRgb)(palette->Color256(i).Value()));
- }
+ } else if (cfbsBitmap->DisplayMode() == EGray256) {
+ for (int i=0; i < 256; ++i)
+ image.setColor(i, qRgb(i, i, i));
+ } else if (cfbsBitmap->DisplayMode() == EColor256) {
+ const TColor256Util *palette = TColor256Util::Default();
+ for (int i=0; i < 256; ++i)
+ image.setColor(i, (QRgb)(palette->Color256(i).Value()));
+ }
+}
+
+QImage QS60PixmapData::toImage(const QRect &r) const
+{
+ QS60PixmapData *that = const_cast<QS60PixmapData*>(this);
+ that->beginDataAccess();
+ QImage copy = that->image.copy(r);
+ that->endDataAccess();
+
+ return copy;
}
void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags)
{
+ release();
+
QImage sourceImage;
if (pixelType() == BitmapType) {
@@ -517,8 +510,8 @@ void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags
}
cfbsBitmap = createSymbianCFbsBitmap(TSize(sourceImage.width(), sourceImage.height()), mode);
- if (!(cfbsBitmap && initSymbianBitmapContext())) {
- qWarning("Could not create CFbsBitmap and/or CBitmapContext");
+ if (!cfbsBitmap) {
+ qWarning("Could not create CFbsBitmap");
release();
return;
}
@@ -544,17 +537,8 @@ void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags
void QS60PixmapData::copy(const QPixmapData *data, const QRect &rect)
{
- if (data->pixelType() == BitmapType) {
- QBitmap::fromImage(data->toImage().copy(rect));
- return;
- }
-
const QS60PixmapData *s60Data = static_cast<const QS60PixmapData*>(data);
-
- resize(rect.width(), rect.height());
- cfbsBitmap->SetDisplayMode(s60Data->cfbsBitmap->DisplayMode());
-
- bitmapGc->BitBlt(TPoint(0, 0), s60Data->cfbsBitmap, qt_QRect2TRect(rect));
+ fromImage(s60Data->toImage(rect), Qt::AutoColor | Qt::OrderedAlphaDither);
}
bool QS60PixmapData::scroll(int dx, int dy, const QRect &rect)
@@ -661,12 +645,7 @@ void QS60PixmapData::setAlphaChannel(const QPixmap &alphaChannel)
QImage QS60PixmapData::toImage() const
{
- QS60PixmapData *that = const_cast<QS60PixmapData*>(this);
- that->beginDataAccess();
- QImage copy = that->image.copy();
- that->endDataAccess();
-
- return copy;
+ return toImage(QRect());
}
QPaintEngine* QS60PixmapData::paintEngine() const
@@ -820,7 +799,9 @@ void* QS60PixmapData::toNativeType(NativeType type)
if(displayMode == EGray2) {
//Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
//So invert mono bitmaps so that masks work correctly.
+ beginDataAccess();
image.invertPixels();
+ endDataAccess();
needsCopy = true;
}
@@ -828,7 +809,9 @@ void* QS60PixmapData::toNativeType(NativeType type)
QImage source;
if (convertToArgb32) {
+ beginDataAccess();
source = image.convertToFormat(QImage::Format_ARGB32);
+ endDataAccess();
displayMode = EColor16MA;
} else {
source = image;
@@ -858,7 +841,9 @@ void* QS60PixmapData::toNativeType(NativeType type)
if(displayMode == EGray2) {
// restore pixels
+ beginDataAccess();
image.invertPixels();
+ endDataAccess();
}
return reinterpret_cast<void*>(bitmap);
diff --git a/src/gui/image/qpixmap_s60_p.h b/src/gui/image/qpixmap_s60_p.h
index 8631ebd..2d93622 100644
--- a/src/gui/image/qpixmap_s60_p.h
+++ b/src/gui/image/qpixmap_s60_p.h
@@ -109,14 +109,12 @@ public:
private:
void release();
- void fromSymbianBitmap(CFbsBitmap* bitmap);
- bool initSymbianBitmapContext();
+ void fromSymbianBitmap(CFbsBitmap* bitmap, bool lockFormat=false);
+ QImage toImage(const QRect &r) const;
QSymbianBitmapDataAccess *symbianBitmapDataAccess;
CFbsBitmap *cfbsBitmap;
- CFbsBitmapDevice *bitmapDevice;
- CFbsBitGc *bitmapGc;
QPaintEngine *pengine;
uchar* bytes;
diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp
index 7008fbd..f3947ff 100644
--- a/src/gui/image/qpixmap_x11.cpp
+++ b/src/gui/image/qpixmap_x11.cpp
@@ -1932,6 +1932,8 @@ QPixmap QX11PixmapData::transformed(const QTransform &transform,
x11Data->hd = (Qt::HANDLE)XCreatePixmap(X11->display,
RootWindow(X11->display, xinfo.screen()),
w, h, d);
+ x11Data->setSerialNumber(++qt_pixmap_serial);
+
#ifndef QT_NO_XRENDER
if (X11->use_xrender) {
XRenderPictFormat *format = x11Data->d == 32
diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp
index 3723500..939b86d 100644
--- a/src/gui/image/qpixmapfilter.cpp
+++ b/src/gui/image/qpixmapfilter.cpp
@@ -52,6 +52,10 @@
#include "private/qgraphicssystem_p.h"
#include "private/qpaintengineex_p.h"
#include "private/qpaintengine_raster_p.h"
+#include "qmath.h"
+#include "private/qmath_p.h"
+#include "private/qmemrotate_p.h"
+#include "private/qdrawhelper_p.h"
#ifndef QT_NO_GRAPHICSEFFECT
QT_BEGIN_NAMESPACE
@@ -585,106 +589,338 @@ QGraphicsBlurEffect::BlurHints QPixmapBlurFilter::blurHints() const
return d->hints;
}
+const qreal radiusScale = qreal(2.5);
+
/*!
\internal
*/
QRectF QPixmapBlurFilter::boundingRectFor(const QRectF &rect) const
{
Q_D(const QPixmapBlurFilter);
- const qreal delta = d->radius + 1;
+ const qreal delta = radiusScale * d->radius + 1;
return rect.adjusted(-delta, -delta, delta, delta);
}
-// Blur the image according to the blur radius
-// Based on exponential blur algorithm by Jani Huhtanen
-// (maximum radius is set to 16)
-static QImage blurred(const QImage& image, const QRect& rect, int radius, bool alphaOnly = false)
+template <int shift>
+inline int qt_static_shift(int value)
{
- int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
- int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1];
+ if (shift == 0)
+ return value;
+ else if (shift > 0)
+ return value << (uint(shift) & 0x1f);
+ else
+ return value >> (uint(-shift) & 0x1f);
+}
- QImage result = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
- int r1 = rect.top();
- int r2 = rect.bottom();
- int c1 = rect.left();
- int c2 = rect.right();
+template<int aprec, int zprec>
+inline void qt_blurinner(uchar *bptr, int &zR, int &zG, int &zB, int &zA, int alpha)
+{
+ QRgb *pixel = (QRgb *)bptr;
+
+#define Z_MASK (0xff << zprec)
+ const int A_zprec = qt_static_shift<zprec - 24>(*pixel) & Z_MASK;
+ const int R_zprec = qt_static_shift<zprec - 16>(*pixel) & Z_MASK;
+ const int G_zprec = qt_static_shift<zprec - 8>(*pixel) & Z_MASK;
+ const int B_zprec = qt_static_shift<zprec>(*pixel) & Z_MASK;
+#undef Z_MASK
+
+ const int zR_zprec = zR >> aprec;
+ const int zG_zprec = zG >> aprec;
+ const int zB_zprec = zB >> aprec;
+ const int zA_zprec = zA >> aprec;
+
+ zR += alpha * (R_zprec - zR_zprec);
+ zG += alpha * (G_zprec - zG_zprec);
+ zB += alpha * (B_zprec - zB_zprec);
+ zA += alpha * (A_zprec - zA_zprec);
+
+#define ZA_MASK (0xff << (zprec + aprec))
+ *pixel =
+ qt_static_shift<24 - zprec - aprec>(zA & ZA_MASK)
+ | qt_static_shift<16 - zprec - aprec>(zR & ZA_MASK)
+ | qt_static_shift<8 - zprec - aprec>(zG & ZA_MASK)
+ | qt_static_shift<-zprec - aprec>(zB & ZA_MASK);
+#undef ZA_MASK
+}
- int bpl = result.bytesPerLine();
- int rgba[4];
- unsigned char* p;
+const int alphaIndex = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);
- int i1 = 0;
- int i2 = 3;
+template<int aprec, int zprec>
+inline void qt_blurinner_alphaOnly(uchar *bptr, int &z, int alpha)
+{
+ const int A_zprec = int(*(bptr)) << zprec;
+ const int z_zprec = z >> aprec;
+ z += alpha * (A_zprec - z_zprec);
+ *(bptr) = z >> (zprec + aprec);
+}
- if (alphaOnly)
- i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);
+template<int aprec, int zprec, bool alphaOnly>
+inline void qt_blurrow(QImage & im, int line, int alpha)
+{
+ uchar *bptr = im.scanLine(line);
+
+ int zR = 0, zG = 0, zB = 0, zA = 0;
+
+ if (alphaOnly && im.format() != QImage::Format_Indexed8)
+ bptr += alphaIndex;
+
+ const int stride = im.depth() >> 3;
+ const int im_width = im.width();
+ for (int index = 0; index < im_width; ++index) {
+ if (alphaOnly)
+ qt_blurinner_alphaOnly<aprec, zprec>(bptr, zA, alpha);
+ else
+ qt_blurinner<aprec, zprec>(bptr, zR, zG, zB, zA, alpha);
+ bptr += stride;
+ }
+
+ bptr -= stride;
+
+ for (int index = im_width - 2; index >= 0; --index) {
+ bptr -= stride;
+ if (alphaOnly)
+ qt_blurinner_alphaOnly<aprec, zprec>(bptr, zA, alpha);
+ else
+ qt_blurinner<aprec, zprec>(bptr, zR, zG, zB, zA, alpha);
+ }
+}
+
+/*
+* expblur(QImage &img, int radius)
+*
+* Based on exponential blur algorithm by Jani Huhtanen
+*
+* In-place blur of image 'img' with kernel
+* of approximate radius 'radius'.
+*
+* Blurs with two sided exponential impulse
+* response.
+*
+* aprec = precision of alpha parameter
+* in fixed-point format 0.aprec
+*
+* zprec = precision of state parameters
+* zR,zG,zB and zA in fp format 8.zprec
+*/
+template <int aprec, int zprec, bool alphaOnly>
+void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transposed = 0)
+{
+ // halve the radius if we're using two passes
+ if (improvedQuality)
+ radius *= qreal(0.5);
+
+ Q_ASSERT(img.format() == QImage::Format_ARGB32_Premultiplied
+ || img.format() == QImage::Format_RGB32);
+
+ // choose the alpha such that pixels at radius distance from a fully
+ // saturated pixel will have an alpha component of no greater than
+ // the cutOffIntensity
+ const qreal cutOffIntensity = 2;
+ int alpha = radius <= qreal(1e-5)
+ ? ((1 << aprec)-1)
+ : qRound((1<<aprec)*(1 - qPow(cutOffIntensity * (1 / qreal(255)), 1 / radius)));
+
+ int img_height = img.height();
+ for (int row = 0; row < img_height; ++row) {
+ for (int i = 0; i <= improvedQuality; ++i)
+ qt_blurrow<aprec, zprec, alphaOnly>(img, row, alpha);
+ }
+
+ QImage temp(img.height(), img.width(), img.format());
+ if (transposed >= 0) {
+ if (img.depth() == 8) {
+ qt_memrotate270(reinterpret_cast<const quint8*>(img.bits()),
+ img.width(), img.height(), img.bytesPerLine(),
+ reinterpret_cast<quint8*>(temp.bits()),
+ temp.bytesPerLine());
+ } else {
+ qt_memrotate270(reinterpret_cast<const quint32*>(img.bits()),
+ img.width(), img.height(), img.bytesPerLine(),
+ reinterpret_cast<quint32*>(temp.bits()),
+ temp.bytesPerLine());
+ }
+ } else {
+ if (img.depth() == 8) {
+ qt_memrotate90(reinterpret_cast<const quint8*>(img.bits()),
+ img.width(), img.height(), img.bytesPerLine(),
+ reinterpret_cast<quint8*>(temp.bits()),
+ temp.bytesPerLine());
+ } else {
+ qt_memrotate90(reinterpret_cast<const quint32*>(img.bits()),
+ img.width(), img.height(), img.bytesPerLine(),
+ reinterpret_cast<quint32*>(temp.bits()),
+ temp.bytesPerLine());
+ }
+ }
- for (int col = c1; col <= c2; col++) {
- p = result.scanLine(r1) + col * 4;
- for (int i = i1; i <= i2; i++)
- rgba[i] = p[i] << 4;
+ img_height = temp.height();
+ for (int row = 0; row < img_height; ++row) {
+ for (int i = 0; i <= improvedQuality; ++i)
+ qt_blurrow<aprec, zprec, alphaOnly>(temp, row, alpha);
+ }
- p += bpl;
- for (int j = r1; j < r2; j++, p += bpl)
- for (int i = i1; i <= i2; i++)
- p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
+ if (transposed == 0) {
+ qt_memrotate90(reinterpret_cast<const quint32*>(temp.bits()),
+ temp.width(), temp.height(), temp.bytesPerLine(),
+ reinterpret_cast<quint32*>(img.bits()),
+ img.bytesPerLine());
+ } else {
+ img = temp;
}
+}
+#define AVG(a,b) ( ((((a)^(b)) & 0xfefefefeUL) >> 1) + ((a)&(b)) )
+#define AVG16(a,b) ( ((((a)^(b)) & 0xf7deUL) >> 1) + ((a)&(b)) )
- for (int row = r1; row <= r2; row++) {
- p = result.scanLine(row) + c1 * 4;
- for (int i = i1; i <= i2; i++)
- rgba[i] = p[i] << 4;
+Q_GUI_EXPORT QImage qt_halfScaled(const QImage &source)
+{
+ QImage srcImage = source;
+
+ if (source.format() == QImage::Format_Indexed8) {
+ // assumes grayscale
+ QImage dest(source.width() / 2, source.height() / 2, srcImage.format());
+
+ const uchar *src = reinterpret_cast<const uchar*>(const_cast<const QImage &>(srcImage).bits());
+ int sx = srcImage.bytesPerLine();
+ int sx2 = sx << 1;
+
+ uchar *dst = reinterpret_cast<uchar*>(dest.bits());
+ int dx = dest.bytesPerLine();
+ int ww = dest.width();
+ int hh = dest.height();
+
+ for (int y = hh; y; --y, dst += dx, src += sx2) {
+ const uchar *p1 = src;
+ const uchar *p2 = src + sx;
+ uchar *q = dst;
+ for (int x = ww; x; --x, ++q, p1 += 2, p2 += 2)
+ *q = ((int(p1[0]) + int(p1[1]) + int(p2[0]) + int(p2[1])) + 2) >> 2;
+ }
+
+ return dest;
+ } else if (source.format() == QImage::Format_ARGB8565_Premultiplied) {
+ QImage dest(source.width() / 2, source.height() / 2, srcImage.format());
+
+ const uchar *src = reinterpret_cast<const uchar*>(const_cast<const QImage &>(srcImage).bits());
+ int sx = srcImage.bytesPerLine();
+ int sx2 = sx << 1;
+
+ uchar *dst = reinterpret_cast<uchar*>(dest.bits());
+ int dx = dest.bytesPerLine();
+ int ww = dest.width();
+ int hh = dest.height();
+
+ for (int y = hh; y; --y, dst += dx, src += sx2) {
+ const uchar *p1 = src;
+ const uchar *p2 = src + sx;
+ uchar *q = dst;
+ for (int x = ww; x; --x, q += 3, p1 += 6, p2 += 6) {
+ // alpha
+ q[0] = AVG(AVG(p1[0], p1[3]), AVG(p2[0], p2[3]));
+ // rgb
+ const quint16 p16_1 = (p1[2] << 8) | p1[1];
+ const quint16 p16_2 = (p1[5] << 8) | p1[4];
+ const quint16 p16_3 = (p2[2] << 8) | p2[1];
+ const quint16 p16_4 = (p2[5] << 8) | p2[4];
+ const quint16 result = AVG16(AVG16(p16_1, p16_2), AVG16(p16_3, p16_4));
+ q[1] = result & 0xff;
+ q[2] = result >> 8;
+ }
+ }
- p += 4;
- for (int j = c1; j < c2; j++, p += 4)
- for (int i = i1; i <= i2; i++)
- p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
+ return dest;
+ } else if (source.format() != QImage::Format_ARGB32_Premultiplied
+ && source.format() != QImage::Format_RGB32)
+ {
+ srcImage = source.convertToFormat(QImage::Format_ARGB32_Premultiplied);
}
- for (int col = c1; col <= c2; col++) {
- p = result.scanLine(r2) + col * 4;
- for (int i = i1; i <= i2; i++)
- rgba[i] = p[i] << 4;
+ QImage dest(source.width() / 2, source.height() / 2, srcImage.format());
+
+ const quint32 *src = reinterpret_cast<const quint32*>(const_cast<const QImage &>(srcImage).bits());
+ int sx = srcImage.bytesPerLine() >> 2;
+ int sx2 = sx << 1;
+
+ quint32 *dst = reinterpret_cast<quint32*>(dest.bits());
+ int dx = dest.bytesPerLine() >> 2;
+ int ww = dest.width();
+ int hh = dest.height();
- p -= bpl;
- for (int j = r1; j < r2; j++, p -= bpl)
- for (int i = i1; i <= i2; i++)
- p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
+ for (int y = hh; y; --y, dst += dx, src += sx2) {
+ const quint32 *p1 = src;
+ const quint32 *p2 = src + sx;
+ quint32 *q = dst;
+ for (int x = ww; x; --x, q++, p1 += 2, p2 += 2)
+ *q = AVG(AVG(p1[0], p1[1]), AVG(p2[0], p2[1]));
}
- for (int row = r1; row <= r2; row++) {
- p = result.scanLine(row) + c2 * 4;
- for (int i = i1; i <= i2; i++)
- rgba[i] = p[i] << 4;
+ return dest;
+}
- p -= 4;
- for (int j = c1; j < c2; j++, p -= 4)
- for (int i = i1; i <= i2; i++)
- p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
+Q_GUI_EXPORT void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0)
+{
+ if (blurImage.format() != QImage::Format_ARGB32_Premultiplied
+ && blurImage.format() != QImage::Format_RGB32)
+ {
+ blurImage = blurImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
}
- return result;
+ qreal scale = 1;
+ if (radius >= 4) {
+ blurImage = qt_halfScaled(blurImage);
+ scale = 2;
+ radius *= qreal(0.5);
+ }
+
+ if (alphaOnly)
+ expblur<12, 10, true>(blurImage, radius, quality, transposed);
+ else
+ expblur<12, 10, false>(blurImage, radius, quality, transposed);
+
+ if (p) {
+ p->scale(scale, scale);
+ p->setRenderHint(QPainter::SmoothPixmapTransform);
+ p->drawImage(QRect(0, 0, blurImage.width(), blurImage.height()), blurImage);
+ }
+}
+
+Q_GUI_EXPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0)
+{
+ if (blurImage.format() == QImage::Format_Indexed8)
+ expblur<12, 10, true>(blurImage, radius, quality, transposed);
+ else
+ expblur<12, 10, false>(blurImage, radius, quality, transposed);
}
+bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
+
/*!
\internal
*/
-void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF &srcRect) const
+void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap &src, const QRectF &rect) const
{
Q_D(const QPixmapBlurFilter);
if (!painter->isActive())
return;
- if (d->radius <= 0) {
+ QRectF srcRect = rect;
+ if (srcRect.isNull())
+ srcRect = src.rect();
+
+ if (d->radius <= 1) {
painter->drawPixmap(srcRect.translated(p), src, srcRect);
return;
}
+ qreal scaledRadius = radiusScale * d->radius;
+ qreal scale;
+ if (qt_scaleForTransform(painter->transform(), &scale))
+ scaledRadius /= scale;
+
QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ?
static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0;
QPixmapBlurFilter *blurFilter = static_cast<QPixmapBlurFilter*>(filter);
if (blurFilter) {
- blurFilter->setRadius(d->radius);
+ blurFilter->setRadius(scaledRadius);
blurFilter->setBlurHints(d->hints);
blurFilter->draw(painter, p, src, srcRect);
return;
@@ -693,17 +929,17 @@ void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap
QImage srcImage;
QImage destImage;
- if (srcRect.isNull()) {
+ if (srcRect == src.rect()) {
srcImage = src.toImage();
- destImage = blurred(srcImage, srcImage.rect(), qRound(d->radius));
} else {
QRect rect = srcRect.toAlignedRect().intersected(src.rect());
-
srcImage = src.copy(rect).toImage();
- destImage = blurred(srcImage, srcImage.rect(), qRound(d->radius));
}
- painter->drawImage(p, destImage);
+ QTransform transform = painter->worldTransform();
+ painter->translate(p);
+ qt_blurImage(painter, srcImage, scaledRadius, (d->hints & QGraphicsBlurEffect::QualityHint), false);
+ painter->setWorldTransform(transform);
}
// grayscales the image to dest (could be same). If rect isn't defined
@@ -1095,7 +1331,13 @@ void QPixmapDropShadowFilter::draw(QPainter *p,
tmpPainter.end();
// blur the alpha channel
- tmp = blurred(tmp, tmp.rect(), qRound(d->radius), true);
+ QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied);
+ blurred.fill(0);
+ QPainter blurPainter(&blurred);
+ qt_blurImage(&blurPainter, tmp, d->radius, false, true);
+ blurPainter.end();
+
+ tmp = blurred;
// blacken the image...
tmpPainter.begin(&tmp);
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index 14c863b..42c48a9 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -67,6 +67,9 @@ QT_BEGIN_NAMESPACE
# define Q_INTERNAL_WIN_NO_THROW
#endif
+// avoid going through QImage::scanLine() which calls detach
+#define FAST_SCAN_LINE(data, bpl, y) (data + (y) * bpl)
+
/*
All PNG files load to the minimal QImage equivalent.
@@ -510,7 +513,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngImage(QImage *outImage)
&& outImage->format() == QImage::Format_Indexed8) {
int color_table_size = outImage->colorCount();
for (int y=0; y<(int)height; ++y) {
- uchar *p = outImage->scanLine(y);
+ uchar *p = FAST_SCAN_LINE(data, bpl, y);
uchar *end = p + width;
while (p < end) {
if (*p >= color_table_size)
@@ -852,7 +855,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in,
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
0, 0, 0);
- const uchar *data = image.bits();
+ const uchar *data = (static_cast<const QImage *>(&image))->bits();
int bpl = image.bytesPerLine();
row_pointers = new png_bytep[height];
uint y;
diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp
index 8ec9efb..f2d51f7 100644
--- a/src/gui/image/qppmhandler.cpp
+++ b/src/gui/image/qppmhandler.cpp
@@ -264,7 +264,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy
bool gray = format == "pgm";
if (format == "pbm") {
- image = image.convertToFormat(QImage::Format_MonoLSB);
+ image = image.convertToFormat(QImage::Format_Mono);
} else if (image.depth() == 1) {
image = image.convertToFormat(QImage::Format_Indexed8);
} else {
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index a295d66..1bf7662 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -139,8 +139,7 @@ void QCoeFepInputContext::widgetDestroyed(QWidget *w)
// Make sure that the input capabilities of whatever new widget got focused are queried.
CCoeControl *ctrl = w->effectiveWinId();
if (ctrl->IsFocused()) {
- ctrl->SetFocus(false);
- ctrl->SetFocus(true);
+ queueInputCapabilitiesChanged();
}
}
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index 4a450b7..f447989 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -70,6 +70,7 @@ QAbstractItemViewPrivate::QAbstractItemViewPrivate()
itemDelegate(0),
selectionModel(0),
ctrlDragSelectionFlag(QItemSelectionModel::NoUpdate),
+ noSelectionOnMousePress(false),
selectionMode(QAbstractItemView::ExtendedSelection),
selectionBehavior(QAbstractItemView::SelectItems),
currentlyCommittingEditor(0),
@@ -1622,6 +1623,7 @@ void QAbstractItemView::mousePressEvent(QMouseEvent *event)
d->pressedIndex = index;
d->pressedModifiers = event->modifiers();
QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
+ d->noSelectionOnMousePress = command == QItemSelectionModel::NoUpdate || !index.isValid();
QPoint offset = d->offset();
if ((command & QItemSelectionModel::Current) == 0)
d->pressedPosition = pos + offset;
@@ -1760,9 +1762,10 @@ void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event)
d->ctrlDragSelectionFlag = QItemSelectionModel::NoUpdate;
- //in the case the user presses on no item we might decide to clear the selection
- if (d->selectionModel && !index.isValid())
- d->selectionModel->select(QModelIndex(), selectionCommand(index, event));
+ if (d->selectionModel && d->noSelectionOnMousePress) {
+ d->noSelectionOnMousePress = false;
+ d->selectionModel->select(index, selectionCommand(index, event));
+ }
setState(NoState);
@@ -2065,9 +2068,13 @@ void QAbstractItemView::focusInEvent(QFocusEvent *event)
{
Q_D(QAbstractItemView);
QAbstractScrollArea::focusInEvent(event);
- if (selectionModel()
+
+ const QItemSelectionModel* model = selectionModel();
+ const bool currentIndexValid = currentIndex().isValid();
+
+ if (model
&& !d->currentIndexSet
- && !currentIndex().isValid()) {
+ && !currentIndexValid) {
bool autoScroll = d->autoScroll;
d->autoScroll = false;
QModelIndex index = moveCursor(MoveNext, Qt::NoModifier); // first visible index
@@ -2075,6 +2082,17 @@ void QAbstractItemView::focusInEvent(QFocusEvent *event)
selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
d->autoScroll = autoScroll;
}
+
+ if (model && currentIndexValid) {
+ if (currentIndex().flags() != Qt::ItemIsEditable)
+ setAttribute(Qt::WA_InputMethodEnabled, false);
+ else
+ setAttribute(Qt::WA_InputMethodEnabled);
+ }
+
+ if (!currentIndexValid)
+ setAttribute(Qt::WA_InputMethodEnabled, false);
+
d->viewport->update();
}
diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h
index 0b5cfbe..7fc6780 100644
--- a/src/gui/itemviews/qabstractitemview_p.h
+++ b/src/gui/itemviews/qabstractitemview_p.h
@@ -347,6 +347,7 @@ public:
QMap<int, QPointer<QAbstractItemDelegate> > columnDelegates;
QPointer<QItemSelectionModel> selectionModel;
QItemSelectionModel::SelectionFlag ctrlDragSelectionFlag;
+ bool noSelectionOnMousePress;
QAbstractItemView::SelectionMode selectionMode;
QAbstractItemView::SelectionBehavior selectionBehavior;
diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp
index fc82f30..0e4af53 100644
--- a/src/gui/itemviews/qsortfilterproxymodel.cpp
+++ b/src/gui/itemviews/qsortfilterproxymodel.cpp
@@ -734,6 +734,33 @@ void QSortFilterProxyModelPrivate::source_items_inserted(
}
}
+ if (model->rowCount(source_parent) == delta_item_count) {
+ // Items were inserted where there were none before.
+ // If it was new rows make sure to create mappings for columns so that a
+ // valid mapping can be retreived later and vice-versa.
+
+ QVector<int> &orthogonal_proxy_to_source = (orient == Qt::Horizontal) ? m->source_rows : m->source_columns;
+ QVector<int> &orthogonal_source_to_proxy = (orient == Qt::Horizontal) ? m->proxy_rows : m->proxy_columns;
+
+ if (orthogonal_source_to_proxy.isEmpty()) {
+ const int ortho_end = (orient == Qt::Horizontal) ? model->rowCount(source_parent) : model->columnCount(source_parent);
+
+ for (int ortho_item = 0; ortho_item < ortho_end; ++ortho_item) {
+ if ((orient == Qt::Horizontal) ? q->filterAcceptsRow(ortho_item, source_parent)
+ : q->filterAcceptsColumn(ortho_item, source_parent)) {
+ orthogonal_proxy_to_source.append(ortho_item);
+ }
+ }
+ orthogonal_source_to_proxy.resize(orthogonal_proxy_to_source.size());
+
+ if (orient == Qt::Horizontal) {
+ // We're reacting to columnsInserted, but we've just inserted new rows. Sort them.
+ sort_source_rows(orthogonal_proxy_to_source, source_parent);
+ }
+ build_source_to_proxy_mapping(orthogonal_proxy_to_source, orthogonal_source_to_proxy);
+ }
+ }
+
// Sort and insert the items
if (orient == Qt::Vertical) // Only sort rows
sort_source_rows(source_items, source_parent);
@@ -1171,9 +1198,10 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged()
{
Q_Q(QSortFilterProxyModel);
saved_persistent_indexes.clear();
+ emit q->layoutAboutToBeChanged();
if (persistent.indexes.isEmpty())
return;
- emit q->layoutAboutToBeChanged();
+
saved_persistent_indexes = store_persistent_indexes();
}
@@ -1181,7 +1209,8 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged()
{
Q_Q(QSortFilterProxyModel);
if (saved_persistent_indexes.isEmpty()) {
- q->invalidate();
+ clear_mapping();
+ emit q->layoutChanged();
return;
}
@@ -1452,7 +1481,6 @@ QSortFilterProxyModel::QSortFilterProxyModel(QObject *parent)
d->filter_column = 0;
d->filter_role = Qt::DisplayRole;
d->dynamic_sortfilter = false;
- connect(this, SIGNAL(modelReset()), this, SLOT(invalidate()));
}
/*!
diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp
index d27e693..26f5a20 100644
--- a/src/gui/itemviews/qtableview.cpp
+++ b/src/gui/itemviews/qtableview.cpp
@@ -2359,12 +2359,22 @@ void QTableView::setColumnHidden(int column, bool hide)
\property QTableView::sortingEnabled
\brief whether sorting is enabled
- If this property is true, sorting is enabled for the table; if the
- property is false, sorting is not enabled. The default value is false.
+ If this property is true, sorting is enabled for the table. If
+ this property is false, sorting is not enabled. The default value
+ is false.
+
+ \note. Setting the property to true with setSortingEnabled()
+ immediately triggers a call to sortByColumn() with the current
+ sort section and order.
\sa sortByColumn()
*/
+/*!
+ If \a enabled true enables sorting for the table and immediately
+ trigger a call to sortByColumn() with the current sort section and
+ order
+ */
void QTableView::setSortingEnabled(bool enable)
{
Q_D(QTableView);
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index f2bd288..30cb043 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -201,6 +201,7 @@ embedded {
OBJECTIVE_HEADERS += \
qcocoawindow_mac_p.h \
+ qcocoapanel_mac_p.h \
qcocoawindowdelegate_mac_p.h \
qcocoaview_mac_p.h \
qcocoaapplication_mac_p.h \
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index edf077b..7c320da 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -2096,7 +2096,11 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason)
if (prev) {
#ifdef QT_KEYPAD_NAVIGATION
if (QApplication::keypadNavigationEnabled()) {
- if (prev->hasEditFocus() && reason != Qt::PopupFocusReason)
+ if (prev->hasEditFocus() && reason != Qt::PopupFocusReason
+#ifdef Q_OS_SYMBIAN
+ && reason != Qt::ActiveWindowFocusReason
+#endif
+ )
prev->setEditFocus(false);
}
#endif
@@ -3629,12 +3633,46 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
// walk through parents and check for gestures
if (qt_gestureManager) {
- if (receiver->isWidgetType()) {
- if (qt_gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
- return true;
- } else if (QGesture *gesture = qobject_cast<QGesture *>(receiver)) {
- if (qt_gestureManager->filterEvent(gesture, e))
- return true;
+ switch (e->type()) {
+ case QEvent::Paint:
+ case QEvent::MetaCall:
+ case QEvent::DeferredDelete:
+ case QEvent::DragEnter: case QEvent::DragMove: case QEvent::DragLeave:
+ case QEvent::Drop: case QEvent::DragResponse:
+ case QEvent::ChildAdded: case QEvent::ChildPolished:
+#ifdef QT3_SUPPORT
+ case QEvent::ChildInsertedRequest:
+ case QEvent::ChildInserted:
+ case QEvent::LayoutHint:
+#endif
+ case QEvent::ChildRemoved:
+ case QEvent::UpdateRequest:
+ case QEvent::UpdateLater:
+ case QEvent::AccessibilityPrepare:
+ case QEvent::LocaleChange:
+ case QEvent::Style:
+ case QEvent::IconDrag:
+ case QEvent::StyleChange:
+ case QEvent::AccessibilityHelp:
+ case QEvent::AccessibilityDescription:
+ case QEvent::GraphicsSceneDragEnter:
+ case QEvent::GraphicsSceneDragMove:
+ case QEvent::GraphicsSceneDragLeave:
+ case QEvent::GraphicsSceneDrop:
+ case QEvent::DynamicPropertyChange:
+ case QEvent::NetworkReplyUpdated:
+ break;
+ default:
+ if (receiver->isWidgetType()) {
+ if (qt_gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
+ return true;
+ } else {
+ // a special case for events that go to QGesture objects.
+ // We pass the object to the gesture manager and it'll figure
+ // out if it's QGesture or not.
+ if (qt_gestureManager->filterEvent(receiver, e))
+ return true;
+ }
}
}
@@ -5192,6 +5230,8 @@ QInputContext *QApplication::inputContext() const
{
Q_D(const QApplication);
Q_UNUSED(d);// only static members being used.
+ if (QApplicationPrivate::is_app_closing)
+ return d->inputContext;
#ifdef Q_WS_X11
if (!X11)
return 0;
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index ab57c32..27f2644 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -361,6 +361,8 @@ void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop)
SetFocusing(true);
m_longTapDetector = QLongTapTimer::NewL(this);
+
+ DrawableWindow()->SetPointerGrab(ETrue);
}
}
@@ -472,41 +474,6 @@ void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent)
QT_TRYCATCH_LEAVING(HandlePointerEvent(pEvent));
}
-typedef QPair<QWidget*,QMouseEvent> Event;
-
-/*
- * Helper function called by HandlePointerEvent - separated to keep that function readable
- */
-static void generateEnterLeaveEvents(QList<Event> &events, QWidget *widgetUnderPointer,
- QPoint globalPos, Qt::MouseButton button, Qt::KeyboardModifiers modifiers)
-{
- //moved to another widget, create enter and leave events
- if (S60->lastPointerEventTarget) {
- QMouseEvent mEventLeave(QEvent::Leave, S60->lastPointerEventTarget->mapFromGlobal(
- S60->lastCursorPos), S60->lastCursorPos, button, QApplicationPrivate::mouse_buttons,
- modifiers);
- events.append(Event(S60->lastPointerEventTarget, mEventLeave));
- }
- if (widgetUnderPointer) {
- QMouseEvent mEventEnter(QEvent::Enter, widgetUnderPointer->mapFromGlobal(globalPos),
- globalPos, button, QApplicationPrivate::mouse_buttons, modifiers);
-
- events.append(Event(widgetUnderPointer, mEventEnter));
-#ifndef QT_NO_CURSOR
- S60->curWin = widgetUnderPointer->effectiveWinId();
- if (!QApplication::overrideCursor()) {
-#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
- if (S60->brokenPointerCursors)
- qt_symbian_set_pointer_sprite(widgetUnderPointer->cursor());
- else
-#endif
- qt_symbian_setWindowCursor(widgetUnderPointer->cursor(), S60->curWin);
- }
-#endif
- }
-}
-
-
void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
{
QMouseEvent::Type type;
@@ -514,85 +481,77 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
mapS60MouseEventTypeToQt(&type, &button, &pEvent);
Qt::KeyboardModifiers modifiers = mapToQtModifiers(pEvent.iModifiers);
- if (type == QMouseEvent::None)
- return;
-
- // store events for later sending/saving
- QList<Event > events;
-
QPoint widgetPos = QPoint(pEvent.iPosition.iX, pEvent.iPosition.iY);
TPoint controlScreenPos = PositionRelativeToScreen();
QPoint globalPos = QPoint(controlScreenPos.iX, controlScreenPos.iY) + widgetPos;
+ S60->lastCursorPos = globalPos;
+ S60->lastPointerEventPos = widgetPos;
- // widgets interested in the event
- QWidget *widgetUnderPointer = qwidget->childAt(widgetPos);
- if (!widgetUnderPointer)
- widgetUnderPointer = qwidget; //i.e. this container widget
+ QWidget *mouseGrabber = QWidget::mouseGrabber();
- QWidget *widgetWithMouseGrab = QWidget::mouseGrabber();
+ QWidget *popupWidget = qApp->activePopupWidget();
+ QWidget *popupReceiver = 0;
+ if (popupWidget) {
+ QWidget *popupChild = popupWidget->childAt(popupWidget->mapFromGlobal(globalPos));
+ popupReceiver = popupChild ? popupChild : popupWidget;
+ }
- // handle auto grab of pointer when pressing / releasing
- if (!widgetWithMouseGrab && type == QEvent::MouseButtonPress) {
- //if previously auto-grabbed, generate a fake mouse release (platform bug: mouse release event was lost)
- if (S60->mousePressTarget) {
- QMouseEvent mEvent(QEvent::MouseButtonRelease, S60->mousePressTarget->mapFromGlobal(globalPos), globalPos,
- button, QApplicationPrivate::mouse_buttons, modifiers);
- events.append(Event(S60->mousePressTarget,mEvent));
+ if (mouseGrabber) {
+ if (popupReceiver) {
+ sendMouseEvent(popupReceiver, type, globalPos, button, modifiers);
+ } else {
+ sendMouseEvent(mouseGrabber, type, globalPos, button, modifiers);
}
- //auto grab the mouse
- widgetWithMouseGrab = S60->mousePressTarget = widgetUnderPointer;
- widgetWithMouseGrab->grabMouse();
- }
- if (widgetWithMouseGrab && widgetWithMouseGrab == S60->mousePressTarget && type == QEvent::MouseButtonRelease) {
- //release the auto grab - note this release event still goes to the autograb widget
- S60->mousePressTarget = 0;
- widgetWithMouseGrab->releaseMouse();
+ // No Enter/Leave events in grabbing mode.
+ return;
}
- QWidget *widgetToReceiveMouseEvent;
- if (widgetWithMouseGrab)
- widgetToReceiveMouseEvent = widgetWithMouseGrab;
- else
- widgetToReceiveMouseEvent = widgetUnderPointer;
-
- //queue QEvent::Enter and QEvent::Leave, if the pointer has moved
- if (widgetUnderPointer != S60->lastPointerEventTarget && (type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick || type == QEvent::MouseMove))
- generateEnterLeaveEvents(events, widgetUnderPointer, globalPos, button, modifiers);
+ QWidget *widgetUnderPointer = qwidget->childAt(widgetPos);
+ if (!widgetUnderPointer)
+ widgetUnderPointer = qwidget;
- //save global state
- S60->lastCursorPos = globalPos;
- S60->lastPointerEventPos = widgetPos;
+ QApplicationPrivate::dispatchEnterLeave(widgetUnderPointer, S60->lastPointerEventTarget);
S60->lastPointerEventTarget = widgetUnderPointer;
+ QWidget *receiver;
+ if (!popupReceiver && S60->mousePressTarget && type != QEvent::MouseButtonPress) {
+ receiver = S60->mousePressTarget;
+ if (type == QEvent::MouseButtonRelease)
+ S60->mousePressTarget = 0;
+ } else {
+ receiver = popupReceiver ? popupReceiver : widgetUnderPointer;
+ if (type == QEvent::MouseButtonPress)
+ S60->mousePressTarget = receiver;
+ }
+
#if !defined(QT_NO_CURSOR) && !defined(Q_SYMBIAN_FIXED_POINTER_CURSORS)
if (S60->brokenPointerCursors)
qt_symbian_move_cursor_sprite();
#endif
- //queue this event.
- Q_ASSERT(widgetToReceiveMouseEvent);
- QMouseEvent mEvent(type, widgetToReceiveMouseEvent->mapFromGlobal(globalPos), globalPos,
+ sendMouseEvent(receiver, type, globalPos, button, modifiers);
+}
+
+void QSymbianControl::sendMouseEvent(
+ QWidget *receiver,
+ QEvent::Type type,
+ const QPoint &globalPos,
+ Qt::MouseButton button,
+ Qt::KeyboardModifiers modifiers)
+{
+ Q_ASSERT(receiver);
+ QMouseEvent mEvent(type, receiver->mapFromGlobal(globalPos), globalPos,
button, QApplicationPrivate::mouse_buttons, modifiers);
- events.append(Event(widgetToReceiveMouseEvent,mEvent));
QEventDispatcherS60 *dispatcher;
// It is theoretically possible for someone to install a different event dispatcher.
- if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(widgetToReceiveMouseEvent->d_func()->threadData->eventDispatcher)) != 0) {
+ if ((dispatcher = qobject_cast<QEventDispatcherS60 *>(receiver->d_func()->threadData->eventDispatcher)) != 0) {
if (dispatcher->excludeUserInputEvents()) {
- for (int i=0;i < events.count();++i)
- {
- Event next = events[i];
- dispatcher->saveInputEvent(this, next.first, new QMouseEvent(next.second));
- }
+ dispatcher->saveInputEvent(this, receiver, new QMouseEvent(mEvent));
return;
}
}
- //send events in the queue
- for (int i=0;i < events.count();++i)
- {
- Event next = events[i];
- sendMouseEvent(next.first, &(next.second));
- }
+ sendMouseEvent(receiver, &mEvent);
}
bool QSymbianControl::sendMouseEvent(QWidget *widget, QMouseEvent *mEvent)
@@ -672,27 +631,58 @@ TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCod
fakeEvent.iType = TPointerEvent::EButton1Up;
S60->virtualMouseAccel = 1;
S60->virtualMouseLastKey = 0;
+ switch (keyCode) {
+ case Qt::Key_Left:
+ S60->virtualMousePressedKeys &= ~QS60Data::Left;
+ break;
+ case Qt::Key_Right:
+ S60->virtualMousePressedKeys &= ~QS60Data::Right;
+ break;
+ case Qt::Key_Up:
+ S60->virtualMousePressedKeys &= ~QS60Data::Up;
+ break;
+ case Qt::Key_Down:
+ S60->virtualMousePressedKeys &= ~QS60Data::Down;
+ break;
+ case Qt::Key_Select:
+ S60->virtualMousePressedKeys &= ~QS60Data::Select;
+ break;
+ }
}
else if (type == EEventKey) {
switch (keyCode) {
case Qt::Key_Left:
+ S60->virtualMousePressedKeys |= QS60Data::Left;
x -= S60->virtualMouseAccel;
fakeEvent.iType = TPointerEvent::EMove;
break;
case Qt::Key_Right:
+ S60->virtualMousePressedKeys |= QS60Data::Right;
x += S60->virtualMouseAccel;
fakeEvent.iType = TPointerEvent::EMove;
break;
case Qt::Key_Up:
+ S60->virtualMousePressedKeys |= QS60Data::Up;
y -= S60->virtualMouseAccel;
fakeEvent.iType = TPointerEvent::EMove;
break;
case Qt::Key_Down:
+ S60->virtualMousePressedKeys |= QS60Data::Down;
y += S60->virtualMouseAccel;
fakeEvent.iType = TPointerEvent::EMove;
break;
case Qt::Key_Select:
- fakeEvent.iType = TPointerEvent::EButton1Down;
+ // Platform bug. If you start pressing several keys simultaneously (for
+ // example for drag'n'drop), Symbian starts producing spurious up and
+ // down messages for some keys. Therefore, make sure we have a clean slate
+ // of pressed keys before starting a new button press.
+ if (S60->virtualMousePressedKeys != 0) {
+ S60->virtualMousePressedKeys |= QS60Data::Select;
+ return EKeyWasConsumed;
+ } else {
+ S60->virtualMousePressedKeys |= QS60Data::Select;
+ fakeEvent.iType = TPointerEvent::EButton1Down;
+ }
break;
}
}
diff --git a/src/gui/kernel/qboxlayout.cpp b/src/gui/kernel/qboxlayout.cpp
index d965933..fd16861 100644
--- a/src/gui/kernel/qboxlayout.cpp
+++ b/src/gui/kernel/qboxlayout.cpp
@@ -830,9 +830,11 @@ void QBoxLayout::setGeometry(const QRect &r)
if (d->hasHfw && !horz(d->dir)) {
for (int i = 0; i < n; i++) {
QBoxLayoutItem *box = d->list.at(i);
- if (box->item->hasHeightForWidth())
+ if (box->item->hasHeightForWidth()) {
+ int width = qBound(box->item->minimumSize().width(), s.width(), box->item->maximumSize().width());
a[i].sizeHint = a[i].minimumSize =
- box->item->heightForWidth(s.width());
+ box->item->heightForWidth(width);
+ }
}
}
diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
index cc5839c..31d81d9 100644
--- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
+++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
@@ -55,6 +55,7 @@ QT_BEGIN_NAMESPACE
extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm
extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
extern const QStringList& qEnabledDraggedTypes(); // qmime_mac.cpp
+extern bool qt_blockCocoaSettingModalWindowLevel; // qeventdispatcher_mac_p.h
Q_GLOBAL_STATIC(QPointer<QWidget>, currentDragTarget);
@@ -88,6 +89,39 @@ QT_END_NAMESPACE
return !(isPopup || isToolTip);
}
+- (BOOL)canBecomeMainWindow
+{
+ QWidget *widget = [self QT_MANGLE_NAMESPACE(qt_qwidget)];
+
+ bool isToolTip = (widget->windowType() == Qt::ToolTip);
+ bool isPopup = (widget->windowType() == Qt::Popup);
+ return !(isPopup || isToolTip);
+}
+
+- (void)orderWindow:(NSWindowOrderingMode)orderingMode relativeTo:(NSInteger)otherWindowNumber
+{
+ if (qt_blockCocoaSettingModalWindowLevel) {
+ // To avoid windows popping in front while restoring modal sessions
+ // in the event dispatcher, we block cocoa from ordering this window
+ // to front. The result of not doing this can be seen if executing
+ // a native color dialog on top of another executing dialog.
+ return;
+ }
+ [super orderWindow:orderingMode relativeTo:otherWindowNumber];
+}
+
+- (void)setLevel:(NSInteger)windowLevel
+{
+ if (qt_blockCocoaSettingModalWindowLevel) {
+ // To avoid windows popping in front while restoring modal sessions
+ // in the event dispatcher, we block cocoa from ordering this window
+ // to front. The result of not doing this can be seen if executing
+ // a native color dialog on top of another executing dialog.
+ return;
+ }
+ [super setLevel:windowLevel];
+}
+
- (void)toggleToolbarShown:(id)sender
{
macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]);
@@ -126,6 +160,13 @@ QT_END_NAMESPACE
qt_dispatchTabletProximityEvent(tabletEvent);
}
+- (void)terminate:(id)sender
+{
+ // This function is called from the quit item in the
+ // menubar, when this window is the first responder
+ [NSApp terminate:sender];
+}
+
- (void)sendEvent:(NSEvent *)event
{
QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self];
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 311cf24..2ed2191 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -317,7 +317,9 @@ extern "C" {
// since we accepted the drag enter event, the widget expects
// future drage move events.
// ### check if we need to treat this like the drag enter event.
- nsActions = QT_PREPEND_NAMESPACE(qt_mac_mapDropAction)(qDEEvent.dropAction());
+ nsActions = NSDragOperationNone;
+ // Save as ignored in the answer rect.
+ qDMEvent.setDropAction(Qt::IgnoreAction);
} else {
nsActions = QT_PREPEND_NAMESPACE(qt_mac_mapDropAction)(qDMEvent.dropAction());
}
@@ -325,7 +327,6 @@ extern "C" {
return nsActions;
}
}
-
- (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender
{
// NB: This function is called from QCoocaWindow/QCocoaPanel rather than directly
@@ -366,13 +367,15 @@ extern "C" {
qDMEvent.setDropAction(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction);
qDMEvent.accept();
QApplication::sendEvent(qwidget, &qDMEvent);
- qt_mac_copy_answer_rect(qDMEvent);
NSDragOperation operation = qt_mac_mapDropAction(qDMEvent.dropAction());
if (!qDMEvent.isAccepted() || qDMEvent.dropAction() == Qt::IgnoreAction) {
// ignore this event (we will still receive further notifications)
operation = NSDragOperationNone;
+ // Save as ignored in the answer rect.
+ qDMEvent.setDropAction(Qt::IgnoreAction);
}
+ qt_mac_copy_answer_rect(qDMEvent);
return operation;
}
@@ -735,7 +738,7 @@ extern "C" {
NSPoint windowPoint = [theEvent locationInWindow];
NSPoint globalPoint = [[theEvent window] convertBaseToScreen:windowPoint];
NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
- QPoint qlocal = QPoint(localPoint.x, flipYCoordinate(localPoint.y));
+ QPoint qlocal = QPoint(localPoint.x, localPoint.y);
QPoint qglobal = QPoint(globalPoint.x, flipYCoordinate(globalPoint.y));
Qt::MouseButtons buttons = QApplication::mouseButtons();
bool wheelOK = false;
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index c4a25e1..eedf0a7 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -409,7 +409,7 @@ QMouseEventEx::~QMouseEventEx()
consider a top-level window A containing a child B which in turn contains a
child C (all with mouse tracking enabled):
- \image hoverEvents.png
+ \image hoverevents.png
Now, if you move the cursor from the top to the bottom in the middle of A,
you will get the following QEvent::MouseMove events:
@@ -432,7 +432,7 @@ QMouseEventEx::~QMouseEventEx()
\o A::HoverMove, B::HoverMove
\o A::HoverMove, B::HoverMove, C::HoverMove
\endlist
-
+
*/
/*!
@@ -3023,7 +3023,7 @@ QShowEvent::~QShowEvent()
This event is only used to notify the application of a request.
It may be safely ignored.
- \note This class is currently supported for Mac Os X only.
+ \note This class is currently supported for Mac OS X only.
*/
/*!
@@ -3066,6 +3066,8 @@ QFileOpenEvent::~QFileOpenEvent()
\fn QUrl QFileOpenEvent::url() const
Returns the url that is being opened.
+
+ \since 4.6
*/
QUrl QFileOpenEvent::url() const
{
diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm
index e0eebfd..ab1e2a1 100644
--- a/src/gui/kernel/qeventdispatcher_mac.mm
+++ b/src/gui/kernel/qeventdispatcher_mac.mm
@@ -90,11 +90,16 @@
#ifndef QT_NO_THREAD
# include "qmutex.h"
+#endif
QT_BEGIN_NAMESPACE
QT_USE_NAMESPACE
-#endif
+
+/*****************************************************************************
+ Internal variables and functions
+ *****************************************************************************/
+bool qt_blockCocoaSettingModalWindowLevel = false;
/*****************************************************************************
Externals
@@ -540,6 +545,12 @@ bool QEventDispatcherMac::processEvents(QEventLoop::ProcessEventsFlags flags)
{
Q_D(QEventDispatcherMac);
d->interrupt = false;
+
+#ifdef QT_MAC_USE_COCOA
+ bool interruptLater = false;
+ QtMacInterruptDispatcherHelp::cancelInterruptLater();
+#endif
+
// In case we end up recursing while we now process events, make sure
// that we send remaining posted Qt events before this call returns:
wakeUp();
@@ -554,25 +565,26 @@ bool QEventDispatcherMac::processEvents(QEventLoop::ProcessEventsFlags flags)
QMacCocoaAutoReleasePool pool;
NSEvent* event = 0;
- // If Qt is used as a plugin, or just added into a native cocoa
- // application, we should not run or stop NSApplication;
- // This will be done from outside Qt.
- // And if processEvents is called manually (rather than from QEventLoop), we
- // cannot enter a tight loop and block the call, but instead return after one flush:
- bool canExec_3rdParty = d->nsAppRunCalledByQt || ![NSApp isRunning];
- bool canExec_Qt = flags & QEventLoop::DialogExec || flags & QEventLoop::EventLoopExec;
+ // If Qt is used as a plugin, or as an extension in a native cocoa
+ // application, we should not run or stop NSApplication; This will be
+ // done from the application itself. And if processEvents is called
+ // manually (rather than from a QEventLoop), we cannot enter a tight
+ // loop and block this call, but instead we need to return after one flush:
+ const bool canExec_3rdParty = d->nsAppRunCalledByQt || ![NSApp isRunning];
+ const bool canExec_Qt = flags & QEventLoop::DialogExec || flags & QEventLoop::EventLoopExec;
if (canExec_Qt && canExec_3rdParty) {
// We can use exec-mode, meaning that we can stay in a tight loop until
- // interrupted. This is mostly an optimization, but it also allow us
- // to use [NSApp run], which is the recommended way of running applications
- // in cocoa. [NSApp run] should be called at least once for any cocoa app.
+ // interrupted. This is mostly an optimization, but it allow us to use
+ // [NSApp run], which is the normal code path for cocoa applications.
if (NSModalSession session = d->currentModalSession()) {
QBoolBlocker execGuard(d->currentExecIsNSAppRun, false);
- while (!d->interrupt && [NSApp runModalSession:session] == NSRunContinuesResponse)
+
+ while ([NSApp runModalSession:session] == NSRunContinuesResponse && !d->interrupt)
qt_mac_waitForMoreModalSessionEvents();
+
if (!d->interrupt && session == d->currentModalSessionCached) {
- // INVARIANT: Someone called e.g. [NSApp stopModal:] from outside the event
+ // Someone called [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();
@@ -583,54 +595,63 @@ bool QEventDispatcherMac::processEvents(QEventLoop::ProcessEventsFlags flags)
[NSApp run];
}
retVal = true;
- } else do {
- // INVARIANT: We cannot block the thread (and run in a tight loop).
+ } else {
+ // We cannot block the thread (and run in a tight loop).
// Instead we will process all current pending events and return.
- bool mustRelease = false;
-
- if (!(flags & QEventLoop::ExcludeUserInputEvents) && !d->queuedUserInputEvents.isEmpty()) {
- // Process a pending user input event
- mustRelease = true;
- event = static_cast<NSEvent *>(d->queuedUserInputEvents.takeFirst());
- } else {
- if (NSModalSession session = d->currentModalSession()) {
- if (flags & QEventLoop::WaitForMoreEvents)
- qt_mac_waitForMoreModalSessionEvents();
- 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;
+ d->ensureNSAppInitialized();
+ do {
+ bool releaseEvent = false;
+
+ if (!(flags & QEventLoop::ExcludeUserInputEvents)
+ && !d->queuedUserInputEvents.isEmpty()) {
+ // Process a pending user input event
+ releaseEvent = true;
+ event = static_cast<NSEvent *>(d->queuedUserInputEvents.takeFirst());
} else {
- event = [NSApp nextEventMatchingMask:NSAnyEventMask
- untilDate:nil
- inMode:NSDefaultRunLoopMode
- dequeue: YES];
-
- if (event != nil) {
- if (flags & QEventLoop::ExcludeUserInputEvents) {
- if (IsMouseOrKeyEvent(event)) {
- // retain event here?
- [event retain];
- d->queuedUserInputEvents.append(event);
- continue;
+ if (NSModalSession session = d->currentModalSession()) {
+ if (flags & QEventLoop::WaitForMoreEvents)
+ qt_mac_waitForMoreModalSessionEvents();
+ NSInteger status = [NSApp runModalSession:session];
+ if (status != NSRunContinuesResponse && session == d->currentModalSessionCached) {
+ // INVARIANT: Someone called [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 {
+ event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:nil
+ inMode:NSDefaultRunLoopMode
+ dequeue: YES];
+
+ if (event != nil) {
+ if (flags & QEventLoop::ExcludeUserInputEvents) {
+ if (IsMouseOrKeyEvent(event)) {
+ [event retain];
+ d->queuedUserInputEvents.append(event);
+ continue;
+ }
}
}
}
}
- }
- if (event) {
- if (!filterEvent(event) && qt_mac_send_event(flags, event, 0))
- retVal = true;
- if (mustRelease)
- [event release];
- }
- } while(!d->interrupt && event != nil);
-
+ if (event) {
+ if (!filterEvent(event) && qt_mac_send_event(flags, event, 0))
+ retVal = true;
+ if (releaseEvent)
+ [event release];
+ }
+ } while (!d->interrupt && event != nil);
+
+ // Since the window that holds modality might have changed while processing
+ // events, we we need to interrupt when we return back the previous process
+ // event recursion to ensure that we spin the correct modal session.
+ // We do the interruptLater at the end of the function to ensure that we don't
+ // disturb the 'wait for more events' below (as deleteLater will post an event):
+ interruptLater = true;
+ }
#else
do {
EventRef event;
@@ -682,25 +703,19 @@ bool QEventDispatcherMac::processEvents(QEventLoop::ProcessEventsFlags flags)
}
}
+ // If we're interrupted, we need to interrupt the _current_
+ // recursion as well to check if it is still supposed to be
+ // executing. This way we wind down the stack until we land
+ // on a recursion that again calls processEvents (typically
+ // from QEventLoop), and set interrupt to false:
+ if (d->interrupt)
+ interrupt();
+
#ifdef QT_MAC_USE_COCOA
- // In case we _now_ process events using [NSApp run], we need to stop it to
- // ensure that:
- // 1. the QEventLoop that called us is still executing, or
- // 2. we have a modal session that needs to be spun instead.
- // In case this is a plain call to processEvents (perhaps from a loop)
- // from the application (rather than from a QEventLoop), we delay the
- // interrupting until we/ actually enter a lower loop level (hence the
- // deffered delete of the object below):
- QtMacInterruptDispatcherHelp::interruptLater();
+ if (interruptLater)
+ QtMacInterruptDispatcherHelp::interruptLater();
#endif
- if (d->interrupt) {
- // We should continue to leave all recursion to processEvents until
- // processEvents is called again (e.g. from a QEventLoop that
- // was not yet told to quit:
- interrupt();
- }
-
return retVal;
}
@@ -729,39 +744,60 @@ void QEventDispatcherMac::flush()
*****************************************************************************/
MacTimerHash QEventDispatcherMacPrivate::macTimerHash;
bool QEventDispatcherMacPrivate::blockSendPostedEvents = false;
+bool QEventDispatcherMacPrivate::interrupt = false;
#ifdef QT_MAC_USE_COCOA
QStack<QCocoaModalSessionInfo> QEventDispatcherMacPrivate::cocoaModalSessionStack;
bool QEventDispatcherMacPrivate::currentExecIsNSAppRun = false;
+bool QEventDispatcherMacPrivate::modalSessionsTemporarilyStopped = false;
bool QEventDispatcherMacPrivate::nsAppRunCalledByQt = false;
+bool QEventDispatcherMacPrivate::cleanupModalSessionsNeeded = false;
NSModalSession QEventDispatcherMacPrivate::currentModalSessionCached = 0;
-int QEventDispatcherMacPrivate::activeModalSessionCount()
+void QEventDispatcherMacPrivate::ensureNSAppInitialized()
{
- // Returns the number of modal sessions created
- // (and not just pushed onto the stack, pending to be created)
- int count = 0;
- for (int i=cocoaModalSessionStack.size()-1; i>=0; --i) {
- QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
- if (info.session)
- ++count;
- }
- return count;
+ // Some elements in Cocoa require NSApplication to be running before
+ // they get fully initialized, in particular the menu bar. This
+ // function is intended for cases where a dialog is told to execute before
+ // QApplication::exec is called, or the application spins the events loop
+ // manually rather than calling QApplication:exec.
+ // The function makes sure that NSApplication starts running, but stops
+ // it again as soon as the send posted events callback is called. That way
+ // we let Cocoa finish the initialization it seems to need. We'll only
+ // apply this trick at most once for any application, and we avoid doing it
+ // for the common case where main just starts QApplication::exec.
+ if (nsAppRunCalledByQt || [NSApp isRunning])
+ return;
+ nsAppRunCalledByQt = true;
+ QBoolBlocker block1(interrupt, true);
+ QBoolBlocker block2(currentExecIsNSAppRun, true);
+ [NSApp run];
}
void QEventDispatcherMacPrivate::temporarilyStopAllModalSessions()
{
- // Stop all created modal session, and as such, make then
- // pending again. The next call to currentModalSession will
- // recreate the session on top again:
+ // Flush, and Stop, all created modal session, and as
+ // such, make them pending again. The next call to
+ // currentModalSession will recreate them again. The
+ // reason to stop all session like this is that otherwise
+ // a call [NSApp stop] would not stop NSApp, but rather
+ // the current modal session. So if we need to stop NSApp
+ // we need to stop all the modal session first. To avoid changing
+ // the stacking order of the windows while doing so, we put
+ // up a block that is used in QCocoaWindow and QCocoaPanel:
+ QBoolBlocker block1(blockSendPostedEvents, true);
+ QBoolBlocker block2(qt_blockCocoaSettingModalWindowLevel, true);
+
int stackSize = cocoaModalSessionStack.size();
for (int i=stackSize-1; i>=0; --i) {
QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
if (info.session) {
+ [NSApp runModalSession:info.session];
[NSApp endModalSession:info.session];
info.session = 0;
}
}
+ modalSessionsTemporarilyStopped = true;
currentModalSessionCached = 0;
}
@@ -775,23 +811,6 @@ NSModalSession QEventDispatcherMacPrivate::currentModalSession()
if (cocoaModalSessionStack.isEmpty())
return 0;
- // Since this code will end up calling our Qt event handler
- // (also from beginModalSessionForWindow), we need to block
- // that to avoid side effects of events beeing delivered:
- QBoolBlocker block(blockSendPostedEvents, true);
-
- if (![NSApp isRunning]) {
- // Sadly, we need to introduce this little event flush
- // to stop dialogs from blinking/poping in front if a
- // modal session restart was needed:
- while (NSEvent *event = [NSApp nextEventMatchingMask:0
- untilDate:nil
- inMode:NSDefaultRunLoopMode
- dequeue: YES]) {
- qt_mac_send_event(0, event, 0);
- }
- }
-
int sessionCount = cocoaModalSessionStack.size();
for (int i=0; i<sessionCount; ++i) {
QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
@@ -804,11 +823,28 @@ NSModalSession QEventDispatcherMacPrivate::currentModalSession()
NSWindow *window = qt_mac_window_for(info.widget);
if (!window)
continue;
+
+ ensureNSAppInitialized();
+ QBoolBlocker block1(blockSendPostedEvents, true);
info.session = [NSApp beginModalSessionForWindow:window];
}
currentModalSessionCached = info.session;
}
+ if (modalSessionsTemporarilyStopped && currentModalSessionCached) {
+ // After a call to temporarilyStopAllModalSessions, cocoa have
+ // now posted events to restore ended modal session windows to
+ // the correct window level. Those events will be processed
+ // _after_ our new calls to beginModalSessionForWindow have
+ // taken effect, which will end up stacking the windows wrong on
+ // screen. To work around this, we block cocoa from changing the
+ // stacking order of the windows, and flush out the pending events
+ // (the block is used in QCocoaWindow and QCocoaPanel):
+ QBoolBlocker block1(blockSendPostedEvents, true);
+ QBoolBlocker block2(qt_blockCocoaSettingModalWindowLevel, true);
+ [NSApp runModalSession:currentModalSessionCached];
+ }
+ modalSessionsTemporarilyStopped = false;
return currentModalSessionCached;
}
@@ -844,6 +880,34 @@ void QEventDispatcherMacPrivate::updateChildrenWorksWhenModal()
}
}
+void QEventDispatcherMacPrivate::cleanupModalSessions()
+{
+ // Go through the list of modal sessions, and end those
+ // that no longer has a widget assosiated; no widget means
+ // the the session has logically ended. The reason we wait like
+ // this to actually end the sessions for real (rather than at the
+ // point they were marked as stopped), is that ending a session
+ // when no other session runs below it on the stack will make cocoa
+ // drop some events on the floor.
+ QMacCocoaAutoReleasePool pool;
+ int stackSize = cocoaModalSessionStack.size();
+
+ for (int i=stackSize-1; i>=0; --i) {
+ QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
+ if (info.widget) {
+ currentModalSessionCached = info.session;
+ break;
+ }
+ cocoaModalSessionStack.remove(i);
+ currentModalSessionCached = 0;
+ if (info.session)
+ [NSApp endModalSession:info.session];
+ }
+
+ updateChildrenWorksWhenModal();
+ cleanupModalSessionsNeeded = false;
+}
+
void QEventDispatcherMacPrivate::beginModalSession(QWidget *widget)
{
// Add a new, empty (null), NSModalSession to the stack.
@@ -852,7 +916,7 @@ void QEventDispatcherMacPrivate::beginModalSession(QWidget *widget)
// is non-zero, and the session pointer is zero (it will become active upon a call to
// currentModalSession). A QCocoaModalSessionInfo is considered pending to be stopped if
// the widget pointer is zero, and the session pointer is non-zero (it will be fully
- // stopped in endModalSession().
+ // stopped in cleanupModalSessions()).
QCocoaModalSessionInfo info = {widget, 0};
cocoaModalSessionStack.push(info);
updateChildrenWorksWhenModal();
@@ -869,38 +933,21 @@ void QEventDispatcherMacPrivate::endModalSession(QWidget *widget)
int stackSize = cocoaModalSessionStack.size();
for (int i=stackSize-1; i>=0; --i) {
QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
- if (info.widget == widget)
+ if (info.widget == widget) {
info.widget = 0;
- }
-
- // Now we stop, and remove, all sessions marked as pending
- // to be stopped on _top_ of the stack, if any:
- bool needToInterruptEventDispatcher = false;
- bool needToUpdateChildrenWorksWhenModal = false;
-
- for (int i=stackSize-1; i>=0; --i) {
- QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
- if (info.widget)
- break;
- cocoaModalSessionStack.remove(i);
- needToUpdateChildrenWorksWhenModal = true;
- currentModalSessionCached = 0;
- if (info.session) {
- [NSApp endModalSession:info.session];
- needToInterruptEventDispatcher = true;
+ if (i == stackSize-1) {
+ // The top sessions ended. Interrupt the event dispatcher
+ // to start spinning the correct session immidiatly:
+ cleanupModalSessionsNeeded = true;
+ QEventDispatcherMac::instance()->interrupt();
+ }
}
}
-
- if (needToUpdateChildrenWorksWhenModal)
- updateChildrenWorksWhenModal();
- if (needToInterruptEventDispatcher)
- QEventDispatcherMac::instance()->interrupt();
}
#endif
QEventDispatcherMacPrivate::QEventDispatcherMacPrivate()
- : interrupt(false)
{
}
@@ -959,13 +1006,39 @@ Boolean QEventDispatcherMacPrivate::postedEventSourceEqualCallback(const void *i
inline static void processPostedEvents(QEventDispatcherMacPrivate *const d, const bool blockSendPostedEvents)
{
- if (blockSendPostedEvents || d->interrupt) {
+ if (blockSendPostedEvents) {
+ // We're told to not send posted events (because the event dispatcher
+ // is currently working on setting up the correct session to run). But
+ // we still need to make sure that we don't fall asleep until pending events
+ // are sendt, so we just signal this need, and return:
CFRunLoopSourceSignal(d->postedEventsSource);
- } else {
- if (!d->threadData->canWait || (d->serialNumber != d->lastSerial)) {
- d->lastSerial = d->serialNumber;
- QApplicationPrivate::sendPostedEvents(0, 0, d->threadData);
+ return;
+ }
+
+#ifdef QT_MAC_USE_COCOA
+ if (d->cleanupModalSessionsNeeded)
+ d->cleanupModalSessions();
+#endif
+
+ if (d->interrupt) {
+#ifdef QT_MAC_USE_COCOA
+ if (d->currentExecIsNSAppRun) {
+ // The event dispatcher has been interrupted. But since
+ // [NSApplication run] is running the event loop, we
+ // delayed stopping it until now (to let cocoa process
+ // pending cocoa events first).
+ if (d->currentModalSessionCached)
+ d->temporarilyStopAllModalSessions();
+ [NSApp stop:NSApp];
+ d->cancelWaitForMoreEvents();
}
+#endif
+ return;
+ }
+
+ if (!d->threadData->canWait || (d->serialNumber != d->lastSerial)) {
+ d->lastSerial = d->serialNumber;
+ QApplicationPrivate::sendPostedEvents(0, 0, d->threadData);
}
}
@@ -983,6 +1056,19 @@ void QEventDispatcherMacPrivate::postedEventsSourcePerformCallback(void *info)
processPostedEvents(static_cast<QEventDispatcherMacPrivate *>(info), blockSendPostedEvents);
}
+#ifdef QT_MAC_USE_COCOA
+void QEventDispatcherMacPrivate::cancelWaitForMoreEvents()
+{
+ // In case the event dispatcher is waiting for more
+ // events somewhere, we post a dummy event to wake it up:
+ QMacCocoaAutoReleasePool pool;
+ static const short NSAppShouldStopForQt = SHRT_MAX;
+ [NSApp postEvent:[NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint
+ modifierFlags:0 timestamp:0. windowNumber:0 context:0
+ subtype:NSAppShouldStopForQt data1:0 data2:0] atStart:NO];
+}
+#endif
+
void QEventDispatcherMac::interrupt()
{
Q_D(QEventDispatcherMac);
@@ -992,20 +1078,14 @@ void QEventDispatcherMac::interrupt()
#ifndef QT_MAC_USE_COCOA
CFRunLoopStop(mainRunLoop());
#else
- QMacCocoaAutoReleasePool pool;
- // In case we wait for more events inside
- // processEvents (or NSApp run), post a dummy to wake it up:
- static const short NSAppShouldStopForQt = SHRT_MAX;
- [NSApp postEvent:[NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint
- modifierFlags:0 timestamp:0. windowNumber:0 context:0
- subtype:NSAppShouldStopForQt data1:0 data2:0] atStart:NO];
-
- if (d->activeModalSessionCount() == 0) {
- // We should only stop NSApp if we actually started it (and
- // not some 3rd party application, e.g. if we are a plugin).
- if (d->nsAppRunCalledByQt)
- [NSApp stop:NSApp];
- }
+ // We do nothing more here than setting d->interrupt = true, and
+ // poke the event loop if it is sleeping. Actually stopping
+ // NSApp, or the current modal session, is done inside the send
+ // posted events callback. We do this to ensure that all current pending
+ // cocoa events gets delivered before we stop. Otherwise, if we now stop
+ // the last event loop recursion, cocoa will just drop pending posted
+ // events on the floor before we get a chance to reestablish a new session.
+ d->cancelWaitForMoreEvents();
#endif
}
@@ -1046,17 +1126,18 @@ QEventDispatcherMac::~QEventDispatcherMac()
CFRelease(d->firstTimeObserver);
}
-/////////////////////////////////////////////////////////////////////////////
-
#ifdef QT_MAC_USE_COCOA
QtMacInterruptDispatcherHelp* QtMacInterruptDispatcherHelp::instance = 0;
QtMacInterruptDispatcherHelp::QtMacInterruptDispatcherHelp() : cancelled(false)
{
- // This is the whole point of encapsulation this code
- // inside a class; we can make the code (inside destructor)
- // execute on lower loop level:
+ // The whole point of this class is that we enable a way to interrupt
+ // the event dispatcher when returning back to a lower recursion level
+ // than where interruptLater was called. This is needed to detect if
+ // [NSApp run] should still be running at the recursion level it is at.
+ // Since the interrupt is canceled if processEvents is called before
+ // this object gets deleted, we also avoid interrupting unnecessary.
deleteLater();
}
@@ -1064,34 +1145,26 @@ QtMacInterruptDispatcherHelp::~QtMacInterruptDispatcherHelp()
{
if (cancelled)
return;
-
instance = 0;
-
- if (QEventDispatcherMacPrivate::currentExecIsNSAppRun) {
- int activeCount = QEventDispatcherMacPrivate::activeModalSessionCount();
- if (activeCount > 0) {
- // The problem we now have hit: [NSApp stop] will not stop NSApp
- // if a session is active; it will stop the session instead.
- // So to stop NSApp, we need to temporarily stop all the
- // sessions, then stop NSApp, then restart the session on top again.
- // We need to do this to ensure that we're not stuck inside
- // [NSApp run] when we really should be running a modal session:
- QEventDispatcherMacPrivate::temporarilyStopAllModalSessions();
- }
- }
- // Always interrupt once more in case the modal session stack changed
- // while processEvents was called manually from within the application:
QEventDispatcherMac::instance()->interrupt();
}
-void QtMacInterruptDispatcherHelp::interruptLater() {
- if (instance) {
- instance->cancelled = true;
- delete instance;
- }
+void QtMacInterruptDispatcherHelp::cancelInterruptLater()
+{
+ if (!instance)
+ return;
+ instance->cancelled = true;
+ delete instance;
+ instance = 0;
+}
+
+void QtMacInterruptDispatcherHelp::interruptLater()
+{
+ cancelInterruptLater();
instance = new QtMacInterruptDispatcherHelp;
}
#endif
QT_END_NAMESPACE
+
diff --git a/src/gui/kernel/qeventdispatcher_mac_p.h b/src/gui/kernel/qeventdispatcher_mac_p.h
index dfcb91f..205f564 100644
--- a/src/gui/kernel/qeventdispatcher_mac_p.h
+++ b/src/gui/kernel/qeventdispatcher_mac_p.h
@@ -174,13 +174,17 @@ public:
static QStack<QCocoaModalSessionInfo> cocoaModalSessionStack;
static bool currentExecIsNSAppRun;
static bool nsAppRunCalledByQt;
+ static bool cleanupModalSessionsNeeded;
+ static bool modalSessionsTemporarilyStopped;
static NSModalSession currentModalSessionCached;
- static void updateChildrenWorksWhenModal();
static NSModalSession currentModalSession();
- static int activeModalSessionCount();
+ static void updateChildrenWorksWhenModal();
static void temporarilyStopAllModalSessions();
static void beginModalSession(QWidget *widget);
static void endModalSession(QWidget *widget);
+ static void cancelWaitForMoreEvents();
+ static void cleanupModalSessions();
+ static void ensureNSAppInitialized();
#endif
MacSocketHash macSockets;
@@ -190,7 +194,7 @@ public:
CFRunLoopObserverRef firstTimeObserver;
QAtomicInt serialNumber;
int lastSerial;
- bool interrupt;
+ static bool interrupt;
private:
static Boolean postedEventSourceEqualCallback(const void *info1, const void *info2);
static void postedEventsSourcePerformCallback(void *info);
@@ -211,6 +215,7 @@ class QtMacInterruptDispatcherHelp : public QObject
public:
static void interruptLater();
+ static void cancelInterruptLater();
};
#endif
diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp
index 192f9ac..d7cbebd 100644
--- a/src/gui/kernel/qgesturemanager.cpp
+++ b/src/gui/kernel/qgesturemanager.cpp
@@ -187,10 +187,8 @@ QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recogni
#endif
}
- QList<QGesture *> states =
- m_objectGestures.value(QGestureManager::ObjectGesture(object, type));
// check if the QGesture for this recognizer has already been created
- foreach (QGesture *state, states) {
+ foreach (QGesture *state, m_objectGestures.value(QGestureManager::ObjectGesture(object, type))) {
if (m_gestureToRecognizer.value(state) == recognizer)
return state;
}
@@ -215,14 +213,13 @@ QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recogni
return state;
}
-bool QGestureManager::filterEventThroughContexts(const QMultiHash<QObject *,
+bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *,
Qt::GestureType> &contexts,
QEvent *event)
{
QSet<QGesture *> triggeredGestures;
QSet<QGesture *> finishedGestures;
QSet<QGesture *> newMaybeGestures;
- QSet<QGesture *> canceledGestures;
QSet<QGesture *> notGestures;
// TODO: sort contexts by the gesture type and check if one of the contexts
@@ -231,7 +228,7 @@ bool QGestureManager::filterEventThroughContexts(const QMultiHash<QObject *,
bool ret = false;
// filter the event through recognizers
- typedef QHash<QObject *, Qt::GestureType>::const_iterator ContextIterator;
+ typedef QMultiMap<QObject *, Qt::GestureType>::const_iterator ContextIterator;
for (ContextIterator cit = contexts.begin(), ce = contexts.end(); cit != ce; ++cit) {
Qt::GestureType gestureType = cit.value();
QMap<Qt::GestureType, QGestureRecognizer *>::const_iterator
@@ -271,6 +268,9 @@ bool QGestureManager::filterEventThroughContexts(const QMultiHash<QObject *,
}
}
}
+ if (triggeredGestures.isEmpty() && finishedGestures.isEmpty()
+ && newMaybeGestures.isEmpty() && notGestures.isEmpty())
+ return ret;
QSet<QGesture *> startedGestures = triggeredGestures - m_activeGestures;
triggeredGestures &= m_activeGestures;
@@ -280,8 +280,7 @@ bool QGestureManager::filterEventThroughContexts(const QMultiHash<QObject *,
// check if a running gesture switched back to not gesture state,
// i.e. were canceled
- QSet<QGesture *> activeToCancelGestures = m_activeGestures & notGestures;
- canceledGestures += activeToCancelGestures;
+ QSet<QGesture *> canceledGestures = m_activeGestures & notGestures;
// start timers for new gestures in maybe state
foreach (QGesture *state, newMaybeGestures) {
@@ -449,14 +448,14 @@ void QGestureManager::cleanupGesturesForRemovedRecognizer(QGesture *gesture)
// return true if accepted (consumed)
bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
{
- QSet<Qt::GestureType> types;
- QMultiHash<QObject *, Qt::GestureType> contexts;
+ QMap<Qt::GestureType, int> types;
+ QMultiMap<QObject *, Qt::GestureType> contexts;
QWidget *w = receiver;
typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
if (!w->d_func()->gestureContext.isEmpty()) {
for(ContextIterator it = w->d_func()->gestureContext.begin(),
e = w->d_func()->gestureContext.end(); it != e; ++it) {
- types.insert(it.key());
+ types.insert(it.key(), 0);
contexts.insertMulti(w, it.key());
}
}
@@ -468,7 +467,7 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
e = w->d_func()->gestureContext.end(); it != e; ++it) {
if (!(it.value() & Qt::DontStartGestureOnChildren)) {
if (!types.contains(it.key())) {
- types.insert(it.key());
+ types.insert(it.key(), 0);
contexts.insertMulti(w, it.key());
}
}
@@ -477,20 +476,20 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
break;
w = w->parentWidget();
}
- return filterEventThroughContexts(contexts, event);
+ return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event);
}
#ifndef QT_NO_GRAPHICSVIEW
bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event)
{
- QSet<Qt::GestureType> types;
- QMultiHash<QObject *, Qt::GestureType> contexts;
+ QMap<Qt::GestureType, int> types;
+ QMultiMap<QObject *, Qt::GestureType> contexts;
QGraphicsObject *item = receiver;
if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) {
typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
- types.insert(it.key());
+ types.insert(it.key(), 0);
contexts.insertMulti(item, it.key());
}
}
@@ -503,20 +502,23 @@ bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event)
e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
if (!(it.value() & Qt::DontStartGestureOnChildren)) {
if (!types.contains(it.key())) {
- types.insert(it.key());
+ types.insert(it.key(), 0);
contexts.insertMulti(item, it.key());
}
}
}
item = item->parentObject();
}
- return filterEventThroughContexts(contexts, event);
+ return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event);
}
#endif
-bool QGestureManager::filterEvent(QGesture *state, QEvent *event)
+bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
{
- QMultiHash<QObject *, Qt::GestureType> contexts;
+ if (!m_gestureToRecognizer.contains(static_cast<QGesture *>(receiver)))
+ return false;
+ QGesture *state = static_cast<QGesture *>(receiver);
+ QMultiMap<QObject *, Qt::GestureType> contexts;
contexts.insert(state, state->gestureType());
return filterEventThroughContexts(contexts, event);
}
diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h
index 4efa10b..5329d1d 100644
--- a/src/gui/kernel/qgesturemanager_p.h
+++ b/src/gui/kernel/qgesturemanager_p.h
@@ -73,7 +73,7 @@ public:
void unregisterGestureRecognizer(Qt::GestureType type);
bool filterEvent(QWidget *receiver, QEvent *event);
- bool filterEvent(QGesture *receiver, QEvent *event);
+ bool filterEvent(QObject *receiver, QEvent *event);
#ifndef QT_NO_GRAPHICSVIEW
bool filterEvent(QGraphicsObject *receiver, QEvent *event);
#endif //QT_NO_GRAPHICSVIEW
@@ -86,7 +86,7 @@ public:
protected:
void timerEvent(QTimerEvent *event);
- bool filterEventThroughContexts(const QMultiHash<QObject *, Qt::GestureType> &contexts,
+ bool filterEventThroughContexts(const QMultiMap<QObject *, Qt::GestureType> &contexts,
QEvent *event);
private:
diff --git a/src/gui/kernel/qguieventdispatcher_glib.cpp b/src/gui/kernel/qguieventdispatcher_glib.cpp
index fc6bc54..475d245 100644
--- a/src/gui/kernel/qguieventdispatcher_glib.cpp
+++ b/src/gui/kernel/qguieventdispatcher_glib.cpp
@@ -152,6 +152,8 @@ static gboolean x11EventSourceDispatch(GSource *s, GSourceFunc callback, gpointe
out:
+ source->d->runTimersOnceWithNormalPriority();
+
if (callback)
callback(user_data);
return true;
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index 08f8bb5..737e9d7 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -103,6 +103,14 @@ public:
int defaultDpiY;
WId curWin;
int virtualMouseLastKey;
+ enum PressedKeys {
+ Select = 0x1,
+ Right = 0x2,
+ Down = 0x4,
+ Left = 0x8,
+ Up = 0x10
+ };
+ int virtualMousePressedKeys; // of the above type, but avoids casting problems
int virtualMouseAccel;
int virtualMouseMaxAccel;
#ifndef Q_SYMBIAN_FIXED_POINTER_CURSORS
@@ -192,6 +200,12 @@ private:
TKeyResponse OfferKeyEvent(const TKeyEvent& aKeyEvent,TEventCode aType);
TKeyResponse sendKeyEvent(QWidget *widget, QKeyEvent *keyEvent);
bool sendMouseEvent(QWidget *widget, QMouseEvent *mEvent);
+ void sendMouseEvent(
+ QWidget *receiver,
+ QEvent::Type type,
+ const QPoint &globalPos,
+ Qt::MouseButton button,
+ Qt::KeyboardModifiers modifiers);
void HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation );
#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
void translateAdvancedPointerEvent(const TAdvancedPointerEvent *event);
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index e0b1499..d28aa7e 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -9782,13 +9782,12 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
}
#endif
- if (newParent) {
- if (QWidgetBackingStore *oldBs = oldtlw->d_func()->maybeBackingStore()) {
+ if (QWidgetBackingStore *oldBs = oldtlw->d_func()->maybeBackingStore()) {
+ if (newParent)
oldBs->removeDirtyWidget(this);
- // Move the widget and all its static children from
- // the old backing store to the new one.
- oldBs->moveStaticWidgets(this);
- }
+ // Move the widget and all its static children from
+ // the old backing store to the new one.
+ oldBs->moveStaticWidgets(this);
}
if ((QApplicationPrivate::app_compile_version < 0x040200
@@ -11880,16 +11879,20 @@ void QWidget::ungrabGesture(Qt::GestureType gesture)
mouse when a mouse button is pressed and keeps it until the last
button is released.
- Note that only visible widgets can grab mouse input. If
- isVisible() returns false for a widget, that widget cannot call
- grabMouse().
+ \note Only visible widgets can grab mouse input. If isVisible()
+ returns false for a widget, that widget cannot call grabMouse().
+
+ \note \bold{(Mac OS X developers)} For \e Cocoa, calling
+ grabMouse() on a widget only works when the mouse is inside the
+ frame of that widget. For \e Carbon, it works outside the widget's
+ frame as well, like for Windows and X11.
\sa releaseMouse() grabKeyboard() releaseKeyboard()
*/
/*!
\fn void QWidget::grabMouse(const QCursor &cursor)
- \overload
+ \overload grabMouse()
Grabs the mouse input and changes the cursor shape.
@@ -11899,6 +11902,8 @@ void QWidget::ungrabGesture(Qt::GestureType gesture)
\warning Grabbing the mouse might lock the terminal.
+ \note \bold{(Mac OS X developers)} See the note in QWidget::grabMouse().
+
\sa releaseMouse(), grabKeyboard(), releaseKeyboard(), setCursor()
*/
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 34a9eed..35e7505 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -1888,13 +1888,15 @@ void QWidgetPrivate::determineWindowClass()
wclass = kDocumentWindowClass;
else if(popup || (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 && type == Qt::SplashScreen))
wclass = kModalWindowClass;
- else if(q->testAttribute(Qt::WA_ShowModal) || type == Qt::Dialog)
+ else if(type == Qt::Dialog)
wclass = kMovableModalWindowClass;
else if(type == Qt::ToolTip)
wclass = kHelpWindowClass;
else if(type == Qt::Tool || (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5
&& type == Qt::SplashScreen))
wclass = kFloatingWindowClass;
+ else if(q->testAttribute(Qt::WA_ShowModal))
+ wclass = kMovableModalWindowClass;
else
wclass = kDocumentWindowClass;
@@ -1998,8 +2000,6 @@ void QWidgetPrivate::determineWindowClass()
for(int i = 0; tmp_wattr && known_attribs[i].name; i++) {
if((tmp_wattr & known_attribs[i].tag) == known_attribs[i].tag) {
tmp_wattr ^= known_attribs[i].tag;
- qDebug("Qt: internal: * %s %s", known_attribs[i].name,
- (GetAvailableWindowAttributes(wclass) & known_attribs[i].tag) ? "" : "(*)");
}
}
if(tmp_wattr)
@@ -3309,13 +3309,23 @@ void QWidgetPrivate::show_sys()
#else
// sync the opacity value back (in case of a fade).
[window setAlphaValue:q->windowOpacity()];
- [window makeKeyAndOrderFront:window];
- // If this window is app modal, we need to start spinning
- // a modal session for it. Interrupting
- // the event dispatcher will make this happend:
- if (data.window_modality == Qt::ApplicationModal)
- QEventDispatcherMac::instance()->interrupt();
+ QWidget *top = 0;
+ if (QApplicationPrivate::tryModalHelper(q, &top)) {
+ [window makeKeyAndOrderFront:window];
+ // If this window is app modal, we need to start spinning
+ // a modal session for it. Interrupting
+ // the event dispatcher will make this happend:
+ if (data.window_modality == Qt::ApplicationModal)
+ QEventDispatcherMac::instance()->interrupt();
+ } else {
+ // The window is modally shaddowed, so we need to make
+ // sure that we don't pop in front of the modal window:
+ [window orderFront:window];
+ if (NSWindow *modalWin = qt_mac_window_for(top))
+ [modalWin orderFront:window];
+ }
+
#endif
if (q->windowType() == Qt::Popup) {
if (q->focusWidget())
@@ -3334,8 +3344,6 @@ void QWidgetPrivate::show_sys()
} else if (!q->testAttribute(Qt::WA_ShowWithoutActivating)) {
#ifndef QT_MAC_USE_COCOA
qt_event_request_activate(q);
-#else
- [qt_mac_window_for(q) makeKeyWindow];
#endif
}
} else if(topData()->embedded || !q->parentWidget() || q->parentWidget()->isVisible()) {
@@ -3411,12 +3419,15 @@ void QWidgetPrivate::hide_sys()
}
#endif
}
- if(q->isActiveWindow() && !(q->windowType() == Qt::Popup)) {
+#ifndef QT_MAC_USE_COCOA
+ // If the window we now hide was the active window, we need
+ // to find, and activate another window on screen. NB: Cocoa takes care of this
+ // logic for us (and distinquishes between main windows and key windows)
+ if (q->isActiveWindow() && !(q->windowType() == Qt::Popup)) {
QWidget *w = 0;
if(q->parentWidget())
w = q->parentWidget()->window();
if(!w || (!w->isVisible() && !w->isMinimized())) {
-#ifndef QT_MAC_USE_COCOA
for (WindowPtr wp = GetFrontWindowOfClass(kMovableModalWindowClass, true);
wp; wp = GetNextWindowOfClass(wp, kMovableModalWindowClass, true)) {
if((w = qt_mac_find_window(wp)))
@@ -3436,24 +3447,12 @@ void QWidgetPrivate::hide_sys()
break;
}
}
-#else
- NSArray *windows = [NSApp windows];
- NSUInteger totalWindows = [windows count];
- for (NSUInteger i = 0; i < totalWindows; ++i) {
- OSWindowRef wp = [windows objectAtIndex:i];
- if ((w = qt_mac_find_window(wp)))
- break;
- }
-#endif
}
if(w && w->isVisible() && !w->isMinimized()) {
-#ifndef QT_MAC_USE_COCOA
- qt_event_request_activate(w);
-#else
- [qt_mac_window_for(w) makeKeyWindow];
-#endif
+ qt_event_request_activate(w);
}
}
+#endif
} else {
invalidateBuffer(q->rect());
#ifndef QT_MAC_USE_COCOA
@@ -3671,6 +3670,7 @@ 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()) {
@@ -4493,10 +4493,14 @@ void QWidgetPrivate::createTLSysExtra()
void QWidgetPrivate::deleteTLSysExtra()
{
#ifndef QT_MAC_USE_COCOA
- if(extra->topextra->group) {
+ if (extra->topextra->group) {
qt_mac_release_window_group(extra->topextra->group);
extra->topextra->group = 0;
}
+ if (extra->topextra->windowIcon) {
+ ReleaseIconRef(extra->topextra->windowIcon);
+ extra->topextra->windowIcon = 0;
+ }
#endif
}
diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp
index 0bc9cbc..f9db485 100644
--- a/src/gui/kernel/qwidget_x11.cpp
+++ b/src/gui/kernel/qwidget_x11.cpp
@@ -1084,7 +1084,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
} else {
// release previous focus information participating with
// preedit preservation of qic
- QInputContext *qic = inputContext();
+ QInputContext *qic = QApplicationPrivate::inputContext;
if (qic)
qic->widgetDestroyed(this);
}
diff --git a/src/gui/mac/qt_menu.nib/classes.nib b/src/gui/mac/qt_menu.nib/classes.nib
index fed50a3..0031e0e 100644
--- a/src/gui/mac/qt_menu.nib/classes.nib
+++ b/src/gui/mac/qt_menu.nib/classes.nib
@@ -5,14 +5,6 @@
<key>IBClasses</key>
<array>
<dict>
- <key>CLASS</key>
- <string>FirstResponder</string>
- <key>LANGUAGE</key>
- <string>ObjC</string>
- <key>SUPERCLASS</key>
- <string>NSObject</string>
- </dict>
- <dict>
<key>ACTIONS</key>
<dict>
<key>hide</key>
@@ -52,6 +44,14 @@
<key>SUPERCLASS</key>
<string>NSResponder</string>
</dict>
+ <dict>
+ <key>CLASS</key>
+ <string>FirstResponder</string>
+ <key>LANGUAGE</key>
+ <string>ObjC</string>
+ <key>SUPERCLASS</key>
+ <string>NSObject</string>
+ </dict>
</array>
<key>IBVersion</key>
<string>1</string>
diff --git a/src/gui/mac/qt_menu.nib/info.nib b/src/gui/mac/qt_menu.nib/info.nib
index 768cb8b..02e5cca 100644
--- a/src/gui/mac/qt_menu.nib/info.nib
+++ b/src/gui/mac/qt_menu.nib/info.nib
@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>IBFramework Version</key>
- <string>670</string>
+ <string>672</string>
<key>IBOldestOS</key>
<integer>5</integer>
<key>IBOpenObjects</key>
@@ -11,7 +11,7 @@
<integer>57</integer>
</array>
<key>IBSystem Version</key>
- <string>9G55</string>
+ <string>9L31a</string>
<key>targetFramework</key>
<string>IBCocoaFramework</string>
</dict>
diff --git a/src/gui/mac/qt_menu.nib/keyedobjects.nib b/src/gui/mac/qt_menu.nib/keyedobjects.nib
index 18a6648..3edb0ed 100644
--- a/src/gui/mac/qt_menu.nib/keyedobjects.nib
+++ b/src/gui/mac/qt_menu.nib/keyedobjects.nib
Binary files differ
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 628a109..a6cc9c7 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -379,6 +379,13 @@ symbian {
QMAKE_CXXFLAGS.ARMCC *= -O3
}
+neon {
+ DEFINES += QT_HAVE_NEON
+ HEADERS += painting/qdrawhelper_neon_p.h
+ SOURCES += painting/qdrawhelper_neon.cpp
+ QMAKE_CXXFLAGS *= -mfpu=neon
+}
+
contains(QT_CONFIG, zlib) {
INCLUDEPATH += ../3rdparty/zlib
} else:!contains(QT_CONFIG, no-zlib) {
diff --git a/src/gui/painting/qbezier.cpp b/src/gui/painting/qbezier.cpp
index a6b4cef..f626494 100644
--- a/src/gui/painting/qbezier.cpp
+++ b/src/gui/painting/qbezier.cpp
@@ -497,7 +497,7 @@ static bool addCircle(const QBezier *b, qreal offset, QBezier *o)
cos_a = 1.;
if (cos_a < -1.)
cos_a = -1;
- angles[i] = acos(cos_a)/Q_PI;
+ angles[i] = qAcos(cos_a)/Q_PI;
}
if (angles[0] + angles[1] > 1.) {
@@ -816,17 +816,17 @@ bool QBezier::findIntersections(const QBezier &a, const QBezier &b,
QVector<QPair<qreal, qreal> > *t)
{
if (IntersectBB(a, b)) {
- QPointF la1(fabs((a.x3 - a.x2) - (a.x2 - a.x1)),
- fabs((a.y3 - a.y2) - (a.y2 - a.y1)));
- QPointF la2(fabs((a.x4 - a.x3) - (a.x3 - a.x2)),
- fabs((a.y4 - a.y3) - (a.y3 - a.y2)));
+ QPointF la1(qFabs((a.x3 - a.x2) - (a.x2 - a.x1)),
+ qFabs((a.y3 - a.y2) - (a.y2 - a.y1)));
+ QPointF la2(qFabs((a.x4 - a.x3) - (a.x3 - a.x2)),
+ qFabs((a.y4 - a.y3) - (a.y3 - a.y2)));
QPointF la;
if (la1.x() > la2.x()) la.setX(la1.x()); else la.setX(la2.x());
if (la1.y() > la2.y()) la.setY(la1.y()); else la.setY(la2.y());
- QPointF lb1(fabs((b.x3 - b.x2) - (b.x2 - b.x1)),
- fabs((b.y3 - b.y2) - (b.y2 - b.y1)));
- QPointF lb2(fabs((b.x4 - b.x3) - (b.x3 - b.x2)),
- fabs((b.y4 - b.y3) - (b.y3 - b.y2)));
+ QPointF lb1(qFabs((b.x3 - b.x2) - (b.x2 - b.x1)),
+ qFabs((b.y3 - b.y2) - (b.y2 - b.y1)));
+ QPointF lb2(qFabs((b.x4 - b.x3) - (b.x3 - b.x2)),
+ qFabs((b.y4 - b.y3) - (b.y3 - b.y2)));
QPointF lb;
if (lb1.x() > lb2.x()) lb.setX(lb1.x()); else lb.setX(lb2.x());
if (lb1.y() > lb2.y()) lb.setY(lb1.y()); else lb.setY(lb2.y());
@@ -1120,7 +1120,7 @@ static inline void bindInflectionPoint(const QBezier &bez, const qreal t,
qreal ey = 3 * (right.y2 - right.y3);
qreal s4 = qAbs(6 * (ey * ax - ex * ay) / qSqrt(ex * ex + ey * ey)) + 0.00001f;
- qreal tf = pow(qreal(9 * flatness / s4), qreal(1./3.));
+ qreal tf = qPow(qreal(9 * flatness / s4), qreal(1./3.));
*tMinus = t - (1 - t) * tf;
*tPlus = t + (1 - t) * tf;
}
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index 1d15dac..81d1515 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -605,7 +605,7 @@ static void qt_blend_argb32_on_argb32(uchar *destPixels, int dbpl,
}
-static void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl,
+void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
int w, int h,
int const_alpha)
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 4df7f8a..9bb4486 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -44,6 +44,7 @@
#include <private/qpainter_p.h>
#include <private/qdrawhelper_x86_p.h>
#include <private/qdrawhelper_armv6_p.h>
+#include <private/qdrawhelper_neon_p.h>
#include <private/qmath_p.h>
#include <qmath.h>
@@ -1182,7 +1183,7 @@ static const uint * QT_FASTCALL fetchConicalGradient(uint *buffer, const Operato
rx -= data->gradient.conical.center.x;
ry -= data->gradient.conical.center.y;
while (buffer < end) {
- qreal angle = atan2(ry, rx) + data->gradient.conical.angle;
+ qreal angle = qAtan2(ry, rx) + data->gradient.conical.angle;
*buffer = qt_gradient_pixel(&data->gradient, 1 - angle / (2*Q_PI));
@@ -1196,7 +1197,7 @@ static const uint * QT_FASTCALL fetchConicalGradient(uint *buffer, const Operato
if (!rw)
rw = 1;
while (buffer < end) {
- qreal angle = atan2(ry/rw - data->gradient.conical.center.x,
+ qreal angle = qAtan2(ry/rw - data->gradient.conical.center.x,
rx/rw - data->gradient.conical.center.y)
+ data->gradient.conical.angle;
@@ -1363,7 +1364,10 @@ static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int le
for (int i = 0; i < length; ++i) {
PRELOAD_COND2(dest, src)
uint s = src[i];
- dest[i] = s + BYTE_MUL(dest[i], qAlpha(~s));
+ if (s >= 0xff000000)
+ dest[i] = s;
+ else if (s != 0)
+ dest[i] = s + BYTE_MUL(dest[i], qAlpha(~s));
}
} else {
for (int i = 0; i < length; ++i) {
@@ -7140,17 +7144,17 @@ void qt_build_pow_tables() {
}
#else
for (int i=0; i<256; ++i) {
- qt_pow_rgb_gamma[i] = uchar(qRound(pow(i / qreal(255.0), smoothing) * 255));
- qt_pow_rgb_invgamma[i] = uchar(qRound(pow(i / qreal(255.), 1 / smoothing) * 255));
+ qt_pow_rgb_gamma[i] = uchar(qRound(qPow(i / qreal(255.0), smoothing) * 255));
+ qt_pow_rgb_invgamma[i] = uchar(qRound(qPow(i / qreal(255.), 1 / smoothing) * 255));
}
#endif
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
const qreal gray_gamma = 2.31;
for (int i=0; i<256; ++i)
- qt_pow_gamma[i] = uint(qRound(pow(i / qreal(255.), gray_gamma) * 2047));
+ qt_pow_gamma[i] = uint(qRound(qPow(i / qreal(255.), gray_gamma) * 2047));
for (int i=0; i<2048; ++i)
- qt_pow_invgamma[i] = uchar(qRound(pow(i / 2047.0, 1 / gray_gamma) * 255));
+ qt_pow_invgamma[i] = uchar(qRound(qPow(i / 2047.0, 1 / gray_gamma) * 255));
#endif
}
@@ -7725,7 +7729,8 @@ enum CPUFeatures {
SSE = 0x10,
SSE2 = 0x20,
CMOV = 0x40,
- IWMMXT = 0x80
+ IWMMXT = 0x80,
+ NEON = 0x100
};
static uint detectCPUFeatures()
@@ -7751,6 +7756,9 @@ static uint detectCPUFeatures()
// runtime detection only available when running as a previlegied process
static const bool doIWMMXT = !qgetenv("QT_NO_IWMMXT").toInt();
return doIWMMXT ? IWMMXT : 0;
+#elif defined(QT_HAVE_NEON)
+ static const bool doNEON = !qgetenv("QT_NO_NEON").toInt();
+ return doNEON ? NEON : 0;
#else
uint features = 0;
#if defined(__x86_64__) || defined(Q_OS_WIN64)
@@ -8122,7 +8130,14 @@ void qInitDrawhelperAsm()
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_armv6;
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_armv6;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_armv6;
-#endif // Q_CC_RVCT && QT_HAVE_ARMV6
+#elif defined(QT_HAVE_NEON)
+ if (features & NEON) {
+ qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
+ qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
+ }
+#endif
if (functionForModeSolidAsm) {
const int destinationMode = QPainter::CompositionMode_Destination;
diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp
new file mode 100644
index 0000000..7fe11bf
--- /dev/null
+++ b/src/gui/painting/qdrawhelper_neon.cpp
@@ -0,0 +1,260 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include <private/qdrawhelper_p.h>
+
+#ifdef QT_HAVE_NEON
+
+#include <private/qdrawhelper_neon_p.h>
+#include <arm_neon.h>
+
+QT_BEGIN_NAMESPACE
+
+static inline int16x8_t qvdiv_255_s16(int16x8_t x, int16x8_t half)
+{
+ // result = (x + (x >> 8) + 0x80) >> 8
+
+ const int16x8_t temp = vshrq_n_s16(x, 8); // x >> 8
+ const int16x8_t sum_part = vaddq_s16(x, half); // x + 0x80
+ const int16x8_t sum = vaddq_s16(temp, sum_part);
+
+ return vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(sum), 8));
+}
+
+static inline int16x8_t qvbyte_mul_s16(int16x8_t x, int16x8_t alpha, int16x8_t half)
+{
+ // t = qRound(x * alpha / 255.0)
+
+ const int16x8_t t = vmulq_s16(x, alpha); // t
+ return qvdiv_255_s16(t, half);
+}
+
+static inline int16x8_t qvinterpolate_pixel_255(int16x8_t x, int16x8_t a, int16x8_t y, int16x8_t b, int16x8_t half)
+{
+ // t = x * a + y * b
+
+ const int16x8_t ta = vmulq_s16(x, a);
+ const int16x8_t tb = vmulq_s16(y, b);
+
+ return qvdiv_255_s16(vaddq_s16(ta, tb), half);
+}
+
+static inline int16x8_t qvsource_over_s16(int16x8_t src16, int16x8_t dst16, int16x8_t half, int16x8_t full)
+{
+ const int16x4_t alpha16_high = vdup_lane_s16(vget_high_s16(src16), 3);
+ const int16x4_t alpha16_low = vdup_lane_s16(vget_low_s16(src16), 3);
+
+ const int16x8_t alpha16 = vsubq_s16(full, vcombine_s16(alpha16_low, alpha16_high));
+
+ return vaddq_s16(src16, qvbyte_mul_s16(dst16, alpha16, half));
+}
+
+void qt_blend_argb32_on_argb32_neon(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha)
+{
+ const uint *src = (const uint *) srcPixels;
+ uint *dst = (uint *) destPixels;
+ int16x8_t half = vdupq_n_s16(0x80);
+ int16x8_t full = vdupq_n_s16(0xff);
+ if (const_alpha == 256) {
+ for (int y = 0; y < h; ++y) {
+ int x = 0;
+ for (; x < w-3; x += 4) {
+ int32x4_t src32 = vld1q_s32((int32_t *)&src[x]);
+ if ((src[x] & src[x+1] & src[x+2] & src[x+3]) >= 0xff000000) {
+ // all opaque
+ vst1q_s32((int32_t *)&dst[x], src32);
+ } else if (src[x] | src[x+1] | src[x+2] | src[x+3]) {
+ int32x4_t dst32 = vld1q_s32((int32_t *)&dst[x]);
+
+ const uint8x16_t src8 = vreinterpretq_u8_s32(src32);
+ const uint8x16_t dst8 = vreinterpretq_u8_s32(dst32);
+
+ const uint8x8_t src8_low = vget_low_u8(src8);
+ const uint8x8_t dst8_low = vget_low_u8(dst8);
+
+ const uint8x8_t src8_high = vget_high_u8(src8);
+ const uint8x8_t dst8_high = vget_high_u8(dst8);
+
+ const int16x8_t src16_low = vreinterpretq_s16_u16(vmovl_u8(src8_low));
+ const int16x8_t dst16_low = vreinterpretq_s16_u16(vmovl_u8(dst8_low));
+
+ const int16x8_t src16_high = vreinterpretq_s16_u16(vmovl_u8(src8_high));
+ const int16x8_t dst16_high = vreinterpretq_s16_u16(vmovl_u8(dst8_high));
+
+ const int16x8_t result16_low = qvsource_over_s16(src16_low, dst16_low, half, full);
+ const int16x8_t result16_high = qvsource_over_s16(src16_high, dst16_high, half, full);
+
+ const int32x2_t result32_low = vreinterpret_s32_s8(vmovn_s16(result16_low));
+ const int32x2_t result32_high = vreinterpret_s32_s8(vmovn_s16(result16_high));
+
+ vst1q_s32((int32_t *)&dst[x], vcombine_s32(result32_low, result32_high));
+ }
+ }
+ for (; x<w; ++x) {
+ uint s = src[x];
+ if (s >= 0xff000000)
+ dst[x] = s;
+ else if (s != 0)
+ dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s));
+ }
+ dst = (quint32 *)(((uchar *) dst) + dbpl);
+ src = (const quint32 *)(((const uchar *) src) + sbpl);
+ }
+ } else if (const_alpha != 0) {
+ const_alpha = (const_alpha * 255) >> 8;
+ int16x8_t const_alpha16 = vdupq_n_s16(const_alpha);
+ for (int y = 0; y < h; ++y) {
+ int x = 0;
+ for (; x < w-3; x += 4) {
+ if (src[x] | src[x+1] | src[x+2] | src[x+3]) {
+ int32x4_t src32 = vld1q_s32((int32_t *)&src[x]);
+ int32x4_t dst32 = vld1q_s32((int32_t *)&dst[x]);
+
+ const uint8x16_t src8 = vreinterpretq_u8_s32(src32);
+ const uint8x16_t dst8 = vreinterpretq_u8_s32(dst32);
+
+ const uint8x8_t src8_low = vget_low_u8(src8);
+ const uint8x8_t dst8_low = vget_low_u8(dst8);
+
+ const uint8x8_t src8_high = vget_high_u8(src8);
+ const uint8x8_t dst8_high = vget_high_u8(dst8);
+
+ const int16x8_t src16_low = vreinterpretq_s16_u16(vmovl_u8(src8_low));
+ const int16x8_t dst16_low = vreinterpretq_s16_u16(vmovl_u8(dst8_low));
+
+ const int16x8_t src16_high = vreinterpretq_s16_u16(vmovl_u8(src8_high));
+ const int16x8_t dst16_high = vreinterpretq_s16_u16(vmovl_u8(dst8_high));
+
+ const int16x8_t srcalpha16_low = qvbyte_mul_s16(src16_low, const_alpha16, half);
+ const int16x8_t srcalpha16_high = qvbyte_mul_s16(src16_high, const_alpha16, half);
+
+ const int16x8_t result16_low = qvsource_over_s16(srcalpha16_low, dst16_low, half, full);
+ const int16x8_t result16_high = qvsource_over_s16(srcalpha16_high, dst16_high, half, full);
+
+ const int32x2_t result32_low = vreinterpret_s32_s8(vmovn_s16(result16_low));
+ const int32x2_t result32_high = vreinterpret_s32_s8(vmovn_s16(result16_high));
+
+ vst1q_s32((int32_t *)&dst[x], vcombine_s32(result32_low, result32_high));
+ }
+ }
+ for (; x<w; ++x) {
+ uint s = src[x];
+ if (s != 0) {
+ s = BYTE_MUL(s, const_alpha);
+ dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s));
+ }
+ }
+ dst = (quint32 *)(((uchar *) dst) + dbpl);
+ src = (const quint32 *)(((const uchar *) src) + sbpl);
+ }
+ }
+}
+
+// qblendfunctions.cpp
+void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha);
+
+void qt_blend_rgb32_on_rgb32_neon(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha)
+{
+ if (const_alpha != 256) {
+ if (const_alpha != 0) {
+ const uint *src = (const uint *) srcPixels;
+ uint *dst = (uint *) destPixels;
+ int16x8_t half = vdupq_n_s16(0x80);
+ const_alpha = (const_alpha * 255) >> 8;
+ int one_minus_const_alpha = 255 - const_alpha;
+ int16x8_t const_alpha16 = vdupq_n_s16(const_alpha);
+ int16x8_t one_minus_const_alpha16 = vdupq_n_s16(255 - const_alpha);
+ for (int y = 0; y < h; ++y) {
+ int x = 0;
+ for (; x < w-3; x += 4) {
+ int32x4_t src32 = vld1q_s32((int32_t *)&src[x]);
+ int32x4_t dst32 = vld1q_s32((int32_t *)&dst[x]);
+
+ const uint8x16_t src8 = vreinterpretq_u8_s32(src32);
+ const uint8x16_t dst8 = vreinterpretq_u8_s32(dst32);
+
+ const uint8x8_t src8_low = vget_low_u8(src8);
+ const uint8x8_t dst8_low = vget_low_u8(dst8);
+
+ const uint8x8_t src8_high = vget_high_u8(src8);
+ const uint8x8_t dst8_high = vget_high_u8(dst8);
+
+ const int16x8_t src16_low = vreinterpretq_s16_u16(vmovl_u8(src8_low));
+ const int16x8_t dst16_low = vreinterpretq_s16_u16(vmovl_u8(dst8_low));
+
+ const int16x8_t src16_high = vreinterpretq_s16_u16(vmovl_u8(src8_high));
+ const int16x8_t dst16_high = vreinterpretq_s16_u16(vmovl_u8(dst8_high));
+
+ const int16x8_t result16_low = qvinterpolate_pixel_255(src16_low, const_alpha16, dst16_low, one_minus_const_alpha16, half);
+ const int16x8_t result16_high = qvinterpolate_pixel_255(src16_high, const_alpha16, dst16_high, one_minus_const_alpha16, half);
+
+ const int32x2_t result32_low = vreinterpret_s32_s8(vmovn_s16(result16_low));
+ const int32x2_t result32_high = vreinterpret_s32_s8(vmovn_s16(result16_high));
+
+ vst1q_s32((int32_t *)&dst[x], vcombine_s32(result32_low, result32_high));
+ }
+ for (; x<w; ++x) {
+ uint s = src[x];
+ s = BYTE_MUL(s, const_alpha);
+ dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], one_minus_const_alpha);
+ }
+ dst = (quint32 *)(((uchar *) dst) + dbpl);
+ src = (const quint32 *)(((const uchar *) src) + sbpl);
+ }
+ }
+ } else {
+ qt_blend_rgb32_on_rgb32(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
+ }
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_HAVE_NEON
+
diff --git a/src/gui/painting/qdrawhelper_neon_p.h b/src/gui/painting/qdrawhelper_neon_p.h
new file mode 100644
index 0000000..cb9a0d6
--- /dev/null
+++ b/src/gui/painting/qdrawhelper_neon_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef QDRAWHELPER_NEON_P_H
+#define QDRAWHELPER_NEON_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qdrawhelper_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_HAVE_NEON
+
+void qt_blend_argb32_on_argb32_neon(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha);
+
+void qt_blend_rgb32_on_rgb32_neon(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha);
+
+#endif // QT_HAVE_NEON
+
+QT_END_NAMESPACE
+
+#endif // QDRAWHELPER_NEON_P_H
diff --git a/src/gui/painting/qemulationpaintengine.cpp b/src/gui/painting/qemulationpaintengine.cpp
index 662b163..5bd3c71 100644
--- a/src/gui/painting/qemulationpaintengine.cpp
+++ b/src/gui/painting/qemulationpaintengine.cpp
@@ -172,6 +172,36 @@ void QEmulationPaintEngine::drawTextItem(const QPointF &p, const QTextItem &text
QRectF rect(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal());
fillBGRect(rect);
}
+
+ QPainterState *s = state();
+ Qt::BrushStyle style = qbrush_style(s->pen.brush());
+ if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern)
+ {
+ QPen savedPen = s->pen;
+ QGradient g = *s->pen.brush().gradient();
+
+ if (g.coordinateMode() > QGradient::LogicalMode) {
+ QTransform mat = s->pen.brush().transform();
+ if (g.coordinateMode() == QGradient::StretchToDeviceMode) {
+ mat.scale(real_engine->painter()->device()->width(), real_engine->painter()->device()->height());
+ } else if (g.coordinateMode() == QGradient::ObjectBoundingMode) {
+ const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
+ QRectF r(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal());
+ mat.translate(r.x(), r.y());
+ mat.scale(r.width(), r.height());
+ }
+ g.setCoordinateMode(QGradient::LogicalMode);
+ QBrush brush(g);
+ brush.setTransform(mat);
+ s->pen.setBrush(brush);
+ penChanged();
+ real_engine->drawTextItem(p, textItem);
+ s->pen = savedPen;
+ penChanged();
+ return;
+ }
+ }
+
real_engine->drawTextItem(p, textItem);
}
diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp
index 67dc2c7..e3a6f78 100644
--- a/src/gui/painting/qmemrotate.cpp
+++ b/src/gui/painting/qmemrotate.cpp
@@ -572,5 +572,26 @@ QT_IMPL_MEMROTATE(quint32, qrgb_generic16)
QT_IMPL_MEMROTATE(quint16, qrgb_generic16)
#endif
+struct qrgb_gl_rgba
+{
+public:
+ inline qrgb_gl_rgba(quint32 v) {
+ if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
+ data = ((v << 16) & 0xff0000) | ((v >> 16) & 0xff) | (v & 0xff00ff00);
+ else
+ data = (v << 8) | ((v >> 24) & 0xff);
+ }
+
+ inline operator quint32() const { return data; }
+
+private:
+ quint32 data;
+} Q_PACKED;
+
+void Q_GUI_EXPORT qt_memrotate90_gl(const quint32 *src, int srcWidth, int srcHeight, int srcStride,
+ quint32 *dest, int dstStride)
+{
+ qt_memrotate90_template(src, srcWidth, srcHeight, srcStride, reinterpret_cast<qrgb_gl_rgba *>(dest), dstStride);
+}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qmemrotate_p.h b/src/gui/painting/qmemrotate_p.h
index 676a880..8aee575 100644
--- a/src/gui/painting/qmemrotate_p.h
+++ b/src/gui/painting/qmemrotate_p.h
@@ -81,6 +81,8 @@ QT_BEGIN_NAMESPACE
void Q_GUI_QWS_EXPORT qt_memrotate180(const srctype*, int, int, int, desttype*, int); \
void Q_GUI_QWS_EXPORT qt_memrotate270(const srctype*, int, int, int, desttype*, int)
+void Q_GUI_EXPORT qt_memrotate90(const quint32*, int, int, int, quint32*, int);
+
QT_DECL_MEMROTATE(quint32, quint32);
QT_DECL_MEMROTATE(quint32, quint16);
QT_DECL_MEMROTATE(quint16, quint32);
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 8ed126f..fd67f96 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -1329,7 +1329,7 @@ void QPainterPrivate::updateState(QPainterState *newState)
of composition modes, brushes, clipping, transformation, etc, is
close to an impossible task because of the number of
permutations. As a compromise we have selected a subset of the
- QPainter API and backends, were performance is guaranteed to be as
+ QPainter API and backends, where performance is guaranteed to be as
good as we can sensibly get it for the given combination of
hardware and software.
diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp
index 51d6195..a41ab6d 100644
--- a/src/gui/painting/qpathclipper.cpp
+++ b/src/gui/painting/qpathclipper.cpp
@@ -1209,7 +1209,7 @@ static qreal computeAngle(const QPointF &v)
}
#else
// doesn't seem to be robust enough
- return atan2(v.x(), v.y()) + Q_PI;
+ return qAtan2(v.x(), v.y()) + Q_PI;
#endif
}
diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp
index 228a6b1..8bb4728 100644
--- a/src/gui/painting/qstroker.cpp
+++ b/src/gui/painting/qstroker.cpp
@@ -910,8 +910,8 @@ QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLengt
}
}
- int startSegment = int(floor(startAngle / 90));
- int endSegment = int(floor((startAngle + sweepLength) / 90));
+ int startSegment = int(qFloor(startAngle / 90));
+ int endSegment = int(qFloor((startAngle + sweepLength) / 90));
qreal startT = (startAngle - startSegment * 90) / 90;
qreal endT = (startAngle + sweepLength - endSegment * 90) / 90;
diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp
index c66da71..15427c6 100644
--- a/src/gui/painting/qwindowsurface_s60.cpp
+++ b/src/gui/painting/qwindowsurface_s60.cpp
@@ -68,12 +68,14 @@ QS60WindowSurface::QS60WindowSurface(QWidget* widget)
mode = EColor16MA; // Try for transparency anyway
// We create empty CFbsBitmap here -> it will be resized in setGeometry
- CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new
+ CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new
qt_symbian_throwIfError( bitmap->Create( TSize(0, 0), mode ) );
QS60PixmapData *data = new QS60PixmapData(QPixmapData::PixmapType);
- data->fromSymbianBitmap(bitmap);
- d_ptr->device = QPixmap(data);
+ if (data) {
+ data->fromSymbianBitmap(bitmap, true);
+ d_ptr->device = QPixmap(data);
+ }
setStaticContentsSupport(true);
}
diff --git a/src/gui/statemachine/qguistatemachine.cpp b/src/gui/statemachine/qguistatemachine.cpp
index 4f7806f..c3a9228 100644
--- a/src/gui/statemachine/qguistatemachine.cpp
+++ b/src/gui/statemachine/qguistatemachine.cpp
@@ -186,8 +186,10 @@ static QEvent *cloneEvent(QEvent *e)
case QEvent::DeactivateControl:
return new QEvent(*e);
+#ifndef QT_NO_CONTEXTMENU
case QEvent::ContextMenu:
return new QContextMenuEvent(*static_cast<QContextMenuEvent*>(e));
+#endif
case QEvent::InputMethod:
return new QInputMethodEvent(*static_cast<QInputMethodEvent*>(e));
case QEvent::AccessibilityPrepare:
diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp
index 91974c2..64e1919 100644
--- a/src/gui/styles/qcommonstyle.cpp
+++ b/src/gui/styles/qcommonstyle.cpp
@@ -2775,7 +2775,7 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
QSize size = (sr == SE_TabBarTabLeftButton) ? tab->leftButtonSize : tab->rightButtonSize;
int w = size.width();
int h = size.height();
- int midHeight = static_cast<int>(ceil(float(tr.height() - h) / 2));
+ int midHeight = static_cast<int>(qCeil(float(tr.height() - h) / 2));
int midWidth = ((tr.width() - w) / 2);
bool atTheTop = true;
diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm
index 4075cf7..53740fc 100644
--- a/src/gui/styles/qmacstyle_mac.mm
+++ b/src/gui/styles/qmacstyle_mac.mm
@@ -3109,6 +3109,18 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
break;
case PE_PanelLineEdit:
QWindowsStyle::drawPrimitive(pe, opt, p, w);
+ // Draw the focus frame for widgets other than QLineEdit (e.g. for line edits in Webkit).
+ // Focus frame is drawn outside the rectangle passed in the option-rect.
+ if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
+ if ((opt->state & State_HasFocus) && !qobject_cast<const QLineEdit*>(w)) {
+ int vmargin = pixelMetric(QStyle::PM_FocusFrameVMargin);
+ int hmargin = pixelMetric(QStyle::PM_FocusFrameHMargin);
+ QStyleOptionFrame focusFrame = *panel;
+ focusFrame.rect = panel->rect.adjusted(-hmargin, -vmargin, hmargin, vmargin);
+ drawControl(CE_FocusFrame, &focusFrame, p, w);
+ }
+ }
+
break;
case PE_FrameTabWidget:
if (const QStyleOptionTabWidgetFrame *twf
diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp
index 93b517f..bcc993a 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/gui/styles/qs60style.cpp
@@ -88,16 +88,11 @@ static const qreal goldenRatio = 1.618;
const layoutHeader QS60StylePrivate::m_layoutHeaders[] = {
// *** generated layout data ***
-{240,320,1,15,true,"QVGA Landscape Mirrored"},
-{240,320,1,15,false,"QVGA Landscape"},
-{320,240,1,15,true,"QVGA Portrait Mirrored"},
-{320,240,1,15,false,"QVGA Portrait"},
-{360,640,1,15,true,"NHD Landscape Mirrored"},
-{360,640,1,15,false,"NHD Landscape"},
-{640,360,1,15,true,"NHD Portrait Mirrored"},
-{640,360,1,15,false,"NHD Portrait"},
-{352,800,1,12,true,"E90 Landscape Mirrored"},
-{352,800,1,12,false,"E90 Landscape"}
+{240,320,1,15,"QVGA Landscape"},
+{320,240,1,15,"QVGA Portrait"},
+{360,640,1,15,"NHD Landscape"},
+{640,360,1,15,"NHD Portrait"},
+{352,800,1,12,"E90 Landscape"}
// *** End of generated data ***
};
const int QS60StylePrivate::m_numberOfLayouts =
@@ -105,15 +100,10 @@ const int QS60StylePrivate::m_numberOfLayouts =
const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = {
// *** generated pixel metrics ***
-{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,3,3,4,9,13,-909,5,51,11,5,0,6,3,3,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1},
{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,3,3,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1},
-{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,7,4,4,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1},
{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1},
-{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,8,5,5,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1},
{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1},
-{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,5,5,6,8,19,-909,7,74,22,7,0,8,5,5,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1},
{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,5,5,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1},
-{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,5,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,8,6,5,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1},
{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1}
// *** End of generated data ***
};
@@ -200,10 +190,24 @@ void QS60StylePrivate::drawSkinElement(SkinElements element, QPainter *painter,
QS60StyleEnums::SP_QsnCpScrollHandleBottom, Qt::Vertical, painter, rect, flags | SF_PointNorth);
break;
case SE_SliderHandleHorizontal:
- drawPart(QS60StyleEnums::SP_QgnIndiSliderEdit, painter, rect, flags | SF_PointNorth);
+ drawPart(QS60StyleEnums::SP_QgnGrafNsliderMarker, painter, rect, flags | SF_PointNorth);
break;
case SE_SliderHandleVertical:
- drawPart(QS60StyleEnums::SP_QgnIndiSliderEdit, painter, rect, flags | SF_PointEast);
+ drawPart(QS60StyleEnums::SP_QgnGrafNsliderMarker, painter, rect, flags | SF_PointEast);
+ break;
+ case SE_SliderHandleSelectedHorizontal:
+ drawPart(QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected, painter, rect, flags | SF_PointNorth);
+ break;
+ case SE_SliderHandleSelectedVertical:
+ drawPart(QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected, painter, rect, flags | SF_PointEast);
+ break;
+ case SE_SliderGrooveVertical:
+ drawRow(QS60StyleEnums::SP_QgnGrafNsliderEndLeft, QS60StyleEnums::SP_QgnGrafNsliderMiddle,
+ QS60StyleEnums::SP_QgnGrafNsliderEndRight, Qt::Vertical, painter, rect, flags | SF_PointEast);
+ break;
+ case SE_SliderGrooveHorizontal:
+ drawRow(QS60StyleEnums::SP_QgnGrafNsliderEndLeft, QS60StyleEnums::SP_QgnGrafNsliderMiddle,
+ QS60StyleEnums::SP_QgnGrafNsliderEndRight, Qt::Horizontal, painter, rect, flags | SF_PointNorth);
break;
case SE_TabBarTabEastActive:
drawRow(QS60StyleEnums::SP_QgnGrafTabActiveL, QS60StyleEnums::SP_QgnGrafTabActiveM,
@@ -306,8 +310,8 @@ QColor QS60StylePrivate::stateColor(const QColor &color, const QStyleOption *opt
QColor hsvColor = retColor.toHsv();
int colorSat = hsvColor.saturation();
int colorVal = hsvColor.value();
- colorSat = (colorSat!=0) ? (colorSat>>1) : 128;
- colorVal = (colorVal!=0) ? (colorVal>>1) : 128;
+ colorSat = (colorSat != 0) ? (colorSat >> 1) : 128;
+ colorVal = (colorVal != 0) ? (colorVal >> 1) : 128;
hsvColor.setHsv(hsvColor.hue(), colorSat, colorVal);
retColor = hsvColor.toRgb();
}
@@ -335,7 +339,7 @@ QColor QS60StylePrivate::lighterColor(const QColor &baseColor)
bool QS60StylePrivate::drawsOwnThemeBackground(const QWidget *widget)
{
- return qobject_cast<const QDialog *> (widget);
+ return (widget ? (widget->windowType() == Qt::Dialog) : false);
}
QFont QS60StylePrivate::s60Font(
@@ -368,7 +372,6 @@ void QS60StylePrivate::clearCaches(CacheClearReason reason)
case CC_LayoutChange:
// when layout changes, the colors remain in cache, but graphics and fonts can change
m_mappedFontsCache.clear();
- deleteBackground();
QPixmapCache::clear();
break;
case CC_ThemeChange:
@@ -396,10 +399,10 @@ QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const
if (!cachedColorExists) {
const int frameCornerWidth = pixelMetric(PM_Custom_FrameCornerWidth);
const int frameCornerHeight = pixelMetric(PM_Custom_FrameCornerHeight);
- Q_ASSERT(2*frameCornerWidth<32);
- Q_ASSERT(2*frameCornerHeight<32);
+ Q_ASSERT(2 * frameCornerWidth < 32);
+ Q_ASSERT(2 * frameCornerHeight < 32);
- const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32,32)).toImage();
+ const QImage frameImage = QS60StylePrivate::frame(frame, QSize(32, 32)).toImage();
Q_ASSERT(frameImage.bytesPerLine() > 0);
if (frameImage.isNull())
return Qt::black;
@@ -414,14 +417,14 @@ QColor QS60StylePrivate::colorFromFrameGraphics(SkinFrameElements frame) const
int skips = 0;
int estimations = 0;
- const int topBorderLastPixel = frameCornerHeight*frameImage.width()-1;
- const int bottomBorderFirstPixel = frameImage.width()*frameImage.height()-frameCornerHeight*frameImage.width()-1;
- const int rightBorderFirstPixel = frameImage.width()-frameCornerWidth;
+ const int topBorderLastPixel = frameCornerHeight*frameImage.width() - 1;
+ const int bottomBorderFirstPixel = frameImage.width() * frameImage.height() - frameCornerHeight*frameImage.width() - 1;
+ const int rightBorderFirstPixel = frameImage.width() - frameCornerWidth;
const int leftBorderLastPixel = frameCornerWidth;
while ((skips + estimations) < pixels) {
- if ((skips+estimations) > topBorderLastPixel &&
- (skips+estimations) < bottomBorderFirstPixel) {
+ if ((skips + estimations) > topBorderLastPixel &&
+ (skips + estimations) < bottomBorderFirstPixel) {
for (int rowIndex = 0; rowIndex < frameImage.width(); rowIndex++) {
if (rowIndex > leftBorderLastPixel &&
rowIndex < rightBorderFirstPixel) {
@@ -526,18 +529,18 @@ void QS60StylePrivate::drawRow(QS60StyleEnums::SkinParts start,
endRect = startRect.translated(rect.width() - startRect.width(), 0);
middleRect.adjust(startRect.width(), 0, -startRect.width(), 0);
if (startRect.bottomRight().x() > endRect.topLeft().x()) {
- const int overlap = (startRect.bottomRight().x() - endRect.topLeft().x())>>1;
- startRect.setWidth(startRect.width()-overlap);
- endRect.adjust(overlap,0,0,0);
+ const int overlap = (startRect.bottomRight().x() - endRect.topLeft().x()) >> 1;
+ startRect.setWidth(startRect.width() - overlap);
+ endRect.adjust(overlap, 0, 0, 0);
}
} else {
startRect.setHeight(qMin((rect.height() >> 1) - 1, startRect.height()));
endRect = startRect.translated(0, rect.height() - startRect.height());
middleRect.adjust(0, startRect.height(), 0, -startRect.height());
if (startRect.topRight().y() > endRect.bottomLeft().y()) {
- const int overlap = (startRect.topRight().y() - endRect.bottomLeft().y())>>1;
- startRect.setHeight(startRect.height()-overlap);
- endRect.adjust(0,overlap,0,0);
+ const int overlap = (startRect.topRight().y() - endRect.bottomLeft().y()) >> 1;
+ startRect.setHeight(startRect.height() - overlap);
+ endRect.adjust(0, overlap, 0, 0);
}
}
@@ -805,9 +808,17 @@ 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(result.height()>>1);
+ result.setWidth(result.height() >> 1);
+ break;
+
+ case QS60StyleEnums::SP_QgnGrafNsliderEndLeft:
+ case QS60StyleEnums::SP_QgnGrafNsliderEndRight:
+ case QS60StyleEnums::SP_QgnGrafNsliderMiddle:
+ result.setWidth(result.height() >> 1);
break;
- case QS60StyleEnums::SP_QgnIndiSliderEdit:
+
+ case QS60StyleEnums::SP_QgnGrafNsliderMarker:
+ case QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected:
result.scale(pixelMetric(QStyle::PM_SliderLength),
pixelMetric(QStyle::PM_SliderControlThickness), Qt::IgnoreAspectRatio);
break;
@@ -928,22 +939,42 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
case CC_Slider:
if (const QStyleOptionSlider *optionSlider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
- // The groove is just a centered line. Maybe a qgn_graf_line_* at some point
const QRect sliderGroove = subControlRect(control, optionSlider, SC_SliderGroove, widget);
- const QPoint sliderGrooveCenter = sliderGroove.center();
const bool horizontal = optionSlider->orientation == Qt::Horizontal;
- painter->save();
- if (widget)
- painter->setPen(widget->palette().windowText().color());
- if (horizontal)
- painter->drawLine(0, sliderGrooveCenter.y(), sliderGroove.right(), sliderGrooveCenter.y());
- else
- painter->drawLine(sliderGrooveCenter.x(), 0, sliderGrooveCenter.x(), sliderGroove.bottom());
- painter->restore();
+ //Highlight
+/* if (optionSlider->state & QStyle::State_HasFocus)
+ drawPrimitive(PE_FrameFocusRect, optionSlider, painter, widget);*/
+
+ //Groove graphics
+ if (QS60StylePrivate::hasSliderGrooveGraphic()) {
+ const QS60StylePrivate::SkinElements grooveElement = horizontal ?
+ QS60StylePrivate::SE_SliderGrooveHorizontal :
+ QS60StylePrivate::SE_SliderGrooveVertical;
+ QS60StylePrivate::drawSkinElement(grooveElement, painter, sliderGroove, flags);
+ } else {
+ const QRect sliderGroove = subControlRect(control, optionSlider, SC_SliderGroove, widget);
+ const QPoint sliderGrooveCenter = sliderGroove.center();
+ const bool horizontal = optionSlider->orientation == Qt::Horizontal;
+ painter->save();
+ if (widget)
+ painter->setPen(widget->palette().windowText().color());
+ if (horizontal)
+ painter->drawLine(0, sliderGrooveCenter.y(), sliderGroove.right(), sliderGrooveCenter.y());
+ else
+ painter->drawLine(sliderGrooveCenter.x(), 0, sliderGrooveCenter.x(), sliderGroove.bottom());
+ painter->restore();
+ }
+
+ //Handle graphics
const QRect sliderHandle = subControlRect(control, optionSlider, SC_SliderHandle, widget);
- const QS60StylePrivate::SkinElements handleElement =
- horizontal ? QS60StylePrivate::SE_SliderHandleHorizontal : QS60StylePrivate::SE_SliderHandleVertical;
+ QS60StylePrivate::SkinElements handleElement;
+ if (optionSlider->state & QStyle::State_Sunken)
+ handleElement =
+ horizontal ? QS60StylePrivate::SE_SliderHandleSelectedHorizontal : QS60StylePrivate::SE_SliderHandleSelectedVertical;
+ else
+ handleElement =
+ horizontal ? QS60StylePrivate::SE_SliderHandleHorizontal : QS60StylePrivate::SE_SliderHandleVertical;
QS60StylePrivate::drawSkinElement(handleElement, painter, sliderHandle, flags);
}
break;
@@ -960,10 +991,11 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
buttonOption.QStyleOption::operator=(*cmb);
const int maxHeight = cmbxFrame.height();
const int maxWidth = cmbxFrame.width() - cmbxEditField.width();
- const int topLeftPoint = direction ? cmbxEditField.right()+1 : cmbxEditField.left()+1-maxWidth;
+ const int topLeftPoint = direction ?
+ (cmbxEditField.right() + 1) : (cmbxEditField.left() + 1 - maxWidth);
const QRect buttonRect(topLeftPoint, cmbxEditField.top(), maxWidth, maxHeight);
buttonOption.rect = buttonRect;
- buttonOption.state = cmb->state & (State_Enabled | State_MouseOver);
+ buttonOption.state = cmb->state;
drawPrimitive(PE_PanelButtonCommand, &buttonOption, painter, widget);
// draw label background - label itself is drawn separately
@@ -1317,6 +1349,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
painter->setClipRect(voptAdj.rect);
const bool isSelected = (vopt->state & QStyle::State_Selected);
+ const bool hasFocus = (vopt->state & QStyle::State_HasFocus);
bool isScrollBarVisible = false;
int scrollBarWidth = 0;
@@ -1348,9 +1381,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
const QModelIndex index = vopt->index;
//todo: Draw cell background only once - for the first cell.
QStyleOptionViewItemV4 voptAdj2 = voptAdj;
- const QModelIndex indexFirst = itemView->model()->index(0,0);
+ const QModelIndex indexFirst = itemView->model()->index(0, 0);
const QModelIndex indexLast = itemView->model()->index(
- itemView->model()->rowCount()-1,itemView->model()->columnCount()-1);
+ itemView->model()->rowCount() - 1, itemView->model()->columnCount() -1);
if (itemView->viewport())
voptAdj2.rect = QRect( itemView->visualRect(indexFirst).topLeft(),
itemView->visualRect(indexLast).bottomRight()).intersect(itemView->viewport()->rect());
@@ -1359,7 +1392,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
} else { QCommonStyle::drawPrimitive(PE_PanelItemViewItem, &voptAdj, painter, widget);}
// draw the focus rect
- if (isSelected) {
+ if (isSelected | hasFocus) {
QRect highlightRect = option->rect.adjusted(1,1,-1,-1);
QAbstractItemView::SelectionBehavior selectionBehavior =
itemView ? itemView->selectionBehavior() : QAbstractItemView::SelectItems;
@@ -1538,16 +1571,16 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
f.setPointSizeF(f.pointSizeF() * KTabFontMul);
painter->setFont(f);
- if (option->state & QStyle::State_Selected){
+ const bool selected = optionTab.state & State_Selected;
+ if (selected)
optionTab.palette.setColor(QPalette::Active, QPalette::WindowText,
QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 3, option));
- }
const bool verticalTabs = optionTab.shape == QTabBar::RoundedEast
|| optionTab.shape == QTabBar::RoundedWest
|| optionTab.shape == QTabBar::TriangularEast
|| optionTab.shape == QTabBar::TriangularWest;
- const bool selected = optionTab.state & State_Selected;
+
if (verticalTabs) {
painter->save();
int newX, newY, newRotation;
@@ -1585,12 +1618,12 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
QPixmap tabIcon = optionTab.icon.pixmap(iconSize,
(optionTab.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
if (tab->text.isEmpty())
- painter->drawPixmap(tr.center().x() - (tabIcon.height() >>1),
- tr.center().y() - (tabIcon.height() >>1),
+ painter->drawPixmap(tr.center().x() - (tabIcon.height() >> 1),
+ tr.center().y() - (tabIcon.height() >> 1),
tabIcon);
else
painter->drawPixmap(tr.left() + tabOverlap,
- tr.center().y() - (tabIcon.height() >>1),
+ tr.center().y() - (tabIcon.height() >> 1),
tabIcon);
tr.setLeft(tr.left() + iconSize.width() + 4);
}
@@ -1619,7 +1652,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
if (optionProgressBar->orientation == Qt::Horizontal) {
progressRect.setWidth(int(progressRect.width() * progressFactor));
if(optionProgressBar->direction == Qt::RightToLeft)
- progressRect.translate(optionProgressBar->rect.width()-progressRect.width(),0);
+ progressRect.translate(optionProgressBar->rect.width()-progressRect.width(), 0);
progressRect.adjust(1, 0, -1, 0);
} else {
progressRect.adjust(0, 1, 0, -1);
@@ -1685,18 +1718,18 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
optionCheckBox.QStyleOptionMenuItem::operator=(*menuItem);
optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth));
optionCheckBox.rect.setHeight(pixelMetric(PM_IndicatorHeight));
- const int moveByX = optionCheckBox.rect.width()+vSpacing;
+ const int moveByX = optionCheckBox.rect.width() + vSpacing;
if (optionMenuItem.direction == Qt::LeftToRight) {
- textRect.translate(moveByX,0);
+ textRect.translate(moveByX, 0);
iconRect.translate(moveByX, 0);
- iconRect.setWidth(iconRect.width()+vSpacing);
- textRect.setWidth(textRect.width()-moveByX-vSpacing);
- optionCheckBox.rect.translate(vSpacing/2, hSpacing/2);
+ iconRect.setWidth(iconRect.width() + vSpacing);
+ textRect.setWidth(textRect.width() - moveByX - vSpacing);
+ optionCheckBox.rect.translate(vSpacing >> 1, hSpacing >> 1);
} else {
- textRect.setWidth(textRect.width()-moveByX);
- iconRect.setWidth(iconRect.width()+vSpacing);
- iconRect.translate(-optionCheckBox.rect.width()-vSpacing, 0);
- optionCheckBox.rect.translate(textRect.width()+iconRect.width(),0);
+ textRect.setWidth(textRect.width() - moveByX);
+ iconRect.setWidth(iconRect.width() + vSpacing);
+ iconRect.translate(-optionCheckBox.rect.width() - vSpacing, 0);
+ optionCheckBox.rect.translate(textRect.width() + iconRect.width(), 0);
}
drawPrimitive(PE_IndicatorMenuCheckMark, &optionCheckBox, painter, widget);
}
@@ -1707,9 +1740,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
if (itemWithIcon) {
drawItemPixmap(painter, iconRect, text_flags, pix);
if (optionMenuItem.direction == Qt::LeftToRight)
- textRect.translate(vSpacing,0);
+ textRect.translate(vSpacing, 0);
else
- textRect.translate(-vSpacing,0);
+ textRect.translate(-vSpacing, 0);
textRect.setWidth(textRect.width()-vSpacing);
}
@@ -1717,7 +1750,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
if (drawSubMenuIndicator) {
QStyleOptionMenuItem arrowOptions;
arrowOptions.QStyleOption::operator=(*menuItem);
- const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget)>>1) +
+ const int indicatorWidth = (pixelMetric(PM_ListViewIconSize, option, widget) >> 1) +
pixelMetric(QStyle::PM_LayoutVerticalSpacing, option, widget);
if (optionMenuItem.direction == Qt::LeftToRight)
arrowOptions.rect.setLeft(textRect.right());
@@ -1762,8 +1795,8 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
painter->save();
QPen linePen = QPen(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 1, header));
const int penWidth = (header->orientation == Qt::Horizontal) ?
- linePen.width()+QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth)
- : linePen.width()+QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth);
+ linePen.width() + QS60StylePrivate::pixelMetric(PM_Custom_BoldLineWidth)
+ : linePen.width() + QS60StylePrivate::pixelMetric(PM_Custom_ThinLineWidth);
linePen.setWidth(penWidth);
painter->setPen(linePen);
if (header->orientation == Qt::Horizontal){
@@ -1782,7 +1815,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
//Make cornerButton slightly smaller so that it is not on top of table border graphic.
QStyleOptionHeader subopt = *header;
const int borderTweak =
- QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth)>>1;
+ QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1;
if (subopt.direction == Qt::LeftToRight)
subopt.rect.adjust(borderTweak, borderTweak, 0, -borderTweak);
else
@@ -1875,9 +1908,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
} else {
const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
if (option->direction == Qt::LeftToRight)
- headerRect.adjust(-2*frameWidth, 0, 0, 0);
+ headerRect.adjust(-2 * frameWidth, 0, 0, 0);
else
- headerRect.adjust(0, 0, 2*frameWidth, 0);
+ headerRect.adjust(0, 0, 2 * frameWidth, 0);
}
if (option->palette.brush(QPalette::Button).color() == Qt::transparent)
QS60StylePrivate::drawSkinElement(
@@ -2000,7 +2033,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
QRect tickRect = option->rect;
const int frameBorderWidth = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth);
// adjust tickmark rect to exclude frame border
- tickRect.adjust(0,-frameBorderWidth,0,-frameBorderWidth);
+ tickRect.adjust(0, -frameBorderWidth, 0, -frameBorderWidth);
QS60StyleEnums::SkinParts skinPart = QS60StyleEnums::SP_QgnIndiMarkedAdd;
QS60StylePrivate::drawSkinPart(skinPart, painter, tickRect,
(flags | QS60StylePrivate::SF_ColorSkinned));
@@ -2012,7 +2045,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
case PE_IndicatorRadioButton: {
QRect buttonRect = option->rect;
//there is empty (a. 33%) space in svg graphics for radiobutton
- const qreal reduceWidth = (qreal)buttonRect.width()/3.0;
+ const qreal reduceWidth = (qreal)buttonRect.width() / 3.0;
const qreal rectWidth = (qreal)option->rect.width() != 0 ? option->rect.width() : 1.0;
// Try to occupy the full area
const qreal scaler = 1 + (reduceWidth/rectWidth);
@@ -2075,27 +2108,28 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
case PE_IndicatorSpinDown:
case PE_IndicatorSpinUp:
if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
- QStyleOptionSpinBox optionSpinBox = *spinBox;
- if (QS60StylePrivate::canDrawThemeBackground(optionSpinBox.palette.base())) {
+ if (QS60StylePrivate::canDrawThemeBackground(spinBox->palette.base())) {
+ QStyleOptionSpinBox optionSpinBox = *spinBox;
const QS60StyleEnums::SkinParts part = (element == PE_IndicatorSpinUp) ?
QS60StyleEnums::SP_QgnGrafScrollArrowUp :
QS60StyleEnums::SP_QgnGrafScrollArrowDown;
- const int adjustment = qMin(optionSpinBox.rect.width(), optionSpinBox.rect.height())/6;
- optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment );
- QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect,flags);
+ const int iconMargin = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1;
+ optionSpinBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? iconMargin : -iconMargin );
+ QS60StylePrivate::drawSkinPart(part, painter, optionSpinBox.rect, flags);
} else {
commonStyleDraws = true;
}
}
+#endif //QT_NO_SPINBOX
#ifndef QT_NO_COMBOBOX
- else if (const QStyleOptionFrame *cmb = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
+ if (const QStyleOptionFrame *cmb = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
if (QS60StylePrivate::canDrawThemeBackground( option->palette.base())) {
// We want to draw down arrow here for comboboxes as well.
+ QStyleOptionFrame optionsComboBox = *cmb;
const QS60StyleEnums::SkinParts part = QS60StyleEnums::SP_QgnGrafScrollArrowDown;
- QStyleOptionFrame comboBox = *cmb;
- const int adjustment = qMin(comboBox.rect.width(), comboBox.rect.height())/6;
- comboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? adjustment : -adjustment );
- QS60StylePrivate::drawSkinPart(part, painter, comboBox.rect,flags);
+ const int iconMargin = QS60StylePrivate::pixelMetric(PM_Custom_FrameCornerWidth) >> 1;
+ optionsComboBox.rect.translate(0, (element == PE_IndicatorSpinDown) ? iconMargin : -iconMargin );
+ QS60StylePrivate::drawSkinPart(part, painter, optionsComboBox.rect, flags);
} else {
commonStyleDraws = true;
}
@@ -2113,12 +2147,11 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
// We want to draw down arrow here for comboboxes as well.
QStyleOptionFrame comboBox = *cmb;
const int frameWidth = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
- comboBox.rect.adjust(0,frameWidth,0,-frameWidth);
+ comboBox.rect.adjust(0, frameWidth, 0, -frameWidth);
QCommonStyle::drawPrimitive(element, &comboBox, painter, widget);
}
#endif //QT_NO_COMBOBOX
break;
-#endif //QT_NO_SPINBOX
case PE_Widget:
if (QS60StylePrivate::drawsOwnThemeBackground(widget)
#ifndef QT_NO_COMBOBOX
@@ -2128,7 +2161,10 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
|| qobject_cast<const QMenu *> (widget)
#endif //QT_NO_MENU
) {
- if (QS60StylePrivate::canDrawThemeBackground(option->palette.base()))
+ //Need extra check since dialogs have their own theme background
+ if (QS60StylePrivate::canDrawThemeBackground(option->palette.base()) &&
+ option->palette.window().texture().cacheKey() ==
+ QS60StylePrivate::m_themePalette->window().texture().cacheKey())
QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_OptionsMenu, painter, option->rect, flags);
else
commonStyleDraws = true;
@@ -2238,11 +2274,13 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
}
break;
+ case PE_PanelScrollAreaCorner:
+ break;
+
// todo: items are below with #ifdefs "just in case". in final version, remove all non-required cases
case PE_FrameLineEdit:
case PE_IndicatorDockWidgetResizeHandle:
case PE_PanelTipLabel:
- case PE_PanelScrollAreaCorner:
#ifndef QT_NO_TABBAR
case PE_IndicatorTabTear: // No tab tear in S60
@@ -2284,6 +2322,13 @@ int QS60Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const
metricValue = -menuWidth;
}
}
+ //if layout direction is mirrored, switch left and right border margins
+ if (option && option->direction == Qt::RightToLeft) {
+ if (metric == PM_LayoutLeftMargin)
+ metricValue = QS60StylePrivate::pixelMetric(PM_LayoutRightMargin);
+ else if (metric == PM_LayoutRightMargin)
+ metricValue = QS60StylePrivate::pixelMetric(PM_LayoutLeftMargin);
+ }
return metricValue;
}
@@ -2296,22 +2341,22 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
case CT_ToolButton:
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
//FIXME properly - style should calculate the location of border frame-part
- sz += QSize(2*pixelMetric(PM_ButtonMargin), 2*pixelMetric(PM_ButtonMargin));
+ sz += QSize(2 * pixelMetric(PM_ButtonMargin), 2 * pixelMetric(PM_ButtonMargin));
if (const QStyleOptionToolButton *toolBtn = qstyleoption_cast<const QStyleOptionToolButton *>(opt))
if (toolBtn->subControls & SC_ToolButtonMenu)
- sz += QSize(pixelMetric(PM_MenuButtonIndicator),0);
+ sz += QSize(pixelMetric(PM_MenuButtonIndicator), 0);
break;
case CT_PushButton:
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
//FIXME properly - style should calculate the location of border frame-part
- sz += QSize(2*pixelMetric(PM_ButtonMargin), 2*pixelMetric(PM_ButtonMargin));
+ sz += QSize(2 * pixelMetric(PM_ButtonMargin), 2 * pixelMetric(PM_ButtonMargin));
if (const QAbstractButton *buttonWidget = (qobject_cast<const QAbstractButton *>(widget)))
if (buttonWidget->isCheckable())
sz += QSize(pixelMetric(PM_IndicatorWidth) + pixelMetric(PM_CheckBoxLabelSpacing), 0);
break;
case CT_LineEdit:
if (const QStyleOptionFrame *f = qstyleoption_cast<const QStyleOptionFrame *>(opt))
- sz += QSize(2*f->lineWidth, 4*f->lineWidth);
+ sz += QSize(2 * f->lineWidth, 4 * f->lineWidth);
break;
case CT_TabBarTab:
{
@@ -2326,7 +2371,7 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
if (QS60StylePrivate::isTouchSupported())
//Make itemview easier to use in touch devices
//QCommonStyle does not adjust height with horizontal margin, it only adjusts width
- sz.setHeight(sz.height() + 2*pixelMetric(QStyle::PM_FocusFrameVMargin));
+ sz.setHeight(sz.height() + 2 * pixelMetric(QStyle::PM_FocusFrameVMargin));
break;
default:
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
@@ -2342,10 +2387,10 @@ int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w
int retValue = -1;
switch (sh) {
case SH_Table_GridLineColor:
- retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors,2,0).rgba());
+ retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 2, 0).rgba());
break;
case SH_GroupBox_TextLabelColor:
- retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors,6,0).rgba());
+ retValue = int(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, 0).rgba());
break;
case SH_ScrollBar_ScrollWhenPointerLeavesControl:
retValue = true;
@@ -2427,7 +2472,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
sliderlen = (qint64(scrollbarOption->pageStep) * maxlen) / (range + scrollbarOption->pageStep);
const int slidermin = pixelMetric(PM_ScrollBarSliderMin, scrollbarOption, widget);
- if (sliderlen < slidermin || range > (INT_MAX>>1))
+ if (sliderlen < slidermin || range > (INT_MAX >> 1))
sliderlen = slidermin;
if (sliderlen > maxlen)
sliderlen = maxlen;
@@ -2478,39 +2523,40 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
const int frameThickness = spinbox->frame ? pixelMetric(PM_SpinBoxFrameWidth, spinbox, widget) : 0;
const int buttonMargin = spinbox->frame ? 2 : 0;
- const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize) + 2*buttonMargin;
+ const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize) + 2 * buttonMargin;
QSize buttonSize;
buttonSize.setHeight(qMax(8, spinbox->rect.height() - frameThickness));
- buttonSize.setWidth(buttonWidth);
+ //width should at least be equal to height
+ buttonSize.setWidth(qMax(buttonSize.height(), buttonWidth));
buttonSize = buttonSize.expandedTo(QApplication::globalStrut());
const int y = frameThickness + spinbox->rect.y();
- const int x = spinbox->rect.x() + spinbox->rect.width() - frameThickness - 2*buttonSize.width();
+ const int x = spinbox->rect.x() + spinbox->rect.width() - frameThickness - 2 * buttonSize.width();
switch (scontrol) {
case SC_SpinBoxUp:
if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
return QRect();
- ret = QRect(x, y, buttonWidth, buttonSize.height());
+ ret = QRect(x, y, buttonSize.width(), buttonSize.height());
break;
case SC_SpinBoxDown:
if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
return QRect();
- ret = QRect(x+buttonSize.width(), y, buttonWidth, buttonSize.height());
+ ret = QRect(x + buttonSize.width(), y, buttonSize.width(), buttonSize.height());
break;
case SC_SpinBoxEditField:
if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
ret = QRect(
frameThickness,
frameThickness,
- spinbox->rect.width() - 2*frameThickness,
- spinbox->rect.height() - 2*frameThickness);
+ spinbox->rect.width() - 2 * frameThickness,
+ spinbox->rect.height() - 2 * frameThickness);
else
ret = QRect(
frameThickness,
frameThickness,
x - frameThickness,
- spinbox->rect.height() - 2*frameThickness);
+ spinbox->rect.height() - 2 * frameThickness);
break;
case SC_SpinBoxFrame:
ret = spinbox->rect;
@@ -2526,29 +2572,29 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
ret = cmb->rect;
const int width = cmb->rect.width();
const int height = cmb->rect.height();
+ const int buttonIconSize = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize);
const int buttonMargin = cmb->frame ? 2 : 0;
// lets use spinbox frame here as well, as no combobox specific value available.
const int frameThickness = cmb->frame ? pixelMetric(PM_SpinBoxFrameWidth, cmb, widget) : 0;
- const int buttonWidth = QS60StylePrivate::pixelMetric(QStyle::PM_ButtonIconSize);
+ const int buttonWidth = qMax(cmb->rect.height(), buttonIconSize);
+ const int xposMod = (cmb->rect.x()) + width - buttonMargin - buttonWidth;
+ const int ypos = cmb->rect.y();
QSize buttonSize;
- buttonSize.setHeight(qMax(8, (cmb->rect.height()>>1) - frameThickness)); //minimum of 8 pixels
- buttonSize.setWidth(buttonWidth+2*buttonMargin);
+ buttonSize.setWidth(buttonWidth + 2 * buttonMargin);
+ buttonSize.setHeight(qMax(8, (cmb->rect.height() >> 1) - frameThickness)); //buttons should be squares
buttonSize = buttonSize.expandedTo(QApplication::globalStrut());
switch (scontrol) {
case SC_ComboBoxArrow:
- ret.setRect(
- ret.x() + ret.width() - buttonMargin - buttonWidth,
- ret.y() + buttonMargin,
- buttonWidth,
- height - 2*buttonMargin);
+ ret.setRect(xposMod, ypos + buttonMargin, buttonWidth, height - 2 * buttonMargin);
break;
case SC_ComboBoxEditField: {
- ret.setRect(
- ret.x() + frameThickness,
- ret.y() + frameThickness,
- ret.width() - 2*frameThickness - buttonSize.width(),
- ret.height() - 2*frameThickness);
+ const int withFrameX = cmb->rect.x() + cmb->rect.width() - frameThickness - buttonSize.width();
+ ret = QRect(
+ frameThickness,
+ frameThickness,
+ withFrameX - frameThickness,
+ cmb->rect.height() - 2 * frameThickness);
}
break;
default:
@@ -2565,7 +2611,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
//slightly indent text and boxes, so that dialog border does not mess with them.
const int horizontalSpacing =
QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
- ret.adjust(2,horizontalSpacing-3,0,0);
+ ret.adjust(2, horizontalSpacing - 3, 0, 0);
}
break;
case SC_GroupBoxFrame: {
@@ -2573,7 +2619,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
const int tbHeight = textBox.height();
ret.translate(0, -ret.y());
// include title to within the groupBox frame
- ret.setHeight(ret.height()+tbHeight);
+ ret.setHeight(ret.height() + tbHeight);
if (widget && ret.bottom() > widget->rect().bottom())
ret.setBottom(widget->rect().bottom());
}
@@ -2585,7 +2631,7 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple
break;
case CC_ToolButton:
if (const QStyleOptionToolButton *toolButton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
- const int indicatorRect = pixelMetric(PM_MenuButtonIndicator) + 2*pixelMetric(PM_ButtonMargin);
+ 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 &
@@ -2623,13 +2669,13 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
// in S60 the input text box doesn't start from line Edit's TL, but
// a bit indented.
QRect lineEditRect = opt->rect;
- const int adjustment = opt->rect.height()>>2;
- lineEditRect.adjust(adjustment,0,0,0);
+ const int adjustment = opt->rect.height() >> 2;
+ lineEditRect.adjust(adjustment, 0, 0, 0);
ret = lineEditRect;
}
break;
case SE_TabBarTearIndicator:
- ret = QRect(0,0,0,0);
+ ret = QRect(0, 0, 0, 0);
break;
case SE_TabWidgetTabBar:
if (const QStyleOptionTabWidgetFrame *optionTab = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
@@ -2651,12 +2697,12 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
// make sure that gain does not set the rect outside of widget boundaries
if (twf->direction == Qt::RightToLeft) {
if ((ret.left() - gain) < widget->rect().left())
- gain = widget->rect().left()-ret.left();
- ret.adjust(-gain,0,0,0);
+ gain = widget->rect().left() - ret.left();
+ ret.adjust(-gain, 0, 0, 0);
} else {
if ((ret.right() + gain) > widget->rect().right())
- gain = widget->rect().right()-ret.right();
- ret.adjust(0,0,gain,0);
+ gain = widget->rect().right() - ret.right();
+ ret.adjust(0, 0, gain, 0);
}
}
break;
@@ -2664,8 +2710,8 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
default: {
if (widget) {
if ((ret.bottom() + gain) > widget->rect().bottom())
- gain = widget->rect().bottom()-ret.bottom();
- ret.adjust(0,0,0,gain);
+ gain = widget->rect().bottom() - ret.bottom();
+ ret.adjust(0, 0, 0, gain);
}
break;
}
@@ -2691,7 +2737,7 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
QS60StylePrivate::pixelMetric(QStyle::PM_LayoutVerticalSpacing);
//const int horizontalSpacing = QS60StylePrivate::pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
const int checkBoxRectWidth = subElementRect(SE_ItemViewItemCheckIndicator, opt, widget).width();
- ret.adjust(-checkBoxRectWidth-verticalSpacing,0,-checkBoxRectWidth-verticalSpacing,0);
+ ret.adjust(-checkBoxRectWidth - verticalSpacing, 0, -checkBoxRectWidth - verticalSpacing, 0);
}
} else if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
const bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable;
@@ -2716,9 +2762,9 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu){
// submenu indicator is very small, so lets halve the rect
if (menuItem->direction == Qt::LeftToRight)
- ret.adjust(0,0,-(indicatorWidth >> 1),0);
+ ret.adjust(0, 0, -(indicatorWidth >> 1), 0);
else
- ret.adjust((indicatorWidth >> 1),0,0,0);
+ ret.adjust((indicatorWidth >> 1), 0, 0, 0);
}
}
}
@@ -2742,14 +2788,14 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
const int itemHeight = opt->rect.height();
int heightOffset = 0;
if (indicatorHeight < itemHeight)
- heightOffset = ((itemHeight - indicatorHeight)>>1);
+ heightOffset = ((itemHeight - indicatorHeight) >> 1);
if (checkBoxOnly) {
// Move rect and make it slightly smaller, so that
// a) highlight border does not cross the rect
// b) in s60 list checkbox is smaller than normal checkbox
//todo; magic three
- ret.setRect(opt->rect.left()+3, opt->rect.top() + heightOffset,
- indicatorWidth-3, indicatorHeight-3);
+ ret.setRect(opt->rect.left() + 3, opt->rect.top() + heightOffset,
+ indicatorWidth - 3, indicatorHeight - 3);
} else {
ret.setRect(opt->rect.right() - indicatorWidth - spacing, opt->rect.top() + heightOffset,
indicatorWidth, indicatorHeight);
@@ -2913,7 +2959,7 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon,
const QStyleOption *option, const QWidget *widget) const
{
const int iconDimension = QS60StylePrivate::pixelMetric(QStyle::PM_ToolBarIconSize);
- const QRect iconSize = (!option) ? QRect(0,0,iconDimension,iconDimension) : option->rect;
+ const QRect iconSize = (!option) ? QRect(0, 0, iconDimension, iconDimension) : option->rect;
QS60StyleEnums::SkinParts part;
QS60StylePrivate::SkinElementFlags adjustedFlags;
if (option)
diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h
index eed66dc..65d7574 100644
--- a/src/gui/styles/qs60style_p.h
+++ b/src/gui/styles/qs60style_p.h
@@ -119,6 +119,9 @@ public:
SP_QgnGrafTabPassiveL,
SP_QgnGrafTabPassiveM,
SP_QgnGrafTabPassiveR,
+ SP_QgnGrafNsliderEndLeft,
+ SP_QgnGrafNsliderEndRight,
+ SP_QgnGrafNsliderMiddle,
SP_QgnIndiCheckboxOff,
SP_QgnIndiCheckboxOn,
SP_QgnIndiHlColSuper, // Available in S60 release 3.2 and later.
@@ -131,7 +134,8 @@ public:
SP_QgnIndiNaviArrowRight,
SP_QgnIndiRadiobuttOff,
SP_QgnIndiRadiobuttOn,
- SP_QgnIndiSliderEdit,
+ SP_QgnGrafNsliderMarker,
+ SP_QgnGrafNsliderMarkerSelected,
SP_QgnIndiSubMenu,
SP_QgnNoteErased,
SP_QgnNoteError,
@@ -313,6 +317,10 @@ public:
SE_ScrollBarHandleVertical,
SE_SliderHandleHorizontal,
SE_SliderHandleVertical,
+ SE_SliderHandleSelectedHorizontal,
+ SE_SliderHandleSelectedVertical,
+ SE_SliderGrooveVertical,
+ SE_SliderGrooveHorizontal,
SE_TabBarTabEastActive,
SE_TabBarTabEastInactive,
SE_TabBarTabNorthActive,
@@ -403,6 +411,7 @@ public:
static bool isTouchSupported();
static bool isToolBarBackground();
+ static bool hasSliderGrooveGraphic();
// calculates average color based on button skin graphics (minus borders).
QColor colorFromFrameGraphics(SkinFrameElements frame) const;
diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp
index fbea644..fb9665a 100644
--- a/src/gui/styles/qs60style_s60.cpp
+++ b/src/gui/styles/qs60style_s60.cpp
@@ -128,48 +128,57 @@ private:
};
const partMapEntry QS60StyleModeSpecifics::m_partMap[] = {
- /* SP_QgnGrafBarWait */ {KAknsIIDQgnGrafBarWaitAnim, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafBarFrameCenter */ {KAknsIIDQgnGrafBarFrameCenter, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafBarFrameSideL */ {KAknsIIDQgnGrafBarFrameSideL, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafBarFrameSideR */ {KAknsIIDQgnGrafBarFrameSideR, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafBarProgress */ {KAknsIIDQgnGrafBarProgress, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafScrollArrowDown */ {KAknsIIDQgnGrafScrollArrowDown, EDrawGulIcon, ES60_All, -1,-1},
- /* SP_QgnGrafScrollArrowLeft */ {KAknsIIDQgnGrafScrollArrowLeft, EDrawGulIcon, ES60_All, -1,-1},
- /* SP_QgnGrafScrollArrowRight */ {KAknsIIDQgnGrafScrollArrowRight, EDrawGulIcon, ES60_All, -1,-1},
- /* SP_QgnGrafScrollArrowUp */ {KAknsIIDQgnGrafScrollArrowUp, EDrawGulIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabActiveL */ {KAknsIIDQgnGrafTabActiveL, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabActiveM */ {KAknsIIDQgnGrafTabActiveM, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabActiveR */ {KAknsIIDQgnGrafTabActiveR, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabPassiveL */ {KAknsIIDQgnGrafTabPassiveL, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabPassiveM */ {KAknsIIDQgnGrafTabPassiveM, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabPassiveR */ {KAknsIIDQgnGrafTabPassiveR, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnIndiCheckboxOff */ {KAknsIIDQgnIndiCheckboxOff, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnIndiCheckboxOn */ {KAknsIIDQgnIndiCheckboxOn, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafBarWait */ {KAknsIIDQgnGrafBarWaitAnim, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafBarFrameCenter */ {KAknsIIDQgnGrafBarFrameCenter, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafBarFrameSideL */ {KAknsIIDQgnGrafBarFrameSideL, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafBarFrameSideR */ {KAknsIIDQgnGrafBarFrameSideR, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafBarProgress */ {KAknsIIDQgnGrafBarProgress, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafScrollArrowDown */ {KAknsIIDQgnGrafScrollArrowDown, EDrawGulIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafScrollArrowLeft */ {KAknsIIDQgnGrafScrollArrowLeft, EDrawGulIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafScrollArrowRight */ {KAknsIIDQgnGrafScrollArrowRight, EDrawGulIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafScrollArrowUp */ {KAknsIIDQgnGrafScrollArrowUp, EDrawGulIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafTabActiveL */ {KAknsIIDQgnGrafTabActiveL, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafTabActiveM */ {KAknsIIDQgnGrafTabActiveM, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafTabActiveR */ {KAknsIIDQgnGrafTabActiveR, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafTabPassiveL */ {KAknsIIDQgnGrafTabPassiveL, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafTabPassiveM */ {KAknsIIDQgnGrafTabPassiveM, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnGrafTabPassiveR */ {KAknsIIDQgnGrafTabPassiveR, EDrawIcon, ES60_All, -1,-1},
+
+ // In 3.1 there is no slider groove.
+ /* SP_QgnGrafNsliderEndLeft */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19cf /* KAknsIIDQgnGrafNsliderEndLeft */},
+ /* SP_QgnGrafNsliderEndRight */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d0 /* KAknsIIDQgnGrafNsliderEndRight */},
+ /* SP_QgnGrafNsliderMiddle */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d2 /* KAknsIIDQgnGrafNsliderMiddle */},
+ /* SP_QgnIndiCheckboxOff */ {KAknsIIDQgnIndiCheckboxOff, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiCheckboxOn */ {KAknsIIDQgnIndiCheckboxOn, EDrawIcon, ES60_All, -1,-1},
+
// Following 5 items (SP_QgnIndiHlColSuper - SP_QgnIndiHlLineStraight) are available starting from S60 release 3.2.
// In 3.1 CommonStyle drawing is used for these QTreeView elements, since no similar icons in AVKON UI.
- /* SP_QgnIndiHlColSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d5 /* KAknsIIDQgnIndiHlColSuper */},
- /* SP_QgnIndiHlExpSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d6 /* KAknsIIDQgnIndiHlExpSuper */},
- /* SP_QgnIndiHlLineBranch */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d7 /* KAknsIIDQgnIndiHlLineBranch */},
- /* SP_QgnIndiHlLineEnd */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d8 /* KAknsIIDQgnIndiHlLineEnd */},
- /* SP_QgnIndiHlLineStraight */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d9 /* KAknsIIDQgnIndiHlLineStraight */},
- /* SP_QgnIndiMarkedAdd */ {KAknsIIDQgnIndiMarkedAdd, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnIndiNaviArrowLeft */ {KAknsIIDQgnIndiNaviArrowLeft, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnIndiNaviArrowRight */ {KAknsIIDQgnIndiNaviArrowRight, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnIndiRadiobuttOff */ {KAknsIIDQgnIndiRadiobuttOff, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnIndiRadiobuttOn */ {KAknsIIDQgnIndiRadiobuttOn, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnIndiSliderEdit */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnIndiSubMenu */ {KAknsIIDQgnIndiSubmenu, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnNoteErased */ {KAknsIIDQgnNoteErased, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnNoteError */ {KAknsIIDQgnNoteError, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnNoteInfo */ {KAknsIIDQgnNoteInfo, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnNoteOk */ {KAknsIIDQgnNoteOk, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnNoteQuery */ {KAknsIIDQgnNoteQuery, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnNoteWarning */ {KAknsIIDQgnNoteWarning, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnPropFileSmall */ {KAknsIIDQgnPropFileSmall, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnPropFolderCurrent */ {KAknsIIDQgnPropFolderCurrent, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnPropFolderSmall */ {KAknsIIDQgnPropFolderSmall, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnPropFolderSmallNew */ {KAknsIIDQgnPropFolderSmallNew, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnPropPhoneMemcLarge */ {KAknsIIDQgnPropPhoneMemcLarge, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiHlColSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d5 /* KAknsIIDQgnIndiHlColSuper */},
+ /* SP_QgnIndiHlExpSuper */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d6 /* KAknsIIDQgnIndiHlExpSuper */},
+ /* SP_QgnIndiHlLineBranch */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d7 /* KAknsIIDQgnIndiHlLineBranch */},
+ /* SP_QgnIndiHlLineEnd */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d8 /* KAknsIIDQgnIndiHlLineEnd */},
+ /* SP_QgnIndiHlLineStraight */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x17d9 /* KAknsIIDQgnIndiHlLineStraight */},
+ /* SP_QgnIndiMarkedAdd */ {KAknsIIDQgnIndiMarkedAdd, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiNaviArrowLeft */ {KAknsIIDQgnIndiNaviArrowLeft, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiNaviArrowRight */ {KAknsIIDQgnIndiNaviArrowRight, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiRadiobuttOff */ {KAknsIIDQgnIndiRadiobuttOff, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnIndiRadiobuttOn */ {KAknsIIDQgnIndiRadiobuttOn, EDrawIcon, ES60_All, -1,-1},
+
+ // In 3.1 there different slider graphic and no pressed state.
+ /* SP_QgnGrafNsliderMarker */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d1 /* KAknsIIDQgnGrafNsliderMarker */},
+ /* SP_QgnGrafNsliderMarkerSelected */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x1a4a /* KAknsIIDQgnGrafNsliderMarkerSelected */},
+ /* SP_QgnIndiSubMenu */ {KAknsIIDQgnIndiSubmenu, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteErased */ {KAknsIIDQgnNoteErased, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteError */ {KAknsIIDQgnNoteError, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteInfo */ {KAknsIIDQgnNoteInfo, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteOk */ {KAknsIIDQgnNoteOk, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteQuery */ {KAknsIIDQgnNoteQuery, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnNoteWarning */ {KAknsIIDQgnNoteWarning, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropFileSmall */ {KAknsIIDQgnPropFileSmall, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropFolderCurrent */ {KAknsIIDQgnPropFolderCurrent, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropFolderSmall */ {KAknsIIDQgnPropFolderSmall, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropFolderSmallNew */ {KAknsIIDQgnPropFolderSmallNew, EDrawIcon, ES60_All, -1,-1},
+ /* SP_QgnPropPhoneMemcLarge */ {KAknsIIDQgnPropPhoneMemcLarge, EDrawIcon, ES60_All, -1,-1},
// 3.1 & 3.2 do not have pressed state for scrollbar, so use normal scrollbar graphics instead.
/* SP_QsnCpScrollHandleBottomPressed*/ {KAknsIIDQsnCpScrollHandleBottom, EDrawIcon, ES60_3_X, EAknsMajorGeneric, 0x20f8}, /*KAknsIIDQsnCpScrollHandleBottomPressed*/
@@ -431,8 +440,11 @@ void QS60StyleModeSpecifics::fallbackInfo(const QS60StyleEnums::SkinParts &style
case QS60StyleEnums::SP_QgnIndiRadiobuttOn:
fallbackIndex = EMbmAvkonQgn_indi_radiobutt_on;
break;
- case QS60StyleEnums::SP_QgnIndiSliderEdit:
- fallbackIndex = EMbmAvkonQgn_indi_slider_edit;
+ case QS60StyleEnums::SP_QgnGrafNsliderMarker:
+ fallbackIndex = 17572; /* EMbmAvkonQgn_graf_nslider_marker */
+ break;
+ case QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected:
+ fallbackIndex = 17574; /* EMbmAvkonQgn_graf_nslider_marker_selected */
break;
case QS60StyleEnums::SP_QgnIndiSubMenu:
fallbackIndex = EMbmAvkonQgn_indi_submenu;
@@ -587,6 +599,11 @@ bool QS60StylePrivate::isToolBarBackground()
return (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2);
}
+bool QS60StylePrivate::hasSliderGrooveGraphic()
+{
+ return QSysInfo::s60Version() != QSysInfo::SV_S60_3_1;
+}
+
QPoint qt_s60_fill_background_offset(const QWidget *targetWidget)
{
CCoeControl *control = targetWidget->effectiveWinId();
@@ -943,37 +960,23 @@ void QS60StylePrivate::setActiveLayout()
{
const QSize activeScreenSize(screenSize());
int activeLayoutIndex = -1;
- const bool mirrored = !QApplication::isLeftToRight();
const short screenHeight = (short)activeScreenSize.height();
const short screenWidth = (short)activeScreenSize.width();
for (int i=0; i<m_numberOfLayouts; i++) {
if (screenHeight==m_layoutHeaders[i].height &&
- screenWidth==m_layoutHeaders[i].width &&
- mirrored==m_layoutHeaders[i].mirroring) {
+ screenWidth==m_layoutHeaders[i].width) {
activeLayoutIndex = i;
break;
}
}
- //not found, lets try without mirroring info
- if (activeLayoutIndex==-1){
- for (int i=0; i<m_numberOfLayouts; i++) {
- if (screenHeight==m_layoutHeaders[i].height &&
- screenWidth==m_layoutHeaders[i].width) {
- activeLayoutIndex = i;
- break;
- }
- }
- }
-
//not found, lets try with either of dimensions
if (activeLayoutIndex==-1){
const QSysInfo::S60Version currentRelease = QSysInfo::s60Version();
const bool landscape = screenHeight < screenWidth;
- activeLayoutIndex = (currentRelease == QSysInfo::SV_S60_3_1 || currentRelease == QSysInfo::SV_S60_3_2) ? 0 : 4;
- activeLayoutIndex += (!landscape) ? 2 : 0;
- activeLayoutIndex += (!mirrored) ? 1 : 0;
+ activeLayoutIndex = (currentRelease == QSysInfo::SV_S60_3_1 || currentRelease == QSysInfo::SV_S60_3_2) ? 0 : 2;
+ activeLayoutIndex += (!landscape) ? 1 : 0;
}
m_pmPointer = data[activeLayoutIndex];
@@ -1130,9 +1133,21 @@ QPixmap QS60StylePrivate::frame(SkinFrameElements frame, const QSize &size, Skin
QPixmap QS60StylePrivate::backgroundTexture()
{
+ bool createNewBackground = false;
if (!m_background) {
+ createNewBackground = true;
+ } else {
+ //if background brush does not match screensize, re-create it
+ if (m_background->width() != S60->screenWidthInPixels ||
+ m_background->height() != S60->screenHeightInPixels) {
+ delete m_background;
+ createNewBackground = true;
+ }
+ }
+
+ if (createNewBackground) {
QPixmap background = part(QS60StyleEnums::SP_QsnBgScreen,
- QSize(S60->screenWidthInPixels, S60->screenHeightInPixels), 0, SkinElementFlags());
+ QSize(S60->screenWidthInPixels, S60->screenHeightInPixels), 0, SkinElementFlags());
m_background = new QPixmap(background);
}
return *m_background;
@@ -1140,8 +1155,7 @@ QPixmap QS60StylePrivate::backgroundTexture()
QSize QS60StylePrivate::screenSize()
{
- const TSize screenSize = QS60Data::screenDevice()->SizeInPixels();
- return QSize(screenSize.iWidth, screenSize.iHeight);
+ return QSize(S60->screenWidthInPixels, S60->screenHeightInPixels);
}
QS60Style::QS60Style()
diff --git a/src/gui/styles/qs60style_simulated.cpp b/src/gui/styles/qs60style_simulated.cpp
index 55d5771..e49854f 100644
--- a/src/gui/styles/qs60style_simulated.cpp
+++ b/src/gui/styles/qs60style_simulated.cpp
@@ -337,6 +337,11 @@ bool QS60StylePrivate::isToolBarBackground()
return true;
}
+bool QS60StylePrivate::hasSliderGrooveGraphic()
+{
+ return false;
+}
+
QFont QS60StylePrivate::s60Font_specific(QS60StyleEnums::FontCategories fontCategory, int pointSize)
{
QFont result;
diff --git a/src/gui/styles/qstylehelper.cpp b/src/gui/styles/qstylehelper.cpp
index af30f15..f5af960 100644
--- a/src/gui/styles/qstylehelper.cpp
+++ b/src/gui/styles/qstylehelper.cpp
@@ -154,7 +154,7 @@ qreal angle(const QPointF &p1, const QPointF &p2)
}
qreal m = -(y2 - y1) / (x2 - x1);
- _angle = atan(m) * rad_factor;
+ _angle = qAtan(m) * rad_factor;
if (p1.x() < p2.x())
_angle = 180 - _angle;
diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp
index 8b40931..ca6968b 100644
--- a/src/gui/styles/qstylesheetstyle.cpp
+++ b/src/gui/styles/qstylesheetstyle.cpp
@@ -1350,6 +1350,12 @@ void QRenderRule::configurePalette(QPalette *p, QPalette::ColorRole fr, QPalette
if (br != QPalette::NoRole)
p->setBrush(br, bg->brush);
p->setBrush(QPalette::Window, bg->brush);
+ if (bg->brush.style() == Qt::SolidPattern) {
+ p->setBrush(QPalette::Light, bg->brush.color().lighter(115));
+ p->setBrush(QPalette::Midlight, bg->brush.color().lighter(107));
+ p->setBrush(QPalette::Dark, bg->brush.color().darker(150));
+ p->setBrush(QPalette::Shadow, bg->brush.color().darker(300));
+ }
}
if (!hasPalette())
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 7e93aa0..e9c7b89 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -1482,13 +1482,13 @@ QString QFontDatabase::styleString(const QFontInfo &fontInfo)
and style will look attractive.
If the font family is available from two or more foundries the
- foundry name is included in the family name, e.g. "Helvetica
- [Adobe]" and "Helvetica [Cronyx]". When you specify a family you
- can either use the old hyphenated Qt 2.x "foundry-family" format,
- e.g. "Cronyx-Helvetica", or the new bracketed Qt 3.x "family
- [foundry]" format e.g. "Helvetica [Cronyx]". If the family has a
- foundry it is always returned, e.g. by families(), using the
- bracketed format.
+ foundry name is included in the family name; for example:
+ "Helvetica [Adobe]" and "Helvetica [Cronyx]". When you specify a
+ family, you can either use the old hyphenated "foundry-family"
+ format or the bracketed "family [foundry]" format; for example:
+ "Cronyx-Helvetica" or "Helvetica [Cronyx]". If the family has a
+ foundry it is always returned using the bracketed format, as is
+ the case with the value returned by families().
The font() function returns a QFont given a family, style and
point size.
diff --git a/src/gui/text/qfontdatabase_win.cpp b/src/gui/text/qfontdatabase_win.cpp
index 6cde9ed..2fe1196 100644
--- a/src/gui/text/qfontdatabase_win.cpp
+++ b/src/gui/text/qfontdatabase_win.cpp
@@ -1101,7 +1101,6 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
if (AddFontResource((LPCWSTR)fnt->fileName.utf16()) == 0)
return;
#else
- // supported from 2000 on, so no need to deal with the *A variant
PtrAddFontResourceExW ptrAddFontResourceExW = (PtrAddFontResourceExW)QLibrary::resolve(QLatin1String("gdi32"),
"AddFontResourceExW");
if (!ptrAddFontResourceExW
diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
index a4e7c04..a75d70f 100644
--- a/src/gui/text/qfontengine_mac.mm
+++ b/src/gui/text/qfontengine_mac.mm
@@ -404,7 +404,9 @@ QFixed QCoreTextFontEngine::ascent() const
}
QFixed QCoreTextFontEngine::descent() const
{
- return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil();
+ // subtract a pixel to even out the historical +1 in QFontMetrics::height().
+ // Fix in Qt 5.
+ return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil() - 1;
}
QFixed QCoreTextFontEngine::leading() const
{
@@ -1406,7 +1408,9 @@ QFixed QFontEngineMac::ascent() const
QFixed QFontEngineMac::descent() const
{
- return m_descent;
+ // subtract a pixel to even out the historical +1 in QFontMetrics::height().
+ // Fix in Qt 5.
+ return m_descent - 1;
}
QFixed QFontEngineMac::leading() const
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index f96f66b..f523226 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -1938,7 +1938,11 @@ void QTextControlPrivate::focusEvent(QFocusEvent *e)
emit q->updateRequest(q->selectionRect());
if (e->gotFocus()) {
#ifdef QT_KEYPAD_NAVIGATION
- if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && e->reason() == Qt::PopupFocusReason)) {
+ if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && (e->reason() == Qt::PopupFocusReason
+#ifdef Q_OS_SYMBIAN
+ || e->reason() == Qt::ActiveWindowFocusReason
+#endif
+ ))) {
#endif
cursorOn = (interactionFlags & Qt::TextSelectableByKeyboard);
if (interactionFlags & Qt::TextEditable) {
diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp
index ce62834..f1dbf23 100644
--- a/src/gui/text/qtextcursor.cpp
+++ b/src/gui/text/qtextcursor.cpp
@@ -862,27 +862,28 @@ QTextLayout *QTextCursorPrivate::blockLayout(QTextBlock &block) const{
\ingroup richtext-processing
\ingroup shared
-
- Text cursors are objects that are used to access and modify the contents
- and underlying structure of text documents via a programming interface
- that mimics the behavior of a cursor in a text editor. QTextCursor contains
- information about both the cursor's position within a QTextDocument and any
- selection that it has made.
+ Text cursors are objects that are used to access and modify the
+ contents and underlying structure of text documents via a
+ programming interface that mimics the behavior of a cursor in a
+ text editor. QTextCursor contains information about both the
+ cursor's position within a QTextDocument and any selection that it
+ has made.
QTextCursor is modeled on the way a text cursor behaves in a text
- editor, providing a programmatic means of performing standard actions
- through the user interface. A document can be thought of as a
- single string of characters with the cursor's position() being \e
- between any two characters (or at the very beginning or very end
- of the document). Documents can also contain tables, lists,
- images, and other objects in addition to text but, from the developer's
- point of view, the document can be treated as one long string.
- Some portions of that string can be considered to lie within particular
- blocks (e.g. paragraphs), or within a table's cell, or a list's item,
- or other structural elements. When we refer to "current character" we
- mean the character immediately after the cursor position() in the
- document; similarly the "current block" is the block that contains the
- cursor position().
+ editor, providing a programmatic means of performing standard
+ actions through the user interface. A document can be thought of
+ as a single string of characters. The cursor's current position()
+ then is always either \e between two consecutive characters in the
+ string, or else \e before the very first character or \e after the
+ very last character in the string. Documents can also contain
+ tables, lists, images, and other objects in addition to text but,
+ from the developer's point of view, the document can be treated as
+ one long string. Some portions of that string can be considered
+ to lie within particular blocks (e.g. paragraphs), or within a
+ table's cell, or a list's item, or other structural elements. When
+ we refer to "current character" we mean the character immediately
+ \e before the cursor position() in the document. Similarly, the
+ "current block" is the block that contains the cursor position().
A QTextCursor also has an anchor() position. The text that is
between the anchor() and the position() is the selection. If
@@ -940,11 +941,12 @@ QTextLayout *QTextCursorPrivate::blockLayout(QTextBlock &block) const{
undo/redo) using beginEditBlock() and endEditBlock().
Cursor movements are limited to valid cursor positions. In Latin
- writing this is usually after every character in the text. In some
- other writing systems cursor movements are limited to "clusters"
- (e.g. a syllable in Devanagari, or a base letter plus diacritics).
- Functions such as movePosition() and deleteChar() limit cursor
- movement to these valid positions.
+ writing this is between any two consecutive characters in the
+ text, before the first character, or after the last character. In
+ some other writing systems cursor movements are limited to
+ "clusters" (e.g. a syllable in Devanagari, or a base letter plus
+ diacritics). Functions such as movePosition() and deleteChar()
+ limit cursor movement to these valid positions.
\sa \link richtext.html Rich Text Processing\endlink
@@ -1739,8 +1741,9 @@ void QTextCursor::mergeBlockCharFormat(const QTextCharFormat &modifier)
}
/*!
- Returns the format of the character immediately before the cursor position(). If the cursor is
- positioned at the beginning of a text block that is not empty then the format of the character
+ Returns the format of the character immediately before the cursor
+ position(). If the cursor is positioned at the beginning of a text
+ block that is not empty then the format of the character
immediately after the cursor is returned.
\sa insertText(), blockFormat()
diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp
index 1bd4dd6..dcc2e7d 100644
--- a/src/gui/text/qtextodfwriter.cpp
+++ b/src/gui/text/qtextodfwriter.cpp
@@ -484,6 +484,10 @@ void QTextOdfWriter::writeBlockFormat(QXmlStreamWriter &writer, QTextBlockFormat
if (format.pageBreakPolicy() & QTextFormat::PageBreak_AlwaysAfter)
writer.writeAttribute(foNS, QString::fromLatin1("break-after"), QString::fromLatin1("page"));
}
+ if (format.hasProperty(QTextFormat::BackgroundBrush)) {
+ QBrush brush = format.background();
+ writer.writeAttribute(foNS, QString::fromLatin1("background-color"), brush.color().name());
+ }
if (format.hasProperty(QTextFormat::BlockNonBreakableLines))
writer.writeAttribute(foNS, QString::fromLatin1("keep-together"),
format.nonBreakableLines() ? QString::fromLatin1("true") : QString::fromLatin1("false"));
@@ -552,8 +556,8 @@ void QTextOdfWriter::writeCharacterFormat(QXmlStreamWriter &writer, QTextCharFor
}
if (format.hasProperty(QTextFormat::FontLetterSpacing))
writer.writeAttribute(foNS, QString::fromLatin1("letter-spacing"), pixelToPoint(format.fontLetterSpacing()));
- if (format.hasProperty(QTextFormat::FontWordSpacing))
- writer.writeAttribute(foNS, QString::fromLatin1("word-spacing"), pixelToPoint(format.fontWordSpacing()));
+ if (format.hasProperty(QTextFormat::FontWordSpacing) && format.fontWordSpacing() != 0)
+ writer.writeAttribute(foNS, QString::fromLatin1("word-spacing"), pixelToPoint(format.fontWordSpacing()));
if (format.hasProperty(QTextFormat::FontUnderline))
writer.writeAttribute(styleNS, QString::fromLatin1("text-underline-type"),
format.fontUnderline() ? QString::fromLatin1("single") : QString::fromLatin1("none"));
@@ -610,9 +614,12 @@ void QTextOdfWriter::writeCharacterFormat(QXmlStreamWriter &writer, QTextCharFor
}
if (format.hasProperty(QTextFormat::ForegroundBrush)) {
QBrush brush = format.foreground();
- // TODO
writer.writeAttribute(foNS, QString::fromLatin1("color"), brush.color().name());
}
+ if (format.hasProperty(QTextFormat::BackgroundBrush)) {
+ QBrush brush = format.background();
+ writer.writeAttribute(foNS, QString::fromLatin1("background-color"), brush.color().name());
+ }
writer.writeEndElement(); // style
}
diff --git a/src/gui/util/qdesktopservices_win.cpp b/src/gui/util/qdesktopservices_win.cpp
index 39443f2..e4c99a8 100644
--- a/src/gui/util/qdesktopservices_win.cpp
+++ b/src/gui/util/qdesktopservices_win.cpp
@@ -97,19 +97,19 @@ static bool launchWebBrowser(const QUrl &url)
if (url.scheme() == QLatin1String("mailto")) {
//Retrieve the commandline for the default mail client
//the default key used below is the command line for the mailto: shell command
- DWORD bufferSize = 2 * MAX_PATH;
+ DWORD bufferSize = sizeof(wchar_t) * MAX_PATH;
long returnValue = -1;
QString command;
HKEY handle;
LONG res;
- wchar_t keyValue[2 * MAX_PATH] = {0};
+ wchar_t keyValue[MAX_PATH] = {0};
QString keyName(QLatin1String("mailto"));
//Check if user has set preference, otherwise use default.
- res = RegOpenKeyExW(HKEY_CURRENT_USER,
- L"Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\mailto\\UserChoice",
- 0, KEY_READ, &handle);
+ res = RegOpenKeyEx(HKEY_CURRENT_USER,
+ L"Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\mailto\\UserChoice",
+ 0, KEY_READ, &handle);
if (res == ERROR_SUCCESS) {
returnValue = RegQueryValueEx(handle, L"Progid", 0, 0, reinterpret_cast<unsigned char*>(keyValue), &bufferSize);
if (!returnValue)
@@ -121,8 +121,8 @@ static bool launchWebBrowser(const QUrl &url)
if (res != ERROR_SUCCESS)
return false;
- bufferSize = 2 * MAX_PATH;
- returnValue = RegQueryValueExW(handle, L"", 0, 0, reinterpret_cast<unsigned char*>(keyValue), &bufferSize);
+ bufferSize = sizeof(wchar_t) * MAX_PATH;
+ returnValue = RegQueryValueEx(handle, L"", 0, 0, reinterpret_cast<unsigned char*>(keyValue), &bufferSize);
if (!returnValue)
command = QString::fromRawData((QChar*)keyValue, bufferSize);
RegCloseKey(handle);
diff --git a/src/gui/util/qsystemtrayicon_p.h b/src/gui/util/qsystemtrayicon_p.h
index 86de366..029a259 100644
--- a/src/gui/util/qsystemtrayicon_p.h
+++ b/src/gui/util/qsystemtrayicon_p.h
@@ -94,6 +94,7 @@ public:
class QBalloonTip : public QWidget
{
+ Q_OBJECT
public:
static void showBalloon(QSystemTrayIcon::MessageIcon icon, const QString& title,
const QString& msg, QSystemTrayIcon *trayIcon,
diff --git a/src/gui/util/qsystemtrayicon_win.cpp b/src/gui/util/qsystemtrayicon_win.cpp
index 362be5b..474555b 100644
--- a/src/gui/util/qsystemtrayicon_win.cpp
+++ b/src/gui/util/qsystemtrayicon_win.cpp
@@ -83,7 +83,11 @@ struct Q_NOTIFYICONIDENTIFIER {
GUID guidItem;
};
+#define Q_MSGFLT_ALLOW 1
+
typedef HRESULT (WINAPI *PtrShell_NotifyIconGetRect)(const Q_NOTIFYICONIDENTIFIER* identifier, RECT* iconLocation);
+typedef BOOL (WINAPI *PtrChangeWindowMessageFilter)(UINT message, DWORD dwFlag);
+typedef BOOL (WINAPI *PtrChangeWindowMessageFilterEx)(HWND hWnd, UINT message, DWORD action, void* pChangeFilterStruct);
class QSystemTrayIconSys : QWidget
{
@@ -143,6 +147,23 @@ QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *object)
if (!MYWM_TASKBARCREATED) {
MYWM_TASKBARCREATED = RegisterWindowMessage(L"TaskbarCreated");
}
+
+ // Allow the WM_TASKBARCREATED message through the UIPI filter on Windows Vista and higher
+ static PtrChangeWindowMessageFilterEx pChangeWindowMessageFilterEx =
+ (PtrChangeWindowMessageFilterEx)QLibrary::resolve(QLatin1String("user32"), "ChangeWindowMessageFilterEx");
+
+ if (pChangeWindowMessageFilterEx) {
+ // Call the safer ChangeWindowMessageFilterEx API if available
+ pChangeWindowMessageFilterEx(winId(), MYWM_TASKBARCREATED, Q_MSGFLT_ALLOW, 0);
+ } else {
+ static PtrChangeWindowMessageFilter pChangeWindowMessageFilter =
+ (PtrChangeWindowMessageFilter)QLibrary::resolve(QLatin1String("user32"), "ChangeWindowMessageFilter");
+
+ if (pChangeWindowMessageFilter) {
+ // Call the deprecated ChangeWindowMessageFilter API otherwise
+ pChangeWindowMessageFilter(MYWM_TASKBARCREATED, Q_MSGFLT_ALLOW);
+ }
+ }
}
QSystemTrayIconSys::~QSystemTrayIconSys()
diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp
index c015589..e26d5c3 100644
--- a/src/gui/widgets/qabstractspinbox.cpp
+++ b/src/gui/widgets/qabstractspinbox.cpp
@@ -65,6 +65,11 @@
#include <limits.h>
#endif
+#if defined(Q_OS_SYMBIAN)
+#include <W32STD.H>
+#include <private/qt_s60_p.h>
+#endif
+
//#define QABSTRACTSPINBOX_QSBDEBUG
#ifdef QABSTRACTSPINBOX_QSBDEBUG
# define QASBDEBUG qDebug
@@ -939,10 +944,12 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event)
d->edit->setCursorPosition(d->prefix.size());
int steps = 1;
+ bool isPgUpOrDown = false;
switch (event->key()) {
case Qt::Key_PageUp:
case Qt::Key_PageDown:
steps *= 10;
+ isPgUpOrDown = true;
case Qt::Key_Up:
case Qt::Key_Down: {
#ifdef QT_KEYPAD_NAVIGATION
@@ -964,7 +971,13 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event)
if (style()->styleHint(QStyle::SH_SpinBox_AnimateButton, 0, this)) {
d->buttonState = (Keyboard | (up ? Up : Down));
}
- stepBy(steps);
+ if (d->spinClickTimerId == -1)
+ stepBy(steps);
+ if(event->isAutoRepeat() && !isPgUpOrDown) {
+ if(d->spinClickThresholdTimerId == -1 && d->spinClickTimerId == -1) {
+ d->updateState(up, true);
+ }
+ }
#ifndef QT_NO_ACCESSIBILITY
QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged);
#endif
@@ -1061,8 +1074,7 @@ void QAbstractSpinBox::keyReleaseEvent(QKeyEvent *event)
{
Q_D(QAbstractSpinBox);
- if (d->buttonState & Keyboard && !event->isAutoRepeat()
- && style()->styleHint(QStyle::SH_SpinBox_AnimateButton, 0, this)) {
+ if (d->buttonState & Keyboard && !event->isAutoRepeat()) {
d->reset();
} else {
d->edit->event(event);
@@ -1148,6 +1160,34 @@ void QAbstractSpinBox::hideEvent(QHideEvent *event)
QWidget::hideEvent(event);
}
+
+/*!
+ \internal
+
+ Used when acceleration is turned on. We need to get the
+ keyboard auto repeat rate from OS. This value is used as
+ argument when starting acceleration related timers.
+
+ Every platform should, either, use native calls to obtain
+ the value or hard code some reasonable rate.
+
+ Remember that time value should be given in msecs.
+*/
+static int getKeyboardAutoRepeatRate() {
+ int ret = 30;
+#if defined(Q_OS_SYMBIAN)
+ TTimeIntervalMicroSeconds32 initialTime;
+ TTimeIntervalMicroSeconds32 time;
+ S60->wsSession().GetKeyboardRepeatRate(initialTime, time);
+ ret = time.Int() / 1000; // msecs
+#elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ DWORD time;
+ if (SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &time, 0) != FALSE)
+ ret = static_cast<int>(1000 / static_cast<int>(time)); // msecs
+#endif
+ return ret; // msecs
+}
+
/*!
\reimp
*/
@@ -1160,14 +1200,17 @@ void QAbstractSpinBox::timerEvent(QTimerEvent *event)
if (event->timerId() == d->spinClickThresholdTimerId) {
killTimer(d->spinClickThresholdTimerId);
d->spinClickThresholdTimerId = -1;
- d->spinClickTimerId = startTimer(d->spinClickTimerInterval);
+ d->effectiveSpinRepeatRate = d->buttonState & Keyboard
+ ? getKeyboardAutoRepeatRate()
+ : d->spinClickTimerInterval;
+ d->spinClickTimerId = startTimer(d->effectiveSpinRepeatRate);
doStep = true;
} else if (event->timerId() == d->spinClickTimerId) {
if (d->accelerate) {
- d->acceleration = d->acceleration + (int)(d->spinClickTimerInterval * 0.05);
- if (d->spinClickTimerInterval - d->acceleration >= 10) {
+ d->acceleration = d->acceleration + (int)(d->effectiveSpinRepeatRate * 0.05);
+ if (d->effectiveSpinRepeatRate - d->acceleration >= 10) {
killTimer(d->spinClickTimerId);
- d->spinClickTimerId = startTimer(d->spinClickTimerInterval - d->acceleration);
+ d->spinClickTimerId = startTimer(d->effectiveSpinRepeatRate - d->acceleration);
}
}
doStep = true;
@@ -1308,8 +1351,8 @@ void QAbstractSpinBox::mouseReleaseEvent(QMouseEvent *event)
QAbstractSpinBoxPrivate::QAbstractSpinBoxPrivate()
: edit(0), type(QVariant::Invalid), spinClickTimerId(-1),
spinClickTimerInterval(100), spinClickThresholdTimerId(-1), spinClickThresholdTimerInterval(-1),
- buttonState(None), cachedText(QLatin1String("\x01")), cachedState(QValidator::Invalid),
- pendingEmit(false), readOnly(false), wrapping(false),
+ effectiveSpinRepeatRate(1), buttonState(None), cachedText(QLatin1String("\x01")),
+ cachedState(QValidator::Invalid), pendingEmit(false), readOnly(false), wrapping(false),
ignoreCursorPositionChanged(false), frame(true), accelerate(false), keyboardTracking(true),
cleared(false), ignoreUpdateEdit(false), correctionMode(QAbstractSpinBox::CorrectToPreviousValue),
acceleration(0), hoverControl(QStyle::SC_None), buttonSymbols(QAbstractSpinBox::UpDownArrows), validator(0)
@@ -1554,7 +1597,7 @@ void QAbstractSpinBoxPrivate::reset()
Updates the state of the spinbox.
*/
-void QAbstractSpinBoxPrivate::updateState(bool up)
+void QAbstractSpinBoxPrivate::updateState(bool up, bool fromKeyboard /* = false */)
{
Q_Q(QAbstractSpinBox);
if ((up && (buttonState & Up)) || (!up && (buttonState & Down)))
@@ -1563,7 +1606,7 @@ void QAbstractSpinBoxPrivate::updateState(bool up)
if (q && (q->stepEnabled() & (up ? QAbstractSpinBox::StepUpEnabled
: QAbstractSpinBox::StepDownEnabled))) {
spinClickThresholdTimerId = q->startTimer(spinClickThresholdTimerInterval);
- buttonState = (up ? (Mouse | Up) : (Mouse | Down));
+ buttonState = (up ? Up : Down) | (fromKeyboard ? Keyboard : Mouse);
q->stepBy(up ? 1 : -1);
#ifndef QT_NO_ACCESSIBILITY
QAccessible::updateAccessibility(q, 0, QAccessible::ValueChanged);
diff --git a/src/gui/widgets/qabstractspinbox_p.h b/src/gui/widgets/qabstractspinbox_p.h
index 3020cbc..55f94d7 100644
--- a/src/gui/widgets/qabstractspinbox_p.h
+++ b/src/gui/widgets/qabstractspinbox_p.h
@@ -98,7 +98,7 @@ public:
void init();
void reset();
- void updateState(bool up);
+ void updateState(bool up, bool fromKeyboard = false);
QString stripped(const QString &text, int *pos = 0) const;
bool specialValue() const;
virtual QVariant getZeroVariant() const;
@@ -129,6 +129,7 @@ public:
QVariant value, minimum, maximum, singleStep;
QVariant::Type type;
int spinClickTimerId, spinClickTimerInterval, spinClickThresholdTimerId, spinClickThresholdTimerInterval;
+ int effectiveSpinRepeatRate;
uint buttonState;
mutable QString cachedText;
mutable QVariant cachedValue;
diff --git a/src/gui/widgets/qcocoamenu_mac_p.h b/src/gui/widgets/qcocoamenu_mac_p.h
index 3ad0ab8..57b4e17 100644
--- a/src/gui/widgets/qcocoamenu_mac_p.h
+++ b/src/gui/widgets/qcocoamenu_mac_p.h
@@ -52,10 +52,10 @@
#include "qmacdefines_mac.h"
#ifdef QT_MAC_USE_COCOA
-#include <qpointer.h>
#import <Cocoa/Cocoa.h>
QT_FORWARD_DECLARE_CLASS(QMenu)
+QT_FORWARD_DECLARE_CLASS(QAction)
#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
@@ -72,7 +72,7 @@ QT_FORWARD_DECLARE_CLASS(QMenu)
@interface QT_MANGLE_NAMESPACE(QCocoaMenu) : NSMenu <NSMenuDelegate>
{
QMenu *qmenu;
- QPointer<QAction> previousAction;
+ QAction *previousAction;
}
- (id)initWithQMenu:(QMenu*)menu;
- (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event target:(id *)target action:(SEL *)action;
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index ea65a40..2e2acb7 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -931,7 +931,10 @@ void QComboBoxPrivate::init()
QSizePolicy::ComboBox));
setLayoutItemMargins(QStyle::SE_ComboBoxLayoutItem);
q->setModel(new QStandardItemModel(0, 1, q));
- q->setAttribute(Qt::WA_InputMethodEnabled);
+ if (!q->isEditable())
+ q->setAttribute(Qt::WA_InputMethodEnabled, false);
+ else
+ q->setAttribute(Qt::WA_InputMethodEnabled);
}
QComboBoxPrivateContainer* QComboBoxPrivate::viewContainer()
diff --git a/src/gui/widgets/qdial.cpp b/src/gui/widgets/qdial.cpp
index 95e6ed5..dc02c02 100644
--- a/src/gui/widgets/qdial.cpp
+++ b/src/gui/widgets/qdial.cpp
@@ -59,6 +59,7 @@
#ifndef QT_NO_ACCESSIBILITY
#include "qaccessible.h"
#endif
+#include <qmath.h>
QT_BEGIN_NAMESPACE
@@ -135,7 +136,7 @@ int QDialPrivate::valueFromPoint(const QPoint &p) const
Q_Q(const QDial);
double yy = (double)q->height()/2.0 - p.y();
double xx = (double)p.x() - q->width()/2.0;
- double a = (xx || yy) ? atan2(yy, xx) : 0;
+ double a = (xx || yy) ? qAtan2(yy, xx) : 0;
if (a < Q_PI / -2)
a = a + Q_PI * 2;
diff --git a/src/gui/widgets/qfocusframe.cpp b/src/gui/widgets/qfocusframe.cpp
index e96f50d..02f76f1 100644
--- a/src/gui/widgets/qfocusframe.cpp
+++ b/src/gui/widgets/qfocusframe.cpp
@@ -53,11 +53,14 @@ class QFocusFramePrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QFocusFrame)
QWidget *widget;
-
+ QWidget *frameParent;
+ bool showFrameAboveWidget;
public:
QFocusFramePrivate() {
widget = 0;
+ frameParent = 0;
sendChildEvents = false;
+ showFrameAboveWidget = false;
}
void updateSize();
void update();
@@ -66,10 +69,10 @@ public:
void QFocusFramePrivate::update()
{
Q_Q(QFocusFrame);
- q->setParent(widget->parentWidget());
+ q->setParent(frameParent);
updateSize();
if (q->parentWidget()->rect().intersects(q->geometry())) {
- if (q->style()->styleHint(QStyle::SH_FocusFrame_AboveWidget, 0, q))
+ if (showFrameAboveWidget)
q->raise();
else
q->stackUnder(widget);
@@ -84,7 +87,10 @@ void QFocusFramePrivate::updateSize()
Q_Q(QFocusFrame);
int vmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameVMargin),
hmargin = q->style()->pixelMetric(QStyle::PM_FocusFrameHMargin);
- QRect geom(widget->x()-hmargin, widget->y()-vmargin,
+ QPoint pos(widget->x(), widget->y());
+ if (q->parentWidget() != widget->parentWidget())
+ pos = widget->parentWidget()->mapTo(q->parentWidget(), pos);
+ QRect geom(pos.x()-hmargin, pos.y()-vmargin,
widget->width()+(hmargin*2), widget->height()+(vmargin*2));
if(q->geometry() == geom)
return;
@@ -176,14 +182,52 @@ void
QFocusFrame::setWidget(QWidget *widget)
{
Q_D(QFocusFrame);
- if(widget == d->widget)
- return;
- if(d->widget)
- d->widget->removeEventFilter(this);
- if(widget && !widget->isWindow() && widget->parentWidget()->windowType() != Qt::SubWindow) {
+ if (style()->styleHint(QStyle::SH_FocusFrame_AboveWidget, 0, this))
+ d->showFrameAboveWidget = true;
+ else
+ d->showFrameAboveWidget = false;
+
+ if (widget == d->widget)
+ return;
+ if (d->widget) {
+ // Remove event filters from the widget hierarchy.
+ QWidget *p = d->widget;
+ do {
+ p->removeEventFilter(this);
+ if (!d->showFrameAboveWidget || p == d->frameParent)
+ break;
+ p = p->parentWidget();
+ }while (p);
+ }
+ if (widget && !widget->isWindow() && widget->parentWidget()->windowType() != Qt::SubWindow) {
d->widget = widget;
- widget->installEventFilter(this);
+ d->widget->installEventFilter(this);
+ QWidget *p = widget->parentWidget();
+ QWidget *prev = 0;
+ if (d->showFrameAboveWidget) {
+ // Find the right parent for the focus frame.
+ while (p) {
+ // Traverse the hirerarchy of the 'widget' for setting event filter.
+ // During this if come across toolbar or a top level, use that
+ // as the parent for the focus frame. If we find a scroll area
+ // use its viewport as the parent.
+ bool isScrollArea = false;
+ if (p->isWindow() || p->inherits("QToolBar") || (isScrollArea = p->inherits("QAbstractScrollArea"))) {
+ d->frameParent = p;
+ // The previous one in the hierarchy will be the viewport.
+ if (prev && isScrollArea)
+ d->frameParent = prev;
+ break;
+ } else {
+ p->installEventFilter(this);
+ prev = p;
+ p = p->parentWidget();
+ }
+ }
+ } else {
+ d->frameParent = p;
+ }
d->update();
} else {
d->widget = 0;
@@ -210,9 +254,15 @@ QFocusFrame::widget() const
void
QFocusFrame::paintEvent(QPaintEvent *)
{
+ Q_D(QFocusFrame);
QStylePainter p(this);
QStyleOption option;
initStyleOption(&option);
+ int vmargin = style()->pixelMetric(QStyle::PM_FocusFrameVMargin);
+ int hmargin = style()->pixelMetric(QStyle::PM_FocusFrameHMargin);
+ QWidgetPrivate *wd = qt_widget_private(d->widget);
+ QRect rect = wd->clipRect().adjusted(0, 0, hmargin*2, vmargin*2);
+ p.setClipRect(rect);
p.drawControl(QStyle::CE_FocusFrame, option);
}
@@ -233,7 +283,13 @@ QFocusFrame::eventFilter(QObject *o, QEvent *e)
hide();
break;
case QEvent::ParentChange:
- d->update();
+ if (d->showFrameAboveWidget) {
+ QWidget *w = d->widget;
+ setWidget(0);
+ setWidget(w);
+ } else {
+ d->update();
+ }
break;
case QEvent::Show:
d->update();
@@ -254,6 +310,19 @@ QFocusFrame::eventFilter(QObject *o, QEvent *e)
default:
break;
}
+ } else if (d->showFrameAboveWidget) {
+ // Handle changes in the parent widgets we are monitoring.
+ switch(e->type()) {
+ case QEvent::Move:
+ case QEvent::Resize:
+ d->updateSize();
+ break;
+ case QEvent::ZOrderChange:
+ raise();
+ break;
+ default:
+ break;
+ }
}
return false;
}
diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp
index 15dcda2..573b2b5 100644
--- a/src/gui/widgets/qlineedit.cpp
+++ b/src/gui/widgets/qlineedit.cpp
@@ -1761,7 +1761,11 @@ void QLineEdit::focusInEvent(QFocusEvent *e)
d->clickCausedFocus = 1;
}
#ifdef QT_KEYPAD_NAVIGATION
- if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && e->reason() == Qt::PopupFocusReason)){
+ if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && ( e->reason() == Qt::PopupFocusReason
+#ifdef Q_OS_SYMBIAN
+ || e->reason() == Qt::ActiveWindowFocusReason
+#endif
+ ))) {
#endif
d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
QStyleOptionFrameV2 opt;
diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h
index 594e488..3f159f6 100644
--- a/src/gui/widgets/qlineedit.h
+++ b/src/gui/widgets/qlineedit.h
@@ -288,6 +288,7 @@ private:
#ifdef QT_KEYPAD_NAVIGATION
Q_PRIVATE_SLOT(d_func(), void _q_editFocusChange(bool))
#endif
+ Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged())
};
#endif // QT_NO_LINEEDIT
diff --git a/src/gui/widgets/qlineedit_p.cpp b/src/gui/widgets/qlineedit_p.cpp
index 4437fef..c18ca25 100644
--- a/src/gui/widgets/qlineedit_p.cpp
+++ b/src/gui/widgets/qlineedit_p.cpp
@@ -126,6 +126,21 @@ void QLineEditPrivate::_q_editFocusChange(bool e)
}
#endif
+void QLineEditPrivate::_q_selectionChanged()
+{
+ Q_Q(QLineEdit);
+ if (control->preeditAreaText().isEmpty()) {
+ QStyleOptionFrameV2 opt;
+ q->initStyleOption(&opt);
+ bool showCursor = control->hasSelectedText() ?
+ q->style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected, &opt, q):
+ true;
+ setCursorVisible(showCursor);
+ }
+
+ emit q->selectionChanged();
+}
+
void QLineEditPrivate::init(const QString& txt)
{
Q_Q(QLineEdit);
@@ -138,7 +153,7 @@ void QLineEditPrivate::init(const QString& txt)
QObject::connect(control, SIGNAL(cursorPositionChanged(int,int)),
q, SLOT(_q_cursorPositionChanged(int,int)));
QObject::connect(control, SIGNAL(selectionChanged()),
- q, SIGNAL(selectionChanged()));
+ q, SLOT(_q_selectionChanged()));
QObject::connect(control, SIGNAL(accepted()),
q, SIGNAL(returnPressed()));
QObject::connect(control, SIGNAL(editingFinished()),
@@ -149,6 +164,9 @@ void QLineEditPrivate::init(const QString& txt)
#endif
QObject::connect(control, SIGNAL(cursorPositionChanged(int,int)),
q, SLOT(updateMicroFocus()));
+
+ QObject::connect(control, SIGNAL(textChanged(const QString &)),
+ q, SLOT(updateMicroFocus()));
// for now, going completely overboard with updates.
QObject::connect(control, SIGNAL(selectionChanged()),
diff --git a/src/gui/widgets/qlineedit_p.h b/src/gui/widgets/qlineedit_p.h
index dc648e8..f13dce2 100644
--- a/src/gui/widgets/qlineedit_p.h
+++ b/src/gui/widgets/qlineedit_p.h
@@ -128,7 +128,7 @@ public:
#ifdef QT_KEYPAD_NAVIGATION
void _q_editFocusChange(bool);
#endif
-
+ void _q_selectionChanged();
#ifndef QT_NO_COMPLETER
void _q_completionHighlighted(QString);
#endif
diff --git a/src/gui/widgets/qmainwindow.h b/src/gui/widgets/qmainwindow.h
index 8ee0507..316bbb8 100644
--- a/src/gui/widgets/qmainwindow.h
+++ b/src/gui/widgets/qmainwindow.h
@@ -102,8 +102,10 @@ public:
Qt::ToolButtonStyle toolButtonStyle() const;
void setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle);
+#ifndef QT_NO_DOCKWIDGET
bool isAnimated() const;
bool isDockNestingEnabled() const;
+#endif
#ifndef QT_NO_TABBAR
bool documentMode() const;
diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm
index 8d8ffa7..6d50678 100644
--- a/src/gui/widgets/qmainwindowlayout_mac.mm
+++ b/src/gui/widgets/qmainwindowlayout_mac.mm
@@ -463,9 +463,6 @@ void QMainWindowLayout::removeFromMacToolbar(QToolBar *toolbar)
NSToolbarItem *item = static_cast<NSToolbarItem *>(it.key());
[[qt_mac_window_for(layoutState.mainWindow->window()) toolbar]
removeItemAtIndex:toolbarItemsCopy.indexOf(item)];
- // In Carbon this hash and list gets emptied via events. In Cocoa, we have to do it ourselves here.
- it = unifiedToolbarHash.erase(it);
- qtoolbarsInUnifiedToolbarList.removeAll(toolbar);
#endif
break;
}
diff --git a/src/gui/widgets/qmdiarea.cpp b/src/gui/widgets/qmdiarea.cpp
index f3dbe34..a4a4cb2 100644
--- a/src/gui/widgets/qmdiarea.cpp
+++ b/src/gui/widgets/qmdiarea.cpp
@@ -1853,11 +1853,11 @@ void QMdiArea::closeAllSubWindows()
}
/*!
- Gives the keyboard focus to the next window in the list of child
- windows. The windows are activated in the order in which they are
- created (CreationOrder).
+ Gives the keyboard focus to another window in the list of child
+ windows. The window activated will be the next one determined
+ by the current \l{QMdiArea::WindowOrder} {activation order}.
- \sa activatePreviousSubWindow()
+ \sa activatePreviousSubWindow(), QMdiArea::WindowOrder
*/
void QMdiArea::activateNextSubWindow()
{
@@ -1871,11 +1871,11 @@ void QMdiArea::activateNextSubWindow()
}
/*!
- Gives the keyboard focus to the previous window in the list of
- child windows. The windows are activated in the order in which
- they are created (CreationOrder).
+ Gives the keyboard focus to another window in the list of child
+ windows. The window activated will be the previous one determined
+ by the current \l{QMdiArea::WindowOrder} {activation order}.
- \sa activateNextSubWindow()
+ \sa activateNextSubWindow(), QMdiArea::WindowOrder
*/
void QMdiArea::activatePreviousSubWindow()
{
diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm
index 30bbd31..99301ee 100644
--- a/src/gui/widgets/qmenu_mac.mm
+++ b/src/gui/widgets/qmenu_mac.mm
@@ -231,7 +231,7 @@ bool qt_mac_activate_action(MenuRef menu, uint command, QAction::ActionEvent act
//now walk up firing for each "caused" widget (like in the platform independent menu)
QWidget *caused = 0;
- if (GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), 0, &caused) == noErr) {
+ if (action_e == QAction::Hover && GetMenuItemProperty(menu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget, sizeof(caused), 0, &caused) == noErr) {
MenuRef caused_menu = 0;
if (QMenu *qmenu2 = qobject_cast<QMenu*>(caused))
caused_menu = qmenu2->macMenu();
@@ -244,25 +244,17 @@ bool qt_mac_activate_action(MenuRef menu, uint command, QAction::ActionEvent act
QWidget *widget = 0;
GetMenuItemProperty(caused_menu, 0, kMenuCreatorQt, kMenuPropertyQWidget, sizeof(widget), 0, &widget);
if (QMenu *qmenu = qobject_cast<QMenu*>(widget)) {
- if (action_e == QAction::Trigger) {
- emit qmenu->triggered(action->action);
- } else if (action_e == QAction::Hover) {
- action->action->showStatusText(widget);
- emit qmenu->hovered(action->action);
- }
+ action->action->showStatusText(widget);
+ emit qmenu->hovered(action->action);
} else if (QMenuBar *qmenubar = qobject_cast<QMenuBar*>(widget)) {
- if (action_e == QAction::Trigger) {
- emit qmenubar->triggered(action->action);
- } else if (action_e == QAction::Hover) {
- action->action->showStatusText(widget);
- emit qmenubar->hovered(action->action);
- }
+ action->action->showStatusText(widget);
+ emit qmenubar->hovered(action->action);
break; //nothing more..
}
//walk up
if (GetMenuItemProperty(caused_menu, 0, kMenuCreatorQt, kMenuPropertyCausedQWidget,
- sizeof(caused), 0, &caused) != noErr)
+ sizeof(caused), 0, &caused) != noErr)
break;
if (QMenu *qmenu2 = qobject_cast<QMenu*>(caused))
caused_menu = qmenu2->macMenu();
diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp
index be24012..18b793e 100644
--- a/src/gui/widgets/qplaintextedit.cpp
+++ b/src/gui/widgets/qplaintextedit.cpp
@@ -765,6 +765,7 @@ void QPlainTextEditPrivate::init(const QString &txt)
QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(_q_cursorPositionChanged()));
QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
+ QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus()));
// set a null page size initially to avoid any relayouting until the textedit
// is shown. relayoutDocument() will take care of setting the page size to the
diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp
index 1bc0bf1..5d8f134 100644
--- a/src/gui/widgets/qtextedit.cpp
+++ b/src/gui/widgets/qtextedit.cpp
@@ -158,6 +158,8 @@ void QTextEditPrivate::init(const QString &html)
QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
+ QObject::connect(control, SIGNAL(textChanged()), q, SLOT(updateMicroFocus()));
+
QTextDocument *doc = control->document();
// set a null page size initially to avoid any relayouting until the textedit
// is shown. relayoutDocument() will take care of setting the page size to the